Date: Sun, 18 Sep 2016 05:07:18 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r305917 - head/sys/dev/iwm Message-ID: <201609180507.u8I57Ivo039986@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
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) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201609180507.u8I57Ivo039986>