linux icon indicating copy to clipboard operation
linux copied to clipboard

RPI4: WiFi station's signal always is 0

Open yzm157 opened this issue 4 years ago • 9 comments

I upgraded the Raspberry Pi to the latest kernel. When I get all the client information through the command "hostapd_cli all_sta", the signal is always 0, which is good in the 2021-05-07 version.

yzm157 avatar Sep 10 '21 09:09 yzm157

Fill out the Bug template with the required information or you will get no assistance.

pelwell avatar Sep 10 '21 10:09 pelwell

Fill out the Bug template with the required information or you will get no assistance.

@pelwell thank you for your reply。

I use the Raspberry Pi 4B as an AP, and use the create_ap tool to create the AP. Latest kernel: Linux raspberrypi 5.10.63-v7l+ #1496 SMP Wed Dec 1 15:58:56 GMT 2021 armv7l GNU/Linux sudo ./create_ap wlan0 eth0 rpi-4b raspberry

WARN: brmfmac driver doesn't work properly with virtual interfaces and it can cause kernel panic. For this reason we disallow virtual interfaces for your adapter. For more info: https://github.com/oblique/create_ap/issues/203 WARN: Your adapter does not fully support AP virtual interface, enabling --no-virt Config dir: /tmp/create_ap.wlan0.conf.mXhkCVOa PID: 765 Sharing Internet using method: nat hostapd command-line interface: hostapd_cli -p /tmp/create_ap.wlan0.conf.mXhkCVOa/hostapd_ctrl Configuration file: /tmp/create_ap.wlan0.conf.mXhkCVOa/hostapd.conf wlan0: Could not connect to kernel driver Using interface wlan0 with hwaddr dc:a6:32:23:97:82 and ssid "rpi-4b" wlan0: interface state UNINITIALIZED->ENABLED wlan0: AP-ENABLED

Connect to wireless via mobile phone, ssid: rpi-4b, password: raspberry

wlan0: STA d0:49:7c:xx:xx:xx IEEE 802.11: associated wlan0: AP-STA-CONNECTED d0:49:7c:xx:xx:xx wlan0: STA d0:49:7c:xx:xx:xx RADIUS: starting accounting session 7689891474B5DB3C wlan0: STA d0:49:7c:xx:xx:xx WPA: pairwise key handshake completed (WPA) wlan0: STA d0:49:7c:xx:xx:xx WPA: group key handshake completed (WPA)

Now the wireless connection is complete

sudo hostapd_cli -p /tmp/create_ap.wlan0.conf.mXhkCVOa/hostapd_ctrl all_sta

Selected interface 'wlan0' d0:49:7c:xx:xx:xx flags=[AUTH][ASSOC][AUTHORIZED] aid=0 capability=0x0 listen_interval=0 supported_rates= timeout_next=NULLFUNC POLL dot11RSNAStatsSTAAddress=d0:49:7c:20:5d:9f dot11RSNAStatsVersion=1 dot11RSNAStatsSelectedPairwiseCipher=00-50-f2-4 dot11RSNAStatsTKIPLocalMICFailures=0 dot11RSNAStatsTKIPRemoteMICFailures=0 hostapdWPAPTKState=11 hostapdWPAPTKGroupState=0 rx_packets=1145 tx_packets=853 rx_bytes=222539 tx_bytes=398039 inactive_msec=0 signal=0 rx_rate_info=10 tx_rate_info=650 connected_time=159 supp_op_classes=515153547374757677787c7d7e7f8082

When obtaining all client information through hostapd_cli, the signal is always 0,which is good in the 2021-05-07 raspbian firmware version (Linux raspberrypi 5.10.17-v7l+ #1414 SMP Fri Apr 30 13:20:47 BST 2021 armv7l GNU/Linux).

yzm157 avatar Dec 03 '21 15:12 yzm157

[ Reopening this issue because comments on commits are easily lost ] You've identified https://github.com/raspberrypi/linux/commit/5b8d0b0727f62f827a2f35409fa57068dc39d700 as being the breaking commit. You also wrote that:

I printed sta_info_le.rx_lastpkt_rssi[x], it is always 0

[22219.454004] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[0] = -50
[22219.454025] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[0] = 0
[22219.454042] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[1] = 0
[22219.454059] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[1] = 0
[22219.454075] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[2] = 0
[22219.454091] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[2] = 0
[22219.454107] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[3] = 0
[22219.454122] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[3] = 0

What happens if you change the code from:

                       if (sta_info_le.rssi[i] == 0 ||
                           sta_info_le.rx_lastpkt_rssi[i] == 0)
                               continue;

to:

                       if (sta_info_le.rssi[i] == 0)
                               continue;

?

pelwell avatar Dec 06 '21 15:12 pelwell

What happens if you change the code from:

                       if (sta_info_le.rssi[i] == 0 ||
                           sta_info_le.rx_lastpkt_rssi[i] == 0)
                               continue;

to:

                       if (sta_info_le.rssi[i] == 0)
                               continue;

?

                for (i = 0; i < BRCMF_ANT_MAX; i++) {
                        brcmf_err("sta_info_le.rssi[%d] = %d\n", i, sta_info_le.rssi[i]);
                        brcmf_err("sta_info_le.rx_lastpkt_rssi[%d] = %d\n", i, sta_info_le.rx_lastpkt_rssi[i]);
                        if (sta_info_le.rssi[i] == 0)
                                continue;
                        sinfo->chains |= BIT(count_rssi);
                        sinfo->chain_signal[count_rssi] =
                                sta_info_le.rx_lastpkt_rssi[i];
                        sinfo->chain_signal_avg[count_rssi] =
                                sta_info_le.rssi[i];
                        total_rssi += sta_info_le.rx_lastpkt_rssi[i];
                        total_rssi_avg += sta_info_le.rssi[i];
                        count_rssi++;
                        brcmf_err("i = %d, total_rssi = %d, total_rssi_avg = %d, count_rssi = %d\n", i, total_rssi, total_rssi_avg, count_rssi);
                }
                if (count_rssi) {
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
                        sinfo->filled |=
                                BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
                        sinfo->signal = total_rssi / count_rssi;
                        sinfo->signal_avg = total_rssi_avg / count_rssi;
                        brcmf_err("sinfo->signal = %d, sinfo->signal_avg = %d\n", sinfo->signal, sinfo->signal_avg);
                }

I tried to modify the above code, but still can't get the value of sinfo->signal, the value of sinfo->signal_avg exists, and the value of rssi should be sinfo->signal, not sinfo->signal_avg

[47670.394993] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[0] = -50
[47670.395012] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[0] = 0
[47670.395028] brcmfmac: brcmf_cfg80211_get_station: i = 0, total_rssi = 0, total_rssi_avg = -50, count_rssi = 1
[47670.395042] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[1] = 0
[47670.395057] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[1] = 0
[47670.395070] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[2] = 0
[47670.395098] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[2] = 0
[47670.395112] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rssi[3] = 0
[47670.395125] brcmfmac: brcmf_cfg80211_get_station: sta_info_le.rx_lastpkt_rssi[3] = 0
[47670.395139] brcmfmac: brcmf_cfg80211_get_station: sinfo->signal = 0, sinfo->signal_avg = -50

yzm157 avatar Dec 07 '21 02:12 yzm157

All the Broadcom-based chips and firmwares I tried return 0 in the rx_lastpkt_rssi field, i.e. it is only reporting an average value.

In the unmodified rpi-5.10.y version of the code, count_rssi ends up as 0 because of the test for both rssi and rx_lastpkt_rssi being non-zero, which means it falls back to use this bit of code:

		} else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
			&ifp->vif->sme_state)) {
			memset(&scb_val, 0, sizeof(scb_val));
			err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
						     &scb_val, sizeof(scb_val));
			if (err) {
				bphy_err(drvr, "Could not get rssi (%d)\n",
					 err);
				goto done;
			} else {
				rssi = le32_to_cpu(scb_val.val);
				sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
				sinfo->signal = rssi;
				brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
			}
		}

Can you confirm that it is getting as far as sinfo->signal = rssi;, and that the assigned value is non-zero?

pelwell avatar Dec 07 '21 14:12 pelwell

@pelwell The code did not execute this branch.

                brcmf_err("test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) = %d\n", 
                                test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state));
                if (count_rssi) {
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
                        sinfo->filled |=
                                BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
                        sinfo->signal = total_rssi / count_rssi;
                        sinfo->signal_avg = total_rssi_avg / count_rssi;
                } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
                        &ifp->vif->sme_state)) {
                        memset(&scb_val, 0, sizeof(scb_val));
                        err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
                                                     &scb_val, sizeof(scb_val));
                        if (err) {
                                bphy_err(drvr, "Could not get rssi (%d)\n",
                                         err);
                                goto done;
                        } else {
                                rssi = le32_to_cpu(scb_val.val);
                                sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
                                sinfo->signal = rssi;
                                brcmf_err("RSSI %d dBm\n", rssi);
                                brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
                        }
                }

Output:

brcmfmac: brcmf_cfg80211_get_station: test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state) = 0

yzm157 avatar Dec 08 '21 02:12 yzm157

I was assuming, but failed to state, that the other patch (removing the || sta_info_le.rx_lastpkt_rssi[i] == 0) would be reverted. I'm trying to establish what is populating sinfo->filled, sinfo->signal and sinfo->signal_avg (if anything) in the normal path through the code for you.

pelwell avatar Dec 08 '21 08:12 pelwell

@pelwell Is there any progress on this issue?

yzm157 avatar Apr 11 '22 02:04 yzm157

No.

pelwell avatar Apr 13 '22 14:04 pelwell