aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorSenthil Balasubramanian <senthilkumar@atheros.com>2009-07-14 20:17:07 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-07-24 15:05:17 -0400
commita59b5a5e684652eec035c869ab8911a1689c8f53 (patch)
treeb644e52fd4da498979eacd618c13498fe9fc67ad /drivers/net
parent922bac602255d4557c289cabba7857c5be332d34 (diff)
ath9k: Manipulate and report the correct RSSI
RSSI reported by the RX descriptor requires little manipulation. Manipulate and report the correct RSSI to the stack. This will fix the improper signal levels reported by iwconfig iw dev wlanX station dump. Also the Link Quality reported seems to be varying (falls to zero also sometimes) when iperf is run from STA to AP. Also use the default noise floor for now as the one reported during the caliberation seems to be wrong. The Signal and Link Quality before this patch (taken while TX is in progress from STA to AP) 09:59:13.285428037 Link Quality=29/70 Signal level=-81 dBm 09:59:13.410660084 Link Quality=20/70 Signal level=-90 dBm 09:59:13.586864392 Link Quality=21/70 Signal level=-89 dBm 09:59:13.710296281 Link Quality=21/70 Signal level=-89 dBm 09:59:13.821683064 Link Quality=25/70 Signal level=-85 dBm 09:59:13.933402989 Link Quality=24/70 Signal level=-86 dBm 09:59:14.045839276 Link Quality=26/70 Signal level=-84 dBm 09:59:14.193926673 Link Quality=23/70 Signal level=-87 dBm 09:59:14.306230262 Link Quality=31/70 Signal level=-79 dBm 09:59:14.419459667 Link Quality=26/70 Signal level=-84 dBm 09:59:14.530711167 Link Quality=37/70 Signal level=-73 dBm 09:59:14.642593962 Link Quality=29/70 Signal level=-81 dBm 09:59:14.754361169 Link Quality=21/70 Signal level=-89 dBm 09:59:14.866217355 Link Quality=21/70 Signal level=-89 dBm 09:59:14.976963623 Link Quality=28/70 Signal level=-82 dBm 09:59:15.089149809 Link Quality=26/70 Signal level=-84 dBm 09:59:15.205039887 Link Quality=27/70 Signal level=-83 dBm 09:59:15.316368003 Link Quality=23/70 Signal level=-87 dBm 09:59:15.427684036 Link Quality=36/70 Signal level=-74 dBm 09:59:15.539756380 Link Quality=21/70 Signal level=-89 dBm 09:59:15.650549093 Link Quality=22/70 Signal level=-88 dBm 09:59:15.761171672 Link Quality=32/70 Signal level=-78 dBm 09:59:15.872793750 Link Quality=23/70 Signal level=-87 dBm 09:59:15.984421694 Link Quality=22/70 Signal level=-88 dBm 09:59:16.097315093 Link Quality=21/70 Signal level=-89 dBm The link quality and signal level after this patch (take while TX is in progress from STA to AP) 17:21:25.627848091 Link Quality=65/70 Signal level=-45 dBm 17:21:25.762805607 Link Quality=65/70 Signal level=-45 dBm 17:21:25.875521888 Link Quality=66/70 Signal level=-44 dBm 17:21:25.987468448 Link Quality=66/70 Signal level=-44 dBm 17:21:26.100628151 Link Quality=66/70 Signal level=-44 dBm 17:21:26.213129671 Link Quality=66/70 Signal level=-44 dBm 17:21:26.324923070 Link Quality=65/70 Signal level=-45 dBm 17:21:26.436831357 Link Quality=65/70 Signal level=-45 dBm 17:21:26.610356973 Link Quality=65/70 Signal level=-45 dBm 17:21:26.723340047 Link Quality=65/70 Signal level=-45 dBm 17:21:26.835715293 Link Quality=64/70 Signal level=-46 dBm 17:21:26.949542748 Link Quality=64/70 Signal level=-46 dBm 17:21:27.062261613 Link Quality=65/70 Signal level=-45 dBm 17:21:27.174511563 Link Quality=64/70 Signal level=-46 dBm 17:21:27.287616232 Link Quality=64/70 Signal level=-46 dBm 17:21:27.400598119 Link Quality=64/70 Signal level=-46 dBm 17:21:27.511381404 Link Quality=64/70 Signal level=-46 dBm 17:21:27.624530421 Link Quality=65/70 Signal level=-45 dBm 17:21:27.737807109 Link Quality=64/70 Signal level=-46 dBm 17:21:27.850861352 Link Quality=65/70 Signal level=-45 dBm 17:21:27.963369436 Link Quality=64/70 Signal level=-46 dBm 17:21:28.076582289 Link Quality=64/70 Signal level=-46 dBm Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c25
5 files changed, 54 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 3afd7ee41a63..544599b826c1 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -290,12 +290,28 @@ struct ath_tx_control {
290#define ATH_TX_XRETRY 0x02 290#define ATH_TX_XRETRY 0x02
291#define ATH_TX_BAR 0x04 291#define ATH_TX_BAR 0x04
292 292
293#define ATH_RSSI_LPF_LEN 10
294#define RSSI_LPF_THRESHOLD -20
295#define ATH9K_RSSI_BAD 0x80
296#define ATH_RSSI_EP_MULTIPLIER (1<<7)
297#define ATH_EP_MUL(x, mul) ((x) * (mul))
298#define ATH_RSSI_IN(x) (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
299#define ATH_LPF_RSSI(x, y, len) \
300 ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
301#define ATH_RSSI_LPF(x, y) do { \
302 if ((y) >= RSSI_LPF_THRESHOLD) \
303 x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
304} while (0)
305#define ATH_EP_RND(x, mul) \
306 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
307
293struct ath_node { 308struct ath_node {
294 struct ath_softc *an_sc; 309 struct ath_softc *an_sc;
295 struct ath_atx_tid tid[WME_NUM_TID]; 310 struct ath_atx_tid tid[WME_NUM_TID];
296 struct ath_atx_ac ac[WME_NUM_AC]; 311 struct ath_atx_ac ac[WME_NUM_AC];
297 u16 maxampdu; 312 u16 maxampdu;
298 u8 mpdudensity; 313 u8 mpdudensity;
314 int last_rssi;
299}; 315};
300 316
301struct ath_tx { 317struct ath_tx {
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index a32d7e7fecbe..1f0c5fe4a68b 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -691,15 +691,22 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
691void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) 691void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
692{ 692{
693 int i, j; 693 int i, j;
694 s16 noise_floor;
695
696 if (AR_SREV_9280(ah))
697 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
698 else if (AR_SREV_9285(ah))
699 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
700 else
701 noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
694 702
695 for (i = 0; i < NUM_NF_READINGS; i++) { 703 for (i = 0; i < NUM_NF_READINGS; i++) {
696 ah->nfCalHist[i].currIndex = 0; 704 ah->nfCalHist[i].currIndex = 0;
697 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE; 705 ah->nfCalHist[i].privNF = noise_floor;
698 ah->nfCalHist[i].invalidNFcount = 706 ah->nfCalHist[i].invalidNFcount =
699 AR_PHY_CCA_FILTERWINDOW_LENGTH; 707 AR_PHY_CCA_FILTERWINDOW_LENGTH;
700 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { 708 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
701 ah->nfCalHist[i].nfCalBuffer[j] = 709 ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
702 AR_PHY_CCA_MAX_GOOD_VALUE;
703 } 710 }
704 } 711 }
705} 712}
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index fe5367f14148..547e697b9055 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -25,7 +25,9 @@ extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
25extern const struct ath9k_percal_data adc_dc_cal_single_sample; 25extern const struct ath9k_percal_data adc_dc_cal_single_sample;
26extern const struct ath9k_percal_data adc_init_dc_cal; 26extern const struct ath9k_percal_data adc_init_dc_cal;
27 27
28#define AR_PHY_CCA_MAX_GOOD_VALUE -85 28#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85
29#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112
30#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118
29#define AR_PHY_CCA_MAX_HIGH_VALUE -62 31#define AR_PHY_CCA_MAX_HIGH_VALUE -62
30#define AR_PHY_CCA_MIN_BAD_VALUE -140 32#define AR_PHY_CCA_MIN_BAD_VALUE -140
31#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3 33#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 19df7882d0d3..2ad718489c0d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -465,6 +465,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
465 an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + 465 an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
466 sta->ht_cap.ampdu_factor); 466 sta->ht_cap.ampdu_factor);
467 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); 467 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
468 an->last_rssi = ATH_RSSI_DUMMY_MARKER;
468 } 469 }
469} 470}
470 471
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index b3da81db453b..61edfab20ffc 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -145,6 +145,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
145 u8 ratecode; 145 u8 ratecode;
146 __le16 fc; 146 __le16 fc;
147 struct ieee80211_hw *hw; 147 struct ieee80211_hw *hw;
148 struct ieee80211_sta *sta;
149 struct ath_node *an;
150 int last_rssi = ATH_RSSI_DUMMY_MARKER;
151
148 152
149 hdr = (struct ieee80211_hdr *)skb->data; 153 hdr = (struct ieee80211_hdr *)skb->data;
150 fc = hdr->frame_control; 154 fc = hdr->frame_control;
@@ -229,11 +233,30 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
229 } 233 }
230 } 234 }
231 235
236 rcu_read_lock();
237 sta = ieee80211_find_sta(sc->hw, hdr->addr2);
238 if (sta) {
239 an = (struct ath_node *) sta->drv_priv;
240 if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
241 !ds->ds_rxstat.rs_moreaggr)
242 ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
243 last_rssi = an->last_rssi;
244 }
245 rcu_read_unlock();
246
247 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
248 ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
249 ATH_RSSI_EP_MULTIPLIER);
250 if (ds->ds_rxstat.rs_rssi < 0)
251 ds->ds_rxstat.rs_rssi = 0;
252 else if (ds->ds_rxstat.rs_rssi > 127)
253 ds->ds_rxstat.rs_rssi = 127;
254
232 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); 255 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
233 rx_status->band = hw->conf.channel->band; 256 rx_status->band = hw->conf.channel->band;
234 rx_status->freq = hw->conf.channel->center_freq; 257 rx_status->freq = hw->conf.channel->center_freq;
235 rx_status->noise = sc->ani.noise_floor; 258 rx_status->noise = sc->ani.noise_floor;
236 rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; 259 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
237 rx_status->antenna = ds->ds_rxstat.rs_antenna; 260 rx_status->antenna = ds->ds_rxstat.rs_antenna;
238 261
239 /* 262 /*