diff --git a/sys/dev/iwx/if_iwx.c b/sys/dev/iwx/if_iwx.c --- a/sys/dev/iwx/if_iwx.c +++ b/sys/dev/iwx/if_iwx.c @@ -429,10 +429,9 @@ static int iwx_config_ltr(struct iwx_softc *); static void iwx_update_rx_desc(struct iwx_softc *, struct iwx_rx_ring *, int, bus_dma_segment_t *); static int iwx_rx_addbuf(struct iwx_softc *, int, int); -static int iwx_rxmq_get_signal_strength(struct iwx_softc *, struct iwx_rx_mpdu_desc *); +static int8_t iwx_rxmq_get_signal_strength(struct iwx_softc *, struct iwx_rx_mpdu_desc *); static void iwx_rx_rx_phy_cmd(struct iwx_softc *, struct iwx_rx_packet *, struct iwx_rx_data *); -static int iwx_get_noise(const struct iwx_statistics_rx_non_phy *); static int iwx_rx_hwdecrypt(struct iwx_softc *, struct mbuf *, uint32_t); #if 0 int iwx_ccmp_decap(struct iwx_softc *, struct mbuf *, @@ -4176,11 +4175,11 @@ return 0; } -static int +static int8_t iwx_rxmq_get_signal_strength(struct iwx_softc *sc, struct iwx_rx_mpdu_desc *desc) { - int energy_a, energy_b; + int8_t energy_a, energy_b; if (sc->sc_device_family >= IWX_DEVICE_FAMILY_AX210) { energy_a = desc->v3.energy_a; @@ -4189,8 +4188,8 @@ energy_a = desc->v1.energy_a; energy_b = desc->v1.energy_b; } - energy_a = energy_a ? -energy_a : -256; - energy_b = energy_b ? -energy_b : -256; + energy_a = energy_a ? -energy_a : INT8_MIN; + energy_b = energy_b ? -energy_b : INT8_MIN; return MAX(energy_a, energy_b); } @@ -4210,10 +4209,12 @@ /* * Retrieve the average noise (in dBm) among receivers. */ -static int +static uint8_t iwx_get_noise(const struct iwx_statistics_rx_non_phy *stats) { - int i, total, nbant, noise; + int i, nbant; + uint32_t total; + uint8_t noise; total = nbant = noise = 0; for (i = 0; i < 3; i++) { @@ -4225,7 +4226,7 @@ } /* There should be at least one antenna but check anyway. */ - return (nbant == 0) ? -127 : (total / nbant) - 107; + return (nbant == 0) ? -127 : (-127 + (total / nbant)); } #if 0 @@ -4479,7 +4480,7 @@ struct ieee80211_rx_stats rxs; struct iwx_rx_mpdu_desc *desc; uint32_t len, hdrlen, rate_n_flags, device_timestamp; - int rssi; + int8_t rssi; uint8_t chanidx; uint16_t phy_info; size_t desc_size; @@ -4622,8 +4623,6 @@ phy_info = le16toh(desc->phy_info); rssi = iwx_rxmq_get_signal_strength(sc, desc); - rssi = (0 - IWX_MIN_DBM) + rssi; /* normalize */ - rssi = MIN(rssi, (IWX_MAX_DBM - IWX_MIN_DBM)); /* clip to max. 100% */ memset(&rxs, 0, sizeof(rxs)); rxs.r_flags |= IEEE80211_R_IEEE | IEEE80211_R_FREQ; @@ -4639,9 +4638,18 @@ rxs.c_rx_tsf = device_timestamp; rxs.c_chain = chanidx; - /* rssi is in 1/2db units */ - rxs.c_rssi = rssi * 2; + /* + * iwx_attach initialized sc_noise to be reasonably valid before + * the first IWX_STATISTICS_NOTIFICATION with information. + */ rxs.c_nf = sc->sc_noise; + if (rssi != 0) { + /* rssi is in 1/2db units relative to the NF. */ + rxs.c_rssi = (rssi - sc->sc_noise) * 2; + } else { + /* Or we do not set IEEE80211_R_RSSI? */ + rxs.c_rssi = rxs.c_nf; + } if (pad) { rxs.c_pktflags |= IEEE80211_RX_F_DECRYPTED; @@ -10498,6 +10506,9 @@ mbufq_init(&rxba->entries[j].frames, ifqmaxlen); } + /* Initialize to something to have a chance to get S:N values. */ + sc->sc_noise = -127; + sc->sc_preinit_hook.ich_func = iwx_attach_hook; sc->sc_preinit_hook.ich_arg = sc; if (config_intrhook_establish(&sc->sc_preinit_hook) != 0) { diff --git a/sys/dev/iwx/if_iwxvar.h b/sys/dev/iwx/if_iwxvar.h --- a/sys/dev/iwx/if_iwxvar.h +++ b/sys/dev/iwx/if_iwxvar.h @@ -786,7 +786,7 @@ struct iwx_phy_ctxt sc_phyctxt[IWX_NUM_PHY_CTX]; struct iwx_notif_statistics sc_stats; - int sc_noise; + int8_t sc_noise; int sc_pm_support; int sc_ltr_enabled;