brcmfmac: correctly report average RSSI in station info
authorAlvin Šipraga <ALSI@bang-olufsen.dk>
Thu, 6 May 2021 13:20:12 +0000 (13:20 +0000)
committerKalle Valo <kvalo@codeaurora.org>
Tue, 15 Jun 2021 10:36:45 +0000 (13:36 +0300)
The rx_lastpkt_rssi field provided by the firmware is suitable for
NL80211_STA_INFO_{SIGNAL,CHAIN_SIGNAL}, while the rssi field is an
average. Fix up the assignments and set the correct STA_INFO bits. This
lets userspace know that the average RSSI is part of the station info.

Fixes: cae355dc90db ("brcmfmac: Add RSSI information to get_station.")
Signed-off-by: Alvin Šipraga <alsi@bang-olufsen.dk>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20210506132010.3964484-2-alsi@bang-olufsen.dk
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c

index 77458095bbd4ddb2c05cf3b00d89fb8e52a6b482..65fb038d88e74f257421364ad43c3c9c18bf7297 100644 (file)
@@ -2767,8 +2767,9 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
        struct brcmf_sta_info_le sta_info_le;
        u32 sta_flags;
        u32 is_tdls_peer;
-       s32 total_rssi;
-       s32 count_rssi;
+       s32 total_rssi_avg = 0;
+       s32 total_rssi = 0;
+       s32 count_rssi = 0;
        int rssi;
        u32 i;
 
@@ -2834,24 +2835,27 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
                        sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
                }
-               total_rssi = 0;
-               count_rssi = 0;
                for (i = 0; i < BRCMF_ANT_MAX; i++) {
-                       if (sta_info_le.rssi[i]) {
-                               sinfo->chains |= BIT(count_rssi);
-                               sinfo->chain_signal_avg[count_rssi] =
-                                       sta_info_le.rssi[i];
-                               sinfo->chain_signal[count_rssi] =
-                                       sta_info_le.rssi[i];
-                               total_rssi += sta_info_le.rssi[i];
-                               count_rssi++;
-                       }
+                       if (sta_info_le.rssi[i] == 0 ||
+                           sta_info_le.rx_lastpkt_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++;
                }
                if (count_rssi) {
-                       sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
                        sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
-                       total_rssi /= count_rssi;
-                       sinfo->signal = total_rssi;
+                       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));