Author: adrian
Date: Sun Sep 18 05:07:18 2016
New Revision: 305917
URL: https://svnweb.freebsd.org/changeset/base/305917

Log:
  [iwm] fix up RSSI calculations for both scan results and normal RX operations.
  
  * hard code a noise floor of -96 for now. The noise floor update code returns
    some "interesting" values that I can't map to anything useful right now.
  * Ensure a default noise floor is set - otherwise the initial scan results
    have a noise floor of '0'.
  * Fix up the RSSI calculation to be correctly relative to the noise floor.
    The RSSI routines return an absolute value in dBm - so fix this up.
  * Cap RSSI values appropriately.
  * Ensure we pass in a 1/2 dB unit value in to net80211.
  
  Tested:
  
  * Intel 7260, STA mode
  
  iwm0: <Intel Dual Band Wireless AC 7260> mem 0xf1400000-0xf1401fff irq 17 at 
device 0.0 on pci2
  iwm0: hw rev 0x140, fw ver 16.242414.0, address xx:xx:xx:xx:xx:xx

Modified:
  head/sys/dev/iwm/if_iwm.c

Modified: head/sys/dev/iwm/if_iwm.c
==============================================================================
--- head/sys/dev/iwm/if_iwm.c   Sun Sep 18 05:06:15 2016        (r305916)
+++ head/sys/dev/iwm/if_iwm.c   Sun Sep 18 05:07:18 2016        (r305917)
@@ -312,7 +312,8 @@ static int  iwm_mvm_get_signal_strength(s
 static void    iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *,
                                       struct iwm_rx_packet *,
                                       struct iwm_rx_data *);
-static int     iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *);
+static int     iwm_get_noise(struct iwm_softc *sc,
+                   const struct iwm_mvm_statistics_rx_non_phy *);
 static void    iwm_mvm_rx_rx_mpdu(struct iwm_softc *, struct iwm_rx_packet *,
                                    struct iwm_rx_data *);
 static int     iwm_mvm_rx_tx_cmd_single(struct iwm_softc *,
@@ -2871,21 +2872,34 @@ iwm_mvm_rx_rx_phy_cmd(struct iwm_softc *
  * Retrieve the average noise (in dBm) among receivers.
  */
 static int
-iwm_get_noise(const struct iwm_mvm_statistics_rx_non_phy *stats)
+iwm_get_noise(struct iwm_softc *sc,
+    const struct iwm_mvm_statistics_rx_non_phy *stats)
 {
        int i, total, nbant, noise;
 
        total = nbant = noise = 0;
        for (i = 0; i < 3; i++) {
                noise = le32toh(stats->beacon_silence_rssi[i]) & 0xff;
+               IWM_DPRINTF(sc, IWM_DEBUG_RECV, "%s: i=%d, noise=%d\n",
+                   __func__,
+                   i,
+                   noise);
+
                if (noise) {
                        total += noise;
                        nbant++;
                }
        }
 
+       IWM_DPRINTF(sc, IWM_DEBUG_RECV, "%s: nbant=%d, total=%d\n",
+           __func__, nbant, total);
+#if 0
        /* There should be at least one antenna but check anyway. */
        return (nbant == 0) ? -127 : (total / nbant) - 107;
+#else
+       /* For now, just hard-code it to -96 to be safe */
+       return (-96);
+#endif
 }
 
 /*
@@ -2940,8 +2954,15 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc,
        } else {
                rssi = iwm_mvm_calc_rssi(sc, phy_info);
        }
-       rssi = (0 - IWM_MIN_DBM) + rssi;        /* normalize */
-       rssi = MIN(rssi, sc->sc_max_rssi);      /* clip to max. 100% */
+
+       /* Note: RSSI is absolute (ie a -ve value) */
+       if (rssi < IWM_MIN_DBM)
+               rssi = IWM_MIN_DBM;
+       else if (rssi > IWM_MAX_DBM)
+               rssi = IWM_MAX_DBM;
+
+       /* Map it to relative value */
+       rssi = rssi - sc->sc_noise;
 
        /* replenish ring for the buffer we're going to feed to the sharks */
        if (iwm_rx_addbuf(sc, IWM_RBUF_SIZE, sc->rxq.cur) != 0) {
@@ -2950,6 +2971,9 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc,
                return;
        }
 
+       IWM_DPRINTF(sc, IWM_DEBUG_RECV,
+           "%s: rssi=%d, noise=%d\n", __func__, rssi, sc->sc_noise);
+
        ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
 
        IWM_DPRINTF(sc, IWM_DEBUG_RECV,
@@ -2970,7 +2994,9 @@ iwm_mvm_rx_rx_mpdu(struct iwm_softc *sc,
        } else {
                rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, 
IEEE80211_CHAN_5GHZ);
        }
-       rxs.rssi = rssi - sc->sc_noise;
+
+       /* rssi is in 1/2db units */
+       rxs.rssi = rssi * 2;
        rxs.nf = sc->sc_noise;
 
        if (ieee80211_radiotap_active_vap(vap)) {
@@ -5172,7 +5198,7 @@ iwm_notif_intr(struct iwm_softc *sc)
                        struct iwm_notif_statistics *stats;
                        SYNC_RESP_STRUCT(stats, pkt);
                        memcpy(&sc->sc_stats, stats, sizeof(sc->sc_stats));
-                       sc->sc_noise = iwm_get_noise(&stats->rx.general);
+                       sc->sc_noise = iwm_get_noise(sc, &stats->rx.general);
                        break; }
 
                case IWM_NVM_ACCESS_CMD:
@@ -5823,8 +5849,12 @@ iwm_attach(device_t dev)
                sc->sc_phyctxt[i].channel = NULL;
        }
 
+       /* Default noise floor */
+       sc->sc_noise = -96;
+
        /* Max RSSI */
        sc->sc_max_rssi = IWM_MAX_DBM - IWM_MIN_DBM;
+
        sc->sc_preinit_hook.ich_func = iwm_preinit;
        sc->sc_preinit_hook.ich_arg = sc;
        if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to