aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h4
-rw-r--r--drivers/net/wireless/ath5k/base.c50
-rw-r--r--drivers/net/wireless/ath5k/desc.c69
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath9k/beacon.c8
-rw-r--r--drivers/net/wireless/ath9k/core.c145
-rw-r--r--drivers/net/wireless/ath9k/core.h32
-rw-r--r--drivers/net/wireless/ath9k/hw.c35
-rw-r--r--drivers/net/wireless/ath9k/main.c18
-rw-r--r--drivers/net/wireless/ath9k/recv.c17
-rw-r--r--drivers/net/wireless/ath9k/xmit.c12
-rw-r--r--drivers/net/wireless/b43/main.c1
-rw-r--r--drivers/net/wireless/b43/xmit.c6
-rw-r--r--drivers/net/wireless/b43legacy/main.c1
-rw-r--r--drivers/net/wireless/b43legacy/xmit.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c28
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c28
-rw-r--r--drivers/net/wireless/p54/p54common.c5
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00rfkill.c9
-rw-r--r--drivers/net/wireless/rtl8180_dev.c5
-rw-r--r--include/net/mac80211.h33
-rw-r--r--net/mac80211/Kconfig13
-rw-r--r--net/mac80211/Makefile4
-rw-r--r--net/mac80211/key.c14
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/mlme.c47
-rw-r--r--net/mac80211/rate.h14
-rw-r--r--net/mac80211/rc80211_minstrel.c583
-rw-r--r--net/mac80211/rc80211_minstrel.h85
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c164
-rw-r--r--net/mac80211/tx.c36
-rw-r--r--net/mac80211/wep.c3
-rw-r--r--net/mac80211/wpa.c6
-rw-r--r--net/rfkill/rfkill.c5
-rw-r--r--net/wireless/Kconfig2
38 files changed, 1335 insertions, 174 deletions
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
index 7134c40d6a69..53ea439aff48 100644
--- a/drivers/net/wireless/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -431,7 +431,9 @@ struct ath5k_tx_status {
431 u16 ts_seqnum; 431 u16 ts_seqnum;
432 u16 ts_tstamp; 432 u16 ts_tstamp;
433 u8 ts_status; 433 u8 ts_status;
434 u8 ts_rate; 434 u8 ts_rate[4];
435 u8 ts_retry[4];
436 u8 ts_final_idx;
435 s8 ts_rssi; 437 s8 ts_rssi;
436 u8 ts_shortretry; 438 u8 ts_shortretry;
437 u8 ts_longretry; 439 u8 ts_longretry;
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index c151588aa484..9b95c4049b31 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -541,6 +541,12 @@ ath5k_pci_probe(struct pci_dev *pdev,
541 goto err_irq; 541 goto err_irq;
542 } 542 }
543 543
544 /* set up multi-rate retry capabilities */
545 if (sc->ah->ah_version == AR5K_AR5212) {
546 hw->max_altrates = 3;
547 hw->max_altrate_tries = 11;
548 }
549
544 /* Finish private driver data initialization */ 550 /* Finish private driver data initialization */
545 ret = ath5k_attach(pdev, hw); 551 ret = ath5k_attach(pdev, hw);
546 if (ret) 552 if (ret)
@@ -1173,7 +1179,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1173 struct sk_buff *skb = bf->skb; 1179 struct sk_buff *skb = bf->skb;
1174 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1180 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1175 unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; 1181 unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
1176 int ret; 1182 struct ieee80211_rate *rate;
1183 unsigned int mrr_rate[3], mrr_tries[3];
1184 int i, ret;
1177 1185
1178 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; 1186 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
1179 1187
@@ -1188,7 +1196,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1188 1196
1189 if (info->control.hw_key) { 1197 if (info->control.hw_key) {
1190 keyidx = info->control.hw_key->hw_key_idx; 1198 keyidx = info->control.hw_key->hw_key_idx;
1191 pktlen += info->control.icv_len; 1199 pktlen += info->control.hw_key->icv_len;
1192 } 1200 }
1193 ret = ah->ah_setup_tx_desc(ah, ds, pktlen, 1201 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1194 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, 1202 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
@@ -1198,6 +1206,22 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1198 if (ret) 1206 if (ret)
1199 goto err_unmap; 1207 goto err_unmap;
1200 1208
1209 memset(mrr_rate, 0, sizeof(mrr_rate));
1210 memset(mrr_tries, 0, sizeof(mrr_tries));
1211 for (i = 0; i < 3; i++) {
1212 rate = ieee80211_get_alt_retry_rate(sc->hw, info, i);
1213 if (!rate)
1214 break;
1215
1216 mrr_rate[i] = rate->hw_value;
1217 mrr_tries[i] = info->control.retries[i].limit;
1218 }
1219
1220 ah->ah_setup_mrr_tx_desc(ah, ds,
1221 mrr_rate[0], mrr_tries[0],
1222 mrr_rate[1], mrr_tries[1],
1223 mrr_rate[2], mrr_tries[2]);
1224
1201 ds->ds_link = 0; 1225 ds->ds_link = 0;
1202 ds->ds_data = bf->skbaddr; 1226 ds->ds_data = bf->skbaddr;
1203 1227
@@ -1814,7 +1838,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1814 struct ath5k_desc *ds; 1838 struct ath5k_desc *ds;
1815 struct sk_buff *skb; 1839 struct sk_buff *skb;
1816 struct ieee80211_tx_info *info; 1840 struct ieee80211_tx_info *info;
1817 int ret; 1841 int i, ret;
1818 1842
1819 spin_lock(&txq->lock); 1843 spin_lock(&txq->lock);
1820 list_for_each_entry_safe(bf, bf0, &txq->q, list) { 1844 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
@@ -1836,7 +1860,25 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1836 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, 1860 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
1837 PCI_DMA_TODEVICE); 1861 PCI_DMA_TODEVICE);
1838 1862
1839 info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6; 1863 memset(&info->status, 0, sizeof(info->status));
1864 info->tx_rate_idx = ath5k_hw_to_driver_rix(sc,
1865 ts.ts_rate[ts.ts_final_idx]);
1866 info->status.retry_count = ts.ts_longretry;
1867
1868 for (i = 0; i < 4; i++) {
1869 struct ieee80211_tx_altrate *r =
1870 &info->status.retries[i];
1871
1872 if (ts.ts_rate[i]) {
1873 r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]);
1874 r->limit = ts.ts_retry[i];
1875 } else {
1876 r->rate_idx = -1;
1877 r->limit = 0;
1878 }
1879 }
1880
1881 info->status.excessive_retries = 0;
1840 if (unlikely(ts.ts_status)) { 1882 if (unlikely(ts.ts_status)) {
1841 sc->ll_stats.dot11ACKFailureCount++; 1883 sc->ll_stats.dot11ACKFailureCount++;
1842 if (ts.ts_status & AR5K_TXERR_XRETRY) 1884 if (ts.ts_status & AR5K_TXERR_XRETRY)
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c
index d45b90a6e06c..dd1374052ba9 100644
--- a/drivers/net/wireless/ath5k/desc.c
+++ b/drivers/net/wireless/ath5k/desc.c
@@ -318,6 +318,15 @@ ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
318 return 0; 318 return 0;
319} 319}
320 320
321/* no mrr support for cards older than 5212 */
322static int
323ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc,
324 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2,
325 u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3)
326{
327 return 0;
328}
329
321/* 330/*
322 * Proccess the tx status descriptor on 5210/5211 331 * Proccess the tx status descriptor on 5210/5211
323 */ 332 */
@@ -352,8 +361,10 @@ static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
352 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); 361 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
353 ts->ts_antenna = 1; 362 ts->ts_antenna = 1;
354 ts->ts_status = 0; 363 ts->ts_status = 0;
355 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0, 364 ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0,
356 AR5K_2W_TX_DESC_CTL0_XMIT_RATE); 365 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
366 ts->ts_retry[0] = ts->ts_longretry;
367 ts->ts_final_idx = 0;
357 368
358 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { 369 if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) {
359 if (tx_status->tx_status_0 & 370 if (tx_status->tx_status_0 &
@@ -405,29 +416,43 @@ static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
405 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; 416 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
406 ts->ts_status = 0; 417 ts->ts_status = 0;
407 418
408 switch (AR5K_REG_MS(tx_status->tx_status_1, 419 ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1,
409 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) { 420 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX);
410 case 0: 421
411 ts->ts_rate = tx_ctl->tx_control_3 & 422 /* The longretry counter has the number of un-acked retries
412 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; 423 * for the final rate. To get the total number of retries
413 break; 424 * we have to add the retry counters for the other rates
425 * as well
426 */
427 ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry;
428 switch (ts->ts_final_idx) {
429 case 3:
430 ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3,
431 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
432
433 ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2,
434 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
435 ts->ts_longretry += ts->ts_retry[2];
436 /* fall through */
437 case 2:
438 ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3,
439 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
440
441 ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2,
442 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
443 ts->ts_longretry += ts->ts_retry[1];
444 /* fall through */
414 case 1: 445 case 1:
415 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, 446 ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3,
416 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); 447 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
417 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, 448
449 ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2,
418 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); 450 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
419 break; 451 ts->ts_longretry += ts->ts_retry[0];
420 case 2: 452 /* fall through */
421 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, 453 case 0:
422 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); 454 ts->ts_rate[0] = tx_ctl->tx_control_3 &
423 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, 455 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
424 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
425 break;
426 case 3:
427 ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3,
428 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
429 ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2,
430 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
431 break; 456 break;
432 } 457 }
433 458
@@ -653,7 +678,7 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah)
653 } else { 678 } else {
654 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; 679 ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc;
655 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; 680 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
656 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc; 681 ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr;
657 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; 682 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
658 } 683 }
659 684
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index 0e897c276858..accace5f7efb 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -854,7 +854,7 @@ bool ath9k_hw_calibrate(struct ath_hal *ah,
854 u8 rxchainmask, 854 u8 rxchainmask,
855 bool longcal, 855 bool longcal,
856 bool *isCalDone); 856 bool *isCalDone);
857int16_t ath9k_hw_getchan_noise(struct ath_hal *ah, 857s16 ath9k_hw_getchan_noise(struct ath_hal *ah,
858 struct ath9k_channel *chan); 858 struct ath9k_channel *chan);
859void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid, 859void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
860 u16 assocId); 860 u16 assocId);
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
index eedb465d25d3..9e15c30bbc06 100644
--- a/drivers/net/wireless/ath9k/beacon.c
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -129,7 +129,7 @@ static void ath_beacon_setup(struct ath_softc *sc,
129 ds /* first descriptor */ 129 ds /* first descriptor */
130 ); 130 );
131 131
132 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); 132 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
133 series[0].Tries = 1; 133 series[0].Tries = 1;
134 series[0].Rate = rate; 134 series[0].Rate = rate;
135 series[0].ChSel = sc->sc_tx_chainmask; 135 series[0].ChSel = sc->sc_tx_chainmask;
@@ -282,7 +282,7 @@ int ath_beaconq_setup(struct ath_hal *ah)
282{ 282{
283 struct ath9k_tx_queue_info qi; 283 struct ath9k_tx_queue_info qi;
284 284
285 memzero(&qi, sizeof(qi)); 285 memset(&qi, 0, sizeof(qi));
286 qi.tqi_aifs = 1; 286 qi.tqi_aifs = 1;
287 qi.tqi_cwmin = 0; 287 qi.tqi_cwmin = 0;
288 qi.tqi_cwmax = 0; 288 qi.tqi_cwmax = 0;
@@ -662,7 +662,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
662 else 662 else
663 av_opmode = sc->sc_ah->ah_opmode; 663 av_opmode = sc->sc_ah->ah_opmode;
664 664
665 memzero(&conf, sizeof(struct ath_beacon_config)); 665 memset(&conf, 0, sizeof(struct ath_beacon_config));
666 666
667 conf.beacon_interval = sc->hw->conf.beacon_int ? 667 conf.beacon_interval = sc->hw->conf.beacon_int ?
668 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL; 668 sc->hw->conf.beacon_int : ATH_DEFAULT_BINTVAL;
@@ -738,7 +738,7 @@ void ath_beacon_config(struct ath_softc *sc, int if_id)
738 } 738 }
739 } while (nexttbtt < tsftu); 739 } while (nexttbtt < tsftu);
740#undef FUDGE 740#undef FUDGE
741 memzero(&bs, sizeof(bs)); 741 memset(&bs, 0, sizeof(bs));
742 bs.bs_intval = intval; 742 bs.bs_intval = intval;
743 bs.bs_nexttbtt = nexttbtt; 743 bs.bs_nexttbtt = nexttbtt;
744 bs.bs_dtimperiod = dtimperiod*intval; 744 bs.bs_dtimperiod = dtimperiod*intval;
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
index 6c433a4d003e..c5033f6f42ac 100644
--- a/drivers/net/wireless/ath9k/core.c
+++ b/drivers/net/wireless/ath9k/core.c
@@ -65,7 +65,7 @@ static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
65 for (i = 0; i < rt->rateCount; i++) 65 for (i = 0; i < rt->rateCount; i++)
66 sc->sc_rixmap[rt->info[i].rateCode] = (u8) i; 66 sc->sc_rixmap[rt->info[i].rateCode] = (u8) i;
67 67
68 memzero(sc->sc_hwmap, sizeof(sc->sc_hwmap)); 68 memset(sc->sc_hwmap, 0, sizeof(sc->sc_hwmap));
69 for (i = 0; i < 256; i++) { 69 for (i = 0; i < 256; i++) {
70 u8 ix = rt->rateCodeToIndex[i]; 70 u8 ix = rt->rateCodeToIndex[i];
71 71
@@ -288,8 +288,6 @@ static int ath_stop(struct ath_softc *sc)
288 * hardware is gone (invalid). 288 * hardware is gone (invalid).
289 */ 289 */
290 290
291 if (!(sc->sc_flags & SC_OP_INVALID))
292 ath9k_hw_set_interrupts(ah, 0);
293 ath_draintxq(sc, false); 291 ath_draintxq(sc, false);
294 if (!(sc->sc_flags & SC_OP_INVALID)) { 292 if (!(sc->sc_flags & SC_OP_INVALID)) {
295 ath_stoprecv(sc); 293 ath_stoprecv(sc);
@@ -419,7 +417,7 @@ static void ath_chainmask_sel_init(struct ath_softc *sc, struct ath_node *an)
419{ 417{
420 struct ath_chainmask_sel *cm = &an->an_chainmask_sel; 418 struct ath_chainmask_sel *cm = &an->an_chainmask_sel;
421 419
422 memzero(cm, sizeof(struct ath_chainmask_sel)); 420 memset(cm, 0, sizeof(struct ath_chainmask_sel));
423 421
424 cm->cur_tx_mask = sc->sc_tx_chainmask; 422 cm->cur_tx_mask = sc->sc_tx_chainmask;
425 cm->cur_rx_mask = sc->sc_rx_chainmask; 423 cm->cur_rx_mask = sc->sc_rx_chainmask;
@@ -492,6 +490,122 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
492 __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask); 490 __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask);
493} 491}
494 492
493/*******/
494/* ANI */
495/*******/
496
497/*
498 * This routine performs the periodic noise floor calibration function
499 * that is used to adjust and optimize the chip performance. This
500 * takes environmental changes (location, temperature) into account.
501 * When the task is complete, it reschedules itself depending on the
502 * appropriate interval that was calculated.
503 */
504
505static void ath_ani_calibrate(unsigned long data)
506{
507 struct ath_softc *sc;
508 struct ath_hal *ah;
509 bool longcal = false;
510 bool shortcal = false;
511 bool aniflag = false;
512 unsigned int timestamp = jiffies_to_msecs(jiffies);
513 u32 cal_interval;
514
515 sc = (struct ath_softc *)data;
516 ah = sc->sc_ah;
517
518 /*
519 * don't calibrate when we're scanning.
520 * we are most likely not on our home channel.
521 */
522 if (sc->rx_filter & FIF_BCN_PRBRESP_PROMISC)
523 return;
524
525 /* Long calibration runs independently of short calibration. */
526 if ((timestamp - sc->sc_ani.sc_longcal_timer) >= ATH_LONG_CALINTERVAL) {
527 longcal = true;
528 DPRINTF(sc, ATH_DBG_ANI, "%s: longcal @%lu\n",
529 __func__, jiffies);
530 sc->sc_ani.sc_longcal_timer = timestamp;
531 }
532
533 /* Short calibration applies only while sc_caldone is false */
534 if (!sc->sc_ani.sc_caldone) {
535 if ((timestamp - sc->sc_ani.sc_shortcal_timer) >=
536 ATH_SHORT_CALINTERVAL) {
537 shortcal = true;
538 DPRINTF(sc, ATH_DBG_ANI, "%s: shortcal @%lu\n",
539 __func__, jiffies);
540 sc->sc_ani.sc_shortcal_timer = timestamp;
541 sc->sc_ani.sc_resetcal_timer = timestamp;
542 }
543 } else {
544 if ((timestamp - sc->sc_ani.sc_resetcal_timer) >=
545 ATH_RESTART_CALINTERVAL) {
546 ath9k_hw_reset_calvalid(ah, ah->ah_curchan,
547 &sc->sc_ani.sc_caldone);
548 if (sc->sc_ani.sc_caldone)
549 sc->sc_ani.sc_resetcal_timer = timestamp;
550 }
551 }
552
553 /* Verify whether we must check ANI */
554 if ((timestamp - sc->sc_ani.sc_checkani_timer) >=
555 ATH_ANI_POLLINTERVAL) {
556 aniflag = true;
557 sc->sc_ani.sc_checkani_timer = timestamp;
558 }
559
560 /* Skip all processing if there's nothing to do. */
561 if (longcal || shortcal || aniflag) {
562 /* Call ANI routine if necessary */
563 if (aniflag)
564 ath9k_hw_ani_monitor(ah, &sc->sc_halstats,
565 ah->ah_curchan);
566
567 /* Perform calibration if necessary */
568 if (longcal || shortcal) {
569 bool iscaldone = false;
570
571 if (ath9k_hw_calibrate(ah, ah->ah_curchan,
572 sc->sc_rx_chainmask, longcal,
573 &iscaldone)) {
574 if (longcal)
575 sc->sc_ani.sc_noise_floor =
576 ath9k_hw_getchan_noise(ah,
577 ah->ah_curchan);
578
579 DPRINTF(sc, ATH_DBG_ANI,
580 "%s: calibrate chan %u/%x nf: %d\n",
581 __func__,
582 ah->ah_curchan->channel,
583 ah->ah_curchan->channelFlags,
584 sc->sc_ani.sc_noise_floor);
585 } else {
586 DPRINTF(sc, ATH_DBG_ANY,
587 "%s: calibrate chan %u/%x failed\n",
588 __func__,
589 ah->ah_curchan->channel,
590 ah->ah_curchan->channelFlags);
591 }
592 sc->sc_ani.sc_caldone = iscaldone;
593 }
594 }
595
596 /*
597 * Set timer interval based on previous results.
598 * The interval must be the shortest necessary to satisfy ANI,
599 * short calibration and long calibration.
600 */
601
602 cal_interval = ATH_ANI_POLLINTERVAL;
603 if (!sc->sc_ani.sc_caldone)
604 cal_interval = min(cal_interval, (u32)ATH_SHORT_CALINTERVAL);
605
606 mod_timer(&sc->sc_ani.timer, jiffies + msecs_to_jiffies(cal_interval));
607}
608
495/******************/ 609/******************/
496/* VAP management */ 610/* VAP management */
497/******************/ 611/******************/
@@ -528,7 +642,7 @@ int ath_vap_attach(struct ath_softc *sc,
528 if (avp == NULL) 642 if (avp == NULL)
529 return -ENOMEM; 643 return -ENOMEM;
530 644
531 memzero(avp, sizeof(struct ath_vap)); 645 memset(avp, 0, sizeof(struct ath_vap));
532 avp->av_if_data = if_data; 646 avp->av_if_data = if_data;
533 /* Set the VAP opmode */ 647 /* Set the VAP opmode */
534 avp->av_opmode = opmode; 648 avp->av_opmode = opmode;
@@ -678,12 +792,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
678 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT) 792 if (ah->ah_caps.hw_caps & ATH9K_HW_CAP_HT)
679 sc->sc_imask |= ATH9K_INT_CST; 793 sc->sc_imask |= ATH9K_INT_CST;
680 794
681 /* Note: We disable MIB interrupts for now as we don't yet
682 * handle processing ANI, otherwise you will get an interrupt
683 * storm after about 7 hours of usage making the system unusable
684 * with huge latency. Once we do have ANI processing included
685 * we can re-enable this interrupt. */
686#if 0
687 /* 795 /*
688 * Enable MIB interrupts when there are hardware phy counters. 796 * Enable MIB interrupts when there are hardware phy counters.
689 * Note we only do this (at the moment) for station mode. 797 * Note we only do this (at the moment) for station mode.
@@ -692,7 +800,6 @@ int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
692 ((sc->sc_ah->ah_opmode == ATH9K_M_STA) || 800 ((sc->sc_ah->ah_opmode == ATH9K_M_STA) ||
693 (sc->sc_ah->ah_opmode == ATH9K_M_IBSS))) 801 (sc->sc_ah->ah_opmode == ATH9K_M_IBSS)))
694 sc->sc_imask |= ATH9K_INT_MIB; 802 sc->sc_imask |= ATH9K_INT_MIB;
695#endif
696 /* 803 /*
697 * Some hardware processes the TIM IE and fires an 804 * Some hardware processes the TIM IE and fires an
698 * interrupt when the TIM bit is set. For hardware 805 * interrupt when the TIM bit is set. For hardware
@@ -993,6 +1100,10 @@ int ath_init(u16 devid, struct ath_softc *sc)
993 } 1100 }
994 sc->sc_ah = ah; 1101 sc->sc_ah = ah;
995 1102
1103 /* Initializes the noise floor to a reasonable default value.
1104 * Later on this will be updated during ANI processing. */
1105 sc->sc_ani.sc_noise_floor = ATH_DEFAULT_NOISE_FLOOR;
1106
996 /* Get the hardware key cache size. */ 1107 /* Get the hardware key cache size. */
997 sc->sc_keymax = ah->ah_caps.keycache_size; 1108 sc->sc_keymax = ah->ah_caps.keycache_size;
998 if (sc->sc_keymax > ATH_KEYMAX) { 1109 if (sc->sc_keymax > ATH_KEYMAX) {
@@ -1100,6 +1211,8 @@ int ath_init(u16 devid, struct ath_softc *sc)
1100 goto bad2; 1211 goto bad2;
1101 } 1212 }
1102 1213
1214 setup_timer(&sc->sc_ani.timer, ath_ani_calibrate, (unsigned long)sc);
1215
1103 sc->sc_rc = ath_rate_attach(ah); 1216 sc->sc_rc = ath_rate_attach(ah);
1104 if (sc->sc_rc == NULL) { 1217 if (sc->sc_rc == NULL) {
1105 error = -EIO; 1218 error = -EIO;
@@ -1221,7 +1334,7 @@ struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id)
1221 an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC); 1334 an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC);
1222 if (an == NULL) 1335 if (an == NULL)
1223 return NULL; 1336 return NULL;
1224 memzero(an, sizeof(*an)); 1337 memset(an, 0, sizeof(*an));
1225 1338
1226 an->an_sc = sc; 1339 an->an_sc = sc;
1227 memcpy(an->an_addr, addr, ETH_ALEN); 1340 memcpy(an->an_addr, addr, ETH_ALEN);
@@ -1608,7 +1721,7 @@ int ath_descdma_setup(struct ath_softc *sc,
1608 error = -ENOMEM; 1721 error = -ENOMEM;
1609 goto fail2; 1722 goto fail2;
1610 } 1723 }
1611 memzero(bf, bsize); 1724 memset(bf, 0, bsize);
1612 dd->dd_bufptr = bf; 1725 dd->dd_bufptr = bf;
1613 1726
1614 INIT_LIST_HEAD(head); 1727 INIT_LIST_HEAD(head);
@@ -1640,7 +1753,7 @@ fail2:
1640 pci_free_consistent(sc->pdev, 1753 pci_free_consistent(sc->pdev,
1641 dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr); 1754 dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
1642fail: 1755fail:
1643 memzero(dd, sizeof(*dd)); 1756 memset(dd, 0, sizeof(*dd));
1644 return error; 1757 return error;
1645#undef ATH_DESC_4KB_BOUND_CHECK 1758#undef ATH_DESC_4KB_BOUND_CHECK
1646#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED 1759#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
@@ -1665,7 +1778,7 @@ void ath_descdma_cleanup(struct ath_softc *sc,
1665 1778
1666 INIT_LIST_HEAD(head); 1779 INIT_LIST_HEAD(head);
1667 kfree(dd->dd_bufptr); 1780 kfree(dd->dd_bufptr);
1668 memzero(dd, sizeof(*dd)); 1781 memset(dd, 0, sizeof(*dd));
1669} 1782}
1670 1783
1671/*************/ 1784/*************/
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
index 872f0c5a0b0e..cb3e61e57c4d 100644
--- a/drivers/net/wireless/ath9k/core.h
+++ b/drivers/net/wireless/ath9k/core.h
@@ -84,9 +84,6 @@ struct ath_node;
84#define TSF_TO_TU(_h,_l) \ 84#define TSF_TO_TU(_h,_l) \
85 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) 85 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
86 86
87/* XXX: remove */
88#define memzero(_buf, _len) memset(_buf, 0, _len)
89
90#define ATH9K_BH_STATUS_INTACT 0 87#define ATH9K_BH_STATUS_INTACT 0
91#define ATH9K_BH_STATUS_CHANGE 1 88#define ATH9K_BH_STATUS_CHANGE 1
92 89
@@ -184,7 +181,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht);
184 (_bf)->bf_lastbf = NULL; \ 181 (_bf)->bf_lastbf = NULL; \
185 (_bf)->bf_lastfrm = NULL; \ 182 (_bf)->bf_lastfrm = NULL; \
186 (_bf)->bf_next = NULL; \ 183 (_bf)->bf_next = NULL; \
187 memzero(&((_bf)->bf_state), \ 184 memset(&((_bf)->bf_state), 0, \
188 sizeof(struct ath_buf_state)); \ 185 sizeof(struct ath_buf_state)); \
189 } while (0) 186 } while (0)
190 187
@@ -312,7 +309,7 @@ void ath_descdma_cleanup(struct ath_softc *sc,
312#define ATH_RX_TIMEOUT 40 /* 40 milliseconds */ 309#define ATH_RX_TIMEOUT 40 /* 40 milliseconds */
313#define WME_NUM_TID 16 310#define WME_NUM_TID 16
314#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */ 311#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */
315#define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */ 312#define IEEE80211_BAR_CTL_TID_S 12 /* tid shift */
316 313
317enum ATH_RX_TYPE { 314enum ATH_RX_TYPE {
318 ATH_RX_NON_CONSUMED = 0, 315 ATH_RX_NON_CONSUMED = 0,
@@ -803,6 +800,28 @@ void ath_slow_ant_div(struct ath_antdiv *antdiv,
803 struct ath_rx_status *rx_stats); 800 struct ath_rx_status *rx_stats);
804void ath_setdefantenna(void *sc, u32 antenna); 801void ath_setdefantenna(void *sc, u32 antenna);
805 802
803/*******/
804/* ANI */
805/*******/
806
807/* ANI values for STA only.
808 FIXME: Add appropriate values for AP later */
809
810#define ATH_ANI_POLLINTERVAL 100 /* 100 milliseconds between ANI poll */
811#define ATH_SHORT_CALINTERVAL 1000 /* 1 second between calibrations */
812#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds between calibrations */
813#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes between calibrations */
814
815struct ath_ani {
816 bool sc_caldone;
817 int16_t sc_noise_floor;
818 unsigned int sc_longcal_timer;
819 unsigned int sc_shortcal_timer;
820 unsigned int sc_resetcal_timer;
821 unsigned int sc_checkani_timer;
822 struct timer_list timer;
823};
824
806/********************/ 825/********************/
807/* LED Control */ 826/* LED Control */
808/********************/ 827/********************/
@@ -1031,6 +1050,9 @@ struct ath_softc {
1031 1050
1032 /* Rfkill */ 1051 /* Rfkill */
1033 struct ath_rfkill rf_kill; 1052 struct ath_rfkill rf_kill;
1053
1054 /* ANI */
1055 struct ath_ani sc_ani;
1034}; 1056};
1035 1057
1036int ath_init(u16 devid, struct ath_softc *sc); 1058int ath_init(u16 devid, struct ath_softc *sc);
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index 272c75816609..62e44a0ef996 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -329,7 +329,7 @@ static void ath9k_hw_set_defaults(struct ath_hal *ah)
329 ah->ah_config.ofdm_trig_high = 500; 329 ah->ah_config.ofdm_trig_high = 500;
330 ah->ah_config.cck_trig_high = 200; 330 ah->ah_config.cck_trig_high = 200;
331 ah->ah_config.cck_trig_low = 100; 331 ah->ah_config.cck_trig_low = 100;
332 ah->ah_config.enable_ani = 0; 332 ah->ah_config.enable_ani = 1;
333 ah->ah_config.noise_immunity_level = 4; 333 ah->ah_config.noise_immunity_level = 4;
334 ah->ah_config.ofdm_weaksignal_det = 1; 334 ah->ah_config.ofdm_weaksignal_det = 1;
335 ah->ah_config.cck_weaksignal_thr = 0; 335 ah->ah_config.cck_weaksignal_thr = 0;
@@ -8405,23 +8405,48 @@ u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8405 } 8405 }
8406} 8406}
8407 8407
8408int16_t 8408/* We can tune this as we go by monitoring really low values */
8409#define ATH9K_NF_TOO_LOW -60
8410
8411/* AR5416 may return very high value (like -31 dBm), in those cases the nf
8412 * is incorrect and we should use the static NF value. Later we can try to
8413 * find out why they are reporting these values */
8414static bool ath9k_hw_nf_in_range(struct ath_hal *ah, s16 nf)
8415{
8416 if (nf > ATH9K_NF_TOO_LOW) {
8417 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8418 "%s: noise floor value detected (%d) is "
8419 "lower than what we think is a "
8420 "reasonable value (%d)\n",
8421 __func__, nf, ATH9K_NF_TOO_LOW);
8422 return false;
8423 }
8424 return true;
8425}
8426
8427s16
8409ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) 8428ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8410{ 8429{
8411 struct ath9k_channel *ichan; 8430 struct ath9k_channel *ichan;
8431 s16 nf;
8412 8432
8413 ichan = ath9k_regd_check_channel(ah, chan); 8433 ichan = ath9k_regd_check_channel(ah, chan);
8414 if (ichan == NULL) { 8434 if (ichan == NULL) {
8415 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL, 8435 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8416 "%s: invalid channel %u/0x%x; no mapping\n", 8436 "%s: invalid channel %u/0x%x; no mapping\n",
8417 __func__, chan->channel, chan->channelFlags); 8437 __func__, chan->channel, chan->channelFlags);
8418 return 0; 8438 return ATH_DEFAULT_NOISE_FLOOR;
8419 } 8439 }
8420 if (ichan->rawNoiseFloor == 0) { 8440 if (ichan->rawNoiseFloor == 0) {
8421 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); 8441 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8422 return NOISE_FLOOR[mode]; 8442 nf = NOISE_FLOOR[mode];
8423 } else 8443 } else
8424 return ichan->rawNoiseFloor; 8444 nf = ichan->rawNoiseFloor;
8445
8446 if (!ath9k_hw_nf_in_range(ah, nf))
8447 nf = ATH_DEFAULT_NOISE_FLOOR;
8448
8449 return nf;
8425} 8450}
8426 8451
8427bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting) 8452bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index 2caba4403167..74726990d59e 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -274,10 +274,12 @@ static void ath9k_rx_prepare(struct ath_softc *sc,
274 rx_status->mactime = status->tsf; 274 rx_status->mactime = status->tsf;
275 rx_status->band = curchan->band; 275 rx_status->band = curchan->band;
276 rx_status->freq = curchan->center_freq; 276 rx_status->freq = curchan->center_freq;
277 rx_status->noise = ATH_DEFAULT_NOISE_FLOOR; 277 rx_status->noise = sc->sc_ani.sc_noise_floor;
278 rx_status->signal = rx_status->noise + status->rssi; 278 rx_status->signal = rx_status->noise + status->rssi;
279 rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100)); 279 rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100));
280 rx_status->antenna = status->antenna; 280 rx_status->antenna = status->antenna;
281
282 /* XXX Fix me, 64 cannot be the max rssi value, rigure it out */
281 rx_status->qual = status->rssi * 100 / 64; 283 rx_status->qual = status->rssi * 100 / 64;
282 284
283 if (status->flags & ATH_RX_MIC_ERROR) 285 if (status->flags & ATH_RX_MIC_ERROR)
@@ -427,6 +429,11 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
427 ath_rate_newstate(sc, avp); 429 ath_rate_newstate(sc, avp);
428 /* Update ratectrl about the new state */ 430 /* Update ratectrl about the new state */
429 ath_rc_node_update(hw, avp->rc_node); 431 ath_rc_node_update(hw, avp->rc_node);
432
433 /* Start ANI */
434 mod_timer(&sc->sc_ani.timer,
435 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
436
430 } else { 437 } else {
431 DPRINTF(sc, ATH_DBG_CONFIG, 438 DPRINTF(sc, ATH_DBG_CONFIG,
432 "%s: Bss Info DISSOC\n", __func__); 439 "%s: Bss Info DISSOC\n", __func__);
@@ -1173,6 +1180,13 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1173 return error; 1180 return error;
1174 } 1181 }
1175 1182
1183 if (conf->type == NL80211_IFTYPE_AP) {
1184 /* TODO: is this a suitable place to start ANI for AP mode? */
1185 /* Start ANI */
1186 mod_timer(&sc->sc_ani.timer,
1187 jiffies + msecs_to_jiffies(ATH_ANI_POLLINTERVAL));
1188 }
1189
1176 return 0; 1190 return 0;
1177} 1191}
1178 1192
@@ -1195,6 +1209,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1195#ifdef CONFIG_SLOW_ANT_DIV 1209#ifdef CONFIG_SLOW_ANT_DIV
1196 ath_slow_ant_div_stop(&sc->sc_antdiv); 1210 ath_slow_ant_div_stop(&sc->sc_antdiv);
1197#endif 1211#endif
1212 /* Stop ANI */
1213 del_timer_sync(&sc->sc_ani.timer);
1198 1214
1199 /* Update ratectrl */ 1215 /* Update ratectrl */
1200 ath_rate_newstate(sc, avp); 1216 ath_rate_newstate(sc, avp);
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
index 498256309ab7..4983402af559 100644
--- a/drivers/net/wireless/ath9k/recv.c
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -892,7 +892,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
892 892
893 hdr = (struct ieee80211_hdr *)skb->data; 893 hdr = (struct ieee80211_hdr *)skb->data;
894 fc = hdr->frame_control; 894 fc = hdr->frame_control;
895 memzero(&rx_status, sizeof(struct ath_recv_status)); 895 memset(&rx_status, 0, sizeof(struct ath_recv_status));
896 896
897 if (ds->ds_rxstat.rs_more) { 897 if (ds->ds_rxstat.rs_more) {
898 /* 898 /*
@@ -999,20 +999,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
999 rx_status.flags |= ATH_RX_SHORT_GI; 999 rx_status.flags |= ATH_RX_SHORT_GI;
1000 } 1000 }
1001 1001
1002 /* sc->sc_noise_floor is only available when the station 1002 /* sc_noise_floor is only available when the station
1003 attaches to an AP, so we use a default value 1003 attaches to an AP, so we use a default value
1004 if we are not yet attached. */ 1004 if we are not yet attached. */
1005
1006 /* XXX we should use either sc->sc_noise_floor or
1007 * ath_hal_getChanNoise(ah, &sc->sc_curchan)
1008 * to calculate the noise floor.
1009 * However, the value returned by ath_hal_getChanNoise
1010 * seems to be incorrect (-31dBm on the last test),
1011 * so we will use a hard-coded value until we
1012 * figure out what is going on.
1013 */
1014 rx_status.abs_rssi = 1005 rx_status.abs_rssi =
1015 ds->ds_rxstat.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; 1006 ds->ds_rxstat.rs_rssi + sc->sc_ani.sc_noise_floor;
1016 1007
1017 pci_dma_sync_single_for_cpu(sc->pdev, 1008 pci_dma_sync_single_for_cpu(sc->pdev,
1018 bf->bf_buf_addr, 1009 bf->bf_buf_addr,
@@ -1166,7 +1157,7 @@ int ath_rx_aggr_start(struct ath_softc *sc,
1166 } else { 1157 } else {
1167 /* Ensure the memory is zeroed out (all internal 1158 /* Ensure the memory is zeroed out (all internal
1168 * pointers are null) */ 1159 * pointers are null) */
1169 memzero(rxtid->rxbuf, ATH_TID_MAX_BUFS * 1160 memset(rxtid->rxbuf, 0, ATH_TID_MAX_BUFS *
1170 sizeof(struct ath_rxbuf)); 1161 sizeof(struct ath_rxbuf));
1171 DPRINTF(sc, ATH_DBG_AGGR, 1162 DPRINTF(sc, ATH_DBG_AGGR,
1172 "%s: Allocated @%p\n", __func__, rxtid->rxbuf); 1163 "%s: Allocated @%p\n", __func__, rxtid->rxbuf);
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
index 25929059c7dc..3a4757942b3f 100644
--- a/drivers/net/wireless/ath9k/xmit.c
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -237,7 +237,7 @@ static int ath_tx_prepare(struct ath_softc *sc,
237 237
238 if (tx_info->control.hw_key) { 238 if (tx_info->control.hw_key) {
239 txctl->keyix = tx_info->control.hw_key->hw_key_idx; 239 txctl->keyix = tx_info->control.hw_key->hw_key_idx;
240 txctl->frmlen += tx_info->control.icv_len; 240 txctl->frmlen += tx_info->control.hw_key->icv_len;
241 241
242 if (tx_info->control.hw_key->alg == ALG_WEP) 242 if (tx_info->control.hw_key->alg == ALG_WEP)
243 txctl->keytype = ATH9K_KEY_TYPE_WEP; 243 txctl->keytype = ATH9K_KEY_TYPE_WEP;
@@ -729,7 +729,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
729 /* 729 /*
730 * Setup HAL rate series 730 * Setup HAL rate series
731 */ 731 */
732 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4); 732 memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
733 733
734 for (i = 0; i < 4; i++) { 734 for (i = 0; i < 4; i++) {
735 if (!bf->bf_rcs[i].tries) 735 if (!bf->bf_rcs[i].tries)
@@ -817,7 +817,7 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
817 * Disable multi-rate retry when using RTS/CTS by clearing 817 * Disable multi-rate retry when using RTS/CTS by clearing
818 * series 1, 2 and 3. 818 * series 1, 2 and 3.
819 */ 819 */
820 memzero(&series[1], sizeof(struct ath9k_11n_rate_series) * 3); 820 memset(&series[1], 0, sizeof(struct ath9k_11n_rate_series) * 3);
821 } 821 }
822 822
823 /* 823 /*
@@ -930,7 +930,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
930 ATH_DS_BA_BITMAP(ds), 930 ATH_DS_BA_BITMAP(ds),
931 WME_BA_BMP_SIZE >> 3); 931 WME_BA_BMP_SIZE >> 3);
932 } else { 932 } else {
933 memzero(ba, WME_BA_BMP_SIZE >> 3); 933 memset(ba, 0, WME_BA_BMP_SIZE >> 3);
934 934
935 /* 935 /*
936 * AR5416 can become deaf/mute when BA 936 * AR5416 can become deaf/mute when BA
@@ -943,7 +943,7 @@ static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
943 needreset = 1; 943 needreset = 1;
944 } 944 }
945 } else { 945 } else {
946 memzero(ba, WME_BA_BMP_SIZE >> 3); 946 memset(ba, 0, WME_BA_BMP_SIZE >> 3);
947 } 947 }
948 } 948 }
949 949
@@ -2098,7 +2098,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
2098 struct ath9k_tx_queue_info qi; 2098 struct ath9k_tx_queue_info qi;
2099 int qnum; 2099 int qnum;
2100 2100
2101 memzero(&qi, sizeof(qi)); 2101 memset(&qi, 0, sizeof(qi));
2102 qi.tqi_subtype = subtype; 2102 qi.tqi_subtype = subtype;
2103 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; 2103 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
2104 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; 2104 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 3bf74e236abc..14c44df584d0 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4588,6 +4588,7 @@ static int b43_wireless_init(struct ssb_device *dev)
4588 BIT(NL80211_IFTYPE_ADHOC); 4588 BIT(NL80211_IFTYPE_ADHOC);
4589 4589
4590 hw->queues = b43_modparam_qos ? 4 : 1; 4590 hw->queues = b43_modparam_qos ? 4 : 1;
4591 hw->max_altrates = 1;
4591 SET_IEEE80211_DEV(hw, dev->dev); 4592 SET_IEEE80211_DEV(hw, dev->dev);
4592 if (is_valid_ether_addr(sprom->et1mac)) 4593 if (is_valid_ether_addr(sprom->et1mac))
4593 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); 4594 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index 5e0b71c3ad02..2fabcf8f0474 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -208,7 +208,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
208 txrate = ieee80211_get_tx_rate(dev->wl->hw, info); 208 txrate = ieee80211_get_tx_rate(dev->wl->hw, info);
209 rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB; 209 rate = txrate ? txrate->hw_value : B43_CCK_RATE_1MB;
210 rate_ofdm = b43_is_ofdm_rate(rate); 210 rate_ofdm = b43_is_ofdm_rate(rate);
211 fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : txrate; 211 fbrate = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : txrate;
212 rate_fb = fbrate->hw_value; 212 rate_fb = fbrate->hw_value;
213 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb); 213 rate_fb_ofdm = b43_is_ofdm_rate(rate_fb);
214 214
@@ -252,7 +252,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
252 } 252 }
253 253
254 /* Hardware appends ICV. */ 254 /* Hardware appends ICV. */
255 plcp_fragment_len += info->control.icv_len; 255 plcp_fragment_len += info->control.hw_key->icv_len;
256 256
257 key_idx = b43_kidx_to_fw(dev, key_idx); 257 key_idx = b43_kidx_to_fw(dev, key_idx);
258 mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) & 258 mac_ctl |= (key_idx << B43_TXH_MAC_KEYIDX_SHIFT) &
@@ -260,7 +260,7 @@ int b43_generate_txhdr(struct b43_wldev *dev,
260 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) & 260 mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) &
261 B43_TXH_MAC_KEYALG; 261 B43_TXH_MAC_KEYALG;
262 wlhdr_len = ieee80211_hdrlen(fctl); 262 wlhdr_len = ieee80211_hdrlen(fctl);
263 iv_len = min((size_t) info->control.iv_len, 263 iv_len = min((size_t) info->control.hw_key->iv_len,
264 ARRAY_SIZE(txhdr->iv)); 264 ARRAY_SIZE(txhdr->iv));
265 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); 265 memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len);
266 } 266 }
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 9fb1421cbec2..c66d57560e7c 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -3710,6 +3710,7 @@ static int b43legacy_wireless_init(struct ssb_device *dev)
3710 BIT(NL80211_IFTYPE_WDS) | 3710 BIT(NL80211_IFTYPE_WDS) |
3711 BIT(NL80211_IFTYPE_ADHOC); 3711 BIT(NL80211_IFTYPE_ADHOC);
3712 hw->queues = 1; /* FIXME: hardware has more queues */ 3712 hw->queues = 1; /* FIXME: hardware has more queues */
3713 hw->max_altrates = 1;
3713 SET_IEEE80211_DEV(hw, dev->dev); 3714 SET_IEEE80211_DEV(hw, dev->dev);
3714 if (is_valid_ether_addr(sprom->et1mac)) 3715 if (is_valid_ether_addr(sprom->et1mac))
3715 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac); 3716 SET_IEEE80211_PERM_ADDR(hw, sprom->et1mac);
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c
index 6835064758fb..65e833781608 100644
--- a/drivers/net/wireless/b43legacy/xmit.c
+++ b/drivers/net/wireless/b43legacy/xmit.c
@@ -210,7 +210,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
210 210
211 rate = tx_rate->hw_value; 211 rate = tx_rate->hw_value;
212 rate_ofdm = b43legacy_is_ofdm_rate(rate); 212 rate_ofdm = b43legacy_is_ofdm_rate(rate);
213 rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info) ? : tx_rate; 213 rate_fb = ieee80211_get_alt_retry_rate(dev->wl->hw, info, 0) ? : tx_rate;
214 rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value); 214 rate_fb_ofdm = b43legacy_is_ofdm_rate(rate_fb->hw_value);
215 215
216 txhdr->mac_frame_ctl = wlhdr->frame_control; 216 txhdr->mac_frame_ctl = wlhdr->frame_control;
@@ -243,7 +243,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
243 243
244 if (key->enabled) { 244 if (key->enabled) {
245 /* Hardware appends ICV. */ 245 /* Hardware appends ICV. */
246 plcp_fragment_len += info->control.icv_len; 246 plcp_fragment_len += info->control.hw_key->icv_len;
247 247
248 key_idx = b43legacy_kidx_to_fw(dev, key_idx); 248 key_idx = b43legacy_kidx_to_fw(dev, key_idx);
249 mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) & 249 mac_ctl |= (key_idx << B43legacy_TX4_MAC_KEYIDX_SHIFT) &
@@ -252,7 +252,7 @@ static int generate_txhdr_fw3(struct b43legacy_wldev *dev,
252 B43legacy_TX4_MAC_KEYALG_SHIFT) & 252 B43legacy_TX4_MAC_KEYALG_SHIFT) &
253 B43legacy_TX4_MAC_KEYALG; 253 B43legacy_TX4_MAC_KEYALG;
254 wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control); 254 wlhdr_len = ieee80211_hdrlen(wlhdr->frame_control);
255 iv_len = min((size_t)info->control.iv_len, 255 iv_len = min((size_t)info->control.hw_key->iv_len,
256 ARRAY_SIZE(txhdr->iv)); 256 ARRAY_SIZE(txhdr->iv));
257 memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len); 257 memcpy(txhdr->iv, ((u8 *)wlhdr) + wlhdr_len, iv_len);
258 } else { 258 } else {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 204abab76449..24a1aeb6448f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2569,30 +2569,6 @@ static void iwl4965_post_associate(struct iwl_priv *priv)
2569 2569
2570} 2570}
2571 2571
2572static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf);
2573
2574static void iwl_bg_scan_completed(struct work_struct *work)
2575{
2576 struct iwl_priv *priv =
2577 container_of(work, struct iwl_priv, scan_completed);
2578
2579 IWL_DEBUG_SCAN("SCAN complete scan\n");
2580
2581 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2582 return;
2583
2584 if (test_bit(STATUS_CONF_PENDING, &priv->status))
2585 iwl4965_mac_config(priv->hw, ieee80211_get_hw_conf(priv->hw));
2586
2587 ieee80211_scan_completed(priv->hw);
2588
2589 /* Since setting the TXPOWER may have been deferred while
2590 * performing the scan, fire one off */
2591 mutex_lock(&priv->mutex);
2592 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
2593 mutex_unlock(&priv->mutex);
2594}
2595
2596/***************************************************************************** 2572/*****************************************************************************
2597 * 2573 *
2598 * mac80211 entry point functions 2574 * mac80211 entry point functions
@@ -2812,7 +2788,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
2812 if (unlikely(!priv->cfg->mod_params->disable_hw_scan && 2788 if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
2813 test_bit(STATUS_SCANNING, &priv->status))) { 2789 test_bit(STATUS_SCANNING, &priv->status))) {
2814 IWL_DEBUG_MAC80211("leave - scanning\n"); 2790 IWL_DEBUG_MAC80211("leave - scanning\n");
2815 set_bit(STATUS_CONF_PENDING, &priv->status);
2816 mutex_unlock(&priv->mutex); 2791 mutex_unlock(&priv->mutex);
2817 return 0; 2792 return 0;
2818 } 2793 }
@@ -2898,7 +2873,6 @@ static int iwl4965_mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *co
2898 IWL_DEBUG_MAC80211("leave\n"); 2873 IWL_DEBUG_MAC80211("leave\n");
2899 2874
2900out: 2875out:
2901 clear_bit(STATUS_CONF_PENDING, &priv->status);
2902 mutex_unlock(&priv->mutex); 2876 mutex_unlock(&priv->mutex);
2903 return ret; 2877 return ret;
2904} 2878}
@@ -4117,8 +4091,6 @@ static void iwl_setup_deferred_work(struct iwl_priv *priv)
4117 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start); 4091 INIT_DELAYED_WORK(&priv->init_alive_start, iwl_bg_init_alive_start);
4118 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start); 4092 INIT_DELAYED_WORK(&priv->alive_start, iwl_bg_alive_start);
4119 4093
4120 /* FIXME : remove when resolved PENDING */
4121 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
4122 iwl_setup_scan_deferred_work(priv); 4094 iwl_setup_scan_deferred_work(priv);
4123 iwl_setup_power_deferred_work(priv); 4095 iwl_setup_power_deferred_work(priv);
4124 4096
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 55a4b584ce07..288b6a800e03 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -333,8 +333,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv);
333#define STATUS_SCAN_HW 15 333#define STATUS_SCAN_HW 15
334#define STATUS_POWER_PMI 16 334#define STATUS_POWER_PMI 16
335#define STATUS_FW_ERROR 17 335#define STATUS_FW_ERROR 17
336#define STATUS_CONF_PENDING 18 336#define STATUS_MODE_PENDING 18
337#define STATUS_MODE_PENDING 19
338 337
339 338
340static inline int iwl_is_ready(struct iwl_priv *priv) 339static inline int iwl_is_ready(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index bf855c35b0c1..3b0bee331a33 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -703,7 +703,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
703 u16 cmd_len; 703 u16 cmd_len;
704 enum ieee80211_band band; 704 enum ieee80211_band band;
705 u8 n_probes = 2; 705 u8 n_probes = 2;
706 u8 rx_chain = 0x7; /* bitmap: ABC chains */ 706 u8 rx_chain = priv->hw_params.valid_rx_ant;
707 707
708 conf = ieee80211_get_hw_conf(priv->hw); 708 conf = ieee80211_get_hw_conf(priv->hw);
709 709
@@ -843,7 +843,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
843 843
844 /* Force use of chains B and C (0x6) for scan Rx for 4965 844 /* Force use of chains B and C (0x6) for scan Rx for 4965
845 * Avoid A (0x1) because of its off-channel reception on A-band. 845 * Avoid A (0x1) because of its off-channel reception on A-band.
846 * MIMO is not used here, but value is required */ 846 */
847 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) 847 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
848 rx_chain = 0x6; 848 rx_chain = 0x6;
849 } else { 849 } else {
@@ -851,6 +851,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
851 goto done; 851 goto done;
852 } 852 }
853 853
854 /* MIMO is not used here, but value is required */
854 scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK | 855 scan->rx_chain = RXON_RX_CHAIN_DRIVER_FORCE_MSK |
855 cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) | 856 cpu_to_le16((0x7 << RXON_RX_CHAIN_VALID_POS) |
856 (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) | 857 (rx_chain << RXON_RX_CHAIN_FORCE_SEL_POS) |
@@ -915,10 +916,29 @@ static void iwl_bg_abort_scan(struct work_struct *work)
915 mutex_unlock(&priv->mutex); 916 mutex_unlock(&priv->mutex);
916} 917}
917 918
919static void iwl_bg_scan_completed(struct work_struct *work)
920{
921 struct iwl_priv *priv =
922 container_of(work, struct iwl_priv, scan_completed);
923
924 IWL_DEBUG_SCAN("SCAN complete scan\n");
925
926 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
927 return;
928
929 ieee80211_scan_completed(priv->hw);
930
931 /* Since setting the TXPOWER may have been deferred while
932 * performing the scan, fire one off */
933 mutex_lock(&priv->mutex);
934 iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
935 mutex_unlock(&priv->mutex);
936}
937
938
918void iwl_setup_scan_deferred_work(struct iwl_priv *priv) 939void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
919{ 940{
920 /* FIXME: move here when resolved PENDING 941 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
921 * INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); */
922 INIT_WORK(&priv->request_scan, iwl_bg_request_scan); 942 INIT_WORK(&priv->request_scan, iwl_bg_request_scan);
923 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); 943 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
924 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); 944 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index de5e8f44b202..1994aa199d37 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -507,9 +507,10 @@ static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
507 rx_status.noise = priv->noise; 507 rx_status.noise = priv->noise;
508 /* XX correct? */ 508 /* XX correct? */
509 rx_status.qual = (100 * hdr->rssi) / 127; 509 rx_status.qual = (100 * hdr->rssi) / 127;
510 rx_status.rate_idx = hdr->rate & 0xf; 510 rx_status.rate_idx = (dev->conf.channel->band == IEEE80211_BAND_2GHZ ?
511 hdr->rate : (hdr->rate - 4)) & 0xf;
511 rx_status.freq = freq; 512 rx_status.freq = freq;
512 rx_status.band = IEEE80211_BAND_2GHZ; 513 rx_status.band = dev->conf.channel->band;
513 rx_status.antenna = hdr->antenna; 514 rx_status.antenna = hdr->antenna;
514 515
515 tsf32 = le32_to_cpu(hdr->tsf32); 516 tsf32 = le32_to_cpu(hdr->tsf32);
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index e1448cfa9444..5a858e5106c4 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -56,10 +56,10 @@ unsigned int rt2x00crypto_tx_overhead(struct ieee80211_tx_info *tx_info)
56 * note that these lengths should only be added when 56 * note that these lengths should only be added when
57 * mac80211 does not generate it. 57 * mac80211 does not generate it.
58 */ 58 */
59 overhead += tx_info->control.icv_len; 59 overhead += key->icv_len;
60 60
61 if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_IV)) 61 if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_IV))
62 overhead += tx_info->control.iv_len; 62 overhead += key->iv_len;
63 63
64 if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) { 64 if (!(key->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC)) {
65 if (key->alg == ALG_TKIP) 65 if (key->alg == ALG_TKIP)
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index b7f4fe8fba6e..1676ac484790 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -374,7 +374,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
374 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); 374 struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX);
375 struct txentry_desc txdesc; 375 struct txentry_desc txdesc;
376 struct skb_frame_desc *skbdesc; 376 struct skb_frame_desc *skbdesc;
377 unsigned int iv_len = IEEE80211_SKB_CB(skb)->control.iv_len; 377 unsigned int iv_len;
378 378
379 if (unlikely(rt2x00queue_full(queue))) 379 if (unlikely(rt2x00queue_full(queue)))
380 return -EINVAL; 380 return -EINVAL;
@@ -410,8 +410,11 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb)
410 * the frame so we can provide it to the driver seperately. 410 * the frame so we can provide it to the driver seperately.
411 */ 411 */
412 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) && 412 if (test_bit(ENTRY_TXD_ENCRYPT, &txdesc.flags) &&
413 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags)) 413 !test_bit(ENTRY_TXD_ENCRYPT_IV, &txdesc.flags) &&
414 (IEEE80211_SKB_CB(skb)->control.hw_key != NULL)) {
415 iv_len = IEEE80211_SKB_CB(skb)->control.hw_key->iv_len;
414 rt2x00crypto_tx_remove_iv(skb, iv_len); 416 rt2x00crypto_tx_remove_iv(skb, iv_len);
417 }
415 418
416 /* 419 /*
417 * It could be possible that the queue was corrupted and this 420 * It could be possible that the queue was corrupted and this
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
index 55eff58f1889..c3f53a92180a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c
+++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c
@@ -145,10 +145,15 @@ void rt2x00rfkill_allocate(struct rt2x00_dev *rt2x00dev)
145 145
146 rt2x00dev->rfkill->name = rt2x00dev->ops->name; 146 rt2x00dev->rfkill->name = rt2x00dev->ops->name;
147 rt2x00dev->rfkill->data = rt2x00dev; 147 rt2x00dev->rfkill->data = rt2x00dev;
148 rt2x00dev->rfkill->state = -1;
149 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio; 148 rt2x00dev->rfkill->toggle_radio = rt2x00rfkill_toggle_radio;
150 if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) 149 if (test_bit(CONFIG_SUPPORT_HW_BUTTON, &rt2x00dev->flags)) {
151 rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state; 150 rt2x00dev->rfkill->get_state = rt2x00rfkill_get_state;
151 rt2x00dev->rfkill->state =
152 rt2x00dev->ops->lib->rfkill_poll(rt2x00dev) ?
153 RFKILL_STATE_SOFT_BLOCKED : RFKILL_STATE_UNBLOCKED;
154 } else {
155 rt2x00dev->rfkill->state = RFKILL_STATE_UNBLOCKED;
156 }
152 157
153 INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll); 158 INIT_DELAYED_WORK(&rt2x00dev->rfkill_work, rt2x00rfkill_poll);
154 159
diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c
index abcd641c54be..df7e78ee8a88 100644
--- a/drivers/net/wireless/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl8180_dev.c
@@ -292,8 +292,8 @@ static int rtl8180_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
292 entry->plcp_len = cpu_to_le16(plcp_len); 292 entry->plcp_len = cpu_to_le16(plcp_len);
293 entry->tx_buf = cpu_to_le32(mapping); 293 entry->tx_buf = cpu_to_le32(mapping);
294 entry->frame_len = cpu_to_le32(skb->len); 294 entry->frame_len = cpu_to_le32(skb->len);
295 entry->flags2 = info->control.alt_retry_rate_idx >= 0 ? 295 entry->flags2 = info->control.retries[0].rate_idx >= 0 ?
296 ieee80211_get_alt_retry_rate(dev, info)->bitrate << 4 : 0; 296 ieee80211_get_alt_retry_rate(dev, info, 0)->bitrate << 4 : 0;
297 entry->retry_limit = info->control.retry_limit; 297 entry->retry_limit = info->control.retry_limit;
298 entry->flags = cpu_to_le32(tx_flags); 298 entry->flags = cpu_to_le32(tx_flags);
299 __skb_queue_tail(&ring->queue, skb); 299 __skb_queue_tail(&ring->queue, skb);
@@ -855,6 +855,7 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
855 priv = dev->priv; 855 priv = dev->priv;
856 priv->pdev = pdev; 856 priv->pdev = pdev;
857 857
858 dev->max_altrates = 1;
858 SET_IEEE80211_DEV(dev, &pdev->dev); 859 SET_IEEE80211_DEV(dev, &pdev->dev);
859 pci_set_drvdata(pdev, dev); 860 pci_set_drvdata(pdev, dev);
860 861
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f5f5b1ff1584..5617a1613c91 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -292,6 +292,20 @@ enum mac80211_tx_control_flags {
292#define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \ 292#define IEEE80211_TX_INFO_DRIVER_DATA_PTRS \
293 (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *)) 293 (IEEE80211_TX_INFO_DRIVER_DATA_SIZE / sizeof(void *))
294 294
295/* maximum number of alternate rate retry stages */
296#define IEEE80211_TX_MAX_ALTRATE 3
297
298/**
299 * struct ieee80211_tx_altrate - alternate rate selection/status
300 *
301 * @rate_idx: rate index to attempt to send with
302 * @limit: number of retries before fallback
303 */
304struct ieee80211_tx_altrate {
305 s8 rate_idx;
306 u8 limit;
307};
308
295/** 309/**
296 * struct ieee80211_tx_info - skb transmit information 310 * struct ieee80211_tx_info - skb transmit information
297 * 311 *
@@ -335,14 +349,14 @@ struct ieee80211_tx_info {
335 struct ieee80211_key_conf *hw_key; 349 struct ieee80211_key_conf *hw_key;
336 struct ieee80211_sta *sta; 350 struct ieee80211_sta *sta;
337 unsigned long jiffies; 351 unsigned long jiffies;
338 s8 rts_cts_rate_idx, alt_retry_rate_idx; 352 s8 rts_cts_rate_idx;
339 u8 retry_limit; 353 u8 retry_limit;
340 u8 icv_len; 354 struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE];
341 u8 iv_len;
342 } control; 355 } control;
343 struct { 356 struct {
344 u64 ampdu_ack_map; 357 u64 ampdu_ack_map;
345 int ack_signal; 358 int ack_signal;
359 struct ieee80211_tx_altrate retries[IEEE80211_TX_MAX_ALTRATE + 1];
346 u8 retry_count; 360 u8 retry_count;
347 bool excessive_retries; 361 bool excessive_retries;
348 u8 ampdu_ack_len; 362 u8 ampdu_ack_len;
@@ -635,6 +649,8 @@ enum ieee80211_key_flags {
635 */ 649 */
636struct ieee80211_key_conf { 650struct ieee80211_key_conf {
637 enum ieee80211_key_alg alg; 651 enum ieee80211_key_alg alg;
652 u8 icv_len;
653 u8 iv_len;
638 u8 hw_key_idx; 654 u8 hw_key_idx;
639 u8 flags; 655 u8 flags;
640 s8 keyidx; 656 s8 keyidx;
@@ -828,6 +844,9 @@ enum ieee80211_hw_flags {
828 * within &struct ieee80211_vif. 844 * within &struct ieee80211_vif.
829 * @sta_data_size: size (in bytes) of the drv_priv data area 845 * @sta_data_size: size (in bytes) of the drv_priv data area
830 * within &struct ieee80211_sta. 846 * within &struct ieee80211_sta.
847 *
848 * @max_altrates: maximum number of alternate rate retry stages
849 * @max_altrate_tries: maximum number of tries for each stage
831 */ 850 */
832struct ieee80211_hw { 851struct ieee80211_hw {
833 struct ieee80211_conf conf; 852 struct ieee80211_conf conf;
@@ -844,6 +863,8 @@ struct ieee80211_hw {
844 u16 ampdu_queues; 863 u16 ampdu_queues;
845 u16 max_listen_interval; 864 u16 max_listen_interval;
846 s8 max_signal; 865 s8 max_signal;
866 u8 max_altrates;
867 u8 max_altrate_tries;
847}; 868};
848 869
849struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy); 870struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy);
@@ -900,11 +921,11 @@ ieee80211_get_rts_cts_rate(const struct ieee80211_hw *hw,
900 921
901static inline struct ieee80211_rate * 922static inline struct ieee80211_rate *
902ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw, 923ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
903 const struct ieee80211_tx_info *c) 924 const struct ieee80211_tx_info *c, int idx)
904{ 925{
905 if (c->control.alt_retry_rate_idx < 0) 926 if (c->control.retries[idx].rate_idx < 0)
906 return NULL; 927 return NULL;
907 return &hw->wiphy->bands[c->band]->bitrates[c->control.alt_retry_rate_idx]; 928 return &hw->wiphy->bands[c->band]->bitrates[c->control.retries[idx].rate_idx];
908} 929}
909 930
910/** 931/**
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 8427518e4f20..7f710a27e91c 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -22,6 +22,11 @@ config MAC80211_RC_PID
22 mac80211 that uses a PID controller to select the TX 22 mac80211 that uses a PID controller to select the TX
23 rate. 23 rate.
24 24
25config MAC80211_RC_MINSTREL
26 bool "Minstrel"
27 ---help---
28 This option enables the 'minstrel' TX rate control algorithm
29
25choice 30choice
26 prompt "Default rate control algorithm" 31 prompt "Default rate control algorithm"
27 default MAC80211_RC_DEFAULT_PID 32 default MAC80211_RC_DEFAULT_PID
@@ -39,11 +44,19 @@ config MAC80211_RC_DEFAULT_PID
39 default rate control algorithm. You should choose 44 default rate control algorithm. You should choose
40 this unless you know what you are doing. 45 this unless you know what you are doing.
41 46
47config MAC80211_RC_DEFAULT_MINSTREL
48 bool "Minstrel"
49 depends on MAC80211_RC_MINSTREL
50 ---help---
51 Select Minstrel as the default rate control algorithm.
52
53
42endchoice 54endchoice
43 55
44config MAC80211_RC_DEFAULT 56config MAC80211_RC_DEFAULT
45 string 57 string
46 default "pid" if MAC80211_RC_DEFAULT_PID 58 default "pid" if MAC80211_RC_DEFAULT_PID
59 default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL
47 default "" 60 default ""
48 61
49endmenu 62endmenu
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 2dc8f2bff27b..31cfd1f89a72 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -41,4 +41,8 @@ mac80211-$(CONFIG_MAC80211_MESH) += \
41rc80211_pid-y := rc80211_pid_algo.o 41rc80211_pid-y := rc80211_pid_algo.o
42rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o 42rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o
43 43
44rc80211_minstrel-y := rc80211_minstrel.o
45rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o
46
44mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) 47mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y)
48mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 57afcd38cd9e..a5b06fe71980 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -281,6 +281,20 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
281 key->conf.alg = alg; 281 key->conf.alg = alg;
282 key->conf.keyidx = idx; 282 key->conf.keyidx = idx;
283 key->conf.keylen = key_len; 283 key->conf.keylen = key_len;
284 switch (alg) {
285 case ALG_WEP:
286 key->conf.iv_len = WEP_IV_LEN;
287 key->conf.icv_len = WEP_ICV_LEN;
288 break;
289 case ALG_TKIP:
290 key->conf.iv_len = TKIP_IV_LEN;
291 key->conf.icv_len = TKIP_ICV_LEN;
292 break;
293 case ALG_CCMP:
294 key->conf.iv_len = CCMP_HDR_LEN;
295 key->conf.icv_len = CCMP_MIC_LEN;
296 break;
297 }
284 memcpy(key->conf.key, key_data, key_len); 298 memcpy(key->conf.key, key_data, key_len);
285 INIT_LIST_HEAD(&key->list); 299 INIT_LIST_HEAD(&key->list);
286 INIT_LIST_HEAD(&key->todo); 300 INIT_LIST_HEAD(&key->todo);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d608c44047c0..ae62ad40ad63 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1015,6 +1015,10 @@ static int __init ieee80211_init(void)
1015 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + 1015 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
1016 IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); 1016 IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
1017 1017
1018 ret = rc80211_minstrel_init();
1019 if (ret)
1020 return ret;
1021
1018 ret = rc80211_pid_init(); 1022 ret = rc80211_pid_init();
1019 if (ret) 1023 if (ret)
1020 return ret; 1024 return ret;
@@ -1027,6 +1031,7 @@ static int __init ieee80211_init(void)
1027static void __exit ieee80211_exit(void) 1031static void __exit ieee80211_exit(void)
1028{ 1032{
1029 rc80211_pid_exit(); 1033 rc80211_pid_exit();
1034 rc80211_minstrel_exit();
1030 1035
1031 /* 1036 /*
1032 * For key todo, it'll be empty by now but the work 1037 * For key todo, it'll be empty by now but the work
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index e859a0ab6162..49f86fa56bff 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -650,20 +650,53 @@ static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata,
650static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata, 650static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
651 struct ieee80211_if_sta *ifsta) 651 struct ieee80211_if_sta *ifsta)
652{ 652{
653 char *buf;
654 size_t len;
655 int i;
653 union iwreq_data wrqu; 656 union iwreq_data wrqu;
654 657
658 if (!ifsta->assocreq_ies && !ifsta->assocresp_ies)
659 return;
660
661 buf = kmalloc(50 + 2 * (ifsta->assocreq_ies_len +
662 ifsta->assocresp_ies_len), GFP_KERNEL);
663 if (!buf)
664 return;
665
666 len = sprintf(buf, "ASSOCINFO(");
655 if (ifsta->assocreq_ies) { 667 if (ifsta->assocreq_ies) {
656 memset(&wrqu, 0, sizeof(wrqu)); 668 len += sprintf(buf + len, "ReqIEs=");
657 wrqu.data.length = ifsta->assocreq_ies_len; 669 for (i = 0; i < ifsta->assocreq_ies_len; i++) {
658 wireless_send_event(sdata->dev, IWEVASSOCREQIE, &wrqu, 670 len += sprintf(buf + len, "%02x",
659 ifsta->assocreq_ies); 671 ifsta->assocreq_ies[i]);
672 }
660 } 673 }
661 if (ifsta->assocresp_ies) { 674 if (ifsta->assocresp_ies) {
675 if (ifsta->assocreq_ies)
676 len += sprintf(buf + len, " ");
677 len += sprintf(buf + len, "RespIEs=");
678 for (i = 0; i < ifsta->assocresp_ies_len; i++) {
679 len += sprintf(buf + len, "%02x",
680 ifsta->assocresp_ies[i]);
681 }
682 }
683 len += sprintf(buf + len, ")");
684
685 if (len > IW_CUSTOM_MAX) {
686 len = sprintf(buf, "ASSOCRESPIE=");
687 for (i = 0; i < ifsta->assocresp_ies_len; i++) {
688 len += sprintf(buf + len, "%02x",
689 ifsta->assocresp_ies[i]);
690 }
691 }
692
693 if (len <= IW_CUSTOM_MAX) {
662 memset(&wrqu, 0, sizeof(wrqu)); 694 memset(&wrqu, 0, sizeof(wrqu));
663 wrqu.data.length = ifsta->assocresp_ies_len; 695 wrqu.data.length = len;
664 wireless_send_event(sdata->dev, IWEVASSOCRESPIE, &wrqu, 696 wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf);
665 ifsta->assocresp_ies);
666 } 697 }
698
699 kfree(buf);
667} 700}
668 701
669 702
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index eb94e584d24e..d0092f847f82 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -125,4 +125,18 @@ static inline void rc80211_pid_exit(void)
125} 125}
126#endif 126#endif
127 127
128#ifdef CONFIG_MAC80211_RC_MINSTREL
129extern int rc80211_minstrel_init(void);
130extern void rc80211_minstrel_exit(void);
131#else
132static inline int rc80211_minstrel_init(void)
133{
134 return 0;
135}
136static inline void rc80211_minstrel_exit(void)
137{
138}
139#endif
140
141
128#endif /* IEEE80211_RATE_H */ 142#endif /* IEEE80211_RATE_H */
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
new file mode 100644
index 000000000000..f6d69dab07a3
--- /dev/null
+++ b/net/mac80211/rc80211_minstrel.c
@@ -0,0 +1,583 @@
1/*
2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on minstrel.c:
9 * Copyright (C) 2005-2007 Derek Smithies <derek@indranet.co.nz>
10 * Sponsored by Indranet Technologies Ltd
11 *
12 * Based on sample.c:
13 * Copyright (c) 2005 John Bicket
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer,
21 * without modification.
22 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
23 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
24 * redistribution must be conditioned upon including a substantially
25 * similar Disclaimer requirement for further binary redistribution.
26 * 3. Neither the names of the above-listed copyright holders nor the names
27 * of any contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * Alternatively, this software may be distributed under the terms of the
31 * GNU General Public License ("GPL") version 2 as published by the Free
32 * Software Foundation.
33 *
34 * NO WARRANTY
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
38 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
39 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
40 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
43 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGES.
46 */
47#include <linux/netdevice.h>
48#include <linux/types.h>
49#include <linux/skbuff.h>
50#include <linux/debugfs.h>
51#include <linux/random.h>
52#include <linux/ieee80211.h>
53#include <net/mac80211.h>
54#include "rate.h"
55#include "rc80211_minstrel.h"
56
57#define SAMPLE_COLUMNS 10
58#define SAMPLE_TBL(_mi, _idx, _col) \
59 _mi->sample_table[(_idx * SAMPLE_COLUMNS) + _col]
60
61/* convert mac80211 rate index to local array index */
62static inline int
63rix_to_ndx(struct minstrel_sta_info *mi, int rix)
64{
65 int i = rix;
66 for (i = rix; i >= 0; i--)
67 if (mi->r[i].rix == rix)
68 break;
69 WARN_ON(mi->r[i].rix != rix);
70 return i;
71}
72
73static inline bool
74use_low_rate(struct sk_buff *skb)
75{
76 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
77 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
78 u16 fc;
79
80 fc = le16_to_cpu(hdr->frame_control);
81
82 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
83 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
84 is_multicast_ether_addr(hdr->addr1));
85}
86
87
88static void
89minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
90{
91 u32 max_tp = 0, index_max_tp = 0, index_max_tp2 = 0;
92 u32 max_prob = 0, index_max_prob = 0;
93 u32 usecs;
94 u32 p;
95 int i;
96
97 mi->stats_update = jiffies;
98 for (i = 0; i < mi->n_rates; i++) {
99 struct minstrel_rate *mr = &mi->r[i];
100
101 usecs = mr->perfect_tx_time;
102 if (!usecs)
103 usecs = 1000000;
104
105 /* To avoid rounding issues, probabilities scale from 0 (0%)
106 * to 18000 (100%) */
107 if (mr->attempts) {
108 p = (mr->success * 18000) / mr->attempts;
109 mr->succ_hist += mr->success;
110 mr->att_hist += mr->attempts;
111 mr->cur_prob = p;
112 p = ((p * (100 - mp->ewma_level)) + (mr->probability *
113 mp->ewma_level)) / 100;
114 mr->probability = p;
115 mr->cur_tp = p * (1000000 / usecs);
116 }
117
118 mr->last_success = mr->success;
119 mr->last_attempts = mr->attempts;
120 mr->success = 0;
121 mr->attempts = 0;
122
123 /* Sample less often below the 10% chance of success.
124 * Sample less often above the 95% chance of success. */
125 if ((mr->probability > 17100) || (mr->probability < 1800)) {
126 mr->adjusted_retry_count = mr->retry_count >> 1;
127 if (mr->adjusted_retry_count > 2)
128 mr->adjusted_retry_count = 2;
129 } else {
130 mr->adjusted_retry_count = mr->retry_count;
131 }
132 if (!mr->adjusted_retry_count)
133 mr->adjusted_retry_count = 2;
134 }
135
136 for (i = 0; i < mi->n_rates; i++) {
137 struct minstrel_rate *mr = &mi->r[i];
138 if (max_tp < mr->cur_tp) {
139 index_max_tp = i;
140 max_tp = mr->cur_tp;
141 }
142 if (max_prob < mr->probability) {
143 index_max_prob = i;
144 max_prob = mr->probability;
145 }
146 }
147
148 max_tp = 0;
149 for (i = 0; i < mi->n_rates; i++) {
150 struct minstrel_rate *mr = &mi->r[i];
151
152 if (i == index_max_tp)
153 continue;
154
155 if (max_tp < mr->cur_tp) {
156 index_max_tp2 = i;
157 max_tp = mr->cur_tp;
158 }
159 }
160 mi->max_tp_rate = index_max_tp;
161 mi->max_tp_rate2 = index_max_tp2;
162 mi->max_prob_rate = index_max_prob;
163}
164
165static void
166minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
167 struct ieee80211_sta *sta, void *priv_sta,
168 struct sk_buff *skb)
169{
170 struct minstrel_sta_info *mi = priv_sta;
171 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
172 struct ieee80211_tx_altrate *ar = info->status.retries;
173 struct minstrel_priv *mp = priv;
174 int i, ndx, tries;
175 int success = 0;
176
177 if (!info->status.excessive_retries)
178 success = 1;
179
180 if (!mp->has_mrr || (ar[0].rate_idx < 0)) {
181 ndx = rix_to_ndx(mi, info->tx_rate_idx);
182 tries = info->status.retry_count + 1;
183 mi->r[ndx].success += success;
184 mi->r[ndx].attempts += tries;
185 return;
186 }
187
188 for (i = 0; i < 4; i++) {
189 if (ar[i].rate_idx < 0)
190 break;
191
192 ndx = rix_to_ndx(mi, ar[i].rate_idx);
193 mi->r[ndx].attempts += ar[i].limit + 1;
194
195 if ((i != 3) && (ar[i + 1].rate_idx < 0))
196 mi->r[ndx].success += success;
197 }
198
199 if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
200 mi->sample_count++;
201
202 if (mi->sample_deferred > 0)
203 mi->sample_deferred--;
204}
205
206
207static inline unsigned int
208minstrel_get_retry_count(struct minstrel_rate *mr,
209 struct ieee80211_tx_info *info)
210{
211 unsigned int retry = mr->adjusted_retry_count;
212
213 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
214 retry = max(2U, min(mr->retry_count_rtscts, retry));
215 else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
216 retry = max(2U, min(mr->retry_count_cts, retry));
217 return retry;
218}
219
220
221static int
222minstrel_get_next_sample(struct minstrel_sta_info *mi)
223{
224 unsigned int sample_ndx;
225 sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column);
226 mi->sample_idx++;
227 if (mi->sample_idx > (mi->n_rates - 2)) {
228 mi->sample_idx = 0;
229 mi->sample_column++;
230 if (mi->sample_column >= SAMPLE_COLUMNS)
231 mi->sample_column = 0;
232 }
233 return sample_ndx;
234}
235
236void
237minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
238 struct ieee80211_sta *sta, void *priv_sta,
239 struct sk_buff *skb, struct rate_selection *sel)
240{
241 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
242 struct minstrel_sta_info *mi = priv_sta;
243 struct minstrel_priv *mp = priv;
244 struct ieee80211_tx_altrate *ar = info->control.retries;
245 unsigned int ndx, sample_ndx = 0;
246 bool mrr;
247 bool sample_slower = false;
248 bool sample = false;
249 int i, delta;
250 int mrr_ndx[3];
251 int sample_rate;
252
253 if (!sta || !mi || use_low_rate(skb)) {
254 sel->rate_idx = rate_lowest_index(sband, sta);
255 return;
256 }
257
258 mrr = mp->has_mrr;
259
260 /* mac80211 does not allow mrr for RTS/CTS */
261 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
262 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
263 mrr = false;
264
265 if (time_after(jiffies, mi->stats_update + (mp->update_interval *
266 HZ) / 1000))
267 minstrel_update_stats(mp, mi);
268
269 ndx = mi->max_tp_rate;
270
271 if (mrr)
272 sample_rate = mp->lookaround_rate_mrr;
273 else
274 sample_rate = mp->lookaround_rate;
275
276 mi->packet_count++;
277 delta = (mi->packet_count * sample_rate / 100) -
278 (mi->sample_count + mi->sample_deferred / 2);
279
280 /* delta > 0: sampling required */
281 if (delta > 0) {
282 if (mi->packet_count >= 10000) {
283 mi->sample_deferred = 0;
284 mi->sample_count = 0;
285 mi->packet_count = 0;
286 } else if (delta > mi->n_rates * 2) {
287 /* With multi-rate retry, not every planned sample
288 * attempt actually gets used, due to the way the retry
289 * chain is set up - [max_tp,sample,prob,lowest] for
290 * sample_rate < max_tp.
291 *
292 * If there's too much sampling backlog and the link
293 * starts getting worse, minstrel would start bursting
294 * out lots of sampling frames, which would result
295 * in a large throughput loss. */
296 mi->sample_count += (delta - mi->n_rates * 2);
297 }
298
299 sample_ndx = minstrel_get_next_sample(mi);
300 sample = true;
301 sample_slower = mrr && (mi->r[sample_ndx].perfect_tx_time >
302 mi->r[ndx].perfect_tx_time);
303
304 if (!sample_slower) {
305 ndx = sample_ndx;
306 mi->sample_count++;
307 } else {
308 /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
309 * packets that have the sampling rate deferred to the
310 * second MRR stage. Increase the sample counter only
311 * if the deferred sample rate was actually used.
312 * Use the sample_deferred counter to make sure that
313 * the sampling is not done in large bursts */
314 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
315 mi->sample_deferred++;
316 }
317 }
318 sel->rate_idx = mi->r[ndx].rix;
319 info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info);
320
321 if (!mrr) {
322 ar[0].rate_idx = mi->lowest_rix;
323 ar[0].limit = mp->max_retry;
324 ar[1].rate_idx = -1;
325 return;
326 }
327
328 /* MRR setup */
329 if (sample) {
330 if (sample_slower)
331 mrr_ndx[0] = sample_ndx;
332 else
333 mrr_ndx[0] = mi->max_tp_rate;
334 } else {
335 mrr_ndx[0] = mi->max_tp_rate2;
336 }
337 mrr_ndx[1] = mi->max_prob_rate;
338 mrr_ndx[2] = 0;
339 for (i = 0; i < 3; i++) {
340 ar[i].rate_idx = mi->r[mrr_ndx[i]].rix;
341 ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count;
342 }
343}
344
345
346static void
347calc_rate_durations(struct minstrel_sta_info *mi, struct ieee80211_local *local,
348 struct minstrel_rate *d, struct ieee80211_rate *rate)
349{
350 int erp = !!(rate->flags & IEEE80211_RATE_ERP_G);
351
352 d->perfect_tx_time = ieee80211_frame_duration(local, 1200,
353 rate->bitrate, erp, 1);
354 d->ack_time = ieee80211_frame_duration(local, 10,
355 rate->bitrate, erp, 1);
356}
357
358static void
359init_sample_table(struct minstrel_sta_info *mi)
360{
361 unsigned int i, col, new_idx;
362 unsigned int n_srates = mi->n_rates - 1;
363 u8 rnd[8];
364
365 mi->sample_column = 0;
366 mi->sample_idx = 0;
367 memset(mi->sample_table, 0, SAMPLE_COLUMNS * mi->n_rates);
368
369 for (col = 0; col < SAMPLE_COLUMNS; col++) {
370 for (i = 0; i < n_srates; i++) {
371 get_random_bytes(rnd, sizeof(rnd));
372 new_idx = (i + rnd[i & 7]) % n_srates;
373
374 while (SAMPLE_TBL(mi, new_idx, col) != 0)
375 new_idx = (new_idx + 1) % n_srates;
376
377 /* Don't sample the slowest rate (i.e. slowest base
378 * rate). We must presume that the slowest rate works
379 * fine, or else other management frames will also be
380 * failing and the link will break */
381 SAMPLE_TBL(mi, new_idx, col) = i + 1;
382 }
383 }
384}
385
386static void
387minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
388 struct ieee80211_sta *sta, void *priv_sta)
389{
390 struct minstrel_sta_info *mi = priv_sta;
391 struct minstrel_priv *mp = priv;
392 struct minstrel_rate *mr_ctl;
393 unsigned int i, n = 0;
394 unsigned int t_slot = 9; /* FIXME: get real slot time */
395
396 mi->lowest_rix = rate_lowest_index(sband, sta);
397 mr_ctl = &mi->r[rix_to_ndx(mi, mi->lowest_rix)];
398 mi->sp_ack_dur = mr_ctl->ack_time;
399
400 for (i = 0; i < sband->n_bitrates; i++) {
401 struct minstrel_rate *mr = &mi->r[n];
402 unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0;
403 unsigned int tx_time_single;
404 unsigned int cw = mp->cw_min;
405
406 if (!rate_supported(sta, sband->band, i))
407 continue;
408 n++;
409 memset(mr, 0, sizeof(*mr));
410
411 mr->rix = i;
412 mr->bitrate = sband->bitrates[i].bitrate / 5;
413 calc_rate_durations(mi, hw_to_local(mp->hw), mr,
414 &sband->bitrates[i]);
415
416 /* calculate maximum number of retransmissions before
417 * fallback (based on maximum segment size) */
418 mr->retry_count = 1;
419 mr->retry_count_cts = 1;
420 mr->retry_count_rtscts = 1;
421 tx_time = mr->perfect_tx_time + mi->sp_ack_dur;
422 do {
423 /* add one retransmission */
424 tx_time_single = mr->ack_time + mr->perfect_tx_time;
425
426 /* contention window */
427 tx_time_single += t_slot + min(cw, mp->cw_max);
428 cw = (cw + 1) << 1;
429
430 tx_time += tx_time_single;
431 tx_time_cts += tx_time_single + mi->sp_ack_dur;
432 tx_time_rtscts += tx_time_single + 2 * mi->sp_ack_dur;
433 if ((tx_time_cts < mp->segment_size) &&
434 (mr->retry_count_cts < mp->max_retry))
435 mr->retry_count_cts++;
436 if ((tx_time_rtscts < mp->segment_size) &&
437 (mr->retry_count_rtscts < mp->max_retry))
438 mr->retry_count_rtscts++;
439 } while ((tx_time < mp->segment_size) &&
440 (++mr->retry_count < mp->max_retry));
441 mr->adjusted_retry_count = mr->retry_count;
442 }
443
444 for (i = n; i < sband->n_bitrates; i++) {
445 struct minstrel_rate *mr = &mi->r[i];
446 mr->rix = -1;
447 }
448
449 mi->n_rates = n;
450 mi->stats_update = jiffies;
451
452 init_sample_table(mi);
453}
454
455static void *
456minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
457{
458 struct ieee80211_supported_band *sband;
459 struct minstrel_sta_info *mi;
460 struct minstrel_priv *mp = priv;
461 struct ieee80211_hw *hw = mp->hw;
462 int max_rates = 0;
463 int i;
464
465 mi = kzalloc(sizeof(struct minstrel_sta_info), gfp);
466 if (!mi)
467 return NULL;
468
469 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
470 sband = hw->wiphy->bands[hw->conf.channel->band];
471 if (sband->n_bitrates > max_rates)
472 max_rates = sband->n_bitrates;
473 }
474
475 mi->r = kzalloc(sizeof(struct minstrel_rate) * max_rates, gfp);
476 if (!mi->r)
477 goto error;
478
479 mi->sample_table = kmalloc(SAMPLE_COLUMNS * max_rates, gfp);
480 if (!mi->sample_table)
481 goto error1;
482
483 mi->stats_update = jiffies;
484 return mi;
485
486error1:
487 kfree(mi->r);
488error:
489 kfree(mi);
490 return NULL;
491}
492
493static void
494minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
495{
496 struct minstrel_sta_info *mi = priv_sta;
497
498 kfree(mi->sample_table);
499 kfree(mi->r);
500 kfree(mi);
501}
502
503static void
504minstrel_clear(void *priv)
505{
506}
507
508static void *
509minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
510{
511 struct minstrel_priv *mp;
512
513 mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC);
514 if (!mp)
515 return NULL;
516
517 /* contention window settings
518 * Just an approximation. Using the per-queue values would complicate
519 * the calculations and is probably unnecessary */
520 mp->cw_min = 15;
521 mp->cw_max = 1023;
522
523 /* number of packets (in %) to use for sampling other rates
524 * sample less often for non-mrr packets, because the overhead
525 * is much higher than with mrr */
526 mp->lookaround_rate = 5;
527 mp->lookaround_rate_mrr = 10;
528
529 /* moving average weight for EWMA */
530 mp->ewma_level = 75;
531
532 /* maximum time that the hw is allowed to stay in one MRR segment */
533 mp->segment_size = 6000;
534
535 if (hw->max_altrate_tries > 0)
536 mp->max_retry = hw->max_altrate_tries;
537 else
538 /* safe default, does not necessarily have to match hw properties */
539 mp->max_retry = 7;
540
541 if (hw->max_altrates >= 3)
542 mp->has_mrr = true;
543
544 mp->hw = hw;
545 mp->update_interval = 100;
546
547 return mp;
548}
549
550static void
551minstrel_free(void *priv)
552{
553 kfree(priv);
554}
555
556static struct rate_control_ops mac80211_minstrel = {
557 .name = "minstrel",
558 .tx_status = minstrel_tx_status,
559 .get_rate = minstrel_get_rate,
560 .rate_init = minstrel_rate_init,
561 .clear = minstrel_clear,
562 .alloc = minstrel_alloc,
563 .free = minstrel_free,
564 .alloc_sta = minstrel_alloc_sta,
565 .free_sta = minstrel_free_sta,
566#ifdef CONFIG_MAC80211_DEBUGFS
567 .add_sta_debugfs = minstrel_add_sta_debugfs,
568 .remove_sta_debugfs = minstrel_remove_sta_debugfs,
569#endif
570};
571
572int __init
573rc80211_minstrel_init(void)
574{
575 return ieee80211_rate_control_register(&mac80211_minstrel);
576}
577
578void
579rc80211_minstrel_exit(void)
580{
581 ieee80211_rate_control_unregister(&mac80211_minstrel);
582}
583
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
new file mode 100644
index 000000000000..9a90a6aee043
--- /dev/null
+++ b/net/mac80211/rc80211_minstrel.h
@@ -0,0 +1,85 @@
1/*
2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __RC_MINSTREL_H
10#define __RC_MINSTREL_H
11
12struct minstrel_rate {
13 int bitrate;
14 int rix;
15
16 unsigned int perfect_tx_time;
17 unsigned int ack_time;
18
19 unsigned int retry_count;
20 unsigned int retry_count_cts;
21 unsigned int retry_count_rtscts;
22 unsigned int adjusted_retry_count;
23
24 u32 success;
25 u32 attempts;
26 u32 last_attempts;
27 u32 last_success;
28
29 /* parts per thousand */
30 u32 cur_prob;
31 u32 probability;
32
33 /* per-rate throughput */
34 u32 cur_tp;
35 u32 throughput;
36
37 u64 succ_hist;
38 u64 att_hist;
39};
40
41struct minstrel_sta_info {
42 unsigned long stats_update;
43 unsigned int sp_ack_dur;
44 unsigned int rate_avg;
45
46 unsigned int lowest_rix;
47
48 unsigned int max_tp_rate;
49 unsigned int max_tp_rate2;
50 unsigned int max_prob_rate;
51 unsigned int packet_count;
52 unsigned int sample_count;
53 int sample_deferred;
54
55 unsigned int sample_idx;
56 unsigned int sample_column;
57
58 int n_rates;
59 struct minstrel_rate *r;
60
61 /* sampling table */
62 u8 *sample_table;
63
64#ifdef CONFIG_MAC80211_DEBUGFS
65 struct dentry *dbg_stats;
66#endif
67};
68
69struct minstrel_priv {
70 struct ieee80211_hw *hw;
71 bool has_mrr;
72 unsigned int cw_min;
73 unsigned int cw_max;
74 unsigned int max_retry;
75 unsigned int ewma_level;
76 unsigned int segment_size;
77 unsigned int update_interval;
78 unsigned int lookaround_rate;
79 unsigned int lookaround_rate_mrr;
80};
81
82void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
83void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
84
85#endif
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
new file mode 100644
index 000000000000..0b024cd6b809
--- /dev/null
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -0,0 +1,164 @@
1/*
2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on minstrel.c:
9 * Copyright (C) 2005-2007 Derek Smithies <derek@indranet.co.nz>
10 * Sponsored by Indranet Technologies Ltd
11 *
12 * Based on sample.c:
13 * Copyright (c) 2005 John Bicket
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer,
21 * without modification.
22 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
23 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
24 * redistribution must be conditioned upon including a substantially
25 * similar Disclaimer requirement for further binary redistribution.
26 * 3. Neither the names of the above-listed copyright holders nor the names
27 * of any contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * Alternatively, this software may be distributed under the terms of the
31 * GNU General Public License ("GPL") version 2 as published by the Free
32 * Software Foundation.
33 *
34 * NO WARRANTY
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
38 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
39 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
40 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
43 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGES.
46 */
47#include <linux/netdevice.h>
48#include <linux/types.h>
49#include <linux/skbuff.h>
50#include <linux/debugfs.h>
51#include <linux/ieee80211.h>
52#include <net/mac80211.h>
53#include "rc80211_minstrel.h"
54
55struct minstrel_stats_info {
56 struct minstrel_sta_info *mi;
57 char buf[4096];
58 size_t len;
59};
60
61static int
62minstrel_stats_open(struct inode *inode, struct file *file)
63{
64 struct minstrel_sta_info *mi = inode->i_private;
65 struct minstrel_stats_info *ms;
66 unsigned int i, tp, prob, eprob;
67 char *p;
68
69 ms = kmalloc(sizeof(*ms), GFP_KERNEL);
70 if (!ms)
71 return -ENOMEM;
72
73 file->private_data = ms;
74 p = ms->buf;
75 p += sprintf(p, "rate throughput ewma prob this prob "
76 "this succ/attempt success attempts\n");
77 for (i = 0; i < mi->n_rates; i++) {
78 struct minstrel_rate *mr = &mi->r[i];
79
80 *(p++) = (i == mi->max_tp_rate) ? 'T' : ' ';
81 *(p++) = (i == mi->max_tp_rate2) ? 't' : ' ';
82 *(p++) = (i == mi->max_prob_rate) ? 'P' : ' ';
83 p += sprintf(p, "%3u%s", mr->bitrate / 2,
84 (mr->bitrate & 1 ? ".5" : " "));
85
86 tp = ((mr->cur_tp * 96) / 18000) >> 10;
87 prob = mr->cur_prob / 18;
88 eprob = mr->probability / 18;
89
90 p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u "
91 "%3u(%3u) %8llu %8llu\n",
92 tp / 10, tp % 10,
93 eprob / 10, eprob % 10,
94 prob / 10, prob % 10,
95 mr->last_success,
96 mr->last_attempts,
97 mr->succ_hist,
98 mr->att_hist);
99 }
100 p += sprintf(p, "\nTotal packet count:: ideal %d "
101 "lookaround %d\n\n",
102 mi->packet_count - mi->sample_count,
103 mi->sample_count);
104 ms->len = p - ms->buf;
105
106 return 0;
107}
108
109static int
110minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o)
111{
112 struct minstrel_stats_info *ms;
113 char *src;
114
115 ms = file->private_data;
116 src = ms->buf;
117
118 len = min(len, ms->len);
119 if (len <= *o)
120 return 0;
121
122 src += *o;
123 len -= *o;
124 *o += len;
125
126 if (copy_to_user(buf, src, len))
127 return -EFAULT;
128
129 return len;
130}
131
132static int
133minstrel_stats_release(struct inode *inode, struct file *file)
134{
135 struct minstrel_stats_info *ms = file->private_data;
136
137 kfree(ms);
138
139 return 0;
140}
141
142static struct file_operations minstrel_stat_fops = {
143 .owner = THIS_MODULE,
144 .open = minstrel_stats_open,
145 .read = minstrel_stats_read,
146 .release = minstrel_stats_release,
147};
148
149void
150minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir)
151{
152 struct minstrel_sta_info *mi = priv_sta;
153
154 mi->dbg_stats = debugfs_create_file("rc_stats", S_IRUGO, dir, mi,
155 &minstrel_stat_fops);
156}
157
158void
159minstrel_remove_sta_debugfs(void *priv, void *priv_sta)
160{
161 struct minstrel_sta_info *mi = priv_sta;
162
163 debugfs_remove(mi->dbg_stats);
164}
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 0cc2e23f082c..1460537faf33 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -454,15 +454,16 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
454 if (unlikely(rsel.probe_idx >= 0)) { 454 if (unlikely(rsel.probe_idx >= 0)) {
455 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 455 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
456 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; 456 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
457 info->control.alt_retry_rate_idx = tx->rate_idx; 457 info->control.retries[0].rate_idx = tx->rate_idx;
458 info->control.retries[0].limit = tx->local->hw.max_altrate_tries;
458 tx->rate_idx = rsel.probe_idx; 459 tx->rate_idx = rsel.probe_idx;
459 } else 460 } else if (info->control.retries[0].limit == 0)
460 info->control.alt_retry_rate_idx = -1; 461 info->control.retries[0].rate_idx = -1;
461 462
462 if (unlikely(tx->rate_idx < 0)) 463 if (unlikely(tx->rate_idx < 0))
463 return TX_DROP; 464 return TX_DROP;
464 } else 465 } else
465 info->control.alt_retry_rate_idx = -1; 466 info->control.retries[0].rate_idx = -1;
466 467
467 if (tx->sdata->bss_conf.use_cts_prot && 468 if (tx->sdata->bss_conf.use_cts_prot &&
468 (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { 469 (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
@@ -521,7 +522,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
521 * frames. 522 * frames.
522 * TODO: The last fragment could still use multiple retry 523 * TODO: The last fragment could still use multiple retry
523 * rates. */ 524 * rates. */
524 info->control.alt_retry_rate_idx = -1; 525 info->control.retries[0].rate_idx = -1;
525 } 526 }
526 527
527 /* Use CTS protection for unicast frames sent using extended rates if 528 /* Use CTS protection for unicast frames sent using extended rates if
@@ -551,7 +552,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
551 int idx; 552 int idx;
552 553
553 /* Do not use multiple retry rates when using RTS/CTS */ 554 /* Do not use multiple retry rates when using RTS/CTS */
554 info->control.alt_retry_rate_idx = -1; 555 info->control.retries[0].rate_idx = -1;
555 556
556 /* Use min(data rate, max base rate) as CTS/RTS rate */ 557 /* Use min(data rate, max base rate) as CTS/RTS rate */
557 rate = &sband->bitrates[tx->rate_idx]; 558 rate = &sband->bitrates[tx->rate_idx];
@@ -1255,8 +1256,7 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
1255 return 0; 1256 return 0;
1256} 1257}
1257 1258
1258int ieee80211_master_start_xmit(struct sk_buff *skb, 1259int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1259 struct net_device *dev)
1260{ 1260{
1261 struct ieee80211_master_priv *mpriv = netdev_priv(dev); 1261 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
1262 struct ieee80211_local *local = mpriv->local; 1262 struct ieee80211_local *local = mpriv->local;
@@ -1296,20 +1296,16 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1296 1296
1297 if (ieee80211_vif_is_mesh(&osdata->vif) && 1297 if (ieee80211_vif_is_mesh(&osdata->vif) &&
1298 ieee80211_is_data(hdr->frame_control)) { 1298 ieee80211_is_data(hdr->frame_control)) {
1299 if (ieee80211_is_data(hdr->frame_control)) { 1299 if (is_multicast_ether_addr(hdr->addr3))
1300 if (is_multicast_ether_addr(hdr->addr3)) 1300 memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
1301 memcpy(hdr->addr1, hdr->addr3, ETH_ALEN); 1301 else
1302 else 1302 if (mesh_nexthop_lookup(skb, osdata))
1303 if (mesh_nexthop_lookup(skb, osdata)) 1303 return 0;
1304 return 0; 1304 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
1305 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0) 1305 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
1306 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh, 1306 fwded_frames);
1307 fwded_frames);
1308 }
1309 } else if (unlikely(osdata->vif.type == NL80211_IFTYPE_MONITOR)) { 1307 } else if (unlikely(osdata->vif.type == NL80211_IFTYPE_MONITOR)) {
1310 struct ieee80211_sub_if_data *sdata; 1308 struct ieee80211_sub_if_data *sdata;
1311 struct ieee80211_local *local = osdata->local;
1312 struct ieee80211_hdr *hdr;
1313 int hdrlen; 1309 int hdrlen;
1314 u16 len_rthdr; 1310 u16 len_rthdr;
1315 1311
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 376c84987e4f..f0e2d3ecb5c4 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -313,9 +313,6 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
313{ 313{
314 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 314 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
315 315
316 info->control.iv_len = WEP_IV_LEN;
317 info->control.icv_len = WEP_ICV_LEN;
318
319 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { 316 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
320 if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) 317 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
321 return -1; 318 return -1;
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 37ae9a959f63..6db649480e8f 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -152,9 +152,6 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
152 int len, tail; 152 int len, tail;
153 u8 *pos; 153 u8 *pos;
154 154
155 info->control.icv_len = TKIP_ICV_LEN;
156 info->control.iv_len = TKIP_IV_LEN;
157
158 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 155 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
159 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 156 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
160 /* hwaccel - with no need for preallocated room for IV/ICV */ 157 /* hwaccel - with no need for preallocated room for IV/ICV */
@@ -374,9 +371,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
374 u8 *pos, *pn; 371 u8 *pos, *pn;
375 int i; 372 int i;
376 373
377 info->control.icv_len = CCMP_MIC_LEN;
378 info->control.iv_len = CCMP_HDR_LEN;
379
380 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 374 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
381 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 375 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
382 /* hwaccel - with no need for preallocated room for CCMP " 376 /* hwaccel - with no need for preallocated room for CCMP "
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index ea0dc04b3c77..f949a482b007 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -125,6 +125,7 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
125 125
126static void notify_rfkill_state_change(struct rfkill *rfkill) 126static void notify_rfkill_state_change(struct rfkill *rfkill)
127{ 127{
128 rfkill_led_trigger(rfkill, rfkill->state);
128 blocking_notifier_call_chain(&rfkill_notifier_list, 129 blocking_notifier_call_chain(&rfkill_notifier_list,
129 RFKILL_STATE_CHANGED, 130 RFKILL_STATE_CHANGED,
130 rfkill); 131 rfkill);
@@ -217,10 +218,8 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
217 rfkill->state = state; 218 rfkill->state = state;
218 } 219 }
219 220
220 if (force || rfkill->state != oldstate) { 221 if (force || rfkill->state != oldstate)
221 rfkill_led_trigger(rfkill, rfkill->state);
222 notify_rfkill_state_change(rfkill); 222 notify_rfkill_state_change(rfkill);
223 }
224 223
225 return retval; 224 return retval;
226} 225}
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index b97bd9fe6b79..7d82be07fa1d 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -15,7 +15,7 @@ config NL80211
15 If unsure, say Y. 15 If unsure, say Y.
16 16
17config WIRELESS_OLD_REGULATORY 17config WIRELESS_OLD_REGULATORY
18 bool "Old wireless static regulatory defintions" 18 bool "Old wireless static regulatory definitions"
19 default n 19 default n
20 ---help--- 20 ---help---
21 This option enables the old static regulatory information 21 This option enables the old static regulatory information