Ticket #881: madwifi_measured_noise.patch
| File madwifi_measured_noise.patch, 9.4 kB (added by scottraynel@gmail.com, 6 years ago) |
|---|
-
net80211/ieee80211_wireless.c
old new 97 97 * rssi values reported in the tx/rx descriptors in the 98 98 * driver are the SNR expressed in db. 99 99 * 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. 107 102 * 108 103 * NB: various calculations are based on the orinoco/wavelan 109 104 * drivers for compatibility 110 105 */ 111 106 static void 112 set_quality(struct iw_quality *iq, u_int rssi )107 set_quality(struct iw_quality *iq, u_int rssi, int noise) 113 108 { 114 109 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; 120 111 iq->level = iq->noise + iq->qual; 121 112 iq->updated = IW_QUAL_ALL_UPDATED; 122 113 } … … 159 150 { 160 151 struct ieee80211vap *vap = dev->priv; 161 152 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); 164 157 is->status = vap->iv_state; 165 158 is->discard.nwid = vap->iv_stats.is_rx_wrongbss + 166 159 vap->iv_stats.is_rx_ssidmismatch; … … 992 985 } 993 986 994 987 /* Max quality is max field value minus noise floor */ 988 /* XXX Should this be updated to use the current noise floor? */ 995 989 range->max_qual.qual = 0xff - 161; 996 990 997 991 /* … … 1109 1103 struct ieee80211vap *vap = dev->priv; 1110 1104 struct ieee80211_node_table *nt = &vap->iv_ic->ic_sta; 1111 1105 struct ieee80211_node *ni; 1106 struct ieee80211com *ic = vap->iv_ic; 1112 1107 struct sockaddr *address; 1113 1108 struct iw_quality *spy_stat; 1114 1109 unsigned int number = vap->iv_spy.num; … … 1129 1124 /* TODO: free node ? */ 1130 1125 /* check we are associated w/ this vap */ 1131 1126 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); 1133 1128 if (ni->ni_rstamp != vap->iv_spy.ts_rssi[i]) { 1134 1129 vap->iv_spy.ts_rssi[i] = ni->ni_rstamp; 1135 1130 } else { … … 1173 1168 "%s: disabled iw_spy threshold\n", __func__); 1174 1169 } else { 1175 1170 /* calculate corresponding rssi values */ 1171 /* XXX Should we use current noise value? */ 1176 1172 vap->iv_spy.thr_low = threshold.low.level - 161; 1177 1173 vap->iv_spy.thr_high = threshold.high.level - 161; 1178 1174 IEEE80211_DPRINTF(vap, IEEE80211_MSG_DEBUG, … … 1187 1183 struct iw_point *data, char *extra) 1188 1184 { 1189 1185 struct ieee80211vap *vap = dev->priv; 1186 struct ieee80211com *ic = vap->iv_ic; 1190 1187 struct iw_thrspy *threshold; 1191 1188 1192 1189 threshold = (struct iw_thrspy *) extra; 1193 1190 1194 1191 /* 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); 1197 1194 1198 1195 /* copy results to userspace */ 1199 1196 data->length = 1; … … 1468 1465 IEEE80211_ADDR_COPY(req->addr[i].sa_data, se->se_macaddr); 1469 1466 else 1470 1467 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); 1472 1469 req->i = i + 1; 1473 1470 1474 1471 return 0; … … 1665 1662 memset(&iwe, 0, sizeof(iwe)); 1666 1663 last_ev = current_ev; 1667 1664 iwe.cmd = IWEVQUAL; 1668 set_quality(&iwe.u.qual, se->se_rssi );1665 set_quality(&iwe.u.qual, se->se_rssi, -95); 1669 1666 current_ev = iwe_stream_add_event(current_ev, 1670 1667 end_buf, &iwe, IW_EV_QUAL_LEN); 1671 1668 -
net80211/ieee80211_input.c
old new 143 143 * This function is a clone of set_quality(..) in ieee80211_wireless.c 144 144 */ 145 145 static void 146 set_quality(struct iw_quality *iq, u_int rssi )146 set_quality(struct iw_quality *iq, u_int rssi, int noise) 147 147 { 148 148 iq->qual = rssi; 149 /* NB: max is 94 because noise is hardcoded to 161 */150 if (iq->qual > 94)151 iq->qual = 94;152 149 153 iq->noise = 161; /* -95dBm */150 iq->noise = noise; 154 151 iq->level = iq->noise + iq->qual; 155 152 iq->updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | 156 153 IW_QUAL_NOISE_UPDATED; … … 188 185 memcpy(thr.addr.sa_data, ni->ni_macaddr, 189 186 IEEE80211_ADDR_LEN); 190 187 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); 194 191 wireless_send_event(vap->iv_dev, 195 192 SIOCGIWTHRSPY, &wrq, (char*) &thr); 196 193 break; -
net80211/ieee80211_monitor.c
old new 209 209 struct ath_desc *ds, int tx, u_int32_t mactime, struct ath_softc *sc) 210 210 { 211 211 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; 214 214 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 215 221 /* XXX locking */ 216 222 for (vap = TAILQ_FIRST(&ic->ic_vaps); vap != NULL; vap = next) { 217 223 struct sk_buff *skb1; … … 287 293 ph->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi; 288 294 ph->rssi.status = 0; 289 295 ph->rssi.len = 4; 290 ph->rssi.data = signal;296 ph->rssi.data = rssi; 291 297 292 298 ph->noise.did = DIDmsg_lnxind_wlansniffrm_noise; 293 299 ph->noise.status = 0; 294 300 ph->noise.len = 4; 295 ph->noise.data = -95;301 ph->noise.data = noise; 296 302 297 303 ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; 298 304 ph->signal.status = 0; 299 305 ph->signal.len = 4; 300 ph->signal.data = signal;306 ph->signal.data = rssi + noise; 301 307 302 308 ph->rate.did = DIDmsg_lnxind_wlansniffrm_rate; 303 309 ph->rate.status = 0; … … 374 380 break; 375 381 } 376 382 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; 379 385 th->wr_antenna = ds->ds_rxstat.rs_antenna; 380 th->wr_antsignal = signal;386 th->wr_antsignal = rssi; 381 387 memcpy(&th->wr_fcs, &skb1->data[skb1->len - IEEE80211_CRC_LEN], 382 388 IEEE80211_CRC_LEN); 383 389 th->wr_fcs = cpu_to_le32(th->wr_fcs); -
net80211/ieee80211_var.h
old new 167 167 struct ieee80211_channel *ic_curchan; /* current channel */ 168 168 struct ieee80211_channel *ic_bsschan; /* bss channel */ 169 169 struct ieee80211_channel *ic_prevchan; /* previous channel */ 170 170 int16_t ic_channoise; /* current channel noise in dBm */ 171 171 /* regulatory class ids */ 172 172 u_int ic_nregclass; /* # entries in ic_regclassids */ 173 173 u_int8_t ic_regclassids[IEEE80211_REGCLASSIDS_MAX]; -
ath/if_athvar.h
old new 673 673 u_int32_t sc_dturbo_bw_turbo; /* bandwidth threshold */ 674 674 #endif 675 675 u_int sc_slottimeconf; /* manual override for slottime */ 676 int16_t sc_channoise; /* Measured noise of current channel (dBm) */ 676 677 }; 677 678 678 679 typedef void (*ath_callback) (struct ath_softc *); … … 1000 1001 ((*(_ah)->ah_dfsNolCheck)((_ah), (_chan), (_nchans))) 1001 1002 #define ath_hal_radar_wait(_ah, _chan) \ 1002 1003 ((*(_ah)->ah_radarWait)((_ah), (_chan))) 1004 #define ath_hal_get_channel_noise(_ah, _chan) \ 1005 ((*(_ah)->ah_getChanNoise)((_ah), (_chan))) 1003 1006 1004 1007 #endif /* _DEV_ATH_ATHVAR_H */ -
ath/if_ath.c
old new 1648 1648 } 1649 1649 if (status & HAL_INT_RX) { 1650 1650 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)); 1651 1656 ATH_SCHEDULE_TQUEUE(&sc->sc_rxtq, &needmark); 1652 1657 } 1653 1658 if (status & HAL_INT_TX) { … … 5368 5373 int len, type; 5369 5374 u_int phyerr; 5370 5375 5376 /* Let the 802.11 layer know about the new noise floor */ 5377 ic->ic_channoise = sc->sc_channoise; 5378 5371 5379 DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s\n", __func__); 5372 5380 do { 5373 5381 bf = STAILQ_FIRST(&sc->sc_rxbuf); … … 5633 5641 STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); 5634 5642 ATH_RXBUF_UNLOCK_IRQ(sc); 5635 5643 } while (ath_rxbuf_init(sc, bf) == 0); 5636 5644 5637 5645 /* rx signal state monitoring */ 5638 5646 ath_hal_rxmonitor(ah, &sc->sc_halstats, &sc->sc_curchan); 5639 5647 if (ath_hal_radar_event(ah)) {
