aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-07-30 22:26:55 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-30 22:26:55 -0400
commit2f6d7c1b34403b97fa57473edcb6749d1db5ace3 (patch)
tree97da33c077b08b72a361ff5a4542b86d190b0164
parentdf597efb5737063497f1a4f7c996cc9aec294230 (diff)
parent1e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig4
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c85
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h54
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c1203
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h163
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c133
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h1516
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c85
-rw-r--r--drivers/net/wireless/ath/regd_common.h2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c77
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-led.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c45
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c59
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c85
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c23
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-calib.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c35
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c84
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h116
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c63
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.c526
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-power.h93
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c100
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c20
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Makefile2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/netdev.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/wext.c187
-rw-r--r--drivers/net/wireless/p54/txrx.c2
-rw-r--r--drivers/net/wireless/ray_cs.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00lib.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c2
-rw-r--r--include/linux/ieee80211.h25
-rw-r--r--include/linux/nl80211.h9
-rw-r--r--include/net/cfg80211.h104
-rw-r--r--include/net/mac80211.h4
-rw-r--r--net/core/dev.c1
-rw-r--r--net/mac80211/Kconfig1
-rw-r--r--net/mac80211/Makefile1
-rw-r--r--net/mac80211/cfg.c14
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/ieee80211_i.h45
-rw-r--r--net/mac80211/iface.c22
-rw-r--r--net/mac80211/main.c3
-rw-r--r--net/mac80211/mesh.c2
-rw-r--r--net/mac80211/mlme.c35
-rw-r--r--net/mac80211/rx.c21
-rw-r--r--net/mac80211/scan.c304
-rw-r--r--net/mac80211/sta_info.h13
-rw-r--r--net/mac80211/tx.c109
-rw-r--r--net/mac80211/util.c13
-rw-r--r--net/mac80211/wext.c235
-rw-r--r--net/wireless/core.c78
-rw-r--r--net/wireless/core.h8
-rw-r--r--net/wireless/ibss.c13
-rw-r--r--net/wireless/mlme.c8
-rw-r--r--net/wireless/nl80211.c206
-rw-r--r--net/wireless/scan.c25
-rw-r--r--net/wireless/sme.c5
-rw-r--r--net/wireless/wext-compat.c180
-rw-r--r--net/wireless/wext-compat.h50
-rw-r--r--net/wireless/wext-sme.c13
82 files changed, 5381 insertions, 1159 deletions
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index c7287a883a48..85a1452a7c3c 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -1293,7 +1293,9 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1293 flush_workqueue(ar->hw->workqueue); 1293 flush_workqueue(ar->hw->workqueue);
1294 1294
1295 cancel_delayed_work_sync(&ar->tx_janitor); 1295 cancel_delayed_work_sync(&ar->tx_janitor);
1296#ifdef CONFIG_AR9170_LEDS
1296 cancel_delayed_work_sync(&ar->led_work); 1297 cancel_delayed_work_sync(&ar->led_work);
1298#endif
1297 cancel_work_sync(&ar->filter_config_work); 1299 cancel_work_sync(&ar->filter_config_work);
1298 cancel_work_sync(&ar->beacon_work); 1300 cancel_work_sync(&ar->beacon_work);
1299 mutex_lock(&ar->mutex); 1301 mutex_lock(&ar->mutex);
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 2d79610bce12..0f4a6d862d3a 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -18,6 +18,6 @@ config ATH9K_DEBUG
18 Say Y, if you need ath9k to display debug messages. 18 Say Y, if you need ath9k to display debug messages.
19 Pass the debug mask as a module parameter: 19 Pass the debug mask as a module parameter:
20 20
21 modprobe ath9k debug=0x00002000 21 modprobe ath9k debug=0x00000200
22 22
23 Look in ath9k/core.h for possible debug masks 23 Look in ath9k/debug.h for possible debug masks
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 751885a5df47..bda0f302340c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -190,12 +190,9 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
190#define ATH_AGGR_MIN_QDEPTH 2 190#define ATH_AGGR_MIN_QDEPTH 2
191#define ATH_AMPDU_SUBFRAME_DEFAULT 32 191#define ATH_AMPDU_SUBFRAME_DEFAULT 32
192#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1) 192#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
193#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
194 193
195#define IEEE80211_SEQ_SEQ_SHIFT 4 194#define IEEE80211_SEQ_SEQ_SHIFT 4
196#define IEEE80211_SEQ_MAX 4096 195#define IEEE80211_SEQ_MAX 4096
197#define IEEE80211_MIN_AMPDU_BUF 0x8
198#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
199#define IEEE80211_WEP_IVLEN 3 196#define IEEE80211_WEP_IVLEN 3
200#define IEEE80211_WEP_KIDLEN 1 197#define IEEE80211_WEP_KIDLEN 1
201#define IEEE80211_WEP_CRCLEN 4 198#define IEEE80211_WEP_CRCLEN 4
@@ -240,7 +237,6 @@ struct ath_txq {
240 spinlock_t axq_lock; 237 spinlock_t axq_lock;
241 u32 axq_depth; 238 u32 axq_depth;
242 u8 axq_aggr_depth; 239 u8 axq_aggr_depth;
243 u32 axq_totalqueued;
244 bool stopped; 240 bool stopped;
245 bool axq_tx_inprogress; 241 bool axq_tx_inprogress;
246 struct ath_buf *axq_linkbuf; 242 struct ath_buf *axq_linkbuf;
@@ -365,9 +361,9 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
365void ath_tx_tasklet(struct ath_softc *sc); 361void ath_tx_tasklet(struct ath_softc *sc);
366void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); 362void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
367bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); 363bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
368int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, 364void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
369 u16 tid, u16 *ssn); 365 u16 tid, u16 *ssn);
370int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 366void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
371void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); 367void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid);
372 368
373/********/ 369/********/
@@ -576,6 +572,7 @@ struct ath_softc {
576 u32 keymax; 572 u32 keymax;
577 DECLARE_BITMAP(keymap, ATH_KEYMAX); 573 DECLARE_BITMAP(keymap, ATH_KEYMAX);
578 u8 splitmic; 574 u8 splitmic;
575 bool ps_enabled;
579 unsigned long ps_usecount; 576 unsigned long ps_usecount;
580 enum ath9k_int imask; 577 enum ath9k_int imask;
581 enum ath9k_ht_extprotspacing ht_extprotspacing; 578 enum ath9k_ht_extprotspacing ht_extprotspacing;
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 1f0c5fe4a68b..d1bbb02af8de 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -116,7 +116,7 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
116 "NF calibrated [ctl] [chain 1] is %d\n", nf); 116 "NF calibrated [ctl] [chain 1] is %d\n", nf);
117 nfarray[1] = nf; 117 nfarray[1] = nf;
118 118
119 if (!AR_SREV_9280(ah)) { 119 if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
120 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), 120 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
121 AR_PHY_CH2_MINCCA_PWR); 121 AR_PHY_CH2_MINCCA_PWR);
122 if (nf & 0x100) 122 if (nf & 0x100)
@@ -154,7 +154,7 @@ static void ath9k_hw_do_getnf(struct ath_hw *ah,
154 "NF calibrated [ext] [chain 1] is %d\n", nf); 154 "NF calibrated [ext] [chain 1] is %d\n", nf);
155 nfarray[4] = nf; 155 nfarray[4] = nf;
156 156
157 if (!AR_SREV_9280(ah)) { 157 if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) {
158 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), 158 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
159 AR_PHY_CH2_EXT_MINCCA_PWR); 159 AR_PHY_CH2_EXT_MINCCA_PWR);
160 if (nf & 0x100) 160 if (nf & 0x100)
@@ -613,7 +613,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
613 613
614 if (AR_SREV_9285(ah)) 614 if (AR_SREV_9285(ah))
615 chainmask = 0x9; 615 chainmask = 0x9;
616 else if (AR_SREV_9280(ah)) 616 else if (AR_SREV_9280(ah) || AR_SREV_9287(ah))
617 chainmask = 0x1B; 617 chainmask = 0x1B;
618 else 618 else
619 chainmask = 0x3F; 619 chainmask = 0x3F;
@@ -873,7 +873,7 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
873 if (AR_SREV_9285_11_OR_LATER(ah)) 873 if (AR_SREV_9285_11_OR_LATER(ah))
874 ath9k_hw_9285_pa_cal(ah); 874 ath9k_hw_9285_pa_cal(ah);
875 875
876 if (OLC_FOR_AR9280_20_LATER) 876 if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
877 ath9k_olc_temp_compensation(ah); 877 ath9k_olc_temp_compensation(ah);
878 ath9k_hw_getnf(ah, chan); 878 ath9k_hw_getnf(ah, chan);
879 ath9k_hw_loadnf(ah, ah->curchan); 879 ath9k_hw_loadnf(ah, ah->curchan);
@@ -929,8 +929,11 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
929 return false; 929 return false;
930 } else { 930 } else {
931 if (AR_SREV_9280_10_OR_LATER(ah)) { 931 if (AR_SREV_9280_10_OR_LATER(ah)) {
932 REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); 932 if (!AR_SREV_9287_10_OR_LATER(ah))
933 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); 933 REG_CLR_BIT(ah, AR_PHY_ADC_CTL,
934 AR_PHY_ADC_CTL_OFF_PWDADC);
935 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
936 AR_PHY_AGC_CONTROL_FLTR_CAL);
934 } 937 }
935 938
936 /* Calibrate the AGC */ 939 /* Calibrate the AGC */
@@ -948,8 +951,11 @@ bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
948 } 951 }
949 952
950 if (AR_SREV_9280_10_OR_LATER(ah)) { 953 if (AR_SREV_9280_10_OR_LATER(ah)) {
951 REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); 954 if (!AR_SREV_9287_10_OR_LATER(ah))
952 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); 955 REG_SET_BIT(ah, AR_PHY_ADC_CTL,
956 AR_PHY_ADC_CTL_OFF_PWDADC);
957 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
958 AR_PHY_AGC_CONTROL_FLTR_CAL);
953 } 959 }
954 } 960 }
955 961
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 9f99f00c1447..9e369208f7dc 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -486,6 +486,83 @@ static const struct file_operations fops_wiphy = {
486 .owner = THIS_MODULE 486 .owner = THIS_MODULE
487}; 487};
488 488
489#define PR(str, elem) \
490 do { \
491 len += snprintf(buf + len, size - len, \
492 "%s%13u%11u%10u%10u\n", str, \
493 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \
494 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \
495 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \
496 sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \
497} while(0)
498
499static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
500 size_t count, loff_t *ppos)
501{
502 struct ath_softc *sc = file->private_data;
503 char *buf;
504 unsigned int len = 0, size = 2048;
505 ssize_t retval = 0;
506
507 buf = kzalloc(size, GFP_KERNEL);
508 if (buf == NULL)
509 return 0;
510
511 len += sprintf(buf, "%30s %10s%10s%10s\n\n", "BE", "BK", "VI", "VO");
512
513 PR("MPDUs Queued: ", queued);
514 PR("MPDUs Completed: ", completed);
515 PR("Aggregates: ", a_aggr);
516 PR("AMPDUs Queued: ", a_queued);
517 PR("AMPDUs Completed:", a_completed);
518 PR("AMPDUs Retried: ", a_retries);
519 PR("AMPDUs XRetried: ", a_xretries);
520 PR("FIFO Underrun: ", fifo_underrun);
521 PR("TXOP Exceeded: ", xtxop);
522 PR("TXTIMER Expiry: ", timer_exp);
523 PR("DESC CFG Error: ", desc_cfg_err);
524 PR("DATA Underrun: ", data_underrun);
525 PR("DELIM Underrun: ", delim_underrun);
526
527 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
528 kfree(buf);
529
530 return retval;
531}
532
533void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
534 struct ath_buf *bf)
535{
536 struct ath_desc *ds = bf->bf_desc;
537
538 if (bf_isampdu(bf)) {
539 if (bf_isxretried(bf))
540 TX_STAT_INC(txq->axq_qnum, a_xretries);
541 else
542 TX_STAT_INC(txq->axq_qnum, a_completed);
543 } else {
544 TX_STAT_INC(txq->axq_qnum, completed);
545 }
546
547 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)
548 TX_STAT_INC(txq->axq_qnum, fifo_underrun);
549 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP)
550 TX_STAT_INC(txq->axq_qnum, xtxop);
551 if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED)
552 TX_STAT_INC(txq->axq_qnum, timer_exp);
553 if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR)
554 TX_STAT_INC(txq->axq_qnum, desc_cfg_err);
555 if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN)
556 TX_STAT_INC(txq->axq_qnum, data_underrun);
557 if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN)
558 TX_STAT_INC(txq->axq_qnum, delim_underrun);
559}
560
561static const struct file_operations fops_xmit = {
562 .read = read_file_xmit,
563 .open = ath9k_debugfs_open,
564 .owner = THIS_MODULE
565};
489 566
490int ath9k_init_debug(struct ath_softc *sc) 567int ath9k_init_debug(struct ath_softc *sc)
491{ 568{
@@ -529,6 +606,13 @@ int ath9k_init_debug(struct ath_softc *sc)
529 if (!sc->debug.debugfs_wiphy) 606 if (!sc->debug.debugfs_wiphy)
530 goto err; 607 goto err;
531 608
609 sc->debug.debugfs_xmit = debugfs_create_file("xmit",
610 S_IRUSR,
611 sc->debug.debugfs_phy,
612 sc, &fops_xmit);
613 if (!sc->debug.debugfs_xmit)
614 goto err;
615
532 return 0; 616 return 0;
533err: 617err:
534 ath9k_exit_debug(sc); 618 ath9k_exit_debug(sc);
@@ -537,6 +621,7 @@ err:
537 621
538void ath9k_exit_debug(struct ath_softc *sc) 622void ath9k_exit_debug(struct ath_softc *sc)
539{ 623{
624 debugfs_remove(sc->debug.debugfs_xmit);
540 debugfs_remove(sc->debug.debugfs_wiphy); 625 debugfs_remove(sc->debug.debugfs_wiphy);
541 debugfs_remove(sc->debug.debugfs_rcstat); 626 debugfs_remove(sc->debug.debugfs_rcstat);
542 debugfs_remove(sc->debug.debugfs_interrupt); 627 debugfs_remove(sc->debug.debugfs_interrupt);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index edda15bf2c15..5e56b79d0cb0 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -35,6 +35,15 @@ enum ATH_DEBUG {
35 35
36#define DBG_DEFAULT (ATH_DBG_FATAL) 36#define DBG_DEFAULT (ATH_DBG_FATAL)
37 37
38struct ath_txq;
39struct ath_buf;
40
41#ifdef CONFIG_ATH9K_DEBUG
42#define TX_STAT_INC(q, c) sc->debug.stats.txstats[q].c++
43#else
44#define TX_STAT_INC(q, c) do { } while (0)
45#endif
46
38#ifdef CONFIG_ATH9K_DEBUG 47#ifdef CONFIG_ATH9K_DEBUG
39 48
40/** 49/**
@@ -87,9 +96,45 @@ struct ath_rc_stats {
87 u8 per; 96 u8 per;
88}; 97};
89 98
99/**
100 * struct ath_tx_stats - Statistics about TX
101 * @queued: Total MPDUs (non-aggr) queued
102 * @completed: Total MPDUs (non-aggr) completed
103 * @a_aggr: Total no. of aggregates queued
104 * @a_queued: Total AMPDUs queued
105 * @a_completed: Total AMPDUs completed
106 * @a_retries: No. of AMPDUs retried (SW)
107 * @a_xretries: No. of AMPDUs dropped due to xretries
108 * @fifo_underrun: FIFO underrun occurrences
109 Valid only for:
110 - non-aggregate condition.
111 - first packet of aggregate.
112 * @xtxop: No. of frames filtered because of TXOP limit
113 * @timer_exp: Transmit timer expiry
114 * @desc_cfg_err: Descriptor configuration errors
115 * @data_urn: TX data underrun errors
116 * @delim_urn: TX delimiter underrun errors
117 */
118struct ath_tx_stats {
119 u32 queued;
120 u32 completed;
121 u32 a_aggr;
122 u32 a_queued;
123 u32 a_completed;
124 u32 a_retries;
125 u32 a_xretries;
126 u32 fifo_underrun;
127 u32 xtxop;
128 u32 timer_exp;
129 u32 desc_cfg_err;
130 u32 data_underrun;
131 u32 delim_underrun;
132};
133
90struct ath_stats { 134struct ath_stats {
91 struct ath_interrupt_stats istats; 135 struct ath_interrupt_stats istats;
92 struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; 136 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
137 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
93}; 138};
94 139
95struct ath9k_debug { 140struct ath9k_debug {
@@ -100,6 +145,7 @@ struct ath9k_debug {
100 struct dentry *debugfs_interrupt; 145 struct dentry *debugfs_interrupt;
101 struct dentry *debugfs_rcstat; 146 struct dentry *debugfs_rcstat;
102 struct dentry *debugfs_wiphy; 147 struct dentry *debugfs_wiphy;
148 struct dentry *debugfs_xmit;
103 struct ath_stats stats; 149 struct ath_stats stats;
104}; 150};
105 151
@@ -110,6 +156,8 @@ int ath9k_debug_create_root(void);
110void ath9k_debug_remove_root(void); 156void ath9k_debug_remove_root(void);
111void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); 157void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
112void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); 158void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb);
159void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
160 struct ath_buf *bf);
113void ath_debug_stat_retries(struct ath_softc *sc, int rix, 161void ath_debug_stat_retries(struct ath_softc *sc, int rix,
114 int xretries, int retries, u8 per); 162 int xretries, int retries, u8 per);
115 163
@@ -148,6 +196,12 @@ static inline void ath_debug_stat_rc(struct ath_softc *sc,
148{ 196{
149} 197}
150 198
199static inline void ath_debug_stat_tx(struct ath_softc *sc,
200 struct ath_txq *txq,
201 struct ath_buf *bf)
202{
203}
204
151static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, 205static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
152 int xretries, int retries, u8 per) 206 int xretries, int retries, u8 per)
153{ 207{
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 93e8ce0598a4..6fb1a8034b3c 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -2781,11 +2781,1210 @@ static struct eeprom_ops eep_def_ops = {
2781 .get_spur_channel = ath9k_hw_def_get_spur_channel 2781 .get_spur_channel = ath9k_hw_def_get_spur_channel
2782}; 2782};
2783 2783
2784
2785static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah)
2786{
2787 return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF;
2788}
2789
2790static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah)
2791{
2792 return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF;
2793}
2794
2795static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
2796{
2797 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287;
2798 u16 *eep_data;
2799 int addr, eep_start_loc = AR9287_EEP_START_LOC;
2800 eep_data = (u16 *)eep;
2801 if (!ath9k_hw_use_flash(ah)) {
2802 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2803 "Reading from EEPROM, not flash\n");
2804 }
2805
2806 for (addr = 0; addr < sizeof(struct ar9287_eeprom_t) / sizeof(u16);
2807 addr++) {
2808 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
2809 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2810 "Unable to read eeprom region \n");
2811 return false;
2812 }
2813 eep_data++;
2814 }
2815 return true;
2816}
2817static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
2818{
2819#define SIZE_EEPROM_87 (sizeof(struct ar9287_eeprom_t) / sizeof(u16))
2820 u32 sum = 0, el, integer;
2821 u16 temp, word, magic, magic2, *eepdata;
2822 int i, addr;
2823 bool need_swap = false;
2824 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287;
2825
2826 if (!ath9k_hw_use_flash(ah)) {
2827 if (!ath9k_hw_nvram_read
2828 (ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
2829 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
2830 "Reading Magic # failed\n");
2831 return false;
2832 }
2833
2834 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
2835 "Read Magic = 0x%04X\n", magic);
2836 if (magic != AR5416_EEPROM_MAGIC) {
2837
2838
2839 magic2 = swab16(magic);
2840
2841 if (magic2 == AR5416_EEPROM_MAGIC) {
2842 need_swap = true;
2843 eepdata = (u16 *)(&ah->eeprom);
2844
2845 for (addr = 0; addr < SIZE_EEPROM_87; addr++) {
2846 temp = swab16(*eepdata);
2847 *eepdata = temp;
2848 eepdata++;
2849 }
2850 } else {
2851 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
2852 "Invalid EEPROM Magic. "
2853 "endianness mismatch.\n");
2854 return -EINVAL; }
2855 }
2856 }
2857 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n", need_swap ?
2858 "True" : "False");
2859
2860 if (need_swap)
2861 el = swab16(ah->eeprom.map9287.baseEepHeader.length);
2862 else
2863 el = ah->eeprom.map9287.baseEepHeader.length;
2864
2865 eepdata = (u16 *)(&ah->eeprom);
2866 for (i = 0; i < min(el, SIZE_EEPROM_87); i++)
2867 sum ^= *eepdata++;
2868
2869 if (need_swap) {
2870 word = swab16(eep->baseEepHeader.length);
2871 eep->baseEepHeader.length = word;
2872
2873 word = swab16(eep->baseEepHeader.checksum);
2874 eep->baseEepHeader.checksum = word;
2875
2876 word = swab16(eep->baseEepHeader.version);
2877 eep->baseEepHeader.version = word;
2878
2879 word = swab16(eep->baseEepHeader.regDmn[0]);
2880 eep->baseEepHeader.regDmn[0] = word;
2881
2882 word = swab16(eep->baseEepHeader.regDmn[1]);
2883 eep->baseEepHeader.regDmn[1] = word;
2884
2885 word = swab16(eep->baseEepHeader.rfSilent);
2886 eep->baseEepHeader.rfSilent = word;
2887
2888 word = swab16(eep->baseEepHeader.blueToothOptions);
2889 eep->baseEepHeader.blueToothOptions = word;
2890
2891 word = swab16(eep->baseEepHeader.deviceCap);
2892 eep->baseEepHeader.deviceCap = word;
2893
2894 integer = swab32(eep->modalHeader.antCtrlCommon);
2895 eep->modalHeader.antCtrlCommon = integer;
2896
2897 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
2898 integer = swab32(eep->modalHeader.antCtrlChain[i]);
2899 eep->modalHeader.antCtrlChain[i] = integer;
2900 }
2901
2902 for (i = 0; i < AR9287_EEPROM_MODAL_SPURS; i++) {
2903 word = swab16(eep->modalHeader.spurChans[i].spurChan);
2904 eep->modalHeader.spurChans[i].spurChan = word;
2905 }
2906 }
2907
2908 if (sum != 0xffff || ah->eep_ops->get_eeprom_ver(ah) != AR9287_EEP_VER
2909 || ah->eep_ops->get_eeprom_rev(ah) < AR5416_EEP_NO_BACK_VER) {
2910 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
2911 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
2912 sum, ah->eep_ops->get_eeprom_ver(ah));
2913 return -EINVAL;
2914 }
2915
2916 return 0;
2917#undef SIZE_EEPROM_87
2918}
2919
2920static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
2921 enum eeprom_param param)
2922{
2923 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287;
2924 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
2925 struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
2926 u16 ver_minor;
2927
2928 ver_minor = pBase->version & AR9287_EEP_VER_MINOR_MASK;
2929 switch (param) {
2930 case EEP_NFTHRESH_2:
2931 return pModal->noiseFloorThreshCh[0];
2932 case AR_EEPROM_MAC(0):
2933 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
2934 case AR_EEPROM_MAC(1):
2935 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
2936 case AR_EEPROM_MAC(2):
2937 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
2938 case EEP_REG_0:
2939 return pBase->regDmn[0];
2940 case EEP_REG_1:
2941 return pBase->regDmn[1];
2942 case EEP_OP_CAP:
2943 return pBase->deviceCap;
2944 case EEP_OP_MODE:
2945 return pBase->opCapFlags;
2946 case EEP_RF_SILENT:
2947 return pBase->rfSilent;
2948 case EEP_MINOR_REV:
2949 return ver_minor;
2950 case EEP_TX_MASK:
2951 return pBase->txMask;
2952 case EEP_RX_MASK:
2953 return pBase->rxMask;
2954 case EEP_DEV_TYPE:
2955 return pBase->deviceType;
2956 case EEP_OL_PWRCTRL:
2957 return pBase->openLoopPwrCntl;
2958 case EEP_TEMPSENSE_SLOPE:
2959 if (ver_minor >= AR9287_EEP_MINOR_VER_2)
2960 return pBase->tempSensSlope;
2961 else
2962 return 0;
2963 case EEP_TEMPSENSE_SLOPE_PAL_ON:
2964 if (ver_minor >= AR9287_EEP_MINOR_VER_3)
2965 return pBase->tempSensSlopePalOn;
2966 else
2967 return 0;
2968 default:
2969 return 0;
2970 }
2971}
2972
2973
2974static void ath9k_hw_get_AR9287_gain_boundaries_pdadcs(struct ath_hw *ah,
2975 struct ath9k_channel *chan,
2976 struct cal_data_per_freq_ar9287 *pRawDataSet,
2977 u8 *bChans, u16 availPiers,
2978 u16 tPdGainOverlap, int16_t *pMinCalPower,
2979 u16 *pPdGainBoundaries, u8 *pPDADCValues,
2980 u16 numXpdGains)
2981{
2982#define TMP_VAL_VPD_TABLE \
2983 ((vpdTableI[i][sizeCurrVpdTable - 1] + (ss - maxIndex + 1) * vpdStep));
2984 int i, j, k;
2985 int16_t ss;
2986 u16 idxL = 0, idxR = 0, numPiers;
2987 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
2988 u8 minPwrT4[AR9287_NUM_PD_GAINS];
2989 u8 maxPwrT4[AR9287_NUM_PD_GAINS];
2990 int16_t vpdStep;
2991 int16_t tmpVal;
2992 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
2993 bool match;
2994 int16_t minDelta = 0;
2995 struct chan_centers centers;
2996 static u8 vpdTableL[AR5416_EEP4K_NUM_PD_GAINS]
2997 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
2998 static u8 vpdTableR[AR5416_EEP4K_NUM_PD_GAINS]
2999 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3000 static u8 vpdTableI[AR5416_EEP4K_NUM_PD_GAINS]
3001 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3002
3003 ath9k_hw_get_channel_centers(ah, chan, &centers);
3004 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3005 if (bChans[numPiers] == AR9287_BCHAN_UNUSED)
3006 break;
3007 }
3008
3009 match = ath9k_hw_get_lower_upper_index(
3010 (u8)FREQ2FBIN(centers.synth_center,
3011 IS_CHAN_2GHZ(chan)), bChans, numPiers,
3012 &idxL, &idxR);
3013
3014 if (match) {
3015 for (i = 0; i < numXpdGains; i++) {
3016 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3017 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3018 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3019 pRawDataSet[idxL].pwrPdg[i],
3020 pRawDataSet[idxL].vpdPdg[i],
3021 AR9287_PD_GAIN_ICEPTS, vpdTableI[i]);
3022 }
3023 } else {
3024 for (i = 0; i < numXpdGains; i++) {
3025 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3026 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3027 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3028 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3029
3030 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3031
3032 maxPwrT4[i] =
3033 min(pPwrL[AR9287_PD_GAIN_ICEPTS - 1],
3034 pPwrR[AR9287_PD_GAIN_ICEPTS - 1]);
3035
3036 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3037 pPwrL, pVpdL,
3038 AR9287_PD_GAIN_ICEPTS,
3039 vpdTableL[i]);
3040 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3041 pPwrR, pVpdR,
3042 AR9287_PD_GAIN_ICEPTS,
3043 vpdTableR[i]);
3044
3045 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3046 vpdTableI[i][j] =
3047 (u8)(ath9k_hw_interpolate((u16)
3048 FREQ2FBIN(centers. synth_center,
3049 IS_CHAN_2GHZ(chan)),
3050 bChans[idxL], bChans[idxR],
3051 vpdTableL[i][j], vpdTableR[i][j]));
3052 }
3053 }
3054 }
3055 *pMinCalPower = (int16_t)(minPwrT4[0] / 2);
3056
3057 k = 0;
3058 for (i = 0; i < numXpdGains; i++) {
3059 if (i == (numXpdGains - 1))
3060 pPdGainBoundaries[i] = (u16)(maxPwrT4[i] / 2);
3061 else
3062 pPdGainBoundaries[i] = (u16)((maxPwrT4[i] +
3063 minPwrT4[i+1]) / 4);
3064
3065 pPdGainBoundaries[i] = min((u16)AR5416_MAX_RATE_POWER,
3066 pPdGainBoundaries[i]);
3067
3068
3069 if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
3070 minDelta = pPdGainBoundaries[0] - 23;
3071 pPdGainBoundaries[0] = 23;
3072 } else
3073 minDelta = 0;
3074
3075 if (i == 0) {
3076 if (AR_SREV_9280_10_OR_LATER(ah))
3077 ss = (int16_t)(0 - (minPwrT4[i] / 2));
3078 else
3079 ss = 0;
3080 } else
3081 ss = (int16_t)((pPdGainBoundaries[i-1] -
3082 (minPwrT4[i] / 2)) -
3083 tPdGainOverlap + 1 + minDelta);
3084
3085 vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
3086 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
3087 while ((ss < 0) && (k < (AR9287_NUM_PDADC_VALUES - 1))) {
3088 tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
3089 pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
3090 ss++;
3091 }
3092
3093 sizeCurrVpdTable = (u8)((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3094 tgtIndex = (u8)(pPdGainBoundaries[i] +
3095 tPdGainOverlap - (minPwrT4[i] / 2));
3096 maxIndex = (tgtIndex < sizeCurrVpdTable) ?
3097 tgtIndex : sizeCurrVpdTable;
3098
3099 while ((ss < maxIndex) && (k < (AR9287_NUM_PDADC_VALUES - 1)))
3100 pPDADCValues[k++] = vpdTableI[i][ss++];
3101
3102 vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
3103 vpdTableI[i][sizeCurrVpdTable - 2]);
3104 vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
3105 if (tgtIndex > maxIndex) {
3106 while ((ss <= tgtIndex) &&
3107 (k < (AR9287_NUM_PDADC_VALUES - 1))) {
3108 tmpVal = (int16_t) TMP_VAL_VPD_TABLE;
3109 pPDADCValues[k++] = (u8)((tmpVal > 255) ?
3110 255 : tmpVal);
3111 ss++;
3112 }
3113 }
3114 }
3115
3116 while (i < AR9287_PD_GAINS_IN_MASK) {
3117 pPdGainBoundaries[i] = pPdGainBoundaries[i-1];
3118 i++;
3119 }
3120
3121 while (k < AR9287_NUM_PDADC_VALUES) {
3122 pPDADCValues[k] = pPDADCValues[k-1];
3123 k++;
3124 }
3125
3126#undef TMP_VAL_VPD_TABLE
3127}
3128
3129static void ar9287_eeprom_get_tx_gain_index(struct ath_hw *ah,
3130 struct ath9k_channel *chan,
3131 struct cal_data_op_loop_ar9287 *pRawDatasetOpLoop,
3132 u8 *pCalChans, u16 availPiers,
3133 int8_t *pPwr)
3134{
3135 u8 pcdac, i = 0;
3136 u16 idxL = 0, idxR = 0, numPiers;
3137 bool match;
3138 struct chan_centers centers;
3139 ath9k_hw_get_channel_centers(ah, chan, &centers);
3140 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3141 if (pCalChans[numPiers] == AR9287_BCHAN_UNUSED)
3142 break;
3143 }
3144
3145 match = ath9k_hw_get_lower_upper_index(
3146 (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)),
3147 pCalChans, numPiers,
3148 &idxL, &idxR);
3149
3150 if (match) {
3151 pcdac = pRawDatasetOpLoop[idxL].pcdac[0][0];
3152 *pPwr = pRawDatasetOpLoop[idxL].pwrPdg[0][0];
3153 } else {
3154 pcdac = pRawDatasetOpLoop[idxR].pcdac[0][0];
3155 *pPwr = (pRawDatasetOpLoop[idxL].pwrPdg[0][0] +
3156 pRawDatasetOpLoop[idxR].pwrPdg[0][0])/2;
3157 }
3158
3159 while ((pcdac > ah->originalGain[i]) &&
3160 (i < (AR9280_TX_GAIN_TABLE_SIZE - 1)))
3161 i++;
3162}
3163
3164static void ar9287_eeprom_olpc_set_pdadcs(struct ath_hw *ah,
3165 int32_t txPower, u16 chain)
3166{
3167 u32 tmpVal;
3168 u32 a;
3169
3170 tmpVal = REG_READ(ah, 0xa270);
3171 tmpVal = tmpVal & 0xFCFFFFFF;
3172 tmpVal = tmpVal | (0x3 << 24);
3173 REG_WRITE(ah, 0xa270, tmpVal);
3174
3175 tmpVal = REG_READ(ah, 0xb270);
3176 tmpVal = tmpVal & 0xFCFFFFFF;
3177 tmpVal = tmpVal | (0x3 << 24);
3178 REG_WRITE(ah, 0xb270, tmpVal);
3179
3180 if (chain == 0) {
3181 tmpVal = REG_READ(ah, 0xa398);
3182 tmpVal = tmpVal & 0xff00ffff;
3183 a = (txPower)&0xff;
3184 tmpVal = tmpVal | (a << 16);
3185 REG_WRITE(ah, 0xa398, tmpVal);
3186 }
3187
3188 if (chain == 1) {
3189 tmpVal = REG_READ(ah, 0xb398);
3190 tmpVal = tmpVal & 0xff00ffff;
3191 a = (txPower)&0xff;
3192 tmpVal = tmpVal | (a << 16);
3193 REG_WRITE(ah, 0xb398, tmpVal);
3194 }
3195}
3196
3197
3198static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
3199 struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset)
3200{
3201 struct cal_data_per_freq_ar9287 *pRawDataset;
3202 struct cal_data_op_loop_ar9287 *pRawDatasetOpenLoop;
3203 u8 *pCalBChans = NULL;
3204 u16 pdGainOverlap_t2;
3205 u8 pdadcValues[AR9287_NUM_PDADC_VALUES];
3206 u16 gainBoundaries[AR9287_PD_GAINS_IN_MASK];
3207 u16 numPiers = 0, i, j;
3208 int16_t tMinCalPower;
3209 u16 numXpdGain, xpdMask;
3210 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
3211 u32 reg32, regOffset, regChainOffset;
3212 int16_t modalIdx, diff = 0;
3213 struct ar9287_eeprom_t *pEepData = &ah->eeprom.map9287;
3214 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3215 xpdMask = pEepData->modalHeader.xpdGain;
3216 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
3217 AR9287_EEP_MINOR_VER_2)
3218 pdGainOverlap_t2 = pEepData->modalHeader.pdGainOverlap;
3219 else
3220 pdGainOverlap_t2 = (u16)(MS(REG_READ(ah, AR_PHY_TPCRG5),
3221 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3222
3223 if (IS_CHAN_2GHZ(chan)) {
3224 pCalBChans = pEepData->calFreqPier2G;
3225 numPiers = AR9287_NUM_2G_CAL_PIERS;
3226 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3227 pRawDatasetOpenLoop =
3228 (struct cal_data_op_loop_ar9287 *)
3229 pEepData->calPierData2G[0];
3230 ah->initPDADC = pRawDatasetOpenLoop->vpdPdg[0][0];
3231 }
3232 }
3233
3234 numXpdGain = 0;
3235 for (i = 1; i <= AR9287_PD_GAINS_IN_MASK; i++) {
3236 if ((xpdMask >> (AR9287_PD_GAINS_IN_MASK - i)) & 1) {
3237 if (numXpdGain >= AR9287_NUM_PD_GAINS)
3238 break;
3239 xpdGainValues[numXpdGain] =
3240 (u16)(AR9287_PD_GAINS_IN_MASK-i);
3241 numXpdGain++;
3242 }
3243 }
3244
3245 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3246 (numXpdGain - 1) & 0x3);
3247 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3248 xpdGainValues[0]);
3249 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3250 xpdGainValues[1]);
3251 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3252 xpdGainValues[2]);
3253
3254 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
3255 regChainOffset = i * 0x1000;
3256 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3257 pRawDatasetOpenLoop = (struct cal_data_op_loop_ar9287 *)
3258 pEepData->calPierData2G[i];
3259 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3260 int8_t txPower;
3261 ar9287_eeprom_get_tx_gain_index(ah, chan,
3262 pRawDatasetOpenLoop,
3263 pCalBChans, numPiers,
3264 &txPower);
3265 ar9287_eeprom_olpc_set_pdadcs(ah, txPower, i);
3266 } else {
3267 pRawDataset =
3268 (struct cal_data_per_freq_ar9287 *)
3269 pEepData->calPierData2G[i];
3270 ath9k_hw_get_AR9287_gain_boundaries_pdadcs(
3271 ah, chan, pRawDataset,
3272 pCalBChans, numPiers,
3273 pdGainOverlap_t2,
3274 &tMinCalPower, gainBoundaries,
3275 pdadcValues, numXpdGain);
3276 }
3277
3278 if (i == 0) {
3279 if (!ath9k_hw_AR9287_get_eeprom(
3280 ah, EEP_OL_PWRCTRL)) {
3281 REG_WRITE(ah, AR_PHY_TPCRG5 +
3282 regChainOffset,
3283 SM(pdGainOverlap_t2,
3284 AR_PHY_TPCRG5_PD_GAIN_OVERLAP) |
3285 SM(gainBoundaries[0],
3286 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3287 | SM(gainBoundaries[1],
3288 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3289 | SM(gainBoundaries[2],
3290 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3291 | SM(gainBoundaries[3],
3292 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3293 }
3294 }
3295
3296 if ((int32_t)AR9287_PWR_TABLE_OFFSET_DB !=
3297 pEepData->baseEepHeader.pwrTableOffset) {
3298 diff = (u16)
3299 (pEepData->baseEepHeader.pwrTableOffset
3300 - (int32_t)AR9287_PWR_TABLE_OFFSET_DB);
3301 diff *= 2;
3302
3303 for (j = 0;
3304 j < ((u16)AR9287_NUM_PDADC_VALUES-diff);
3305 j++)
3306 pdadcValues[j] = pdadcValues[j+diff];
3307
3308 for (j = (u16)(AR9287_NUM_PDADC_VALUES-diff);
3309 j < AR9287_NUM_PDADC_VALUES; j++)
3310 pdadcValues[j] =
3311 pdadcValues[
3312 AR9287_NUM_PDADC_VALUES-diff];
3313 }
3314 if (!ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3315 regOffset = AR_PHY_BASE + (672 << 2) +
3316 regChainOffset;
3317 for (j = 0; j < 32; j++) {
3318 reg32 = ((pdadcValues[4*j + 0]
3319 & 0xFF) << 0) |
3320 ((pdadcValues[4*j + 1]
3321 & 0xFF) << 8) |
3322 ((pdadcValues[4*j + 2]
3323 & 0xFF) << 16) |
3324 ((pdadcValues[4*j + 3]
3325 & 0xFF) << 24) ;
3326 REG_WRITE(ah, regOffset, reg32);
3327
3328 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3329 "PDADC (%d,%4x): %4.4x %8.8x\n",
3330 i, regChainOffset, regOffset,
3331 reg32);
3332 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3333 "PDADC: Chain %d | "
3334 "PDADC %3d Value %3d | "
3335 "PDADC %3d Value %3d | "
3336 "PDADC %3d Value %3d | "
3337 "PDADC %3d Value %3d |\n",
3338 i, 4 * j, pdadcValues[4 * j],
3339 4 * j + 1,
3340 pdadcValues[4 * j + 1],
3341 4 * j + 2,
3342 pdadcValues[4 * j + 2],
3343 4 * j + 3,
3344 pdadcValues[4 * j + 3]);
3345
3346 regOffset += 4;
3347 }
3348 }
3349 }
3350 }
3351
3352 *pTxPowerIndexOffset = 0;
3353}
3354
3355
3356static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
3357 struct ath9k_channel *chan, int16_t *ratesArray, u16 cfgCtl,
3358 u16 AntennaReduction, u16 twiceMaxRegulatoryPower,
3359 u16 powerLimit)
3360{
3361#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6
3362#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10
3363
3364 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
3365 static const u16 tpScaleReductionTable[5] = { 0, 3, 6, 9,
3366 AR5416_MAX_RATE_POWER };
3367 int i;
3368 int16_t twiceLargestAntenna;
3369 struct cal_ctl_data_ar9287 *rep;
3370 struct cal_target_power_leg targetPowerOfdm = {0, {0, 0, 0, 0} },
3371 targetPowerCck = {0, {0, 0, 0, 0} };
3372 struct cal_target_power_leg targetPowerOfdmExt = {0, {0, 0, 0, 0} },
3373 targetPowerCckExt = {0, {0, 0, 0, 0} };
3374 struct cal_target_power_ht targetPowerHt20,
3375 targetPowerHt40 = {0, {0, 0, 0, 0} };
3376 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
3377 u16 ctlModesFor11g[] = {CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
3378 CTL_11G_EXT, CTL_2GHT40};
3379 u16 numCtlModes = 0, *pCtlMode = NULL, ctlMode, freq;
3380 struct chan_centers centers;
3381 int tx_chainmask;
3382 u16 twiceMinEdgePower;
3383 struct ar9287_eeprom_t *pEepData = &ah->eeprom.map9287;
3384 tx_chainmask = ah->txchainmask;
3385
3386 ath9k_hw_get_channel_centers(ah, chan, &centers);
3387
3388 twiceLargestAntenna = max(pEepData->modalHeader.antennaGainCh[0],
3389 pEepData->modalHeader.antennaGainCh[1]);
3390
3391 twiceLargestAntenna = (int16_t)min((AntennaReduction) -
3392 twiceLargestAntenna, 0);
3393
3394 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
3395 if (ah->regulatory.tp_scale != ATH9K_TP_SCALE_MAX)
3396 maxRegAllowedPower -=
3397 (tpScaleReductionTable[(ah->regulatory.tp_scale)] * 2);
3398
3399 scaledPower = min(powerLimit, maxRegAllowedPower);
3400
3401 switch (ar5416_get_ntxchains(tx_chainmask)) {
3402 case 1:
3403 break;
3404 case 2:
3405 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
3406 break;
3407 case 3:
3408 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
3409 break;
3410 }
3411 scaledPower = max((u16)0, scaledPower);
3412
3413 if (IS_CHAN_2GHZ(chan)) {
3414 numCtlModes = ARRAY_SIZE(ctlModesFor11g) -
3415 SUB_NUM_CTL_MODES_AT_2G_40;
3416 pCtlMode = ctlModesFor11g;
3417
3418 ath9k_hw_get_legacy_target_powers(ah, chan,
3419 pEepData->calTargetPowerCck,
3420 AR9287_NUM_2G_CCK_TARGET_POWERS,
3421 &targetPowerCck, 4, false);
3422 ath9k_hw_get_legacy_target_powers(ah, chan,
3423 pEepData->calTargetPower2G,
3424 AR9287_NUM_2G_20_TARGET_POWERS,
3425 &targetPowerOfdm, 4, false);
3426 ath9k_hw_get_target_powers(ah, chan,
3427 pEepData->calTargetPower2GHT20,
3428 AR9287_NUM_2G_20_TARGET_POWERS,
3429 &targetPowerHt20, 8, false);
3430
3431 if (IS_CHAN_HT40(chan)) {
3432 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
3433 ath9k_hw_get_target_powers(ah, chan,
3434 pEepData->calTargetPower2GHT40,
3435 AR9287_NUM_2G_40_TARGET_POWERS,
3436 &targetPowerHt40, 8, true);
3437 ath9k_hw_get_legacy_target_powers(ah, chan,
3438 pEepData->calTargetPowerCck,
3439 AR9287_NUM_2G_CCK_TARGET_POWERS,
3440 &targetPowerCckExt, 4, true);
3441 ath9k_hw_get_legacy_target_powers(ah, chan,
3442 pEepData->calTargetPower2G,
3443 AR9287_NUM_2G_20_TARGET_POWERS,
3444 &targetPowerOfdmExt, 4, true);
3445 }
3446 }
3447
3448 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
3449
3450 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
3451 (pCtlMode[ctlMode] == CTL_2GHT40);
3452 if (isHt40CtlMode)
3453 freq = centers.synth_center;
3454 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
3455 freq = centers.ext_center;
3456 else
3457 freq = centers.ctl_center;
3458
3459
3460 if (ah->eep_ops->get_eeprom_ver(ah) == 14 &&
3461 ah->eep_ops->get_eeprom_rev(ah) <= 2)
3462 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
3463 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3464 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d,"
3465 "EXT_ADDITIVE %d\n", ctlMode, numCtlModes,
3466 isHt40CtlMode, (pCtlMode[ctlMode] & EXT_ADDITIVE));
3467 for (i = 0; (i < AR9287_NUM_CTLS)
3468 && pEepData->ctlIndex[i]; i++) {
3469 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3470 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x"
3471 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x"
3472 "chan %d chanctl=xxxx\n",
3473 i, cfgCtl, pCtlMode[ctlMode],
3474 pEepData->ctlIndex[i], chan->channel);
3475
3476 if ((((cfgCtl & ~CTL_MODE_M) |
3477 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
3478 pEepData->ctlIndex[i]) ||
3479 (((cfgCtl & ~CTL_MODE_M) |
3480 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
3481 ((pEepData->ctlIndex[i] &
3482 CTL_MODE_M) | SD_NO_CTL))) {
3483
3484 rep = &(pEepData->ctlData[i]);
3485 twiceMinEdgePower = ath9k_hw_get_max_edge_power(
3486 freq,
3487 rep->ctlEdges[ar5416_get_ntxchains(
3488 tx_chainmask) - 1],
3489 IS_CHAN_2GHZ(chan), AR5416_NUM_BAND_EDGES);
3490
3491 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3492 "MATCH-EE_IDX %d: ch %d is2 %d"
3493 "2xMinEdge %d chainmask %d chains %d\n",
3494 i, freq, IS_CHAN_2GHZ(chan),
3495 twiceMinEdgePower, tx_chainmask,
3496 ar5416_get_ntxchains(tx_chainmask));
3497
3498 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
3499 twiceMaxEdgePower = min(
3500 twiceMaxEdgePower,
3501 twiceMinEdgePower);
3502 else {
3503 twiceMaxEdgePower = twiceMinEdgePower;
3504 break;
3505 }
3506 }
3507 }
3508
3509 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
3510
3511 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3512 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d"
3513 "sP %d minCtlPwr %d\n",
3514 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
3515 scaledPower, minCtlPower);
3516
3517
3518 switch (pCtlMode[ctlMode]) {
3519
3520 case CTL_11B:
3521 for (i = 0;
3522 i < ARRAY_SIZE(targetPowerCck.tPow2x);
3523 i++) {
3524 targetPowerCck.tPow2x[i] = (u8)min(
3525 (u16)targetPowerCck.tPow2x[i],
3526 minCtlPower);
3527 }
3528 break;
3529 case CTL_11A:
3530 case CTL_11G:
3531 for (i = 0;
3532 i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
3533 i++) {
3534 targetPowerOfdm.tPow2x[i] = (u8)min(
3535 (u16)targetPowerOfdm.tPow2x[i],
3536 minCtlPower);
3537 }
3538 break;
3539 case CTL_5GHT20:
3540 case CTL_2GHT20:
3541 for (i = 0;
3542 i < ARRAY_SIZE(targetPowerHt20.tPow2x);
3543 i++) {
3544 targetPowerHt20.tPow2x[i] = (u8)min(
3545 (u16)targetPowerHt20.tPow2x[i],
3546 minCtlPower);
3547 }
3548 break;
3549 case CTL_11B_EXT:
3550 targetPowerCckExt.tPow2x[0] = (u8)min(
3551 (u16)targetPowerCckExt.tPow2x[0],
3552 minCtlPower);
3553 break;
3554 case CTL_11A_EXT:
3555 case CTL_11G_EXT:
3556 targetPowerOfdmExt.tPow2x[0] = (u8)min(
3557 (u16)targetPowerOfdmExt.tPow2x[0],
3558 minCtlPower);
3559 break;
3560 case CTL_5GHT40:
3561 case CTL_2GHT40:
3562 for (i = 0;
3563 i < ARRAY_SIZE(targetPowerHt40.tPow2x);
3564 i++) {
3565 targetPowerHt40.tPow2x[i] = (u8)min(
3566 (u16)targetPowerHt40.tPow2x[i],
3567 minCtlPower);
3568 }
3569 break;
3570 default:
3571 break;
3572 }
3573 }
3574
3575 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
3576 ratesArray[rate18mb] = ratesArray[rate24mb] =
3577 targetPowerOfdm.tPow2x[0];
3578 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
3579 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
3580 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
3581 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
3582
3583 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
3584 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
3585
3586 if (IS_CHAN_2GHZ(chan)) {
3587 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
3588 ratesArray[rate2s] = ratesArray[rate2l] =
3589 targetPowerCck.tPow2x[1];
3590 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
3591 targetPowerCck.tPow2x[2];
3592 ratesArray[rate11s] = ratesArray[rate11l] =
3593 targetPowerCck.tPow2x[3];
3594 }
3595 if (IS_CHAN_HT40(chan)) {
3596 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++)
3597 ratesArray[rateHt40_0 + i] = targetPowerHt40.tPow2x[i];
3598
3599 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
3600 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
3601 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
3602 if (IS_CHAN_2GHZ(chan))
3603 ratesArray[rateExtCck] = targetPowerCckExt.tPow2x[0];
3604 }
3605#undef REDUCE_SCALED_POWER_BY_TWO_CHAIN
3606#undef REDUCE_SCALED_POWER_BY_THREE_CHAIN
3607}
3608
3609static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
3610 struct ath9k_channel *chan, u16 cfgCtl,
3611 u8 twiceAntennaReduction, u8 twiceMaxRegulatoryPower,
3612 u8 powerLimit)
3613{
3614#define INCREASE_MAXPOW_BY_TWO_CHAIN 6
3615#define INCREASE_MAXPOW_BY_THREE_CHAIN 10
3616 struct ar9287_eeprom_t *pEepData = &ah->eeprom.map9287;
3617 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
3618 int16_t ratesArray[Ar5416RateSize];
3619 int16_t txPowerIndexOffset = 0;
3620 u8 ht40PowerIncForPdadc = 2;
3621 int i;
3622 memset(ratesArray, 0, sizeof(ratesArray));
3623
3624 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
3625 AR9287_EEP_MINOR_VER_2)
3626 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
3627
3628 ath9k_hw_set_AR9287_power_per_rate_table(ah, chan,
3629 &ratesArray[0], cfgCtl,
3630 twiceAntennaReduction,
3631 twiceMaxRegulatoryPower,
3632 powerLimit);
3633
3634
3635 ath9k_hw_set_AR9287_power_cal_table(ah, chan, &txPowerIndexOffset);
3636
3637 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
3638 ratesArray[i] = (int16_t)(txPowerIndexOffset + ratesArray[i]);
3639 if (ratesArray[i] > AR9287_MAX_RATE_POWER)
3640 ratesArray[i] = AR9287_MAX_RATE_POWER;
3641 }
3642
3643 if (AR_SREV_9280_10_OR_LATER(ah)) {
3644 for (i = 0; i < Ar5416RateSize; i++)
3645 ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
3646 }
3647
3648
3649 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
3650 ATH9K_POW_SM(ratesArray[rate18mb], 24)
3651 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
3652 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
3653 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
3654 );
3655
3656 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
3657 ATH9K_POW_SM(ratesArray[rate54mb], 24)
3658 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
3659 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
3660 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
3661 );
3662
3663 if (IS_CHAN_2GHZ(chan)) {
3664 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
3665 ATH9K_POW_SM(ratesArray[rate2s], 24)
3666 | ATH9K_POW_SM(ratesArray[rate2l], 16)
3667 | ATH9K_POW_SM(ratesArray[rateXr], 8)
3668 | ATH9K_POW_SM(ratesArray[rate1l], 0)
3669 );
3670 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
3671 ATH9K_POW_SM(ratesArray[rate11s], 24)
3672 | ATH9K_POW_SM(ratesArray[rate11l], 16)
3673 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
3674 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
3675 );
3676 }
3677
3678 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
3679 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
3680 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
3681 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
3682 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
3683 );
3684
3685 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
3686 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
3687 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
3688 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
3689 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
3690 );
3691
3692 if (IS_CHAN_HT40(chan)) {
3693 if (ath9k_hw_AR9287_get_eeprom(ah, EEP_OL_PWRCTRL)) {
3694 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
3695 ATH9K_POW_SM(ratesArray[rateHt40_3], 24)
3696 | ATH9K_POW_SM(ratesArray[rateHt40_2], 16)
3697 | ATH9K_POW_SM(ratesArray[rateHt40_1], 8)
3698 | ATH9K_POW_SM(ratesArray[rateHt40_0], 0)
3699 );
3700
3701 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
3702 ATH9K_POW_SM(ratesArray[rateHt40_7], 24)
3703 | ATH9K_POW_SM(ratesArray[rateHt40_6], 16)
3704 | ATH9K_POW_SM(ratesArray[rateHt40_5], 8)
3705 | ATH9K_POW_SM(ratesArray[rateHt40_4], 0)
3706 );
3707 } else {
3708 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
3709 ATH9K_POW_SM(ratesArray[rateHt40_3] +
3710 ht40PowerIncForPdadc, 24)
3711 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
3712 ht40PowerIncForPdadc, 16)
3713 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
3714 ht40PowerIncForPdadc, 8)
3715 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
3716 ht40PowerIncForPdadc, 0)
3717 );
3718
3719 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
3720 ATH9K_POW_SM(ratesArray[rateHt40_7] +
3721 ht40PowerIncForPdadc, 24)
3722 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
3723 ht40PowerIncForPdadc, 16)
3724 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
3725 ht40PowerIncForPdadc, 8)
3726 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
3727 ht40PowerIncForPdadc, 0)
3728 );
3729
3730 }
3731
3732 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
3733 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
3734 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
3735 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
3736 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
3737 );
3738 }
3739
3740
3741 if (IS_CHAN_2GHZ(chan))
3742 i = rate1l;
3743 else
3744 i = rate6mb;
3745
3746 if (AR_SREV_9280_10_OR_LATER(ah))
3747 ah->regulatory.max_power_level =
3748 ratesArray[i] + AR9287_PWR_TABLE_OFFSET_DB * 2;
3749 else
3750 ah->regulatory.max_power_level = ratesArray[i];
3751
3752 switch (ar5416_get_ntxchains(ah->txchainmask)) {
3753 case 1:
3754 break;
3755 case 2:
3756 ah->regulatory.max_power_level +=
3757 INCREASE_MAXPOW_BY_TWO_CHAIN;
3758 break;
3759 case 3:
3760 ah->regulatory.max_power_level +=
3761 INCREASE_MAXPOW_BY_THREE_CHAIN;
3762 break;
3763 default:
3764 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
3765 "Invalid chainmask configuration\n");
3766 break;
3767 }
3768}
3769
3770static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah,
3771 struct ath9k_channel *chan)
3772{
3773 return;
3774}
3775
3776static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah,
3777 struct ath9k_channel *chan)
3778{
3779 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287;
3780 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
3781
3782 u16 antWrites[AR9287_ANT_16S];
3783 u32 regChainOffset;
3784 u8 txRxAttenLocal;
3785 int i, j, offset_num;
3786
3787 pModal = &eep->modalHeader;
3788
3789 antWrites[0] = (u16)((pModal->antCtrlCommon >> 28) & 0xF);
3790 antWrites[1] = (u16)((pModal->antCtrlCommon >> 24) & 0xF);
3791 antWrites[2] = (u16)((pModal->antCtrlCommon >> 20) & 0xF);
3792 antWrites[3] = (u16)((pModal->antCtrlCommon >> 16) & 0xF);
3793 antWrites[4] = (u16)((pModal->antCtrlCommon >> 12) & 0xF);
3794 antWrites[5] = (u16)((pModal->antCtrlCommon >> 8) & 0xF);
3795 antWrites[6] = (u16)((pModal->antCtrlCommon >> 4) & 0xF);
3796 antWrites[7] = (u16)(pModal->antCtrlCommon & 0xF);
3797
3798 offset_num = 8;
3799
3800 for (i = 0, j = offset_num; i < AR9287_MAX_CHAINS; i++) {
3801 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 28) & 0xf);
3802 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 10) & 0x3);
3803 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 8) & 0x3);
3804 antWrites[j++] = 0;
3805 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 6) & 0x3);
3806 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 4) & 0x3);
3807 antWrites[j++] = (u16)((pModal->antCtrlChain[i] >> 2) & 0x3);
3808 antWrites[j++] = (u16)(pModal->antCtrlChain[i] & 0x3);
3809 }
3810
3811
3812 REG_WRITE(ah, AR_PHY_SWITCH_COM,
3813 ah->eep_ops->get_eeprom_antenna_cfg(ah, chan));
3814
3815 for (i = 0; i < AR9287_MAX_CHAINS; i++) {
3816 regChainOffset = i * 0x1000;
3817
3818 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
3819 pModal->antCtrlChain[i]);
3820
3821 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
3822 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset)
3823 & ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
3824 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
3825 SM(pModal->iqCalICh[i],
3826 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
3827 SM(pModal->iqCalQCh[i],
3828 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
3829
3830 txRxAttenLocal = pModal->txRxAttenCh[i];
3831
3832 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
3833 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
3834 pModal->bswMargin[i]);
3835 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
3836 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
3837 pModal->bswAtten[i]);
3838 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
3839 AR9280_PHY_RXGAIN_TXRX_ATTEN,
3840 txRxAttenLocal);
3841 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
3842 AR9280_PHY_RXGAIN_TXRX_MARGIN,
3843 pModal->rxTxMarginCh[i]);
3844 }
3845
3846
3847 if (IS_CHAN_HT40(chan))
3848 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
3849 AR_PHY_SETTLING_SWITCH, pModal->swSettleHt40);
3850 else
3851 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
3852 AR_PHY_SETTLING_SWITCH, pModal->switchSettling);
3853
3854 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
3855 AR_PHY_DESIRED_SZ_ADC, pModal->adcDesiredSize);
3856
3857 REG_WRITE(ah, AR_PHY_RF_CTL4,
3858 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
3859 | SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
3860 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON)
3861 | SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON));
3862
3863 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3,
3864 AR_PHY_TX_END_TO_A2_RX_ON, pModal->txEndToRxOn);
3865
3866 REG_RMW_FIELD(ah, AR_PHY_CCA,
3867 AR9280_PHY_CCA_THRESH62, pModal->thresh62);
3868 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
3869 AR_PHY_EXT_CCA0_THRESH62, pModal->thresh62);
3870
3871 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB1,
3872 AR9287_AN_RF2G3_DB1_S, pModal->db1);
3873 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0, AR9287_AN_RF2G3_DB2,
3874 AR9287_AN_RF2G3_DB2_S, pModal->db2);
3875 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3876 AR9287_AN_RF2G3_OB_CCK,
3877 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
3878 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3879 AR9287_AN_RF2G3_OB_PSK,
3880 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
3881 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3882 AR9287_AN_RF2G3_OB_QAM,
3883 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
3884 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH0,
3885 AR9287_AN_RF2G3_OB_PAL_OFF,
3886 AR9287_AN_RF2G3_OB_PAL_OFF_S,
3887 pModal->ob_pal_off);
3888
3889 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3890 AR9287_AN_RF2G3_DB1, AR9287_AN_RF2G3_DB1_S,
3891 pModal->db1);
3892 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1, AR9287_AN_RF2G3_DB2,
3893 AR9287_AN_RF2G3_DB2_S, pModal->db2);
3894 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3895 AR9287_AN_RF2G3_OB_CCK,
3896 AR9287_AN_RF2G3_OB_CCK_S, pModal->ob_cck);
3897 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3898 AR9287_AN_RF2G3_OB_PSK,
3899 AR9287_AN_RF2G3_OB_PSK_S, pModal->ob_psk);
3900 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3901 AR9287_AN_RF2G3_OB_QAM,
3902 AR9287_AN_RF2G3_OB_QAM_S, pModal->ob_qam);
3903 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_RF2G3_CH1,
3904 AR9287_AN_RF2G3_OB_PAL_OFF,
3905 AR9287_AN_RF2G3_OB_PAL_OFF_S,
3906 pModal->ob_pal_off);
3907
3908 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
3909 AR_PHY_TX_END_DATA_START, pModal->txFrameToDataStart);
3910 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
3911 AR_PHY_TX_END_PA_ON, pModal->txFrameToPaOn);
3912
3913 ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TOP2,
3914 AR9287_AN_TOP2_XPABIAS_LVL,
3915 AR9287_AN_TOP2_XPABIAS_LVL_S,
3916 pModal->xpaBiasLvl);
3917}
3918
3919static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah,
3920 enum ieee80211_band freq_band)
3921{
3922 return 1;
3923}
3924
3925
3926
3927
3928static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
3929 struct ath9k_channel *chan)
3930{
3931 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287;
3932 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
3933 return pModal->antCtrlCommon & 0xFFFF;
3934}
3935
3936
3937static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah,
3938 u16 i, bool is2GHz)
3939{
3940#define EEP_MAP9287_SPURCHAN \
3941 (ah->eeprom.map9287.modalHeader.spurChans[i].spurChan)
3942 u16 spur_val = AR_NO_SPUR;
3943
3944 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
3945 "Getting spur idx %d is2Ghz. %d val %x\n",
3946 i, is2GHz, ah->config.spurchans[i][is2GHz]);
3947
3948 switch (ah->config.spurmode) {
3949 case SPUR_DISABLE:
3950 break;
3951 case SPUR_ENABLE_IOCTL:
3952 spur_val = ah->config.spurchans[i][is2GHz];
3953 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
3954 "Getting spur val from new loc. %d\n", spur_val);
3955 break;
3956 case SPUR_ENABLE_EEPROM:
3957 spur_val = EEP_MAP9287_SPURCHAN;
3958 break;
3959 }
3960
3961 return spur_val;
3962
3963#undef EEP_MAP9287_SPURCHAN
3964}
3965
3966static struct eeprom_ops eep_AR9287_ops = {
3967 .check_eeprom = ath9k_hw_AR9287_check_eeprom,
3968 .get_eeprom = ath9k_hw_AR9287_get_eeprom,
3969 .fill_eeprom = ath9k_hw_AR9287_fill_eeprom,
3970 .get_eeprom_ver = ath9k_hw_AR9287_get_eeprom_ver,
3971 .get_eeprom_rev = ath9k_hw_AR9287_get_eeprom_rev,
3972 .get_num_ant_config = ath9k_hw_AR9287_get_num_ant_config,
3973 .get_eeprom_antenna_cfg = ath9k_hw_AR9287_get_eeprom_antenna_cfg,
3974 .set_board_values = ath9k_hw_AR9287_set_board_values,
3975 .set_addac = ath9k_hw_AR9287_set_addac,
3976 .set_txpower = ath9k_hw_AR9287_set_txpower,
3977 .get_spur_channel = ath9k_hw_AR9287_get_spur_channel
3978};
3979
3980
2784int ath9k_hw_eeprom_attach(struct ath_hw *ah) 3981int ath9k_hw_eeprom_attach(struct ath_hw *ah)
2785{ 3982{
2786 int status; 3983 int status;
2787 3984 if (AR_SREV_9287(ah)) {
2788 if (AR_SREV_9285(ah)) { 3985 ah->eep_map = EEP_MAP_AR9287;
3986 ah->eep_ops = &eep_AR9287_ops;
3987 } else if (AR_SREV_9285(ah)) {
2789 ah->eep_map = EEP_MAP_4KBITS; 3988 ah->eep_map = EEP_MAP_4KBITS;
2790 ah->eep_ops = &eep_4k_ops; 3989 ah->eep_ops = &eep_4k_ops;
2791 } else { 3990 } else {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 67b8bd12941a..7ddd016a99ff 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -100,6 +100,8 @@
100#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) 100#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
101#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ 101#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
102 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) 102 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
103#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_10_OR_LATER(ah) && \
104 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
103 105
104#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c 106#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
105#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2 107#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
@@ -176,6 +178,57 @@
176 178
177#define AR9280_TX_GAIN_TABLE_SIZE 22 179#define AR9280_TX_GAIN_TABLE_SIZE 22
178 180
181#define AR9287_EEP_VER 0xE
182#define AR9287_EEP_VER_MINOR_MASK 0xFFF
183#define AR9287_EEP_MINOR_VER_1 0x1
184#define AR9287_EEP_MINOR_VER_2 0x2
185#define AR9287_EEP_MINOR_VER_3 0x3
186#define AR9287_EEP_MINOR_VER AR9287_EEP_MINOR_VER_3
187#define AR9287_EEP_MINOR_VER_b AR9287_EEP_MINOR_VER
188#define AR9287_EEP_NO_BACK_VER AR9287_EEP_MINOR_VER_1
189
190#define AR9287_EEP_START_LOC 128
191#define AR9287_NUM_2G_CAL_PIERS 3
192#define AR9287_NUM_2G_CCK_TARGET_POWERS 3
193#define AR9287_NUM_2G_20_TARGET_POWERS 3
194#define AR9287_NUM_2G_40_TARGET_POWERS 3
195#define AR9287_NUM_CTLS 12
196#define AR9287_NUM_BAND_EDGES 4
197#define AR9287_NUM_PD_GAINS 4
198#define AR9287_PD_GAINS_IN_MASK 4
199#define AR9287_PD_GAIN_ICEPTS 1
200#define AR9287_EEPROM_MODAL_SPURS 5
201#define AR9287_MAX_RATE_POWER 63
202#define AR9287_NUM_PDADC_VALUES 128
203#define AR9287_NUM_RATES 16
204#define AR9287_BCHAN_UNUSED 0xFF
205#define AR9287_MAX_PWR_RANGE_IN_HALF_DB 64
206#define AR9287_OPFLAGS_11A 0x01
207#define AR9287_OPFLAGS_11G 0x02
208#define AR9287_OPFLAGS_2G_HT40 0x08
209#define AR9287_OPFLAGS_2G_HT20 0x20
210#define AR9287_OPFLAGS_5G_HT40 0x04
211#define AR9287_OPFLAGS_5G_HT20 0x10
212#define AR9287_EEPMISC_BIG_ENDIAN 0x01
213#define AR9287_EEPMISC_WOW 0x02
214#define AR9287_MAX_CHAINS 2
215#define AR9287_ANT_16S 32
216#define AR9287_custdatasize 20
217
218#define AR9287_NUM_ANT_CHAIN_FIELDS 6
219#define AR9287_NUM_ANT_COMMON_FIELDS 4
220#define AR9287_SIZE_ANT_CHAIN_FIELD 2
221#define AR9287_SIZE_ANT_COMMON_FIELD 4
222#define AR9287_ANT_CHAIN_MASK 0x3
223#define AR9287_ANT_COMMON_MASK 0xf
224#define AR9287_CHAIN_0_IDX 0
225#define AR9287_CHAIN_1_IDX 1
226#define AR9287_DATA_SZ 32
227
228#define AR9287_PWR_TABLE_OFFSET_DB -5
229
230#define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
231
179enum eeprom_param { 232enum eeprom_param {
180 EEP_NFTHRESH_5, 233 EEP_NFTHRESH_5,
181 EEP_NFTHRESH_2, 234 EEP_NFTHRESH_2,
@@ -199,7 +252,11 @@ enum eeprom_param {
199 EEP_OL_PWRCTRL, 252 EEP_OL_PWRCTRL,
200 EEP_RC_CHAIN_MASK, 253 EEP_RC_CHAIN_MASK,
201 EEP_DAC_HPWR_5G, 254 EEP_DAC_HPWR_5G,
202 EEP_FRAC_N_5G 255 EEP_FRAC_N_5G,
256 EEP_DEV_TYPE,
257 EEP_TEMPSENSE_SLOPE,
258 EEP_TEMPSENSE_SLOPE_PAL_ON,
259 EEP_PWR_TABLE_OFFSET
203}; 260};
204 261
205enum ar5416_rates { 262enum ar5416_rates {
@@ -368,6 +425,65 @@ struct modal_eep_4k_header {
368 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; 425 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
369} __packed; 426} __packed;
370 427
428struct base_eep_ar9287_header {
429 u16 length;
430 u16 checksum;
431 u16 version;
432 u8 opCapFlags;
433 u8 eepMisc;
434 u16 regDmn[2];
435 u8 macAddr[6];
436 u8 rxMask;
437 u8 txMask;
438 u16 rfSilent;
439 u16 blueToothOptions;
440 u16 deviceCap;
441 u32 binBuildNumber;
442 u8 deviceType;
443 u8 openLoopPwrCntl;
444 int8_t pwrTableOffset;
445 int8_t tempSensSlope;
446 int8_t tempSensSlopePalOn;
447 u8 futureBase[29];
448} __packed;
449
450struct modal_eep_ar9287_header {
451 u32 antCtrlChain[AR9287_MAX_CHAINS];
452 u32 antCtrlCommon;
453 int8_t antennaGainCh[AR9287_MAX_CHAINS];
454 u8 switchSettling;
455 u8 txRxAttenCh[AR9287_MAX_CHAINS];
456 u8 rxTxMarginCh[AR9287_MAX_CHAINS];
457 int8_t adcDesiredSize;
458 u8 txEndToXpaOff;
459 u8 txEndToRxOn;
460 u8 txFrameToXpaOn;
461 u8 thresh62;
462 int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
463 u8 xpdGain;
464 u8 xpd;
465 int8_t iqCalICh[AR9287_MAX_CHAINS];
466 int8_t iqCalQCh[AR9287_MAX_CHAINS];
467 u8 pdGainOverlap;
468 u8 xpaBiasLvl;
469 u8 txFrameToDataStart;
470 u8 txFrameToPaOn;
471 u8 ht40PowerIncForPdadc;
472 u8 bswAtten[AR9287_MAX_CHAINS];
473 u8 bswMargin[AR9287_MAX_CHAINS];
474 u8 swSettleHt40;
475 u8 version;
476 u8 db1;
477 u8 db2;
478 u8 ob_cck;
479 u8 ob_psk;
480 u8 ob_qam;
481 u8 ob_pal_off;
482 u8 futureModal[30];
483 struct spur_chan spurChans[AR9287_EEPROM_MODAL_SPURS];
484} __packed;
485
486
371 487
372struct cal_data_per_freq { 488struct cal_data_per_freq {
373 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS]; 489 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
@@ -402,6 +518,29 @@ struct cal_ctl_edges {
402} __packed; 518} __packed;
403#endif 519#endif
404 520
521struct cal_data_op_loop_ar9287 {
522 u8 pwrPdg[2][5];
523 u8 vpdPdg[2][5];
524 u8 pcdac[2][5];
525 u8 empty[2][5];
526} __packed;
527
528
529struct cal_data_per_freq_ar9287 {
530 u8 pwrPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
531 u8 vpdPdg[AR9287_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
532} __packed;
533
534union cal_data_per_freq_ar9287_u {
535 struct cal_data_op_loop_ar9287 calDataOpen;
536 struct cal_data_per_freq_ar9287 calDataClose;
537} __packed;
538
539struct cal_ctl_data_ar9287 {
540 struct cal_ctl_edges
541 ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES];
542} __packed;
543
405struct cal_ctl_data { 544struct cal_ctl_data {
406 struct cal_ctl_edges 545 struct cal_ctl_edges
407 ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES]; 546 ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
@@ -461,6 +600,27 @@ struct ar5416_eeprom_4k {
461 u8 padding; 600 u8 padding;
462} __packed; 601} __packed;
463 602
603struct ar9287_eeprom_t {
604 struct base_eep_ar9287_header baseEepHeader;
605 u8 custData[AR9287_DATA_SZ];
606 struct modal_eep_ar9287_header modalHeader;
607 u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
608 union cal_data_per_freq_ar9287_u
609 calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
610 struct cal_target_power_leg
611 calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
612 struct cal_target_power_leg
613 calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
614 struct cal_target_power_ht
615 calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
616 struct cal_target_power_ht
617 calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
618 u8 ctlIndex[AR9287_NUM_CTLS];
619 struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS];
620 u8 padding;
621} __packed;
622
623
464enum reg_ext_bitmap { 624enum reg_ext_bitmap {
465 REG_EXT_JAPAN_MIDBAND = 1, 625 REG_EXT_JAPAN_MIDBAND = 1,
466 REG_EXT_FCC_DFS_HT40 = 2, 626 REG_EXT_FCC_DFS_HT40 = 2,
@@ -480,6 +640,7 @@ struct ath9k_country_entry {
480enum ath9k_eep_map { 640enum ath9k_eep_map {
481 EEP_MAP_DEFAULT = 0x0, 641 EEP_MAP_DEFAULT = 0x0,
482 EEP_MAP_4KBITS, 642 EEP_MAP_4KBITS,
643 EEP_MAP_AR9287,
483 EEP_MAP_MAX 644 EEP_MAP_MAX
484}; 645};
485 646
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 605803ae9ed8..431854ccb65b 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -380,6 +380,9 @@ static const char *ath9k_hw_devname(u16 devid)
380 return "Atheros 9280"; 380 return "Atheros 9280";
381 case AR9285_DEVID_PCIE: 381 case AR9285_DEVID_PCIE:
382 return "Atheros 9285"; 382 return "Atheros 9285";
383 case AR5416_DEVID_AR9287_PCI:
384 case AR5416_DEVID_AR9287_PCIE:
385 return "Atheros 9287";
383 } 386 }
384 387
385 return NULL; 388 return NULL;
@@ -475,6 +478,8 @@ static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
475 478
476 ah->gbeacon_rate = 0; 479 ah->gbeacon_rate = 0;
477 480
481 ah->power_mode = ATH9K_PM_UNDEFINED;
482
478 return ah; 483 return ah;
479} 484}
480 485
@@ -660,7 +665,8 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
660 if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) && 665 if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
661 (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) && 666 (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
662 (ah->hw_version.macVersion != AR_SREV_VERSION_9160) && 667 (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
663 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) && (!AR_SREV_9285(ah))) { 668 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) &&
669 (!AR_SREV_9285(ah)) && (!AR_SREV_9287(ah))) {
664 DPRINTF(sc, ATH_DBG_FATAL, 670 DPRINTF(sc, ATH_DBG_FATAL,
665 "Mac Chip Rev 0x%02x.%x is not supported by " 671 "Mac Chip Rev 0x%02x.%x is not supported by "
666 "this driver\n", ah->hw_version.macVersion, 672 "this driver\n", ah->hw_version.macVersion,
@@ -700,8 +706,37 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
700 ah->ani_function = ATH9K_ANI_ALL; 706 ah->ani_function = ATH9K_ANI_ALL;
701 if (AR_SREV_9280_10_OR_LATER(ah)) 707 if (AR_SREV_9280_10_OR_LATER(ah))
702 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; 708 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
709 if (AR_SREV_9287_11_OR_LATER(ah)) {
710 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
711 ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
712 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
713 ARRAY_SIZE(ar9287Common_9287_1_1), 2);
714 if (ah->config.pcie_clock_req)
715 INIT_INI_ARRAY(&ah->iniPcieSerdes,
716 ar9287PciePhy_clkreq_off_L1_9287_1_1,
717 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
718 else
719 INIT_INI_ARRAY(&ah->iniPcieSerdes,
720 ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
721 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
722 2);
723 } else if (AR_SREV_9287_10_OR_LATER(ah)) {
724 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0,
725 ARRAY_SIZE(ar9287Modes_9287_1_0), 6);
726 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0,
727 ARRAY_SIZE(ar9287Common_9287_1_0), 2);
728
729 if (ah->config.pcie_clock_req)
730 INIT_INI_ARRAY(&ah->iniPcieSerdes,
731 ar9287PciePhy_clkreq_off_L1_9287_1_0,
732 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2);
733 else
734 INIT_INI_ARRAY(&ah->iniPcieSerdes,
735 ar9287PciePhy_clkreq_always_on_L1_9287_1_0,
736 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0),
737 2);
738 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
703 739
704 if (AR_SREV_9285_12_OR_LATER(ah)) {
705 740
706 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, 741 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
707 ARRAY_SIZE(ar9285Modes_9285_1_2), 6); 742 ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
@@ -842,7 +877,28 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
842 if (ecode != 0) 877 if (ecode != 0)
843 goto bad; 878 goto bad;
844 879
845 if (AR_SREV_9285_12_OR_LATER(ah)) { 880 if (AR_SREV_9287_11(ah))
881 INIT_INI_ARRAY(&ah->iniModesRxGain,
882 ar9287Modes_rx_gain_9287_1_1,
883 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
884 else if (AR_SREV_9287_10(ah))
885 INIT_INI_ARRAY(&ah->iniModesRxGain,
886 ar9287Modes_rx_gain_9287_1_0,
887 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6);
888 else if (AR_SREV_9280_20(ah))
889 ath9k_hw_init_rxgain_ini(ah);
890
891 if (AR_SREV_9287_11(ah)) {
892 INIT_INI_ARRAY(&ah->iniModesTxGain,
893 ar9287Modes_tx_gain_9287_1_1,
894 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
895 } else if (AR_SREV_9287_10(ah)) {
896 INIT_INI_ARRAY(&ah->iniModesTxGain,
897 ar9287Modes_tx_gain_9287_1_0,
898 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6);
899 } else if (AR_SREV_9280_20(ah)) {
900 ath9k_hw_init_txgain_ini(ah);
901 } else if (AR_SREV_9285_12_OR_LATER(ah)) {
846 u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); 902 u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
847 903
848 /* txgain table */ 904 /* txgain table */
@@ -858,14 +914,6 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
858 914
859 } 915 }
860 916
861 /* rxgain table */
862 if (AR_SREV_9280_20(ah))
863 ath9k_hw_init_rxgain_ini(ah);
864
865 /* txgain table */
866 if (AR_SREV_9280_20(ah))
867 ath9k_hw_init_txgain_ini(ah);
868
869 ath9k_hw_fill_cap_info(ah); 917 ath9k_hw_fill_cap_info(ah);
870 918
871 if ((ah->hw_version.devid == AR9280_DEVID_PCI) && 919 if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
@@ -1165,6 +1213,8 @@ struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
1165 case AR9280_DEVID_PCI: 1213 case AR9280_DEVID_PCI:
1166 case AR9280_DEVID_PCIE: 1214 case AR9280_DEVID_PCIE:
1167 case AR9285_DEVID_PCIE: 1215 case AR9285_DEVID_PCIE:
1216 case AR5416_DEVID_AR9287_PCI:
1217 case AR5416_DEVID_AR9287_PCIE:
1168 ah = ath9k_hw_do_attach(devid, sc, error); 1218 ah = ath9k_hw_do_attach(devid, sc, error);
1169 break; 1219 break;
1170 default: 1220 default:
@@ -1341,10 +1391,11 @@ static int ath9k_hw_process_ini(struct ath_hw *ah,
1341 DO_DELAY(regWrites); 1391 DO_DELAY(regWrites);
1342 } 1392 }
1343 1393
1344 if (AR_SREV_9280(ah)) 1394 if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah))
1345 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); 1395 REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);
1346 1396
1347 if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah)) 1397 if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||
1398 AR_SREV_9287_10_OR_LATER(ah))
1348 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); 1399 REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
1349 1400
1350 for (i = 0; i < ah->iniCommon.ia_rows; i++) { 1401 for (i = 0; i < ah->iniCommon.ia_rows; i++) {
@@ -2254,6 +2305,16 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2254 if (AR_SREV_9280_10_OR_LATER(ah)) 2305 if (AR_SREV_9280_10_OR_LATER(ah))
2255 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 2306 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
2256 2307
2308 if (AR_SREV_9287_10_OR_LATER(ah)) {
2309 /* Enable ASYNC FIFO */
2310 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
2311 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
2312 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
2313 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
2314 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
2315 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
2316 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
2317 }
2257 r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width); 2318 r = ath9k_hw_process_ini(ah, chan, sc->tx_chan_width);
2258 if (r) 2319 if (r)
2259 return r; 2320 return r;
@@ -2330,6 +2391,27 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2330 2391
2331 ath9k_hw_init_user_settings(ah); 2392 ath9k_hw_init_user_settings(ah);
2332 2393
2394 if (AR_SREV_9287_10_OR_LATER(ah)) {
2395 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
2396 AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
2397 REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
2398 AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
2399 REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
2400 AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
2401
2402 REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
2403 REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
2404
2405 REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
2406 AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
2407 REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
2408 AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
2409 }
2410 if (AR_SREV_9287_10_OR_LATER(ah)) {
2411 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
2412 AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
2413 }
2414
2333 REG_WRITE(ah, AR_STA_ID1, 2415 REG_WRITE(ah, AR_STA_ID1,
2334 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM); 2416 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
2335 2417
@@ -2739,6 +2821,9 @@ static bool ath9k_hw_setpower_nolock(struct ath_hw *ah,
2739 "UNDEFINED" 2821 "UNDEFINED"
2740 }; 2822 };
2741 2823
2824 if (ah->power_mode == mode)
2825 return status;
2826
2742 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n", 2827 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s -> %s\n",
2743 modes[ah->power_mode], modes[mode]); 2828 modes[ah->power_mode], modes[mode]);
2744 2829
@@ -2783,10 +2868,7 @@ void ath9k_ps_wakeup(struct ath_softc *sc)
2783 if (++sc->ps_usecount != 1) 2868 if (++sc->ps_usecount != 1)
2784 goto unlock; 2869 goto unlock;
2785 2870
2786 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) { 2871 ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
2787 sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
2788 ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
2789 }
2790 2872
2791 unlock: 2873 unlock:
2792 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 2874 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -2800,13 +2882,12 @@ void ath9k_ps_restore(struct ath_softc *sc)
2800 if (--sc->ps_usecount != 0) 2882 if (--sc->ps_usecount != 0)
2801 goto unlock; 2883 goto unlock;
2802 2884
2803 if ((sc->hw->conf.flags & IEEE80211_CONF_PS) && 2885 if (sc->ps_enabled &&
2804 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 2886 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
2805 SC_OP_WAIT_FOR_CAB | 2887 SC_OP_WAIT_FOR_CAB |
2806 SC_OP_WAIT_FOR_PSPOLL_DATA | 2888 SC_OP_WAIT_FOR_PSPOLL_DATA |
2807 SC_OP_WAIT_FOR_TX_ACK))) 2889 SC_OP_WAIT_FOR_TX_ACK)))
2808 ath9k_hw_setpower_nolock(sc->sc_ah, 2890 ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
2809 sc->sc_ah->restore_mode);
2810 2891
2811 unlock: 2892 unlock:
2812 spin_unlock_irqrestore(&sc->sc_pm_lock, flags); 2893 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
@@ -3644,7 +3725,9 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
3644 if (gpio >= ah->caps.num_gpio_pins) 3725 if (gpio >= ah->caps.num_gpio_pins)
3645 return 0xffffffff; 3726 return 0xffffffff;
3646 3727
3647 if (AR_SREV_9285_10_OR_LATER(ah)) 3728 if (AR_SREV_9287_10_OR_LATER(ah))
3729 return MS_REG_READ(AR9287, gpio) != 0;
3730 else if (AR_SREV_9285_10_OR_LATER(ah))
3648 return MS_REG_READ(AR9285, gpio) != 0; 3731 return MS_REG_READ(AR9285, gpio) != 0;
3649 else if (AR_SREV_9280_10_OR_LATER(ah)) 3732 else if (AR_SREV_9280_10_OR_LATER(ah))
3650 return MS_REG_READ(AR928X, gpio) != 0; 3733 return MS_REG_READ(AR928X, gpio) != 0;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 28bffdb365a2..2e196df10894 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -42,6 +42,9 @@
42#define AR_SUBVENDOR_ID_NEW_A 0x7065 42#define AR_SUBVENDOR_ID_NEW_A 0x7065
43#define AR5416_MAGIC 0x19641014 43#define AR5416_MAGIC 0x19641014
44 44
45#define AR5416_DEVID_AR9287_PCI 0x002D
46#define AR5416_DEVID_AR9287_PCIE 0x002E
47
45/* Register read/write primitives */ 48/* Register read/write primitives */
46#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val)) 49#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
47#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg)) 50#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
@@ -400,6 +403,7 @@ struct ath_hw {
400 union { 403 union {
401 struct ar5416_eeprom_def def; 404 struct ar5416_eeprom_def def;
402 struct ar5416_eeprom_4k map4k; 405 struct ar5416_eeprom_4k map4k;
406 struct ar9287_eeprom_t map9287;
403 } eeprom; 407 } eeprom;
404 const struct eeprom_ops *eep_ops; 408 const struct eeprom_ops *eep_ops;
405 enum ath9k_eep_map eep_map; 409 enum ath9k_eep_map eep_map;
@@ -417,7 +421,6 @@ struct ath_hw {
417 421
418 enum nl80211_iftype opmode; 422 enum nl80211_iftype opmode;
419 enum ath9k_power_mode power_mode; 423 enum ath9k_power_mode power_mode;
420 enum ath9k_power_mode restore_mode;
421 424
422 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; 425 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
423 struct ar5416Stats stats; 426 struct ar5416Stats stats;
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index f67a2a96cc5c..af4a1bafa7e7 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -4849,3 +4849,1519 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = {
4849 {0x00004040, 0x00043007 }, 4849 {0x00004040, 0x00043007 },
4850 {0x00004044, 0x00000000 }, 4850 {0x00004044, 0x00000000 },
4851}; 4851};
4852
4853/* AR9287 Revision 10 */
4854static const u_int32_t ar9287Modes_9287_1_0[][6] = {
4855 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
4856 { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
4857 { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
4858 { 0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180 },
4859 { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
4860 { 0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0 },
4861 { 0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f },
4862 { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
4863 { 0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a },
4864 { 0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880 },
4865 { 0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303 },
4866 { 0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200 },
4867 { 0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e },
4868 { 0x00009828, 0x00000000, 0x00000000, 0x0a020001, 0x0a020001, 0x0a020001 },
4869 { 0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e },
4870 { 0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007 },
4871 { 0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e },
4872 { 0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0 },
4873 { 0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
4874 { 0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
4875 { 0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e },
4876 { 0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18 },
4877 { 0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
4878 { 0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
4879 { 0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881 },
4880 { 0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0 },
4881 { 0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016 },
4882 { 0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
4883 { 0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010 },
4884 { 0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
4885 { 0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
4886 { 0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210 },
4887 { 0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce },
4888 { 0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c },
4889 { 0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00 },
4890 { 0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
4891 { 0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444 },
4892 { 0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4893 { 0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4894 { 0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a },
4895 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
4896 { 0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000 },
4897 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
4898 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4899};
4900
4901static const u_int32_t ar9287Common_9287_1_0[][2] = {
4902 { 0x0000000c, 0x00000000 },
4903 { 0x00000030, 0x00020015 },
4904 { 0x00000034, 0x00000005 },
4905 { 0x00000040, 0x00000000 },
4906 { 0x00000044, 0x00000008 },
4907 { 0x00000048, 0x00000008 },
4908 { 0x0000004c, 0x00000010 },
4909 { 0x00000050, 0x00000000 },
4910 { 0x00000054, 0x0000001f },
4911 { 0x00000800, 0x00000000 },
4912 { 0x00000804, 0x00000000 },
4913 { 0x00000808, 0x00000000 },
4914 { 0x0000080c, 0x00000000 },
4915 { 0x00000810, 0x00000000 },
4916 { 0x00000814, 0x00000000 },
4917 { 0x00000818, 0x00000000 },
4918 { 0x0000081c, 0x00000000 },
4919 { 0x00000820, 0x00000000 },
4920 { 0x00000824, 0x00000000 },
4921 { 0x00001040, 0x002ffc0f },
4922 { 0x00001044, 0x002ffc0f },
4923 { 0x00001048, 0x002ffc0f },
4924 { 0x0000104c, 0x002ffc0f },
4925 { 0x00001050, 0x002ffc0f },
4926 { 0x00001054, 0x002ffc0f },
4927 { 0x00001058, 0x002ffc0f },
4928 { 0x0000105c, 0x002ffc0f },
4929 { 0x00001060, 0x002ffc0f },
4930 { 0x00001064, 0x002ffc0f },
4931 { 0x00001230, 0x00000000 },
4932 { 0x00001270, 0x00000000 },
4933 { 0x00001038, 0x00000000 },
4934 { 0x00001078, 0x00000000 },
4935 { 0x000010b8, 0x00000000 },
4936 { 0x000010f8, 0x00000000 },
4937 { 0x00001138, 0x00000000 },
4938 { 0x00001178, 0x00000000 },
4939 { 0x000011b8, 0x00000000 },
4940 { 0x000011f8, 0x00000000 },
4941 { 0x00001238, 0x00000000 },
4942 { 0x00001278, 0x00000000 },
4943 { 0x000012b8, 0x00000000 },
4944 { 0x000012f8, 0x00000000 },
4945 { 0x00001338, 0x00000000 },
4946 { 0x00001378, 0x00000000 },
4947 { 0x000013b8, 0x00000000 },
4948 { 0x000013f8, 0x00000000 },
4949 { 0x00001438, 0x00000000 },
4950 { 0x00001478, 0x00000000 },
4951 { 0x000014b8, 0x00000000 },
4952 { 0x000014f8, 0x00000000 },
4953 { 0x00001538, 0x00000000 },
4954 { 0x00001578, 0x00000000 },
4955 { 0x000015b8, 0x00000000 },
4956 { 0x000015f8, 0x00000000 },
4957 { 0x00001638, 0x00000000 },
4958 { 0x00001678, 0x00000000 },
4959 { 0x000016b8, 0x00000000 },
4960 { 0x000016f8, 0x00000000 },
4961 { 0x00001738, 0x00000000 },
4962 { 0x00001778, 0x00000000 },
4963 { 0x000017b8, 0x00000000 },
4964 { 0x000017f8, 0x00000000 },
4965 { 0x0000103c, 0x00000000 },
4966 { 0x0000107c, 0x00000000 },
4967 { 0x000010bc, 0x00000000 },
4968 { 0x000010fc, 0x00000000 },
4969 { 0x0000113c, 0x00000000 },
4970 { 0x0000117c, 0x00000000 },
4971 { 0x000011bc, 0x00000000 },
4972 { 0x000011fc, 0x00000000 },
4973 { 0x0000123c, 0x00000000 },
4974 { 0x0000127c, 0x00000000 },
4975 { 0x000012bc, 0x00000000 },
4976 { 0x000012fc, 0x00000000 },
4977 { 0x0000133c, 0x00000000 },
4978 { 0x0000137c, 0x00000000 },
4979 { 0x000013bc, 0x00000000 },
4980 { 0x000013fc, 0x00000000 },
4981 { 0x0000143c, 0x00000000 },
4982 { 0x0000147c, 0x00000000 },
4983 { 0x00004030, 0x00000002 },
4984 { 0x0000403c, 0x00000002 },
4985 { 0x00004024, 0x0000001f },
4986 { 0x00004060, 0x00000000 },
4987 { 0x00004064, 0x00000000 },
4988 { 0x00007010, 0x00000033 },
4989 { 0x00007020, 0x00000000 },
4990 { 0x00007034, 0x00000002 },
4991 { 0x00007038, 0x000004c2 },
4992 { 0x00008004, 0x00000000 },
4993 { 0x00008008, 0x00000000 },
4994 { 0x0000800c, 0x00000000 },
4995 { 0x00008018, 0x00000700 },
4996 { 0x00008020, 0x00000000 },
4997 { 0x00008038, 0x00000000 },
4998 { 0x0000803c, 0x00000000 },
4999 { 0x00008048, 0x40000000 },
5000 { 0x00008054, 0x00000000 },
5001 { 0x00008058, 0x00000000 },
5002 { 0x0000805c, 0x000fc78f },
5003 { 0x00008060, 0x0000000f },
5004 { 0x00008064, 0x00000000 },
5005 { 0x00008070, 0x00000000 },
5006 { 0x000080c0, 0x2a80001a },
5007 { 0x000080c4, 0x05dc01e0 },
5008 { 0x000080c8, 0x1f402710 },
5009 { 0x000080cc, 0x01f40000 },
5010 { 0x000080d0, 0x00001e00 },
5011 { 0x000080d4, 0x00000000 },
5012 { 0x000080d8, 0x00400000 },
5013 { 0x000080e0, 0xffffffff },
5014 { 0x000080e4, 0x0000ffff },
5015 { 0x000080e8, 0x003f3f3f },
5016 { 0x000080ec, 0x00000000 },
5017 { 0x000080f0, 0x00000000 },
5018 { 0x000080f4, 0x00000000 },
5019 { 0x000080f8, 0x00000000 },
5020 { 0x000080fc, 0x00020000 },
5021 { 0x00008100, 0x00020000 },
5022 { 0x00008104, 0x00000001 },
5023 { 0x00008108, 0x00000052 },
5024 { 0x0000810c, 0x00000000 },
5025 { 0x00008110, 0x00000168 },
5026 { 0x00008118, 0x000100aa },
5027 { 0x0000811c, 0x00003210 },
5028 { 0x00008124, 0x00000000 },
5029 { 0x00008128, 0x00000000 },
5030 { 0x0000812c, 0x00000000 },
5031 { 0x00008130, 0x00000000 },
5032 { 0x00008134, 0x00000000 },
5033 { 0x00008138, 0x00000000 },
5034 { 0x0000813c, 0x00000000 },
5035 { 0x00008144, 0xffffffff },
5036 { 0x00008168, 0x00000000 },
5037 { 0x0000816c, 0x00000000 },
5038 { 0x00008170, 0x18487320 },
5039 { 0x00008174, 0xfaa4fa50 },
5040 { 0x00008178, 0x00000100 },
5041 { 0x0000817c, 0x00000000 },
5042 { 0x000081c0, 0x00000000 },
5043 { 0x000081c4, 0x00000000 },
5044 { 0x000081d4, 0x00000000 },
5045 { 0x000081ec, 0x00000000 },
5046 { 0x000081f0, 0x00000000 },
5047 { 0x000081f4, 0x00000000 },
5048 { 0x000081f8, 0x00000000 },
5049 { 0x000081fc, 0x00000000 },
5050 { 0x00008200, 0x00000000 },
5051 { 0x00008204, 0x00000000 },
5052 { 0x00008208, 0x00000000 },
5053 { 0x0000820c, 0x00000000 },
5054 { 0x00008210, 0x00000000 },
5055 { 0x00008214, 0x00000000 },
5056 { 0x00008218, 0x00000000 },
5057 { 0x0000821c, 0x00000000 },
5058 { 0x00008220, 0x00000000 },
5059 { 0x00008224, 0x00000000 },
5060 { 0x00008228, 0x00000000 },
5061 { 0x0000822c, 0x00000000 },
5062 { 0x00008230, 0x00000000 },
5063 { 0x00008234, 0x00000000 },
5064 { 0x00008238, 0x00000000 },
5065 { 0x0000823c, 0x00000000 },
5066 { 0x00008240, 0x00100000 },
5067 { 0x00008244, 0x0010f400 },
5068 { 0x00008248, 0x00000100 },
5069 { 0x0000824c, 0x0001e800 },
5070 { 0x00008250, 0x00000000 },
5071 { 0x00008254, 0x00000000 },
5072 { 0x00008258, 0x00000000 },
5073 { 0x0000825c, 0x400000ff },
5074 { 0x00008260, 0x00080922 },
5075 { 0x00008264, 0xa8a00010 },
5076 { 0x00008270, 0x00000000 },
5077 { 0x00008274, 0x40000000 },
5078 { 0x00008278, 0x003e4180 },
5079 { 0x0000827c, 0x00000000 },
5080 { 0x00008284, 0x0000002c },
5081 { 0x00008288, 0x0000002c },
5082 { 0x0000828c, 0x000000ff },
5083 { 0x00008294, 0x00000000 },
5084 { 0x00008298, 0x00000000 },
5085 { 0x0000829c, 0x00000000 },
5086 { 0x00008300, 0x00000040 },
5087 { 0x00008314, 0x00000000 },
5088 { 0x00008328, 0x00000000 },
5089 { 0x0000832c, 0x00000007 },
5090 { 0x00008330, 0x00000302 },
5091 { 0x00008334, 0x00000e00 },
5092 { 0x00008338, 0x00ff0000 },
5093 { 0x0000833c, 0x00000000 },
5094 { 0x00008340, 0x000107ff },
5095 { 0x00008344, 0x01c81043 },
5096 { 0x00008360, 0xffffffff },
5097 { 0x00008364, 0xffffffff },
5098 { 0x00008368, 0x00000000 },
5099 { 0x00008370, 0x00000000 },
5100 { 0x00008374, 0x000000ff },
5101 { 0x00008378, 0x00000000 },
5102 { 0x0000837c, 0x00000000 },
5103 { 0x00008380, 0xffffffff },
5104 { 0x00008384, 0xffffffff },
5105 { 0x00008390, 0x0fffffff },
5106 { 0x00008394, 0x0fffffff },
5107 { 0x00008398, 0x00000000 },
5108 { 0x0000839c, 0x00000000 },
5109 { 0x000083a0, 0x00000000 },
5110 { 0x00009808, 0x00000000 },
5111 { 0x0000980c, 0xafe68e30 },
5112 { 0x00009810, 0xfd14e000 },
5113 { 0x00009814, 0x9c0a9f6b },
5114 { 0x0000981c, 0x00000000 },
5115 { 0x0000982c, 0x0000a000 },
5116 { 0x00009830, 0x00000000 },
5117 { 0x0000983c, 0x00200400 },
5118 { 0x0000984c, 0x0040233c },
5119 { 0x0000a84c, 0x0040233c },
5120 { 0x00009854, 0x00000044 },
5121 { 0x00009900, 0x00000000 },
5122 { 0x00009904, 0x00000000 },
5123 { 0x00009908, 0x00000000 },
5124 { 0x0000990c, 0x00000000 },
5125 { 0x00009910, 0x10002310 },
5126 { 0x0000991c, 0x10000fff },
5127 { 0x00009920, 0x04900000 },
5128 { 0x0000a920, 0x04900000 },
5129 { 0x00009928, 0x00000001 },
5130 { 0x0000992c, 0x00000004 },
5131 { 0x00009930, 0x00000000 },
5132 { 0x0000a930, 0x00000000 },
5133 { 0x00009934, 0x1e1f2022 },
5134 { 0x00009938, 0x0a0b0c0d },
5135 { 0x0000993c, 0x00000000 },
5136 { 0x00009948, 0x9280c00a },
5137 { 0x0000994c, 0x00020028 },
5138 { 0x00009954, 0x5f3ca3de },
5139 { 0x00009958, 0x0108ecff },
5140 { 0x00009940, 0x14750604 },
5141 { 0x0000c95c, 0x004b6a8e },
5142 { 0x00009970, 0x990bb515 },
5143 { 0x00009974, 0x00000000 },
5144 { 0x00009978, 0x00000001 },
5145 { 0x0000997c, 0x00000000 },
5146 { 0x000099a0, 0x00000000 },
5147 { 0x000099a4, 0x00000001 },
5148 { 0x000099a8, 0x201fff00 },
5149 { 0x000099ac, 0x0c6f0000 },
5150 { 0x000099b0, 0x03051000 },
5151 { 0x000099b4, 0x00000820 },
5152 { 0x000099c4, 0x06336f77 },
5153 { 0x000099c8, 0x6af65329 },
5154 { 0x000099cc, 0x08f186c8 },
5155 { 0x000099d0, 0x00046384 },
5156 { 0x000099dc, 0x00000000 },
5157 { 0x000099e0, 0x00000000 },
5158 { 0x000099e4, 0xaaaaaaaa },
5159 { 0x000099e8, 0x3c466478 },
5160 { 0x000099ec, 0x0cc80caa },
5161 { 0x000099f0, 0x00000000 },
5162 { 0x000099fc, 0x00001042 },
5163 { 0x0000a1f4, 0x00fffeff },
5164 { 0x0000a1f8, 0x00f5f9ff },
5165 { 0x0000a1fc, 0xb79f6427 },
5166 { 0x0000a208, 0x803e4788 },
5167 { 0x0000a210, 0x4080a333 },
5168 { 0x0000a214, 0x40206c10 },
5169 { 0x0000a218, 0x009c4060 },
5170 { 0x0000a220, 0x01834061 },
5171 { 0x0000a224, 0x00000400 },
5172 { 0x0000a228, 0x000003b5 },
5173 { 0x0000a22c, 0x233f7180 },
5174 { 0x0000a234, 0x20202020 },
5175 { 0x0000a238, 0x20202020 },
5176 { 0x0000a23c, 0x13c889af },
5177 { 0x0000a240, 0x38490a20 },
5178 { 0x0000a244, 0x00000000 },
5179 { 0x0000a248, 0xfffffffc },
5180 { 0x0000a24c, 0x00000000 },
5181 { 0x0000a254, 0x00000000 },
5182 { 0x0000a258, 0x0cdbd380 },
5183 { 0x0000a25c, 0x0f0f0f01 },
5184 { 0x0000a260, 0xdfa91f01 },
5185 { 0x0000a264, 0x00418a11 },
5186 { 0x0000b264, 0x00418a11 },
5187 { 0x0000a268, 0x00000000 },
5188 { 0x0000a26c, 0x0e79e5c6 },
5189 { 0x0000b26c, 0x0e79e5c6 },
5190 { 0x0000d270, 0x00820820 },
5191 { 0x0000a278, 0x1ce739ce },
5192 { 0x0000a27c, 0x050701ce },
5193 { 0x0000d35c, 0x07ffffef },
5194 { 0x0000d360, 0x0fffffe7 },
5195 { 0x0000d364, 0x17ffffe5 },
5196 { 0x0000d368, 0x1fffffe4 },
5197 { 0x0000d36c, 0x37ffffe3 },
5198 { 0x0000d370, 0x3fffffe3 },
5199 { 0x0000d374, 0x57ffffe3 },
5200 { 0x0000d378, 0x5fffffe2 },
5201 { 0x0000d37c, 0x7fffffe2 },
5202 { 0x0000d380, 0x7f3c7bba },
5203 { 0x0000d384, 0xf3307ff0 },
5204 { 0x0000a388, 0x0c000000 },
5205 { 0x0000a38c, 0x20202020 },
5206 { 0x0000a390, 0x20202020 },
5207 { 0x0000a394, 0x1ce739ce },
5208 { 0x0000a398, 0x000001ce },
5209 { 0x0000b398, 0x000001ce },
5210 { 0x0000a39c, 0x00000001 },
5211 { 0x0000a3c8, 0x00000246 },
5212 { 0x0000a3cc, 0x20202020 },
5213 { 0x0000a3d0, 0x20202020 },
5214 { 0x0000a3d4, 0x20202020 },
5215 { 0x0000a3dc, 0x1ce739ce },
5216 { 0x0000a3e0, 0x000001ce },
5217 { 0x0000a3e4, 0x00000000 },
5218 { 0x0000a3e8, 0x18c43433 },
5219 { 0x0000a3ec, 0x00f70081 },
5220 { 0x0000a3f0, 0x01036a1e },
5221 { 0x0000a3f4, 0x00000000 },
5222 { 0x0000b3f4, 0x00000000 },
5223 { 0x0000a7d8, 0x00000001 },
5224 { 0x00007800, 0x00000800 },
5225 { 0x00007804, 0x6c35ffb0 },
5226 { 0x00007808, 0x6db6c000 },
5227 { 0x0000780c, 0x6db6cb30 },
5228 { 0x00007810, 0x6db6cb6c },
5229 { 0x00007814, 0x0501e200 },
5230 { 0x00007818, 0x0094128d },
5231 { 0x0000781c, 0x976ee392 },
5232 { 0x00007820, 0xf75ff6fc },
5233 { 0x00007824, 0x00040000 },
5234 { 0x00007828, 0xdb003012 },
5235 { 0x0000782c, 0x04924914 },
5236 { 0x00007830, 0x21084210 },
5237 { 0x00007834, 0x00140000 },
5238 { 0x00007838, 0x0e4548d8 },
5239 { 0x0000783c, 0x54214514 },
5240 { 0x00007840, 0x02025820 },
5241 { 0x00007844, 0x71c0d388 },
5242 { 0x00007848, 0x934934a8 },
5243 { 0x00007850, 0x00000000 },
5244 { 0x00007854, 0x00000800 },
5245 { 0x00007858, 0x6c35ffb0 },
5246 { 0x0000785c, 0x6db6c000 },
5247 { 0x00007860, 0x6db6cb2c },
5248 { 0x00007864, 0x6db6cb6c },
5249 { 0x00007868, 0x0501e200 },
5250 { 0x0000786c, 0x0094128d },
5251 { 0x00007870, 0x976ee392 },
5252 { 0x00007874, 0xf75ff6fc },
5253 { 0x00007878, 0x00040000 },
5254 { 0x0000787c, 0xdb003012 },
5255 { 0x00007880, 0x04924914 },
5256 { 0x00007884, 0x21084210 },
5257 { 0x00007888, 0x001b6db0 },
5258 { 0x0000788c, 0x00376b63 },
5259 { 0x00007890, 0x06db6db6 },
5260 { 0x00007894, 0x006d8000 },
5261 { 0x00007898, 0x48100000 },
5262 { 0x0000789c, 0x00000000 },
5263 { 0x000078a0, 0x08000000 },
5264 { 0x000078a4, 0x0007ffd8 },
5265 { 0x000078a8, 0x0007ffd8 },
5266 { 0x000078ac, 0x001c0020 },
5267 { 0x000078b0, 0x000611eb },
5268 { 0x000078b4, 0x40008080 },
5269 { 0x000078b8, 0x2a850160 },
5270};
5271
5272static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = {
5273 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
5274 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
5275 { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
5276 { 0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004 },
5277 { 0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a },
5278 { 0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c },
5279 { 0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b },
5280 { 0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a },
5281 { 0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a },
5282 { 0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a },
5283 { 0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a },
5284 { 0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a },
5285 { 0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a },
5286 { 0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a },
5287 { 0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a },
5288 { 0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c },
5289 { 0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc },
5290 { 0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4 },
5291 { 0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc },
5292 { 0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede },
5293 { 0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e },
5294 { 0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e },
5295 { 0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e },
5296 { 0x0000a780, 0x00000000, 0x00000000, 0x00000060, 0x00000060, 0x00000060 },
5297 { 0x0000a784, 0x00000000, 0x00000000, 0x00004062, 0x00004062, 0x00004062 },
5298 { 0x0000a788, 0x00000000, 0x00000000, 0x00008064, 0x00008064, 0x00008064 },
5299 { 0x0000a78c, 0x00000000, 0x00000000, 0x0000c0a4, 0x0000c0a4, 0x0000c0a4 },
5300 { 0x0000a790, 0x00000000, 0x00000000, 0x000100b0, 0x000100b0, 0x000100b0 },
5301 { 0x0000a794, 0x00000000, 0x00000000, 0x000140b2, 0x000140b2, 0x000140b2 },
5302 { 0x0000a798, 0x00000000, 0x00000000, 0x000180b4, 0x000180b4, 0x000180b4 },
5303 { 0x0000a79c, 0x00000000, 0x00000000, 0x0001c0f4, 0x0001c0f4, 0x0001c0f4 },
5304 { 0x0000a7a0, 0x00000000, 0x00000000, 0x00020134, 0x00020134, 0x00020134 },
5305 { 0x0000a7a4, 0x00000000, 0x00000000, 0x000240fe, 0x000240fe, 0x000240fe },
5306 { 0x0000a7a8, 0x00000000, 0x00000000, 0x0002813e, 0x0002813e, 0x0002813e },
5307 { 0x0000a7ac, 0x00000000, 0x00000000, 0x0002c17e, 0x0002c17e, 0x0002c17e },
5308 { 0x0000a7b0, 0x00000000, 0x00000000, 0x000301be, 0x000301be, 0x000301be },
5309 { 0x0000a7b4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5310 { 0x0000a7b8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5311 { 0x0000a7bc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5312 { 0x0000a7c0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5313 { 0x0000a7c4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5314 { 0x0000a7c8, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5315 { 0x0000a7cc, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5316 { 0x0000a7d0, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5317 { 0x0000a7d4, 0x00000000, 0x00000000, 0x000341fe, 0x000341fe, 0x000341fe },
5318 { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 },
5319};
5320
5321
5322static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = {
5323 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
5324 { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
5325 { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
5326 { 0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
5327 { 0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
5328 { 0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
5329 { 0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
5330 { 0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
5331 { 0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
5332 { 0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
5333 { 0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
5334 { 0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
5335 { 0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
5336 { 0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
5337 { 0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
5338 { 0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
5339 { 0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
5340 { 0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
5341 { 0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
5342 { 0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
5343 { 0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
5344 { 0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
5345 { 0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
5346 { 0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
5347 { 0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
5348 { 0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
5349 { 0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
5350 { 0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
5351 { 0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
5352 { 0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
5353 { 0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
5354 { 0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
5355 { 0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
5356 { 0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
5357 { 0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
5358 { 0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
5359 { 0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
5360 { 0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
5361 { 0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
5362 { 0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
5363 { 0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
5364 { 0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
5365 { 0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
5366 { 0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
5367 { 0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
5368 { 0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
5369 { 0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
5370 { 0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
5371 { 0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
5372 { 0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
5373 { 0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
5374 { 0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
5375 { 0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
5376 { 0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
5377 { 0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
5378 { 0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
5379 { 0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
5380 { 0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
5381 { 0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
5382 { 0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
5383 { 0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
5384 { 0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
5385 { 0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
5386 { 0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
5387 { 0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
5388 { 0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
5389 { 0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
5390 { 0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
5391 { 0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
5392 { 0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
5393 { 0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
5394 { 0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
5395 { 0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
5396 { 0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
5397 { 0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
5398 { 0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
5399 { 0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
5400 { 0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
5401 { 0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
5402 { 0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
5403 { 0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
5404 { 0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
5405 { 0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
5406 { 0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
5407 { 0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
5408 { 0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
5409 { 0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
5410 { 0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
5411 { 0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
5412 { 0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
5413 { 0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
5414 { 0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
5415 { 0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
5416 { 0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
5417 { 0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
5418 { 0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
5419 { 0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
5420 { 0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
5421 { 0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
5422 { 0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
5423 { 0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
5424 { 0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
5425 { 0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
5426 { 0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
5427 { 0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5428 { 0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5429 { 0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5430 { 0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5431 { 0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5432 { 0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5433 { 0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5434 { 0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5435 { 0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5436 { 0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5437 { 0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5438 { 0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5439 { 0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5440 { 0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5441 { 0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5442 { 0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5443 { 0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5444 { 0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5445 { 0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5446 { 0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5447 { 0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5448 { 0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5449 { 0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5450 { 0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5451 { 0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5452 { 0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
5453 { 0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
5454 { 0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
5455 { 0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
5456 { 0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
5457 { 0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
5458 { 0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
5459 { 0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
5460 { 0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
5461 { 0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
5462 { 0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
5463 { 0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
5464 { 0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
5465 { 0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
5466 { 0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
5467 { 0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
5468 { 0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
5469 { 0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
5470 { 0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
5471 { 0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
5472 { 0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
5473 { 0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
5474 { 0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
5475 { 0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
5476 { 0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
5477 { 0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
5478 { 0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
5479 { 0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
5480 { 0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
5481 { 0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
5482 { 0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
5483 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
5484 { 0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
5485 { 0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
5486 { 0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
5487 { 0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
5488 { 0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
5489 { 0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
5490 { 0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
5491 { 0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
5492 { 0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
5493 { 0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
5494 { 0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
5495 { 0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
5496 { 0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
5497 { 0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
5498 { 0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
5499 { 0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
5500 { 0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
5501 { 0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
5502 { 0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
5503 { 0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
5504 { 0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
5505 { 0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
5506 { 0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
5507 { 0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
5508 { 0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
5509 { 0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
5510 { 0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
5511 { 0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
5512 { 0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
5513 { 0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
5514 { 0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
5515 { 0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
5516 { 0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
5517 { 0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
5518 { 0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
5519 { 0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
5520 { 0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
5521 { 0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
5522 { 0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
5523 { 0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
5524 { 0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
5525 { 0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
5526 { 0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
5527 { 0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
5528 { 0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
5529 { 0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
5530 { 0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
5531 { 0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
5532 { 0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
5533 { 0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
5534 { 0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
5535 { 0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
5536 { 0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
5537 { 0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
5538 { 0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
5539 { 0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
5540 { 0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
5541 { 0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
5542 { 0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
5543 { 0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
5544 { 0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
5545 { 0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
5546 { 0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
5547 { 0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
5548 { 0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
5549 { 0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
5550 { 0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
5551 { 0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
5552 { 0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
5553 { 0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
5554 { 0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
5555 { 0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5556 { 0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5557 { 0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5558 { 0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5559 { 0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5560 { 0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5561 { 0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5562 { 0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5563 { 0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5564 { 0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5565 { 0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5566 { 0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5567 { 0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5568 { 0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5569 { 0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5570 { 0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5571 { 0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5572 { 0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5573 { 0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5574 { 0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5575 { 0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5576 { 0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5577 { 0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5578 { 0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5579 { 0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
5580 { 0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
5581 { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
5582};
5583
5584static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = {
5585 {0x00004040, 0x9248fd00 },
5586 {0x00004040, 0x24924924 },
5587 {0x00004040, 0xa8000019 },
5588 {0x00004040, 0x13160820 },
5589 {0x00004040, 0xe5980560 },
5590 {0x00004040, 0xc01dcffd },
5591 {0x00004040, 0x1aaabe41 },
5592 {0x00004040, 0xbe105554 },
5593 {0x00004040, 0x00043007 },
5594 {0x00004044, 0x00000000 },
5595};
5596
5597static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = {
5598 {0x00004040, 0x9248fd00 },
5599 {0x00004040, 0x24924924 },
5600 {0x00004040, 0xa8000019 },
5601 {0x00004040, 0x13160820 },
5602 {0x00004040, 0xe5980560 },
5603 {0x00004040, 0xc01dcffc },
5604 {0x00004040, 0x1aaabe41 },
5605 {0x00004040, 0xbe105554 },
5606 {0x00004040, 0x00043007 },
5607 {0x00004044, 0x00000000 },
5608};
5609
5610/* AR9287 Revision 11 */
5611
5612static const u_int32_t ar9287Modes_9287_1_1[][6] = {
5613 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
5614 { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 },
5615 { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 },
5616 { 0x000010b0, 0x00000000, 0x00000000, 0x00007c70, 0x00003e38, 0x00001180 },
5617 { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
5618 { 0x00008014, 0x00000000, 0x00000000, 0x10801600, 0x08400b00, 0x06e006e0 },
5619 { 0x0000801c, 0x00000000, 0x00000000, 0x12e00057, 0x12e0002b, 0x0988004f },
5620 { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 },
5621 { 0x000081d0, 0x00003200, 0x00003200, 0x0000320a, 0x0000320a, 0x0000320a },
5622 { 0x00008318, 0x00000000, 0x00000000, 0x00006880, 0x00003440, 0x00006880 },
5623 { 0x00009804, 0x00000000, 0x00000000, 0x000003c4, 0x00000300, 0x00000303 },
5624 { 0x00009820, 0x00000000, 0x00000000, 0x02020200, 0x02020200, 0x02020200 },
5625 { 0x00009824, 0x00000000, 0x00000000, 0x01000e0e, 0x01000e0e, 0x01000e0e },
5626 { 0x00009828, 0x00000000, 0x00000000, 0x3a020001, 0x3a020001, 0x3a020001 },
5627 { 0x00009834, 0x00000000, 0x00000000, 0x00000e0e, 0x00000e0e, 0x00000e0e },
5628 { 0x00009838, 0x00000003, 0x00000003, 0x00000007, 0x00000007, 0x00000007 },
5629 { 0x00009840, 0x206a002e, 0x206a002e, 0x206a012e, 0x206a012e, 0x206a012e },
5630 { 0x00009844, 0x03720000, 0x03720000, 0x037216a0, 0x037216a0, 0x037216a0 },
5631 { 0x00009850, 0x60000000, 0x60000000, 0x6d4000e2, 0x6c4000e2, 0x6c4000e2 },
5632 { 0x00009858, 0x7c000d00, 0x7c000d00, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
5633 { 0x0000985c, 0x3100005e, 0x3100005e, 0x3139605e, 0x31395d5e, 0x31395d5e },
5634 { 0x00009860, 0x00058d00, 0x00058d00, 0x00058d20, 0x00058d20, 0x00058d18 },
5635 { 0x00009864, 0x00000e00, 0x00000e00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
5636 { 0x00009868, 0x000040c0, 0x000040c0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
5637 { 0x0000986c, 0x00000080, 0x00000080, 0x06903881, 0x06903881, 0x06903881 },
5638 { 0x00009914, 0x00000000, 0x00000000, 0x00001130, 0x00000898, 0x000007d0 },
5639 { 0x00009918, 0x00000000, 0x00000000, 0x00000016, 0x0000000b, 0x00000016 },
5640 { 0x00009924, 0xd00a8a01, 0xd00a8a01, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
5641 { 0x00009944, 0xefbc0000, 0xefbc0000, 0xefbc1010, 0xefbc1010, 0xefbc1010 },
5642 { 0x00009960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
5643 { 0x0000a960, 0x00000000, 0x00000000, 0x00000010, 0x00000010, 0x00000010 },
5644 { 0x00009964, 0x00000000, 0x00000000, 0x00000210, 0x00000210, 0x00000210 },
5645 { 0x0000c968, 0x00000200, 0x00000200, 0x000003ce, 0x000003ce, 0x000003ce },
5646 { 0x000099b8, 0x00000000, 0x00000000, 0x0000001c, 0x0000001c, 0x0000001c },
5647 { 0x000099bc, 0x00000000, 0x00000000, 0x00000c00, 0x00000c00, 0x00000c00 },
5648 { 0x000099c0, 0x00000000, 0x00000000, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
5649 { 0x0000a204, 0x00000440, 0x00000440, 0x00000444, 0x00000444, 0x00000444 },
5650 { 0x0000a20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
5651 { 0x0000b20c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
5652 { 0x0000a21c, 0x1803800a, 0x1803800a, 0x1883800a, 0x1883800a, 0x1883800a },
5653 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
5654 { 0x0000a250, 0x00000000, 0x00000000, 0x0004a000, 0x0004a000, 0x0004a000 },
5655 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
5656 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
5657};
5658
5659static const u_int32_t ar9287Common_9287_1_1[][2] = {
5660 { 0x0000000c, 0x00000000 },
5661 { 0x00000030, 0x00020015 },
5662 { 0x00000034, 0x00000005 },
5663 { 0x00000040, 0x00000000 },
5664 { 0x00000044, 0x00000008 },
5665 { 0x00000048, 0x00000008 },
5666 { 0x0000004c, 0x00000010 },
5667 { 0x00000050, 0x00000000 },
5668 { 0x00000054, 0x0000001f },
5669 { 0x00000800, 0x00000000 },
5670 { 0x00000804, 0x00000000 },
5671 { 0x00000808, 0x00000000 },
5672 { 0x0000080c, 0x00000000 },
5673 { 0x00000810, 0x00000000 },
5674 { 0x00000814, 0x00000000 },
5675 { 0x00000818, 0x00000000 },
5676 { 0x0000081c, 0x00000000 },
5677 { 0x00000820, 0x00000000 },
5678 { 0x00000824, 0x00000000 },
5679 { 0x00001040, 0x002ffc0f },
5680 { 0x00001044, 0x002ffc0f },
5681 { 0x00001048, 0x002ffc0f },
5682 { 0x0000104c, 0x002ffc0f },
5683 { 0x00001050, 0x002ffc0f },
5684 { 0x00001054, 0x002ffc0f },
5685 { 0x00001058, 0x002ffc0f },
5686 { 0x0000105c, 0x002ffc0f },
5687 { 0x00001060, 0x002ffc0f },
5688 { 0x00001064, 0x002ffc0f },
5689 { 0x00001230, 0x00000000 },
5690 { 0x00001270, 0x00000000 },
5691 { 0x00001038, 0x00000000 },
5692 { 0x00001078, 0x00000000 },
5693 { 0x000010b8, 0x00000000 },
5694 { 0x000010f8, 0x00000000 },
5695 { 0x00001138, 0x00000000 },
5696 { 0x00001178, 0x00000000 },
5697 { 0x000011b8, 0x00000000 },
5698 { 0x000011f8, 0x00000000 },
5699 { 0x00001238, 0x00000000 },
5700 { 0x00001278, 0x00000000 },
5701 { 0x000012b8, 0x00000000 },
5702 { 0x000012f8, 0x00000000 },
5703 { 0x00001338, 0x00000000 },
5704 { 0x00001378, 0x00000000 },
5705 { 0x000013b8, 0x00000000 },
5706 { 0x000013f8, 0x00000000 },
5707 { 0x00001438, 0x00000000 },
5708 { 0x00001478, 0x00000000 },
5709 { 0x000014b8, 0x00000000 },
5710 { 0x000014f8, 0x00000000 },
5711 { 0x00001538, 0x00000000 },
5712 { 0x00001578, 0x00000000 },
5713 { 0x000015b8, 0x00000000 },
5714 { 0x000015f8, 0x00000000 },
5715 { 0x00001638, 0x00000000 },
5716 { 0x00001678, 0x00000000 },
5717 { 0x000016b8, 0x00000000 },
5718 { 0x000016f8, 0x00000000 },
5719 { 0x00001738, 0x00000000 },
5720 { 0x00001778, 0x00000000 },
5721 { 0x000017b8, 0x00000000 },
5722 { 0x000017f8, 0x00000000 },
5723 { 0x0000103c, 0x00000000 },
5724 { 0x0000107c, 0x00000000 },
5725 { 0x000010bc, 0x00000000 },
5726 { 0x000010fc, 0x00000000 },
5727 { 0x0000113c, 0x00000000 },
5728 { 0x0000117c, 0x00000000 },
5729 { 0x000011bc, 0x00000000 },
5730 { 0x000011fc, 0x00000000 },
5731 { 0x0000123c, 0x00000000 },
5732 { 0x0000127c, 0x00000000 },
5733 { 0x000012bc, 0x00000000 },
5734 { 0x000012fc, 0x00000000 },
5735 { 0x0000133c, 0x00000000 },
5736 { 0x0000137c, 0x00000000 },
5737 { 0x000013bc, 0x00000000 },
5738 { 0x000013fc, 0x00000000 },
5739 { 0x0000143c, 0x00000000 },
5740 { 0x0000147c, 0x00000000 },
5741 { 0x00004030, 0x00000002 },
5742 { 0x0000403c, 0x00000002 },
5743 { 0x00004024, 0x0000001f },
5744 { 0x00004060, 0x00000000 },
5745 { 0x00004064, 0x00000000 },
5746 { 0x00007010, 0x00000033 },
5747 { 0x00007020, 0x00000000 },
5748 { 0x00007034, 0x00000002 },
5749 { 0x00007038, 0x000004c2 },
5750 { 0x00008004, 0x00000000 },
5751 { 0x00008008, 0x00000000 },
5752 { 0x0000800c, 0x00000000 },
5753 { 0x00008018, 0x00000700 },
5754 { 0x00008020, 0x00000000 },
5755 { 0x00008038, 0x00000000 },
5756 { 0x0000803c, 0x00000000 },
5757 { 0x00008048, 0x40000000 },
5758 { 0x00008054, 0x00000000 },
5759 { 0x00008058, 0x00000000 },
5760 { 0x0000805c, 0x000fc78f },
5761 { 0x00008060, 0x0000000f },
5762 { 0x00008064, 0x00000000 },
5763 { 0x00008070, 0x00000000 },
5764 { 0x000080c0, 0x2a80001a },
5765 { 0x000080c4, 0x05dc01e0 },
5766 { 0x000080c8, 0x1f402710 },
5767 { 0x000080cc, 0x01f40000 },
5768 { 0x000080d0, 0x00001e00 },
5769 { 0x000080d4, 0x00000000 },
5770 { 0x000080d8, 0x00400000 },
5771 { 0x000080e0, 0xffffffff },
5772 { 0x000080e4, 0x0000ffff },
5773 { 0x000080e8, 0x003f3f3f },
5774 { 0x000080ec, 0x00000000 },
5775 { 0x000080f0, 0x00000000 },
5776 { 0x000080f4, 0x00000000 },
5777 { 0x000080f8, 0x00000000 },
5778 { 0x000080fc, 0x00020000 },
5779 { 0x00008100, 0x00020000 },
5780 { 0x00008104, 0x00000001 },
5781 { 0x00008108, 0x00000052 },
5782 { 0x0000810c, 0x00000000 },
5783 { 0x00008110, 0x00000168 },
5784 { 0x00008118, 0x000100aa },
5785 { 0x0000811c, 0x00003210 },
5786 { 0x00008124, 0x00000000 },
5787 { 0x00008128, 0x00000000 },
5788 { 0x0000812c, 0x00000000 },
5789 { 0x00008130, 0x00000000 },
5790 { 0x00008134, 0x00000000 },
5791 { 0x00008138, 0x00000000 },
5792 { 0x0000813c, 0x00000000 },
5793 { 0x00008144, 0xffffffff },
5794 { 0x00008168, 0x00000000 },
5795 { 0x0000816c, 0x00000000 },
5796 { 0x00008170, 0x18487320 },
5797 { 0x00008174, 0xfaa4fa50 },
5798 { 0x00008178, 0x00000100 },
5799 { 0x0000817c, 0x00000000 },
5800 { 0x000081c0, 0x00000000 },
5801 { 0x000081c4, 0x00000000 },
5802 { 0x000081d4, 0x00000000 },
5803 { 0x000081ec, 0x00000000 },
5804 { 0x000081f0, 0x00000000 },
5805 { 0x000081f4, 0x00000000 },
5806 { 0x000081f8, 0x00000000 },
5807 { 0x000081fc, 0x00000000 },
5808 { 0x00008200, 0x00000000 },
5809 { 0x00008204, 0x00000000 },
5810 { 0x00008208, 0x00000000 },
5811 { 0x0000820c, 0x00000000 },
5812 { 0x00008210, 0x00000000 },
5813 { 0x00008214, 0x00000000 },
5814 { 0x00008218, 0x00000000 },
5815 { 0x0000821c, 0x00000000 },
5816 { 0x00008220, 0x00000000 },
5817 { 0x00008224, 0x00000000 },
5818 { 0x00008228, 0x00000000 },
5819 { 0x0000822c, 0x00000000 },
5820 { 0x00008230, 0x00000000 },
5821 { 0x00008234, 0x00000000 },
5822 { 0x00008238, 0x00000000 },
5823 { 0x0000823c, 0x00000000 },
5824 { 0x00008240, 0x00100000 },
5825 { 0x00008244, 0x0010f400 },
5826 { 0x00008248, 0x00000100 },
5827 { 0x0000824c, 0x0001e800 },
5828 { 0x00008250, 0x00000000 },
5829 { 0x00008254, 0x00000000 },
5830 { 0x00008258, 0x00000000 },
5831 { 0x0000825c, 0x400000ff },
5832 { 0x00008260, 0x00080922 },
5833 { 0x00008264, 0x88a00010 },
5834 { 0x00008270, 0x00000000 },
5835 { 0x00008274, 0x40000000 },
5836 { 0x00008278, 0x003e4180 },
5837 { 0x0000827c, 0x00000000 },
5838 { 0x00008284, 0x0000002c },
5839 { 0x00008288, 0x0000002c },
5840 { 0x0000828c, 0x000000ff },
5841 { 0x00008294, 0x00000000 },
5842 { 0x00008298, 0x00000000 },
5843 { 0x0000829c, 0x00000000 },
5844 { 0x00008300, 0x00000040 },
5845 { 0x00008314, 0x00000000 },
5846 { 0x00008328, 0x00000000 },
5847 { 0x0000832c, 0x00000007 },
5848 { 0x00008330, 0x00000302 },
5849 { 0x00008334, 0x00000e00 },
5850 { 0x00008338, 0x00ff0000 },
5851 { 0x0000833c, 0x00000000 },
5852 { 0x00008340, 0x000107ff },
5853 { 0x00008344, 0x01c81043 },
5854 { 0x00008360, 0xffffffff },
5855 { 0x00008364, 0xffffffff },
5856 { 0x00008368, 0x00000000 },
5857 { 0x00008370, 0x00000000 },
5858 { 0x00008374, 0x000000ff },
5859 { 0x00008378, 0x00000000 },
5860 { 0x0000837c, 0x00000000 },
5861 { 0x00008380, 0xffffffff },
5862 { 0x00008384, 0xffffffff },
5863 { 0x00008390, 0x0fffffff },
5864 { 0x00008394, 0x0fffffff },
5865 { 0x00008398, 0x00000000 },
5866 { 0x0000839c, 0x00000000 },
5867 { 0x000083a0, 0x00000000 },
5868 { 0x00009808, 0x00000000 },
5869 { 0x0000980c, 0xafe68e30 },
5870 { 0x00009810, 0xfd14e000 },
5871 { 0x00009814, 0x9c0a9f6b },
5872 { 0x0000981c, 0x00000000 },
5873 { 0x0000982c, 0x0000a000 },
5874 { 0x00009830, 0x00000000 },
5875 { 0x0000983c, 0x00200400 },
5876 { 0x0000984c, 0x0040233c },
5877 { 0x0000a84c, 0x0040233c },
5878 { 0x00009854, 0x00000044 },
5879 { 0x00009900, 0x00000000 },
5880 { 0x00009904, 0x00000000 },
5881 { 0x00009908, 0x00000000 },
5882 { 0x0000990c, 0x00000000 },
5883 { 0x00009910, 0x10002310 },
5884 { 0x0000991c, 0x10000fff },
5885 { 0x00009920, 0x04900000 },
5886 { 0x0000a920, 0x04900000 },
5887 { 0x00009928, 0x00000001 },
5888 { 0x0000992c, 0x00000004 },
5889 { 0x00009930, 0x00000000 },
5890 { 0x0000a930, 0x00000000 },
5891 { 0x00009934, 0x1e1f2022 },
5892 { 0x00009938, 0x0a0b0c0d },
5893 { 0x0000993c, 0x00000000 },
5894 { 0x00009948, 0x9280c00a },
5895 { 0x0000994c, 0x00020028 },
5896 { 0x00009954, 0x5f3ca3de },
5897 { 0x00009958, 0x0108ecff },
5898 { 0x00009940, 0x14750604 },
5899 { 0x0000c95c, 0x004b6a8e },
5900 { 0x00009970, 0x990bb514 },
5901 { 0x00009974, 0x00000000 },
5902 { 0x00009978, 0x00000001 },
5903 { 0x0000997c, 0x00000000 },
5904 { 0x000099a0, 0x00000000 },
5905 { 0x000099a4, 0x00000001 },
5906 { 0x000099a8, 0x201fff00 },
5907 { 0x000099ac, 0x0c6f0000 },
5908 { 0x000099b0, 0x03051000 },
5909 { 0x000099b4, 0x00000820 },
5910 { 0x000099c4, 0x06336f77 },
5911 { 0x000099c8, 0x6af6532f },
5912 { 0x000099cc, 0x08f186c8 },
5913 { 0x000099d0, 0x00046384 },
5914 { 0x000099dc, 0x00000000 },
5915 { 0x000099e0, 0x00000000 },
5916 { 0x000099e4, 0xaaaaaaaa },
5917 { 0x000099e8, 0x3c466478 },
5918 { 0x000099ec, 0x0cc80caa },
5919 { 0x000099f0, 0x00000000 },
5920 { 0x000099fc, 0x00001042 },
5921 { 0x0000a1f4, 0x00fffeff },
5922 { 0x0000a1f8, 0x00f5f9ff },
5923 { 0x0000a1fc, 0xb79f6427 },
5924 { 0x0000a208, 0x803e4788 },
5925 { 0x0000a210, 0x4080a333 },
5926 { 0x0000a214, 0x40206c10 },
5927 { 0x0000a218, 0x009c4060 },
5928 { 0x0000a220, 0x01834061 },
5929 { 0x0000a224, 0x00000400 },
5930 { 0x0000a228, 0x000003b5 },
5931 { 0x0000a22c, 0x233f7180 },
5932 { 0x0000a234, 0x20202020 },
5933 { 0x0000a238, 0x20202020 },
5934 { 0x0000a23c, 0x13c889af },
5935 { 0x0000a240, 0x38490a20 },
5936 { 0x0000a244, 0x00000000 },
5937 { 0x0000a248, 0xfffffffc },
5938 { 0x0000a24c, 0x00000000 },
5939 { 0x0000a254, 0x00000000 },
5940 { 0x0000a258, 0x0cdbd380 },
5941 { 0x0000a25c, 0x0f0f0f01 },
5942 { 0x0000a260, 0xdfa91f01 },
5943 { 0x0000a264, 0x00418a11 },
5944 { 0x0000b264, 0x00418a11 },
5945 { 0x0000a268, 0x00000000 },
5946 { 0x0000a26c, 0x0e79e5c6 },
5947 { 0x0000b26c, 0x0e79e5c6 },
5948 { 0x0000d270, 0x00820820 },
5949 { 0x0000a278, 0x1ce739ce },
5950 { 0x0000a27c, 0x050701ce },
5951 { 0x0000d35c, 0x07ffffef },
5952 { 0x0000d360, 0x0fffffe7 },
5953 { 0x0000d364, 0x17ffffe5 },
5954 { 0x0000d368, 0x1fffffe4 },
5955 { 0x0000d36c, 0x37ffffe3 },
5956 { 0x0000d370, 0x3fffffe3 },
5957 { 0x0000d374, 0x57ffffe3 },
5958 { 0x0000d378, 0x5fffffe2 },
5959 { 0x0000d37c, 0x7fffffe2 },
5960 { 0x0000d380, 0x7f3c7bba },
5961 { 0x0000d384, 0xf3307ff0 },
5962 { 0x0000a388, 0x0c000000 },
5963 { 0x0000a38c, 0x20202020 },
5964 { 0x0000a390, 0x20202020 },
5965 { 0x0000a394, 0x1ce739ce },
5966 { 0x0000a398, 0x000001ce },
5967 { 0x0000b398, 0x000001ce },
5968 { 0x0000a39c, 0x00000001 },
5969 { 0x0000a3c8, 0x00000246 },
5970 { 0x0000a3cc, 0x20202020 },
5971 { 0x0000a3d0, 0x20202020 },
5972 { 0x0000a3d4, 0x20202020 },
5973 { 0x0000a3dc, 0x1ce739ce },
5974 { 0x0000a3e0, 0x000001ce },
5975 { 0x0000a3e4, 0x00000000 },
5976 { 0x0000a3e8, 0x18c43433 },
5977 { 0x0000a3ec, 0x00f70081 },
5978 { 0x0000a3f0, 0x01036a1e },
5979 { 0x0000a3f4, 0x00000000 },
5980 { 0x0000b3f4, 0x00000000 },
5981 { 0x0000a7d8, 0x000003f1 },
5982 { 0x00007800, 0x00000800 },
5983 { 0x00007804, 0x6c35ffc2 },
5984 { 0x00007808, 0x6db6c000 },
5985 { 0x0000780c, 0x6db6cb30 },
5986 { 0x00007810, 0x6db6cb6c },
5987 { 0x00007814, 0x0501e200 },
5988 { 0x00007818, 0x0094128d },
5989 { 0x0000781c, 0x976ee392 },
5990 { 0x00007820, 0xf75ff6fc },
5991 { 0x00007824, 0x00040000 },
5992 { 0x00007828, 0xdb003012 },
5993 { 0x0000782c, 0x04924914 },
5994 { 0x00007830, 0x21084210 },
5995 { 0x00007834, 0x00140000 },
5996 { 0x00007838, 0x0e4548d8 },
5997 { 0x0000783c, 0x54214514 },
5998 { 0x00007840, 0x02025830 },
5999 { 0x00007844, 0x71c0d388 },
6000 { 0x00007848, 0x934934a8 },
6001 { 0x00007850, 0x00000000 },
6002 { 0x00007854, 0x00000800 },
6003 { 0x00007858, 0x6c35ffc2 },
6004 { 0x0000785c, 0x6db6c000 },
6005 { 0x00007860, 0x6db6cb30 },
6006 { 0x00007864, 0x6db6cb6c },
6007 { 0x00007868, 0x0501e200 },
6008 { 0x0000786c, 0x0094128d },
6009 { 0x00007870, 0x976ee392 },
6010 { 0x00007874, 0xf75ff6fc },
6011 { 0x00007878, 0x00040000 },
6012 { 0x0000787c, 0xdb003012 },
6013 { 0x00007880, 0x04924914 },
6014 { 0x00007884, 0x21084210 },
6015 { 0x00007888, 0x001b6db0 },
6016 { 0x0000788c, 0x00376b63 },
6017 { 0x00007890, 0x06db6db6 },
6018 { 0x00007894, 0x006d8000 },
6019 { 0x00007898, 0x48100000 },
6020 { 0x0000789c, 0x00000000 },
6021 { 0x000078a0, 0x08000000 },
6022 { 0x000078a4, 0x0007ffd8 },
6023 { 0x000078a8, 0x0007ffd8 },
6024 { 0x000078ac, 0x001c0020 },
6025 { 0x000078b0, 0x00060aeb },
6026 { 0x000078b4, 0x40008080 },
6027 { 0x000078b8, 0x2a850160 },
6028};
6029
6030static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = {
6031 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
6032 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6033 { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 },
6034 { 0x0000a308, 0x00000000, 0x00000000, 0x00008004, 0x00008004, 0x00008004 },
6035 { 0x0000a30c, 0x00000000, 0x00000000, 0x0000c00a, 0x0000c00a, 0x0000c00a },
6036 { 0x0000a310, 0x00000000, 0x00000000, 0x0001000c, 0x0001000c, 0x0001000c },
6037 { 0x0000a314, 0x00000000, 0x00000000, 0x0001420b, 0x0001420b, 0x0001420b },
6038 { 0x0000a318, 0x00000000, 0x00000000, 0x0001824a, 0x0001824a, 0x0001824a },
6039 { 0x0000a31c, 0x00000000, 0x00000000, 0x0001c44a, 0x0001c44a, 0x0001c44a },
6040 { 0x0000a320, 0x00000000, 0x00000000, 0x0002064a, 0x0002064a, 0x0002064a },
6041 { 0x0000a324, 0x00000000, 0x00000000, 0x0002484a, 0x0002484a, 0x0002484a },
6042 { 0x0000a328, 0x00000000, 0x00000000, 0x00028a4a, 0x00028a4a, 0x00028a4a },
6043 { 0x0000a32c, 0x00000000, 0x00000000, 0x0002cc4a, 0x0002cc4a, 0x0002cc4a },
6044 { 0x0000a330, 0x00000000, 0x00000000, 0x00030e4a, 0x00030e4a, 0x00030e4a },
6045 { 0x0000a334, 0x00000000, 0x00000000, 0x00034e8a, 0x00034e8a, 0x00034e8a },
6046 { 0x0000a338, 0x00000000, 0x00000000, 0x00038e8c, 0x00038e8c, 0x00038e8c },
6047 { 0x0000a33c, 0x00000000, 0x00000000, 0x0003cecc, 0x0003cecc, 0x0003cecc },
6048 { 0x0000a340, 0x00000000, 0x00000000, 0x00040ed4, 0x00040ed4, 0x00040ed4 },
6049 { 0x0000a344, 0x00000000, 0x00000000, 0x00044edc, 0x00044edc, 0x00044edc },
6050 { 0x0000a348, 0x00000000, 0x00000000, 0x00048ede, 0x00048ede, 0x00048ede },
6051 { 0x0000a34c, 0x00000000, 0x00000000, 0x0004cf1e, 0x0004cf1e, 0x0004cf1e },
6052 { 0x0000a350, 0x00000000, 0x00000000, 0x00050f5e, 0x00050f5e, 0x00050f5e },
6053 { 0x0000a354, 0x00000000, 0x00000000, 0x00054f9e, 0x00054f9e, 0x00054f9e },
6054 { 0x0000a780, 0x00000000, 0x00000000, 0x00000062, 0x00000062, 0x00000062 },
6055 { 0x0000a784, 0x00000000, 0x00000000, 0x00004064, 0x00004064, 0x00004064 },
6056 { 0x0000a788, 0x00000000, 0x00000000, 0x000080a4, 0x000080a4, 0x000080a4 },
6057 { 0x0000a78c, 0x00000000, 0x00000000, 0x0000c0aa, 0x0000c0aa, 0x0000c0aa },
6058 { 0x0000a790, 0x00000000, 0x00000000, 0x000100ac, 0x000100ac, 0x000100ac },
6059 { 0x0000a794, 0x00000000, 0x00000000, 0x000140b4, 0x000140b4, 0x000140b4 },
6060 { 0x0000a798, 0x00000000, 0x00000000, 0x000180f4, 0x000180f4, 0x000180f4 },
6061 { 0x0000a79c, 0x00000000, 0x00000000, 0x0001c134, 0x0001c134, 0x0001c134 },
6062 { 0x0000a7a0, 0x00000000, 0x00000000, 0x00020174, 0x00020174, 0x00020174 },
6063 { 0x0000a7a4, 0x00000000, 0x00000000, 0x0002417c, 0x0002417c, 0x0002417c },
6064 { 0x0000a7a8, 0x00000000, 0x00000000, 0x0002817e, 0x0002817e, 0x0002817e },
6065 { 0x0000a7ac, 0x00000000, 0x00000000, 0x0002c1be, 0x0002c1be, 0x0002c1be },
6066 { 0x0000a7b0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6067 { 0x0000a7b4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6068 { 0x0000a7b8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6069 { 0x0000a7bc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6070 { 0x0000a7c0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6071 { 0x0000a7c4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6072 { 0x0000a7c8, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6073 { 0x0000a7cc, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6074 { 0x0000a7d0, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6075 { 0x0000a7d4, 0x00000000, 0x00000000, 0x000301fe, 0x000301fe, 0x000301fe },
6076 { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 },
6077};
6078
6079static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = {
6080 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
6081 { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
6082 { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
6083 { 0x00009a08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
6084 { 0x00009a0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
6085 { 0x00009a10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
6086 { 0x00009a14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
6087 { 0x00009a18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
6088 { 0x00009a1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
6089 { 0x00009a20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
6090 { 0x00009a24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
6091 { 0x00009a28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
6092 { 0x00009a2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
6093 { 0x00009a30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
6094 { 0x00009a34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
6095 { 0x00009a38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
6096 { 0x00009a3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
6097 { 0x00009a40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
6098 { 0x00009a44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
6099 { 0x00009a48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
6100 { 0x00009a4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
6101 { 0x00009a50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
6102 { 0x00009a54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
6103 { 0x00009a58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
6104 { 0x00009a5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
6105 { 0x00009a60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
6106 { 0x00009a64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
6107 { 0x00009a68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
6108 { 0x00009a6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
6109 { 0x00009a70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
6110 { 0x00009a74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
6111 { 0x00009a78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
6112 { 0x00009a7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
6113 { 0x00009a80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
6114 { 0x00009a84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
6115 { 0x00009a88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
6116 { 0x00009a8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
6117 { 0x00009a90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
6118 { 0x00009a94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
6119 { 0x00009a98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
6120 { 0x00009a9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
6121 { 0x00009aa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
6122 { 0x00009aa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
6123 { 0x00009aa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
6124 { 0x00009aac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
6125 { 0x00009ab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
6126 { 0x00009ab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
6127 { 0x00009ab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
6128 { 0x00009abc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
6129 { 0x00009ac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
6130 { 0x00009ac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
6131 { 0x00009ac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
6132 { 0x00009acc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
6133 { 0x00009ad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
6134 { 0x00009ad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
6135 { 0x00009ad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
6136 { 0x00009adc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
6137 { 0x00009ae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
6138 { 0x00009ae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
6139 { 0x00009ae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
6140 { 0x00009aec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
6141 { 0x00009af0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
6142 { 0x00009af4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
6143 { 0x00009af8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
6144 { 0x00009afc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
6145 { 0x00009b00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
6146 { 0x00009b04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
6147 { 0x00009b08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
6148 { 0x00009b0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
6149 { 0x00009b10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
6150 { 0x00009b14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
6151 { 0x00009b18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
6152 { 0x00009b1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
6153 { 0x00009b20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
6154 { 0x00009b24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
6155 { 0x00009b28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
6156 { 0x00009b2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
6157 { 0x00009b30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
6158 { 0x00009b34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
6159 { 0x00009b38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
6160 { 0x00009b3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
6161 { 0x00009b40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
6162 { 0x00009b44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
6163 { 0x00009b48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
6164 { 0x00009b4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
6165 { 0x00009b50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
6166 { 0x00009b54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
6167 { 0x00009b58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
6168 { 0x00009b5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
6169 { 0x00009b60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
6170 { 0x00009b64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
6171 { 0x00009b68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
6172 { 0x00009b6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
6173 { 0x00009b70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
6174 { 0x00009b74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
6175 { 0x00009b78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
6176 { 0x00009b7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
6177 { 0x00009b80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
6178 { 0x00009b84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
6179 { 0x00009b88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
6180 { 0x00009b8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
6181 { 0x00009b90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
6182 { 0x00009b94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
6183 { 0x00009b98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
6184 { 0x00009b9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6185 { 0x00009ba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6186 { 0x00009ba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6187 { 0x00009ba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6188 { 0x00009bac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6189 { 0x00009bb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6190 { 0x00009bb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6191 { 0x00009bb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6192 { 0x00009bbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6193 { 0x00009bc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6194 { 0x00009bc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6195 { 0x00009bc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6196 { 0x00009bcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6197 { 0x00009bd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6198 { 0x00009bd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6199 { 0x00009bd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6200 { 0x00009bdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6201 { 0x00009be0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6202 { 0x00009be4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6203 { 0x00009be8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6204 { 0x00009bec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6205 { 0x00009bf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6206 { 0x00009bf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6207 { 0x00009bf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6208 { 0x00009bfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6209 { 0x0000aa00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 },
6210 { 0x0000aa04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 },
6211 { 0x0000aa08, 0x00000000, 0x00000000, 0x0000a128, 0x0000a128, 0x0000a128 },
6212 { 0x0000aa0c, 0x00000000, 0x00000000, 0x0000a12c, 0x0000a12c, 0x0000a12c },
6213 { 0x0000aa10, 0x00000000, 0x00000000, 0x0000a130, 0x0000a130, 0x0000a130 },
6214 { 0x0000aa14, 0x00000000, 0x00000000, 0x0000a194, 0x0000a194, 0x0000a194 },
6215 { 0x0000aa18, 0x00000000, 0x00000000, 0x0000a198, 0x0000a198, 0x0000a198 },
6216 { 0x0000aa1c, 0x00000000, 0x00000000, 0x0000a20c, 0x0000a20c, 0x0000a20c },
6217 { 0x0000aa20, 0x00000000, 0x00000000, 0x0000a210, 0x0000a210, 0x0000a210 },
6218 { 0x0000aa24, 0x00000000, 0x00000000, 0x0000a284, 0x0000a284, 0x0000a284 },
6219 { 0x0000aa28, 0x00000000, 0x00000000, 0x0000a288, 0x0000a288, 0x0000a288 },
6220 { 0x0000aa2c, 0x00000000, 0x00000000, 0x0000a28c, 0x0000a28c, 0x0000a28c },
6221 { 0x0000aa30, 0x00000000, 0x00000000, 0x0000a290, 0x0000a290, 0x0000a290 },
6222 { 0x0000aa34, 0x00000000, 0x00000000, 0x0000a294, 0x0000a294, 0x0000a294 },
6223 { 0x0000aa38, 0x00000000, 0x00000000, 0x0000a2a0, 0x0000a2a0, 0x0000a2a0 },
6224 { 0x0000aa3c, 0x00000000, 0x00000000, 0x0000a2a4, 0x0000a2a4, 0x0000a2a4 },
6225 { 0x0000aa40, 0x00000000, 0x00000000, 0x0000a2a8, 0x0000a2a8, 0x0000a2a8 },
6226 { 0x0000aa44, 0x00000000, 0x00000000, 0x0000a2ac, 0x0000a2ac, 0x0000a2ac },
6227 { 0x0000aa48, 0x00000000, 0x00000000, 0x0000a2b0, 0x0000a2b0, 0x0000a2b0 },
6228 { 0x0000aa4c, 0x00000000, 0x00000000, 0x0000a2b4, 0x0000a2b4, 0x0000a2b4 },
6229 { 0x0000aa50, 0x00000000, 0x00000000, 0x0000a2b8, 0x0000a2b8, 0x0000a2b8 },
6230 { 0x0000aa54, 0x00000000, 0x00000000, 0x0000a2c4, 0x0000a2c4, 0x0000a2c4 },
6231 { 0x0000aa58, 0x00000000, 0x00000000, 0x0000a708, 0x0000a708, 0x0000a708 },
6232 { 0x0000aa5c, 0x00000000, 0x00000000, 0x0000a70c, 0x0000a70c, 0x0000a70c },
6233 { 0x0000aa60, 0x00000000, 0x00000000, 0x0000a710, 0x0000a710, 0x0000a710 },
6234 { 0x0000aa64, 0x00000000, 0x00000000, 0x0000ab04, 0x0000ab04, 0x0000ab04 },
6235 { 0x0000aa68, 0x00000000, 0x00000000, 0x0000ab08, 0x0000ab08, 0x0000ab08 },
6236 { 0x0000aa6c, 0x00000000, 0x00000000, 0x0000ab0c, 0x0000ab0c, 0x0000ab0c },
6237 { 0x0000aa70, 0x00000000, 0x00000000, 0x0000ab10, 0x0000ab10, 0x0000ab10 },
6238 { 0x0000aa74, 0x00000000, 0x00000000, 0x0000ab14, 0x0000ab14, 0x0000ab14 },
6239 { 0x0000aa78, 0x00000000, 0x00000000, 0x0000ab18, 0x0000ab18, 0x0000ab18 },
6240 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0000ab8c, 0x0000ab8c, 0x0000ab8c },
6241 { 0x0000aa80, 0x00000000, 0x00000000, 0x0000ab90, 0x0000ab90, 0x0000ab90 },
6242 { 0x0000aa84, 0x00000000, 0x00000000, 0x0000ab94, 0x0000ab94, 0x0000ab94 },
6243 { 0x0000aa88, 0x00000000, 0x00000000, 0x0000ab98, 0x0000ab98, 0x0000ab98 },
6244 { 0x0000aa8c, 0x00000000, 0x00000000, 0x0000aba4, 0x0000aba4, 0x0000aba4 },
6245 { 0x0000aa90, 0x00000000, 0x00000000, 0x0000aba8, 0x0000aba8, 0x0000aba8 },
6246 { 0x0000aa94, 0x00000000, 0x00000000, 0x0000cb04, 0x0000cb04, 0x0000cb04 },
6247 { 0x0000aa98, 0x00000000, 0x00000000, 0x0000cb08, 0x0000cb08, 0x0000cb08 },
6248 { 0x0000aa9c, 0x00000000, 0x00000000, 0x0000cb0c, 0x0000cb0c, 0x0000cb0c },
6249 { 0x0000aaa0, 0x00000000, 0x00000000, 0x0000cb10, 0x0000cb10, 0x0000cb10 },
6250 { 0x0000aaa4, 0x00000000, 0x00000000, 0x0000cb14, 0x0000cb14, 0x0000cb14 },
6251 { 0x0000aaa8, 0x00000000, 0x00000000, 0x0000cb18, 0x0000cb18, 0x0000cb18 },
6252 { 0x0000aaac, 0x00000000, 0x00000000, 0x0000cb8c, 0x0000cb8c, 0x0000cb8c },
6253 { 0x0000aab0, 0x00000000, 0x00000000, 0x0000cb90, 0x0000cb90, 0x0000cb90 },
6254 { 0x0000aab4, 0x00000000, 0x00000000, 0x0000cf18, 0x0000cf18, 0x0000cf18 },
6255 { 0x0000aab8, 0x00000000, 0x00000000, 0x0000cf24, 0x0000cf24, 0x0000cf24 },
6256 { 0x0000aabc, 0x00000000, 0x00000000, 0x0000cf28, 0x0000cf28, 0x0000cf28 },
6257 { 0x0000aac0, 0x00000000, 0x00000000, 0x0000d314, 0x0000d314, 0x0000d314 },
6258 { 0x0000aac4, 0x00000000, 0x00000000, 0x0000d318, 0x0000d318, 0x0000d318 },
6259 { 0x0000aac8, 0x00000000, 0x00000000, 0x0000d38c, 0x0000d38c, 0x0000d38c },
6260 { 0x0000aacc, 0x00000000, 0x00000000, 0x0000d390, 0x0000d390, 0x0000d390 },
6261 { 0x0000aad0, 0x00000000, 0x00000000, 0x0000d394, 0x0000d394, 0x0000d394 },
6262 { 0x0000aad4, 0x00000000, 0x00000000, 0x0000d398, 0x0000d398, 0x0000d398 },
6263 { 0x0000aad8, 0x00000000, 0x00000000, 0x0000d3a4, 0x0000d3a4, 0x0000d3a4 },
6264 { 0x0000aadc, 0x00000000, 0x00000000, 0x0000d3a8, 0x0000d3a8, 0x0000d3a8 },
6265 { 0x0000aae0, 0x00000000, 0x00000000, 0x0000d3ac, 0x0000d3ac, 0x0000d3ac },
6266 { 0x0000aae4, 0x00000000, 0x00000000, 0x0000d3b0, 0x0000d3b0, 0x0000d3b0 },
6267 { 0x0000aae8, 0x00000000, 0x00000000, 0x0000f380, 0x0000f380, 0x0000f380 },
6268 { 0x0000aaec, 0x00000000, 0x00000000, 0x0000f384, 0x0000f384, 0x0000f384 },
6269 { 0x0000aaf0, 0x00000000, 0x00000000, 0x0000f388, 0x0000f388, 0x0000f388 },
6270 { 0x0000aaf4, 0x00000000, 0x00000000, 0x0000f710, 0x0000f710, 0x0000f710 },
6271 { 0x0000aaf8, 0x00000000, 0x00000000, 0x0000f714, 0x0000f714, 0x0000f714 },
6272 { 0x0000aafc, 0x00000000, 0x00000000, 0x0000f718, 0x0000f718, 0x0000f718 },
6273 { 0x0000ab00, 0x00000000, 0x00000000, 0x0000fb10, 0x0000fb10, 0x0000fb10 },
6274 { 0x0000ab04, 0x00000000, 0x00000000, 0x0000fb14, 0x0000fb14, 0x0000fb14 },
6275 { 0x0000ab08, 0x00000000, 0x00000000, 0x0000fb18, 0x0000fb18, 0x0000fb18 },
6276 { 0x0000ab0c, 0x00000000, 0x00000000, 0x0000fb8c, 0x0000fb8c, 0x0000fb8c },
6277 { 0x0000ab10, 0x00000000, 0x00000000, 0x0000fb90, 0x0000fb90, 0x0000fb90 },
6278 { 0x0000ab14, 0x00000000, 0x00000000, 0x0000fb94, 0x0000fb94, 0x0000fb94 },
6279 { 0x0000ab18, 0x00000000, 0x00000000, 0x0000ff8c, 0x0000ff8c, 0x0000ff8c },
6280 { 0x0000ab1c, 0x00000000, 0x00000000, 0x0000ff90, 0x0000ff90, 0x0000ff90 },
6281 { 0x0000ab20, 0x00000000, 0x00000000, 0x0000ff94, 0x0000ff94, 0x0000ff94 },
6282 { 0x0000ab24, 0x00000000, 0x00000000, 0x0000ffa0, 0x0000ffa0, 0x0000ffa0 },
6283 { 0x0000ab28, 0x00000000, 0x00000000, 0x0000ffa4, 0x0000ffa4, 0x0000ffa4 },
6284 { 0x0000ab2c, 0x00000000, 0x00000000, 0x0000ffa8, 0x0000ffa8, 0x0000ffa8 },
6285 { 0x0000ab30, 0x00000000, 0x00000000, 0x0000ffac, 0x0000ffac, 0x0000ffac },
6286 { 0x0000ab34, 0x00000000, 0x00000000, 0x0000ffb0, 0x0000ffb0, 0x0000ffb0 },
6287 { 0x0000ab38, 0x00000000, 0x00000000, 0x0000ffb4, 0x0000ffb4, 0x0000ffb4 },
6288 { 0x0000ab3c, 0x00000000, 0x00000000, 0x0000ffa1, 0x0000ffa1, 0x0000ffa1 },
6289 { 0x0000ab40, 0x00000000, 0x00000000, 0x0000ffa5, 0x0000ffa5, 0x0000ffa5 },
6290 { 0x0000ab44, 0x00000000, 0x00000000, 0x0000ffa9, 0x0000ffa9, 0x0000ffa9 },
6291 { 0x0000ab48, 0x00000000, 0x00000000, 0x0000ffad, 0x0000ffad, 0x0000ffad },
6292 { 0x0000ab4c, 0x00000000, 0x00000000, 0x0000ffb1, 0x0000ffb1, 0x0000ffb1 },
6293 { 0x0000ab50, 0x00000000, 0x00000000, 0x0000ffb5, 0x0000ffb5, 0x0000ffb5 },
6294 { 0x0000ab54, 0x00000000, 0x00000000, 0x0000ffb9, 0x0000ffb9, 0x0000ffb9 },
6295 { 0x0000ab58, 0x00000000, 0x00000000, 0x0000ffc5, 0x0000ffc5, 0x0000ffc5 },
6296 { 0x0000ab5c, 0x00000000, 0x00000000, 0x0000ffc9, 0x0000ffc9, 0x0000ffc9 },
6297 { 0x0000ab60, 0x00000000, 0x00000000, 0x0000ffcd, 0x0000ffcd, 0x0000ffcd },
6298 { 0x0000ab64, 0x00000000, 0x00000000, 0x0000ffd1, 0x0000ffd1, 0x0000ffd1 },
6299 { 0x0000ab68, 0x00000000, 0x00000000, 0x0000ffd5, 0x0000ffd5, 0x0000ffd5 },
6300 { 0x0000ab6c, 0x00000000, 0x00000000, 0x0000ffc2, 0x0000ffc2, 0x0000ffc2 },
6301 { 0x0000ab70, 0x00000000, 0x00000000, 0x0000ffc6, 0x0000ffc6, 0x0000ffc6 },
6302 { 0x0000ab74, 0x00000000, 0x00000000, 0x0000ffca, 0x0000ffca, 0x0000ffca },
6303 { 0x0000ab78, 0x00000000, 0x00000000, 0x0000ffce, 0x0000ffce, 0x0000ffce },
6304 { 0x0000ab7c, 0x00000000, 0x00000000, 0x0000ffd2, 0x0000ffd2, 0x0000ffd2 },
6305 { 0x0000ab80, 0x00000000, 0x00000000, 0x0000ffd6, 0x0000ffd6, 0x0000ffd6 },
6306 { 0x0000ab84, 0x00000000, 0x00000000, 0x0000ffda, 0x0000ffda, 0x0000ffda },
6307 { 0x0000ab88, 0x00000000, 0x00000000, 0x0000ffc7, 0x0000ffc7, 0x0000ffc7 },
6308 { 0x0000ab8c, 0x00000000, 0x00000000, 0x0000ffcb, 0x0000ffcb, 0x0000ffcb },
6309 { 0x0000ab90, 0x00000000, 0x00000000, 0x0000ffcf, 0x0000ffcf, 0x0000ffcf },
6310 { 0x0000ab94, 0x00000000, 0x00000000, 0x0000ffd3, 0x0000ffd3, 0x0000ffd3 },
6311 { 0x0000ab98, 0x00000000, 0x00000000, 0x0000ffd7, 0x0000ffd7, 0x0000ffd7 },
6312 { 0x0000ab9c, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6313 { 0x0000aba0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6314 { 0x0000aba4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6315 { 0x0000aba8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6316 { 0x0000abac, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6317 { 0x0000abb0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6318 { 0x0000abb4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6319 { 0x0000abb8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6320 { 0x0000abbc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6321 { 0x0000abc0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6322 { 0x0000abc4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6323 { 0x0000abc8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6324 { 0x0000abcc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6325 { 0x0000abd0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6326 { 0x0000abd4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6327 { 0x0000abd8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6328 { 0x0000abdc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6329 { 0x0000abe0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6330 { 0x0000abe4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6331 { 0x0000abe8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6332 { 0x0000abec, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6333 { 0x0000abf0, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6334 { 0x0000abf4, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6335 { 0x0000abf8, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6336 { 0x0000abfc, 0x00000000, 0x00000000, 0x0000ffdb, 0x0000ffdb, 0x0000ffdb },
6337 { 0x00009848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
6338 { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 },
6339};
6340
6341static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = {
6342 {0x00004040, 0x9248fd00 },
6343 {0x00004040, 0x24924924 },
6344 {0x00004040, 0xa8000019 },
6345 {0x00004040, 0x13160820 },
6346 {0x00004040, 0xe5980560 },
6347 {0x00004040, 0xc01dcffd },
6348 {0x00004040, 0x1aaabe41 },
6349 {0x00004040, 0xbe105554 },
6350 {0x00004040, 0x00043007 },
6351 {0x00004044, 0x00000000 },
6352};
6353
6354static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
6355 {0x00004040, 0x9248fd00 },
6356 {0x00004040, 0x24924924 },
6357 {0x00004040, 0xa8000019 },
6358 {0x00004040, 0x13160820 },
6359 {0x00004040, 0xe5980560 },
6360 {0x00004040, 0xc01dcffc },
6361 {0x00004040, 0x1aaabe41 },
6362 {0x00004040, 0xbe105554 },
6363 {0x00004040, 0x00043007 },
6364 {0x00004044, 0x00000000 },
6365};
6366
6367
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 3436295e0509..75ddb2acb644 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -17,8 +17,6 @@
17#include <linux/nl80211.h> 17#include <linux/nl80211.h>
18#include "ath9k.h" 18#include "ath9k.h"
19 19
20#define ATH_PCI_VERSION "0.1"
21
22static char *dev_info = "ath9k"; 20static char *dev_info = "ath9k";
23 21
24MODULE_AUTHOR("Atheros Communications"); 22MODULE_AUTHOR("Atheros Communications");
@@ -462,7 +460,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
462 460
463 if (sc->sc_flags & SC_OP_TXAGGR) { 461 if (sc->sc_flags & SC_OP_TXAGGR) {
464 ath_tx_node_init(sc, an); 462 ath_tx_node_init(sc, an);
465 an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + 463 an->maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR +
466 sta->ht_cap.ampdu_factor); 464 sta->ht_cap.ampdu_factor);
467 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); 465 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
468 an->last_rssi = ATH_RSSI_DUMMY_MARKER; 466 an->last_rssi = ATH_RSSI_DUMMY_MARKER;
@@ -499,8 +497,7 @@ static void ath9k_tasklet(unsigned long data)
499 if (status & ATH9K_INT_TX) 497 if (status & ATH9K_INT_TX)
500 ath_tx_tasklet(sc); 498 ath_tx_tasklet(sc);
501 499
502 if ((status & ATH9K_INT_TSFOOR) && 500 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {
503 (sc->hw->conf.flags & IEEE80211_CONF_PS)) {
504 /* 501 /*
505 * TSF sync does not look correct; remain awake to sync with 502 * TSF sync does not look correct; remain awake to sync with
506 * the next Beacon. 503 * the next Beacon.
@@ -888,8 +885,6 @@ static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
888static void setup_ht_cap(struct ath_softc *sc, 885static void setup_ht_cap(struct ath_softc *sc,
889 struct ieee80211_sta_ht_cap *ht_info) 886 struct ieee80211_sta_ht_cap *ht_info)
890{ 887{
891#define ATH9K_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
892#define ATH9K_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
893 u8 tx_streams, rx_streams; 888 u8 tx_streams, rx_streams;
894 889
895 ht_info->ht_supported = true; 890 ht_info->ht_supported = true;
@@ -898,8 +893,8 @@ static void setup_ht_cap(struct ath_softc *sc,
898 IEEE80211_HT_CAP_SGI_40 | 893 IEEE80211_HT_CAP_SGI_40 |
899 IEEE80211_HT_CAP_DSSSCCK40; 894 IEEE80211_HT_CAP_DSSSCCK40;
900 895
901 ht_info->ampdu_factor = ATH9K_HT_CAP_MAXRXAMPDU_65536; 896 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
902 ht_info->ampdu_density = ATH9K_HT_CAP_MPDUDENSITY_8; 897 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
903 898
904 /* set up supported mcs set */ 899 /* set up supported mcs set */
905 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); 900 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
@@ -2003,7 +1998,7 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2003 goto exit; 1998 goto exit;
2004 } 1999 }
2005 2000
2006 if (sc->hw->conf.flags & IEEE80211_CONF_PS) { 2001 if (sc->ps_enabled) {
2007 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 2002 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
2008 /* 2003 /*
2009 * mac80211 does not set PM field for normal data frames, so we 2004 * mac80211 does not set PM field for normal data frames, so we
@@ -2291,8 +2286,9 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2291 } 2286 }
2292 ath9k_hw_setrxabort(sc->sc_ah, 1); 2287 ath9k_hw_setrxabort(sc->sc_ah, 1);
2293 } 2288 }
2294 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); 2289 sc->ps_enabled = true;
2295 } else { 2290 } else {
2291 sc->ps_enabled = false;
2296 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); 2292 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
2297 if (!(ah->caps.hw_caps & 2293 if (!(ah->caps.hw_caps &
2298 ATH9K_HW_CAP_AUTOSLEEP)) { 2294 ATH9K_HW_CAP_AUTOSLEEP)) {
@@ -2671,19 +2667,11 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw,
2671 case IEEE80211_AMPDU_RX_STOP: 2667 case IEEE80211_AMPDU_RX_STOP:
2672 break; 2668 break;
2673 case IEEE80211_AMPDU_TX_START: 2669 case IEEE80211_AMPDU_TX_START:
2674 ret = ath_tx_aggr_start(sc, sta, tid, ssn); 2670 ath_tx_aggr_start(sc, sta, tid, ssn);
2675 if (ret < 0) 2671 ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2676 DPRINTF(sc, ATH_DBG_FATAL,
2677 "Unable to start TX aggregation\n");
2678 else
2679 ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2680 break; 2672 break;
2681 case IEEE80211_AMPDU_TX_STOP: 2673 case IEEE80211_AMPDU_TX_STOP:
2682 ret = ath_tx_aggr_stop(sc, sta, tid); 2674 ath_tx_aggr_stop(sc, sta, tid);
2683 if (ret < 0)
2684 DPRINTF(sc, ATH_DBG_FATAL,
2685 "Unable to stop TX aggregation\n");
2686
2687 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid); 2675 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2688 break; 2676 break;
2689 case IEEE80211_AMPDU_TX_OPERATIONAL: 2677 case IEEE80211_AMPDU_TX_OPERATIONAL:
@@ -2761,7 +2749,8 @@ static struct {
2761 { AR_SREV_VERSION_9100, "9100" }, 2749 { AR_SREV_VERSION_9100, "9100" },
2762 { AR_SREV_VERSION_9160, "9160" }, 2750 { AR_SREV_VERSION_9160, "9160" },
2763 { AR_SREV_VERSION_9280, "9280" }, 2751 { AR_SREV_VERSION_9280, "9280" },
2764 { AR_SREV_VERSION_9285, "9285" } 2752 { AR_SREV_VERSION_9285, "9285" },
2753 { AR_SREV_VERSION_9287, "9287" }
2765}; 2754};
2766 2755
2767static struct { 2756static struct {
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 170c5b32e49b..cd4841be80af 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -25,6 +25,8 @@ static struct pci_device_id ath_pci_id_table[] __devinitdata = {
25 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */ 25 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
26 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */ 26 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
27 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */ 27 { PCI_VDEVICE(ATHEROS, 0x002B) }, /* PCI-E */
28 { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */
29 { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */
28 { 0 } 30 { 0 }
29}; 31};
30 32
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index c70f530642f6..de4fadadbce5 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -375,6 +375,7 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
375#define AR_PHY_CHAN_INFO_GAIN 0x9CFC 375#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
376 376
377#define AR_PHY_MODE 0xA200 377#define AR_PHY_MODE 0xA200
378#define AR_PHY_MODE_ASYNCFIFO 0x80
378#define AR_PHY_MODE_AR2133 0x08 379#define AR_PHY_MODE_AR2133 0x08
379#define AR_PHY_MODE_AR5111 0x00 380#define AR_PHY_MODE_AR5111 0x00
380#define AR_PHY_MODE_AR5112 0x08 381#define AR_PHY_MODE_AR5112 0x08
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 4ff155e8ee59..b7806e2ca0e1 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -59,6 +59,7 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
59 struct ath_atx_tid *tid, 59 struct ath_atx_tid *tid,
60 struct list_head *bf_head); 60 struct list_head *bf_head);
61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 61static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
62 struct ath_txq *txq,
62 struct list_head *bf_q, 63 struct list_head *bf_q,
63 int txok, int sendbar); 64 int txok, int sendbar);
64static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, 65static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
@@ -212,7 +213,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
212 ath_tx_update_baw(sc, tid, bf->bf_seqno); 213 ath_tx_update_baw(sc, tid, bf->bf_seqno);
213 214
214 spin_unlock(&txq->axq_lock); 215 spin_unlock(&txq->axq_lock);
215 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 216 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
216 spin_lock(&txq->axq_lock); 217 spin_lock(&txq->axq_lock);
217 } 218 }
218 219
@@ -220,13 +221,15 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq,
220 tid->baw_tail = tid->baw_head; 221 tid->baw_tail = tid->baw_head;
221} 222}
222 223
223static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) 224static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq,
225 struct ath_buf *bf)
224{ 226{
225 struct sk_buff *skb; 227 struct sk_buff *skb;
226 struct ieee80211_hdr *hdr; 228 struct ieee80211_hdr *hdr;
227 229
228 bf->bf_state.bf_type |= BUF_RETRY; 230 bf->bf_state.bf_type |= BUF_RETRY;
229 bf->bf_retries++; 231 bf->bf_retries++;
232 TX_STAT_INC(txq->axq_qnum, a_retries);
230 233
231 skb = bf->bf_mpdu; 234 skb = bf->bf_mpdu;
232 hdr = (struct ieee80211_hdr *)skb->data; 235 hdr = (struct ieee80211_hdr *)skb->data;
@@ -328,7 +331,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
328 if (!(tid->state & AGGR_CLEANUP) && 331 if (!(tid->state & AGGR_CLEANUP) &&
329 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { 332 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
330 if (bf->bf_retries < ATH_MAX_SW_RETRIES) { 333 if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
331 ath_tx_set_retry(sc, bf); 334 ath_tx_set_retry(sc, txq, bf);
332 txpending = 1; 335 txpending = 1;
333 } else { 336 } else {
334 bf->bf_state.bf_type |= BUF_XRETRY; 337 bf->bf_state.bf_type |= BUF_XRETRY;
@@ -375,7 +378,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
375 ath_tx_rc_status(bf, ds, nbad, txok, false); 378 ath_tx_rc_status(bf, ds, nbad, txok, false);
376 } 379 }
377 380
378 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar); 381 ath_tx_complete_buf(sc, bf, txq, &bf_head, !txfail, sendbar);
379 } else { 382 } else {
380 /* retry the un-acked ones */ 383 /* retry the un-acked ones */
381 if (bf->bf_next == NULL && bf_last->bf_stale) { 384 if (bf->bf_next == NULL && bf_last->bf_stale) {
@@ -395,8 +398,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
395 bf->bf_state.bf_type |= BUF_XRETRY; 398 bf->bf_state.bf_type |= BUF_XRETRY;
396 ath_tx_rc_status(bf, ds, nbad, 399 ath_tx_rc_status(bf, ds, nbad,
397 0, false); 400 0, false);
398 ath_tx_complete_buf(sc, bf, &bf_head, 401 ath_tx_complete_buf(sc, bf, txq,
399 0, 0); 402 &bf_head, 0, 0);
400 break; 403 break;
401 } 404 }
402 405
@@ -455,7 +458,7 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
455 struct ieee80211_tx_rate *rates; 458 struct ieee80211_tx_rate *rates;
456 struct ath_tx_info_priv *tx_info_priv; 459 struct ath_tx_info_priv *tx_info_priv;
457 u32 max_4ms_framelen, frmlen; 460 u32 max_4ms_framelen, frmlen;
458 u16 aggr_limit, legacy = 0, maxampdu; 461 u16 aggr_limit, legacy = 0;
459 int i; 462 int i;
460 463
461 skb = bf->bf_mpdu; 464 skb = bf->bf_mpdu;
@@ -490,16 +493,15 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
490 if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy) 493 if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
491 return 0; 494 return 0;
492 495
493 aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_DEFAULT); 496 aggr_limit = min(max_4ms_framelen, (u32)ATH_AMPDU_LIMIT_MAX);
494 497
495 /* 498 /*
496 * h/w can accept aggregates upto 16 bit lengths (65535). 499 * h/w can accept aggregates upto 16 bit lengths (65535).
497 * The IE, however can hold upto 65536, which shows up here 500 * The IE, however can hold upto 65536, which shows up here
498 * as zero. Ignore 65536 since we are constrained by hw. 501 * as zero. Ignore 65536 since we are constrained by hw.
499 */ 502 */
500 maxampdu = tid->an->maxampdu; 503 if (tid->an->maxampdu)
501 if (maxampdu) 504 aggr_limit = min(aggr_limit, tid->an->maxampdu);
502 aggr_limit = min(aggr_limit, maxampdu);
503 505
504 return aggr_limit; 506 return aggr_limit;
505} 507}
@@ -507,7 +509,6 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf,
507/* 509/*
508 * Returns the number of delimiters to be added to 510 * Returns the number of delimiters to be added to
509 * meet the minimum required mpdudensity. 511 * meet the minimum required mpdudensity.
510 * caller should make sure that the rate is HT rate .
511 */ 512 */
512static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, 513static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
513 struct ath_buf *bf, u16 frmlen) 514 struct ath_buf *bf, u16 frmlen)
@@ -515,7 +516,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
515 const struct ath_rate_table *rt = sc->cur_rate_table; 516 const struct ath_rate_table *rt = sc->cur_rate_table;
516 struct sk_buff *skb = bf->bf_mpdu; 517 struct sk_buff *skb = bf->bf_mpdu;
517 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 518 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
518 u32 nsymbits, nsymbols, mpdudensity; 519 u32 nsymbits, nsymbols;
519 u16 minlen; 520 u16 minlen;
520 u8 rc, flags, rix; 521 u8 rc, flags, rix;
521 int width, half_gi, ndelim, mindelim; 522 int width, half_gi, ndelim, mindelim;
@@ -537,14 +538,12 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
537 * on highest rate in rate series (i.e. first rate) to determine 538 * on highest rate in rate series (i.e. first rate) to determine
538 * required minimum length for subframe. Take into account 539 * required minimum length for subframe. Take into account
539 * whether high rate is 20 or 40Mhz and half or full GI. 540 * whether high rate is 20 or 40Mhz and half or full GI.
540 */ 541 *
541 mpdudensity = tid->an->mpdudensity;
542
543 /*
544 * If there is no mpdu density restriction, no further calculation 542 * If there is no mpdu density restriction, no further calculation
545 * is needed. 543 * is needed.
546 */ 544 */
547 if (mpdudensity == 0) 545
546 if (tid->an->mpdudensity == 0)
548 return ndelim; 547 return ndelim;
549 548
550 rix = tx_info->control.rates[0].idx; 549 rix = tx_info->control.rates[0].idx;
@@ -554,9 +553,9 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
554 half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0; 553 half_gi = (flags & IEEE80211_TX_RC_SHORT_GI) ? 1 : 0;
555 554
556 if (half_gi) 555 if (half_gi)
557 nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity); 556 nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(tid->an->mpdudensity);
558 else 557 else
559 nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity); 558 nsymbols = NUM_SYMBOLS_PER_USEC(tid->an->mpdudensity);
560 559
561 if (nsymbols == 0) 560 if (nsymbols == 0)
562 nsymbols = 1; 561 nsymbols = 1;
@@ -573,6 +572,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid,
573} 572}
574 573
575static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, 574static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
575 struct ath_txq *txq,
576 struct ath_atx_tid *tid, 576 struct ath_atx_tid *tid,
577 struct list_head *bf_q) 577 struct list_head *bf_q)
578{ 578{
@@ -637,6 +637,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
637 bf_prev->bf_desc->ds_link = bf->bf_daddr; 637 bf_prev->bf_desc->ds_link = bf->bf_daddr;
638 } 638 }
639 bf_prev = bf; 639 bf_prev = bf;
640
640 } while (!list_empty(&tid->buf_q)); 641 } while (!list_empty(&tid->buf_q));
641 642
642 bf_first->bf_al = al; 643 bf_first->bf_al = al;
@@ -659,7 +660,7 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
659 660
660 INIT_LIST_HEAD(&bf_q); 661 INIT_LIST_HEAD(&bf_q);
661 662
662 status = ath_tx_form_aggr(sc, tid, &bf_q); 663 status = ath_tx_form_aggr(sc, txq, tid, &bf_q);
663 664
664 /* 665 /*
665 * no frames picked up to be aggregated; 666 * no frames picked up to be aggregated;
@@ -690,30 +691,26 @@ static void ath_tx_sched_aggr(struct ath_softc *sc, struct ath_txq *txq,
690 691
691 txq->axq_aggr_depth++; 692 txq->axq_aggr_depth++;
692 ath_tx_txqaddbuf(sc, txq, &bf_q); 693 ath_tx_txqaddbuf(sc, txq, &bf_q);
694 TX_STAT_INC(txq->axq_qnum, a_aggr);
693 695
694 } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH && 696 } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
695 status != ATH_AGGR_BAW_CLOSED); 697 status != ATH_AGGR_BAW_CLOSED);
696} 698}
697 699
698int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, 700void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
699 u16 tid, u16 *ssn) 701 u16 tid, u16 *ssn)
700{ 702{
701 struct ath_atx_tid *txtid; 703 struct ath_atx_tid *txtid;
702 struct ath_node *an; 704 struct ath_node *an;
703 705
704 an = (struct ath_node *)sta->drv_priv; 706 an = (struct ath_node *)sta->drv_priv;
705 707 txtid = ATH_AN_2_TID(an, tid);
706 if (sc->sc_flags & SC_OP_TXAGGR) { 708 txtid->state |= AGGR_ADDBA_PROGRESS;
707 txtid = ATH_AN_2_TID(an, tid); 709 ath_tx_pause_tid(sc, txtid);
708 txtid->state |= AGGR_ADDBA_PROGRESS; 710 *ssn = txtid->seq_start;
709 ath_tx_pause_tid(sc, txtid);
710 *ssn = txtid->seq_start;
711 }
712
713 return 0;
714} 711}
715 712
716int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) 713void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
717{ 714{
718 struct ath_node *an = (struct ath_node *)sta->drv_priv; 715 struct ath_node *an = (struct ath_node *)sta->drv_priv;
719 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); 716 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
@@ -723,11 +720,11 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
723 INIT_LIST_HEAD(&bf_head); 720 INIT_LIST_HEAD(&bf_head);
724 721
725 if (txtid->state & AGGR_CLEANUP) 722 if (txtid->state & AGGR_CLEANUP)
726 return 0; 723 return;
727 724
728 if (!(txtid->state & AGGR_ADDBA_COMPLETE)) { 725 if (!(txtid->state & AGGR_ADDBA_COMPLETE)) {
729 txtid->state &= ~AGGR_ADDBA_PROGRESS; 726 txtid->state &= ~AGGR_ADDBA_PROGRESS;
730 return 0; 727 return;
731 } 728 }
732 729
733 ath_tx_pause_tid(sc, txtid); 730 ath_tx_pause_tid(sc, txtid);
@@ -746,7 +743,7 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
746 } 743 }
747 list_move_tail(&bf->list, &bf_head); 744 list_move_tail(&bf->list, &bf_head);
748 ath_tx_update_baw(sc, txtid, bf->bf_seqno); 745 ath_tx_update_baw(sc, txtid, bf->bf_seqno);
749 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 746 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
750 } 747 }
751 spin_unlock_bh(&txq->axq_lock); 748 spin_unlock_bh(&txq->axq_lock);
752 749
@@ -756,8 +753,6 @@ int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
756 txtid->state &= ~AGGR_ADDBA_COMPLETE; 753 txtid->state &= ~AGGR_ADDBA_COMPLETE;
757 ath_tx_flush_tid(sc, txtid); 754 ath_tx_flush_tid(sc, txtid);
758 } 755 }
759
760 return 0;
761} 756}
762 757
763void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) 758void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
@@ -870,7 +865,6 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
870 spin_lock_init(&txq->axq_lock); 865 spin_lock_init(&txq->axq_lock);
871 txq->axq_depth = 0; 866 txq->axq_depth = 0;
872 txq->axq_aggr_depth = 0; 867 txq->axq_aggr_depth = 0;
873 txq->axq_totalqueued = 0;
874 txq->axq_linkbuf = NULL; 868 txq->axq_linkbuf = NULL;
875 txq->axq_tx_inprogress = false; 869 txq->axq_tx_inprogress = false;
876 sc->tx.txqsetup |= 1<<qnum; 870 sc->tx.txqsetup |= 1<<qnum;
@@ -1036,7 +1030,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1036 if (bf_isampdu(bf)) 1030 if (bf_isampdu(bf))
1037 ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); 1031 ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0);
1038 else 1032 else
1039 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 1033 ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0);
1040 } 1034 }
1041 1035
1042 spin_lock_bh(&txq->axq_lock); 1036 spin_lock_bh(&txq->axq_lock);
@@ -1187,7 +1181,6 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1187 1181
1188 list_splice_tail_init(head, &txq->axq_q); 1182 list_splice_tail_init(head, &txq->axq_q);
1189 txq->axq_depth++; 1183 txq->axq_depth++;
1190 txq->axq_totalqueued++;
1191 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list); 1184 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
1192 1185
1193 DPRINTF(sc, ATH_DBG_QUEUE, 1186 DPRINTF(sc, ATH_DBG_QUEUE,
@@ -1235,6 +1228,7 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1235 1228
1236 bf = list_first_entry(bf_head, struct ath_buf, list); 1229 bf = list_first_entry(bf_head, struct ath_buf, list);
1237 bf->bf_state.bf_type |= BUF_AMPDU; 1230 bf->bf_state.bf_type |= BUF_AMPDU;
1231 TX_STAT_INC(txctl->txq->axq_qnum, a_queued);
1238 1232
1239 /* 1233 /*
1240 * Do not queue to h/w when any of the following conditions is true: 1234 * Do not queue to h/w when any of the following conditions is true:
@@ -1281,6 +1275,7 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq,
1281 bf->bf_lastbf = bf; 1275 bf->bf_lastbf = bf;
1282 ath_buf_set_rate(sc, bf); 1276 ath_buf_set_rate(sc, bf);
1283 ath_tx_txqaddbuf(sc, txq, bf_head); 1277 ath_tx_txqaddbuf(sc, txq, bf_head);
1278 TX_STAT_INC(txq->axq_qnum, queued);
1284} 1279}
1285 1280
1286static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, 1281static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
@@ -1294,6 +1289,7 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
1294 bf->bf_nframes = 1; 1289 bf->bf_nframes = 1;
1295 ath_buf_set_rate(sc, bf); 1290 ath_buf_set_rate(sc, bf);
1296 ath_tx_txqaddbuf(sc, txq, bf_head); 1291 ath_tx_txqaddbuf(sc, txq, bf_head);
1292 TX_STAT_INC(txq->axq_qnum, queued);
1297} 1293}
1298 1294
1299static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) 1295static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb)
@@ -1819,6 +1815,7 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1819} 1815}
1820 1816
1821static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, 1817static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1818 struct ath_txq *txq,
1822 struct list_head *bf_q, 1819 struct list_head *bf_q,
1823 int txok, int sendbar) 1820 int txok, int sendbar)
1824{ 1821{
@@ -1826,7 +1823,6 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1826 unsigned long flags; 1823 unsigned long flags;
1827 int tx_flags = 0; 1824 int tx_flags = 0;
1828 1825
1829
1830 if (sendbar) 1826 if (sendbar)
1831 tx_flags = ATH_TX_BAR; 1827 tx_flags = ATH_TX_BAR;
1832 1828
@@ -1839,6 +1835,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1839 1835
1840 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); 1836 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1841 ath_tx_complete(sc, skb, tx_flags); 1837 ath_tx_complete(sc, skb, tx_flags);
1838 ath_debug_stat_tx(sc, txq, bf);
1842 1839
1843 /* 1840 /*
1844 * Return the list of ath_buf of this mpdu to free queue 1841 * Return the list of ath_buf of this mpdu to free queue
@@ -2026,7 +2023,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2026 if (bf_isampdu(bf)) 2023 if (bf_isampdu(bf))
2027 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); 2024 ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok);
2028 else 2025 else
2029 ath_tx_complete_buf(sc, bf, &bf_head, txok, 0); 2026 ath_tx_complete_buf(sc, bf, txq, &bf_head, txok, 0);
2030 2027
2031 ath_wake_mac80211_queue(sc, txq); 2028 ath_wake_mac80211_queue(sc, txq);
2032 2029
@@ -2037,7 +2034,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2037 } 2034 }
2038} 2035}
2039 2036
2040void ath_tx_complete_poll_work(struct work_struct *work) 2037static void ath_tx_complete_poll_work(struct work_struct *work)
2041{ 2038{
2042 struct ath_softc *sc = container_of(work, struct ath_softc, 2039 struct ath_softc *sc = container_of(work, struct ath_softc,
2043 tx_complete_work.work); 2040 tx_complete_work.work);
diff --git a/drivers/net/wireless/ath/regd_common.h b/drivers/net/wireless/ath/regd_common.h
index 4d0e298cd1c7..ad6d938d3cf6 100644
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -450,7 +450,7 @@ static struct country_code_to_enum_rd allCountries[] = {
450 {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"}, 450 {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
451 {CTRY_SYRIA, NULL1_WORLD, "SY"}, 451 {CTRY_SYRIA, NULL1_WORLD, "SY"},
452 {CTRY_TAIWAN, APL3_FCCA, "TW"}, 452 {CTRY_TAIWAN, APL3_FCCA, "TW"},
453 {CTRY_THAILAND, NULL1_WORLD, "TH"}, 453 {CTRY_THAILAND, FCC3_WORLD, "TH"},
454 {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"}, 454 {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
455 {CTRY_TUNISIA, ETSI3_WORLD, "TN"}, 455 {CTRY_TUNISIA, ETSI3_WORLD, "TN"},
456 {CTRY_TURKEY, ETSI3_WORLD, "TR"}, 456 {CTRY_TURKEY, ETSI3_WORLD, "TR"},
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index e092af09d6bf..99310c033253 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -9,6 +9,9 @@ config IWLWIFI
9config IWLWIFI_LEDS 9config IWLWIFI_LEDS
10 bool "Enable LED support in iwlagn and iwl3945 drivers" 10 bool "Enable LED support in iwlagn and iwl3945 drivers"
11 depends on IWLWIFI 11 depends on IWLWIFI
12 default y
13 ---help---
14 Select this if you want LED support.
12 15
13config IWLWIFI_SPECTRUM_MEASUREMENT 16config IWLWIFI_SPECTRUM_MEASUREMENT
14 bool "Enable Spectrum Measurement in iwlagn driver" 17 bool "Enable Spectrum Measurement in iwlagn driver"
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index a899be914ebf..5f7c52053c18 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -55,13 +55,88 @@
55#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" 55#define _IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode"
56#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api) 56#define IWL1000_MODULE_FIRMWARE(api) _IWL1000_MODULE_FIRMWARE(api)
57 57
58
59/*
60 * For 1000, use advance thermal throttling critical temperature threshold,
61 * but legacy thermal management implementation for now.
62 * This is for the reason of 1000 uCode using advance thermal throttling API
63 * but not implement ct_kill_exit based on ct_kill exit temperature
64 * so the thermal throttling will still based on legacy thermal throttling
65 * management.
66 * The code here need to be modified once 1000 uCode has the advanced thermal
67 * throttling algorithm in place
68 */
69static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
70{
71 /* want Celsius */
72 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
73 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
74}
75
76static struct iwl_lib_ops iwl1000_lib = {
77 .set_hw_params = iwl5000_hw_set_hw_params,
78 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
79 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
80 .txq_set_sched = iwl5000_txq_set_sched,
81 .txq_agg_enable = iwl5000_txq_agg_enable,
82 .txq_agg_disable = iwl5000_txq_agg_disable,
83 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
84 .txq_free_tfd = iwl_hw_txq_free_tfd,
85 .txq_init = iwl_hw_tx_queue_init,
86 .rx_handler_setup = iwl5000_rx_handler_setup,
87 .setup_deferred_work = iwl5000_setup_deferred_work,
88 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
89 .load_ucode = iwl5000_load_ucode,
90 .init_alive_start = iwl5000_init_alive_start,
91 .alive_notify = iwl5000_alive_notify,
92 .send_tx_power = iwl5000_send_tx_power,
93 .update_chain_flags = iwl_update_chain_flags,
94 .apm_ops = {
95 .init = iwl5000_apm_init,
96 .reset = iwl5000_apm_reset,
97 .stop = iwl5000_apm_stop,
98 .config = iwl5000_nic_config,
99 .set_pwr_src = iwl_set_pwr_src,
100 },
101 .eeprom_ops = {
102 .regulatory_bands = {
103 EEPROM_5000_REG_BAND_1_CHANNELS,
104 EEPROM_5000_REG_BAND_2_CHANNELS,
105 EEPROM_5000_REG_BAND_3_CHANNELS,
106 EEPROM_5000_REG_BAND_4_CHANNELS,
107 EEPROM_5000_REG_BAND_5_CHANNELS,
108 EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
109 EEPROM_5000_REG_BAND_52_FAT_CHANNELS
110 },
111 .verify_signature = iwlcore_eeprom_verify_signature,
112 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
113 .release_semaphore = iwlcore_eeprom_release_semaphore,
114 .calib_version = iwl5000_eeprom_calib_version,
115 .query_addr = iwl5000_eeprom_query_addr,
116 },
117 .post_associate = iwl_post_associate,
118 .isr = iwl_isr_ict,
119 .config_ap = iwl_config_ap,
120 .temp_ops = {
121 .temperature = iwl5000_temperature,
122 .set_ct_kill = iwl1000_set_ct_threshold,
123 },
124};
125
126static struct iwl_ops iwl1000_ops = {
127 .ucode = &iwl5000_ucode,
128 .lib = &iwl1000_lib,
129 .hcmd = &iwl5000_hcmd,
130 .utils = &iwl5000_hcmd_utils,
131};
132
58struct iwl_cfg iwl1000_bgn_cfg = { 133struct iwl_cfg iwl1000_bgn_cfg = {
59 .name = "1000 Series BGN", 134 .name = "1000 Series BGN",
60 .fw_name_pre = IWL1000_FW_PRE, 135 .fw_name_pre = IWL1000_FW_PRE,
61 .ucode_api_max = IWL1000_UCODE_API_MAX, 136 .ucode_api_max = IWL1000_UCODE_API_MAX,
62 .ucode_api_min = IWL1000_UCODE_API_MIN, 137 .ucode_api_min = IWL1000_UCODE_API_MIN,
63 .sku = IWL_SKU_G|IWL_SKU_N, 138 .sku = IWL_SKU_G|IWL_SKU_N,
64 .ops = &iwl5000_ops, 139 .ops = &iwl1000_ops,
65 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 140 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
66 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 141 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
67 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 142 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-led.c b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
index 225e5f889346..8c29ded7d02c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-led.c
@@ -79,11 +79,10 @@ static const struct {
79#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/ 79#define IWL_MAX_BLINK_TBL (ARRAY_SIZE(blink_tbl) - 1) /*Exclude Solid on*/
80#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1) 80#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)
81 81
82static int iwl3945_led_cmd_callback(struct iwl_priv *priv, 82static void iwl3945_led_cmd_callback(struct iwl_priv *priv,
83 struct iwl_cmd *cmd, 83 struct iwl_device_cmd *cmd,
84 struct sk_buff *skb) 84 struct sk_buff *skb)
85{ 85{
86 return 1;
87} 86}
88 87
89static inline int iwl3945_brightness_to_idx(enum led_brightness brightness) 88static inline int iwl3945_brightness_to_idx(enum led_brightness brightness)
@@ -99,8 +98,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv,
99 .id = REPLY_LEDS_CMD, 98 .id = REPLY_LEDS_CMD,
100 .len = sizeof(struct iwl_led_cmd), 99 .len = sizeof(struct iwl_led_cmd),
101 .data = led_cmd, 100 .data = led_cmd,
102 .meta.flags = CMD_ASYNC, 101 .flags = CMD_ASYNC,
103 .meta.u.callback = iwl3945_led_cmd_callback, 102 .callback = iwl3945_led_cmd_callback,
104 }; 103 };
105 104
106 return iwl_send_cmd(priv, &cmd); 105 return iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8ee403cd9b99..e1b0ef3c56a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -749,8 +749,8 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
749 /* Unmap tx_cmd */ 749 /* Unmap tx_cmd */
750 if (counter) 750 if (counter)
751 pci_unmap_single(dev, 751 pci_unmap_single(dev,
752 pci_unmap_addr(&txq->cmd[index]->meta, mapping), 752 pci_unmap_addr(&txq->meta[index], mapping),
753 pci_unmap_len(&txq->cmd[index]->meta, len), 753 pci_unmap_len(&txq->meta[index], len),
754 PCI_DMA_TODEVICE); 754 PCI_DMA_TODEVICE);
755 755
756 /* unmap chunks if any */ 756 /* unmap chunks if any */
@@ -774,9 +774,11 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
774 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD: 774 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
775 * 775 *
776*/ 776*/
777void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, 777void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
778 struct ieee80211_tx_info *info, 778 struct iwl_device_cmd *cmd,
779 struct ieee80211_hdr *hdr, int sta_id, int tx_id) 779 struct ieee80211_tx_info *info,
780 struct ieee80211_hdr *hdr,
781 int sta_id, int tx_id)
780{ 782{
781 u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value; 783 u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
782 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1); 784 u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
@@ -1858,7 +1860,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1858 struct iwl_host_cmd cmd = { 1860 struct iwl_host_cmd cmd = {
1859 .id = REPLY_RXON_ASSOC, 1861 .id = REPLY_RXON_ASSOC,
1860 .len = sizeof(rxon_assoc), 1862 .len = sizeof(rxon_assoc),
1861 .meta.flags = CMD_WANT_SKB, 1863 .flags = CMD_WANT_SKB,
1862 .data = &rxon_assoc, 1864 .data = &rxon_assoc,
1863 }; 1865 };
1864 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; 1866 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
@@ -1882,14 +1884,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1882 if (rc) 1884 if (rc)
1883 return rc; 1885 return rc;
1884 1886
1885 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 1887 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
1886 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 1888 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
1887 IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n"); 1889 IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
1888 rc = -EIO; 1890 rc = -EIO;
1889 } 1891 }
1890 1892
1891 priv->alloc_rxb_skb--; 1893 priv->alloc_rxb_skb--;
1892 dev_kfree_skb_any(cmd.meta.u.skb); 1894 dev_kfree_skb_any(cmd.reply_skb);
1893 1895
1894 return rc; 1896 return rc;
1895} 1897}
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index f2ffc48cbaf8..f24036909916 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -254,10 +254,11 @@ extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
254 struct iwl_tx_queue *txq); 254 struct iwl_tx_queue *txq);
255extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, 255extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
256 struct iwl3945_frame *frame, u8 rate); 256 struct iwl3945_frame *frame, u8 rate);
257void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, 257void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
258 struct ieee80211_tx_info *info, 258 struct iwl_device_cmd *cmd,
259 struct ieee80211_hdr *hdr, 259 struct ieee80211_tx_info *info,
260 int sta_id, int tx_id); 260 struct ieee80211_hdr *hdr,
261 int sta_id, int tx_id);
261extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); 262extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv);
262extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); 263extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power);
263extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, 264extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index c30a1b960576..670214823cb9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -776,7 +776,8 @@ static struct iwl_sensitivity_ranges iwl4965_sensitivity = {
776static void iwl4965_set_ct_threshold(struct iwl_priv *priv) 776static void iwl4965_set_ct_threshold(struct iwl_priv *priv)
777{ 777{
778 /* want Kelvin */ 778 /* want Kelvin */
779 priv->hw_params.ct_kill_threshold = CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD); 779 priv->hw_params.ct_kill_threshold =
780 CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY);
780} 781}
781 782
782/** 783/**
@@ -1796,6 +1797,7 @@ static void iwl4965_temperature_calib(struct iwl_priv *priv)
1796 } 1797 }
1797 1798
1798 priv->temperature = temp; 1799 priv->temperature = temp;
1800 iwl_tt_handler(priv);
1799 set_bit(STATUS_TEMPERATURE, &priv->status); 1801 set_bit(STATUS_TEMPERATURE, &priv->status);
1800 1802
1801 if (!priv->disable_tx_power_cal && 1803 if (!priv->disable_tx_power_cal &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 702db07fa382..ddd64fef3039 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -91,7 +91,7 @@ static int iwl5000_apm_stop_master(struct iwl_priv *priv)
91} 91}
92 92
93 93
94static int iwl5000_apm_init(struct iwl_priv *priv) 94int iwl5000_apm_init(struct iwl_priv *priv)
95{ 95{
96 int ret = 0; 96 int ret = 0;
97 97
@@ -137,7 +137,7 @@ static int iwl5000_apm_init(struct iwl_priv *priv)
137} 137}
138 138
139/* FIXME: this is identical to 4965 */ 139/* FIXME: this is identical to 4965 */
140static void iwl5000_apm_stop(struct iwl_priv *priv) 140void iwl5000_apm_stop(struct iwl_priv *priv)
141{ 141{
142 unsigned long flags; 142 unsigned long flags;
143 143
@@ -156,7 +156,7 @@ static void iwl5000_apm_stop(struct iwl_priv *priv)
156} 156}
157 157
158 158
159static int iwl5000_apm_reset(struct iwl_priv *priv) 159int iwl5000_apm_reset(struct iwl_priv *priv)
160{ 160{
161 int ret = 0; 161 int ret = 0;
162 162
@@ -198,7 +198,7 @@ out:
198} 198}
199 199
200 200
201static void iwl5000_nic_config(struct iwl_priv *priv) 201void iwl5000_nic_config(struct iwl_priv *priv)
202{ 202{
203 unsigned long flags; 203 unsigned long flags;
204 u16 radio_cfg; 204 u16 radio_cfg;
@@ -290,7 +290,7 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address)
290 return (address & ADDRESS_MSK) + (offset << 1); 290 return (address & ADDRESS_MSK) + (offset << 1);
291} 291}
292 292
293static u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv) 293u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv)
294{ 294{
295 struct iwl_eeprom_calib_hdr { 295 struct iwl_eeprom_calib_hdr {
296 u8 version; 296 u8 version;
@@ -436,7 +436,7 @@ static struct iwl_sensitivity_ranges iwl5150_sensitivity = {
436 .nrg_th_ofdm = 95, 436 .nrg_th_ofdm = 95,
437}; 437};
438 438
439static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, 439const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
440 size_t offset) 440 size_t offset)
441{ 441{
442 u32 address = eeprom_indirect_address(priv, offset); 442 u32 address = eeprom_indirect_address(priv, offset);
@@ -447,7 +447,7 @@ static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
447static void iwl5150_set_ct_threshold(struct iwl_priv *priv) 447static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
448{ 448{
449 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF; 449 const s32 volt2temp_coef = IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF;
450 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD) - 450 s32 threshold = (s32)CELSIUS_TO_KELVIN(CT_KILL_THRESHOLD_LEGACY) -
451 iwl_temp_calib_to_offset(priv); 451 iwl_temp_calib_to_offset(priv);
452 452
453 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef; 453 priv->hw_params.ct_kill_threshold = threshold * volt2temp_coef;
@@ -456,7 +456,7 @@ static void iwl5150_set_ct_threshold(struct iwl_priv *priv)
456static void iwl5000_set_ct_threshold(struct iwl_priv *priv) 456static void iwl5000_set_ct_threshold(struct iwl_priv *priv)
457{ 457{
458 /* want Celsius */ 458 /* want Celsius */
459 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD; 459 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD_LEGACY;
460} 460}
461 461
462/* 462/*
@@ -631,7 +631,7 @@ static int iwl5000_load_given_ucode(struct iwl_priv *priv,
631 return ret; 631 return ret;
632} 632}
633 633
634static int iwl5000_load_ucode(struct iwl_priv *priv) 634int iwl5000_load_ucode(struct iwl_priv *priv)
635{ 635{
636 int ret = 0; 636 int ret = 0;
637 637
@@ -658,7 +658,7 @@ static int iwl5000_load_ucode(struct iwl_priv *priv)
658 return ret; 658 return ret;
659} 659}
660 660
661static void iwl5000_init_alive_start(struct iwl_priv *priv) 661void iwl5000_init_alive_start(struct iwl_priv *priv)
662{ 662{
663 int ret = 0; 663 int ret = 0;
664 664
@@ -734,7 +734,7 @@ static int iwl5000_send_wimax_coex(struct iwl_priv *priv)
734 sizeof(coex_cmd), &coex_cmd); 734 sizeof(coex_cmd), &coex_cmd);
735} 735}
736 736
737static int iwl5000_alive_notify(struct iwl_priv *priv) 737int iwl5000_alive_notify(struct iwl_priv *priv)
738{ 738{
739 u32 a; 739 u32 a;
740 unsigned long flags; 740 unsigned long flags;
@@ -821,7 +821,7 @@ static int iwl5000_alive_notify(struct iwl_priv *priv)
821 return 0; 821 return 0;
822} 822}
823 823
824static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) 824int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
825{ 825{
826 if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) || 826 if ((priv->cfg->mod_params->num_of_queues > IWL50_NUM_QUEUES) ||
827 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) { 827 (priv->cfg->mod_params->num_of_queues < IWL_MIN_NUM_QUEUES)) {
@@ -892,7 +892,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
892/** 892/**
893 * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array 893 * iwl5000_txq_update_byte_cnt_tbl - Set up entry in Tx byte-count array
894 */ 894 */
895static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, 895void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
896 struct iwl_tx_queue *txq, 896 struct iwl_tx_queue *txq,
897 u16 byte_cnt) 897 u16 byte_cnt)
898{ 898{
@@ -932,7 +932,7 @@ static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
932 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 932 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
933} 933}
934 934
935static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, 935void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
936 struct iwl_tx_queue *txq) 936 struct iwl_tx_queue *txq)
937{ 937{
938 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr; 938 struct iwl5000_scd_bc_tbl *scd_bc_tbl = priv->scd_bc_tbls.addr;
@@ -987,7 +987,7 @@ static void iwl5000_tx_queue_stop_scheduler(struct iwl_priv *priv, u16 txq_id)
987 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN)); 987 (1 << IWL50_SCD_QUEUE_STTS_REG_POS_SCD_ACT_EN));
988} 988}
989 989
990static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, 990int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
991 int tx_fifo, int sta_id, int tid, u16 ssn_idx) 991 int tx_fifo, int sta_id, int tid, u16 ssn_idx)
992{ 992{
993 unsigned long flags; 993 unsigned long flags;
@@ -1048,7 +1048,7 @@ static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
1048 return 0; 1048 return 0;
1049} 1049}
1050 1050
1051static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, 1051int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
1052 u16 ssn_idx, u8 tx_fifo) 1052 u16 ssn_idx, u8 tx_fifo)
1053{ 1053{
1054 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) || 1054 if ((IWL50_FIRST_AMPDU_QUEUE > txq_id) ||
@@ -1091,7 +1091,7 @@ u16 iwl5000_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
1091 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask 1091 * Activate/Deactivate Tx DMA/FIFO channels according tx fifos mask
1092 * must be called under priv->lock and mac access 1092 * must be called under priv->lock and mac access
1093 */ 1093 */
1094static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask) 1094void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask)
1095{ 1095{
1096 iwl_write_prph(priv, IWL50_SCD_TXFACT, mask); 1096 iwl_write_prph(priv, IWL50_SCD_TXFACT, mask);
1097} 1097}
@@ -1312,13 +1312,13 @@ u16 iwl5000_get_hcmd_size(u8 cmd_id, u16 len)
1312 return len; 1312 return len;
1313} 1313}
1314 1314
1315static void iwl5000_setup_deferred_work(struct iwl_priv *priv) 1315void iwl5000_setup_deferred_work(struct iwl_priv *priv)
1316{ 1316{
1317 /* in 5000 the tx power calibration is done in uCode */ 1317 /* in 5000 the tx power calibration is done in uCode */
1318 priv->disable_tx_power_cal = 1; 1318 priv->disable_tx_power_cal = 1;
1319} 1319}
1320 1320
1321static void iwl5000_rx_handler_setup(struct iwl_priv *priv) 1321void iwl5000_rx_handler_setup(struct iwl_priv *priv)
1322{ 1322{
1323 /* init calibration handlers */ 1323 /* init calibration handlers */
1324 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] = 1324 priv->rx_handlers[CALIBRATION_RES_NOTIFICATION] =
@@ -1329,7 +1329,7 @@ static void iwl5000_rx_handler_setup(struct iwl_priv *priv)
1329} 1329}
1330 1330
1331 1331
1332static int iwl5000_hw_valid_rtc_data_addr(u32 addr) 1332int iwl5000_hw_valid_rtc_data_addr(u32 addr)
1333{ 1333{
1334 return (addr >= IWL50_RTC_DATA_LOWER_BOUND) && 1334 return (addr >= IWL50_RTC_DATA_LOWER_BOUND) &&
1335 (addr < IWL50_RTC_DATA_UPPER_BOUND); 1335 (addr < IWL50_RTC_DATA_UPPER_BOUND);
@@ -1381,7 +1381,7 @@ static int iwl5000_send_rxon_assoc(struct iwl_priv *priv)
1381 1381
1382 return ret; 1382 return ret;
1383} 1383}
1384static int iwl5000_send_tx_power(struct iwl_priv *priv) 1384int iwl5000_send_tx_power(struct iwl_priv *priv)
1385{ 1385{
1386 struct iwl5000_tx_power_dbm_cmd tx_power_cmd; 1386 struct iwl5000_tx_power_dbm_cmd tx_power_cmd;
1387 u8 tx_ant_cfg_cmd; 1387 u8 tx_ant_cfg_cmd;
@@ -1401,10 +1401,11 @@ static int iwl5000_send_tx_power(struct iwl_priv *priv)
1401 NULL); 1401 NULL);
1402} 1402}
1403 1403
1404static void iwl5000_temperature(struct iwl_priv *priv) 1404void iwl5000_temperature(struct iwl_priv *priv)
1405{ 1405{
1406 /* store temperature from statistics (in Celsius) */ 1406 /* store temperature from statistics (in Celsius) */
1407 priv->temperature = le32_to_cpu(priv->statistics.general.temperature); 1407 priv->temperature = le32_to_cpu(priv->statistics.general.temperature);
1408 iwl_tt_handler(priv);
1408} 1409}
1409 1410
1410static void iwl5150_temperature(struct iwl_priv *priv) 1411static void iwl5150_temperature(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 26c5d4a60d17..59ff73536f3a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -61,6 +61,63 @@
61#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" 61#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
62#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api) 62#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
63 63
64static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
65{
66 /* want Celsius */
67 priv->hw_params.ct_kill_threshold = CT_KILL_THRESHOLD;
68 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
69}
70
71static struct iwl_lib_ops iwl6000_lib = {
72 .set_hw_params = iwl5000_hw_set_hw_params,
73 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
74 .txq_inval_byte_cnt_tbl = iwl5000_txq_inval_byte_cnt_tbl,
75 .txq_set_sched = iwl5000_txq_set_sched,
76 .txq_agg_enable = iwl5000_txq_agg_enable,
77 .txq_agg_disable = iwl5000_txq_agg_disable,
78 .txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
79 .txq_free_tfd = iwl_hw_txq_free_tfd,
80 .txq_init = iwl_hw_tx_queue_init,
81 .rx_handler_setup = iwl5000_rx_handler_setup,
82 .setup_deferred_work = iwl5000_setup_deferred_work,
83 .is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
84 .load_ucode = iwl5000_load_ucode,
85 .init_alive_start = iwl5000_init_alive_start,
86 .alive_notify = iwl5000_alive_notify,
87 .send_tx_power = iwl5000_send_tx_power,
88 .update_chain_flags = iwl_update_chain_flags,
89 .apm_ops = {
90 .init = iwl5000_apm_init,
91 .reset = iwl5000_apm_reset,
92 .stop = iwl5000_apm_stop,
93 .config = iwl5000_nic_config,
94 .set_pwr_src = iwl_set_pwr_src,
95 },
96 .eeprom_ops = {
97 .regulatory_bands = {
98 EEPROM_5000_REG_BAND_1_CHANNELS,
99 EEPROM_5000_REG_BAND_2_CHANNELS,
100 EEPROM_5000_REG_BAND_3_CHANNELS,
101 EEPROM_5000_REG_BAND_4_CHANNELS,
102 EEPROM_5000_REG_BAND_5_CHANNELS,
103 EEPROM_5000_REG_BAND_24_FAT_CHANNELS,
104 EEPROM_5000_REG_BAND_52_FAT_CHANNELS
105 },
106 .verify_signature = iwlcore_eeprom_verify_signature,
107 .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
108 .release_semaphore = iwlcore_eeprom_release_semaphore,
109 .calib_version = iwl5000_eeprom_calib_version,
110 .query_addr = iwl5000_eeprom_query_addr,
111 },
112 .post_associate = iwl_post_associate,
113 .isr = iwl_isr_ict,
114 .config_ap = iwl_config_ap,
115 .temp_ops = {
116 .temperature = iwl5000_temperature,
117 .set_ct_kill = iwl6000_set_ct_threshold,
118 },
119};
120
64static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = { 121static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
65 .get_hcmd_size = iwl5000_get_hcmd_size, 122 .get_hcmd_size = iwl5000_get_hcmd_size,
66 .build_addsta_hcmd = iwl5000_build_addsta_hcmd, 123 .build_addsta_hcmd = iwl5000_build_addsta_hcmd,
@@ -70,7 +127,7 @@ static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
70 127
71static struct iwl_ops iwl6000_ops = { 128static struct iwl_ops iwl6000_ops = {
72 .ucode = &iwl5000_ucode, 129 .ucode = &iwl5000_ucode,
73 .lib = &iwl5000_lib, 130 .lib = &iwl6000_lib,
74 .hcmd = &iwl5000_hcmd, 131 .hcmd = &iwl5000_hcmd,
75 .utils = &iwl6000_hcmd_utils, 132 .utils = &iwl6000_hcmd_utils,
76}; 133};
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 63280411fd58..52a4810274e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -177,7 +177,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
177 struct sk_buff *skb, 177 struct sk_buff *skb,
178 struct ieee80211_sta *sta, 178 struct ieee80211_sta *sta,
179 struct iwl_lq_sta *lq_sta); 179 struct iwl_lq_sta *lq_sta);
180static void rs_fill_link_cmd(const struct iwl_priv *priv, 180static void rs_fill_link_cmd(struct iwl_priv *priv,
181 struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 181 struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
182 182
183 183
@@ -1398,6 +1398,12 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
1398 int ret = 0; 1398 int ret = 0;
1399 u8 update_search_tbl_counter = 0; 1399 u8 update_search_tbl_counter = 0;
1400 1400
1401 if (!iwl_ht_enabled(priv))
1402 /* stay in Legacy */
1403 tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
1404 else if (iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE &&
1405 tbl->action > IWL_LEGACY_SWITCH_SISO)
1406 tbl->action = IWL_LEGACY_SWITCH_SISO;
1401 for (; ;) { 1407 for (; ;) {
1402 lq_sta->action_counter++; 1408 lq_sta->action_counter++;
1403 switch (tbl->action) { 1409 switch (tbl->action) {
@@ -1529,6 +1535,11 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
1529 u8 update_search_tbl_counter = 0; 1535 u8 update_search_tbl_counter = 0;
1530 int ret; 1536 int ret;
1531 1537
1538 if (iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE &&
1539 tbl->action > IWL_SISO_SWITCH_ANTENNA2) {
1540 /* stay in SISO */
1541 tbl->action = IWL_SISO_SWITCH_ANTENNA1;
1542 }
1532 for (;;) { 1543 for (;;) {
1533 lq_sta->action_counter++; 1544 lq_sta->action_counter++;
1534 switch (tbl->action) { 1545 switch (tbl->action) {
@@ -1663,6 +1674,12 @@ static int rs_move_mimo2_to_other(struct iwl_priv *priv,
1663 u8 update_search_tbl_counter = 0; 1674 u8 update_search_tbl_counter = 0;
1664 int ret; 1675 int ret;
1665 1676
1677 if ((iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE) &&
1678 (tbl->action < IWL_MIMO2_SWITCH_SISO_A ||
1679 tbl->action > IWL_MIMO2_SWITCH_SISO_C)) {
1680 /* switch in SISO */
1681 tbl->action = IWL_MIMO2_SWITCH_SISO_A;
1682 }
1666 for (;;) { 1683 for (;;) {
1667 lq_sta->action_counter++; 1684 lq_sta->action_counter++;
1668 switch (tbl->action) { 1685 switch (tbl->action) {
@@ -1799,6 +1816,12 @@ static int rs_move_mimo3_to_other(struct iwl_priv *priv,
1799 int ret; 1816 int ret;
1800 u8 update_search_tbl_counter = 0; 1817 u8 update_search_tbl_counter = 0;
1801 1818
1819 if ((iwl_tx_ant_restriction(priv) == IWL_TX_SINGLE) &&
1820 (tbl->action < IWL_MIMO3_SWITCH_SISO_A ||
1821 tbl->action > IWL_MIMO3_SWITCH_SISO_C)) {
1822 /* switch in SISO */
1823 tbl->action = IWL_MIMO3_SWITCH_SISO_A;
1824 }
1802 for (;;) { 1825 for (;;) {
1803 lq_sta->action_counter++; 1826 lq_sta->action_counter++;
1804 switch (tbl->action) { 1827 switch (tbl->action) {
@@ -2003,6 +2026,25 @@ static void rs_stay_in_table(struct iwl_lq_sta *lq_sta)
2003} 2026}
2004 2027
2005/* 2028/*
2029 * setup rate table in uCode
2030 * return rate_n_flags as used in the table
2031 */
2032static u32 rs_update_rate_tbl(struct iwl_priv *priv,
2033 struct iwl_lq_sta *lq_sta,
2034 struct iwl_scale_tbl_info *tbl,
2035 int index, u8 is_green)
2036{
2037 u32 rate;
2038
2039 /* Update uCode's rate table. */
2040 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green);
2041 rs_fill_link_cmd(priv, lq_sta, rate);
2042 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2043
2044 return rate;
2045}
2046
2047/*
2006 * Do rate scaling and search for new modulation mode. 2048 * Do rate scaling and search for new modulation mode.
2007 */ 2049 */
2008static void rs_rate_scale_perform(struct iwl_priv *priv, 2050static void rs_rate_scale_perform(struct iwl_priv *priv,
@@ -2098,6 +2140,16 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2098 2140
2099 if (!((1 << index) & rate_scale_index_msk)) { 2141 if (!((1 << index) & rate_scale_index_msk)) {
2100 IWL_ERR(priv, "Current Rate is not valid\n"); 2142 IWL_ERR(priv, "Current Rate is not valid\n");
2143 if (lq_sta->search_better_tbl) {
2144 /* revert to active table if search table is not valid*/
2145 tbl->lq_type = LQ_NONE;
2146 lq_sta->search_better_tbl = 0;
2147 tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
2148 /* get "active" rate info */
2149 index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
2150 rate = rs_update_rate_tbl(priv, lq_sta,
2151 tbl, index, is_green);
2152 }
2101 return; 2153 return;
2102 } 2154 }
2103 2155
@@ -2149,8 +2201,8 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2149 tbl->expected_tpt[index] + 64) / 128)); 2201 tbl->expected_tpt[index] + 64) / 128));
2150 2202
2151 /* If we are searching for better modulation mode, check success. */ 2203 /* If we are searching for better modulation mode, check success. */
2152 if (lq_sta->search_better_tbl) { 2204 if (lq_sta->search_better_tbl &&
2153 2205 (iwl_tx_ant_restriction(priv) == IWL_TX_MULTI)) {
2154 /* If good success, continue using the "search" mode; 2206 /* If good success, continue using the "search" mode;
2155 * no need to send new link quality command, since we're 2207 * no need to send new link quality command, since we're
2156 * continuing to use the setup that we've been trying. */ 2208 * continuing to use the setup that we've been trying. */
@@ -2278,7 +2330,11 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2278 ((sr > IWL_RATE_HIGH_TH) || 2330 ((sr > IWL_RATE_HIGH_TH) ||
2279 (current_tpt > (100 * tbl->expected_tpt[low])))) 2331 (current_tpt > (100 * tbl->expected_tpt[low]))))
2280 scale_action = 0; 2332 scale_action = 0;
2281 2333 if (!iwl_ht_enabled(priv) && !is_legacy(tbl->lq_type))
2334 scale_action = -1;
2335 if (iwl_tx_ant_restriction(priv) != IWL_TX_MULTI &&
2336 (is_mimo2(tbl->lq_type) || is_mimo3(tbl->lq_type)))
2337 scale_action = -1;
2282 switch (scale_action) { 2338 switch (scale_action) {
2283 case -1: 2339 case -1:
2284 /* Decrease starting rate, update uCode's rate table */ 2340 /* Decrease starting rate, update uCode's rate table */
@@ -2308,15 +2364,15 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2308 2364
2309lq_update: 2365lq_update:
2310 /* Replace uCode's rate table for the destination station. */ 2366 /* Replace uCode's rate table for the destination station. */
2311 if (update_lq) { 2367 if (update_lq)
2312 rate = rate_n_flags_from_tbl(priv, tbl, index, is_green); 2368 rate = rs_update_rate_tbl(priv, lq_sta,
2313 rs_fill_link_cmd(priv, lq_sta, rate); 2369 tbl, index, is_green);
2314 iwl_send_lq_cmd(priv, &lq_sta->lq, CMD_ASYNC);
2315 }
2316
2317 /* Should we stay with this modulation mode, or search for a new one? */
2318 rs_stay_in_table(lq_sta);
2319 2370
2371 if (iwl_tx_ant_restriction(priv) == IWL_TX_MULTI) {
2372 /* Should we stay with this modulation mode,
2373 * or search for a new one? */
2374 rs_stay_in_table(lq_sta);
2375 }
2320 /* 2376 /*
2321 * Search for new modulation mode if we're: 2377 * Search for new modulation mode if we're:
2322 * 1) Not changing rates right now 2378 * 1) Not changing rates right now
@@ -2373,7 +2429,8 @@ lq_update:
2373 * have been tried and compared, stay in this best modulation 2429 * have been tried and compared, stay in this best modulation
2374 * mode for a while before next round of mode comparisons. */ 2430 * mode for a while before next round of mode comparisons. */
2375 if (lq_sta->enable_counter && 2431 if (lq_sta->enable_counter &&
2376 (lq_sta->action_counter >= tbl1->max_search)) { 2432 (lq_sta->action_counter >= tbl1->max_search) &&
2433 iwl_ht_enabled(priv)) {
2377 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && 2434 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2378 (lq_sta->tx_agg_tid_en & (1 << tid)) && 2435 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2379 (tid != MAX_TID_COUNT)) { 2436 (tid != MAX_TID_COUNT)) {
@@ -2659,7 +2716,7 @@ static void rs_rate_init(void *priv_r, struct ieee80211_supported_band *sband,
2659 rs_initialize_lq(priv, conf, sta, lq_sta); 2716 rs_initialize_lq(priv, conf, sta, lq_sta);
2660} 2717}
2661 2718
2662static void rs_fill_link_cmd(const struct iwl_priv *priv, 2719static void rs_fill_link_cmd(struct iwl_priv *priv,
2663 struct iwl_lq_sta *lq_sta, u32 new_rate) 2720 struct iwl_lq_sta *lq_sta, u32 new_rate)
2664{ 2721{
2665 struct iwl_scale_tbl_info tbl_type; 2722 struct iwl_scale_tbl_info tbl_type;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 44c7f236a7a3..4cb1a1b73483 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -442,8 +442,8 @@ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
442 /* Unmap tx_cmd */ 442 /* Unmap tx_cmd */
443 if (num_tbs) 443 if (num_tbs)
444 pci_unmap_single(dev, 444 pci_unmap_single(dev,
445 pci_unmap_addr(&txq->cmd[index]->meta, mapping), 445 pci_unmap_addr(&txq->meta[index], mapping),
446 pci_unmap_len(&txq->cmd[index]->meta, len), 446 pci_unmap_len(&txq->meta[index], len),
447 PCI_DMA_BIDIRECTIONAL); 447 PCI_DMA_BIDIRECTIONAL);
448 448
449 /* Unmap chunks, if any. */ 449 /* Unmap chunks, if any. */
@@ -637,7 +637,6 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
637 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data; 637 struct iwl_rx_packet *pkt = (struct iwl_rx_packet *)rxb->skb->data;
638 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); 638 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
639 unsigned long status = priv->status; 639 unsigned long status = priv->status;
640 unsigned long reg_flags;
641 640
642 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", 641 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n",
643 (flags & HW_CARD_DISABLED) ? "Kill" : "On", 642 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
@@ -657,19 +656,12 @@ static void iwl_rx_card_state_notif(struct iwl_priv *priv,
657 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED); 656 CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED);
658 iwl_write_direct32(priv, HBUS_TARG_MBX_C, 657 iwl_write_direct32(priv, HBUS_TARG_MBX_C,
659 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED); 658 HBUS_TARG_MBX_C_REG_BIT_CMD_BLOCKED);
660
661 }
662
663 if (flags & RF_CARD_DISABLED) {
664 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
665 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
666 iwl_read32(priv, CSR_UCODE_DRV_GP1);
667 spin_lock_irqsave(&priv->reg_lock, reg_flags);
668 if (!iwl_grab_nic_access(priv))
669 iwl_release_nic_access(priv);
670 spin_unlock_irqrestore(&priv->reg_lock, reg_flags);
671 } 659 }
660 if (flags & RF_CARD_DISABLED)
661 iwl_tt_enter_ct_kill(priv);
672 } 662 }
663 if (!(flags & RF_CARD_DISABLED))
664 iwl_tt_exit_ct_kill(priv);
673 665
674 if (flags & HW_CARD_DISABLED) 666 if (flags & HW_CARD_DISABLED)
675 set_bit(STATUS_RF_KILL_HW, &priv->status); 667 set_bit(STATUS_RF_KILL_HW, &priv->status);
@@ -3015,6 +3007,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3015 test_bit(STATUS_RF_KILL_HW, &priv->status)); 3007 test_bit(STATUS_RF_KILL_HW, &priv->status));
3016 3008
3017 iwl_power_initialize(priv); 3009 iwl_power_initialize(priv);
3010 iwl_tt_initialize(priv);
3018 return 0; 3011 return 0;
3019 3012
3020 out_remove_sysfs: 3013 out_remove_sysfs:
@@ -3067,6 +3060,8 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
3067 iwl_down(priv); 3060 iwl_down(priv);
3068 } 3061 }
3069 3062
3063 iwl_tt_exit(priv);
3064
3070 /* make sure we flush any pending irq or 3065 /* make sure we flush any pending irq or
3071 * tasklet for the driver 3066 * tasklet for the driver
3072 */ 3067 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-calib.c b/drivers/net/wireless/iwlwifi/iwl-calib.c
index f8bf592e939c..13180d6ee2f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-calib.c
@@ -86,7 +86,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)
86 86
87 struct iwl_host_cmd hcmd = { 87 struct iwl_host_cmd hcmd = {
88 .id = REPLY_PHY_CALIBRATION_CMD, 88 .id = REPLY_PHY_CALIBRATION_CMD,
89 .meta.flags = CMD_SIZE_HUGE, 89 .flags = CMD_SIZE_HUGE,
90 }; 90 };
91 91
92 for (i = 0; i < IWL_CALIB_MAX; i++) { 92 for (i = 0; i < IWL_CALIB_MAX; i++) {
@@ -419,7 +419,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
419 struct iwl_host_cmd cmd_out = { 419 struct iwl_host_cmd cmd_out = {
420 .id = SENSITIVITY_CMD, 420 .id = SENSITIVITY_CMD,
421 .len = sizeof(struct iwl_sensitivity_cmd), 421 .len = sizeof(struct iwl_sensitivity_cmd),
422 .meta.flags = CMD_ASYNC, 422 .flags = CMD_ASYNC,
423 .data = &cmd, 423 .data = &cmd,
424 }; 424 };
425 425
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index ebb2fbce5365..39ede5727fe4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2413,6 +2413,13 @@ struct iwl_ct_kill_config {
2413 __le32 critical_temperature_R; 2413 __le32 critical_temperature_R;
2414} __attribute__ ((packed)); 2414} __attribute__ ((packed));
2415 2415
2416/* 1000, and 6x00 */
2417struct iwl_ct_kill_throttling_config {
2418 __le32 critical_temperature_exit;
2419 __le32 reserved;
2420 __le32 critical_temperature_enter;
2421} __attribute__ ((packed));
2422
2416/****************************************************************************** 2423/******************************************************************************
2417 * (8) 2424 * (8)
2418 * Scan Commands, Responses, Notifications: 2425 * Scan Commands, Responses, Notifications:
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 6aea02644809..8570d56b3124 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -632,6 +632,10 @@ u8 iwl_is_fat_tx_allowed(struct iwl_priv *priv,
632 if (!sta_ht_inf->ht_supported) 632 if (!sta_ht_inf->ht_supported)
633 return 0; 633 return 0;
634 } 634 }
635#ifdef CONFIG_IWLWIFI_DEBUG
636 if (priv->disable_ht40)
637 return 0;
638#endif
635 return iwl_is_channel_extension(priv, priv->band, 639 return iwl_is_channel_extension(priv, priv->band,
636 le16_to_cpu(priv->staging_rxon.channel), 640 le16_to_cpu(priv->staging_rxon.channel),
637 iwl_ht_conf->extension_chan_offset); 641 iwl_ht_conf->extension_chan_offset);
@@ -1291,7 +1295,6 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
1291 IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr); 1295 IWL_DEBUG_RADIO(priv, "u8[6] bssid_addr: %pM\n", rxon->bssid_addr);
1292 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id)); 1296 IWL_DEBUG_RADIO(priv, "u16 assoc_id: 0x%x\n", le16_to_cpu(rxon->assoc_id));
1293} 1297}
1294#endif
1295 1298
1296static const char *desc_lookup_text[] = { 1299static const char *desc_lookup_text[] = {
1297 "OK", 1300 "OK",
@@ -1496,6 +1499,7 @@ void iwl_dump_nic_event_log(struct iwl_priv *priv)
1496 iwl_print_event_log(priv, 0, next_entry, mode); 1499 iwl_print_event_log(priv, 0, next_entry, mode);
1497 1500
1498} 1501}
1502#endif
1499/** 1503/**
1500 * iwl_irq_handle_error - called for HW or SW error interrupt from card 1504 * iwl_irq_handle_error - called for HW or SW error interrupt from card
1501 */ 1505 */
@@ -2089,7 +2093,7 @@ int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
2089 u32 stat_flags = 0; 2093 u32 stat_flags = 0;
2090 struct iwl_host_cmd cmd = { 2094 struct iwl_host_cmd cmd = {
2091 .id = REPLY_STATISTICS_CMD, 2095 .id = REPLY_STATISTICS_CMD,
2092 .meta.flags = flags, 2096 .flags = flags,
2093 .len = sizeof(stat_flags), 2097 .len = sizeof(stat_flags),
2094 .data = (u8 *) &stat_flags, 2098 .data = (u8 *) &stat_flags,
2095 }; 2099 };
@@ -2224,6 +2228,7 @@ EXPORT_SYMBOL(iwl_verify_ucode);
2224void iwl_rf_kill_ct_config(struct iwl_priv *priv) 2228void iwl_rf_kill_ct_config(struct iwl_priv *priv)
2225{ 2229{
2226 struct iwl_ct_kill_config cmd; 2230 struct iwl_ct_kill_config cmd;
2231 struct iwl_ct_kill_throttling_config adv_cmd;
2227 unsigned long flags; 2232 unsigned long flags;
2228 int ret = 0; 2233 int ret = 0;
2229 2234
@@ -2231,10 +2236,28 @@ void iwl_rf_kill_ct_config(struct iwl_priv *priv)
2231 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, 2236 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
2232 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT); 2237 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
2233 spin_unlock_irqrestore(&priv->lock, flags); 2238 spin_unlock_irqrestore(&priv->lock, flags);
2239 priv->power_data.ct_kill_toggle = false;
2240
2241 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
2242 case CSR_HW_REV_TYPE_1000:
2243 case CSR_HW_REV_TYPE_6x00:
2244 case CSR_HW_REV_TYPE_6x50:
2245 adv_cmd.critical_temperature_enter =
2246 cpu_to_le32(priv->hw_params.ct_kill_threshold);
2247 adv_cmd.critical_temperature_exit =
2248 cpu_to_le32(priv->hw_params.ct_kill_exit_threshold);
2249
2250 ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
2251 sizeof(adv_cmd), &adv_cmd);
2252 break;
2253 default:
2254 cmd.critical_temperature_R =
2255 cpu_to_le32(priv->hw_params.ct_kill_threshold);
2234 2256
2235 cmd.critical_temperature_R = 2257 ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
2236 cpu_to_le32(priv->hw_params.ct_kill_threshold); 2258 sizeof(cmd), &cmd);
2237 2259 break;
2260 }
2238 ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD, 2261 ret = iwl_send_cmd_pdu(priv, REPLY_CT_KILL_CONFIG_CMD,
2239 sizeof(cmd), &cmd); 2262 sizeof(cmd), &cmd);
2240 if (ret) 2263 if (ret)
@@ -2263,7 +2286,7 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
2263 .id = REPLY_CARD_STATE_CMD, 2286 .id = REPLY_CARD_STATE_CMD,
2264 .len = sizeof(u32), 2287 .len = sizeof(u32),
2265 .data = &flags, 2288 .data = &flags,
2266 .meta.flags = meta_flag, 2289 .flags = meta_flag,
2267 }; 2290 };
2268 2291
2269 return iwl_send_cmd(priv, &cmd); 2292 return iwl_send_cmd(priv, &cmd);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 614ec7cc5b31..febcf76e1d41 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -446,9 +446,9 @@ int __must_check iwl_send_cmd_pdu(struct iwl_priv *priv, u8 id,
446 u16 len, const void *data); 446 u16 len, const void *data);
447int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, 447int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
448 const void *data, 448 const void *data,
449 int (*callback)(struct iwl_priv *priv, 449 void (*callback)(struct iwl_priv *priv,
450 struct iwl_cmd *cmd, 450 struct iwl_device_cmd *cmd,
451 struct sk_buff *skb)); 451 struct sk_buff *skb));
452 452
453int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); 453int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
454 454
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 9faf0c2ff608..fbe177608bc7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -84,9 +84,11 @@ struct iwl_debugfs {
84 struct dentry *file_status; 84 struct dentry *file_status;
85 struct dentry *file_interrupt; 85 struct dentry *file_interrupt;
86 struct dentry *file_qos; 86 struct dentry *file_qos;
87 struct dentry *file_thermal_throttling;
87#ifdef CONFIG_IWLWIFI_LEDS 88#ifdef CONFIG_IWLWIFI_LEDS
88 struct dentry *file_led; 89 struct dentry *file_led;
89#endif 90#endif
91 struct dentry *file_disable_ht40;
90 } dbgfs_data_files; 92 } dbgfs_data_files;
91 struct dir_rf_files { 93 struct dir_rf_files {
92 struct dentry *file_disable_sensitivity; 94 struct dentry *file_disable_sensitivity;
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 0ab3463aa07e..7707a2655994 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -618,6 +618,84 @@ static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
618} 618}
619#endif 619#endif
620 620
621static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
622 char __user *user_buf,
623 size_t count, loff_t *ppos)
624{
625 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
626 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
627 struct iwl_tt_restriction *restriction;
628 char buf[100];
629 int pos = 0;
630 const size_t bufsz = sizeof(buf);
631 ssize_t ret;
632
633 pos += scnprintf(buf + pos, bufsz - pos,
634 "Thermal Throttling Mode: %s\n",
635 (priv->power_data.adv_tt)
636 ? "Advance" : "Legacy");
637 pos += scnprintf(buf + pos, bufsz - pos,
638 "Thermal Throttling State: %d\n",
639 tt->state);
640 if (priv->power_data.adv_tt) {
641 restriction = tt->restriction + tt->state;
642 pos += scnprintf(buf + pos, bufsz - pos,
643 "Tx mode: %d\n",
644 restriction->tx_stream);
645 pos += scnprintf(buf + pos, bufsz - pos,
646 "Rx mode: %d\n",
647 restriction->rx_stream);
648 pos += scnprintf(buf + pos, bufsz - pos,
649 "HT mode: %d\n",
650 restriction->is_ht);
651 }
652 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
653 return ret;
654}
655
656static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
657 const char __user *user_buf,
658 size_t count, loff_t *ppos)
659{
660 struct iwl_priv *priv = file->private_data;
661 char buf[8];
662 int buf_size;
663 int ht40;
664
665 memset(buf, 0, sizeof(buf));
666 buf_size = min(count, sizeof(buf) - 1);
667 if (copy_from_user(buf, user_buf, buf_size))
668 return -EFAULT;
669 if (sscanf(buf, "%d", &ht40) != 1)
670 return -EFAULT;
671 if (!iwl_is_associated(priv))
672 priv->disable_ht40 = ht40 ? true : false;
673 else {
674 IWL_ERR(priv, "Sta associated with AP - "
675 "Change to 40MHz channel support is not allowed\n");
676 return -EINVAL;
677 }
678
679 return count;
680}
681
682static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
683 char __user *user_buf,
684 size_t count, loff_t *ppos)
685{
686 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
687 char buf[100];
688 int pos = 0;
689 const size_t bufsz = sizeof(buf);
690 ssize_t ret;
691
692 pos += scnprintf(buf + pos, bufsz - pos,
693 "11n 40MHz Mode: %s\n",
694 priv->disable_ht40 ? "Disabled" : "Enabled");
695 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
696 return ret;
697}
698
621DEBUGFS_READ_WRITE_FILE_OPS(sram); 699DEBUGFS_READ_WRITE_FILE_OPS(sram);
622DEBUGFS_WRITE_FILE_OPS(log_event); 700DEBUGFS_WRITE_FILE_OPS(log_event);
623DEBUGFS_READ_FILE_OPS(nvm); 701DEBUGFS_READ_FILE_OPS(nvm);
@@ -631,6 +709,8 @@ DEBUGFS_READ_FILE_OPS(qos);
631#ifdef CONFIG_IWLWIFI_LEDS 709#ifdef CONFIG_IWLWIFI_LEDS
632DEBUGFS_READ_FILE_OPS(led); 710DEBUGFS_READ_FILE_OPS(led);
633#endif 711#endif
712DEBUGFS_READ_FILE_OPS(thermal_throttling);
713DEBUGFS_READ_WRITE_FILE_OPS(disable_ht40);
634 714
635/* 715/*
636 * Create the debugfs files and directories 716 * Create the debugfs files and directories
@@ -671,6 +751,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
671#ifdef CONFIG_IWLWIFI_LEDS 751#ifdef CONFIG_IWLWIFI_LEDS
672 DEBUGFS_ADD_FILE(led, data); 752 DEBUGFS_ADD_FILE(led, data);
673#endif 753#endif
754 DEBUGFS_ADD_FILE(thermal_throttling, data);
755 DEBUGFS_ADD_FILE(disable_ht40, data);
674 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 756 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
675 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 757 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
676 &priv->disable_chain_noise_cal); 758 &priv->disable_chain_noise_cal);
@@ -709,6 +791,8 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
709#ifdef CONFIG_IWLWIFI_LEDS 791#ifdef CONFIG_IWLWIFI_LEDS
710 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led); 792 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
711#endif 793#endif
794 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_thermal_throttling);
795 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_disable_ht40);
712 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 796 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
713 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 797 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
714 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 798 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0751891f4ab7..0ee3ad245697 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -63,6 +63,8 @@ extern struct iwl_cfg iwl6050_2agn_cfg;
63extern struct iwl_cfg iwl6050_3agn_cfg; 63extern struct iwl_cfg iwl6050_3agn_cfg;
64extern struct iwl_cfg iwl1000_bgn_cfg; 64extern struct iwl_cfg iwl1000_bgn_cfg;
65 65
66struct iwl_tx_queue;
67
66/* shared structures from iwl-5000.c */ 68/* shared structures from iwl-5000.c */
67extern struct iwl_mod_params iwl50_mod_params; 69extern struct iwl_mod_params iwl50_mod_params;
68extern struct iwl_ops iwl5000_ops; 70extern struct iwl_ops iwl5000_ops;
@@ -79,9 +81,37 @@ extern void iwl5000_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
79 __le32 *tx_flags); 81 __le32 *tx_flags);
80extern int iwl5000_calc_rssi(struct iwl_priv *priv, 82extern int iwl5000_calc_rssi(struct iwl_priv *priv,
81 struct iwl_rx_phy_res *rx_resp); 83 struct iwl_rx_phy_res *rx_resp);
84extern int iwl5000_apm_init(struct iwl_priv *priv);
85extern void iwl5000_apm_stop(struct iwl_priv *priv);
86extern int iwl5000_apm_reset(struct iwl_priv *priv);
87extern void iwl5000_nic_config(struct iwl_priv *priv);
88extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv);
89extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv,
90 size_t offset);
91extern void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
92 struct iwl_tx_queue *txq,
93 u16 byte_cnt);
94extern void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
95 struct iwl_tx_queue *txq);
96extern int iwl5000_load_ucode(struct iwl_priv *priv);
97extern void iwl5000_init_alive_start(struct iwl_priv *priv);
98extern int iwl5000_alive_notify(struct iwl_priv *priv);
99extern int iwl5000_hw_set_hw_params(struct iwl_priv *priv);
100extern int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id,
101 int tx_fifo, int sta_id, int tid, u16 ssn_idx);
102extern int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id,
103 u16 ssn_idx, u8 tx_fifo);
104extern void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask);
105extern void iwl5000_setup_deferred_work(struct iwl_priv *priv);
106extern void iwl5000_rx_handler_setup(struct iwl_priv *priv);
107extern int iwl5000_hw_valid_rtc_data_addr(u32 addr);
108extern int iwl5000_send_tx_power(struct iwl_priv *priv);
109extern void iwl5000_temperature(struct iwl_priv *priv);
82 110
83/* CT-KILL constants */ 111/* CT-KILL constants */
84#define CT_KILL_THRESHOLD 110 /* in Celsius */ 112#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */
113#define CT_KILL_THRESHOLD 114 /* in Celsius */
114#define CT_KILL_EXIT_THRESHOLD 95 /* in Celsius */
85 115
86/* Default noise level to report when noise measurement is not available. 116/* Default noise level to report when noise measurement is not available.
87 * This may be because we're: 117 * This may be because we're:
@@ -120,6 +150,31 @@ struct iwl_rx_mem_buffer {
120 struct list_head list; 150 struct list_head list;
121}; 151};
122 152
153/* defined below */
154struct iwl_device_cmd;
155
156struct iwl_cmd_meta {
157 /* only for SYNC commands, iff the reply skb is wanted */
158 struct iwl_host_cmd *source;
159 /*
160 * only for ASYNC commands
161 * (which is somewhat stupid -- look at iwl-sta.c for instance
162 * which duplicates a bunch of code because the callback isn't
163 * invoked for SYNC commands, if it were and its result passed
164 * through it would be simpler...)
165 */
166 void (*callback)(struct iwl_priv *priv,
167 struct iwl_device_cmd *cmd,
168 struct sk_buff *skb);
169
170 /* The CMD_SIZE_HUGE flag bit indicates that the command
171 * structure is stored at the end of the shared queue memory. */
172 u32 flags;
173
174 DECLARE_PCI_UNMAP_ADDR(mapping)
175 DECLARE_PCI_UNMAP_LEN(len)
176};
177
123/* 178/*
124 * Generic queue structure 179 * Generic queue structure
125 * 180 *
@@ -147,7 +202,8 @@ struct iwl_tx_info {
147 * struct iwl_tx_queue - Tx Queue for DMA 202 * struct iwl_tx_queue - Tx Queue for DMA
148 * @q: generic Rx/Tx queue descriptor 203 * @q: generic Rx/Tx queue descriptor
149 * @bd: base of circular buffer of TFDs 204 * @bd: base of circular buffer of TFDs
150 * @cmd: array of command/Tx buffers 205 * @cmd: array of command/TX buffer pointers
206 * @meta: array of meta data for each command/tx buffer
151 * @dma_addr_cmd: physical address of cmd/tx buffer array 207 * @dma_addr_cmd: physical address of cmd/tx buffer array
152 * @txb: array of per-TFD driver data 208 * @txb: array of per-TFD driver data
153 * @need_update: indicates need to update read/write index 209 * @need_update: indicates need to update read/write index
@@ -162,7 +218,8 @@ struct iwl_tx_info {
162struct iwl_tx_queue { 218struct iwl_tx_queue {
163 struct iwl_queue q; 219 struct iwl_queue q;
164 void *tfds; 220 void *tfds;
165 struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS]; 221 struct iwl_device_cmd **cmd;
222 struct iwl_cmd_meta *meta;
166 struct iwl_tx_info *txb; 223 struct iwl_tx_info *txb;
167 u8 need_update; 224 u8 need_update;
168 u8 sched_retry; 225 u8 sched_retry;
@@ -299,35 +356,16 @@ enum {
299 CMD_WANT_SKB = (1 << 2), 356 CMD_WANT_SKB = (1 << 2),
300}; 357};
301 358
302struct iwl_cmd;
303struct iwl_priv;
304
305struct iwl_cmd_meta {
306 struct iwl_cmd_meta *source;
307 union {
308 struct sk_buff *skb;
309 int (*callback)(struct iwl_priv *priv,
310 struct iwl_cmd *cmd, struct sk_buff *skb);
311 } __attribute__ ((packed)) u;
312
313 /* The CMD_SIZE_HUGE flag bit indicates that the command
314 * structure is stored at the end of the shared queue memory. */
315 u32 flags;
316 DECLARE_PCI_UNMAP_ADDR(mapping)
317 DECLARE_PCI_UNMAP_LEN(len)
318} __attribute__ ((packed));
319
320#define IWL_CMD_MAX_PAYLOAD 320 359#define IWL_CMD_MAX_PAYLOAD 320
321 360
322/** 361/**
323 * struct iwl_cmd 362 * struct iwl_device_cmd
324 * 363 *
325 * For allocation of the command and tx queues, this establishes the overall 364 * For allocation of the command and tx queues, this establishes the overall
326 * size of the largest command we send to uCode, except for a scan command 365 * size of the largest command we send to uCode, except for a scan command
327 * (which is relatively huge; space is allocated separately). 366 * (which is relatively huge; space is allocated separately).
328 */ 367 */
329struct iwl_cmd { 368struct iwl_device_cmd {
330 struct iwl_cmd_meta meta; /* driver data */
331 struct iwl_cmd_header hdr; /* uCode API */ 369 struct iwl_cmd_header hdr; /* uCode API */
332 union { 370 union {
333 u32 flags; 371 u32 flags;
@@ -339,17 +377,20 @@ struct iwl_cmd {
339 } __attribute__ ((packed)) cmd; 377 } __attribute__ ((packed)) cmd;
340} __attribute__ ((packed)); 378} __attribute__ ((packed));
341 379
380#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd))
381
342 382
343struct iwl_host_cmd { 383struct iwl_host_cmd {
344 u8 id;
345 u16 len;
346 struct iwl_cmd_meta meta;
347 const void *data; 384 const void *data;
385 struct sk_buff *reply_skb;
386 void (*callback)(struct iwl_priv *priv,
387 struct iwl_device_cmd *cmd,
388 struct sk_buff *skb);
389 u32 flags;
390 u16 len;
391 u8 id;
348}; 392};
349 393
350#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_cmd) - \
351 sizeof(struct iwl_cmd_meta))
352
353/* 394/*
354 * RX related structures and functions 395 * RX related structures and functions
355 */ 396 */
@@ -450,8 +491,16 @@ union iwl_ht_rate_supp {
450}; 491};
451 492
452#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3) 493#define CFG_HT_RX_AMPDU_FACTOR_DEF (0x3)
453#define CFG_HT_MPDU_DENSITY_2USEC (0x5) 494
454#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_2USEC 495/*
496 * Maximal MPDU density for TX aggregation
497 * 4 - 2us density
498 * 5 - 4us density
499 * 6 - 8us density
500 * 7 - 16us density
501 */
502#define CFG_HT_MPDU_DENSITY_4USEC (0x5)
503#define CFG_HT_MPDU_DENSITY_DEF CFG_HT_MPDU_DENSITY_4USEC
455 504
456struct iwl_ht_info { 505struct iwl_ht_info {
457 /* self configuration data */ 506 /* self configuration data */
@@ -630,6 +679,8 @@ struct iwl_hw_params {
630 u32 max_data_size; 679 u32 max_data_size;
631 u32 max_bsm_size; 680 u32 max_bsm_size;
632 u32 ct_kill_threshold; /* value in hw-dependent units */ 681 u32 ct_kill_threshold; /* value in hw-dependent units */
682 u32 ct_kill_exit_threshold; /* value in hw-dependent units */
683 /* for 1000, 6000 series and up */
633 u32 calib_init_cfg; 684 u32 calib_init_cfg;
634 const struct iwl_sensitivity_ranges *sens; 685 const struct iwl_sensitivity_ranges *sens;
635}; 686};
@@ -1113,6 +1164,7 @@ struct iwl_priv {
1113 /* debugging info */ 1164 /* debugging info */
1114 u32 framecnt_to_us; 1165 u32 framecnt_to_us;
1115 atomic_t restrict_refcnt; 1166 atomic_t restrict_refcnt;
1167 bool disable_ht40;
1116#ifdef CONFIG_IWLWIFI_DEBUGFS 1168#ifdef CONFIG_IWLWIFI_DEBUGFS
1117 /* debugfs */ 1169 /* debugfs */
1118 struct iwl_debugfs *dbgfs; 1170 struct iwl_debugfs *dbgfs;
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 17d61ac8ed61..b82ad15d5189 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -103,22 +103,23 @@ EXPORT_SYMBOL(get_cmd_string);
103 103
104#define HOST_COMPLETE_TIMEOUT (HZ / 2) 104#define HOST_COMPLETE_TIMEOUT (HZ / 2)
105 105
106static int iwl_generic_cmd_callback(struct iwl_priv *priv, 106static void iwl_generic_cmd_callback(struct iwl_priv *priv,
107 struct iwl_cmd *cmd, struct sk_buff *skb) 107 struct iwl_device_cmd *cmd,
108 struct sk_buff *skb)
108{ 109{
109 struct iwl_rx_packet *pkt = NULL; 110 struct iwl_rx_packet *pkt = NULL;
110 111
111 if (!skb) { 112 if (!skb) {
112 IWL_ERR(priv, "Error: Response NULL in %s.\n", 113 IWL_ERR(priv, "Error: Response NULL in %s.\n",
113 get_cmd_string(cmd->hdr.cmd)); 114 get_cmd_string(cmd->hdr.cmd));
114 return 1; 115 return;
115 } 116 }
116 117
117 pkt = (struct iwl_rx_packet *)skb->data; 118 pkt = (struct iwl_rx_packet *)skb->data;
118 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) { 119 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
119 IWL_ERR(priv, "Bad return from %s (0x%08X)\n", 120 IWL_ERR(priv, "Bad return from %s (0x%08X)\n",
120 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); 121 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
121 return 1; 122 return;
122 } 123 }
123 124
124#ifdef CONFIG_IWLWIFI_DEBUG 125#ifdef CONFIG_IWLWIFI_DEBUG
@@ -127,29 +128,26 @@ static int iwl_generic_cmd_callback(struct iwl_priv *priv,
127 case SENSITIVITY_CMD: 128 case SENSITIVITY_CMD:
128 IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n", 129 IWL_DEBUG_HC_DUMP(priv, "back from %s (0x%08X)\n",
129 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); 130 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
130 break; 131 break;
131 default: 132 default:
132 IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n", 133 IWL_DEBUG_HC(priv, "back from %s (0x%08X)\n",
133 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags); 134 get_cmd_string(cmd->hdr.cmd), pkt->hdr.flags);
134 } 135 }
135#endif 136#endif
136
137 /* Let iwl_tx_complete free the response skb */
138 return 1;
139} 137}
140 138
141static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) 139static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
142{ 140{
143 int ret; 141 int ret;
144 142
145 BUG_ON(!(cmd->meta.flags & CMD_ASYNC)); 143 BUG_ON(!(cmd->flags & CMD_ASYNC));
146 144
147 /* An asynchronous command can not expect an SKB to be set. */ 145 /* An asynchronous command can not expect an SKB to be set. */
148 BUG_ON(cmd->meta.flags & CMD_WANT_SKB); 146 BUG_ON(cmd->flags & CMD_WANT_SKB);
149 147
150 /* Assign a generic callback if one is not provided */ 148 /* Assign a generic callback if one is not provided */
151 if (!cmd->meta.u.callback) 149 if (!cmd->callback)
152 cmd->meta.u.callback = iwl_generic_cmd_callback; 150 cmd->callback = iwl_generic_cmd_callback;
153 151
154 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 152 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
155 return -EBUSY; 153 return -EBUSY;
@@ -168,10 +166,10 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
168 int cmd_idx; 166 int cmd_idx;
169 int ret; 167 int ret;
170 168
171 BUG_ON(cmd->meta.flags & CMD_ASYNC); 169 BUG_ON(cmd->flags & CMD_ASYNC);
172 170
173 /* A synchronous command can not have a callback set. */ 171 /* A synchronous command can not have a callback set. */
174 BUG_ON(cmd->meta.u.callback != NULL); 172 BUG_ON(cmd->callback);
175 173
176 if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) { 174 if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {
177 IWL_ERR(priv, 175 IWL_ERR(priv,
@@ -183,9 +181,6 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
183 181
184 set_bit(STATUS_HCMD_ACTIVE, &priv->status); 182 set_bit(STATUS_HCMD_ACTIVE, &priv->status);
185 183
186 if (cmd->meta.flags & CMD_WANT_SKB)
187 cmd->meta.source = &cmd->meta;
188
189 cmd_idx = iwl_enqueue_hcmd(priv, cmd); 184 cmd_idx = iwl_enqueue_hcmd(priv, cmd);
190 if (cmd_idx < 0) { 185 if (cmd_idx < 0) {
191 ret = cmd_idx; 186 ret = cmd_idx;
@@ -222,7 +217,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
222 ret = -EIO; 217 ret = -EIO;
223 goto fail; 218 goto fail;
224 } 219 }
225 if ((cmd->meta.flags & CMD_WANT_SKB) && !cmd->meta.u.skb) { 220 if ((cmd->flags & CMD_WANT_SKB) && !cmd->reply_skb) {
226 IWL_ERR(priv, "Error: Response NULL in '%s'\n", 221 IWL_ERR(priv, "Error: Response NULL in '%s'\n",
227 get_cmd_string(cmd->id)); 222 get_cmd_string(cmd->id));
228 ret = -EIO; 223 ret = -EIO;
@@ -233,20 +228,20 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
233 goto out; 228 goto out;
234 229
235cancel: 230cancel:
236 if (cmd->meta.flags & CMD_WANT_SKB) { 231 if (cmd->flags & CMD_WANT_SKB) {
237 struct iwl_cmd *qcmd; 232 /*
238 233 * Cancel the CMD_WANT_SKB flag for the cmd in the
239 /* Cancel the CMD_WANT_SKB flag for the cmd in the
240 * TX cmd queue. Otherwise in case the cmd comes 234 * TX cmd queue. Otherwise in case the cmd comes
241 * in later, it will possibly set an invalid 235 * in later, it will possibly set an invalid
242 * address (cmd->meta.source). */ 236 * address (cmd->meta.source).
243 qcmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_idx]; 237 */
244 qcmd->meta.flags &= ~CMD_WANT_SKB; 238 priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_idx].flags &=
239 ~CMD_WANT_SKB;
245 } 240 }
246fail: 241fail:
247 if (cmd->meta.u.skb) { 242 if (cmd->reply_skb) {
248 dev_kfree_skb_any(cmd->meta.u.skb); 243 dev_kfree_skb_any(cmd->reply_skb);
249 cmd->meta.u.skb = NULL; 244 cmd->reply_skb = NULL;
250 } 245 }
251out: 246out:
252 clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status); 247 clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);
@@ -256,7 +251,7 @@ EXPORT_SYMBOL(iwl_send_cmd_sync);
256 251
257int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) 252int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
258{ 253{
259 if (cmd->meta.flags & CMD_ASYNC) 254 if (cmd->flags & CMD_ASYNC)
260 return iwl_send_cmd_async(priv, cmd); 255 return iwl_send_cmd_async(priv, cmd);
261 256
262 return iwl_send_cmd_sync(priv, cmd); 257 return iwl_send_cmd_sync(priv, cmd);
@@ -277,9 +272,9 @@ EXPORT_SYMBOL(iwl_send_cmd_pdu);
277 272
278int iwl_send_cmd_pdu_async(struct iwl_priv *priv, 273int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
279 u8 id, u16 len, const void *data, 274 u8 id, u16 len, const void *data,
280 int (*callback)(struct iwl_priv *priv, 275 void (*callback)(struct iwl_priv *priv,
281 struct iwl_cmd *cmd, 276 struct iwl_device_cmd *cmd,
282 struct sk_buff *skb)) 277 struct sk_buff *skb))
283{ 278{
284 struct iwl_host_cmd cmd = { 279 struct iwl_host_cmd cmd = {
285 .id = id, 280 .id = id,
@@ -287,8 +282,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv,
287 .data = data, 282 .data = data,
288 }; 283 };
289 284
290 cmd.meta.flags |= CMD_ASYNC; 285 cmd.flags |= CMD_ASYNC;
291 cmd.meta.u.callback = callback; 286 cmd.callback = callback;
292 287
293 return iwl_send_cmd_async(priv, &cmd); 288 return iwl_send_cmd_async(priv, &cmd);
294} 289}
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 8c8115293b3c..7cce8f85bcc6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -91,8 +91,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
91 .id = REPLY_LEDS_CMD, 91 .id = REPLY_LEDS_CMD,
92 .len = sizeof(struct iwl_led_cmd), 92 .len = sizeof(struct iwl_led_cmd),
93 .data = led_cmd, 93 .data = led_cmd,
94 .meta.flags = CMD_ASYNC, 94 .flags = CMD_ASYNC,
95 .meta.u.callback = NULL, 95 .callback = NULL,
96 }; 96 };
97 u32 reg; 97 u32 reg;
98 98
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index f2ea3f05f6e1..00937b3ee8ec 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -36,6 +36,7 @@
36#include "iwl-eeprom.h" 36#include "iwl-eeprom.h"
37#include "iwl-dev.h" 37#include "iwl-dev.h"
38#include "iwl-core.h" 38#include "iwl-core.h"
39#include "iwl-io.h"
39#include "iwl-commands.h" 40#include "iwl-commands.h"
40#include "iwl-debug.h" 41#include "iwl-debug.h"
41#include "iwl-power.h" 42#include "iwl-power.h"
@@ -97,6 +98,45 @@ static const struct iwl_power_vec_entry range_2[IWL_POWER_NUM] = {
97 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0} 98 {{SLP, SLP_TOUT(25), SLP_TOUT(25), SLP_VEC(4, 7, 10, 10, 0xFF)}, 0}
98}; 99};
99 100
101/* default Thermal Throttling transaction table
102 * Current state | Throttling Down | Throttling Up
103 *=============================================================================
104 * Condition Nxt State Condition Nxt State Condition Nxt State
105 *-----------------------------------------------------------------------------
106 * IWL_TI_0 T >= 115 CT_KILL 115>T>=105 TI_1 N/A N/A
107 * IWL_TI_1 T >= 115 CT_KILL 115>T>=110 TI_2 T<=95 TI_0
108 * IWL_TI_2 T >= 115 CT_KILL T<=100 TI_1
109 * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
110 *=============================================================================
111 */
112static const struct iwl_tt_trans tt_range_0[IWL_TI_STATE_MAX - 1] = {
113 {IWL_TI_0, IWL_ABSOLUTE_ZERO, 104},
114 {IWL_TI_1, 105, CT_KILL_THRESHOLD},
115 {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
116};
117static const struct iwl_tt_trans tt_range_1[IWL_TI_STATE_MAX - 1] = {
118 {IWL_TI_0, IWL_ABSOLUTE_ZERO, 95},
119 {IWL_TI_2, 110, CT_KILL_THRESHOLD},
120 {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
121};
122static const struct iwl_tt_trans tt_range_2[IWL_TI_STATE_MAX - 1] = {
123 {IWL_TI_1, IWL_ABSOLUTE_ZERO, 100},
124 {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
125 {IWL_TI_CT_KILL, CT_KILL_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
126};
127static const struct iwl_tt_trans tt_range_3[IWL_TI_STATE_MAX - 1] = {
128 {IWL_TI_0, IWL_ABSOLUTE_ZERO, CT_KILL_EXIT_THRESHOLD},
129 {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX},
130 {IWL_TI_CT_KILL, CT_KILL_EXIT_THRESHOLD + 1, IWL_ABSOLUTE_MAX}
131};
132
133/* Advance Thermal Throttling default restriction table */
134static const struct iwl_tt_restriction restriction_range[IWL_TI_STATE_MAX] = {
135 {IWL_TX_MULTI, true, IWL_RX_MULTI},
136 {IWL_TX_SINGLE, true, IWL_RX_MULTI},
137 {IWL_TX_SINGLE, false, IWL_RX_SINGLE},
138 {IWL_TX_NONE, false, IWL_RX_NONE}
139};
100 140
101/* set card power command */ 141/* set card power command */
102static int iwl_set_power(struct iwl_priv *priv, void *cmd) 142static int iwl_set_power(struct iwl_priv *priv, void *cmd)
@@ -211,6 +251,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
211{ 251{
212 struct iwl_power_mgr *setting = &(priv->power_data); 252 struct iwl_power_mgr *setting = &(priv->power_data);
213 int ret = 0; 253 int ret = 0;
254 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
214 u16 uninitialized_var(final_mode); 255 u16 uninitialized_var(final_mode);
215 bool update_chains; 256 bool update_chains;
216 257
@@ -223,6 +264,10 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
223 if (setting->power_disabled) 264 if (setting->power_disabled)
224 final_mode = IWL_POWER_MODE_CAM; 265 final_mode = IWL_POWER_MODE_CAM;
225 266
267 if (tt->state >= IWL_TI_1) {
268 /* TT power setting overwrite user & system power setting */
269 final_mode = tt->tt_power_mode;
270 }
226 if (iwl_is_ready_rf(priv) && 271 if (iwl_is_ready_rf(priv) &&
227 ((setting->power_mode != final_mode) || force)) { 272 ((setting->power_mode != final_mode) || force)) {
228 struct iwl_powertable_cmd cmd; 273 struct iwl_powertable_cmd cmd;
@@ -267,6 +312,487 @@ int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode)
267} 312}
268EXPORT_SYMBOL(iwl_power_set_user_mode); 313EXPORT_SYMBOL(iwl_power_set_user_mode);
269 314
315bool iwl_ht_enabled(struct iwl_priv *priv)
316{
317 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
318 struct iwl_tt_restriction *restriction;
319
320 if (!priv->power_data.adv_tt)
321 return true;
322 restriction = tt->restriction + tt->state;
323 return restriction->is_ht;
324}
325EXPORT_SYMBOL(iwl_ht_enabled);
326
327u8 iwl_tx_ant_restriction(struct iwl_priv *priv)
328{
329 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
330 struct iwl_tt_restriction *restriction;
331
332 if (!priv->power_data.adv_tt)
333 return IWL_TX_MULTI;
334 restriction = tt->restriction + tt->state;
335 return restriction->tx_stream;
336}
337EXPORT_SYMBOL(iwl_tx_ant_restriction);
338
339u8 iwl_rx_ant_restriction(struct iwl_priv *priv)
340{
341 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
342 struct iwl_tt_restriction *restriction;
343
344 if (!priv->power_data.adv_tt)
345 return IWL_RX_MULTI;
346 restriction = tt->restriction + tt->state;
347 return restriction->rx_stream;
348}
349EXPORT_SYMBOL(iwl_rx_ant_restriction);
350
351#define CT_KILL_EXIT_DURATION (5) /* 5 seconds duration */
352
353/*
354 * toggle the bit to wake up uCode and check the temperature
355 * if the temperature is below CT, uCode will stay awake and send card
356 * state notification with CT_KILL bit clear to inform Thermal Throttling
357 * Management to change state. Otherwise, uCode will go back to sleep
358 * without doing anything, driver should continue the 5 seconds timer
359 * to wake up uCode for temperature check until temperature drop below CT
360 */
361static void iwl_tt_check_exit_ct_kill(unsigned long data)
362{
363 struct iwl_priv *priv = (struct iwl_priv *)data;
364 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
365 unsigned long flags;
366
367 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
368 return;
369
370 if (tt->state == IWL_TI_CT_KILL) {
371 if (priv->power_data.ct_kill_toggle) {
372 iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR,
373 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
374 priv->power_data.ct_kill_toggle = false;
375 } else {
376 iwl_write32(priv, CSR_UCODE_DRV_GP1_SET,
377 CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT);
378 priv->power_data.ct_kill_toggle = true;
379 }
380 iwl_read32(priv, CSR_UCODE_DRV_GP1);
381 spin_lock_irqsave(&priv->reg_lock, flags);
382 if (!iwl_grab_nic_access(priv))
383 iwl_release_nic_access(priv);
384 spin_unlock_irqrestore(&priv->reg_lock, flags);
385
386 /* Reschedule the ct_kill timer to occur in
387 * CT_KILL_EXIT_DURATION seconds to ensure we get a
388 * thermal update */
389 mod_timer(&priv->power_data.ct_kill_exit_tm, jiffies +
390 CT_KILL_EXIT_DURATION * HZ);
391 }
392}
393
394static void iwl_perform_ct_kill_task(struct iwl_priv *priv,
395 bool stop)
396{
397 if (stop) {
398 IWL_DEBUG_POWER(priv, "Stop all queues\n");
399 if (priv->mac80211_registered)
400 ieee80211_stop_queues(priv->hw);
401 IWL_DEBUG_POWER(priv,
402 "Schedule 5 seconds CT_KILL Timer\n");
403 mod_timer(&priv->power_data.ct_kill_exit_tm, jiffies +
404 CT_KILL_EXIT_DURATION * HZ);
405 } else {
406 IWL_DEBUG_POWER(priv, "Wake all queues\n");
407 if (priv->mac80211_registered)
408 ieee80211_wake_queues(priv->hw);
409 }
410}
411
412#define IWL_MINIMAL_POWER_THRESHOLD (CT_KILL_THRESHOLD_LEGACY)
413#define IWL_REDUCED_PERFORMANCE_THRESHOLD_2 (100)
414#define IWL_REDUCED_PERFORMANCE_THRESHOLD_1 (90)
415
416/*
417 * Legacy thermal throttling
418 * 1) Avoid NIC destruction due to high temperatures
419 * Chip will identify dangerously high temperatures that can
420 * harm the device and will power down
421 * 2) Avoid the NIC power down due to high temperature
422 * Throttle early enough to lower the power consumption before
423 * drastic steps are needed
424 */
425static void iwl_legacy_tt_handler(struct iwl_priv *priv, s32 temp)
426{
427 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
428 enum iwl_tt_state new_state;
429 struct iwl_power_mgr *setting = &priv->power_data;
430
431#ifdef CONFIG_IWLWIFI_DEBUG
432 if ((tt->tt_previous_temp) &&
433 (temp > tt->tt_previous_temp) &&
434 ((temp - tt->tt_previous_temp) >
435 IWL_TT_INCREASE_MARGIN)) {
436 IWL_DEBUG_POWER(priv,
437 "Temperature increase %d degree Celsius\n",
438 (temp - tt->tt_previous_temp));
439 }
440#endif
441 /* in Celsius */
442 if (temp >= IWL_MINIMAL_POWER_THRESHOLD)
443 new_state = IWL_TI_CT_KILL;
444 else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_2)
445 new_state = IWL_TI_2;
446 else if (temp >= IWL_REDUCED_PERFORMANCE_THRESHOLD_1)
447 new_state = IWL_TI_1;
448 else
449 new_state = IWL_TI_0;
450
451#ifdef CONFIG_IWLWIFI_DEBUG
452 tt->tt_previous_temp = temp;
453#endif
454 if (tt->state != new_state) {
455 if (tt->state == IWL_TI_0) {
456 tt->sys_power_mode = setting->power_mode;
457 IWL_DEBUG_POWER(priv, "current power mode: %u\n",
458 setting->power_mode);
459 }
460 switch (new_state) {
461 case IWL_TI_0:
462 /* when system ready to go back to IWL_TI_0 state
463 * using system power mode instead of TT power mode
464 * revert back to the orginal power mode which was saved
465 * before enter Thermal Throttling state
466 * update priv->power_data.user_power_setting to the
467 * required power mode to make sure
468 * iwl_power_update_mode() will update power correctly.
469 */
470 priv->power_data.user_power_setting =
471 tt->sys_power_mode;
472 tt->tt_power_mode = tt->sys_power_mode;
473 break;
474 case IWL_TI_1:
475 tt->tt_power_mode = IWL_POWER_INDEX_3;
476 break;
477 case IWL_TI_2:
478 tt->tt_power_mode = IWL_POWER_INDEX_4;
479 break;
480 default:
481 tt->tt_power_mode = IWL_POWER_INDEX_5;
482 break;
483 }
484 if (iwl_power_update_mode(priv, true)) {
485 /* TT state not updated
486 * try again during next temperature read
487 */
488 IWL_ERR(priv, "Cannot update power mode, "
489 "TT state not updated\n");
490 } else {
491 if (new_state == IWL_TI_CT_KILL)
492 iwl_perform_ct_kill_task(priv, true);
493 else if (tt->state == IWL_TI_CT_KILL &&
494 new_state != IWL_TI_CT_KILL)
495 iwl_perform_ct_kill_task(priv, false);
496 tt->state = new_state;
497 IWL_DEBUG_POWER(priv, "Temperature state changed %u\n",
498 tt->state);
499 IWL_DEBUG_POWER(priv, "Power Index change to %u\n",
500 tt->tt_power_mode);
501 }
502 }
503}
504
505/*
506 * Advance thermal throttling
507 * 1) Avoid NIC destruction due to high temperatures
508 * Chip will identify dangerously high temperatures that can
509 * harm the device and will power down
510 * 2) Avoid the NIC power down due to high temperature
511 * Throttle early enough to lower the power consumption before
512 * drastic steps are needed
513 * Actions include relaxing the power down sleep thresholds and
514 * decreasing the number of TX streams
515 * 3) Avoid throughput performance impact as much as possible
516 *
517 *=============================================================================
518 * Condition Nxt State Condition Nxt State Condition Nxt State
519 *-----------------------------------------------------------------------------
520 * IWL_TI_0 T >= 115 CT_KILL 115>T>=105 TI_1 N/A N/A
521 * IWL_TI_1 T >= 115 CT_KILL 115>T>=110 TI_2 T<=95 TI_0
522 * IWL_TI_2 T >= 115 CT_KILL T<=100 TI_1
523 * IWL_CT_KILL N/A N/A N/A N/A T<=95 TI_0
524 *=============================================================================
525 */
526static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp)
527{
528 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
529 int i;
530 bool changed = false;
531 enum iwl_tt_state old_state;
532 struct iwl_tt_trans *transaction;
533
534 old_state = tt->state;
535 for (i = 0; i < IWL_TI_STATE_MAX - 1; i++) {
536 /* based on the current TT state,
537 * find the curresponding transaction table
538 * each table has (IWL_TI_STATE_MAX - 1) entries
539 * tt->transaction + ((old_state * (IWL_TI_STATE_MAX - 1))
540 * will advance to the correct table.
541 * then based on the current temperature
542 * find the next state need to transaction to
543 * go through all the possible (IWL_TI_STATE_MAX - 1) entries
544 * in the current table to see if transaction is needed
545 */
546 transaction = tt->transaction +
547 ((old_state * (IWL_TI_STATE_MAX - 1)) + i);
548 if (temp >= transaction->tt_low &&
549 temp <= transaction->tt_high) {
550#ifdef CONFIG_IWLWIFI_DEBUG
551 if ((tt->tt_previous_temp) &&
552 (temp > tt->tt_previous_temp) &&
553 ((temp - tt->tt_previous_temp) >
554 IWL_TT_INCREASE_MARGIN)) {
555 IWL_DEBUG_POWER(priv,
556 "Temperature increase %d "
557 "degree Celsius\n",
558 (temp - tt->tt_previous_temp));
559 }
560 tt->tt_previous_temp = temp;
561#endif
562 if (old_state !=
563 transaction->next_state) {
564 changed = true;
565 tt->state =
566 transaction->next_state;
567 }
568 break;
569 }
570 }
571 if (changed) {
572 struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
573 struct iwl_power_mgr *setting = &priv->power_data;
574
575 if (tt->state >= IWL_TI_1) {
576 /* if switching from IWL_TI_0 to other TT state
577 * save previous power setting in tt->sys_power_mode */
578 if (old_state == IWL_TI_0)
579 tt->sys_power_mode = setting->power_mode;
580 /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
581 tt->tt_power_mode = IWL_POWER_INDEX_5;
582 if (!iwl_ht_enabled(priv))
583 /* disable HT */
584 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
585 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
586 RXON_FLG_FAT_PROT_MSK |
587 RXON_FLG_HT_PROT_MSK);
588 else {
589 /* check HT capability and set
590 * according to the system HT capability
591 * in case get disabled before */
592 iwl_set_rxon_ht(priv, &priv->current_ht_config);
593 }
594
595 } else {
596 /* restore system power setting */
597 /* the previous power mode was saved in
598 * tt->sys_power_mode when system move into
599 * Thermal Throttling state
600 * set power_data.user_power_setting to the previous
601 * system power mode to make sure power will get
602 * updated correctly
603 */
604 priv->power_data.user_power_setting =
605 tt->sys_power_mode;
606 tt->tt_power_mode = tt->sys_power_mode;
607 /* check HT capability and set
608 * according to the system HT capability
609 * in case get disabled before */
610 iwl_set_rxon_ht(priv, &priv->current_ht_config);
611 }
612 if (iwl_power_update_mode(priv, true)) {
613 /* TT state not updated
614 * try again during next temperature read
615 */
616 IWL_ERR(priv, "Cannot update power mode, "
617 "TT state not updated\n");
618 tt->state = old_state;
619 } else {
620 IWL_DEBUG_POWER(priv,
621 "Thermal Throttling to new state: %u\n",
622 tt->state);
623 if (old_state != IWL_TI_CT_KILL &&
624 tt->state == IWL_TI_CT_KILL) {
625 IWL_DEBUG_POWER(priv, "Enter IWL_TI_CT_KILL\n");
626 iwl_perform_ct_kill_task(priv, true);
627
628 } else if (old_state == IWL_TI_CT_KILL &&
629 tt->state != IWL_TI_CT_KILL) {
630 IWL_DEBUG_POWER(priv, "Exit IWL_TI_CT_KILL\n");
631 iwl_perform_ct_kill_task(priv, false);
632 }
633 }
634 }
635}
636
637/* Card State Notification indicated reach critical temperature
638 * if PSP not enable, no Thermal Throttling function will be performed
639 * just set the GP1 bit to acknowledge the event
640 * otherwise, go into IWL_TI_CT_KILL state
641 * since Card State Notification will not provide any temperature reading
642 * for Legacy mode
643 * so just pass the CT_KILL temperature to iwl_legacy_tt_handler()
644 * for advance mode
645 * pass CT_KILL_THRESHOLD+1 to make sure move into IWL_TI_CT_KILL state
646 */
647void iwl_tt_enter_ct_kill(struct iwl_priv *priv)
648{
649 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
650
651 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
652 return;
653
654 if (tt->state != IWL_TI_CT_KILL) {
655 IWL_ERR(priv, "Device reached critical temperature "
656 "- ucode going to sleep!\n");
657 if (!priv->power_data.adv_tt)
658 iwl_legacy_tt_handler(priv,
659 IWL_MINIMAL_POWER_THRESHOLD);
660 else
661 iwl_advance_tt_handler(priv,
662 CT_KILL_THRESHOLD + 1);
663 }
664}
665EXPORT_SYMBOL(iwl_tt_enter_ct_kill);
666
667/* Card State Notification indicated out of critical temperature
668 * since Card State Notification will not provide any temperature reading
669 * so pass the IWL_REDUCED_PERFORMANCE_THRESHOLD_2 temperature
670 * to iwl_legacy_tt_handler() to get out of IWL_CT_KILL state
671 */
672void iwl_tt_exit_ct_kill(struct iwl_priv *priv)
673{
674 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
675
676 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
677 return;
678
679 /* stop ct_kill_exit_tm timer */
680 del_timer_sync(&priv->power_data.ct_kill_exit_tm);
681
682 if (tt->state == IWL_TI_CT_KILL) {
683 IWL_ERR(priv,
684 "Device temperature below critical"
685 "- ucode awake!\n");
686 if (!priv->power_data.adv_tt)
687 iwl_legacy_tt_handler(priv,
688 IWL_REDUCED_PERFORMANCE_THRESHOLD_2);
689 else
690 iwl_advance_tt_handler(priv, CT_KILL_EXIT_THRESHOLD);
691 }
692}
693EXPORT_SYMBOL(iwl_tt_exit_ct_kill);
694
695void iwl_tt_handler(struct iwl_priv *priv)
696{
697 s32 temp = priv->temperature; /* degrees CELSIUS except 4965 */
698
699 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
700 return;
701
702 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)
703 temp = KELVIN_TO_CELSIUS(priv->temperature);
704
705 if (!priv->power_data.adv_tt)
706 iwl_legacy_tt_handler(priv, temp);
707 else
708 iwl_advance_tt_handler(priv, temp);
709}
710EXPORT_SYMBOL(iwl_tt_handler);
711
712/* Thermal throttling initialization
713 * For advance thermal throttling:
714 * Initialize Thermal Index and temperature threshold table
715 * Initialize thermal throttling restriction table
716 */
717void iwl_tt_initialize(struct iwl_priv *priv)
718{
719 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
720 struct iwl_power_mgr *setting = &priv->power_data;
721 int size = sizeof(struct iwl_tt_trans) * (IWL_TI_STATE_MAX - 1);
722 struct iwl_tt_trans *transaction;
723
724 IWL_DEBUG_POWER(priv, "Initialize Thermal Throttling \n");
725
726 memset(tt, 0, sizeof(struct iwl_tt_mgmt));
727
728 tt->state = IWL_TI_0;
729 tt->sys_power_mode = setting->power_mode;
730 tt->tt_power_mode = tt->sys_power_mode;
731 init_timer(&priv->power_data.ct_kill_exit_tm);
732 priv->power_data.ct_kill_exit_tm.data = (unsigned long)priv;
733 priv->power_data.ct_kill_exit_tm.function = iwl_tt_check_exit_ct_kill;
734 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
735 case CSR_HW_REV_TYPE_6x00:
736 case CSR_HW_REV_TYPE_6x50:
737 IWL_DEBUG_POWER(priv, "Advanced Thermal Throttling\n");
738 tt->restriction = kzalloc(sizeof(struct iwl_tt_restriction) *
739 IWL_TI_STATE_MAX, GFP_KERNEL);
740 tt->transaction = kzalloc(sizeof(struct iwl_tt_trans) *
741 IWL_TI_STATE_MAX * (IWL_TI_STATE_MAX - 1),
742 GFP_KERNEL);
743 if (!tt->restriction || !tt->transaction) {
744 IWL_ERR(priv, "Fallback to Legacy Throttling\n");
745 priv->power_data.adv_tt = false;
746 kfree(tt->restriction);
747 tt->restriction = NULL;
748 kfree(tt->transaction);
749 tt->transaction = NULL;
750 } else {
751 transaction = tt->transaction +
752 (IWL_TI_0 * (IWL_TI_STATE_MAX - 1));
753 memcpy(transaction, &tt_range_0[0], size);
754 transaction = tt->transaction +
755 (IWL_TI_1 * (IWL_TI_STATE_MAX - 1));
756 memcpy(transaction, &tt_range_1[0], size);
757 transaction = tt->transaction +
758 (IWL_TI_2 * (IWL_TI_STATE_MAX - 1));
759 memcpy(transaction, &tt_range_2[0], size);
760 transaction = tt->transaction +
761 (IWL_TI_CT_KILL * (IWL_TI_STATE_MAX - 1));
762 memcpy(transaction, &tt_range_3[0], size);
763 size = sizeof(struct iwl_tt_restriction) *
764 IWL_TI_STATE_MAX;
765 memcpy(tt->restriction,
766 &restriction_range[0], size);
767 priv->power_data.adv_tt = true;
768 }
769 break;
770 default:
771 IWL_DEBUG_POWER(priv, "Legacy Thermal Throttling\n");
772 priv->power_data.adv_tt = false;
773 break;
774 }
775}
776EXPORT_SYMBOL(iwl_tt_initialize);
777
778/* cleanup thermal throttling management related memory and timer */
779void iwl_tt_exit(struct iwl_priv *priv)
780{
781 struct iwl_tt_mgmt *tt = &priv->power_data.tt;
782
783 /* stop ct_kill_exit_tm timer if activated */
784 del_timer_sync(&priv->power_data.ct_kill_exit_tm);
785
786 if (priv->power_data.adv_tt) {
787 /* free advance thermal throttling memory */
788 kfree(tt->restriction);
789 tt->restriction = NULL;
790 kfree(tt->transaction);
791 tt->transaction = NULL;
792 }
793}
794EXPORT_SYMBOL(iwl_tt_exit);
795
270/* initialize to default */ 796/* initialize to default */
271void iwl_power_initialize(struct iwl_priv *priv) 797void iwl_power_initialize(struct iwl_priv *priv)
272{ 798{
diff --git a/drivers/net/wireless/iwlwifi/iwl-power.h b/drivers/net/wireless/iwlwifi/iwl-power.h
index 37ba3bb7a25a..3d49b7a45b74 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.h
+++ b/drivers/net/wireless/iwlwifi/iwl-power.h
@@ -33,6 +33,84 @@
33 33
34struct iwl_priv; 34struct iwl_priv;
35 35
36#define IWL_ABSOLUTE_ZERO 0
37#define IWL_ABSOLUTE_MAX 0xFFFFFFFF
38#define IWL_TT_INCREASE_MARGIN 5
39
40/* Tx/Rx restrictions */
41#define IWL_TX_MULTI 0x02
42#define IWL_TX_SINGLE 0x01
43#define IWL_TX_NONE 0x00
44#define IWL_RX_MULTI 0x02
45#define IWL_RX_SINGLE 0x01
46#define IWL_RX_NONE 0x00
47
48/* Thermal Throttling State Machine states */
49enum iwl_tt_state {
50 IWL_TI_0, /* normal temperature, system power state */
51 IWL_TI_1, /* high temperature detect, low power state */
52 IWL_TI_2, /* higher temperature detected, lower power state */
53 IWL_TI_CT_KILL, /* critical temperature detected, lowest power state */
54 IWL_TI_STATE_MAX
55};
56
57/**
58 * struct iwl_tt_restriction - Thermal Throttling restriction table used
59 * by advance thermal throttling management
60 * based on the current thermal throttling state, determine
61 * number of tx/rx streams; and the status of HT operation
62 * @tx_stream: number of tx stream allowed
63 * @is_ht: ht enable/disable
64 * @rx_stream: number of rx stream allowed
65 */
66struct iwl_tt_restriction {
67 u8 tx_stream;
68 bool is_ht;
69 u8 rx_stream;
70};
71
72/**
73 * struct iwl_tt_trans - Thermal Throttling transaction table; used by
74 * advance thermal throttling algorithm to determine next
75 * thermal state to go based on the current temperature
76 * @next_state: next thermal throttling mode
77 * @tt_low: low temperature threshold to change state
78 * @tt_high: high temperature threshold to change state
79 */
80struct iwl_tt_trans {
81 enum iwl_tt_state next_state;
82 u32 tt_low;
83 u32 tt_high;
84};
85
86/**
87 * struct iwl_tt_mgnt - Thermal Throttling Management structure
88 * @state: current Thermal Throttling state
89 * @tt_power_mode: Thermal Throttling power mode index
90 * being used to set power level when
91 * when thermal throttling state != IWL_TI_0
92 * the tt_power_mode should set to different
93 * power mode based on the current tt state
94 * @sys_power_mode: previous system power mode
95 * before transition into TT state
96 * @tt_previous_temperature: last measured temperature
97 * @iwl_tt_restriction: ptr to restriction tbl, used by advance
98 * thermal throttling to determine how many tx/rx streams
99 * should be used in tt state; and can HT be enabled or not
100 * @iwl_tt_trans: ptr to adv trans table, used by advance thermal throttling
101 * state transaction
102 */
103struct iwl_tt_mgmt {
104 enum iwl_tt_state state;
105 u8 tt_power_mode;
106 u8 sys_power_mode;
107#ifdef CONFIG_IWLWIFI_DEBUG
108 s32 tt_previous_temp;
109#endif
110 struct iwl_tt_restriction *restriction;
111 struct iwl_tt_trans *transaction;
112};
113
36enum { 114enum {
37 IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */ 115 IWL_POWER_MODE_CAM, /* Continuously Aware Mode, always on */
38 IWL_POWER_INDEX_1, 116 IWL_POWER_INDEX_1,
@@ -59,10 +137,25 @@ struct iwl_power_mgr {
59 u8 power_mode; 137 u8 power_mode;
60 u8 user_power_setting; /* set by user through sysfs */ 138 u8 user_power_setting; /* set by user through sysfs */
61 u8 power_disabled; /* set by mac80211's CONF_PS */ 139 u8 power_disabled; /* set by mac80211's CONF_PS */
140 struct iwl_tt_mgmt tt; /* Thermal Throttling Management */
141 bool adv_tt; /* false: legacy mode */
142 /* true: advance mode */
143 bool ct_kill_toggle; /* use to toggle the CSR bit when
144 * checking uCode temperature
145 */
146 struct timer_list ct_kill_exit_tm;
62}; 147};
63 148
64int iwl_power_update_mode(struct iwl_priv *priv, bool force); 149int iwl_power_update_mode(struct iwl_priv *priv, bool force);
65int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); 150int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode);
151bool iwl_ht_enabled(struct iwl_priv *priv);
152u8 iwl_tx_ant_restriction(struct iwl_priv *priv);
153u8 iwl_rx_ant_restriction(struct iwl_priv *priv);
154void iwl_tt_enter_ct_kill(struct iwl_priv *priv);
155void iwl_tt_exit_ct_kill(struct iwl_priv *priv);
156void iwl_tt_handler(struct iwl_priv *priv);
157void iwl_tt_initialize(struct iwl_priv *priv);
158void iwl_tt_exit(struct iwl_priv *priv);
66void iwl_power_initialize(struct iwl_priv *priv); 159void iwl_power_initialize(struct iwl_priv *priv);
67 160
68#endif /* __iwl_power_setting_h__ */ 161#endif /* __iwl_power_setting_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 00398d973a07..c4c916df4a43 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -115,7 +115,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
115 struct iwl_rx_packet *res; 115 struct iwl_rx_packet *res;
116 struct iwl_host_cmd cmd = { 116 struct iwl_host_cmd cmd = {
117 .id = REPLY_SCAN_ABORT_CMD, 117 .id = REPLY_SCAN_ABORT_CMD,
118 .meta.flags = CMD_WANT_SKB, 118 .flags = CMD_WANT_SKB,
119 }; 119 };
120 120
121 /* If there isn't a scan actively going on in the hardware 121 /* If there isn't a scan actively going on in the hardware
@@ -132,7 +132,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
132 return ret; 132 return ret;
133 } 133 }
134 134
135 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 135 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
136 if (res->u.status != CAN_ABORT_STATUS) { 136 if (res->u.status != CAN_ABORT_STATUS) {
137 /* The scan abort will return 1 for success or 137 /* The scan abort will return 1 for success or
138 * 2 for "failure". A failure condition can be 138 * 2 for "failure". A failure condition can be
@@ -146,7 +146,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)
146 } 146 }
147 147
148 priv->alloc_rxb_skb--; 148 priv->alloc_rxb_skb--;
149 dev_kfree_skb_any(cmd.meta.u.skb); 149 dev_kfree_skb_any(cmd.reply_skb);
150 150
151 return ret; 151 return ret;
152} 152}
@@ -567,7 +567,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
567 struct iwl_host_cmd cmd = { 567 struct iwl_host_cmd cmd = {
568 .id = REPLY_SCAN_CMD, 568 .id = REPLY_SCAN_CMD,
569 .len = sizeof(struct iwl_scan_cmd), 569 .len = sizeof(struct iwl_scan_cmd),
570 .meta.flags = CMD_SIZE_HUGE, 570 .flags = CMD_SIZE_HUGE,
571 }; 571 };
572 struct iwl_scan_cmd *scan; 572 struct iwl_scan_cmd *scan;
573 struct ieee80211_conf *conf = NULL; 573 struct ieee80211_conf *conf = NULL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index cbe4e26d053f..79ea5cc2c89a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -97,8 +97,9 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
97 spin_unlock_irqrestore(&priv->sta_lock, flags); 97 spin_unlock_irqrestore(&priv->sta_lock, flags);
98} 98}
99 99
100static int iwl_add_sta_callback(struct iwl_priv *priv, 100static void iwl_add_sta_callback(struct iwl_priv *priv,
101 struct iwl_cmd *cmd, struct sk_buff *skb) 101 struct iwl_device_cmd *cmd,
102 struct sk_buff *skb)
102{ 103{
103 struct iwl_rx_packet *res = NULL; 104 struct iwl_rx_packet *res = NULL;
104 struct iwl_addsta_cmd *addsta = 105 struct iwl_addsta_cmd *addsta =
@@ -107,14 +108,14 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
107 108
108 if (!skb) { 109 if (!skb) {
109 IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n"); 110 IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
110 return 1; 111 return;
111 } 112 }
112 113
113 res = (struct iwl_rx_packet *)skb->data; 114 res = (struct iwl_rx_packet *)skb->data;
114 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 115 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
115 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 116 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
116 res->hdr.flags); 117 res->hdr.flags);
117 return 1; 118 return;
118 } 119 }
119 120
120 switch (res->u.add_sta.status) { 121 switch (res->u.add_sta.status) {
@@ -126,9 +127,6 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
126 res->u.add_sta.status); 127 res->u.add_sta.status);
127 break; 128 break;
128 } 129 }
129
130 /* We didn't cache the SKB; let the caller free it */
131 return 1;
132} 130}
133 131
134int iwl_send_add_sta(struct iwl_priv *priv, 132int iwl_send_add_sta(struct iwl_priv *priv,
@@ -139,14 +137,14 @@ int iwl_send_add_sta(struct iwl_priv *priv,
139 u8 data[sizeof(*sta)]; 137 u8 data[sizeof(*sta)];
140 struct iwl_host_cmd cmd = { 138 struct iwl_host_cmd cmd = {
141 .id = REPLY_ADD_STA, 139 .id = REPLY_ADD_STA,
142 .meta.flags = flags, 140 .flags = flags,
143 .data = data, 141 .data = data,
144 }; 142 };
145 143
146 if (flags & CMD_ASYNC) 144 if (flags & CMD_ASYNC)
147 cmd.meta.u.callback = iwl_add_sta_callback; 145 cmd.callback = iwl_add_sta_callback;
148 else 146 else
149 cmd.meta.flags |= CMD_WANT_SKB; 147 cmd.flags |= CMD_WANT_SKB;
150 148
151 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data); 149 cmd.len = priv->cfg->ops->utils->build_addsta_hcmd(sta, data);
152 ret = iwl_send_cmd(priv, &cmd); 150 ret = iwl_send_cmd(priv, &cmd);
@@ -154,7 +152,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
154 if (ret || (flags & CMD_ASYNC)) 152 if (ret || (flags & CMD_ASYNC))
155 return ret; 153 return ret;
156 154
157 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 155 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
158 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 156 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
159 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n", 157 IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
160 res->hdr.flags); 158 res->hdr.flags);
@@ -175,7 +173,7 @@ int iwl_send_add_sta(struct iwl_priv *priv,
175 } 173 }
176 174
177 priv->alloc_rxb_skb--; 175 priv->alloc_rxb_skb--;
178 dev_kfree_skb_any(cmd.meta.u.skb); 176 dev_kfree_skb_any(cmd.reply_skb);
179 177
180 return ret; 178 return ret;
181} 179}
@@ -324,8 +322,9 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, const char *addr)
324 spin_unlock_irqrestore(&priv->sta_lock, flags); 322 spin_unlock_irqrestore(&priv->sta_lock, flags);
325} 323}
326 324
327static int iwl_remove_sta_callback(struct iwl_priv *priv, 325static void iwl_remove_sta_callback(struct iwl_priv *priv,
328 struct iwl_cmd *cmd, struct sk_buff *skb) 326 struct iwl_device_cmd *cmd,
327 struct sk_buff *skb)
329{ 328{
330 struct iwl_rx_packet *res = NULL; 329 struct iwl_rx_packet *res = NULL;
331 struct iwl_rem_sta_cmd *rm_sta = 330 struct iwl_rem_sta_cmd *rm_sta =
@@ -334,14 +333,14 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
334 333
335 if (!skb) { 334 if (!skb) {
336 IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n"); 335 IWL_ERR(priv, "Error: Response NULL in REPLY_REMOVE_STA.\n");
337 return 1; 336 return;
338 } 337 }
339 338
340 res = (struct iwl_rx_packet *)skb->data; 339 res = (struct iwl_rx_packet *)skb->data;
341 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 340 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
342 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", 341 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
343 res->hdr.flags); 342 res->hdr.flags);
344 return 1; 343 return;
345 } 344 }
346 345
347 switch (res->u.rem_sta.status) { 346 switch (res->u.rem_sta.status) {
@@ -352,9 +351,6 @@ static int iwl_remove_sta_callback(struct iwl_priv *priv,
352 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n"); 351 IWL_ERR(priv, "REPLY_REMOVE_STA failed\n");
353 break; 352 break;
354 } 353 }
355
356 /* We didn't cache the SKB; let the caller free it */
357 return 1;
358} 354}
359 355
360static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, 356static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
@@ -368,7 +364,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
368 struct iwl_host_cmd cmd = { 364 struct iwl_host_cmd cmd = {
369 .id = REPLY_REMOVE_STA, 365 .id = REPLY_REMOVE_STA,
370 .len = sizeof(struct iwl_rem_sta_cmd), 366 .len = sizeof(struct iwl_rem_sta_cmd),
371 .meta.flags = flags, 367 .flags = flags,
372 .data = &rm_sta_cmd, 368 .data = &rm_sta_cmd,
373 }; 369 };
374 370
@@ -377,15 +373,15 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
377 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN); 373 memcpy(&rm_sta_cmd.addr, addr , ETH_ALEN);
378 374
379 if (flags & CMD_ASYNC) 375 if (flags & CMD_ASYNC)
380 cmd.meta.u.callback = iwl_remove_sta_callback; 376 cmd.callback = iwl_remove_sta_callback;
381 else 377 else
382 cmd.meta.flags |= CMD_WANT_SKB; 378 cmd.flags |= CMD_WANT_SKB;
383 ret = iwl_send_cmd(priv, &cmd); 379 ret = iwl_send_cmd(priv, &cmd);
384 380
385 if (ret || (flags & CMD_ASYNC)) 381 if (ret || (flags & CMD_ASYNC))
386 return ret; 382 return ret;
387 383
388 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 384 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
389 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 385 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
390 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n", 386 IWL_ERR(priv, "Bad return from REPLY_REMOVE_STA (0x%08X)\n",
391 res->hdr.flags); 387 res->hdr.flags);
@@ -406,7 +402,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr,
406 } 402 }
407 403
408 priv->alloc_rxb_skb--; 404 priv->alloc_rxb_skb--;
409 dev_kfree_skb_any(cmd.meta.u.skb); 405 dev_kfree_skb_any(cmd.reply_skb);
410 406
411 return ret; 407 return ret;
412} 408}
@@ -525,7 +521,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
525 struct iwl_host_cmd cmd = { 521 struct iwl_host_cmd cmd = {
526 .id = REPLY_WEPKEY, 522 .id = REPLY_WEPKEY,
527 .data = wep_cmd, 523 .data = wep_cmd,
528 .meta.flags = CMD_ASYNC, 524 .flags = CMD_ASYNC,
529 }; 525 };
530 526
531 memset(wep_cmd, 0, cmd_size + 527 memset(wep_cmd, 0, cmd_size +
@@ -930,7 +926,7 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
930 struct iwl_host_cmd cmd = { 926 struct iwl_host_cmd cmd = {
931 .id = REPLY_TX_LINK_QUALITY_CMD, 927 .id = REPLY_TX_LINK_QUALITY_CMD,
932 .len = sizeof(struct iwl_link_quality_cmd), 928 .len = sizeof(struct iwl_link_quality_cmd),
933 .meta.flags = flags, 929 .flags = flags,
934 .data = lq, 930 .data = lq,
935 }; 931 };
936 932
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index c7100b9dcede..6bb9602f3477 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -141,7 +141,7 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
141 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) 141 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
142 priv->cfg->ops->lib->txq_free_tfd(priv, txq); 142 priv->cfg->ops->lib->txq_free_tfd(priv, txq);
143 143
144 len = sizeof(struct iwl_cmd) * q->n_window; 144 len = sizeof(struct iwl_device_cmd) * q->n_window;
145 145
146 /* De-alloc array of command/tx buffers */ 146 /* De-alloc array of command/tx buffers */
147 for (i = 0; i < TFD_TX_CMD_SLOTS; i++) 147 for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
@@ -156,6 +156,12 @@ void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
156 kfree(txq->txb); 156 kfree(txq->txb);
157 txq->txb = NULL; 157 txq->txb = NULL;
158 158
159 /* deallocate arrays */
160 kfree(txq->cmd);
161 kfree(txq->meta);
162 txq->cmd = NULL;
163 txq->meta = NULL;
164
159 /* 0-fill queue descriptor structure */ 165 /* 0-fill queue descriptor structure */
160 memset(txq, 0, sizeof(*txq)); 166 memset(txq, 0, sizeof(*txq));
161} 167}
@@ -179,7 +185,7 @@ void iwl_cmd_queue_free(struct iwl_priv *priv)
179 if (q->n_bd == 0) 185 if (q->n_bd == 0)
180 return; 186 return;
181 187
182 len = sizeof(struct iwl_cmd) * q->n_window; 188 len = sizeof(struct iwl_device_cmd) * q->n_window;
183 len += IWL_MAX_SCAN_SIZE; 189 len += IWL_MAX_SCAN_SIZE;
184 190
185 /* De-alloc array of command/tx buffers */ 191 /* De-alloc array of command/tx buffers */
@@ -318,6 +324,7 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
318{ 324{
319 int i, len; 325 int i, len;
320 int ret; 326 int ret;
327 int actual_slots = slots_num;
321 328
322 /* 329 /*
323 * Alloc buffer array for commands (Tx or other types of commands). 330 * Alloc buffer array for commands (Tx or other types of commands).
@@ -327,14 +334,22 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
327 * For normal Tx queues (all other queues), no super-size command 334 * For normal Tx queues (all other queues), no super-size command
328 * space is needed. 335 * space is needed.
329 */ 336 */
330 len = sizeof(struct iwl_cmd); 337 if (txq_id == IWL_CMD_QUEUE_NUM)
331 for (i = 0; i <= slots_num; i++) { 338 actual_slots++;
332 if (i == slots_num) { 339
333 if (txq_id == IWL_CMD_QUEUE_NUM) 340 txq->meta = kzalloc(sizeof(struct iwl_cmd_meta) * actual_slots,
334 len += IWL_MAX_SCAN_SIZE; 341 GFP_KERNEL);
335 else 342 txq->cmd = kzalloc(sizeof(struct iwl_device_cmd *) * actual_slots,
336 continue; 343 GFP_KERNEL);
337 } 344
345 if (!txq->meta || !txq->cmd)
346 goto out_free_arrays;
347
348 len = sizeof(struct iwl_device_cmd);
349 for (i = 0; i < actual_slots; i++) {
350 /* only happens for cmd queue */
351 if (i == slots_num)
352 len += IWL_MAX_SCAN_SIZE;
338 353
339 txq->cmd[i] = kmalloc(len, GFP_KERNEL); 354 txq->cmd[i] = kmalloc(len, GFP_KERNEL);
340 if (!txq->cmd[i]) 355 if (!txq->cmd[i])
@@ -364,15 +379,12 @@ int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
364 379
365 return 0; 380 return 0;
366err: 381err:
367 for (i = 0; i < slots_num; i++) { 382 for (i = 0; i < actual_slots; i++)
368 kfree(txq->cmd[i]); 383 kfree(txq->cmd[i]);
369 txq->cmd[i] = NULL; 384out_free_arrays:
370 } 385 kfree(txq->meta);
386 kfree(txq->cmd);
371 387
372 if (txq_id == IWL_CMD_QUEUE_NUM) {
373 kfree(txq->cmd[slots_num]);
374 txq->cmd[slots_num] = NULL;
375 }
376 return -ENOMEM; 388 return -ENOMEM;
377} 389}
378EXPORT_SYMBOL(iwl_tx_queue_init); 390EXPORT_SYMBOL(iwl_tx_queue_init);
@@ -673,7 +685,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
673 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 685 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
674 struct iwl_tx_queue *txq; 686 struct iwl_tx_queue *txq;
675 struct iwl_queue *q; 687 struct iwl_queue *q;
676 struct iwl_cmd *out_cmd; 688 struct iwl_device_cmd *out_cmd;
689 struct iwl_cmd_meta *out_meta;
677 struct iwl_tx_cmd *tx_cmd; 690 struct iwl_tx_cmd *tx_cmd;
678 int swq_id, txq_id; 691 int swq_id, txq_id;
679 dma_addr_t phys_addr; 692 dma_addr_t phys_addr;
@@ -767,6 +780,7 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
767 780
768 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 781 /* Set up first empty entry in queue's array of Tx/cmd buffers */
769 out_cmd = txq->cmd[q->write_ptr]; 782 out_cmd = txq->cmd[q->write_ptr];
783 out_meta = &txq->meta[q->write_ptr];
770 tx_cmd = &out_cmd->cmd.tx; 784 tx_cmd = &out_cmd->cmd.tx;
771 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); 785 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
772 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd)); 786 memset(tx_cmd, 0, sizeof(struct iwl_tx_cmd));
@@ -829,8 +843,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
829 txcmd_phys = pci_map_single(priv->pci_dev, 843 txcmd_phys = pci_map_single(priv->pci_dev,
830 &out_cmd->hdr, len, 844 &out_cmd->hdr, len,
831 PCI_DMA_BIDIRECTIONAL); 845 PCI_DMA_BIDIRECTIONAL);
832 pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); 846 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
833 pci_unmap_len_set(&out_cmd->meta, len, len); 847 pci_unmap_len_set(out_meta, len, len);
834 /* Add buffer containing Tx command and MAC(!) header to TFD's 848 /* Add buffer containing Tx command and MAC(!) header to TFD's
835 * first entry */ 849 * first entry */
836 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 850 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
@@ -923,7 +937,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
923{ 937{
924 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM]; 938 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];
925 struct iwl_queue *q = &txq->q; 939 struct iwl_queue *q = &txq->q;
926 struct iwl_cmd *out_cmd; 940 struct iwl_device_cmd *out_cmd;
941 struct iwl_cmd_meta *out_meta;
927 dma_addr_t phys_addr; 942 dma_addr_t phys_addr;
928 unsigned long flags; 943 unsigned long flags;
929 int len, ret; 944 int len, ret;
@@ -937,25 +952,31 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
937 * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then 952 * the TFD_MAX_PAYLOAD_SIZE, and it sent as a 'small' command then
938 * we will need to increase the size of the TFD entries */ 953 * we will need to increase the size of the TFD entries */
939 BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) && 954 BUG_ON((fix_size > TFD_MAX_PAYLOAD_SIZE) &&
940 !(cmd->meta.flags & CMD_SIZE_HUGE)); 955 !(cmd->flags & CMD_SIZE_HUGE));
941 956
942 if (iwl_is_rfkill(priv)) { 957 if (iwl_is_rfkill(priv)) {
943 IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n"); 958 IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n");
944 return -EIO; 959 return -EIO;
945 } 960 }
946 961
947 if (iwl_queue_space(q) < ((cmd->meta.flags & CMD_ASYNC) ? 2 : 1)) { 962 if (iwl_queue_space(q) < ((cmd->flags & CMD_ASYNC) ? 2 : 1)) {
948 IWL_ERR(priv, "No space for Tx\n"); 963 IWL_ERR(priv, "No space for Tx\n");
949 return -ENOSPC; 964 return -ENOSPC;
950 } 965 }
951 966
952 spin_lock_irqsave(&priv->hcmd_lock, flags); 967 spin_lock_irqsave(&priv->hcmd_lock, flags);
953 968
954 idx = get_cmd_index(q, q->write_ptr, cmd->meta.flags & CMD_SIZE_HUGE); 969 idx = get_cmd_index(q, q->write_ptr, cmd->flags & CMD_SIZE_HUGE);
955 out_cmd = txq->cmd[idx]; 970 out_cmd = txq->cmd[idx];
971 out_meta = &txq->meta[idx];
972
973 out_meta->flags = cmd->flags;
974 if (cmd->flags & CMD_WANT_SKB)
975 out_meta->source = cmd;
976 if (cmd->flags & CMD_ASYNC)
977 out_meta->callback = cmd->callback;
956 978
957 out_cmd->hdr.cmd = cmd->id; 979 out_cmd->hdr.cmd = cmd->id;
958 memcpy(&out_cmd->meta, &cmd->meta, sizeof(cmd->meta));
959 memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); 980 memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
960 981
961 /* At this point, the out_cmd now has all of the incoming cmd 982 /* At this point, the out_cmd now has all of the incoming cmd
@@ -964,9 +985,9 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
964 out_cmd->hdr.flags = 0; 985 out_cmd->hdr.flags = 0;
965 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) | 986 out_cmd->hdr.sequence = cpu_to_le16(QUEUE_TO_SEQ(IWL_CMD_QUEUE_NUM) |
966 INDEX_TO_SEQ(q->write_ptr)); 987 INDEX_TO_SEQ(q->write_ptr));
967 if (out_cmd->meta.flags & CMD_SIZE_HUGE) 988 if (cmd->flags & CMD_SIZE_HUGE)
968 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME; 989 out_cmd->hdr.sequence |= SEQ_HUGE_FRAME;
969 len = sizeof(struct iwl_cmd) - sizeof(struct iwl_cmd_meta); 990 len = sizeof(struct iwl_device_cmd);
970 len += (idx == TFD_CMD_SLOTS) ? IWL_MAX_SCAN_SIZE : 0; 991 len += (idx == TFD_CMD_SLOTS) ? IWL_MAX_SCAN_SIZE : 0;
971 992
972 993
@@ -998,8 +1019,8 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
998 1019
999 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr, 1020 phys_addr = pci_map_single(priv->pci_dev, &out_cmd->hdr,
1000 fix_size, PCI_DMA_BIDIRECTIONAL); 1021 fix_size, PCI_DMA_BIDIRECTIONAL);
1001 pci_unmap_addr_set(&out_cmd->meta, mapping, phys_addr); 1022 pci_unmap_addr_set(out_meta, mapping, phys_addr);
1002 pci_unmap_len_set(&out_cmd->meta, len, fix_size); 1023 pci_unmap_len_set(out_meta, len, fix_size);
1003 1024
1004 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq, 1025 priv->cfg->ops->lib->txq_attach_buf_to_tfd(priv, txq,
1005 phys_addr, fix_size, 1, 1026 phys_addr, fix_size, 1,
@@ -1068,8 +1089,8 @@ static void iwl_hcmd_queue_reclaim(struct iwl_priv *priv, int txq_id,
1068 } 1089 }
1069 1090
1070 pci_unmap_single(priv->pci_dev, 1091 pci_unmap_single(priv->pci_dev,
1071 pci_unmap_addr(&txq->cmd[cmd_idx]->meta, mapping), 1092 pci_unmap_addr(&txq->meta[cmd_idx], mapping),
1072 pci_unmap_len(&txq->cmd[cmd_idx]->meta, len), 1093 pci_unmap_len(&txq->meta[cmd_idx], len),
1073 PCI_DMA_BIDIRECTIONAL); 1094 PCI_DMA_BIDIRECTIONAL);
1074 1095
1075 for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; 1096 for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx;
@@ -1100,7 +1121,8 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1100 int index = SEQ_TO_INDEX(sequence); 1121 int index = SEQ_TO_INDEX(sequence);
1101 int cmd_index; 1122 int cmd_index;
1102 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME); 1123 bool huge = !!(pkt->hdr.sequence & SEQ_HUGE_FRAME);
1103 struct iwl_cmd *cmd; 1124 struct iwl_device_cmd *cmd;
1125 struct iwl_cmd_meta *meta;
1104 1126
1105 /* If a Tx command is being handled and it isn't in the actual 1127 /* If a Tx command is being handled and it isn't in the actual
1106 * command queue then there a command routing bug has been introduced 1128 * command queue then there a command routing bug has been introduced
@@ -1110,24 +1132,24 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1110 txq_id, sequence, 1132 txq_id, sequence,
1111 priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr, 1133 priv->txq[IWL_CMD_QUEUE_NUM].q.read_ptr,
1112 priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) { 1134 priv->txq[IWL_CMD_QUEUE_NUM].q.write_ptr)) {
1113 iwl_print_hex_error(priv, rxb, 32); 1135 iwl_print_hex_error(priv, pkt, 32);
1114 return; 1136 return;
1115 } 1137 }
1116 1138
1117 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge); 1139 cmd_index = get_cmd_index(&priv->txq[IWL_CMD_QUEUE_NUM].q, index, huge);
1118 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index]; 1140 cmd = priv->txq[IWL_CMD_QUEUE_NUM].cmd[cmd_index];
1141 meta = &priv->txq[IWL_CMD_QUEUE_NUM].meta[cmd_index];
1119 1142
1120 /* Input error checking is done when commands are added to queue. */ 1143 /* Input error checking is done when commands are added to queue. */
1121 if (cmd->meta.flags & CMD_WANT_SKB) { 1144 if (meta->flags & CMD_WANT_SKB) {
1122 cmd->meta.source->u.skb = rxb->skb; 1145 meta->source->reply_skb = rxb->skb;
1123 rxb->skb = NULL;
1124 } else if (cmd->meta.u.callback &&
1125 !cmd->meta.u.callback(priv, cmd, rxb->skb))
1126 rxb->skb = NULL; 1146 rxb->skb = NULL;
1147 } else if (meta->callback)
1148 meta->callback(priv, cmd, rxb->skb);
1127 1149
1128 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index); 1150 iwl_hcmd_queue_reclaim(priv, txq_id, index, cmd_index);
1129 1151
1130 if (!(cmd->meta.flags & CMD_ASYNC)) { 1152 if (!(meta->flags & CMD_ASYNC)) {
1131 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1153 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1132 wake_up_interruptible(&priv->wait_command_queue); 1154 wake_up_interruptible(&priv->wait_command_queue);
1133 } 1155 }
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 2cc7e30d7743..5ded8983b915 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -363,7 +363,7 @@ static void iwl3945_unset_hw_params(struct iwl_priv *priv)
363 363
364static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, 364static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
365 struct ieee80211_tx_info *info, 365 struct ieee80211_tx_info *info,
366 struct iwl_cmd *cmd, 366 struct iwl_device_cmd *cmd,
367 struct sk_buff *skb_frag, 367 struct sk_buff *skb_frag,
368 int sta_id) 368 int sta_id)
369{ 369{
@@ -403,7 +403,7 @@ static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,
403 * handle build REPLY_TX command notification. 403 * handle build REPLY_TX command notification.
404 */ 404 */
405static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, 405static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv,
406 struct iwl_cmd *cmd, 406 struct iwl_device_cmd *cmd,
407 struct ieee80211_tx_info *info, 407 struct ieee80211_tx_info *info,
408 struct ieee80211_hdr *hdr, u8 std_id) 408 struct ieee80211_hdr *hdr, u8 std_id)
409{ 409{
@@ -476,7 +476,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
476 struct iwl3945_tx_cmd *tx; 476 struct iwl3945_tx_cmd *tx;
477 struct iwl_tx_queue *txq = NULL; 477 struct iwl_tx_queue *txq = NULL;
478 struct iwl_queue *q = NULL; 478 struct iwl_queue *q = NULL;
479 struct iwl_cmd *out_cmd = NULL; 479 struct iwl_device_cmd *out_cmd;
480 struct iwl_cmd_meta *out_meta;
480 dma_addr_t phys_addr; 481 dma_addr_t phys_addr;
481 dma_addr_t txcmd_phys; 482 dma_addr_t txcmd_phys;
482 int txq_id = skb_get_queue_mapping(skb); 483 int txq_id = skb_get_queue_mapping(skb);
@@ -565,6 +566,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
565 566
566 /* Init first empty entry in queue's array of Tx/cmd buffers */ 567 /* Init first empty entry in queue's array of Tx/cmd buffers */
567 out_cmd = txq->cmd[idx]; 568 out_cmd = txq->cmd[idx];
569 out_meta = &txq->meta[idx];
568 tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload; 570 tx = (struct iwl3945_tx_cmd *)out_cmd->cmd.payload;
569 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr)); 571 memset(&out_cmd->hdr, 0, sizeof(out_cmd->hdr));
570 memset(tx, 0, sizeof(*tx)); 572 memset(tx, 0, sizeof(*tx));
@@ -642,8 +644,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
642 len, PCI_DMA_TODEVICE); 644 len, PCI_DMA_TODEVICE);
643 /* we do not map meta data ... so we can safely access address to 645 /* we do not map meta data ... so we can safely access address to
644 * provide to unmap command*/ 646 * provide to unmap command*/
645 pci_unmap_addr_set(&out_cmd->meta, mapping, txcmd_phys); 647 pci_unmap_addr_set(out_meta, mapping, txcmd_phys);
646 pci_unmap_len_set(&out_cmd->meta, len, len); 648 pci_unmap_len_set(out_meta, len, len);
647 649
648 /* Add buffer containing Tx command and MAC(!) header to TFD's 650 /* Add buffer containing Tx command and MAC(!) header to TFD's
649 * first entry */ 651 * first entry */
@@ -753,7 +755,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
753 struct iwl_host_cmd cmd = { 755 struct iwl_host_cmd cmd = {
754 .id = REPLY_SPECTRUM_MEASUREMENT_CMD, 756 .id = REPLY_SPECTRUM_MEASUREMENT_CMD,
755 .data = (void *)&spectrum, 757 .data = (void *)&spectrum,
756 .meta.flags = CMD_WANT_SKB, 758 .flags = CMD_WANT_SKB,
757 }; 759 };
758 u32 add_time = le64_to_cpu(params->start_time); 760 u32 add_time = le64_to_cpu(params->start_time);
759 int rc; 761 int rc;
@@ -794,7 +796,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
794 if (rc) 796 if (rc)
795 return rc; 797 return rc;
796 798
797 res = (struct iwl_rx_packet *)cmd.meta.u.skb->data; 799 res = (struct iwl_rx_packet *)cmd.reply_skb->data;
798 if (res->hdr.flags & IWL_CMD_FAILED_MSK) { 800 if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
799 IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n"); 801 IWL_ERR(priv, "Bad return from REPLY_RX_ON_ASSOC command\n");
800 rc = -EIO; 802 rc = -EIO;
@@ -817,7 +819,7 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
817 break; 819 break;
818 } 820 }
819 821
820 dev_kfree_skb_any(cmd.meta.u.skb); 822 dev_kfree_skb_any(cmd.reply_skb);
821 823
822 return rc; 824 return rc;
823} 825}
@@ -2717,7 +2719,7 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
2717 struct iwl_host_cmd cmd = { 2719 struct iwl_host_cmd cmd = {
2718 .id = REPLY_SCAN_CMD, 2720 .id = REPLY_SCAN_CMD,
2719 .len = sizeof(struct iwl3945_scan_cmd), 2721 .len = sizeof(struct iwl3945_scan_cmd),
2720 .meta.flags = CMD_SIZE_HUGE, 2722 .flags = CMD_SIZE_HUGE,
2721 }; 2723 };
2722 int rc = 0; 2724 int rc = 0;
2723 struct iwl3945_scan_cmd *scan; 2725 struct iwl3945_scan_cmd *scan;
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig
index 030401d367d3..c62da435285a 100644
--- a/drivers/net/wireless/iwmc3200wifi/Kconfig
+++ b/drivers/net/wireless/iwmc3200wifi/Kconfig
@@ -2,7 +2,6 @@ config IWM
2 tristate "Intel Wireless Multicomm 3200 WiFi driver" 2 tristate "Intel Wireless Multicomm 3200 WiFi driver"
3 depends on MMC && WLAN_80211 && EXPERIMENTAL 3 depends on MMC && WLAN_80211 && EXPERIMENTAL
4 depends on CFG80211 4 depends on CFG80211
5 select WIRELESS_EXT
6 select FW_LOADER 5 select FW_LOADER
7 help 6 help
8 The Intel Wireless Multicomm 3200 hardware is a combo 7 The Intel Wireless Multicomm 3200 hardware is a combo
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile
index 927f022545c1..d34291b652d3 100644
--- a/drivers/net/wireless/iwmc3200wifi/Makefile
+++ b/drivers/net/wireless/iwmc3200wifi/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_IWM) := iwmc3200wifi.o 1obj-$(CONFIG_IWM) := iwmc3200wifi.o
2iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o 2iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o
3iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o 3iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o
4 4
5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o 5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 2175a481d2f4..7a51bc340fda 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -306,8 +306,6 @@ static inline void *iwm_private(struct iwm_priv *iwm)
306#define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb)) 306#define skb_to_rx_info(s) ((struct iwm_rx_info *)(s->cb))
307#define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb) 307#define skb_to_tx_info(s) ((struct iwm_tx_info *)s->cb)
308 308
309extern const struct iw_handler_def iwm_iw_handler_def;
310
311void *iwm_if_alloc(int sizeof_bus, struct device *dev, 309void *iwm_if_alloc(int sizeof_bus, struct device *dev,
312 struct iwm_if_ops *if_ops); 310 struct iwm_if_ops *if_ops);
313void iwm_if_free(struct iwm_priv *iwm); 311void iwm_if_free(struct iwm_priv *iwm);
diff --git a/drivers/net/wireless/iwmc3200wifi/netdev.c b/drivers/net/wireless/iwmc3200wifi/netdev.c
index 93cc1b3e7f48..35ec006c2d2c 100644
--- a/drivers/net/wireless/iwmc3200wifi/netdev.c
+++ b/drivers/net/wireless/iwmc3200wifi/netdev.c
@@ -121,7 +121,6 @@ void *iwm_if_alloc(int sizeof_bus, struct device *dev,
121 } 121 }
122 122
123 ndev->netdev_ops = &iwm_netdev_ops; 123 ndev->netdev_ops = &iwm_netdev_ops;
124 ndev->wireless_handlers = &iwm_iw_handler_def;
125 ndev->ieee80211_ptr = wdev; 124 ndev->ieee80211_ptr = wdev;
126 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy)); 125 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
127 wdev->netdev = ndev; 126 wdev->netdev = ndev;
diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c
deleted file mode 100644
index c3c90d5963bf..000000000000
--- a/drivers/net/wireless/iwmc3200wifi/wext.c
+++ /dev/null
@@ -1,187 +0,0 @@
1/*
2 * Intel Wireless Multicomm 3200 WiFi driver
3 *
4 * Copyright (C) 2009 Intel Corporation <ilw@linux.intel.com>
5 * Samuel Ortiz <samuel.ortiz@intel.com>
6 * Zhu Yi <yi.zhu@intel.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License version
10 * 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *
22 */
23
24#include <linux/wireless.h>
25#include <net/cfg80211.h>
26
27#include "iwm.h"
28#include "commands.h"
29
30static int iwm_wext_siwfreq(struct net_device *dev,
31 struct iw_request_info *info,
32 struct iw_freq *freq, char *extra)
33{
34 struct iwm_priv *iwm = ndev_to_iwm(dev);
35
36 switch (iwm->conf.mode) {
37 case UMAC_MODE_IBSS:
38 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
39 default:
40 return -EOPNOTSUPP;
41 }
42}
43
44static int iwm_wext_giwfreq(struct net_device *dev,
45 struct iw_request_info *info,
46 struct iw_freq *freq, char *extra)
47{
48 struct iwm_priv *iwm = ndev_to_iwm(dev);
49
50 switch (iwm->conf.mode) {
51 case UMAC_MODE_IBSS:
52 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
53 case UMAC_MODE_BSS:
54 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
55 default:
56 return -EOPNOTSUPP;
57 }
58}
59
60static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info,
61 struct sockaddr *ap_addr, char *extra)
62{
63 struct iwm_priv *iwm = ndev_to_iwm(dev);
64
65 switch (iwm->conf.mode) {
66 case UMAC_MODE_IBSS:
67 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
68 case UMAC_MODE_BSS:
69 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
70 default:
71 return -EOPNOTSUPP;
72 }
73}
74
75static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info,
76 struct sockaddr *ap_addr, char *extra)
77{
78 struct iwm_priv *iwm = ndev_to_iwm(dev);
79
80 switch (iwm->conf.mode) {
81 case UMAC_MODE_IBSS:
82 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
83 case UMAC_MODE_BSS:
84 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
85 default:
86 return -EOPNOTSUPP;
87 }
88}
89
90static int iwm_wext_siwessid(struct net_device *dev,
91 struct iw_request_info *info,
92 struct iw_point *data, char *ssid)
93{
94 struct iwm_priv *iwm = ndev_to_iwm(dev);
95
96 switch (iwm->conf.mode) {
97 case UMAC_MODE_IBSS:
98 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
99 case UMAC_MODE_BSS:
100 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
101 default:
102 return -EOPNOTSUPP;
103 }
104}
105
106static int iwm_wext_giwessid(struct net_device *dev,
107 struct iw_request_info *info,
108 struct iw_point *data, char *ssid)
109{
110 struct iwm_priv *iwm = ndev_to_iwm(dev);
111
112 switch (iwm->conf.mode) {
113 case UMAC_MODE_IBSS:
114 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
115 case UMAC_MODE_BSS:
116 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
117 default:
118 return -EOPNOTSUPP;
119 }
120}
121
122static const iw_handler iwm_handlers[] =
123{
124 (iw_handler) NULL, /* SIOCSIWCOMMIT */
125 (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */
126 (iw_handler) NULL, /* SIOCSIWNWID */
127 (iw_handler) NULL, /* SIOCGIWNWID */
128 (iw_handler) iwm_wext_siwfreq, /* SIOCSIWFREQ */
129 (iw_handler) iwm_wext_giwfreq, /* SIOCGIWFREQ */
130 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
131 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
132 (iw_handler) NULL, /* SIOCSIWSENS */
133 (iw_handler) NULL, /* SIOCGIWSENS */
134 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
135 (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */
136 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
137 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
138 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
139 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
140 (iw_handler) NULL, /* SIOCSIWSPY */
141 (iw_handler) NULL, /* SIOCGIWSPY */
142 (iw_handler) NULL, /* SIOCSIWTHRSPY */
143 (iw_handler) NULL, /* SIOCGIWTHRSPY */
144 (iw_handler) iwm_wext_siwap, /* SIOCSIWAP */
145 (iw_handler) iwm_wext_giwap, /* SIOCGIWAP */
146 (iw_handler) NULL, /* SIOCSIWMLME */
147 (iw_handler) NULL, /* SIOCGIWAPLIST */
148 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
149 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
150 (iw_handler) iwm_wext_siwessid, /* SIOCSIWESSID */
151 (iw_handler) iwm_wext_giwessid, /* SIOCGIWESSID */
152 (iw_handler) NULL, /* SIOCSIWNICKN */
153 (iw_handler) NULL, /* SIOCGIWNICKN */
154 (iw_handler) NULL, /* -- hole -- */
155 (iw_handler) NULL, /* -- hole -- */
156 (iw_handler) NULL, /* SIOCSIWRATE */
157 (iw_handler) cfg80211_wext_giwrate, /* SIOCGIWRATE */
158 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
159 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
160 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
161 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
162 (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */
163 (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */
164 (iw_handler) NULL, /* SIOCSIWRETRY */
165 (iw_handler) NULL, /* SIOCGIWRETRY */
166 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
167 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
168 (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */
169 (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */
170 (iw_handler) NULL, /* -- hole -- */
171 (iw_handler) NULL, /* -- hole -- */
172 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
173 (iw_handler) NULL, /* SIOCGIWGENIE */
174 (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */
175 (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */
176 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
177 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
178 (iw_handler) NULL, /* SIOCSIWPMKSA */
179 (iw_handler) NULL, /* -- hole -- */
180};
181
182const struct iw_handler_def iwm_iw_handler_def = {
183 .num_standard = ARRAY_SIZE(iwm_handlers),
184 .standard = (iw_handler *) iwm_handlers,
185 .get_wireless_stats = cfg80211_wireless_stats,
186};
187
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 0d589d68e547..c32a0d2fa1f7 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -614,7 +614,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
614 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) 614 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ)
615 *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR; 615 *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
616 616
617 if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT) 617 if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)
618 *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; 618 *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
619 619
620 *queue = skb_get_queue_mapping(skb) + P54_QUEUE_DATA; 620 *queue = skb_get_queue_mapping(skb) + P54_QUEUE_DATA;
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 64e574c3655c..2be78201633f 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1511,9 +1511,6 @@ static iw_stats *ray_get_wireless_stats(struct net_device *dev)
1511 struct pcmcia_device *link = local->finder; 1511 struct pcmcia_device *link = local->finder;
1512 struct status __iomem *p = local->sram + STATUS_BASE; 1512 struct status __iomem *p = local->sram + STATUS_BASE;
1513 1513
1514 if (local == (ray_dev_t *) NULL)
1515 return (iw_stats *) NULL;
1516
1517 local->wstats.status = local->card_status; 1514 local->wstats.status = local->card_status;
1518#ifdef WIRELESS_SPY 1515#ifdef WIRELESS_SPY
1519 if ((local->spy_data.spy_number > 0) 1516 if ((local->spy_data.spy_number > 0)
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index c6e0bcf78e9e..3845316ccd39 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -124,7 +124,7 @@ enum antenna rt2x00lib_config_antenna_check(enum antenna current_ant,
124} 124}
125 125
126void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, 126void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
127 struct antenna_setup *ant) 127 struct antenna_setup ant)
128{ 128{
129 struct antenna_setup *def = &rt2x00dev->default_ant; 129 struct antenna_setup *def = &rt2x00dev->default_ant;
130 struct antenna_setup *active = &rt2x00dev->link.ant.active; 130 struct antenna_setup *active = &rt2x00dev->link.ant.active;
@@ -138,10 +138,10 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
138 * might have caused that we restore back to the already 138 * might have caused that we restore back to the already
139 * active setting. If that has happened we can quit. 139 * active setting. If that has happened we can quit.
140 */ 140 */
141 ant->rx = rt2x00lib_config_antenna_check(ant->rx, def->rx); 141 ant.rx = rt2x00lib_config_antenna_check(ant.rx, def->rx);
142 ant->tx = rt2x00lib_config_antenna_check(ant->tx, def->tx); 142 ant.tx = rt2x00lib_config_antenna_check(ant.tx, def->tx);
143 143
144 if (ant->rx == active->rx && ant->tx == active->tx) 144 if (ant.rx == active->rx && ant.tx == active->tx)
145 return; 145 return;
146 146
147 /* 147 /*
@@ -156,11 +156,11 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
156 * The latter is required since we need to recalibrate the 156 * The latter is required since we need to recalibrate the
157 * noise-sensitivity ratio for the new setup. 157 * noise-sensitivity ratio for the new setup.
158 */ 158 */
159 rt2x00dev->ops->lib->config_ant(rt2x00dev, ant); 159 rt2x00dev->ops->lib->config_ant(rt2x00dev, &ant);
160 160
161 rt2x00link_reset_tuner(rt2x00dev, true); 161 rt2x00link_reset_tuner(rt2x00dev, true);
162 162
163 memcpy(active, ant, sizeof(*ant)); 163 memcpy(active, &ant, sizeof(ant));
164 164
165 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) 165 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
166 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK); 166 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON_LINK);
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
index 512fa2bc3a10..eeb2881e818e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00lib.h
+++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
@@ -88,7 +88,7 @@ void rt2x00lib_config_erp(struct rt2x00_dev *rt2x00dev,
88 struct rt2x00_intf *intf, 88 struct rt2x00_intf *intf,
89 struct ieee80211_bss_conf *conf); 89 struct ieee80211_bss_conf *conf);
90void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, 90void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
91 struct antenna_setup *ant); 91 struct antenna_setup ant);
92void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, 92void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
93 struct ieee80211_conf *conf, 93 struct ieee80211_conf *conf,
94 const unsigned int changed_flags); 94 const unsigned int changed_flags);
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 32570758e67c..79915687e744 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -173,7 +173,7 @@ static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
173 if (ant->flags & ANTENNA_TX_DIVERSITY) 173 if (ant->flags & ANTENNA_TX_DIVERSITY)
174 new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B; 174 new_ant.tx = (sample_a > sample_b) ? ANTENNA_A : ANTENNA_B;
175 175
176 rt2x00lib_config_antenna(rt2x00dev, &new_ant); 176 rt2x00lib_config_antenna(rt2x00dev, new_ant);
177} 177}
178 178
179static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev) 179static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
@@ -213,7 +213,7 @@ static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev)
213 if (ant->flags & ANTENNA_TX_DIVERSITY) 213 if (ant->flags & ANTENNA_TX_DIVERSITY)
214 new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A; 214 new_ant.tx = (new_ant.tx == ANTENNA_A) ? ANTENNA_B : ANTENNA_A;
215 215
216 rt2x00lib_config_antenna(rt2x00dev, &new_ant); 216 rt2x00lib_config_antenna(rt2x00dev, new_ant);
217} 217}
218 218
219static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) 219static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 9d31c23b92fa..7de1a2cdcf8c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -378,7 +378,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
378 */ 378 */
379 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED) 379 if (changed & IEEE80211_CONF_CHANGE_RADIO_ENABLED)
380 rt2x00lib_config_antenna(rt2x00dev, 380 rt2x00lib_config_antenna(rt2x00dev,
381 &rt2x00dev->default_ant); 381 rt2x00dev->default_ant);
382 382
383 /* Turn RX back on */ 383 /* Turn RX back on */
384 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON); 384 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 23343ab0bb03..21556a2d9e7e 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -802,6 +802,31 @@ struct ieee80211_ht_cap {
802#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 802#define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03
803#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C 803#define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C
804 804
805/*
806 * Maximum length of AMPDU that the STA can receive.
807 * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
808 */
809enum ieee80211_max_ampdu_length_exp {
810 IEEE80211_HT_MAX_AMPDU_8K = 0,
811 IEEE80211_HT_MAX_AMPDU_16K = 1,
812 IEEE80211_HT_MAX_AMPDU_32K = 2,
813 IEEE80211_HT_MAX_AMPDU_64K = 3
814};
815
816#define IEEE80211_HT_MAX_AMPDU_FACTOR 13
817
818/* Minimum MPDU start spacing */
819enum ieee80211_min_mpdu_spacing {
820 IEEE80211_HT_MPDU_DENSITY_NONE = 0, /* No restriction */
821 IEEE80211_HT_MPDU_DENSITY_0_25 = 1, /* 1/4 usec */
822 IEEE80211_HT_MPDU_DENSITY_0_5 = 2, /* 1/2 usec */
823 IEEE80211_HT_MPDU_DENSITY_1 = 3, /* 1 usec */
824 IEEE80211_HT_MPDU_DENSITY_2 = 4, /* 2 usec */
825 IEEE80211_HT_MPDU_DENSITY_4 = 5, /* 4 usec */
826 IEEE80211_HT_MPDU_DENSITY_8 = 6, /* 8 usec */
827 IEEE80211_HT_MPDU_DENSITY_16 = 7 /* 16 usec */
828};
829
805/** 830/**
806 * struct ieee80211_ht_info - HT information 831 * struct ieee80211_ht_info - HT information
807 * 832 *
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 962e2232a074..cb3dc6027fd9 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -262,6 +262,9 @@
262 * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and 262 * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and
263 * %NL80211_ATTR_REASON_CODE attributes are used. 263 * %NL80211_ATTR_REASON_CODE attributes are used.
264 * 264 *
265 * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices
266 * associated with this wiphy must be down and will follow.
267 *
265 * @NL80211_CMD_MAX: highest used command number 268 * @NL80211_CMD_MAX: highest used command number
266 * @__NL80211_CMD_AFTER_LAST: internal use 269 * @__NL80211_CMD_AFTER_LAST: internal use
267 */ 270 */
@@ -336,6 +339,8 @@ enum nl80211_commands {
336 NL80211_CMD_ROAM, 339 NL80211_CMD_ROAM,
337 NL80211_CMD_DISCONNECT, 340 NL80211_CMD_DISCONNECT,
338 341
342 NL80211_CMD_SET_WIPHY_NETNS,
343
339 /* add new commands above here */ 344 /* add new commands above here */
340 345
341 /* used to define NL80211_CMD_MAX below */ 346 /* used to define NL80211_CMD_MAX below */
@@ -573,6 +578,8 @@ enum nl80211_commands {
573 * and join_ibss(), key information is in a nested attribute each 578 * and join_ibss(), key information is in a nested attribute each
574 * with %NL80211_KEY_* sub-attributes 579 * with %NL80211_KEY_* sub-attributes
575 * 580 *
581 * @NL80211_ATTR_PID: Process ID of a network namespace.
582 *
576 * @NL80211_ATTR_MAX: highest attribute number currently defined 583 * @NL80211_ATTR_MAX: highest attribute number currently defined
577 * @__NL80211_ATTR_AFTER_LAST: internal use 584 * @__NL80211_ATTR_AFTER_LAST: internal use
578 */ 585 */
@@ -701,6 +708,8 @@ enum nl80211_attrs {
701 NL80211_ATTR_KEY, 708 NL80211_ATTR_KEY,
702 NL80211_ATTR_KEYS, 709 NL80211_ATTR_KEYS,
703 710
711 NL80211_ATTR_PID,
712
704 /* add attributes here, update the policy in nl80211.c */ 713 /* add attributes here, update the policy in nl80211.c */
705 714
706 __NL80211_ATTR_AFTER_LAST, 715 __NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index a981ca8a5701..e1b92358242b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -542,7 +542,7 @@ struct cfg80211_ssid {
542 * @ie: optional information element(s) to add into Probe Request or %NULL 542 * @ie: optional information element(s) to add into Probe Request or %NULL
543 * @ie_len: length of ie in octets 543 * @ie_len: length of ie in octets
544 * @wiphy: the wiphy this was for 544 * @wiphy: the wiphy this was for
545 * @ifidx: the interface index 545 * @dev: the interface
546 */ 546 */
547struct cfg80211_scan_request { 547struct cfg80211_scan_request {
548 struct cfg80211_ssid *ssids; 548 struct cfg80211_ssid *ssids;
@@ -554,7 +554,7 @@ struct cfg80211_scan_request {
554 554
555 /* internal */ 555 /* internal */
556 struct wiphy *wiphy; 556 struct wiphy *wiphy;
557 int ifidx; 557 struct net_device *dev;
558 bool aborted; 558 bool aborted;
559}; 559};
560 560
@@ -845,7 +845,8 @@ struct cfg80211_bitrate_mask {
845 * @resume: wiphy device needs to be resumed 845 * @resume: wiphy device needs to be resumed
846 * 846 *
847 * @add_virtual_intf: create a new virtual interface with the given name, 847 * @add_virtual_intf: create a new virtual interface with the given name,
848 * must set the struct wireless_dev's iftype. 848 * must set the struct wireless_dev's iftype. Beware: You must create
849 * the new netdev in the wiphy's network namespace!
849 * 850 *
850 * @del_virtual_intf: remove the virtual interface determined by ifindex. 851 * @del_virtual_intf: remove the virtual interface determined by ifindex.
851 * 852 *
@@ -937,7 +938,7 @@ struct cfg80211_ops {
937 int (*add_virtual_intf)(struct wiphy *wiphy, char *name, 938 int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
938 enum nl80211_iftype type, u32 *flags, 939 enum nl80211_iftype type, u32 *flags,
939 struct vif_params *params); 940 struct vif_params *params);
940 int (*del_virtual_intf)(struct wiphy *wiphy, int ifindex); 941 int (*del_virtual_intf)(struct wiphy *wiphy, struct net_device *dev);
941 int (*change_virtual_intf)(struct wiphy *wiphy, 942 int (*change_virtual_intf)(struct wiphy *wiphy,
942 struct net_device *dev, 943 struct net_device *dev,
943 enum nl80211_iftype type, u32 *flags, 944 enum nl80211_iftype type, u32 *flags,
@@ -1088,6 +1089,9 @@ struct cfg80211_ops {
1088 * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold); 1089 * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold);
1089 * -1 = fragmentation disabled, only odd values >= 256 used 1090 * -1 = fragmentation disabled, only odd values >= 256 used
1090 * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled 1091 * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled
1092 * @net: the network namespace this wiphy currently lives in
1093 * @netnsok: if set to false, do not allow changing the netns of this
1094 * wiphy at all
1091 */ 1095 */
1092struct wiphy { 1096struct wiphy {
1093 /* assign these fields before you register the wiphy */ 1097 /* assign these fields before you register the wiphy */
@@ -1101,6 +1105,8 @@ struct wiphy {
1101 bool custom_regulatory; 1105 bool custom_regulatory;
1102 bool strict_regulatory; 1106 bool strict_regulatory;
1103 1107
1108 bool netnsok;
1109
1104 enum cfg80211_signal_type signal_type; 1110 enum cfg80211_signal_type signal_type;
1105 1111
1106 int bss_priv_size; 1112 int bss_priv_size;
@@ -1139,9 +1145,35 @@ struct wiphy {
1139 /* dir in debugfs: ieee80211/<wiphyname> */ 1145 /* dir in debugfs: ieee80211/<wiphyname> */
1140 struct dentry *debugfsdir; 1146 struct dentry *debugfsdir;
1141 1147
1148#ifdef CONFIG_NET_NS
1149 /* the network namespace this phy lives in currently */
1150 struct net *_net;
1151#endif
1152
1142 char priv[0] __attribute__((__aligned__(NETDEV_ALIGN))); 1153 char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
1143}; 1154};
1144 1155
1156#ifdef CONFIG_NET_NS
1157static inline struct net *wiphy_net(struct wiphy *wiphy)
1158{
1159 return wiphy->_net;
1160}
1161
1162static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net)
1163{
1164 wiphy->_net = net;
1165}
1166#else
1167static inline struct net *wiphy_net(struct wiphy *wiphy)
1168{
1169 return &init_net;
1170}
1171
1172static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net)
1173{
1174}
1175#endif
1176
1145/** 1177/**
1146 * wiphy_priv - return priv from wiphy 1178 * wiphy_priv - return priv from wiphy
1147 * 1179 *
@@ -1563,43 +1595,6 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
1563int cfg80211_wext_giwrange(struct net_device *dev, 1595int cfg80211_wext_giwrange(struct net_device *dev,
1564 struct iw_request_info *info, 1596 struct iw_request_info *info,
1565 struct iw_point *data, char *extra); 1597 struct iw_point *data, char *extra);
1566int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
1567 struct iw_request_info *info,
1568 struct iw_freq *freq, char *extra);
1569int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
1570 struct iw_request_info *info,
1571 struct iw_freq *freq, char *extra);
1572int cfg80211_ibss_wext_siwessid(struct net_device *dev,
1573 struct iw_request_info *info,
1574 struct iw_point *data, char *ssid);
1575int cfg80211_ibss_wext_giwessid(struct net_device *dev,
1576 struct iw_request_info *info,
1577 struct iw_point *data, char *ssid);
1578int cfg80211_ibss_wext_siwap(struct net_device *dev,
1579 struct iw_request_info *info,
1580 struct sockaddr *ap_addr, char *extra);
1581int cfg80211_ibss_wext_giwap(struct net_device *dev,
1582 struct iw_request_info *info,
1583 struct sockaddr *ap_addr, char *extra);
1584
1585int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
1586 struct iw_request_info *info,
1587 struct iw_freq *freq, char *extra);
1588int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
1589 struct iw_request_info *info,
1590 struct iw_freq *freq, char *extra);
1591int cfg80211_mgd_wext_siwessid(struct net_device *dev,
1592 struct iw_request_info *info,
1593 struct iw_point *data, char *ssid);
1594int cfg80211_mgd_wext_giwessid(struct net_device *dev,
1595 struct iw_request_info *info,
1596 struct iw_point *data, char *ssid);
1597int cfg80211_mgd_wext_siwap(struct net_device *dev,
1598 struct iw_request_info *info,
1599 struct sockaddr *ap_addr, char *extra);
1600int cfg80211_mgd_wext_giwap(struct net_device *dev,
1601 struct iw_request_info *info,
1602 struct sockaddr *ap_addr, char *extra);
1603int cfg80211_wext_siwgenie(struct net_device *dev, 1598int cfg80211_wext_siwgenie(struct net_device *dev,
1604 struct iw_request_info *info, 1599 struct iw_request_info *info,
1605 struct iw_point *data, char *extra); 1600 struct iw_point *data, char *extra);
@@ -1610,9 +1605,18 @@ int cfg80211_wext_giwauth(struct net_device *dev,
1610 struct iw_request_info *info, 1605 struct iw_request_info *info,
1611 struct iw_param *data, char *extra); 1606 struct iw_param *data, char *extra);
1612 1607
1613struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, 1608int cfg80211_wext_siwfreq(struct net_device *dev,
1614 struct iw_freq *freq); 1609 struct iw_request_info *info,
1615 1610 struct iw_freq *freq, char *extra);
1611int cfg80211_wext_giwfreq(struct net_device *dev,
1612 struct iw_request_info *info,
1613 struct iw_freq *freq, char *extra);
1614int cfg80211_wext_siwessid(struct net_device *dev,
1615 struct iw_request_info *info,
1616 struct iw_point *data, char *ssid);
1617int cfg80211_wext_giwessid(struct net_device *dev,
1618 struct iw_request_info *info,
1619 struct iw_point *data, char *ssid);
1616int cfg80211_wext_siwrate(struct net_device *dev, 1620int cfg80211_wext_siwrate(struct net_device *dev,
1617 struct iw_request_info *info, 1621 struct iw_request_info *info,
1618 struct iw_param *rate, char *extra); 1622 struct iw_param *rate, char *extra);
@@ -1662,12 +1666,12 @@ int cfg80211_wext_giwpower(struct net_device *dev,
1662 struct iw_request_info *info, 1666 struct iw_request_info *info,
1663 struct iw_param *wrq, char *extra); 1667 struct iw_param *wrq, char *extra);
1664 1668
1665int cfg80211_wds_wext_siwap(struct net_device *dev, 1669int cfg80211_wext_siwap(struct net_device *dev,
1666 struct iw_request_info *info, 1670 struct iw_request_info *info,
1667 struct sockaddr *addr, char *extra); 1671 struct sockaddr *ap_addr, char *extra);
1668int cfg80211_wds_wext_giwap(struct net_device *dev, 1672int cfg80211_wext_giwap(struct net_device *dev,
1669 struct iw_request_info *info, 1673 struct iw_request_info *info,
1670 struct sockaddr *addr, char *extra); 1674 struct sockaddr *ap_addr, char *extra);
1671 1675
1672/* 1676/*
1673 * callbacks for asynchronous cfg80211 methods, notification 1677 * callbacks for asynchronous cfg80211 methods, notification
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 7dd67a1ff4d5..d4e09a06b4a2 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -243,6 +243,9 @@ struct ieee80211_bss_conf {
243 * used to indicate that a frame was already retried due to PS 243 * used to indicate that a frame was already retried due to PS
244 * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211, 244 * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
245 * used to indicate frame should not be encrypted 245 * used to indicate frame should not be encrypted
246 * @IEEE80211_TX_CTL_PSPOLL_RESPONSE: (internal?)
247 * This frame is a response to a PS-poll frame and should be sent
248 * although the station is in powersave mode.
246 */ 249 */
247enum mac80211_tx_control_flags { 250enum mac80211_tx_control_flags {
248 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), 251 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -262,6 +265,7 @@ enum mac80211_tx_control_flags {
262 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), 265 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
263 IEEE80211_TX_INTFL_RETRIED = BIT(15), 266 IEEE80211_TX_INTFL_RETRIED = BIT(15),
264 IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), 267 IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
268 IEEE80211_TX_CTL_PSPOLL_RESPONSE = BIT(17),
265}; 269};
266 270
267/** 271/**
diff --git a/net/core/dev.c b/net/core/dev.c
index d6c657ee413d..71347668c506 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5344,6 +5344,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
5344out: 5344out:
5345 return err; 5345 return err;
5346} 5346}
5347EXPORT_SYMBOL_GPL(dev_change_net_namespace);
5347 5348
5348static int dev_cpu_callback(struct notifier_block *nfb, 5349static int dev_cpu_callback(struct notifier_block *nfb,
5349 unsigned long action, 5350 unsigned long action,
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 19a4c66e143e..7dd77b6d4c9a 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -6,7 +6,6 @@ config MAC80211
6 select CRYPTO_ARC4 6 select CRYPTO_ARC4
7 select CRYPTO_AES 7 select CRYPTO_AES
8 select CRC32 8 select CRC32
9 select WIRELESS_EXT
10 ---help--- 9 ---help---
11 This option enables the hardware independent IEEE 802.11 10 This option enables the hardware independent IEEE 802.11
12 networking stack. 11 networking stack.
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 91284a74ff91..9f3cf7129324 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -3,7 +3,6 @@ obj-$(CONFIG_MAC80211) += mac80211.o
3# mac80211 objects 3# mac80211 objects
4mac80211-y := \ 4mac80211-y := \
5 main.o \ 5 main.o \
6 wext.o \
7 sta_info.o \ 6 sta_info.o \
8 wep.o \ 7 wep.o \
9 wpa.o \ 8 wpa.o \
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 52928ad90570..4bbf5007799b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -57,19 +57,9 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
57 return 0; 57 return 0;
58} 58}
59 59
60static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) 60static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev)
61{ 61{
62 struct net_device *dev; 62 ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev));
63 struct ieee80211_sub_if_data *sdata;
64
65 /* we're under RTNL */
66 dev = __dev_get_by_index(&init_net, ifindex);
67 if (!dev)
68 return -ENODEV;
69
70 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
71
72 ieee80211_if_remove(sdata);
73 63
74 return 0; 64 return 0;
75} 65}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 8e2220000e5c..6e3cca65c460 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -742,7 +742,7 @@ static void ieee80211_ibss_work(struct work_struct *work)
742 if (!netif_running(sdata->dev)) 742 if (!netif_running(sdata->dev))
743 return; 743 return;
744 744
745 if (local->sw_scanning || local->hw_scanning) 745 if (local->scanning)
746 return; 746 return;
747 747
748 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC)) 748 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC))
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 6a0177137dd5..aec6853cb435 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -24,7 +24,6 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <net/cfg80211.h> 26#include <net/cfg80211.h>
27#include <net/iw_handler.h>
28#include <net/mac80211.h> 27#include <net/mac80211.h>
29#include "key.h" 28#include "key.h"
30#include "sta_info.h" 29#include "sta_info.h"
@@ -570,6 +569,43 @@ enum queue_stop_reason {
570 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 569 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
571}; 570};
572 571
572/**
573 * mac80211 scan flags - currently active scan mode
574 *
575 * @SCAN_SW_SCANNING: We're currently in the process of scanning but may as
576 * well be on the operating channel
577 * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to
578 * determine if we are on the operating channel or not
579 * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning,
580 * gets only set in conjunction with SCAN_SW_SCANNING
581 */
582enum {
583 SCAN_SW_SCANNING,
584 SCAN_HW_SCANNING,
585 SCAN_OFF_CHANNEL,
586};
587
588/**
589 * enum mac80211_scan_state - scan state machine states
590 *
591 * @SCAN_DECISION: Main entry point to the scan state machine, this state
592 * determines if we should keep on scanning or switch back to the
593 * operating channel
594 * @SCAN_SET_CHANNEL: Set the next channel to be scanned
595 * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses
596 * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP
597 * about us leaving the channel and stop all associated STA interfaces
598 * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the
599 * AP about us being back and restart all associated STA interfaces
600 */
601enum mac80211_scan_state {
602 SCAN_DECISION,
603 SCAN_SET_CHANNEL,
604 SCAN_SEND_PROBE,
605 SCAN_LEAVE_OPER_CHANNEL,
606 SCAN_ENTER_OPER_CHANNEL,
607};
608
573struct ieee80211_local { 609struct ieee80211_local {
574 /* embed the driver visible part. 610 /* embed the driver visible part.
575 * don't cast (use the static inlines below), but we keep 611 * don't cast (use the static inlines below), but we keep
@@ -668,7 +704,7 @@ struct ieee80211_local {
668 704
669 /* Scanning and BSS list */ 705 /* Scanning and BSS list */
670 struct mutex scan_mtx; 706 struct mutex scan_mtx;
671 bool sw_scanning, hw_scanning; 707 unsigned long scanning;
672 struct cfg80211_ssid scan_ssid; 708 struct cfg80211_ssid scan_ssid;
673 struct cfg80211_scan_request int_scan_req; 709 struct cfg80211_scan_request int_scan_req;
674 struct cfg80211_scan_request *scan_req; 710 struct cfg80211_scan_request *scan_req;
@@ -678,7 +714,7 @@ struct ieee80211_local {
678 int scan_channel_idx; 714 int scan_channel_idx;
679 int scan_ies_len; 715 int scan_ies_len;
680 716
681 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; 717 enum mac80211_scan_state next_scan_state;
682 struct delayed_work scan_work; 718 struct delayed_work scan_work;
683 struct ieee80211_sub_if_data *scan_sdata; 719 struct ieee80211_sub_if_data *scan_sdata;
684 enum nl80211_channel_type oper_channel_type; 720 enum nl80211_channel_type oper_channel_type;
@@ -914,9 +950,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
914void ieee80211_configure_filter(struct ieee80211_local *local); 950void ieee80211_configure_filter(struct ieee80211_local *local);
915u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); 951u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
916 952
917/* wireless extensions */
918extern const struct iw_handler_def ieee80211_iw_handler_def;
919
920/* STA code */ 953/* STA code */
921void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); 954void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
922int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, 955int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 2f797a86ced5..6c655b6547fb 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -335,7 +335,10 @@ static int ieee80211_stop(struct net_device *dev)
335 struct ieee80211_local *local = sdata->local; 335 struct ieee80211_local *local = sdata->local;
336 struct ieee80211_if_init_conf conf; 336 struct ieee80211_if_init_conf conf;
337 struct sta_info *sta; 337 struct sta_info *sta;
338 unsigned long flags;
339 struct sk_buff *skb, *tmp;
338 u32 hw_reconf_flags = 0; 340 u32 hw_reconf_flags = 0;
341 int i;
339 342
340 /* 343 /*
341 * Stop TX on this interface first. 344 * Stop TX on this interface first.
@@ -515,7 +518,7 @@ static int ieee80211_stop(struct net_device *dev)
515 * the scan_sdata is NULL already don't send out a 518 * the scan_sdata is NULL already don't send out a
516 * scan event to userspace -- the scan is incomplete. 519 * scan event to userspace -- the scan is incomplete.
517 */ 520 */
518 if (local->sw_scanning) 521 if (test_bit(SCAN_SW_SCANNING, &local->scanning))
519 ieee80211_scan_completed(&local->hw, true); 522 ieee80211_scan_completed(&local->hw, true);
520 } 523 }
521 524
@@ -551,6 +554,18 @@ static int ieee80211_stop(struct net_device *dev)
551 if (hw_reconf_flags) 554 if (hw_reconf_flags)
552 ieee80211_hw_config(local, hw_reconf_flags); 555 ieee80211_hw_config(local, hw_reconf_flags);
553 556
557 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
558 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
559 skb_queue_walk_safe(&local->pending[i], skb, tmp) {
560 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
561 if (info->control.vif == &sdata->vif) {
562 __skb_unlink(skb, &local->pending[i]);
563 dev_kfree_skb_irq(skb);
564 }
565 }
566 }
567 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
568
554 return 0; 569 return 0;
555} 570}
556 571
@@ -669,7 +684,6 @@ static void ieee80211_if_setup(struct net_device *dev)
669{ 684{
670 ether_setup(dev); 685 ether_setup(dev);
671 dev->netdev_ops = &ieee80211_dataif_ops; 686 dev->netdev_ops = &ieee80211_dataif_ops;
672 dev->wireless_handlers = &ieee80211_iw_handler_def;
673 dev->destructor = free_netdev; 687 dev->destructor = free_netdev;
674} 688}
675 689
@@ -772,6 +786,7 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
772 name, ieee80211_if_setup); 786 name, ieee80211_if_setup);
773 if (!ndev) 787 if (!ndev)
774 return -ENOMEM; 788 return -ENOMEM;
789 dev_net_set(ndev, wiphy_net(local->hw.wiphy));
775 790
776 ndev->needed_headroom = local->tx_headroom + 791 ndev->needed_headroom = local->tx_headroom +
777 4*6 /* four MAC addresses */ 792 4*6 /* four MAC addresses */
@@ -788,7 +803,6 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
788 803
789 memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN); 804 memcpy(ndev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
790 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy)); 805 SET_NETDEV_DEV(ndev, wiphy_dev(local->hw.wiphy));
791 ndev->features |= NETIF_F_NETNS_LOCAL;
792 806
793 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */ 807 /* don't use IEEE80211_DEV_TO_SUB_IF because it checks too much */
794 sdata = netdev_priv(ndev); 808 sdata = netdev_priv(ndev);
@@ -905,7 +919,7 @@ u32 __ieee80211_recalc_idle(struct ieee80211_local *local)
905 struct ieee80211_sub_if_data *sdata; 919 struct ieee80211_sub_if_data *sdata;
906 int count = 0; 920 int count = 0;
907 921
908 if (local->hw_scanning || local->sw_scanning) 922 if (local->scanning)
909 return ieee80211_idle_off(local, "scanning"); 923 return ieee80211_idle_off(local, "scanning");
910 924
911 list_for_each_entry(sdata, &local->interfaces, list) { 925 list_for_each_entry(sdata, &local->interfaces, list) {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 3234f3751d22..c1a799194fff 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -198,7 +198,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
198 } 198 }
199 199
200 if (changed & BSS_CHANGED_BEACON_ENABLED) { 200 if (changed & BSS_CHANGED_BEACON_ENABLED) {
201 if (local->sw_scanning) { 201 if (test_bit(SCAN_SW_SCANNING, &local->scanning)) {
202 sdata->vif.bss_conf.enable_beacon = false; 202 sdata->vif.bss_conf.enable_beacon = false;
203 } else { 203 } else {
204 /* 204 /*
@@ -620,6 +620,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
620 if (!wiphy) 620 if (!wiphy)
621 return NULL; 621 return NULL;
622 622
623 wiphy->netnsok = true;
623 wiphy->privid = mac80211_wiphy_privid; 624 wiphy->privid = mac80211_wiphy_privid;
624 625
625 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ 626 /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 8a97b1423088..9a3826978b1c 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -597,7 +597,7 @@ static void ieee80211_mesh_work(struct work_struct *work)
597 if (!netif_running(sdata->dev)) 597 if (!netif_running(sdata->dev))
598 return; 598 return;
599 599
600 if (local->sw_scanning || local->hw_scanning) 600 if (local->scanning)
601 return; 601 return;
602 602
603 while ((skb = skb_dequeue(&ifmsh->skb_queue))) 603 while ((skb = skb_dequeue(&ifmsh->skb_queue)))
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 0b3551da8f43..ee83125ed179 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -581,7 +581,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
581 if (!ifmgd->associated) 581 if (!ifmgd->associated)
582 return; 582 return;
583 583
584 if (sdata->local->sw_scanning || sdata->local->hw_scanning) 584 if (sdata->local->scanning)
585 return; 585 return;
586 586
587 /* Disregard subsequent beacons if we are already running a timer 587 /* Disregard subsequent beacons if we are already running a timer
@@ -639,7 +639,7 @@ static void ieee80211_enable_ps(struct ieee80211_local *local,
639 * If we are scanning right now then the parameters will 639 * If we are scanning right now then the parameters will
640 * take effect when scan finishes. 640 * take effect when scan finishes.
641 */ 641 */
642 if (local->hw_scanning || local->sw_scanning) 642 if (local->scanning)
643 return; 643 return;
644 644
645 if (conf->dynamic_ps_timeout > 0 && 645 if (conf->dynamic_ps_timeout > 0 &&
@@ -1166,6 +1166,9 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1166 if (!netif_running(sdata->dev)) 1166 if (!netif_running(sdata->dev))
1167 return; 1167 return;
1168 1168
1169 if (sdata->local->scanning)
1170 return;
1171
1169 mutex_lock(&ifmgd->mtx); 1172 mutex_lock(&ifmgd->mtx);
1170 1173
1171 if (!ifmgd->associated) 1174 if (!ifmgd->associated)
@@ -2000,6 +2003,9 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
2000 case RX_MGMT_CFG80211_ASSOC: 2003 case RX_MGMT_CFG80211_ASSOC:
2001 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len); 2004 cfg80211_send_rx_assoc(sdata->dev, (u8 *) mgmt, skb->len);
2002 break; 2005 break;
2006 case RX_MGMT_CFG80211_DEAUTH:
2007 cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len, NULL);
2008 break;
2003 default: 2009 default:
2004 WARN(1, "unexpected: %d", rma); 2010 WARN(1, "unexpected: %d", rma);
2005 } 2011 }
@@ -2038,7 +2044,7 @@ static void ieee80211_sta_work(struct work_struct *work)
2038 if (!netif_running(sdata->dev)) 2044 if (!netif_running(sdata->dev))
2039 return; 2045 return;
2040 2046
2041 if (local->sw_scanning || local->hw_scanning) 2047 if (local->scanning)
2042 return; 2048 return;
2043 2049
2044 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) 2050 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
@@ -2213,9 +2219,6 @@ static void ieee80211_sta_monitor_work(struct work_struct *work)
2213 container_of(work, struct ieee80211_sub_if_data, 2219 container_of(work, struct ieee80211_sub_if_data,
2214 u.mgd.monitor_work); 2220 u.mgd.monitor_work);
2215 2221
2216 if (sdata->local->sw_scanning || sdata->local->hw_scanning)
2217 return;
2218
2219 ieee80211_mgd_probe_ap(sdata, false); 2222 ieee80211_mgd_probe_ap(sdata, false);
2220} 2223}
2221 2224
@@ -2377,6 +2380,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2377 2380
2378 wk->state = IEEE80211_MGD_STATE_PROBE; 2381 wk->state = IEEE80211_MGD_STATE_PROBE;
2379 wk->auth_alg = auth_alg; 2382 wk->auth_alg = auth_alg;
2383 wk->timeout = jiffies; /* run right away */
2380 2384
2381 /* 2385 /*
2382 * XXX: if still associated need to tell AP that we're going 2386 * XXX: if still associated need to tell AP that we're going
@@ -2448,6 +2452,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2448 2452
2449 wk->state = IEEE80211_MGD_STATE_ASSOC; 2453 wk->state = IEEE80211_MGD_STATE_ASSOC;
2450 wk->tries = 0; 2454 wk->tries = 0;
2455 wk->timeout = jiffies; /* run right away */
2451 2456
2452 if (req->use_mfp) { 2457 if (req->use_mfp) {
2453 ifmgd->mfp = IEEE80211_MFP_REQUIRED; 2458 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2496,8 +2501,13 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2496 } 2501 }
2497 } 2502 }
2498 2503
2499 /* cfg80211 should catch this... */ 2504 /*
2500 if (WARN_ON(!bssid)) { 2505 * cfg80211 should catch this ... but it's racy since
2506 * we can receive a deauth frame, process it, hand it
2507 * to cfg80211 while that's in a locked section already
2508 * trying to tell us that the user wants to disconnect.
2509 */
2510 if (!bssid) {
2501 mutex_unlock(&ifmgd->mtx); 2511 mutex_unlock(&ifmgd->mtx);
2502 return -ENOLINK; 2512 return -ENOLINK;
2503 } 2513 }
@@ -2522,8 +2532,13 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2522 2532
2523 mutex_lock(&ifmgd->mtx); 2533 mutex_lock(&ifmgd->mtx);
2524 2534
2525 /* cfg80211 should catch that */ 2535 /*
2526 if (WARN_ON(&ifmgd->associated->cbss != req->bss)) { 2536 * cfg80211 should catch this ... but it's racy since
2537 * we can receive a disassoc frame, process it, hand it
2538 * to cfg80211 while that's in a locked section already
2539 * trying to tell us that the user wants to disconnect.
2540 */
2541 if (&ifmgd->associated->cbss != req->bss) {
2527 mutex_unlock(&ifmgd->mtx); 2542 mutex_unlock(&ifmgd->mtx);
2528 return -ENOLINK; 2543 return -ENOLINK;
2529 } 2544 }
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index b6ddde3848fb..25a669c86e14 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -418,10 +418,11 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
418 struct ieee80211_local *local = rx->local; 418 struct ieee80211_local *local = rx->local;
419 struct sk_buff *skb = rx->skb; 419 struct sk_buff *skb = rx->skb;
420 420
421 if (unlikely(local->hw_scanning)) 421 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning)))
422 return ieee80211_scan_rx(rx->sdata, skb); 422 return ieee80211_scan_rx(rx->sdata, skb);
423 423
424 if (unlikely(local->sw_scanning)) { 424 if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning) &&
425 (rx->flags & IEEE80211_RX_IN_SCAN))) {
425 /* drop all the other packets during a software scan anyway */ 426 /* drop all the other packets during a software scan anyway */
426 if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED) 427 if (ieee80211_scan_rx(rx->sdata, skb) != RX_QUEUED)
427 dev_kfree_skb(skb); 428 dev_kfree_skb(skb);
@@ -782,7 +783,7 @@ static void ap_sta_ps_start(struct sta_info *sta)
782 struct ieee80211_local *local = sdata->local; 783 struct ieee80211_local *local = sdata->local;
783 784
784 atomic_inc(&sdata->bss->num_sta_ps); 785 atomic_inc(&sdata->bss->num_sta_ps);
785 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); 786 set_sta_flags(sta, WLAN_STA_PS);
786 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); 787 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta);
787#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 788#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
788 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", 789 printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n",
@@ -798,7 +799,7 @@ static int ap_sta_ps_end(struct sta_info *sta)
798 799
799 atomic_dec(&sdata->bss->num_sta_ps); 800 atomic_dec(&sdata->bss->num_sta_ps);
800 801
801 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); 802 clear_sta_flags(sta, WLAN_STA_PS);
802 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta); 803 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta);
803 804
804 if (!skb_queue_empty(&sta->ps_tx_buf)) 805 if (!skb_queue_empty(&sta->ps_tx_buf))
@@ -1116,14 +1117,15 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1116 skb_queue_empty(&rx->sta->ps_tx_buf); 1117 skb_queue_empty(&rx->sta->ps_tx_buf);
1117 1118
1118 if (skb) { 1119 if (skb) {
1120 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1119 struct ieee80211_hdr *hdr = 1121 struct ieee80211_hdr *hdr =
1120 (struct ieee80211_hdr *) skb->data; 1122 (struct ieee80211_hdr *) skb->data;
1121 1123
1122 /* 1124 /*
1123 * Tell TX path to send one frame even though the STA may 1125 * Tell TX path to send this frame even though the STA may
1124 * still remain is PS mode after this frame exchange. 1126 * still remain is PS mode after this frame exchange.
1125 */ 1127 */
1126 set_sta_flags(rx->sta, WLAN_STA_PSPOLL); 1128 info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE;
1127 1129
1128#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1130#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1129 printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", 1131 printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n",
@@ -1138,7 +1140,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1138 else 1140 else
1139 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 1141 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
1140 1142
1141 dev_queue_xmit(skb); 1143 ieee80211_add_pending_skb(rx->local, skb);
1142 1144
1143 if (no_pending_pkts) 1145 if (no_pending_pkts)
1144 sta_info_clear_tim_bit(rx->sta); 1146 sta_info_clear_tim_bit(rx->sta);
@@ -1539,7 +1541,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1539 info = IEEE80211_SKB_CB(fwd_skb); 1541 info = IEEE80211_SKB_CB(fwd_skb);
1540 memset(info, 0, sizeof(*info)); 1542 memset(info, 0, sizeof(*info));
1541 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1543 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1542 fwd_skb->iif = rx->dev->ifindex; 1544 info->control.vif = &rx->sdata->vif;
1543 ieee80211_select_queue(local, fwd_skb); 1545 ieee80211_select_queue(local, fwd_skb);
1544 if (is_multicast_ether_addr(fwd_hdr->addr3)) 1546 if (is_multicast_ether_addr(fwd_hdr->addr3))
1545 memcpy(fwd_hdr->addr1, fwd_hdr->addr3, 1547 memcpy(fwd_hdr->addr1, fwd_hdr->addr3,
@@ -2136,7 +2138,8 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2136 return; 2138 return;
2137 } 2139 }
2138 2140
2139 if (unlikely(local->sw_scanning || local->hw_scanning)) 2141 if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
2142 test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
2140 rx.flags |= IEEE80211_RX_IN_SCAN; 2143 rx.flags |= IEEE80211_RX_IN_SCAN;
2141 2144
2142 ieee80211_parse_qos(&rx); 2145 ieee80211_parse_qos(&rx);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 74820656dc89..45731000eb8d 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -18,7 +18,6 @@
18#include <linux/if_arp.h> 18#include <linux/if_arp.h>
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <net/mac80211.h> 20#include <net/mac80211.h>
21#include <net/iw_handler.h>
22 21
23#include "ieee80211_i.h" 22#include "ieee80211_i.h"
24#include "driver-ops.h" 23#include "driver-ops.h"
@@ -265,7 +264,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
265 264
266 mutex_lock(&local->scan_mtx); 265 mutex_lock(&local->scan_mtx);
267 266
268 if (WARN_ON(!local->hw_scanning && !local->sw_scanning)) { 267 if (WARN_ON(!local->scanning)) {
269 mutex_unlock(&local->scan_mtx); 268 mutex_unlock(&local->scan_mtx);
270 return; 269 return;
271 } 270 }
@@ -275,16 +274,15 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
275 return; 274 return;
276 } 275 }
277 276
278 if (local->hw_scanning) 277 if (test_bit(SCAN_HW_SCANNING, &local->scanning))
279 ieee80211_restore_scan_ies(local); 278 ieee80211_restore_scan_ies(local);
280 279
281 if (local->scan_req != &local->int_scan_req) 280 if (local->scan_req != &local->int_scan_req)
282 cfg80211_scan_done(local->scan_req, aborted); 281 cfg80211_scan_done(local->scan_req, aborted);
283 local->scan_req = NULL; 282 local->scan_req = NULL;
284 283
285 was_hw_scan = local->hw_scanning; 284 was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning);
286 local->hw_scanning = false; 285 local->scanning = 0;
287 local->sw_scanning = false;
288 local->scan_channel = NULL; 286 local->scan_channel = NULL;
289 287
290 /* we only have to protect scan_req and hw/sw scan */ 288 /* we only have to protect scan_req and hw/sw scan */
@@ -366,17 +364,16 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
366 ieee80211_bss_info_change_notify( 364 ieee80211_bss_info_change_notify(
367 sdata, BSS_CHANGED_BEACON_ENABLED); 365 sdata, BSS_CHANGED_BEACON_ENABLED);
368 366
369 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 367 /*
370 if (sdata->u.mgd.associated) { 368 * only handle non-STA interfaces here, STA interfaces
371 netif_tx_stop_all_queues(sdata->dev); 369 * are handled in the scan state machine
372 ieee80211_scan_ps_enable(sdata); 370 */
373 } 371 if (sdata->vif.type != NL80211_IFTYPE_STATION)
374 } else
375 netif_tx_stop_all_queues(sdata->dev); 372 netif_tx_stop_all_queues(sdata->dev);
376 } 373 }
377 mutex_unlock(&local->iflist_mtx); 374 mutex_unlock(&local->iflist_mtx);
378 375
379 local->scan_state = SCAN_SET_CHANNEL; 376 local->next_scan_state = SCAN_DECISION;
380 local->scan_channel_idx = 0; 377 local->scan_channel_idx = 0;
381 378
382 spin_lock_bh(&local->filter_lock); 379 spin_lock_bh(&local->filter_lock);
@@ -434,9 +431,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
434 } 431 }
435 432
436 if (local->ops->hw_scan) 433 if (local->ops->hw_scan)
437 local->hw_scanning = true; 434 __set_bit(SCAN_HW_SCANNING, &local->scanning);
438 else 435 else
439 local->sw_scanning = true; 436 __set_bit(SCAN_SW_SCANNING, &local->scanning);
440 /* 437 /*
441 * Kicking off the scan need not be protected, 438 * Kicking off the scan need not be protected,
442 * only the scan variable stuff, since now 439 * only the scan variable stuff, since now
@@ -459,11 +456,9 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
459 mutex_lock(&local->scan_mtx); 456 mutex_lock(&local->scan_mtx);
460 457
461 if (rc) { 458 if (rc) {
462 if (local->ops->hw_scan) { 459 if (local->ops->hw_scan)
463 local->hw_scanning = false;
464 ieee80211_restore_scan_ies(local); 460 ieee80211_restore_scan_ies(local);
465 } else 461 local->scanning = 0;
466 local->sw_scanning = false;
467 462
468 ieee80211_recalc_idle(local); 463 ieee80211_recalc_idle(local);
469 464
@@ -474,13 +469,195 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
474 return rc; 469 return rc;
475} 470}
476 471
472static int ieee80211_scan_state_decision(struct ieee80211_local *local,
473 unsigned long *next_delay)
474{
475 bool associated = false;
476 struct ieee80211_sub_if_data *sdata;
477
478 /* if no more bands/channels left, complete scan and advance to the idle state */
479 if (local->scan_channel_idx >= local->scan_req->n_channels) {
480 ieee80211_scan_completed(&local->hw, false);
481 return 1;
482 }
483
484 /* check if at least one STA interface is associated */
485 mutex_lock(&local->iflist_mtx);
486 list_for_each_entry(sdata, &local->interfaces, list) {
487 if (!netif_running(sdata->dev))
488 continue;
489
490 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
491 if (sdata->u.mgd.associated) {
492 associated = true;
493 break;
494 }
495 }
496 }
497 mutex_unlock(&local->iflist_mtx);
498
499 if (local->scan_channel) {
500 /*
501 * we're currently scanning a different channel, let's
502 * switch back to the operating channel now if at least
503 * one interface is associated. Otherwise just scan the
504 * next channel
505 */
506 if (associated)
507 local->next_scan_state = SCAN_ENTER_OPER_CHANNEL;
508 else
509 local->next_scan_state = SCAN_SET_CHANNEL;
510 } else {
511 /*
512 * we're on the operating channel currently, let's
513 * leave that channel now to scan another one
514 */
515 local->next_scan_state = SCAN_LEAVE_OPER_CHANNEL;
516 }
517
518 *next_delay = 0;
519 return 0;
520}
521
522static void ieee80211_scan_state_leave_oper_channel(struct ieee80211_local *local,
523 unsigned long *next_delay)
524{
525 struct ieee80211_sub_if_data *sdata;
526
527 /*
528 * notify the AP about us leaving the channel and stop all STA interfaces
529 */
530 mutex_lock(&local->iflist_mtx);
531 list_for_each_entry(sdata, &local->interfaces, list) {
532 if (!netif_running(sdata->dev))
533 continue;
534
535 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
536 netif_tx_stop_all_queues(sdata->dev);
537 if (sdata->u.mgd.associated)
538 ieee80211_scan_ps_enable(sdata);
539 }
540 }
541 mutex_unlock(&local->iflist_mtx);
542
543 __set_bit(SCAN_OFF_CHANNEL, &local->scanning);
544
545 /* advance to the next channel to be scanned */
546 *next_delay = HZ / 10;
547 local->next_scan_state = SCAN_SET_CHANNEL;
548}
549
550static void ieee80211_scan_state_enter_oper_channel(struct ieee80211_local *local,
551 unsigned long *next_delay)
552{
553 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
554
555 /* switch back to the operating channel */
556 local->scan_channel = NULL;
557 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
558
559 /*
560 * notify the AP about us being back and restart all STA interfaces
561 */
562 mutex_lock(&local->iflist_mtx);
563 list_for_each_entry(sdata, &local->interfaces, list) {
564 if (!netif_running(sdata->dev))
565 continue;
566
567 /* Tell AP we're back */
568 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
569 if (sdata->u.mgd.associated)
570 ieee80211_scan_ps_disable(sdata);
571 netif_tx_wake_all_queues(sdata->dev);
572 }
573 }
574 mutex_unlock(&local->iflist_mtx);
575
576 __clear_bit(SCAN_OFF_CHANNEL, &local->scanning);
577
578 *next_delay = HZ / 5;
579 local->next_scan_state = SCAN_DECISION;
580}
581
582static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
583 unsigned long *next_delay)
584{
585 int skip;
586 struct ieee80211_channel *chan;
587 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
588
589 skip = 0;
590 chan = local->scan_req->channels[local->scan_channel_idx];
591
592 if (chan->flags & IEEE80211_CHAN_DISABLED ||
593 (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
594 chan->flags & IEEE80211_CHAN_NO_IBSS))
595 skip = 1;
596
597 if (!skip) {
598 local->scan_channel = chan;
599 if (ieee80211_hw_config(local,
600 IEEE80211_CONF_CHANGE_CHANNEL))
601 skip = 1;
602 }
603
604 /* advance state machine to next channel/band */
605 local->scan_channel_idx++;
606
607 if (skip) {
608 /* if we skip this channel return to the decision state */
609 local->next_scan_state = SCAN_DECISION;
610 return;
611 }
612
613 /*
614 * Probe delay is used to update the NAV, cf. 11.1.3.2.2
615 * (which unfortunately doesn't say _why_ step a) is done,
616 * but it waits for the probe delay or until a frame is
617 * received - and the received frame would update the NAV).
618 * For now, we do not support waiting until a frame is
619 * received.
620 *
621 * In any case, it is not necessary for a passive scan.
622 */
623 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
624 !local->scan_req->n_ssids) {
625 *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
626 local->next_scan_state = SCAN_DECISION;
627 return;
628 }
629
630 /* active scan, send probes */
631 *next_delay = IEEE80211_PROBE_DELAY;
632 local->next_scan_state = SCAN_SEND_PROBE;
633}
634
635static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
636 unsigned long *next_delay)
637{
638 int i;
639 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
640
641 for (i = 0; i < local->scan_req->n_ssids; i++)
642 ieee80211_send_probe_req(
643 sdata, NULL,
644 local->scan_req->ssids[i].ssid,
645 local->scan_req->ssids[i].ssid_len,
646 local->scan_req->ie, local->scan_req->ie_len);
647
648 /*
649 * After sending probe requests, wait for probe responses
650 * on the channel.
651 */
652 *next_delay = IEEE80211_CHANNEL_TIME;
653 local->next_scan_state = SCAN_DECISION;
654}
655
477void ieee80211_scan_work(struct work_struct *work) 656void ieee80211_scan_work(struct work_struct *work)
478{ 657{
479 struct ieee80211_local *local = 658 struct ieee80211_local *local =
480 container_of(work, struct ieee80211_local, scan_work.work); 659 container_of(work, struct ieee80211_local, scan_work.work);
481 struct ieee80211_sub_if_data *sdata = local->scan_sdata; 660 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
482 struct ieee80211_channel *chan;
483 int skip, i;
484 unsigned long next_delay = 0; 661 unsigned long next_delay = 0;
485 662
486 mutex_lock(&local->scan_mtx); 663 mutex_lock(&local->scan_mtx);
@@ -489,7 +666,7 @@ void ieee80211_scan_work(struct work_struct *work)
489 return; 666 return;
490 } 667 }
491 668
492 if (local->scan_req && !(local->sw_scanning || local->hw_scanning)) { 669 if (local->scan_req && !local->scanning) {
493 struct cfg80211_scan_request *req = local->scan_req; 670 struct cfg80211_scan_request *req = local->scan_req;
494 int rc; 671 int rc;
495 672
@@ -513,69 +690,30 @@ void ieee80211_scan_work(struct work_struct *work)
513 return; 690 return;
514 } 691 }
515 692
516 switch (local->scan_state) { 693 /*
517 case SCAN_SET_CHANNEL: 694 * as long as no delay is required advance immediately
518 /* if no more bands/channels left, complete scan */ 695 * without scheduling a new work
519 if (local->scan_channel_idx >= local->scan_req->n_channels) { 696 */
520 ieee80211_scan_completed(&local->hw, false); 697 do {
521 return; 698 switch (local->next_scan_state) {
522 } 699 case SCAN_DECISION:
523 skip = 0; 700 if (ieee80211_scan_state_decision(local, &next_delay))
524 chan = local->scan_req->channels[local->scan_channel_idx]; 701 return;
525
526 if (chan->flags & IEEE80211_CHAN_DISABLED ||
527 (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
528 chan->flags & IEEE80211_CHAN_NO_IBSS))
529 skip = 1;
530
531 if (!skip) {
532 local->scan_channel = chan;
533 if (ieee80211_hw_config(local,
534 IEEE80211_CONF_CHANGE_CHANNEL))
535 skip = 1;
536 }
537
538 /* advance state machine to next channel/band */
539 local->scan_channel_idx++;
540
541 if (skip)
542 break; 702 break;
543 703 case SCAN_SET_CHANNEL:
544 /* 704 ieee80211_scan_state_set_channel(local, &next_delay);
545 * Probe delay is used to update the NAV, cf. 11.1.3.2.2 705 break;
546 * (which unfortunately doesn't say _why_ step a) is done, 706 case SCAN_SEND_PROBE:
547 * but it waits for the probe delay or until a frame is 707 ieee80211_scan_state_send_probe(local, &next_delay);
548 * received - and the received frame would update the NAV). 708 break;
549 * For now, we do not support waiting until a frame is 709 case SCAN_LEAVE_OPER_CHANNEL:
550 * received. 710 ieee80211_scan_state_leave_oper_channel(local, &next_delay);
551 * 711 break;
552 * In any case, it is not necessary for a passive scan. 712 case SCAN_ENTER_OPER_CHANNEL:
553 */ 713 ieee80211_scan_state_enter_oper_channel(local, &next_delay);
554 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN ||
555 !local->scan_req->n_ssids) {
556 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
557 break; 714 break;
558 } 715 }
559 716 } while (next_delay == 0);
560 next_delay = IEEE80211_PROBE_DELAY;
561 local->scan_state = SCAN_SEND_PROBE;
562 break;
563 case SCAN_SEND_PROBE:
564 for (i = 0; i < local->scan_req->n_ssids; i++)
565 ieee80211_send_probe_req(
566 sdata, NULL,
567 local->scan_req->ssids[i].ssid,
568 local->scan_req->ssids[i].ssid_len,
569 local->scan_req->ie, local->scan_req->ie_len);
570
571 /*
572 * After sending probe requests, wait for probe responses
573 * on the channel.
574 */
575 next_delay = IEEE80211_CHANNEL_TIME;
576 local->scan_state = SCAN_SET_CHANNEL;
577 break;
578 }
579 717
580 queue_delayed_work(local->hw.workqueue, &local->scan_work, 718 queue_delayed_work(local->hw.workqueue, &local->scan_work,
581 next_delay); 719 next_delay);
@@ -625,7 +763,7 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
625 * queued -- mostly at suspend under RTNL. 763 * queued -- mostly at suspend under RTNL.
626 */ 764 */
627 mutex_lock(&local->scan_mtx); 765 mutex_lock(&local->scan_mtx);
628 swscan = local->sw_scanning; 766 swscan = test_bit(SCAN_SW_SCANNING, &local->scanning);
629 mutex_unlock(&local->scan_mtx); 767 mutex_unlock(&local->scan_mtx);
630 768
631 if (swscan) 769 if (swscan)
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 4ecf10a9bd00..ccc3adf962c7 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -30,7 +30,6 @@
30 * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP. 30 * @WLAN_STA_ASSOC_AP: We're associated to that station, it is an AP.
31 * @WLAN_STA_WME: Station is a QoS-STA. 31 * @WLAN_STA_WME: Station is a QoS-STA.
32 * @WLAN_STA_WDS: Station is one of our WDS peers. 32 * @WLAN_STA_WDS: Station is one of our WDS peers.
33 * @WLAN_STA_PSPOLL: Station has just PS-polled us.
34 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the 33 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
35 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next 34 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
36 * frame to this station is transmitted. 35 * frame to this station is transmitted.
@@ -47,7 +46,6 @@ enum ieee80211_sta_info_flags {
47 WLAN_STA_ASSOC_AP = 1<<5, 46 WLAN_STA_ASSOC_AP = 1<<5,
48 WLAN_STA_WME = 1<<6, 47 WLAN_STA_WME = 1<<6,
49 WLAN_STA_WDS = 1<<7, 48 WLAN_STA_WDS = 1<<7,
50 WLAN_STA_PSPOLL = 1<<8,
51 WLAN_STA_CLEAR_PS_FILT = 1<<9, 49 WLAN_STA_CLEAR_PS_FILT = 1<<9,
52 WLAN_STA_MFP = 1<<10, 50 WLAN_STA_MFP = 1<<10,
53 WLAN_STA_SUSPEND = 1<<11 51 WLAN_STA_SUSPEND = 1<<11
@@ -359,17 +357,6 @@ static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
359 spin_unlock_irqrestore(&sta->flaglock, irqfl); 357 spin_unlock_irqrestore(&sta->flaglock, irqfl);
360} 358}
361 359
362static inline void set_and_clear_sta_flags(struct sta_info *sta,
363 const u32 set, const u32 clear)
364{
365 unsigned long irqfl;
366
367 spin_lock_irqsave(&sta->flaglock, irqfl);
368 sta->flags |= set;
369 sta->flags &= ~clear;
370 spin_unlock_irqrestore(&sta->flaglock, irqfl);
371}
372
373static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) 360static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
374{ 361{
375 u32 ret; 362 u32 ret;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 2572509d5568..4e1b2ba122cd 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -192,7 +192,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
192 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) 192 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
193 return TX_CONTINUE; 193 return TX_CONTINUE;
194 194
195 if (unlikely(tx->local->sw_scanning) && 195 if (unlikely(test_bit(SCAN_OFF_CHANNEL, &tx->local->scanning)) &&
196 !ieee80211_is_probe_req(hdr->frame_control) && 196 !ieee80211_is_probe_req(hdr->frame_control) &&
197 !ieee80211_is_nullfunc(hdr->frame_control)) 197 !ieee80211_is_nullfunc(hdr->frame_control))
198 /* 198 /*
@@ -373,7 +373,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
373 staflags = get_sta_flags(sta); 373 staflags = get_sta_flags(sta);
374 374
375 if (unlikely((staflags & WLAN_STA_PS) && 375 if (unlikely((staflags & WLAN_STA_PS) &&
376 !(staflags & WLAN_STA_PSPOLL))) { 376 !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) {
377#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 377#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
378 printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " 378 printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries "
379 "before %d)\n", 379 "before %d)\n",
@@ -400,6 +400,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
400 sta_info_set_tim_bit(sta); 400 sta_info_set_tim_bit(sta);
401 401
402 info->control.jiffies = jiffies; 402 info->control.jiffies = jiffies;
403 info->control.vif = &tx->sdata->vif;
403 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 404 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
404 skb_queue_tail(&sta->ps_tx_buf, tx->skb); 405 skb_queue_tail(&sta->ps_tx_buf, tx->skb);
405 return TX_QUEUED; 406 return TX_QUEUED;
@@ -411,24 +412,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
411 sta->sta.addr); 412 sta->sta.addr);
412 } 413 }
413#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 414#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
414 if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) {
415 /*
416 * The sleeping station with pending data is now snoozing.
417 * It queried us for its buffered frames and will go back
418 * to deep sleep once it got everything.
419 *
420 * inform the driver, in case the hardware does powersave
421 * frame filtering and keeps a station blacklist on its own
422 * (e.g: p54), so that frames can be delivered unimpeded.
423 *
424 * Note: It should be safe to disable the filter now.
425 * As, it is really unlikely that we still have any pending
426 * frame for this station in the hw's buffers/fifos left,
427 * that is not rejected with a unsuccessful tx_status yet.
428 */
429 415
430 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
431 }
432 return TX_CONTINUE; 416 return TX_CONTINUE;
433} 417}
434 418
@@ -551,7 +535,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
551 * Lets not bother rate control if we're associated and cannot 535 * Lets not bother rate control if we're associated and cannot
552 * talk to the sta. This should not happen. 536 * talk to the sta. This should not happen.
553 */ 537 */
554 if (WARN((tx->local->sw_scanning) && 538 if (WARN(test_bit(SCAN_SW_SCANNING, &tx->local->scanning) &&
555 (sta_flags & WLAN_STA_ASSOC) && 539 (sta_flags & WLAN_STA_ASSOC) &&
556 !rate_usable_index_exists(sband, &tx->sta->sta), 540 !rate_usable_index_exists(sband, &tx->sta->sta),
557 "%s: Dropped data frame as no usable bitrate found while " 541 "%s: Dropped data frame as no usable bitrate found while "
@@ -696,7 +680,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
696 * number, if we have no matching interface then we 680 * number, if we have no matching interface then we
697 * neither assign one ourselves nor ask the driver to. 681 * neither assign one ourselves nor ask the driver to.
698 */ 682 */
699 if (unlikely(!info->control.vif)) 683 if (unlikely(info->control.vif->type == NL80211_IFTYPE_MONITOR))
700 return TX_CONTINUE; 684 return TX_CONTINUE;
701 685
702 if (unlikely(ieee80211_is_ctl(hdr->frame_control))) 686 if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
@@ -1092,6 +1076,7 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1092 } else if (*state != HT_AGG_STATE_IDLE) { 1076 } else if (*state != HT_AGG_STATE_IDLE) {
1093 /* in progress */ 1077 /* in progress */
1094 queued = true; 1078 queued = true;
1079 info->control.vif = &sdata->vif;
1095 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1080 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1096 __skb_queue_tail(&tid_tx->pending, skb); 1081 __skb_queue_tail(&tid_tx->pending, skb);
1097 } 1082 }
@@ -1143,6 +1128,7 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1143{ 1128{
1144 struct sk_buff *skb = *skbp, *next; 1129 struct sk_buff *skb = *skbp, *next;
1145 struct ieee80211_tx_info *info; 1130 struct ieee80211_tx_info *info;
1131 struct ieee80211_sub_if_data *sdata;
1146 unsigned long flags; 1132 unsigned long flags;
1147 int ret, len; 1133 int ret, len;
1148 bool fragm = false; 1134 bool fragm = false;
@@ -1167,13 +1153,32 @@ static int __ieee80211_tx(struct ieee80211_local *local,
1167 1153
1168 next = skb->next; 1154 next = skb->next;
1169 len = skb->len; 1155 len = skb->len;
1156
1157 sdata = vif_to_sdata(info->control.vif);
1158
1159 switch (sdata->vif.type) {
1160 case NL80211_IFTYPE_MONITOR:
1161 info->control.vif = NULL;
1162 break;
1163 case NL80211_IFTYPE_AP_VLAN:
1164 info->control.vif = &container_of(sdata->bss,
1165 struct ieee80211_sub_if_data, u.ap)->vif;
1166 break;
1167 default:
1168 /* keep */
1169 break;
1170 }
1171
1170 ret = drv_tx(local, skb); 1172 ret = drv_tx(local, skb);
1171 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { 1173 if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) {
1172 dev_kfree_skb(skb); 1174 dev_kfree_skb(skb);
1173 ret = NETDEV_TX_OK; 1175 ret = NETDEV_TX_OK;
1174 } 1176 }
1175 if (ret != NETDEV_TX_OK) 1177 if (ret != NETDEV_TX_OK) {
1178 info->control.vif = &sdata->vif;
1176 return IEEE80211_TX_AGAIN; 1179 return IEEE80211_TX_AGAIN;
1180 }
1181
1177 *skbp = skb = next; 1182 *skbp = skb = next;
1178 ieee80211_led_tx(local, 1); 1183 ieee80211_led_tx(local, 1);
1179 fragm = true; 1184 fragm = true;
@@ -1386,17 +1391,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1386 struct ieee80211_sub_if_data *tmp_sdata; 1391 struct ieee80211_sub_if_data *tmp_sdata;
1387 int headroom; 1392 int headroom;
1388 bool may_encrypt; 1393 bool may_encrypt;
1389 enum {
1390 NOT_MONITOR,
1391 FOUND_SDATA,
1392 UNKNOWN_ADDRESS,
1393 } monitor_iface = NOT_MONITOR;
1394 1394
1395 dev_hold(sdata->dev); 1395 dev_hold(sdata->dev);
1396 1396
1397 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 1397 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
1398 local->hw.conf.dynamic_ps_timeout > 0 && 1398 local->hw.conf.dynamic_ps_timeout > 0 &&
1399 !local->sw_scanning && !local->hw_scanning && local->ps_sdata) { 1399 !(local->scanning) && local->ps_sdata) {
1400 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 1400 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
1401 ieee80211_stop_queues_by_reason(&local->hw, 1401 ieee80211_stop_queues_by_reason(&local->hw,
1402 IEEE80211_QUEUE_STOP_REASON_PS); 1402 IEEE80211_QUEUE_STOP_REASON_PS);
@@ -1424,7 +1424,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1424 u16 len_rthdr; 1424 u16 len_rthdr;
1425 1425
1426 info->flags |= IEEE80211_TX_CTL_INJECTED; 1426 info->flags |= IEEE80211_TX_CTL_INJECTED;
1427 monitor_iface = UNKNOWN_ADDRESS;
1428 1427
1429 len_rthdr = ieee80211_get_radiotap_len(skb->data); 1428 len_rthdr = ieee80211_get_radiotap_len(skb->data);
1430 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); 1429 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
@@ -1454,7 +1453,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1454 dev_hold(tmp_sdata->dev); 1453 dev_hold(tmp_sdata->dev);
1455 dev_put(sdata->dev); 1454 dev_put(sdata->dev);
1456 sdata = tmp_sdata; 1455 sdata = tmp_sdata;
1457 monitor_iface = FOUND_SDATA;
1458 break; 1456 break;
1459 } 1457 }
1460 } 1458 }
@@ -1476,13 +1474,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1476 return; 1474 return;
1477 } 1475 }
1478 1476
1479 tmp_sdata = sdata; 1477 info->control.vif = &sdata->vif;
1480 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1481 tmp_sdata = container_of(sdata->bss,
1482 struct ieee80211_sub_if_data,
1483 u.ap);
1484 if (likely(monitor_iface != UNKNOWN_ADDRESS))
1485 info->control.vif = &tmp_sdata->vif;
1486 1478
1487 ieee80211_select_queue(local, skb); 1479 ieee80211_select_queue(local, skb);
1488 ieee80211_tx(sdata, skb, false); 1480 ieee80211_tx(sdata, skb, false);
@@ -1534,9 +1526,6 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1534 if (unlikely(skb->len < len_rthdr)) 1526 if (unlikely(skb->len < len_rthdr))
1535 goto fail; /* skb too short for claimed rt header extent */ 1527 goto fail; /* skb too short for claimed rt header extent */
1536 1528
1537 /* needed because we set skb device to master */
1538 skb->iif = dev->ifindex;
1539
1540 /* 1529 /*
1541 * fix up the pointers accounting for the radiotap 1530 * fix up the pointers accounting for the radiotap
1542 * header still being in there. We are being given 1531 * header still being in there. We are being given
@@ -1810,8 +1799,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1810 nh_pos += hdrlen; 1799 nh_pos += hdrlen;
1811 h_pos += hdrlen; 1800 h_pos += hdrlen;
1812 1801
1813 skb->iif = dev->ifindex;
1814
1815 dev->stats.tx_packets++; 1802 dev->stats.tx_packets++;
1816 dev->stats.tx_bytes += skb->len; 1803 dev->stats.tx_bytes += skb->len;
1817 1804
@@ -1856,32 +1843,13 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1856 struct ieee80211_sub_if_data *sdata; 1843 struct ieee80211_sub_if_data *sdata;
1857 struct sta_info *sta; 1844 struct sta_info *sta;
1858 struct ieee80211_hdr *hdr; 1845 struct ieee80211_hdr *hdr;
1859 struct net_device *dev;
1860 int ret; 1846 int ret;
1861 bool result = true; 1847 bool result = true;
1862 1848
1863 /* does interface still exist? */ 1849 sdata = vif_to_sdata(info->control.vif);
1864 dev = dev_get_by_index(&init_net, skb->iif);
1865 if (!dev) {
1866 dev_kfree_skb(skb);
1867 return true;
1868 }
1869
1870 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1871 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1872 sdata = container_of(sdata->bss,
1873 struct ieee80211_sub_if_data,
1874 u.ap);
1875
1876 if (unlikely(info->control.vif && info->control.vif != &sdata->vif)) {
1877 dev_kfree_skb(skb);
1878 result = true;
1879 goto out;
1880 }
1881 1850
1882 if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { 1851 if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) {
1883 /* do not use sdata, it may have been changed above */ 1852 ieee80211_tx(sdata, skb, true);
1884 ieee80211_tx(IEEE80211_DEV_TO_SUB_IF(dev), skb, true);
1885 } else { 1853 } else {
1886 hdr = (struct ieee80211_hdr *)skb->data; 1854 hdr = (struct ieee80211_hdr *)skb->data;
1887 sta = sta_info_get(local, hdr->addr1); 1855 sta = sta_info_get(local, hdr->addr1);
@@ -1891,9 +1859,6 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1891 result = false; 1859 result = false;
1892 } 1860 }
1893 1861
1894 out:
1895 dev_put(dev);
1896
1897 return result; 1862 return result;
1898} 1863}
1899 1864
@@ -1921,10 +1886,21 @@ void ieee80211_tx_pending(unsigned long data)
1921 1886
1922 while (!skb_queue_empty(&local->pending[i])) { 1887 while (!skb_queue_empty(&local->pending[i])) {
1923 struct sk_buff *skb = __skb_dequeue(&local->pending[i]); 1888 struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
1889 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1890 struct ieee80211_sub_if_data *sdata;
1891
1892 if (WARN_ON(!info->control.vif)) {
1893 kfree_skb(skb);
1894 continue;
1895 }
1896
1897 sdata = vif_to_sdata(info->control.vif);
1898 dev_hold(sdata->dev);
1924 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 1899 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1925 flags); 1900 flags);
1926 1901
1927 txok = ieee80211_tx_pending_skb(local, skb); 1902 txok = ieee80211_tx_pending_skb(local, skb);
1903 dev_put(sdata->dev);
1928 if (!txok) 1904 if (!txok)
1929 __skb_queue_head(&local->pending[i], skb); 1905 __skb_queue_head(&local->pending[i], skb);
1930 spin_lock_irqsave(&local->queue_stop_reason_lock, 1906 spin_lock_irqsave(&local->queue_stop_reason_lock,
@@ -2234,7 +2210,6 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
2234 skb_set_network_header(skb, 0); 2210 skb_set_network_header(skb, 0);
2235 skb_set_transport_header(skb, 0); 2211 skb_set_transport_header(skb, 0);
2236 2212
2237 skb->iif = sdata->dev->ifindex;
2238 if (!encrypt) 2213 if (!encrypt)
2239 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 2214 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
2240 2215
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7fc55846d601..8502936e5314 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -336,6 +336,12 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
336 struct ieee80211_hw *hw = &local->hw; 336 struct ieee80211_hw *hw = &local->hw;
337 unsigned long flags; 337 unsigned long flags;
338 int queue = skb_get_queue_mapping(skb); 338 int queue = skb_get_queue_mapping(skb);
339 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
340
341 if (WARN_ON(!info->control.vif)) {
342 kfree(skb);
343 return;
344 }
339 345
340 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 346 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
341 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 347 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
@@ -358,6 +364,13 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
358 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 364 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
359 365
360 while ((skb = skb_dequeue(skbs))) { 366 while ((skb = skb_dequeue(skbs))) {
367 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
368
369 if (WARN_ON(!info->control.vif)) {
370 kfree(skb);
371 continue;
372 }
373
361 ret++; 374 ret++;
362 queue = skb_get_queue_mapping(skb); 375 queue = skb_get_queue_mapping(skb);
363 __skb_queue_tail(&local->pending[queue], skb); 376 __skb_queue_tail(&local->pending[queue], skb);
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
deleted file mode 100644
index 5acb8140ee58..000000000000
--- a/net/mac80211/wext.c
+++ /dev/null
@@ -1,235 +0,0 @@
1/*
2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9
10#include <linux/module.h>
11#include <linux/init.h>
12#include <linux/netdevice.h>
13#include <linux/types.h>
14#include <linux/slab.h>
15#include <linux/skbuff.h>
16#include <linux/etherdevice.h>
17#include <linux/if_arp.h>
18#include <linux/wireless.h>
19#include <net/iw_handler.h>
20#include <asm/uaccess.h>
21
22#include <net/mac80211.h>
23#include "ieee80211_i.h"
24#include "led.h"
25#include "rate.h"
26#include "wpa.h"
27#include "aes_ccm.h"
28
29
30static int ieee80211_ioctl_siwfreq(struct net_device *dev,
31 struct iw_request_info *info,
32 struct iw_freq *freq, char *extra)
33{
34 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
35 struct ieee80211_local *local = sdata->local;
36 struct ieee80211_channel *chan;
37
38 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
39 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
40 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
41 return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
42
43 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
44 if (freq->e == 0) {
45 if (freq->m < 0)
46 return -EINVAL;
47 else
48 chan = ieee80211_get_channel(local->hw.wiphy,
49 ieee80211_channel_to_frequency(freq->m));
50 } else {
51 int i, div = 1000000;
52 for (i = 0; i < freq->e; i++)
53 div /= 10;
54 if (div <= 0)
55 return -EINVAL;
56 chan = ieee80211_get_channel(local->hw.wiphy, freq->m / div);
57 }
58
59 if (!chan)
60 return -EINVAL;
61
62 if (chan->flags & IEEE80211_CHAN_DISABLED)
63 return -EINVAL;
64
65 /*
66 * no change except maybe auto -> fixed, ignore the HT
67 * setting so you can fix a channel you're on already
68 */
69 if (local->oper_channel == chan)
70 return 0;
71
72 local->oper_channel = chan;
73 local->oper_channel_type = NL80211_CHAN_NO_HT;
74 ieee80211_hw_config(local, 0);
75
76 return 0;
77}
78
79
80static int ieee80211_ioctl_giwfreq(struct net_device *dev,
81 struct iw_request_info *info,
82 struct iw_freq *freq, char *extra)
83{
84 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
85 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
86
87 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
88 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
89 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
90 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
91
92 freq->m = local->oper_channel->center_freq;
93 freq->e = 6;
94
95 return 0;
96}
97
98
99static int ieee80211_ioctl_siwessid(struct net_device *dev,
100 struct iw_request_info *info,
101 struct iw_point *data, char *ssid)
102{
103 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
104
105 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
106 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
107 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
108 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
109
110 return -EOPNOTSUPP;
111}
112
113
114static int ieee80211_ioctl_giwessid(struct net_device *dev,
115 struct iw_request_info *info,
116 struct iw_point *data, char *ssid)
117{
118 struct ieee80211_sub_if_data *sdata;
119
120 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
121
122 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
123 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
124 else if (sdata->vif.type == NL80211_IFTYPE_STATION)
125 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
126
127 return -EOPNOTSUPP;
128}
129
130
131static int ieee80211_ioctl_siwap(struct net_device *dev,
132 struct iw_request_info *info,
133 struct sockaddr *ap_addr, char *extra)
134{
135 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
136
137 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
138 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
139
140 if (sdata->vif.type == NL80211_IFTYPE_STATION)
141 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
142
143 if (sdata->vif.type == NL80211_IFTYPE_WDS)
144 return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
145 return -EOPNOTSUPP;
146}
147
148
149static int ieee80211_ioctl_giwap(struct net_device *dev,
150 struct iw_request_info *info,
151 struct sockaddr *ap_addr, char *extra)
152{
153 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
154
155 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
156 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
157
158 if (sdata->vif.type == NL80211_IFTYPE_STATION)
159 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
160
161 if (sdata->vif.type == NL80211_IFTYPE_WDS)
162 return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
163
164 return -EOPNOTSUPP;
165}
166
167
168/* Structures to export the Wireless Handlers */
169
170static const iw_handler ieee80211_handler[] =
171{
172 (iw_handler) NULL, /* SIOCSIWCOMMIT */
173 (iw_handler) cfg80211_wext_giwname, /* SIOCGIWNAME */
174 (iw_handler) NULL, /* SIOCSIWNWID */
175 (iw_handler) NULL, /* SIOCGIWNWID */
176 (iw_handler) ieee80211_ioctl_siwfreq, /* SIOCSIWFREQ */
177 (iw_handler) ieee80211_ioctl_giwfreq, /* SIOCGIWFREQ */
178 (iw_handler) cfg80211_wext_siwmode, /* SIOCSIWMODE */
179 (iw_handler) cfg80211_wext_giwmode, /* SIOCGIWMODE */
180 (iw_handler) NULL, /* SIOCSIWSENS */
181 (iw_handler) NULL, /* SIOCGIWSENS */
182 (iw_handler) NULL /* not used */, /* SIOCSIWRANGE */
183 (iw_handler) cfg80211_wext_giwrange, /* SIOCGIWRANGE */
184 (iw_handler) NULL /* not used */, /* SIOCSIWPRIV */
185 (iw_handler) NULL /* kernel code */, /* SIOCGIWPRIV */
186 (iw_handler) NULL /* not used */, /* SIOCSIWSTATS */
187 (iw_handler) NULL /* kernel code */, /* SIOCGIWSTATS */
188 (iw_handler) NULL, /* SIOCSIWSPY */
189 (iw_handler) NULL, /* SIOCGIWSPY */
190 (iw_handler) NULL, /* SIOCSIWTHRSPY */
191 (iw_handler) NULL, /* SIOCGIWTHRSPY */
192 (iw_handler) ieee80211_ioctl_siwap, /* SIOCSIWAP */
193 (iw_handler) ieee80211_ioctl_giwap, /* SIOCGIWAP */
194 (iw_handler) cfg80211_wext_siwmlme, /* SIOCSIWMLME */
195 (iw_handler) NULL, /* SIOCGIWAPLIST */
196 (iw_handler) cfg80211_wext_siwscan, /* SIOCSIWSCAN */
197 (iw_handler) cfg80211_wext_giwscan, /* SIOCGIWSCAN */
198 (iw_handler) ieee80211_ioctl_siwessid, /* SIOCSIWESSID */
199 (iw_handler) ieee80211_ioctl_giwessid, /* SIOCGIWESSID */
200 (iw_handler) NULL, /* SIOCSIWNICKN */
201 (iw_handler) NULL, /* SIOCGIWNICKN */
202 (iw_handler) NULL, /* -- hole -- */
203 (iw_handler) NULL, /* -- hole -- */
204 (iw_handler) cfg80211_wext_siwrate, /* SIOCSIWRATE */
205 (iw_handler) cfg80211_wext_giwrate, /* SIOCGIWRATE */
206 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
207 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
208 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
209 (iw_handler) cfg80211_wext_giwfrag, /* SIOCGIWFRAG */
210 (iw_handler) cfg80211_wext_siwtxpower, /* SIOCSIWTXPOW */
211 (iw_handler) cfg80211_wext_giwtxpower, /* SIOCGIWTXPOW */
212 (iw_handler) cfg80211_wext_siwretry, /* SIOCSIWRETRY */
213 (iw_handler) cfg80211_wext_giwretry, /* SIOCGIWRETRY */
214 (iw_handler) cfg80211_wext_siwencode, /* SIOCSIWENCODE */
215 (iw_handler) cfg80211_wext_giwencode, /* SIOCGIWENCODE */
216 (iw_handler) cfg80211_wext_siwpower, /* SIOCSIWPOWER */
217 (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */
218 (iw_handler) NULL, /* -- hole -- */
219 (iw_handler) NULL, /* -- hole -- */
220 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
221 (iw_handler) NULL, /* SIOCGIWGENIE */
222 (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */
223 (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */
224 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
225 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
226 (iw_handler) NULL, /* SIOCSIWPMKSA */
227 (iw_handler) NULL, /* -- hole -- */
228};
229
230const struct iw_handler_def ieee80211_iw_handler_def =
231{
232 .num_standard = ARRAY_SIZE(ieee80211_handler),
233 .standard = (iw_handler *) ieee80211_handler,
234 .get_wireless_stats = cfg80211_wireless_stats,
235};
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 6891cd0e38d5..f9fee65dc06a 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -19,6 +19,7 @@
19#include "core.h" 19#include "core.h"
20#include "sysfs.h" 20#include "sysfs.h"
21#include "debugfs.h" 21#include "debugfs.h"
22#include "wext-compat.h"
22 23
23/* name for sysfs, %d is appended */ 24/* name for sysfs, %d is appended */
24#define PHY_NAME "phy" 25#define PHY_NAME "phy"
@@ -106,7 +107,7 @@ __cfg80211_rdev_from_info(struct genl_info *info)
106 107
107 if (info->attrs[NL80211_ATTR_IFINDEX]) { 108 if (info->attrs[NL80211_ATTR_IFINDEX]) {
108 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); 109 ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
109 dev = dev_get_by_index(&init_net, ifindex); 110 dev = dev_get_by_index(genl_info_net(info), ifindex);
110 if (dev) { 111 if (dev) {
111 if (dev->ieee80211_ptr) 112 if (dev->ieee80211_ptr)
112 byifidx = 113 byifidx =
@@ -151,13 +152,13 @@ cfg80211_get_dev_from_info(struct genl_info *info)
151} 152}
152 153
153struct cfg80211_registered_device * 154struct cfg80211_registered_device *
154cfg80211_get_dev_from_ifindex(int ifindex) 155cfg80211_get_dev_from_ifindex(struct net *net, int ifindex)
155{ 156{
156 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV); 157 struct cfg80211_registered_device *rdev = ERR_PTR(-ENODEV);
157 struct net_device *dev; 158 struct net_device *dev;
158 159
159 mutex_lock(&cfg80211_mutex); 160 mutex_lock(&cfg80211_mutex);
160 dev = dev_get_by_index(&init_net, ifindex); 161 dev = dev_get_by_index(net, ifindex);
161 if (!dev) 162 if (!dev)
162 goto out; 163 goto out;
163 if (dev->ieee80211_ptr) { 164 if (dev->ieee80211_ptr) {
@@ -222,6 +223,42 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
222 return 0; 223 return 0;
223} 224}
224 225
226int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
227 struct net *net)
228{
229 struct wireless_dev *wdev;
230 int err = 0;
231
232 if (!rdev->wiphy.netnsok)
233 return -EOPNOTSUPP;
234
235 list_for_each_entry(wdev, &rdev->netdev_list, list) {
236 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
237 err = dev_change_net_namespace(wdev->netdev, net, "wlan%d");
238 if (err)
239 break;
240 wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
241 }
242
243 if (err) {
244 /* failed -- clean up to old netns */
245 net = wiphy_net(&rdev->wiphy);
246
247 list_for_each_entry_continue_reverse(wdev, &rdev->netdev_list,
248 list) {
249 wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
250 err = dev_change_net_namespace(wdev->netdev, net,
251 "wlan%d");
252 WARN_ON(err);
253 wdev->netdev->features |= NETIF_F_NETNS_LOCAL;
254 }
255 }
256
257 wiphy_net_set(&rdev->wiphy, net);
258
259 return err;
260}
261
225static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) 262static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data)
226{ 263{
227 struct cfg80211_registered_device *rdev = data; 264 struct cfg80211_registered_device *rdev = data;
@@ -375,6 +412,8 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
375 rdev->wiphy.dev.class = &ieee80211_class; 412 rdev->wiphy.dev.class = &ieee80211_class;
376 rdev->wiphy.dev.platform_data = rdev; 413 rdev->wiphy.dev.platform_data = rdev;
377 414
415 wiphy_net_set(&rdev->wiphy, &init_net);
416
378 rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block; 417 rdev->rfkill_ops.set_block = cfg80211_rfkill_set_block;
379 rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev), 418 rdev->rfkill = rfkill_alloc(dev_name(&rdev->wiphy.dev),
380 &rdev->wiphy.dev, RFKILL_TYPE_WLAN, 419 &rdev->wiphy.dev, RFKILL_TYPE_WLAN,
@@ -615,6 +654,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
615 spin_lock_init(&wdev->event_lock); 654 spin_lock_init(&wdev->event_lock);
616 mutex_lock(&rdev->devlist_mtx); 655 mutex_lock(&rdev->devlist_mtx);
617 list_add(&wdev->list, &rdev->netdev_list); 656 list_add(&wdev->list, &rdev->netdev_list);
657 /* can only change netns with wiphy */
658 dev->features |= NETIF_F_NETNS_LOCAL;
659
618 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj, 660 if (sysfs_create_link(&dev->dev.kobj, &rdev->wiphy.dev.kobj,
619 "phy80211")) { 661 "phy80211")) {
620 printk(KERN_ERR "wireless: failed to add phy80211 " 662 printk(KERN_ERR "wireless: failed to add phy80211 "
@@ -624,6 +666,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
624 wdev->sme_state = CFG80211_SME_IDLE; 666 wdev->sme_state = CFG80211_SME_IDLE;
625 mutex_unlock(&rdev->devlist_mtx); 667 mutex_unlock(&rdev->devlist_mtx);
626#ifdef CONFIG_WIRELESS_EXT 668#ifdef CONFIG_WIRELESS_EXT
669 if (!dev->wireless_handlers)
670 dev->wireless_handlers = &cfg80211_wext_handler;
627 wdev->wext.default_key = -1; 671 wdev->wext.default_key = -1;
628 wdev->wext.default_mgmt_key = -1; 672 wdev->wext.default_mgmt_key = -1;
629 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 673 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
@@ -705,10 +749,32 @@ static struct notifier_block cfg80211_netdev_notifier = {
705 .notifier_call = cfg80211_netdev_notifier_call, 749 .notifier_call = cfg80211_netdev_notifier_call,
706}; 750};
707 751
708static int cfg80211_init(void) 752static void __net_exit cfg80211_pernet_exit(struct net *net)
753{
754 struct cfg80211_registered_device *rdev;
755
756 rtnl_lock();
757 mutex_lock(&cfg80211_mutex);
758 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
759 if (net_eq(wiphy_net(&rdev->wiphy), net))
760 WARN_ON(cfg80211_switch_netns(rdev, &init_net));
761 }
762 mutex_unlock(&cfg80211_mutex);
763 rtnl_unlock();
764}
765
766static struct pernet_operations cfg80211_pernet_ops = {
767 .exit = cfg80211_pernet_exit,
768};
769
770static int __init cfg80211_init(void)
709{ 771{
710 int err; 772 int err;
711 773
774 err = register_pernet_device(&cfg80211_pernet_ops);
775 if (err)
776 goto out_fail_pernet;
777
712 err = wiphy_sysfs_init(); 778 err = wiphy_sysfs_init();
713 if (err) 779 if (err)
714 goto out_fail_sysfs; 780 goto out_fail_sysfs;
@@ -736,9 +802,10 @@ out_fail_nl80211:
736out_fail_notifier: 802out_fail_notifier:
737 wiphy_sysfs_exit(); 803 wiphy_sysfs_exit();
738out_fail_sysfs: 804out_fail_sysfs:
805 unregister_pernet_device(&cfg80211_pernet_ops);
806out_fail_pernet:
739 return err; 807 return err;
740} 808}
741
742subsys_initcall(cfg80211_init); 809subsys_initcall(cfg80211_init);
743 810
744static void cfg80211_exit(void) 811static void cfg80211_exit(void)
@@ -748,5 +815,6 @@ static void cfg80211_exit(void)
748 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 815 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
749 wiphy_sysfs_exit(); 816 wiphy_sysfs_exit();
750 regulatory_exit(); 817 regulatory_exit();
818 unregister_pernet_device(&cfg80211_pernet_ops);
751} 819}
752module_exit(cfg80211_exit); 820module_exit(cfg80211_exit);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 2ec8ddbe57de..6d903c1d721d 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -66,6 +66,9 @@ struct cfg80211_registered_device {
66 struct work_struct conn_work; 66 struct work_struct conn_work;
67 struct work_struct event_work; 67 struct work_struct event_work;
68 68
69 /* current channel */
70 struct ieee80211_channel *channel;
71
69#ifdef CONFIG_CFG80211_DEBUGFS 72#ifdef CONFIG_CFG80211_DEBUGFS
70 /* Debugfs entries */ 73 /* Debugfs entries */
71 struct wiphy_debugfsdentries { 74 struct wiphy_debugfsdentries {
@@ -170,7 +173,10 @@ struct wiphy *wiphy_idx_to_wiphy(int wiphy_idx);
170 173
171/* identical to cfg80211_get_dev_from_info but only operate on ifindex */ 174/* identical to cfg80211_get_dev_from_info but only operate on ifindex */
172extern struct cfg80211_registered_device * 175extern struct cfg80211_registered_device *
173cfg80211_get_dev_from_ifindex(int ifindex); 176cfg80211_get_dev_from_ifindex(struct net *net, int ifindex);
177
178int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
179 struct net *net);
174 180
175static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev) 181static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev)
176{ 182{
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 8b65e212ae49..4d7a084b35e2 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -7,6 +7,7 @@
7#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
8#include <linux/if_arp.h> 8#include <linux/if_arp.h>
9#include <net/cfg80211.h> 9#include <net/cfg80211.h>
10#include "wext-compat.h"
10#include "nl80211.h" 11#include "nl80211.h"
11 12
12 13
@@ -312,8 +313,6 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
312 313
313 return err; 314 return err;
314} 315}
315/* temporary symbol - mark GPL - in the future the handler won't be */
316EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
317 316
318int cfg80211_ibss_wext_giwfreq(struct net_device *dev, 317int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
319 struct iw_request_info *info, 318 struct iw_request_info *info,
@@ -342,8 +341,6 @@ int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
342 /* no channel if not joining */ 341 /* no channel if not joining */
343 return -EINVAL; 342 return -EINVAL;
344} 343}
345/* temporary symbol - mark GPL - in the future the handler won't be */
346EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq);
347 344
348int cfg80211_ibss_wext_siwessid(struct net_device *dev, 345int cfg80211_ibss_wext_siwessid(struct net_device *dev,
349 struct iw_request_info *info, 346 struct iw_request_info *info,
@@ -384,8 +381,6 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
384 381
385 return err; 382 return err;
386} 383}
387/* temporary symbol - mark GPL - in the future the handler won't be */
388EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
389 384
390int cfg80211_ibss_wext_giwessid(struct net_device *dev, 385int cfg80211_ibss_wext_giwessid(struct net_device *dev,
391 struct iw_request_info *info, 386 struct iw_request_info *info,
@@ -413,8 +408,6 @@ int cfg80211_ibss_wext_giwessid(struct net_device *dev,
413 408
414 return 0; 409 return 0;
415} 410}
416/* temporary symbol - mark GPL - in the future the handler won't be */
417EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid);
418 411
419int cfg80211_ibss_wext_siwap(struct net_device *dev, 412int cfg80211_ibss_wext_siwap(struct net_device *dev,
420 struct iw_request_info *info, 413 struct iw_request_info *info,
@@ -469,8 +462,6 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
469 462
470 return err; 463 return err;
471} 464}
472/* temporary symbol - mark GPL - in the future the handler won't be */
473EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
474 465
475int cfg80211_ibss_wext_giwap(struct net_device *dev, 466int cfg80211_ibss_wext_giwap(struct net_device *dev,
476 struct iw_request_info *info, 467 struct iw_request_info *info,
@@ -496,6 +487,4 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev,
496 487
497 return 0; 488 return 0;
498} 489}
499/* temporary symbol - mark GPL - in the future the handler won't be */
500EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwap);
501#endif 490#endif
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 5b9b22120824..097a87d7bae1 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -8,7 +8,9 @@
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/netdevice.h> 9#include <linux/netdevice.h>
10#include <linux/nl80211.h> 10#include <linux/nl80211.h>
11#include <linux/wireless.h>
11#include <net/cfg80211.h> 12#include <net/cfg80211.h>
13#include <net/iw_handler.h>
12#include "core.h" 14#include "core.h"
13#include "nl80211.h" 15#include "nl80211.h"
14 16
@@ -545,6 +547,12 @@ static int __cfg80211_mlme_disassoc(struct cfg80211_registered_device *rdev,
545 547
546 ASSERT_WDEV_LOCK(wdev); 548 ASSERT_WDEV_LOCK(wdev);
547 549
550 if (wdev->sme_state != CFG80211_SME_CONNECTED)
551 return -ENOTCONN;
552
553 if (WARN_ON(!wdev->current_bss))
554 return -ENOTCONN;
555
548 memset(&req, 0, sizeof(req)); 556 memset(&req, 0, sizeof(req));
549 req.reason_code = reason; 557 req.reason_code = reason;
550 req.ie = ie; 558 req.ie = ie;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index da450ef1fc7e..0cd548267d4a 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14,8 +14,10 @@
14#include <linux/rtnetlink.h> 14#include <linux/rtnetlink.h>
15#include <linux/netlink.h> 15#include <linux/netlink.h>
16#include <linux/etherdevice.h> 16#include <linux/etherdevice.h>
17#include <net/net_namespace.h>
17#include <net/genetlink.h> 18#include <net/genetlink.h>
18#include <net/cfg80211.h> 19#include <net/cfg80211.h>
20#include <net/sock.h>
19#include "core.h" 21#include "core.h"
20#include "nl80211.h" 22#include "nl80211.h"
21#include "reg.h" 23#include "reg.h"
@@ -27,24 +29,26 @@ static struct genl_family nl80211_fam = {
27 .hdrsize = 0, /* no private header */ 29 .hdrsize = 0, /* no private header */
28 .version = 1, /* no particular meaning now */ 30 .version = 1, /* no particular meaning now */
29 .maxattr = NL80211_ATTR_MAX, 31 .maxattr = NL80211_ATTR_MAX,
32 .netnsok = true,
30}; 33};
31 34
32/* internal helper: get rdev and dev */ 35/* internal helper: get rdev and dev */
33static int get_rdev_dev_by_info_ifindex(struct nlattr **attrs, 36static int get_rdev_dev_by_info_ifindex(struct genl_info *info,
34 struct cfg80211_registered_device **rdev, 37 struct cfg80211_registered_device **rdev,
35 struct net_device **dev) 38 struct net_device **dev)
36{ 39{
40 struct nlattr **attrs = info->attrs;
37 int ifindex; 41 int ifindex;
38 42
39 if (!attrs[NL80211_ATTR_IFINDEX]) 43 if (!attrs[NL80211_ATTR_IFINDEX])
40 return -EINVAL; 44 return -EINVAL;
41 45
42 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); 46 ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);
43 *dev = dev_get_by_index(&init_net, ifindex); 47 *dev = dev_get_by_index(genl_info_net(info), ifindex);
44 if (!*dev) 48 if (!*dev)
45 return -ENODEV; 49 return -ENODEV;
46 50
47 *rdev = cfg80211_get_dev_from_ifindex(ifindex); 51 *rdev = cfg80211_get_dev_from_ifindex(genl_info_net(info), ifindex);
48 if (IS_ERR(*rdev)) { 52 if (IS_ERR(*rdev)) {
49 dev_put(*dev); 53 dev_put(*dev);
50 return PTR_ERR(*rdev); 54 return PTR_ERR(*rdev);
@@ -133,6 +137,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
133 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, 137 [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG },
134 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, 138 [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 },
135 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, 139 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
140 [NL80211_ATTR_PID] = { .type = NLA_U32 },
136}; 141};
137 142
138/* policy for the attributes */ 143/* policy for the attributes */
@@ -532,6 +537,10 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
532 CMD(deauth, DEAUTHENTICATE); 537 CMD(deauth, DEAUTHENTICATE);
533 CMD(disassoc, DISASSOCIATE); 538 CMD(disassoc, DISASSOCIATE);
534 CMD(join_ibss, JOIN_IBSS); 539 CMD(join_ibss, JOIN_IBSS);
540 if (dev->wiphy.netnsok) {
541 i++;
542 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
543 }
535 544
536#undef CMD 545#undef CMD
537 546
@@ -562,6 +571,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
562 571
563 mutex_lock(&cfg80211_mutex); 572 mutex_lock(&cfg80211_mutex);
564 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 573 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
574 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
575 continue;
565 if (++idx <= start) 576 if (++idx <= start)
566 continue; 577 continue;
567 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid, 578 if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).pid,
@@ -746,6 +757,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
746 channel_type); 757 channel_type);
747 if (result) 758 if (result)
748 goto bad_res; 759 goto bad_res;
760
761 rdev->channel = chan;
749 } 762 }
750 763
751 changed = 0; 764 changed = 0;
@@ -867,6 +880,8 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
867 880
868 mutex_lock(&cfg80211_mutex); 881 mutex_lock(&cfg80211_mutex);
869 list_for_each_entry(dev, &cfg80211_rdev_list, list) { 882 list_for_each_entry(dev, &cfg80211_rdev_list, list) {
883 if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk)))
884 continue;
870 if (wp_idx < wp_start) { 885 if (wp_idx < wp_start) {
871 wp_idx++; 886 wp_idx++;
872 continue; 887 continue;
@@ -907,7 +922,7 @@ static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info)
907 struct net_device *netdev; 922 struct net_device *netdev;
908 int err; 923 int err;
909 924
910 err = get_rdev_dev_by_info_ifindex(info->attrs, &dev, &netdev); 925 err = get_rdev_dev_by_info_ifindex(info, &dev, &netdev);
911 if (err) 926 if (err)
912 return err; 927 return err;
913 928
@@ -975,7 +990,7 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
975 990
976 rtnl_lock(); 991 rtnl_lock();
977 992
978 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 993 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
979 if (err) 994 if (err)
980 goto unlock_rtnl; 995 goto unlock_rtnl;
981 996
@@ -1098,26 +1113,25 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
1098static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) 1113static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
1099{ 1114{
1100 struct cfg80211_registered_device *rdev; 1115 struct cfg80211_registered_device *rdev;
1101 int ifindex, err; 1116 int err;
1102 struct net_device *dev; 1117 struct net_device *dev;
1103 1118
1104 rtnl_lock(); 1119 rtnl_lock();
1105 1120
1106 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1121 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1107 if (err) 1122 if (err)
1108 goto unlock_rtnl; 1123 goto unlock_rtnl;
1109 ifindex = dev->ifindex;
1110 dev_put(dev);
1111 1124
1112 if (!rdev->ops->del_virtual_intf) { 1125 if (!rdev->ops->del_virtual_intf) {
1113 err = -EOPNOTSUPP; 1126 err = -EOPNOTSUPP;
1114 goto out; 1127 goto out;
1115 } 1128 }
1116 1129
1117 err = rdev->ops->del_virtual_intf(&rdev->wiphy, ifindex); 1130 err = rdev->ops->del_virtual_intf(&rdev->wiphy, dev);
1118 1131
1119 out: 1132 out:
1120 cfg80211_unlock_rdev(rdev); 1133 cfg80211_unlock_rdev(rdev);
1134 dev_put(dev);
1121 unlock_rtnl: 1135 unlock_rtnl:
1122 rtnl_unlock(); 1136 rtnl_unlock();
1123 return err; 1137 return err;
@@ -1195,7 +1209,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1195 1209
1196 rtnl_lock(); 1210 rtnl_lock();
1197 1211
1198 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1212 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1199 if (err) 1213 if (err)
1200 goto unlock_rtnl; 1214 goto unlock_rtnl;
1201 1215
@@ -1274,7 +1288,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1274 1288
1275 rtnl_lock(); 1289 rtnl_lock();
1276 1290
1277 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1291 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1278 if (err) 1292 if (err)
1279 goto unlock_rtnl; 1293 goto unlock_rtnl;
1280 1294
@@ -1333,7 +1347,7 @@ static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1333 1347
1334 rtnl_lock(); 1348 rtnl_lock();
1335 1349
1336 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1350 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1337 if (err) 1351 if (err)
1338 goto unlock_rtnl; 1352 goto unlock_rtnl;
1339 1353
@@ -1380,7 +1394,7 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1380 1394
1381 rtnl_lock(); 1395 rtnl_lock();
1382 1396
1383 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1397 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1384 if (err) 1398 if (err)
1385 goto unlock_rtnl; 1399 goto unlock_rtnl;
1386 1400
@@ -1429,7 +1443,7 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1429 1443
1430 rtnl_lock(); 1444 rtnl_lock();
1431 1445
1432 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1446 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1433 if (err) 1447 if (err)
1434 goto unlock_rtnl; 1448 goto unlock_rtnl;
1435 1449
@@ -1516,7 +1530,7 @@ static int nl80211_del_beacon(struct sk_buff *skb, struct genl_info *info)
1516 1530
1517 rtnl_lock(); 1531 rtnl_lock();
1518 1532
1519 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1533 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1520 if (err) 1534 if (err)
1521 goto unlock_rtnl; 1535 goto unlock_rtnl;
1522 1536
@@ -1726,13 +1740,13 @@ static int nl80211_dump_station(struct sk_buff *skb,
1726 1740
1727 rtnl_lock(); 1741 rtnl_lock();
1728 1742
1729 netdev = __dev_get_by_index(&init_net, ifidx); 1743 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
1730 if (!netdev) { 1744 if (!netdev) {
1731 err = -ENODEV; 1745 err = -ENODEV;
1732 goto out_rtnl; 1746 goto out_rtnl;
1733 } 1747 }
1734 1748
1735 dev = cfg80211_get_dev_from_ifindex(ifidx); 1749 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
1736 if (IS_ERR(dev)) { 1750 if (IS_ERR(dev)) {
1737 err = PTR_ERR(dev); 1751 err = PTR_ERR(dev);
1738 goto out_rtnl; 1752 goto out_rtnl;
@@ -1791,7 +1805,7 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1791 1805
1792 rtnl_lock(); 1806 rtnl_lock();
1793 1807
1794 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1808 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1795 if (err) 1809 if (err)
1796 goto out_rtnl; 1810 goto out_rtnl;
1797 1811
@@ -1829,14 +1843,16 @@ static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)
1829/* 1843/*
1830 * Get vlan interface making sure it is on the right wiphy. 1844 * Get vlan interface making sure it is on the right wiphy.
1831 */ 1845 */
1832static int get_vlan(struct nlattr *vlanattr, 1846static int get_vlan(struct genl_info *info,
1833 struct cfg80211_registered_device *rdev, 1847 struct cfg80211_registered_device *rdev,
1834 struct net_device **vlan) 1848 struct net_device **vlan)
1835{ 1849{
1850 struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN];
1836 *vlan = NULL; 1851 *vlan = NULL;
1837 1852
1838 if (vlanattr) { 1853 if (vlanattr) {
1839 *vlan = dev_get_by_index(&init_net, nla_get_u32(vlanattr)); 1854 *vlan = dev_get_by_index(genl_info_net(info),
1855 nla_get_u32(vlanattr));
1840 if (!*vlan) 1856 if (!*vlan)
1841 return -ENODEV; 1857 return -ENODEV;
1842 if (!(*vlan)->ieee80211_ptr) 1858 if (!(*vlan)->ieee80211_ptr)
@@ -1891,11 +1907,11 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1891 1907
1892 rtnl_lock(); 1908 rtnl_lock();
1893 1909
1894 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1910 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
1895 if (err) 1911 if (err)
1896 goto out_rtnl; 1912 goto out_rtnl;
1897 1913
1898 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan); 1914 err = get_vlan(info, rdev, &params.vlan);
1899 if (err) 1915 if (err)
1900 goto out; 1916 goto out;
1901 1917
@@ -2004,11 +2020,11 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
2004 2020
2005 rtnl_lock(); 2021 rtnl_lock();
2006 2022
2007 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2023 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2008 if (err) 2024 if (err)
2009 goto out_rtnl; 2025 goto out_rtnl;
2010 2026
2011 err = get_vlan(info->attrs[NL80211_ATTR_STA_VLAN], rdev, &params.vlan); 2027 err = get_vlan(info, rdev, &params.vlan);
2012 if (err) 2028 if (err)
2013 goto out; 2029 goto out;
2014 2030
@@ -2079,7 +2095,7 @@ static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info)
2079 2095
2080 rtnl_lock(); 2096 rtnl_lock();
2081 2097
2082 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2098 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2083 if (err) 2099 if (err)
2084 goto out_rtnl; 2100 goto out_rtnl;
2085 2101
@@ -2185,13 +2201,13 @@ static int nl80211_dump_mpath(struct sk_buff *skb,
2185 2201
2186 rtnl_lock(); 2202 rtnl_lock();
2187 2203
2188 netdev = __dev_get_by_index(&init_net, ifidx); 2204 netdev = __dev_get_by_index(sock_net(skb->sk), ifidx);
2189 if (!netdev) { 2205 if (!netdev) {
2190 err = -ENODEV; 2206 err = -ENODEV;
2191 goto out_rtnl; 2207 goto out_rtnl;
2192 } 2208 }
2193 2209
2194 dev = cfg80211_get_dev_from_ifindex(ifidx); 2210 dev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
2195 if (IS_ERR(dev)) { 2211 if (IS_ERR(dev)) {
2196 err = PTR_ERR(dev); 2212 err = PTR_ERR(dev);
2197 goto out_rtnl; 2213 goto out_rtnl;
@@ -2255,7 +2271,7 @@ static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)
2255 2271
2256 rtnl_lock(); 2272 rtnl_lock();
2257 2273
2258 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2274 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2259 if (err) 2275 if (err)
2260 goto out_rtnl; 2276 goto out_rtnl;
2261 2277
@@ -2314,7 +2330,7 @@ static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info)
2314 2330
2315 rtnl_lock(); 2331 rtnl_lock();
2316 2332
2317 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2333 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2318 if (err) 2334 if (err)
2319 goto out_rtnl; 2335 goto out_rtnl;
2320 2336
@@ -2362,7 +2378,7 @@ static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info)
2362 2378
2363 rtnl_lock(); 2379 rtnl_lock();
2364 2380
2365 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2381 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2366 if (err) 2382 if (err)
2367 goto out_rtnl; 2383 goto out_rtnl;
2368 2384
@@ -2404,7 +2420,7 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
2404 2420
2405 rtnl_lock(); 2421 rtnl_lock();
2406 2422
2407 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2423 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2408 if (err) 2424 if (err)
2409 goto out_rtnl; 2425 goto out_rtnl;
2410 2426
@@ -2455,7 +2471,7 @@ static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
2455 2471
2456 rtnl_lock(); 2472 rtnl_lock();
2457 2473
2458 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2474 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2459 if (err) 2475 if (err)
2460 goto out_rtnl; 2476 goto out_rtnl;
2461 2477
@@ -2574,7 +2590,7 @@ static int nl80211_get_mesh_params(struct sk_buff *skb,
2574 rtnl_lock(); 2590 rtnl_lock();
2575 2591
2576 /* Look up our device */ 2592 /* Look up our device */
2577 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2593 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2578 if (err) 2594 if (err)
2579 goto out_rtnl; 2595 goto out_rtnl;
2580 2596
@@ -2691,7 +2707,7 @@ static int nl80211_set_mesh_params(struct sk_buff *skb, struct genl_info *info)
2691 2707
2692 rtnl_lock(); 2708 rtnl_lock();
2693 2709
2694 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2710 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2695 if (err) 2711 if (err)
2696 goto out_rtnl; 2712 goto out_rtnl;
2697 2713
@@ -2947,7 +2963,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2947 2963
2948 rtnl_lock(); 2964 rtnl_lock();
2949 2965
2950 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 2966 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
2951 if (err) 2967 if (err)
2952 goto out_rtnl; 2968 goto out_rtnl;
2953 2969
@@ -3069,14 +3085,16 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
3069 request->ie_len); 3085 request->ie_len);
3070 } 3086 }
3071 3087
3072 request->ifidx = dev->ifindex; 3088 request->dev = dev;
3073 request->wiphy = &rdev->wiphy; 3089 request->wiphy = &rdev->wiphy;
3074 3090
3075 rdev->scan_req = request; 3091 rdev->scan_req = request;
3076 err = rdev->ops->scan(&rdev->wiphy, dev, request); 3092 err = rdev->ops->scan(&rdev->wiphy, dev, request);
3077 3093
3078 if (!err) 3094 if (!err) {
3079 nl80211_send_scan_start(rdev, dev); 3095 nl80211_send_scan_start(rdev, dev);
3096 dev_hold(dev);
3097 }
3080 3098
3081 out_free: 3099 out_free:
3082 if (err) { 3100 if (err) {
@@ -3198,11 +3216,11 @@ static int nl80211_dump_scan(struct sk_buff *skb,
3198 cb->args[0] = ifidx; 3216 cb->args[0] = ifidx;
3199 } 3217 }
3200 3218
3201 dev = dev_get_by_index(&init_net, ifidx); 3219 dev = dev_get_by_index(sock_net(skb->sk), ifidx);
3202 if (!dev) 3220 if (!dev)
3203 return -ENODEV; 3221 return -ENODEV;
3204 3222
3205 rdev = cfg80211_get_dev_from_ifindex(ifidx); 3223 rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx);
3206 if (IS_ERR(rdev)) { 3224 if (IS_ERR(rdev)) {
3207 err = PTR_ERR(rdev); 3225 err = PTR_ERR(rdev);
3208 goto out_put_netdev; 3226 goto out_put_netdev;
@@ -3312,7 +3330,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3312 3330
3313 rtnl_lock(); 3331 rtnl_lock();
3314 3332
3315 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3333 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3316 if (err) 3334 if (err)
3317 goto unlock_rtnl; 3335 goto unlock_rtnl;
3318 3336
@@ -3369,6 +3387,8 @@ static int nl80211_crypto_settings(struct genl_info *info,
3369 struct cfg80211_crypto_settings *settings, 3387 struct cfg80211_crypto_settings *settings,
3370 int cipher_limit) 3388 int cipher_limit)
3371{ 3389{
3390 memset(settings, 0, sizeof(*settings));
3391
3372 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT]; 3392 settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT];
3373 3393
3374 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) { 3394 if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) {
@@ -3448,7 +3468,7 @@ static int nl80211_associate(struct sk_buff *skb, struct genl_info *info)
3448 3468
3449 rtnl_lock(); 3469 rtnl_lock();
3450 3470
3451 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3471 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3452 if (err) 3472 if (err)
3453 goto unlock_rtnl; 3473 goto unlock_rtnl;
3454 3474
@@ -3531,7 +3551,7 @@ static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info)
3531 3551
3532 rtnl_lock(); 3552 rtnl_lock();
3533 3553
3534 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3554 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3535 if (err) 3555 if (err)
3536 goto unlock_rtnl; 3556 goto unlock_rtnl;
3537 3557
@@ -3593,7 +3613,7 @@ static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info)
3593 3613
3594 rtnl_lock(); 3614 rtnl_lock();
3595 3615
3596 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3616 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3597 if (err) 3617 if (err)
3598 goto unlock_rtnl; 3618 goto unlock_rtnl;
3599 3619
@@ -3666,7 +3686,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3666 3686
3667 rtnl_lock(); 3687 rtnl_lock();
3668 3688
3669 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3689 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3670 if (err) 3690 if (err)
3671 goto unlock_rtnl; 3691 goto unlock_rtnl;
3672 3692
@@ -3739,7 +3759,7 @@ static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info)
3739 3759
3740 rtnl_lock(); 3760 rtnl_lock();
3741 3761
3742 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3762 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3743 if (err) 3763 if (err)
3744 goto unlock_rtnl; 3764 goto unlock_rtnl;
3745 3765
@@ -3924,7 +3944,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
3924 return err; 3944 return err;
3925 rtnl_lock(); 3945 rtnl_lock();
3926 3946
3927 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3947 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
3928 if (err) 3948 if (err)
3929 goto unlock_rtnl; 3949 goto unlock_rtnl;
3930 3950
@@ -4000,7 +4020,7 @@ static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info)
4000 4020
4001 rtnl_lock(); 4021 rtnl_lock();
4002 4022
4003 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 4023 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4004 if (err) 4024 if (err)
4005 goto unlock_rtnl; 4025 goto unlock_rtnl;
4006 4026
@@ -4024,6 +4044,47 @@ unlock_rtnl:
4024 return err; 4044 return err;
4025} 4045}
4026 4046
4047static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info)
4048{
4049 struct cfg80211_registered_device *rdev;
4050 struct net *net;
4051 int err;
4052 u32 pid;
4053
4054 if (!info->attrs[NL80211_ATTR_PID])
4055 return -EINVAL;
4056
4057 pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]);
4058
4059 rtnl_lock();
4060
4061 rdev = cfg80211_get_dev_from_info(info);
4062 if (IS_ERR(rdev)) {
4063 err = PTR_ERR(rdev);
4064 goto out;
4065 }
4066
4067 net = get_net_ns_by_pid(pid);
4068 if (IS_ERR(net)) {
4069 err = PTR_ERR(net);
4070 goto out;
4071 }
4072
4073 err = 0;
4074
4075 /* check if anything to do */
4076 if (net_eq(wiphy_net(&rdev->wiphy), net))
4077 goto out_put_net;
4078
4079 err = cfg80211_switch_netns(rdev, net);
4080 out_put_net:
4081 put_net(net);
4082 out:
4083 cfg80211_unlock_rdev(rdev);
4084 rtnl_unlock();
4085 return err;
4086}
4087
4027static struct genl_ops nl80211_ops[] = { 4088static struct genl_ops nl80211_ops[] = {
4028 { 4089 {
4029 .cmd = NL80211_CMD_GET_WIPHY, 4090 .cmd = NL80211_CMD_GET_WIPHY,
@@ -4257,6 +4318,12 @@ static struct genl_ops nl80211_ops[] = {
4257 .policy = nl80211_policy, 4318 .policy = nl80211_policy,
4258 .flags = GENL_ADMIN_PERM, 4319 .flags = GENL_ADMIN_PERM,
4259 }, 4320 },
4321 {
4322 .cmd = NL80211_CMD_SET_WIPHY_NETNS,
4323 .doit = nl80211_wiphy_netns,
4324 .policy = nl80211_policy,
4325 .flags = GENL_ADMIN_PERM,
4326 },
4260}; 4327};
4261static struct genl_multicast_group nl80211_mlme_mcgrp = { 4328static struct genl_multicast_group nl80211_mlme_mcgrp = {
4262 .name = "mlme", 4329 .name = "mlme",
@@ -4288,7 +4355,8 @@ void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev)
4288 return; 4355 return;
4289 } 4356 }
4290 4357
4291 genlmsg_multicast(msg, 0, nl80211_config_mcgrp.id, GFP_KERNEL); 4358 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4359 nl80211_config_mcgrp.id, GFP_KERNEL);
4292} 4360}
4293 4361
4294static int nl80211_add_scan_req(struct sk_buff *msg, 4362static int nl80211_add_scan_req(struct sk_buff *msg,
@@ -4365,7 +4433,8 @@ void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
4365 return; 4433 return;
4366 } 4434 }
4367 4435
4368 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4436 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4437 nl80211_scan_mcgrp.id, GFP_KERNEL);
4369} 4438}
4370 4439
4371void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, 4440void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
@@ -4383,7 +4452,8 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
4383 return; 4452 return;
4384 } 4453 }
4385 4454
4386 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4455 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4456 nl80211_scan_mcgrp.id, GFP_KERNEL);
4387} 4457}
4388 4458
4389void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, 4459void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
@@ -4401,7 +4471,8 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
4401 return; 4471 return;
4402 } 4472 }
4403 4473
4404 genlmsg_multicast(msg, 0, nl80211_scan_mcgrp.id, GFP_KERNEL); 4474 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4475 nl80211_scan_mcgrp.id, GFP_KERNEL);
4405} 4476}
4406 4477
4407/* 4478/*
@@ -4450,7 +4521,10 @@ void nl80211_send_reg_change_event(struct regulatory_request *request)
4450 return; 4521 return;
4451 } 4522 }
4452 4523
4453 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_KERNEL); 4524 rcu_read_lock();
4525 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
4526 GFP_ATOMIC);
4527 rcu_read_unlock();
4454 4528
4455 return; 4529 return;
4456 4530
@@ -4486,7 +4560,8 @@ static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev,
4486 return; 4560 return;
4487 } 4561 }
4488 4562
4489 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4563 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4564 nl80211_mlme_mcgrp.id, gfp);
4490 return; 4565 return;
4491 4566
4492 nla_put_failure: 4567 nla_put_failure:
@@ -4553,7 +4628,8 @@ static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev,
4553 return; 4628 return;
4554 } 4629 }
4555 4630
4556 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4631 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4632 nl80211_mlme_mcgrp.id, gfp);
4557 return; 4633 return;
4558 4634
4559 nla_put_failure: 4635 nla_put_failure:
@@ -4611,7 +4687,8 @@ void nl80211_send_connect_result(struct cfg80211_registered_device *rdev,
4611 return; 4687 return;
4612 } 4688 }
4613 4689
4614 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4690 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4691 nl80211_mlme_mcgrp.id, gfp);
4615 return; 4692 return;
4616 4693
4617 nla_put_failure: 4694 nla_put_failure:
@@ -4651,7 +4728,8 @@ void nl80211_send_roamed(struct cfg80211_registered_device *rdev,
4651 return; 4728 return;
4652 } 4729 }
4653 4730
4654 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4731 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4732 nl80211_mlme_mcgrp.id, gfp);
4655 return; 4733 return;
4656 4734
4657 nla_put_failure: 4735 nla_put_failure:
@@ -4691,7 +4769,8 @@ void nl80211_send_disconnected(struct cfg80211_registered_device *rdev,
4691 return; 4769 return;
4692 } 4770 }
4693 4771
4694 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, GFP_KERNEL); 4772 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4773 nl80211_mlme_mcgrp.id, GFP_KERNEL);
4695 return; 4774 return;
4696 4775
4697 nla_put_failure: 4776 nla_put_failure:
@@ -4726,7 +4805,8 @@ void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev,
4726 return; 4805 return;
4727 } 4806 }
4728 4807
4729 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4808 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4809 nl80211_mlme_mcgrp.id, gfp);
4730 return; 4810 return;
4731 4811
4732 nla_put_failure: 4812 nla_put_failure:
@@ -4766,7 +4846,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev,
4766 return; 4846 return;
4767 } 4847 }
4768 4848
4769 genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); 4849 genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
4850 nl80211_mlme_mcgrp.id, gfp);
4770 return; 4851 return;
4771 4852
4772 nla_put_failure: 4853 nla_put_failure:
@@ -4819,7 +4900,10 @@ void nl80211_send_beacon_hint_event(struct wiphy *wiphy,
4819 return; 4900 return;
4820 } 4901 }
4821 4902
4822 genlmsg_multicast(msg, 0, nl80211_regulatory_mcgrp.id, GFP_ATOMIC); 4903 rcu_read_lock();
4904 genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id,
4905 GFP_ATOMIC);
4906 rcu_read_unlock();
4823 4907
4824 return; 4908 return;
4825 4909
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index decc59fe0ee8..67714d7ed5b4 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -14,8 +14,9 @@
14#include <net/iw_handler.h> 14#include <net/iw_handler.h>
15#include "core.h" 15#include "core.h"
16#include "nl80211.h" 16#include "nl80211.h"
17#include "wext-compat.h"
17 18
18#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) 19#define IEEE80211_SCAN_RESULT_EXPIRE (15 * HZ)
19 20
20void __cfg80211_scan_done(struct work_struct *wk) 21void __cfg80211_scan_done(struct work_struct *wk)
21{ 22{
@@ -32,9 +33,7 @@ void __cfg80211_scan_done(struct work_struct *wk)
32 mutex_lock(&rdev->mtx); 33 mutex_lock(&rdev->mtx);
33 request = rdev->scan_req; 34 request = rdev->scan_req;
34 35
35 dev = dev_get_by_index(&init_net, request->ifidx); 36 dev = request->dev;
36 if (!dev)
37 goto out;
38 37
39 /* 38 /*
40 * This must be before sending the other events! 39 * This must be before sending the other events!
@@ -58,7 +57,6 @@ void __cfg80211_scan_done(struct work_struct *wk)
58 57
59 dev_put(dev); 58 dev_put(dev);
60 59
61 out:
62 cfg80211_unlock_rdev(rdev); 60 cfg80211_unlock_rdev(rdev);
63 wiphy_to_dev(request->wiphy)->scan_req = NULL; 61 wiphy_to_dev(request->wiphy)->scan_req = NULL;
64 kfree(request); 62 kfree(request);
@@ -66,17 +64,10 @@ void __cfg80211_scan_done(struct work_struct *wk)
66 64
67void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) 65void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
68{ 66{
69 struct net_device *dev = dev_get_by_index(&init_net, request->ifidx);
70 if (WARN_ON(!dev)) {
71 kfree(request);
72 return;
73 }
74
75 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); 67 WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req);
76 68
77 request->aborted = aborted; 69 request->aborted = aborted;
78 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk); 70 schedule_work(&wiphy_to_dev(request->wiphy)->scan_done_wk);
79 dev_put(dev);
80} 71}
81EXPORT_SYMBOL(cfg80211_scan_done); 72EXPORT_SYMBOL(cfg80211_scan_done);
82 73
@@ -592,7 +583,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
592 if (!netif_running(dev)) 583 if (!netif_running(dev))
593 return -ENETDOWN; 584 return -ENETDOWN;
594 585
595 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex); 586 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
596 587
597 if (IS_ERR(rdev)) 588 if (IS_ERR(rdev))
598 return PTR_ERR(rdev); 589 return PTR_ERR(rdev);
@@ -617,7 +608,7 @@ int cfg80211_wext_siwscan(struct net_device *dev,
617 } 608 }
618 609
619 creq->wiphy = wiphy; 610 creq->wiphy = wiphy;
620 creq->ifidx = dev->ifindex; 611 creq->dev = dev;
621 creq->ssids = (void *)(creq + 1); 612 creq->ssids = (void *)(creq + 1);
622 creq->channels = (void *)(creq->ssids + 1); 613 creq->channels = (void *)(creq->ssids + 1);
623 creq->n_channels = n_channels; 614 creq->n_channels = n_channels;
@@ -654,8 +645,10 @@ int cfg80211_wext_siwscan(struct net_device *dev,
654 if (err) { 645 if (err) {
655 rdev->scan_req = NULL; 646 rdev->scan_req = NULL;
656 kfree(creq); 647 kfree(creq);
657 } else 648 } else {
658 nl80211_send_scan_start(rdev, dev); 649 nl80211_send_scan_start(rdev, dev);
650 dev_hold(dev);
651 }
659 out: 652 out:
660 cfg80211_unlock_rdev(rdev); 653 cfg80211_unlock_rdev(rdev);
661 return err; 654 return err;
@@ -948,7 +941,7 @@ int cfg80211_wext_giwscan(struct net_device *dev,
948 if (!netif_running(dev)) 941 if (!netif_running(dev))
949 return -ENETDOWN; 942 return -ENETDOWN;
950 943
951 rdev = cfg80211_get_dev_from_ifindex(dev->ifindex); 944 rdev = cfg80211_get_dev_from_ifindex(dev_net(dev), dev->ifindex);
952 945
953 if (IS_ERR(rdev)) 946 if (IS_ERR(rdev))
954 return PTR_ERR(rdev); 947 return PTR_ERR(rdev);
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 82de2d9795f4..d2b5d4ce0a00 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -8,6 +8,8 @@
8#include <linux/etherdevice.h> 8#include <linux/etherdevice.h>
9#include <linux/if_arp.h> 9#include <linux/if_arp.h>
10#include <linux/workqueue.h> 10#include <linux/workqueue.h>
11#include <linux/wireless.h>
12#include <net/iw_handler.h>
11#include <net/cfg80211.h> 13#include <net/cfg80211.h>
12#include <net/rtnetlink.h> 14#include <net/rtnetlink.h>
13#include "nl80211.h" 15#include "nl80211.h"
@@ -86,7 +88,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
86 wdev->conn->params.ssid_len); 88 wdev->conn->params.ssid_len);
87 request->ssids[0].ssid_len = wdev->conn->params.ssid_len; 89 request->ssids[0].ssid_len = wdev->conn->params.ssid_len;
88 90
89 request->ifidx = wdev->netdev->ifindex; 91 request->dev = wdev->netdev;
90 request->wiphy = &rdev->wiphy; 92 request->wiphy = &rdev->wiphy;
91 93
92 rdev->scan_req = request; 94 rdev->scan_req = request;
@@ -95,6 +97,7 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
95 if (!err) { 97 if (!err) {
96 wdev->conn->state = CFG80211_CONN_SCANNING; 98 wdev->conn->state = CFG80211_CONN_SCANNING;
97 nl80211_send_scan_start(rdev, wdev->netdev); 99 nl80211_send_scan_start(rdev, wdev->netdev);
100 dev_hold(wdev->netdev);
98 } else { 101 } else {
99 rdev->scan_req = NULL; 102 rdev->scan_req = NULL;
100 kfree(request); 103 kfree(request);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index c7351a98e660..e4e90e249bab 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -14,6 +14,7 @@
14#include <linux/etherdevice.h> 14#include <linux/etherdevice.h>
15#include <net/iw_handler.h> 15#include <net/iw_handler.h>
16#include <net/cfg80211.h> 16#include <net/cfg80211.h>
17#include "wext-compat.h"
17#include "core.h" 18#include "core.h"
18 19
19int cfg80211_wext_giwname(struct net_device *dev, 20int cfg80211_wext_giwname(struct net_device *dev,
@@ -300,7 +301,6 @@ struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
300 return ERR_PTR(-EINVAL); 301 return ERR_PTR(-EINVAL);
301 return chan; 302 return chan;
302} 303}
303EXPORT_SYMBOL_GPL(cfg80211_wext_freq);
304 304
305int cfg80211_wext_siwrts(struct net_device *dev, 305int cfg80211_wext_siwrts(struct net_device *dev,
306 struct iw_request_info *info, 306 struct iw_request_info *info,
@@ -759,6 +759,58 @@ int cfg80211_wext_giwencode(struct net_device *dev,
759} 759}
760EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); 760EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
761 761
762int cfg80211_wext_siwfreq(struct net_device *dev,
763 struct iw_request_info *info,
764 struct iw_freq *freq, char *extra)
765{
766 struct wireless_dev *wdev = dev->ieee80211_ptr;
767 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
768 struct ieee80211_channel *chan;
769 int err;
770
771 switch (wdev->iftype) {
772 case NL80211_IFTYPE_STATION:
773 return cfg80211_mgd_wext_siwfreq(dev, info, freq, extra);
774 case NL80211_IFTYPE_ADHOC:
775 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
776 default:
777 chan = cfg80211_wext_freq(wdev->wiphy, freq);
778 if (!chan)
779 return -EINVAL;
780 if (IS_ERR(chan))
781 return PTR_ERR(chan);
782 err = rdev->ops->set_channel(wdev->wiphy, chan,
783 NL80211_CHAN_NO_HT);
784 if (err)
785 return err;
786 rdev->channel = chan;
787 return 0;
788 }
789}
790EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
791
792int cfg80211_wext_giwfreq(struct net_device *dev,
793 struct iw_request_info *info,
794 struct iw_freq *freq, char *extra)
795{
796 struct wireless_dev *wdev = dev->ieee80211_ptr;
797 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
798
799 switch (wdev->iftype) {
800 case NL80211_IFTYPE_STATION:
801 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
802 case NL80211_IFTYPE_ADHOC:
803 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
804 default:
805 if (!rdev->channel)
806 return -EINVAL;
807 freq->m = rdev->channel->center_freq;
808 freq->e = 6;
809 return 0;
810 }
811}
812EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
813
762int cfg80211_wext_siwtxpower(struct net_device *dev, 814int cfg80211_wext_siwtxpower(struct net_device *dev,
763 struct iw_request_info *info, 815 struct iw_request_info *info,
764 union iwreq_data *data, char *extra) 816 union iwreq_data *data, char *extra)
@@ -1097,9 +1149,9 @@ int cfg80211_wext_giwpower(struct net_device *dev,
1097} 1149}
1098EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); 1150EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
1099 1151
1100int cfg80211_wds_wext_siwap(struct net_device *dev, 1152static int cfg80211_wds_wext_siwap(struct net_device *dev,
1101 struct iw_request_info *info, 1153 struct iw_request_info *info,
1102 struct sockaddr *addr, char *extra) 1154 struct sockaddr *addr, char *extra)
1103{ 1155{
1104 struct wireless_dev *wdev = dev->ieee80211_ptr; 1156 struct wireless_dev *wdev = dev->ieee80211_ptr;
1105 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1157 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1125,11 +1177,10 @@ int cfg80211_wds_wext_siwap(struct net_device *dev,
1125 1177
1126 return 0; 1178 return 0;
1127} 1179}
1128EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap);
1129 1180
1130int cfg80211_wds_wext_giwap(struct net_device *dev, 1181static int cfg80211_wds_wext_giwap(struct net_device *dev,
1131 struct iw_request_info *info, 1182 struct iw_request_info *info,
1132 struct sockaddr *addr, char *extra) 1183 struct sockaddr *addr, char *extra)
1133{ 1184{
1134 struct wireless_dev *wdev = dev->ieee80211_ptr; 1185 struct wireless_dev *wdev = dev->ieee80211_ptr;
1135 1186
@@ -1141,7 +1192,6 @@ int cfg80211_wds_wext_giwap(struct net_device *dev,
1141 1192
1142 return 0; 1193 return 0;
1143} 1194}
1144EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap);
1145 1195
1146int cfg80211_wext_siwrate(struct net_device *dev, 1196int cfg80211_wext_siwrate(struct net_device *dev,
1147 struct iw_request_info *info, 1197 struct iw_request_info *info,
@@ -1275,3 +1325,115 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1275 return &wstats; 1325 return &wstats;
1276} 1326}
1277EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); 1327EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
1328
1329int cfg80211_wext_siwap(struct net_device *dev,
1330 struct iw_request_info *info,
1331 struct sockaddr *ap_addr, char *extra)
1332{
1333 struct wireless_dev *wdev = dev->ieee80211_ptr;
1334
1335 switch (wdev->iftype) {
1336 case NL80211_IFTYPE_ADHOC:
1337 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
1338 case NL80211_IFTYPE_STATION:
1339 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
1340 case NL80211_IFTYPE_WDS:
1341 return cfg80211_wds_wext_siwap(dev, info, ap_addr, extra);
1342 default:
1343 return -EOPNOTSUPP;
1344 }
1345}
1346EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
1347
1348int cfg80211_wext_giwap(struct net_device *dev,
1349 struct iw_request_info *info,
1350 struct sockaddr *ap_addr, char *extra)
1351{
1352 struct wireless_dev *wdev = dev->ieee80211_ptr;
1353
1354 switch (wdev->iftype) {
1355 case NL80211_IFTYPE_ADHOC:
1356 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
1357 case NL80211_IFTYPE_STATION:
1358 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
1359 case NL80211_IFTYPE_WDS:
1360 return cfg80211_wds_wext_giwap(dev, info, ap_addr, extra);
1361 default:
1362 return -EOPNOTSUPP;
1363 }
1364}
1365EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
1366
1367int cfg80211_wext_siwessid(struct net_device *dev,
1368 struct iw_request_info *info,
1369 struct iw_point *data, char *ssid)
1370{
1371 struct wireless_dev *wdev = dev->ieee80211_ptr;
1372
1373 switch (wdev->iftype) {
1374 case NL80211_IFTYPE_ADHOC:
1375 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
1376 case NL80211_IFTYPE_STATION:
1377 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
1378 default:
1379 return -EOPNOTSUPP;
1380 }
1381}
1382EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
1383
1384int cfg80211_wext_giwessid(struct net_device *dev,
1385 struct iw_request_info *info,
1386 struct iw_point *data, char *ssid)
1387{
1388 struct wireless_dev *wdev = dev->ieee80211_ptr;
1389
1390 switch (wdev->iftype) {
1391 case NL80211_IFTYPE_ADHOC:
1392 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
1393 case NL80211_IFTYPE_STATION:
1394 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
1395 default:
1396 return -EOPNOTSUPP;
1397 }
1398}
1399EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
1400
1401static const iw_handler cfg80211_handlers[] = {
1402 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
1403 [IW_IOCTL_IDX(SIOCSIWFREQ)] = (iw_handler) cfg80211_wext_siwfreq,
1404 [IW_IOCTL_IDX(SIOCGIWFREQ)] = (iw_handler) cfg80211_wext_giwfreq,
1405 [IW_IOCTL_IDX(SIOCSIWMODE)] = (iw_handler) cfg80211_wext_siwmode,
1406 [IW_IOCTL_IDX(SIOCGIWMODE)] = (iw_handler) cfg80211_wext_giwmode,
1407 [IW_IOCTL_IDX(SIOCGIWRANGE)] = (iw_handler) cfg80211_wext_giwrange,
1408 [IW_IOCTL_IDX(SIOCSIWAP)] = (iw_handler) cfg80211_wext_siwap,
1409 [IW_IOCTL_IDX(SIOCGIWAP)] = (iw_handler) cfg80211_wext_giwap,
1410 [IW_IOCTL_IDX(SIOCSIWMLME)] = (iw_handler) cfg80211_wext_siwmlme,
1411 [IW_IOCTL_IDX(SIOCSIWSCAN)] = (iw_handler) cfg80211_wext_siwscan,
1412 [IW_IOCTL_IDX(SIOCGIWSCAN)] = (iw_handler) cfg80211_wext_giwscan,
1413 [IW_IOCTL_IDX(SIOCSIWESSID)] = (iw_handler) cfg80211_wext_siwessid,
1414 [IW_IOCTL_IDX(SIOCGIWESSID)] = (iw_handler) cfg80211_wext_giwessid,
1415 [IW_IOCTL_IDX(SIOCSIWRATE)] = (iw_handler) cfg80211_wext_siwrate,
1416 [IW_IOCTL_IDX(SIOCGIWRATE)] = (iw_handler) cfg80211_wext_giwrate,
1417 [IW_IOCTL_IDX(SIOCSIWRTS)] = (iw_handler) cfg80211_wext_siwrts,
1418 [IW_IOCTL_IDX(SIOCGIWRTS)] = (iw_handler) cfg80211_wext_giwrts,
1419 [IW_IOCTL_IDX(SIOCSIWFRAG)] = (iw_handler) cfg80211_wext_siwfrag,
1420 [IW_IOCTL_IDX(SIOCGIWFRAG)] = (iw_handler) cfg80211_wext_giwfrag,
1421 [IW_IOCTL_IDX(SIOCSIWTXPOW)] = (iw_handler) cfg80211_wext_siwtxpower,
1422 [IW_IOCTL_IDX(SIOCGIWTXPOW)] = (iw_handler) cfg80211_wext_giwtxpower,
1423 [IW_IOCTL_IDX(SIOCSIWRETRY)] = (iw_handler) cfg80211_wext_siwretry,
1424 [IW_IOCTL_IDX(SIOCGIWRETRY)] = (iw_handler) cfg80211_wext_giwretry,
1425 [IW_IOCTL_IDX(SIOCSIWENCODE)] = (iw_handler) cfg80211_wext_siwencode,
1426 [IW_IOCTL_IDX(SIOCGIWENCODE)] = (iw_handler) cfg80211_wext_giwencode,
1427 [IW_IOCTL_IDX(SIOCSIWPOWER)] = (iw_handler) cfg80211_wext_siwpower,
1428 [IW_IOCTL_IDX(SIOCGIWPOWER)] = (iw_handler) cfg80211_wext_giwpower,
1429 [IW_IOCTL_IDX(SIOCSIWGENIE)] = (iw_handler) cfg80211_wext_siwgenie,
1430 [IW_IOCTL_IDX(SIOCSIWAUTH)] = (iw_handler) cfg80211_wext_siwauth,
1431 [IW_IOCTL_IDX(SIOCGIWAUTH)] = (iw_handler) cfg80211_wext_giwauth,
1432 [IW_IOCTL_IDX(SIOCSIWENCODEEXT)]= (iw_handler) cfg80211_wext_siwencodeext,
1433};
1434
1435const struct iw_handler_def cfg80211_wext_handler = {
1436 .num_standard = ARRAY_SIZE(cfg80211_handlers),
1437 .standard = cfg80211_handlers,
1438 .get_wireless_stats = cfg80211_wireless_stats,
1439};
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h
new file mode 100644
index 000000000000..9a3774749589
--- /dev/null
+++ b/net/wireless/wext-compat.h
@@ -0,0 +1,50 @@
1#ifndef __WEXT_COMPAT
2#define __WEXT_COMPAT
3
4#include <net/iw_handler.h>
5#include <linux/wireless.h>
6
7int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
8 struct iw_request_info *info,
9 struct iw_freq *freq, char *extra);
10int cfg80211_ibss_wext_giwfreq(struct net_device *dev,
11 struct iw_request_info *info,
12 struct iw_freq *freq, char *extra);
13int cfg80211_ibss_wext_siwap(struct net_device *dev,
14 struct iw_request_info *info,
15 struct sockaddr *ap_addr, char *extra);
16int cfg80211_ibss_wext_giwap(struct net_device *dev,
17 struct iw_request_info *info,
18 struct sockaddr *ap_addr, char *extra);
19int cfg80211_ibss_wext_siwessid(struct net_device *dev,
20 struct iw_request_info *info,
21 struct iw_point *data, char *ssid);
22int cfg80211_ibss_wext_giwessid(struct net_device *dev,
23 struct iw_request_info *info,
24 struct iw_point *data, char *ssid);
25
26int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
27 struct iw_request_info *info,
28 struct iw_freq *freq, char *extra);
29int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
30 struct iw_request_info *info,
31 struct iw_freq *freq, char *extra);
32int cfg80211_mgd_wext_siwap(struct net_device *dev,
33 struct iw_request_info *info,
34 struct sockaddr *ap_addr, char *extra);
35int cfg80211_mgd_wext_giwap(struct net_device *dev,
36 struct iw_request_info *info,
37 struct sockaddr *ap_addr, char *extra);
38int cfg80211_mgd_wext_siwessid(struct net_device *dev,
39 struct iw_request_info *info,
40 struct iw_point *data, char *ssid);
41int cfg80211_mgd_wext_giwessid(struct net_device *dev,
42 struct iw_request_info *info,
43 struct iw_point *data, char *ssid);
44
45struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
46 struct iw_freq *freq);
47
48
49extern const struct iw_handler_def cfg80211_wext_handler;
50#endif /* __WEXT_COMPAT */
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 4c689fd865b0..7bacbd1c2af6 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -8,6 +8,7 @@
8#include <linux/etherdevice.h> 8#include <linux/etherdevice.h>
9#include <linux/if_arp.h> 9#include <linux/if_arp.h>
10#include <net/cfg80211.h> 10#include <net/cfg80211.h>
11#include "wext-compat.h"
11#include "nl80211.h" 12#include "nl80211.h"
12 13
13int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 14int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
@@ -108,8 +109,6 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
108 cfg80211_unlock_rdev(rdev); 109 cfg80211_unlock_rdev(rdev);
109 return err; 110 return err;
110} 111}
111/* temporary symbol - mark GPL - in the future the handler won't be */
112EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwfreq);
113 112
114int cfg80211_mgd_wext_giwfreq(struct net_device *dev, 113int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
115 struct iw_request_info *info, 114 struct iw_request_info *info,
@@ -138,8 +137,6 @@ int cfg80211_mgd_wext_giwfreq(struct net_device *dev,
138 /* no channel if not joining */ 137 /* no channel if not joining */
139 return -EINVAL; 138 return -EINVAL;
140} 139}
141/* temporary symbol - mark GPL - in the future the handler won't be */
142EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwfreq);
143 140
144int cfg80211_mgd_wext_siwessid(struct net_device *dev, 141int cfg80211_mgd_wext_siwessid(struct net_device *dev,
145 struct iw_request_info *info, 142 struct iw_request_info *info,
@@ -195,8 +192,6 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
195 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); 192 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy));
196 return err; 193 return err;
197} 194}
198/* temporary symbol - mark GPL - in the future the handler won't be */
199EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwessid);
200 195
201int cfg80211_mgd_wext_giwessid(struct net_device *dev, 196int cfg80211_mgd_wext_giwessid(struct net_device *dev,
202 struct iw_request_info *info, 197 struct iw_request_info *info,
@@ -221,8 +216,6 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
221 216
222 return 0; 217 return 0;
223} 218}
224/* temporary symbol - mark GPL - in the future the handler won't be */
225EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwessid);
226 219
227int cfg80211_mgd_wext_siwap(struct net_device *dev, 220int cfg80211_mgd_wext_siwap(struct net_device *dev,
228 struct iw_request_info *info, 221 struct iw_request_info *info,
@@ -276,8 +269,6 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
276 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy)); 269 cfg80211_unlock_rdev(wiphy_to_dev(wdev->wiphy));
277 return err; 270 return err;
278} 271}
279/* temporary symbol - mark GPL - in the future the handler won't be */
280EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwap);
281 272
282int cfg80211_mgd_wext_giwap(struct net_device *dev, 273int cfg80211_mgd_wext_giwap(struct net_device *dev,
283 struct iw_request_info *info, 274 struct iw_request_info *info,
@@ -302,8 +293,6 @@ int cfg80211_mgd_wext_giwap(struct net_device *dev,
302 293
303 return 0; 294 return 0;
304} 295}
305/* temporary symbol - mark GPL - in the future the handler won't be */
306EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwap);
307 296
308int cfg80211_wext_siwgenie(struct net_device *dev, 297int cfg80211_wext_siwgenie(struct net_device *dev,
309 struct iw_request_info *info, 298 struct iw_request_info *info,