diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-05-11 14:24:55 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-11 14:24:55 -0400 |
commit | cc755896a4274f11283bca32d1d658203844057a (patch) | |
tree | 218970ece71df99f686b9416b7fd88b921690ebb /drivers/net/wireless/ath | |
parent | d250fe91ae129bff0968e685cc9c466d3a5e3482 (diff) | |
parent | 9459d59fbf0bc82ff4c804679fa8bc22788eca63 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Conflicts:
drivers/net/wireless/ath/ar9170/main.c
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r-- | drivers/net/wireless/ath/ar9170/ar9170.h | 52 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ar9170/main.c | 558 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ani.c | 6 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_initvals.h | 204 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/common.c | 49 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | 39 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_init.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 42 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.c | 20 |
10 files changed, 205 insertions, 772 deletions
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index dc662b76a1c..4f845f80c09 100644 --- a/drivers/net/wireless/ath/ar9170/ar9170.h +++ b/drivers/net/wireless/ath/ar9170/ar9170.h | |||
@@ -109,41 +109,6 @@ struct ar9170_rxstream_mpdu_merge { | |||
109 | bool has_plcp; | 109 | bool has_plcp; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | #define AR9170_NUM_TID 16 | ||
113 | #define WME_BA_BMP_SIZE 64 | ||
114 | #define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE) | ||
115 | |||
116 | #define WME_AC_BE 2 | ||
117 | #define WME_AC_BK 3 | ||
118 | #define WME_AC_VI 1 | ||
119 | #define WME_AC_VO 0 | ||
120 | |||
121 | #define TID_TO_WME_AC(_tid) \ | ||
122 | ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \ | ||
123 | (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \ | ||
124 | (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \ | ||
125 | WME_AC_VO) | ||
126 | |||
127 | #define BAW_WITHIN(_start, _bawsz, _seqno) \ | ||
128 | ((((_seqno) - (_start)) & 0xfff) < (_bawsz)) | ||
129 | |||
130 | enum ar9170_tid_state { | ||
131 | AR9170_TID_STATE_INVALID, | ||
132 | AR9170_TID_STATE_SHUTDOWN, | ||
133 | AR9170_TID_STATE_PROGRESS, | ||
134 | AR9170_TID_STATE_COMPLETE, | ||
135 | }; | ||
136 | |||
137 | struct ar9170_sta_tid { | ||
138 | struct list_head list; | ||
139 | struct sk_buff_head queue; | ||
140 | u8 addr[ETH_ALEN]; | ||
141 | u16 ssn; | ||
142 | u16 tid; | ||
143 | enum ar9170_tid_state state; | ||
144 | bool active; | ||
145 | }; | ||
146 | |||
147 | struct ar9170_tx_queue_stats { | 112 | struct ar9170_tx_queue_stats { |
148 | unsigned int len; | 113 | unsigned int len; |
149 | unsigned int limit; | 114 | unsigned int limit; |
@@ -152,14 +117,11 @@ struct ar9170_tx_queue_stats { | |||
152 | 117 | ||
153 | #define AR9170_QUEUE_TIMEOUT 64 | 118 | #define AR9170_QUEUE_TIMEOUT 64 |
154 | #define AR9170_TX_TIMEOUT 8 | 119 | #define AR9170_TX_TIMEOUT 8 |
155 | #define AR9170_BA_TIMEOUT 4 | ||
156 | #define AR9170_JANITOR_DELAY 128 | 120 | #define AR9170_JANITOR_DELAY 128 |
157 | #define AR9170_TX_INVALID_RATE 0xffffffff | 121 | #define AR9170_TX_INVALID_RATE 0xffffffff |
158 | 122 | ||
159 | #define AR9170_NUM_TX_STATUS 128 | 123 | #define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH |
160 | #define AR9170_NUM_TX_AGG_MAX 30 | 124 | #define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10) |
161 | #define AR9170_NUM_TX_LIMIT_HARD AR9170_TXQ_DEPTH | ||
162 | #define AR9170_NUM_TX_LIMIT_SOFT (AR9170_TXQ_DEPTH - 10) | ||
163 | 125 | ||
164 | struct ar9170 { | 126 | struct ar9170 { |
165 | struct ieee80211_hw *hw; | 127 | struct ieee80211_hw *hw; |
@@ -234,11 +196,6 @@ struct ar9170 { | |||
234 | struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; | 196 | struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; |
235 | struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; | 197 | struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; |
236 | struct delayed_work tx_janitor; | 198 | struct delayed_work tx_janitor; |
237 | /* tx ampdu */ | ||
238 | struct sk_buff_head tx_status_ampdu; | ||
239 | spinlock_t tx_ampdu_list_lock; | ||
240 | struct list_head tx_ampdu_list; | ||
241 | atomic_t tx_ampdu_pending; | ||
242 | 199 | ||
243 | /* rxstream mpdu merge */ | 200 | /* rxstream mpdu merge */ |
244 | struct ar9170_rxstream_mpdu_merge rx_mpdu; | 201 | struct ar9170_rxstream_mpdu_merge rx_mpdu; |
@@ -250,11 +207,6 @@ struct ar9170 { | |||
250 | u8 global_ampdu_factor; | 207 | u8 global_ampdu_factor; |
251 | }; | 208 | }; |
252 | 209 | ||
253 | struct ar9170_sta_info { | ||
254 | struct ar9170_sta_tid agg[AR9170_NUM_TID]; | ||
255 | unsigned int ampdu_max_len; | ||
256 | }; | ||
257 | |||
258 | struct ar9170_tx_info { | 210 | struct ar9170_tx_info { |
259 | unsigned long timeout; | 211 | unsigned long timeout; |
260 | }; | 212 | }; |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index 2e9b330f641..2abc8757899 100644 --- a/drivers/net/wireless/ath/ar9170/main.c +++ b/drivers/net/wireless/ath/ar9170/main.c | |||
@@ -50,10 +50,6 @@ static int modparam_nohwcrypt; | |||
50 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 50 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); |
51 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 51 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
52 | 52 | ||
53 | static int modparam_ht; | ||
54 | module_param_named(ht, modparam_ht, bool, S_IRUGO); | ||
55 | MODULE_PARM_DESC(ht, "enable MPDU aggregation."); | ||
56 | |||
57 | #define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ | 53 | #define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ |
58 | .bitrate = (_bitrate), \ | 54 | .bitrate = (_bitrate), \ |
59 | .flags = (_flags), \ | 55 | .flags = (_flags), \ |
@@ -182,7 +178,6 @@ static struct ieee80211_supported_band ar9170_band_5GHz = { | |||
182 | }; | 178 | }; |
183 | 179 | ||
184 | static void ar9170_tx(struct ar9170 *ar); | 180 | static void ar9170_tx(struct ar9170 *ar); |
185 | static bool ar9170_tx_ampdu(struct ar9170 *ar); | ||
186 | 181 | ||
187 | static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr) | 182 | static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr) |
188 | { | 183 | { |
@@ -195,21 +190,7 @@ static inline u16 ar9170_get_seq(struct sk_buff *skb) | |||
195 | return ar9170_get_seq_h((void *) txc->frame_data); | 190 | return ar9170_get_seq_h((void *) txc->frame_data); |
196 | } | 191 | } |
197 | 192 | ||
198 | static inline u16 ar9170_get_tid_h(struct ieee80211_hdr *hdr) | 193 | #ifdef AR9170_QUEUE_DEBUG |
199 | { | ||
200 | return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
201 | } | ||
202 | |||
203 | static inline u16 ar9170_get_tid(struct sk_buff *skb) | ||
204 | { | ||
205 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
206 | return ar9170_get_tid_h((struct ieee80211_hdr *) txc->frame_data); | ||
207 | } | ||
208 | |||
209 | #define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff) | ||
210 | #define GET_NEXT_SEQ_FROM_SKB(skb) (GET_NEXT_SEQ(ar9170_get_seq(skb))) | ||
211 | |||
212 | #if (defined AR9170_QUEUE_DEBUG) || (defined AR9170_TXAGG_DEBUG) | ||
213 | static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) | 194 | static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) |
214 | { | 195 | { |
215 | struct ar9170_tx_control *txc = (void *) skb->data; | 196 | struct ar9170_tx_control *txc = (void *) skb->data; |
@@ -244,7 +225,7 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar, | |||
244 | "mismatch %d != %d\n", skb_queue_len(queue), i); | 225 | "mismatch %d != %d\n", skb_queue_len(queue), i); |
245 | printk(KERN_DEBUG "---[ end ]---\n"); | 226 | printk(KERN_DEBUG "---[ end ]---\n"); |
246 | } | 227 | } |
247 | #endif /* AR9170_QUEUE_DEBUG || AR9170_TXAGG_DEBUG */ | 228 | #endif /* AR9170_QUEUE_DEBUG */ |
248 | 229 | ||
249 | #ifdef AR9170_QUEUE_DEBUG | 230 | #ifdef AR9170_QUEUE_DEBUG |
250 | static void ar9170_dump_txqueue(struct ar9170 *ar, | 231 | static void ar9170_dump_txqueue(struct ar9170 *ar, |
@@ -275,20 +256,6 @@ static void __ar9170_dump_txstats(struct ar9170 *ar) | |||
275 | } | 256 | } |
276 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | 257 | #endif /* AR9170_QUEUE_STOP_DEBUG */ |
277 | 258 | ||
278 | #ifdef AR9170_TXAGG_DEBUG | ||
279 | static void ar9170_dump_tx_status_ampdu(struct ar9170 *ar) | ||
280 | { | ||
281 | unsigned long flags; | ||
282 | |||
283 | spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags); | ||
284 | printk(KERN_DEBUG "%s: A-MPDU tx_status queue =>\n", | ||
285 | wiphy_name(ar->hw->wiphy)); | ||
286 | __ar9170_dump_txqueue(ar, &ar->tx_status_ampdu); | ||
287 | spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags); | ||
288 | } | ||
289 | |||
290 | #endif /* AR9170_TXAGG_DEBUG */ | ||
291 | |||
292 | /* caller must guarantee exclusive access for _bin_ queue. */ | 259 | /* caller must guarantee exclusive access for _bin_ queue. */ |
293 | static void ar9170_recycle_expired(struct ar9170 *ar, | 260 | static void ar9170_recycle_expired(struct ar9170 *ar, |
294 | struct sk_buff_head *queue, | 261 | struct sk_buff_head *queue, |
@@ -360,70 +327,6 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb, | |||
360 | ieee80211_tx_status_irqsafe(ar->hw, skb); | 327 | ieee80211_tx_status_irqsafe(ar->hw, skb); |
361 | } | 328 | } |
362 | 329 | ||
363 | static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar) | ||
364 | { | ||
365 | struct sk_buff_head success; | ||
366 | struct sk_buff *skb; | ||
367 | unsigned int i; | ||
368 | unsigned long queue_bitmap = 0; | ||
369 | |||
370 | skb_queue_head_init(&success); | ||
371 | |||
372 | while (skb_queue_len(&ar->tx_status_ampdu) > AR9170_NUM_TX_STATUS) | ||
373 | __skb_queue_tail(&success, skb_dequeue(&ar->tx_status_ampdu)); | ||
374 | |||
375 | ar9170_recycle_expired(ar, &ar->tx_status_ampdu, &success); | ||
376 | |||
377 | #ifdef AR9170_TXAGG_DEBUG | ||
378 | printk(KERN_DEBUG "%s: collected %d A-MPDU frames.\n", | ||
379 | wiphy_name(ar->hw->wiphy), skb_queue_len(&success)); | ||
380 | __ar9170_dump_txqueue(ar, &success); | ||
381 | #endif /* AR9170_TXAGG_DEBUG */ | ||
382 | |||
383 | while ((skb = __skb_dequeue(&success))) { | ||
384 | struct ieee80211_tx_info *txinfo; | ||
385 | |||
386 | queue_bitmap |= BIT(skb_get_queue_mapping(skb)); | ||
387 | |||
388 | txinfo = IEEE80211_SKB_CB(skb); | ||
389 | ieee80211_tx_info_clear_status(txinfo); | ||
390 | |||
391 | txinfo->flags |= IEEE80211_TX_STAT_ACK; | ||
392 | txinfo->status.rates[0].count = 1; | ||
393 | |||
394 | skb_pull(skb, sizeof(struct ar9170_tx_control)); | ||
395 | ieee80211_tx_status_irqsafe(ar->hw, skb); | ||
396 | } | ||
397 | |||
398 | for_each_set_bit(i, &queue_bitmap, BITS_PER_BYTE) { | ||
399 | #ifdef AR9170_QUEUE_STOP_DEBUG | ||
400 | printk(KERN_DEBUG "%s: wake queue %d\n", | ||
401 | wiphy_name(ar->hw->wiphy), i); | ||
402 | __ar9170_dump_txstats(ar); | ||
403 | #endif /* AR9170_QUEUE_STOP_DEBUG */ | ||
404 | ieee80211_wake_queue(ar->hw, i); | ||
405 | } | ||
406 | |||
407 | if (queue_bitmap) | ||
408 | ar9170_tx(ar); | ||
409 | } | ||
410 | |||
411 | static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb) | ||
412 | { | ||
413 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); | ||
414 | struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; | ||
415 | |||
416 | arinfo->timeout = jiffies + | ||
417 | msecs_to_jiffies(AR9170_BA_TIMEOUT); | ||
418 | |||
419 | skb_queue_tail(&ar->tx_status_ampdu, skb); | ||
420 | ar9170_tx_fake_ampdu_status(ar); | ||
421 | |||
422 | if (atomic_dec_and_test(&ar->tx_ampdu_pending) && | ||
423 | !list_empty(&ar->tx_ampdu_list)) | ||
424 | ar9170_tx_ampdu(ar); | ||
425 | } | ||
426 | |||
427 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | 330 | void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) |
428 | { | 331 | { |
429 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 332 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
@@ -447,14 +350,10 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) | |||
447 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) { | 350 | if (info->flags & IEEE80211_TX_CTL_NO_ACK) { |
448 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); | 351 | ar9170_tx_status(ar, skb, AR9170_TX_STATUS_FAILED); |
449 | } else { | 352 | } else { |
450 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | 353 | arinfo->timeout = jiffies + |
451 | ar9170_tx_ampdu_callback(ar, skb); | 354 | msecs_to_jiffies(AR9170_TX_TIMEOUT); |
452 | } else { | ||
453 | arinfo->timeout = jiffies + | ||
454 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | ||
455 | 355 | ||
456 | skb_queue_tail(&ar->tx_status[queue], skb); | 356 | skb_queue_tail(&ar->tx_status[queue], skb); |
457 | } | ||
458 | } | 357 | } |
459 | 358 | ||
460 | if (!ar->tx_stats[queue].len && | 359 | if (!ar->tx_stats[queue].len && |
@@ -524,38 +423,6 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar, | |||
524 | return NULL; | 423 | return NULL; |
525 | } | 424 | } |
526 | 425 | ||
527 | static void ar9170_handle_block_ack(struct ar9170 *ar, u16 count, u16 r) | ||
528 | { | ||
529 | struct sk_buff *skb; | ||
530 | struct ieee80211_tx_info *txinfo; | ||
531 | |||
532 | while (count) { | ||
533 | skb = ar9170_get_queued_skb(ar, NULL, &ar->tx_status_ampdu, r); | ||
534 | if (!skb) | ||
535 | break; | ||
536 | |||
537 | txinfo = IEEE80211_SKB_CB(skb); | ||
538 | ieee80211_tx_info_clear_status(txinfo); | ||
539 | |||
540 | /* FIXME: maybe more ? */ | ||
541 | txinfo->status.rates[0].count = 1; | ||
542 | |||
543 | skb_pull(skb, sizeof(struct ar9170_tx_control)); | ||
544 | ieee80211_tx_status_irqsafe(ar->hw, skb); | ||
545 | count--; | ||
546 | } | ||
547 | |||
548 | #ifdef AR9170_TXAGG_DEBUG | ||
549 | if (count) { | ||
550 | printk(KERN_DEBUG "%s: got %d more failed mpdus, but no more " | ||
551 | "suitable frames left in tx_status queue.\n", | ||
552 | wiphy_name(ar->hw->wiphy), count); | ||
553 | |||
554 | ar9170_dump_tx_status_ampdu(ar); | ||
555 | } | ||
556 | #endif /* AR9170_TXAGG_DEBUG */ | ||
557 | } | ||
558 | |||
559 | /* | 426 | /* |
560 | * This worker tries to keeps an maintain tx_status queues. | 427 | * This worker tries to keeps an maintain tx_status queues. |
561 | * So we can guarantee that incoming tx_status reports are | 428 | * So we can guarantee that incoming tx_status reports are |
@@ -592,8 +459,6 @@ static void ar9170_tx_janitor(struct work_struct *work) | |||
592 | resched = true; | 459 | resched = true; |
593 | } | 460 | } |
594 | 461 | ||
595 | ar9170_tx_fake_ampdu_status(ar); | ||
596 | |||
597 | if (!resched) | 462 | if (!resched) |
598 | return; | 463 | return; |
599 | 464 | ||
@@ -673,10 +538,6 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
673 | 538 | ||
674 | case 0xc5: | 539 | case 0xc5: |
675 | /* BlockACK events */ | 540 | /* BlockACK events */ |
676 | ar9170_handle_block_ack(ar, | ||
677 | le16_to_cpu(cmd->ba_fail_cnt.failed), | ||
678 | le16_to_cpu(cmd->ba_fail_cnt.rate)); | ||
679 | ar9170_tx_fake_ampdu_status(ar); | ||
680 | break; | 541 | break; |
681 | 542 | ||
682 | case 0xc6: | 543 | case 0xc6: |
@@ -1247,7 +1108,6 @@ static int ar9170_op_start(struct ieee80211_hw *hw) | |||
1247 | ar->global_ampdu_density = 6; | 1108 | ar->global_ampdu_density = 6; |
1248 | ar->global_ampdu_factor = 3; | 1109 | ar->global_ampdu_factor = 3; |
1249 | 1110 | ||
1250 | atomic_set(&ar->tx_ampdu_pending, 0); | ||
1251 | ar->bad_hw_nagger = jiffies; | 1111 | ar->bad_hw_nagger = jiffies; |
1252 | 1112 | ||
1253 | err = ar->open(ar); | 1113 | err = ar->open(ar); |
@@ -1310,40 +1170,10 @@ static void ar9170_op_stop(struct ieee80211_hw *hw) | |||
1310 | skb_queue_purge(&ar->tx_pending[i]); | 1170 | skb_queue_purge(&ar->tx_pending[i]); |
1311 | skb_queue_purge(&ar->tx_status[i]); | 1171 | skb_queue_purge(&ar->tx_status[i]); |
1312 | } | 1172 | } |
1313 | skb_queue_purge(&ar->tx_status_ampdu); | ||
1314 | 1173 | ||
1315 | mutex_unlock(&ar->mutex); | 1174 | mutex_unlock(&ar->mutex); |
1316 | } | 1175 | } |
1317 | 1176 | ||
1318 | static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb) | ||
1319 | { | ||
1320 | struct ar9170_tx_control *txc = (void *) skb->data; | ||
1321 | |||
1322 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU); | ||
1323 | } | ||
1324 | |||
1325 | static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst, | ||
1326 | struct sk_buff *src) | ||
1327 | { | ||
1328 | struct ar9170_tx_control *dst_txc, *src_txc; | ||
1329 | struct ieee80211_tx_info *dst_info, *src_info; | ||
1330 | struct ar9170_tx_info *dst_arinfo, *src_arinfo; | ||
1331 | |||
1332 | src_txc = (void *) src->data; | ||
1333 | src_info = IEEE80211_SKB_CB(src); | ||
1334 | src_arinfo = (void *) src_info->rate_driver_data; | ||
1335 | |||
1336 | dst_txc = (void *) dst->data; | ||
1337 | dst_info = IEEE80211_SKB_CB(dst); | ||
1338 | dst_arinfo = (void *) dst_info->rate_driver_data; | ||
1339 | |||
1340 | dst_txc->phy_control = src_txc->phy_control; | ||
1341 | |||
1342 | /* same MCS for the whole aggregate */ | ||
1343 | memcpy(dst_info->driver_rates, src_info->driver_rates, | ||
1344 | sizeof(dst_info->driver_rates)); | ||
1345 | } | ||
1346 | |||
1347 | static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | 1177 | static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) |
1348 | { | 1178 | { |
1349 | struct ieee80211_hdr *hdr; | 1179 | struct ieee80211_hdr *hdr; |
@@ -1420,14 +1250,7 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
1420 | txc->phy_control |= | 1250 | txc->phy_control |= |
1421 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); | 1251 | cpu_to_le32(queue << AR9170_TX_PHY_QOS_SHIFT); |
1422 | 1252 | ||
1423 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | 1253 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); |
1424 | if (unlikely(!info->control.sta)) | ||
1425 | goto err_out; | ||
1426 | |||
1427 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); | ||
1428 | } else { | ||
1429 | txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_RATE_PROBE); | ||
1430 | } | ||
1431 | } | 1254 | } |
1432 | 1255 | ||
1433 | return 0; | 1256 | return 0; |
@@ -1537,158 +1360,6 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb) | |||
1537 | txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); | 1360 | txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); |
1538 | } | 1361 | } |
1539 | 1362 | ||
1540 | static bool ar9170_tx_ampdu(struct ar9170 *ar) | ||
1541 | { | ||
1542 | struct sk_buff_head agg; | ||
1543 | struct ar9170_sta_tid *tid_info = NULL, *tmp; | ||
1544 | struct sk_buff *skb, *first = NULL; | ||
1545 | unsigned long flags, f2; | ||
1546 | unsigned int i = 0; | ||
1547 | u16 seq, queue, tmpssn; | ||
1548 | bool run = false; | ||
1549 | |||
1550 | skb_queue_head_init(&agg); | ||
1551 | |||
1552 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
1553 | if (list_empty(&ar->tx_ampdu_list)) { | ||
1554 | #ifdef AR9170_TXAGG_DEBUG | ||
1555 | printk(KERN_DEBUG "%s: aggregation list is empty.\n", | ||
1556 | wiphy_name(ar->hw->wiphy)); | ||
1557 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1558 | goto out_unlock; | ||
1559 | } | ||
1560 | |||
1561 | list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) { | ||
1562 | if (tid_info->state != AR9170_TID_STATE_COMPLETE) { | ||
1563 | #ifdef AR9170_TXAGG_DEBUG | ||
1564 | printk(KERN_DEBUG "%s: dangling aggregation entry!\n", | ||
1565 | wiphy_name(ar->hw->wiphy)); | ||
1566 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1567 | continue; | ||
1568 | } | ||
1569 | |||
1570 | if (++i > 64) { | ||
1571 | #ifdef AR9170_TXAGG_DEBUG | ||
1572 | printk(KERN_DEBUG "%s: enough frames aggregated.\n", | ||
1573 | wiphy_name(ar->hw->wiphy)); | ||
1574 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1575 | break; | ||
1576 | } | ||
1577 | |||
1578 | queue = TID_TO_WME_AC(tid_info->tid); | ||
1579 | |||
1580 | if (skb_queue_len(&ar->tx_pending[queue]) >= | ||
1581 | AR9170_NUM_TX_AGG_MAX) { | ||
1582 | #ifdef AR9170_TXAGG_DEBUG | ||
1583 | printk(KERN_DEBUG "%s: queue %d full.\n", | ||
1584 | wiphy_name(ar->hw->wiphy), queue); | ||
1585 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1586 | continue; | ||
1587 | } | ||
1588 | |||
1589 | list_del_init(&tid_info->list); | ||
1590 | |||
1591 | spin_lock_irqsave(&tid_info->queue.lock, f2); | ||
1592 | tmpssn = seq = tid_info->ssn; | ||
1593 | first = skb_peek(&tid_info->queue); | ||
1594 | |||
1595 | if (likely(first)) | ||
1596 | tmpssn = ar9170_get_seq(first); | ||
1597 | |||
1598 | if (unlikely(tmpssn != seq)) { | ||
1599 | #ifdef AR9170_TXAGG_DEBUG | ||
1600 | printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.", | ||
1601 | wiphy_name(ar->hw->wiphy), seq, tmpssn); | ||
1602 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1603 | tid_info->ssn = tmpssn; | ||
1604 | } | ||
1605 | |||
1606 | #ifdef AR9170_TXAGG_DEBUG | ||
1607 | printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with " | ||
1608 | "%d queued frames.\n", wiphy_name(ar->hw->wiphy), | ||
1609 | tid_info->tid, tid_info->ssn, | ||
1610 | skb_queue_len(&tid_info->queue)); | ||
1611 | __ar9170_dump_txqueue(ar, &tid_info->queue); | ||
1612 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1613 | |||
1614 | while ((skb = skb_peek(&tid_info->queue))) { | ||
1615 | if (unlikely(ar9170_get_seq(skb) != seq)) | ||
1616 | break; | ||
1617 | |||
1618 | __skb_unlink(skb, &tid_info->queue); | ||
1619 | tid_info->ssn = seq = GET_NEXT_SEQ(seq); | ||
1620 | |||
1621 | if (unlikely(skb_get_queue_mapping(skb) != queue)) { | ||
1622 | #ifdef AR9170_TXAGG_DEBUG | ||
1623 | printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d " | ||
1624 | "!match.\n", wiphy_name(ar->hw->wiphy), | ||
1625 | tid_info->tid, | ||
1626 | TID_TO_WME_AC(tid_info->tid), | ||
1627 | skb_get_queue_mapping(skb)); | ||
1628 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1629 | dev_kfree_skb_any(skb); | ||
1630 | continue; | ||
1631 | } | ||
1632 | |||
1633 | if (unlikely(first == skb)) { | ||
1634 | ar9170_tx_prepare_phy(ar, skb); | ||
1635 | __skb_queue_tail(&agg, skb); | ||
1636 | first = skb; | ||
1637 | } else { | ||
1638 | ar9170_tx_copy_phy(ar, skb, first); | ||
1639 | __skb_queue_tail(&agg, skb); | ||
1640 | } | ||
1641 | |||
1642 | if (unlikely(skb_queue_len(&agg) == | ||
1643 | AR9170_NUM_TX_AGG_MAX)) | ||
1644 | break; | ||
1645 | } | ||
1646 | |||
1647 | if (skb_queue_empty(&tid_info->queue)) | ||
1648 | tid_info->active = false; | ||
1649 | else | ||
1650 | list_add_tail(&tid_info->list, | ||
1651 | &ar->tx_ampdu_list); | ||
1652 | |||
1653 | spin_unlock_irqrestore(&tid_info->queue.lock, f2); | ||
1654 | |||
1655 | if (unlikely(skb_queue_empty(&agg))) { | ||
1656 | #ifdef AR9170_TXAGG_DEBUG | ||
1657 | printk(KERN_DEBUG "%s: queued empty list!\n", | ||
1658 | wiphy_name(ar->hw->wiphy)); | ||
1659 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1660 | continue; | ||
1661 | } | ||
1662 | |||
1663 | /* | ||
1664 | * tell the FW/HW that this is the last frame, | ||
1665 | * that way it will wait for the immediate block ack. | ||
1666 | */ | ||
1667 | ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg)); | ||
1668 | |||
1669 | #ifdef AR9170_TXAGG_DEBUG | ||
1670 | printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n", | ||
1671 | wiphy_name(ar->hw->wiphy)); | ||
1672 | __ar9170_dump_txqueue(ar, &agg); | ||
1673 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1674 | |||
1675 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
1676 | |||
1677 | spin_lock_irqsave(&ar->tx_pending[queue].lock, flags); | ||
1678 | skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]); | ||
1679 | spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags); | ||
1680 | run = true; | ||
1681 | |||
1682 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
1683 | } | ||
1684 | |||
1685 | out_unlock: | ||
1686 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
1687 | __skb_queue_purge(&agg); | ||
1688 | |||
1689 | return run; | ||
1690 | } | ||
1691 | |||
1692 | static void ar9170_tx(struct ar9170 *ar) | 1363 | static void ar9170_tx(struct ar9170 *ar) |
1693 | { | 1364 | { |
1694 | struct sk_buff *skb; | 1365 | struct sk_buff *skb; |
@@ -1763,9 +1434,6 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1763 | arinfo->timeout = jiffies + | 1434 | arinfo->timeout = jiffies + |
1764 | msecs_to_jiffies(AR9170_TX_TIMEOUT); | 1435 | msecs_to_jiffies(AR9170_TX_TIMEOUT); |
1765 | 1436 | ||
1766 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1767 | atomic_inc(&ar->tx_ampdu_pending); | ||
1768 | |||
1769 | #ifdef AR9170_QUEUE_DEBUG | 1437 | #ifdef AR9170_QUEUE_DEBUG |
1770 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", | 1438 | printk(KERN_DEBUG "%s: send frame q:%d =>\n", |
1771 | wiphy_name(ar->hw->wiphy), i); | 1439 | wiphy_name(ar->hw->wiphy), i); |
@@ -1774,9 +1442,6 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1774 | 1442 | ||
1775 | err = ar->tx(ar, skb); | 1443 | err = ar->tx(ar, skb); |
1776 | if (unlikely(err)) { | 1444 | if (unlikely(err)) { |
1777 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | ||
1778 | atomic_dec(&ar->tx_ampdu_pending); | ||
1779 | |||
1780 | frames_failed++; | 1445 | frames_failed++; |
1781 | dev_kfree_skb_any(skb); | 1446 | dev_kfree_skb_any(skb); |
1782 | } else { | 1447 | } else { |
@@ -1823,94 +1488,11 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1823 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); | 1488 | msecs_to_jiffies(AR9170_JANITOR_DELAY)); |
1824 | } | 1489 | } |
1825 | 1490 | ||
1826 | static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb) | ||
1827 | { | ||
1828 | struct ieee80211_tx_info *txinfo; | ||
1829 | struct ar9170_sta_info *sta_info; | ||
1830 | struct ar9170_sta_tid *agg; | ||
1831 | struct sk_buff *iter; | ||
1832 | unsigned long flags, f2; | ||
1833 | unsigned int max; | ||
1834 | u16 tid, seq, qseq; | ||
1835 | bool run = false, queue = false; | ||
1836 | |||
1837 | tid = ar9170_get_tid(skb); | ||
1838 | seq = ar9170_get_seq(skb); | ||
1839 | txinfo = IEEE80211_SKB_CB(skb); | ||
1840 | sta_info = (void *) txinfo->control.sta->drv_priv; | ||
1841 | agg = &sta_info->agg[tid]; | ||
1842 | max = sta_info->ampdu_max_len; | ||
1843 | |||
1844 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
1845 | |||
1846 | if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) { | ||
1847 | #ifdef AR9170_TXAGG_DEBUG | ||
1848 | printk(KERN_DEBUG "%s: BlockACK session not fully initialized " | ||
1849 | "for ESS:%pM tid:%d state:%d.\n", | ||
1850 | wiphy_name(ar->hw->wiphy), agg->addr, agg->tid, | ||
1851 | agg->state); | ||
1852 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1853 | goto err_unlock; | ||
1854 | } | ||
1855 | |||
1856 | if (!agg->active) { | ||
1857 | agg->active = true; | ||
1858 | agg->ssn = seq; | ||
1859 | queue = true; | ||
1860 | } | ||
1861 | |||
1862 | /* check if seq is within the BA window */ | ||
1863 | if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) { | ||
1864 | #ifdef AR9170_TXAGG_DEBUG | ||
1865 | printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not " | ||
1866 | "fit into BA window (%d - %d)\n", | ||
1867 | wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn, | ||
1868 | (agg->ssn + max) & 0xfff); | ||
1869 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1870 | goto err_unlock; | ||
1871 | } | ||
1872 | |||
1873 | spin_lock_irqsave(&agg->queue.lock, f2); | ||
1874 | |||
1875 | skb_queue_reverse_walk(&agg->queue, iter) { | ||
1876 | qseq = ar9170_get_seq(iter); | ||
1877 | |||
1878 | if (GET_NEXT_SEQ(qseq) == seq) { | ||
1879 | __skb_queue_after(&agg->queue, iter, skb); | ||
1880 | goto queued; | ||
1881 | } | ||
1882 | } | ||
1883 | |||
1884 | __skb_queue_head(&agg->queue, skb); | ||
1885 | |||
1886 | queued: | ||
1887 | spin_unlock_irqrestore(&agg->queue.lock, f2); | ||
1888 | |||
1889 | #ifdef AR9170_TXAGG_DEBUG | ||
1890 | printk(KERN_DEBUG "%s: new aggregate %p queued.\n", | ||
1891 | wiphy_name(ar->hw->wiphy), skb); | ||
1892 | __ar9170_dump_txqueue(ar, &agg->queue); | ||
1893 | #endif /* AR9170_TXAGG_DEBUG */ | ||
1894 | |||
1895 | if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX) | ||
1896 | run = true; | ||
1897 | |||
1898 | if (queue) | ||
1899 | list_add_tail(&agg->list, &ar->tx_ampdu_list); | ||
1900 | |||
1901 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
1902 | return run; | ||
1903 | |||
1904 | err_unlock: | ||
1905 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
1906 | dev_kfree_skb_irq(skb); | ||
1907 | return false; | ||
1908 | } | ||
1909 | |||
1910 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | 1491 | int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) |
1911 | { | 1492 | { |
1912 | struct ar9170 *ar = hw->priv; | 1493 | struct ar9170 *ar = hw->priv; |
1913 | struct ieee80211_tx_info *info; | 1494 | struct ieee80211_tx_info *info; |
1495 | unsigned int queue; | ||
1914 | 1496 | ||
1915 | if (unlikely(!IS_STARTED(ar))) | 1497 | if (unlikely(!IS_STARTED(ar))) |
1916 | goto err_free; | 1498 | goto err_free; |
@@ -1918,18 +1500,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1918 | if (unlikely(ar9170_tx_prepare(ar, skb))) | 1500 | if (unlikely(ar9170_tx_prepare(ar, skb))) |
1919 | goto err_free; | 1501 | goto err_free; |
1920 | 1502 | ||
1503 | queue = skb_get_queue_mapping(skb); | ||
1921 | info = IEEE80211_SKB_CB(skb); | 1504 | info = IEEE80211_SKB_CB(skb); |
1922 | if (info->flags & IEEE80211_TX_CTL_AMPDU) { | 1505 | ar9170_tx_prepare_phy(ar, skb); |
1923 | bool run = ar9170_tx_ampdu_queue(ar, skb); | 1506 | skb_queue_tail(&ar->tx_pending[queue], skb); |
1924 | |||
1925 | if (run || !atomic_read(&ar->tx_ampdu_pending)) | ||
1926 | ar9170_tx_ampdu(ar); | ||
1927 | } else { | ||
1928 | unsigned int queue = skb_get_queue_mapping(skb); | ||
1929 | |||
1930 | ar9170_tx_prepare_phy(ar, skb); | ||
1931 | skb_queue_tail(&ar->tx_pending[queue], skb); | ||
1932 | } | ||
1933 | 1507 | ||
1934 | ar9170_tx(ar); | 1508 | ar9170_tx(ar); |
1935 | return NETDEV_TX_OK; | 1509 | return NETDEV_TX_OK; |
@@ -2326,57 +1900,6 @@ out: | |||
2326 | return err; | 1900 | return err; |
2327 | } | 1901 | } |
2328 | 1902 | ||
2329 | static int ar9170_sta_add(struct ieee80211_hw *hw, | ||
2330 | struct ieee80211_vif *vif, | ||
2331 | struct ieee80211_sta *sta) | ||
2332 | { | ||
2333 | struct ar9170 *ar = hw->priv; | ||
2334 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2335 | unsigned int i; | ||
2336 | |||
2337 | memset(sta_info, 0, sizeof(*sta_info)); | ||
2338 | |||
2339 | if (!sta->ht_cap.ht_supported) | ||
2340 | return 0; | ||
2341 | |||
2342 | if (sta->ht_cap.ampdu_density > ar->global_ampdu_density) | ||
2343 | ar->global_ampdu_density = sta->ht_cap.ampdu_density; | ||
2344 | |||
2345 | if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor) | ||
2346 | ar->global_ampdu_factor = sta->ht_cap.ampdu_factor; | ||
2347 | |||
2348 | for (i = 0; i < AR9170_NUM_TID; i++) { | ||
2349 | sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; | ||
2350 | sta_info->agg[i].active = false; | ||
2351 | sta_info->agg[i].ssn = 0; | ||
2352 | sta_info->agg[i].tid = i; | ||
2353 | INIT_LIST_HEAD(&sta_info->agg[i].list); | ||
2354 | skb_queue_head_init(&sta_info->agg[i].queue); | ||
2355 | } | ||
2356 | |||
2357 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); | ||
2358 | |||
2359 | return 0; | ||
2360 | } | ||
2361 | |||
2362 | static int ar9170_sta_remove(struct ieee80211_hw *hw, | ||
2363 | struct ieee80211_vif *vif, | ||
2364 | struct ieee80211_sta *sta) | ||
2365 | { | ||
2366 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2367 | unsigned int i; | ||
2368 | |||
2369 | if (!sta->ht_cap.ht_supported) | ||
2370 | return 0; | ||
2371 | |||
2372 | for (i = 0; i < AR9170_NUM_TID; i++) { | ||
2373 | sta_info->agg[i].state = AR9170_TID_STATE_INVALID; | ||
2374 | skb_queue_purge(&sta_info->agg[i].queue); | ||
2375 | } | ||
2376 | |||
2377 | return 0; | ||
2378 | } | ||
2379 | |||
2380 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 1903 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
2381 | struct ieee80211_low_level_stats *stats) | 1904 | struct ieee80211_low_level_stats *stats) |
2382 | { | 1905 | { |
@@ -2419,55 +1942,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2419 | enum ieee80211_ampdu_mlme_action action, | 1942 | enum ieee80211_ampdu_mlme_action action, |
2420 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 1943 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2421 | { | 1944 | { |
2422 | struct ar9170 *ar = hw->priv; | ||
2423 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2424 | struct ar9170_sta_tid *tid_info = &sta_info->agg[tid]; | ||
2425 | unsigned long flags; | ||
2426 | |||
2427 | if (!modparam_ht) | ||
2428 | return -EOPNOTSUPP; | ||
2429 | |||
2430 | switch (action) { | 1945 | switch (action) { |
2431 | case IEEE80211_AMPDU_TX_START: | ||
2432 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
2433 | if (tid_info->state != AR9170_TID_STATE_SHUTDOWN || | ||
2434 | !list_empty(&tid_info->list)) { | ||
2435 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2436 | #ifdef AR9170_TXAGG_DEBUG | ||
2437 | printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] " | ||
2438 | "is in a very bad state!\n", | ||
2439 | wiphy_name(hw->wiphy), sta->addr, tid); | ||
2440 | #endif /* AR9170_TXAGG_DEBUG */ | ||
2441 | return -EBUSY; | ||
2442 | } | ||
2443 | |||
2444 | *ssn = tid_info->ssn; | ||
2445 | tid_info->state = AR9170_TID_STATE_PROGRESS; | ||
2446 | tid_info->active = false; | ||
2447 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2448 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
2449 | break; | ||
2450 | |||
2451 | case IEEE80211_AMPDU_TX_STOP: | ||
2452 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
2453 | tid_info->state = AR9170_TID_STATE_SHUTDOWN; | ||
2454 | list_del_init(&tid_info->list); | ||
2455 | tid_info->active = false; | ||
2456 | skb_queue_purge(&tid_info->queue); | ||
2457 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2458 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
2459 | break; | ||
2460 | |||
2461 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
2462 | #ifdef AR9170_TXAGG_DEBUG | ||
2463 | printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n", | ||
2464 | wiphy_name(hw->wiphy), sta->addr, tid); | ||
2465 | #endif /* AR9170_TXAGG_DEBUG */ | ||
2466 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
2467 | sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE; | ||
2468 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2469 | break; | ||
2470 | |||
2471 | case IEEE80211_AMPDU_RX_START: | 1946 | case IEEE80211_AMPDU_RX_START: |
2472 | case IEEE80211_AMPDU_RX_STOP: | 1947 | case IEEE80211_AMPDU_RX_STOP: |
2473 | /* Handled by firmware */ | 1948 | /* Handled by firmware */ |
@@ -2493,8 +1968,6 @@ static const struct ieee80211_ops ar9170_ops = { | |||
2493 | .bss_info_changed = ar9170_op_bss_info_changed, | 1968 | .bss_info_changed = ar9170_op_bss_info_changed, |
2494 | .get_tsf = ar9170_op_get_tsf, | 1969 | .get_tsf = ar9170_op_get_tsf, |
2495 | .set_key = ar9170_set_key, | 1970 | .set_key = ar9170_set_key, |
2496 | .sta_add = ar9170_sta_add, | ||
2497 | .sta_remove = ar9170_sta_remove, | ||
2498 | .get_stats = ar9170_get_stats, | 1971 | .get_stats = ar9170_get_stats, |
2499 | .ampdu_action = ar9170_ampdu_action, | 1972 | .ampdu_action = ar9170_ampdu_action, |
2500 | }; | 1973 | }; |
@@ -2527,8 +2000,6 @@ void *ar9170_alloc(size_t priv_size) | |||
2527 | mutex_init(&ar->mutex); | 2000 | mutex_init(&ar->mutex); |
2528 | spin_lock_init(&ar->cmdlock); | 2001 | spin_lock_init(&ar->cmdlock); |
2529 | spin_lock_init(&ar->tx_stats_lock); | 2002 | spin_lock_init(&ar->tx_stats_lock); |
2530 | spin_lock_init(&ar->tx_ampdu_list_lock); | ||
2531 | skb_queue_head_init(&ar->tx_status_ampdu); | ||
2532 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | 2003 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
2533 | skb_queue_head_init(&ar->tx_status[i]); | 2004 | skb_queue_head_init(&ar->tx_status[i]); |
2534 | skb_queue_head_init(&ar->tx_pending[i]); | 2005 | skb_queue_head_init(&ar->tx_pending[i]); |
@@ -2536,7 +2007,6 @@ void *ar9170_alloc(size_t priv_size) | |||
2536 | ar9170_rx_reset_rx_mpdu(ar); | 2007 | ar9170_rx_reset_rx_mpdu(ar); |
2537 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | 2008 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); |
2538 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); | 2009 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); |
2539 | INIT_LIST_HEAD(&ar->tx_ampdu_list); | ||
2540 | 2010 | ||
2541 | /* all hw supports 2.4 GHz, so set channel to 1 by default */ | 2011 | /* all hw supports 2.4 GHz, so set channel to 1 by default */ |
2542 | ar->channel = &ar9170_2ghz_chantable[0]; | 2012 | ar->channel = &ar9170_2ghz_chantable[0]; |
@@ -2549,16 +2019,8 @@ void *ar9170_alloc(size_t priv_size) | |||
2549 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 2019 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2550 | IEEE80211_HW_SIGNAL_DBM; | 2020 | IEEE80211_HW_SIGNAL_DBM; |
2551 | 2021 | ||
2552 | if (modparam_ht) { | ||
2553 | ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | ||
2554 | } else { | ||
2555 | ar9170_band_2GHz.ht_cap.ht_supported = false; | ||
2556 | ar9170_band_5GHz.ht_cap.ht_supported = false; | ||
2557 | } | ||
2558 | |||
2559 | ar->hw->queues = __AR9170_NUM_TXQ; | 2022 | ar->hw->queues = __AR9170_NUM_TXQ; |
2560 | ar->hw->extra_tx_headroom = 8; | 2023 | ar->hw->extra_tx_headroom = 8; |
2561 | ar->hw->sta_data_size = sizeof(struct ar9170_sta_info); | ||
2562 | 2024 | ||
2563 | ar->hw->max_rates = 1; | 2025 | ar->hw->max_rates = 1; |
2564 | ar->hw->max_rate_tries = 3; | 2026 | ar->hw->max_rate_tries = 3; |
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c index 584a32859bd..f2311ab3550 100644 --- a/drivers/net/wireless/ath/ath5k/ani.c +++ b/drivers/net/wireless/ath/ath5k/ani.c | |||
@@ -73,7 +73,7 @@ ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) | |||
73 | const s8 hi[] = { -14, -12 }; | 73 | const s8 hi[] = { -14, -12 }; |
74 | const s8 fr[] = { -78, -80 }; | 74 | const s8 fr[] = { -78, -80 }; |
75 | #endif | 75 | #endif |
76 | if (level < 0 || level > ARRAY_SIZE(sz)) { | 76 | if (level < 0 || level >= ARRAY_SIZE(sz)) { |
77 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | 77 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, |
78 | "level out of range %d", level); | 78 | "level out of range %d", level); |
79 | return; | 79 | return; |
@@ -104,7 +104,7 @@ ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) | |||
104 | { | 104 | { |
105 | const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; | 105 | const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; |
106 | 106 | ||
107 | if (level < 0 || level > ARRAY_SIZE(val) || | 107 | if (level < 0 || level >= ARRAY_SIZE(val) || |
108 | level > ah->ah_sc->ani_state.max_spur_level) { | 108 | level > ah->ah_sc->ani_state.max_spur_level) { |
109 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | 109 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, |
110 | "level out of range %d", level); | 110 | "level out of range %d", level); |
@@ -129,7 +129,7 @@ ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) | |||
129 | { | 129 | { |
130 | const int val[] = { 0, 4, 8 }; | 130 | const int val[] = { 0, 4, 8 }; |
131 | 131 | ||
132 | if (level < 0 || level > ARRAY_SIZE(val)) { | 132 | if (level < 0 || level >= ARRAY_SIZE(val)) { |
133 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | 133 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, |
134 | "level out of range %d", level); | 134 | "level out of range %d", level); |
135 | return; | 135 | return; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h index a131cd10ef2..ef6116e1303 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h | |||
@@ -541,7 +541,7 @@ static const u32 ar9300_2p0_mac_postamble[][5] = { | |||
541 | 541 | ||
542 | static const u32 ar9300_2p0_soc_postamble[][5] = { | 542 | static const u32 ar9300_2p0_soc_postamble[][5] = { |
543 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 543 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
544 | {0x00007010, 0x00000023, 0x00000023, 0x00000022, 0x00000022}, | 544 | {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, |
545 | }; | 545 | }; |
546 | 546 | ||
547 | static const u32 ar9200_merlin_2p0_radio_core[][2] = { | 547 | static const u32 ar9200_merlin_2p0_radio_core[][2] = { |
@@ -588,12 +588,12 @@ static const u32 ar9200_merlin_2p0_radio_core[][2] = { | |||
588 | 588 | ||
589 | static const u32 ar9300_2p0_baseband_postamble[][5] = { | 589 | static const u32 ar9300_2p0_baseband_postamble[][5] = { |
590 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 590 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
591 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a8005}, | 591 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a800b}, |
592 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, | 592 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, |
593 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | 593 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, |
594 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | 594 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, |
595 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | 595 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, |
596 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, | 596 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x00000b9c}, |
597 | {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, | 597 | {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, |
598 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, | 598 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, |
599 | {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, | 599 | {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, |
@@ -744,7 +744,7 @@ static const u32 ar9300_2p0_baseband_core[][2] = { | |||
744 | {0x0000a408, 0x0e79e5c6}, | 744 | {0x0000a408, 0x0e79e5c6}, |
745 | {0x0000a40c, 0x00820820}, | 745 | {0x0000a40c, 0x00820820}, |
746 | {0x0000a414, 0x1ce739ce}, | 746 | {0x0000a414, 0x1ce739ce}, |
747 | {0x0000a418, 0x7d001dce}, | 747 | {0x0000a418, 0x2d001dce}, |
748 | {0x0000a41c, 0x1ce739ce}, | 748 | {0x0000a41c, 0x1ce739ce}, |
749 | {0x0000a420, 0x000001ce}, | 749 | {0x0000a420, 0x000001ce}, |
750 | {0x0000a424, 0x1ce739ce}, | 750 | {0x0000a424, 0x1ce739ce}, |
@@ -756,7 +756,7 @@ static const u32 ar9300_2p0_baseband_core[][2] = { | |||
756 | {0x0000a43c, 0x00000000}, | 756 | {0x0000a43c, 0x00000000}, |
757 | {0x0000a440, 0x00000000}, | 757 | {0x0000a440, 0x00000000}, |
758 | {0x0000a444, 0x00000000}, | 758 | {0x0000a444, 0x00000000}, |
759 | {0x0000a448, 0x07000080}, | 759 | {0x0000a448, 0x04000080}, |
760 | {0x0000a44c, 0x00000001}, | 760 | {0x0000a44c, 0x00000001}, |
761 | {0x0000a450, 0x00010000}, | 761 | {0x0000a450, 0x00010000}, |
762 | {0x0000a458, 0x00000000}, | 762 | {0x0000a458, 0x00000000}, |
@@ -777,7 +777,7 @@ static const u32 ar9300_2p0_baseband_core[][2] = { | |||
777 | {0x0000a638, 0x00000000}, | 777 | {0x0000a638, 0x00000000}, |
778 | {0x0000a63c, 0x00000000}, | 778 | {0x0000a63c, 0x00000000}, |
779 | {0x0000a640, 0x00000000}, | 779 | {0x0000a640, 0x00000000}, |
780 | {0x0000a644, 0x3ffd9d74}, | 780 | {0x0000a644, 0x3fad9d74}, |
781 | {0x0000a648, 0x0048060a}, | 781 | {0x0000a648, 0x0048060a}, |
782 | {0x0000a64c, 0x00000637}, | 782 | {0x0000a64c, 0x00000637}, |
783 | {0x0000a670, 0x03020100}, | 783 | {0x0000a670, 0x03020100}, |
@@ -835,9 +835,9 @@ static const u32 ar9300_2p0_baseband_core[][2] = { | |||
835 | 835 | ||
836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { | 836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { |
837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
838 | {0x0000a410, 0x000050db, 0x000050db, 0x000050d9, 0x000050d9}, | 838 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
839 | {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, | 839 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
840 | {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, | 840 | {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, |
841 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, | 841 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, |
842 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, | 842 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, |
843 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, | 843 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, |
@@ -848,28 +848,28 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { | |||
848 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, | 848 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, |
849 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, | 849 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, |
850 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, | 850 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, |
851 | {0x0000a530, 0x34043643, 0x34043643, 0x2a000e20, 0x2a000e20}, | 851 | {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, |
852 | {0x0000a534, 0x38043a44, 0x38043a44, 0x2e000e22, 0x2e000e22}, | 852 | {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, |
853 | {0x0000a538, 0x3b043e45, 0x3b043e45, 0x31000e24, 0x31000e24}, | 853 | {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, |
854 | {0x0000a53c, 0x40063e46, 0x40063e46, 0x34001640, 0x34001640}, | 854 | {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, |
855 | {0x0000a540, 0x44083e46, 0x44083e46, 0x38001660, 0x38001660}, | 855 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, |
856 | {0x0000a544, 0x46083e66, 0x46083e66, 0x3b001861, 0x3b001861}, | 856 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, |
857 | {0x0000a548, 0x4b0a3e69, 0x4b0a3e69, 0x3e001a81, 0x3e001a81}, | 857 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, |
858 | {0x0000a54c, 0x4f0a5e66, 0x4f0a5e66, 0x42001a83, 0x42001a83}, | 858 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, |
859 | {0x0000a550, 0x540a7e66, 0x540a7e66, 0x44001c84, 0x44001c84}, | 859 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, |
860 | {0x0000a554, 0x570a7e89, 0x570a7e89, 0x48001ce3, 0x48001ce3}, | 860 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, |
861 | {0x0000a558, 0x5c0e7e8a, 0x5c0e7e8a, 0x4c001ce5, 0x4c001ce5}, | 861 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, |
862 | {0x0000a55c, 0x60127e8b, 0x60127e8b, 0x50001ce9, 0x50001ce9}, | 862 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, |
863 | {0x0000a560, 0x65127ecc, 0x65127ecc, 0x54001ceb, 0x54001ceb}, | 863 | {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, |
864 | {0x0000a564, 0x6b169ecd, 0x6b169ecd, 0x56001eec, 0x56001eec}, | 864 | {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
865 | {0x0000a568, 0x70169f0e, 0x70169f0e, 0x56001eec, 0x56001eec}, | 865 | {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
866 | {0x0000a56c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 866 | {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
867 | {0x0000a570, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 867 | {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
868 | {0x0000a574, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 868 | {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
869 | {0x0000a578, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 869 | {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
870 | {0x0000a57c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 870 | {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
871 | {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, | 871 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, |
872 | {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, | 872 | {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, |
873 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, | 873 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, |
874 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, | 874 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, |
875 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, | 875 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, |
@@ -880,42 +880,42 @@ static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { | |||
880 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, | 880 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, |
881 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, | 881 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, |
882 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, | 882 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, |
883 | {0x0000a5b0, 0x34843643, 0x34843643, 0x2a800e20, 0x2a800e20}, | 883 | {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, |
884 | {0x0000a5b4, 0x38843a44, 0x38843a44, 0x2e800e22, 0x2e800e22}, | 884 | {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, |
885 | {0x0000a5b8, 0x3b843e45, 0x3b843e45, 0x31800e24, 0x31800e24}, | 885 | {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, |
886 | {0x0000a5bc, 0x40863e46, 0x40863e46, 0x34801640, 0x34801640}, | 886 | {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, |
887 | {0x0000a5c0, 0x4c8a3065, 0x44883e46, 0x44883e46, 0x38801660}, | 887 | {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, |
888 | {0x0000a5c4, 0x46883e66, 0x46883e66, 0x3b801861, 0x3b801861}, | 888 | {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, |
889 | {0x0000a5c8, 0x4b8a3e69, 0x4b8a3e69, 0x3e801a81, 0x3e801a81}, | 889 | {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, |
890 | {0x0000a5cc, 0x4f8a5e66, 0x4f8a5e66, 0x42801a83, 0x42801a83}, | 890 | {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, |
891 | {0x0000a5d0, 0x548a7e66, 0x548a7e66, 0x44801c84, 0x44801c84}, | 891 | {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, |
892 | {0x0000a5d4, 0x578a7e89, 0x578a7e89, 0x48801ce3, 0x48801ce3}, | 892 | {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, |
893 | {0x0000a5d8, 0x5c8e7e8a, 0x5c8e7e8a, 0x4c801ce5, 0x4c801ce5}, | 893 | {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, |
894 | {0x0000a5dc, 0x60927e8b, 0x60927e8b, 0x50801ce9, 0x50801ce9}, | 894 | {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, |
895 | {0x0000a5e0, 0x65927ecc, 0x65927ecc, 0x54801ceb, 0x54801ceb}, | 895 | {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, |
896 | {0x0000a5e4, 0x6b969ecd, 0x6b969ecd, 0x56801eec, 0x56801eec}, | 896 | {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
897 | {0x0000a5e8, 0x70969f0e, 0x70969f0e, 0x56801eec, 0x56801eec}, | 897 | {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
898 | {0x0000a5ec, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 898 | {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
899 | {0x0000a5f0, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 899 | {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
900 | {0x0000a5f4, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 900 | {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
901 | {0x0000a5f8, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 901 | {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
902 | {0x0000a5fc, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 902 | {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
903 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | 903 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, |
904 | {0x00016048, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61}, | 904 | {0x00016048, 0xae481a61, 0xae481a61, 0xae481a61, 0xae481a61}, |
905 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | 905 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, |
906 | {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | 906 | {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, |
907 | {0x00016448, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61}, | 907 | {0x00016448, 0xae481a61, 0xae481a61, 0xae481a61, 0xae481a61}, |
908 | {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | 908 | {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, |
909 | {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | 909 | {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, |
910 | {0x00016848, 0xad241a61, 0xad241a61, 0xad241a61, 0xad241a61}, | 910 | {0x00016848, 0xae481a61, 0xae481a61, 0xae481a61, 0xae481a61}, |
911 | {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | 911 | {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, |
912 | }; | 912 | }; |
913 | 913 | ||
914 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { | 914 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { |
915 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | 915 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ |
916 | {0x0000a410, 0x000050db, 0x000050db, 0x000050d9, 0x000050d9}, | 916 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, |
917 | {0x0000a500, 0x00020220, 0x00020220, 0x00000000, 0x00000000}, | 917 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, |
918 | {0x0000a504, 0x06020223, 0x06020223, 0x04000002, 0x04000002}, | 918 | {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, |
919 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, | 919 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, |
920 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, | 920 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, |
921 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, | 921 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, |
@@ -926,28 +926,28 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { | |||
926 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, | 926 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, |
927 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, | 927 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, |
928 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, | 928 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, |
929 | {0x0000a530, 0x34043643, 0x34043643, 0x2a000e20, 0x2a000e20}, | 929 | {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, |
930 | {0x0000a534, 0x38043a44, 0x38043a44, 0x2e000e22, 0x2e000e22}, | 930 | {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, |
931 | {0x0000a538, 0x3b043e45, 0x3b043e45, 0x31000e24, 0x31000e24}, | 931 | {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, |
932 | {0x0000a53c, 0x40063e46, 0x40063e46, 0x34001640, 0x34001640}, | 932 | {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, |
933 | {0x0000a540, 0x44083e46, 0x44083e46, 0x38001660, 0x38001660}, | 933 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, |
934 | {0x0000a544, 0x46083e66, 0x46083e66, 0x3b001861, 0x3b001861}, | 934 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, |
935 | {0x0000a548, 0x4b0a3e69, 0x4b0a3e69, 0x3e001a81, 0x3e001a81}, | 935 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, |
936 | {0x0000a54c, 0x4f0a5e66, 0x4f0a5e66, 0x42001a83, 0x42001a83}, | 936 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, |
937 | {0x0000a550, 0x540a7e66, 0x540a7e66, 0x44001c84, 0x44001c84}, | 937 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, |
938 | {0x0000a554, 0x570a7e89, 0x570a7e89, 0x48001ce3, 0x48001ce3}, | 938 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, |
939 | {0x0000a558, 0x5c0e7e8a, 0x5c0e7e8a, 0x4c001ce5, 0x4c001ce5}, | 939 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, |
940 | {0x0000a55c, 0x60127e8b, 0x60127e8b, 0x50001ce9, 0x50001ce9}, | 940 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, |
941 | {0x0000a560, 0x65127ecc, 0x65127ecc, 0x54001ceb, 0x54001ceb}, | 941 | {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, |
942 | {0x0000a564, 0x6b169ecd, 0x6b169ecd, 0x56001eec, 0x56001eec}, | 942 | {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
943 | {0x0000a568, 0x70169f0e, 0x70169f0e, 0x56001eec, 0x56001eec}, | 943 | {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
944 | {0x0000a56c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 944 | {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
945 | {0x0000a570, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 945 | {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
946 | {0x0000a574, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 946 | {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
947 | {0x0000a578, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 947 | {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
948 | {0x0000a57c, 0x75169f4f, 0x75169f4f, 0x56001eec, 0x56001eec}, | 948 | {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, |
949 | {0x0000a580, 0x00820220, 0x00820220, 0x00800000, 0x00800000}, | 949 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, |
950 | {0x0000a584, 0x06820223, 0x06820223, 0x04800002, 0x04800002}, | 950 | {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, |
951 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, | 951 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, |
952 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, | 952 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, |
953 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, | 953 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, |
@@ -958,34 +958,34 @@ static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { | |||
958 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, | 958 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, |
959 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, | 959 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, |
960 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, | 960 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, |
961 | {0x0000a5b0, 0x34843643, 0x34843643, 0x2a800e20, 0x2a800e20}, | 961 | {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, |
962 | {0x0000a5b4, 0x38843a44, 0x38843a44, 0x2e800e22, 0x2e800e22}, | 962 | {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, |
963 | {0x0000a5b8, 0x3b843e45, 0x3b843e45, 0x31800e24, 0x31800e24}, | 963 | {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, |
964 | {0x0000a5bc, 0x40863e46, 0x40863e46, 0x34801640, 0x34801640}, | 964 | {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, |
965 | {0x0000a5c0, 0x44883e46, 0x44883e46, 0x38801660, 0x38801660}, | 965 | {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, |
966 | {0x0000a5c4, 0x46883e66, 0x46883e66, 0x3b801861, 0x3b801861}, | 966 | {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, |
967 | {0x0000a5c8, 0x4b8a3e69, 0x4b8a3e69, 0x3e801a81, 0x3e801a81}, | 967 | {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, |
968 | {0x0000a5cc, 0x4f8a5e66, 0x4f8a5e66, 0x42801a83, 0x42801a83}, | 968 | {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, |
969 | {0x0000a5d0, 0x548a7e66, 0x548a7e66, 0x44801c84, 0x44801c84}, | 969 | {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, |
970 | {0x0000a5d4, 0x578a7e89, 0x578a7e89, 0x48801ce3, 0x48801ce3}, | 970 | {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, |
971 | {0x0000a5d8, 0x5c8e7e8a, 0x5c8e7e8a, 0x4c801ce5, 0x4c801ce5}, | 971 | {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, |
972 | {0x0000a5dc, 0x60927e8b, 0x60927e8b, 0x50801ce9, 0x50801ce9}, | 972 | {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, |
973 | {0x0000a5e0, 0x65927ecc, 0x65927ecc, 0x54801ceb, 0x54801ceb}, | 973 | {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, |
974 | {0x0000a5e4, 0x6b969ecd, 0x6b969ecd, 0x56801eec, 0x56801eec}, | 974 | {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
975 | {0x0000a5e8, 0x70969f0e, 0x70969f0e, 0x56801eec, 0x56801eec}, | 975 | {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
976 | {0x0000a5ec, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 976 | {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
977 | {0x0000a5f0, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 977 | {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
978 | {0x0000a5f4, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 978 | {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
979 | {0x0000a5f8, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 979 | {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
980 | {0x0000a5fc, 0x75969f4f, 0x75969f4f, 0x56801eec, 0x56801eec}, | 980 | {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, |
981 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | 981 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, |
982 | {0x00016048, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61}, | 982 | {0x00016048, 0x8e481a61, 0x8e481a61, 0x8e481a61, 0x8e481a61}, |
983 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 983 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
984 | {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | 984 | {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, |
985 | {0x00016448, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61}, | 985 | {0x00016448, 0x8e481a61, 0x8e481a61, 0x8e481a61, 0x8e481a61}, |
986 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 986 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
987 | {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | 987 | {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, |
988 | {0x00016848, 0x8c001a61, 0x8c001a61, 0x8c001a61, 0x8c001a61}, | 988 | {0x00016848, 0x8e481a61, 0x8e481a61, 0x8e481a61, 0x8e481a61}, |
989 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | 989 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, |
990 | }; | 990 | }; |
991 | 991 | ||
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index b4424a623cf..7707341cd0d 100644 --- a/drivers/net/wireless/ath/ath9k/common.c +++ b/drivers/net/wireless/ath/ath9k/common.c | |||
@@ -57,13 +57,19 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
57 | * rs_more indicates chained descriptors which can be used | 57 | * rs_more indicates chained descriptors which can be used |
58 | * to link buffers together for a sort of scatter-gather | 58 | * to link buffers together for a sort of scatter-gather |
59 | * operation. | 59 | * operation. |
60 | * | 60 | * reject the frame, we don't support scatter-gather yet and |
61 | * the frame is probably corrupt anyway | ||
62 | */ | ||
63 | if (rx_stats->rs_more) | ||
64 | return false; | ||
65 | |||
66 | /* | ||
61 | * The rx_stats->rs_status will not be set until the end of the | 67 | * The rx_stats->rs_status will not be set until the end of the |
62 | * chained descriptors so it can be ignored if rs_more is set. The | 68 | * chained descriptors so it can be ignored if rs_more is set. The |
63 | * rs_more will be false at the last element of the chained | 69 | * rs_more will be false at the last element of the chained |
64 | * descriptors. | 70 | * descriptors. |
65 | */ | 71 | */ |
66 | if (!rx_stats->rs_more && rx_stats->rs_status != 0) { | 72 | if (rx_stats->rs_status != 0) { |
67 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) | 73 | if (rx_stats->rs_status & ATH9K_RXERR_CRC) |
68 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; | 74 | rxs->flag |= RX_FLAG_FAILED_FCS_CRC; |
69 | if (rx_stats->rs_status & ATH9K_RXERR_PHY) | 75 | if (rx_stats->rs_status & ATH9K_RXERR_PHY) |
@@ -102,11 +108,11 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
102 | return true; | 108 | return true; |
103 | } | 109 | } |
104 | 110 | ||
105 | static u8 ath9k_process_rate(struct ath_common *common, | 111 | static int ath9k_process_rate(struct ath_common *common, |
106 | struct ieee80211_hw *hw, | 112 | struct ieee80211_hw *hw, |
107 | struct ath_rx_status *rx_stats, | 113 | struct ath_rx_status *rx_stats, |
108 | struct ieee80211_rx_status *rxs, | 114 | struct ieee80211_rx_status *rxs, |
109 | struct sk_buff *skb) | 115 | struct sk_buff *skb) |
110 | { | 116 | { |
111 | struct ieee80211_supported_band *sband; | 117 | struct ieee80211_supported_band *sband; |
112 | enum ieee80211_band band; | 118 | enum ieee80211_band band; |
@@ -122,25 +128,32 @@ static u8 ath9k_process_rate(struct ath_common *common, | |||
122 | rxs->flag |= RX_FLAG_40MHZ; | 128 | rxs->flag |= RX_FLAG_40MHZ; |
123 | if (rx_stats->rs_flags & ATH9K_RX_GI) | 129 | if (rx_stats->rs_flags & ATH9K_RX_GI) |
124 | rxs->flag |= RX_FLAG_SHORT_GI; | 130 | rxs->flag |= RX_FLAG_SHORT_GI; |
125 | return rx_stats->rs_rate & 0x7f; | 131 | rxs->rate_idx = rx_stats->rs_rate & 0x7f; |
132 | return 0; | ||
126 | } | 133 | } |
127 | 134 | ||
128 | for (i = 0; i < sband->n_bitrates; i++) { | 135 | for (i = 0; i < sband->n_bitrates; i++) { |
129 | if (sband->bitrates[i].hw_value == rx_stats->rs_rate) | 136 | if (sband->bitrates[i].hw_value == rx_stats->rs_rate) { |
130 | return i; | 137 | rxs->rate_idx = i; |
138 | return 0; | ||
139 | } | ||
131 | if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { | 140 | if (sband->bitrates[i].hw_value_short == rx_stats->rs_rate) { |
132 | rxs->flag |= RX_FLAG_SHORTPRE; | 141 | rxs->flag |= RX_FLAG_SHORTPRE; |
133 | return i; | 142 | rxs->rate_idx = i; |
143 | return 0; | ||
134 | } | 144 | } |
135 | } | 145 | } |
136 | 146 | ||
137 | /* No valid hardware bitrate found -- we should not get here */ | 147 | /* |
148 | * No valid hardware bitrate found -- we should not get here | ||
149 | * because hardware has already validated this frame as OK. | ||
150 | */ | ||
138 | ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " | 151 | ath_print(common, ATH_DBG_XMIT, "unsupported hw bitrate detected " |
139 | "0x%02x using 1 Mbit\n", rx_stats->rs_rate); | 152 | "0x%02x using 1 Mbit\n", rx_stats->rs_rate); |
140 | if ((common->debug_mask & ATH_DBG_XMIT)) | 153 | if ((common->debug_mask & ATH_DBG_XMIT)) |
141 | print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len); | 154 | print_hex_dump_bytes("", DUMP_PREFIX_NONE, skb->data, skb->len); |
142 | 155 | ||
143 | return 0; | 156 | return -EINVAL; |
144 | } | 157 | } |
145 | 158 | ||
146 | static void ath9k_process_rssi(struct ath_common *common, | 159 | static void ath9k_process_rssi(struct ath_common *common, |
@@ -202,13 +215,19 @@ int ath9k_cmn_rx_skb_preprocess(struct ath_common *common, | |||
202 | struct ath_hw *ah = common->ah; | 215 | struct ath_hw *ah = common->ah; |
203 | 216 | ||
204 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | 217 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); |
218 | |||
219 | /* | ||
220 | * everything but the rate is checked here, the rate check is done | ||
221 | * separately to avoid doing two lookups for a rate for each frame. | ||
222 | */ | ||
205 | if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) | 223 | if (!ath9k_rx_accept(common, skb, rx_status, rx_stats, decrypt_error)) |
206 | return -EINVAL; | 224 | return -EINVAL; |
207 | 225 | ||
208 | ath9k_process_rssi(common, hw, skb, rx_stats); | 226 | ath9k_process_rssi(common, hw, skb, rx_stats); |
209 | 227 | ||
210 | rx_status->rate_idx = ath9k_process_rate(common, hw, | 228 | if (ath9k_process_rate(common, hw, rx_stats, rx_status, skb)) |
211 | rx_stats, rx_status, skb); | 229 | return -EINVAL; |
230 | |||
212 | rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); | 231 | rx_status->mactime = ath9k_hw_extend_tsf(ah, rx_stats->rs_tstamp); |
213 | rx_status->band = hw->conf.channel->band; | 232 | rx_status->band = hw->conf.channel->band; |
214 | rx_status->freq = hw->conf.channel->center_freq; | 233 | rx_status->freq = hw->conf.channel->center_freq; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 1ae18bbc4d9..ad556aa8da3 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -356,7 +356,6 @@ struct ath9k_htc_priv { | |||
356 | u16 seq_no; | 356 | u16 seq_no; |
357 | u32 bmiss_cnt; | 357 | u32 bmiss_cnt; |
358 | 358 | ||
359 | struct sk_buff *beacon; | ||
360 | spinlock_t beacon_lock; | 359 | spinlock_t beacon_lock; |
361 | 360 | ||
362 | bool tx_queues_stop; | 361 | bool tx_queues_stop; |
@@ -408,13 +407,13 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
408 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | 407 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, |
409 | struct ieee80211_vif *vif); | 408 | struct ieee80211_vif *vif); |
410 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); | 409 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); |
411 | void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv, | ||
412 | struct ieee80211_vif *vif); | ||
413 | 410 | ||
414 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, | 411 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, |
415 | enum htc_endpoint_id ep_id); | 412 | enum htc_endpoint_id ep_id); |
416 | void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, | 413 | void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, |
417 | bool txok); | 414 | bool txok); |
415 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | ||
416 | enum htc_endpoint_id ep_id, bool txok); | ||
418 | 417 | ||
419 | void ath9k_htc_station_work(struct work_struct *work); | 418 | void ath9k_htc_station_work(struct work_struct *work); |
420 | void ath9k_htc_aggr_work(struct work_struct *work); | 419 | void ath9k_htc_aggr_work(struct work_struct *work); |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c index 7cb55f5b071..c10c7d002eb 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -165,22 +165,10 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | |||
165 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | 165 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); |
166 | } | 166 | } |
167 | 167 | ||
168 | void ath9k_htc_beacon_update(struct ath9k_htc_priv *priv, | 168 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, |
169 | struct ieee80211_vif *vif) | 169 | enum htc_endpoint_id ep_id, bool txok) |
170 | { | 170 | { |
171 | struct ath_common *common = ath9k_hw_common(priv->ah); | 171 | dev_kfree_skb_any(skb); |
172 | |||
173 | spin_lock_bh(&priv->beacon_lock); | ||
174 | |||
175 | if (priv->beacon) | ||
176 | dev_kfree_skb_any(priv->beacon); | ||
177 | |||
178 | priv->beacon = ieee80211_beacon_get(priv->hw, vif); | ||
179 | if (!priv->beacon) | ||
180 | ath_print(common, ATH_DBG_BEACON, | ||
181 | "Unable to allocate beacon\n"); | ||
182 | |||
183 | spin_unlock_bh(&priv->beacon_lock); | ||
184 | } | 172 | } |
185 | 173 | ||
186 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | 174 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) |
@@ -189,6 +177,7 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | |||
189 | struct tx_beacon_header beacon_hdr; | 177 | struct tx_beacon_header beacon_hdr; |
190 | struct ath9k_htc_tx_ctl tx_ctl; | 178 | struct ath9k_htc_tx_ctl tx_ctl; |
191 | struct ieee80211_tx_info *info; | 179 | struct ieee80211_tx_info *info; |
180 | struct sk_buff *beacon; | ||
192 | u8 *tx_fhdr; | 181 | u8 *tx_fhdr; |
193 | 182 | ||
194 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); | 183 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); |
@@ -207,25 +196,17 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | |||
207 | return; | 196 | return; |
208 | } | 197 | } |
209 | 198 | ||
210 | if (unlikely(priv->beacon == NULL)) { | ||
211 | spin_unlock_bh(&priv->beacon_lock); | ||
212 | return; | ||
213 | } | ||
214 | |||
215 | /* Free the old SKB first */ | ||
216 | dev_kfree_skb_any(priv->beacon); | ||
217 | |||
218 | /* Get a new beacon */ | 199 | /* Get a new beacon */ |
219 | priv->beacon = ieee80211_beacon_get(priv->hw, priv->vif); | 200 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); |
220 | if (!priv->beacon) { | 201 | if (!beacon) { |
221 | spin_unlock_bh(&priv->beacon_lock); | 202 | spin_unlock_bh(&priv->beacon_lock); |
222 | return; | 203 | return; |
223 | } | 204 | } |
224 | 205 | ||
225 | info = IEEE80211_SKB_CB(priv->beacon); | 206 | info = IEEE80211_SKB_CB(beacon); |
226 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | 207 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { |
227 | struct ieee80211_hdr *hdr = | 208 | struct ieee80211_hdr *hdr = |
228 | (struct ieee80211_hdr *) priv->beacon->data; | 209 | (struct ieee80211_hdr *) beacon->data; |
229 | priv->seq_no += 0x10; | 210 | priv->seq_no += 0x10; |
230 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | 211 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); |
231 | hdr->seq_ctrl |= cpu_to_le16(priv->seq_no); | 212 | hdr->seq_ctrl |= cpu_to_le16(priv->seq_no); |
@@ -233,10 +214,10 @@ void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | |||
233 | 214 | ||
234 | tx_ctl.type = ATH9K_HTC_NORMAL; | 215 | tx_ctl.type = ATH9K_HTC_NORMAL; |
235 | beacon_hdr.vif_index = avp->index; | 216 | beacon_hdr.vif_index = avp->index; |
236 | tx_fhdr = skb_push(priv->beacon, sizeof(beacon_hdr)); | 217 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); |
237 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); | 218 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); |
238 | 219 | ||
239 | htc_send(priv->htc, priv->beacon, priv->beacon_ep, &tx_ctl); | 220 | htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); |
240 | 221 | ||
241 | spin_unlock_bh(&priv->beacon_lock); | 222 | spin_unlock_bh(&priv->beacon_lock); |
242 | } | 223 | } |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 701f2ef5a44..17111fc1d2c 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -144,7 +144,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv) | |||
144 | goto err; | 144 | goto err; |
145 | 145 | ||
146 | /* Beacon */ | 146 | /* Beacon */ |
147 | ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, NULL, | 147 | ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, ath9k_htc_beaconep, |
148 | &priv->beacon_ep); | 148 | &priv->beacon_ep); |
149 | if (ret) | 149 | if (ret) |
150 | goto err; | 150 | goto err; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index ca7f3a78eb1..6c386dad1d4 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -461,11 +461,11 @@ static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv, | |||
461 | struct ath_common *common = ath9k_hw_common(priv->ah); | 461 | struct ath_common *common = ath9k_hw_common(priv->ah); |
462 | struct ath9k_htc_target_aggr aggr; | 462 | struct ath9k_htc_target_aggr aggr; |
463 | struct ieee80211_sta *sta = NULL; | 463 | struct ieee80211_sta *sta = NULL; |
464 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; | 464 | struct ath9k_htc_sta *ista; |
465 | int ret = 0; | 465 | int ret = 0; |
466 | u8 cmd_rsp; | 466 | u8 cmd_rsp; |
467 | 467 | ||
468 | if (tid > ATH9K_HTC_MAX_TID) | 468 | if (tid >= ATH9K_HTC_MAX_TID) |
469 | return -EINVAL; | 469 | return -EINVAL; |
470 | 470 | ||
471 | memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr)); | 471 | memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr)); |
@@ -1099,7 +1099,7 @@ fail_tx: | |||
1099 | return 0; | 1099 | return 0; |
1100 | } | 1100 | } |
1101 | 1101 | ||
1102 | static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) | 1102 | static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) |
1103 | { | 1103 | { |
1104 | struct ath9k_htc_priv *priv = hw->priv; | 1104 | struct ath9k_htc_priv *priv = hw->priv; |
1105 | struct ath_hw *ah = priv->ah; | 1105 | struct ath_hw *ah = priv->ah; |
@@ -1147,6 +1147,13 @@ static int ath9k_htc_radio_enable(struct ieee80211_hw *hw) | |||
1147 | priv->tx_queues_stop = false; | 1147 | priv->tx_queues_stop = false; |
1148 | spin_unlock_bh(&priv->tx_lock); | 1148 | spin_unlock_bh(&priv->tx_lock); |
1149 | 1149 | ||
1150 | if (led) { | ||
1151 | /* Enable LED */ | ||
1152 | ath9k_hw_cfg_output(ah, ah->led_pin, | ||
1153 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
1154 | ath9k_hw_set_gpio(ah, ah->led_pin, 0); | ||
1155 | } | ||
1156 | |||
1150 | ieee80211_wake_queues(hw); | 1157 | ieee80211_wake_queues(hw); |
1151 | 1158 | ||
1152 | return ret; | 1159 | return ret; |
@@ -1158,13 +1165,13 @@ static int ath9k_htc_start(struct ieee80211_hw *hw) | |||
1158 | int ret = 0; | 1165 | int ret = 0; |
1159 | 1166 | ||
1160 | mutex_lock(&priv->mutex); | 1167 | mutex_lock(&priv->mutex); |
1161 | ret = ath9k_htc_radio_enable(hw); | 1168 | ret = ath9k_htc_radio_enable(hw, false); |
1162 | mutex_unlock(&priv->mutex); | 1169 | mutex_unlock(&priv->mutex); |
1163 | 1170 | ||
1164 | return ret; | 1171 | return ret; |
1165 | } | 1172 | } |
1166 | 1173 | ||
1167 | static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) | 1174 | static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) |
1168 | { | 1175 | { |
1169 | struct ath9k_htc_priv *priv = hw->priv; | 1176 | struct ath9k_htc_priv *priv = hw->priv; |
1170 | struct ath_hw *ah = priv->ah; | 1177 | struct ath_hw *ah = priv->ah; |
@@ -1177,6 +1184,12 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw) | |||
1177 | return; | 1184 | return; |
1178 | } | 1185 | } |
1179 | 1186 | ||
1187 | if (led) { | ||
1188 | /* Disable LED */ | ||
1189 | ath9k_hw_set_gpio(ah, ah->led_pin, 1); | ||
1190 | ath9k_hw_cfg_gpio_input(ah, ah->led_pin); | ||
1191 | } | ||
1192 | |||
1180 | /* Cancel all the running timers/work .. */ | 1193 | /* Cancel all the running timers/work .. */ |
1181 | cancel_work_sync(&priv->ps_work); | 1194 | cancel_work_sync(&priv->ps_work); |
1182 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | 1195 | cancel_delayed_work_sync(&priv->ath9k_ani_work); |
@@ -1217,7 +1230,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw) | |||
1217 | struct ath9k_htc_priv *priv = hw->priv; | 1230 | struct ath9k_htc_priv *priv = hw->priv; |
1218 | 1231 | ||
1219 | mutex_lock(&priv->mutex); | 1232 | mutex_lock(&priv->mutex); |
1220 | ath9k_htc_radio_disable(hw); | 1233 | ath9k_htc_radio_disable(hw, false); |
1221 | mutex_unlock(&priv->mutex); | 1234 | mutex_unlock(&priv->mutex); |
1222 | } | 1235 | } |
1223 | 1236 | ||
@@ -1313,15 +1326,6 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | |||
1313 | priv->nvifs--; | 1326 | priv->nvifs--; |
1314 | 1327 | ||
1315 | ath9k_htc_remove_station(priv, vif, NULL); | 1328 | ath9k_htc_remove_station(priv, vif, NULL); |
1316 | |||
1317 | if (vif->type == NL80211_IFTYPE_ADHOC) { | ||
1318 | spin_lock_bh(&priv->beacon_lock); | ||
1319 | if (priv->beacon) | ||
1320 | dev_kfree_skb_any(priv->beacon); | ||
1321 | priv->beacon = NULL; | ||
1322 | spin_unlock_bh(&priv->beacon_lock); | ||
1323 | } | ||
1324 | |||
1325 | priv->vif = NULL; | 1329 | priv->vif = NULL; |
1326 | 1330 | ||
1327 | mutex_unlock(&priv->mutex); | 1331 | mutex_unlock(&priv->mutex); |
@@ -1346,7 +1350,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1346 | 1350 | ||
1347 | if (enable_radio) { | 1351 | if (enable_radio) { |
1348 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | 1352 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); |
1349 | ath9k_htc_radio_enable(hw); | 1353 | ath9k_htc_radio_enable(hw, true); |
1350 | ath_print(common, ATH_DBG_CONFIG, | 1354 | ath_print(common, ATH_DBG_CONFIG, |
1351 | "not-idle: enabling radio\n"); | 1355 | "not-idle: enabling radio\n"); |
1352 | } | 1356 | } |
@@ -1398,10 +1402,9 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | |||
1398 | if (priv->ps_idle) { | 1402 | if (priv->ps_idle) { |
1399 | ath_print(common, ATH_DBG_CONFIG, | 1403 | ath_print(common, ATH_DBG_CONFIG, |
1400 | "idle: disabling radio\n"); | 1404 | "idle: disabling radio\n"); |
1401 | ath9k_htc_radio_disable(hw); | 1405 | ath9k_htc_radio_disable(hw, true); |
1402 | } | 1406 | } |
1403 | 1407 | ||
1404 | |||
1405 | mutex_unlock(&priv->mutex); | 1408 | mutex_unlock(&priv->mutex); |
1406 | 1409 | ||
1407 | return 0; | 1410 | return 0; |
@@ -1590,9 +1593,6 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1590 | ath9k_htc_beacon_config(priv, vif); | 1593 | ath9k_htc_beacon_config(priv, vif); |
1591 | } | 1594 | } |
1592 | 1595 | ||
1593 | if (changed & BSS_CHANGED_BEACON) | ||
1594 | ath9k_htc_beacon_update(priv, vif); | ||
1595 | |||
1596 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && | 1596 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && |
1597 | !bss_conf->enable_beacon) { | 1597 | !bss_conf->enable_beacon) { |
1598 | priv->op_flags &= ~OP_ENABLE_BEACON; | 1598 | priv->op_flags &= ~OP_ENABLE_BEACON; |
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 559019262d3..c33f17dbe6f 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -574,6 +574,26 @@ static int __ath9k_hw_init(struct ath_hw *ah) | |||
574 | 574 | ||
575 | ath9k_hw_init_mode_regs(ah); | 575 | ath9k_hw_init_mode_regs(ah); |
576 | 576 | ||
577 | /* | ||
578 | * Configire PCIE after Ini init. SERDES values now come from ini file | ||
579 | * This enables PCIe low power mode. | ||
580 | */ | ||
581 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
582 | u32 regval; | ||
583 | unsigned int i; | ||
584 | |||
585 | /* Set Bits 16 and 17 in the AR_WA register. */ | ||
586 | regval = REG_READ(ah, AR_WA); | ||
587 | regval |= 0x00030000; | ||
588 | REG_WRITE(ah, AR_WA, regval); | ||
589 | |||
590 | for (i = 0; i < ah->iniPcieSerdesLowPower.ia_rows; i++) { | ||
591 | REG_WRITE(ah, | ||
592 | INI_RA(&ah->iniPcieSerdesLowPower, i, 0), | ||
593 | INI_RA(&ah->iniPcieSerdesLowPower, i, 1)); | ||
594 | } | ||
595 | } | ||
596 | |||
577 | if (ah->is_pciexpress) | 597 | if (ah->is_pciexpress) |
578 | ath9k_hw_configpcipowersave(ah, 0, 0); | 598 | ath9k_hw_configpcipowersave(ah, 0, 0); |
579 | else | 599 | else |