Ticket #881: madwifi_measured_noise.patch

File madwifi_measured_noise.patch, 9.4 kB (added by scottraynel@gmail.com, 6 years ago)

Use measured noise levels instead of assuming -95 dBm

  • net80211/ieee80211_wireless.c

    old new  
    9797 * rssi values reported in the tx/rx descriptors in the 
    9898 * driver are the SNR expressed in db. 
    9999 * 
    100  * If you assume that the noise floor is -95, which is an 
    101  * excellent assumption 99.5 % of the time, then you can 
    102  * derive the absolute signal level (i.e. -95 + rssi).  
    103  * There are some other slight factors to take into account 
    104  * depending on whether the rssi measurement is from 11b, 
    105  * 11g, or 11a.   These differences are at most 2db and 
    106  * can be documented. 
     100 * noise is measured in dBm. Signal becomes the noise + 
     101 * the rssi. 
    107102 * 
    108103 * NB: various calculations are based on the orinoco/wavelan 
    109104 *     drivers for compatibility 
    110105 */ 
    111106static void 
    112 set_quality(struct iw_quality *iq, u_int rssi
     107set_quality(struct iw_quality *iq, u_int rssi, int noise
    113108{ 
    114109        iq->qual = rssi; 
    115         /* NB: max is 94 because noise is hardcoded to 161 */ 
    116         if (iq->qual > 94) 
    117                 iq->qual = 94; 
    118  
    119         iq->noise = 161;                /* -95dBm */ 
     110        iq->noise = noise;  
    120111        iq->level = iq->noise + iq->qual; 
    121112        iq->updated = IW_QUAL_ALL_UPDATED; 
    122113} 
     
    159150{ 
    160151        struct ieee80211vap *vap = dev->priv; 
    161152        struct iw_statistics *is = &vap->iv_iwstats; 
    162  
    163         set_quality(&is->qual, ieee80211_getrssi(vap->iv_ic)); 
     153        struct ieee80211com *ic = vap->iv_ic; 
     154         
     155        set_quality(&is->qual, ieee80211_getrssi(vap->iv_ic),  
     156                        ic->ic_channoise); 
    164157        is->status = vap->iv_state; 
    165158        is->discard.nwid = vap->iv_stats.is_rx_wrongbss + 
    166159                vap->iv_stats.is_rx_ssidmismatch; 
     
    992985        } 
    993986 
    994987        /* Max quality is max field value minus noise floor */ 
     988        /* XXX Should this be updated to use the current noise floor? */ 
    995989        range->max_qual.qual  = 0xff - 161; 
    996990 
    997991        /* 
     
    11091103        struct ieee80211vap *vap = dev->priv; 
    11101104        struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta; 
    11111105        struct ieee80211_node *ni; 
     1106        struct ieee80211com *ic = vap->iv_ic; 
    11121107        struct sockaddr *address; 
    11131108        struct iw_quality *spy_stat; 
    11141109        unsigned int number = vap->iv_spy.num; 
     
    11291124                /* TODO: free node ? */ 
    11301125                /* check we are associated w/ this vap */ 
    11311126                if (ni && (ni->ni_vap == vap)) { 
    1132                         set_quality(&spy_stat[i], ni->ni_rssi); 
     1127                        set_quality(&spy_stat[i], ni->ni_rssi, ic->ic_channoise); 
    11331128                        if (ni->ni_rstamp != vap->iv_spy.ts_rssi[i]) { 
    11341129                                vap->iv_spy.ts_rssi[i] = ni->ni_rstamp; 
    11351130                        } else { 
     
    11731168                        "%s: disabled iw_spy threshold\n", __func__); 
    11741169        } else { 
    11751170                /* calculate corresponding rssi values */ 
     1171                /* XXX Should we use current noise value? */ 
    11761172                vap->iv_spy.thr_low = threshold.low.level - 161; 
    11771173                vap->iv_spy.thr_high = threshold.high.level - 161; 
    11781174                IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG, 
     
    11871183        struct iw_point *data, char *extra) 
    11881184{ 
    11891185        struct ieee80211vap *vap = dev->priv; 
     1186        struct ieee80211com *ic = vap->iv_ic; 
    11901187        struct iw_thrspy *threshold;     
    11911188         
    11921189        threshold = (struct iw_thrspy *) extra; 
    11931190 
    11941191        /* set threshold values */ 
    1195         set_quality(&(threshold->low), vap->iv_spy.thr_low); 
    1196         set_quality(&(threshold->high), vap->iv_spy.thr_high); 
     1192        set_quality(&(threshold->low), vap->iv_spy.thr_low, ic->ic_channoise); 
     1193        set_quality(&(threshold->high), vap->iv_spy.thr_high, ic->ic_channoise); 
    11971194 
    11981195        /* copy results to userspace */ 
    11991196        data->length = 1; 
     
    14681465                IEEE80211_ADDR_COPY(req->addr[i].sa_data, se->se_macaddr); 
    14691466        else 
    14701467                IEEE80211_ADDR_COPY(req->addr[i].sa_data, se->se_bssid); 
    1471         set_quality(&req->qual[i], se->se_rssi); 
     1468        set_quality(&req->qual[i], se->se_rssi, -95); 
    14721469        req->i = i + 1; 
    14731470 
    14741471        return 0; 
     
    16651662        memset(&iwe, 0, sizeof(iwe)); 
    16661663        last_ev = current_ev; 
    16671664        iwe.cmd = IWEVQUAL; 
    1668         set_quality(&iwe.u.qual, se->se_rssi); 
     1665        set_quality(&iwe.u.qual, se->se_rssi, -95); 
    16691666        current_ev = iwe_stream_add_event(current_ev, 
    16701667                end_buf, &iwe, IW_EV_QUAL_LEN); 
    16711668 
  • net80211/ieee80211_input.c

    old new  
    143143 * This function is a clone of set_quality(..) in ieee80211_wireless.c 
    144144 */ 
    145145static void 
    146 set_quality(struct iw_quality *iq, u_int rssi
     146set_quality(struct iw_quality *iq, u_int rssi, int noise
    147147{ 
    148148        iq->qual = rssi; 
    149         /* NB: max is 94 because noise is hardcoded to 161 */ 
    150         if (iq->qual > 94) 
    151                 iq->qual = 94; 
    152149 
    153         iq->noise = 161;               /* -95dBm */ 
     150        iq->noise = noise;      
    154151        iq->level = iq->noise + iq->qual; 
    155152        iq->updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | 
    156153                IW_QUAL_NOISE_UPDATED; 
     
    188185                                memcpy(thr.addr.sa_data, ni->ni_macaddr, 
    189186                                        IEEE80211_ADDR_LEN); 
    190187                                thr.addr.sa_family = ARPHRD_ETHER; 
    191                                 set_quality(&thr.qual, rssi); 
    192                                 set_quality(&thr.low, vap->iv_spy.thr_low); 
    193                                 set_quality(&thr.high, vap->iv_spy.thr_high); 
     188                                set_quality(&thr.qual, rssi, vap->iv_ic->ic_channoise); 
     189                                set_quality(&thr.low, vap->iv_spy.thr_low, vap->iv_ic->ic_channoise); 
     190                                set_quality(&thr.high, vap->iv_spy.thr_high, vap->iv_ic->ic_channoise); 
    194191                                wireless_send_event(vap->iv_dev, 
    195192                                        SIOCGIWTHRSPY, &wrq, (char*) &thr); 
    196193                                break; 
  • net80211/ieee80211_monitor.c

    old new  
    209209        struct ath_desc *ds, int tx, u_int32_t mactime, struct ath_softc *sc)  
    210210{ 
    211211        struct ieee80211vap *vap, *next; 
    212         u_int32_t signal = 0; 
    213         signal = tx ? ds->ds_txstat.ts_rssi : ds->ds_rxstat.rs_rssi
     212        int noise = 0; 
     213        u_int32_t rssi = 0
    214214         
     215        rssi = tx ? ds->ds_txstat.ts_rssi : ds->ds_rxstat.rs_rssi; 
     216         
     217        /* We don't have access to the noise value in the descriptor, but it's saved 
     218         * in the softc during the last receive interrupt. */ 
     219        noise = sc->sc_channoise; 
     220 
    215221        /* XXX locking */ 
    216222        for (vap = TAILQ_FIRST(&ic->ic_vaps); vap != NULL; vap = next) { 
    217223                struct sk_buff *skb1; 
     
    287293                        ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; 
    288294                        ph->rssi.status = 0; 
    289295                        ph->rssi.len = 4; 
    290                         ph->rssi.data = signal
     296                        ph->rssi.data = rssi
    291297                         
    292298                        ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; 
    293299                        ph->noise.status = 0; 
    294300                        ph->noise.len = 4; 
    295                         ph->noise.data = -95
     301                        ph->noise.data = noise
    296302                         
    297303                        ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; 
    298304                        ph->signal.status = 0; 
    299305                        ph->signal.len = 4; 
    300                         ph->signal.data = signal
     306                        ph->signal.data = rssi + noise
    301307                         
    302308                        ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; 
    303309                        ph->rate.status = 0; 
     
    374380                                                break; 
    375381                                } 
    376382 
    377                                 th->wr_dbm_antnoise = -95
    378                                 th->wr_dbm_antsignal = th->wr_dbm_antnoise + signal
     383                                th->wr_dbm_antnoise = (int8_t) noise
     384                                th->wr_dbm_antsignal = th->wr_dbm_antnoise + rssi
    379385                                th->wr_antenna = ds->ds_rxstat.rs_antenna; 
    380                                 th->wr_antsignal = signal
     386                                th->wr_antsignal = rssi
    381387                                memcpy(&th->wr_fcs, &skb1->data[skb1->len - IEEE80211_CRC_LEN], 
    382388                                       IEEE80211_CRC_LEN); 
    383389                                th->wr_fcs = cpu_to_le32(th->wr_fcs); 
  • net80211/ieee80211_var.h

    old new  
    167167        struct ieee80211_channel *ic_curchan;   /* current channel */ 
    168168        struct ieee80211_channel *ic_bsschan;   /* bss channel */ 
    169169        struct ieee80211_channel *ic_prevchan;  /* previous channel */ 
    170  
     170        int16_t ic_channoise;                   /* current channel noise in dBm */ 
    171171        /* regulatory class ids */ 
    172172        u_int ic_nregclass;                     /* # entries in ic_regclassids */ 
    173173        u_int8_t ic_regclassids[IEEE80211_REGCLASSIDS_MAX]; 
  • ath/if_athvar.h

    old new  
    673673        u_int32_t sc_dturbo_bw_turbo;           /* bandwidth threshold */ 
    674674#endif 
    675675        u_int sc_slottimeconf;                  /* manual override for slottime */ 
     676        int16_t sc_channoise;                   /* Measured noise of current channel (dBm) */ 
    676677}; 
    677678 
    678679typedef void (*ath_callback) (struct ath_softc *); 
     
    10001001        ((*(_ah)->ah_dfsNolCheck)((_ah), (_chan), (_nchans))) 
    10011002#define ath_hal_radar_wait(_ah, _chan) \ 
    10021003        ((*(_ah)->ah_radarWait)((_ah), (_chan))) 
     1004#define ath_hal_get_channel_noise(_ah, _chan) \ 
     1005        ((*(_ah)->ah_getChanNoise)((_ah), (_chan))) 
    10031006 
    10041007#endif /* _DEV_ATH_ATHVAR_H */ 
  • ath/if_ath.c

    old new  
    16481648                } 
    16491649                if (status & HAL_INT_RX) { 
    16501650                        ath_uapsd_processtriggers(sc); 
     1651                        /* Get the noise floor data in interrupt context as we can't get it 
     1652                         * per frame, so we need to get it as soon as possible (i.e. the tasklet 
     1653                         * might take too long to fire */ 
     1654                        ath_hal_process_noisefloor(ah); 
     1655                        sc->sc_channoise = ath_hal_get_channel_noise(ah, &(sc->sc_curchan)); 
    16511656                        ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark); 
    16521657                } 
    16531658                if (status & HAL_INT_TX) { 
     
    53685373        int len, type; 
    53695374        u_int phyerr; 
    53705375 
     5376        /* Let the 802.11 layer know about the new noise floor */ 
     5377        ic->ic_channoise = sc->sc_channoise; 
     5378         
    53715379        DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__); 
    53725380        do { 
    53735381                bf = STAILQ_FIRST(&sc->sc_rxbuf); 
     
    56335641                STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); 
    56345642                ATH_RXBUF_UNLOCK_IRQ(sc); 
    56355643        } while (ath_rxbuf_init(sc, bf) == 0); 
    5636  
     5644         
    56375645        /* rx signal state monitoring */ 
    56385646        ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); 
    56395647        if (ath_hal_radar_event(ah)) {