Changeset 1713

Show
Ignore:
Timestamp:
09/15/06 03:43:03 (2 years ago)
Author:
kelmo
Message:

The current HAL exports two functions which appear to have gone
unnoticed for quite some time.

This patch makes use of those functions and gives measured noise data
from the HAL to the driver and stack instead of simply assuming
-95dBm throughout.

Currently the noise level is retrived on every rx interrupt and
stored in the softc for the device. It is then passed to the 802.11
stack during the rx tasklet where it is used by the wireless
extensions code. It is also used by the monitor mode functions to
record the current noise level.

Because the descriptors only have an RSSI value in them and not a
noise value, there is some error. The noise can not be retrived per
frame, only per interrupt, and we cannot be sure if the RSSI was
calculated using the noise level we just retrieved or some "older"
value.

The other problem is scanning. Currently we do not keep a list of
channels and their associated noise levels, we only keep a
"current noise" value, which will end up being the last noise value
retrieved. This means that all scan results will have the same noise
level rather than individual levels for each channel. Presumably we
could keep a list of channels, and then before we switch to the next
channel to scan, get the noise and store it. The scan result list can
then be made up using this information. For now however, scans simply
report -95dBm as they always have.

In summary, this patch does the following:

  • Gets the measured noise level per rx interrupt from the HAL
  • Passes the noise level to wireless extensions (iwconfig, etc)
  • Use this level to calculate signal strength of frames in monitor mode.
  • Does not apply to scanning (working on it).

Signed-off-by: Scott Raynel <scottraynel@gmail.com>

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/ath/if_ath.c

    r1706 r1713  
    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                } 
     
    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 { 
     
    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); 
  • trunk/ath/if_athvar.h

    r1704 r1713  
    674674#endif 
    675675        u_int sc_slottimeconf;                  /* manual override for slottime */ 
     676        int16_t sc_channoise;                   /* Measured noise of current channel (dBm) */ 
    676677}; 
    677678 
     
    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 */ 
  • trunk/net80211/ieee80211_input.c

    r1712 r1713  
    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; 
    152  
    153         iq->noise = 161;                /* -95dBm */ 
     149 
     150        iq->noise = noise;       
    154151        iq->level = iq->noise + iq->qual; 
    155152        iq->updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | 
     
    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); 
  • trunk/net80211/ieee80211_monitor.c

    r1710 r1713  
    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) { 
     
    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; 
     
    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); 
  • trunk/net80211/ieee80211_var.h

    r1696 r1713  
    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 */ 
  • trunk/net80211/ieee80211_wireless.c

    r1703 r1713  
    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 
     
    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; 
     
    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 + 
     
    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 
     
    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; 
     
    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; 
     
    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; 
     
    11881184{ 
    11891185        struct ieee80211vap *vap = dev->priv; 
     1186        struct ieee80211com *ic = vap->iv_ic; 
    11901187        struct iw_thrspy *threshold;     
    11911188         
     
    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 */ 
     
    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 
     
    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);