diff options
author | David S. Miller <davem@davemloft.net> | 2009-07-30 22:26:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-07-30 22:26:55 -0400 |
commit | 2f6d7c1b34403b97fa57473edcb6749d1db5ace3 (patch) | |
tree | 97da33c077b08b72a361ff5a4542b86d190b0164 | |
parent | df597efb5737063497f1a4f7c996cc9aec294230 (diff) | |
parent | 1e4247d457c6a42e4a05cb7dfa4e6ea1fa65c112 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
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, | |||
365 | void ath_tx_tasklet(struct ath_softc *sc); | 361 | void ath_tx_tasklet(struct ath_softc *sc); |
366 | void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); | 362 | void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); |
367 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); | 363 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); |
368 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 364 | void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
369 | u16 tid, u16 *ssn); | 365 | u16 tid, u16 *ssn); |
370 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 366 | void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); |
371 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid); | 367 | void 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 | |||
499 | static 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 | |||
533 | void 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 | |||
561 | static const struct file_operations fops_xmit = { | ||
562 | .read = read_file_xmit, | ||
563 | .open = ath9k_debugfs_open, | ||
564 | .owner = THIS_MODULE | ||
565 | }; | ||
489 | 566 | ||
490 | int ath9k_init_debug(struct ath_softc *sc) | 567 | int 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; |
533 | err: | 617 | err: |
534 | ath9k_exit_debug(sc); | 618 | ath9k_exit_debug(sc); |
@@ -537,6 +621,7 @@ err: | |||
537 | 621 | ||
538 | void ath9k_exit_debug(struct ath_softc *sc) | 622 | void 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 | ||
38 | struct ath_txq; | ||
39 | struct 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 | */ | ||
118 | struct 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 | |||
90 | struct ath_stats { | 134 | struct 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 | ||
95 | struct ath9k_debug { | 140 | struct 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); | |||
110 | void ath9k_debug_remove_root(void); | 156 | void ath9k_debug_remove_root(void); |
111 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 157 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
112 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); | 158 | void ath_debug_stat_rc(struct ath_softc *sc, struct sk_buff *skb); |
159 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | ||
160 | struct ath_buf *bf); | ||
113 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 161 | void 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 | ||
199 | static inline void ath_debug_stat_tx(struct ath_softc *sc, | ||
200 | struct ath_txq *txq, | ||
201 | struct ath_buf *bf) | ||
202 | { | ||
203 | } | ||
204 | |||
151 | static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 205 | static 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 | |||
2785 | static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) | ||
2786 | { | ||
2787 | return (ah->eeprom.map9287.baseEepHeader.version >> 12) & 0xF; | ||
2788 | } | ||
2789 | |||
2790 | static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah) | ||
2791 | { | ||
2792 | return (ah->eeprom.map9287.baseEepHeader.version) & 0xFFF; | ||
2793 | } | ||
2794 | |||
2795 | static 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 | } | ||
2817 | static 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 | |||
2920 | static 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 | |||
2974 | static 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, ¢ers); | ||
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 | |||
3129 | static 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, ¢ers); | ||
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 | |||
3164 | static 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 | |||
3198 | static 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 | |||
3356 | static 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, ¢ers); | ||
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 | |||
3609 | static 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 | |||
3770 | static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah, | ||
3771 | struct ath9k_channel *chan) | ||
3772 | { | ||
3773 | return; | ||
3774 | } | ||
3775 | |||
3776 | static 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 | |||
3919 | static 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 | |||
3928 | static 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 | |||
3937 | static 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 | |||
3966 | static 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 | |||
2784 | int ath9k_hw_eeprom_attach(struct ath_hw *ah) | 3981 | int 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 | |||
179 | enum eeprom_param { | 232 | enum 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 | ||
205 | enum ar5416_rates { | 262 | enum 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 | ||
428 | struct 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 | |||
450 | struct 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 | ||
372 | struct cal_data_per_freq { | 488 | struct 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 | ||
521 | struct 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 | |||
529 | struct 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 | |||
534 | union 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 | |||
539 | struct cal_ctl_data_ar9287 { | ||
540 | struct cal_ctl_edges | ||
541 | ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES]; | ||
542 | } __packed; | ||
543 | |||
405 | struct cal_ctl_data { | 544 | struct 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 | ||
603 | struct 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 | |||
464 | enum reg_ext_bitmap { | 624 | enum 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 { | |||
480 | enum ath9k_eep_map { | 640 | enum 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 */ | ||
4854 | static 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 | |||
4901 | static 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 | |||
5272 | static 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 | |||
5322 | static 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 | |||
5584 | static 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 | |||
5597 | static 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 | |||
5612 | static 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 | |||
5659 | static 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 | |||
6030 | static 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 | |||
6079 | static 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 | |||
6341 | static 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 | |||
6354 | static 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 | |||
22 | static char *dev_info = "ath9k"; | 20 | static char *dev_info = "ath9k"; |
23 | 21 | ||
24 | MODULE_AUTHOR("Atheros Communications"); | 22 | MODULE_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) | |||
888 | static void setup_ht_cap(struct ath_softc *sc, | 885 | static 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 | ||
2767 | static struct { | 2756 | static 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); |
61 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 61 | static 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); |
64 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 65 | static 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 | ||
223 | static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) | 224 | static 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 | */ |
512 | static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | 513 | static 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 | ||
575 | static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | 574 | static 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 | ||
698 | int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 700 | void 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 | ||
716 | int ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 713 | void 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 | ||
763 | void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | 758 | void 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 | ||
1286 | static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq, | 1281 | static 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 | ||
1299 | static enum ath9k_pkt_type get_hw_packet_type(struct sk_buff *skb) | 1295 | static 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 | ||
1821 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1817 | static 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 | ||
2040 | void ath_tx_complete_poll_work(struct work_struct *work) | 2037 | static 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 | |||
9 | config IWLWIFI_LEDS | 9 | config 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 | ||
13 | config IWLWIFI_SPECTRUM_MEASUREMENT | 16 | config 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 | */ | ||
69 | static 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 | |||
76 | static 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 | |||
126 | static struct iwl_ops iwl1000_ops = { | ||
127 | .ucode = &iwl5000_ucode, | ||
128 | .lib = &iwl1000_lib, | ||
129 | .hcmd = &iwl5000_hcmd, | ||
130 | .utils = &iwl5000_hcmd_utils, | ||
131 | }; | ||
132 | |||
58 | struct iwl_cfg iwl1000_bgn_cfg = { | 133 | struct 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 | ||
82 | static int iwl3945_led_cmd_callback(struct iwl_priv *priv, | 82 | static 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 | ||
89 | static inline int iwl3945_brightness_to_idx(enum led_brightness brightness) | 88 | static 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 | */ |
777 | void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, | 777 | void 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); |
255 | extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv, | 255 | extern 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); |
257 | void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd, | 257 | void 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); | ||
261 | extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); | 262 | extern int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv); |
262 | extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); | 263 | extern int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power); |
263 | extern void iwl3945_hw_rx_statistics(struct iwl_priv *priv, | 264 | extern 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 = { | |||
776 | static void iwl4965_set_ct_threshold(struct iwl_priv *priv) | 776 | static 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 | ||
94 | static int iwl5000_apm_init(struct iwl_priv *priv) | 94 | int 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 */ |
140 | static void iwl5000_apm_stop(struct iwl_priv *priv) | 140 | void 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 | ||
159 | static int iwl5000_apm_reset(struct iwl_priv *priv) | 159 | int 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 | ||
201 | static void iwl5000_nic_config(struct iwl_priv *priv) | 201 | void 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 | ||
293 | static u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv) | 293 | u16 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 | ||
439 | static const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | 439 | const 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, | |||
447 | static void iwl5150_set_ct_threshold(struct iwl_priv *priv) | 447 | static 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) | |||
456 | static void iwl5000_set_ct_threshold(struct iwl_priv *priv) | 456 | static 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 | ||
634 | static int iwl5000_load_ucode(struct iwl_priv *priv) | 634 | int 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 | ||
661 | static void iwl5000_init_alive_start(struct iwl_priv *priv) | 661 | void 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 | ||
737 | static int iwl5000_alive_notify(struct iwl_priv *priv) | 737 | int 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 | ||
824 | static int iwl5000_hw_set_hw_params(struct iwl_priv *priv) | 824 | int 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 | */ |
895 | static void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | 895 | void 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 | ||
935 | static void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, | 935 | void 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 | ||
990 | static int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, | 990 | int 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 | ||
1051 | static int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | 1051 | int 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 | */ |
1094 | static void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask) | 1094 | void 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 | ||
1315 | static void iwl5000_setup_deferred_work(struct iwl_priv *priv) | 1315 | void 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 | ||
1321 | static void iwl5000_rx_handler_setup(struct iwl_priv *priv) | 1321 | void 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 | ||
1332 | static int iwl5000_hw_valid_rtc_data_addr(u32 addr) | 1332 | int 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 | } |
1384 | static int iwl5000_send_tx_power(struct iwl_priv *priv) | 1384 | int 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 | ||
1404 | static void iwl5000_temperature(struct iwl_priv *priv) | 1404 | void 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 | ||
1410 | static void iwl5150_temperature(struct iwl_priv *priv) | 1411 | static 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 | ||
64 | static 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 | |||
71 | static 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 | |||
64 | static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = { | 121 | static 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 | ||
71 | static struct iwl_ops iwl6000_ops = { | 128 | static 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); |
180 | static void rs_fill_link_cmd(const struct iwl_priv *priv, | 180 | static 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 | */ | ||
2032 | static 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 | */ |
2008 | static void rs_rate_scale_perform(struct iwl_priv *priv, | 2050 | static 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 | ||
2309 | lq_update: | 2365 | lq_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 | ||
2662 | static void rs_fill_link_cmd(const struct iwl_priv *priv, | 2719 | static 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 */ | ||
2417 | struct 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 | ||
1296 | static const char *desc_lookup_text[] = { | 1299 | static 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); | |||
2224 | void iwl_rf_kill_ct_config(struct iwl_priv *priv) | 2228 | void 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); |
447 | int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len, | 447 | int 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 | ||
453 | int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd); | 453 | int 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 | ||
621 | static 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 | |||
656 | static 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 | |||
682 | static 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 | |||
621 | DEBUGFS_READ_WRITE_FILE_OPS(sram); | 699 | DEBUGFS_READ_WRITE_FILE_OPS(sram); |
622 | DEBUGFS_WRITE_FILE_OPS(log_event); | 700 | DEBUGFS_WRITE_FILE_OPS(log_event); |
623 | DEBUGFS_READ_FILE_OPS(nvm); | 701 | DEBUGFS_READ_FILE_OPS(nvm); |
@@ -631,6 +709,8 @@ DEBUGFS_READ_FILE_OPS(qos); | |||
631 | #ifdef CONFIG_IWLWIFI_LEDS | 709 | #ifdef CONFIG_IWLWIFI_LEDS |
632 | DEBUGFS_READ_FILE_OPS(led); | 710 | DEBUGFS_READ_FILE_OPS(led); |
633 | #endif | 711 | #endif |
712 | DEBUGFS_READ_FILE_OPS(thermal_throttling); | ||
713 | DEBUGFS_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; | |||
63 | extern struct iwl_cfg iwl6050_3agn_cfg; | 63 | extern struct iwl_cfg iwl6050_3agn_cfg; |
64 | extern struct iwl_cfg iwl1000_bgn_cfg; | 64 | extern struct iwl_cfg iwl1000_bgn_cfg; |
65 | 65 | ||
66 | struct iwl_tx_queue; | ||
67 | |||
66 | /* shared structures from iwl-5000.c */ | 68 | /* shared structures from iwl-5000.c */ |
67 | extern struct iwl_mod_params iwl50_mod_params; | 69 | extern struct iwl_mod_params iwl50_mod_params; |
68 | extern struct iwl_ops iwl5000_ops; | 70 | extern 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); |
80 | extern int iwl5000_calc_rssi(struct iwl_priv *priv, | 82 | extern int iwl5000_calc_rssi(struct iwl_priv *priv, |
81 | struct iwl_rx_phy_res *rx_resp); | 83 | struct iwl_rx_phy_res *rx_resp); |
84 | extern int iwl5000_apm_init(struct iwl_priv *priv); | ||
85 | extern void iwl5000_apm_stop(struct iwl_priv *priv); | ||
86 | extern int iwl5000_apm_reset(struct iwl_priv *priv); | ||
87 | extern void iwl5000_nic_config(struct iwl_priv *priv); | ||
88 | extern u16 iwl5000_eeprom_calib_version(struct iwl_priv *priv); | ||
89 | extern const u8 *iwl5000_eeprom_query_addr(const struct iwl_priv *priv, | ||
90 | size_t offset); | ||
91 | extern void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv, | ||
92 | struct iwl_tx_queue *txq, | ||
93 | u16 byte_cnt); | ||
94 | extern void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv, | ||
95 | struct iwl_tx_queue *txq); | ||
96 | extern int iwl5000_load_ucode(struct iwl_priv *priv); | ||
97 | extern void iwl5000_init_alive_start(struct iwl_priv *priv); | ||
98 | extern int iwl5000_alive_notify(struct iwl_priv *priv); | ||
99 | extern int iwl5000_hw_set_hw_params(struct iwl_priv *priv); | ||
100 | extern int iwl5000_txq_agg_enable(struct iwl_priv *priv, int txq_id, | ||
101 | int tx_fifo, int sta_id, int tid, u16 ssn_idx); | ||
102 | extern int iwl5000_txq_agg_disable(struct iwl_priv *priv, u16 txq_id, | ||
103 | u16 ssn_idx, u8 tx_fifo); | ||
104 | extern void iwl5000_txq_set_sched(struct iwl_priv *priv, u32 mask); | ||
105 | extern void iwl5000_setup_deferred_work(struct iwl_priv *priv); | ||
106 | extern void iwl5000_rx_handler_setup(struct iwl_priv *priv); | ||
107 | extern int iwl5000_hw_valid_rtc_data_addr(u32 addr); | ||
108 | extern int iwl5000_send_tx_power(struct iwl_priv *priv); | ||
109 | extern 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 */ | ||
154 | struct iwl_device_cmd; | ||
155 | |||
156 | struct 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 { | |||
162 | struct iwl_tx_queue { | 218 | struct 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 | ||
302 | struct iwl_cmd; | ||
303 | struct iwl_priv; | ||
304 | |||
305 | struct 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 | */ |
329 | struct iwl_cmd { | 368 | struct 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 | ||
343 | struct iwl_host_cmd { | 383 | struct 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 | ||
456 | struct iwl_ht_info { | 505 | struct 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 | ||
106 | static int iwl_generic_cmd_callback(struct iwl_priv *priv, | 106 | static 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 | ||
141 | static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | 139 | static 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 | ||
235 | cancel: | 230 | cancel: |
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 | } |
246 | fail: | 241 | fail: |
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 | } |
251 | out: | 246 | out: |
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 | ||
257 | int iwl_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | 252 | int 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 | ||
278 | int iwl_send_cmd_pdu_async(struct iwl_priv *priv, | 273 | int 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 | */ | ||
112 | static 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 | }; | ||
117 | static 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 | }; | ||
122 | static 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 | }; | ||
127 | static 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 */ | ||
134 | static 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 */ |
102 | static int iwl_set_power(struct iwl_priv *priv, void *cmd) | 142 | static 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 | } |
268 | EXPORT_SYMBOL(iwl_power_set_user_mode); | 313 | EXPORT_SYMBOL(iwl_power_set_user_mode); |
269 | 314 | ||
315 | bool 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 | } | ||
325 | EXPORT_SYMBOL(iwl_ht_enabled); | ||
326 | |||
327 | u8 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 | } | ||
337 | EXPORT_SYMBOL(iwl_tx_ant_restriction); | ||
338 | |||
339 | u8 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 | } | ||
349 | EXPORT_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 | */ | ||
361 | static 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 | |||
394 | static 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 | */ | ||
425 | static 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 | */ | ||
526 | static 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 | */ | ||
647 | void 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 | } | ||
665 | EXPORT_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 | */ | ||
672 | void 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 | } | ||
693 | EXPORT_SYMBOL(iwl_tt_exit_ct_kill); | ||
694 | |||
695 | void 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 | } | ||
710 | EXPORT_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 | */ | ||
717 | void 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 | } | ||
776 | EXPORT_SYMBOL(iwl_tt_initialize); | ||
777 | |||
778 | /* cleanup thermal throttling management related memory and timer */ | ||
779 | void 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 | } | ||
794 | EXPORT_SYMBOL(iwl_tt_exit); | ||
795 | |||
270 | /* initialize to default */ | 796 | /* initialize to default */ |
271 | void iwl_power_initialize(struct iwl_priv *priv) | 797 | void 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 | ||
34 | struct iwl_priv; | 34 | struct 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 */ | ||
49 | enum 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 | */ | ||
66 | struct 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 | */ | ||
80 | struct 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 | */ | ||
103 | struct 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 | |||
36 | enum { | 114 | enum { |
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 | ||
64 | int iwl_power_update_mode(struct iwl_priv *priv, bool force); | 149 | int iwl_power_update_mode(struct iwl_priv *priv, bool force); |
65 | int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); | 150 | int iwl_power_set_user_mode(struct iwl_priv *priv, u16 mode); |
151 | bool iwl_ht_enabled(struct iwl_priv *priv); | ||
152 | u8 iwl_tx_ant_restriction(struct iwl_priv *priv); | ||
153 | u8 iwl_rx_ant_restriction(struct iwl_priv *priv); | ||
154 | void iwl_tt_enter_ct_kill(struct iwl_priv *priv); | ||
155 | void iwl_tt_exit_ct_kill(struct iwl_priv *priv); | ||
156 | void iwl_tt_handler(struct iwl_priv *priv); | ||
157 | void iwl_tt_initialize(struct iwl_priv *priv); | ||
158 | void iwl_tt_exit(struct iwl_priv *priv); | ||
66 | void iwl_power_initialize(struct iwl_priv *priv); | 159 | void 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 | ||
100 | static int iwl_add_sta_callback(struct iwl_priv *priv, | 100 | static 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 | ||
134 | int iwl_send_add_sta(struct iwl_priv *priv, | 132 | int 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 | ||
327 | static int iwl_remove_sta_callback(struct iwl_priv *priv, | 325 | static 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 | ||
360 | static int iwl_send_remove_station(struct iwl_priv *priv, const u8 *addr, | 356 | static 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; |
366 | err: | 381 | err: |
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; | 384 | out_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 | } |
378 | EXPORT_SYMBOL(iwl_tx_queue_init); | 390 | EXPORT_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 | ||
364 | static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv, | 364 | static 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 | */ |
405 | static void iwl3945_build_tx_cmd_basic(struct iwl_priv *priv, | 405 | static 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 @@ | |||
1 | obj-$(CONFIG_IWM) := iwmc3200wifi.o | 1 | obj-$(CONFIG_IWM) := iwmc3200wifi.o |
2 | iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o | 2 | iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o |
3 | iwmc3200wifi-objs += commands.o wext.o cfg80211.o eeprom.o | 3 | iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o |
4 | 4 | ||
5 | iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o | 5 | iwmc3200wifi-$(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 | ||
309 | extern const struct iw_handler_def iwm_iw_handler_def; | ||
310 | |||
311 | void *iwm_if_alloc(int sizeof_bus, struct device *dev, | 309 | void *iwm_if_alloc(int sizeof_bus, struct device *dev, |
312 | struct iwm_if_ops *if_ops); | 310 | struct iwm_if_ops *if_ops); |
313 | void iwm_if_free(struct iwm_priv *iwm); | 311 | void 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 | |||
30 | static 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 | |||
44 | static 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 | |||
60 | static 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 | |||
75 | static 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 | |||
90 | static 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 | |||
106 | static 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 | |||
122 | static 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 | |||
182 | const 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 | ||
126 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 126 | void 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); |
90 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | 90 | void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, |
91 | struct antenna_setup *ant); | 91 | struct antenna_setup ant); |
92 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 92 | void 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 | ||
179 | static void rt2x00lib_antenna_diversity_eval(struct rt2x00_dev *rt2x00dev) | 179 | static 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 | ||
219 | static void rt2x00lib_antenna_diversity(struct rt2x00_dev *rt2x00dev) | 219 | static 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 | */ | ||
809 | enum 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 */ | ||
819 | enum 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 | */ |
547 | struct cfg80211_scan_request { | 547 | struct 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 | */ |
1092 | struct wiphy { | 1096 | struct 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 | ||
1157 | static inline struct net *wiphy_net(struct wiphy *wiphy) | ||
1158 | { | ||
1159 | return wiphy->_net; | ||
1160 | } | ||
1161 | |||
1162 | static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net) | ||
1163 | { | ||
1164 | wiphy->_net = net; | ||
1165 | } | ||
1166 | #else | ||
1167 | static inline struct net *wiphy_net(struct wiphy *wiphy) | ||
1168 | { | ||
1169 | return &init_net; | ||
1170 | } | ||
1171 | |||
1172 | static 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, | |||
1563 | int cfg80211_wext_giwrange(struct net_device *dev, | 1595 | int 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); |
1566 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | ||
1567 | struct iw_request_info *info, | ||
1568 | struct iw_freq *freq, char *extra); | ||
1569 | int cfg80211_ibss_wext_giwfreq(struct net_device *dev, | ||
1570 | struct iw_request_info *info, | ||
1571 | struct iw_freq *freq, char *extra); | ||
1572 | int cfg80211_ibss_wext_siwessid(struct net_device *dev, | ||
1573 | struct iw_request_info *info, | ||
1574 | struct iw_point *data, char *ssid); | ||
1575 | int cfg80211_ibss_wext_giwessid(struct net_device *dev, | ||
1576 | struct iw_request_info *info, | ||
1577 | struct iw_point *data, char *ssid); | ||
1578 | int cfg80211_ibss_wext_siwap(struct net_device *dev, | ||
1579 | struct iw_request_info *info, | ||
1580 | struct sockaddr *ap_addr, char *extra); | ||
1581 | int cfg80211_ibss_wext_giwap(struct net_device *dev, | ||
1582 | struct iw_request_info *info, | ||
1583 | struct sockaddr *ap_addr, char *extra); | ||
1584 | |||
1585 | int cfg80211_mgd_wext_siwfreq(struct net_device *dev, | ||
1586 | struct iw_request_info *info, | ||
1587 | struct iw_freq *freq, char *extra); | ||
1588 | int cfg80211_mgd_wext_giwfreq(struct net_device *dev, | ||
1589 | struct iw_request_info *info, | ||
1590 | struct iw_freq *freq, char *extra); | ||
1591 | int cfg80211_mgd_wext_siwessid(struct net_device *dev, | ||
1592 | struct iw_request_info *info, | ||
1593 | struct iw_point *data, char *ssid); | ||
1594 | int cfg80211_mgd_wext_giwessid(struct net_device *dev, | ||
1595 | struct iw_request_info *info, | ||
1596 | struct iw_point *data, char *ssid); | ||
1597 | int cfg80211_mgd_wext_siwap(struct net_device *dev, | ||
1598 | struct iw_request_info *info, | ||
1599 | struct sockaddr *ap_addr, char *extra); | ||
1600 | int cfg80211_mgd_wext_giwap(struct net_device *dev, | ||
1601 | struct iw_request_info *info, | ||
1602 | struct sockaddr *ap_addr, char *extra); | ||
1603 | int cfg80211_wext_siwgenie(struct net_device *dev, | 1598 | int 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 | ||
1613 | struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, | 1608 | int 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); | |
1611 | int cfg80211_wext_giwfreq(struct net_device *dev, | ||
1612 | struct iw_request_info *info, | ||
1613 | struct iw_freq *freq, char *extra); | ||
1614 | int cfg80211_wext_siwessid(struct net_device *dev, | ||
1615 | struct iw_request_info *info, | ||
1616 | struct iw_point *data, char *ssid); | ||
1617 | int cfg80211_wext_giwessid(struct net_device *dev, | ||
1618 | struct iw_request_info *info, | ||
1619 | struct iw_point *data, char *ssid); | ||
1616 | int cfg80211_wext_siwrate(struct net_device *dev, | 1620 | int 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 | ||
1665 | int cfg80211_wds_wext_siwap(struct net_device *dev, | 1669 | int 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); |
1668 | int cfg80211_wds_wext_giwap(struct net_device *dev, | 1672 | int 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 | */ |
247 | enum mac80211_tx_control_flags { | 250 | enum 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 | |||
5344 | out: | 5344 | out: |
5345 | return err; | 5345 | return err; |
5346 | } | 5346 | } |
5347 | EXPORT_SYMBOL_GPL(dev_change_net_namespace); | ||
5347 | 5348 | ||
5348 | static int dev_cpu_callback(struct notifier_block *nfb, | 5349 | static 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 |
4 | mac80211-y := \ | 4 | mac80211-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 | ||
60 | static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) | 60 | static 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 | */ | ||
582 | enum { | ||
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 | */ | ||
601 | enum 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 | |||
573 | struct ieee80211_local { | 609 | struct 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, | |||
914 | void ieee80211_configure_filter(struct ieee80211_local *local); | 950 | void ieee80211_configure_filter(struct ieee80211_local *local); |
915 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); | 951 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); |
916 | 952 | ||
917 | /* wireless extensions */ | ||
918 | extern const struct iw_handler_def ieee80211_iw_handler_def; | ||
919 | |||
920 | /* STA code */ | 953 | /* STA code */ |
921 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); | 954 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); |
922 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 955 | int 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 | ||
472 | static 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 | |||
522 | static 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 | |||
550 | static 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 | |||
582 | static 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 | |||
635 | static 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 | |||
477 | void ieee80211_scan_work(struct work_struct *work) | 656 | void 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 | ||
362 | static 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 | |||
373 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | 360 | static 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 | |||
30 | static 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 | |||
80 | static 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 | |||
99 | static 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 | |||
114 | static 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 | |||
131 | static 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 | |||
149 | static 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 | |||
170 | static 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 | |||
230 | const 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 | ||
153 | struct cfg80211_registered_device * | 154 | struct cfg80211_registered_device * |
154 | cfg80211_get_dev_from_ifindex(int ifindex) | 155 | cfg80211_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 | ||
226 | int 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 | |||
225 | static void cfg80211_rfkill_poll(struct rfkill *rfkill, void *data) | 262 | static 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 | ||
708 | static int cfg80211_init(void) | 752 | static 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 | |||
766 | static struct pernet_operations cfg80211_pernet_ops = { | ||
767 | .exit = cfg80211_pernet_exit, | ||
768 | }; | ||
769 | |||
770 | static 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: | |||
736 | out_fail_notifier: | 802 | out_fail_notifier: |
737 | wiphy_sysfs_exit(); | 803 | wiphy_sysfs_exit(); |
738 | out_fail_sysfs: | 804 | out_fail_sysfs: |
805 | unregister_pernet_device(&cfg80211_pernet_ops); | ||
806 | out_fail_pernet: | ||
739 | return err; | 807 | return err; |
740 | } | 808 | } |
741 | |||
742 | subsys_initcall(cfg80211_init); | 809 | subsys_initcall(cfg80211_init); |
743 | 810 | ||
744 | static void cfg80211_exit(void) | 811 | static 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 | } |
752 | module_exit(cfg80211_exit); | 820 | module_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 */ |
172 | extern struct cfg80211_registered_device * | 175 | extern struct cfg80211_registered_device * |
173 | cfg80211_get_dev_from_ifindex(int ifindex); | 176 | cfg80211_get_dev_from_ifindex(struct net *net, int ifindex); |
177 | |||
178 | int cfg80211_switch_netns(struct cfg80211_registered_device *rdev, | ||
179 | struct net *net); | ||
174 | 180 | ||
175 | static inline void cfg80211_lock_rdev(struct cfg80211_registered_device *rdev) | 181 | static 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 */ | ||
316 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); | ||
317 | 316 | ||
318 | int cfg80211_ibss_wext_giwfreq(struct net_device *dev, | 317 | int 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 */ | ||
346 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwfreq); | ||
347 | 344 | ||
348 | int cfg80211_ibss_wext_siwessid(struct net_device *dev, | 345 | int 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 */ | ||
388 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); | ||
389 | 384 | ||
390 | int cfg80211_ibss_wext_giwessid(struct net_device *dev, | 385 | int 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 */ | ||
417 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_giwessid); | ||
418 | 411 | ||
419 | int cfg80211_ibss_wext_siwap(struct net_device *dev, | 412 | int 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 */ | ||
473 | EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); | ||
474 | 465 | ||
475 | int cfg80211_ibss_wext_giwap(struct net_device *dev, | 466 | int 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 */ | ||
500 | EXPORT_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 */ |
33 | static int get_rdev_dev_by_info_ifindex(struct nlattr **attrs, | 36 | static 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) | |||
1098 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | 1113 | static 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 | */ |
1832 | static int get_vlan(struct nlattr *vlanattr, | 1846 | static 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, ¶ms.vlan); | 1914 | err = get_vlan(info, rdev, ¶ms.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, ¶ms.vlan); | 2027 | err = get_vlan(info, rdev, ¶ms.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 | ||
4047 | static 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 | |||
4027 | static struct genl_ops nl80211_ops[] = { | 4088 | static 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 | }; |
4261 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 4328 | static 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 | ||
4294 | static int nl80211_add_scan_req(struct sk_buff *msg, | 4362 | static 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 | ||
4371 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 4440 | void 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 | ||
4389 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 4459 | void 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 | ||
20 | void __cfg80211_scan_done(struct work_struct *wk) | 21 | void __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 | ||
67 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted) | 65 | void 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 | } |
81 | EXPORT_SYMBOL(cfg80211_scan_done); | 72 | EXPORT_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 | ||
19 | int cfg80211_wext_giwname(struct net_device *dev, | 20 | int 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 | } |
303 | EXPORT_SYMBOL_GPL(cfg80211_wext_freq); | ||
304 | 304 | ||
305 | int cfg80211_wext_siwrts(struct net_device *dev, | 305 | int 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 | } |
760 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); | 760 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); |
761 | 761 | ||
762 | int 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 | } | ||
790 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq); | ||
791 | |||
792 | int 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 | } | ||
812 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq); | ||
813 | |||
762 | int cfg80211_wext_siwtxpower(struct net_device *dev, | 814 | int 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 | } |
1098 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); | 1150 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower); |
1099 | 1151 | ||
1100 | int cfg80211_wds_wext_siwap(struct net_device *dev, | 1152 | static 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 | } |
1128 | EXPORT_SYMBOL_GPL(cfg80211_wds_wext_siwap); | ||
1129 | 1180 | ||
1130 | int cfg80211_wds_wext_giwap(struct net_device *dev, | 1181 | static 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 | } |
1144 | EXPORT_SYMBOL_GPL(cfg80211_wds_wext_giwap); | ||
1145 | 1195 | ||
1146 | int cfg80211_wext_siwrate(struct net_device *dev, | 1196 | int 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 | } |
1277 | EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); | 1327 | EXPORT_SYMBOL_GPL(cfg80211_wireless_stats); |
1328 | |||
1329 | int 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 | } | ||
1346 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwap); | ||
1347 | |||
1348 | int 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 | } | ||
1365 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwap); | ||
1366 | |||
1367 | int 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 | } | ||
1382 | EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid); | ||
1383 | |||
1384 | int 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 | } | ||
1399 | EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid); | ||
1400 | |||
1401 | static 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 | |||
1435 | const 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 | |||
7 | int cfg80211_ibss_wext_siwfreq(struct net_device *dev, | ||
8 | struct iw_request_info *info, | ||
9 | struct iw_freq *freq, char *extra); | ||
10 | int cfg80211_ibss_wext_giwfreq(struct net_device *dev, | ||
11 | struct iw_request_info *info, | ||
12 | struct iw_freq *freq, char *extra); | ||
13 | int cfg80211_ibss_wext_siwap(struct net_device *dev, | ||
14 | struct iw_request_info *info, | ||
15 | struct sockaddr *ap_addr, char *extra); | ||
16 | int cfg80211_ibss_wext_giwap(struct net_device *dev, | ||
17 | struct iw_request_info *info, | ||
18 | struct sockaddr *ap_addr, char *extra); | ||
19 | int cfg80211_ibss_wext_siwessid(struct net_device *dev, | ||
20 | struct iw_request_info *info, | ||
21 | struct iw_point *data, char *ssid); | ||
22 | int cfg80211_ibss_wext_giwessid(struct net_device *dev, | ||
23 | struct iw_request_info *info, | ||
24 | struct iw_point *data, char *ssid); | ||
25 | |||
26 | int cfg80211_mgd_wext_siwfreq(struct net_device *dev, | ||
27 | struct iw_request_info *info, | ||
28 | struct iw_freq *freq, char *extra); | ||
29 | int cfg80211_mgd_wext_giwfreq(struct net_device *dev, | ||
30 | struct iw_request_info *info, | ||
31 | struct iw_freq *freq, char *extra); | ||
32 | int cfg80211_mgd_wext_siwap(struct net_device *dev, | ||
33 | struct iw_request_info *info, | ||
34 | struct sockaddr *ap_addr, char *extra); | ||
35 | int cfg80211_mgd_wext_giwap(struct net_device *dev, | ||
36 | struct iw_request_info *info, | ||
37 | struct sockaddr *ap_addr, char *extra); | ||
38 | int cfg80211_mgd_wext_siwessid(struct net_device *dev, | ||
39 | struct iw_request_info *info, | ||
40 | struct iw_point *data, char *ssid); | ||
41 | int cfg80211_mgd_wext_giwessid(struct net_device *dev, | ||
42 | struct iw_request_info *info, | ||
43 | struct iw_point *data, char *ssid); | ||
44 | |||
45 | struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, | ||
46 | struct iw_freq *freq); | ||
47 | |||
48 | |||
49 | extern 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 | ||
13 | int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, | 14 | int 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 */ | ||
112 | EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwfreq); | ||
113 | 112 | ||
114 | int cfg80211_mgd_wext_giwfreq(struct net_device *dev, | 113 | int 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 */ | ||
142 | EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwfreq); | ||
143 | 140 | ||
144 | int cfg80211_mgd_wext_siwessid(struct net_device *dev, | 141 | int 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 */ | ||
199 | EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwessid); | ||
200 | 195 | ||
201 | int cfg80211_mgd_wext_giwessid(struct net_device *dev, | 196 | int 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 */ | ||
225 | EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwessid); | ||
226 | 219 | ||
227 | int cfg80211_mgd_wext_siwap(struct net_device *dev, | 220 | int 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 */ | ||
280 | EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_siwap); | ||
281 | 272 | ||
282 | int cfg80211_mgd_wext_giwap(struct net_device *dev, | 273 | int 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 */ | ||
306 | EXPORT_SYMBOL_GPL(cfg80211_mgd_wext_giwap); | ||
307 | 296 | ||
308 | int cfg80211_wext_siwgenie(struct net_device *dev, | 297 | int cfg80211_wext_siwgenie(struct net_device *dev, |
309 | struct iw_request_info *info, | 298 | struct iw_request_info *info, |