diff options
Diffstat (limited to 'drivers/net/wireless/ath')
94 files changed, 26036 insertions, 8660 deletions
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig index 4e7a7fd695c8..0a75be027afa 100644 --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig | |||
@@ -3,7 +3,7 @@ menuconfig ATH_COMMON | |||
3 | depends on CFG80211 | 3 | depends on CFG80211 |
4 | ---help--- | 4 | ---help--- |
5 | This will enable the support for the Atheros wireless drivers. | 5 | This will enable the support for the Atheros wireless drivers. |
6 | ath5k, ath9k and ar9170 drivers share some common code, this option | 6 | ath5k, ath9k, ath9k_htc and ar9170 drivers share some common code, this option |
7 | enables the common ath.ko module which shares common helpers. | 7 | enables the common ath.ko module which shares common helpers. |
8 | 8 | ||
9 | For more information and documentation on this module you can visit: | 9 | For more information and documentation on this module you can visit: |
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h index dc662b76a1c8..4f845f80c098 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/cmd.h b/drivers/net/wireless/ath/ar9170/cmd.h index 826c45e6b274..ec8134b4b949 100644 --- a/drivers/net/wireless/ath/ar9170/cmd.h +++ b/drivers/net/wireless/ath/ar9170/cmd.h | |||
@@ -79,7 +79,7 @@ __regwrite_out : \ | |||
79 | if (__nreg) { \ | 79 | if (__nreg) { \ |
80 | if (IS_ACCEPTING_CMD(__ar)) \ | 80 | if (IS_ACCEPTING_CMD(__ar)) \ |
81 | __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ | 81 | __err = ar->exec_cmd(__ar, AR9170_CMD_WREG, \ |
82 | 8 * __nreg, \ | 82 | 8 * __nreg, \ |
83 | (u8 *) &__ar->cmdbuf[1], \ | 83 | (u8 *) &__ar->cmdbuf[1], \ |
84 | 0, NULL); \ | 84 | 0, NULL); \ |
85 | __nreg = 0; \ | 85 | __nreg = 0; \ |
diff --git a/drivers/net/wireless/ath/ar9170/eeprom.h b/drivers/net/wireless/ath/ar9170/eeprom.h index d2c8cc83f1dd..6c4663883423 100644 --- a/drivers/net/wireless/ath/ar9170/eeprom.h +++ b/drivers/net/wireless/ath/ar9170/eeprom.h | |||
@@ -127,8 +127,8 @@ struct ar9170_eeprom { | |||
127 | __le16 checksum; | 127 | __le16 checksum; |
128 | __le16 version; | 128 | __le16 version; |
129 | u8 operating_flags; | 129 | u8 operating_flags; |
130 | #define AR9170_OPFLAG_5GHZ 1 | 130 | #define AR9170_OPFLAG_5GHZ 1 |
131 | #define AR9170_OPFLAG_2GHZ 2 | 131 | #define AR9170_OPFLAG_2GHZ 2 |
132 | u8 misc; | 132 | u8 misc; |
133 | __le16 reg_domain[2]; | 133 | __le16 reg_domain[2]; |
134 | u8 mac_address[6]; | 134 | u8 mac_address[6]; |
diff --git a/drivers/net/wireless/ath/ar9170/hw.h b/drivers/net/wireless/ath/ar9170/hw.h index 0a1d4c28e68a..06f1f3c951a4 100644 --- a/drivers/net/wireless/ath/ar9170/hw.h +++ b/drivers/net/wireless/ath/ar9170/hw.h | |||
@@ -425,5 +425,6 @@ enum ar9170_txq { | |||
425 | 425 | ||
426 | #define AR9170_TXQ_DEPTH 32 | 426 | #define AR9170_TXQ_DEPTH 32 |
427 | #define AR9170_TX_MAX_PENDING 128 | 427 | #define AR9170_TX_MAX_PENDING 128 |
428 | #define AR9170_RX_STREAM_MAX_SIZE 65535 | ||
428 | 429 | ||
429 | #endif /* __AR9170_HW_H */ | 430 | #endif /* __AR9170_HW_H */ |
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c index c53692980990..2abc87578994 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; |
@@ -236,7 +217,7 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar, | |||
236 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); | 217 | wiphy_name(ar->hw->wiphy), skb_queue_len(queue)); |
237 | 218 | ||
238 | skb_queue_walk(queue, skb) { | 219 | skb_queue_walk(queue, skb) { |
239 | printk(KERN_DEBUG "index:%d => \n", i++); | 220 | printk(KERN_DEBUG "index:%d =>\n", i++); |
240 | ar9170_print_txheader(ar, skb); | 221 | ar9170_print_txheader(ar, skb); |
241 | } | 222 | } |
242 | if (i != skb_queue_len(queue)) | 223 | if (i != skb_queue_len(queue)) |
@@ -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, |
@@ -308,7 +275,7 @@ static void ar9170_recycle_expired(struct ar9170 *ar, | |||
308 | if (time_is_before_jiffies(arinfo->timeout)) { | 275 | if (time_is_before_jiffies(arinfo->timeout)) { |
309 | #ifdef AR9170_QUEUE_DEBUG | 276 | #ifdef AR9170_QUEUE_DEBUG |
310 | printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " | 277 | printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => " |
311 | "recycle \n", wiphy_name(ar->hw->wiphy), | 278 | "recycle\n", wiphy_name(ar->hw->wiphy), |
312 | jiffies, arinfo->timeout); | 279 | jiffies, arinfo->timeout); |
313 | ar9170_print_txheader(ar, skb); | 280 | ar9170_print_txheader(ar, skb); |
314 | #endif /* AR9170_QUEUE_DEBUG */ | 281 | #endif /* AR9170_QUEUE_DEBUG */ |
@@ -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: |
@@ -689,7 +550,8 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | |||
689 | 550 | ||
690 | /* firmware debug */ | 551 | /* firmware debug */ |
691 | case 0xca: | 552 | case 0xca: |
692 | printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, (char *)buf + 4); | 553 | printk(KERN_DEBUG "ar9170 FW: %.*s\n", len - 4, |
554 | (char *)buf + 4); | ||
693 | break; | 555 | break; |
694 | case 0xcb: | 556 | case 0xcb: |
695 | len -= 4; | 557 | len -= 4; |
@@ -926,7 +788,6 @@ static void ar9170_rx_phy_status(struct ar9170 *ar, | |||
926 | 788 | ||
927 | /* TODO: we could do something with phy_errors */ | 789 | /* TODO: we could do something with phy_errors */ |
928 | status->signal = ar->noise[0] + phy->rssi_combined; | 790 | status->signal = ar->noise[0] + phy->rssi_combined; |
929 | status->noise = ar->noise[0]; | ||
930 | } | 791 | } |
931 | 792 | ||
932 | static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) | 793 | static struct sk_buff *ar9170_rx_copy_data(u8 *buf, int len) |
@@ -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; |
@@ -1728,7 +1399,7 @@ static void ar9170_tx(struct ar9170 *ar) | |||
1728 | printk(KERN_DEBUG "%s: queue %d full\n", | 1399 | printk(KERN_DEBUG "%s: queue %d full\n", |
1729 | wiphy_name(ar->hw->wiphy), i); | 1400 | wiphy_name(ar->hw->wiphy), i); |
1730 | 1401 | ||
1731 | printk(KERN_DEBUG "%s: stuck frames: ===> \n", | 1402 | printk(KERN_DEBUG "%s: stuck frames: ===>\n", |
1732 | wiphy_name(ar->hw->wiphy)); | 1403 | wiphy_name(ar->hw->wiphy)); |
1733 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); | 1404 | ar9170_dump_txqueue(ar, &ar->tx_pending[i]); |
1734 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); | 1405 | ar9170_dump_txqueue(ar, &ar->tx_status[i]); |
@@ -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; |
@@ -2046,21 +1620,17 @@ out: | |||
2046 | return err; | 1620 | return err; |
2047 | } | 1621 | } |
2048 | 1622 | ||
2049 | static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, int mc_count, | 1623 | static u64 ar9170_op_prepare_multicast(struct ieee80211_hw *hw, |
2050 | struct dev_addr_list *mclist) | 1624 | struct netdev_hw_addr_list *mc_list) |
2051 | { | 1625 | { |
2052 | u64 mchash; | 1626 | u64 mchash; |
2053 | int i; | 1627 | struct netdev_hw_addr *ha; |
2054 | 1628 | ||
2055 | /* always get broadcast frames */ | 1629 | /* always get broadcast frames */ |
2056 | mchash = 1ULL << (0xff >> 2); | 1630 | mchash = 1ULL << (0xff >> 2); |
2057 | 1631 | ||
2058 | for (i = 0; i < mc_count; i++) { | 1632 | netdev_hw_addr_list_for_each(ha, mc_list) |
2059 | if (WARN_ON(!mclist)) | 1633 | mchash |= 1ULL << (ha->addr[5] >> 2); |
2060 | break; | ||
2061 | mchash |= 1ULL << (mclist->dmi_addr[5] >> 2); | ||
2062 | mclist = mclist->next; | ||
2063 | } | ||
2064 | 1634 | ||
2065 | return mchash; | 1635 | return mchash; |
2066 | } | 1636 | } |
@@ -2330,57 +1900,6 @@ out: | |||
2330 | return err; | 1900 | return err; |
2331 | } | 1901 | } |
2332 | 1902 | ||
2333 | static int ar9170_sta_add(struct ieee80211_hw *hw, | ||
2334 | struct ieee80211_vif *vif, | ||
2335 | struct ieee80211_sta *sta) | ||
2336 | { | ||
2337 | struct ar9170 *ar = hw->priv; | ||
2338 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2339 | unsigned int i; | ||
2340 | |||
2341 | memset(sta_info, 0, sizeof(*sta_info)); | ||
2342 | |||
2343 | if (!sta->ht_cap.ht_supported) | ||
2344 | return 0; | ||
2345 | |||
2346 | if (sta->ht_cap.ampdu_density > ar->global_ampdu_density) | ||
2347 | ar->global_ampdu_density = sta->ht_cap.ampdu_density; | ||
2348 | |||
2349 | if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor) | ||
2350 | ar->global_ampdu_factor = sta->ht_cap.ampdu_factor; | ||
2351 | |||
2352 | for (i = 0; i < AR9170_NUM_TID; i++) { | ||
2353 | sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN; | ||
2354 | sta_info->agg[i].active = false; | ||
2355 | sta_info->agg[i].ssn = 0; | ||
2356 | sta_info->agg[i].tid = i; | ||
2357 | INIT_LIST_HEAD(&sta_info->agg[i].list); | ||
2358 | skb_queue_head_init(&sta_info->agg[i].queue); | ||
2359 | } | ||
2360 | |||
2361 | sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor); | ||
2362 | |||
2363 | return 0; | ||
2364 | } | ||
2365 | |||
2366 | static int ar9170_sta_remove(struct ieee80211_hw *hw, | ||
2367 | struct ieee80211_vif *vif, | ||
2368 | struct ieee80211_sta *sta) | ||
2369 | { | ||
2370 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2371 | unsigned int i; | ||
2372 | |||
2373 | if (!sta->ht_cap.ht_supported) | ||
2374 | return 0; | ||
2375 | |||
2376 | for (i = 0; i < AR9170_NUM_TID; i++) { | ||
2377 | sta_info->agg[i].state = AR9170_TID_STATE_INVALID; | ||
2378 | skb_queue_purge(&sta_info->agg[i].queue); | ||
2379 | } | ||
2380 | |||
2381 | return 0; | ||
2382 | } | ||
2383 | |||
2384 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 1903 | static int ar9170_get_stats(struct ieee80211_hw *hw, |
2385 | struct ieee80211_low_level_stats *stats) | 1904 | struct ieee80211_low_level_stats *stats) |
2386 | { | 1905 | { |
@@ -2423,55 +1942,7 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw, | |||
2423 | enum ieee80211_ampdu_mlme_action action, | 1942 | enum ieee80211_ampdu_mlme_action action, |
2424 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) | 1943 | struct ieee80211_sta *sta, u16 tid, u16 *ssn) |
2425 | { | 1944 | { |
2426 | struct ar9170 *ar = hw->priv; | ||
2427 | struct ar9170_sta_info *sta_info = (void *) sta->drv_priv; | ||
2428 | struct ar9170_sta_tid *tid_info = &sta_info->agg[tid]; | ||
2429 | unsigned long flags; | ||
2430 | |||
2431 | if (!modparam_ht) | ||
2432 | return -EOPNOTSUPP; | ||
2433 | |||
2434 | switch (action) { | 1945 | switch (action) { |
2435 | case IEEE80211_AMPDU_TX_START: | ||
2436 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
2437 | if (tid_info->state != AR9170_TID_STATE_SHUTDOWN || | ||
2438 | !list_empty(&tid_info->list)) { | ||
2439 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2440 | #ifdef AR9170_TXAGG_DEBUG | ||
2441 | printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] " | ||
2442 | "is in a very bad state!\n", | ||
2443 | wiphy_name(hw->wiphy), sta->addr, tid); | ||
2444 | #endif /* AR9170_TXAGG_DEBUG */ | ||
2445 | return -EBUSY; | ||
2446 | } | ||
2447 | |||
2448 | *ssn = tid_info->ssn; | ||
2449 | tid_info->state = AR9170_TID_STATE_PROGRESS; | ||
2450 | tid_info->active = false; | ||
2451 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2452 | ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
2453 | break; | ||
2454 | |||
2455 | case IEEE80211_AMPDU_TX_STOP: | ||
2456 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
2457 | tid_info->state = AR9170_TID_STATE_SHUTDOWN; | ||
2458 | list_del_init(&tid_info->list); | ||
2459 | tid_info->active = false; | ||
2460 | skb_queue_purge(&tid_info->queue); | ||
2461 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2462 | ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); | ||
2463 | break; | ||
2464 | |||
2465 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
2466 | #ifdef AR9170_TXAGG_DEBUG | ||
2467 | printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n", | ||
2468 | wiphy_name(hw->wiphy), sta->addr, tid); | ||
2469 | #endif /* AR9170_TXAGG_DEBUG */ | ||
2470 | spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags); | ||
2471 | sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE; | ||
2472 | spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags); | ||
2473 | break; | ||
2474 | |||
2475 | case IEEE80211_AMPDU_RX_START: | 1946 | case IEEE80211_AMPDU_RX_START: |
2476 | case IEEE80211_AMPDU_RX_STOP: | 1947 | case IEEE80211_AMPDU_RX_STOP: |
2477 | /* Handled by firmware */ | 1948 | /* Handled by firmware */ |
@@ -2497,8 +1968,6 @@ static const struct ieee80211_ops ar9170_ops = { | |||
2497 | .bss_info_changed = ar9170_op_bss_info_changed, | 1968 | .bss_info_changed = ar9170_op_bss_info_changed, |
2498 | .get_tsf = ar9170_op_get_tsf, | 1969 | .get_tsf = ar9170_op_get_tsf, |
2499 | .set_key = ar9170_set_key, | 1970 | .set_key = ar9170_set_key, |
2500 | .sta_add = ar9170_sta_add, | ||
2501 | .sta_remove = ar9170_sta_remove, | ||
2502 | .get_stats = ar9170_get_stats, | 1971 | .get_stats = ar9170_get_stats, |
2503 | .ampdu_action = ar9170_ampdu_action, | 1972 | .ampdu_action = ar9170_ampdu_action, |
2504 | }; | 1973 | }; |
@@ -2516,7 +1985,7 @@ void *ar9170_alloc(size_t priv_size) | |||
2516 | * tends to split the streams into separate rx descriptors. | 1985 | * tends to split the streams into separate rx descriptors. |
2517 | */ | 1986 | */ |
2518 | 1987 | ||
2519 | skb = __dev_alloc_skb(AR9170_MAX_RX_BUFFER_SIZE, GFP_KERNEL); | 1988 | skb = __dev_alloc_skb(AR9170_RX_STREAM_MAX_SIZE, GFP_KERNEL); |
2520 | if (!skb) | 1989 | if (!skb) |
2521 | goto err_nomem; | 1990 | goto err_nomem; |
2522 | 1991 | ||
@@ -2531,8 +2000,6 @@ void *ar9170_alloc(size_t priv_size) | |||
2531 | mutex_init(&ar->mutex); | 2000 | mutex_init(&ar->mutex); |
2532 | spin_lock_init(&ar->cmdlock); | 2001 | spin_lock_init(&ar->cmdlock); |
2533 | spin_lock_init(&ar->tx_stats_lock); | 2002 | spin_lock_init(&ar->tx_stats_lock); |
2534 | spin_lock_init(&ar->tx_ampdu_list_lock); | ||
2535 | skb_queue_head_init(&ar->tx_status_ampdu); | ||
2536 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { | 2003 | for (i = 0; i < __AR9170_NUM_TXQ; i++) { |
2537 | skb_queue_head_init(&ar->tx_status[i]); | 2004 | skb_queue_head_init(&ar->tx_status[i]); |
2538 | skb_queue_head_init(&ar->tx_pending[i]); | 2005 | skb_queue_head_init(&ar->tx_pending[i]); |
@@ -2540,7 +2007,6 @@ void *ar9170_alloc(size_t priv_size) | |||
2540 | ar9170_rx_reset_rx_mpdu(ar); | 2007 | ar9170_rx_reset_rx_mpdu(ar); |
2541 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); | 2008 | INIT_WORK(&ar->beacon_work, ar9170_new_beacon); |
2542 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); | 2009 | INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); |
2543 | INIT_LIST_HEAD(&ar->tx_ampdu_list); | ||
2544 | 2010 | ||
2545 | /* 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 */ |
2546 | ar->channel = &ar9170_2ghz_chantable[0]; | 2012 | ar->channel = &ar9170_2ghz_chantable[0]; |
@@ -2551,19 +2017,10 @@ void *ar9170_alloc(size_t priv_size) | |||
2551 | BIT(NL80211_IFTYPE_ADHOC); | 2017 | BIT(NL80211_IFTYPE_ADHOC); |
2552 | ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | | 2018 | ar->hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | |
2553 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 2019 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
2554 | IEEE80211_HW_SIGNAL_DBM | | 2020 | IEEE80211_HW_SIGNAL_DBM; |
2555 | IEEE80211_HW_NOISE_DBM; | ||
2556 | |||
2557 | if (modparam_ht) { | ||
2558 | ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; | ||
2559 | } else { | ||
2560 | ar9170_band_2GHz.ht_cap.ht_supported = false; | ||
2561 | ar9170_band_5GHz.ht_cap.ht_supported = false; | ||
2562 | } | ||
2563 | 2021 | ||
2564 | ar->hw->queues = __AR9170_NUM_TXQ; | 2022 | ar->hw->queues = __AR9170_NUM_TXQ; |
2565 | ar->hw->extra_tx_headroom = 8; | 2023 | ar->hw->extra_tx_headroom = 8; |
2566 | ar->hw->sta_data_size = sizeof(struct ar9170_sta_info); | ||
2567 | 2024 | ||
2568 | ar->hw->max_rates = 1; | 2025 | ar->hw->max_rates = 1; |
2569 | ar->hw->max_rate_tries = 3; | 2026 | ar->hw->max_rate_tries = 3; |
diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index a1f5444f7ccd..82ab532a4923 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <linux/usb.h> | 42 | #include <linux/usb.h> |
43 | #include <linux/firmware.h> | 43 | #include <linux/firmware.h> |
44 | #include <linux/etherdevice.h> | 44 | #include <linux/etherdevice.h> |
45 | #include <linux/device.h> | ||
45 | #include <net/mac80211.h> | 46 | #include <net/mac80211.h> |
46 | #include "ar9170.h" | 47 | #include "ar9170.h" |
47 | #include "cmd.h" | 48 | #include "cmd.h" |
@@ -67,18 +68,28 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
67 | { USB_DEVICE(0x0cf3, 0x1001) }, | 68 | { USB_DEVICE(0x0cf3, 0x1001) }, |
68 | /* TP-Link TL-WN821N v2 */ | 69 | /* TP-Link TL-WN821N v2 */ |
69 | { USB_DEVICE(0x0cf3, 0x1002) }, | 70 | { USB_DEVICE(0x0cf3, 0x1002) }, |
71 | /* 3Com Dual Band 802.11n USB Adapter */ | ||
72 | { USB_DEVICE(0x0cf3, 0x1010) }, | ||
73 | /* H3C Dual Band 802.11n USB Adapter */ | ||
74 | { USB_DEVICE(0x0cf3, 0x1011) }, | ||
70 | /* Cace Airpcap NX */ | 75 | /* Cace Airpcap NX */ |
71 | { USB_DEVICE(0xcace, 0x0300) }, | 76 | { USB_DEVICE(0xcace, 0x0300) }, |
72 | /* D-Link DWA 160 A1 */ | 77 | /* D-Link DWA 160 A1 */ |
73 | { USB_DEVICE(0x07d1, 0x3c10) }, | 78 | { USB_DEVICE(0x07d1, 0x3c10) }, |
74 | /* D-Link DWA 160 A2 */ | 79 | /* D-Link DWA 160 A2 */ |
75 | { USB_DEVICE(0x07d1, 0x3a09) }, | 80 | { USB_DEVICE(0x07d1, 0x3a09) }, |
81 | /* Netgear WNA1000 */ | ||
82 | { USB_DEVICE(0x0846, 0x9040) }, | ||
76 | /* Netgear WNDA3100 */ | 83 | /* Netgear WNDA3100 */ |
77 | { USB_DEVICE(0x0846, 0x9010) }, | 84 | { USB_DEVICE(0x0846, 0x9010) }, |
78 | /* Netgear WN111 v2 */ | 85 | /* Netgear WN111 v2 */ |
79 | { USB_DEVICE(0x0846, 0x9001) }, | 86 | { USB_DEVICE(0x0846, 0x9001) }, |
80 | /* Zydas ZD1221 */ | 87 | /* Zydas ZD1221 */ |
81 | { USB_DEVICE(0x0ace, 0x1221) }, | 88 | { USB_DEVICE(0x0ace, 0x1221) }, |
89 | /* Proxim ORiNOCO 802.11n USB */ | ||
90 | { USB_DEVICE(0x1435, 0x0804) }, | ||
91 | /* WNC Generic 11n USB Dongle */ | ||
92 | { USB_DEVICE(0x1435, 0x0326) }, | ||
82 | /* ZyXEL NWD271N */ | 93 | /* ZyXEL NWD271N */ |
83 | { USB_DEVICE(0x0586, 0x3417) }, | 94 | { USB_DEVICE(0x0586, 0x3417) }, |
84 | /* Z-Com UB81 BG */ | 95 | /* Z-Com UB81 BG */ |
@@ -99,6 +110,8 @@ static struct usb_device_id ar9170_usb_ids[] = { | |||
99 | { USB_DEVICE(0x0409, 0x0249) }, | 110 | { USB_DEVICE(0x0409, 0x0249) }, |
100 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ | 111 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ |
101 | { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, | 112 | { USB_DEVICE(0x057C, 0x8402), .driver_info = AR9170_REQ_FW1_ONLY }, |
113 | /* Qwest/Actiontec 802AIN Wireless N USB Network Adapter */ | ||
114 | { USB_DEVICE(0x1668, 0x1200) }, | ||
102 | 115 | ||
103 | /* terminate */ | 116 | /* terminate */ |
104 | {} | 117 | {} |
@@ -731,10 +744,10 @@ static void ar9170_usb_firmware_failed(struct ar9170_usb *aru) | |||
731 | 744 | ||
732 | /* unbind anything failed */ | 745 | /* unbind anything failed */ |
733 | if (parent) | 746 | if (parent) |
734 | down(&parent->sem); | 747 | device_lock(parent); |
735 | device_release_driver(&aru->udev->dev); | 748 | device_release_driver(&aru->udev->dev); |
736 | if (parent) | 749 | if (parent) |
737 | up(&parent->sem); | 750 | device_unlock(parent); |
738 | 751 | ||
739 | usb_put_dev(aru->udev); | 752 | usb_put_dev(aru->udev); |
740 | } | 753 | } |
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 71fc960814f0..d32f2828b098 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h | |||
@@ -48,6 +48,12 @@ enum ath_device_state { | |||
48 | ATH_HW_INITIALIZED, | 48 | ATH_HW_INITIALIZED, |
49 | }; | 49 | }; |
50 | 50 | ||
51 | enum ath_bus_type { | ||
52 | ATH_PCI, | ||
53 | ATH_AHB, | ||
54 | ATH_USB, | ||
55 | }; | ||
56 | |||
51 | struct reg_dmn_pair_mapping { | 57 | struct reg_dmn_pair_mapping { |
52 | u16 regDmnEnum; | 58 | u16 regDmnEnum; |
53 | u16 reg_5ghz_ctl; | 59 | u16 reg_5ghz_ctl; |
@@ -65,17 +71,30 @@ struct ath_regulatory { | |||
65 | struct reg_dmn_pair_mapping *regpair; | 71 | struct reg_dmn_pair_mapping *regpair; |
66 | }; | 72 | }; |
67 | 73 | ||
74 | /** | ||
75 | * struct ath_ops - Register read/write operations | ||
76 | * | ||
77 | * @read: Register read | ||
78 | * @write: Register write | ||
79 | * @enable_write_buffer: Enable multiple register writes | ||
80 | * @disable_write_buffer: Disable multiple register writes | ||
81 | * @write_flush: Flush buffered register writes | ||
82 | */ | ||
68 | struct ath_ops { | 83 | struct ath_ops { |
69 | unsigned int (*read)(void *, u32 reg_offset); | 84 | unsigned int (*read)(void *, u32 reg_offset); |
70 | void (*write)(void *, u32 val, u32 reg_offset); | 85 | void (*write)(void *, u32 val, u32 reg_offset); |
86 | void (*enable_write_buffer)(void *); | ||
87 | void (*disable_write_buffer)(void *); | ||
88 | void (*write_flush) (void *); | ||
71 | }; | 89 | }; |
72 | 90 | ||
73 | struct ath_common; | 91 | struct ath_common; |
74 | 92 | ||
75 | struct ath_bus_ops { | 93 | struct ath_bus_ops { |
76 | void (*read_cachesize)(struct ath_common *common, int *csz); | 94 | enum ath_bus_type ath_bus_type; |
77 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); | 95 | void (*read_cachesize)(struct ath_common *common, int *csz); |
78 | void (*bt_coex_prep)(struct ath_common *common); | 96 | bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); |
97 | void (*bt_coex_prep)(struct ath_common *common); | ||
79 | }; | 98 | }; |
80 | 99 | ||
81 | struct ath_common { | 100 | struct ath_common { |
diff --git a/drivers/net/wireless/ath/ath5k/Makefile b/drivers/net/wireless/ath/ath5k/Makefile index 090dc6d268a3..cc09595b781a 100644 --- a/drivers/net/wireless/ath/ath5k/Makefile +++ b/drivers/net/wireless/ath/ath5k/Makefile | |||
@@ -12,5 +12,6 @@ ath5k-y += attach.o | |||
12 | ath5k-y += base.o | 12 | ath5k-y += base.o |
13 | ath5k-y += led.o | 13 | ath5k-y += led.o |
14 | ath5k-y += rfkill.o | 14 | ath5k-y += rfkill.o |
15 | ath5k-y += ani.o | ||
15 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | 16 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o |
16 | obj-$(CONFIG_ATH5K) += ath5k.o | 17 | obj-$(CONFIG_ATH5K) += ath5k.o |
diff --git a/drivers/net/wireless/ath/ath5k/ani.c b/drivers/net/wireless/ath/ath5k/ani.c new file mode 100644 index 000000000000..f2311ab35504 --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/ani.c | |||
@@ -0,0 +1,744 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Bruno Randolf <br1@einfach.org> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "ath5k.h" | ||
18 | #include "base.h" | ||
19 | #include "reg.h" | ||
20 | #include "debug.h" | ||
21 | #include "ani.h" | ||
22 | |||
23 | /** | ||
24 | * DOC: Basic ANI Operation | ||
25 | * | ||
26 | * Adaptive Noise Immunity (ANI) controls five noise immunity parameters | ||
27 | * depending on the amount of interference in the environment, increasing | ||
28 | * or reducing sensitivity as necessary. | ||
29 | * | ||
30 | * The parameters are: | ||
31 | * - "noise immunity" | ||
32 | * - "spur immunity" | ||
33 | * - "firstep level" | ||
34 | * - "OFDM weak signal detection" | ||
35 | * - "CCK weak signal detection" | ||
36 | * | ||
37 | * Basically we look at the amount of ODFM and CCK timing errors we get and then | ||
38 | * raise or lower immunity accordingly by setting one or more of these | ||
39 | * parameters. | ||
40 | * Newer chipsets have PHY error counters in hardware which will generate a MIB | ||
41 | * interrupt when they overflow. Older hardware has too enable PHY error frames | ||
42 | * by setting a RX flag and then count every single PHY error. When a specified | ||
43 | * threshold of errors has been reached we will raise immunity. | ||
44 | * Also we regularly check the amount of errors and lower or raise immunity as | ||
45 | * necessary. | ||
46 | */ | ||
47 | |||
48 | |||
49 | /*** ANI parameter control ***/ | ||
50 | |||
51 | /** | ||
52 | * ath5k_ani_set_noise_immunity_level() - Set noise immunity level | ||
53 | * | ||
54 | * @level: level between 0 and @ATH5K_ANI_MAX_NOISE_IMM_LVL | ||
55 | */ | ||
56 | void | ||
57 | ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level) | ||
58 | { | ||
59 | /* TODO: | ||
60 | * ANI documents suggest the following five levels to use, but the HAL | ||
61 | * and ath9k use only use the last two levels, making this | ||
62 | * essentially an on/off option. There *may* be a reason for this (???), | ||
63 | * so i stick with the HAL version for now... | ||
64 | */ | ||
65 | #if 0 | ||
66 | const s8 hi[] = { -18, -18, -16, -14, -12 }; | ||
67 | const s8 lo[] = { -52, -56, -60, -64, -70 }; | ||
68 | const s8 sz[] = { -34, -41, -48, -55, -62 }; | ||
69 | const s8 fr[] = { -70, -72, -75, -78, -80 }; | ||
70 | #else | ||
71 | const s8 sz[] = { -55, -62 }; | ||
72 | const s8 lo[] = { -64, -70 }; | ||
73 | const s8 hi[] = { -14, -12 }; | ||
74 | const s8 fr[] = { -78, -80 }; | ||
75 | #endif | ||
76 | if (level < 0 || level >= ARRAY_SIZE(sz)) { | ||
77 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
78 | "level out of range %d", level); | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
83 | AR5K_PHY_DESIRED_SIZE_TOT, sz[level]); | ||
84 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE, | ||
85 | AR5K_PHY_AGCCOARSE_LO, lo[level]); | ||
86 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_AGCCOARSE, | ||
87 | AR5K_PHY_AGCCOARSE_HI, hi[level]); | ||
88 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG, | ||
89 | AR5K_PHY_SIG_FIRPWR, fr[level]); | ||
90 | |||
91 | ah->ah_sc->ani_state.noise_imm_level = level; | ||
92 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level); | ||
93 | } | ||
94 | |||
95 | |||
96 | /** | ||
97 | * ath5k_ani_set_spur_immunity_level() - Set spur immunity level | ||
98 | * | ||
99 | * @level: level between 0 and @max_spur_level (the maximum level is dependent | ||
100 | * on the chip revision). | ||
101 | */ | ||
102 | void | ||
103 | ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level) | ||
104 | { | ||
105 | const int val[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; | ||
106 | |||
107 | if (level < 0 || level >= ARRAY_SIZE(val) || | ||
108 | level > ah->ah_sc->ani_state.max_spur_level) { | ||
109 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
110 | "level out of range %d", level); | ||
111 | return; | ||
112 | } | ||
113 | |||
114 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, | ||
115 | AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, val[level]); | ||
116 | |||
117 | ah->ah_sc->ani_state.spur_level = level; | ||
118 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level); | ||
119 | } | ||
120 | |||
121 | |||
122 | /** | ||
123 | * ath5k_ani_set_firstep_level() - Set "firstep" level | ||
124 | * | ||
125 | * @level: level between 0 and @ATH5K_ANI_MAX_FIRSTEP_LVL | ||
126 | */ | ||
127 | void | ||
128 | ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level) | ||
129 | { | ||
130 | const int val[] = { 0, 4, 8 }; | ||
131 | |||
132 | if (level < 0 || level >= ARRAY_SIZE(val)) { | ||
133 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
134 | "level out of range %d", level); | ||
135 | return; | ||
136 | } | ||
137 | |||
138 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SIG, | ||
139 | AR5K_PHY_SIG_FIRSTEP, val[level]); | ||
140 | |||
141 | ah->ah_sc->ani_state.firstep_level = level; | ||
142 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "new level %d", level); | ||
143 | } | ||
144 | |||
145 | |||
146 | /** | ||
147 | * ath5k_ani_set_ofdm_weak_signal_detection() - Control OFDM weak signal | ||
148 | * detection | ||
149 | * | ||
150 | * @on: turn on or off | ||
151 | */ | ||
152 | void | ||
153 | ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on) | ||
154 | { | ||
155 | const int m1l[] = { 127, 50 }; | ||
156 | const int m2l[] = { 127, 40 }; | ||
157 | const int m1[] = { 127, 0x4d }; | ||
158 | const int m2[] = { 127, 0x40 }; | ||
159 | const int m2cnt[] = { 31, 16 }; | ||
160 | const int m2lcnt[] = { 63, 48 }; | ||
161 | |||
162 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, | ||
163 | AR5K_PHY_WEAK_OFDM_LOW_THR_M1, m1l[on]); | ||
164 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, | ||
165 | AR5K_PHY_WEAK_OFDM_LOW_THR_M2, m2l[on]); | ||
166 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR, | ||
167 | AR5K_PHY_WEAK_OFDM_HIGH_THR_M1, m1[on]); | ||
168 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR, | ||
169 | AR5K_PHY_WEAK_OFDM_HIGH_THR_M2, m2[on]); | ||
170 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_HIGH_THR, | ||
171 | AR5K_PHY_WEAK_OFDM_HIGH_THR_M2_COUNT, m2cnt[on]); | ||
172 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, | ||
173 | AR5K_PHY_WEAK_OFDM_LOW_THR_M2_COUNT, m2lcnt[on]); | ||
174 | |||
175 | if (on) | ||
176 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, | ||
177 | AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN); | ||
178 | else | ||
179 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_WEAK_OFDM_LOW_THR, | ||
180 | AR5K_PHY_WEAK_OFDM_LOW_THR_SELFCOR_EN); | ||
181 | |||
182 | ah->ah_sc->ani_state.ofdm_weak_sig = on; | ||
183 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s", | ||
184 | on ? "on" : "off"); | ||
185 | } | ||
186 | |||
187 | |||
188 | /** | ||
189 | * ath5k_ani_set_cck_weak_signal_detection() - control CCK weak signal detection | ||
190 | * | ||
191 | * @on: turn on or off | ||
192 | */ | ||
193 | void | ||
194 | ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on) | ||
195 | { | ||
196 | const int val[] = { 8, 6 }; | ||
197 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_CCK_CROSSCORR, | ||
198 | AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR, val[on]); | ||
199 | ah->ah_sc->ani_state.cck_weak_sig = on; | ||
200 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "turned %s", | ||
201 | on ? "on" : "off"); | ||
202 | } | ||
203 | |||
204 | |||
205 | /*** ANI algorithm ***/ | ||
206 | |||
207 | /** | ||
208 | * ath5k_ani_raise_immunity() - Increase noise immunity | ||
209 | * | ||
210 | * @ofdm_trigger: If this is true we are called because of too many OFDM errors, | ||
211 | * the algorithm will tune more parameters then. | ||
212 | * | ||
213 | * Try to raise noise immunity (=decrease sensitivity) in several steps | ||
214 | * depending on the average RSSI of the beacons we received. | ||
215 | */ | ||
216 | static void | ||
217 | ath5k_ani_raise_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as, | ||
218 | bool ofdm_trigger) | ||
219 | { | ||
220 | int rssi = ah->ah_beacon_rssi_avg.avg; | ||
221 | |||
222 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "raise immunity (%s)", | ||
223 | ofdm_trigger ? "ODFM" : "CCK"); | ||
224 | |||
225 | /* first: raise noise immunity */ | ||
226 | if (as->noise_imm_level < ATH5K_ANI_MAX_NOISE_IMM_LVL) { | ||
227 | ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level + 1); | ||
228 | return; | ||
229 | } | ||
230 | |||
231 | /* only OFDM: raise spur immunity level */ | ||
232 | if (ofdm_trigger && | ||
233 | as->spur_level < ah->ah_sc->ani_state.max_spur_level) { | ||
234 | ath5k_ani_set_spur_immunity_level(ah, as->spur_level + 1); | ||
235 | return; | ||
236 | } | ||
237 | |||
238 | /* AP mode */ | ||
239 | if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) { | ||
240 | if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) | ||
241 | ath5k_ani_set_firstep_level(ah, as->firstep_level + 1); | ||
242 | return; | ||
243 | } | ||
244 | |||
245 | /* STA and IBSS mode */ | ||
246 | |||
247 | /* TODO: for IBSS mode it would be better to keep a beacon RSSI average | ||
248 | * per each neighbour node and use the minimum of these, to make sure we | ||
249 | * don't shut out a remote node by raising immunity too high. */ | ||
250 | |||
251 | if (rssi > ATH5K_ANI_RSSI_THR_HIGH) { | ||
252 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
253 | "beacon RSSI high"); | ||
254 | /* only OFDM: beacon RSSI is high, we can disable ODFM weak | ||
255 | * signal detection */ | ||
256 | if (ofdm_trigger && as->ofdm_weak_sig == true) { | ||
257 | ath5k_ani_set_ofdm_weak_signal_detection(ah, false); | ||
258 | ath5k_ani_set_spur_immunity_level(ah, 0); | ||
259 | return; | ||
260 | } | ||
261 | /* as a last resort or CCK: raise firstep level */ | ||
262 | if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) { | ||
263 | ath5k_ani_set_firstep_level(ah, as->firstep_level + 1); | ||
264 | return; | ||
265 | } | ||
266 | } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) { | ||
267 | /* beacon RSSI in mid range, we need OFDM weak signal detect, | ||
268 | * but can raise firstep level */ | ||
269 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
270 | "beacon RSSI mid"); | ||
271 | if (ofdm_trigger && as->ofdm_weak_sig == false) | ||
272 | ath5k_ani_set_ofdm_weak_signal_detection(ah, true); | ||
273 | if (as->firstep_level < ATH5K_ANI_MAX_FIRSTEP_LVL) | ||
274 | ath5k_ani_set_firstep_level(ah, as->firstep_level + 1); | ||
275 | return; | ||
276 | } else if (ah->ah_current_channel->band == IEEE80211_BAND_2GHZ) { | ||
277 | /* beacon RSSI is low. in B/G mode turn of OFDM weak signal | ||
278 | * detect and zero firstep level to maximize CCK sensitivity */ | ||
279 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
280 | "beacon RSSI low, 2GHz"); | ||
281 | if (ofdm_trigger && as->ofdm_weak_sig == true) | ||
282 | ath5k_ani_set_ofdm_weak_signal_detection(ah, false); | ||
283 | if (as->firstep_level > 0) | ||
284 | ath5k_ani_set_firstep_level(ah, 0); | ||
285 | return; | ||
286 | } | ||
287 | |||
288 | /* TODO: why not?: | ||
289 | if (as->cck_weak_sig == true) { | ||
290 | ath5k_ani_set_cck_weak_signal_detection(ah, false); | ||
291 | } | ||
292 | */ | ||
293 | } | ||
294 | |||
295 | |||
296 | /** | ||
297 | * ath5k_ani_lower_immunity() - Decrease noise immunity | ||
298 | * | ||
299 | * Try to lower noise immunity (=increase sensitivity) in several steps | ||
300 | * depending on the average RSSI of the beacons we received. | ||
301 | */ | ||
302 | static void | ||
303 | ath5k_ani_lower_immunity(struct ath5k_hw *ah, struct ath5k_ani_state *as) | ||
304 | { | ||
305 | int rssi = ah->ah_beacon_rssi_avg.avg; | ||
306 | |||
307 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "lower immunity"); | ||
308 | |||
309 | if (ah->ah_sc->opmode == NL80211_IFTYPE_AP) { | ||
310 | /* AP mode */ | ||
311 | if (as->firstep_level > 0) { | ||
312 | ath5k_ani_set_firstep_level(ah, as->firstep_level - 1); | ||
313 | return; | ||
314 | } | ||
315 | } else { | ||
316 | /* STA and IBSS mode (see TODO above) */ | ||
317 | if (rssi > ATH5K_ANI_RSSI_THR_HIGH) { | ||
318 | /* beacon signal is high, leave OFDM weak signal | ||
319 | * detection off or it may oscillate | ||
320 | * TODO: who said it's off??? */ | ||
321 | } else if (rssi > ATH5K_ANI_RSSI_THR_LOW) { | ||
322 | /* beacon RSSI is mid-range: turn on ODFM weak signal | ||
323 | * detection and next, lower firstep level */ | ||
324 | if (as->ofdm_weak_sig == false) { | ||
325 | ath5k_ani_set_ofdm_weak_signal_detection(ah, | ||
326 | true); | ||
327 | return; | ||
328 | } | ||
329 | if (as->firstep_level > 0) { | ||
330 | ath5k_ani_set_firstep_level(ah, | ||
331 | as->firstep_level - 1); | ||
332 | return; | ||
333 | } | ||
334 | } else { | ||
335 | /* beacon signal is low: only reduce firstep level */ | ||
336 | if (as->firstep_level > 0) { | ||
337 | ath5k_ani_set_firstep_level(ah, | ||
338 | as->firstep_level - 1); | ||
339 | return; | ||
340 | } | ||
341 | } | ||
342 | } | ||
343 | |||
344 | /* all modes */ | ||
345 | if (as->spur_level > 0) { | ||
346 | ath5k_ani_set_spur_immunity_level(ah, as->spur_level - 1); | ||
347 | return; | ||
348 | } | ||
349 | |||
350 | /* finally, reduce noise immunity */ | ||
351 | if (as->noise_imm_level > 0) { | ||
352 | ath5k_ani_set_noise_immunity_level(ah, as->noise_imm_level - 1); | ||
353 | return; | ||
354 | } | ||
355 | } | ||
356 | |||
357 | |||
358 | /** | ||
359 | * ath5k_hw_ani_get_listen_time() - Calculate time spent listening | ||
360 | * | ||
361 | * Return an approximation of the time spent "listening" in milliseconds (ms) | ||
362 | * since the last call of this function by deducting the cycles spent | ||
363 | * transmitting and receiving from the total cycle count. | ||
364 | * Save profile count values for debugging/statistics and because we might want | ||
365 | * to use them later. | ||
366 | * | ||
367 | * We assume no one else clears these registers! | ||
368 | */ | ||
369 | static int | ||
370 | ath5k_hw_ani_get_listen_time(struct ath5k_hw *ah, struct ath5k_ani_state *as) | ||
371 | { | ||
372 | int listen; | ||
373 | |||
374 | /* freeze */ | ||
375 | ath5k_hw_reg_write(ah, AR5K_MIBC_FMC, AR5K_MIBC); | ||
376 | /* read */ | ||
377 | as->pfc_cycles = ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE); | ||
378 | as->pfc_busy = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR); | ||
379 | as->pfc_tx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX); | ||
380 | as->pfc_rx = ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX); | ||
381 | /* clear */ | ||
382 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); | ||
383 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); | ||
384 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); | ||
385 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); | ||
386 | /* un-freeze */ | ||
387 | ath5k_hw_reg_write(ah, 0, AR5K_MIBC); | ||
388 | |||
389 | /* TODO: where does 44000 come from? (11g clock rate?) */ | ||
390 | listen = (as->pfc_cycles - as->pfc_rx - as->pfc_tx) / 44000; | ||
391 | |||
392 | if (as->pfc_cycles == 0 || listen < 0) | ||
393 | return 0; | ||
394 | return listen; | ||
395 | } | ||
396 | |||
397 | |||
398 | /** | ||
399 | * ath5k_ani_save_and_clear_phy_errors() - Clear and save PHY error counters | ||
400 | * | ||
401 | * Clear the PHY error counters as soon as possible, since this might be called | ||
402 | * from a MIB interrupt and we want to make sure we don't get interrupted again. | ||
403 | * Add the count of CCK and OFDM errors to our internal state, so it can be used | ||
404 | * by the algorithm later. | ||
405 | * | ||
406 | * Will be called from interrupt and tasklet context. | ||
407 | * Returns 0 if both counters are zero. | ||
408 | */ | ||
409 | static int | ||
410 | ath5k_ani_save_and_clear_phy_errors(struct ath5k_hw *ah, | ||
411 | struct ath5k_ani_state *as) | ||
412 | { | ||
413 | unsigned int ofdm_err, cck_err; | ||
414 | |||
415 | if (!ah->ah_capabilities.cap_has_phyerr_counters) | ||
416 | return 0; | ||
417 | |||
418 | ofdm_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1); | ||
419 | cck_err = ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2); | ||
420 | |||
421 | /* reset counters first, we might be in a hurry (interrupt) */ | ||
422 | ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH, | ||
423 | AR5K_PHYERR_CNT1); | ||
424 | ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH, | ||
425 | AR5K_PHYERR_CNT2); | ||
426 | |||
427 | ofdm_err = ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - ofdm_err); | ||
428 | cck_err = ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - cck_err); | ||
429 | |||
430 | /* sometimes both can be zero, especially when there is a superfluous | ||
431 | * second interrupt. detect that here and return an error. */ | ||
432 | if (ofdm_err <= 0 && cck_err <= 0) | ||
433 | return 0; | ||
434 | |||
435 | /* avoid negative values should one of the registers overflow */ | ||
436 | if (ofdm_err > 0) { | ||
437 | as->ofdm_errors += ofdm_err; | ||
438 | as->sum_ofdm_errors += ofdm_err; | ||
439 | } | ||
440 | if (cck_err > 0) { | ||
441 | as->cck_errors += cck_err; | ||
442 | as->sum_cck_errors += cck_err; | ||
443 | } | ||
444 | return 1; | ||
445 | } | ||
446 | |||
447 | |||
448 | /** | ||
449 | * ath5k_ani_period_restart() - Restart ANI period | ||
450 | * | ||
451 | * Just reset counters, so they are clear for the next "ani period". | ||
452 | */ | ||
453 | static void | ||
454 | ath5k_ani_period_restart(struct ath5k_hw *ah, struct ath5k_ani_state *as) | ||
455 | { | ||
456 | /* keep last values for debugging */ | ||
457 | as->last_ofdm_errors = as->ofdm_errors; | ||
458 | as->last_cck_errors = as->cck_errors; | ||
459 | as->last_listen = as->listen_time; | ||
460 | |||
461 | as->ofdm_errors = 0; | ||
462 | as->cck_errors = 0; | ||
463 | as->listen_time = 0; | ||
464 | } | ||
465 | |||
466 | |||
467 | /** | ||
468 | * ath5k_ani_calibration() - The main ANI calibration function | ||
469 | * | ||
470 | * We count OFDM and CCK errors relative to the time where we did not send or | ||
471 | * receive ("listen" time) and raise or lower immunity accordingly. | ||
472 | * This is called regularly (every second) from the calibration timer, but also | ||
473 | * when an error threshold has been reached. | ||
474 | * | ||
475 | * In order to synchronize access from different contexts, this should be | ||
476 | * called only indirectly by scheduling the ANI tasklet! | ||
477 | */ | ||
478 | void | ||
479 | ath5k_ani_calibration(struct ath5k_hw *ah) | ||
480 | { | ||
481 | struct ath5k_ani_state *as = &ah->ah_sc->ani_state; | ||
482 | int listen, ofdm_high, ofdm_low, cck_high, cck_low; | ||
483 | |||
484 | if (as->ani_mode != ATH5K_ANI_MODE_AUTO) | ||
485 | return; | ||
486 | |||
487 | /* get listen time since last call and add it to the counter because we | ||
488 | * might not have restarted the "ani period" last time */ | ||
489 | listen = ath5k_hw_ani_get_listen_time(ah, as); | ||
490 | as->listen_time += listen; | ||
491 | |||
492 | ath5k_ani_save_and_clear_phy_errors(ah, as); | ||
493 | |||
494 | ofdm_high = as->listen_time * ATH5K_ANI_OFDM_TRIG_HIGH / 1000; | ||
495 | cck_high = as->listen_time * ATH5K_ANI_CCK_TRIG_HIGH / 1000; | ||
496 | ofdm_low = as->listen_time * ATH5K_ANI_OFDM_TRIG_LOW / 1000; | ||
497 | cck_low = as->listen_time * ATH5K_ANI_CCK_TRIG_LOW / 1000; | ||
498 | |||
499 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
500 | "listen %d (now %d)", as->listen_time, listen); | ||
501 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
502 | "check high ofdm %d/%d cck %d/%d", | ||
503 | as->ofdm_errors, ofdm_high, as->cck_errors, cck_high); | ||
504 | |||
505 | if (as->ofdm_errors > ofdm_high || as->cck_errors > cck_high) { | ||
506 | /* too many PHY errors - we have to raise immunity */ | ||
507 | bool ofdm_flag = as->ofdm_errors > ofdm_high ? true : false; | ||
508 | ath5k_ani_raise_immunity(ah, as, ofdm_flag); | ||
509 | ath5k_ani_period_restart(ah, as); | ||
510 | |||
511 | } else if (as->listen_time > 5 * ATH5K_ANI_LISTEN_PERIOD) { | ||
512 | /* If more than 5 (TODO: why 5?) periods have passed and we got | ||
513 | * relatively little errors we can try to lower immunity */ | ||
514 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
515 | "check low ofdm %d/%d cck %d/%d", | ||
516 | as->ofdm_errors, ofdm_low, as->cck_errors, cck_low); | ||
517 | |||
518 | if (as->ofdm_errors <= ofdm_low && as->cck_errors <= cck_low) | ||
519 | ath5k_ani_lower_immunity(ah, as); | ||
520 | |||
521 | ath5k_ani_period_restart(ah, as); | ||
522 | } | ||
523 | } | ||
524 | |||
525 | |||
526 | /*** INTERRUPT HANDLER ***/ | ||
527 | |||
528 | /** | ||
529 | * ath5k_ani_mib_intr() - Interrupt handler for ANI MIB counters | ||
530 | * | ||
531 | * Just read & reset the registers quickly, so they don't generate more | ||
532 | * interrupts, save the counters and schedule the tasklet to decide whether | ||
533 | * to raise immunity or not. | ||
534 | * | ||
535 | * We just need to handle PHY error counters, ath5k_hw_update_mib_counters() | ||
536 | * should take care of all "normal" MIB interrupts. | ||
537 | */ | ||
538 | void | ||
539 | ath5k_ani_mib_intr(struct ath5k_hw *ah) | ||
540 | { | ||
541 | struct ath5k_ani_state *as = &ah->ah_sc->ani_state; | ||
542 | |||
543 | /* nothing to do here if HW does not have PHY error counters - they | ||
544 | * can't be the reason for the MIB interrupt then */ | ||
545 | if (!ah->ah_capabilities.cap_has_phyerr_counters) | ||
546 | return; | ||
547 | |||
548 | /* not in use but clear anyways */ | ||
549 | ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT); | ||
550 | ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT); | ||
551 | |||
552 | if (ah->ah_sc->ani_state.ani_mode != ATH5K_ANI_MODE_AUTO) | ||
553 | return; | ||
554 | |||
555 | /* if one of the errors triggered, we can get a superfluous second | ||
556 | * interrupt, even though we have already reset the register. the | ||
557 | * function detects that so we can return early */ | ||
558 | if (ath5k_ani_save_and_clear_phy_errors(ah, as) == 0) | ||
559 | return; | ||
560 | |||
561 | if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH || | ||
562 | as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH) | ||
563 | tasklet_schedule(&ah->ah_sc->ani_tasklet); | ||
564 | } | ||
565 | |||
566 | |||
567 | /** | ||
568 | * ath5k_ani_phy_error_report() - Used by older HW to report PHY errors | ||
569 | * | ||
570 | * This is used by hardware without PHY error counters to report PHY errors | ||
571 | * on a frame-by-frame basis, instead of the interrupt. | ||
572 | */ | ||
573 | void | ||
574 | ath5k_ani_phy_error_report(struct ath5k_hw *ah, | ||
575 | enum ath5k_phy_error_code phyerr) | ||
576 | { | ||
577 | struct ath5k_ani_state *as = &ah->ah_sc->ani_state; | ||
578 | |||
579 | if (phyerr == AR5K_RX_PHY_ERROR_OFDM_TIMING) { | ||
580 | as->ofdm_errors++; | ||
581 | if (as->ofdm_errors > ATH5K_ANI_OFDM_TRIG_HIGH) | ||
582 | tasklet_schedule(&ah->ah_sc->ani_tasklet); | ||
583 | } else if (phyerr == AR5K_RX_PHY_ERROR_CCK_TIMING) { | ||
584 | as->cck_errors++; | ||
585 | if (as->cck_errors > ATH5K_ANI_CCK_TRIG_HIGH) | ||
586 | tasklet_schedule(&ah->ah_sc->ani_tasklet); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | |||
591 | /*** INIT ***/ | ||
592 | |||
593 | /** | ||
594 | * ath5k_enable_phy_err_counters() - Enable PHY error counters | ||
595 | * | ||
596 | * Enable PHY error counters for OFDM and CCK timing errors. | ||
597 | */ | ||
598 | static void | ||
599 | ath5k_enable_phy_err_counters(struct ath5k_hw *ah) | ||
600 | { | ||
601 | ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_OFDM_TRIG_HIGH, | ||
602 | AR5K_PHYERR_CNT1); | ||
603 | ath5k_hw_reg_write(ah, ATH5K_PHYERR_CNT_MAX - ATH5K_ANI_CCK_TRIG_HIGH, | ||
604 | AR5K_PHYERR_CNT2); | ||
605 | ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_OFDM, AR5K_PHYERR_CNT1_MASK); | ||
606 | ath5k_hw_reg_write(ah, AR5K_PHY_ERR_FIL_CCK, AR5K_PHYERR_CNT2_MASK); | ||
607 | |||
608 | /* not in use */ | ||
609 | ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT); | ||
610 | ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT); | ||
611 | } | ||
612 | |||
613 | |||
614 | /** | ||
615 | * ath5k_disable_phy_err_counters() - Disable PHY error counters | ||
616 | * | ||
617 | * Disable PHY error counters for OFDM and CCK timing errors. | ||
618 | */ | ||
619 | static void | ||
620 | ath5k_disable_phy_err_counters(struct ath5k_hw *ah) | ||
621 | { | ||
622 | ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1); | ||
623 | ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2); | ||
624 | ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT1_MASK); | ||
625 | ath5k_hw_reg_write(ah, 0, AR5K_PHYERR_CNT2_MASK); | ||
626 | |||
627 | /* not in use */ | ||
628 | ath5k_hw_reg_write(ah, 0, AR5K_OFDM_FIL_CNT); | ||
629 | ath5k_hw_reg_write(ah, 0, AR5K_CCK_FIL_CNT); | ||
630 | } | ||
631 | |||
632 | |||
633 | /** | ||
634 | * ath5k_ani_init() - Initialize ANI | ||
635 | * @mode: Which mode to use (auto, manual high, manual low, off) | ||
636 | * | ||
637 | * Initialize ANI according to mode. | ||
638 | */ | ||
639 | void | ||
640 | ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode) | ||
641 | { | ||
642 | /* ANI is only possible on 5212 and newer */ | ||
643 | if (ah->ah_version < AR5K_AR5212) | ||
644 | return; | ||
645 | |||
646 | /* clear old state information */ | ||
647 | memset(&ah->ah_sc->ani_state, 0, sizeof(ah->ah_sc->ani_state)); | ||
648 | |||
649 | /* older hardware has more spur levels than newer */ | ||
650 | if (ah->ah_mac_srev < AR5K_SREV_AR2414) | ||
651 | ah->ah_sc->ani_state.max_spur_level = 7; | ||
652 | else | ||
653 | ah->ah_sc->ani_state.max_spur_level = 2; | ||
654 | |||
655 | /* initial values for our ani parameters */ | ||
656 | if (mode == ATH5K_ANI_MODE_OFF) { | ||
657 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI off\n"); | ||
658 | } else if (mode == ATH5K_ANI_MODE_MANUAL_LOW) { | ||
659 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
660 | "ANI manual low -> high sensitivity\n"); | ||
661 | ath5k_ani_set_noise_immunity_level(ah, 0); | ||
662 | ath5k_ani_set_spur_immunity_level(ah, 0); | ||
663 | ath5k_ani_set_firstep_level(ah, 0); | ||
664 | ath5k_ani_set_ofdm_weak_signal_detection(ah, true); | ||
665 | ath5k_ani_set_cck_weak_signal_detection(ah, true); | ||
666 | } else if (mode == ATH5K_ANI_MODE_MANUAL_HIGH) { | ||
667 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, | ||
668 | "ANI manual high -> low sensitivity\n"); | ||
669 | ath5k_ani_set_noise_immunity_level(ah, | ||
670 | ATH5K_ANI_MAX_NOISE_IMM_LVL); | ||
671 | ath5k_ani_set_spur_immunity_level(ah, | ||
672 | ah->ah_sc->ani_state.max_spur_level); | ||
673 | ath5k_ani_set_firstep_level(ah, ATH5K_ANI_MAX_FIRSTEP_LVL); | ||
674 | ath5k_ani_set_ofdm_weak_signal_detection(ah, false); | ||
675 | ath5k_ani_set_cck_weak_signal_detection(ah, false); | ||
676 | } else if (mode == ATH5K_ANI_MODE_AUTO) { | ||
677 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_ANI, "ANI auto\n"); | ||
678 | ath5k_ani_set_noise_immunity_level(ah, 0); | ||
679 | ath5k_ani_set_spur_immunity_level(ah, 0); | ||
680 | ath5k_ani_set_firstep_level(ah, 0); | ||
681 | ath5k_ani_set_ofdm_weak_signal_detection(ah, true); | ||
682 | ath5k_ani_set_cck_weak_signal_detection(ah, false); | ||
683 | } | ||
684 | |||
685 | /* newer hardware has PHY error counter registers which we can use to | ||
686 | * get OFDM and CCK error counts. older hardware has to set rxfilter and | ||
687 | * report every single PHY error by calling ath5k_ani_phy_error_report() | ||
688 | */ | ||
689 | if (mode == ATH5K_ANI_MODE_AUTO) { | ||
690 | if (ah->ah_capabilities.cap_has_phyerr_counters) | ||
691 | ath5k_enable_phy_err_counters(ah); | ||
692 | else | ||
693 | ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) | | ||
694 | AR5K_RX_FILTER_PHYERR); | ||
695 | } else { | ||
696 | if (ah->ah_capabilities.cap_has_phyerr_counters) | ||
697 | ath5k_disable_phy_err_counters(ah); | ||
698 | else | ||
699 | ath5k_hw_set_rx_filter(ah, ath5k_hw_get_rx_filter(ah) & | ||
700 | ~AR5K_RX_FILTER_PHYERR); | ||
701 | } | ||
702 | |||
703 | ah->ah_sc->ani_state.ani_mode = mode; | ||
704 | } | ||
705 | |||
706 | |||
707 | /*** DEBUG ***/ | ||
708 | |||
709 | #ifdef CONFIG_ATH5K_DEBUG | ||
710 | |||
711 | void | ||
712 | ath5k_ani_print_counters(struct ath5k_hw *ah) | ||
713 | { | ||
714 | /* clears too */ | ||
715 | printk(KERN_NOTICE "ACK fail\t%d\n", | ||
716 | ath5k_hw_reg_read(ah, AR5K_ACK_FAIL)); | ||
717 | printk(KERN_NOTICE "RTS fail\t%d\n", | ||
718 | ath5k_hw_reg_read(ah, AR5K_RTS_FAIL)); | ||
719 | printk(KERN_NOTICE "RTS success\t%d\n", | ||
720 | ath5k_hw_reg_read(ah, AR5K_RTS_OK)); | ||
721 | printk(KERN_NOTICE "FCS error\t%d\n", | ||
722 | ath5k_hw_reg_read(ah, AR5K_FCS_FAIL)); | ||
723 | |||
724 | /* no clear */ | ||
725 | printk(KERN_NOTICE "tx\t%d\n", | ||
726 | ath5k_hw_reg_read(ah, AR5K_PROFCNT_TX)); | ||
727 | printk(KERN_NOTICE "rx\t%d\n", | ||
728 | ath5k_hw_reg_read(ah, AR5K_PROFCNT_RX)); | ||
729 | printk(KERN_NOTICE "busy\t%d\n", | ||
730 | ath5k_hw_reg_read(ah, AR5K_PROFCNT_RXCLR)); | ||
731 | printk(KERN_NOTICE "cycles\t%d\n", | ||
732 | ath5k_hw_reg_read(ah, AR5K_PROFCNT_CYCLE)); | ||
733 | |||
734 | printk(KERN_NOTICE "AR5K_PHYERR_CNT1\t%d\n", | ||
735 | ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT1)); | ||
736 | printk(KERN_NOTICE "AR5K_PHYERR_CNT2\t%d\n", | ||
737 | ath5k_hw_reg_read(ah, AR5K_PHYERR_CNT2)); | ||
738 | printk(KERN_NOTICE "AR5K_OFDM_FIL_CNT\t%d\n", | ||
739 | ath5k_hw_reg_read(ah, AR5K_OFDM_FIL_CNT)); | ||
740 | printk(KERN_NOTICE "AR5K_CCK_FIL_CNT\t%d\n", | ||
741 | ath5k_hw_reg_read(ah, AR5K_CCK_FIL_CNT)); | ||
742 | } | ||
743 | |||
744 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath5k/ani.h b/drivers/net/wireless/ath/ath5k/ani.h new file mode 100644 index 000000000000..55cf26d8522c --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/ani.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Bruno Randolf <br1@einfach.org> | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | #ifndef ANI_H | ||
17 | #define ANI_H | ||
18 | |||
19 | /* these thresholds are relative to the ATH5K_ANI_LISTEN_PERIOD */ | ||
20 | #define ATH5K_ANI_LISTEN_PERIOD 100 | ||
21 | #define ATH5K_ANI_OFDM_TRIG_HIGH 500 | ||
22 | #define ATH5K_ANI_OFDM_TRIG_LOW 200 | ||
23 | #define ATH5K_ANI_CCK_TRIG_HIGH 200 | ||
24 | #define ATH5K_ANI_CCK_TRIG_LOW 100 | ||
25 | |||
26 | /* average beacon RSSI thresholds */ | ||
27 | #define ATH5K_ANI_RSSI_THR_HIGH 40 | ||
28 | #define ATH5K_ANI_RSSI_THR_LOW 7 | ||
29 | |||
30 | /* maximum availabe levels */ | ||
31 | #define ATH5K_ANI_MAX_FIRSTEP_LVL 2 | ||
32 | #define ATH5K_ANI_MAX_NOISE_IMM_LVL 1 | ||
33 | |||
34 | |||
35 | /** | ||
36 | * enum ath5k_ani_mode - mode for ANI / noise sensitivity | ||
37 | * | ||
38 | * @ATH5K_ANI_MODE_OFF: Turn ANI off. This can be useful to just stop the ANI | ||
39 | * algorithm after it has been on auto mode. | ||
40 | * ATH5K_ANI_MODE_MANUAL_LOW: Manually set all immunity parameters to low, | ||
41 | * maximizing sensitivity. ANI will not run. | ||
42 | * ATH5K_ANI_MODE_MANUAL_HIGH: Manually set all immunity parameters to high, | ||
43 | * minimizing sensitivity. ANI will not run. | ||
44 | * ATH5K_ANI_MODE_AUTO: Automatically control immunity parameters based on the | ||
45 | * amount of OFDM and CCK frame errors (default). | ||
46 | */ | ||
47 | enum ath5k_ani_mode { | ||
48 | ATH5K_ANI_MODE_OFF = 0, | ||
49 | ATH5K_ANI_MODE_MANUAL_LOW = 1, | ||
50 | ATH5K_ANI_MODE_MANUAL_HIGH = 2, | ||
51 | ATH5K_ANI_MODE_AUTO = 3 | ||
52 | }; | ||
53 | |||
54 | |||
55 | /** | ||
56 | * struct ath5k_ani_state - ANI state and associated counters | ||
57 | * | ||
58 | * @max_spur_level: the maximum spur level is chip dependent | ||
59 | */ | ||
60 | struct ath5k_ani_state { | ||
61 | enum ath5k_ani_mode ani_mode; | ||
62 | |||
63 | /* state */ | ||
64 | int noise_imm_level; | ||
65 | int spur_level; | ||
66 | int firstep_level; | ||
67 | bool ofdm_weak_sig; | ||
68 | bool cck_weak_sig; | ||
69 | |||
70 | int max_spur_level; | ||
71 | |||
72 | /* used by the algorithm */ | ||
73 | unsigned int listen_time; | ||
74 | unsigned int ofdm_errors; | ||
75 | unsigned int cck_errors; | ||
76 | |||
77 | /* debug/statistics only: numbers from last ANI calibration */ | ||
78 | unsigned int pfc_tx; | ||
79 | unsigned int pfc_rx; | ||
80 | unsigned int pfc_busy; | ||
81 | unsigned int pfc_cycles; | ||
82 | unsigned int last_listen; | ||
83 | unsigned int last_ofdm_errors; | ||
84 | unsigned int last_cck_errors; | ||
85 | unsigned int sum_ofdm_errors; | ||
86 | unsigned int sum_cck_errors; | ||
87 | }; | ||
88 | |||
89 | void ath5k_ani_init(struct ath5k_hw *ah, enum ath5k_ani_mode mode); | ||
90 | void ath5k_ani_mib_intr(struct ath5k_hw *ah); | ||
91 | void ath5k_ani_calibration(struct ath5k_hw *ah); | ||
92 | void ath5k_ani_phy_error_report(struct ath5k_hw *ah, | ||
93 | enum ath5k_phy_error_code phyerr); | ||
94 | |||
95 | /* for manual control */ | ||
96 | void ath5k_ani_set_noise_immunity_level(struct ath5k_hw *ah, int level); | ||
97 | void ath5k_ani_set_spur_immunity_level(struct ath5k_hw *ah, int level); | ||
98 | void ath5k_ani_set_firstep_level(struct ath5k_hw *ah, int level); | ||
99 | void ath5k_ani_set_ofdm_weak_signal_detection(struct ath5k_hw *ah, bool on); | ||
100 | void ath5k_ani_set_cck_weak_signal_detection(struct ath5k_hw *ah, bool on); | ||
101 | |||
102 | void ath5k_ani_print_counters(struct ath5k_hw *ah); | ||
103 | |||
104 | #endif /* ANI_H */ | ||
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index ac67f02e26d8..2785946f659a 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -202,7 +202,8 @@ | |||
202 | #define AR5K_TUNE_MAX_TXPOWER 63 | 202 | #define AR5K_TUNE_MAX_TXPOWER 63 |
203 | #define AR5K_TUNE_DEFAULT_TXPOWER 25 | 203 | #define AR5K_TUNE_DEFAULT_TXPOWER 25 |
204 | #define AR5K_TUNE_TPC_TXPOWER false | 204 | #define AR5K_TUNE_TPC_TXPOWER false |
205 | #define AR5K_TUNE_HWTXTRIES 4 | 205 | #define ATH5K_TUNE_CALIBRATION_INTERVAL_FULL 10000 /* 10 sec */ |
206 | #define ATH5K_TUNE_CALIBRATION_INTERVAL_ANI 1000 /* 1 sec */ | ||
206 | 207 | ||
207 | #define AR5K_INIT_CARR_SENSE_EN 1 | 208 | #define AR5K_INIT_CARR_SENSE_EN 1 |
208 | 209 | ||
@@ -614,28 +615,6 @@ struct ath5k_rx_status { | |||
614 | #define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ | 615 | #define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/ |
615 | #define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ | 616 | #define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/ |
616 | 617 | ||
617 | #if 0 | ||
618 | /** | ||
619 | * struct ath5k_beacon_state - Per-station beacon timer state. | ||
620 | * @bs_interval: in TU's, can also include the above flags | ||
621 | * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a | ||
622 | * Point Coordination Function capable AP | ||
623 | */ | ||
624 | struct ath5k_beacon_state { | ||
625 | u32 bs_next_beacon; | ||
626 | u32 bs_next_dtim; | ||
627 | u32 bs_interval; | ||
628 | u8 bs_dtim_period; | ||
629 | u8 bs_cfp_period; | ||
630 | u16 bs_cfp_max_duration; | ||
631 | u16 bs_cfp_du_remain; | ||
632 | u16 bs_tim_offset; | ||
633 | u16 bs_sleep_duration; | ||
634 | u16 bs_bmiss_threshold; | ||
635 | u32 bs_cfp_next; | ||
636 | }; | ||
637 | #endif | ||
638 | |||
639 | 618 | ||
640 | /* | 619 | /* |
641 | * TSF to TU conversion: | 620 | * TSF to TU conversion: |
@@ -822,9 +801,9 @@ struct ath5k_athchan_2ghz { | |||
822 | * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold | 801 | * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold |
823 | * We currently do increments on interrupt by | 802 | * We currently do increments on interrupt by |
824 | * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 | 803 | * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2 |
825 | * @AR5K_INT_MIB: Indicates the Management Information Base counters should be | 804 | * @AR5K_INT_MIB: Indicates the either Management Information Base counters or |
826 | * checked. We should do this with ath5k_hw_update_mib_counters() but | 805 | * one of the PHY error counters reached the maximum value and should be |
827 | * it seems we should also then do some noise immunity work. | 806 | * read and cleared. |
828 | * @AR5K_INT_RXPHY: RX PHY Error | 807 | * @AR5K_INT_RXPHY: RX PHY Error |
829 | * @AR5K_INT_RXKCM: RX Key cache miss | 808 | * @AR5K_INT_RXKCM: RX Key cache miss |
830 | * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a | 809 | * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a |
@@ -912,10 +891,11 @@ enum ath5k_int { | |||
912 | AR5K_INT_NOCARD = 0xffffffff | 891 | AR5K_INT_NOCARD = 0xffffffff |
913 | }; | 892 | }; |
914 | 893 | ||
915 | /* Software interrupts used for calibration */ | 894 | /* mask which calibration is active at the moment */ |
916 | enum ath5k_software_interrupt { | 895 | enum ath5k_calibration_mask { |
917 | AR5K_SWI_FULL_CALIBRATION = 0x01, | 896 | AR5K_CALIBRATION_FULL = 0x01, |
918 | AR5K_SWI_SHORT_CALIBRATION = 0x02, | 897 | AR5K_CALIBRATION_SHORT = 0x02, |
898 | AR5K_CALIBRATION_ANI = 0x04, | ||
919 | }; | 899 | }; |
920 | 900 | ||
921 | /* | 901 | /* |
@@ -1004,6 +984,8 @@ struct ath5k_capabilities { | |||
1004 | struct { | 984 | struct { |
1005 | u8 q_tx_num; | 985 | u8 q_tx_num; |
1006 | } cap_queues; | 986 | } cap_queues; |
987 | |||
988 | bool cap_has_phyerr_counters; | ||
1007 | }; | 989 | }; |
1008 | 990 | ||
1009 | /* size of noise floor history (keep it a power of two) */ | 991 | /* size of noise floor history (keep it a power of two) */ |
@@ -1014,6 +996,15 @@ struct ath5k_nfcal_hist | |||
1014 | s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ | 996 | s16 nfval[ATH5K_NF_CAL_HIST_MAX]; /* last few noise floors */ |
1015 | }; | 997 | }; |
1016 | 998 | ||
999 | /** | ||
1000 | * struct avg_val - Helper structure for average calculation | ||
1001 | * @avg: contains the actual average value | ||
1002 | * @avg_weight: is used internally during calculation to prevent rounding errors | ||
1003 | */ | ||
1004 | struct ath5k_avg_val { | ||
1005 | int avg; | ||
1006 | int avg_weight; | ||
1007 | }; | ||
1017 | 1008 | ||
1018 | /***************************************\ | 1009 | /***************************************\ |
1019 | HARDWARE ABSTRACTION LAYER STRUCTURE | 1010 | HARDWARE ABSTRACTION LAYER STRUCTURE |
@@ -1028,7 +1019,6 @@ struct ath5k_nfcal_hist | |||
1028 | 1019 | ||
1029 | /* TODO: Clean up and merge with ath5k_softc */ | 1020 | /* TODO: Clean up and merge with ath5k_softc */ |
1030 | struct ath5k_hw { | 1021 | struct ath5k_hw { |
1031 | u32 ah_magic; | ||
1032 | struct ath_common common; | 1022 | struct ath_common common; |
1033 | 1023 | ||
1034 | struct ath5k_softc *ah_sc; | 1024 | struct ath5k_softc *ah_sc; |
@@ -1036,7 +1026,6 @@ struct ath5k_hw { | |||
1036 | 1026 | ||
1037 | enum ath5k_int ah_imr; | 1027 | enum ath5k_int ah_imr; |
1038 | 1028 | ||
1039 | enum nl80211_iftype ah_op_mode; | ||
1040 | struct ieee80211_channel *ah_current_channel; | 1029 | struct ieee80211_channel *ah_current_channel; |
1041 | bool ah_turbo; | 1030 | bool ah_turbo; |
1042 | bool ah_calibration; | 1031 | bool ah_calibration; |
@@ -1049,7 +1038,6 @@ struct ath5k_hw { | |||
1049 | u32 ah_phy; | 1038 | u32 ah_phy; |
1050 | u32 ah_mac_srev; | 1039 | u32 ah_mac_srev; |
1051 | u16 ah_mac_version; | 1040 | u16 ah_mac_version; |
1052 | u16 ah_mac_revision; | ||
1053 | u16 ah_phy_revision; | 1041 | u16 ah_phy_revision; |
1054 | u16 ah_radio_5ghz_revision; | 1042 | u16 ah_radio_5ghz_revision; |
1055 | u16 ah_radio_2ghz_revision; | 1043 | u16 ah_radio_2ghz_revision; |
@@ -1071,8 +1059,6 @@ struct ath5k_hw { | |||
1071 | u8 ah_def_ant; | 1059 | u8 ah_def_ant; |
1072 | bool ah_software_retry; | 1060 | bool ah_software_retry; |
1073 | 1061 | ||
1074 | int ah_gpio_npins; | ||
1075 | |||
1076 | struct ath5k_capabilities ah_capabilities; | 1062 | struct ath5k_capabilities ah_capabilities; |
1077 | 1063 | ||
1078 | struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; | 1064 | struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES]; |
@@ -1123,17 +1109,18 @@ struct ath5k_hw { | |||
1123 | 1109 | ||
1124 | struct ath5k_nfcal_hist ah_nfcal_hist; | 1110 | struct ath5k_nfcal_hist ah_nfcal_hist; |
1125 | 1111 | ||
1112 | /* average beacon RSSI in our BSS (used by ANI) */ | ||
1113 | struct ath5k_avg_val ah_beacon_rssi_avg; | ||
1114 | |||
1126 | /* noise floor from last periodic calibration */ | 1115 | /* noise floor from last periodic calibration */ |
1127 | s32 ah_noise_floor; | 1116 | s32 ah_noise_floor; |
1128 | 1117 | ||
1129 | /* Calibration timestamp */ | 1118 | /* Calibration timestamp */ |
1130 | unsigned long ah_cal_tstamp; | 1119 | unsigned long ah_cal_next_full; |
1131 | 1120 | unsigned long ah_cal_next_ani; | |
1132 | /* Calibration interval (secs) */ | ||
1133 | u8 ah_cal_intval; | ||
1134 | 1121 | ||
1135 | /* Software interrupt mask */ | 1122 | /* Calibration mask */ |
1136 | u8 ah_swi_mask; | 1123 | u8 ah_cal_mask; |
1137 | 1124 | ||
1138 | /* | 1125 | /* |
1139 | * Function pointers | 1126 | * Function pointers |
@@ -1141,9 +1128,9 @@ struct ath5k_hw { | |||
1141 | int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, | 1128 | int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, |
1142 | u32 size, unsigned int flags); | 1129 | u32 size, unsigned int flags); |
1143 | int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, | 1130 | int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, |
1144 | unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, | 1131 | unsigned int, unsigned int, int, enum ath5k_pkt_type, |
1145 | unsigned int, unsigned int, unsigned int, unsigned int, | 1132 | unsigned int, unsigned int, unsigned int, unsigned int, |
1146 | unsigned int, unsigned int, unsigned int); | 1133 | unsigned int, unsigned int, unsigned int, unsigned int); |
1147 | int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, | 1134 | int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, |
1148 | unsigned int, unsigned int, unsigned int, unsigned int, | 1135 | unsigned int, unsigned int, unsigned int, unsigned int, |
1149 | unsigned int, unsigned int); | 1136 | unsigned int, unsigned int); |
@@ -1158,158 +1145,145 @@ struct ath5k_hw { | |||
1158 | */ | 1145 | */ |
1159 | 1146 | ||
1160 | /* Attach/Detach Functions */ | 1147 | /* Attach/Detach Functions */ |
1161 | extern int ath5k_hw_attach(struct ath5k_softc *sc); | 1148 | int ath5k_hw_attach(struct ath5k_softc *sc); |
1162 | extern void ath5k_hw_detach(struct ath5k_hw *ah); | 1149 | void ath5k_hw_detach(struct ath5k_hw *ah); |
1163 | 1150 | ||
1164 | /* LED functions */ | 1151 | /* LED functions */ |
1165 | extern int ath5k_init_leds(struct ath5k_softc *sc); | 1152 | int ath5k_init_leds(struct ath5k_softc *sc); |
1166 | extern void ath5k_led_enable(struct ath5k_softc *sc); | 1153 | void ath5k_led_enable(struct ath5k_softc *sc); |
1167 | extern void ath5k_led_off(struct ath5k_softc *sc); | 1154 | void ath5k_led_off(struct ath5k_softc *sc); |
1168 | extern void ath5k_unregister_leds(struct ath5k_softc *sc); | 1155 | void ath5k_unregister_leds(struct ath5k_softc *sc); |
1169 | 1156 | ||
1170 | /* Reset Functions */ | 1157 | /* Reset Functions */ |
1171 | extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); | 1158 | int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); |
1172 | extern int ath5k_hw_on_hold(struct ath5k_hw *ah); | 1159 | int ath5k_hw_on_hold(struct ath5k_hw *ah); |
1173 | extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); | 1160 | int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, |
1161 | struct ieee80211_channel *channel, bool change_channel); | ||
1162 | int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, | ||
1163 | bool is_set); | ||
1174 | /* Power management functions */ | 1164 | /* Power management functions */ |
1175 | extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration); | ||
1176 | 1165 | ||
1177 | /* DMA Related Functions */ | 1166 | /* DMA Related Functions */ |
1178 | extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); | 1167 | void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); |
1179 | extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); | 1168 | int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); |
1180 | extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); | 1169 | u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); |
1181 | extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); | 1170 | void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); |
1182 | extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); | 1171 | int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); |
1183 | extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); | 1172 | int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); |
1184 | extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); | 1173 | u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); |
1185 | extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, | 1174 | int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, |
1186 | u32 phys_addr); | 1175 | u32 phys_addr); |
1187 | extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); | 1176 | int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); |
1188 | /* Interrupt handling */ | 1177 | /* Interrupt handling */ |
1189 | extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); | 1178 | bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); |
1190 | extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); | 1179 | int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); |
1191 | extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum | 1180 | enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask); |
1192 | ath5k_int new_mask); | 1181 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah); |
1193 | extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats); | ||
1194 | 1182 | ||
1195 | /* EEPROM access functions */ | 1183 | /* EEPROM access functions */ |
1196 | extern int ath5k_eeprom_init(struct ath5k_hw *ah); | 1184 | int ath5k_eeprom_init(struct ath5k_hw *ah); |
1197 | extern void ath5k_eeprom_detach(struct ath5k_hw *ah); | 1185 | void ath5k_eeprom_detach(struct ath5k_hw *ah); |
1198 | extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); | 1186 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); |
1199 | extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah); | ||
1200 | 1187 | ||
1201 | /* Protocol Control Unit Functions */ | 1188 | /* Protocol Control Unit Functions */ |
1202 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); | 1189 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); |
1203 | extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); | 1190 | void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class); |
1204 | /* BSSID Functions */ | 1191 | /* BSSID Functions */ |
1205 | extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); | 1192 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); |
1206 | extern void ath5k_hw_set_associd(struct ath5k_hw *ah); | 1193 | void ath5k_hw_set_associd(struct ath5k_hw *ah); |
1207 | extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); | 1194 | void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); |
1208 | /* Receive start/stop functions */ | 1195 | /* Receive start/stop functions */ |
1209 | extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); | 1196 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); |
1210 | extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); | 1197 | void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); |
1211 | /* RX Filter functions */ | 1198 | /* RX Filter functions */ |
1212 | extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); | 1199 | void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); |
1213 | extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index); | 1200 | u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); |
1214 | extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); | 1201 | void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); |
1215 | extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); | ||
1216 | extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); | ||
1217 | /* Beacon control functions */ | 1202 | /* Beacon control functions */ |
1218 | extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); | 1203 | u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); |
1219 | extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); | 1204 | void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); |
1220 | extern void ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64); | 1205 | void ath5k_hw_reset_tsf(struct ath5k_hw *ah); |
1221 | extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); | 1206 | void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); |
1222 | extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval); | ||
1223 | #if 0 | ||
1224 | extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state); | ||
1225 | extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah); | ||
1226 | extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr); | ||
1227 | #endif | ||
1228 | /* ACK bit rate */ | 1207 | /* ACK bit rate */ |
1229 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); | 1208 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high); |
1230 | /* ACK/CTS Timeouts */ | ||
1231 | extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout); | ||
1232 | extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); | ||
1233 | extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); | ||
1234 | extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); | ||
1235 | /* Clock rate related functions */ | 1209 | /* Clock rate related functions */ |
1236 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); | 1210 | unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec); |
1237 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); | 1211 | unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock); |
1238 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); | 1212 | unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah); |
1239 | /* Key table (WEP) functions */ | 1213 | /* Key table (WEP) functions */ |
1240 | extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); | 1214 | int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); |
1241 | extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); | 1215 | int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, |
1242 | extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); | 1216 | const struct ieee80211_key_conf *key, const u8 *mac); |
1243 | extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); | 1217 | int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); |
1244 | 1218 | ||
1245 | /* Queue Control Unit, DFS Control Unit Functions */ | 1219 | /* Queue Control Unit, DFS Control Unit Functions */ |
1246 | extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); | 1220 | int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, |
1247 | extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, | 1221 | struct ath5k_txq_info *queue_info); |
1248 | const struct ath5k_txq_info *queue_info); | 1222 | int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, |
1249 | extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, | 1223 | const struct ath5k_txq_info *queue_info); |
1250 | enum ath5k_tx_queue queue_type, | 1224 | int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, |
1251 | struct ath5k_txq_info *queue_info); | 1225 | enum ath5k_tx_queue queue_type, |
1252 | extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); | 1226 | struct ath5k_txq_info *queue_info); |
1253 | extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1227 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); |
1254 | extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1228 | void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
1255 | extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); | 1229 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
1256 | extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); | 1230 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); |
1257 | 1231 | ||
1258 | /* Hardware Descriptor Functions */ | 1232 | /* Hardware Descriptor Functions */ |
1259 | extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); | 1233 | int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); |
1260 | 1234 | ||
1261 | /* GPIO Functions */ | 1235 | /* GPIO Functions */ |
1262 | extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); | 1236 | void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); |
1263 | extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); | 1237 | int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); |
1264 | extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); | 1238 | int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); |
1265 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); | 1239 | u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); |
1266 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); | 1240 | int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); |
1267 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); | 1241 | void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, |
1242 | u32 interrupt_level); | ||
1268 | 1243 | ||
1269 | /* rfkill Functions */ | 1244 | /* rfkill Functions */ |
1270 | extern void ath5k_rfkill_hw_start(struct ath5k_hw *ah); | 1245 | void ath5k_rfkill_hw_start(struct ath5k_hw *ah); |
1271 | extern void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); | 1246 | void ath5k_rfkill_hw_stop(struct ath5k_hw *ah); |
1272 | 1247 | ||
1273 | /* Misc functions */ | 1248 | /* Misc functions */ |
1274 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); | 1249 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); |
1275 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); | 1250 | int ath5k_hw_get_capability(struct ath5k_hw *ah, |
1276 | extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); | 1251 | enum ath5k_capability_type cap_type, u32 capability, |
1277 | extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); | 1252 | u32 *result); |
1253 | int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); | ||
1254 | int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); | ||
1278 | 1255 | ||
1279 | /* Initial register settings functions */ | 1256 | /* Initial register settings functions */ |
1280 | extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); | 1257 | int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); |
1281 | 1258 | ||
1282 | /* Initialize RF */ | 1259 | /* Initialize RF */ |
1283 | extern int ath5k_hw_rfregs_init(struct ath5k_hw *ah, | 1260 | int ath5k_hw_rfregs_init(struct ath5k_hw *ah, |
1284 | struct ieee80211_channel *channel, | 1261 | struct ieee80211_channel *channel, |
1285 | unsigned int mode); | 1262 | unsigned int mode); |
1286 | extern int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); | 1263 | int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq); |
1287 | extern enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); | 1264 | enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah); |
1288 | extern int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); | 1265 | int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah); |
1289 | /* PHY/RF channel functions */ | 1266 | /* PHY/RF channel functions */ |
1290 | extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); | 1267 | bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); |
1291 | extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); | 1268 | int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); |
1292 | /* PHY calibration */ | 1269 | /* PHY calibration */ |
1293 | void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); | 1270 | void ath5k_hw_init_nfcal_hist(struct ath5k_hw *ah); |
1294 | extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); | 1271 | int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, |
1295 | extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); | 1272 | struct ieee80211_channel *channel); |
1296 | extern s16 ath5k_hw_get_noise_floor(struct ath5k_hw *ah); | ||
1297 | extern void ath5k_hw_calibration_poll(struct ath5k_hw *ah); | ||
1298 | /* Spur mitigation */ | 1273 | /* Spur mitigation */ |
1299 | bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, | 1274 | bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, |
1300 | struct ieee80211_channel *channel); | 1275 | struct ieee80211_channel *channel); |
1301 | void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, | 1276 | void ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, |
1302 | struct ieee80211_channel *channel); | 1277 | struct ieee80211_channel *channel); |
1303 | /* Misc PHY functions */ | 1278 | /* Misc PHY functions */ |
1304 | extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); | 1279 | u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); |
1305 | extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); | 1280 | int ath5k_hw_phy_disable(struct ath5k_hw *ah); |
1306 | /* Antenna control */ | 1281 | /* Antenna control */ |
1307 | extern void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); | 1282 | void ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode); |
1308 | extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant); | ||
1309 | extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); | ||
1310 | /* TX power setup */ | 1283 | /* TX power setup */ |
1311 | extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, u8 ee_mode, u8 txpower); | 1284 | int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
1312 | extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); | 1285 | u8 ee_mode, u8 txpower); |
1286 | int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower); | ||
1313 | 1287 | ||
1314 | /* | 1288 | /* |
1315 | * Functions used internaly | 1289 | * Functions used internaly |
@@ -1335,29 +1309,6 @@ static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | |||
1335 | iowrite32(val, ah->ah_iobase + reg); | 1309 | iowrite32(val, ah->ah_iobase + reg); |
1336 | } | 1310 | } |
1337 | 1311 | ||
1338 | #if defined(_ATH5K_RESET) || defined(_ATH5K_PHY) | ||
1339 | /* | ||
1340 | * Check if a register write has been completed | ||
1341 | */ | ||
1342 | static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, | ||
1343 | u32 val, bool is_set) | ||
1344 | { | ||
1345 | int i; | ||
1346 | u32 data; | ||
1347 | |||
1348 | for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { | ||
1349 | data = ath5k_hw_reg_read(ah, reg); | ||
1350 | if (is_set && (data & flag)) | ||
1351 | break; | ||
1352 | else if ((data & flag) == val) | ||
1353 | break; | ||
1354 | udelay(15); | ||
1355 | } | ||
1356 | |||
1357 | return (i <= 0) ? -EAGAIN : 0; | ||
1358 | } | ||
1359 | #endif | ||
1360 | |||
1361 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) | 1312 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) |
1362 | { | 1313 | { |
1363 | u32 retval = 0, bit, i; | 1314 | u32 retval = 0, bit, i; |
@@ -1370,9 +1321,27 @@ static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) | |||
1370 | return retval; | 1321 | return retval; |
1371 | } | 1322 | } |
1372 | 1323 | ||
1373 | static inline int ath5k_pad_size(int hdrlen) | 1324 | #define AVG_SAMPLES 8 |
1325 | #define AVG_FACTOR 1000 | ||
1326 | |||
1327 | /** | ||
1328 | * ath5k_moving_average - Exponentially weighted moving average | ||
1329 | * @avg: average structure | ||
1330 | * @val: current value | ||
1331 | * | ||
1332 | * This implementation make use of a struct ath5k_avg_val to prevent rounding | ||
1333 | * errors. | ||
1334 | */ | ||
1335 | static inline struct ath5k_avg_val | ||
1336 | ath5k_moving_average(const struct ath5k_avg_val avg, const int val) | ||
1374 | { | 1337 | { |
1375 | return (hdrlen < 24) ? 0 : hdrlen & 3; | 1338 | struct ath5k_avg_val new; |
1339 | new.avg_weight = avg.avg_weight ? | ||
1340 | (((avg.avg_weight * ((AVG_SAMPLES) - 1)) + | ||
1341 | (val * (AVG_FACTOR))) / (AVG_SAMPLES)) : | ||
1342 | (val * (AVG_FACTOR)); | ||
1343 | new.avg = new.avg_weight / (AVG_FACTOR); | ||
1344 | return new; | ||
1376 | } | 1345 | } |
1377 | 1346 | ||
1378 | #endif | 1347 | #endif |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index dc0786cc2639..e0c244b02f05 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -114,7 +114,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
114 | /* | 114 | /* |
115 | * HW information | 115 | * HW information |
116 | */ | 116 | */ |
117 | ah->ah_op_mode = NL80211_IFTYPE_STATION; | ||
118 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | 117 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; |
119 | ah->ah_turbo = false; | 118 | ah->ah_turbo = false; |
120 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | 119 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; |
@@ -124,6 +123,9 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
124 | ah->ah_cw_min = AR5K_TUNE_CWMIN; | 123 | ah->ah_cw_min = AR5K_TUNE_CWMIN; |
125 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; | 124 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; |
126 | ah->ah_software_retry = false; | 125 | ah->ah_software_retry = false; |
126 | ah->ah_ant_mode = AR5K_ANTMODE_DEFAULT; | ||
127 | ah->ah_noise_floor = -95; /* until first NF calibration is run */ | ||
128 | sc->ani_state.ani_mode = ATH5K_ANI_MODE_AUTO; | ||
127 | 129 | ||
128 | /* | 130 | /* |
129 | * Find the mac version | 131 | * Find the mac version |
@@ -149,7 +151,6 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
149 | /* Get MAC, PHY and RADIO revisions */ | 151 | /* Get MAC, PHY and RADIO revisions */ |
150 | ah->ah_mac_srev = srev; | 152 | ah->ah_mac_srev = srev; |
151 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); | 153 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); |
152 | ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV); | ||
153 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & | 154 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & |
154 | 0xffffffff; | 155 | 0xffffffff; |
155 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, | 156 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, |
@@ -328,7 +329,7 @@ int ath5k_hw_attach(struct ath5k_softc *sc) | |||
328 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | 329 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ |
329 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); | 330 | memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN); |
330 | ath5k_hw_set_associd(ah); | 331 | ath5k_hw_set_associd(ah); |
331 | ath5k_hw_set_opmode(ah); | 332 | ath5k_hw_set_opmode(ah, sc->opmode); |
332 | 333 | ||
333 | ath5k_hw_rfgain_opt_init(ah); | 334 | ath5k_hw_rfgain_opt_init(ah); |
334 | 335 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 3abbe7513ab5..5f04cf38a5bc 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -59,8 +59,8 @@ | |||
59 | #include "base.h" | 59 | #include "base.h" |
60 | #include "reg.h" | 60 | #include "reg.h" |
61 | #include "debug.h" | 61 | #include "debug.h" |
62 | #include "ani.h" | ||
62 | 63 | ||
63 | static u8 ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */ | ||
64 | static int modparam_nohwcrypt; | 64 | static int modparam_nohwcrypt; |
65 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); | 65 | module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); |
66 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); | 66 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); |
@@ -199,7 +199,7 @@ static void __devexit ath5k_pci_remove(struct pci_dev *pdev); | |||
199 | static int ath5k_pci_suspend(struct device *dev); | 199 | static int ath5k_pci_suspend(struct device *dev); |
200 | static int ath5k_pci_resume(struct device *dev); | 200 | static int ath5k_pci_resume(struct device *dev); |
201 | 201 | ||
202 | SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); | 202 | static SIMPLE_DEV_PM_OPS(ath5k_pm_ops, ath5k_pci_suspend, ath5k_pci_resume); |
203 | #define ATH5K_PM_OPS (&ath5k_pm_ops) | 203 | #define ATH5K_PM_OPS (&ath5k_pm_ops) |
204 | #else | 204 | #else |
205 | #define ATH5K_PM_OPS NULL | 205 | #define ATH5K_PM_OPS NULL |
@@ -231,7 +231,7 @@ static void ath5k_remove_interface(struct ieee80211_hw *hw, | |||
231 | struct ieee80211_vif *vif); | 231 | struct ieee80211_vif *vif); |
232 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); | 232 | static int ath5k_config(struct ieee80211_hw *hw, u32 changed); |
233 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | 233 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, |
234 | int mc_count, struct dev_addr_list *mc_list); | 234 | struct netdev_hw_addr_list *mc_list); |
235 | static void ath5k_configure_filter(struct ieee80211_hw *hw, | 235 | static void ath5k_configure_filter(struct ieee80211_hw *hw, |
236 | unsigned int changed_flags, | 236 | unsigned int changed_flags, |
237 | unsigned int *new_flags, | 237 | unsigned int *new_flags, |
@@ -242,6 +242,8 @@ static int ath5k_set_key(struct ieee80211_hw *hw, | |||
242 | struct ieee80211_key_conf *key); | 242 | struct ieee80211_key_conf *key); |
243 | static int ath5k_get_stats(struct ieee80211_hw *hw, | 243 | static int ath5k_get_stats(struct ieee80211_hw *hw, |
244 | struct ieee80211_low_level_stats *stats); | 244 | struct ieee80211_low_level_stats *stats); |
245 | static int ath5k_get_survey(struct ieee80211_hw *hw, | ||
246 | int idx, struct survey_info *survey); | ||
245 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); | 247 | static u64 ath5k_get_tsf(struct ieee80211_hw *hw); |
246 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); | 248 | static void ath5k_set_tsf(struct ieee80211_hw *hw, u64 tsf); |
247 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); | 249 | static void ath5k_reset_tsf(struct ieee80211_hw *hw); |
@@ -267,6 +269,7 @@ static const struct ieee80211_ops ath5k_hw_ops = { | |||
267 | .configure_filter = ath5k_configure_filter, | 269 | .configure_filter = ath5k_configure_filter, |
268 | .set_key = ath5k_set_key, | 270 | .set_key = ath5k_set_key, |
269 | .get_stats = ath5k_get_stats, | 271 | .get_stats = ath5k_get_stats, |
272 | .get_survey = ath5k_get_survey, | ||
270 | .conf_tx = NULL, | 273 | .conf_tx = NULL, |
271 | .get_tsf = ath5k_get_tsf, | 274 | .get_tsf = ath5k_get_tsf, |
272 | .set_tsf = ath5k_set_tsf, | 275 | .set_tsf = ath5k_set_tsf, |
@@ -308,7 +311,7 @@ static int ath5k_rxbuf_setup(struct ath5k_softc *sc, | |||
308 | struct ath5k_buf *bf); | 311 | struct ath5k_buf *bf); |
309 | static int ath5k_txbuf_setup(struct ath5k_softc *sc, | 312 | static int ath5k_txbuf_setup(struct ath5k_softc *sc, |
310 | struct ath5k_buf *bf, | 313 | struct ath5k_buf *bf, |
311 | struct ath5k_txq *txq); | 314 | struct ath5k_txq *txq, int padsize); |
312 | static inline void ath5k_txbuf_free(struct ath5k_softc *sc, | 315 | static inline void ath5k_txbuf_free(struct ath5k_softc *sc, |
313 | struct ath5k_buf *bf) | 316 | struct ath5k_buf *bf) |
314 | { | 317 | { |
@@ -365,6 +368,7 @@ static void ath5k_beacon_send(struct ath5k_softc *sc); | |||
365 | static void ath5k_beacon_config(struct ath5k_softc *sc); | 368 | static void ath5k_beacon_config(struct ath5k_softc *sc); |
366 | static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); | 369 | static void ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf); |
367 | static void ath5k_tasklet_beacon(unsigned long data); | 370 | static void ath5k_tasklet_beacon(unsigned long data); |
371 | static void ath5k_tasklet_ani(unsigned long data); | ||
368 | 372 | ||
369 | static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) | 373 | static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) |
370 | { | 374 | { |
@@ -544,8 +548,7 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
544 | SET_IEEE80211_DEV(hw, &pdev->dev); | 548 | SET_IEEE80211_DEV(hw, &pdev->dev); |
545 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 549 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
546 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | | 550 | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | |
547 | IEEE80211_HW_SIGNAL_DBM | | 551 | IEEE80211_HW_SIGNAL_DBM; |
548 | IEEE80211_HW_NOISE_DBM; | ||
549 | 552 | ||
550 | hw->wiphy->interface_modes = | 553 | hw->wiphy->interface_modes = |
551 | BIT(NL80211_IFTYPE_AP) | | 554 | BIT(NL80211_IFTYPE_AP) | |
@@ -830,6 +833,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
830 | tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); | 833 | tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); |
831 | tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); | 834 | tasklet_init(&sc->calib, ath5k_tasklet_calibrate, (unsigned long)sc); |
832 | tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); | 835 | tasklet_init(&sc->beacontq, ath5k_tasklet_beacon, (unsigned long)sc); |
836 | tasklet_init(&sc->ani_tasklet, ath5k_tasklet_ani, (unsigned long)sc); | ||
833 | 837 | ||
834 | ret = ath5k_eeprom_read_mac(ah, mac); | 838 | ret = ath5k_eeprom_read_mac(ah, mac); |
835 | if (ret) { | 839 | if (ret) { |
@@ -1138,8 +1142,6 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1138 | struct ath5k_hw *ah = sc->ah; | 1142 | struct ath5k_hw *ah = sc->ah; |
1139 | u32 rfilt; | 1143 | u32 rfilt; |
1140 | 1144 | ||
1141 | ah->ah_op_mode = sc->opmode; | ||
1142 | |||
1143 | /* configure rx filter */ | 1145 | /* configure rx filter */ |
1144 | rfilt = sc->filter_flags; | 1146 | rfilt = sc->filter_flags; |
1145 | ath5k_hw_set_rx_filter(ah, rfilt); | 1147 | ath5k_hw_set_rx_filter(ah, rfilt); |
@@ -1148,8 +1150,9 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1148 | ath5k_hw_set_bssid_mask(ah, sc->bssidmask); | 1150 | ath5k_hw_set_bssid_mask(ah, sc->bssidmask); |
1149 | 1151 | ||
1150 | /* configure operational mode */ | 1152 | /* configure operational mode */ |
1151 | ath5k_hw_set_opmode(ah); | 1153 | ath5k_hw_set_opmode(ah, sc->opmode); |
1152 | 1154 | ||
1155 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "mode setup opmode %d\n", sc->opmode); | ||
1153 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 1156 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1154 | } | 1157 | } |
1155 | 1158 | ||
@@ -1272,7 +1275,7 @@ static enum ath5k_pkt_type get_hw_packet_type(struct sk_buff *skb) | |||
1272 | 1275 | ||
1273 | static int | 1276 | static int |
1274 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | 1277 | ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, |
1275 | struct ath5k_txq *txq) | 1278 | struct ath5k_txq *txq, int padsize) |
1276 | { | 1279 | { |
1277 | struct ath5k_hw *ah = sc->ah; | 1280 | struct ath5k_hw *ah = sc->ah; |
1278 | struct ath5k_desc *ds = bf->desc; | 1281 | struct ath5k_desc *ds = bf->desc; |
@@ -1324,7 +1327,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf, | |||
1324 | sc->vif, pktlen, info)); | 1327 | sc->vif, pktlen, info)); |
1325 | } | 1328 | } |
1326 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1329 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1327 | ieee80211_get_hdrlen_from_skb(skb), | 1330 | ieee80211_get_hdrlen_from_skb(skb), padsize, |
1328 | get_hw_packet_type(skb), | 1331 | get_hw_packet_type(skb), |
1329 | (sc->power_level * 2), | 1332 | (sc->power_level * 2), |
1330 | hw_rate, | 1333 | hw_rate, |
@@ -1636,7 +1639,6 @@ ath5k_txq_cleanup(struct ath5k_softc *sc) | |||
1636 | sc->txqs[i].link); | 1639 | sc->txqs[i].link); |
1637 | } | 1640 | } |
1638 | } | 1641 | } |
1639 | ieee80211_wake_queues(sc->hw); /* XXX move to callers */ | ||
1640 | 1642 | ||
1641 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) | 1643 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) |
1642 | if (sc->txqs[i].setup) | 1644 | if (sc->txqs[i].setup) |
@@ -1807,6 +1809,86 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1807 | } | 1809 | } |
1808 | 1810 | ||
1809 | static void | 1811 | static void |
1812 | ath5k_update_beacon_rssi(struct ath5k_softc *sc, struct sk_buff *skb, int rssi) | ||
1813 | { | ||
1814 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | ||
1815 | struct ath5k_hw *ah = sc->ah; | ||
1816 | struct ath_common *common = ath5k_hw_common(ah); | ||
1817 | |||
1818 | /* only beacons from our BSSID */ | ||
1819 | if (!ieee80211_is_beacon(mgmt->frame_control) || | ||
1820 | memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) != 0) | ||
1821 | return; | ||
1822 | |||
1823 | ah->ah_beacon_rssi_avg = ath5k_moving_average(ah->ah_beacon_rssi_avg, | ||
1824 | rssi); | ||
1825 | |||
1826 | /* in IBSS mode we should keep RSSI statistics per neighbour */ | ||
1827 | /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */ | ||
1828 | } | ||
1829 | |||
1830 | /* | ||
1831 | * Compute padding position. skb must contains an IEEE 802.11 frame | ||
1832 | */ | ||
1833 | static int ath5k_common_padpos(struct sk_buff *skb) | ||
1834 | { | ||
1835 | struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; | ||
1836 | __le16 frame_control = hdr->frame_control; | ||
1837 | int padpos = 24; | ||
1838 | |||
1839 | if (ieee80211_has_a4(frame_control)) { | ||
1840 | padpos += ETH_ALEN; | ||
1841 | } | ||
1842 | if (ieee80211_is_data_qos(frame_control)) { | ||
1843 | padpos += IEEE80211_QOS_CTL_LEN; | ||
1844 | } | ||
1845 | |||
1846 | return padpos; | ||
1847 | } | ||
1848 | |||
1849 | /* | ||
1850 | * This function expects a 802.11 frame and returns the number of | ||
1851 | * bytes added, or -1 if we don't have enought header room. | ||
1852 | */ | ||
1853 | |||
1854 | static int ath5k_add_padding(struct sk_buff *skb) | ||
1855 | { | ||
1856 | int padpos = ath5k_common_padpos(skb); | ||
1857 | int padsize = padpos & 3; | ||
1858 | |||
1859 | if (padsize && skb->len>padpos) { | ||
1860 | |||
1861 | if (skb_headroom(skb) < padsize) | ||
1862 | return -1; | ||
1863 | |||
1864 | skb_push(skb, padsize); | ||
1865 | memmove(skb->data, skb->data+padsize, padpos); | ||
1866 | return padsize; | ||
1867 | } | ||
1868 | |||
1869 | return 0; | ||
1870 | } | ||
1871 | |||
1872 | /* | ||
1873 | * This function expects a 802.11 frame and returns the number of | ||
1874 | * bytes removed | ||
1875 | */ | ||
1876 | |||
1877 | static int ath5k_remove_padding(struct sk_buff *skb) | ||
1878 | { | ||
1879 | int padpos = ath5k_common_padpos(skb); | ||
1880 | int padsize = padpos & 3; | ||
1881 | |||
1882 | if (padsize && skb->len>=padpos+padsize) { | ||
1883 | memmove(skb->data + padsize, skb->data, padpos); | ||
1884 | skb_pull(skb, padsize); | ||
1885 | return padsize; | ||
1886 | } | ||
1887 | |||
1888 | return 0; | ||
1889 | } | ||
1890 | |||
1891 | static void | ||
1810 | ath5k_tasklet_rx(unsigned long data) | 1892 | ath5k_tasklet_rx(unsigned long data) |
1811 | { | 1893 | { |
1812 | struct ieee80211_rx_status *rxs; | 1894 | struct ieee80211_rx_status *rxs; |
@@ -1819,8 +1901,6 @@ ath5k_tasklet_rx(unsigned long data) | |||
1819 | struct ath5k_buf *bf; | 1901 | struct ath5k_buf *bf; |
1820 | struct ath5k_desc *ds; | 1902 | struct ath5k_desc *ds; |
1821 | int ret; | 1903 | int ret; |
1822 | int hdrlen; | ||
1823 | int padsize; | ||
1824 | int rx_flag; | 1904 | int rx_flag; |
1825 | 1905 | ||
1826 | spin_lock(&sc->rxbuflock); | 1906 | spin_lock(&sc->rxbuflock); |
@@ -1845,18 +1925,24 @@ ath5k_tasklet_rx(unsigned long data) | |||
1845 | break; | 1925 | break; |
1846 | else if (unlikely(ret)) { | 1926 | else if (unlikely(ret)) { |
1847 | ATH5K_ERR(sc, "error in processing rx descriptor\n"); | 1927 | ATH5K_ERR(sc, "error in processing rx descriptor\n"); |
1928 | sc->stats.rxerr_proc++; | ||
1848 | spin_unlock(&sc->rxbuflock); | 1929 | spin_unlock(&sc->rxbuflock); |
1849 | return; | 1930 | return; |
1850 | } | 1931 | } |
1851 | 1932 | ||
1852 | if (unlikely(rs.rs_more)) { | 1933 | sc->stats.rx_all_count++; |
1853 | ATH5K_WARN(sc, "unsupported jumbo\n"); | ||
1854 | goto next; | ||
1855 | } | ||
1856 | 1934 | ||
1857 | if (unlikely(rs.rs_status)) { | 1935 | if (unlikely(rs.rs_status)) { |
1858 | if (rs.rs_status & AR5K_RXERR_PHY) | 1936 | if (rs.rs_status & AR5K_RXERR_CRC) |
1937 | sc->stats.rxerr_crc++; | ||
1938 | if (rs.rs_status & AR5K_RXERR_FIFO) | ||
1939 | sc->stats.rxerr_fifo++; | ||
1940 | if (rs.rs_status & AR5K_RXERR_PHY) { | ||
1941 | sc->stats.rxerr_phy++; | ||
1942 | if (rs.rs_phyerr > 0 && rs.rs_phyerr < 32) | ||
1943 | sc->stats.rxerr_phy_code[rs.rs_phyerr]++; | ||
1859 | goto next; | 1944 | goto next; |
1945 | } | ||
1860 | if (rs.rs_status & AR5K_RXERR_DECRYPT) { | 1946 | if (rs.rs_status & AR5K_RXERR_DECRYPT) { |
1861 | /* | 1947 | /* |
1862 | * Decrypt error. If the error occurred | 1948 | * Decrypt error. If the error occurred |
@@ -1868,12 +1954,14 @@ ath5k_tasklet_rx(unsigned long data) | |||
1868 | * | 1954 | * |
1869 | * XXX do key cache faulting | 1955 | * XXX do key cache faulting |
1870 | */ | 1956 | */ |
1957 | sc->stats.rxerr_decrypt++; | ||
1871 | if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && | 1958 | if (rs.rs_keyix == AR5K_RXKEYIX_INVALID && |
1872 | !(rs.rs_status & AR5K_RXERR_CRC)) | 1959 | !(rs.rs_status & AR5K_RXERR_CRC)) |
1873 | goto accept; | 1960 | goto accept; |
1874 | } | 1961 | } |
1875 | if (rs.rs_status & AR5K_RXERR_MIC) { | 1962 | if (rs.rs_status & AR5K_RXERR_MIC) { |
1876 | rx_flag |= RX_FLAG_MMIC_ERROR; | 1963 | rx_flag |= RX_FLAG_MMIC_ERROR; |
1964 | sc->stats.rxerr_mic++; | ||
1877 | goto accept; | 1965 | goto accept; |
1878 | } | 1966 | } |
1879 | 1967 | ||
@@ -1883,6 +1971,12 @@ ath5k_tasklet_rx(unsigned long data) | |||
1883 | sc->opmode != NL80211_IFTYPE_MONITOR) | 1971 | sc->opmode != NL80211_IFTYPE_MONITOR) |
1884 | goto next; | 1972 | goto next; |
1885 | } | 1973 | } |
1974 | |||
1975 | if (unlikely(rs.rs_more)) { | ||
1976 | sc->stats.rxerr_jumbo++; | ||
1977 | goto next; | ||
1978 | |||
1979 | } | ||
1886 | accept: | 1980 | accept: |
1887 | next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); | 1981 | next_skb = ath5k_rx_skb_alloc(sc, &next_skb_addr); |
1888 | 1982 | ||
@@ -1905,12 +1999,8 @@ accept: | |||
1905 | * bytes and we can optimize this a bit. In addition, we must | 1999 | * bytes and we can optimize this a bit. In addition, we must |
1906 | * not try to remove padding from short control frames that do | 2000 | * not try to remove padding from short control frames that do |
1907 | * not have payload. */ | 2001 | * not have payload. */ |
1908 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 2002 | ath5k_remove_padding(skb); |
1909 | padsize = ath5k_pad_size(hdrlen); | 2003 | |
1910 | if (padsize) { | ||
1911 | memmove(skb->data + padsize, skb->data, hdrlen); | ||
1912 | skb_pull(skb, padsize); | ||
1913 | } | ||
1914 | rxs = IEEE80211_SKB_RXCB(skb); | 2004 | rxs = IEEE80211_SKB_RXCB(skb); |
1915 | 2005 | ||
1916 | /* | 2006 | /* |
@@ -1939,10 +2029,15 @@ accept: | |||
1939 | rxs->freq = sc->curchan->center_freq; | 2029 | rxs->freq = sc->curchan->center_freq; |
1940 | rxs->band = sc->curband->band; | 2030 | rxs->band = sc->curband->band; |
1941 | 2031 | ||
1942 | rxs->noise = sc->ah->ah_noise_floor; | 2032 | rxs->signal = sc->ah->ah_noise_floor + rs.rs_rssi; |
1943 | rxs->signal = rxs->noise + rs.rs_rssi; | ||
1944 | 2033 | ||
1945 | rxs->antenna = rs.rs_antenna; | 2034 | rxs->antenna = rs.rs_antenna; |
2035 | |||
2036 | if (rs.rs_antenna > 0 && rs.rs_antenna < 5) | ||
2037 | sc->stats.antenna_rx[rs.rs_antenna]++; | ||
2038 | else | ||
2039 | sc->stats.antenna_rx[0]++; /* invalid */ | ||
2040 | |||
1946 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 2041 | rxs->rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
1947 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); | 2042 | rxs->flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
1948 | 2043 | ||
@@ -1952,6 +2047,8 @@ accept: | |||
1952 | 2047 | ||
1953 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 2048 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); |
1954 | 2049 | ||
2050 | ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi); | ||
2051 | |||
1955 | /* check beacons in IBSS mode */ | 2052 | /* check beacons in IBSS mode */ |
1956 | if (sc->opmode == NL80211_IFTYPE_ADHOC) | 2053 | if (sc->opmode == NL80211_IFTYPE_ADHOC) |
1957 | ath5k_check_ibss_tsf(sc, skb, rxs); | 2054 | ath5k_check_ibss_tsf(sc, skb, rxs); |
@@ -1988,6 +2085,17 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1988 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 2085 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
1989 | ds = bf->desc; | 2086 | ds = bf->desc; |
1990 | 2087 | ||
2088 | /* | ||
2089 | * It's possible that the hardware can say the buffer is | ||
2090 | * completed when it hasn't yet loaded the ds_link from | ||
2091 | * host memory and moved on. If there are more TX | ||
2092 | * descriptors in the queue, wait for TXDP to change | ||
2093 | * before processing this one. | ||
2094 | */ | ||
2095 | if (ath5k_hw_get_txdp(sc->ah, txq->qnum) == bf->daddr && | ||
2096 | !list_is_last(&bf->list, &txq->q)) | ||
2097 | break; | ||
2098 | |||
1991 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); | 2099 | ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts); |
1992 | if (unlikely(ret == -EINPROGRESS)) | 2100 | if (unlikely(ret == -EINPROGRESS)) |
1993 | break; | 2101 | break; |
@@ -1997,6 +2105,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1997 | break; | 2105 | break; |
1998 | } | 2106 | } |
1999 | 2107 | ||
2108 | sc->stats.tx_all_count++; | ||
2000 | skb = bf->skb; | 2109 | skb = bf->skb; |
2001 | info = IEEE80211_SKB_CB(skb); | 2110 | info = IEEE80211_SKB_CB(skb); |
2002 | bf->skb = NULL; | 2111 | bf->skb = NULL; |
@@ -2022,14 +2131,31 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
2022 | info->status.rates[ts.ts_final_idx].count++; | 2131 | info->status.rates[ts.ts_final_idx].count++; |
2023 | 2132 | ||
2024 | if (unlikely(ts.ts_status)) { | 2133 | if (unlikely(ts.ts_status)) { |
2025 | sc->ll_stats.dot11ACKFailureCount++; | 2134 | sc->stats.ack_fail++; |
2026 | if (ts.ts_status & AR5K_TXERR_FILT) | 2135 | if (ts.ts_status & AR5K_TXERR_FILT) { |
2027 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 2136 | info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
2137 | sc->stats.txerr_filt++; | ||
2138 | } | ||
2139 | if (ts.ts_status & AR5K_TXERR_XRETRY) | ||
2140 | sc->stats.txerr_retry++; | ||
2141 | if (ts.ts_status & AR5K_TXERR_FIFO) | ||
2142 | sc->stats.txerr_fifo++; | ||
2028 | } else { | 2143 | } else { |
2029 | info->flags |= IEEE80211_TX_STAT_ACK; | 2144 | info->flags |= IEEE80211_TX_STAT_ACK; |
2030 | info->status.ack_signal = ts.ts_rssi; | 2145 | info->status.ack_signal = ts.ts_rssi; |
2031 | } | 2146 | } |
2032 | 2147 | ||
2148 | /* | ||
2149 | * Remove MAC header padding before giving the frame | ||
2150 | * back to mac80211. | ||
2151 | */ | ||
2152 | ath5k_remove_padding(skb); | ||
2153 | |||
2154 | if (ts.ts_antenna > 0 && ts.ts_antenna < 5) | ||
2155 | sc->stats.antenna_tx[ts.ts_antenna]++; | ||
2156 | else | ||
2157 | sc->stats.antenna_tx[0]++; /* invalid */ | ||
2158 | |||
2033 | ieee80211_tx_status(sc->hw, skb); | 2159 | ieee80211_tx_status(sc->hw, skb); |
2034 | 2160 | ||
2035 | spin_lock(&sc->txbuflock); | 2161 | spin_lock(&sc->txbuflock); |
@@ -2073,6 +2199,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2073 | int ret = 0; | 2199 | int ret = 0; |
2074 | u8 antenna; | 2200 | u8 antenna; |
2075 | u32 flags; | 2201 | u32 flags; |
2202 | const int padsize = 0; | ||
2076 | 2203 | ||
2077 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, | 2204 | bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len, |
2078 | PCI_DMA_TODEVICE); | 2205 | PCI_DMA_TODEVICE); |
@@ -2120,7 +2247,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
2120 | * from tx power (value is in dB units already) */ | 2247 | * from tx power (value is in dB units already) */ |
2121 | ds->ds_data = bf->skbaddr; | 2248 | ds->ds_data = bf->skbaddr; |
2122 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, | 2249 | ret = ah->ah_setup_tx_desc(ah, ds, skb->len, |
2123 | ieee80211_get_hdrlen_from_skb(skb), | 2250 | ieee80211_get_hdrlen_from_skb(skb), padsize, |
2124 | AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), | 2251 | AR5K_PKT_TYPE_BEACON, (sc->power_level * 2), |
2125 | ieee80211_get_tx_rate(sc->hw, info)->hw_value, | 2252 | ieee80211_get_tx_rate(sc->hw, info)->hw_value, |
2126 | 1, AR5K_TXKEYIX_INVALID, | 2253 | 1, AR5K_TXKEYIX_INVALID, |
@@ -2407,9 +2534,6 @@ ath5k_init(struct ath5k_softc *sc) | |||
2407 | */ | 2534 | */ |
2408 | ath5k_stop_locked(sc); | 2535 | ath5k_stop_locked(sc); |
2409 | 2536 | ||
2410 | /* Set PHY calibration interval */ | ||
2411 | ah->ah_cal_intval = ath5k_calinterval; | ||
2412 | |||
2413 | /* | 2537 | /* |
2414 | * The basic interface to setting the hardware in a good | 2538 | * The basic interface to setting the hardware in a good |
2415 | * state is ``reset''. On return the hardware is known to | 2539 | * state is ``reset''. On return the hardware is known to |
@@ -2421,7 +2545,8 @@ ath5k_init(struct ath5k_softc *sc) | |||
2421 | sc->curband = &sc->sbands[sc->curchan->band]; | 2545 | sc->curband = &sc->sbands[sc->curchan->band]; |
2422 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | | 2546 | sc->imask = AR5K_INT_RXOK | AR5K_INT_RXERR | AR5K_INT_RXEOL | |
2423 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | | 2547 | AR5K_INT_RXORN | AR5K_INT_TXDESC | AR5K_INT_TXEOL | |
2424 | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_SWI; | 2548 | AR5K_INT_FATAL | AR5K_INT_GLOBAL | AR5K_INT_MIB; |
2549 | |||
2425 | ret = ath5k_reset(sc, NULL); | 2550 | ret = ath5k_reset(sc, NULL); |
2426 | if (ret) | 2551 | if (ret) |
2427 | goto done; | 2552 | goto done; |
@@ -2435,8 +2560,7 @@ ath5k_init(struct ath5k_softc *sc) | |||
2435 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) | 2560 | for (i = 0; i < AR5K_KEYTABLE_SIZE; i++) |
2436 | ath5k_hw_reset_key(ah, i); | 2561 | ath5k_hw_reset_key(ah, i); |
2437 | 2562 | ||
2438 | /* Set ack to be sent at low bit-rates */ | 2563 | ath5k_hw_set_ack_bitrate_high(ah, true); |
2439 | ath5k_hw_set_ack_bitrate_high(ah, false); | ||
2440 | ret = 0; | 2564 | ret = 0; |
2441 | done: | 2565 | done: |
2442 | mmiowb(); | 2566 | mmiowb(); |
@@ -2533,12 +2657,33 @@ ath5k_stop_hw(struct ath5k_softc *sc) | |||
2533 | tasklet_kill(&sc->restq); | 2657 | tasklet_kill(&sc->restq); |
2534 | tasklet_kill(&sc->calib); | 2658 | tasklet_kill(&sc->calib); |
2535 | tasklet_kill(&sc->beacontq); | 2659 | tasklet_kill(&sc->beacontq); |
2660 | tasklet_kill(&sc->ani_tasklet); | ||
2536 | 2661 | ||
2537 | ath5k_rfkill_hw_stop(sc->ah); | 2662 | ath5k_rfkill_hw_stop(sc->ah); |
2538 | 2663 | ||
2539 | return ret; | 2664 | return ret; |
2540 | } | 2665 | } |
2541 | 2666 | ||
2667 | static void | ||
2668 | ath5k_intr_calibration_poll(struct ath5k_hw *ah) | ||
2669 | { | ||
2670 | if (time_is_before_eq_jiffies(ah->ah_cal_next_ani) && | ||
2671 | !(ah->ah_cal_mask & AR5K_CALIBRATION_FULL)) { | ||
2672 | /* run ANI only when full calibration is not active */ | ||
2673 | ah->ah_cal_next_ani = jiffies + | ||
2674 | msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_ANI); | ||
2675 | tasklet_schedule(&ah->ah_sc->ani_tasklet); | ||
2676 | |||
2677 | } else if (time_is_before_eq_jiffies(ah->ah_cal_next_full)) { | ||
2678 | ah->ah_cal_next_full = jiffies + | ||
2679 | msecs_to_jiffies(ATH5K_TUNE_CALIBRATION_INTERVAL_FULL); | ||
2680 | tasklet_schedule(&ah->ah_sc->calib); | ||
2681 | } | ||
2682 | /* we could use SWI to generate enough interrupts to meet our | ||
2683 | * calibration interval requirements, if necessary: | ||
2684 | * AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); */ | ||
2685 | } | ||
2686 | |||
2542 | static irqreturn_t | 2687 | static irqreturn_t |
2543 | ath5k_intr(int irq, void *dev_id) | 2688 | ath5k_intr(int irq, void *dev_id) |
2544 | { | 2689 | { |
@@ -2562,7 +2707,20 @@ ath5k_intr(int irq, void *dev_id) | |||
2562 | */ | 2707 | */ |
2563 | tasklet_schedule(&sc->restq); | 2708 | tasklet_schedule(&sc->restq); |
2564 | } else if (unlikely(status & AR5K_INT_RXORN)) { | 2709 | } else if (unlikely(status & AR5K_INT_RXORN)) { |
2565 | tasklet_schedule(&sc->restq); | 2710 | /* |
2711 | * Receive buffers are full. Either the bus is busy or | ||
2712 | * the CPU is not fast enough to process all received | ||
2713 | * frames. | ||
2714 | * Older chipsets need a reset to come out of this | ||
2715 | * condition, but we treat it as RX for newer chips. | ||
2716 | * We don't know exactly which versions need a reset - | ||
2717 | * this guess is copied from the HAL. | ||
2718 | */ | ||
2719 | sc->stats.rxorn_intr++; | ||
2720 | if (ah->ah_mac_srev < AR5K_SREV_AR5212) | ||
2721 | tasklet_schedule(&sc->restq); | ||
2722 | else | ||
2723 | tasklet_schedule(&sc->rxtq); | ||
2566 | } else { | 2724 | } else { |
2567 | if (status & AR5K_INT_SWBA) { | 2725 | if (status & AR5K_INT_SWBA) { |
2568 | tasklet_hi_schedule(&sc->beacontq); | 2726 | tasklet_hi_schedule(&sc->beacontq); |
@@ -2587,15 +2745,10 @@ ath5k_intr(int irq, void *dev_id) | |||
2587 | if (status & AR5K_INT_BMISS) { | 2745 | if (status & AR5K_INT_BMISS) { |
2588 | /* TODO */ | 2746 | /* TODO */ |
2589 | } | 2747 | } |
2590 | if (status & AR5K_INT_SWI) { | ||
2591 | tasklet_schedule(&sc->calib); | ||
2592 | } | ||
2593 | if (status & AR5K_INT_MIB) { | 2748 | if (status & AR5K_INT_MIB) { |
2594 | /* | 2749 | sc->stats.mib_intr++; |
2595 | * These stats are also used for ANI i think | 2750 | ath5k_hw_update_mib_counters(ah); |
2596 | * so how about updating them more often ? | 2751 | ath5k_ani_mib_intr(ah); |
2597 | */ | ||
2598 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); | ||
2599 | } | 2752 | } |
2600 | if (status & AR5K_INT_GPIO) | 2753 | if (status & AR5K_INT_GPIO) |
2601 | tasklet_schedule(&sc->rf_kill.toggleq); | 2754 | tasklet_schedule(&sc->rf_kill.toggleq); |
@@ -2606,7 +2759,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2606 | if (unlikely(!counter)) | 2759 | if (unlikely(!counter)) |
2607 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); | 2760 | ATH5K_WARN(sc, "too many interrupts, giving up for now\n"); |
2608 | 2761 | ||
2609 | ath5k_hw_calibration_poll(ah); | 2762 | ath5k_intr_calibration_poll(ah); |
2610 | 2763 | ||
2611 | return IRQ_HANDLED; | 2764 | return IRQ_HANDLED; |
2612 | } | 2765 | } |
@@ -2630,8 +2783,7 @@ ath5k_tasklet_calibrate(unsigned long data) | |||
2630 | struct ath5k_hw *ah = sc->ah; | 2783 | struct ath5k_hw *ah = sc->ah; |
2631 | 2784 | ||
2632 | /* Only full calibration for now */ | 2785 | /* Only full calibration for now */ |
2633 | if (ah->ah_swi_mask != AR5K_SWI_FULL_CALIBRATION) | 2786 | ah->ah_cal_mask |= AR5K_CALIBRATION_FULL; |
2634 | return; | ||
2635 | 2787 | ||
2636 | /* Stop queues so that calibration | 2788 | /* Stop queues so that calibration |
2637 | * doesn't interfere with tx */ | 2789 | * doesn't interfere with tx */ |
@@ -2647,18 +2799,29 @@ ath5k_tasklet_calibrate(unsigned long data) | |||
2647 | * to load new gain values. | 2799 | * to load new gain values. |
2648 | */ | 2800 | */ |
2649 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); | 2801 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); |
2650 | ath5k_reset_wake(sc); | 2802 | ath5k_reset(sc, sc->curchan); |
2651 | } | 2803 | } |
2652 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) | 2804 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) |
2653 | ATH5K_ERR(sc, "calibration of channel %u failed\n", | 2805 | ATH5K_ERR(sc, "calibration of channel %u failed\n", |
2654 | ieee80211_frequency_to_channel( | 2806 | ieee80211_frequency_to_channel( |
2655 | sc->curchan->center_freq)); | 2807 | sc->curchan->center_freq)); |
2656 | 2808 | ||
2657 | ah->ah_swi_mask = 0; | ||
2658 | |||
2659 | /* Wake queues */ | 2809 | /* Wake queues */ |
2660 | ieee80211_wake_queues(sc->hw); | 2810 | ieee80211_wake_queues(sc->hw); |
2661 | 2811 | ||
2812 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_FULL; | ||
2813 | } | ||
2814 | |||
2815 | |||
2816 | static void | ||
2817 | ath5k_tasklet_ani(unsigned long data) | ||
2818 | { | ||
2819 | struct ath5k_softc *sc = (void *)data; | ||
2820 | struct ath5k_hw *ah = sc->ah; | ||
2821 | |||
2822 | ah->ah_cal_mask |= AR5K_CALIBRATION_ANI; | ||
2823 | ath5k_ani_calibration(ah); | ||
2824 | ah->ah_cal_mask &= ~AR5K_CALIBRATION_ANI; | ||
2662 | } | 2825 | } |
2663 | 2826 | ||
2664 | 2827 | ||
@@ -2680,7 +2843,6 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2680 | struct ath5k_softc *sc = hw->priv; | 2843 | struct ath5k_softc *sc = hw->priv; |
2681 | struct ath5k_buf *bf; | 2844 | struct ath5k_buf *bf; |
2682 | unsigned long flags; | 2845 | unsigned long flags; |
2683 | int hdrlen; | ||
2684 | int padsize; | 2846 | int padsize; |
2685 | 2847 | ||
2686 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | 2848 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); |
@@ -2692,17 +2854,11 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2692 | * the hardware expects the header padded to 4 byte boundaries | 2854 | * the hardware expects the header padded to 4 byte boundaries |
2693 | * if this is not the case we add the padding after the header | 2855 | * if this is not the case we add the padding after the header |
2694 | */ | 2856 | */ |
2695 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 2857 | padsize = ath5k_add_padding(skb); |
2696 | padsize = ath5k_pad_size(hdrlen); | 2858 | if (padsize < 0) { |
2697 | if (padsize) { | 2859 | ATH5K_ERR(sc, "tx hdrlen not %%4: not enough" |
2698 | 2860 | " headroom to pad"); | |
2699 | if (skb_headroom(skb) < padsize) { | 2861 | goto drop_packet; |
2700 | ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough" | ||
2701 | " headroom to pad %d\n", hdrlen, padsize); | ||
2702 | goto drop_packet; | ||
2703 | } | ||
2704 | skb_push(skb, padsize); | ||
2705 | memmove(skb->data, skb->data+padsize, hdrlen); | ||
2706 | } | 2862 | } |
2707 | 2863 | ||
2708 | spin_lock_irqsave(&sc->txbuflock, flags); | 2864 | spin_lock_irqsave(&sc->txbuflock, flags); |
@@ -2721,7 +2877,7 @@ static int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2721 | 2877 | ||
2722 | bf->skb = skb; | 2878 | bf->skb = skb; |
2723 | 2879 | ||
2724 | if (ath5k_txbuf_setup(sc, bf, txq)) { | 2880 | if (ath5k_txbuf_setup(sc, bf, txq, padsize)) { |
2725 | bf->skb = NULL; | 2881 | bf->skb = NULL; |
2726 | spin_lock_irqsave(&sc->txbuflock, flags); | 2882 | spin_lock_irqsave(&sc->txbuflock, flags); |
2727 | list_add_tail(&bf->list, &sc->txbuf); | 2883 | list_add_tail(&bf->list, &sc->txbuf); |
@@ -2768,6 +2924,8 @@ ath5k_reset(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
2768 | goto err; | 2924 | goto err; |
2769 | } | 2925 | } |
2770 | 2926 | ||
2927 | ath5k_ani_init(ah, ah->ah_sc->ani_state.ani_mode); | ||
2928 | |||
2771 | /* | 2929 | /* |
2772 | * Change channels and update the h/w rate map if we're switching; | 2930 | * Change channels and update the h/w rate map if we're switching; |
2773 | * e.g. 11a to 11b/g. | 2931 | * e.g. 11a to 11b/g. |
@@ -2836,6 +2994,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2836 | goto end; | 2994 | goto end; |
2837 | } | 2995 | } |
2838 | 2996 | ||
2997 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "add interface mode %d\n", sc->opmode); | ||
2998 | |||
2839 | ath5k_hw_set_lladdr(sc->ah, vif->addr); | 2999 | ath5k_hw_set_lladdr(sc->ah, vif->addr); |
2840 | ath5k_mode_setup(sc); | 3000 | ath5k_mode_setup(sc); |
2841 | 3001 | ||
@@ -2906,7 +3066,7 @@ ath5k_config(struct ieee80211_hw *hw, u32 changed) | |||
2906 | * then we must allow the user to set how many tx antennas we | 3066 | * then we must allow the user to set how many tx antennas we |
2907 | * have available | 3067 | * have available |
2908 | */ | 3068 | */ |
2909 | ath5k_hw_set_antenna_mode(ah, AR5K_ANTMODE_DEFAULT); | 3069 | ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); |
2910 | 3070 | ||
2911 | unlock: | 3071 | unlock: |
2912 | mutex_unlock(&sc->lock); | 3072 | mutex_unlock(&sc->lock); |
@@ -2914,22 +3074,20 @@ unlock: | |||
2914 | } | 3074 | } |
2915 | 3075 | ||
2916 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | 3076 | static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, |
2917 | int mc_count, struct dev_addr_list *mclist) | 3077 | struct netdev_hw_addr_list *mc_list) |
2918 | { | 3078 | { |
2919 | u32 mfilt[2], val; | 3079 | u32 mfilt[2], val; |
2920 | int i; | ||
2921 | u8 pos; | 3080 | u8 pos; |
3081 | struct netdev_hw_addr *ha; | ||
2922 | 3082 | ||
2923 | mfilt[0] = 0; | 3083 | mfilt[0] = 0; |
2924 | mfilt[1] = 1; | 3084 | mfilt[1] = 1; |
2925 | 3085 | ||
2926 | for (i = 0; i < mc_count; i++) { | 3086 | netdev_hw_addr_list_for_each(ha, mc_list) { |
2927 | if (!mclist) | ||
2928 | break; | ||
2929 | /* calculate XOR of eight 6-bit values */ | 3087 | /* calculate XOR of eight 6-bit values */ |
2930 | val = get_unaligned_le32(mclist->dmi_addr + 0); | 3088 | val = get_unaligned_le32(ha->addr + 0); |
2931 | pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; | 3089 | pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; |
2932 | val = get_unaligned_le32(mclist->dmi_addr + 3); | 3090 | val = get_unaligned_le32(ha->addr + 3); |
2933 | pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; | 3091 | pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val; |
2934 | pos &= 0x3f; | 3092 | pos &= 0x3f; |
2935 | mfilt[pos / 32] |= (1 << (pos % 32)); | 3093 | mfilt[pos / 32] |= (1 << (pos % 32)); |
@@ -2937,8 +3095,7 @@ static u64 ath5k_prepare_multicast(struct ieee80211_hw *hw, | |||
2937 | * but not sure, needs testing, if we do use this we'd | 3095 | * but not sure, needs testing, if we do use this we'd |
2938 | * neet to inform below to not reset the mcast */ | 3096 | * neet to inform below to not reset the mcast */ |
2939 | /* ath5k_hw_set_mcast_filterindex(ah, | 3097 | /* ath5k_hw_set_mcast_filterindex(ah, |
2940 | * mclist->dmi_addr[5]); */ | 3098 | * ha->addr[5]); */ |
2941 | mclist = mclist->next; | ||
2942 | } | 3099 | } |
2943 | 3100 | ||
2944 | return ((u64)(mfilt[1]) << 32) | mfilt[0]; | 3101 | return ((u64)(mfilt[1]) << 32) | mfilt[0]; |
@@ -3124,12 +3281,30 @@ ath5k_get_stats(struct ieee80211_hw *hw, | |||
3124 | struct ieee80211_low_level_stats *stats) | 3281 | struct ieee80211_low_level_stats *stats) |
3125 | { | 3282 | { |
3126 | struct ath5k_softc *sc = hw->priv; | 3283 | struct ath5k_softc *sc = hw->priv; |
3127 | struct ath5k_hw *ah = sc->ah; | ||
3128 | 3284 | ||
3129 | /* Force update */ | 3285 | /* Force update */ |
3130 | ath5k_hw_update_mib_counters(ah, &sc->ll_stats); | 3286 | ath5k_hw_update_mib_counters(sc->ah); |
3287 | |||
3288 | stats->dot11ACKFailureCount = sc->stats.ack_fail; | ||
3289 | stats->dot11RTSFailureCount = sc->stats.rts_fail; | ||
3290 | stats->dot11RTSSuccessCount = sc->stats.rts_ok; | ||
3291 | stats->dot11FCSErrorCount = sc->stats.fcs_error; | ||
3292 | |||
3293 | return 0; | ||
3294 | } | ||
3295 | |||
3296 | static int ath5k_get_survey(struct ieee80211_hw *hw, int idx, | ||
3297 | struct survey_info *survey) | ||
3298 | { | ||
3299 | struct ath5k_softc *sc = hw->priv; | ||
3300 | struct ieee80211_conf *conf = &hw->conf; | ||
3301 | |||
3302 | if (idx != 0) | ||
3303 | return -ENOENT; | ||
3131 | 3304 | ||
3132 | memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats)); | 3305 | survey->channel = conf->channel; |
3306 | survey->filled = SURVEY_INFO_NOISE_DBM; | ||
3307 | survey->noise = sc->ah->ah_noise_floor; | ||
3133 | 3308 | ||
3134 | return 0; | 3309 | return 0; |
3135 | } | 3310 | } |
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h index 7e1a88a5abdb..56221bc7c8cd 100644 --- a/drivers/net/wireless/ath/ath5k/base.h +++ b/drivers/net/wireless/ath/ath5k/base.h | |||
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | #include "ath5k.h" | 51 | #include "ath5k.h" |
52 | #include "debug.h" | 52 | #include "debug.h" |
53 | #include "ani.h" | ||
53 | 54 | ||
54 | #include "../regd.h" | 55 | #include "../regd.h" |
55 | #include "../ath.h" | 56 | #include "../ath.h" |
@@ -105,6 +106,38 @@ struct ath5k_rfkill { | |||
105 | struct tasklet_struct toggleq; | 106 | struct tasklet_struct toggleq; |
106 | }; | 107 | }; |
107 | 108 | ||
109 | /* statistics */ | ||
110 | struct ath5k_statistics { | ||
111 | /* antenna use */ | ||
112 | unsigned int antenna_rx[5]; /* frames count per antenna RX */ | ||
113 | unsigned int antenna_tx[5]; /* frames count per antenna TX */ | ||
114 | |||
115 | /* frame errors */ | ||
116 | unsigned int rx_all_count; /* all RX frames, including errors */ | ||
117 | unsigned int tx_all_count; /* all TX frames, including errors */ | ||
118 | unsigned int rxerr_crc; | ||
119 | unsigned int rxerr_phy; | ||
120 | unsigned int rxerr_phy_code[32]; | ||
121 | unsigned int rxerr_fifo; | ||
122 | unsigned int rxerr_decrypt; | ||
123 | unsigned int rxerr_mic; | ||
124 | unsigned int rxerr_proc; | ||
125 | unsigned int rxerr_jumbo; | ||
126 | unsigned int txerr_retry; | ||
127 | unsigned int txerr_fifo; | ||
128 | unsigned int txerr_filt; | ||
129 | |||
130 | /* MIB counters */ | ||
131 | unsigned int ack_fail; | ||
132 | unsigned int rts_fail; | ||
133 | unsigned int rts_ok; | ||
134 | unsigned int fcs_error; | ||
135 | unsigned int beacons; | ||
136 | |||
137 | unsigned int mib_intr; | ||
138 | unsigned int rxorn_intr; | ||
139 | }; | ||
140 | |||
108 | #if CHAN_DEBUG | 141 | #if CHAN_DEBUG |
109 | #define ATH_CHAN_MAX (26+26+26+200+200) | 142 | #define ATH_CHAN_MAX (26+26+26+200+200) |
110 | #else | 143 | #else |
@@ -117,7 +150,6 @@ struct ath5k_softc { | |||
117 | struct pci_dev *pdev; /* for dma mapping */ | 150 | struct pci_dev *pdev; /* for dma mapping */ |
118 | void __iomem *iobase; /* address of the device */ | 151 | void __iomem *iobase; /* address of the device */ |
119 | struct mutex lock; /* dev-level lock */ | 152 | struct mutex lock; /* dev-level lock */ |
120 | struct ieee80211_low_level_stats ll_stats; | ||
121 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ | 153 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ |
122 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | 154 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
123 | struct ieee80211_channel channels[ATH_CHAN_MAX]; | 155 | struct ieee80211_channel channels[ATH_CHAN_MAX]; |
@@ -191,6 +223,11 @@ struct ath5k_softc { | |||
191 | int power_level; /* Requested tx power in dbm */ | 223 | int power_level; /* Requested tx power in dbm */ |
192 | bool assoc; /* associate state */ | 224 | bool assoc; /* associate state */ |
193 | bool enable_beacon; /* true if beacons are on */ | 225 | bool enable_beacon; /* true if beacons are on */ |
226 | |||
227 | struct ath5k_statistics stats; | ||
228 | |||
229 | struct ath5k_ani_state ani_state; | ||
230 | struct tasklet_struct ani_tasklet; /* ANI calibration */ | ||
194 | }; | 231 | }; |
195 | 232 | ||
196 | #define ath5k_hw_hasbssidmask(_ah) \ | 233 | #define ath5k_hw_hasbssidmask(_ah) \ |
diff --git a/drivers/net/wireless/ath/ath5k/caps.c b/drivers/net/wireless/ath/ath5k/caps.c index 367a6c7d3cc7..74f007126f41 100644 --- a/drivers/net/wireless/ath/ath5k/caps.c +++ b/drivers/net/wireless/ath/ath5k/caps.c | |||
@@ -102,9 +102,6 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
102 | } | 102 | } |
103 | } | 103 | } |
104 | 104 | ||
105 | /* GPIO */ | ||
106 | ah->ah_gpio_npins = AR5K_NUM_GPIO; | ||
107 | |||
108 | /* Set number of supported TX queues */ | 105 | /* Set number of supported TX queues */ |
109 | if (ah->ah_version == AR5K_AR5210) | 106 | if (ah->ah_version == AR5K_AR5210) |
110 | ah->ah_capabilities.cap_queues.q_tx_num = | 107 | ah->ah_capabilities.cap_queues.q_tx_num = |
@@ -112,6 +109,12 @@ int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | |||
112 | else | 109 | else |
113 | ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; | 110 | ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; |
114 | 111 | ||
112 | /* newer hardware has PHY error counters */ | ||
113 | if (ah->ah_mac_srev >= AR5K_SREV_AR5213A) | ||
114 | ah->ah_capabilities.cap_has_phyerr_counters = true; | ||
115 | else | ||
116 | ah->ah_capabilities.cap_has_phyerr_counters = false; | ||
117 | |||
115 | return 0; | 118 | return 0; |
116 | } | 119 | } |
117 | 120 | ||
diff --git a/drivers/net/wireless/ath/ath5k/debug.c b/drivers/net/wireless/ath/ath5k/debug.c index 747508c15d34..6fb5c5ffa5b1 100644 --- a/drivers/net/wireless/ath/ath5k/debug.c +++ b/drivers/net/wireless/ath/ath5k/debug.c | |||
@@ -69,6 +69,7 @@ module_param_named(debug, ath5k_debug, uint, 0); | |||
69 | 69 | ||
70 | #include <linux/seq_file.h> | 70 | #include <linux/seq_file.h> |
71 | #include "reg.h" | 71 | #include "reg.h" |
72 | #include "ani.h" | ||
72 | 73 | ||
73 | static struct dentry *ath5k_global_debugfs; | 74 | static struct dentry *ath5k_global_debugfs; |
74 | 75 | ||
@@ -307,6 +308,7 @@ static const struct { | |||
307 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, | 308 | { ATH5K_DEBUG_DUMP_TX, "dumptx", "print transmit skb content" }, |
308 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, | 309 | { ATH5K_DEBUG_DUMPBANDS, "dumpbands", "dump bands" }, |
309 | { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, | 310 | { ATH5K_DEBUG_TRACE, "trace", "trace function calls" }, |
311 | { ATH5K_DEBUG_ANI, "ani", "adaptive noise immunity" }, | ||
310 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, | 312 | { ATH5K_DEBUG_ANY, "all", "show all debug levels" }, |
311 | }; | 313 | }; |
312 | 314 | ||
@@ -364,6 +366,369 @@ static const struct file_operations fops_debug = { | |||
364 | }; | 366 | }; |
365 | 367 | ||
366 | 368 | ||
369 | /* debugfs: antenna */ | ||
370 | |||
371 | static ssize_t read_file_antenna(struct file *file, char __user *user_buf, | ||
372 | size_t count, loff_t *ppos) | ||
373 | { | ||
374 | struct ath5k_softc *sc = file->private_data; | ||
375 | char buf[700]; | ||
376 | unsigned int len = 0; | ||
377 | unsigned int i; | ||
378 | unsigned int v; | ||
379 | |||
380 | len += snprintf(buf+len, sizeof(buf)-len, "antenna mode\t%d\n", | ||
381 | sc->ah->ah_ant_mode); | ||
382 | len += snprintf(buf+len, sizeof(buf)-len, "default antenna\t%d\n", | ||
383 | sc->ah->ah_def_ant); | ||
384 | len += snprintf(buf+len, sizeof(buf)-len, "tx antenna\t%d\n", | ||
385 | sc->ah->ah_tx_ant); | ||
386 | |||
387 | len += snprintf(buf+len, sizeof(buf)-len, "\nANTENNA\t\tRX\tTX\n"); | ||
388 | for (i = 1; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) { | ||
389 | len += snprintf(buf+len, sizeof(buf)-len, | ||
390 | "[antenna %d]\t%d\t%d\n", | ||
391 | i, sc->stats.antenna_rx[i], sc->stats.antenna_tx[i]); | ||
392 | } | ||
393 | len += snprintf(buf+len, sizeof(buf)-len, "[invalid]\t%d\t%d\n", | ||
394 | sc->stats.antenna_rx[0], sc->stats.antenna_tx[0]); | ||
395 | |||
396 | v = ath5k_hw_reg_read(sc->ah, AR5K_DEFAULT_ANTENNA); | ||
397 | len += snprintf(buf+len, sizeof(buf)-len, | ||
398 | "\nAR5K_DEFAULT_ANTENNA\t0x%08x\n", v); | ||
399 | |||
400 | v = ath5k_hw_reg_read(sc->ah, AR5K_STA_ID1); | ||
401 | len += snprintf(buf+len, sizeof(buf)-len, | ||
402 | "AR5K_STA_ID1_DEFAULT_ANTENNA\t%d\n", | ||
403 | (v & AR5K_STA_ID1_DEFAULT_ANTENNA) != 0); | ||
404 | len += snprintf(buf+len, sizeof(buf)-len, | ||
405 | "AR5K_STA_ID1_DESC_ANTENNA\t%d\n", | ||
406 | (v & AR5K_STA_ID1_DESC_ANTENNA) != 0); | ||
407 | len += snprintf(buf+len, sizeof(buf)-len, | ||
408 | "AR5K_STA_ID1_RTS_DEF_ANTENNA\t%d\n", | ||
409 | (v & AR5K_STA_ID1_RTS_DEF_ANTENNA) != 0); | ||
410 | len += snprintf(buf+len, sizeof(buf)-len, | ||
411 | "AR5K_STA_ID1_SELFGEN_DEF_ANT\t%d\n", | ||
412 | (v & AR5K_STA_ID1_SELFGEN_DEF_ANT) != 0); | ||
413 | |||
414 | v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_AGCCTL); | ||
415 | len += snprintf(buf+len, sizeof(buf)-len, | ||
416 | "\nAR5K_PHY_AGCCTL_OFDM_DIV_DIS\t%d\n", | ||
417 | (v & AR5K_PHY_AGCCTL_OFDM_DIV_DIS) != 0); | ||
418 | |||
419 | v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_RESTART); | ||
420 | len += snprintf(buf+len, sizeof(buf)-len, | ||
421 | "AR5K_PHY_RESTART_DIV_GC\t\t%x\n", | ||
422 | (v & AR5K_PHY_RESTART_DIV_GC) >> AR5K_PHY_RESTART_DIV_GC_S); | ||
423 | |||
424 | v = ath5k_hw_reg_read(sc->ah, AR5K_PHY_FAST_ANT_DIV); | ||
425 | len += snprintf(buf+len, sizeof(buf)-len, | ||
426 | "AR5K_PHY_FAST_ANT_DIV_EN\t%d\n", | ||
427 | (v & AR5K_PHY_FAST_ANT_DIV_EN) != 0); | ||
428 | |||
429 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
430 | } | ||
431 | |||
432 | static ssize_t write_file_antenna(struct file *file, | ||
433 | const char __user *userbuf, | ||
434 | size_t count, loff_t *ppos) | ||
435 | { | ||
436 | struct ath5k_softc *sc = file->private_data; | ||
437 | unsigned int i; | ||
438 | char buf[20]; | ||
439 | |||
440 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
441 | return -EFAULT; | ||
442 | |||
443 | if (strncmp(buf, "diversity", 9) == 0) { | ||
444 | ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_DEFAULT); | ||
445 | printk(KERN_INFO "ath5k debug: enable diversity\n"); | ||
446 | } else if (strncmp(buf, "fixed-a", 7) == 0) { | ||
447 | ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_A); | ||
448 | printk(KERN_INFO "ath5k debugfs: fixed antenna A\n"); | ||
449 | } else if (strncmp(buf, "fixed-b", 7) == 0) { | ||
450 | ath5k_hw_set_antenna_mode(sc->ah, AR5K_ANTMODE_FIXED_B); | ||
451 | printk(KERN_INFO "ath5k debug: fixed antenna B\n"); | ||
452 | } else if (strncmp(buf, "clear", 5) == 0) { | ||
453 | for (i = 0; i < ARRAY_SIZE(sc->stats.antenna_rx); i++) { | ||
454 | sc->stats.antenna_rx[i] = 0; | ||
455 | sc->stats.antenna_tx[i] = 0; | ||
456 | } | ||
457 | printk(KERN_INFO "ath5k debug: cleared antenna stats\n"); | ||
458 | } | ||
459 | return count; | ||
460 | } | ||
461 | |||
462 | static const struct file_operations fops_antenna = { | ||
463 | .read = read_file_antenna, | ||
464 | .write = write_file_antenna, | ||
465 | .open = ath5k_debugfs_open, | ||
466 | .owner = THIS_MODULE, | ||
467 | }; | ||
468 | |||
469 | |||
470 | /* debugfs: frameerrors */ | ||
471 | |||
472 | static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf, | ||
473 | size_t count, loff_t *ppos) | ||
474 | { | ||
475 | struct ath5k_softc *sc = file->private_data; | ||
476 | struct ath5k_statistics *st = &sc->stats; | ||
477 | char buf[700]; | ||
478 | unsigned int len = 0; | ||
479 | int i; | ||
480 | |||
481 | len += snprintf(buf+len, sizeof(buf)-len, | ||
482 | "RX\n---------------------\n"); | ||
483 | len += snprintf(buf+len, sizeof(buf)-len, "CRC\t%d\t(%d%%)\n", | ||
484 | st->rxerr_crc, | ||
485 | st->rx_all_count > 0 ? | ||
486 | st->rxerr_crc*100/st->rx_all_count : 0); | ||
487 | len += snprintf(buf+len, sizeof(buf)-len, "PHY\t%d\t(%d%%)\n", | ||
488 | st->rxerr_phy, | ||
489 | st->rx_all_count > 0 ? | ||
490 | st->rxerr_phy*100/st->rx_all_count : 0); | ||
491 | for (i = 0; i < 32; i++) { | ||
492 | if (st->rxerr_phy_code[i]) | ||
493 | len += snprintf(buf+len, sizeof(buf)-len, | ||
494 | " phy_err[%d]\t%d\n", | ||
495 | i, st->rxerr_phy_code[i]); | ||
496 | } | ||
497 | |||
498 | len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", | ||
499 | st->rxerr_fifo, | ||
500 | st->rx_all_count > 0 ? | ||
501 | st->rxerr_fifo*100/st->rx_all_count : 0); | ||
502 | len += snprintf(buf+len, sizeof(buf)-len, "decrypt\t%d\t(%d%%)\n", | ||
503 | st->rxerr_decrypt, | ||
504 | st->rx_all_count > 0 ? | ||
505 | st->rxerr_decrypt*100/st->rx_all_count : 0); | ||
506 | len += snprintf(buf+len, sizeof(buf)-len, "MIC\t%d\t(%d%%)\n", | ||
507 | st->rxerr_mic, | ||
508 | st->rx_all_count > 0 ? | ||
509 | st->rxerr_mic*100/st->rx_all_count : 0); | ||
510 | len += snprintf(buf+len, sizeof(buf)-len, "process\t%d\t(%d%%)\n", | ||
511 | st->rxerr_proc, | ||
512 | st->rx_all_count > 0 ? | ||
513 | st->rxerr_proc*100/st->rx_all_count : 0); | ||
514 | len += snprintf(buf+len, sizeof(buf)-len, "jumbo\t%d\t(%d%%)\n", | ||
515 | st->rxerr_jumbo, | ||
516 | st->rx_all_count > 0 ? | ||
517 | st->rxerr_jumbo*100/st->rx_all_count : 0); | ||
518 | len += snprintf(buf+len, sizeof(buf)-len, "[RX all\t%d]\n", | ||
519 | st->rx_all_count); | ||
520 | |||
521 | len += snprintf(buf+len, sizeof(buf)-len, | ||
522 | "\nTX\n---------------------\n"); | ||
523 | len += snprintf(buf+len, sizeof(buf)-len, "retry\t%d\t(%d%%)\n", | ||
524 | st->txerr_retry, | ||
525 | st->tx_all_count > 0 ? | ||
526 | st->txerr_retry*100/st->tx_all_count : 0); | ||
527 | len += snprintf(buf+len, sizeof(buf)-len, "FIFO\t%d\t(%d%%)\n", | ||
528 | st->txerr_fifo, | ||
529 | st->tx_all_count > 0 ? | ||
530 | st->txerr_fifo*100/st->tx_all_count : 0); | ||
531 | len += snprintf(buf+len, sizeof(buf)-len, "filter\t%d\t(%d%%)\n", | ||
532 | st->txerr_filt, | ||
533 | st->tx_all_count > 0 ? | ||
534 | st->txerr_filt*100/st->tx_all_count : 0); | ||
535 | len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n", | ||
536 | st->tx_all_count); | ||
537 | |||
538 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
539 | } | ||
540 | |||
541 | static ssize_t write_file_frameerrors(struct file *file, | ||
542 | const char __user *userbuf, | ||
543 | size_t count, loff_t *ppos) | ||
544 | { | ||
545 | struct ath5k_softc *sc = file->private_data; | ||
546 | struct ath5k_statistics *st = &sc->stats; | ||
547 | char buf[20]; | ||
548 | |||
549 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
550 | return -EFAULT; | ||
551 | |||
552 | if (strncmp(buf, "clear", 5) == 0) { | ||
553 | st->rxerr_crc = 0; | ||
554 | st->rxerr_phy = 0; | ||
555 | st->rxerr_fifo = 0; | ||
556 | st->rxerr_decrypt = 0; | ||
557 | st->rxerr_mic = 0; | ||
558 | st->rxerr_proc = 0; | ||
559 | st->rxerr_jumbo = 0; | ||
560 | st->rx_all_count = 0; | ||
561 | st->txerr_retry = 0; | ||
562 | st->txerr_fifo = 0; | ||
563 | st->txerr_filt = 0; | ||
564 | st->tx_all_count = 0; | ||
565 | printk(KERN_INFO "ath5k debug: cleared frameerrors stats\n"); | ||
566 | } | ||
567 | return count; | ||
568 | } | ||
569 | |||
570 | static const struct file_operations fops_frameerrors = { | ||
571 | .read = read_file_frameerrors, | ||
572 | .write = write_file_frameerrors, | ||
573 | .open = ath5k_debugfs_open, | ||
574 | .owner = THIS_MODULE, | ||
575 | }; | ||
576 | |||
577 | |||
578 | /* debugfs: ani */ | ||
579 | |||
580 | static ssize_t read_file_ani(struct file *file, char __user *user_buf, | ||
581 | size_t count, loff_t *ppos) | ||
582 | { | ||
583 | struct ath5k_softc *sc = file->private_data; | ||
584 | struct ath5k_statistics *st = &sc->stats; | ||
585 | struct ath5k_ani_state *as = &sc->ani_state; | ||
586 | |||
587 | char buf[700]; | ||
588 | unsigned int len = 0; | ||
589 | |||
590 | len += snprintf(buf+len, sizeof(buf)-len, | ||
591 | "HW has PHY error counters:\t%s\n", | ||
592 | sc->ah->ah_capabilities.cap_has_phyerr_counters ? | ||
593 | "yes" : "no"); | ||
594 | len += snprintf(buf+len, sizeof(buf)-len, | ||
595 | "HW max spur immunity level:\t%d\n", | ||
596 | as->max_spur_level); | ||
597 | len += snprintf(buf+len, sizeof(buf)-len, | ||
598 | "\nANI state\n--------------------------------------------\n"); | ||
599 | len += snprintf(buf+len, sizeof(buf)-len, "operating mode:\t\t\t"); | ||
600 | switch (as->ani_mode) { | ||
601 | case ATH5K_ANI_MODE_OFF: | ||
602 | len += snprintf(buf+len, sizeof(buf)-len, "OFF\n"); | ||
603 | break; | ||
604 | case ATH5K_ANI_MODE_MANUAL_LOW: | ||
605 | len += snprintf(buf+len, sizeof(buf)-len, | ||
606 | "MANUAL LOW\n"); | ||
607 | break; | ||
608 | case ATH5K_ANI_MODE_MANUAL_HIGH: | ||
609 | len += snprintf(buf+len, sizeof(buf)-len, | ||
610 | "MANUAL HIGH\n"); | ||
611 | break; | ||
612 | case ATH5K_ANI_MODE_AUTO: | ||
613 | len += snprintf(buf+len, sizeof(buf)-len, "AUTO\n"); | ||
614 | break; | ||
615 | default: | ||
616 | len += snprintf(buf+len, sizeof(buf)-len, | ||
617 | "??? (not good)\n"); | ||
618 | break; | ||
619 | } | ||
620 | len += snprintf(buf+len, sizeof(buf)-len, | ||
621 | "noise immunity level:\t\t%d\n", | ||
622 | as->noise_imm_level); | ||
623 | len += snprintf(buf+len, sizeof(buf)-len, | ||
624 | "spur immunity level:\t\t%d\n", | ||
625 | as->spur_level); | ||
626 | len += snprintf(buf+len, sizeof(buf)-len, "firstep level:\t\t\t%d\n", | ||
627 | as->firstep_level); | ||
628 | len += snprintf(buf+len, sizeof(buf)-len, | ||
629 | "OFDM weak signal detection:\t%s\n", | ||
630 | as->ofdm_weak_sig ? "on" : "off"); | ||
631 | len += snprintf(buf+len, sizeof(buf)-len, | ||
632 | "CCK weak signal detection:\t%s\n", | ||
633 | as->cck_weak_sig ? "on" : "off"); | ||
634 | |||
635 | len += snprintf(buf+len, sizeof(buf)-len, | ||
636 | "\nMIB INTERRUPTS:\t\t%u\n", | ||
637 | st->mib_intr); | ||
638 | len += snprintf(buf+len, sizeof(buf)-len, | ||
639 | "beacon RSSI average:\t%d\n", | ||
640 | sc->ah->ah_beacon_rssi_avg.avg); | ||
641 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt tx\t\t%u\t(%d%%)\n", | ||
642 | as->pfc_tx, | ||
643 | as->pfc_cycles > 0 ? | ||
644 | as->pfc_tx*100/as->pfc_cycles : 0); | ||
645 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt rx\t\t%u\t(%d%%)\n", | ||
646 | as->pfc_rx, | ||
647 | as->pfc_cycles > 0 ? | ||
648 | as->pfc_rx*100/as->pfc_cycles : 0); | ||
649 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt busy\t\t%u\t(%d%%)\n", | ||
650 | as->pfc_busy, | ||
651 | as->pfc_cycles > 0 ? | ||
652 | as->pfc_busy*100/as->pfc_cycles : 0); | ||
653 | len += snprintf(buf+len, sizeof(buf)-len, "profcnt cycles\t\t%u\n", | ||
654 | as->pfc_cycles); | ||
655 | len += snprintf(buf+len, sizeof(buf)-len, | ||
656 | "listen time\t\t%d\tlast: %d\n", | ||
657 | as->listen_time, as->last_listen); | ||
658 | len += snprintf(buf+len, sizeof(buf)-len, | ||
659 | "OFDM errors\t\t%u\tlast: %u\tsum: %u\n", | ||
660 | as->ofdm_errors, as->last_ofdm_errors, | ||
661 | as->sum_ofdm_errors); | ||
662 | len += snprintf(buf+len, sizeof(buf)-len, | ||
663 | "CCK errors\t\t%u\tlast: %u\tsum: %u\n", | ||
664 | as->cck_errors, as->last_cck_errors, | ||
665 | as->sum_cck_errors); | ||
666 | len += snprintf(buf+len, sizeof(buf)-len, | ||
667 | "AR5K_PHYERR_CNT1\t%x\t(=%d)\n", | ||
668 | ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1), | ||
669 | ATH5K_ANI_OFDM_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - | ||
670 | ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT1))); | ||
671 | len += snprintf(buf+len, sizeof(buf)-len, | ||
672 | "AR5K_PHYERR_CNT2\t%x\t(=%d)\n", | ||
673 | ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2), | ||
674 | ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX - | ||
675 | ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2))); | ||
676 | |||
677 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
678 | } | ||
679 | |||
680 | static ssize_t write_file_ani(struct file *file, | ||
681 | const char __user *userbuf, | ||
682 | size_t count, loff_t *ppos) | ||
683 | { | ||
684 | struct ath5k_softc *sc = file->private_data; | ||
685 | char buf[20]; | ||
686 | |||
687 | if (copy_from_user(buf, userbuf, min(count, sizeof(buf)))) | ||
688 | return -EFAULT; | ||
689 | |||
690 | if (strncmp(buf, "sens-low", 8) == 0) { | ||
691 | ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_HIGH); | ||
692 | } else if (strncmp(buf, "sens-high", 9) == 0) { | ||
693 | ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_MANUAL_LOW); | ||
694 | } else if (strncmp(buf, "ani-off", 7) == 0) { | ||
695 | ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_OFF); | ||
696 | } else if (strncmp(buf, "ani-on", 6) == 0) { | ||
697 | ath5k_ani_init(sc->ah, ATH5K_ANI_MODE_AUTO); | ||
698 | } else if (strncmp(buf, "noise-low", 9) == 0) { | ||
699 | ath5k_ani_set_noise_immunity_level(sc->ah, 0); | ||
700 | } else if (strncmp(buf, "noise-high", 10) == 0) { | ||
701 | ath5k_ani_set_noise_immunity_level(sc->ah, | ||
702 | ATH5K_ANI_MAX_NOISE_IMM_LVL); | ||
703 | } else if (strncmp(buf, "spur-low", 8) == 0) { | ||
704 | ath5k_ani_set_spur_immunity_level(sc->ah, 0); | ||
705 | } else if (strncmp(buf, "spur-high", 9) == 0) { | ||
706 | ath5k_ani_set_spur_immunity_level(sc->ah, | ||
707 | sc->ani_state.max_spur_level); | ||
708 | } else if (strncmp(buf, "fir-low", 7) == 0) { | ||
709 | ath5k_ani_set_firstep_level(sc->ah, 0); | ||
710 | } else if (strncmp(buf, "fir-high", 8) == 0) { | ||
711 | ath5k_ani_set_firstep_level(sc->ah, ATH5K_ANI_MAX_FIRSTEP_LVL); | ||
712 | } else if (strncmp(buf, "ofdm-off", 8) == 0) { | ||
713 | ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, false); | ||
714 | } else if (strncmp(buf, "ofdm-on", 7) == 0) { | ||
715 | ath5k_ani_set_ofdm_weak_signal_detection(sc->ah, true); | ||
716 | } else if (strncmp(buf, "cck-off", 7) == 0) { | ||
717 | ath5k_ani_set_cck_weak_signal_detection(sc->ah, false); | ||
718 | } else if (strncmp(buf, "cck-on", 6) == 0) { | ||
719 | ath5k_ani_set_cck_weak_signal_detection(sc->ah, true); | ||
720 | } | ||
721 | return count; | ||
722 | } | ||
723 | |||
724 | static const struct file_operations fops_ani = { | ||
725 | .read = read_file_ani, | ||
726 | .write = write_file_ani, | ||
727 | .open = ath5k_debugfs_open, | ||
728 | .owner = THIS_MODULE, | ||
729 | }; | ||
730 | |||
731 | |||
367 | /* init */ | 732 | /* init */ |
368 | 733 | ||
369 | void | 734 | void |
@@ -393,6 +758,20 @@ ath5k_debug_init_device(struct ath5k_softc *sc) | |||
393 | 758 | ||
394 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, | 759 | sc->debug.debugfs_reset = debugfs_create_file("reset", S_IWUSR, |
395 | sc->debug.debugfs_phydir, sc, &fops_reset); | 760 | sc->debug.debugfs_phydir, sc, &fops_reset); |
761 | |||
762 | sc->debug.debugfs_antenna = debugfs_create_file("antenna", | ||
763 | S_IWUSR | S_IRUSR, | ||
764 | sc->debug.debugfs_phydir, sc, &fops_antenna); | ||
765 | |||
766 | sc->debug.debugfs_frameerrors = debugfs_create_file("frameerrors", | ||
767 | S_IWUSR | S_IRUSR, | ||
768 | sc->debug.debugfs_phydir, sc, | ||
769 | &fops_frameerrors); | ||
770 | |||
771 | sc->debug.debugfs_ani = debugfs_create_file("ani", | ||
772 | S_IWUSR | S_IRUSR, | ||
773 | sc->debug.debugfs_phydir, sc, | ||
774 | &fops_ani); | ||
396 | } | 775 | } |
397 | 776 | ||
398 | void | 777 | void |
@@ -408,6 +787,9 @@ ath5k_debug_finish_device(struct ath5k_softc *sc) | |||
408 | debugfs_remove(sc->debug.debugfs_registers); | 787 | debugfs_remove(sc->debug.debugfs_registers); |
409 | debugfs_remove(sc->debug.debugfs_beacon); | 788 | debugfs_remove(sc->debug.debugfs_beacon); |
410 | debugfs_remove(sc->debug.debugfs_reset); | 789 | debugfs_remove(sc->debug.debugfs_reset); |
790 | debugfs_remove(sc->debug.debugfs_antenna); | ||
791 | debugfs_remove(sc->debug.debugfs_frameerrors); | ||
792 | debugfs_remove(sc->debug.debugfs_ani); | ||
411 | debugfs_remove(sc->debug.debugfs_phydir); | 793 | debugfs_remove(sc->debug.debugfs_phydir); |
412 | } | 794 | } |
413 | 795 | ||
diff --git a/drivers/net/wireless/ath/ath5k/debug.h b/drivers/net/wireless/ath/ath5k/debug.h index 66f69f04e55e..ddd5b3a99e8d 100644 --- a/drivers/net/wireless/ath/ath5k/debug.h +++ b/drivers/net/wireless/ath/ath5k/debug.h | |||
@@ -74,6 +74,9 @@ struct ath5k_dbg_info { | |||
74 | struct dentry *debugfs_registers; | 74 | struct dentry *debugfs_registers; |
75 | struct dentry *debugfs_beacon; | 75 | struct dentry *debugfs_beacon; |
76 | struct dentry *debugfs_reset; | 76 | struct dentry *debugfs_reset; |
77 | struct dentry *debugfs_antenna; | ||
78 | struct dentry *debugfs_frameerrors; | ||
79 | struct dentry *debugfs_ani; | ||
77 | }; | 80 | }; |
78 | 81 | ||
79 | /** | 82 | /** |
@@ -113,6 +116,7 @@ enum ath5k_debug_level { | |||
113 | ATH5K_DEBUG_DUMP_TX = 0x00000200, | 116 | ATH5K_DEBUG_DUMP_TX = 0x00000200, |
114 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, | 117 | ATH5K_DEBUG_DUMPBANDS = 0x00000400, |
115 | ATH5K_DEBUG_TRACE = 0x00001000, | 118 | ATH5K_DEBUG_TRACE = 0x00001000, |
119 | ATH5K_DEBUG_ANI = 0x00002000, | ||
116 | ATH5K_DEBUG_ANY = 0xffffffff | 120 | ATH5K_DEBUG_ANY = 0xffffffff |
117 | }; | 121 | }; |
118 | 122 | ||
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index dc30a2b70a6b..7d7b646ab65a 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
@@ -35,7 +35,8 @@ | |||
35 | */ | 35 | */ |
36 | static int | 36 | static int |
37 | ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | 37 | ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, |
38 | unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, | 38 | unsigned int pkt_len, unsigned int hdr_len, int padsize, |
39 | enum ath5k_pkt_type type, | ||
39 | unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, | 40 | unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, |
40 | unsigned int key_index, unsigned int antenna_mode, unsigned int flags, | 41 | unsigned int key_index, unsigned int antenna_mode, unsigned int flags, |
41 | unsigned int rtscts_rate, unsigned int rtscts_duration) | 42 | unsigned int rtscts_rate, unsigned int rtscts_duration) |
@@ -71,7 +72,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
71 | /* Verify and set frame length */ | 72 | /* Verify and set frame length */ |
72 | 73 | ||
73 | /* remove padding we might have added before */ | 74 | /* remove padding we might have added before */ |
74 | frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; | 75 | frame_len = pkt_len - padsize + FCS_LEN; |
75 | 76 | ||
76 | if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) | 77 | if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) |
77 | return -EINVAL; | 78 | return -EINVAL; |
@@ -100,7 +101,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
100 | AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); | 101 | AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); |
101 | } | 102 | } |
102 | 103 | ||
103 | /*Diferences between 5210-5211*/ | 104 | /*Differences between 5210-5211*/ |
104 | if (ah->ah_version == AR5K_AR5210) { | 105 | if (ah->ah_version == AR5K_AR5210) { |
105 | switch (type) { | 106 | switch (type) { |
106 | case AR5K_PKT_TYPE_BEACON: | 107 | case AR5K_PKT_TYPE_BEACON: |
@@ -165,6 +166,7 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
165 | */ | 166 | */ |
166 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | 167 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, |
167 | struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, | 168 | struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, |
169 | int padsize, | ||
168 | enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, | 170 | enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, |
169 | unsigned int tx_tries0, unsigned int key_index, | 171 | unsigned int tx_tries0, unsigned int key_index, |
170 | unsigned int antenna_mode, unsigned int flags, | 172 | unsigned int antenna_mode, unsigned int flags, |
@@ -206,7 +208,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
206 | /* Verify and set frame length */ | 208 | /* Verify and set frame length */ |
207 | 209 | ||
208 | /* remove padding we might have added before */ | 210 | /* remove padding we might have added before */ |
209 | frame_len = pkt_len - ath5k_pad_size(hdr_len) + FCS_LEN; | 211 | frame_len = pkt_len - padsize + FCS_LEN; |
210 | 212 | ||
211 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | 213 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) |
212 | return -EINVAL; | 214 | return -EINVAL; |
@@ -229,7 +231,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | |||
229 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | 231 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); |
230 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | 232 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, |
231 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | 233 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); |
232 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, | 234 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0, |
233 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | 235 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); |
234 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | 236 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; |
235 | 237 | ||
@@ -643,6 +645,7 @@ static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | |||
643 | rs->rs_status |= AR5K_RXERR_PHY; | 645 | rs->rs_status |= AR5K_RXERR_PHY; |
644 | rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, | 646 | rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, |
645 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); | 647 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); |
648 | ath5k_ani_phy_error_report(ah, rs->rs_phyerr); | ||
646 | } | 649 | } |
647 | 650 | ||
648 | if (rx_status->rx_status_1 & | 651 | if (rx_status->rx_status_1 & |
@@ -668,12 +671,6 @@ int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) | |||
668 | ah->ah_version != AR5K_AR5212) | 671 | ah->ah_version != AR5K_AR5212) |
669 | return -ENOTSUPP; | 672 | return -ENOTSUPP; |
670 | 673 | ||
671 | /* XXX: What is this magic value and where is it used ? */ | ||
672 | if (ah->ah_version == AR5K_AR5212) | ||
673 | ah->ah_magic = AR5K_EEPROM_MAGIC_5212; | ||
674 | else if (ah->ah_version == AR5K_AR5211) | ||
675 | ah->ah_magic = AR5K_EEPROM_MAGIC_5211; | ||
676 | |||
677 | if (ah->ah_version == AR5K_AR5212) { | 674 | if (ah->ah_version == AR5K_AR5212) { |
678 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; | 675 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; |
679 | ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; | 676 | ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; |
diff --git a/drivers/net/wireless/ath/ath5k/desc.h b/drivers/net/wireless/ath/ath5k/desc.h index 56158c804e3e..64538fbe4167 100644 --- a/drivers/net/wireless/ath/ath5k/desc.h +++ b/drivers/net/wireless/ath/ath5k/desc.h | |||
@@ -112,15 +112,32 @@ struct ath5k_hw_rx_error { | |||
112 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 | 112 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 |
113 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 | 113 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 |
114 | 114 | ||
115 | /* PHY Error codes */ | 115 | /** |
116 | #define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 | 116 | * enum ath5k_phy_error_code - PHY Error codes |
117 | #define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 | 117 | */ |
118 | #define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 | 118 | enum ath5k_phy_error_code { |
119 | #define AR5K_DESC_RX_PHY_ERROR_RATE 0x60 | 119 | AR5K_RX_PHY_ERROR_UNDERRUN = 0, /* Transmit underrun */ |
120 | #define AR5K_DESC_RX_PHY_ERROR_LENGTH 0x80 | 120 | AR5K_RX_PHY_ERROR_TIMING = 1, /* Timing error */ |
121 | #define AR5K_DESC_RX_PHY_ERROR_64QAM 0xa0 | 121 | AR5K_RX_PHY_ERROR_PARITY = 2, /* Illegal parity */ |
122 | #define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0 | 122 | AR5K_RX_PHY_ERROR_RATE = 3, /* Illegal rate */ |
123 | #define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0 | 123 | AR5K_RX_PHY_ERROR_LENGTH = 4, /* Illegal length */ |
124 | AR5K_RX_PHY_ERROR_RADAR = 5, /* Radar detect */ | ||
125 | AR5K_RX_PHY_ERROR_SERVICE = 6, /* Illegal service */ | ||
126 | AR5K_RX_PHY_ERROR_TOR = 7, /* Transmit override receive */ | ||
127 | /* these are specific to the 5212 */ | ||
128 | AR5K_RX_PHY_ERROR_OFDM_TIMING = 17, | ||
129 | AR5K_RX_PHY_ERROR_OFDM_SIGNAL_PARITY = 18, | ||
130 | AR5K_RX_PHY_ERROR_OFDM_RATE_ILLEGAL = 19, | ||
131 | AR5K_RX_PHY_ERROR_OFDM_LENGTH_ILLEGAL = 20, | ||
132 | AR5K_RX_PHY_ERROR_OFDM_POWER_DROP = 21, | ||
133 | AR5K_RX_PHY_ERROR_OFDM_SERVICE = 22, | ||
134 | AR5K_RX_PHY_ERROR_OFDM_RESTART = 23, | ||
135 | AR5K_RX_PHY_ERROR_CCK_TIMING = 25, | ||
136 | AR5K_RX_PHY_ERROR_CCK_HEADER_CRC = 26, | ||
137 | AR5K_RX_PHY_ERROR_CCK_RATE_ILLEGAL = 27, | ||
138 | AR5K_RX_PHY_ERROR_CCK_SERVICE = 30, | ||
139 | AR5K_RX_PHY_ERROR_CCK_RESTART = 31, | ||
140 | }; | ||
124 | 141 | ||
125 | /* | 142 | /* |
126 | * 5210/5211 hardware 2-word TX control descriptor | 143 | * 5210/5211 hardware 2-word TX control descriptor |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 67665cdc7afe..ed0263672d6d 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -331,7 +331,8 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
331 | ee->ee_x_gain[mode] = (val >> 1) & 0xf; | 331 | ee->ee_x_gain[mode] = (val >> 1) & 0xf; |
332 | ee->ee_xpd[mode] = val & 0x1; | 332 | ee->ee_xpd[mode] = val & 0x1; |
333 | 333 | ||
334 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) | 334 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && |
335 | mode != AR5K_EEPROM_MODE_11B) | ||
335 | ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; | 336 | ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; |
336 | 337 | ||
337 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { | 338 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { |
@@ -341,6 +342,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | |||
341 | if (mode == AR5K_EEPROM_MODE_11A) | 342 | if (mode == AR5K_EEPROM_MODE_11A) |
342 | ee->ee_xr_power[mode] = val & 0x3f; | 343 | ee->ee_xr_power[mode] = val & 0x3f; |
343 | else { | 344 | else { |
345 | /* b_DB_11[bg] and b_OB_11[bg] */ | ||
344 | ee->ee_ob[mode][0] = val & 0x7; | 346 | ee->ee_ob[mode][0] = val & 0x7; |
345 | ee->ee_db[mode][0] = (val >> 3) & 0x7; | 347 | ee->ee_db[mode][0] = (val >> 3) & 0x7; |
346 | } | 348 | } |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index 473a483bb9c3..c4a6d5f26af4 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h | |||
@@ -24,9 +24,6 @@ | |||
24 | * SERDES infos are present */ | 24 | * SERDES infos are present */ |
25 | #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ | 25 | #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ |
26 | #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ | 26 | #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ |
27 | #define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */ | ||
28 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ | ||
29 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ | ||
30 | 27 | ||
31 | #define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ | 28 | #define AR5K_EEPROM_IS_HB63 0x000b /* Talon detect */ |
32 | 29 | ||
@@ -78,9 +75,9 @@ | |||
78 | #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) | 75 | #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) |
79 | #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) | 76 | #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) |
80 | #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) | 77 | #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) |
81 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ | 78 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz */ |
82 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ | 79 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for < 2W power consumption */ |
83 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) | 80 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) /* Device type (1 Cardbus, 2 PCI, 3 MiniPCI, 4 AP) */ |
84 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ | 81 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ |
85 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ | 82 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz */ |
86 | 83 | ||
@@ -101,7 +98,7 @@ | |||
101 | 98 | ||
102 | #define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) | 99 | #define AR5K_EEPROM_MISC1 AR5K_EEPROM_INFO(5) |
103 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) | 100 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) |
104 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) | 101 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) /* has 32KHz crystal for sleep mode */ |
105 | #define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) | 102 | #define AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(_v) (((_v) >> 15) & 0x1) |
106 | 103 | ||
107 | #define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) | 104 | #define AR5K_EEPROM_MISC2 AR5K_EEPROM_INFO(6) |
@@ -114,26 +111,27 @@ | |||
114 | 111 | ||
115 | #define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) | 112 | #define AR5K_EEPROM_MISC4 AR5K_EEPROM_INFO(8) |
116 | #define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) | 113 | #define AR5K_EEPROM_CAL_DATA_START(_v) (((_v) >> 4) & 0xfff) |
117 | #define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) | 114 | #define AR5K_EEPROM_MASK_R0(_v) (((_v) >> 2) & 0x3) /* modes supported by radio 0 (bit 1: G, bit 2: A) */ |
118 | #define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) | 115 | #define AR5K_EEPROM_MASK_R1(_v) ((_v) & 0x3) /* modes supported by radio 1 (bit 1: G, bit 2: A) */ |
119 | 116 | ||
120 | #define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) | 117 | #define AR5K_EEPROM_MISC5 AR5K_EEPROM_INFO(9) |
121 | #define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) | 118 | #define AR5K_EEPROM_COMP_DIS(_v) ((_v) & 0x1) /* disable compression */ |
122 | #define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) | 119 | #define AR5K_EEPROM_AES_DIS(_v) (((_v) >> 1) & 0x1) /* disable AES */ |
123 | #define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) | 120 | #define AR5K_EEPROM_FF_DIS(_v) (((_v) >> 2) & 0x1) /* disable fast frames */ |
124 | #define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) | 121 | #define AR5K_EEPROM_BURST_DIS(_v) (((_v) >> 3) & 0x1) /* disable bursting */ |
125 | #define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) | 122 | #define AR5K_EEPROM_MAX_QCU(_v) (((_v) >> 4) & 0xf) /* max number of QCUs. defaults to 10 */ |
126 | #define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) | 123 | #define AR5K_EEPROM_HEAVY_CLIP_EN(_v) (((_v) >> 8) & 0x1) /* enable heayy clipping */ |
127 | #define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) | 124 | #define AR5K_EEPROM_KEY_CACHE_SIZE(_v) (((_v) >> 12) & 0xf) /* key cache size. defaults to 128 */ |
128 | 125 | ||
129 | #define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) | 126 | #define AR5K_EEPROM_MISC6 AR5K_EEPROM_INFO(10) |
130 | #define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x8) | 127 | #define AR5K_EEPROM_TX_CHAIN_DIS ((_v) & 0x7) /* MIMO chains disabled for TX bitmask */ |
131 | #define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x8) | 128 | #define AR5K_EEPROM_RX_CHAIN_DIS (((_v) >> 3) & 0x7) /* MIMO chains disabled for RX bitmask */ |
132 | #define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) | 129 | #define AR5K_EEPROM_FCC_MID_EN (((_v) >> 6) & 0x1) /* 5.47-5.7GHz supported */ |
133 | #define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) | 130 | #define AR5K_EEPROM_JAP_U1EVEN_EN (((_v) >> 7) & 0x1) /* Japan UNII1 band (5.15-5.25GHz) on even channels (5180, 5200, 5220, 5240) supported */ |
134 | #define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) | 131 | #define AR5K_EEPROM_JAP_U2_EN (((_v) >> 8) & 0x1) /* Japan UNII2 band (5.25-5.35GHz) supported */ |
135 | #define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 9) & 0x1) | 132 | #define AR5K_EEPROM_JAP_MID_EN (((_v) >> 9) & 0x1) /* Japan band from 5.47-5.7GHz supported */ |
136 | #define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 10) & 0x1) | 133 | #define AR5K_EEPROM_JAP_U1ODD_EN (((_v) >> 10) & 0x1) /* Japan UNII2 band (5.15-5.25GHz) on odd channels (5170, 5190, 5210, 5230) supported */ |
134 | #define AR5K_EEPROM_JAP_11A_NEW_EN (((_v) >> 11) & 0x1) /* Japan A mode enabled (using even channels) */ | ||
137 | 135 | ||
138 | /* calibration settings */ | 136 | /* calibration settings */ |
139 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) | 137 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) |
@@ -389,7 +387,49 @@ struct ath5k_edge_power { | |||
389 | bool flag; | 387 | bool flag; |
390 | }; | 388 | }; |
391 | 389 | ||
392 | /* EEPROM calibration data */ | 390 | /** |
391 | * struct ath5k_eeprom_info - EEPROM calibration data | ||
392 | * | ||
393 | * @ee_regdomain: ath/regd.c takes care of COUNTRY_ERD and WORLDWIDE_ROAMING | ||
394 | * flags | ||
395 | * @ee_ant_gain: Antenna gain in 0.5dB steps signed [5211 only?] | ||
396 | * @ee_cck_ofdm_gain_delta: difference in gainF to output the same power for | ||
397 | * OFDM and CCK packets | ||
398 | * @ee_cck_ofdm_power_delta: power difference between OFDM (6Mbps) and CCK | ||
399 | * (11Mbps) rate in G mode. 0.1dB steps | ||
400 | * @ee_scaled_cck_delta: for Japan Channel 14: 0.1dB resolution | ||
401 | * | ||
402 | * @ee_i_cal: Initial I coefficient to correct I/Q mismatch in the receive path | ||
403 | * @ee_q_cal: Initial Q coefficient to correct I/Q mismatch in the receive path | ||
404 | * @ee_fixed_bias: use ee_ob and ee_db settings or use automatic control | ||
405 | * @ee_switch_settling: RX/TX Switch settling time | ||
406 | * @ee_atn_tx_rx: Difference in attenuation between TX and RX in 1dB steps | ||
407 | * @ee_ant_control: Antenna Control Settings | ||
408 | * @ee_ob: Bias current for Output stage of PA | ||
409 | * B/G mode: Index [0] is used for AR2112/5112, otherwise [1] | ||
410 | * A mode: [0] 5.15-5.25 [1] 5.25-5.50 [2] 5.50-5.70 [3] 5.70-5.85 GHz | ||
411 | * @ee_db: Bias current for Output stage of PA. see @ee_ob | ||
412 | * @ee_tx_end2xlna_enable: Time difference from when BB finishes sending a frame | ||
413 | * to when the external LNA is activated | ||
414 | * @ee_tx_end2xpa_disable: Time difference from when BB finishes sending a frame | ||
415 | * to when the external PA switch is deactivated | ||
416 | * @ee_tx_frm2xpa_enable: Time difference from when MAC sends frame to when | ||
417 | * external PA switch is activated | ||
418 | * @ee_thr_62: Clear Channel Assessment (CCA) sensitivity | ||
419 | * (IEEE802.11a section 17.3.10.5 ) | ||
420 | * @ee_xlna_gain: Total gain of the LNA (information only) | ||
421 | * @ee_xpd: Use external (1) or internal power detector | ||
422 | * @ee_x_gain: Gain for external power detector output (differences in EEMAP | ||
423 | * versions!) | ||
424 | * @ee_i_gain: Initial gain value after reset | ||
425 | * @ee_margin_tx_rx: Margin in dB when final attenuation stage should be used | ||
426 | * | ||
427 | * @ee_false_detect: Backoff in Sensitivity (dB) on channels with spur signals | ||
428 | * @ee_noise_floor_thr: Noise floor threshold in 1dB steps | ||
429 | * @ee_adc_desired_size: Desired amplitude for ADC, used by AGC; in 0.5 dB steps | ||
430 | * @ee_pga_desired_size: Desired output of PGA (for BB gain) in 0.5 dB steps | ||
431 | * @ee_pd_gain_overlap: PD ADC curves need to overlap in 0.5dB steps (ee_map>=2) | ||
432 | */ | ||
393 | struct ath5k_eeprom_info { | 433 | struct ath5k_eeprom_info { |
394 | 434 | ||
395 | /* Header information */ | 435 | /* Header information */ |
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c index aefe84f9c04b..5212e275f1c7 100644 --- a/drivers/net/wireless/ath/ath5k/pcu.c +++ b/drivers/net/wireless/ath/ath5k/pcu.c | |||
@@ -39,16 +39,16 @@ | |||
39 | * ath5k_hw_set_opmode - Set PCU operating mode | 39 | * ath5k_hw_set_opmode - Set PCU operating mode |
40 | * | 40 | * |
41 | * @ah: The &struct ath5k_hw | 41 | * @ah: The &struct ath5k_hw |
42 | * @op_mode: &enum nl80211_iftype operating mode | ||
42 | * | 43 | * |
43 | * Initialize PCU for the various operating modes (AP/STA etc) | 44 | * Initialize PCU for the various operating modes (AP/STA etc) |
44 | * | ||
45 | * NOTE: ah->ah_op_mode must be set before calling this. | ||
46 | */ | 45 | */ |
47 | int ath5k_hw_set_opmode(struct ath5k_hw *ah) | 46 | int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode) |
48 | { | 47 | { |
49 | struct ath_common *common = ath5k_hw_common(ah); | 48 | struct ath_common *common = ath5k_hw_common(ah); |
50 | u32 pcu_reg, beacon_reg, low_id, high_id; | 49 | u32 pcu_reg, beacon_reg, low_id, high_id; |
51 | 50 | ||
51 | ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_MODE, "mode %d\n", op_mode); | ||
52 | 52 | ||
53 | /* Preserve rest settings */ | 53 | /* Preserve rest settings */ |
54 | pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; | 54 | pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000; |
@@ -61,7 +61,7 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah) | |||
61 | 61 | ||
62 | ATH5K_TRACE(ah->ah_sc); | 62 | ATH5K_TRACE(ah->ah_sc); |
63 | 63 | ||
64 | switch (ah->ah_op_mode) { | 64 | switch (op_mode) { |
65 | case NL80211_IFTYPE_ADHOC: | 65 | case NL80211_IFTYPE_ADHOC: |
66 | pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; | 66 | pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE; |
67 | beacon_reg |= AR5K_BCR_ADHOC; | 67 | beacon_reg |= AR5K_BCR_ADHOC; |
@@ -113,39 +113,26 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah) | |||
113 | } | 113 | } |
114 | 114 | ||
115 | /** | 115 | /** |
116 | * ath5k_hw_update - Update mib counters (mac layer statistics) | 116 | * ath5k_hw_update - Update MIB counters (mac layer statistics) |
117 | * | 117 | * |
118 | * @ah: The &struct ath5k_hw | 118 | * @ah: The &struct ath5k_hw |
119 | * @stats: The &struct ieee80211_low_level_stats we use to track | ||
120 | * statistics on the driver | ||
121 | * | 119 | * |
122 | * Reads MIB counters from PCU and updates sw statistics. Must be | 120 | * Reads MIB counters from PCU and updates sw statistics. Is called after a |
123 | * called after a MIB interrupt. | 121 | * MIB interrupt, because one of these counters might have reached their maximum |
122 | * and triggered the MIB interrupt, to let us read and clear the counter. | ||
123 | * | ||
124 | * Is called in interrupt context! | ||
124 | */ | 125 | */ |
125 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, | 126 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah) |
126 | struct ieee80211_low_level_stats *stats) | ||
127 | { | 127 | { |
128 | ATH5K_TRACE(ah->ah_sc); | 128 | struct ath5k_statistics *stats = &ah->ah_sc->stats; |
129 | 129 | ||
130 | /* Read-And-Clear */ | 130 | /* Read-And-Clear */ |
131 | stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); | 131 | stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); |
132 | stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); | 132 | stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); |
133 | stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); | 133 | stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK); |
134 | stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); | 134 | stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); |
135 | 135 | stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); | |
136 | /* XXX: Should we use this to track beacon count ? | ||
137 | * -we read it anyway to clear the register */ | ||
138 | ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); | ||
139 | |||
140 | /* Reset profile count registers on 5212*/ | ||
141 | if (ah->ah_version == AR5K_AR5212) { | ||
142 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); | ||
143 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); | ||
144 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); | ||
145 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); | ||
146 | } | ||
147 | |||
148 | /* TODO: Handle ANI stats */ | ||
149 | } | 136 | } |
150 | 137 | ||
151 | /** | 138 | /** |
@@ -167,9 +154,9 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) | |||
167 | else { | 154 | else { |
168 | u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; | 155 | u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; |
169 | if (high) | 156 | if (high) |
170 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); | ||
171 | else | ||
172 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); | 157 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); |
158 | else | ||
159 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); | ||
173 | } | 160 | } |
174 | } | 161 | } |
175 | 162 | ||
@@ -179,25 +166,12 @@ void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) | |||
179 | \******************/ | 166 | \******************/ |
180 | 167 | ||
181 | /** | 168 | /** |
182 | * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec | ||
183 | * | ||
184 | * @ah: The &struct ath5k_hw | ||
185 | */ | ||
186 | unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah) | ||
187 | { | ||
188 | ATH5K_TRACE(ah->ah_sc); | ||
189 | |||
190 | return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
191 | AR5K_TIME_OUT), AR5K_TIME_OUT_ACK)); | ||
192 | } | ||
193 | |||
194 | /** | ||
195 | * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU | 169 | * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU |
196 | * | 170 | * |
197 | * @ah: The &struct ath5k_hw | 171 | * @ah: The &struct ath5k_hw |
198 | * @timeout: Timeout in usec | 172 | * @timeout: Timeout in usec |
199 | */ | 173 | */ |
200 | int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | 174 | static int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) |
201 | { | 175 | { |
202 | ATH5K_TRACE(ah->ah_sc); | 176 | ATH5K_TRACE(ah->ah_sc); |
203 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) | 177 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK)) |
@@ -211,24 +185,12 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | |||
211 | } | 185 | } |
212 | 186 | ||
213 | /** | 187 | /** |
214 | * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec | ||
215 | * | ||
216 | * @ah: The &struct ath5k_hw | ||
217 | */ | ||
218 | unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) | ||
219 | { | ||
220 | ATH5K_TRACE(ah->ah_sc); | ||
221 | return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
222 | AR5K_TIME_OUT), AR5K_TIME_OUT_CTS)); | ||
223 | } | ||
224 | |||
225 | /** | ||
226 | * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU | 188 | * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU |
227 | * | 189 | * |
228 | * @ah: The &struct ath5k_hw | 190 | * @ah: The &struct ath5k_hw |
229 | * @timeout: Timeout in usec | 191 | * @timeout: Timeout in usec |
230 | */ | 192 | */ |
231 | int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) | 193 | static int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) |
232 | { | 194 | { |
233 | ATH5K_TRACE(ah->ah_sc); | 195 | ATH5K_TRACE(ah->ah_sc); |
234 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) | 196 | if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS)) |
@@ -290,7 +252,7 @@ unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah) | |||
290 | * | 252 | * |
291 | * @ah: The &struct ath5k_hw | 253 | * @ah: The &struct ath5k_hw |
292 | */ | 254 | */ |
293 | unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | 255 | static unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) |
294 | { | 256 | { |
295 | struct ieee80211_channel *channel = ah->ah_current_channel; | 257 | struct ieee80211_channel *channel = ah->ah_current_channel; |
296 | 258 | ||
@@ -308,7 +270,7 @@ unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah) | |||
308 | * | 270 | * |
309 | * @ah: The &struct ath5k_hw | 271 | * @ah: The &struct ath5k_hw |
310 | */ | 272 | */ |
311 | unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) | 273 | static unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah) |
312 | { | 274 | { |
313 | struct ieee80211_channel *channel = ah->ah_current_channel; | 275 | struct ieee80211_channel *channel = ah->ah_current_channel; |
314 | 276 | ||
@@ -417,7 +379,6 @@ void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) | |||
417 | * (ACK etc). | 379 | * (ACK etc). |
418 | * | 380 | * |
419 | * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma | 381 | * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma |
420 | * TODO: Init ANI here | ||
421 | */ | 382 | */ |
422 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) | 383 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) |
423 | { | 384 | { |
@@ -451,42 +412,6 @@ void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) | |||
451 | ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); | 412 | ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); |
452 | } | 413 | } |
453 | 414 | ||
454 | /* | ||
455 | * Set multicast filter by index | ||
456 | */ | ||
457 | int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index) | ||
458 | { | ||
459 | |||
460 | ATH5K_TRACE(ah->ah_sc); | ||
461 | if (index >= 64) | ||
462 | return -EINVAL; | ||
463 | else if (index >= 32) | ||
464 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
465 | (1 << (index - 32))); | ||
466 | else | ||
467 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | /* | ||
473 | * Clear Multicast filter by index | ||
474 | */ | ||
475 | int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index) | ||
476 | { | ||
477 | |||
478 | ATH5K_TRACE(ah->ah_sc); | ||
479 | if (index >= 64) | ||
480 | return -EINVAL; | ||
481 | else if (index >= 32) | ||
482 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
483 | (1 << (index - 32))); | ||
484 | else | ||
485 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
486 | |||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | /** | 415 | /** |
491 | * ath5k_hw_get_rx_filter - Get current rx filter | 416 | * ath5k_hw_get_rx_filter - Get current rx filter |
492 | * | 417 | * |
@@ -571,18 +496,7 @@ void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) | |||
571 | * Beacon control * | 496 | * Beacon control * |
572 | \****************/ | 497 | \****************/ |
573 | 498 | ||
574 | /** | 499 | #define ATH5K_MAX_TSF_READ 10 |
575 | * ath5k_hw_get_tsf32 - Get a 32bit TSF | ||
576 | * | ||
577 | * @ah: The &struct ath5k_hw | ||
578 | * | ||
579 | * Returns lower 32 bits of current TSF | ||
580 | */ | ||
581 | u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah) | ||
582 | { | ||
583 | ATH5K_TRACE(ah->ah_sc); | ||
584 | return ath5k_hw_reg_read(ah, AR5K_TSF_L32); | ||
585 | } | ||
586 | 500 | ||
587 | /** | 501 | /** |
588 | * ath5k_hw_get_tsf64 - Get the full 64bit TSF | 502 | * ath5k_hw_get_tsf64 - Get the full 64bit TSF |
@@ -593,10 +507,35 @@ u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah) | |||
593 | */ | 507 | */ |
594 | u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) | 508 | u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) |
595 | { | 509 | { |
596 | u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32); | 510 | u32 tsf_lower, tsf_upper1, tsf_upper2; |
511 | int i; | ||
512 | |||
513 | /* | ||
514 | * While reading TSF upper and then lower part, the clock is still | ||
515 | * counting (or jumping in case of IBSS merge) so we might get | ||
516 | * inconsistent values. To avoid this, we read the upper part again | ||
517 | * and check it has not been changed. We make the hypothesis that a | ||
518 | * maximum of 3 changes can happens in a row (we use 10 as a safe | ||
519 | * value). | ||
520 | * | ||
521 | * Impact on performance is pretty small, since in most cases, only | ||
522 | * 3 register reads are needed. | ||
523 | */ | ||
524 | |||
525 | tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32); | ||
526 | for (i = 0; i < ATH5K_MAX_TSF_READ; i++) { | ||
527 | tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32); | ||
528 | tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32); | ||
529 | if (tsf_upper2 == tsf_upper1) | ||
530 | break; | ||
531 | tsf_upper1 = tsf_upper2; | ||
532 | } | ||
533 | |||
534 | WARN_ON( i == ATH5K_MAX_TSF_READ ); | ||
535 | |||
597 | ATH5K_TRACE(ah->ah_sc); | 536 | ATH5K_TRACE(ah->ah_sc); |
598 | 537 | ||
599 | return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32); | 538 | return (((u64)tsf_upper1 << 32) | tsf_lower); |
600 | } | 539 | } |
601 | 540 | ||
602 | /** | 541 | /** |
@@ -651,7 +590,7 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
651 | /* | 590 | /* |
652 | * Set the additional timers by mode | 591 | * Set the additional timers by mode |
653 | */ | 592 | */ |
654 | switch (ah->ah_op_mode) { | 593 | switch (ah->ah_sc->opmode) { |
655 | case NL80211_IFTYPE_MONITOR: | 594 | case NL80211_IFTYPE_MONITOR: |
656 | case NL80211_IFTYPE_STATION: | 595 | case NL80211_IFTYPE_STATION: |
657 | /* In STA mode timer1 is used as next wakeup | 596 | /* In STA mode timer1 is used as next wakeup |
@@ -688,8 +627,8 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
688 | * Set the beacon register and enable all timers. | 627 | * Set the beacon register and enable all timers. |
689 | */ | 628 | */ |
690 | /* When in AP or Mesh Point mode zero timer0 to start TSF */ | 629 | /* When in AP or Mesh Point mode zero timer0 to start TSF */ |
691 | if (ah->ah_op_mode == NL80211_IFTYPE_AP || | 630 | if (ah->ah_sc->opmode == NL80211_IFTYPE_AP || |
692 | ah->ah_op_mode == NL80211_IFTYPE_MESH_POINT) | 631 | ah->ah_sc->opmode == NL80211_IFTYPE_MESH_POINT) |
693 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); | 632 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); |
694 | 633 | ||
695 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); | 634 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); |
@@ -722,203 +661,6 @@ void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | |||
722 | 661 | ||
723 | } | 662 | } |
724 | 663 | ||
725 | #if 0 | ||
726 | /* | ||
727 | * Set beacon timers | ||
728 | */ | ||
729 | int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, | ||
730 | const struct ath5k_beacon_state *state) | ||
731 | { | ||
732 | u32 cfp_period, next_cfp, dtim, interval, next_beacon; | ||
733 | |||
734 | /* | ||
735 | * TODO: should be changed through *state | ||
736 | * review struct ath5k_beacon_state struct | ||
737 | * | ||
738 | * XXX: These are used for cfp period bellow, are they | ||
739 | * ok ? Is it O.K. for tsf here to be 0 or should we use | ||
740 | * get_tsf ? | ||
741 | */ | ||
742 | u32 dtim_count = 0; /* XXX */ | ||
743 | u32 cfp_count = 0; /* XXX */ | ||
744 | u32 tsf = 0; /* XXX */ | ||
745 | |||
746 | ATH5K_TRACE(ah->ah_sc); | ||
747 | /* Return on an invalid beacon state */ | ||
748 | if (state->bs_interval < 1) | ||
749 | return -EINVAL; | ||
750 | |||
751 | interval = state->bs_interval; | ||
752 | dtim = state->bs_dtim_period; | ||
753 | |||
754 | /* | ||
755 | * PCF support? | ||
756 | */ | ||
757 | if (state->bs_cfp_period > 0) { | ||
758 | /* | ||
759 | * Enable PCF mode and set the CFP | ||
760 | * (Contention Free Period) and timer registers | ||
761 | */ | ||
762 | cfp_period = state->bs_cfp_period * state->bs_dtim_period * | ||
763 | state->bs_interval; | ||
764 | next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) * | ||
765 | state->bs_interval; | ||
766 | |||
767 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, | ||
768 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
769 | AR5K_STA_ID1_PCF); | ||
770 | ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD); | ||
771 | ath5k_hw_reg_write(ah, state->bs_cfp_max_duration, | ||
772 | AR5K_CFP_DUR); | ||
773 | ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period : | ||
774 | next_cfp)) << 3, AR5K_TIMER2); | ||
775 | } else { | ||
776 | /* Disable PCF mode */ | ||
777 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
778 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
779 | AR5K_STA_ID1_PCF); | ||
780 | } | ||
781 | |||
782 | /* | ||
783 | * Enable the beacon timer register | ||
784 | */ | ||
785 | ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0); | ||
786 | |||
787 | /* | ||
788 | * Start the beacon timers | ||
789 | */ | ||
790 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) & | ||
791 | ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) | | ||
792 | AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0, | ||
793 | AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval, | ||
794 | AR5K_BEACON_PERIOD), AR5K_BEACON); | ||
795 | |||
796 | /* | ||
797 | * Write new beacon miss threshold, if it appears to be valid | ||
798 | * XXX: Figure out right values for min <= bs_bmiss_threshold <= max | ||
799 | * and return if its not in range. We can test this by reading value and | ||
800 | * setting value to a largest value and seeing which values register. | ||
801 | */ | ||
802 | |||
803 | AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS, | ||
804 | state->bs_bmiss_threshold); | ||
805 | |||
806 | /* | ||
807 | * Set sleep control register | ||
808 | * XXX: Didn't find this in 5210 code but since this register | ||
809 | * exists also in ar5k's 5210 headers i leave it as common code. | ||
810 | */ | ||
811 | AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR, | ||
812 | (state->bs_sleep_duration - 3) << 3); | ||
813 | |||
814 | /* | ||
815 | * Set enhanced sleep registers on 5212 | ||
816 | */ | ||
817 | if (ah->ah_version == AR5K_AR5212) { | ||
818 | if (state->bs_sleep_duration > state->bs_interval && | ||
819 | roundup(state->bs_sleep_duration, interval) == | ||
820 | state->bs_sleep_duration) | ||
821 | interval = state->bs_sleep_duration; | ||
822 | |||
823 | if (state->bs_sleep_duration > dtim && (dtim == 0 || | ||
824 | roundup(state->bs_sleep_duration, dtim) == | ||
825 | state->bs_sleep_duration)) | ||
826 | dtim = state->bs_sleep_duration; | ||
827 | |||
828 | if (interval > dtim) | ||
829 | return -EINVAL; | ||
830 | |||
831 | next_beacon = interval == dtim ? state->bs_next_dtim : | ||
832 | state->bs_next_beacon; | ||
833 | |||
834 | ath5k_hw_reg_write(ah, | ||
835 | AR5K_REG_SM((state->bs_next_dtim - 3) << 3, | ||
836 | AR5K_SLEEP0_NEXT_DTIM) | | ||
837 | AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) | | ||
838 | AR5K_SLEEP0_ENH_SLEEP_EN | | ||
839 | AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0); | ||
840 | |||
841 | ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3, | ||
842 | AR5K_SLEEP1_NEXT_TIM) | | ||
843 | AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1); | ||
844 | |||
845 | ath5k_hw_reg_write(ah, | ||
846 | AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) | | ||
847 | AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2); | ||
848 | } | ||
849 | |||
850 | return 0; | ||
851 | } | ||
852 | |||
853 | /* | ||
854 | * Reset beacon timers | ||
855 | */ | ||
856 | void ath5k_hw_reset_beacon(struct ath5k_hw *ah) | ||
857 | { | ||
858 | ATH5K_TRACE(ah->ah_sc); | ||
859 | /* | ||
860 | * Disable beacon timer | ||
861 | */ | ||
862 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); | ||
863 | |||
864 | /* | ||
865 | * Disable some beacon register values | ||
866 | */ | ||
867 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
868 | AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF); | ||
869 | ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON); | ||
870 | } | ||
871 | |||
872 | /* | ||
873 | * Wait for beacon queue to finish | ||
874 | */ | ||
875 | int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr) | ||
876 | { | ||
877 | unsigned int i; | ||
878 | int ret; | ||
879 | |||
880 | ATH5K_TRACE(ah->ah_sc); | ||
881 | |||
882 | /* 5210 doesn't have QCU*/ | ||
883 | if (ah->ah_version == AR5K_AR5210) { | ||
884 | /* | ||
885 | * Wait for beaconn queue to finish by checking | ||
886 | * Control Register and Beacon Status Register. | ||
887 | */ | ||
888 | for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) { | ||
889 | if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F) | ||
890 | || | ||
891 | !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F)) | ||
892 | break; | ||
893 | udelay(10); | ||
894 | } | ||
895 | |||
896 | /* Timeout... */ | ||
897 | if (i <= 0) { | ||
898 | /* | ||
899 | * Re-schedule the beacon queue | ||
900 | */ | ||
901 | ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1); | ||
902 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE, | ||
903 | AR5K_BCR); | ||
904 | |||
905 | return -EIO; | ||
906 | } | ||
907 | ret = 0; | ||
908 | } else { | ||
909 | /*5211/5212*/ | ||
910 | ret = ath5k_hw_register_timeout(ah, | ||
911 | AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON), | ||
912 | AR5K_QCU_STS_FRMPENDCNT, 0, false); | ||
913 | |||
914 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON)) | ||
915 | return -EIO; | ||
916 | } | ||
917 | |||
918 | return ret; | ||
919 | } | ||
920 | #endif | ||
921 | |||
922 | 664 | ||
923 | /*********************\ | 665 | /*********************\ |
924 | * Key table functions * | 666 | * Key table functions * |
@@ -971,19 +713,6 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) | |||
971 | return 0; | 713 | return 0; |
972 | } | 714 | } |
973 | 715 | ||
974 | /* | ||
975 | * Check if a table entry is valid | ||
976 | */ | ||
977 | int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry) | ||
978 | { | ||
979 | ATH5K_TRACE(ah->ah_sc); | ||
980 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
981 | |||
982 | /* Check the validation flag at the end of the entry */ | ||
983 | return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) & | ||
984 | AR5K_KEYTABLE_VALID; | ||
985 | } | ||
986 | |||
987 | static | 716 | static |
988 | int ath5k_keycache_type(const struct ieee80211_key_conf *key) | 717 | int ath5k_keycache_type(const struct ieee80211_key_conf *key) |
989 | { | 718 | { |
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 68e2bccd90d3..1b81c4778800 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -20,8 +20,6 @@ | |||
20 | * | 20 | * |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #define _ATH5K_PHY | ||
24 | |||
25 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
26 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
27 | 25 | ||
@@ -982,7 +980,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, | |||
982 | return -EINVAL; | 980 | return -EINVAL; |
983 | 981 | ||
984 | data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8); | 982 | data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8); |
985 | } else if ((c - (c % 5)) != 2 || c > 5435) { | 983 | } else if ((c % 5) != 2 || c > 5435) { |
986 | if (!(c % 20) && c >= 5120) { | 984 | if (!(c % 20) && c >= 5120) { |
987 | data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); | 985 | data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); |
988 | data2 = ath5k_hw_bitswap(3, 2); | 986 | data2 = ath5k_hw_bitswap(3, 2); |
@@ -995,7 +993,7 @@ static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah, | |||
995 | } else | 993 | } else |
996 | return -EINVAL; | 994 | return -EINVAL; |
997 | } else { | 995 | } else { |
998 | data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8); | 996 | data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8); |
999 | data2 = ath5k_hw_bitswap(0, 2); | 997 | data2 = ath5k_hw_bitswap(0, 2); |
1000 | } | 998 | } |
1001 | 999 | ||
@@ -1023,7 +1021,7 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah, | |||
1023 | data0 = ath5k_hw_bitswap((c - 2272), 8); | 1021 | data0 = ath5k_hw_bitswap((c - 2272), 8); |
1024 | data2 = 0; | 1022 | data2 = 0; |
1025 | /* ? 5GHz ? */ | 1023 | /* ? 5GHz ? */ |
1026 | } else if ((c - (c % 5)) != 2 || c > 5435) { | 1024 | } else if ((c % 5) != 2 || c > 5435) { |
1027 | if (!(c % 20) && c < 5120) | 1025 | if (!(c % 20) && c < 5120) |
1028 | data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); | 1026 | data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8); |
1029 | else if (!(c % 10)) | 1027 | else if (!(c % 10)) |
@@ -1034,7 +1032,7 @@ static int ath5k_hw_rf2425_channel(struct ath5k_hw *ah, | |||
1034 | return -EINVAL; | 1032 | return -EINVAL; |
1035 | data2 = ath5k_hw_bitswap(1, 2); | 1033 | data2 = ath5k_hw_bitswap(1, 2); |
1036 | } else { | 1034 | } else { |
1037 | data0 = ath5k_hw_bitswap((10 * (c - 2) - 4800) / 25 + 1, 8); | 1035 | data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8); |
1038 | data2 = ath5k_hw_bitswap(0, 2); | 1036 | data2 = ath5k_hw_bitswap(0, 2); |
1039 | } | 1037 | } |
1040 | 1038 | ||
@@ -1105,28 +1103,6 @@ int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel) | |||
1105 | PHY calibration | 1103 | PHY calibration |
1106 | \*****************/ | 1104 | \*****************/ |
1107 | 1105 | ||
1108 | void | ||
1109 | ath5k_hw_calibration_poll(struct ath5k_hw *ah) | ||
1110 | { | ||
1111 | /* Calibration interval in jiffies */ | ||
1112 | unsigned long cal_intval; | ||
1113 | |||
1114 | cal_intval = msecs_to_jiffies(ah->ah_cal_intval * 1000); | ||
1115 | |||
1116 | /* Initialize timestamp if needed */ | ||
1117 | if (!ah->ah_cal_tstamp) | ||
1118 | ah->ah_cal_tstamp = jiffies; | ||
1119 | |||
1120 | /* For now we always do full calibration | ||
1121 | * Mark software interrupt mask and fire software | ||
1122 | * interrupt (bit gets auto-cleared) */ | ||
1123 | if (time_is_before_eq_jiffies(ah->ah_cal_tstamp + cal_intval)) { | ||
1124 | ah->ah_cal_tstamp = jiffies; | ||
1125 | ah->ah_swi_mask = AR5K_SWI_FULL_CALIBRATION; | ||
1126 | AR5K_REG_ENABLE_BITS(ah, AR5K_CR, AR5K_CR_SWI); | ||
1127 | } | ||
1128 | } | ||
1129 | |||
1130 | static int sign_extend(int val, const int nbits) | 1106 | static int sign_extend(int val, const int nbits) |
1131 | { | 1107 | { |
1132 | int order = BIT(nbits-1); | 1108 | int order = BIT(nbits-1); |
@@ -1191,7 +1167,7 @@ static s16 ath5k_hw_get_median_noise_floor(struct ath5k_hw *ah) | |||
1191 | * The median of the values in the history is then loaded into the | 1167 | * The median of the values in the history is then loaded into the |
1192 | * hardware for its own use for RSSI and CCA measurements. | 1168 | * hardware for its own use for RSSI and CCA measurements. |
1193 | */ | 1169 | */ |
1194 | void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) | 1170 | static void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) |
1195 | { | 1171 | { |
1196 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 1172 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
1197 | u32 val; | 1173 | u32 val; |
@@ -1400,7 +1376,11 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1400 | } | 1376 | } |
1401 | 1377 | ||
1402 | i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; | 1378 | i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7; |
1403 | q_coffd = q_pwr >> 7; | 1379 | |
1380 | if (ah->ah_version == AR5K_AR5211) | ||
1381 | q_coffd = q_pwr >> 6; | ||
1382 | else | ||
1383 | q_coffd = q_pwr >> 7; | ||
1404 | 1384 | ||
1405 | /* protect against divide by 0 and loss of sign bits */ | 1385 | /* protect against divide by 0 and loss of sign bits */ |
1406 | if (i_coffd == 0 || q_coffd < 2) | 1386 | if (i_coffd == 0 || q_coffd < 2) |
@@ -1409,7 +1389,10 @@ static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah, | |||
1409 | i_coff = (-iq_corr) / i_coffd; | 1389 | i_coff = (-iq_corr) / i_coffd; |
1410 | i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ | 1390 | i_coff = clamp(i_coff, -32, 31); /* signed 6 bit */ |
1411 | 1391 | ||
1412 | q_coff = (i_pwr / q_coffd) - 128; | 1392 | if (ah->ah_version == AR5K_AR5211) |
1393 | q_coff = (i_pwr / q_coffd) - 64; | ||
1394 | else | ||
1395 | q_coff = (i_pwr / q_coffd) - 128; | ||
1413 | q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */ | 1396 | q_coff = clamp(q_coff, -16, 15); /* signed 5 bit */ |
1414 | 1397 | ||
1415 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, | 1398 | ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE, |
@@ -1769,7 +1752,7 @@ u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan) | |||
1769 | * Antenna control * | 1752 | * Antenna control * |
1770 | \*****************/ | 1753 | \*****************/ |
1771 | 1754 | ||
1772 | void /*TODO:Boundary check*/ | 1755 | static void /*TODO:Boundary check*/ |
1773 | ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) | 1756 | ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) |
1774 | { | 1757 | { |
1775 | ATH5K_TRACE(ah->ah_sc); | 1758 | ATH5K_TRACE(ah->ah_sc); |
@@ -1778,16 +1761,6 @@ ath5k_hw_set_def_antenna(struct ath5k_hw *ah, u8 ant) | |||
1778 | ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); | 1761 | ath5k_hw_reg_write(ah, ant & 0x7, AR5K_DEFAULT_ANTENNA); |
1779 | } | 1762 | } |
1780 | 1763 | ||
1781 | unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah) | ||
1782 | { | ||
1783 | ATH5K_TRACE(ah->ah_sc); | ||
1784 | |||
1785 | if (ah->ah_version != AR5K_AR5210) | ||
1786 | return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA) & 0x7; | ||
1787 | |||
1788 | return false; /*XXX: What do we return for 5210 ?*/ | ||
1789 | } | ||
1790 | |||
1791 | /* | 1764 | /* |
1792 | * Enable/disable fast rx antenna diversity | 1765 | * Enable/disable fast rx antenna diversity |
1793 | */ | 1766 | */ |
@@ -1931,6 +1904,7 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
1931 | 1904 | ||
1932 | ah->ah_tx_ant = tx_ant; | 1905 | ah->ah_tx_ant = tx_ant; |
1933 | ah->ah_ant_mode = ant_mode; | 1906 | ah->ah_ant_mode = ant_mode; |
1907 | ah->ah_def_ant = def_ant; | ||
1934 | 1908 | ||
1935 | sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; | 1909 | sta_id1 |= use_def_for_tx ? AR5K_STA_ID1_DEFAULT_ANTENNA : 0; |
1936 | sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; | 1910 | sta_id1 |= update_def_on_tx ? AR5K_STA_ID1_DESC_ANTENNA : 0; |
@@ -2171,8 +2145,6 @@ ath5k_get_chan_pcal_surrounding_piers(struct ath5k_hw *ah, | |||
2171 | done: | 2145 | done: |
2172 | *pcinfo_l = &pcinfo[idx_l]; | 2146 | *pcinfo_l = &pcinfo[idx_l]; |
2173 | *pcinfo_r = &pcinfo[idx_r]; | 2147 | *pcinfo_r = &pcinfo[idx_r]; |
2174 | |||
2175 | return; | ||
2176 | } | 2148 | } |
2177 | 2149 | ||
2178 | /* | 2150 | /* |
@@ -2441,19 +2413,6 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, | |||
2441 | pcdac_tmp = pcdac_high_pwr; | 2413 | pcdac_tmp = pcdac_high_pwr; |
2442 | 2414 | ||
2443 | edge_flag = 0x40; | 2415 | edge_flag = 0x40; |
2444 | #if 0 | ||
2445 | /* If both min and max power limits are in lower | ||
2446 | * power curve's range, only use the low power curve. | ||
2447 | * TODO: min/max levels are related to target | ||
2448 | * power values requested from driver/user | ||
2449 | * XXX: Is this really needed ? */ | ||
2450 | if (min_pwr < table_max[1] && | ||
2451 | max_pwr < table_max[1]) { | ||
2452 | edge_flag = 0; | ||
2453 | pcdac_tmp = pcdac_low_pwr; | ||
2454 | max_pwr_idx = (table_max[1] - table_min[1])/2; | ||
2455 | } | ||
2456 | #endif | ||
2457 | } else { | 2416 | } else { |
2458 | pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ | 2417 | pcdac_low_pwr = ah->ah_txpower.tmpL[1]; /* Zeroed */ |
2459 | pcdac_high_pwr = ah->ah_txpower.tmpL[0]; | 2418 | pcdac_high_pwr = ah->ah_txpower.tmpL[0]; |
@@ -2600,7 +2559,7 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, | |||
2600 | max_idx = (pdadc_n < table_size) ? pdadc_n : table_size; | 2559 | max_idx = (pdadc_n < table_size) ? pdadc_n : table_size; |
2601 | 2560 | ||
2602 | /* Fill pdadc_out table */ | 2561 | /* Fill pdadc_out table */ |
2603 | while (pdadc_0 < max_idx) | 2562 | while (pdadc_0 < max_idx && pdadc_i < 128) |
2604 | pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++]; | 2563 | pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++]; |
2605 | 2564 | ||
2606 | /* Need to extrapolate above this pdgain? */ | 2565 | /* Need to extrapolate above this pdgain? */ |
@@ -3144,5 +3103,3 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) | |||
3144 | 3103 | ||
3145 | return ath5k_hw_txpower(ah, channel, ee_mode, txpower); | 3104 | return ath5k_hw_txpower(ah, channel, ee_mode, txpower); |
3146 | } | 3105 | } |
3147 | |||
3148 | #undef _ATH5K_PHY | ||
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c index 9122a8556f45..f5831da33f7b 100644 --- a/drivers/net/wireless/ath/ath5k/qcu.c +++ b/drivers/net/wireless/ath/ath5k/qcu.c | |||
@@ -517,23 +517,6 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | |||
517 | } | 517 | } |
518 | 518 | ||
519 | /* | 519 | /* |
520 | * Get slot time from DCU | ||
521 | */ | ||
522 | unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) | ||
523 | { | ||
524 | unsigned int slot_time_clock; | ||
525 | |||
526 | ATH5K_TRACE(ah->ah_sc); | ||
527 | |||
528 | if (ah->ah_version == AR5K_AR5210) | ||
529 | slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME); | ||
530 | else | ||
531 | slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT); | ||
532 | |||
533 | return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff); | ||
534 | } | ||
535 | |||
536 | /* | ||
537 | * Set slot time on DCU | 520 | * Set slot time on DCU |
538 | */ | 521 | */ |
539 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) | 522 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) |
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index 1464f89b249c..55b4ac6d236f 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h | |||
@@ -212,10 +212,10 @@ | |||
212 | * MIB control register | 212 | * MIB control register |
213 | */ | 213 | */ |
214 | #define AR5K_MIBC 0x0040 /* Register Address */ | 214 | #define AR5K_MIBC 0x0040 /* Register Address */ |
215 | #define AR5K_MIBC_COW 0x00000001 /* Warn test indicator */ | 215 | #define AR5K_MIBC_COW 0x00000001 /* Counter Overflow Warning */ |
216 | #define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ | 216 | #define AR5K_MIBC_FMC 0x00000002 /* Freeze MIB Counters */ |
217 | #define AR5K_MIBC_CMC 0x00000004 /* Clean MIB Counters */ | 217 | #define AR5K_MIBC_CMC 0x00000004 /* Clear MIB Counters */ |
218 | #define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe */ | 218 | #define AR5K_MIBC_MCS 0x00000008 /* MIB counter strobe, increment all */ |
219 | 219 | ||
220 | /* | 220 | /* |
221 | * Timeout prescale register | 221 | * Timeout prescale register |
@@ -1139,8 +1139,8 @@ | |||
1139 | #define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */ | 1139 | #define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */ |
1140 | #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ | 1140 | #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ |
1141 | #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ | 1141 | #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ |
1142 | #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */ | 1142 | #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Rate to use for ACK/CTS. 0: highest mandatory rate <= RX rate; 1: 1Mbps in B mode */ |
1143 | #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate for ACK/CTS [5211+] */ | 1143 | #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* 802.11b base rate. 0: 1, 2, 5.5 and 11Mbps; 1: 1 and 2Mbps. [5211+] */ |
1144 | #define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ | 1144 | #define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ |
1145 | #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ | 1145 | #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ |
1146 | #define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ | 1146 | #define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ |
@@ -1516,7 +1516,14 @@ | |||
1516 | AR5K_NAV_5210 : AR5K_NAV_5211) | 1516 | AR5K_NAV_5210 : AR5K_NAV_5211) |
1517 | 1517 | ||
1518 | /* | 1518 | /* |
1519 | * RTS success register | 1519 | * MIB counters: |
1520 | * | ||
1521 | * max value is 0xc000, if this is reached we get a MIB interrupt. | ||
1522 | * they can be controlled via AR5K_MIBC and are cleared on read. | ||
1523 | */ | ||
1524 | |||
1525 | /* | ||
1526 | * RTS success (MIB counter) | ||
1520 | */ | 1527 | */ |
1521 | #define AR5K_RTS_OK_5210 0x8090 | 1528 | #define AR5K_RTS_OK_5210 0x8090 |
1522 | #define AR5K_RTS_OK_5211 0x8088 | 1529 | #define AR5K_RTS_OK_5211 0x8088 |
@@ -1524,7 +1531,7 @@ | |||
1524 | AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) | 1531 | AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211) |
1525 | 1532 | ||
1526 | /* | 1533 | /* |
1527 | * RTS failure register | 1534 | * RTS failure (MIB counter) |
1528 | */ | 1535 | */ |
1529 | #define AR5K_RTS_FAIL_5210 0x8094 | 1536 | #define AR5K_RTS_FAIL_5210 0x8094 |
1530 | #define AR5K_RTS_FAIL_5211 0x808c | 1537 | #define AR5K_RTS_FAIL_5211 0x808c |
@@ -1532,7 +1539,7 @@ | |||
1532 | AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) | 1539 | AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211) |
1533 | 1540 | ||
1534 | /* | 1541 | /* |
1535 | * ACK failure register | 1542 | * ACK failure (MIB counter) |
1536 | */ | 1543 | */ |
1537 | #define AR5K_ACK_FAIL_5210 0x8098 | 1544 | #define AR5K_ACK_FAIL_5210 0x8098 |
1538 | #define AR5K_ACK_FAIL_5211 0x8090 | 1545 | #define AR5K_ACK_FAIL_5211 0x8090 |
@@ -1540,7 +1547,7 @@ | |||
1540 | AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) | 1547 | AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211) |
1541 | 1548 | ||
1542 | /* | 1549 | /* |
1543 | * FCS failure register | 1550 | * FCS failure (MIB counter) |
1544 | */ | 1551 | */ |
1545 | #define AR5K_FCS_FAIL_5210 0x809c | 1552 | #define AR5K_FCS_FAIL_5210 0x809c |
1546 | #define AR5K_FCS_FAIL_5211 0x8094 | 1553 | #define AR5K_FCS_FAIL_5211 0x8094 |
@@ -1667,11 +1674,17 @@ | |||
1667 | 1674 | ||
1668 | /* | 1675 | /* |
1669 | * Profile count registers | 1676 | * Profile count registers |
1677 | * | ||
1678 | * These registers can be cleared and freezed with ATH5K_MIBC, but they do not | ||
1679 | * generate a MIB interrupt. | ||
1680 | * Instead of overflowing, they shift by one bit to the right. All registers | ||
1681 | * shift together, i.e. when one reaches the max, all shift at the same time by | ||
1682 | * one bit to the right. This way we should always get consistent values. | ||
1670 | */ | 1683 | */ |
1671 | #define AR5K_PROFCNT_TX 0x80ec /* Tx count */ | 1684 | #define AR5K_PROFCNT_TX 0x80ec /* Tx count */ |
1672 | #define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ | 1685 | #define AR5K_PROFCNT_RX 0x80f0 /* Rx count */ |
1673 | #define AR5K_PROFCNT_RXCLR 0x80f4 /* Clear Rx count */ | 1686 | #define AR5K_PROFCNT_RXCLR 0x80f4 /* Busy count */ |
1674 | #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ | 1687 | #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle counter */ |
1675 | 1688 | ||
1676 | /* | 1689 | /* |
1677 | * Quiet period control registers | 1690 | * Quiet period control registers |
@@ -1758,7 +1771,7 @@ | |||
1758 | #define AR5K_CCK_FIL_CNT 0x8128 | 1771 | #define AR5K_CCK_FIL_CNT 0x8128 |
1759 | 1772 | ||
1760 | /* | 1773 | /* |
1761 | * PHY Error Counters (?) | 1774 | * PHY Error Counters (same masks as AR5K_PHY_ERR_FIL) |
1762 | */ | 1775 | */ |
1763 | #define AR5K_PHYERR_CNT1 0x812c | 1776 | #define AR5K_PHYERR_CNT1 0x812c |
1764 | #define AR5K_PHYERR_CNT1_MASK 0x8130 | 1777 | #define AR5K_PHYERR_CNT1_MASK 0x8130 |
@@ -1766,6 +1779,9 @@ | |||
1766 | #define AR5K_PHYERR_CNT2 0x8134 | 1779 | #define AR5K_PHYERR_CNT2 0x8134 |
1767 | #define AR5K_PHYERR_CNT2_MASK 0x8138 | 1780 | #define AR5K_PHYERR_CNT2_MASK 0x8138 |
1768 | 1781 | ||
1782 | /* if the PHY Error Counters reach this maximum, we get MIB interrupts */ | ||
1783 | #define ATH5K_PHYERR_CNT_MAX 0x00c00000 | ||
1784 | |||
1769 | /* | 1785 | /* |
1770 | * TSF Threshold register (?) | 1786 | * TSF Threshold register (?) |
1771 | */ | 1787 | */ |
@@ -1974,7 +1990,7 @@ | |||
1974 | #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ | 1990 | #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ |
1975 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ | 1991 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ |
1976 | #define AR5K_PHY_SETTLING_AGC_S 0 | 1992 | #define AR5K_PHY_SETTLING_AGC_S 0 |
1977 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ | 1993 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settling time */ |
1978 | #define AR5K_PHY_SETTLING_SWITCH_S 7 | 1994 | #define AR5K_PHY_SETTLING_SWITCH_S 7 |
1979 | 1995 | ||
1980 | /* | 1996 | /* |
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c index cbf28e379843..307f80e83f94 100644 --- a/drivers/net/wireless/ath/ath5k/reset.c +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -19,8 +19,6 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define _ATH5K_RESET | ||
23 | |||
24 | /*****************************\ | 22 | /*****************************\ |
25 | Reset functions and helpers | 23 | Reset functions and helpers |
26 | \*****************************/ | 24 | \*****************************/ |
@@ -34,6 +32,27 @@ | |||
34 | #include "base.h" | 32 | #include "base.h" |
35 | #include "debug.h" | 33 | #include "debug.h" |
36 | 34 | ||
35 | /* | ||
36 | * Check if a register write has been completed | ||
37 | */ | ||
38 | int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, | ||
39 | bool is_set) | ||
40 | { | ||
41 | int i; | ||
42 | u32 data; | ||
43 | |||
44 | for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { | ||
45 | data = ath5k_hw_reg_read(ah, reg); | ||
46 | if (is_set && (data & flag)) | ||
47 | break; | ||
48 | else if ((data & flag) == val) | ||
49 | break; | ||
50 | udelay(15); | ||
51 | } | ||
52 | |||
53 | return (i <= 0) ? -EAGAIN : 0; | ||
54 | } | ||
55 | |||
37 | /** | 56 | /** |
38 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 | 57 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 |
39 | * | 58 | * |
@@ -221,8 +240,8 @@ static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) | |||
221 | /* | 240 | /* |
222 | * Sleep control | 241 | * Sleep control |
223 | */ | 242 | */ |
224 | int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | 243 | static int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, |
225 | bool set_chip, u16 sleep_duration) | 244 | bool set_chip, u16 sleep_duration) |
226 | { | 245 | { |
227 | unsigned int i; | 246 | unsigned int i; |
228 | u32 staid, data; | 247 | u32 staid, data; |
@@ -608,7 +627,6 @@ static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) | |||
608 | 627 | ||
609 | AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); | 628 | AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); |
610 | } | 629 | } |
611 | return; | ||
612 | } | 630 | } |
613 | 631 | ||
614 | /* TODO: Half/Quarter rate */ | 632 | /* TODO: Half/Quarter rate */ |
@@ -864,8 +882,6 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, | |||
864 | /* Heavy clipping -disable for now */ | 882 | /* Heavy clipping -disable for now */ |
865 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) | 883 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) |
866 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); | 884 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); |
867 | |||
868 | return; | ||
869 | } | 885 | } |
870 | 886 | ||
871 | /* | 887 | /* |
@@ -1017,11 +1033,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1017 | if (ret) | 1033 | if (ret) |
1018 | return ret; | 1034 | return ret; |
1019 | 1035 | ||
1020 | /* | ||
1021 | * Initialize operating mode | ||
1022 | */ | ||
1023 | ah->ah_op_mode = op_mode; | ||
1024 | |||
1025 | /* PHY access enable */ | 1036 | /* PHY access enable */ |
1026 | if (ah->ah_mac_srev >= AR5K_SREV_AR5211) | 1037 | if (ah->ah_mac_srev >= AR5K_SREV_AR5211) |
1027 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | 1038 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); |
@@ -1192,7 +1203,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1192 | ath5k_hw_set_associd(ah); | 1203 | ath5k_hw_set_associd(ah); |
1193 | 1204 | ||
1194 | /* Set PCU config */ | 1205 | /* Set PCU config */ |
1195 | ath5k_hw_set_opmode(ah); | 1206 | ath5k_hw_set_opmode(ah, op_mode); |
1196 | 1207 | ||
1197 | /* Clear any pending interrupts | 1208 | /* Clear any pending interrupts |
1198 | * PISR/SISR Not available on 5210 */ | 1209 | * PISR/SISR Not available on 5210 */ |
@@ -1378,7 +1389,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1378 | * external 32KHz crystal when sleeping if one | 1389 | * external 32KHz crystal when sleeping if one |
1379 | * exists */ | 1390 | * exists */ |
1380 | if (ah->ah_version == AR5K_AR5212 && | 1391 | if (ah->ah_version == AR5K_AR5212 && |
1381 | ah->ah_op_mode != NL80211_IFTYPE_AP) | 1392 | op_mode != NL80211_IFTYPE_AP) |
1382 | ath5k_hw_set_sleep_clock(ah, true); | 1393 | ath5k_hw_set_sleep_clock(ah, true); |
1383 | 1394 | ||
1384 | /* | 1395 | /* |
@@ -1388,5 +1399,3 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | |||
1388 | ath5k_hw_reset_tsf(ah); | 1399 | ath5k_hw_reset_tsf(ah); |
1389 | return 0; | 1400 | return 0; |
1390 | } | 1401 | } |
1391 | |||
1392 | #undef _ATH5K_RESET | ||
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig index 5774cea23a3b..35f23bdc442f 100644 --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig | |||
@@ -32,3 +32,24 @@ config ATH9K_DEBUGFS | |||
32 | 32 | ||
33 | Also required for changing debug message flags at run time. | 33 | Also required for changing debug message flags at run time. |
34 | 34 | ||
35 | config ATH9K_HTC | ||
36 | tristate "Atheros HTC based wireless cards support" | ||
37 | depends on USB && MAC80211 | ||
38 | select ATH9K_HW | ||
39 | select MAC80211_LEDS | ||
40 | select LEDS_CLASS | ||
41 | select NEW_LEDS | ||
42 | select ATH9K_COMMON | ||
43 | ---help--- | ||
44 | Support for Atheros HTC based cards. | ||
45 | Chipsets supported: AR9271 | ||
46 | |||
47 | For more information: http://wireless.kernel.org/en/users/Drivers/ath9k_htc | ||
48 | |||
49 | The built module will be ath9k_htc. | ||
50 | |||
51 | config ATH9K_HTC_DEBUGFS | ||
52 | bool "Atheros ath9k_htc debugging" | ||
53 | depends on ATH9K_HTC && DEBUG_FS | ||
54 | ---help--- | ||
55 | Say Y, if you need access to ath9k_htc's statistics. | ||
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index 6b50d5eb9ec3..dd112be218ab 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -13,18 +13,38 @@ ath9k-$(CONFIG_ATH9K_DEBUGFS) += debug.o | |||
13 | 13 | ||
14 | obj-$(CONFIG_ATH9K) += ath9k.o | 14 | obj-$(CONFIG_ATH9K) += ath9k.o |
15 | 15 | ||
16 | ath9k_hw-y:= hw.o \ | 16 | ath9k_hw-y:= \ |
17 | ar9002_hw.o \ | ||
18 | ar9003_hw.o \ | ||
19 | hw.o \ | ||
20 | ar9003_phy.o \ | ||
21 | ar9002_phy.o \ | ||
22 | ar5008_phy.o \ | ||
23 | ar9002_calib.o \ | ||
24 | ar9003_calib.o \ | ||
25 | calib.o \ | ||
17 | eeprom.o \ | 26 | eeprom.o \ |
18 | eeprom_def.o \ | 27 | eeprom_def.o \ |
19 | eeprom_4k.o \ | 28 | eeprom_4k.o \ |
20 | eeprom_9287.o \ | 29 | eeprom_9287.o \ |
21 | calib.o \ | ||
22 | ani.o \ | 30 | ani.o \ |
23 | phy.o \ | ||
24 | btcoex.o \ | 31 | btcoex.o \ |
25 | mac.o \ | 32 | mac.o \ |
33 | ar9002_mac.o \ | ||
34 | ar9003_mac.o \ | ||
35 | ar9003_eeprom.o | ||
26 | 36 | ||
27 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o | 37 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o |
28 | 38 | ||
29 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o | 39 | obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o |
30 | ath9k_common-y:= common.o | 40 | ath9k_common-y:= common.o |
41 | |||
42 | ath9k_htc-y += htc_hst.o \ | ||
43 | hif_usb.o \ | ||
44 | wmi.o \ | ||
45 | htc_drv_txrx.o \ | ||
46 | htc_drv_main.o \ | ||
47 | htc_drv_beacon.o \ | ||
48 | htc_drv_init.o | ||
49 | |||
50 | obj-$(CONFIG_ATH9K_HTC) += ath9k_htc.o | ||
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index ca4994f13151..85fdd26039c8 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -47,6 +47,7 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) | |||
47 | } | 47 | } |
48 | 48 | ||
49 | static struct ath_bus_ops ath_ahb_bus_ops = { | 49 | static struct ath_bus_ops ath_ahb_bus_ops = { |
50 | .ath_bus_type = ATH_AHB, | ||
50 | .read_cachesize = ath_ahb_read_cachesize, | 51 | .read_cachesize = ath_ahb_read_cachesize, |
51 | .eeprom_read = ath_ahb_eeprom_read, | 52 | .eeprom_read = ath_ahb_eeprom_read, |
52 | }; | 53 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 2a0cd64c2bfb..ba8b20f01594 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "hw-ops.h" | ||
18 | 19 | ||
19 | static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, | 20 | static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, |
20 | struct ath9k_channel *chan) | 21 | struct ath9k_channel *chan) |
@@ -37,190 +38,6 @@ static int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah, | |||
37 | return 0; | 38 | return 0; |
38 | } | 39 | } |
39 | 40 | ||
40 | static bool ath9k_hw_ani_control(struct ath_hw *ah, | ||
41 | enum ath9k_ani_cmd cmd, int param) | ||
42 | { | ||
43 | struct ar5416AniState *aniState = ah->curani; | ||
44 | struct ath_common *common = ath9k_hw_common(ah); | ||
45 | |||
46 | switch (cmd & ah->ani_function) { | ||
47 | case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ | ||
48 | u32 level = param; | ||
49 | |||
50 | if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { | ||
51 | ath_print(common, ATH_DBG_ANI, | ||
52 | "level out of range (%u > %u)\n", | ||
53 | level, | ||
54 | (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); | ||
55 | return false; | ||
56 | } | ||
57 | |||
58 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, | ||
59 | AR_PHY_DESIRED_SZ_TOT_DES, | ||
60 | ah->totalSizeDesired[level]); | ||
61 | REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, | ||
62 | AR_PHY_AGC_CTL1_COARSE_LOW, | ||
63 | ah->coarse_low[level]); | ||
64 | REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, | ||
65 | AR_PHY_AGC_CTL1_COARSE_HIGH, | ||
66 | ah->coarse_high[level]); | ||
67 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
68 | AR_PHY_FIND_SIG_FIRPWR, | ||
69 | ah->firpwr[level]); | ||
70 | |||
71 | if (level > aniState->noiseImmunityLevel) | ||
72 | ah->stats.ast_ani_niup++; | ||
73 | else if (level < aniState->noiseImmunityLevel) | ||
74 | ah->stats.ast_ani_nidown++; | ||
75 | aniState->noiseImmunityLevel = level; | ||
76 | break; | ||
77 | } | ||
78 | case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ | ||
79 | const int m1ThreshLow[] = { 127, 50 }; | ||
80 | const int m2ThreshLow[] = { 127, 40 }; | ||
81 | const int m1Thresh[] = { 127, 0x4d }; | ||
82 | const int m2Thresh[] = { 127, 0x40 }; | ||
83 | const int m2CountThr[] = { 31, 16 }; | ||
84 | const int m2CountThrLow[] = { 63, 48 }; | ||
85 | u32 on = param ? 1 : 0; | ||
86 | |||
87 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
88 | AR_PHY_SFCORR_LOW_M1_THRESH_LOW, | ||
89 | m1ThreshLow[on]); | ||
90 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
91 | AR_PHY_SFCORR_LOW_M2_THRESH_LOW, | ||
92 | m2ThreshLow[on]); | ||
93 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
94 | AR_PHY_SFCORR_M1_THRESH, | ||
95 | m1Thresh[on]); | ||
96 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
97 | AR_PHY_SFCORR_M2_THRESH, | ||
98 | m2Thresh[on]); | ||
99 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
100 | AR_PHY_SFCORR_M2COUNT_THR, | ||
101 | m2CountThr[on]); | ||
102 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
103 | AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, | ||
104 | m2CountThrLow[on]); | ||
105 | |||
106 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
107 | AR_PHY_SFCORR_EXT_M1_THRESH_LOW, | ||
108 | m1ThreshLow[on]); | ||
109 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
110 | AR_PHY_SFCORR_EXT_M2_THRESH_LOW, | ||
111 | m2ThreshLow[on]); | ||
112 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
113 | AR_PHY_SFCORR_EXT_M1_THRESH, | ||
114 | m1Thresh[on]); | ||
115 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
116 | AR_PHY_SFCORR_EXT_M2_THRESH, | ||
117 | m2Thresh[on]); | ||
118 | |||
119 | if (on) | ||
120 | REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, | ||
121 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
122 | else | ||
123 | REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, | ||
124 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
125 | |||
126 | if (!on != aniState->ofdmWeakSigDetectOff) { | ||
127 | if (on) | ||
128 | ah->stats.ast_ani_ofdmon++; | ||
129 | else | ||
130 | ah->stats.ast_ani_ofdmoff++; | ||
131 | aniState->ofdmWeakSigDetectOff = !on; | ||
132 | } | ||
133 | break; | ||
134 | } | ||
135 | case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ | ||
136 | const int weakSigThrCck[] = { 8, 6 }; | ||
137 | u32 high = param ? 1 : 0; | ||
138 | |||
139 | REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, | ||
140 | AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, | ||
141 | weakSigThrCck[high]); | ||
142 | if (high != aniState->cckWeakSigThreshold) { | ||
143 | if (high) | ||
144 | ah->stats.ast_ani_cckhigh++; | ||
145 | else | ||
146 | ah->stats.ast_ani_ccklow++; | ||
147 | aniState->cckWeakSigThreshold = high; | ||
148 | } | ||
149 | break; | ||
150 | } | ||
151 | case ATH9K_ANI_FIRSTEP_LEVEL:{ | ||
152 | const int firstep[] = { 0, 4, 8 }; | ||
153 | u32 level = param; | ||
154 | |||
155 | if (level >= ARRAY_SIZE(firstep)) { | ||
156 | ath_print(common, ATH_DBG_ANI, | ||
157 | "level out of range (%u > %u)\n", | ||
158 | level, | ||
159 | (unsigned) ARRAY_SIZE(firstep)); | ||
160 | return false; | ||
161 | } | ||
162 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
163 | AR_PHY_FIND_SIG_FIRSTEP, | ||
164 | firstep[level]); | ||
165 | if (level > aniState->firstepLevel) | ||
166 | ah->stats.ast_ani_stepup++; | ||
167 | else if (level < aniState->firstepLevel) | ||
168 | ah->stats.ast_ani_stepdown++; | ||
169 | aniState->firstepLevel = level; | ||
170 | break; | ||
171 | } | ||
172 | case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ | ||
173 | const int cycpwrThr1[] = | ||
174 | { 2, 4, 6, 8, 10, 12, 14, 16 }; | ||
175 | u32 level = param; | ||
176 | |||
177 | if (level >= ARRAY_SIZE(cycpwrThr1)) { | ||
178 | ath_print(common, ATH_DBG_ANI, | ||
179 | "level out of range (%u > %u)\n", | ||
180 | level, | ||
181 | (unsigned) ARRAY_SIZE(cycpwrThr1)); | ||
182 | return false; | ||
183 | } | ||
184 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, | ||
185 | AR_PHY_TIMING5_CYCPWR_THR1, | ||
186 | cycpwrThr1[level]); | ||
187 | if (level > aniState->spurImmunityLevel) | ||
188 | ah->stats.ast_ani_spurup++; | ||
189 | else if (level < aniState->spurImmunityLevel) | ||
190 | ah->stats.ast_ani_spurdown++; | ||
191 | aniState->spurImmunityLevel = level; | ||
192 | break; | ||
193 | } | ||
194 | case ATH9K_ANI_PRESENT: | ||
195 | break; | ||
196 | default: | ||
197 | ath_print(common, ATH_DBG_ANI, | ||
198 | "invalid cmd %u\n", cmd); | ||
199 | return false; | ||
200 | } | ||
201 | |||
202 | ath_print(common, ATH_DBG_ANI, "ANI parameters:\n"); | ||
203 | ath_print(common, ATH_DBG_ANI, | ||
204 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, " | ||
205 | "ofdmWeakSigDetectOff=%d\n", | ||
206 | aniState->noiseImmunityLevel, | ||
207 | aniState->spurImmunityLevel, | ||
208 | !aniState->ofdmWeakSigDetectOff); | ||
209 | ath_print(common, ATH_DBG_ANI, | ||
210 | "cckWeakSigThreshold=%d, " | ||
211 | "firstepLevel=%d, listenTime=%d\n", | ||
212 | aniState->cckWeakSigThreshold, | ||
213 | aniState->firstepLevel, | ||
214 | aniState->listenTime); | ||
215 | ath_print(common, ATH_DBG_ANI, | ||
216 | "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", | ||
217 | aniState->cycleCount, | ||
218 | aniState->ofdmPhyErrCount, | ||
219 | aniState->cckPhyErrCount); | ||
220 | |||
221 | return true; | ||
222 | } | ||
223 | |||
224 | static void ath9k_hw_update_mibstats(struct ath_hw *ah, | 41 | static void ath9k_hw_update_mibstats(struct ath_hw *ah, |
225 | struct ath9k_mib_stats *stats) | 42 | struct ath9k_mib_stats *stats) |
226 | { | 43 | { |
@@ -262,11 +79,17 @@ static void ath9k_ani_restart(struct ath_hw *ah) | |||
262 | "Writing ofdmbase=%u cckbase=%u\n", | 79 | "Writing ofdmbase=%u cckbase=%u\n", |
263 | aniState->ofdmPhyErrBase, | 80 | aniState->ofdmPhyErrBase, |
264 | aniState->cckPhyErrBase); | 81 | aniState->cckPhyErrBase); |
82 | |||
83 | ENABLE_REGWRITE_BUFFER(ah); | ||
84 | |||
265 | REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); | 85 | REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase); |
266 | REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); | 86 | REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase); |
267 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); | 87 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); |
268 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); | 88 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); |
269 | 89 | ||
90 | REGWRITE_BUFFER_FLUSH(ah); | ||
91 | DISABLE_REGWRITE_BUFFER(ah); | ||
92 | |||
270 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | 93 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); |
271 | 94 | ||
272 | aniState->ofdmPhyErrCount = 0; | 95 | aniState->ofdmPhyErrCount = 0; |
@@ -540,8 +363,14 @@ void ath9k_ani_reset(struct ath_hw *ah) | |||
540 | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & | 363 | ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) & |
541 | ~ATH9K_RX_FILTER_PHYERR); | 364 | ~ATH9K_RX_FILTER_PHYERR); |
542 | ath9k_ani_restart(ah); | 365 | ath9k_ani_restart(ah); |
366 | |||
367 | ENABLE_REGWRITE_BUFFER(ah); | ||
368 | |||
543 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); | 369 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); |
544 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); | 370 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); |
371 | |||
372 | REGWRITE_BUFFER_FLUSH(ah); | ||
373 | DISABLE_REGWRITE_BUFFER(ah); | ||
545 | } | 374 | } |
546 | 375 | ||
547 | void ath9k_hw_ani_monitor(struct ath_hw *ah, | 376 | void ath9k_hw_ani_monitor(struct ath_hw *ah, |
@@ -639,6 +468,8 @@ void ath9k_enable_mib_counters(struct ath_hw *ah) | |||
639 | 468 | ||
640 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); | 469 | ath9k_hw_update_mibstats(ah, &ah->ah_mibStats); |
641 | 470 | ||
471 | ENABLE_REGWRITE_BUFFER(ah); | ||
472 | |||
642 | REG_WRITE(ah, AR_FILT_OFDM, 0); | 473 | REG_WRITE(ah, AR_FILT_OFDM, 0); |
643 | REG_WRITE(ah, AR_FILT_CCK, 0); | 474 | REG_WRITE(ah, AR_FILT_CCK, 0); |
644 | REG_WRITE(ah, AR_MIBC, | 475 | REG_WRITE(ah, AR_MIBC, |
@@ -646,6 +477,9 @@ void ath9k_enable_mib_counters(struct ath_hw *ah) | |||
646 | & 0x0f); | 477 | & 0x0f); |
647 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); | 478 | REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING); |
648 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); | 479 | REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING); |
480 | |||
481 | REGWRITE_BUFFER_FLUSH(ah); | ||
482 | DISABLE_REGWRITE_BUFFER(ah); | ||
649 | } | 483 | } |
650 | 484 | ||
651 | /* Freeze the MIB counters, get the stats and then clear them */ | 485 | /* Freeze the MIB counters, get the stats and then clear them */ |
@@ -809,20 +643,17 @@ void ath9k_hw_ani_init(struct ath_hw *ah) | |||
809 | ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", | 643 | ath_print(common, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n", |
810 | ah->ani[0].cckPhyErrBase); | 644 | ah->ani[0].cckPhyErrBase); |
811 | 645 | ||
646 | ENABLE_REGWRITE_BUFFER(ah); | ||
647 | |||
812 | REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase); | 648 | REG_WRITE(ah, AR_PHY_ERR_1, ah->ani[0].ofdmPhyErrBase); |
813 | REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); | 649 | REG_WRITE(ah, AR_PHY_ERR_2, ah->ani[0].cckPhyErrBase); |
650 | |||
651 | REGWRITE_BUFFER_FLUSH(ah); | ||
652 | DISABLE_REGWRITE_BUFFER(ah); | ||
653 | |||
814 | ath9k_enable_mib_counters(ah); | 654 | ath9k_enable_mib_counters(ah); |
815 | 655 | ||
816 | ah->aniperiod = ATH9K_ANI_PERIOD; | 656 | ah->aniperiod = ATH9K_ANI_PERIOD; |
817 | if (ah->config.enable_ani) | 657 | if (ah->config.enable_ani) |
818 | ah->proc_phyerr |= HAL_PROCESS_ANI; | 658 | ah->proc_phyerr |= HAL_PROCESS_ANI; |
819 | } | 659 | } |
820 | |||
821 | void ath9k_hw_ani_disable(struct ath_hw *ah) | ||
822 | { | ||
823 | ath_print(ath9k_hw_common(ah), ATH_DBG_ANI, "Disabling ANI\n"); | ||
824 | |||
825 | ath9k_hw_disable_mib_counters(ah); | ||
826 | REG_WRITE(ah, AR_PHY_ERR_1, 0); | ||
827 | REG_WRITE(ah, AR_PHY_ERR_2, 0); | ||
828 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h index 4e1ab94a5153..3356762ea384 100644 --- a/drivers/net/wireless/ath/ath9k/ani.h +++ b/drivers/net/wireless/ath/ath9k/ani.h | |||
@@ -118,6 +118,5 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt, | |||
118 | void ath9k_hw_procmibevent(struct ath_hw *ah); | 118 | void ath9k_hw_procmibevent(struct ath_hw *ah); |
119 | void ath9k_hw_ani_setup(struct ath_hw *ah); | 119 | void ath9k_hw_ani_setup(struct ath_hw *ah); |
120 | void ath9k_hw_ani_init(struct ath_hw *ah); | 120 | void ath9k_hw_ani_init(struct ath_hw *ah); |
121 | void ath9k_hw_ani_disable(struct ath_hw *ah); | ||
122 | 121 | ||
123 | #endif /* ANI_H */ | 122 | #endif /* ANI_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_initvals.h b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h new file mode 100644 index 000000000000..025c31ac6146 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar5008_initvals.h | |||
@@ -0,0 +1,742 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef INITVALS_AR5008_H | ||
18 | #define INITVALS_AR5008_H | ||
19 | |||
20 | static const u32 ar5416Modes[][6] = { | ||
21 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
22 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
23 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
24 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
25 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
26 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
27 | { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, | ||
28 | { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a }, | ||
29 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
30 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
31 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
32 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
33 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
34 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
35 | { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 }, | ||
36 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
37 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
38 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
39 | { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de }, | ||
40 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, | ||
41 | { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e }, | ||
42 | { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 }, | ||
43 | { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
44 | { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 }, | ||
45 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
46 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
47 | { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 }, | ||
48 | { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b }, | ||
49 | { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, | ||
50 | { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
51 | { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
52 | { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
53 | { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 }, | ||
54 | { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 }, | ||
55 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
56 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
57 | { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c }, | ||
58 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
59 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
60 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
61 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
62 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
63 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
64 | { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
65 | { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
66 | { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
67 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
68 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
69 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
70 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
71 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
72 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
73 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
74 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
75 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
76 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
77 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
78 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
79 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
80 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
81 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
82 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
83 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
84 | }; | ||
85 | |||
86 | static const u32 ar5416Common[][2] = { | ||
87 | { 0x0000000c, 0x00000000 }, | ||
88 | { 0x00000030, 0x00020015 }, | ||
89 | { 0x00000034, 0x00000005 }, | ||
90 | { 0x00000040, 0x00000000 }, | ||
91 | { 0x00000044, 0x00000008 }, | ||
92 | { 0x00000048, 0x00000008 }, | ||
93 | { 0x0000004c, 0x00000010 }, | ||
94 | { 0x00000050, 0x00000000 }, | ||
95 | { 0x00000054, 0x0000001f }, | ||
96 | { 0x00000800, 0x00000000 }, | ||
97 | { 0x00000804, 0x00000000 }, | ||
98 | { 0x00000808, 0x00000000 }, | ||
99 | { 0x0000080c, 0x00000000 }, | ||
100 | { 0x00000810, 0x00000000 }, | ||
101 | { 0x00000814, 0x00000000 }, | ||
102 | { 0x00000818, 0x00000000 }, | ||
103 | { 0x0000081c, 0x00000000 }, | ||
104 | { 0x00000820, 0x00000000 }, | ||
105 | { 0x00000824, 0x00000000 }, | ||
106 | { 0x00001040, 0x002ffc0f }, | ||
107 | { 0x00001044, 0x002ffc0f }, | ||
108 | { 0x00001048, 0x002ffc0f }, | ||
109 | { 0x0000104c, 0x002ffc0f }, | ||
110 | { 0x00001050, 0x002ffc0f }, | ||
111 | { 0x00001054, 0x002ffc0f }, | ||
112 | { 0x00001058, 0x002ffc0f }, | ||
113 | { 0x0000105c, 0x002ffc0f }, | ||
114 | { 0x00001060, 0x002ffc0f }, | ||
115 | { 0x00001064, 0x002ffc0f }, | ||
116 | { 0x00001230, 0x00000000 }, | ||
117 | { 0x00001270, 0x00000000 }, | ||
118 | { 0x00001038, 0x00000000 }, | ||
119 | { 0x00001078, 0x00000000 }, | ||
120 | { 0x000010b8, 0x00000000 }, | ||
121 | { 0x000010f8, 0x00000000 }, | ||
122 | { 0x00001138, 0x00000000 }, | ||
123 | { 0x00001178, 0x00000000 }, | ||
124 | { 0x000011b8, 0x00000000 }, | ||
125 | { 0x000011f8, 0x00000000 }, | ||
126 | { 0x00001238, 0x00000000 }, | ||
127 | { 0x00001278, 0x00000000 }, | ||
128 | { 0x000012b8, 0x00000000 }, | ||
129 | { 0x000012f8, 0x00000000 }, | ||
130 | { 0x00001338, 0x00000000 }, | ||
131 | { 0x00001378, 0x00000000 }, | ||
132 | { 0x000013b8, 0x00000000 }, | ||
133 | { 0x000013f8, 0x00000000 }, | ||
134 | { 0x00001438, 0x00000000 }, | ||
135 | { 0x00001478, 0x00000000 }, | ||
136 | { 0x000014b8, 0x00000000 }, | ||
137 | { 0x000014f8, 0x00000000 }, | ||
138 | { 0x00001538, 0x00000000 }, | ||
139 | { 0x00001578, 0x00000000 }, | ||
140 | { 0x000015b8, 0x00000000 }, | ||
141 | { 0x000015f8, 0x00000000 }, | ||
142 | { 0x00001638, 0x00000000 }, | ||
143 | { 0x00001678, 0x00000000 }, | ||
144 | { 0x000016b8, 0x00000000 }, | ||
145 | { 0x000016f8, 0x00000000 }, | ||
146 | { 0x00001738, 0x00000000 }, | ||
147 | { 0x00001778, 0x00000000 }, | ||
148 | { 0x000017b8, 0x00000000 }, | ||
149 | { 0x000017f8, 0x00000000 }, | ||
150 | { 0x0000103c, 0x00000000 }, | ||
151 | { 0x0000107c, 0x00000000 }, | ||
152 | { 0x000010bc, 0x00000000 }, | ||
153 | { 0x000010fc, 0x00000000 }, | ||
154 | { 0x0000113c, 0x00000000 }, | ||
155 | { 0x0000117c, 0x00000000 }, | ||
156 | { 0x000011bc, 0x00000000 }, | ||
157 | { 0x000011fc, 0x00000000 }, | ||
158 | { 0x0000123c, 0x00000000 }, | ||
159 | { 0x0000127c, 0x00000000 }, | ||
160 | { 0x000012bc, 0x00000000 }, | ||
161 | { 0x000012fc, 0x00000000 }, | ||
162 | { 0x0000133c, 0x00000000 }, | ||
163 | { 0x0000137c, 0x00000000 }, | ||
164 | { 0x000013bc, 0x00000000 }, | ||
165 | { 0x000013fc, 0x00000000 }, | ||
166 | { 0x0000143c, 0x00000000 }, | ||
167 | { 0x0000147c, 0x00000000 }, | ||
168 | { 0x00004030, 0x00000002 }, | ||
169 | { 0x0000403c, 0x00000002 }, | ||
170 | { 0x00007010, 0x00000000 }, | ||
171 | { 0x00007038, 0x000004c2 }, | ||
172 | { 0x00008004, 0x00000000 }, | ||
173 | { 0x00008008, 0x00000000 }, | ||
174 | { 0x0000800c, 0x00000000 }, | ||
175 | { 0x00008018, 0x00000700 }, | ||
176 | { 0x00008020, 0x00000000 }, | ||
177 | { 0x00008038, 0x00000000 }, | ||
178 | { 0x0000803c, 0x00000000 }, | ||
179 | { 0x00008048, 0x40000000 }, | ||
180 | { 0x00008054, 0x00000000 }, | ||
181 | { 0x00008058, 0x00000000 }, | ||
182 | { 0x0000805c, 0x000fc78f }, | ||
183 | { 0x00008060, 0x0000000f }, | ||
184 | { 0x00008064, 0x00000000 }, | ||
185 | { 0x000080c0, 0x2a82301a }, | ||
186 | { 0x000080c4, 0x05dc01e0 }, | ||
187 | { 0x000080c8, 0x1f402710 }, | ||
188 | { 0x000080cc, 0x01f40000 }, | ||
189 | { 0x000080d0, 0x00001e00 }, | ||
190 | { 0x000080d4, 0x00000000 }, | ||
191 | { 0x000080d8, 0x00400000 }, | ||
192 | { 0x000080e0, 0xffffffff }, | ||
193 | { 0x000080e4, 0x0000ffff }, | ||
194 | { 0x000080e8, 0x003f3f3f }, | ||
195 | { 0x000080ec, 0x00000000 }, | ||
196 | { 0x000080f0, 0x00000000 }, | ||
197 | { 0x000080f4, 0x00000000 }, | ||
198 | { 0x000080f8, 0x00000000 }, | ||
199 | { 0x000080fc, 0x00020000 }, | ||
200 | { 0x00008100, 0x00020000 }, | ||
201 | { 0x00008104, 0x00000001 }, | ||
202 | { 0x00008108, 0x00000052 }, | ||
203 | { 0x0000810c, 0x00000000 }, | ||
204 | { 0x00008110, 0x00000168 }, | ||
205 | { 0x00008118, 0x000100aa }, | ||
206 | { 0x0000811c, 0x00003210 }, | ||
207 | { 0x00008124, 0x00000000 }, | ||
208 | { 0x00008128, 0x00000000 }, | ||
209 | { 0x0000812c, 0x00000000 }, | ||
210 | { 0x00008130, 0x00000000 }, | ||
211 | { 0x00008134, 0x00000000 }, | ||
212 | { 0x00008138, 0x00000000 }, | ||
213 | { 0x0000813c, 0x00000000 }, | ||
214 | { 0x00008144, 0xffffffff }, | ||
215 | { 0x00008168, 0x00000000 }, | ||
216 | { 0x0000816c, 0x00000000 }, | ||
217 | { 0x00008170, 0x32143320 }, | ||
218 | { 0x00008174, 0xfaa4fa50 }, | ||
219 | { 0x00008178, 0x00000100 }, | ||
220 | { 0x0000817c, 0x00000000 }, | ||
221 | { 0x000081c4, 0x00000000 }, | ||
222 | { 0x000081ec, 0x00000000 }, | ||
223 | { 0x000081f0, 0x00000000 }, | ||
224 | { 0x000081f4, 0x00000000 }, | ||
225 | { 0x000081f8, 0x00000000 }, | ||
226 | { 0x000081fc, 0x00000000 }, | ||
227 | { 0x00008200, 0x00000000 }, | ||
228 | { 0x00008204, 0x00000000 }, | ||
229 | { 0x00008208, 0x00000000 }, | ||
230 | { 0x0000820c, 0x00000000 }, | ||
231 | { 0x00008210, 0x00000000 }, | ||
232 | { 0x00008214, 0x00000000 }, | ||
233 | { 0x00008218, 0x00000000 }, | ||
234 | { 0x0000821c, 0x00000000 }, | ||
235 | { 0x00008220, 0x00000000 }, | ||
236 | { 0x00008224, 0x00000000 }, | ||
237 | { 0x00008228, 0x00000000 }, | ||
238 | { 0x0000822c, 0x00000000 }, | ||
239 | { 0x00008230, 0x00000000 }, | ||
240 | { 0x00008234, 0x00000000 }, | ||
241 | { 0x00008238, 0x00000000 }, | ||
242 | { 0x0000823c, 0x00000000 }, | ||
243 | { 0x00008240, 0x00100000 }, | ||
244 | { 0x00008244, 0x0010f400 }, | ||
245 | { 0x00008248, 0x00000100 }, | ||
246 | { 0x0000824c, 0x0001e800 }, | ||
247 | { 0x00008250, 0x00000000 }, | ||
248 | { 0x00008254, 0x00000000 }, | ||
249 | { 0x00008258, 0x00000000 }, | ||
250 | { 0x0000825c, 0x400000ff }, | ||
251 | { 0x00008260, 0x00080922 }, | ||
252 | { 0x00008264, 0x88000010 }, | ||
253 | { 0x00008270, 0x00000000 }, | ||
254 | { 0x00008274, 0x40000000 }, | ||
255 | { 0x00008278, 0x003e4180 }, | ||
256 | { 0x0000827c, 0x00000000 }, | ||
257 | { 0x00008284, 0x0000002c }, | ||
258 | { 0x00008288, 0x0000002c }, | ||
259 | { 0x0000828c, 0x00000000 }, | ||
260 | { 0x00008294, 0x00000000 }, | ||
261 | { 0x00008298, 0x00000000 }, | ||
262 | { 0x00008300, 0x00000000 }, | ||
263 | { 0x00008304, 0x00000000 }, | ||
264 | { 0x00008308, 0x00000000 }, | ||
265 | { 0x0000830c, 0x00000000 }, | ||
266 | { 0x00008310, 0x00000000 }, | ||
267 | { 0x00008314, 0x00000000 }, | ||
268 | { 0x00008318, 0x00000000 }, | ||
269 | { 0x00008328, 0x00000000 }, | ||
270 | { 0x0000832c, 0x00000007 }, | ||
271 | { 0x00008330, 0x00000302 }, | ||
272 | { 0x00008334, 0x00000e00 }, | ||
273 | { 0x00008338, 0x00070000 }, | ||
274 | { 0x0000833c, 0x00000000 }, | ||
275 | { 0x00008340, 0x000107ff }, | ||
276 | { 0x00009808, 0x00000000 }, | ||
277 | { 0x0000980c, 0xad848e19 }, | ||
278 | { 0x00009810, 0x7d14e000 }, | ||
279 | { 0x00009814, 0x9c0a9f6b }, | ||
280 | { 0x0000981c, 0x00000000 }, | ||
281 | { 0x0000982c, 0x0000a000 }, | ||
282 | { 0x00009830, 0x00000000 }, | ||
283 | { 0x0000983c, 0x00200400 }, | ||
284 | { 0x00009840, 0x206a002e }, | ||
285 | { 0x0000984c, 0x1284233c }, | ||
286 | { 0x00009854, 0x00000859 }, | ||
287 | { 0x00009900, 0x00000000 }, | ||
288 | { 0x00009904, 0x00000000 }, | ||
289 | { 0x00009908, 0x00000000 }, | ||
290 | { 0x0000990c, 0x00000000 }, | ||
291 | { 0x0000991c, 0x10000fff }, | ||
292 | { 0x00009920, 0x05100000 }, | ||
293 | { 0x0000a920, 0x05100000 }, | ||
294 | { 0x0000b920, 0x05100000 }, | ||
295 | { 0x00009928, 0x00000001 }, | ||
296 | { 0x0000992c, 0x00000004 }, | ||
297 | { 0x00009934, 0x1e1f2022 }, | ||
298 | { 0x00009938, 0x0a0b0c0d }, | ||
299 | { 0x0000993c, 0x00000000 }, | ||
300 | { 0x00009948, 0x9280b212 }, | ||
301 | { 0x0000994c, 0x00020028 }, | ||
302 | { 0x00009954, 0x5d50e188 }, | ||
303 | { 0x00009958, 0x00081fff }, | ||
304 | { 0x0000c95c, 0x004b6a8e }, | ||
305 | { 0x0000c968, 0x000003ce }, | ||
306 | { 0x00009970, 0x190fb515 }, | ||
307 | { 0x00009974, 0x00000000 }, | ||
308 | { 0x00009978, 0x00000001 }, | ||
309 | { 0x0000997c, 0x00000000 }, | ||
310 | { 0x00009980, 0x00000000 }, | ||
311 | { 0x00009984, 0x00000000 }, | ||
312 | { 0x00009988, 0x00000000 }, | ||
313 | { 0x0000998c, 0x00000000 }, | ||
314 | { 0x00009990, 0x00000000 }, | ||
315 | { 0x00009994, 0x00000000 }, | ||
316 | { 0x00009998, 0x00000000 }, | ||
317 | { 0x0000999c, 0x00000000 }, | ||
318 | { 0x000099a0, 0x00000000 }, | ||
319 | { 0x000099a4, 0x00000001 }, | ||
320 | { 0x000099a8, 0x001fff00 }, | ||
321 | { 0x000099ac, 0x00000000 }, | ||
322 | { 0x000099b0, 0x03051000 }, | ||
323 | { 0x000099dc, 0x00000000 }, | ||
324 | { 0x000099e0, 0x00000200 }, | ||
325 | { 0x000099e4, 0xaaaaaaaa }, | ||
326 | { 0x000099e8, 0x3c466478 }, | ||
327 | { 0x000099ec, 0x000000aa }, | ||
328 | { 0x000099fc, 0x00001042 }, | ||
329 | { 0x00009b00, 0x00000000 }, | ||
330 | { 0x00009b04, 0x00000001 }, | ||
331 | { 0x00009b08, 0x00000002 }, | ||
332 | { 0x00009b0c, 0x00000003 }, | ||
333 | { 0x00009b10, 0x00000004 }, | ||
334 | { 0x00009b14, 0x00000005 }, | ||
335 | { 0x00009b18, 0x00000008 }, | ||
336 | { 0x00009b1c, 0x00000009 }, | ||
337 | { 0x00009b20, 0x0000000a }, | ||
338 | { 0x00009b24, 0x0000000b }, | ||
339 | { 0x00009b28, 0x0000000c }, | ||
340 | { 0x00009b2c, 0x0000000d }, | ||
341 | { 0x00009b30, 0x00000010 }, | ||
342 | { 0x00009b34, 0x00000011 }, | ||
343 | { 0x00009b38, 0x00000012 }, | ||
344 | { 0x00009b3c, 0x00000013 }, | ||
345 | { 0x00009b40, 0x00000014 }, | ||
346 | { 0x00009b44, 0x00000015 }, | ||
347 | { 0x00009b48, 0x00000018 }, | ||
348 | { 0x00009b4c, 0x00000019 }, | ||
349 | { 0x00009b50, 0x0000001a }, | ||
350 | { 0x00009b54, 0x0000001b }, | ||
351 | { 0x00009b58, 0x0000001c }, | ||
352 | { 0x00009b5c, 0x0000001d }, | ||
353 | { 0x00009b60, 0x00000020 }, | ||
354 | { 0x00009b64, 0x00000021 }, | ||
355 | { 0x00009b68, 0x00000022 }, | ||
356 | { 0x00009b6c, 0x00000023 }, | ||
357 | { 0x00009b70, 0x00000024 }, | ||
358 | { 0x00009b74, 0x00000025 }, | ||
359 | { 0x00009b78, 0x00000028 }, | ||
360 | { 0x00009b7c, 0x00000029 }, | ||
361 | { 0x00009b80, 0x0000002a }, | ||
362 | { 0x00009b84, 0x0000002b }, | ||
363 | { 0x00009b88, 0x0000002c }, | ||
364 | { 0x00009b8c, 0x0000002d }, | ||
365 | { 0x00009b90, 0x00000030 }, | ||
366 | { 0x00009b94, 0x00000031 }, | ||
367 | { 0x00009b98, 0x00000032 }, | ||
368 | { 0x00009b9c, 0x00000033 }, | ||
369 | { 0x00009ba0, 0x00000034 }, | ||
370 | { 0x00009ba4, 0x00000035 }, | ||
371 | { 0x00009ba8, 0x00000035 }, | ||
372 | { 0x00009bac, 0x00000035 }, | ||
373 | { 0x00009bb0, 0x00000035 }, | ||
374 | { 0x00009bb4, 0x00000035 }, | ||
375 | { 0x00009bb8, 0x00000035 }, | ||
376 | { 0x00009bbc, 0x00000035 }, | ||
377 | { 0x00009bc0, 0x00000035 }, | ||
378 | { 0x00009bc4, 0x00000035 }, | ||
379 | { 0x00009bc8, 0x00000035 }, | ||
380 | { 0x00009bcc, 0x00000035 }, | ||
381 | { 0x00009bd0, 0x00000035 }, | ||
382 | { 0x00009bd4, 0x00000035 }, | ||
383 | { 0x00009bd8, 0x00000035 }, | ||
384 | { 0x00009bdc, 0x00000035 }, | ||
385 | { 0x00009be0, 0x00000035 }, | ||
386 | { 0x00009be4, 0x00000035 }, | ||
387 | { 0x00009be8, 0x00000035 }, | ||
388 | { 0x00009bec, 0x00000035 }, | ||
389 | { 0x00009bf0, 0x00000035 }, | ||
390 | { 0x00009bf4, 0x00000035 }, | ||
391 | { 0x00009bf8, 0x00000010 }, | ||
392 | { 0x00009bfc, 0x0000001a }, | ||
393 | { 0x0000a210, 0x40806333 }, | ||
394 | { 0x0000a214, 0x00106c10 }, | ||
395 | { 0x0000a218, 0x009c4060 }, | ||
396 | { 0x0000a220, 0x018830c6 }, | ||
397 | { 0x0000a224, 0x00000400 }, | ||
398 | { 0x0000a228, 0x00000bb5 }, | ||
399 | { 0x0000a22c, 0x00000011 }, | ||
400 | { 0x0000a234, 0x20202020 }, | ||
401 | { 0x0000a238, 0x20202020 }, | ||
402 | { 0x0000a23c, 0x13c889af }, | ||
403 | { 0x0000a240, 0x38490a20 }, | ||
404 | { 0x0000a244, 0x00007bb6 }, | ||
405 | { 0x0000a248, 0x0fff3ffc }, | ||
406 | { 0x0000a24c, 0x00000001 }, | ||
407 | { 0x0000a250, 0x0000a000 }, | ||
408 | { 0x0000a254, 0x00000000 }, | ||
409 | { 0x0000a258, 0x0cc75380 }, | ||
410 | { 0x0000a25c, 0x0f0f0f01 }, | ||
411 | { 0x0000a260, 0xdfa91f01 }, | ||
412 | { 0x0000a268, 0x00000000 }, | ||
413 | { 0x0000a26c, 0x0e79e5c6 }, | ||
414 | { 0x0000b26c, 0x0e79e5c6 }, | ||
415 | { 0x0000c26c, 0x0e79e5c6 }, | ||
416 | { 0x0000d270, 0x00820820 }, | ||
417 | { 0x0000a278, 0x1ce739ce }, | ||
418 | { 0x0000a27c, 0x051701ce }, | ||
419 | { 0x0000a338, 0x00000000 }, | ||
420 | { 0x0000a33c, 0x00000000 }, | ||
421 | { 0x0000a340, 0x00000000 }, | ||
422 | { 0x0000a344, 0x00000000 }, | ||
423 | { 0x0000a348, 0x3fffffff }, | ||
424 | { 0x0000a34c, 0x3fffffff }, | ||
425 | { 0x0000a350, 0x3fffffff }, | ||
426 | { 0x0000a354, 0x0003ffff }, | ||
427 | { 0x0000a358, 0x79a8aa1f }, | ||
428 | { 0x0000d35c, 0x07ffffef }, | ||
429 | { 0x0000d360, 0x0fffffe7 }, | ||
430 | { 0x0000d364, 0x17ffffe5 }, | ||
431 | { 0x0000d368, 0x1fffffe4 }, | ||
432 | { 0x0000d36c, 0x37ffffe3 }, | ||
433 | { 0x0000d370, 0x3fffffe3 }, | ||
434 | { 0x0000d374, 0x57ffffe3 }, | ||
435 | { 0x0000d378, 0x5fffffe2 }, | ||
436 | { 0x0000d37c, 0x7fffffe2 }, | ||
437 | { 0x0000d380, 0x7f3c7bba }, | ||
438 | { 0x0000d384, 0xf3307ff0 }, | ||
439 | { 0x0000a388, 0x08000000 }, | ||
440 | { 0x0000a38c, 0x20202020 }, | ||
441 | { 0x0000a390, 0x20202020 }, | ||
442 | { 0x0000a394, 0x1ce739ce }, | ||
443 | { 0x0000a398, 0x000001ce }, | ||
444 | { 0x0000a39c, 0x00000001 }, | ||
445 | { 0x0000a3a0, 0x00000000 }, | ||
446 | { 0x0000a3a4, 0x00000000 }, | ||
447 | { 0x0000a3a8, 0x00000000 }, | ||
448 | { 0x0000a3ac, 0x00000000 }, | ||
449 | { 0x0000a3b0, 0x00000000 }, | ||
450 | { 0x0000a3b4, 0x00000000 }, | ||
451 | { 0x0000a3b8, 0x00000000 }, | ||
452 | { 0x0000a3bc, 0x00000000 }, | ||
453 | { 0x0000a3c0, 0x00000000 }, | ||
454 | { 0x0000a3c4, 0x00000000 }, | ||
455 | { 0x0000a3c8, 0x00000246 }, | ||
456 | { 0x0000a3cc, 0x20202020 }, | ||
457 | { 0x0000a3d0, 0x20202020 }, | ||
458 | { 0x0000a3d4, 0x20202020 }, | ||
459 | { 0x0000a3dc, 0x1ce739ce }, | ||
460 | { 0x0000a3e0, 0x000001ce }, | ||
461 | }; | ||
462 | |||
463 | static const u32 ar5416Bank0[][2] = { | ||
464 | { 0x000098b0, 0x1e5795e5 }, | ||
465 | { 0x000098e0, 0x02008020 }, | ||
466 | }; | ||
467 | |||
468 | static const u32 ar5416BB_RfGain[][3] = { | ||
469 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
470 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
471 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
472 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
473 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
474 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
475 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
476 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
477 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
478 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
479 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
480 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
481 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
482 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
483 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
484 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
485 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
486 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
487 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
488 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
489 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
490 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
491 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
492 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
493 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
494 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
495 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
496 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
497 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
498 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
499 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
500 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
501 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
502 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
503 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
504 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
505 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
506 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
507 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
508 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
509 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
510 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
511 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
512 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
513 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
514 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
515 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
516 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
517 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
518 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
519 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
520 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
521 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
522 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
523 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
524 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
525 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
526 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
527 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
528 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
529 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
530 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
531 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
532 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
533 | }; | ||
534 | |||
535 | static const u32 ar5416Bank1[][2] = { | ||
536 | { 0x000098b0, 0x02108421 }, | ||
537 | { 0x000098ec, 0x00000008 }, | ||
538 | }; | ||
539 | |||
540 | static const u32 ar5416Bank2[][2] = { | ||
541 | { 0x000098b0, 0x0e73ff17 }, | ||
542 | { 0x000098e0, 0x00000420 }, | ||
543 | }; | ||
544 | |||
545 | static const u32 ar5416Bank3[][3] = { | ||
546 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
547 | }; | ||
548 | |||
549 | static const u32 ar5416Bank6[][3] = { | ||
550 | |||
551 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
552 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
553 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
554 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
555 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
556 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
557 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
558 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
559 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
560 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
561 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
562 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
563 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
564 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
565 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
566 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
567 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
568 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
569 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
570 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
571 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
572 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
573 | { 0x0000989c, 0x0014008f, 0x0014008f }, | ||
574 | { 0x0000989c, 0x00c40003, 0x00c40003 }, | ||
575 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
576 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
577 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
578 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
579 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
580 | { 0x0000989c, 0x000000f1, 0x000000f1 }, | ||
581 | { 0x0000989c, 0x00002081, 0x00002081 }, | ||
582 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
583 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
584 | }; | ||
585 | |||
586 | static const u32 ar5416Bank6TPC[][3] = { | ||
587 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
588 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
589 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
590 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
591 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
592 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
593 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
594 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
595 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
596 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
597 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
598 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
599 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
600 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
601 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
602 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
603 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
604 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
605 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
606 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
607 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
608 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
609 | { 0x0000989c, 0x201400df, 0x201400df }, | ||
610 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
611 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
612 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
613 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
614 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
615 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
616 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
617 | { 0x0000989c, 0x00007081, 0x00007081 }, | ||
618 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
619 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
620 | }; | ||
621 | |||
622 | static const u32 ar5416Bank7[][2] = { | ||
623 | { 0x0000989c, 0x00000500 }, | ||
624 | { 0x0000989c, 0x00000800 }, | ||
625 | { 0x000098cc, 0x0000000e }, | ||
626 | }; | ||
627 | |||
628 | static const u32 ar5416Addac[][2] = { | ||
629 | {0x0000989c, 0x00000000 }, | ||
630 | {0x0000989c, 0x00000003 }, | ||
631 | {0x0000989c, 0x00000000 }, | ||
632 | {0x0000989c, 0x0000000c }, | ||
633 | {0x0000989c, 0x00000000 }, | ||
634 | {0x0000989c, 0x00000030 }, | ||
635 | {0x0000989c, 0x00000000 }, | ||
636 | {0x0000989c, 0x00000000 }, | ||
637 | {0x0000989c, 0x00000000 }, | ||
638 | {0x0000989c, 0x00000000 }, | ||
639 | {0x0000989c, 0x00000000 }, | ||
640 | {0x0000989c, 0x00000000 }, | ||
641 | {0x0000989c, 0x00000000 }, | ||
642 | {0x0000989c, 0x00000000 }, | ||
643 | {0x0000989c, 0x00000000 }, | ||
644 | {0x0000989c, 0x00000000 }, | ||
645 | {0x0000989c, 0x00000000 }, | ||
646 | {0x0000989c, 0x00000000 }, | ||
647 | {0x0000989c, 0x00000060 }, | ||
648 | {0x0000989c, 0x00000000 }, | ||
649 | {0x0000989c, 0x00000000 }, | ||
650 | {0x0000989c, 0x00000000 }, | ||
651 | {0x0000989c, 0x00000000 }, | ||
652 | {0x0000989c, 0x00000000 }, | ||
653 | {0x0000989c, 0x00000000 }, | ||
654 | {0x0000989c, 0x00000000 }, | ||
655 | {0x0000989c, 0x00000000 }, | ||
656 | {0x0000989c, 0x00000000 }, | ||
657 | {0x0000989c, 0x00000000 }, | ||
658 | {0x0000989c, 0x00000000 }, | ||
659 | {0x0000989c, 0x00000000 }, | ||
660 | {0x0000989c, 0x00000058 }, | ||
661 | {0x0000989c, 0x00000000 }, | ||
662 | {0x0000989c, 0x00000000 }, | ||
663 | {0x0000989c, 0x00000000 }, | ||
664 | {0x0000989c, 0x00000000 }, | ||
665 | {0x000098cc, 0x00000000 }, | ||
666 | }; | ||
667 | |||
668 | static const u32 ar5416Modes_9100[][6] = { | ||
669 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
670 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
671 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
672 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
673 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
674 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
675 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
676 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
677 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
678 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
679 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
680 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
681 | { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, | ||
682 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
683 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
684 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
685 | { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 }, | ||
686 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e }, | ||
687 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e }, | ||
688 | { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, | ||
689 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
690 | { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, | ||
691 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
692 | { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 }, | ||
693 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
694 | { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d }, | ||
695 | { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 }, | ||
696 | { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 }, | ||
697 | { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e }, | ||
698 | { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff }, | ||
699 | #ifdef TB243 | ||
700 | { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
701 | { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
702 | { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
703 | { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 }, | ||
704 | #else | ||
705 | { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
706 | { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
707 | { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
708 | { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, | ||
709 | #endif | ||
710 | { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 }, | ||
711 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
712 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
713 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
714 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
715 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
716 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
717 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
718 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
719 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
720 | { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
721 | { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
722 | { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
723 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
724 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
725 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
726 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
727 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
728 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
729 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
730 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
731 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
732 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
733 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
734 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
735 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
736 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
737 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
738 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
739 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
740 | }; | ||
741 | |||
742 | #endif /* INITVALS_AR5008_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c new file mode 100644 index 000000000000..b2c17c98bb38 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c | |||
@@ -0,0 +1,1374 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | #include "hw-ops.h" | ||
19 | #include "../regd.h" | ||
20 | #include "ar9002_phy.h" | ||
21 | |||
22 | /* All code below is for non single-chip solutions */ | ||
23 | |||
24 | /** | ||
25 | * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters | ||
26 | * @rfbuf: | ||
27 | * @reg32: | ||
28 | * @numBits: | ||
29 | * @firstBit: | ||
30 | * @column: | ||
31 | * | ||
32 | * Performs analog "swizzling" of parameters into their location. | ||
33 | * Used on external AR2133/AR5133 radios. | ||
34 | */ | ||
35 | static void ar5008_hw_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32, | ||
36 | u32 numBits, u32 firstBit, | ||
37 | u32 column) | ||
38 | { | ||
39 | u32 tmp32, mask, arrayEntry, lastBit; | ||
40 | int32_t bitPosition, bitsLeft; | ||
41 | |||
42 | tmp32 = ath9k_hw_reverse_bits(reg32, numBits); | ||
43 | arrayEntry = (firstBit - 1) / 8; | ||
44 | bitPosition = (firstBit - 1) % 8; | ||
45 | bitsLeft = numBits; | ||
46 | while (bitsLeft > 0) { | ||
47 | lastBit = (bitPosition + bitsLeft > 8) ? | ||
48 | 8 : bitPosition + bitsLeft; | ||
49 | mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << | ||
50 | (column * 8); | ||
51 | rfBuf[arrayEntry] &= ~mask; | ||
52 | rfBuf[arrayEntry] |= ((tmp32 << bitPosition) << | ||
53 | (column * 8)) & mask; | ||
54 | bitsLeft -= 8 - bitPosition; | ||
55 | tmp32 = tmp32 >> (8 - bitPosition); | ||
56 | bitPosition = 0; | ||
57 | arrayEntry++; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * Fix on 2.4 GHz band for orientation sensitivity issue by increasing | ||
63 | * rf_pwd_icsyndiv. | ||
64 | * | ||
65 | * Theoretical Rules: | ||
66 | * if 2 GHz band | ||
67 | * if forceBiasAuto | ||
68 | * if synth_freq < 2412 | ||
69 | * bias = 0 | ||
70 | * else if 2412 <= synth_freq <= 2422 | ||
71 | * bias = 1 | ||
72 | * else // synth_freq > 2422 | ||
73 | * bias = 2 | ||
74 | * else if forceBias > 0 | ||
75 | * bias = forceBias & 7 | ||
76 | * else | ||
77 | * no change, use value from ini file | ||
78 | * else | ||
79 | * no change, invalid band | ||
80 | * | ||
81 | * 1st Mod: | ||
82 | * 2422 also uses value of 2 | ||
83 | * <approved> | ||
84 | * | ||
85 | * 2nd Mod: | ||
86 | * Less than 2412 uses value of 0, 2412 and above uses value of 2 | ||
87 | */ | ||
88 | static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq) | ||
89 | { | ||
90 | struct ath_common *common = ath9k_hw_common(ah); | ||
91 | u32 tmp_reg; | ||
92 | int reg_writes = 0; | ||
93 | u32 new_bias = 0; | ||
94 | |||
95 | if (!AR_SREV_5416(ah) || synth_freq >= 3000) | ||
96 | return; | ||
97 | |||
98 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
99 | |||
100 | if (synth_freq < 2412) | ||
101 | new_bias = 0; | ||
102 | else if (synth_freq < 2422) | ||
103 | new_bias = 1; | ||
104 | else | ||
105 | new_bias = 2; | ||
106 | |||
107 | /* pre-reverse this field */ | ||
108 | tmp_reg = ath9k_hw_reverse_bits(new_bias, 3); | ||
109 | |||
110 | ath_print(common, ATH_DBG_CONFIG, | ||
111 | "Force rf_pwd_icsyndiv to %1d on %4d\n", | ||
112 | new_bias, synth_freq); | ||
113 | |||
114 | /* swizzle rf_pwd_icsyndiv */ | ||
115 | ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); | ||
116 | |||
117 | /* write Bank 6 with new params */ | ||
118 | REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes); | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios | ||
123 | * @ah: atheros hardware stucture | ||
124 | * @chan: | ||
125 | * | ||
126 | * For the external AR2133/AR5133 radios, takes the MHz channel value and set | ||
127 | * the channel value. Assumes writes enabled to analog bus and bank6 register | ||
128 | * cache in ah->analogBank6Data. | ||
129 | */ | ||
130 | static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
131 | { | ||
132 | struct ath_common *common = ath9k_hw_common(ah); | ||
133 | u32 channelSel = 0; | ||
134 | u32 bModeSynth = 0; | ||
135 | u32 aModeRefSel = 0; | ||
136 | u32 reg32 = 0; | ||
137 | u16 freq; | ||
138 | struct chan_centers centers; | ||
139 | |||
140 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
141 | freq = centers.synth_center; | ||
142 | |||
143 | if (freq < 4800) { | ||
144 | u32 txctl; | ||
145 | |||
146 | if (((freq - 2192) % 5) == 0) { | ||
147 | channelSel = ((freq - 672) * 2 - 3040) / 10; | ||
148 | bModeSynth = 0; | ||
149 | } else if (((freq - 2224) % 5) == 0) { | ||
150 | channelSel = ((freq - 704) * 2 - 3040) / 10; | ||
151 | bModeSynth = 1; | ||
152 | } else { | ||
153 | ath_print(common, ATH_DBG_FATAL, | ||
154 | "Invalid channel %u MHz\n", freq); | ||
155 | return -EINVAL; | ||
156 | } | ||
157 | |||
158 | channelSel = (channelSel << 2) & 0xff; | ||
159 | channelSel = ath9k_hw_reverse_bits(channelSel, 8); | ||
160 | |||
161 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
162 | if (freq == 2484) { | ||
163 | |||
164 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
165 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
166 | } else { | ||
167 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
168 | txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); | ||
169 | } | ||
170 | |||
171 | } else if ((freq % 20) == 0 && freq >= 5120) { | ||
172 | channelSel = | ||
173 | ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8); | ||
174 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
175 | } else if ((freq % 10) == 0) { | ||
176 | channelSel = | ||
177 | ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8); | ||
178 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) | ||
179 | aModeRefSel = ath9k_hw_reverse_bits(2, 2); | ||
180 | else | ||
181 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
182 | } else if ((freq % 5) == 0) { | ||
183 | channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8); | ||
184 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
185 | } else { | ||
186 | ath_print(common, ATH_DBG_FATAL, | ||
187 | "Invalid channel %u MHz\n", freq); | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | |||
191 | ar5008_hw_force_bias(ah, freq); | ||
192 | |||
193 | reg32 = | ||
194 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | | ||
195 | (1 << 5) | 0x1; | ||
196 | |||
197 | REG_WRITE(ah, AR_PHY(0x37), reg32); | ||
198 | |||
199 | ah->curchan = chan; | ||
200 | ah->curchan_rad_index = -1; | ||
201 | |||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | /** | ||
206 | * ar5008_hw_spur_mitigate - convert baseband spur frequency for external radios | ||
207 | * @ah: atheros hardware structure | ||
208 | * @chan: | ||
209 | * | ||
210 | * For non single-chip solutions. Converts to baseband spur frequency given the | ||
211 | * input channel frequency and compute register settings below. | ||
212 | */ | ||
213 | static void ar5008_hw_spur_mitigate(struct ath_hw *ah, | ||
214 | struct ath9k_channel *chan) | ||
215 | { | ||
216 | int bb_spur = AR_NO_SPUR; | ||
217 | int bin, cur_bin; | ||
218 | int spur_freq_sd; | ||
219 | int spur_delta_phase; | ||
220 | int denominator; | ||
221 | int upper, lower, cur_vit_mask; | ||
222 | int tmp, new; | ||
223 | int i; | ||
224 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
225 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
226 | }; | ||
227 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
228 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
229 | }; | ||
230 | int inc[4] = { 0, 100, 0, 0 }; | ||
231 | |||
232 | int8_t mask_m[123]; | ||
233 | int8_t mask_p[123]; | ||
234 | int8_t mask_amt; | ||
235 | int tmp_mask; | ||
236 | int cur_bb_spur; | ||
237 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
238 | |||
239 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
240 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
241 | |||
242 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
243 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
244 | if (AR_NO_SPUR == cur_bb_spur) | ||
245 | break; | ||
246 | cur_bb_spur = cur_bb_spur - (chan->channel * 10); | ||
247 | if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { | ||
248 | bb_spur = cur_bb_spur; | ||
249 | break; | ||
250 | } | ||
251 | } | ||
252 | |||
253 | if (AR_NO_SPUR == bb_spur) | ||
254 | return; | ||
255 | |||
256 | bin = bb_spur * 32; | ||
257 | |||
258 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
259 | new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
260 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
261 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
262 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
263 | |||
264 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new); | ||
265 | |||
266 | new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
267 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
268 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
269 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
270 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
271 | REG_WRITE(ah, AR_PHY_SPUR_REG, new); | ||
272 | |||
273 | spur_delta_phase = ((bb_spur * 524288) / 100) & | ||
274 | AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
275 | |||
276 | denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; | ||
277 | spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; | ||
278 | |||
279 | new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
280 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
281 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
282 | REG_WRITE(ah, AR_PHY_TIMING11, new); | ||
283 | |||
284 | cur_bin = -6000; | ||
285 | upper = bin + 100; | ||
286 | lower = bin - 100; | ||
287 | |||
288 | for (i = 0; i < 4; i++) { | ||
289 | int pilot_mask = 0; | ||
290 | int chan_mask = 0; | ||
291 | int bp = 0; | ||
292 | for (bp = 0; bp < 30; bp++) { | ||
293 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
294 | pilot_mask = pilot_mask | 0x1 << bp; | ||
295 | chan_mask = chan_mask | 0x1 << bp; | ||
296 | } | ||
297 | cur_bin += 100; | ||
298 | } | ||
299 | cur_bin += inc[i]; | ||
300 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
301 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
302 | } | ||
303 | |||
304 | cur_vit_mask = 6100; | ||
305 | upper = bin + 120; | ||
306 | lower = bin - 120; | ||
307 | |||
308 | for (i = 0; i < 123; i++) { | ||
309 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
310 | |||
311 | /* workaround for gcc bug #37014 */ | ||
312 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
313 | |||
314 | if (tmp_v < 75) | ||
315 | mask_amt = 1; | ||
316 | else | ||
317 | mask_amt = 0; | ||
318 | if (cur_vit_mask < 0) | ||
319 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
320 | else | ||
321 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
322 | } | ||
323 | cur_vit_mask -= 100; | ||
324 | } | ||
325 | |||
326 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
327 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
328 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
329 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
330 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
331 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
332 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
333 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
334 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
335 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
336 | |||
337 | tmp_mask = (mask_m[31] << 28) | ||
338 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
339 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
340 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
341 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
342 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
343 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
344 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
345 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
346 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
347 | |||
348 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
349 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
350 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
351 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
352 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
353 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
354 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
355 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
356 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
357 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
358 | |||
359 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
360 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
361 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
362 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
363 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
364 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
365 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
366 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
367 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
368 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
369 | |||
370 | tmp_mask = (mask_p[15] << 28) | ||
371 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
372 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
373 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
374 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
375 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
376 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
377 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
378 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
379 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
380 | |||
381 | tmp_mask = (mask_p[30] << 28) | ||
382 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
383 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
384 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
385 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
386 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
387 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
388 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
389 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
390 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
391 | |||
392 | tmp_mask = (mask_p[45] << 28) | ||
393 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
394 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
395 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
396 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
397 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
398 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
399 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
400 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
401 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
402 | |||
403 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
404 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
405 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
406 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
407 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
408 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
409 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
410 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
411 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
412 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
413 | } | ||
414 | |||
415 | /** | ||
416 | * ar5008_hw_rf_alloc_ext_banks - allocates banks for external radio programming | ||
417 | * @ah: atheros hardware structure | ||
418 | * | ||
419 | * Only required for older devices with external AR2133/AR5133 radios. | ||
420 | */ | ||
421 | static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah) | ||
422 | { | ||
423 | #define ATH_ALLOC_BANK(bank, size) do { \ | ||
424 | bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \ | ||
425 | if (!bank) { \ | ||
426 | ath_print(common, ATH_DBG_FATAL, \ | ||
427 | "Cannot allocate RF banks\n"); \ | ||
428 | return -ENOMEM; \ | ||
429 | } \ | ||
430 | } while (0); | ||
431 | |||
432 | struct ath_common *common = ath9k_hw_common(ah); | ||
433 | |||
434 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
435 | |||
436 | ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); | ||
437 | ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); | ||
438 | ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows); | ||
439 | ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows); | ||
440 | ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); | ||
441 | ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); | ||
442 | ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); | ||
443 | ATH_ALLOC_BANK(ah->addac5416_21, | ||
444 | ah->iniAddac.ia_rows * ah->iniAddac.ia_columns); | ||
445 | ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); | ||
446 | |||
447 | return 0; | ||
448 | #undef ATH_ALLOC_BANK | ||
449 | } | ||
450 | |||
451 | |||
452 | /** | ||
453 | * ar5008_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers | ||
454 | * @ah: atheros hardware struture | ||
455 | * For the external AR2133/AR5133 radios banks. | ||
456 | */ | ||
457 | static void ar5008_hw_rf_free_ext_banks(struct ath_hw *ah) | ||
458 | { | ||
459 | #define ATH_FREE_BANK(bank) do { \ | ||
460 | kfree(bank); \ | ||
461 | bank = NULL; \ | ||
462 | } while (0); | ||
463 | |||
464 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
465 | |||
466 | ATH_FREE_BANK(ah->analogBank0Data); | ||
467 | ATH_FREE_BANK(ah->analogBank1Data); | ||
468 | ATH_FREE_BANK(ah->analogBank2Data); | ||
469 | ATH_FREE_BANK(ah->analogBank3Data); | ||
470 | ATH_FREE_BANK(ah->analogBank6Data); | ||
471 | ATH_FREE_BANK(ah->analogBank6TPCData); | ||
472 | ATH_FREE_BANK(ah->analogBank7Data); | ||
473 | ATH_FREE_BANK(ah->addac5416_21); | ||
474 | ATH_FREE_BANK(ah->bank6Temp); | ||
475 | |||
476 | #undef ATH_FREE_BANK | ||
477 | } | ||
478 | |||
479 | /* * | ||
480 | * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM | ||
481 | * @ah: atheros hardware structure | ||
482 | * @chan: | ||
483 | * @modesIndex: | ||
484 | * | ||
485 | * Used for the external AR2133/AR5133 radios. | ||
486 | * | ||
487 | * Reads the EEPROM header info from the device structure and programs | ||
488 | * all rf registers. This routine requires access to the analog | ||
489 | * rf device. This is not required for single-chip devices. | ||
490 | */ | ||
491 | static bool ar5008_hw_set_rf_regs(struct ath_hw *ah, | ||
492 | struct ath9k_channel *chan, | ||
493 | u16 modesIndex) | ||
494 | { | ||
495 | u32 eepMinorRev; | ||
496 | u32 ob5GHz = 0, db5GHz = 0; | ||
497 | u32 ob2GHz = 0, db2GHz = 0; | ||
498 | int regWrites = 0; | ||
499 | |||
500 | /* | ||
501 | * Software does not need to program bank data | ||
502 | * for single chip devices, that is AR9280 or anything | ||
503 | * after that. | ||
504 | */ | ||
505 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
506 | return true; | ||
507 | |||
508 | /* Setup rf parameters */ | ||
509 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); | ||
510 | |||
511 | /* Setup Bank 0 Write */ | ||
512 | RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); | ||
513 | |||
514 | /* Setup Bank 1 Write */ | ||
515 | RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); | ||
516 | |||
517 | /* Setup Bank 2 Write */ | ||
518 | RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); | ||
519 | |||
520 | /* Setup Bank 6 Write */ | ||
521 | RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, | ||
522 | modesIndex); | ||
523 | { | ||
524 | int i; | ||
525 | for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) { | ||
526 | ah->analogBank6Data[i] = | ||
527 | INI_RA(&ah->iniBank6TPC, i, modesIndex); | ||
528 | } | ||
529 | } | ||
530 | |||
531 | /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ | ||
532 | if (eepMinorRev >= 2) { | ||
533 | if (IS_CHAN_2GHZ(chan)) { | ||
534 | ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2); | ||
535 | db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2); | ||
536 | ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, | ||
537 | ob2GHz, 3, 197, 0); | ||
538 | ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, | ||
539 | db2GHz, 3, 194, 0); | ||
540 | } else { | ||
541 | ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5); | ||
542 | db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5); | ||
543 | ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, | ||
544 | ob5GHz, 3, 203, 0); | ||
545 | ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, | ||
546 | db5GHz, 3, 200, 0); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | /* Setup Bank 7 Setup */ | ||
551 | RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); | ||
552 | |||
553 | /* Write Analog registers */ | ||
554 | REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, | ||
555 | regWrites); | ||
556 | REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, | ||
557 | regWrites); | ||
558 | REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, | ||
559 | regWrites); | ||
560 | REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data, | ||
561 | regWrites); | ||
562 | REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data, | ||
563 | regWrites); | ||
564 | REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data, | ||
565 | regWrites); | ||
566 | |||
567 | return true; | ||
568 | } | ||
569 | |||
570 | static void ar5008_hw_init_bb(struct ath_hw *ah, | ||
571 | struct ath9k_channel *chan) | ||
572 | { | ||
573 | u32 synthDelay; | ||
574 | |||
575 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | ||
576 | if (IS_CHAN_B(chan)) | ||
577 | synthDelay = (4 * synthDelay) / 22; | ||
578 | else | ||
579 | synthDelay /= 10; | ||
580 | |||
581 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
582 | |||
583 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
584 | } | ||
585 | |||
586 | static void ar5008_hw_init_chain_masks(struct ath_hw *ah) | ||
587 | { | ||
588 | int rx_chainmask, tx_chainmask; | ||
589 | |||
590 | rx_chainmask = ah->rxchainmask; | ||
591 | tx_chainmask = ah->txchainmask; | ||
592 | |||
593 | ENABLE_REGWRITE_BUFFER(ah); | ||
594 | |||
595 | switch (rx_chainmask) { | ||
596 | case 0x5: | ||
597 | DISABLE_REGWRITE_BUFFER(ah); | ||
598 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
599 | AR_PHY_SWAP_ALT_CHAIN); | ||
600 | ENABLE_REGWRITE_BUFFER(ah); | ||
601 | case 0x3: | ||
602 | if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { | ||
603 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); | ||
604 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); | ||
605 | break; | ||
606 | } | ||
607 | case 0x1: | ||
608 | case 0x2: | ||
609 | case 0x7: | ||
610 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); | ||
611 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); | ||
612 | break; | ||
613 | default: | ||
614 | break; | ||
615 | } | ||
616 | |||
617 | REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); | ||
618 | |||
619 | REGWRITE_BUFFER_FLUSH(ah); | ||
620 | DISABLE_REGWRITE_BUFFER(ah); | ||
621 | |||
622 | if (tx_chainmask == 0x5) { | ||
623 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
624 | AR_PHY_SWAP_ALT_CHAIN); | ||
625 | } | ||
626 | if (AR_SREV_9100(ah)) | ||
627 | REG_WRITE(ah, AR_PHY_ANALOG_SWAP, | ||
628 | REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); | ||
629 | } | ||
630 | |||
631 | static void ar5008_hw_override_ini(struct ath_hw *ah, | ||
632 | struct ath9k_channel *chan) | ||
633 | { | ||
634 | u32 val; | ||
635 | |||
636 | /* | ||
637 | * Set the RX_ABORT and RX_DIS and clear if off only after | ||
638 | * RXE is set for MAC. This prevents frames with corrupted | ||
639 | * descriptor status. | ||
640 | */ | ||
641 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
642 | |||
643 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
644 | val = REG_READ(ah, AR_PCU_MISC_MODE2); | ||
645 | |||
646 | if (!AR_SREV_9271(ah)) | ||
647 | val &= ~AR_PCU_MISC_MODE2_HWWAR1; | ||
648 | |||
649 | if (AR_SREV_9287_10_OR_LATER(ah)) | ||
650 | val = val & (~AR_PCU_MISC_MODE2_HWWAR2); | ||
651 | |||
652 | REG_WRITE(ah, AR_PCU_MISC_MODE2, val); | ||
653 | } | ||
654 | |||
655 | if (!AR_SREV_5416_20_OR_LATER(ah) || | ||
656 | AR_SREV_9280_10_OR_LATER(ah)) | ||
657 | return; | ||
658 | /* | ||
659 | * Disable BB clock gating | ||
660 | * Necessary to avoid issues on AR5416 2.0 | ||
661 | */ | ||
662 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | ||
663 | |||
664 | /* | ||
665 | * Disable RIFS search on some chips to avoid baseband | ||
666 | * hang issues. | ||
667 | */ | ||
668 | if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { | ||
669 | val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); | ||
670 | val &= ~AR_PHY_RIFS_INIT_DELAY; | ||
671 | REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); | ||
672 | } | ||
673 | } | ||
674 | |||
675 | static void ar5008_hw_set_channel_regs(struct ath_hw *ah, | ||
676 | struct ath9k_channel *chan) | ||
677 | { | ||
678 | u32 phymode; | ||
679 | u32 enableDacFifo = 0; | ||
680 | |||
681 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
682 | enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & | ||
683 | AR_PHY_FC_ENABLE_DAC_FIFO); | ||
684 | |||
685 | phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 | ||
686 | | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; | ||
687 | |||
688 | if (IS_CHAN_HT40(chan)) { | ||
689 | phymode |= AR_PHY_FC_DYN2040_EN; | ||
690 | |||
691 | if ((chan->chanmode == CHANNEL_A_HT40PLUS) || | ||
692 | (chan->chanmode == CHANNEL_G_HT40PLUS)) | ||
693 | phymode |= AR_PHY_FC_DYN2040_PRI_CH; | ||
694 | |||
695 | } | ||
696 | REG_WRITE(ah, AR_PHY_TURBO, phymode); | ||
697 | |||
698 | ath9k_hw_set11nmac2040(ah); | ||
699 | |||
700 | ENABLE_REGWRITE_BUFFER(ah); | ||
701 | |||
702 | REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); | ||
703 | REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); | ||
704 | |||
705 | REGWRITE_BUFFER_FLUSH(ah); | ||
706 | DISABLE_REGWRITE_BUFFER(ah); | ||
707 | } | ||
708 | |||
709 | |||
710 | static int ar5008_hw_process_ini(struct ath_hw *ah, | ||
711 | struct ath9k_channel *chan) | ||
712 | { | ||
713 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | ||
714 | int i, regWrites = 0; | ||
715 | struct ieee80211_channel *channel = chan->chan; | ||
716 | u32 modesIndex, freqIndex; | ||
717 | |||
718 | switch (chan->chanmode) { | ||
719 | case CHANNEL_A: | ||
720 | case CHANNEL_A_HT20: | ||
721 | modesIndex = 1; | ||
722 | freqIndex = 1; | ||
723 | break; | ||
724 | case CHANNEL_A_HT40PLUS: | ||
725 | case CHANNEL_A_HT40MINUS: | ||
726 | modesIndex = 2; | ||
727 | freqIndex = 1; | ||
728 | break; | ||
729 | case CHANNEL_G: | ||
730 | case CHANNEL_G_HT20: | ||
731 | case CHANNEL_B: | ||
732 | modesIndex = 4; | ||
733 | freqIndex = 2; | ||
734 | break; | ||
735 | case CHANNEL_G_HT40PLUS: | ||
736 | case CHANNEL_G_HT40MINUS: | ||
737 | modesIndex = 3; | ||
738 | freqIndex = 2; | ||
739 | break; | ||
740 | |||
741 | default: | ||
742 | return -EINVAL; | ||
743 | } | ||
744 | |||
745 | if (AR_SREV_9287_12_OR_LATER(ah)) { | ||
746 | /* Enable ASYNC FIFO */ | ||
747 | REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, | ||
748 | AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL); | ||
749 | REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO); | ||
750 | REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, | ||
751 | AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); | ||
752 | REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, | ||
753 | AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); | ||
754 | } | ||
755 | |||
756 | /* | ||
757 | * Set correct baseband to analog shift setting to | ||
758 | * access analog chips. | ||
759 | */ | ||
760 | REG_WRITE(ah, AR_PHY(0), 0x00000007); | ||
761 | |||
762 | /* Write ADDAC shifts */ | ||
763 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); | ||
764 | ah->eep_ops->set_addac(ah, chan); | ||
765 | |||
766 | if (AR_SREV_5416_22_OR_LATER(ah)) { | ||
767 | REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); | ||
768 | } else { | ||
769 | struct ar5416IniArray temp; | ||
770 | u32 addacSize = | ||
771 | sizeof(u32) * ah->iniAddac.ia_rows * | ||
772 | ah->iniAddac.ia_columns; | ||
773 | |||
774 | /* For AR5416 2.0/2.1 */ | ||
775 | memcpy(ah->addac5416_21, | ||
776 | ah->iniAddac.ia_array, addacSize); | ||
777 | |||
778 | /* override CLKDRV value at [row, column] = [31, 1] */ | ||
779 | (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; | ||
780 | |||
781 | temp.ia_array = ah->addac5416_21; | ||
782 | temp.ia_columns = ah->iniAddac.ia_columns; | ||
783 | temp.ia_rows = ah->iniAddac.ia_rows; | ||
784 | REG_WRITE_ARRAY(&temp, 1, regWrites); | ||
785 | } | ||
786 | |||
787 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); | ||
788 | |||
789 | ENABLE_REGWRITE_BUFFER(ah); | ||
790 | |||
791 | for (i = 0; i < ah->iniModes.ia_rows; i++) { | ||
792 | u32 reg = INI_RA(&ah->iniModes, i, 0); | ||
793 | u32 val = INI_RA(&ah->iniModes, i, modesIndex); | ||
794 | |||
795 | if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup) | ||
796 | val &= ~AR_AN_TOP2_PWDCLKIND; | ||
797 | |||
798 | REG_WRITE(ah, reg, val); | ||
799 | |||
800 | if (reg >= 0x7800 && reg < 0x78a0 | ||
801 | && ah->config.analog_shiftreg) { | ||
802 | udelay(100); | ||
803 | } | ||
804 | |||
805 | DO_DELAY(regWrites); | ||
806 | } | ||
807 | |||
808 | REGWRITE_BUFFER_FLUSH(ah); | ||
809 | DISABLE_REGWRITE_BUFFER(ah); | ||
810 | |||
811 | if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah)) | ||
812 | REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); | ||
813 | |||
814 | if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) || | ||
815 | AR_SREV_9287_10_OR_LATER(ah)) | ||
816 | REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); | ||
817 | |||
818 | if (AR_SREV_9271_10(ah)) | ||
819 | REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, | ||
820 | modesIndex, regWrites); | ||
821 | |||
822 | ENABLE_REGWRITE_BUFFER(ah); | ||
823 | |||
824 | /* Write common array parameters */ | ||
825 | for (i = 0; i < ah->iniCommon.ia_rows; i++) { | ||
826 | u32 reg = INI_RA(&ah->iniCommon, i, 0); | ||
827 | u32 val = INI_RA(&ah->iniCommon, i, 1); | ||
828 | |||
829 | REG_WRITE(ah, reg, val); | ||
830 | |||
831 | if (reg >= 0x7800 && reg < 0x78a0 | ||
832 | && ah->config.analog_shiftreg) { | ||
833 | udelay(100); | ||
834 | } | ||
835 | |||
836 | DO_DELAY(regWrites); | ||
837 | } | ||
838 | |||
839 | REGWRITE_BUFFER_FLUSH(ah); | ||
840 | DISABLE_REGWRITE_BUFFER(ah); | ||
841 | |||
842 | if (AR_SREV_9271(ah)) { | ||
843 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == 1) | ||
844 | REG_WRITE_ARRAY(&ah->iniModes_high_power_tx_gain_9271, | ||
845 | modesIndex, regWrites); | ||
846 | else | ||
847 | REG_WRITE_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, | ||
848 | modesIndex, regWrites); | ||
849 | } | ||
850 | |||
851 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); | ||
852 | |||
853 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) { | ||
854 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, | ||
855 | regWrites); | ||
856 | } | ||
857 | |||
858 | ar5008_hw_override_ini(ah, chan); | ||
859 | ar5008_hw_set_channel_regs(ah, chan); | ||
860 | ar5008_hw_init_chain_masks(ah); | ||
861 | ath9k_olc_init(ah); | ||
862 | |||
863 | /* Set TX power */ | ||
864 | ah->eep_ops->set_txpower(ah, chan, | ||
865 | ath9k_regd_get_ctl(regulatory, chan), | ||
866 | channel->max_antenna_gain * 2, | ||
867 | channel->max_power * 2, | ||
868 | min((u32) MAX_RATE_POWER, | ||
869 | (u32) regulatory->power_limit)); | ||
870 | |||
871 | /* Write analog registers */ | ||
872 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { | ||
873 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
874 | "ar5416SetRfRegs failed\n"); | ||
875 | return -EIO; | ||
876 | } | ||
877 | |||
878 | return 0; | ||
879 | } | ||
880 | |||
881 | static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) | ||
882 | { | ||
883 | u32 rfMode = 0; | ||
884 | |||
885 | if (chan == NULL) | ||
886 | return; | ||
887 | |||
888 | rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) | ||
889 | ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; | ||
890 | |||
891 | if (!AR_SREV_9280_10_OR_LATER(ah)) | ||
892 | rfMode |= (IS_CHAN_5GHZ(chan)) ? | ||
893 | AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; | ||
894 | |||
895 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | ||
896 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | ||
897 | |||
898 | REG_WRITE(ah, AR_PHY_MODE, rfMode); | ||
899 | } | ||
900 | |||
901 | static void ar5008_hw_mark_phy_inactive(struct ath_hw *ah) | ||
902 | { | ||
903 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||
904 | } | ||
905 | |||
906 | static void ar5008_hw_set_delta_slope(struct ath_hw *ah, | ||
907 | struct ath9k_channel *chan) | ||
908 | { | ||
909 | u32 coef_scaled, ds_coef_exp, ds_coef_man; | ||
910 | u32 clockMhzScaled = 0x64000000; | ||
911 | struct chan_centers centers; | ||
912 | |||
913 | if (IS_CHAN_HALF_RATE(chan)) | ||
914 | clockMhzScaled = clockMhzScaled >> 1; | ||
915 | else if (IS_CHAN_QUARTER_RATE(chan)) | ||
916 | clockMhzScaled = clockMhzScaled >> 2; | ||
917 | |||
918 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
919 | coef_scaled = clockMhzScaled / centers.synth_center; | ||
920 | |||
921 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
922 | &ds_coef_exp); | ||
923 | |||
924 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
925 | AR_PHY_TIMING3_DSC_MAN, ds_coef_man); | ||
926 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
927 | AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); | ||
928 | |||
929 | coef_scaled = (9 * coef_scaled) / 10; | ||
930 | |||
931 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
932 | &ds_coef_exp); | ||
933 | |||
934 | REG_RMW_FIELD(ah, AR_PHY_HALFGI, | ||
935 | AR_PHY_HALFGI_DSC_MAN, ds_coef_man); | ||
936 | REG_RMW_FIELD(ah, AR_PHY_HALFGI, | ||
937 | AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); | ||
938 | } | ||
939 | |||
940 | static bool ar5008_hw_rfbus_req(struct ath_hw *ah) | ||
941 | { | ||
942 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); | ||
943 | return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, | ||
944 | AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT); | ||
945 | } | ||
946 | |||
947 | static void ar5008_hw_rfbus_done(struct ath_hw *ah) | ||
948 | { | ||
949 | u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | ||
950 | if (IS_CHAN_B(ah->curchan)) | ||
951 | synthDelay = (4 * synthDelay) / 22; | ||
952 | else | ||
953 | synthDelay /= 10; | ||
954 | |||
955 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
956 | |||
957 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); | ||
958 | } | ||
959 | |||
960 | static void ar5008_hw_enable_rfkill(struct ath_hw *ah) | ||
961 | { | ||
962 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
963 | AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); | ||
964 | |||
965 | REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, | ||
966 | AR_GPIO_INPUT_MUX2_RFSILENT); | ||
967 | |||
968 | ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); | ||
969 | REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); | ||
970 | } | ||
971 | |||
972 | static void ar5008_restore_chainmask(struct ath_hw *ah) | ||
973 | { | ||
974 | int rx_chainmask = ah->rxchainmask; | ||
975 | |||
976 | if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { | ||
977 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); | ||
978 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); | ||
979 | } | ||
980 | } | ||
981 | |||
982 | static void ar5008_set_diversity(struct ath_hw *ah, bool value) | ||
983 | { | ||
984 | u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); | ||
985 | if (value) | ||
986 | v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
987 | else | ||
988 | v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
989 | REG_WRITE(ah, AR_PHY_CCK_DETECT, v); | ||
990 | } | ||
991 | |||
992 | static u32 ar9100_hw_compute_pll_control(struct ath_hw *ah, | ||
993 | struct ath9k_channel *chan) | ||
994 | { | ||
995 | if (chan && IS_CHAN_5GHZ(chan)) | ||
996 | return 0x1450; | ||
997 | return 0x1458; | ||
998 | } | ||
999 | |||
1000 | static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah, | ||
1001 | struct ath9k_channel *chan) | ||
1002 | { | ||
1003 | u32 pll; | ||
1004 | |||
1005 | pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); | ||
1006 | |||
1007 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
1008 | pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); | ||
1009 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
1010 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); | ||
1011 | |||
1012 | if (chan && IS_CHAN_5GHZ(chan)) | ||
1013 | pll |= SM(0x50, AR_RTC_9160_PLL_DIV); | ||
1014 | else | ||
1015 | pll |= SM(0x58, AR_RTC_9160_PLL_DIV); | ||
1016 | |||
1017 | return pll; | ||
1018 | } | ||
1019 | |||
1020 | static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah, | ||
1021 | struct ath9k_channel *chan) | ||
1022 | { | ||
1023 | u32 pll; | ||
1024 | |||
1025 | pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; | ||
1026 | |||
1027 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
1028 | pll |= SM(0x1, AR_RTC_PLL_CLKSEL); | ||
1029 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
1030 | pll |= SM(0x2, AR_RTC_PLL_CLKSEL); | ||
1031 | |||
1032 | if (chan && IS_CHAN_5GHZ(chan)) | ||
1033 | pll |= SM(0xa, AR_RTC_PLL_DIV); | ||
1034 | else | ||
1035 | pll |= SM(0xb, AR_RTC_PLL_DIV); | ||
1036 | |||
1037 | return pll; | ||
1038 | } | ||
1039 | |||
1040 | static bool ar5008_hw_ani_control(struct ath_hw *ah, | ||
1041 | enum ath9k_ani_cmd cmd, int param) | ||
1042 | { | ||
1043 | struct ar5416AniState *aniState = ah->curani; | ||
1044 | struct ath_common *common = ath9k_hw_common(ah); | ||
1045 | |||
1046 | switch (cmd & ah->ani_function) { | ||
1047 | case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ | ||
1048 | u32 level = param; | ||
1049 | |||
1050 | if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { | ||
1051 | ath_print(common, ATH_DBG_ANI, | ||
1052 | "level out of range (%u > %u)\n", | ||
1053 | level, | ||
1054 | (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); | ||
1055 | return false; | ||
1056 | } | ||
1057 | |||
1058 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, | ||
1059 | AR_PHY_DESIRED_SZ_TOT_DES, | ||
1060 | ah->totalSizeDesired[level]); | ||
1061 | REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, | ||
1062 | AR_PHY_AGC_CTL1_COARSE_LOW, | ||
1063 | ah->coarse_low[level]); | ||
1064 | REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1, | ||
1065 | AR_PHY_AGC_CTL1_COARSE_HIGH, | ||
1066 | ah->coarse_high[level]); | ||
1067 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
1068 | AR_PHY_FIND_SIG_FIRPWR, | ||
1069 | ah->firpwr[level]); | ||
1070 | |||
1071 | if (level > aniState->noiseImmunityLevel) | ||
1072 | ah->stats.ast_ani_niup++; | ||
1073 | else if (level < aniState->noiseImmunityLevel) | ||
1074 | ah->stats.ast_ani_nidown++; | ||
1075 | aniState->noiseImmunityLevel = level; | ||
1076 | break; | ||
1077 | } | ||
1078 | case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ | ||
1079 | const int m1ThreshLow[] = { 127, 50 }; | ||
1080 | const int m2ThreshLow[] = { 127, 40 }; | ||
1081 | const int m1Thresh[] = { 127, 0x4d }; | ||
1082 | const int m2Thresh[] = { 127, 0x40 }; | ||
1083 | const int m2CountThr[] = { 31, 16 }; | ||
1084 | const int m2CountThrLow[] = { 63, 48 }; | ||
1085 | u32 on = param ? 1 : 0; | ||
1086 | |||
1087 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
1088 | AR_PHY_SFCORR_LOW_M1_THRESH_LOW, | ||
1089 | m1ThreshLow[on]); | ||
1090 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
1091 | AR_PHY_SFCORR_LOW_M2_THRESH_LOW, | ||
1092 | m2ThreshLow[on]); | ||
1093 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
1094 | AR_PHY_SFCORR_M1_THRESH, | ||
1095 | m1Thresh[on]); | ||
1096 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
1097 | AR_PHY_SFCORR_M2_THRESH, | ||
1098 | m2Thresh[on]); | ||
1099 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
1100 | AR_PHY_SFCORR_M2COUNT_THR, | ||
1101 | m2CountThr[on]); | ||
1102 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
1103 | AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, | ||
1104 | m2CountThrLow[on]); | ||
1105 | |||
1106 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
1107 | AR_PHY_SFCORR_EXT_M1_THRESH_LOW, | ||
1108 | m1ThreshLow[on]); | ||
1109 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
1110 | AR_PHY_SFCORR_EXT_M2_THRESH_LOW, | ||
1111 | m2ThreshLow[on]); | ||
1112 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
1113 | AR_PHY_SFCORR_EXT_M1_THRESH, | ||
1114 | m1Thresh[on]); | ||
1115 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
1116 | AR_PHY_SFCORR_EXT_M2_THRESH, | ||
1117 | m2Thresh[on]); | ||
1118 | |||
1119 | if (on) | ||
1120 | REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, | ||
1121 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
1122 | else | ||
1123 | REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, | ||
1124 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
1125 | |||
1126 | if (!on != aniState->ofdmWeakSigDetectOff) { | ||
1127 | if (on) | ||
1128 | ah->stats.ast_ani_ofdmon++; | ||
1129 | else | ||
1130 | ah->stats.ast_ani_ofdmoff++; | ||
1131 | aniState->ofdmWeakSigDetectOff = !on; | ||
1132 | } | ||
1133 | break; | ||
1134 | } | ||
1135 | case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ | ||
1136 | const int weakSigThrCck[] = { 8, 6 }; | ||
1137 | u32 high = param ? 1 : 0; | ||
1138 | |||
1139 | REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, | ||
1140 | AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, | ||
1141 | weakSigThrCck[high]); | ||
1142 | if (high != aniState->cckWeakSigThreshold) { | ||
1143 | if (high) | ||
1144 | ah->stats.ast_ani_cckhigh++; | ||
1145 | else | ||
1146 | ah->stats.ast_ani_ccklow++; | ||
1147 | aniState->cckWeakSigThreshold = high; | ||
1148 | } | ||
1149 | break; | ||
1150 | } | ||
1151 | case ATH9K_ANI_FIRSTEP_LEVEL:{ | ||
1152 | const int firstep[] = { 0, 4, 8 }; | ||
1153 | u32 level = param; | ||
1154 | |||
1155 | if (level >= ARRAY_SIZE(firstep)) { | ||
1156 | ath_print(common, ATH_DBG_ANI, | ||
1157 | "level out of range (%u > %u)\n", | ||
1158 | level, | ||
1159 | (unsigned) ARRAY_SIZE(firstep)); | ||
1160 | return false; | ||
1161 | } | ||
1162 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
1163 | AR_PHY_FIND_SIG_FIRSTEP, | ||
1164 | firstep[level]); | ||
1165 | if (level > aniState->firstepLevel) | ||
1166 | ah->stats.ast_ani_stepup++; | ||
1167 | else if (level < aniState->firstepLevel) | ||
1168 | ah->stats.ast_ani_stepdown++; | ||
1169 | aniState->firstepLevel = level; | ||
1170 | break; | ||
1171 | } | ||
1172 | case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ | ||
1173 | const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; | ||
1174 | u32 level = param; | ||
1175 | |||
1176 | if (level >= ARRAY_SIZE(cycpwrThr1)) { | ||
1177 | ath_print(common, ATH_DBG_ANI, | ||
1178 | "level out of range (%u > %u)\n", | ||
1179 | level, | ||
1180 | (unsigned) ARRAY_SIZE(cycpwrThr1)); | ||
1181 | return false; | ||
1182 | } | ||
1183 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, | ||
1184 | AR_PHY_TIMING5_CYCPWR_THR1, | ||
1185 | cycpwrThr1[level]); | ||
1186 | if (level > aniState->spurImmunityLevel) | ||
1187 | ah->stats.ast_ani_spurup++; | ||
1188 | else if (level < aniState->spurImmunityLevel) | ||
1189 | ah->stats.ast_ani_spurdown++; | ||
1190 | aniState->spurImmunityLevel = level; | ||
1191 | break; | ||
1192 | } | ||
1193 | case ATH9K_ANI_PRESENT: | ||
1194 | break; | ||
1195 | default: | ||
1196 | ath_print(common, ATH_DBG_ANI, | ||
1197 | "invalid cmd %u\n", cmd); | ||
1198 | return false; | ||
1199 | } | ||
1200 | |||
1201 | ath_print(common, ATH_DBG_ANI, "ANI parameters:\n"); | ||
1202 | ath_print(common, ATH_DBG_ANI, | ||
1203 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, " | ||
1204 | "ofdmWeakSigDetectOff=%d\n", | ||
1205 | aniState->noiseImmunityLevel, | ||
1206 | aniState->spurImmunityLevel, | ||
1207 | !aniState->ofdmWeakSigDetectOff); | ||
1208 | ath_print(common, ATH_DBG_ANI, | ||
1209 | "cckWeakSigThreshold=%d, " | ||
1210 | "firstepLevel=%d, listenTime=%d\n", | ||
1211 | aniState->cckWeakSigThreshold, | ||
1212 | aniState->firstepLevel, | ||
1213 | aniState->listenTime); | ||
1214 | ath_print(common, ATH_DBG_ANI, | ||
1215 | "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", | ||
1216 | aniState->cycleCount, | ||
1217 | aniState->ofdmPhyErrCount, | ||
1218 | aniState->cckPhyErrCount); | ||
1219 | |||
1220 | return true; | ||
1221 | } | ||
1222 | |||
1223 | static void ar5008_hw_do_getnf(struct ath_hw *ah, | ||
1224 | int16_t nfarray[NUM_NF_READINGS]) | ||
1225 | { | ||
1226 | struct ath_common *common = ath9k_hw_common(ah); | ||
1227 | int16_t nf; | ||
1228 | |||
1229 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); | ||
1230 | if (nf & 0x100) | ||
1231 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
1232 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1233 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | ||
1234 | nfarray[0] = nf; | ||
1235 | |||
1236 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR); | ||
1237 | if (nf & 0x100) | ||
1238 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
1239 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1240 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | ||
1241 | nfarray[1] = nf; | ||
1242 | |||
1243 | nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR); | ||
1244 | if (nf & 0x100) | ||
1245 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
1246 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1247 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | ||
1248 | nfarray[2] = nf; | ||
1249 | |||
1250 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); | ||
1251 | if (nf & 0x100) | ||
1252 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
1253 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1254 | "NF calibrated [ext] [chain 0] is %d\n", nf); | ||
1255 | nfarray[3] = nf; | ||
1256 | |||
1257 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR); | ||
1258 | if (nf & 0x100) | ||
1259 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
1260 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1261 | "NF calibrated [ext] [chain 1] is %d\n", nf); | ||
1262 | nfarray[4] = nf; | ||
1263 | |||
1264 | nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR); | ||
1265 | if (nf & 0x100) | ||
1266 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
1267 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1268 | "NF calibrated [ext] [chain 2] is %d\n", nf); | ||
1269 | nfarray[5] = nf; | ||
1270 | } | ||
1271 | |||
1272 | static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1273 | { | ||
1274 | struct ath9k_nfcal_hist *h; | ||
1275 | int i, j; | ||
1276 | int32_t val; | ||
1277 | const u32 ar5416_cca_regs[6] = { | ||
1278 | AR_PHY_CCA, | ||
1279 | AR_PHY_CH1_CCA, | ||
1280 | AR_PHY_CH2_CCA, | ||
1281 | AR_PHY_EXT_CCA, | ||
1282 | AR_PHY_CH1_EXT_CCA, | ||
1283 | AR_PHY_CH2_EXT_CCA | ||
1284 | }; | ||
1285 | u8 chainmask, rx_chain_status; | ||
1286 | |||
1287 | rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK); | ||
1288 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) | ||
1289 | chainmask = 0x9; | ||
1290 | else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { | ||
1291 | if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4)) | ||
1292 | chainmask = 0x1B; | ||
1293 | else | ||
1294 | chainmask = 0x09; | ||
1295 | } else { | ||
1296 | if (rx_chain_status & 0x4) | ||
1297 | chainmask = 0x3F; | ||
1298 | else if (rx_chain_status & 0x2) | ||
1299 | chainmask = 0x1B; | ||
1300 | else | ||
1301 | chainmask = 0x09; | ||
1302 | } | ||
1303 | |||
1304 | h = ah->nfCalHist; | ||
1305 | |||
1306 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
1307 | if (chainmask & (1 << i)) { | ||
1308 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
1309 | val &= 0xFFFFFE00; | ||
1310 | val |= (((u32) (h[i].privNF) << 1) & 0x1ff); | ||
1311 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
1312 | } | ||
1313 | } | ||
1314 | |||
1315 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
1316 | AR_PHY_AGC_CONTROL_ENABLE_NF); | ||
1317 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
1318 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
1319 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | ||
1320 | |||
1321 | for (j = 0; j < 5; j++) { | ||
1322 | if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
1323 | AR_PHY_AGC_CONTROL_NF) == 0) | ||
1324 | break; | ||
1325 | udelay(50); | ||
1326 | } | ||
1327 | |||
1328 | ENABLE_REGWRITE_BUFFER(ah); | ||
1329 | |||
1330 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
1331 | if (chainmask & (1 << i)) { | ||
1332 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
1333 | val &= 0xFFFFFE00; | ||
1334 | val |= (((u32) (-50) << 1) & 0x1ff); | ||
1335 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
1336 | } | ||
1337 | } | ||
1338 | |||
1339 | REGWRITE_BUFFER_FLUSH(ah); | ||
1340 | DISABLE_REGWRITE_BUFFER(ah); | ||
1341 | } | ||
1342 | |||
1343 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah) | ||
1344 | { | ||
1345 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
1346 | |||
1347 | priv_ops->rf_set_freq = ar5008_hw_set_channel; | ||
1348 | priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate; | ||
1349 | |||
1350 | priv_ops->rf_alloc_ext_banks = ar5008_hw_rf_alloc_ext_banks; | ||
1351 | priv_ops->rf_free_ext_banks = ar5008_hw_rf_free_ext_banks; | ||
1352 | priv_ops->set_rf_regs = ar5008_hw_set_rf_regs; | ||
1353 | priv_ops->set_channel_regs = ar5008_hw_set_channel_regs; | ||
1354 | priv_ops->init_bb = ar5008_hw_init_bb; | ||
1355 | priv_ops->process_ini = ar5008_hw_process_ini; | ||
1356 | priv_ops->set_rfmode = ar5008_hw_set_rfmode; | ||
1357 | priv_ops->mark_phy_inactive = ar5008_hw_mark_phy_inactive; | ||
1358 | priv_ops->set_delta_slope = ar5008_hw_set_delta_slope; | ||
1359 | priv_ops->rfbus_req = ar5008_hw_rfbus_req; | ||
1360 | priv_ops->rfbus_done = ar5008_hw_rfbus_done; | ||
1361 | priv_ops->enable_rfkill = ar5008_hw_enable_rfkill; | ||
1362 | priv_ops->restore_chainmask = ar5008_restore_chainmask; | ||
1363 | priv_ops->set_diversity = ar5008_set_diversity; | ||
1364 | priv_ops->ani_control = ar5008_hw_ani_control; | ||
1365 | priv_ops->do_getnf = ar5008_hw_do_getnf; | ||
1366 | priv_ops->loadnf = ar5008_hw_loadnf; | ||
1367 | |||
1368 | if (AR_SREV_9100(ah)) | ||
1369 | priv_ops->compute_pll_control = ar9100_hw_compute_pll_control; | ||
1370 | else if (AR_SREV_9160_10_OR_LATER(ah)) | ||
1371 | priv_ops->compute_pll_control = ar9160_hw_compute_pll_control; | ||
1372 | else | ||
1373 | priv_ops->compute_pll_control = ar5008_hw_compute_pll_control; | ||
1374 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9001_initvals.h b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h new file mode 100644 index 000000000000..0b94bd385b0a --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9001_initvals.h | |||
@@ -0,0 +1,1254 @@ | |||
1 | |||
2 | static const u32 ar5416Common_9100[][2] = { | ||
3 | { 0x0000000c, 0x00000000 }, | ||
4 | { 0x00000030, 0x00020015 }, | ||
5 | { 0x00000034, 0x00000005 }, | ||
6 | { 0x00000040, 0x00000000 }, | ||
7 | { 0x00000044, 0x00000008 }, | ||
8 | { 0x00000048, 0x00000008 }, | ||
9 | { 0x0000004c, 0x00000010 }, | ||
10 | { 0x00000050, 0x00000000 }, | ||
11 | { 0x00000054, 0x0000001f }, | ||
12 | { 0x00000800, 0x00000000 }, | ||
13 | { 0x00000804, 0x00000000 }, | ||
14 | { 0x00000808, 0x00000000 }, | ||
15 | { 0x0000080c, 0x00000000 }, | ||
16 | { 0x00000810, 0x00000000 }, | ||
17 | { 0x00000814, 0x00000000 }, | ||
18 | { 0x00000818, 0x00000000 }, | ||
19 | { 0x0000081c, 0x00000000 }, | ||
20 | { 0x00000820, 0x00000000 }, | ||
21 | { 0x00000824, 0x00000000 }, | ||
22 | { 0x00001040, 0x002ffc0f }, | ||
23 | { 0x00001044, 0x002ffc0f }, | ||
24 | { 0x00001048, 0x002ffc0f }, | ||
25 | { 0x0000104c, 0x002ffc0f }, | ||
26 | { 0x00001050, 0x002ffc0f }, | ||
27 | { 0x00001054, 0x002ffc0f }, | ||
28 | { 0x00001058, 0x002ffc0f }, | ||
29 | { 0x0000105c, 0x002ffc0f }, | ||
30 | { 0x00001060, 0x002ffc0f }, | ||
31 | { 0x00001064, 0x002ffc0f }, | ||
32 | { 0x00001230, 0x00000000 }, | ||
33 | { 0x00001270, 0x00000000 }, | ||
34 | { 0x00001038, 0x00000000 }, | ||
35 | { 0x00001078, 0x00000000 }, | ||
36 | { 0x000010b8, 0x00000000 }, | ||
37 | { 0x000010f8, 0x00000000 }, | ||
38 | { 0x00001138, 0x00000000 }, | ||
39 | { 0x00001178, 0x00000000 }, | ||
40 | { 0x000011b8, 0x00000000 }, | ||
41 | { 0x000011f8, 0x00000000 }, | ||
42 | { 0x00001238, 0x00000000 }, | ||
43 | { 0x00001278, 0x00000000 }, | ||
44 | { 0x000012b8, 0x00000000 }, | ||
45 | { 0x000012f8, 0x00000000 }, | ||
46 | { 0x00001338, 0x00000000 }, | ||
47 | { 0x00001378, 0x00000000 }, | ||
48 | { 0x000013b8, 0x00000000 }, | ||
49 | { 0x000013f8, 0x00000000 }, | ||
50 | { 0x00001438, 0x00000000 }, | ||
51 | { 0x00001478, 0x00000000 }, | ||
52 | { 0x000014b8, 0x00000000 }, | ||
53 | { 0x000014f8, 0x00000000 }, | ||
54 | { 0x00001538, 0x00000000 }, | ||
55 | { 0x00001578, 0x00000000 }, | ||
56 | { 0x000015b8, 0x00000000 }, | ||
57 | { 0x000015f8, 0x00000000 }, | ||
58 | { 0x00001638, 0x00000000 }, | ||
59 | { 0x00001678, 0x00000000 }, | ||
60 | { 0x000016b8, 0x00000000 }, | ||
61 | { 0x000016f8, 0x00000000 }, | ||
62 | { 0x00001738, 0x00000000 }, | ||
63 | { 0x00001778, 0x00000000 }, | ||
64 | { 0x000017b8, 0x00000000 }, | ||
65 | { 0x000017f8, 0x00000000 }, | ||
66 | { 0x0000103c, 0x00000000 }, | ||
67 | { 0x0000107c, 0x00000000 }, | ||
68 | { 0x000010bc, 0x00000000 }, | ||
69 | { 0x000010fc, 0x00000000 }, | ||
70 | { 0x0000113c, 0x00000000 }, | ||
71 | { 0x0000117c, 0x00000000 }, | ||
72 | { 0x000011bc, 0x00000000 }, | ||
73 | { 0x000011fc, 0x00000000 }, | ||
74 | { 0x0000123c, 0x00000000 }, | ||
75 | { 0x0000127c, 0x00000000 }, | ||
76 | { 0x000012bc, 0x00000000 }, | ||
77 | { 0x000012fc, 0x00000000 }, | ||
78 | { 0x0000133c, 0x00000000 }, | ||
79 | { 0x0000137c, 0x00000000 }, | ||
80 | { 0x000013bc, 0x00000000 }, | ||
81 | { 0x000013fc, 0x00000000 }, | ||
82 | { 0x0000143c, 0x00000000 }, | ||
83 | { 0x0000147c, 0x00000000 }, | ||
84 | { 0x00020010, 0x00000003 }, | ||
85 | { 0x00020038, 0x000004c2 }, | ||
86 | { 0x00008004, 0x00000000 }, | ||
87 | { 0x00008008, 0x00000000 }, | ||
88 | { 0x0000800c, 0x00000000 }, | ||
89 | { 0x00008018, 0x00000700 }, | ||
90 | { 0x00008020, 0x00000000 }, | ||
91 | { 0x00008038, 0x00000000 }, | ||
92 | { 0x0000803c, 0x00000000 }, | ||
93 | { 0x00008048, 0x40000000 }, | ||
94 | { 0x00008054, 0x00004000 }, | ||
95 | { 0x00008058, 0x00000000 }, | ||
96 | { 0x0000805c, 0x000fc78f }, | ||
97 | { 0x00008060, 0x0000000f }, | ||
98 | { 0x00008064, 0x00000000 }, | ||
99 | { 0x000080c0, 0x2a82301a }, | ||
100 | { 0x000080c4, 0x05dc01e0 }, | ||
101 | { 0x000080c8, 0x1f402710 }, | ||
102 | { 0x000080cc, 0x01f40000 }, | ||
103 | { 0x000080d0, 0x00001e00 }, | ||
104 | { 0x000080d4, 0x00000000 }, | ||
105 | { 0x000080d8, 0x00400000 }, | ||
106 | { 0x000080e0, 0xffffffff }, | ||
107 | { 0x000080e4, 0x0000ffff }, | ||
108 | { 0x000080e8, 0x003f3f3f }, | ||
109 | { 0x000080ec, 0x00000000 }, | ||
110 | { 0x000080f0, 0x00000000 }, | ||
111 | { 0x000080f4, 0x00000000 }, | ||
112 | { 0x000080f8, 0x00000000 }, | ||
113 | { 0x000080fc, 0x00020000 }, | ||
114 | { 0x00008100, 0x00020000 }, | ||
115 | { 0x00008104, 0x00000001 }, | ||
116 | { 0x00008108, 0x00000052 }, | ||
117 | { 0x0000810c, 0x00000000 }, | ||
118 | { 0x00008110, 0x00000168 }, | ||
119 | { 0x00008118, 0x000100aa }, | ||
120 | { 0x0000811c, 0x00003210 }, | ||
121 | { 0x00008120, 0x08f04800 }, | ||
122 | { 0x00008124, 0x00000000 }, | ||
123 | { 0x00008128, 0x00000000 }, | ||
124 | { 0x0000812c, 0x00000000 }, | ||
125 | { 0x00008130, 0x00000000 }, | ||
126 | { 0x00008134, 0x00000000 }, | ||
127 | { 0x00008138, 0x00000000 }, | ||
128 | { 0x0000813c, 0x00000000 }, | ||
129 | { 0x00008144, 0x00000000 }, | ||
130 | { 0x00008168, 0x00000000 }, | ||
131 | { 0x0000816c, 0x00000000 }, | ||
132 | { 0x00008170, 0x32143320 }, | ||
133 | { 0x00008174, 0xfaa4fa50 }, | ||
134 | { 0x00008178, 0x00000100 }, | ||
135 | { 0x0000817c, 0x00000000 }, | ||
136 | { 0x000081c4, 0x00000000 }, | ||
137 | { 0x000081d0, 0x00003210 }, | ||
138 | { 0x000081ec, 0x00000000 }, | ||
139 | { 0x000081f0, 0x00000000 }, | ||
140 | { 0x000081f4, 0x00000000 }, | ||
141 | { 0x000081f8, 0x00000000 }, | ||
142 | { 0x000081fc, 0x00000000 }, | ||
143 | { 0x00008200, 0x00000000 }, | ||
144 | { 0x00008204, 0x00000000 }, | ||
145 | { 0x00008208, 0x00000000 }, | ||
146 | { 0x0000820c, 0x00000000 }, | ||
147 | { 0x00008210, 0x00000000 }, | ||
148 | { 0x00008214, 0x00000000 }, | ||
149 | { 0x00008218, 0x00000000 }, | ||
150 | { 0x0000821c, 0x00000000 }, | ||
151 | { 0x00008220, 0x00000000 }, | ||
152 | { 0x00008224, 0x00000000 }, | ||
153 | { 0x00008228, 0x00000000 }, | ||
154 | { 0x0000822c, 0x00000000 }, | ||
155 | { 0x00008230, 0x00000000 }, | ||
156 | { 0x00008234, 0x00000000 }, | ||
157 | { 0x00008238, 0x00000000 }, | ||
158 | { 0x0000823c, 0x00000000 }, | ||
159 | { 0x00008240, 0x00100000 }, | ||
160 | { 0x00008244, 0x0010f400 }, | ||
161 | { 0x00008248, 0x00000100 }, | ||
162 | { 0x0000824c, 0x0001e800 }, | ||
163 | { 0x00008250, 0x00000000 }, | ||
164 | { 0x00008254, 0x00000000 }, | ||
165 | { 0x00008258, 0x00000000 }, | ||
166 | { 0x0000825c, 0x400000ff }, | ||
167 | { 0x00008260, 0x00080922 }, | ||
168 | { 0x00008270, 0x00000000 }, | ||
169 | { 0x00008274, 0x40000000 }, | ||
170 | { 0x00008278, 0x003e4180 }, | ||
171 | { 0x0000827c, 0x00000000 }, | ||
172 | { 0x00008284, 0x0000002c }, | ||
173 | { 0x00008288, 0x0000002c }, | ||
174 | { 0x0000828c, 0x00000000 }, | ||
175 | { 0x00008294, 0x00000000 }, | ||
176 | { 0x00008298, 0x00000000 }, | ||
177 | { 0x00008300, 0x00000000 }, | ||
178 | { 0x00008304, 0x00000000 }, | ||
179 | { 0x00008308, 0x00000000 }, | ||
180 | { 0x0000830c, 0x00000000 }, | ||
181 | { 0x00008310, 0x00000000 }, | ||
182 | { 0x00008314, 0x00000000 }, | ||
183 | { 0x00008318, 0x00000000 }, | ||
184 | { 0x00008328, 0x00000000 }, | ||
185 | { 0x0000832c, 0x00000007 }, | ||
186 | { 0x00008330, 0x00000302 }, | ||
187 | { 0x00008334, 0x00000e00 }, | ||
188 | { 0x00008338, 0x00000000 }, | ||
189 | { 0x0000833c, 0x00000000 }, | ||
190 | { 0x00008340, 0x000107ff }, | ||
191 | { 0x00009808, 0x00000000 }, | ||
192 | { 0x0000980c, 0xad848e19 }, | ||
193 | { 0x00009810, 0x7d14e000 }, | ||
194 | { 0x00009814, 0x9c0a9f6b }, | ||
195 | { 0x0000981c, 0x00000000 }, | ||
196 | { 0x0000982c, 0x0000a000 }, | ||
197 | { 0x00009830, 0x00000000 }, | ||
198 | { 0x0000983c, 0x00200400 }, | ||
199 | { 0x00009840, 0x206a01ae }, | ||
200 | { 0x0000984c, 0x1284233c }, | ||
201 | { 0x00009854, 0x00000859 }, | ||
202 | { 0x00009900, 0x00000000 }, | ||
203 | { 0x00009904, 0x00000000 }, | ||
204 | { 0x00009908, 0x00000000 }, | ||
205 | { 0x0000990c, 0x00000000 }, | ||
206 | { 0x0000991c, 0x10000fff }, | ||
207 | { 0x00009920, 0x05100000 }, | ||
208 | { 0x0000a920, 0x05100000 }, | ||
209 | { 0x0000b920, 0x05100000 }, | ||
210 | { 0x00009928, 0x00000001 }, | ||
211 | { 0x0000992c, 0x00000004 }, | ||
212 | { 0x00009934, 0x1e1f2022 }, | ||
213 | { 0x00009938, 0x0a0b0c0d }, | ||
214 | { 0x0000993c, 0x00000000 }, | ||
215 | { 0x00009948, 0x9280b212 }, | ||
216 | { 0x0000994c, 0x00020028 }, | ||
217 | { 0x0000c95c, 0x004b6a8e }, | ||
218 | { 0x0000c968, 0x000003ce }, | ||
219 | { 0x00009970, 0x190fb515 }, | ||
220 | { 0x00009974, 0x00000000 }, | ||
221 | { 0x00009978, 0x00000001 }, | ||
222 | { 0x0000997c, 0x00000000 }, | ||
223 | { 0x00009980, 0x00000000 }, | ||
224 | { 0x00009984, 0x00000000 }, | ||
225 | { 0x00009988, 0x00000000 }, | ||
226 | { 0x0000998c, 0x00000000 }, | ||
227 | { 0x00009990, 0x00000000 }, | ||
228 | { 0x00009994, 0x00000000 }, | ||
229 | { 0x00009998, 0x00000000 }, | ||
230 | { 0x0000999c, 0x00000000 }, | ||
231 | { 0x000099a0, 0x00000000 }, | ||
232 | { 0x000099a4, 0x00000001 }, | ||
233 | { 0x000099a8, 0x201fff00 }, | ||
234 | { 0x000099ac, 0x006f0000 }, | ||
235 | { 0x000099b0, 0x03051000 }, | ||
236 | { 0x000099dc, 0x00000000 }, | ||
237 | { 0x000099e0, 0x00000200 }, | ||
238 | { 0x000099e4, 0xaaaaaaaa }, | ||
239 | { 0x000099e8, 0x3c466478 }, | ||
240 | { 0x000099ec, 0x0cc80caa }, | ||
241 | { 0x000099fc, 0x00001042 }, | ||
242 | { 0x00009b00, 0x00000000 }, | ||
243 | { 0x00009b04, 0x00000001 }, | ||
244 | { 0x00009b08, 0x00000002 }, | ||
245 | { 0x00009b0c, 0x00000003 }, | ||
246 | { 0x00009b10, 0x00000004 }, | ||
247 | { 0x00009b14, 0x00000005 }, | ||
248 | { 0x00009b18, 0x00000008 }, | ||
249 | { 0x00009b1c, 0x00000009 }, | ||
250 | { 0x00009b20, 0x0000000a }, | ||
251 | { 0x00009b24, 0x0000000b }, | ||
252 | { 0x00009b28, 0x0000000c }, | ||
253 | { 0x00009b2c, 0x0000000d }, | ||
254 | { 0x00009b30, 0x00000010 }, | ||
255 | { 0x00009b34, 0x00000011 }, | ||
256 | { 0x00009b38, 0x00000012 }, | ||
257 | { 0x00009b3c, 0x00000013 }, | ||
258 | { 0x00009b40, 0x00000014 }, | ||
259 | { 0x00009b44, 0x00000015 }, | ||
260 | { 0x00009b48, 0x00000018 }, | ||
261 | { 0x00009b4c, 0x00000019 }, | ||
262 | { 0x00009b50, 0x0000001a }, | ||
263 | { 0x00009b54, 0x0000001b }, | ||
264 | { 0x00009b58, 0x0000001c }, | ||
265 | { 0x00009b5c, 0x0000001d }, | ||
266 | { 0x00009b60, 0x00000020 }, | ||
267 | { 0x00009b64, 0x00000021 }, | ||
268 | { 0x00009b68, 0x00000022 }, | ||
269 | { 0x00009b6c, 0x00000023 }, | ||
270 | { 0x00009b70, 0x00000024 }, | ||
271 | { 0x00009b74, 0x00000025 }, | ||
272 | { 0x00009b78, 0x00000028 }, | ||
273 | { 0x00009b7c, 0x00000029 }, | ||
274 | { 0x00009b80, 0x0000002a }, | ||
275 | { 0x00009b84, 0x0000002b }, | ||
276 | { 0x00009b88, 0x0000002c }, | ||
277 | { 0x00009b8c, 0x0000002d }, | ||
278 | { 0x00009b90, 0x00000030 }, | ||
279 | { 0x00009b94, 0x00000031 }, | ||
280 | { 0x00009b98, 0x00000032 }, | ||
281 | { 0x00009b9c, 0x00000033 }, | ||
282 | { 0x00009ba0, 0x00000034 }, | ||
283 | { 0x00009ba4, 0x00000035 }, | ||
284 | { 0x00009ba8, 0x00000035 }, | ||
285 | { 0x00009bac, 0x00000035 }, | ||
286 | { 0x00009bb0, 0x00000035 }, | ||
287 | { 0x00009bb4, 0x00000035 }, | ||
288 | { 0x00009bb8, 0x00000035 }, | ||
289 | { 0x00009bbc, 0x00000035 }, | ||
290 | { 0x00009bc0, 0x00000035 }, | ||
291 | { 0x00009bc4, 0x00000035 }, | ||
292 | { 0x00009bc8, 0x00000035 }, | ||
293 | { 0x00009bcc, 0x00000035 }, | ||
294 | { 0x00009bd0, 0x00000035 }, | ||
295 | { 0x00009bd4, 0x00000035 }, | ||
296 | { 0x00009bd8, 0x00000035 }, | ||
297 | { 0x00009bdc, 0x00000035 }, | ||
298 | { 0x00009be0, 0x00000035 }, | ||
299 | { 0x00009be4, 0x00000035 }, | ||
300 | { 0x00009be8, 0x00000035 }, | ||
301 | { 0x00009bec, 0x00000035 }, | ||
302 | { 0x00009bf0, 0x00000035 }, | ||
303 | { 0x00009bf4, 0x00000035 }, | ||
304 | { 0x00009bf8, 0x00000010 }, | ||
305 | { 0x00009bfc, 0x0000001a }, | ||
306 | { 0x0000a210, 0x40806333 }, | ||
307 | { 0x0000a214, 0x00106c10 }, | ||
308 | { 0x0000a218, 0x009c4060 }, | ||
309 | { 0x0000a220, 0x018830c6 }, | ||
310 | { 0x0000a224, 0x00000400 }, | ||
311 | { 0x0000a228, 0x001a0bb5 }, | ||
312 | { 0x0000a22c, 0x00000000 }, | ||
313 | { 0x0000a234, 0x20202020 }, | ||
314 | { 0x0000a238, 0x20202020 }, | ||
315 | { 0x0000a23c, 0x13c889ae }, | ||
316 | { 0x0000a240, 0x38490a20 }, | ||
317 | { 0x0000a244, 0x00007bb6 }, | ||
318 | { 0x0000a248, 0x0fff3ffc }, | ||
319 | { 0x0000a24c, 0x00000001 }, | ||
320 | { 0x0000a250, 0x0000a000 }, | ||
321 | { 0x0000a254, 0x00000000 }, | ||
322 | { 0x0000a258, 0x0cc75380 }, | ||
323 | { 0x0000a25c, 0x0f0f0f01 }, | ||
324 | { 0x0000a260, 0xdfa91f01 }, | ||
325 | { 0x0000a268, 0x00000001 }, | ||
326 | { 0x0000a26c, 0x0ebae9c6 }, | ||
327 | { 0x0000b26c, 0x0ebae9c6 }, | ||
328 | { 0x0000c26c, 0x0ebae9c6 }, | ||
329 | { 0x0000d270, 0x00820820 }, | ||
330 | { 0x0000a278, 0x1ce739ce }, | ||
331 | { 0x0000a27c, 0x050701ce }, | ||
332 | { 0x0000a338, 0x00000000 }, | ||
333 | { 0x0000a33c, 0x00000000 }, | ||
334 | { 0x0000a340, 0x00000000 }, | ||
335 | { 0x0000a344, 0x00000000 }, | ||
336 | { 0x0000a348, 0x3fffffff }, | ||
337 | { 0x0000a34c, 0x3fffffff }, | ||
338 | { 0x0000a350, 0x3fffffff }, | ||
339 | { 0x0000a354, 0x0003ffff }, | ||
340 | { 0x0000a358, 0x79a8aa33 }, | ||
341 | { 0x0000d35c, 0x07ffffef }, | ||
342 | { 0x0000d360, 0x0fffffe7 }, | ||
343 | { 0x0000d364, 0x17ffffe5 }, | ||
344 | { 0x0000d368, 0x1fffffe4 }, | ||
345 | { 0x0000d36c, 0x37ffffe3 }, | ||
346 | { 0x0000d370, 0x3fffffe3 }, | ||
347 | { 0x0000d374, 0x57ffffe3 }, | ||
348 | { 0x0000d378, 0x5fffffe2 }, | ||
349 | { 0x0000d37c, 0x7fffffe2 }, | ||
350 | { 0x0000d380, 0x7f3c7bba }, | ||
351 | { 0x0000d384, 0xf3307ff0 }, | ||
352 | { 0x0000a388, 0x0c000000 }, | ||
353 | { 0x0000a38c, 0x20202020 }, | ||
354 | { 0x0000a390, 0x20202020 }, | ||
355 | { 0x0000a394, 0x1ce739ce }, | ||
356 | { 0x0000a398, 0x000001ce }, | ||
357 | { 0x0000a39c, 0x00000001 }, | ||
358 | { 0x0000a3a0, 0x00000000 }, | ||
359 | { 0x0000a3a4, 0x00000000 }, | ||
360 | { 0x0000a3a8, 0x00000000 }, | ||
361 | { 0x0000a3ac, 0x00000000 }, | ||
362 | { 0x0000a3b0, 0x00000000 }, | ||
363 | { 0x0000a3b4, 0x00000000 }, | ||
364 | { 0x0000a3b8, 0x00000000 }, | ||
365 | { 0x0000a3bc, 0x00000000 }, | ||
366 | { 0x0000a3c0, 0x00000000 }, | ||
367 | { 0x0000a3c4, 0x00000000 }, | ||
368 | { 0x0000a3c8, 0x00000246 }, | ||
369 | { 0x0000a3cc, 0x20202020 }, | ||
370 | { 0x0000a3d0, 0x20202020 }, | ||
371 | { 0x0000a3d4, 0x20202020 }, | ||
372 | { 0x0000a3dc, 0x1ce739ce }, | ||
373 | { 0x0000a3e0, 0x000001ce }, | ||
374 | }; | ||
375 | |||
376 | static const u32 ar5416Bank0_9100[][2] = { | ||
377 | { 0x000098b0, 0x1e5795e5 }, | ||
378 | { 0x000098e0, 0x02008020 }, | ||
379 | }; | ||
380 | |||
381 | static const u32 ar5416BB_RfGain_9100[][3] = { | ||
382 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
383 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
384 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
385 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
386 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
387 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
388 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
389 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
390 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
391 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
392 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
393 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
394 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
395 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
396 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
397 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
398 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
399 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
400 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
401 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
402 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
403 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
404 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
405 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
406 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
407 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
408 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
409 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
410 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
411 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
412 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
413 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
414 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
415 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
416 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
417 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
418 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
419 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
420 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
421 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
422 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
423 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
424 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
425 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
426 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
427 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
428 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
429 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
430 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
431 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
432 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
433 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
434 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
435 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
436 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
437 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
438 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
439 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
440 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
441 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
442 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
443 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
444 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
445 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
446 | }; | ||
447 | |||
448 | static const u32 ar5416Bank1_9100[][2] = { | ||
449 | { 0x000098b0, 0x02108421}, | ||
450 | { 0x000098ec, 0x00000008}, | ||
451 | }; | ||
452 | |||
453 | static const u32 ar5416Bank2_9100[][2] = { | ||
454 | { 0x000098b0, 0x0e73ff17}, | ||
455 | { 0x000098e0, 0x00000420}, | ||
456 | }; | ||
457 | |||
458 | static const u32 ar5416Bank3_9100[][3] = { | ||
459 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
460 | }; | ||
461 | |||
462 | static const u32 ar5416Bank6_9100[][3] = { | ||
463 | |||
464 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
465 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
466 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
467 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
468 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
469 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
470 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
471 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
472 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
473 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
474 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
475 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
476 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
477 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
478 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
479 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
480 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
481 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
482 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
483 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
484 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
485 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
486 | { 0x0000989c, 0x0014000f, 0x0014000f }, | ||
487 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
488 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
489 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
490 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
491 | { 0x0000989c, 0x000180d6, 0x000180d6 }, | ||
492 | { 0x0000989c, 0x0000c0aa, 0x0000c0aa }, | ||
493 | { 0x0000989c, 0x000000b1, 0x000000b1 }, | ||
494 | { 0x0000989c, 0x00002000, 0x00002000 }, | ||
495 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
496 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
497 | }; | ||
498 | |||
499 | |||
500 | static const u32 ar5416Bank6TPC_9100[][3] = { | ||
501 | |||
502 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
503 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
504 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
505 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
506 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
507 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
508 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
509 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
510 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
511 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
512 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
513 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
514 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
515 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
516 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
517 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
518 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
519 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
520 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
521 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
522 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
523 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
524 | { 0x0000989c, 0x2014008f, 0x2014008f }, | ||
525 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
526 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
527 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
528 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
529 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
530 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
531 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
532 | { 0x0000989c, 0x00007080, 0x00007080 }, | ||
533 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
534 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
535 | }; | ||
536 | |||
537 | static const u32 ar5416Bank7_9100[][2] = { | ||
538 | { 0x0000989c, 0x00000500 }, | ||
539 | { 0x0000989c, 0x00000800 }, | ||
540 | { 0x000098cc, 0x0000000e }, | ||
541 | }; | ||
542 | |||
543 | static const u32 ar5416Addac_9100[][2] = { | ||
544 | {0x0000989c, 0x00000000 }, | ||
545 | {0x0000989c, 0x00000000 }, | ||
546 | {0x0000989c, 0x00000000 }, | ||
547 | {0x0000989c, 0x00000000 }, | ||
548 | {0x0000989c, 0x00000000 }, | ||
549 | {0x0000989c, 0x00000000 }, | ||
550 | {0x0000989c, 0x00000000 }, | ||
551 | {0x0000989c, 0x00000010 }, | ||
552 | {0x0000989c, 0x00000000 }, | ||
553 | {0x0000989c, 0x00000000 }, | ||
554 | {0x0000989c, 0x00000000 }, | ||
555 | {0x0000989c, 0x00000000 }, | ||
556 | {0x0000989c, 0x00000000 }, | ||
557 | {0x0000989c, 0x00000000 }, | ||
558 | {0x0000989c, 0x00000000 }, | ||
559 | {0x0000989c, 0x00000000 }, | ||
560 | {0x0000989c, 0x00000000 }, | ||
561 | {0x0000989c, 0x00000000 }, | ||
562 | {0x0000989c, 0x00000000 }, | ||
563 | {0x0000989c, 0x00000000 }, | ||
564 | {0x0000989c, 0x00000000 }, | ||
565 | {0x0000989c, 0x000000c0 }, | ||
566 | {0x0000989c, 0x00000015 }, | ||
567 | {0x0000989c, 0x00000000 }, | ||
568 | {0x0000989c, 0x00000000 }, | ||
569 | {0x0000989c, 0x00000000 }, | ||
570 | {0x0000989c, 0x00000000 }, | ||
571 | {0x0000989c, 0x00000000 }, | ||
572 | {0x0000989c, 0x00000000 }, | ||
573 | {0x0000989c, 0x00000000 }, | ||
574 | {0x0000989c, 0x00000000 }, | ||
575 | {0x000098cc, 0x00000000 }, | ||
576 | }; | ||
577 | |||
578 | static const u32 ar5416Modes_9160[][6] = { | ||
579 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
580 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
581 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
582 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
583 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
584 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
585 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
586 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
587 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
588 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
589 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
590 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
591 | { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, | ||
592 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
593 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
594 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
595 | { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 }, | ||
596 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, | ||
597 | { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e }, | ||
598 | { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, | ||
599 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
600 | { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, | ||
601 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
602 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
603 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
604 | { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, | ||
605 | { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, | ||
606 | { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
607 | { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
608 | { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
609 | { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, | ||
610 | { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce }, | ||
611 | { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 }, | ||
612 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
613 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
614 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
615 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
616 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
617 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
618 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
619 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
620 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
621 | { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
622 | { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
623 | { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
624 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
625 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
626 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
627 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
628 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
629 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
630 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
631 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
632 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
633 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
634 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
635 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
636 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
637 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
638 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
639 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
640 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
641 | }; | ||
642 | |||
643 | static const u32 ar5416Common_9160[][2] = { | ||
644 | { 0x0000000c, 0x00000000 }, | ||
645 | { 0x00000030, 0x00020015 }, | ||
646 | { 0x00000034, 0x00000005 }, | ||
647 | { 0x00000040, 0x00000000 }, | ||
648 | { 0x00000044, 0x00000008 }, | ||
649 | { 0x00000048, 0x00000008 }, | ||
650 | { 0x0000004c, 0x00000010 }, | ||
651 | { 0x00000050, 0x00000000 }, | ||
652 | { 0x00000054, 0x0000001f }, | ||
653 | { 0x00000800, 0x00000000 }, | ||
654 | { 0x00000804, 0x00000000 }, | ||
655 | { 0x00000808, 0x00000000 }, | ||
656 | { 0x0000080c, 0x00000000 }, | ||
657 | { 0x00000810, 0x00000000 }, | ||
658 | { 0x00000814, 0x00000000 }, | ||
659 | { 0x00000818, 0x00000000 }, | ||
660 | { 0x0000081c, 0x00000000 }, | ||
661 | { 0x00000820, 0x00000000 }, | ||
662 | { 0x00000824, 0x00000000 }, | ||
663 | { 0x00001040, 0x002ffc0f }, | ||
664 | { 0x00001044, 0x002ffc0f }, | ||
665 | { 0x00001048, 0x002ffc0f }, | ||
666 | { 0x0000104c, 0x002ffc0f }, | ||
667 | { 0x00001050, 0x002ffc0f }, | ||
668 | { 0x00001054, 0x002ffc0f }, | ||
669 | { 0x00001058, 0x002ffc0f }, | ||
670 | { 0x0000105c, 0x002ffc0f }, | ||
671 | { 0x00001060, 0x002ffc0f }, | ||
672 | { 0x00001064, 0x002ffc0f }, | ||
673 | { 0x00001230, 0x00000000 }, | ||
674 | { 0x00001270, 0x00000000 }, | ||
675 | { 0x00001038, 0x00000000 }, | ||
676 | { 0x00001078, 0x00000000 }, | ||
677 | { 0x000010b8, 0x00000000 }, | ||
678 | { 0x000010f8, 0x00000000 }, | ||
679 | { 0x00001138, 0x00000000 }, | ||
680 | { 0x00001178, 0x00000000 }, | ||
681 | { 0x000011b8, 0x00000000 }, | ||
682 | { 0x000011f8, 0x00000000 }, | ||
683 | { 0x00001238, 0x00000000 }, | ||
684 | { 0x00001278, 0x00000000 }, | ||
685 | { 0x000012b8, 0x00000000 }, | ||
686 | { 0x000012f8, 0x00000000 }, | ||
687 | { 0x00001338, 0x00000000 }, | ||
688 | { 0x00001378, 0x00000000 }, | ||
689 | { 0x000013b8, 0x00000000 }, | ||
690 | { 0x000013f8, 0x00000000 }, | ||
691 | { 0x00001438, 0x00000000 }, | ||
692 | { 0x00001478, 0x00000000 }, | ||
693 | { 0x000014b8, 0x00000000 }, | ||
694 | { 0x000014f8, 0x00000000 }, | ||
695 | { 0x00001538, 0x00000000 }, | ||
696 | { 0x00001578, 0x00000000 }, | ||
697 | { 0x000015b8, 0x00000000 }, | ||
698 | { 0x000015f8, 0x00000000 }, | ||
699 | { 0x00001638, 0x00000000 }, | ||
700 | { 0x00001678, 0x00000000 }, | ||
701 | { 0x000016b8, 0x00000000 }, | ||
702 | { 0x000016f8, 0x00000000 }, | ||
703 | { 0x00001738, 0x00000000 }, | ||
704 | { 0x00001778, 0x00000000 }, | ||
705 | { 0x000017b8, 0x00000000 }, | ||
706 | { 0x000017f8, 0x00000000 }, | ||
707 | { 0x0000103c, 0x00000000 }, | ||
708 | { 0x0000107c, 0x00000000 }, | ||
709 | { 0x000010bc, 0x00000000 }, | ||
710 | { 0x000010fc, 0x00000000 }, | ||
711 | { 0x0000113c, 0x00000000 }, | ||
712 | { 0x0000117c, 0x00000000 }, | ||
713 | { 0x000011bc, 0x00000000 }, | ||
714 | { 0x000011fc, 0x00000000 }, | ||
715 | { 0x0000123c, 0x00000000 }, | ||
716 | { 0x0000127c, 0x00000000 }, | ||
717 | { 0x000012bc, 0x00000000 }, | ||
718 | { 0x000012fc, 0x00000000 }, | ||
719 | { 0x0000133c, 0x00000000 }, | ||
720 | { 0x0000137c, 0x00000000 }, | ||
721 | { 0x000013bc, 0x00000000 }, | ||
722 | { 0x000013fc, 0x00000000 }, | ||
723 | { 0x0000143c, 0x00000000 }, | ||
724 | { 0x0000147c, 0x00000000 }, | ||
725 | { 0x00004030, 0x00000002 }, | ||
726 | { 0x0000403c, 0x00000002 }, | ||
727 | { 0x00007010, 0x00000020 }, | ||
728 | { 0x00007038, 0x000004c2 }, | ||
729 | { 0x00008004, 0x00000000 }, | ||
730 | { 0x00008008, 0x00000000 }, | ||
731 | { 0x0000800c, 0x00000000 }, | ||
732 | { 0x00008018, 0x00000700 }, | ||
733 | { 0x00008020, 0x00000000 }, | ||
734 | { 0x00008038, 0x00000000 }, | ||
735 | { 0x0000803c, 0x00000000 }, | ||
736 | { 0x00008048, 0x40000000 }, | ||
737 | { 0x00008054, 0x00000000 }, | ||
738 | { 0x00008058, 0x00000000 }, | ||
739 | { 0x0000805c, 0x000fc78f }, | ||
740 | { 0x00008060, 0x0000000f }, | ||
741 | { 0x00008064, 0x00000000 }, | ||
742 | { 0x000080c0, 0x2a82301a }, | ||
743 | { 0x000080c4, 0x05dc01e0 }, | ||
744 | { 0x000080c8, 0x1f402710 }, | ||
745 | { 0x000080cc, 0x01f40000 }, | ||
746 | { 0x000080d0, 0x00001e00 }, | ||
747 | { 0x000080d4, 0x00000000 }, | ||
748 | { 0x000080d8, 0x00400000 }, | ||
749 | { 0x000080e0, 0xffffffff }, | ||
750 | { 0x000080e4, 0x0000ffff }, | ||
751 | { 0x000080e8, 0x003f3f3f }, | ||
752 | { 0x000080ec, 0x00000000 }, | ||
753 | { 0x000080f0, 0x00000000 }, | ||
754 | { 0x000080f4, 0x00000000 }, | ||
755 | { 0x000080f8, 0x00000000 }, | ||
756 | { 0x000080fc, 0x00020000 }, | ||
757 | { 0x00008100, 0x00020000 }, | ||
758 | { 0x00008104, 0x00000001 }, | ||
759 | { 0x00008108, 0x00000052 }, | ||
760 | { 0x0000810c, 0x00000000 }, | ||
761 | { 0x00008110, 0x00000168 }, | ||
762 | { 0x00008118, 0x000100aa }, | ||
763 | { 0x0000811c, 0x00003210 }, | ||
764 | { 0x00008120, 0x08f04800 }, | ||
765 | { 0x00008124, 0x00000000 }, | ||
766 | { 0x00008128, 0x00000000 }, | ||
767 | { 0x0000812c, 0x00000000 }, | ||
768 | { 0x00008130, 0x00000000 }, | ||
769 | { 0x00008134, 0x00000000 }, | ||
770 | { 0x00008138, 0x00000000 }, | ||
771 | { 0x0000813c, 0x00000000 }, | ||
772 | { 0x00008144, 0xffffffff }, | ||
773 | { 0x00008168, 0x00000000 }, | ||
774 | { 0x0000816c, 0x00000000 }, | ||
775 | { 0x00008170, 0x32143320 }, | ||
776 | { 0x00008174, 0xfaa4fa50 }, | ||
777 | { 0x00008178, 0x00000100 }, | ||
778 | { 0x0000817c, 0x00000000 }, | ||
779 | { 0x000081c4, 0x00000000 }, | ||
780 | { 0x000081d0, 0x00003210 }, | ||
781 | { 0x000081ec, 0x00000000 }, | ||
782 | { 0x000081f0, 0x00000000 }, | ||
783 | { 0x000081f4, 0x00000000 }, | ||
784 | { 0x000081f8, 0x00000000 }, | ||
785 | { 0x000081fc, 0x00000000 }, | ||
786 | { 0x00008200, 0x00000000 }, | ||
787 | { 0x00008204, 0x00000000 }, | ||
788 | { 0x00008208, 0x00000000 }, | ||
789 | { 0x0000820c, 0x00000000 }, | ||
790 | { 0x00008210, 0x00000000 }, | ||
791 | { 0x00008214, 0x00000000 }, | ||
792 | { 0x00008218, 0x00000000 }, | ||
793 | { 0x0000821c, 0x00000000 }, | ||
794 | { 0x00008220, 0x00000000 }, | ||
795 | { 0x00008224, 0x00000000 }, | ||
796 | { 0x00008228, 0x00000000 }, | ||
797 | { 0x0000822c, 0x00000000 }, | ||
798 | { 0x00008230, 0x00000000 }, | ||
799 | { 0x00008234, 0x00000000 }, | ||
800 | { 0x00008238, 0x00000000 }, | ||
801 | { 0x0000823c, 0x00000000 }, | ||
802 | { 0x00008240, 0x00100000 }, | ||
803 | { 0x00008244, 0x0010f400 }, | ||
804 | { 0x00008248, 0x00000100 }, | ||
805 | { 0x0000824c, 0x0001e800 }, | ||
806 | { 0x00008250, 0x00000000 }, | ||
807 | { 0x00008254, 0x00000000 }, | ||
808 | { 0x00008258, 0x00000000 }, | ||
809 | { 0x0000825c, 0x400000ff }, | ||
810 | { 0x00008260, 0x00080922 }, | ||
811 | { 0x00008270, 0x00000000 }, | ||
812 | { 0x00008274, 0x40000000 }, | ||
813 | { 0x00008278, 0x003e4180 }, | ||
814 | { 0x0000827c, 0x00000000 }, | ||
815 | { 0x00008284, 0x0000002c }, | ||
816 | { 0x00008288, 0x0000002c }, | ||
817 | { 0x0000828c, 0x00000000 }, | ||
818 | { 0x00008294, 0x00000000 }, | ||
819 | { 0x00008298, 0x00000000 }, | ||
820 | { 0x00008300, 0x00000000 }, | ||
821 | { 0x00008304, 0x00000000 }, | ||
822 | { 0x00008308, 0x00000000 }, | ||
823 | { 0x0000830c, 0x00000000 }, | ||
824 | { 0x00008310, 0x00000000 }, | ||
825 | { 0x00008314, 0x00000000 }, | ||
826 | { 0x00008318, 0x00000000 }, | ||
827 | { 0x00008328, 0x00000000 }, | ||
828 | { 0x0000832c, 0x00000007 }, | ||
829 | { 0x00008330, 0x00000302 }, | ||
830 | { 0x00008334, 0x00000e00 }, | ||
831 | { 0x00008338, 0x00ff0000 }, | ||
832 | { 0x0000833c, 0x00000000 }, | ||
833 | { 0x00008340, 0x000107ff }, | ||
834 | { 0x00009808, 0x00000000 }, | ||
835 | { 0x0000980c, 0xad848e19 }, | ||
836 | { 0x00009810, 0x7d14e000 }, | ||
837 | { 0x00009814, 0x9c0a9f6b }, | ||
838 | { 0x0000981c, 0x00000000 }, | ||
839 | { 0x0000982c, 0x0000a000 }, | ||
840 | { 0x00009830, 0x00000000 }, | ||
841 | { 0x0000983c, 0x00200400 }, | ||
842 | { 0x00009840, 0x206a01ae }, | ||
843 | { 0x0000984c, 0x1284233c }, | ||
844 | { 0x00009854, 0x00000859 }, | ||
845 | { 0x00009900, 0x00000000 }, | ||
846 | { 0x00009904, 0x00000000 }, | ||
847 | { 0x00009908, 0x00000000 }, | ||
848 | { 0x0000990c, 0x00000000 }, | ||
849 | { 0x0000991c, 0x10000fff }, | ||
850 | { 0x00009920, 0x05100000 }, | ||
851 | { 0x0000a920, 0x05100000 }, | ||
852 | { 0x0000b920, 0x05100000 }, | ||
853 | { 0x00009928, 0x00000001 }, | ||
854 | { 0x0000992c, 0x00000004 }, | ||
855 | { 0x00009934, 0x1e1f2022 }, | ||
856 | { 0x00009938, 0x0a0b0c0d }, | ||
857 | { 0x0000993c, 0x00000000 }, | ||
858 | { 0x00009948, 0x9280b212 }, | ||
859 | { 0x0000994c, 0x00020028 }, | ||
860 | { 0x00009954, 0x5f3ca3de }, | ||
861 | { 0x00009958, 0x2108ecff }, | ||
862 | { 0x00009940, 0x00750604 }, | ||
863 | { 0x0000c95c, 0x004b6a8e }, | ||
864 | { 0x00009970, 0x190fb515 }, | ||
865 | { 0x00009974, 0x00000000 }, | ||
866 | { 0x00009978, 0x00000001 }, | ||
867 | { 0x0000997c, 0x00000000 }, | ||
868 | { 0x00009980, 0x00000000 }, | ||
869 | { 0x00009984, 0x00000000 }, | ||
870 | { 0x00009988, 0x00000000 }, | ||
871 | { 0x0000998c, 0x00000000 }, | ||
872 | { 0x00009990, 0x00000000 }, | ||
873 | { 0x00009994, 0x00000000 }, | ||
874 | { 0x00009998, 0x00000000 }, | ||
875 | { 0x0000999c, 0x00000000 }, | ||
876 | { 0x000099a0, 0x00000000 }, | ||
877 | { 0x000099a4, 0x00000001 }, | ||
878 | { 0x000099a8, 0x201fff00 }, | ||
879 | { 0x000099ac, 0x006f0000 }, | ||
880 | { 0x000099b0, 0x03051000 }, | ||
881 | { 0x000099dc, 0x00000000 }, | ||
882 | { 0x000099e0, 0x00000200 }, | ||
883 | { 0x000099e4, 0xaaaaaaaa }, | ||
884 | { 0x000099e8, 0x3c466478 }, | ||
885 | { 0x000099ec, 0x0cc80caa }, | ||
886 | { 0x000099fc, 0x00001042 }, | ||
887 | { 0x00009b00, 0x00000000 }, | ||
888 | { 0x00009b04, 0x00000001 }, | ||
889 | { 0x00009b08, 0x00000002 }, | ||
890 | { 0x00009b0c, 0x00000003 }, | ||
891 | { 0x00009b10, 0x00000004 }, | ||
892 | { 0x00009b14, 0x00000005 }, | ||
893 | { 0x00009b18, 0x00000008 }, | ||
894 | { 0x00009b1c, 0x00000009 }, | ||
895 | { 0x00009b20, 0x0000000a }, | ||
896 | { 0x00009b24, 0x0000000b }, | ||
897 | { 0x00009b28, 0x0000000c }, | ||
898 | { 0x00009b2c, 0x0000000d }, | ||
899 | { 0x00009b30, 0x00000010 }, | ||
900 | { 0x00009b34, 0x00000011 }, | ||
901 | { 0x00009b38, 0x00000012 }, | ||
902 | { 0x00009b3c, 0x00000013 }, | ||
903 | { 0x00009b40, 0x00000014 }, | ||
904 | { 0x00009b44, 0x00000015 }, | ||
905 | { 0x00009b48, 0x00000018 }, | ||
906 | { 0x00009b4c, 0x00000019 }, | ||
907 | { 0x00009b50, 0x0000001a }, | ||
908 | { 0x00009b54, 0x0000001b }, | ||
909 | { 0x00009b58, 0x0000001c }, | ||
910 | { 0x00009b5c, 0x0000001d }, | ||
911 | { 0x00009b60, 0x00000020 }, | ||
912 | { 0x00009b64, 0x00000021 }, | ||
913 | { 0x00009b68, 0x00000022 }, | ||
914 | { 0x00009b6c, 0x00000023 }, | ||
915 | { 0x00009b70, 0x00000024 }, | ||
916 | { 0x00009b74, 0x00000025 }, | ||
917 | { 0x00009b78, 0x00000028 }, | ||
918 | { 0x00009b7c, 0x00000029 }, | ||
919 | { 0x00009b80, 0x0000002a }, | ||
920 | { 0x00009b84, 0x0000002b }, | ||
921 | { 0x00009b88, 0x0000002c }, | ||
922 | { 0x00009b8c, 0x0000002d }, | ||
923 | { 0x00009b90, 0x00000030 }, | ||
924 | { 0x00009b94, 0x00000031 }, | ||
925 | { 0x00009b98, 0x00000032 }, | ||
926 | { 0x00009b9c, 0x00000033 }, | ||
927 | { 0x00009ba0, 0x00000034 }, | ||
928 | { 0x00009ba4, 0x00000035 }, | ||
929 | { 0x00009ba8, 0x00000035 }, | ||
930 | { 0x00009bac, 0x00000035 }, | ||
931 | { 0x00009bb0, 0x00000035 }, | ||
932 | { 0x00009bb4, 0x00000035 }, | ||
933 | { 0x00009bb8, 0x00000035 }, | ||
934 | { 0x00009bbc, 0x00000035 }, | ||
935 | { 0x00009bc0, 0x00000035 }, | ||
936 | { 0x00009bc4, 0x00000035 }, | ||
937 | { 0x00009bc8, 0x00000035 }, | ||
938 | { 0x00009bcc, 0x00000035 }, | ||
939 | { 0x00009bd0, 0x00000035 }, | ||
940 | { 0x00009bd4, 0x00000035 }, | ||
941 | { 0x00009bd8, 0x00000035 }, | ||
942 | { 0x00009bdc, 0x00000035 }, | ||
943 | { 0x00009be0, 0x00000035 }, | ||
944 | { 0x00009be4, 0x00000035 }, | ||
945 | { 0x00009be8, 0x00000035 }, | ||
946 | { 0x00009bec, 0x00000035 }, | ||
947 | { 0x00009bf0, 0x00000035 }, | ||
948 | { 0x00009bf4, 0x00000035 }, | ||
949 | { 0x00009bf8, 0x00000010 }, | ||
950 | { 0x00009bfc, 0x0000001a }, | ||
951 | { 0x0000a210, 0x40806333 }, | ||
952 | { 0x0000a214, 0x00106c10 }, | ||
953 | { 0x0000a218, 0x009c4060 }, | ||
954 | { 0x0000a220, 0x018830c6 }, | ||
955 | { 0x0000a224, 0x00000400 }, | ||
956 | { 0x0000a228, 0x001a0bb5 }, | ||
957 | { 0x0000a22c, 0x00000000 }, | ||
958 | { 0x0000a234, 0x20202020 }, | ||
959 | { 0x0000a238, 0x20202020 }, | ||
960 | { 0x0000a23c, 0x13c889af }, | ||
961 | { 0x0000a240, 0x38490a20 }, | ||
962 | { 0x0000a244, 0x00007bb6 }, | ||
963 | { 0x0000a248, 0x0fff3ffc }, | ||
964 | { 0x0000a24c, 0x00000001 }, | ||
965 | { 0x0000a250, 0x0000e000 }, | ||
966 | { 0x0000a254, 0x00000000 }, | ||
967 | { 0x0000a258, 0x0cc75380 }, | ||
968 | { 0x0000a25c, 0x0f0f0f01 }, | ||
969 | { 0x0000a260, 0xdfa91f01 }, | ||
970 | { 0x0000a268, 0x00000001 }, | ||
971 | { 0x0000a26c, 0x0ebae9c6 }, | ||
972 | { 0x0000b26c, 0x0ebae9c6 }, | ||
973 | { 0x0000c26c, 0x0ebae9c6 }, | ||
974 | { 0x0000d270, 0x00820820 }, | ||
975 | { 0x0000a278, 0x1ce739ce }, | ||
976 | { 0x0000a27c, 0x050701ce }, | ||
977 | { 0x0000a338, 0x00000000 }, | ||
978 | { 0x0000a33c, 0x00000000 }, | ||
979 | { 0x0000a340, 0x00000000 }, | ||
980 | { 0x0000a344, 0x00000000 }, | ||
981 | { 0x0000a348, 0x3fffffff }, | ||
982 | { 0x0000a34c, 0x3fffffff }, | ||
983 | { 0x0000a350, 0x3fffffff }, | ||
984 | { 0x0000a354, 0x0003ffff }, | ||
985 | { 0x0000a358, 0x79bfaa03 }, | ||
986 | { 0x0000d35c, 0x07ffffef }, | ||
987 | { 0x0000d360, 0x0fffffe7 }, | ||
988 | { 0x0000d364, 0x17ffffe5 }, | ||
989 | { 0x0000d368, 0x1fffffe4 }, | ||
990 | { 0x0000d36c, 0x37ffffe3 }, | ||
991 | { 0x0000d370, 0x3fffffe3 }, | ||
992 | { 0x0000d374, 0x57ffffe3 }, | ||
993 | { 0x0000d378, 0x5fffffe2 }, | ||
994 | { 0x0000d37c, 0x7fffffe2 }, | ||
995 | { 0x0000d380, 0x7f3c7bba }, | ||
996 | { 0x0000d384, 0xf3307ff0 }, | ||
997 | { 0x0000a388, 0x0c000000 }, | ||
998 | { 0x0000a38c, 0x20202020 }, | ||
999 | { 0x0000a390, 0x20202020 }, | ||
1000 | { 0x0000a394, 0x1ce739ce }, | ||
1001 | { 0x0000a398, 0x000001ce }, | ||
1002 | { 0x0000a39c, 0x00000001 }, | ||
1003 | { 0x0000a3a0, 0x00000000 }, | ||
1004 | { 0x0000a3a4, 0x00000000 }, | ||
1005 | { 0x0000a3a8, 0x00000000 }, | ||
1006 | { 0x0000a3ac, 0x00000000 }, | ||
1007 | { 0x0000a3b0, 0x00000000 }, | ||
1008 | { 0x0000a3b4, 0x00000000 }, | ||
1009 | { 0x0000a3b8, 0x00000000 }, | ||
1010 | { 0x0000a3bc, 0x00000000 }, | ||
1011 | { 0x0000a3c0, 0x00000000 }, | ||
1012 | { 0x0000a3c4, 0x00000000 }, | ||
1013 | { 0x0000a3c8, 0x00000246 }, | ||
1014 | { 0x0000a3cc, 0x20202020 }, | ||
1015 | { 0x0000a3d0, 0x20202020 }, | ||
1016 | { 0x0000a3d4, 0x20202020 }, | ||
1017 | { 0x0000a3dc, 0x1ce739ce }, | ||
1018 | { 0x0000a3e0, 0x000001ce }, | ||
1019 | }; | ||
1020 | |||
1021 | static const u32 ar5416Bank0_9160[][2] = { | ||
1022 | { 0x000098b0, 0x1e5795e5 }, | ||
1023 | { 0x000098e0, 0x02008020 }, | ||
1024 | }; | ||
1025 | |||
1026 | static const u32 ar5416BB_RfGain_9160[][3] = { | ||
1027 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
1028 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
1029 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
1030 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
1031 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
1032 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
1033 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
1034 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
1035 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
1036 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
1037 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
1038 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
1039 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
1040 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
1041 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
1042 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
1043 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
1044 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
1045 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
1046 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
1047 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
1048 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
1049 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
1050 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
1051 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
1052 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
1053 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
1054 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
1055 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
1056 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
1057 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
1058 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
1059 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
1060 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
1061 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
1062 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
1063 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
1064 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
1065 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
1066 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
1067 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
1068 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
1069 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
1070 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
1071 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
1072 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
1073 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
1074 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
1075 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
1076 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
1077 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
1078 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
1079 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
1080 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
1081 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
1082 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
1083 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
1084 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
1085 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
1086 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
1087 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
1088 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
1089 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
1090 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
1091 | }; | ||
1092 | |||
1093 | static const u32 ar5416Bank1_9160[][2] = { | ||
1094 | { 0x000098b0, 0x02108421 }, | ||
1095 | { 0x000098ec, 0x00000008 }, | ||
1096 | }; | ||
1097 | |||
1098 | static const u32 ar5416Bank2_9160[][2] = { | ||
1099 | { 0x000098b0, 0x0e73ff17 }, | ||
1100 | { 0x000098e0, 0x00000420 }, | ||
1101 | }; | ||
1102 | |||
1103 | static const u32 ar5416Bank3_9160[][3] = { | ||
1104 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
1105 | }; | ||
1106 | |||
1107 | static const u32 ar5416Bank6_9160[][3] = { | ||
1108 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1109 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1110 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1111 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1112 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1113 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1114 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1115 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1116 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1117 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1118 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1119 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1120 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1121 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1122 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1123 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1124 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1125 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1126 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1127 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1128 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1129 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
1130 | { 0x0000989c, 0x0014008f, 0x0014008f }, | ||
1131 | { 0x0000989c, 0x00c40003, 0x00c40003 }, | ||
1132 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1133 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1134 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1135 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1136 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1137 | { 0x0000989c, 0x000000f1, 0x000000f1 }, | ||
1138 | { 0x0000989c, 0x00002081, 0x00002081 }, | ||
1139 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1140 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1141 | }; | ||
1142 | |||
1143 | static const u32 ar5416Bank6TPC_9160[][3] = { | ||
1144 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1145 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1146 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1147 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1148 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1149 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1150 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1151 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1152 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1153 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1154 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1155 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1156 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1157 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1158 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1159 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1160 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1161 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1162 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1163 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1164 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1165 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
1166 | { 0x0000989c, 0x2014008f, 0x2014008f }, | ||
1167 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
1168 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1169 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1170 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1171 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1172 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1173 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
1174 | { 0x0000989c, 0x00007080, 0x00007080 }, | ||
1175 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1176 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1177 | }; | ||
1178 | |||
1179 | static const u32 ar5416Bank7_9160[][2] = { | ||
1180 | { 0x0000989c, 0x00000500 }, | ||
1181 | { 0x0000989c, 0x00000800 }, | ||
1182 | { 0x000098cc, 0x0000000e }, | ||
1183 | }; | ||
1184 | |||
1185 | static const u32 ar5416Addac_9160[][2] = { | ||
1186 | {0x0000989c, 0x00000000 }, | ||
1187 | {0x0000989c, 0x00000000 }, | ||
1188 | {0x0000989c, 0x00000000 }, | ||
1189 | {0x0000989c, 0x00000000 }, | ||
1190 | {0x0000989c, 0x00000000 }, | ||
1191 | {0x0000989c, 0x00000000 }, | ||
1192 | {0x0000989c, 0x000000c0 }, | ||
1193 | {0x0000989c, 0x00000018 }, | ||
1194 | {0x0000989c, 0x00000004 }, | ||
1195 | {0x0000989c, 0x00000000 }, | ||
1196 | {0x0000989c, 0x00000000 }, | ||
1197 | {0x0000989c, 0x00000000 }, | ||
1198 | {0x0000989c, 0x00000000 }, | ||
1199 | {0x0000989c, 0x00000000 }, | ||
1200 | {0x0000989c, 0x00000000 }, | ||
1201 | {0x0000989c, 0x00000000 }, | ||
1202 | {0x0000989c, 0x00000000 }, | ||
1203 | {0x0000989c, 0x00000000 }, | ||
1204 | {0x0000989c, 0x00000000 }, | ||
1205 | {0x0000989c, 0x00000000 }, | ||
1206 | {0x0000989c, 0x00000000 }, | ||
1207 | {0x0000989c, 0x000000c0 }, | ||
1208 | {0x0000989c, 0x00000019 }, | ||
1209 | {0x0000989c, 0x00000004 }, | ||
1210 | {0x0000989c, 0x00000000 }, | ||
1211 | {0x0000989c, 0x00000000 }, | ||
1212 | {0x0000989c, 0x00000000 }, | ||
1213 | {0x0000989c, 0x00000004 }, | ||
1214 | {0x0000989c, 0x00000003 }, | ||
1215 | {0x0000989c, 0x00000008 }, | ||
1216 | {0x0000989c, 0x00000000 }, | ||
1217 | {0x000098cc, 0x00000000 }, | ||
1218 | }; | ||
1219 | |||
1220 | static const u32 ar5416Addac_91601_1[][2] = { | ||
1221 | {0x0000989c, 0x00000000 }, | ||
1222 | {0x0000989c, 0x00000000 }, | ||
1223 | {0x0000989c, 0x00000000 }, | ||
1224 | {0x0000989c, 0x00000000 }, | ||
1225 | {0x0000989c, 0x00000000 }, | ||
1226 | {0x0000989c, 0x00000000 }, | ||
1227 | {0x0000989c, 0x000000c0 }, | ||
1228 | {0x0000989c, 0x00000018 }, | ||
1229 | {0x0000989c, 0x00000004 }, | ||
1230 | {0x0000989c, 0x00000000 }, | ||
1231 | {0x0000989c, 0x00000000 }, | ||
1232 | {0x0000989c, 0x00000000 }, | ||
1233 | {0x0000989c, 0x00000000 }, | ||
1234 | {0x0000989c, 0x00000000 }, | ||
1235 | {0x0000989c, 0x00000000 }, | ||
1236 | {0x0000989c, 0x00000000 }, | ||
1237 | {0x0000989c, 0x00000000 }, | ||
1238 | {0x0000989c, 0x00000000 }, | ||
1239 | {0x0000989c, 0x00000000 }, | ||
1240 | {0x0000989c, 0x00000000 }, | ||
1241 | {0x0000989c, 0x00000000 }, | ||
1242 | {0x0000989c, 0x000000c0 }, | ||
1243 | {0x0000989c, 0x00000019 }, | ||
1244 | {0x0000989c, 0x00000004 }, | ||
1245 | {0x0000989c, 0x00000000 }, | ||
1246 | {0x0000989c, 0x00000000 }, | ||
1247 | {0x0000989c, 0x00000000 }, | ||
1248 | {0x0000989c, 0x00000000 }, | ||
1249 | {0x0000989c, 0x00000000 }, | ||
1250 | {0x0000989c, 0x00000000 }, | ||
1251 | {0x0000989c, 0x00000000 }, | ||
1252 | {0x000098cc, 0x00000000 }, | ||
1253 | }; | ||
1254 | |||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c new file mode 100644 index 000000000000..5fdbb53b47e0 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c | |||
@@ -0,0 +1,1000 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | #include "hw-ops.h" | ||
19 | #include "ar9002_phy.h" | ||
20 | |||
21 | #define AR9285_CLCAL_REDO_THRESH 1 | ||
22 | |||
23 | static void ar9002_hw_setup_calibration(struct ath_hw *ah, | ||
24 | struct ath9k_cal_list *currCal) | ||
25 | { | ||
26 | struct ath_common *common = ath9k_hw_common(ah); | ||
27 | |||
28 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), | ||
29 | AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, | ||
30 | currCal->calData->calCountMax); | ||
31 | |||
32 | switch (currCal->calData->calType) { | ||
33 | case IQ_MISMATCH_CAL: | ||
34 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | ||
35 | ath_print(common, ATH_DBG_CALIBRATE, | ||
36 | "starting IQ Mismatch Calibration\n"); | ||
37 | break; | ||
38 | case ADC_GAIN_CAL: | ||
39 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); | ||
40 | ath_print(common, ATH_DBG_CALIBRATE, | ||
41 | "starting ADC Gain Calibration\n"); | ||
42 | break; | ||
43 | case ADC_DC_CAL: | ||
44 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); | ||
45 | ath_print(common, ATH_DBG_CALIBRATE, | ||
46 | "starting ADC DC Calibration\n"); | ||
47 | break; | ||
48 | case ADC_DC_INIT_CAL: | ||
49 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); | ||
50 | ath_print(common, ATH_DBG_CALIBRATE, | ||
51 | "starting Init ADC DC Calibration\n"); | ||
52 | break; | ||
53 | case TEMP_COMP_CAL: | ||
54 | break; /* Not supported */ | ||
55 | } | ||
56 | |||
57 | REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), | ||
58 | AR_PHY_TIMING_CTRL4_DO_CAL); | ||
59 | } | ||
60 | |||
61 | static bool ar9002_hw_per_calibration(struct ath_hw *ah, | ||
62 | struct ath9k_channel *ichan, | ||
63 | u8 rxchainmask, | ||
64 | struct ath9k_cal_list *currCal) | ||
65 | { | ||
66 | bool iscaldone = false; | ||
67 | |||
68 | if (currCal->calState == CAL_RUNNING) { | ||
69 | if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & | ||
70 | AR_PHY_TIMING_CTRL4_DO_CAL)) { | ||
71 | |||
72 | currCal->calData->calCollect(ah); | ||
73 | ah->cal_samples++; | ||
74 | |||
75 | if (ah->cal_samples >= | ||
76 | currCal->calData->calNumSamples) { | ||
77 | int i, numChains = 0; | ||
78 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
79 | if (rxchainmask & (1 << i)) | ||
80 | numChains++; | ||
81 | } | ||
82 | |||
83 | currCal->calData->calPostProc(ah, numChains); | ||
84 | ichan->CalValid |= currCal->calData->calType; | ||
85 | currCal->calState = CAL_DONE; | ||
86 | iscaldone = true; | ||
87 | } else { | ||
88 | ar9002_hw_setup_calibration(ah, currCal); | ||
89 | } | ||
90 | } | ||
91 | } else if (!(ichan->CalValid & currCal->calData->calType)) { | ||
92 | ath9k_hw_reset_calibration(ah, currCal); | ||
93 | } | ||
94 | |||
95 | return iscaldone; | ||
96 | } | ||
97 | |||
98 | /* Assumes you are talking about the currently configured channel */ | ||
99 | static bool ar9002_hw_iscal_supported(struct ath_hw *ah, | ||
100 | enum ath9k_cal_types calType) | ||
101 | { | ||
102 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
103 | |||
104 | switch (calType & ah->supp_cals) { | ||
105 | case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ | ||
106 | return true; | ||
107 | case ADC_GAIN_CAL: | ||
108 | case ADC_DC_CAL: | ||
109 | if (!(conf->channel->band == IEEE80211_BAND_2GHZ && | ||
110 | conf_is_ht20(conf))) | ||
111 | return true; | ||
112 | break; | ||
113 | } | ||
114 | return false; | ||
115 | } | ||
116 | |||
117 | static void ar9002_hw_iqcal_collect(struct ath_hw *ah) | ||
118 | { | ||
119 | int i; | ||
120 | |||
121 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
122 | ah->totalPowerMeasI[i] += | ||
123 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
124 | ah->totalPowerMeasQ[i] += | ||
125 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
126 | ah->totalIqCorrMeas[i] += | ||
127 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
128 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
129 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | ||
130 | ah->cal_samples, i, ah->totalPowerMeasI[i], | ||
131 | ah->totalPowerMeasQ[i], | ||
132 | ah->totalIqCorrMeas[i]); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | static void ar9002_hw_adc_gaincal_collect(struct ath_hw *ah) | ||
137 | { | ||
138 | int i; | ||
139 | |||
140 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
141 | ah->totalAdcIOddPhase[i] += | ||
142 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
143 | ah->totalAdcIEvenPhase[i] += | ||
144 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
145 | ah->totalAdcQOddPhase[i] += | ||
146 | REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
147 | ah->totalAdcQEvenPhase[i] += | ||
148 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
149 | |||
150 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
151 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
152 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
153 | ah->cal_samples, i, | ||
154 | ah->totalAdcIOddPhase[i], | ||
155 | ah->totalAdcIEvenPhase[i], | ||
156 | ah->totalAdcQOddPhase[i], | ||
157 | ah->totalAdcQEvenPhase[i]); | ||
158 | } | ||
159 | } | ||
160 | |||
161 | static void ar9002_hw_adc_dccal_collect(struct ath_hw *ah) | ||
162 | { | ||
163 | int i; | ||
164 | |||
165 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
166 | ah->totalAdcDcOffsetIOddPhase[i] += | ||
167 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
168 | ah->totalAdcDcOffsetIEvenPhase[i] += | ||
169 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
170 | ah->totalAdcDcOffsetQOddPhase[i] += | ||
171 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
172 | ah->totalAdcDcOffsetQEvenPhase[i] += | ||
173 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
174 | |||
175 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
176 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
177 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
178 | ah->cal_samples, i, | ||
179 | ah->totalAdcDcOffsetIOddPhase[i], | ||
180 | ah->totalAdcDcOffsetIEvenPhase[i], | ||
181 | ah->totalAdcDcOffsetQOddPhase[i], | ||
182 | ah->totalAdcDcOffsetQEvenPhase[i]); | ||
183 | } | ||
184 | } | ||
185 | |||
186 | static void ar9002_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | ||
187 | { | ||
188 | struct ath_common *common = ath9k_hw_common(ah); | ||
189 | u32 powerMeasQ, powerMeasI, iqCorrMeas; | ||
190 | u32 qCoffDenom, iCoffDenom; | ||
191 | int32_t qCoff, iCoff; | ||
192 | int iqCorrNeg, i; | ||
193 | |||
194 | for (i = 0; i < numChains; i++) { | ||
195 | powerMeasI = ah->totalPowerMeasI[i]; | ||
196 | powerMeasQ = ah->totalPowerMeasQ[i]; | ||
197 | iqCorrMeas = ah->totalIqCorrMeas[i]; | ||
198 | |||
199 | ath_print(common, ATH_DBG_CALIBRATE, | ||
200 | "Starting IQ Cal and Correction for Chain %d\n", | ||
201 | i); | ||
202 | |||
203 | ath_print(common, ATH_DBG_CALIBRATE, | ||
204 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | ||
205 | i, ah->totalIqCorrMeas[i]); | ||
206 | |||
207 | iqCorrNeg = 0; | ||
208 | |||
209 | if (iqCorrMeas > 0x80000000) { | ||
210 | iqCorrMeas = (0xffffffff - iqCorrMeas) + 1; | ||
211 | iqCorrNeg = 1; | ||
212 | } | ||
213 | |||
214 | ath_print(common, ATH_DBG_CALIBRATE, | ||
215 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | ||
216 | ath_print(common, ATH_DBG_CALIBRATE, | ||
217 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | ||
218 | ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | ||
219 | iqCorrNeg); | ||
220 | |||
221 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; | ||
222 | qCoffDenom = powerMeasQ / 64; | ||
223 | |||
224 | if ((powerMeasQ != 0) && (iCoffDenom != 0) && | ||
225 | (qCoffDenom != 0)) { | ||
226 | iCoff = iqCorrMeas / iCoffDenom; | ||
227 | qCoff = powerMeasI / qCoffDenom - 64; | ||
228 | ath_print(common, ATH_DBG_CALIBRATE, | ||
229 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
230 | ath_print(common, ATH_DBG_CALIBRATE, | ||
231 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | ||
232 | |||
233 | iCoff = iCoff & 0x3f; | ||
234 | ath_print(common, ATH_DBG_CALIBRATE, | ||
235 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
236 | if (iqCorrNeg == 0x0) | ||
237 | iCoff = 0x40 - iCoff; | ||
238 | |||
239 | if (qCoff > 15) | ||
240 | qCoff = 15; | ||
241 | else if (qCoff <= -16) | ||
242 | qCoff = 16; | ||
243 | |||
244 | ath_print(common, ATH_DBG_CALIBRATE, | ||
245 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | ||
246 | i, iCoff, qCoff); | ||
247 | |||
248 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
249 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, | ||
250 | iCoff); | ||
251 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
252 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, | ||
253 | qCoff); | ||
254 | ath_print(common, ATH_DBG_CALIBRATE, | ||
255 | "IQ Cal and Correction done for Chain %d\n", | ||
256 | i); | ||
257 | } | ||
258 | } | ||
259 | |||
260 | REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), | ||
261 | AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); | ||
262 | } | ||
263 | |||
264 | static void ar9002_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | ||
265 | { | ||
266 | struct ath_common *common = ath9k_hw_common(ah); | ||
267 | u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; | ||
268 | u32 qGainMismatch, iGainMismatch, val, i; | ||
269 | |||
270 | for (i = 0; i < numChains; i++) { | ||
271 | iOddMeasOffset = ah->totalAdcIOddPhase[i]; | ||
272 | iEvenMeasOffset = ah->totalAdcIEvenPhase[i]; | ||
273 | qOddMeasOffset = ah->totalAdcQOddPhase[i]; | ||
274 | qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; | ||
275 | |||
276 | ath_print(common, ATH_DBG_CALIBRATE, | ||
277 | "Starting ADC Gain Cal for Chain %d\n", i); | ||
278 | |||
279 | ath_print(common, ATH_DBG_CALIBRATE, | ||
280 | "Chn %d pwr_meas_odd_i = 0x%08x\n", i, | ||
281 | iOddMeasOffset); | ||
282 | ath_print(common, ATH_DBG_CALIBRATE, | ||
283 | "Chn %d pwr_meas_even_i = 0x%08x\n", i, | ||
284 | iEvenMeasOffset); | ||
285 | ath_print(common, ATH_DBG_CALIBRATE, | ||
286 | "Chn %d pwr_meas_odd_q = 0x%08x\n", i, | ||
287 | qOddMeasOffset); | ||
288 | ath_print(common, ATH_DBG_CALIBRATE, | ||
289 | "Chn %d pwr_meas_even_q = 0x%08x\n", i, | ||
290 | qEvenMeasOffset); | ||
291 | |||
292 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { | ||
293 | iGainMismatch = | ||
294 | ((iEvenMeasOffset * 32) / | ||
295 | iOddMeasOffset) & 0x3f; | ||
296 | qGainMismatch = | ||
297 | ((qOddMeasOffset * 32) / | ||
298 | qEvenMeasOffset) & 0x3f; | ||
299 | |||
300 | ath_print(common, ATH_DBG_CALIBRATE, | ||
301 | "Chn %d gain_mismatch_i = 0x%08x\n", i, | ||
302 | iGainMismatch); | ||
303 | ath_print(common, ATH_DBG_CALIBRATE, | ||
304 | "Chn %d gain_mismatch_q = 0x%08x\n", i, | ||
305 | qGainMismatch); | ||
306 | |||
307 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
308 | val &= 0xfffff000; | ||
309 | val |= (qGainMismatch) | (iGainMismatch << 6); | ||
310 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
311 | |||
312 | ath_print(common, ATH_DBG_CALIBRATE, | ||
313 | "ADC Gain Cal done for Chain %d\n", i); | ||
314 | } | ||
315 | } | ||
316 | |||
317 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
318 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
319 | AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); | ||
320 | } | ||
321 | |||
322 | static void ar9002_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) | ||
323 | { | ||
324 | struct ath_common *common = ath9k_hw_common(ah); | ||
325 | u32 iOddMeasOffset, iEvenMeasOffset, val, i; | ||
326 | int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; | ||
327 | const struct ath9k_percal_data *calData = | ||
328 | ah->cal_list_curr->calData; | ||
329 | u32 numSamples = | ||
330 | (1 << (calData->calCountMax + 5)) * calData->calNumSamples; | ||
331 | |||
332 | for (i = 0; i < numChains; i++) { | ||
333 | iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i]; | ||
334 | iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i]; | ||
335 | qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; | ||
336 | qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; | ||
337 | |||
338 | ath_print(common, ATH_DBG_CALIBRATE, | ||
339 | "Starting ADC DC Offset Cal for Chain %d\n", i); | ||
340 | |||
341 | ath_print(common, ATH_DBG_CALIBRATE, | ||
342 | "Chn %d pwr_meas_odd_i = %d\n", i, | ||
343 | iOddMeasOffset); | ||
344 | ath_print(common, ATH_DBG_CALIBRATE, | ||
345 | "Chn %d pwr_meas_even_i = %d\n", i, | ||
346 | iEvenMeasOffset); | ||
347 | ath_print(common, ATH_DBG_CALIBRATE, | ||
348 | "Chn %d pwr_meas_odd_q = %d\n", i, | ||
349 | qOddMeasOffset); | ||
350 | ath_print(common, ATH_DBG_CALIBRATE, | ||
351 | "Chn %d pwr_meas_even_q = %d\n", i, | ||
352 | qEvenMeasOffset); | ||
353 | |||
354 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / | ||
355 | numSamples) & 0x1ff; | ||
356 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / | ||
357 | numSamples) & 0x1ff; | ||
358 | |||
359 | ath_print(common, ATH_DBG_CALIBRATE, | ||
360 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, | ||
361 | iDcMismatch); | ||
362 | ath_print(common, ATH_DBG_CALIBRATE, | ||
363 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, | ||
364 | qDcMismatch); | ||
365 | |||
366 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
367 | val &= 0xc0000fff; | ||
368 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); | ||
369 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
370 | |||
371 | ath_print(common, ATH_DBG_CALIBRATE, | ||
372 | "ADC DC Offset Cal done for Chain %d\n", i); | ||
373 | } | ||
374 | |||
375 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
376 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
377 | AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); | ||
378 | } | ||
379 | |||
380 | static void ar9287_hw_olc_temp_compensation(struct ath_hw *ah) | ||
381 | { | ||
382 | u32 rddata; | ||
383 | int32_t delta, currPDADC, slope; | ||
384 | |||
385 | rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); | ||
386 | currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); | ||
387 | |||
388 | if (ah->initPDADC == 0 || currPDADC == 0) { | ||
389 | /* | ||
390 | * Zero value indicates that no frames have been transmitted | ||
391 | * yet, can't do temperature compensation until frames are | ||
392 | * transmitted. | ||
393 | */ | ||
394 | return; | ||
395 | } else { | ||
396 | slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE); | ||
397 | |||
398 | if (slope == 0) { /* to avoid divide by zero case */ | ||
399 | delta = 0; | ||
400 | } else { | ||
401 | delta = ((currPDADC - ah->initPDADC)*4) / slope; | ||
402 | } | ||
403 | REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11, | ||
404 | AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); | ||
405 | REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11, | ||
406 | AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | static void ar9280_hw_olc_temp_compensation(struct ath_hw *ah) | ||
411 | { | ||
412 | u32 rddata, i; | ||
413 | int delta, currPDADC, regval; | ||
414 | |||
415 | rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); | ||
416 | currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); | ||
417 | |||
418 | if (ah->initPDADC == 0 || currPDADC == 0) | ||
419 | return; | ||
420 | |||
421 | if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) | ||
422 | delta = (currPDADC - ah->initPDADC + 4) / 8; | ||
423 | else | ||
424 | delta = (currPDADC - ah->initPDADC + 5) / 10; | ||
425 | |||
426 | if (delta != ah->PDADCdelta) { | ||
427 | ah->PDADCdelta = delta; | ||
428 | for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { | ||
429 | regval = ah->originalGain[i] - delta; | ||
430 | if (regval < 0) | ||
431 | regval = 0; | ||
432 | |||
433 | REG_RMW_FIELD(ah, | ||
434 | AR_PHY_TX_GAIN_TBL1 + i * 4, | ||
435 | AR_PHY_TX_GAIN, regval); | ||
436 | } | ||
437 | } | ||
438 | } | ||
439 | |||
440 | static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset) | ||
441 | { | ||
442 | u32 regVal; | ||
443 | unsigned int i; | ||
444 | u32 regList[][2] = { | ||
445 | { 0x786c, 0 }, | ||
446 | { 0x7854, 0 }, | ||
447 | { 0x7820, 0 }, | ||
448 | { 0x7824, 0 }, | ||
449 | { 0x7868, 0 }, | ||
450 | { 0x783c, 0 }, | ||
451 | { 0x7838, 0 } , | ||
452 | { 0x7828, 0 } , | ||
453 | }; | ||
454 | |||
455 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
456 | regList[i][1] = REG_READ(ah, regList[i][0]); | ||
457 | |||
458 | regVal = REG_READ(ah, 0x7834); | ||
459 | regVal &= (~(0x1)); | ||
460 | REG_WRITE(ah, 0x7834, regVal); | ||
461 | regVal = REG_READ(ah, 0x9808); | ||
462 | regVal |= (0x1 << 27); | ||
463 | REG_WRITE(ah, 0x9808, regVal); | ||
464 | |||
465 | /* 786c,b23,1, pwddac=1 */ | ||
466 | REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); | ||
467 | /* 7854, b5,1, pdrxtxbb=1 */ | ||
468 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); | ||
469 | /* 7854, b7,1, pdv2i=1 */ | ||
470 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); | ||
471 | /* 7854, b8,1, pddacinterface=1 */ | ||
472 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); | ||
473 | /* 7824,b12,0, offcal=0 */ | ||
474 | REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); | ||
475 | /* 7838, b1,0, pwddb=0 */ | ||
476 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); | ||
477 | /* 7820,b11,0, enpacal=0 */ | ||
478 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); | ||
479 | /* 7820,b25,1, pdpadrv1=0 */ | ||
480 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0); | ||
481 | /* 7820,b24,0, pdpadrv2=0 */ | ||
482 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0); | ||
483 | /* 7820,b23,0, pdpaout=0 */ | ||
484 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); | ||
485 | /* 783c,b14-16,7, padrvgn2tab_0=7 */ | ||
486 | REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); | ||
487 | /* | ||
488 | * 7838,b29-31,0, padrvgn1tab_0=0 | ||
489 | * does not matter since we turn it off | ||
490 | */ | ||
491 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); | ||
492 | |||
493 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff); | ||
494 | |||
495 | /* Set: | ||
496 | * localmode=1,bmode=1,bmoderxtx=1,synthon=1, | ||
497 | * txon=1,paon=1,oscon=1,synthon_force=1 | ||
498 | */ | ||
499 | REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); | ||
500 | udelay(30); | ||
501 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0); | ||
502 | |||
503 | /* find off_6_1; */ | ||
504 | for (i = 6; i > 0; i--) { | ||
505 | regVal = REG_READ(ah, 0x7834); | ||
506 | regVal |= (1 << (20 + i)); | ||
507 | REG_WRITE(ah, 0x7834, regVal); | ||
508 | udelay(1); | ||
509 | /* regVal = REG_READ(ah, 0x7834); */ | ||
510 | regVal &= (~(0x1 << (20 + i))); | ||
511 | regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9) | ||
512 | << (20 + i)); | ||
513 | REG_WRITE(ah, 0x7834, regVal); | ||
514 | } | ||
515 | |||
516 | regVal = (regVal >> 20) & 0x7f; | ||
517 | |||
518 | /* Update PA cal info */ | ||
519 | if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) { | ||
520 | if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT) | ||
521 | ah->pacal_info.max_skipcount = | ||
522 | 2 * ah->pacal_info.max_skipcount; | ||
523 | ah->pacal_info.skipcount = ah->pacal_info.max_skipcount; | ||
524 | } else { | ||
525 | ah->pacal_info.max_skipcount = 1; | ||
526 | ah->pacal_info.skipcount = 0; | ||
527 | ah->pacal_info.prev_offset = regVal; | ||
528 | } | ||
529 | |||
530 | ENABLE_REGWRITE_BUFFER(ah); | ||
531 | |||
532 | regVal = REG_READ(ah, 0x7834); | ||
533 | regVal |= 0x1; | ||
534 | REG_WRITE(ah, 0x7834, regVal); | ||
535 | regVal = REG_READ(ah, 0x9808); | ||
536 | regVal &= (~(0x1 << 27)); | ||
537 | REG_WRITE(ah, 0x9808, regVal); | ||
538 | |||
539 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
540 | REG_WRITE(ah, regList[i][0], regList[i][1]); | ||
541 | |||
542 | REGWRITE_BUFFER_FLUSH(ah); | ||
543 | DISABLE_REGWRITE_BUFFER(ah); | ||
544 | } | ||
545 | |||
546 | static inline void ar9285_hw_pa_cal(struct ath_hw *ah, bool is_reset) | ||
547 | { | ||
548 | struct ath_common *common = ath9k_hw_common(ah); | ||
549 | u32 regVal; | ||
550 | int i, offset, offs_6_1, offs_0; | ||
551 | u32 ccomp_org, reg_field; | ||
552 | u32 regList[][2] = { | ||
553 | { 0x786c, 0 }, | ||
554 | { 0x7854, 0 }, | ||
555 | { 0x7820, 0 }, | ||
556 | { 0x7824, 0 }, | ||
557 | { 0x7868, 0 }, | ||
558 | { 0x783c, 0 }, | ||
559 | { 0x7838, 0 }, | ||
560 | }; | ||
561 | |||
562 | ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n"); | ||
563 | |||
564 | /* PA CAL is not needed for high power solution */ | ||
565 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == | ||
566 | AR5416_EEP_TXGAIN_HIGH_POWER) | ||
567 | return; | ||
568 | |||
569 | if (AR_SREV_9285_11(ah)) { | ||
570 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); | ||
571 | udelay(10); | ||
572 | } | ||
573 | |||
574 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
575 | regList[i][1] = REG_READ(ah, regList[i][0]); | ||
576 | |||
577 | regVal = REG_READ(ah, 0x7834); | ||
578 | regVal &= (~(0x1)); | ||
579 | REG_WRITE(ah, 0x7834, regVal); | ||
580 | regVal = REG_READ(ah, 0x9808); | ||
581 | regVal |= (0x1 << 27); | ||
582 | REG_WRITE(ah, 0x9808, regVal); | ||
583 | |||
584 | REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); | ||
585 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); | ||
586 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); | ||
587 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); | ||
588 | REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); | ||
589 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); | ||
590 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); | ||
591 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0); | ||
592 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0); | ||
593 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); | ||
594 | REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); | ||
595 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); | ||
596 | ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP); | ||
597 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf); | ||
598 | |||
599 | REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); | ||
600 | udelay(30); | ||
601 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0); | ||
602 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0); | ||
603 | |||
604 | for (i = 6; i > 0; i--) { | ||
605 | regVal = REG_READ(ah, 0x7834); | ||
606 | regVal |= (1 << (19 + i)); | ||
607 | REG_WRITE(ah, 0x7834, regVal); | ||
608 | udelay(1); | ||
609 | regVal = REG_READ(ah, 0x7834); | ||
610 | regVal &= (~(0x1 << (19 + i))); | ||
611 | reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9); | ||
612 | regVal |= (reg_field << (19 + i)); | ||
613 | REG_WRITE(ah, 0x7834, regVal); | ||
614 | } | ||
615 | |||
616 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1); | ||
617 | udelay(1); | ||
618 | reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9); | ||
619 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field); | ||
620 | offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS); | ||
621 | offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP); | ||
622 | |||
623 | offset = (offs_6_1<<1) | offs_0; | ||
624 | offset = offset - 0; | ||
625 | offs_6_1 = offset>>1; | ||
626 | offs_0 = offset & 1; | ||
627 | |||
628 | if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) { | ||
629 | if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT) | ||
630 | ah->pacal_info.max_skipcount = | ||
631 | 2 * ah->pacal_info.max_skipcount; | ||
632 | ah->pacal_info.skipcount = ah->pacal_info.max_skipcount; | ||
633 | } else { | ||
634 | ah->pacal_info.max_skipcount = 1; | ||
635 | ah->pacal_info.skipcount = 0; | ||
636 | ah->pacal_info.prev_offset = offset; | ||
637 | } | ||
638 | |||
639 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1); | ||
640 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0); | ||
641 | |||
642 | regVal = REG_READ(ah, 0x7834); | ||
643 | regVal |= 0x1; | ||
644 | REG_WRITE(ah, 0x7834, regVal); | ||
645 | regVal = REG_READ(ah, 0x9808); | ||
646 | regVal &= (~(0x1 << 27)); | ||
647 | REG_WRITE(ah, 0x9808, regVal); | ||
648 | |||
649 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
650 | REG_WRITE(ah, regList[i][0], regList[i][1]); | ||
651 | |||
652 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org); | ||
653 | |||
654 | if (AR_SREV_9285_11(ah)) | ||
655 | REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); | ||
656 | |||
657 | } | ||
658 | |||
659 | static void ar9002_hw_pa_cal(struct ath_hw *ah, bool is_reset) | ||
660 | { | ||
661 | if (AR_SREV_9271(ah)) { | ||
662 | if (is_reset || !ah->pacal_info.skipcount) | ||
663 | ar9271_hw_pa_cal(ah, is_reset); | ||
664 | else | ||
665 | ah->pacal_info.skipcount--; | ||
666 | } else if (AR_SREV_9285_11_OR_LATER(ah)) { | ||
667 | if (is_reset || !ah->pacal_info.skipcount) | ||
668 | ar9285_hw_pa_cal(ah, is_reset); | ||
669 | else | ||
670 | ah->pacal_info.skipcount--; | ||
671 | } | ||
672 | } | ||
673 | |||
674 | static void ar9002_hw_olc_temp_compensation(struct ath_hw *ah) | ||
675 | { | ||
676 | if (OLC_FOR_AR9287_10_LATER) | ||
677 | ar9287_hw_olc_temp_compensation(ah); | ||
678 | else if (OLC_FOR_AR9280_20_LATER) | ||
679 | ar9280_hw_olc_temp_compensation(ah); | ||
680 | } | ||
681 | |||
682 | static bool ar9002_hw_calibrate(struct ath_hw *ah, | ||
683 | struct ath9k_channel *chan, | ||
684 | u8 rxchainmask, | ||
685 | bool longcal) | ||
686 | { | ||
687 | bool iscaldone = true; | ||
688 | struct ath9k_cal_list *currCal = ah->cal_list_curr; | ||
689 | |||
690 | if (currCal && | ||
691 | (currCal->calState == CAL_RUNNING || | ||
692 | currCal->calState == CAL_WAITING)) { | ||
693 | iscaldone = ar9002_hw_per_calibration(ah, chan, | ||
694 | rxchainmask, currCal); | ||
695 | if (iscaldone) { | ||
696 | ah->cal_list_curr = currCal = currCal->calNext; | ||
697 | |||
698 | if (currCal->calState == CAL_WAITING) { | ||
699 | iscaldone = false; | ||
700 | ath9k_hw_reset_calibration(ah, currCal); | ||
701 | } | ||
702 | } | ||
703 | } | ||
704 | |||
705 | /* Do NF cal only at longer intervals */ | ||
706 | if (longcal) { | ||
707 | /* Do periodic PAOffset Cal */ | ||
708 | ar9002_hw_pa_cal(ah, false); | ||
709 | ar9002_hw_olc_temp_compensation(ah); | ||
710 | |||
711 | /* | ||
712 | * Get the value from the previous NF cal and update | ||
713 | * history buffer. | ||
714 | */ | ||
715 | ath9k_hw_getnf(ah, chan); | ||
716 | |||
717 | /* | ||
718 | * Load the NF from history buffer of the current channel. | ||
719 | * NF is slow time-variant, so it is OK to use a historical | ||
720 | * value. | ||
721 | */ | ||
722 | ath9k_hw_loadnf(ah, ah->curchan); | ||
723 | |||
724 | ath9k_hw_start_nfcal(ah); | ||
725 | } | ||
726 | |||
727 | return iscaldone; | ||
728 | } | ||
729 | |||
730 | /* Carrier leakage Calibration fix */ | ||
731 | static bool ar9285_hw_cl_cal(struct ath_hw *ah, struct ath9k_channel *chan) | ||
732 | { | ||
733 | struct ath_common *common = ath9k_hw_common(ah); | ||
734 | |||
735 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
736 | if (IS_CHAN_HT20(chan)) { | ||
737 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); | ||
738 | REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); | ||
739 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
740 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
741 | REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); | ||
742 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | ||
743 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
744 | AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { | ||
745 | ath_print(common, ATH_DBG_CALIBRATE, "offset " | ||
746 | "calibration failed to complete in " | ||
747 | "1ms; noisy ??\n"); | ||
748 | return false; | ||
749 | } | ||
750 | REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); | ||
751 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); | ||
752 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
753 | } | ||
754 | REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
755 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
756 | REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); | ||
757 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | ||
758 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | ||
759 | 0, AH_WAIT_TIMEOUT)) { | ||
760 | ath_print(common, ATH_DBG_CALIBRATE, "offset calibration " | ||
761 | "failed to complete in 1ms; noisy ??\n"); | ||
762 | return false; | ||
763 | } | ||
764 | |||
765 | REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
766 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
767 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
768 | |||
769 | return true; | ||
770 | } | ||
771 | |||
772 | static bool ar9285_hw_clc(struct ath_hw *ah, struct ath9k_channel *chan) | ||
773 | { | ||
774 | int i; | ||
775 | u_int32_t txgain_max; | ||
776 | u_int32_t clc_gain, gain_mask = 0, clc_num = 0; | ||
777 | u_int32_t reg_clc_I0, reg_clc_Q0; | ||
778 | u_int32_t i0_num = 0; | ||
779 | u_int32_t q0_num = 0; | ||
780 | u_int32_t total_num = 0; | ||
781 | u_int32_t reg_rf2g5_org; | ||
782 | bool retv = true; | ||
783 | |||
784 | if (!(ar9285_hw_cl_cal(ah, chan))) | ||
785 | return false; | ||
786 | |||
787 | txgain_max = MS(REG_READ(ah, AR_PHY_TX_PWRCTRL7), | ||
788 | AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX); | ||
789 | |||
790 | for (i = 0; i < (txgain_max+1); i++) { | ||
791 | clc_gain = (REG_READ(ah, (AR_PHY_TX_GAIN_TBL1+(i<<2))) & | ||
792 | AR_PHY_TX_GAIN_CLC) >> AR_PHY_TX_GAIN_CLC_S; | ||
793 | if (!(gain_mask & (1 << clc_gain))) { | ||
794 | gain_mask |= (1 << clc_gain); | ||
795 | clc_num++; | ||
796 | } | ||
797 | } | ||
798 | |||
799 | for (i = 0; i < clc_num; i++) { | ||
800 | reg_clc_I0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2))) | ||
801 | & AR_PHY_CLC_I0) >> AR_PHY_CLC_I0_S; | ||
802 | reg_clc_Q0 = (REG_READ(ah, (AR_PHY_CLC_TBL1 + (i << 2))) | ||
803 | & AR_PHY_CLC_Q0) >> AR_PHY_CLC_Q0_S; | ||
804 | if (reg_clc_I0 == 0) | ||
805 | i0_num++; | ||
806 | |||
807 | if (reg_clc_Q0 == 0) | ||
808 | q0_num++; | ||
809 | } | ||
810 | total_num = i0_num + q0_num; | ||
811 | if (total_num > AR9285_CLCAL_REDO_THRESH) { | ||
812 | reg_rf2g5_org = REG_READ(ah, AR9285_RF2G5); | ||
813 | if (AR_SREV_9285E_20(ah)) { | ||
814 | REG_WRITE(ah, AR9285_RF2G5, | ||
815 | (reg_rf2g5_org & AR9285_RF2G5_IC50TX) | | ||
816 | AR9285_RF2G5_IC50TX_XE_SET); | ||
817 | } else { | ||
818 | REG_WRITE(ah, AR9285_RF2G5, | ||
819 | (reg_rf2g5_org & AR9285_RF2G5_IC50TX) | | ||
820 | AR9285_RF2G5_IC50TX_SET); | ||
821 | } | ||
822 | retv = ar9285_hw_cl_cal(ah, chan); | ||
823 | REG_WRITE(ah, AR9285_RF2G5, reg_rf2g5_org); | ||
824 | } | ||
825 | return retv; | ||
826 | } | ||
827 | |||
828 | static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | ||
829 | { | ||
830 | struct ath_common *common = ath9k_hw_common(ah); | ||
831 | |||
832 | if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) { | ||
833 | if (!ar9285_hw_clc(ah, chan)) | ||
834 | return false; | ||
835 | } else { | ||
836 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
837 | if (!AR_SREV_9287_10_OR_LATER(ah)) | ||
838 | REG_CLR_BIT(ah, AR_PHY_ADC_CTL, | ||
839 | AR_PHY_ADC_CTL_OFF_PWDADC); | ||
840 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
841 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
842 | } | ||
843 | |||
844 | /* Calibrate the AGC */ | ||
845 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
846 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
847 | AR_PHY_AGC_CONTROL_CAL); | ||
848 | |||
849 | /* Poll for offset calibration complete */ | ||
850 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
851 | AR_PHY_AGC_CONTROL_CAL, | ||
852 | 0, AH_WAIT_TIMEOUT)) { | ||
853 | ath_print(common, ATH_DBG_CALIBRATE, | ||
854 | "offset calibration failed to " | ||
855 | "complete in 1ms; noisy environment?\n"); | ||
856 | return false; | ||
857 | } | ||
858 | |||
859 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
860 | if (!AR_SREV_9287_10_OR_LATER(ah)) | ||
861 | REG_SET_BIT(ah, AR_PHY_ADC_CTL, | ||
862 | AR_PHY_ADC_CTL_OFF_PWDADC); | ||
863 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
864 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
865 | } | ||
866 | } | ||
867 | |||
868 | /* Do PA Calibration */ | ||
869 | ar9002_hw_pa_cal(ah, true); | ||
870 | |||
871 | /* Do NF Calibration after DC offset and other calibrations */ | ||
872 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
873 | REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF); | ||
874 | |||
875 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | ||
876 | |||
877 | /* Enable IQ, ADC Gain and ADC DC offset CALs */ | ||
878 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { | ||
879 | if (ar9002_hw_iscal_supported(ah, ADC_GAIN_CAL)) { | ||
880 | INIT_CAL(&ah->adcgain_caldata); | ||
881 | INSERT_CAL(ah, &ah->adcgain_caldata); | ||
882 | ath_print(common, ATH_DBG_CALIBRATE, | ||
883 | "enabling ADC Gain Calibration.\n"); | ||
884 | } | ||
885 | if (ar9002_hw_iscal_supported(ah, ADC_DC_CAL)) { | ||
886 | INIT_CAL(&ah->adcdc_caldata); | ||
887 | INSERT_CAL(ah, &ah->adcdc_caldata); | ||
888 | ath_print(common, ATH_DBG_CALIBRATE, | ||
889 | "enabling ADC DC Calibration.\n"); | ||
890 | } | ||
891 | if (ar9002_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { | ||
892 | INIT_CAL(&ah->iq_caldata); | ||
893 | INSERT_CAL(ah, &ah->iq_caldata); | ||
894 | ath_print(common, ATH_DBG_CALIBRATE, | ||
895 | "enabling IQ Calibration.\n"); | ||
896 | } | ||
897 | |||
898 | ah->cal_list_curr = ah->cal_list; | ||
899 | |||
900 | if (ah->cal_list_curr) | ||
901 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | ||
902 | } | ||
903 | |||
904 | chan->CalValid = 0; | ||
905 | |||
906 | return true; | ||
907 | } | ||
908 | |||
909 | static const struct ath9k_percal_data iq_cal_multi_sample = { | ||
910 | IQ_MISMATCH_CAL, | ||
911 | MAX_CAL_SAMPLES, | ||
912 | PER_MIN_LOG_COUNT, | ||
913 | ar9002_hw_iqcal_collect, | ||
914 | ar9002_hw_iqcalibrate | ||
915 | }; | ||
916 | static const struct ath9k_percal_data iq_cal_single_sample = { | ||
917 | IQ_MISMATCH_CAL, | ||
918 | MIN_CAL_SAMPLES, | ||
919 | PER_MAX_LOG_COUNT, | ||
920 | ar9002_hw_iqcal_collect, | ||
921 | ar9002_hw_iqcalibrate | ||
922 | }; | ||
923 | static const struct ath9k_percal_data adc_gain_cal_multi_sample = { | ||
924 | ADC_GAIN_CAL, | ||
925 | MAX_CAL_SAMPLES, | ||
926 | PER_MIN_LOG_COUNT, | ||
927 | ar9002_hw_adc_gaincal_collect, | ||
928 | ar9002_hw_adc_gaincal_calibrate | ||
929 | }; | ||
930 | static const struct ath9k_percal_data adc_gain_cal_single_sample = { | ||
931 | ADC_GAIN_CAL, | ||
932 | MIN_CAL_SAMPLES, | ||
933 | PER_MAX_LOG_COUNT, | ||
934 | ar9002_hw_adc_gaincal_collect, | ||
935 | ar9002_hw_adc_gaincal_calibrate | ||
936 | }; | ||
937 | static const struct ath9k_percal_data adc_dc_cal_multi_sample = { | ||
938 | ADC_DC_CAL, | ||
939 | MAX_CAL_SAMPLES, | ||
940 | PER_MIN_LOG_COUNT, | ||
941 | ar9002_hw_adc_dccal_collect, | ||
942 | ar9002_hw_adc_dccal_calibrate | ||
943 | }; | ||
944 | static const struct ath9k_percal_data adc_dc_cal_single_sample = { | ||
945 | ADC_DC_CAL, | ||
946 | MIN_CAL_SAMPLES, | ||
947 | PER_MAX_LOG_COUNT, | ||
948 | ar9002_hw_adc_dccal_collect, | ||
949 | ar9002_hw_adc_dccal_calibrate | ||
950 | }; | ||
951 | static const struct ath9k_percal_data adc_init_dc_cal = { | ||
952 | ADC_DC_INIT_CAL, | ||
953 | MIN_CAL_SAMPLES, | ||
954 | INIT_LOG_COUNT, | ||
955 | ar9002_hw_adc_dccal_collect, | ||
956 | ar9002_hw_adc_dccal_calibrate | ||
957 | }; | ||
958 | |||
959 | static void ar9002_hw_init_cal_settings(struct ath_hw *ah) | ||
960 | { | ||
961 | if (AR_SREV_9100(ah)) { | ||
962 | ah->iq_caldata.calData = &iq_cal_multi_sample; | ||
963 | ah->supp_cals = IQ_MISMATCH_CAL; | ||
964 | return; | ||
965 | } | ||
966 | |||
967 | if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
968 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
969 | ah->iq_caldata.calData = &iq_cal_single_sample; | ||
970 | ah->adcgain_caldata.calData = | ||
971 | &adc_gain_cal_single_sample; | ||
972 | ah->adcdc_caldata.calData = | ||
973 | &adc_dc_cal_single_sample; | ||
974 | ah->adcdc_calinitdata.calData = | ||
975 | &adc_init_dc_cal; | ||
976 | } else { | ||
977 | ah->iq_caldata.calData = &iq_cal_multi_sample; | ||
978 | ah->adcgain_caldata.calData = | ||
979 | &adc_gain_cal_multi_sample; | ||
980 | ah->adcdc_caldata.calData = | ||
981 | &adc_dc_cal_multi_sample; | ||
982 | ah->adcdc_calinitdata.calData = | ||
983 | &adc_init_dc_cal; | ||
984 | } | ||
985 | ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; | ||
986 | } | ||
987 | } | ||
988 | |||
989 | void ar9002_hw_attach_calib_ops(struct ath_hw *ah) | ||
990 | { | ||
991 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
992 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
993 | |||
994 | priv_ops->init_cal_settings = ar9002_hw_init_cal_settings; | ||
995 | priv_ops->init_cal = ar9002_hw_init_cal; | ||
996 | priv_ops->setup_calibration = ar9002_hw_setup_calibration; | ||
997 | priv_ops->iscal_supported = ar9002_hw_iscal_supported; | ||
998 | |||
999 | ops->calibrate = ar9002_hw_calibrate; | ||
1000 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_hw.c b/drivers/net/wireless/ath/ath9k/ar9002_hw.c new file mode 100644 index 000000000000..a8a8cdc04afa --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9002_hw.c | |||
@@ -0,0 +1,598 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | #include "ar5008_initvals.h" | ||
19 | #include "ar9001_initvals.h" | ||
20 | #include "ar9002_initvals.h" | ||
21 | |||
22 | /* General hardware code for the A5008/AR9001/AR9002 hadware families */ | ||
23 | |||
24 | static bool ar9002_hw_macversion_supported(u32 macversion) | ||
25 | { | ||
26 | switch (macversion) { | ||
27 | case AR_SREV_VERSION_5416_PCI: | ||
28 | case AR_SREV_VERSION_5416_PCIE: | ||
29 | case AR_SREV_VERSION_9160: | ||
30 | case AR_SREV_VERSION_9100: | ||
31 | case AR_SREV_VERSION_9280: | ||
32 | case AR_SREV_VERSION_9285: | ||
33 | case AR_SREV_VERSION_9287: | ||
34 | case AR_SREV_VERSION_9271: | ||
35 | return true; | ||
36 | default: | ||
37 | break; | ||
38 | } | ||
39 | return false; | ||
40 | } | ||
41 | |||
42 | static void ar9002_hw_init_mode_regs(struct ath_hw *ah) | ||
43 | { | ||
44 | if (AR_SREV_9271(ah)) { | ||
45 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271, | ||
46 | ARRAY_SIZE(ar9271Modes_9271), 6); | ||
47 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, | ||
48 | ARRAY_SIZE(ar9271Common_9271), 2); | ||
49 | INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271, | ||
50 | ar9271Common_normal_cck_fir_coeff_9271, | ||
51 | ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2); | ||
52 | INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271, | ||
53 | ar9271Common_japan_2484_cck_fir_coeff_9271, | ||
54 | ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2); | ||
55 | INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, | ||
56 | ar9271Modes_9271_1_0_only, | ||
57 | ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6); | ||
58 | INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg, | ||
59 | ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6); | ||
60 | INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271, | ||
61 | ar9271Modes_high_power_tx_gain_9271, | ||
62 | ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6); | ||
63 | INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271, | ||
64 | ar9271Modes_normal_power_tx_gain_9271, | ||
65 | ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6); | ||
66 | return; | ||
67 | } | ||
68 | |||
69 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
70 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, | ||
71 | ARRAY_SIZE(ar9287Modes_9287_1_1), 6); | ||
72 | INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1, | ||
73 | ARRAY_SIZE(ar9287Common_9287_1_1), 2); | ||
74 | if (ah->config.pcie_clock_req) | ||
75 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
76 | ar9287PciePhy_clkreq_off_L1_9287_1_1, | ||
77 | ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2); | ||
78 | else | ||
79 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
80 | ar9287PciePhy_clkreq_always_on_L1_9287_1_1, | ||
81 | ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1), | ||
82 | 2); | ||
83 | } else if (AR_SREV_9287_10_OR_LATER(ah)) { | ||
84 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0, | ||
85 | ARRAY_SIZE(ar9287Modes_9287_1_0), 6); | ||
86 | INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0, | ||
87 | ARRAY_SIZE(ar9287Common_9287_1_0), 2); | ||
88 | |||
89 | if (ah->config.pcie_clock_req) | ||
90 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
91 | ar9287PciePhy_clkreq_off_L1_9287_1_0, | ||
92 | ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2); | ||
93 | else | ||
94 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
95 | ar9287PciePhy_clkreq_always_on_L1_9287_1_0, | ||
96 | ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0), | ||
97 | 2); | ||
98 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | ||
99 | |||
100 | |||
101 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, | ||
102 | ARRAY_SIZE(ar9285Modes_9285_1_2), 6); | ||
103 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, | ||
104 | ARRAY_SIZE(ar9285Common_9285_1_2), 2); | ||
105 | |||
106 | if (ah->config.pcie_clock_req) { | ||
107 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
108 | ar9285PciePhy_clkreq_off_L1_9285_1_2, | ||
109 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2); | ||
110 | } else { | ||
111 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
112 | ar9285PciePhy_clkreq_always_on_L1_9285_1_2, | ||
113 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), | ||
114 | 2); | ||
115 | } | ||
116 | } else if (AR_SREV_9285_10_OR_LATER(ah)) { | ||
117 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285, | ||
118 | ARRAY_SIZE(ar9285Modes_9285), 6); | ||
119 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285, | ||
120 | ARRAY_SIZE(ar9285Common_9285), 2); | ||
121 | |||
122 | if (ah->config.pcie_clock_req) { | ||
123 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
124 | ar9285PciePhy_clkreq_off_L1_9285, | ||
125 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); | ||
126 | } else { | ||
127 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
128 | ar9285PciePhy_clkreq_always_on_L1_9285, | ||
129 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); | ||
130 | } | ||
131 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
132 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, | ||
133 | ARRAY_SIZE(ar9280Modes_9280_2), 6); | ||
134 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, | ||
135 | ARRAY_SIZE(ar9280Common_9280_2), 2); | ||
136 | |||
137 | if (ah->config.pcie_clock_req) { | ||
138 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
139 | ar9280PciePhy_clkreq_off_L1_9280, | ||
140 | ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2); | ||
141 | } else { | ||
142 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
143 | ar9280PciePhy_clkreq_always_on_L1_9280, | ||
144 | ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); | ||
145 | } | ||
146 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
147 | ar9280Modes_fast_clock_9280_2, | ||
148 | ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); | ||
149 | } else if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
150 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280, | ||
151 | ARRAY_SIZE(ar9280Modes_9280), 6); | ||
152 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280, | ||
153 | ARRAY_SIZE(ar9280Common_9280), 2); | ||
154 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
155 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, | ||
156 | ARRAY_SIZE(ar5416Modes_9160), 6); | ||
157 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, | ||
158 | ARRAY_SIZE(ar5416Common_9160), 2); | ||
159 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160, | ||
160 | ARRAY_SIZE(ar5416Bank0_9160), 2); | ||
161 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160, | ||
162 | ARRAY_SIZE(ar5416BB_RfGain_9160), 3); | ||
163 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160, | ||
164 | ARRAY_SIZE(ar5416Bank1_9160), 2); | ||
165 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160, | ||
166 | ARRAY_SIZE(ar5416Bank2_9160), 2); | ||
167 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160, | ||
168 | ARRAY_SIZE(ar5416Bank3_9160), 3); | ||
169 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160, | ||
170 | ARRAY_SIZE(ar5416Bank6_9160), 3); | ||
171 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160, | ||
172 | ARRAY_SIZE(ar5416Bank6TPC_9160), 3); | ||
173 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160, | ||
174 | ARRAY_SIZE(ar5416Bank7_9160), 2); | ||
175 | if (AR_SREV_9160_11(ah)) { | ||
176 | INIT_INI_ARRAY(&ah->iniAddac, | ||
177 | ar5416Addac_91601_1, | ||
178 | ARRAY_SIZE(ar5416Addac_91601_1), 2); | ||
179 | } else { | ||
180 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160, | ||
181 | ARRAY_SIZE(ar5416Addac_9160), 2); | ||
182 | } | ||
183 | } else if (AR_SREV_9100_OR_LATER(ah)) { | ||
184 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100, | ||
185 | ARRAY_SIZE(ar5416Modes_9100), 6); | ||
186 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, | ||
187 | ARRAY_SIZE(ar5416Common_9100), 2); | ||
188 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100, | ||
189 | ARRAY_SIZE(ar5416Bank0_9100), 2); | ||
190 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100, | ||
191 | ARRAY_SIZE(ar5416BB_RfGain_9100), 3); | ||
192 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100, | ||
193 | ARRAY_SIZE(ar5416Bank1_9100), 2); | ||
194 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100, | ||
195 | ARRAY_SIZE(ar5416Bank2_9100), 2); | ||
196 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100, | ||
197 | ARRAY_SIZE(ar5416Bank3_9100), 3); | ||
198 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100, | ||
199 | ARRAY_SIZE(ar5416Bank6_9100), 3); | ||
200 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100, | ||
201 | ARRAY_SIZE(ar5416Bank6TPC_9100), 3); | ||
202 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100, | ||
203 | ARRAY_SIZE(ar5416Bank7_9100), 2); | ||
204 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100, | ||
205 | ARRAY_SIZE(ar5416Addac_9100), 2); | ||
206 | } else { | ||
207 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes, | ||
208 | ARRAY_SIZE(ar5416Modes), 6); | ||
209 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, | ||
210 | ARRAY_SIZE(ar5416Common), 2); | ||
211 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, | ||
212 | ARRAY_SIZE(ar5416Bank0), 2); | ||
213 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain, | ||
214 | ARRAY_SIZE(ar5416BB_RfGain), 3); | ||
215 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1, | ||
216 | ARRAY_SIZE(ar5416Bank1), 2); | ||
217 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2, | ||
218 | ARRAY_SIZE(ar5416Bank2), 2); | ||
219 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3, | ||
220 | ARRAY_SIZE(ar5416Bank3), 3); | ||
221 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6, | ||
222 | ARRAY_SIZE(ar5416Bank6), 3); | ||
223 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC, | ||
224 | ARRAY_SIZE(ar5416Bank6TPC), 3); | ||
225 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7, | ||
226 | ARRAY_SIZE(ar5416Bank7), 2); | ||
227 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, | ||
228 | ARRAY_SIZE(ar5416Addac), 2); | ||
229 | } | ||
230 | } | ||
231 | |||
232 | /* Support for Japan ch.14 (2484) spread */ | ||
233 | void ar9002_hw_cck_chan14_spread(struct ath_hw *ah) | ||
234 | { | ||
235 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
236 | INIT_INI_ARRAY(&ah->iniCckfirNormal, | ||
237 | ar9287Common_normal_cck_fir_coeff_92871_1, | ||
238 | ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), | ||
239 | 2); | ||
240 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | ||
241 | ar9287Common_japan_2484_cck_fir_coeff_92871_1, | ||
242 | ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), | ||
243 | 2); | ||
244 | } | ||
245 | } | ||
246 | |||
247 | static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah) | ||
248 | { | ||
249 | u32 rxgain_type; | ||
250 | |||
251 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= | ||
252 | AR5416_EEP_MINOR_VER_17) { | ||
253 | rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE); | ||
254 | |||
255 | if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) | ||
256 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
257 | ar9280Modes_backoff_13db_rxgain_9280_2, | ||
258 | ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6); | ||
259 | else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) | ||
260 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
261 | ar9280Modes_backoff_23db_rxgain_9280_2, | ||
262 | ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6); | ||
263 | else | ||
264 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
265 | ar9280Modes_original_rxgain_9280_2, | ||
266 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); | ||
267 | } else { | ||
268 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
269 | ar9280Modes_original_rxgain_9280_2, | ||
270 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); | ||
271 | } | ||
272 | } | ||
273 | |||
274 | static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah) | ||
275 | { | ||
276 | u32 txgain_type; | ||
277 | |||
278 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= | ||
279 | AR5416_EEP_MINOR_VER_19) { | ||
280 | txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
281 | |||
282 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) | ||
283 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
284 | ar9280Modes_high_power_tx_gain_9280_2, | ||
285 | ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6); | ||
286 | else | ||
287 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
288 | ar9280Modes_original_tx_gain_9280_2, | ||
289 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); | ||
290 | } else { | ||
291 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
292 | ar9280Modes_original_tx_gain_9280_2, | ||
293 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); | ||
294 | } | ||
295 | } | ||
296 | |||
297 | static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah) | ||
298 | { | ||
299 | if (AR_SREV_9287_11_OR_LATER(ah)) | ||
300 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
301 | ar9287Modes_rx_gain_9287_1_1, | ||
302 | ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); | ||
303 | else if (AR_SREV_9287_10(ah)) | ||
304 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
305 | ar9287Modes_rx_gain_9287_1_0, | ||
306 | ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6); | ||
307 | else if (AR_SREV_9280_20(ah)) | ||
308 | ar9280_20_hw_init_rxgain_ini(ah); | ||
309 | |||
310 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
311 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
312 | ar9287Modes_tx_gain_9287_1_1, | ||
313 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); | ||
314 | } else if (AR_SREV_9287_10(ah)) { | ||
315 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
316 | ar9287Modes_tx_gain_9287_1_0, | ||
317 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6); | ||
318 | } else if (AR_SREV_9280_20(ah)) { | ||
319 | ar9280_20_hw_init_txgain_ini(ah); | ||
320 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | ||
321 | u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
322 | |||
323 | /* txgain table */ | ||
324 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { | ||
325 | if (AR_SREV_9285E_20(ah)) { | ||
326 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
327 | ar9285Modes_XE2_0_high_power, | ||
328 | ARRAY_SIZE( | ||
329 | ar9285Modes_XE2_0_high_power), 6); | ||
330 | } else { | ||
331 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
332 | ar9285Modes_high_power_tx_gain_9285_1_2, | ||
333 | ARRAY_SIZE( | ||
334 | ar9285Modes_high_power_tx_gain_9285_1_2), 6); | ||
335 | } | ||
336 | } else { | ||
337 | if (AR_SREV_9285E_20(ah)) { | ||
338 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
339 | ar9285Modes_XE2_0_normal_power, | ||
340 | ARRAY_SIZE( | ||
341 | ar9285Modes_XE2_0_normal_power), 6); | ||
342 | } else { | ||
343 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
344 | ar9285Modes_original_tx_gain_9285_1_2, | ||
345 | ARRAY_SIZE( | ||
346 | ar9285Modes_original_tx_gain_9285_1_2), 6); | ||
347 | } | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | |||
352 | /* | ||
353 | * Helper for ASPM support. | ||
354 | * | ||
355 | * Disable PLL when in L0s as well as receiver clock when in L1. | ||
356 | * This power saving option must be enabled through the SerDes. | ||
357 | * | ||
358 | * Programming the SerDes must go through the same 288 bit serial shift | ||
359 | * register as the other analog registers. Hence the 9 writes. | ||
360 | */ | ||
361 | static void ar9002_hw_configpcipowersave(struct ath_hw *ah, | ||
362 | int restore, | ||
363 | int power_off) | ||
364 | { | ||
365 | u8 i; | ||
366 | u32 val; | ||
367 | |||
368 | if (ah->is_pciexpress != true) | ||
369 | return; | ||
370 | |||
371 | /* Do not touch SerDes registers */ | ||
372 | if (ah->config.pcie_powersave_enable == 2) | ||
373 | return; | ||
374 | |||
375 | /* Nothing to do on restore for 11N */ | ||
376 | if (!restore) { | ||
377 | if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
378 | /* | ||
379 | * AR9280 2.0 or later chips use SerDes values from the | ||
380 | * initvals.h initialized depending on chipset during | ||
381 | * __ath9k_hw_init() | ||
382 | */ | ||
383 | for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { | ||
384 | REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), | ||
385 | INI_RA(&ah->iniPcieSerdes, i, 1)); | ||
386 | } | ||
387 | } else if (AR_SREV_9280(ah) && | ||
388 | (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) { | ||
389 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); | ||
390 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
391 | |||
392 | /* RX shut off when elecidle is asserted */ | ||
393 | REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); | ||
394 | REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); | ||
395 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); | ||
396 | |||
397 | /* Shut off CLKREQ active in L1 */ | ||
398 | if (ah->config.pcie_clock_req) | ||
399 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); | ||
400 | else | ||
401 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); | ||
402 | |||
403 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
404 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
405 | REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); | ||
406 | |||
407 | /* Load the new settings */ | ||
408 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | ||
409 | |||
410 | } else { | ||
411 | ENABLE_REGWRITE_BUFFER(ah); | ||
412 | |||
413 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); | ||
414 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
415 | |||
416 | /* RX shut off when elecidle is asserted */ | ||
417 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); | ||
418 | REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); | ||
419 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); | ||
420 | |||
421 | /* | ||
422 | * Ignore ah->ah_config.pcie_clock_req setting for | ||
423 | * pre-AR9280 11n | ||
424 | */ | ||
425 | REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); | ||
426 | |||
427 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
428 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
429 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); | ||
430 | |||
431 | /* Load the new settings */ | ||
432 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | ||
433 | |||
434 | REGWRITE_BUFFER_FLUSH(ah); | ||
435 | DISABLE_REGWRITE_BUFFER(ah); | ||
436 | } | ||
437 | |||
438 | udelay(1000); | ||
439 | |||
440 | /* set bit 19 to allow forcing of pcie core into L1 state */ | ||
441 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); | ||
442 | |||
443 | /* Several PCIe massages to ensure proper behaviour */ | ||
444 | if (ah->config.pcie_waen) { | ||
445 | val = ah->config.pcie_waen; | ||
446 | if (!power_off) | ||
447 | val &= (~AR_WA_D3_L1_DISABLE); | ||
448 | } else { | ||
449 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || | ||
450 | AR_SREV_9287(ah)) { | ||
451 | val = AR9285_WA_DEFAULT; | ||
452 | if (!power_off) | ||
453 | val &= (~AR_WA_D3_L1_DISABLE); | ||
454 | } else if (AR_SREV_9280(ah)) { | ||
455 | /* | ||
456 | * On AR9280 chips bit 22 of 0x4004 needs to be | ||
457 | * set otherwise card may disappear. | ||
458 | */ | ||
459 | val = AR9280_WA_DEFAULT; | ||
460 | if (!power_off) | ||
461 | val &= (~AR_WA_D3_L1_DISABLE); | ||
462 | } else | ||
463 | val = AR_WA_DEFAULT; | ||
464 | } | ||
465 | |||
466 | REG_WRITE(ah, AR_WA, val); | ||
467 | } | ||
468 | |||
469 | if (power_off) { | ||
470 | /* | ||
471 | * Set PCIe workaround bits | ||
472 | * bit 14 in WA register (disable L1) should only | ||
473 | * be set when device enters D3 and be cleared | ||
474 | * when device comes back to D0. | ||
475 | */ | ||
476 | if (ah->config.pcie_waen) { | ||
477 | if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE) | ||
478 | REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); | ||
479 | } else { | ||
480 | if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) || | ||
481 | AR_SREV_9287(ah)) && | ||
482 | (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) || | ||
483 | (AR_SREV_9280(ah) && | ||
484 | (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) { | ||
485 | REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); | ||
486 | } | ||
487 | } | ||
488 | } | ||
489 | } | ||
490 | |||
491 | static int ar9002_hw_get_radiorev(struct ath_hw *ah) | ||
492 | { | ||
493 | u32 val; | ||
494 | int i; | ||
495 | |||
496 | ENABLE_REGWRITE_BUFFER(ah); | ||
497 | |||
498 | REG_WRITE(ah, AR_PHY(0x36), 0x00007058); | ||
499 | for (i = 0; i < 8; i++) | ||
500 | REG_WRITE(ah, AR_PHY(0x20), 0x00010000); | ||
501 | |||
502 | REGWRITE_BUFFER_FLUSH(ah); | ||
503 | DISABLE_REGWRITE_BUFFER(ah); | ||
504 | |||
505 | val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; | ||
506 | val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); | ||
507 | |||
508 | return ath9k_hw_reverse_bits(val, 8); | ||
509 | } | ||
510 | |||
511 | int ar9002_hw_rf_claim(struct ath_hw *ah) | ||
512 | { | ||
513 | u32 val; | ||
514 | |||
515 | REG_WRITE(ah, AR_PHY(0), 0x00000007); | ||
516 | |||
517 | val = ar9002_hw_get_radiorev(ah); | ||
518 | switch (val & AR_RADIO_SREV_MAJOR) { | ||
519 | case 0: | ||
520 | val = AR_RAD5133_SREV_MAJOR; | ||
521 | break; | ||
522 | case AR_RAD5133_SREV_MAJOR: | ||
523 | case AR_RAD5122_SREV_MAJOR: | ||
524 | case AR_RAD2133_SREV_MAJOR: | ||
525 | case AR_RAD2122_SREV_MAJOR: | ||
526 | break; | ||
527 | default: | ||
528 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
529 | "Radio Chip Rev 0x%02X not supported\n", | ||
530 | val & AR_RADIO_SREV_MAJOR); | ||
531 | return -EOPNOTSUPP; | ||
532 | } | ||
533 | |||
534 | ah->hw_version.analog5GhzRev = val; | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Enable ASYNC FIFO | ||
541 | * | ||
542 | * If Async FIFO is enabled, the following counters change as MAC now runs | ||
543 | * at 117 Mhz instead of 88/44MHz when async FIFO is disabled. | ||
544 | * | ||
545 | * The values below tested for ht40 2 chain. | ||
546 | * Overwrite the delay/timeouts initialized in process ini. | ||
547 | */ | ||
548 | void ar9002_hw_enable_async_fifo(struct ath_hw *ah) | ||
549 | { | ||
550 | if (AR_SREV_9287_12_OR_LATER(ah)) { | ||
551 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, | ||
552 | AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); | ||
553 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, | ||
554 | AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR); | ||
555 | REG_WRITE(ah, AR_D_GBL_IFS_EIFS, | ||
556 | AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR); | ||
557 | |||
558 | REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR); | ||
559 | REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR); | ||
560 | |||
561 | REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER, | ||
562 | AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768); | ||
563 | REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN, | ||
564 | AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL); | ||
565 | } | ||
566 | } | ||
567 | |||
568 | /* | ||
569 | * We don't enable WEP aggregation on mac80211 but we keep this | ||
570 | * around for HAL unification purposes. | ||
571 | */ | ||
572 | void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah) | ||
573 | { | ||
574 | if (AR_SREV_9287_12_OR_LATER(ah)) { | ||
575 | REG_SET_BIT(ah, AR_PCU_MISC_MODE2, | ||
576 | AR_PCU_MISC_MODE2_ENABLE_AGGWEP); | ||
577 | } | ||
578 | } | ||
579 | |||
580 | /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */ | ||
581 | void ar9002_hw_attach_ops(struct ath_hw *ah) | ||
582 | { | ||
583 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
584 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
585 | |||
586 | priv_ops->init_mode_regs = ar9002_hw_init_mode_regs; | ||
587 | priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs; | ||
588 | priv_ops->macversion_supported = ar9002_hw_macversion_supported; | ||
589 | |||
590 | ops->config_pci_powersave = ar9002_hw_configpcipowersave; | ||
591 | |||
592 | ar5008_hw_attach_phy_ops(ah); | ||
593 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
594 | ar9002_hw_attach_phy_ops(ah); | ||
595 | |||
596 | ar9002_hw_attach_calib_ops(ah); | ||
597 | ar9002_hw_attach_mac_ops(ah); | ||
598 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h index 8a3bf3ab998d..dae7f3304eb8 100644 --- a/drivers/net/wireless/ath/ath9k/initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9002_initvals.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2010 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -14,1982 +14,9 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | static const u32 ar5416Modes[][6] = { | 17 | #ifndef INITVALS_9002_10_H |
18 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 18 | #define INITVALS_9002_10_H |
19 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
20 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
21 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
22 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
23 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
24 | { 0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810 }, | ||
25 | { 0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a }, | ||
26 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
27 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
28 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
29 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
30 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
31 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
32 | { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 }, | ||
33 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
34 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
35 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
36 | { 0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de }, | ||
37 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, | ||
38 | { 0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e }, | ||
39 | { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 }, | ||
40 | { 0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
41 | { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 }, | ||
42 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
43 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
44 | { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 }, | ||
45 | { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b }, | ||
46 | { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, | ||
47 | { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
48 | { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
49 | { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 }, | ||
50 | { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 }, | ||
51 | { 0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 }, | ||
52 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
53 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
54 | { 0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c }, | ||
55 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
56 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
57 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
58 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
59 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
60 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
61 | { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
62 | { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
63 | { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
64 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
65 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
66 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
67 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
68 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
69 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
70 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
71 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
72 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
73 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
74 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
75 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
76 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
77 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
78 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
79 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
80 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
81 | }; | ||
82 | |||
83 | static const u32 ar5416Common[][2] = { | ||
84 | { 0x0000000c, 0x00000000 }, | ||
85 | { 0x00000030, 0x00020015 }, | ||
86 | { 0x00000034, 0x00000005 }, | ||
87 | { 0x00000040, 0x00000000 }, | ||
88 | { 0x00000044, 0x00000008 }, | ||
89 | { 0x00000048, 0x00000008 }, | ||
90 | { 0x0000004c, 0x00000010 }, | ||
91 | { 0x00000050, 0x00000000 }, | ||
92 | { 0x00000054, 0x0000001f }, | ||
93 | { 0x00000800, 0x00000000 }, | ||
94 | { 0x00000804, 0x00000000 }, | ||
95 | { 0x00000808, 0x00000000 }, | ||
96 | { 0x0000080c, 0x00000000 }, | ||
97 | { 0x00000810, 0x00000000 }, | ||
98 | { 0x00000814, 0x00000000 }, | ||
99 | { 0x00000818, 0x00000000 }, | ||
100 | { 0x0000081c, 0x00000000 }, | ||
101 | { 0x00000820, 0x00000000 }, | ||
102 | { 0x00000824, 0x00000000 }, | ||
103 | { 0x00001040, 0x002ffc0f }, | ||
104 | { 0x00001044, 0x002ffc0f }, | ||
105 | { 0x00001048, 0x002ffc0f }, | ||
106 | { 0x0000104c, 0x002ffc0f }, | ||
107 | { 0x00001050, 0x002ffc0f }, | ||
108 | { 0x00001054, 0x002ffc0f }, | ||
109 | { 0x00001058, 0x002ffc0f }, | ||
110 | { 0x0000105c, 0x002ffc0f }, | ||
111 | { 0x00001060, 0x002ffc0f }, | ||
112 | { 0x00001064, 0x002ffc0f }, | ||
113 | { 0x00001230, 0x00000000 }, | ||
114 | { 0x00001270, 0x00000000 }, | ||
115 | { 0x00001038, 0x00000000 }, | ||
116 | { 0x00001078, 0x00000000 }, | ||
117 | { 0x000010b8, 0x00000000 }, | ||
118 | { 0x000010f8, 0x00000000 }, | ||
119 | { 0x00001138, 0x00000000 }, | ||
120 | { 0x00001178, 0x00000000 }, | ||
121 | { 0x000011b8, 0x00000000 }, | ||
122 | { 0x000011f8, 0x00000000 }, | ||
123 | { 0x00001238, 0x00000000 }, | ||
124 | { 0x00001278, 0x00000000 }, | ||
125 | { 0x000012b8, 0x00000000 }, | ||
126 | { 0x000012f8, 0x00000000 }, | ||
127 | { 0x00001338, 0x00000000 }, | ||
128 | { 0x00001378, 0x00000000 }, | ||
129 | { 0x000013b8, 0x00000000 }, | ||
130 | { 0x000013f8, 0x00000000 }, | ||
131 | { 0x00001438, 0x00000000 }, | ||
132 | { 0x00001478, 0x00000000 }, | ||
133 | { 0x000014b8, 0x00000000 }, | ||
134 | { 0x000014f8, 0x00000000 }, | ||
135 | { 0x00001538, 0x00000000 }, | ||
136 | { 0x00001578, 0x00000000 }, | ||
137 | { 0x000015b8, 0x00000000 }, | ||
138 | { 0x000015f8, 0x00000000 }, | ||
139 | { 0x00001638, 0x00000000 }, | ||
140 | { 0x00001678, 0x00000000 }, | ||
141 | { 0x000016b8, 0x00000000 }, | ||
142 | { 0x000016f8, 0x00000000 }, | ||
143 | { 0x00001738, 0x00000000 }, | ||
144 | { 0x00001778, 0x00000000 }, | ||
145 | { 0x000017b8, 0x00000000 }, | ||
146 | { 0x000017f8, 0x00000000 }, | ||
147 | { 0x0000103c, 0x00000000 }, | ||
148 | { 0x0000107c, 0x00000000 }, | ||
149 | { 0x000010bc, 0x00000000 }, | ||
150 | { 0x000010fc, 0x00000000 }, | ||
151 | { 0x0000113c, 0x00000000 }, | ||
152 | { 0x0000117c, 0x00000000 }, | ||
153 | { 0x000011bc, 0x00000000 }, | ||
154 | { 0x000011fc, 0x00000000 }, | ||
155 | { 0x0000123c, 0x00000000 }, | ||
156 | { 0x0000127c, 0x00000000 }, | ||
157 | { 0x000012bc, 0x00000000 }, | ||
158 | { 0x000012fc, 0x00000000 }, | ||
159 | { 0x0000133c, 0x00000000 }, | ||
160 | { 0x0000137c, 0x00000000 }, | ||
161 | { 0x000013bc, 0x00000000 }, | ||
162 | { 0x000013fc, 0x00000000 }, | ||
163 | { 0x0000143c, 0x00000000 }, | ||
164 | { 0x0000147c, 0x00000000 }, | ||
165 | { 0x00004030, 0x00000002 }, | ||
166 | { 0x0000403c, 0x00000002 }, | ||
167 | { 0x00007010, 0x00000000 }, | ||
168 | { 0x00007038, 0x000004c2 }, | ||
169 | { 0x00008004, 0x00000000 }, | ||
170 | { 0x00008008, 0x00000000 }, | ||
171 | { 0x0000800c, 0x00000000 }, | ||
172 | { 0x00008018, 0x00000700 }, | ||
173 | { 0x00008020, 0x00000000 }, | ||
174 | { 0x00008038, 0x00000000 }, | ||
175 | { 0x0000803c, 0x00000000 }, | ||
176 | { 0x00008048, 0x40000000 }, | ||
177 | { 0x00008054, 0x00000000 }, | ||
178 | { 0x00008058, 0x00000000 }, | ||
179 | { 0x0000805c, 0x000fc78f }, | ||
180 | { 0x00008060, 0x0000000f }, | ||
181 | { 0x00008064, 0x00000000 }, | ||
182 | { 0x000080c0, 0x2a82301a }, | ||
183 | { 0x000080c4, 0x05dc01e0 }, | ||
184 | { 0x000080c8, 0x1f402710 }, | ||
185 | { 0x000080cc, 0x01f40000 }, | ||
186 | { 0x000080d0, 0x00001e00 }, | ||
187 | { 0x000080d4, 0x00000000 }, | ||
188 | { 0x000080d8, 0x00400000 }, | ||
189 | { 0x000080e0, 0xffffffff }, | ||
190 | { 0x000080e4, 0x0000ffff }, | ||
191 | { 0x000080e8, 0x003f3f3f }, | ||
192 | { 0x000080ec, 0x00000000 }, | ||
193 | { 0x000080f0, 0x00000000 }, | ||
194 | { 0x000080f4, 0x00000000 }, | ||
195 | { 0x000080f8, 0x00000000 }, | ||
196 | { 0x000080fc, 0x00020000 }, | ||
197 | { 0x00008100, 0x00020000 }, | ||
198 | { 0x00008104, 0x00000001 }, | ||
199 | { 0x00008108, 0x00000052 }, | ||
200 | { 0x0000810c, 0x00000000 }, | ||
201 | { 0x00008110, 0x00000168 }, | ||
202 | { 0x00008118, 0x000100aa }, | ||
203 | { 0x0000811c, 0x00003210 }, | ||
204 | { 0x00008124, 0x00000000 }, | ||
205 | { 0x00008128, 0x00000000 }, | ||
206 | { 0x0000812c, 0x00000000 }, | ||
207 | { 0x00008130, 0x00000000 }, | ||
208 | { 0x00008134, 0x00000000 }, | ||
209 | { 0x00008138, 0x00000000 }, | ||
210 | { 0x0000813c, 0x00000000 }, | ||
211 | { 0x00008144, 0xffffffff }, | ||
212 | { 0x00008168, 0x00000000 }, | ||
213 | { 0x0000816c, 0x00000000 }, | ||
214 | { 0x00008170, 0x32143320 }, | ||
215 | { 0x00008174, 0xfaa4fa50 }, | ||
216 | { 0x00008178, 0x00000100 }, | ||
217 | { 0x0000817c, 0x00000000 }, | ||
218 | { 0x000081c4, 0x00000000 }, | ||
219 | { 0x000081ec, 0x00000000 }, | ||
220 | { 0x000081f0, 0x00000000 }, | ||
221 | { 0x000081f4, 0x00000000 }, | ||
222 | { 0x000081f8, 0x00000000 }, | ||
223 | { 0x000081fc, 0x00000000 }, | ||
224 | { 0x00008200, 0x00000000 }, | ||
225 | { 0x00008204, 0x00000000 }, | ||
226 | { 0x00008208, 0x00000000 }, | ||
227 | { 0x0000820c, 0x00000000 }, | ||
228 | { 0x00008210, 0x00000000 }, | ||
229 | { 0x00008214, 0x00000000 }, | ||
230 | { 0x00008218, 0x00000000 }, | ||
231 | { 0x0000821c, 0x00000000 }, | ||
232 | { 0x00008220, 0x00000000 }, | ||
233 | { 0x00008224, 0x00000000 }, | ||
234 | { 0x00008228, 0x00000000 }, | ||
235 | { 0x0000822c, 0x00000000 }, | ||
236 | { 0x00008230, 0x00000000 }, | ||
237 | { 0x00008234, 0x00000000 }, | ||
238 | { 0x00008238, 0x00000000 }, | ||
239 | { 0x0000823c, 0x00000000 }, | ||
240 | { 0x00008240, 0x00100000 }, | ||
241 | { 0x00008244, 0x0010f400 }, | ||
242 | { 0x00008248, 0x00000100 }, | ||
243 | { 0x0000824c, 0x0001e800 }, | ||
244 | { 0x00008250, 0x00000000 }, | ||
245 | { 0x00008254, 0x00000000 }, | ||
246 | { 0x00008258, 0x00000000 }, | ||
247 | { 0x0000825c, 0x400000ff }, | ||
248 | { 0x00008260, 0x00080922 }, | ||
249 | { 0x00008264, 0xa8000010 }, | ||
250 | { 0x00008270, 0x00000000 }, | ||
251 | { 0x00008274, 0x40000000 }, | ||
252 | { 0x00008278, 0x003e4180 }, | ||
253 | { 0x0000827c, 0x00000000 }, | ||
254 | { 0x00008284, 0x0000002c }, | ||
255 | { 0x00008288, 0x0000002c }, | ||
256 | { 0x0000828c, 0x00000000 }, | ||
257 | { 0x00008294, 0x00000000 }, | ||
258 | { 0x00008298, 0x00000000 }, | ||
259 | { 0x00008300, 0x00000000 }, | ||
260 | { 0x00008304, 0x00000000 }, | ||
261 | { 0x00008308, 0x00000000 }, | ||
262 | { 0x0000830c, 0x00000000 }, | ||
263 | { 0x00008310, 0x00000000 }, | ||
264 | { 0x00008314, 0x00000000 }, | ||
265 | { 0x00008318, 0x00000000 }, | ||
266 | { 0x00008328, 0x00000000 }, | ||
267 | { 0x0000832c, 0x00000007 }, | ||
268 | { 0x00008330, 0x00000302 }, | ||
269 | { 0x00008334, 0x00000e00 }, | ||
270 | { 0x00008338, 0x00070000 }, | ||
271 | { 0x0000833c, 0x00000000 }, | ||
272 | { 0x00008340, 0x000107ff }, | ||
273 | { 0x00009808, 0x00000000 }, | ||
274 | { 0x0000980c, 0xad848e19 }, | ||
275 | { 0x00009810, 0x7d14e000 }, | ||
276 | { 0x00009814, 0x9c0a9f6b }, | ||
277 | { 0x0000981c, 0x00000000 }, | ||
278 | { 0x0000982c, 0x0000a000 }, | ||
279 | { 0x00009830, 0x00000000 }, | ||
280 | { 0x0000983c, 0x00200400 }, | ||
281 | { 0x00009840, 0x206a002e }, | ||
282 | { 0x0000984c, 0x1284233c }, | ||
283 | { 0x00009854, 0x00000859 }, | ||
284 | { 0x00009900, 0x00000000 }, | ||
285 | { 0x00009904, 0x00000000 }, | ||
286 | { 0x00009908, 0x00000000 }, | ||
287 | { 0x0000990c, 0x00000000 }, | ||
288 | { 0x0000991c, 0x10000fff }, | ||
289 | { 0x00009920, 0x05100000 }, | ||
290 | { 0x0000a920, 0x05100000 }, | ||
291 | { 0x0000b920, 0x05100000 }, | ||
292 | { 0x00009928, 0x00000001 }, | ||
293 | { 0x0000992c, 0x00000004 }, | ||
294 | { 0x00009934, 0x1e1f2022 }, | ||
295 | { 0x00009938, 0x0a0b0c0d }, | ||
296 | { 0x0000993c, 0x00000000 }, | ||
297 | { 0x00009948, 0x9280b212 }, | ||
298 | { 0x0000994c, 0x00020028 }, | ||
299 | { 0x00009954, 0x5d50e188 }, | ||
300 | { 0x00009958, 0x00081fff }, | ||
301 | { 0x0000c95c, 0x004b6a8e }, | ||
302 | { 0x0000c968, 0x000003ce }, | ||
303 | { 0x00009970, 0x190fb515 }, | ||
304 | { 0x00009974, 0x00000000 }, | ||
305 | { 0x00009978, 0x00000001 }, | ||
306 | { 0x0000997c, 0x00000000 }, | ||
307 | { 0x00009980, 0x00000000 }, | ||
308 | { 0x00009984, 0x00000000 }, | ||
309 | { 0x00009988, 0x00000000 }, | ||
310 | { 0x0000998c, 0x00000000 }, | ||
311 | { 0x00009990, 0x00000000 }, | ||
312 | { 0x00009994, 0x00000000 }, | ||
313 | { 0x00009998, 0x00000000 }, | ||
314 | { 0x0000999c, 0x00000000 }, | ||
315 | { 0x000099a0, 0x00000000 }, | ||
316 | { 0x000099a4, 0x00000001 }, | ||
317 | { 0x000099a8, 0x001fff00 }, | ||
318 | { 0x000099ac, 0x00000000 }, | ||
319 | { 0x000099b0, 0x03051000 }, | ||
320 | { 0x000099dc, 0x00000000 }, | ||
321 | { 0x000099e0, 0x00000200 }, | ||
322 | { 0x000099e4, 0xaaaaaaaa }, | ||
323 | { 0x000099e8, 0x3c466478 }, | ||
324 | { 0x000099ec, 0x000000aa }, | ||
325 | { 0x000099fc, 0x00001042 }, | ||
326 | { 0x00009b00, 0x00000000 }, | ||
327 | { 0x00009b04, 0x00000001 }, | ||
328 | { 0x00009b08, 0x00000002 }, | ||
329 | { 0x00009b0c, 0x00000003 }, | ||
330 | { 0x00009b10, 0x00000004 }, | ||
331 | { 0x00009b14, 0x00000005 }, | ||
332 | { 0x00009b18, 0x00000008 }, | ||
333 | { 0x00009b1c, 0x00000009 }, | ||
334 | { 0x00009b20, 0x0000000a }, | ||
335 | { 0x00009b24, 0x0000000b }, | ||
336 | { 0x00009b28, 0x0000000c }, | ||
337 | { 0x00009b2c, 0x0000000d }, | ||
338 | { 0x00009b30, 0x00000010 }, | ||
339 | { 0x00009b34, 0x00000011 }, | ||
340 | { 0x00009b38, 0x00000012 }, | ||
341 | { 0x00009b3c, 0x00000013 }, | ||
342 | { 0x00009b40, 0x00000014 }, | ||
343 | { 0x00009b44, 0x00000015 }, | ||
344 | { 0x00009b48, 0x00000018 }, | ||
345 | { 0x00009b4c, 0x00000019 }, | ||
346 | { 0x00009b50, 0x0000001a }, | ||
347 | { 0x00009b54, 0x0000001b }, | ||
348 | { 0x00009b58, 0x0000001c }, | ||
349 | { 0x00009b5c, 0x0000001d }, | ||
350 | { 0x00009b60, 0x00000020 }, | ||
351 | { 0x00009b64, 0x00000021 }, | ||
352 | { 0x00009b68, 0x00000022 }, | ||
353 | { 0x00009b6c, 0x00000023 }, | ||
354 | { 0x00009b70, 0x00000024 }, | ||
355 | { 0x00009b74, 0x00000025 }, | ||
356 | { 0x00009b78, 0x00000028 }, | ||
357 | { 0x00009b7c, 0x00000029 }, | ||
358 | { 0x00009b80, 0x0000002a }, | ||
359 | { 0x00009b84, 0x0000002b }, | ||
360 | { 0x00009b88, 0x0000002c }, | ||
361 | { 0x00009b8c, 0x0000002d }, | ||
362 | { 0x00009b90, 0x00000030 }, | ||
363 | { 0x00009b94, 0x00000031 }, | ||
364 | { 0x00009b98, 0x00000032 }, | ||
365 | { 0x00009b9c, 0x00000033 }, | ||
366 | { 0x00009ba0, 0x00000034 }, | ||
367 | { 0x00009ba4, 0x00000035 }, | ||
368 | { 0x00009ba8, 0x00000035 }, | ||
369 | { 0x00009bac, 0x00000035 }, | ||
370 | { 0x00009bb0, 0x00000035 }, | ||
371 | { 0x00009bb4, 0x00000035 }, | ||
372 | { 0x00009bb8, 0x00000035 }, | ||
373 | { 0x00009bbc, 0x00000035 }, | ||
374 | { 0x00009bc0, 0x00000035 }, | ||
375 | { 0x00009bc4, 0x00000035 }, | ||
376 | { 0x00009bc8, 0x00000035 }, | ||
377 | { 0x00009bcc, 0x00000035 }, | ||
378 | { 0x00009bd0, 0x00000035 }, | ||
379 | { 0x00009bd4, 0x00000035 }, | ||
380 | { 0x00009bd8, 0x00000035 }, | ||
381 | { 0x00009bdc, 0x00000035 }, | ||
382 | { 0x00009be0, 0x00000035 }, | ||
383 | { 0x00009be4, 0x00000035 }, | ||
384 | { 0x00009be8, 0x00000035 }, | ||
385 | { 0x00009bec, 0x00000035 }, | ||
386 | { 0x00009bf0, 0x00000035 }, | ||
387 | { 0x00009bf4, 0x00000035 }, | ||
388 | { 0x00009bf8, 0x00000010 }, | ||
389 | { 0x00009bfc, 0x0000001a }, | ||
390 | { 0x0000a210, 0x40806333 }, | ||
391 | { 0x0000a214, 0x00106c10 }, | ||
392 | { 0x0000a218, 0x009c4060 }, | ||
393 | { 0x0000a220, 0x018830c6 }, | ||
394 | { 0x0000a224, 0x00000400 }, | ||
395 | { 0x0000a228, 0x00000bb5 }, | ||
396 | { 0x0000a22c, 0x00000011 }, | ||
397 | { 0x0000a234, 0x20202020 }, | ||
398 | { 0x0000a238, 0x20202020 }, | ||
399 | { 0x0000a23c, 0x13c889af }, | ||
400 | { 0x0000a240, 0x38490a20 }, | ||
401 | { 0x0000a244, 0x00007bb6 }, | ||
402 | { 0x0000a248, 0x0fff3ffc }, | ||
403 | { 0x0000a24c, 0x00000001 }, | ||
404 | { 0x0000a250, 0x0000a000 }, | ||
405 | { 0x0000a254, 0x00000000 }, | ||
406 | { 0x0000a258, 0x0cc75380 }, | ||
407 | { 0x0000a25c, 0x0f0f0f01 }, | ||
408 | { 0x0000a260, 0xdfa91f01 }, | ||
409 | { 0x0000a268, 0x00000000 }, | ||
410 | { 0x0000a26c, 0x0e79e5c6 }, | ||
411 | { 0x0000b26c, 0x0e79e5c6 }, | ||
412 | { 0x0000c26c, 0x0e79e5c6 }, | ||
413 | { 0x0000d270, 0x00820820 }, | ||
414 | { 0x0000a278, 0x1ce739ce }, | ||
415 | { 0x0000a27c, 0x051701ce }, | ||
416 | { 0x0000a338, 0x00000000 }, | ||
417 | { 0x0000a33c, 0x00000000 }, | ||
418 | { 0x0000a340, 0x00000000 }, | ||
419 | { 0x0000a344, 0x00000000 }, | ||
420 | { 0x0000a348, 0x3fffffff }, | ||
421 | { 0x0000a34c, 0x3fffffff }, | ||
422 | { 0x0000a350, 0x3fffffff }, | ||
423 | { 0x0000a354, 0x0003ffff }, | ||
424 | { 0x0000a358, 0x79a8aa1f }, | ||
425 | { 0x0000d35c, 0x07ffffef }, | ||
426 | { 0x0000d360, 0x0fffffe7 }, | ||
427 | { 0x0000d364, 0x17ffffe5 }, | ||
428 | { 0x0000d368, 0x1fffffe4 }, | ||
429 | { 0x0000d36c, 0x37ffffe3 }, | ||
430 | { 0x0000d370, 0x3fffffe3 }, | ||
431 | { 0x0000d374, 0x57ffffe3 }, | ||
432 | { 0x0000d378, 0x5fffffe2 }, | ||
433 | { 0x0000d37c, 0x7fffffe2 }, | ||
434 | { 0x0000d380, 0x7f3c7bba }, | ||
435 | { 0x0000d384, 0xf3307ff0 }, | ||
436 | { 0x0000a388, 0x08000000 }, | ||
437 | { 0x0000a38c, 0x20202020 }, | ||
438 | { 0x0000a390, 0x20202020 }, | ||
439 | { 0x0000a394, 0x1ce739ce }, | ||
440 | { 0x0000a398, 0x000001ce }, | ||
441 | { 0x0000a39c, 0x00000001 }, | ||
442 | { 0x0000a3a0, 0x00000000 }, | ||
443 | { 0x0000a3a4, 0x00000000 }, | ||
444 | { 0x0000a3a8, 0x00000000 }, | ||
445 | { 0x0000a3ac, 0x00000000 }, | ||
446 | { 0x0000a3b0, 0x00000000 }, | ||
447 | { 0x0000a3b4, 0x00000000 }, | ||
448 | { 0x0000a3b8, 0x00000000 }, | ||
449 | { 0x0000a3bc, 0x00000000 }, | ||
450 | { 0x0000a3c0, 0x00000000 }, | ||
451 | { 0x0000a3c4, 0x00000000 }, | ||
452 | { 0x0000a3c8, 0x00000246 }, | ||
453 | { 0x0000a3cc, 0x20202020 }, | ||
454 | { 0x0000a3d0, 0x20202020 }, | ||
455 | { 0x0000a3d4, 0x20202020 }, | ||
456 | { 0x0000a3dc, 0x1ce739ce }, | ||
457 | { 0x0000a3e0, 0x000001ce }, | ||
458 | }; | ||
459 | |||
460 | static const u32 ar5416Bank0[][2] = { | ||
461 | { 0x000098b0, 0x1e5795e5 }, | ||
462 | { 0x000098e0, 0x02008020 }, | ||
463 | }; | ||
464 | |||
465 | static const u32 ar5416BB_RfGain[][3] = { | ||
466 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
467 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
468 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
469 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
470 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
471 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
472 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
473 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
474 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
475 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
476 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
477 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
478 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
479 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
480 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
481 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
482 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
483 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
484 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
485 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
486 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
487 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
488 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
489 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
490 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
491 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
492 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
493 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
494 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
495 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
496 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
497 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
498 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
499 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
500 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
501 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
502 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
503 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
504 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
505 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
506 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
507 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
508 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
509 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
510 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
511 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
512 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
513 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
514 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
515 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
516 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
517 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
518 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
519 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
520 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
521 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
522 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
523 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
524 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
525 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
526 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
527 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
528 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
529 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
530 | }; | ||
531 | |||
532 | static const u32 ar5416Bank1[][2] = { | ||
533 | { 0x000098b0, 0x02108421 }, | ||
534 | { 0x000098ec, 0x00000008 }, | ||
535 | }; | ||
536 | |||
537 | static const u32 ar5416Bank2[][2] = { | ||
538 | { 0x000098b0, 0x0e73ff17 }, | ||
539 | { 0x000098e0, 0x00000420 }, | ||
540 | }; | ||
541 | |||
542 | static const u32 ar5416Bank3[][3] = { | ||
543 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
544 | }; | ||
545 | |||
546 | static const u32 ar5416Bank6[][3] = { | ||
547 | |||
548 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
549 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
550 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
551 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
552 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
553 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
554 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
555 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
556 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
557 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
558 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
559 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
560 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
561 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
562 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
563 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
564 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
565 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
566 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
567 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
568 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
569 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
570 | { 0x0000989c, 0x0014008f, 0x0014008f }, | ||
571 | { 0x0000989c, 0x00c40003, 0x00c40003 }, | ||
572 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
573 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
574 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
575 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
576 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
577 | { 0x0000989c, 0x000000f1, 0x000000f1 }, | ||
578 | { 0x0000989c, 0x00002081, 0x00002081 }, | ||
579 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
580 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
581 | }; | ||
582 | |||
583 | static const u32 ar5416Bank6TPC[][3] = { | ||
584 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
585 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
586 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
587 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
588 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
589 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
590 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
591 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
592 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
593 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
594 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
595 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
596 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
597 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
598 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
599 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
600 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
601 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
602 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
603 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
604 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
605 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
606 | { 0x0000989c, 0x201400df, 0x201400df }, | ||
607 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
608 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
609 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
610 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
611 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
612 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
613 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
614 | { 0x0000989c, 0x00007081, 0x00007081 }, | ||
615 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
616 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
617 | }; | ||
618 | |||
619 | static const u32 ar5416Bank7[][2] = { | ||
620 | { 0x0000989c, 0x00000500 }, | ||
621 | { 0x0000989c, 0x00000800 }, | ||
622 | { 0x000098cc, 0x0000000e }, | ||
623 | }; | ||
624 | |||
625 | static const u32 ar5416Addac[][2] = { | ||
626 | {0x0000989c, 0x00000000 }, | ||
627 | {0x0000989c, 0x00000003 }, | ||
628 | {0x0000989c, 0x00000000 }, | ||
629 | {0x0000989c, 0x0000000c }, | ||
630 | {0x0000989c, 0x00000000 }, | ||
631 | {0x0000989c, 0x00000030 }, | ||
632 | {0x0000989c, 0x00000000 }, | ||
633 | {0x0000989c, 0x00000000 }, | ||
634 | {0x0000989c, 0x00000000 }, | ||
635 | {0x0000989c, 0x00000000 }, | ||
636 | {0x0000989c, 0x00000000 }, | ||
637 | {0x0000989c, 0x00000000 }, | ||
638 | {0x0000989c, 0x00000000 }, | ||
639 | {0x0000989c, 0x00000000 }, | ||
640 | {0x0000989c, 0x00000000 }, | ||
641 | {0x0000989c, 0x00000000 }, | ||
642 | {0x0000989c, 0x00000000 }, | ||
643 | {0x0000989c, 0x00000000 }, | ||
644 | {0x0000989c, 0x00000060 }, | ||
645 | {0x0000989c, 0x00000000 }, | ||
646 | {0x0000989c, 0x00000000 }, | ||
647 | {0x0000989c, 0x00000000 }, | ||
648 | {0x0000989c, 0x00000000 }, | ||
649 | {0x0000989c, 0x00000000 }, | ||
650 | {0x0000989c, 0x00000000 }, | ||
651 | {0x0000989c, 0x00000000 }, | ||
652 | {0x0000989c, 0x00000000 }, | ||
653 | {0x0000989c, 0x00000000 }, | ||
654 | {0x0000989c, 0x00000000 }, | ||
655 | {0x0000989c, 0x00000000 }, | ||
656 | {0x0000989c, 0x00000000 }, | ||
657 | {0x0000989c, 0x00000058 }, | ||
658 | {0x0000989c, 0x00000000 }, | ||
659 | {0x0000989c, 0x00000000 }, | ||
660 | {0x0000989c, 0x00000000 }, | ||
661 | {0x0000989c, 0x00000000 }, | ||
662 | {0x000098cc, 0x00000000 }, | ||
663 | }; | ||
664 | |||
665 | static const u32 ar5416Modes_9100[][6] = { | ||
666 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
667 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
668 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
669 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
670 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
671 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
672 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
673 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
674 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
675 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
676 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
677 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
678 | { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, | ||
679 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
680 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
681 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
682 | { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 }, | ||
683 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e }, | ||
684 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e }, | ||
685 | { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, | ||
686 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
687 | { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, | ||
688 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
689 | { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 }, | ||
690 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
691 | { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d }, | ||
692 | { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 }, | ||
693 | { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 }, | ||
694 | { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e }, | ||
695 | { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff }, | ||
696 | #ifdef TB243 | ||
697 | { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
698 | { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
699 | { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 }, | ||
700 | { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 }, | ||
701 | #else | ||
702 | { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
703 | { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
704 | { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 }, | ||
705 | { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, | ||
706 | #endif | ||
707 | { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 }, | ||
708 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
709 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
710 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
711 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
712 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
713 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
714 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
715 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
716 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
717 | { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
718 | { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
719 | { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
720 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
721 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
722 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
723 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
724 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
725 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
726 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
727 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
728 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
729 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
730 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
731 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
732 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
733 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
734 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
735 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
736 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
737 | }; | ||
738 | |||
739 | static const u32 ar5416Common_9100[][2] = { | ||
740 | { 0x0000000c, 0x00000000 }, | ||
741 | { 0x00000030, 0x00020015 }, | ||
742 | { 0x00000034, 0x00000005 }, | ||
743 | { 0x00000040, 0x00000000 }, | ||
744 | { 0x00000044, 0x00000008 }, | ||
745 | { 0x00000048, 0x00000008 }, | ||
746 | { 0x0000004c, 0x00000010 }, | ||
747 | { 0x00000050, 0x00000000 }, | ||
748 | { 0x00000054, 0x0000001f }, | ||
749 | { 0x00000800, 0x00000000 }, | ||
750 | { 0x00000804, 0x00000000 }, | ||
751 | { 0x00000808, 0x00000000 }, | ||
752 | { 0x0000080c, 0x00000000 }, | ||
753 | { 0x00000810, 0x00000000 }, | ||
754 | { 0x00000814, 0x00000000 }, | ||
755 | { 0x00000818, 0x00000000 }, | ||
756 | { 0x0000081c, 0x00000000 }, | ||
757 | { 0x00000820, 0x00000000 }, | ||
758 | { 0x00000824, 0x00000000 }, | ||
759 | { 0x00001040, 0x002ffc0f }, | ||
760 | { 0x00001044, 0x002ffc0f }, | ||
761 | { 0x00001048, 0x002ffc0f }, | ||
762 | { 0x0000104c, 0x002ffc0f }, | ||
763 | { 0x00001050, 0x002ffc0f }, | ||
764 | { 0x00001054, 0x002ffc0f }, | ||
765 | { 0x00001058, 0x002ffc0f }, | ||
766 | { 0x0000105c, 0x002ffc0f }, | ||
767 | { 0x00001060, 0x002ffc0f }, | ||
768 | { 0x00001064, 0x002ffc0f }, | ||
769 | { 0x00001230, 0x00000000 }, | ||
770 | { 0x00001270, 0x00000000 }, | ||
771 | { 0x00001038, 0x00000000 }, | ||
772 | { 0x00001078, 0x00000000 }, | ||
773 | { 0x000010b8, 0x00000000 }, | ||
774 | { 0x000010f8, 0x00000000 }, | ||
775 | { 0x00001138, 0x00000000 }, | ||
776 | { 0x00001178, 0x00000000 }, | ||
777 | { 0x000011b8, 0x00000000 }, | ||
778 | { 0x000011f8, 0x00000000 }, | ||
779 | { 0x00001238, 0x00000000 }, | ||
780 | { 0x00001278, 0x00000000 }, | ||
781 | { 0x000012b8, 0x00000000 }, | ||
782 | { 0x000012f8, 0x00000000 }, | ||
783 | { 0x00001338, 0x00000000 }, | ||
784 | { 0x00001378, 0x00000000 }, | ||
785 | { 0x000013b8, 0x00000000 }, | ||
786 | { 0x000013f8, 0x00000000 }, | ||
787 | { 0x00001438, 0x00000000 }, | ||
788 | { 0x00001478, 0x00000000 }, | ||
789 | { 0x000014b8, 0x00000000 }, | ||
790 | { 0x000014f8, 0x00000000 }, | ||
791 | { 0x00001538, 0x00000000 }, | ||
792 | { 0x00001578, 0x00000000 }, | ||
793 | { 0x000015b8, 0x00000000 }, | ||
794 | { 0x000015f8, 0x00000000 }, | ||
795 | { 0x00001638, 0x00000000 }, | ||
796 | { 0x00001678, 0x00000000 }, | ||
797 | { 0x000016b8, 0x00000000 }, | ||
798 | { 0x000016f8, 0x00000000 }, | ||
799 | { 0x00001738, 0x00000000 }, | ||
800 | { 0x00001778, 0x00000000 }, | ||
801 | { 0x000017b8, 0x00000000 }, | ||
802 | { 0x000017f8, 0x00000000 }, | ||
803 | { 0x0000103c, 0x00000000 }, | ||
804 | { 0x0000107c, 0x00000000 }, | ||
805 | { 0x000010bc, 0x00000000 }, | ||
806 | { 0x000010fc, 0x00000000 }, | ||
807 | { 0x0000113c, 0x00000000 }, | ||
808 | { 0x0000117c, 0x00000000 }, | ||
809 | { 0x000011bc, 0x00000000 }, | ||
810 | { 0x000011fc, 0x00000000 }, | ||
811 | { 0x0000123c, 0x00000000 }, | ||
812 | { 0x0000127c, 0x00000000 }, | ||
813 | { 0x000012bc, 0x00000000 }, | ||
814 | { 0x000012fc, 0x00000000 }, | ||
815 | { 0x0000133c, 0x00000000 }, | ||
816 | { 0x0000137c, 0x00000000 }, | ||
817 | { 0x000013bc, 0x00000000 }, | ||
818 | { 0x000013fc, 0x00000000 }, | ||
819 | { 0x0000143c, 0x00000000 }, | ||
820 | { 0x0000147c, 0x00000000 }, | ||
821 | { 0x00020010, 0x00000003 }, | ||
822 | { 0x00020038, 0x000004c2 }, | ||
823 | { 0x00008004, 0x00000000 }, | ||
824 | { 0x00008008, 0x00000000 }, | ||
825 | { 0x0000800c, 0x00000000 }, | ||
826 | { 0x00008018, 0x00000700 }, | ||
827 | { 0x00008020, 0x00000000 }, | ||
828 | { 0x00008038, 0x00000000 }, | ||
829 | { 0x0000803c, 0x00000000 }, | ||
830 | { 0x00008048, 0x40000000 }, | ||
831 | { 0x00008054, 0x00004000 }, | ||
832 | { 0x00008058, 0x00000000 }, | ||
833 | { 0x0000805c, 0x000fc78f }, | ||
834 | { 0x00008060, 0x0000000f }, | ||
835 | { 0x00008064, 0x00000000 }, | ||
836 | { 0x000080c0, 0x2a82301a }, | ||
837 | { 0x000080c4, 0x05dc01e0 }, | ||
838 | { 0x000080c8, 0x1f402710 }, | ||
839 | { 0x000080cc, 0x01f40000 }, | ||
840 | { 0x000080d0, 0x00001e00 }, | ||
841 | { 0x000080d4, 0x00000000 }, | ||
842 | { 0x000080d8, 0x00400000 }, | ||
843 | { 0x000080e0, 0xffffffff }, | ||
844 | { 0x000080e4, 0x0000ffff }, | ||
845 | { 0x000080e8, 0x003f3f3f }, | ||
846 | { 0x000080ec, 0x00000000 }, | ||
847 | { 0x000080f0, 0x00000000 }, | ||
848 | { 0x000080f4, 0x00000000 }, | ||
849 | { 0x000080f8, 0x00000000 }, | ||
850 | { 0x000080fc, 0x00020000 }, | ||
851 | { 0x00008100, 0x00020000 }, | ||
852 | { 0x00008104, 0x00000001 }, | ||
853 | { 0x00008108, 0x00000052 }, | ||
854 | { 0x0000810c, 0x00000000 }, | ||
855 | { 0x00008110, 0x00000168 }, | ||
856 | { 0x00008118, 0x000100aa }, | ||
857 | { 0x0000811c, 0x00003210 }, | ||
858 | { 0x00008120, 0x08f04800 }, | ||
859 | { 0x00008124, 0x00000000 }, | ||
860 | { 0x00008128, 0x00000000 }, | ||
861 | { 0x0000812c, 0x00000000 }, | ||
862 | { 0x00008130, 0x00000000 }, | ||
863 | { 0x00008134, 0x00000000 }, | ||
864 | { 0x00008138, 0x00000000 }, | ||
865 | { 0x0000813c, 0x00000000 }, | ||
866 | { 0x00008144, 0x00000000 }, | ||
867 | { 0x00008168, 0x00000000 }, | ||
868 | { 0x0000816c, 0x00000000 }, | ||
869 | { 0x00008170, 0x32143320 }, | ||
870 | { 0x00008174, 0xfaa4fa50 }, | ||
871 | { 0x00008178, 0x00000100 }, | ||
872 | { 0x0000817c, 0x00000000 }, | ||
873 | { 0x000081c4, 0x00000000 }, | ||
874 | { 0x000081d0, 0x00003210 }, | ||
875 | { 0x000081ec, 0x00000000 }, | ||
876 | { 0x000081f0, 0x00000000 }, | ||
877 | { 0x000081f4, 0x00000000 }, | ||
878 | { 0x000081f8, 0x00000000 }, | ||
879 | { 0x000081fc, 0x00000000 }, | ||
880 | { 0x00008200, 0x00000000 }, | ||
881 | { 0x00008204, 0x00000000 }, | ||
882 | { 0x00008208, 0x00000000 }, | ||
883 | { 0x0000820c, 0x00000000 }, | ||
884 | { 0x00008210, 0x00000000 }, | ||
885 | { 0x00008214, 0x00000000 }, | ||
886 | { 0x00008218, 0x00000000 }, | ||
887 | { 0x0000821c, 0x00000000 }, | ||
888 | { 0x00008220, 0x00000000 }, | ||
889 | { 0x00008224, 0x00000000 }, | ||
890 | { 0x00008228, 0x00000000 }, | ||
891 | { 0x0000822c, 0x00000000 }, | ||
892 | { 0x00008230, 0x00000000 }, | ||
893 | { 0x00008234, 0x00000000 }, | ||
894 | { 0x00008238, 0x00000000 }, | ||
895 | { 0x0000823c, 0x00000000 }, | ||
896 | { 0x00008240, 0x00100000 }, | ||
897 | { 0x00008244, 0x0010f400 }, | ||
898 | { 0x00008248, 0x00000100 }, | ||
899 | { 0x0000824c, 0x0001e800 }, | ||
900 | { 0x00008250, 0x00000000 }, | ||
901 | { 0x00008254, 0x00000000 }, | ||
902 | { 0x00008258, 0x00000000 }, | ||
903 | { 0x0000825c, 0x400000ff }, | ||
904 | { 0x00008260, 0x00080922 }, | ||
905 | { 0x00008270, 0x00000000 }, | ||
906 | { 0x00008274, 0x40000000 }, | ||
907 | { 0x00008278, 0x003e4180 }, | ||
908 | { 0x0000827c, 0x00000000 }, | ||
909 | { 0x00008284, 0x0000002c }, | ||
910 | { 0x00008288, 0x0000002c }, | ||
911 | { 0x0000828c, 0x00000000 }, | ||
912 | { 0x00008294, 0x00000000 }, | ||
913 | { 0x00008298, 0x00000000 }, | ||
914 | { 0x00008300, 0x00000000 }, | ||
915 | { 0x00008304, 0x00000000 }, | ||
916 | { 0x00008308, 0x00000000 }, | ||
917 | { 0x0000830c, 0x00000000 }, | ||
918 | { 0x00008310, 0x00000000 }, | ||
919 | { 0x00008314, 0x00000000 }, | ||
920 | { 0x00008318, 0x00000000 }, | ||
921 | { 0x00008328, 0x00000000 }, | ||
922 | { 0x0000832c, 0x00000007 }, | ||
923 | { 0x00008330, 0x00000302 }, | ||
924 | { 0x00008334, 0x00000e00 }, | ||
925 | { 0x00008338, 0x00000000 }, | ||
926 | { 0x0000833c, 0x00000000 }, | ||
927 | { 0x00008340, 0x000107ff }, | ||
928 | { 0x00009808, 0x00000000 }, | ||
929 | { 0x0000980c, 0xad848e19 }, | ||
930 | { 0x00009810, 0x7d14e000 }, | ||
931 | { 0x00009814, 0x9c0a9f6b }, | ||
932 | { 0x0000981c, 0x00000000 }, | ||
933 | { 0x0000982c, 0x0000a000 }, | ||
934 | { 0x00009830, 0x00000000 }, | ||
935 | { 0x0000983c, 0x00200400 }, | ||
936 | { 0x00009840, 0x206a01ae }, | ||
937 | { 0x0000984c, 0x1284233c }, | ||
938 | { 0x00009854, 0x00000859 }, | ||
939 | { 0x00009900, 0x00000000 }, | ||
940 | { 0x00009904, 0x00000000 }, | ||
941 | { 0x00009908, 0x00000000 }, | ||
942 | { 0x0000990c, 0x00000000 }, | ||
943 | { 0x0000991c, 0x10000fff }, | ||
944 | { 0x00009920, 0x05100000 }, | ||
945 | { 0x0000a920, 0x05100000 }, | ||
946 | { 0x0000b920, 0x05100000 }, | ||
947 | { 0x00009928, 0x00000001 }, | ||
948 | { 0x0000992c, 0x00000004 }, | ||
949 | { 0x00009934, 0x1e1f2022 }, | ||
950 | { 0x00009938, 0x0a0b0c0d }, | ||
951 | { 0x0000993c, 0x00000000 }, | ||
952 | { 0x00009948, 0x9280b212 }, | ||
953 | { 0x0000994c, 0x00020028 }, | ||
954 | { 0x0000c95c, 0x004b6a8e }, | ||
955 | { 0x0000c968, 0x000003ce }, | ||
956 | { 0x00009970, 0x190fb515 }, | ||
957 | { 0x00009974, 0x00000000 }, | ||
958 | { 0x00009978, 0x00000001 }, | ||
959 | { 0x0000997c, 0x00000000 }, | ||
960 | { 0x00009980, 0x00000000 }, | ||
961 | { 0x00009984, 0x00000000 }, | ||
962 | { 0x00009988, 0x00000000 }, | ||
963 | { 0x0000998c, 0x00000000 }, | ||
964 | { 0x00009990, 0x00000000 }, | ||
965 | { 0x00009994, 0x00000000 }, | ||
966 | { 0x00009998, 0x00000000 }, | ||
967 | { 0x0000999c, 0x00000000 }, | ||
968 | { 0x000099a0, 0x00000000 }, | ||
969 | { 0x000099a4, 0x00000001 }, | ||
970 | { 0x000099a8, 0x201fff00 }, | ||
971 | { 0x000099ac, 0x006f0000 }, | ||
972 | { 0x000099b0, 0x03051000 }, | ||
973 | { 0x000099dc, 0x00000000 }, | ||
974 | { 0x000099e0, 0x00000200 }, | ||
975 | { 0x000099e4, 0xaaaaaaaa }, | ||
976 | { 0x000099e8, 0x3c466478 }, | ||
977 | { 0x000099ec, 0x0cc80caa }, | ||
978 | { 0x000099fc, 0x00001042 }, | ||
979 | { 0x00009b00, 0x00000000 }, | ||
980 | { 0x00009b04, 0x00000001 }, | ||
981 | { 0x00009b08, 0x00000002 }, | ||
982 | { 0x00009b0c, 0x00000003 }, | ||
983 | { 0x00009b10, 0x00000004 }, | ||
984 | { 0x00009b14, 0x00000005 }, | ||
985 | { 0x00009b18, 0x00000008 }, | ||
986 | { 0x00009b1c, 0x00000009 }, | ||
987 | { 0x00009b20, 0x0000000a }, | ||
988 | { 0x00009b24, 0x0000000b }, | ||
989 | { 0x00009b28, 0x0000000c }, | ||
990 | { 0x00009b2c, 0x0000000d }, | ||
991 | { 0x00009b30, 0x00000010 }, | ||
992 | { 0x00009b34, 0x00000011 }, | ||
993 | { 0x00009b38, 0x00000012 }, | ||
994 | { 0x00009b3c, 0x00000013 }, | ||
995 | { 0x00009b40, 0x00000014 }, | ||
996 | { 0x00009b44, 0x00000015 }, | ||
997 | { 0x00009b48, 0x00000018 }, | ||
998 | { 0x00009b4c, 0x00000019 }, | ||
999 | { 0x00009b50, 0x0000001a }, | ||
1000 | { 0x00009b54, 0x0000001b }, | ||
1001 | { 0x00009b58, 0x0000001c }, | ||
1002 | { 0x00009b5c, 0x0000001d }, | ||
1003 | { 0x00009b60, 0x00000020 }, | ||
1004 | { 0x00009b64, 0x00000021 }, | ||
1005 | { 0x00009b68, 0x00000022 }, | ||
1006 | { 0x00009b6c, 0x00000023 }, | ||
1007 | { 0x00009b70, 0x00000024 }, | ||
1008 | { 0x00009b74, 0x00000025 }, | ||
1009 | { 0x00009b78, 0x00000028 }, | ||
1010 | { 0x00009b7c, 0x00000029 }, | ||
1011 | { 0x00009b80, 0x0000002a }, | ||
1012 | { 0x00009b84, 0x0000002b }, | ||
1013 | { 0x00009b88, 0x0000002c }, | ||
1014 | { 0x00009b8c, 0x0000002d }, | ||
1015 | { 0x00009b90, 0x00000030 }, | ||
1016 | { 0x00009b94, 0x00000031 }, | ||
1017 | { 0x00009b98, 0x00000032 }, | ||
1018 | { 0x00009b9c, 0x00000033 }, | ||
1019 | { 0x00009ba0, 0x00000034 }, | ||
1020 | { 0x00009ba4, 0x00000035 }, | ||
1021 | { 0x00009ba8, 0x00000035 }, | ||
1022 | { 0x00009bac, 0x00000035 }, | ||
1023 | { 0x00009bb0, 0x00000035 }, | ||
1024 | { 0x00009bb4, 0x00000035 }, | ||
1025 | { 0x00009bb8, 0x00000035 }, | ||
1026 | { 0x00009bbc, 0x00000035 }, | ||
1027 | { 0x00009bc0, 0x00000035 }, | ||
1028 | { 0x00009bc4, 0x00000035 }, | ||
1029 | { 0x00009bc8, 0x00000035 }, | ||
1030 | { 0x00009bcc, 0x00000035 }, | ||
1031 | { 0x00009bd0, 0x00000035 }, | ||
1032 | { 0x00009bd4, 0x00000035 }, | ||
1033 | { 0x00009bd8, 0x00000035 }, | ||
1034 | { 0x00009bdc, 0x00000035 }, | ||
1035 | { 0x00009be0, 0x00000035 }, | ||
1036 | { 0x00009be4, 0x00000035 }, | ||
1037 | { 0x00009be8, 0x00000035 }, | ||
1038 | { 0x00009bec, 0x00000035 }, | ||
1039 | { 0x00009bf0, 0x00000035 }, | ||
1040 | { 0x00009bf4, 0x00000035 }, | ||
1041 | { 0x00009bf8, 0x00000010 }, | ||
1042 | { 0x00009bfc, 0x0000001a }, | ||
1043 | { 0x0000a210, 0x40806333 }, | ||
1044 | { 0x0000a214, 0x00106c10 }, | ||
1045 | { 0x0000a218, 0x009c4060 }, | ||
1046 | { 0x0000a220, 0x018830c6 }, | ||
1047 | { 0x0000a224, 0x00000400 }, | ||
1048 | { 0x0000a228, 0x001a0bb5 }, | ||
1049 | { 0x0000a22c, 0x00000000 }, | ||
1050 | { 0x0000a234, 0x20202020 }, | ||
1051 | { 0x0000a238, 0x20202020 }, | ||
1052 | { 0x0000a23c, 0x13c889ae }, | ||
1053 | { 0x0000a240, 0x38490a20 }, | ||
1054 | { 0x0000a244, 0x00007bb6 }, | ||
1055 | { 0x0000a248, 0x0fff3ffc }, | ||
1056 | { 0x0000a24c, 0x00000001 }, | ||
1057 | { 0x0000a250, 0x0000a000 }, | ||
1058 | { 0x0000a254, 0x00000000 }, | ||
1059 | { 0x0000a258, 0x0cc75380 }, | ||
1060 | { 0x0000a25c, 0x0f0f0f01 }, | ||
1061 | { 0x0000a260, 0xdfa91f01 }, | ||
1062 | { 0x0000a268, 0x00000001 }, | ||
1063 | { 0x0000a26c, 0x0ebae9c6 }, | ||
1064 | { 0x0000b26c, 0x0ebae9c6 }, | ||
1065 | { 0x0000c26c, 0x0ebae9c6 }, | ||
1066 | { 0x0000d270, 0x00820820 }, | ||
1067 | { 0x0000a278, 0x1ce739ce }, | ||
1068 | { 0x0000a27c, 0x050701ce }, | ||
1069 | { 0x0000a338, 0x00000000 }, | ||
1070 | { 0x0000a33c, 0x00000000 }, | ||
1071 | { 0x0000a340, 0x00000000 }, | ||
1072 | { 0x0000a344, 0x00000000 }, | ||
1073 | { 0x0000a348, 0x3fffffff }, | ||
1074 | { 0x0000a34c, 0x3fffffff }, | ||
1075 | { 0x0000a350, 0x3fffffff }, | ||
1076 | { 0x0000a354, 0x0003ffff }, | ||
1077 | { 0x0000a358, 0x79a8aa33 }, | ||
1078 | { 0x0000d35c, 0x07ffffef }, | ||
1079 | { 0x0000d360, 0x0fffffe7 }, | ||
1080 | { 0x0000d364, 0x17ffffe5 }, | ||
1081 | { 0x0000d368, 0x1fffffe4 }, | ||
1082 | { 0x0000d36c, 0x37ffffe3 }, | ||
1083 | { 0x0000d370, 0x3fffffe3 }, | ||
1084 | { 0x0000d374, 0x57ffffe3 }, | ||
1085 | { 0x0000d378, 0x5fffffe2 }, | ||
1086 | { 0x0000d37c, 0x7fffffe2 }, | ||
1087 | { 0x0000d380, 0x7f3c7bba }, | ||
1088 | { 0x0000d384, 0xf3307ff0 }, | ||
1089 | { 0x0000a388, 0x0c000000 }, | ||
1090 | { 0x0000a38c, 0x20202020 }, | ||
1091 | { 0x0000a390, 0x20202020 }, | ||
1092 | { 0x0000a394, 0x1ce739ce }, | ||
1093 | { 0x0000a398, 0x000001ce }, | ||
1094 | { 0x0000a39c, 0x00000001 }, | ||
1095 | { 0x0000a3a0, 0x00000000 }, | ||
1096 | { 0x0000a3a4, 0x00000000 }, | ||
1097 | { 0x0000a3a8, 0x00000000 }, | ||
1098 | { 0x0000a3ac, 0x00000000 }, | ||
1099 | { 0x0000a3b0, 0x00000000 }, | ||
1100 | { 0x0000a3b4, 0x00000000 }, | ||
1101 | { 0x0000a3b8, 0x00000000 }, | ||
1102 | { 0x0000a3bc, 0x00000000 }, | ||
1103 | { 0x0000a3c0, 0x00000000 }, | ||
1104 | { 0x0000a3c4, 0x00000000 }, | ||
1105 | { 0x0000a3c8, 0x00000246 }, | ||
1106 | { 0x0000a3cc, 0x20202020 }, | ||
1107 | { 0x0000a3d0, 0x20202020 }, | ||
1108 | { 0x0000a3d4, 0x20202020 }, | ||
1109 | { 0x0000a3dc, 0x1ce739ce }, | ||
1110 | { 0x0000a3e0, 0x000001ce }, | ||
1111 | }; | ||
1112 | |||
1113 | static const u32 ar5416Bank0_9100[][2] = { | ||
1114 | { 0x000098b0, 0x1e5795e5 }, | ||
1115 | { 0x000098e0, 0x02008020 }, | ||
1116 | }; | ||
1117 | |||
1118 | static const u32 ar5416BB_RfGain_9100[][3] = { | ||
1119 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
1120 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
1121 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
1122 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
1123 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
1124 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
1125 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
1126 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
1127 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
1128 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
1129 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
1130 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
1131 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
1132 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
1133 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
1134 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
1135 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
1136 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
1137 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
1138 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
1139 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
1140 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
1141 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
1142 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
1143 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
1144 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
1145 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
1146 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
1147 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
1148 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
1149 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
1150 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
1151 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
1152 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
1153 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
1154 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
1155 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
1156 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
1157 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
1158 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
1159 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
1160 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
1161 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
1162 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
1163 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
1164 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
1165 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
1166 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
1167 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
1168 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
1169 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
1170 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
1171 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
1172 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
1173 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
1174 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
1175 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
1176 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
1177 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
1178 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
1179 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
1180 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
1181 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
1182 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
1183 | }; | ||
1184 | |||
1185 | static const u32 ar5416Bank1_9100[][2] = { | ||
1186 | { 0x000098b0, 0x02108421}, | ||
1187 | { 0x000098ec, 0x00000008}, | ||
1188 | }; | ||
1189 | |||
1190 | static const u32 ar5416Bank2_9100[][2] = { | ||
1191 | { 0x000098b0, 0x0e73ff17}, | ||
1192 | { 0x000098e0, 0x00000420}, | ||
1193 | }; | ||
1194 | |||
1195 | static const u32 ar5416Bank3_9100[][3] = { | ||
1196 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
1197 | }; | ||
1198 | |||
1199 | static const u32 ar5416Bank6_9100[][3] = { | ||
1200 | |||
1201 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1202 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1203 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1204 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1205 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1206 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1207 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1208 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1209 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1210 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1211 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1212 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1213 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1214 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1215 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1216 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1217 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1218 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1219 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1220 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1221 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1222 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
1223 | { 0x0000989c, 0x0014000f, 0x0014000f }, | ||
1224 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
1225 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1226 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1227 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1228 | { 0x0000989c, 0x000180d6, 0x000180d6 }, | ||
1229 | { 0x0000989c, 0x0000c0aa, 0x0000c0aa }, | ||
1230 | { 0x0000989c, 0x000000b1, 0x000000b1 }, | ||
1231 | { 0x0000989c, 0x00002000, 0x00002000 }, | ||
1232 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1233 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1234 | }; | ||
1235 | |||
1236 | |||
1237 | static const u32 ar5416Bank6TPC_9100[][3] = { | ||
1238 | |||
1239 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1240 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1241 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1242 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1243 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1244 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1245 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1246 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1247 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1248 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1249 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1250 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1251 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1252 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1253 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1254 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1255 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1256 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1257 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1258 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1259 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1260 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
1261 | { 0x0000989c, 0x2014008f, 0x2014008f }, | ||
1262 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
1263 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1264 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1265 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1266 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1267 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1268 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
1269 | { 0x0000989c, 0x00007080, 0x00007080 }, | ||
1270 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1271 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1272 | }; | ||
1273 | |||
1274 | static const u32 ar5416Bank7_9100[][2] = { | ||
1275 | { 0x0000989c, 0x00000500 }, | ||
1276 | { 0x0000989c, 0x00000800 }, | ||
1277 | { 0x000098cc, 0x0000000e }, | ||
1278 | }; | ||
1279 | |||
1280 | static const u32 ar5416Addac_9100[][2] = { | ||
1281 | {0x0000989c, 0x00000000 }, | ||
1282 | {0x0000989c, 0x00000000 }, | ||
1283 | {0x0000989c, 0x00000000 }, | ||
1284 | {0x0000989c, 0x00000000 }, | ||
1285 | {0x0000989c, 0x00000000 }, | ||
1286 | {0x0000989c, 0x00000000 }, | ||
1287 | {0x0000989c, 0x00000000 }, | ||
1288 | {0x0000989c, 0x00000010 }, | ||
1289 | {0x0000989c, 0x00000000 }, | ||
1290 | {0x0000989c, 0x00000000 }, | ||
1291 | {0x0000989c, 0x00000000 }, | ||
1292 | {0x0000989c, 0x00000000 }, | ||
1293 | {0x0000989c, 0x00000000 }, | ||
1294 | {0x0000989c, 0x00000000 }, | ||
1295 | {0x0000989c, 0x00000000 }, | ||
1296 | {0x0000989c, 0x00000000 }, | ||
1297 | {0x0000989c, 0x00000000 }, | ||
1298 | {0x0000989c, 0x00000000 }, | ||
1299 | {0x0000989c, 0x00000000 }, | ||
1300 | {0x0000989c, 0x00000000 }, | ||
1301 | {0x0000989c, 0x00000000 }, | ||
1302 | {0x0000989c, 0x000000c0 }, | ||
1303 | {0x0000989c, 0x00000015 }, | ||
1304 | {0x0000989c, 0x00000000 }, | ||
1305 | {0x0000989c, 0x00000000 }, | ||
1306 | {0x0000989c, 0x00000000 }, | ||
1307 | {0x0000989c, 0x00000000 }, | ||
1308 | {0x0000989c, 0x00000000 }, | ||
1309 | {0x0000989c, 0x00000000 }, | ||
1310 | {0x0000989c, 0x00000000 }, | ||
1311 | {0x0000989c, 0x00000000 }, | ||
1312 | {0x000098cc, 0x00000000 }, | ||
1313 | }; | ||
1314 | |||
1315 | static const u32 ar5416Modes_9160[][6] = { | ||
1316 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | ||
1317 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | ||
1318 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | ||
1319 | { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 }, | ||
1320 | { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 }, | ||
1321 | { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf }, | ||
1322 | { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 }, | ||
1323 | { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 }, | ||
1324 | { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
1325 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | ||
1326 | { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e }, | ||
1327 | { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 }, | ||
1328 | { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 }, | ||
1329 | { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
1330 | { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
1331 | { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 }, | ||
1332 | { 0x00009850, 0x6c48b4e2, 0x6c48b4e2, 0x6c48b0e2, 0x6c48b0e2, 0x6c48b0e2 }, | ||
1333 | { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e }, | ||
1334 | { 0x0000985c, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e, 0x31395d5e }, | ||
1335 | { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 }, | ||
1336 | { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 }, | ||
1337 | { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 }, | ||
1338 | { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 }, | ||
1339 | { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 }, | ||
1340 | { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 }, | ||
1341 | { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d }, | ||
1342 | { 0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020 }, | ||
1343 | { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
1344 | { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
1345 | { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 }, | ||
1346 | { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 }, | ||
1347 | { 0x0000c968, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce, 0x000003ce }, | ||
1348 | { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 }, | ||
1349 | { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be }, | ||
1350 | { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 }, | ||
1351 | { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 }, | ||
1352 | { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 }, | ||
1353 | { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 }, | ||
1354 | { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1355 | { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1356 | { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 }, | ||
1357 | { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 }, | ||
1358 | { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
1359 | { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
1360 | { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 }, | ||
1361 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | ||
1362 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | ||
1363 | { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa }, | ||
1364 | { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 }, | ||
1365 | { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 }, | ||
1366 | { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 }, | ||
1367 | { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b }, | ||
1368 | { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b }, | ||
1369 | { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a }, | ||
1370 | { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf }, | ||
1371 | { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f }, | ||
1372 | { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f }, | ||
1373 | { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f }, | ||
1374 | { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 }, | ||
1375 | { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1376 | { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1377 | { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
1378 | }; | ||
1379 | |||
1380 | static const u32 ar5416Common_9160[][2] = { | ||
1381 | { 0x0000000c, 0x00000000 }, | ||
1382 | { 0x00000030, 0x00020015 }, | ||
1383 | { 0x00000034, 0x00000005 }, | ||
1384 | { 0x00000040, 0x00000000 }, | ||
1385 | { 0x00000044, 0x00000008 }, | ||
1386 | { 0x00000048, 0x00000008 }, | ||
1387 | { 0x0000004c, 0x00000010 }, | ||
1388 | { 0x00000050, 0x00000000 }, | ||
1389 | { 0x00000054, 0x0000001f }, | ||
1390 | { 0x00000800, 0x00000000 }, | ||
1391 | { 0x00000804, 0x00000000 }, | ||
1392 | { 0x00000808, 0x00000000 }, | ||
1393 | { 0x0000080c, 0x00000000 }, | ||
1394 | { 0x00000810, 0x00000000 }, | ||
1395 | { 0x00000814, 0x00000000 }, | ||
1396 | { 0x00000818, 0x00000000 }, | ||
1397 | { 0x0000081c, 0x00000000 }, | ||
1398 | { 0x00000820, 0x00000000 }, | ||
1399 | { 0x00000824, 0x00000000 }, | ||
1400 | { 0x00001040, 0x002ffc0f }, | ||
1401 | { 0x00001044, 0x002ffc0f }, | ||
1402 | { 0x00001048, 0x002ffc0f }, | ||
1403 | { 0x0000104c, 0x002ffc0f }, | ||
1404 | { 0x00001050, 0x002ffc0f }, | ||
1405 | { 0x00001054, 0x002ffc0f }, | ||
1406 | { 0x00001058, 0x002ffc0f }, | ||
1407 | { 0x0000105c, 0x002ffc0f }, | ||
1408 | { 0x00001060, 0x002ffc0f }, | ||
1409 | { 0x00001064, 0x002ffc0f }, | ||
1410 | { 0x00001230, 0x00000000 }, | ||
1411 | { 0x00001270, 0x00000000 }, | ||
1412 | { 0x00001038, 0x00000000 }, | ||
1413 | { 0x00001078, 0x00000000 }, | ||
1414 | { 0x000010b8, 0x00000000 }, | ||
1415 | { 0x000010f8, 0x00000000 }, | ||
1416 | { 0x00001138, 0x00000000 }, | ||
1417 | { 0x00001178, 0x00000000 }, | ||
1418 | { 0x000011b8, 0x00000000 }, | ||
1419 | { 0x000011f8, 0x00000000 }, | ||
1420 | { 0x00001238, 0x00000000 }, | ||
1421 | { 0x00001278, 0x00000000 }, | ||
1422 | { 0x000012b8, 0x00000000 }, | ||
1423 | { 0x000012f8, 0x00000000 }, | ||
1424 | { 0x00001338, 0x00000000 }, | ||
1425 | { 0x00001378, 0x00000000 }, | ||
1426 | { 0x000013b8, 0x00000000 }, | ||
1427 | { 0x000013f8, 0x00000000 }, | ||
1428 | { 0x00001438, 0x00000000 }, | ||
1429 | { 0x00001478, 0x00000000 }, | ||
1430 | { 0x000014b8, 0x00000000 }, | ||
1431 | { 0x000014f8, 0x00000000 }, | ||
1432 | { 0x00001538, 0x00000000 }, | ||
1433 | { 0x00001578, 0x00000000 }, | ||
1434 | { 0x000015b8, 0x00000000 }, | ||
1435 | { 0x000015f8, 0x00000000 }, | ||
1436 | { 0x00001638, 0x00000000 }, | ||
1437 | { 0x00001678, 0x00000000 }, | ||
1438 | { 0x000016b8, 0x00000000 }, | ||
1439 | { 0x000016f8, 0x00000000 }, | ||
1440 | { 0x00001738, 0x00000000 }, | ||
1441 | { 0x00001778, 0x00000000 }, | ||
1442 | { 0x000017b8, 0x00000000 }, | ||
1443 | { 0x000017f8, 0x00000000 }, | ||
1444 | { 0x0000103c, 0x00000000 }, | ||
1445 | { 0x0000107c, 0x00000000 }, | ||
1446 | { 0x000010bc, 0x00000000 }, | ||
1447 | { 0x000010fc, 0x00000000 }, | ||
1448 | { 0x0000113c, 0x00000000 }, | ||
1449 | { 0x0000117c, 0x00000000 }, | ||
1450 | { 0x000011bc, 0x00000000 }, | ||
1451 | { 0x000011fc, 0x00000000 }, | ||
1452 | { 0x0000123c, 0x00000000 }, | ||
1453 | { 0x0000127c, 0x00000000 }, | ||
1454 | { 0x000012bc, 0x00000000 }, | ||
1455 | { 0x000012fc, 0x00000000 }, | ||
1456 | { 0x0000133c, 0x00000000 }, | ||
1457 | { 0x0000137c, 0x00000000 }, | ||
1458 | { 0x000013bc, 0x00000000 }, | ||
1459 | { 0x000013fc, 0x00000000 }, | ||
1460 | { 0x0000143c, 0x00000000 }, | ||
1461 | { 0x0000147c, 0x00000000 }, | ||
1462 | { 0x00004030, 0x00000002 }, | ||
1463 | { 0x0000403c, 0x00000002 }, | ||
1464 | { 0x00007010, 0x00000020 }, | ||
1465 | { 0x00007038, 0x000004c2 }, | ||
1466 | { 0x00008004, 0x00000000 }, | ||
1467 | { 0x00008008, 0x00000000 }, | ||
1468 | { 0x0000800c, 0x00000000 }, | ||
1469 | { 0x00008018, 0x00000700 }, | ||
1470 | { 0x00008020, 0x00000000 }, | ||
1471 | { 0x00008038, 0x00000000 }, | ||
1472 | { 0x0000803c, 0x00000000 }, | ||
1473 | { 0x00008048, 0x40000000 }, | ||
1474 | { 0x00008054, 0x00000000 }, | ||
1475 | { 0x00008058, 0x00000000 }, | ||
1476 | { 0x0000805c, 0x000fc78f }, | ||
1477 | { 0x00008060, 0x0000000f }, | ||
1478 | { 0x00008064, 0x00000000 }, | ||
1479 | { 0x000080c0, 0x2a82301a }, | ||
1480 | { 0x000080c4, 0x05dc01e0 }, | ||
1481 | { 0x000080c8, 0x1f402710 }, | ||
1482 | { 0x000080cc, 0x01f40000 }, | ||
1483 | { 0x000080d0, 0x00001e00 }, | ||
1484 | { 0x000080d4, 0x00000000 }, | ||
1485 | { 0x000080d8, 0x00400000 }, | ||
1486 | { 0x000080e0, 0xffffffff }, | ||
1487 | { 0x000080e4, 0x0000ffff }, | ||
1488 | { 0x000080e8, 0x003f3f3f }, | ||
1489 | { 0x000080ec, 0x00000000 }, | ||
1490 | { 0x000080f0, 0x00000000 }, | ||
1491 | { 0x000080f4, 0x00000000 }, | ||
1492 | { 0x000080f8, 0x00000000 }, | ||
1493 | { 0x000080fc, 0x00020000 }, | ||
1494 | { 0x00008100, 0x00020000 }, | ||
1495 | { 0x00008104, 0x00000001 }, | ||
1496 | { 0x00008108, 0x00000052 }, | ||
1497 | { 0x0000810c, 0x00000000 }, | ||
1498 | { 0x00008110, 0x00000168 }, | ||
1499 | { 0x00008118, 0x000100aa }, | ||
1500 | { 0x0000811c, 0x00003210 }, | ||
1501 | { 0x00008120, 0x08f04800 }, | ||
1502 | { 0x00008124, 0x00000000 }, | ||
1503 | { 0x00008128, 0x00000000 }, | ||
1504 | { 0x0000812c, 0x00000000 }, | ||
1505 | { 0x00008130, 0x00000000 }, | ||
1506 | { 0x00008134, 0x00000000 }, | ||
1507 | { 0x00008138, 0x00000000 }, | ||
1508 | { 0x0000813c, 0x00000000 }, | ||
1509 | { 0x00008144, 0xffffffff }, | ||
1510 | { 0x00008168, 0x00000000 }, | ||
1511 | { 0x0000816c, 0x00000000 }, | ||
1512 | { 0x00008170, 0x32143320 }, | ||
1513 | { 0x00008174, 0xfaa4fa50 }, | ||
1514 | { 0x00008178, 0x00000100 }, | ||
1515 | { 0x0000817c, 0x00000000 }, | ||
1516 | { 0x000081c4, 0x00000000 }, | ||
1517 | { 0x000081d0, 0x00003210 }, | ||
1518 | { 0x000081ec, 0x00000000 }, | ||
1519 | { 0x000081f0, 0x00000000 }, | ||
1520 | { 0x000081f4, 0x00000000 }, | ||
1521 | { 0x000081f8, 0x00000000 }, | ||
1522 | { 0x000081fc, 0x00000000 }, | ||
1523 | { 0x00008200, 0x00000000 }, | ||
1524 | { 0x00008204, 0x00000000 }, | ||
1525 | { 0x00008208, 0x00000000 }, | ||
1526 | { 0x0000820c, 0x00000000 }, | ||
1527 | { 0x00008210, 0x00000000 }, | ||
1528 | { 0x00008214, 0x00000000 }, | ||
1529 | { 0x00008218, 0x00000000 }, | ||
1530 | { 0x0000821c, 0x00000000 }, | ||
1531 | { 0x00008220, 0x00000000 }, | ||
1532 | { 0x00008224, 0x00000000 }, | ||
1533 | { 0x00008228, 0x00000000 }, | ||
1534 | { 0x0000822c, 0x00000000 }, | ||
1535 | { 0x00008230, 0x00000000 }, | ||
1536 | { 0x00008234, 0x00000000 }, | ||
1537 | { 0x00008238, 0x00000000 }, | ||
1538 | { 0x0000823c, 0x00000000 }, | ||
1539 | { 0x00008240, 0x00100000 }, | ||
1540 | { 0x00008244, 0x0010f400 }, | ||
1541 | { 0x00008248, 0x00000100 }, | ||
1542 | { 0x0000824c, 0x0001e800 }, | ||
1543 | { 0x00008250, 0x00000000 }, | ||
1544 | { 0x00008254, 0x00000000 }, | ||
1545 | { 0x00008258, 0x00000000 }, | ||
1546 | { 0x0000825c, 0x400000ff }, | ||
1547 | { 0x00008260, 0x00080922 }, | ||
1548 | { 0x00008270, 0x00000000 }, | ||
1549 | { 0x00008274, 0x40000000 }, | ||
1550 | { 0x00008278, 0x003e4180 }, | ||
1551 | { 0x0000827c, 0x00000000 }, | ||
1552 | { 0x00008284, 0x0000002c }, | ||
1553 | { 0x00008288, 0x0000002c }, | ||
1554 | { 0x0000828c, 0x00000000 }, | ||
1555 | { 0x00008294, 0x00000000 }, | ||
1556 | { 0x00008298, 0x00000000 }, | ||
1557 | { 0x00008300, 0x00000000 }, | ||
1558 | { 0x00008304, 0x00000000 }, | ||
1559 | { 0x00008308, 0x00000000 }, | ||
1560 | { 0x0000830c, 0x00000000 }, | ||
1561 | { 0x00008310, 0x00000000 }, | ||
1562 | { 0x00008314, 0x00000000 }, | ||
1563 | { 0x00008318, 0x00000000 }, | ||
1564 | { 0x00008328, 0x00000000 }, | ||
1565 | { 0x0000832c, 0x00000007 }, | ||
1566 | { 0x00008330, 0x00000302 }, | ||
1567 | { 0x00008334, 0x00000e00 }, | ||
1568 | { 0x00008338, 0x00ff0000 }, | ||
1569 | { 0x0000833c, 0x00000000 }, | ||
1570 | { 0x00008340, 0x000107ff }, | ||
1571 | { 0x00009808, 0x00000000 }, | ||
1572 | { 0x0000980c, 0xad848e19 }, | ||
1573 | { 0x00009810, 0x7d14e000 }, | ||
1574 | { 0x00009814, 0x9c0a9f6b }, | ||
1575 | { 0x0000981c, 0x00000000 }, | ||
1576 | { 0x0000982c, 0x0000a000 }, | ||
1577 | { 0x00009830, 0x00000000 }, | ||
1578 | { 0x0000983c, 0x00200400 }, | ||
1579 | { 0x00009840, 0x206a01ae }, | ||
1580 | { 0x0000984c, 0x1284233c }, | ||
1581 | { 0x00009854, 0x00000859 }, | ||
1582 | { 0x00009900, 0x00000000 }, | ||
1583 | { 0x00009904, 0x00000000 }, | ||
1584 | { 0x00009908, 0x00000000 }, | ||
1585 | { 0x0000990c, 0x00000000 }, | ||
1586 | { 0x0000991c, 0x10000fff }, | ||
1587 | { 0x00009920, 0x05100000 }, | ||
1588 | { 0x0000a920, 0x05100000 }, | ||
1589 | { 0x0000b920, 0x05100000 }, | ||
1590 | { 0x00009928, 0x00000001 }, | ||
1591 | { 0x0000992c, 0x00000004 }, | ||
1592 | { 0x00009934, 0x1e1f2022 }, | ||
1593 | { 0x00009938, 0x0a0b0c0d }, | ||
1594 | { 0x0000993c, 0x00000000 }, | ||
1595 | { 0x00009948, 0x9280b212 }, | ||
1596 | { 0x0000994c, 0x00020028 }, | ||
1597 | { 0x00009954, 0x5f3ca3de }, | ||
1598 | { 0x00009958, 0x2108ecff }, | ||
1599 | { 0x00009940, 0x00750604 }, | ||
1600 | { 0x0000c95c, 0x004b6a8e }, | ||
1601 | { 0x00009970, 0x190fb515 }, | ||
1602 | { 0x00009974, 0x00000000 }, | ||
1603 | { 0x00009978, 0x00000001 }, | ||
1604 | { 0x0000997c, 0x00000000 }, | ||
1605 | { 0x00009980, 0x00000000 }, | ||
1606 | { 0x00009984, 0x00000000 }, | ||
1607 | { 0x00009988, 0x00000000 }, | ||
1608 | { 0x0000998c, 0x00000000 }, | ||
1609 | { 0x00009990, 0x00000000 }, | ||
1610 | { 0x00009994, 0x00000000 }, | ||
1611 | { 0x00009998, 0x00000000 }, | ||
1612 | { 0x0000999c, 0x00000000 }, | ||
1613 | { 0x000099a0, 0x00000000 }, | ||
1614 | { 0x000099a4, 0x00000001 }, | ||
1615 | { 0x000099a8, 0x201fff00 }, | ||
1616 | { 0x000099ac, 0x006f0000 }, | ||
1617 | { 0x000099b0, 0x03051000 }, | ||
1618 | { 0x000099dc, 0x00000000 }, | ||
1619 | { 0x000099e0, 0x00000200 }, | ||
1620 | { 0x000099e4, 0xaaaaaaaa }, | ||
1621 | { 0x000099e8, 0x3c466478 }, | ||
1622 | { 0x000099ec, 0x0cc80caa }, | ||
1623 | { 0x000099fc, 0x00001042 }, | ||
1624 | { 0x00009b00, 0x00000000 }, | ||
1625 | { 0x00009b04, 0x00000001 }, | ||
1626 | { 0x00009b08, 0x00000002 }, | ||
1627 | { 0x00009b0c, 0x00000003 }, | ||
1628 | { 0x00009b10, 0x00000004 }, | ||
1629 | { 0x00009b14, 0x00000005 }, | ||
1630 | { 0x00009b18, 0x00000008 }, | ||
1631 | { 0x00009b1c, 0x00000009 }, | ||
1632 | { 0x00009b20, 0x0000000a }, | ||
1633 | { 0x00009b24, 0x0000000b }, | ||
1634 | { 0x00009b28, 0x0000000c }, | ||
1635 | { 0x00009b2c, 0x0000000d }, | ||
1636 | { 0x00009b30, 0x00000010 }, | ||
1637 | { 0x00009b34, 0x00000011 }, | ||
1638 | { 0x00009b38, 0x00000012 }, | ||
1639 | { 0x00009b3c, 0x00000013 }, | ||
1640 | { 0x00009b40, 0x00000014 }, | ||
1641 | { 0x00009b44, 0x00000015 }, | ||
1642 | { 0x00009b48, 0x00000018 }, | ||
1643 | { 0x00009b4c, 0x00000019 }, | ||
1644 | { 0x00009b50, 0x0000001a }, | ||
1645 | { 0x00009b54, 0x0000001b }, | ||
1646 | { 0x00009b58, 0x0000001c }, | ||
1647 | { 0x00009b5c, 0x0000001d }, | ||
1648 | { 0x00009b60, 0x00000020 }, | ||
1649 | { 0x00009b64, 0x00000021 }, | ||
1650 | { 0x00009b68, 0x00000022 }, | ||
1651 | { 0x00009b6c, 0x00000023 }, | ||
1652 | { 0x00009b70, 0x00000024 }, | ||
1653 | { 0x00009b74, 0x00000025 }, | ||
1654 | { 0x00009b78, 0x00000028 }, | ||
1655 | { 0x00009b7c, 0x00000029 }, | ||
1656 | { 0x00009b80, 0x0000002a }, | ||
1657 | { 0x00009b84, 0x0000002b }, | ||
1658 | { 0x00009b88, 0x0000002c }, | ||
1659 | { 0x00009b8c, 0x0000002d }, | ||
1660 | { 0x00009b90, 0x00000030 }, | ||
1661 | { 0x00009b94, 0x00000031 }, | ||
1662 | { 0x00009b98, 0x00000032 }, | ||
1663 | { 0x00009b9c, 0x00000033 }, | ||
1664 | { 0x00009ba0, 0x00000034 }, | ||
1665 | { 0x00009ba4, 0x00000035 }, | ||
1666 | { 0x00009ba8, 0x00000035 }, | ||
1667 | { 0x00009bac, 0x00000035 }, | ||
1668 | { 0x00009bb0, 0x00000035 }, | ||
1669 | { 0x00009bb4, 0x00000035 }, | ||
1670 | { 0x00009bb8, 0x00000035 }, | ||
1671 | { 0x00009bbc, 0x00000035 }, | ||
1672 | { 0x00009bc0, 0x00000035 }, | ||
1673 | { 0x00009bc4, 0x00000035 }, | ||
1674 | { 0x00009bc8, 0x00000035 }, | ||
1675 | { 0x00009bcc, 0x00000035 }, | ||
1676 | { 0x00009bd0, 0x00000035 }, | ||
1677 | { 0x00009bd4, 0x00000035 }, | ||
1678 | { 0x00009bd8, 0x00000035 }, | ||
1679 | { 0x00009bdc, 0x00000035 }, | ||
1680 | { 0x00009be0, 0x00000035 }, | ||
1681 | { 0x00009be4, 0x00000035 }, | ||
1682 | { 0x00009be8, 0x00000035 }, | ||
1683 | { 0x00009bec, 0x00000035 }, | ||
1684 | { 0x00009bf0, 0x00000035 }, | ||
1685 | { 0x00009bf4, 0x00000035 }, | ||
1686 | { 0x00009bf8, 0x00000010 }, | ||
1687 | { 0x00009bfc, 0x0000001a }, | ||
1688 | { 0x0000a210, 0x40806333 }, | ||
1689 | { 0x0000a214, 0x00106c10 }, | ||
1690 | { 0x0000a218, 0x009c4060 }, | ||
1691 | { 0x0000a220, 0x018830c6 }, | ||
1692 | { 0x0000a224, 0x00000400 }, | ||
1693 | { 0x0000a228, 0x001a0bb5 }, | ||
1694 | { 0x0000a22c, 0x00000000 }, | ||
1695 | { 0x0000a234, 0x20202020 }, | ||
1696 | { 0x0000a238, 0x20202020 }, | ||
1697 | { 0x0000a23c, 0x13c889af }, | ||
1698 | { 0x0000a240, 0x38490a20 }, | ||
1699 | { 0x0000a244, 0x00007bb6 }, | ||
1700 | { 0x0000a248, 0x0fff3ffc }, | ||
1701 | { 0x0000a24c, 0x00000001 }, | ||
1702 | { 0x0000a250, 0x0000e000 }, | ||
1703 | { 0x0000a254, 0x00000000 }, | ||
1704 | { 0x0000a258, 0x0cc75380 }, | ||
1705 | { 0x0000a25c, 0x0f0f0f01 }, | ||
1706 | { 0x0000a260, 0xdfa91f01 }, | ||
1707 | { 0x0000a268, 0x00000001 }, | ||
1708 | { 0x0000a26c, 0x0ebae9c6 }, | ||
1709 | { 0x0000b26c, 0x0ebae9c6 }, | ||
1710 | { 0x0000c26c, 0x0ebae9c6 }, | ||
1711 | { 0x0000d270, 0x00820820 }, | ||
1712 | { 0x0000a278, 0x1ce739ce }, | ||
1713 | { 0x0000a27c, 0x050701ce }, | ||
1714 | { 0x0000a338, 0x00000000 }, | ||
1715 | { 0x0000a33c, 0x00000000 }, | ||
1716 | { 0x0000a340, 0x00000000 }, | ||
1717 | { 0x0000a344, 0x00000000 }, | ||
1718 | { 0x0000a348, 0x3fffffff }, | ||
1719 | { 0x0000a34c, 0x3fffffff }, | ||
1720 | { 0x0000a350, 0x3fffffff }, | ||
1721 | { 0x0000a354, 0x0003ffff }, | ||
1722 | { 0x0000a358, 0x79bfaa03 }, | ||
1723 | { 0x0000d35c, 0x07ffffef }, | ||
1724 | { 0x0000d360, 0x0fffffe7 }, | ||
1725 | { 0x0000d364, 0x17ffffe5 }, | ||
1726 | { 0x0000d368, 0x1fffffe4 }, | ||
1727 | { 0x0000d36c, 0x37ffffe3 }, | ||
1728 | { 0x0000d370, 0x3fffffe3 }, | ||
1729 | { 0x0000d374, 0x57ffffe3 }, | ||
1730 | { 0x0000d378, 0x5fffffe2 }, | ||
1731 | { 0x0000d37c, 0x7fffffe2 }, | ||
1732 | { 0x0000d380, 0x7f3c7bba }, | ||
1733 | { 0x0000d384, 0xf3307ff0 }, | ||
1734 | { 0x0000a388, 0x0c000000 }, | ||
1735 | { 0x0000a38c, 0x20202020 }, | ||
1736 | { 0x0000a390, 0x20202020 }, | ||
1737 | { 0x0000a394, 0x1ce739ce }, | ||
1738 | { 0x0000a398, 0x000001ce }, | ||
1739 | { 0x0000a39c, 0x00000001 }, | ||
1740 | { 0x0000a3a0, 0x00000000 }, | ||
1741 | { 0x0000a3a4, 0x00000000 }, | ||
1742 | { 0x0000a3a8, 0x00000000 }, | ||
1743 | { 0x0000a3ac, 0x00000000 }, | ||
1744 | { 0x0000a3b0, 0x00000000 }, | ||
1745 | { 0x0000a3b4, 0x00000000 }, | ||
1746 | { 0x0000a3b8, 0x00000000 }, | ||
1747 | { 0x0000a3bc, 0x00000000 }, | ||
1748 | { 0x0000a3c0, 0x00000000 }, | ||
1749 | { 0x0000a3c4, 0x00000000 }, | ||
1750 | { 0x0000a3c8, 0x00000246 }, | ||
1751 | { 0x0000a3cc, 0x20202020 }, | ||
1752 | { 0x0000a3d0, 0x20202020 }, | ||
1753 | { 0x0000a3d4, 0x20202020 }, | ||
1754 | { 0x0000a3dc, 0x1ce739ce }, | ||
1755 | { 0x0000a3e0, 0x000001ce }, | ||
1756 | }; | ||
1757 | |||
1758 | static const u32 ar5416Bank0_9160[][2] = { | ||
1759 | { 0x000098b0, 0x1e5795e5 }, | ||
1760 | { 0x000098e0, 0x02008020 }, | ||
1761 | }; | ||
1762 | |||
1763 | static const u32 ar5416BB_RfGain_9160[][3] = { | ||
1764 | { 0x00009a00, 0x00000000, 0x00000000 }, | ||
1765 | { 0x00009a04, 0x00000040, 0x00000040 }, | ||
1766 | { 0x00009a08, 0x00000080, 0x00000080 }, | ||
1767 | { 0x00009a0c, 0x000001a1, 0x00000141 }, | ||
1768 | { 0x00009a10, 0x000001e1, 0x00000181 }, | ||
1769 | { 0x00009a14, 0x00000021, 0x000001c1 }, | ||
1770 | { 0x00009a18, 0x00000061, 0x00000001 }, | ||
1771 | { 0x00009a1c, 0x00000168, 0x00000041 }, | ||
1772 | { 0x00009a20, 0x000001a8, 0x000001a8 }, | ||
1773 | { 0x00009a24, 0x000001e8, 0x000001e8 }, | ||
1774 | { 0x00009a28, 0x00000028, 0x00000028 }, | ||
1775 | { 0x00009a2c, 0x00000068, 0x00000068 }, | ||
1776 | { 0x00009a30, 0x00000189, 0x000000a8 }, | ||
1777 | { 0x00009a34, 0x000001c9, 0x00000169 }, | ||
1778 | { 0x00009a38, 0x00000009, 0x000001a9 }, | ||
1779 | { 0x00009a3c, 0x00000049, 0x000001e9 }, | ||
1780 | { 0x00009a40, 0x00000089, 0x00000029 }, | ||
1781 | { 0x00009a44, 0x00000170, 0x00000069 }, | ||
1782 | { 0x00009a48, 0x000001b0, 0x00000190 }, | ||
1783 | { 0x00009a4c, 0x000001f0, 0x000001d0 }, | ||
1784 | { 0x00009a50, 0x00000030, 0x00000010 }, | ||
1785 | { 0x00009a54, 0x00000070, 0x00000050 }, | ||
1786 | { 0x00009a58, 0x00000191, 0x00000090 }, | ||
1787 | { 0x00009a5c, 0x000001d1, 0x00000151 }, | ||
1788 | { 0x00009a60, 0x00000011, 0x00000191 }, | ||
1789 | { 0x00009a64, 0x00000051, 0x000001d1 }, | ||
1790 | { 0x00009a68, 0x00000091, 0x00000011 }, | ||
1791 | { 0x00009a6c, 0x000001b8, 0x00000051 }, | ||
1792 | { 0x00009a70, 0x000001f8, 0x00000198 }, | ||
1793 | { 0x00009a74, 0x00000038, 0x000001d8 }, | ||
1794 | { 0x00009a78, 0x00000078, 0x00000018 }, | ||
1795 | { 0x00009a7c, 0x00000199, 0x00000058 }, | ||
1796 | { 0x00009a80, 0x000001d9, 0x00000098 }, | ||
1797 | { 0x00009a84, 0x00000019, 0x00000159 }, | ||
1798 | { 0x00009a88, 0x00000059, 0x00000199 }, | ||
1799 | { 0x00009a8c, 0x00000099, 0x000001d9 }, | ||
1800 | { 0x00009a90, 0x000000d9, 0x00000019 }, | ||
1801 | { 0x00009a94, 0x000000f9, 0x00000059 }, | ||
1802 | { 0x00009a98, 0x000000f9, 0x00000099 }, | ||
1803 | { 0x00009a9c, 0x000000f9, 0x000000d9 }, | ||
1804 | { 0x00009aa0, 0x000000f9, 0x000000f9 }, | ||
1805 | { 0x00009aa4, 0x000000f9, 0x000000f9 }, | ||
1806 | { 0x00009aa8, 0x000000f9, 0x000000f9 }, | ||
1807 | { 0x00009aac, 0x000000f9, 0x000000f9 }, | ||
1808 | { 0x00009ab0, 0x000000f9, 0x000000f9 }, | ||
1809 | { 0x00009ab4, 0x000000f9, 0x000000f9 }, | ||
1810 | { 0x00009ab8, 0x000000f9, 0x000000f9 }, | ||
1811 | { 0x00009abc, 0x000000f9, 0x000000f9 }, | ||
1812 | { 0x00009ac0, 0x000000f9, 0x000000f9 }, | ||
1813 | { 0x00009ac4, 0x000000f9, 0x000000f9 }, | ||
1814 | { 0x00009ac8, 0x000000f9, 0x000000f9 }, | ||
1815 | { 0x00009acc, 0x000000f9, 0x000000f9 }, | ||
1816 | { 0x00009ad0, 0x000000f9, 0x000000f9 }, | ||
1817 | { 0x00009ad4, 0x000000f9, 0x000000f9 }, | ||
1818 | { 0x00009ad8, 0x000000f9, 0x000000f9 }, | ||
1819 | { 0x00009adc, 0x000000f9, 0x000000f9 }, | ||
1820 | { 0x00009ae0, 0x000000f9, 0x000000f9 }, | ||
1821 | { 0x00009ae4, 0x000000f9, 0x000000f9 }, | ||
1822 | { 0x00009ae8, 0x000000f9, 0x000000f9 }, | ||
1823 | { 0x00009aec, 0x000000f9, 0x000000f9 }, | ||
1824 | { 0x00009af0, 0x000000f9, 0x000000f9 }, | ||
1825 | { 0x00009af4, 0x000000f9, 0x000000f9 }, | ||
1826 | { 0x00009af8, 0x000000f9, 0x000000f9 }, | ||
1827 | { 0x00009afc, 0x000000f9, 0x000000f9 }, | ||
1828 | }; | ||
1829 | |||
1830 | static const u32 ar5416Bank1_9160[][2] = { | ||
1831 | { 0x000098b0, 0x02108421 }, | ||
1832 | { 0x000098ec, 0x00000008 }, | ||
1833 | }; | ||
1834 | |||
1835 | static const u32 ar5416Bank2_9160[][2] = { | ||
1836 | { 0x000098b0, 0x0e73ff17 }, | ||
1837 | { 0x000098e0, 0x00000420 }, | ||
1838 | }; | ||
1839 | |||
1840 | static const u32 ar5416Bank3_9160[][3] = { | ||
1841 | { 0x000098f0, 0x01400018, 0x01c00018 }, | ||
1842 | }; | ||
1843 | |||
1844 | static const u32 ar5416Bank6_9160[][3] = { | ||
1845 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1846 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1847 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1848 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1849 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1850 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1851 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1852 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1853 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1854 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1855 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1856 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1857 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1858 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1859 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1860 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1861 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1862 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1863 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1864 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1865 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1866 | { 0x0000989c, 0x004210a2, 0x004210a2 }, | ||
1867 | { 0x0000989c, 0x0014008f, 0x0014008f }, | ||
1868 | { 0x0000989c, 0x00c40003, 0x00c40003 }, | ||
1869 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1870 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1871 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1872 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1873 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1874 | { 0x0000989c, 0x000000f1, 0x000000f1 }, | ||
1875 | { 0x0000989c, 0x00002081, 0x00002081 }, | ||
1876 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1877 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1878 | }; | ||
1879 | |||
1880 | static const u32 ar5416Bank6TPC_9160[][3] = { | ||
1881 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1882 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1883 | { 0x0000989c, 0x00000000, 0x00000000 }, | ||
1884 | { 0x0000989c, 0x00e00000, 0x00e00000 }, | ||
1885 | { 0x0000989c, 0x005e0000, 0x005e0000 }, | ||
1886 | { 0x0000989c, 0x00120000, 0x00120000 }, | ||
1887 | { 0x0000989c, 0x00620000, 0x00620000 }, | ||
1888 | { 0x0000989c, 0x00020000, 0x00020000 }, | ||
1889 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1890 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1891 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1892 | { 0x0000989c, 0x40ff0000, 0x40ff0000 }, | ||
1893 | { 0x0000989c, 0x005f0000, 0x005f0000 }, | ||
1894 | { 0x0000989c, 0x00870000, 0x00870000 }, | ||
1895 | { 0x0000989c, 0x00f90000, 0x00f90000 }, | ||
1896 | { 0x0000989c, 0x007b0000, 0x007b0000 }, | ||
1897 | { 0x0000989c, 0x00ff0000, 0x00ff0000 }, | ||
1898 | { 0x0000989c, 0x00f50000, 0x00f50000 }, | ||
1899 | { 0x0000989c, 0x00dc0000, 0x00dc0000 }, | ||
1900 | { 0x0000989c, 0x00110000, 0x00110000 }, | ||
1901 | { 0x0000989c, 0x006100a8, 0x006100a8 }, | ||
1902 | { 0x0000989c, 0x00423022, 0x00423022 }, | ||
1903 | { 0x0000989c, 0x2014008f, 0x2014008f }, | ||
1904 | { 0x0000989c, 0x00c40002, 0x00c40002 }, | ||
1905 | { 0x0000989c, 0x003000f2, 0x003000f2 }, | ||
1906 | { 0x0000989c, 0x00440016, 0x00440016 }, | ||
1907 | { 0x0000989c, 0x00410040, 0x00410040 }, | ||
1908 | { 0x0000989c, 0x0001805e, 0x0001805e }, | ||
1909 | { 0x0000989c, 0x0000c0ab, 0x0000c0ab }, | ||
1910 | { 0x0000989c, 0x000000e1, 0x000000e1 }, | ||
1911 | { 0x0000989c, 0x00007080, 0x00007080 }, | ||
1912 | { 0x0000989c, 0x000000d4, 0x000000d4 }, | ||
1913 | { 0x000098d0, 0x0000000f, 0x0010000f }, | ||
1914 | }; | ||
1915 | |||
1916 | static const u32 ar5416Bank7_9160[][2] = { | ||
1917 | { 0x0000989c, 0x00000500 }, | ||
1918 | { 0x0000989c, 0x00000800 }, | ||
1919 | { 0x000098cc, 0x0000000e }, | ||
1920 | }; | ||
1921 | 19 | ||
1922 | static u32 ar5416Addac_9160[][2] = { | ||
1923 | {0x0000989c, 0x00000000 }, | ||
1924 | {0x0000989c, 0x00000000 }, | ||
1925 | {0x0000989c, 0x00000000 }, | ||
1926 | {0x0000989c, 0x00000000 }, | ||
1927 | {0x0000989c, 0x00000000 }, | ||
1928 | {0x0000989c, 0x00000000 }, | ||
1929 | {0x0000989c, 0x000000c0 }, | ||
1930 | {0x0000989c, 0x00000018 }, | ||
1931 | {0x0000989c, 0x00000004 }, | ||
1932 | {0x0000989c, 0x00000000 }, | ||
1933 | {0x0000989c, 0x00000000 }, | ||
1934 | {0x0000989c, 0x00000000 }, | ||
1935 | {0x0000989c, 0x00000000 }, | ||
1936 | {0x0000989c, 0x00000000 }, | ||
1937 | {0x0000989c, 0x00000000 }, | ||
1938 | {0x0000989c, 0x00000000 }, | ||
1939 | {0x0000989c, 0x00000000 }, | ||
1940 | {0x0000989c, 0x00000000 }, | ||
1941 | {0x0000989c, 0x00000000 }, | ||
1942 | {0x0000989c, 0x00000000 }, | ||
1943 | {0x0000989c, 0x00000000 }, | ||
1944 | {0x0000989c, 0x000000c0 }, | ||
1945 | {0x0000989c, 0x00000019 }, | ||
1946 | {0x0000989c, 0x00000004 }, | ||
1947 | {0x0000989c, 0x00000000 }, | ||
1948 | {0x0000989c, 0x00000000 }, | ||
1949 | {0x0000989c, 0x00000000 }, | ||
1950 | {0x0000989c, 0x00000004 }, | ||
1951 | {0x0000989c, 0x00000003 }, | ||
1952 | {0x0000989c, 0x00000008 }, | ||
1953 | {0x0000989c, 0x00000000 }, | ||
1954 | {0x000098cc, 0x00000000 }, | ||
1955 | }; | ||
1956 | |||
1957 | static u32 ar5416Addac_91601_1[][2] = { | ||
1958 | {0x0000989c, 0x00000000 }, | ||
1959 | {0x0000989c, 0x00000000 }, | ||
1960 | {0x0000989c, 0x00000000 }, | ||
1961 | {0x0000989c, 0x00000000 }, | ||
1962 | {0x0000989c, 0x00000000 }, | ||
1963 | {0x0000989c, 0x00000000 }, | ||
1964 | {0x0000989c, 0x000000c0 }, | ||
1965 | {0x0000989c, 0x00000018 }, | ||
1966 | {0x0000989c, 0x00000004 }, | ||
1967 | {0x0000989c, 0x00000000 }, | ||
1968 | {0x0000989c, 0x00000000 }, | ||
1969 | {0x0000989c, 0x00000000 }, | ||
1970 | {0x0000989c, 0x00000000 }, | ||
1971 | {0x0000989c, 0x00000000 }, | ||
1972 | {0x0000989c, 0x00000000 }, | ||
1973 | {0x0000989c, 0x00000000 }, | ||
1974 | {0x0000989c, 0x00000000 }, | ||
1975 | {0x0000989c, 0x00000000 }, | ||
1976 | {0x0000989c, 0x00000000 }, | ||
1977 | {0x0000989c, 0x00000000 }, | ||
1978 | {0x0000989c, 0x00000000 }, | ||
1979 | {0x0000989c, 0x000000c0 }, | ||
1980 | {0x0000989c, 0x00000019 }, | ||
1981 | {0x0000989c, 0x00000004 }, | ||
1982 | {0x0000989c, 0x00000000 }, | ||
1983 | {0x0000989c, 0x00000000 }, | ||
1984 | {0x0000989c, 0x00000000 }, | ||
1985 | {0x0000989c, 0x00000000 }, | ||
1986 | {0x0000989c, 0x00000000 }, | ||
1987 | {0x0000989c, 0x00000000 }, | ||
1988 | {0x0000989c, 0x00000000 }, | ||
1989 | {0x000098cc, 0x00000000 }, | ||
1990 | }; | ||
1991 | |||
1992 | /* XXX 9280 1 */ | ||
1993 | static const u32 ar9280Modes_9280[][6] = { | 20 | static const u32 ar9280Modes_9280[][6] = { |
1994 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 21 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, |
1995 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | 22 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, |
@@ -2766,7 +793,7 @@ static const u32 ar9280Common_9280_2[][2] = { | |||
2766 | { 0x00008258, 0x00000000 }, | 793 | { 0x00008258, 0x00000000 }, |
2767 | { 0x0000825c, 0x400000ff }, | 794 | { 0x0000825c, 0x400000ff }, |
2768 | { 0x00008260, 0x00080922 }, | 795 | { 0x00008260, 0x00080922 }, |
2769 | { 0x00008264, 0xa8a00010 }, | 796 | { 0x00008264, 0x88a00010 }, |
2770 | { 0x00008270, 0x00000000 }, | 797 | { 0x00008270, 0x00000000 }, |
2771 | { 0x00008274, 0x40000000 }, | 798 | { 0x00008274, 0x40000000 }, |
2772 | { 0x00008278, 0x003e4180 }, | 799 | { 0x00008278, 0x003e4180 }, |
@@ -3441,7 +1468,7 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = { | |||
3441 | }; | 1468 | }; |
3442 | 1469 | ||
3443 | /* AR9285 Revsion 10*/ | 1470 | /* AR9285 Revsion 10*/ |
3444 | static const u_int32_t ar9285Modes_9285[][6] = { | 1471 | static const u32 ar9285Modes_9285[][6] = { |
3445 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 1472 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, |
3446 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | 1473 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, |
3447 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | 1474 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, |
@@ -3763,7 +1790,7 @@ static const u_int32_t ar9285Modes_9285[][6] = { | |||
3763 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, | 1790 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, |
3764 | }; | 1791 | }; |
3765 | 1792 | ||
3766 | static const u_int32_t ar9285Common_9285[][2] = { | 1793 | static const u32 ar9285Common_9285[][2] = { |
3767 | { 0x0000000c, 0x00000000 }, | 1794 | { 0x0000000c, 0x00000000 }, |
3768 | { 0x00000030, 0x00020045 }, | 1795 | { 0x00000030, 0x00020045 }, |
3769 | { 0x00000034, 0x00000005 }, | 1796 | { 0x00000034, 0x00000005 }, |
@@ -3936,7 +1963,7 @@ static const u_int32_t ar9285Common_9285[][2] = { | |||
3936 | { 0x00008258, 0x00000000 }, | 1963 | { 0x00008258, 0x00000000 }, |
3937 | { 0x0000825c, 0x400000ff }, | 1964 | { 0x0000825c, 0x400000ff }, |
3938 | { 0x00008260, 0x00080922 }, | 1965 | { 0x00008260, 0x00080922 }, |
3939 | { 0x00008264, 0xa8a00010 }, | 1966 | { 0x00008264, 0x88a00010 }, |
3940 | { 0x00008270, 0x00000000 }, | 1967 | { 0x00008270, 0x00000000 }, |
3941 | { 0x00008274, 0x40000000 }, | 1968 | { 0x00008274, 0x40000000 }, |
3942 | { 0x00008278, 0x003e4180 }, | 1969 | { 0x00008278, 0x003e4180 }, |
@@ -4096,7 +2123,7 @@ static const u_int32_t ar9285Common_9285[][2] = { | |||
4096 | { 0x00007870, 0x10142c00 }, | 2123 | { 0x00007870, 0x10142c00 }, |
4097 | }; | 2124 | }; |
4098 | 2125 | ||
4099 | static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { | 2126 | static const u32 ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { |
4100 | {0x00004040, 0x9248fd00 }, | 2127 | {0x00004040, 0x9248fd00 }, |
4101 | {0x00004040, 0x24924924 }, | 2128 | {0x00004040, 0x24924924 }, |
4102 | {0x00004040, 0xa8000019 }, | 2129 | {0x00004040, 0xa8000019 }, |
@@ -4109,7 +2136,7 @@ static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285[][2] = { | |||
4109 | {0x00004044, 0x00000000 }, | 2136 | {0x00004044, 0x00000000 }, |
4110 | }; | 2137 | }; |
4111 | 2138 | ||
4112 | static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = { | 2139 | static const u32 ar9285PciePhy_clkreq_off_L1_9285[][2] = { |
4113 | {0x00004040, 0x9248fd00 }, | 2140 | {0x00004040, 0x9248fd00 }, |
4114 | {0x00004040, 0x24924924 }, | 2141 | {0x00004040, 0x24924924 }, |
4115 | {0x00004040, 0xa8000019 }, | 2142 | {0x00004040, 0xa8000019 }, |
@@ -4123,7 +2150,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = { | |||
4123 | }; | 2150 | }; |
4124 | 2151 | ||
4125 | /* AR9285 v1_2 PCI Register Writes. Created: 04/13/09 */ | 2152 | /* AR9285 v1_2 PCI Register Writes. Created: 04/13/09 */ |
4126 | static const u_int32_t ar9285Modes_9285_1_2[][6] = { | 2153 | static const u32 ar9285Modes_9285_1_2[][6] = { |
4127 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 2154 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
4128 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 2155 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, |
4129 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | 2156 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, |
@@ -4184,7 +2211,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = { | |||
4184 | { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, | 2211 | { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, |
4185 | { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, | 2212 | { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, |
4186 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, | 2213 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, |
4187 | { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, | 2214 | { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, |
4188 | { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, | 2215 | { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, |
4189 | { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, | 2216 | { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, |
4190 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, | 2217 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, |
@@ -4198,8 +2225,8 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = { | |||
4198 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | 2225 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, |
4199 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | 2226 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, |
4200 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | 2227 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, |
4201 | { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, | 2228 | { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, |
4202 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 2229 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, |
4203 | { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 2230 | { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
4204 | { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, | 2231 | { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, |
4205 | { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, | 2232 | { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, |
@@ -4312,7 +2339,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = { | |||
4312 | { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, | 2339 | { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, |
4313 | { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, | 2340 | { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, |
4314 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, | 2341 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, |
4315 | { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, | 2342 | { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, |
4316 | { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, | 2343 | { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, |
4317 | { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, | 2344 | { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, |
4318 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, | 2345 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, |
@@ -4326,8 +2353,8 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = { | |||
4326 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | 2353 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, |
4327 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | 2354 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, |
4328 | { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | 2355 | { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, |
4329 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, | 2356 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, |
4330 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 2357 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, |
4331 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 2358 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
4332 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, | 2359 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, |
4333 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, | 2360 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, |
@@ -4429,7 +2456,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = { | |||
4429 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, | 2456 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, |
4430 | }; | 2457 | }; |
4431 | 2458 | ||
4432 | static const u_int32_t ar9285Common_9285_1_2[][2] = { | 2459 | static const u32 ar9285Common_9285_1_2[][2] = { |
4433 | { 0x0000000c, 0x00000000 }, | 2460 | { 0x0000000c, 0x00000000 }, |
4434 | { 0x00000030, 0x00020045 }, | 2461 | { 0x00000030, 0x00020045 }, |
4435 | { 0x00000034, 0x00000005 }, | 2462 | { 0x00000034, 0x00000005 }, |
@@ -4731,17 +2758,12 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = { | |||
4731 | { 0x00007808, 0x54214514 }, | 2758 | { 0x00007808, 0x54214514 }, |
4732 | { 0x0000780c, 0x02025830 }, | 2759 | { 0x0000780c, 0x02025830 }, |
4733 | { 0x00007810, 0x71c0d388 }, | 2760 | { 0x00007810, 0x71c0d388 }, |
4734 | { 0x00007814, 0x924934a8 }, | ||
4735 | { 0x0000781c, 0x00000000 }, | 2761 | { 0x0000781c, 0x00000000 }, |
4736 | { 0x00007824, 0x00d86fff }, | 2762 | { 0x00007824, 0x00d86fff }, |
4737 | { 0x00007828, 0x26d2491b }, | ||
4738 | { 0x0000782c, 0x6e36d97b }, | 2763 | { 0x0000782c, 0x6e36d97b }, |
4739 | { 0x00007830, 0xedb6d96e }, | ||
4740 | { 0x00007834, 0x71400087 }, | 2764 | { 0x00007834, 0x71400087 }, |
4741 | { 0x0000783c, 0x0001fffe }, | ||
4742 | { 0x00007840, 0xffeb1a20 }, | ||
4743 | { 0x00007844, 0x000c0db6 }, | 2765 | { 0x00007844, 0x000c0db6 }, |
4744 | { 0x00007848, 0x6db61b6f }, | 2766 | { 0x00007848, 0x6db6246f }, |
4745 | { 0x0000784c, 0x6d9b66db }, | 2767 | { 0x0000784c, 0x6d9b66db }, |
4746 | { 0x00007850, 0x6d8c6dba }, | 2768 | { 0x00007850, 0x6d8c6dba }, |
4747 | { 0x00007854, 0x00040000 }, | 2769 | { 0x00007854, 0x00040000 }, |
@@ -4753,7 +2775,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = { | |||
4753 | { 0x00007870, 0x10142c00 }, | 2775 | { 0x00007870, 0x10142c00 }, |
4754 | }; | 2776 | }; |
4755 | 2777 | ||
4756 | static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { | 2778 | static const u32 ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { |
4757 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 2779 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
4758 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 2780 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
4759 | { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 }, | 2781 | { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 }, |
@@ -4777,7 +2799,12 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { | |||
4777 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | 2799 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, |
4778 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | 2800 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, |
4779 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | 2801 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, |
2802 | { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 }, | ||
2803 | { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b }, | ||
2804 | { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e }, | ||
4780 | { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 }, | 2805 | { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 }, |
2806 | { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe }, | ||
2807 | { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 }, | ||
4781 | { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, | 2808 | { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, |
4782 | { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, | 2809 | { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, |
4783 | { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 }, | 2810 | { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 }, |
@@ -4789,7 +2816,7 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { | |||
4789 | { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, | 2816 | { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, |
4790 | }; | 2817 | }; |
4791 | 2818 | ||
4792 | static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = { | 2819 | static const u32 ar9285Modes_original_tx_gain_9285_1_2[][6] = { |
4793 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 2820 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
4794 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 2821 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
4795 | { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, | 2822 | { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, |
@@ -4813,7 +2840,52 @@ static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = { | |||
4813 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | 2840 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, |
4814 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | 2841 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, |
4815 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | 2842 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, |
2843 | { 0x00007814, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8, 0x924934a8 }, | ||
2844 | { 0x00007828, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b, 0x26d2491b }, | ||
2845 | { 0x00007830, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e, 0xedb6d96e }, | ||
4816 | { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 }, | 2846 | { 0x00007838, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801, 0xfac68801 }, |
2847 | { 0x0000783c, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe, 0x0001fffe }, | ||
2848 | { 0x00007840, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20, 0xffeb1a20 }, | ||
2849 | { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, | ||
2850 | { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, | ||
2851 | { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, | ||
2852 | { 0x0000a278, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, | ||
2853 | { 0x0000a27c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c, 0x050e039c }, | ||
2854 | { 0x0000a394, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, | ||
2855 | { 0x0000a398, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, | ||
2856 | { 0x0000a3dc, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c, 0x39ce739c }, | ||
2857 | { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, | ||
2858 | }; | ||
2859 | |||
2860 | static const u32 ar9285Modes_XE2_0_normal_power[][6] = { | ||
2861 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2862 | { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, | ||
2863 | { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 }, | ||
2864 | { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 }, | ||
2865 | { 0x0000a310, 0x00000000, 0x00000000, 0x00022618, 0x00022618, 0x00000000 }, | ||
2866 | { 0x0000a314, 0x00000000, 0x00000000, 0x0002a6c9, 0x0002a6c9, 0x00000000 }, | ||
2867 | { 0x0000a318, 0x00000000, 0x00000000, 0x00031710, 0x00031710, 0x00000000 }, | ||
2868 | { 0x0000a31c, 0x00000000, 0x00000000, 0x00035718, 0x00035718, 0x00000000 }, | ||
2869 | { 0x0000a320, 0x00000000, 0x00000000, 0x00038758, 0x00038758, 0x00000000 }, | ||
2870 | { 0x0000a324, 0x00000000, 0x00000000, 0x0003c75a, 0x0003c75a, 0x00000000 }, | ||
2871 | { 0x0000a328, 0x00000000, 0x00000000, 0x0004075c, 0x0004075c, 0x00000000 }, | ||
2872 | { 0x0000a32c, 0x00000000, 0x00000000, 0x0004475e, 0x0004475e, 0x00000000 }, | ||
2873 | { 0x0000a330, 0x00000000, 0x00000000, 0x0004679f, 0x0004679f, 0x00000000 }, | ||
2874 | { 0x0000a334, 0x00000000, 0x00000000, 0x000487df, 0x000487df, 0x00000000 }, | ||
2875 | { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, | ||
2876 | { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, | ||
2877 | { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2878 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2879 | { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2880 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2881 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2882 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2883 | { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 }, | ||
2884 | { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b }, | ||
2885 | { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6dbae }, | ||
2886 | { 0x00007838, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441, 0xdac71441 }, | ||
2887 | { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe }, | ||
2888 | { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c }, | ||
4817 | { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, | 2889 | { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, |
4818 | { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, | 2890 | { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, |
4819 | { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, | 2891 | { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, |
@@ -4825,7 +2897,47 @@ static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = { | |||
4825 | { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, | 2897 | { 0x0000a3e0, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c, 0x0000039c }, |
4826 | }; | 2898 | }; |
4827 | 2899 | ||
4828 | static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { | 2900 | static const u32 ar9285Modes_XE2_0_high_power[][6] = { |
2901 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
2902 | { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 }, | ||
2903 | { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 }, | ||
2904 | { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 }, | ||
2905 | { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 }, | ||
2906 | { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 }, | ||
2907 | { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 }, | ||
2908 | { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 }, | ||
2909 | { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 }, | ||
2910 | { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 }, | ||
2911 | { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 }, | ||
2912 | { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 }, | ||
2913 | { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 }, | ||
2914 | { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 }, | ||
2915 | { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, | ||
2916 | { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, | ||
2917 | { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2918 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2919 | { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2920 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2921 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2922 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
2923 | { 0x00007814, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8, 0x92497ca8 }, | ||
2924 | { 0x00007828, 0x4ad2491b, 0x4ad2491b, 0x2ad2491b, 0x4ad2491b, 0x4ad2491b }, | ||
2925 | { 0x00007830, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e, 0xedb6da6e }, | ||
2926 | { 0x00007838, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443, 0xdac71443 }, | ||
2927 | { 0x0000783c, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe, 0x2481f6fe }, | ||
2928 | { 0x00007840, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c, 0xba5f638c }, | ||
2929 | { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, | ||
2930 | { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, | ||
2931 | { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 }, | ||
2932 | { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, | ||
2933 | { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 }, | ||
2934 | { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, | ||
2935 | { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, | ||
2936 | { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, | ||
2937 | { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 }, | ||
2938 | }; | ||
2939 | |||
2940 | static const u32 ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { | ||
4829 | {0x00004040, 0x9248fd00 }, | 2941 | {0x00004040, 0x9248fd00 }, |
4830 | {0x00004040, 0x24924924 }, | 2942 | {0x00004040, 0x24924924 }, |
4831 | {0x00004040, 0xa8000019 }, | 2943 | {0x00004040, 0xa8000019 }, |
@@ -4838,7 +2950,7 @@ static const u_int32_t ar9285PciePhy_clkreq_always_on_L1_9285_1_2[][2] = { | |||
4838 | {0x00004044, 0x00000000 }, | 2950 | {0x00004044, 0x00000000 }, |
4839 | }; | 2951 | }; |
4840 | 2952 | ||
4841 | static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { | 2953 | static const u32 ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { |
4842 | {0x00004040, 0x9248fd00 }, | 2954 | {0x00004040, 0x9248fd00 }, |
4843 | {0x00004040, 0x24924924 }, | 2955 | {0x00004040, 0x24924924 }, |
4844 | {0x00004040, 0xa8000019 }, | 2956 | {0x00004040, 0xa8000019 }, |
@@ -4852,7 +2964,7 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285_1_2[][2] = { | |||
4852 | }; | 2964 | }; |
4853 | 2965 | ||
4854 | /* AR9287 Revision 10 */ | 2966 | /* AR9287 Revision 10 */ |
4855 | static const u_int32_t ar9287Modes_9287_1_0[][6] = { | 2967 | static const u32 ar9287Modes_9287_1_0[][6] = { |
4856 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 2968 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
4857 | { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, | 2969 | { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, |
4858 | { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, | 2970 | { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, |
@@ -4899,7 +3011,7 @@ static const u_int32_t ar9287Modes_9287_1_0[][6] = { | |||
4899 | { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 3011 | { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
4900 | }; | 3012 | }; |
4901 | 3013 | ||
4902 | static const u_int32_t ar9287Common_9287_1_0[][2] = { | 3014 | static const u32 ar9287Common_9287_1_0[][2] = { |
4903 | { 0x0000000c, 0x00000000 }, | 3015 | { 0x0000000c, 0x00000000 }, |
4904 | { 0x00000030, 0x00020015 }, | 3016 | { 0x00000030, 0x00020015 }, |
4905 | { 0x00000034, 0x00000005 }, | 3017 | { 0x00000034, 0x00000005 }, |
@@ -5073,7 +3185,7 @@ static const u_int32_t ar9287Common_9287_1_0[][2] = { | |||
5073 | { 0x00008258, 0x00000000 }, | 3185 | { 0x00008258, 0x00000000 }, |
5074 | { 0x0000825c, 0x400000ff }, | 3186 | { 0x0000825c, 0x400000ff }, |
5075 | { 0x00008260, 0x00080922 }, | 3187 | { 0x00008260, 0x00080922 }, |
5076 | { 0x00008264, 0xa8a00010 }, | 3188 | { 0x00008264, 0x88a00010 }, |
5077 | { 0x00008270, 0x00000000 }, | 3189 | { 0x00008270, 0x00000000 }, |
5078 | { 0x00008274, 0x40000000 }, | 3190 | { 0x00008274, 0x40000000 }, |
5079 | { 0x00008278, 0x003e4180 }, | 3191 | { 0x00008278, 0x003e4180 }, |
@@ -5270,7 +3382,7 @@ static const u_int32_t ar9287Common_9287_1_0[][2] = { | |||
5270 | { 0x000078b8, 0x2a850160 }, | 3382 | { 0x000078b8, 0x2a850160 }, |
5271 | }; | 3383 | }; |
5272 | 3384 | ||
5273 | static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = { | 3385 | static const u32 ar9287Modes_tx_gain_9287_1_0[][6] = { |
5274 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 3386 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
5275 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 3387 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
5276 | { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, | 3388 | { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, |
@@ -5320,7 +3432,7 @@ static const u_int32_t ar9287Modes_tx_gain_9287_1_0[][6] = { | |||
5320 | }; | 3432 | }; |
5321 | 3433 | ||
5322 | 3434 | ||
5323 | static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = { | 3435 | static const u32 ar9287Modes_rx_gain_9287_1_0[][6] = { |
5324 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 3436 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
5325 | { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, | 3437 | { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, |
5326 | { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, | 3438 | { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, |
@@ -5582,7 +3694,7 @@ static const u_int32_t ar9287Modes_rx_gain_9287_1_0[][6] = { | |||
5582 | { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, | 3694 | { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, |
5583 | }; | 3695 | }; |
5584 | 3696 | ||
5585 | static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = { | 3697 | static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = { |
5586 | {0x00004040, 0x9248fd00 }, | 3698 | {0x00004040, 0x9248fd00 }, |
5587 | {0x00004040, 0x24924924 }, | 3699 | {0x00004040, 0x24924924 }, |
5588 | {0x00004040, 0xa8000019 }, | 3700 | {0x00004040, 0xa8000019 }, |
@@ -5595,7 +3707,7 @@ static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_0[][2] = { | |||
5595 | {0x00004044, 0x00000000 }, | 3707 | {0x00004044, 0x00000000 }, |
5596 | }; | 3708 | }; |
5597 | 3709 | ||
5598 | static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = { | 3710 | static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = { |
5599 | {0x00004040, 0x9248fd00 }, | 3711 | {0x00004040, 0x9248fd00 }, |
5600 | {0x00004040, 0x24924924 }, | 3712 | {0x00004040, 0x24924924 }, |
5601 | {0x00004040, 0xa8000019 }, | 3713 | {0x00004040, 0xa8000019 }, |
@@ -5610,7 +3722,7 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_0[][2] = { | |||
5610 | 3722 | ||
5611 | /* AR9287 Revision 11 */ | 3723 | /* AR9287 Revision 11 */ |
5612 | 3724 | ||
5613 | static const u_int32_t ar9287Modes_9287_1_1[][6] = { | 3725 | static const u32 ar9287Modes_9287_1_1[][6] = { |
5614 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 3726 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
5615 | { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, | 3727 | { 0x00001030, 0x00000000, 0x00000000, 0x000002c0, 0x00000160, 0x000001e0 }, |
5616 | { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, | 3728 | { 0x00001070, 0x00000000, 0x00000000, 0x00000318, 0x0000018c, 0x000001e0 }, |
@@ -5657,7 +3769,7 @@ static const u_int32_t ar9287Modes_9287_1_1[][6] = { | |||
5657 | { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 3769 | { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
5658 | }; | 3770 | }; |
5659 | 3771 | ||
5660 | static const u_int32_t ar9287Common_9287_1_1[][2] = { | 3772 | static const u32 ar9287Common_9287_1_1[][2] = { |
5661 | { 0x0000000c, 0x00000000 }, | 3773 | { 0x0000000c, 0x00000000 }, |
5662 | { 0x00000030, 0x00020015 }, | 3774 | { 0x00000030, 0x00020015 }, |
5663 | { 0x00000034, 0x00000005 }, | 3775 | { 0x00000034, 0x00000005 }, |
@@ -6027,21 +4139,22 @@ static const u_int32_t ar9287Common_9287_1_1[][2] = { | |||
6027 | 4139 | ||
6028 | /* | 4140 | /* |
6029 | * For Japanese regulatory requirements, 2484 MHz requires the following three | 4141 | * For Japanese regulatory requirements, 2484 MHz requires the following three |
6030 | * registers be programmed differently from the channel between 2412 and 2472 MHz. | 4142 | * registers be programmed differently from the channel between 2412 and |
4143 | * 2472 MHz. | ||
6031 | */ | 4144 | */ |
6032 | static const u_int32_t ar9287Common_normal_cck_fir_coeff_92871_1[][2] = { | 4145 | static const u32 ar9287Common_normal_cck_fir_coeff_92871_1[][2] = { |
6033 | { 0x0000a1f4, 0x00fffeff }, | 4146 | { 0x0000a1f4, 0x00fffeff }, |
6034 | { 0x0000a1f8, 0x00f5f9ff }, | 4147 | { 0x0000a1f8, 0x00f5f9ff }, |
6035 | { 0x0000a1fc, 0xb79f6427 }, | 4148 | { 0x0000a1fc, 0xb79f6427 }, |
6036 | }; | 4149 | }; |
6037 | 4150 | ||
6038 | static const u_int32_t ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = { | 4151 | static const u32 ar9287Common_japan_2484_cck_fir_coeff_92871_1[][2] = { |
6039 | { 0x0000a1f4, 0x00000000 }, | 4152 | { 0x0000a1f4, 0x00000000 }, |
6040 | { 0x0000a1f8, 0xefff0301 }, | 4153 | { 0x0000a1f8, 0xefff0301 }, |
6041 | { 0x0000a1fc, 0xca9228ee }, | 4154 | { 0x0000a1fc, 0xca9228ee }, |
6042 | }; | 4155 | }; |
6043 | 4156 | ||
6044 | static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = { | 4157 | static const u32 ar9287Modes_tx_gain_9287_1_1[][6] = { |
6045 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 4158 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
6046 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | 4159 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, |
6047 | { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, | 4160 | { 0x0000a304, 0x00000000, 0x00000000, 0x00004002, 0x00004002, 0x00004002 }, |
@@ -6090,7 +4203,7 @@ static const u_int32_t ar9287Modes_tx_gain_9287_1_1[][6] = { | |||
6090 | { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 }, | 4203 | { 0x0000a274, 0x0a180000, 0x0a180000, 0x0a1aa000, 0x0a1aa000, 0x0a1aa000 }, |
6091 | }; | 4204 | }; |
6092 | 4205 | ||
6093 | static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = { | 4206 | static const u32 ar9287Modes_rx_gain_9287_1_1[][6] = { |
6094 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ | 4207 | /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ |
6095 | { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, | 4208 | { 0x00009a00, 0x00000000, 0x00000000, 0x0000a120, 0x0000a120, 0x0000a120 }, |
6096 | { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, | 4209 | { 0x00009a04, 0x00000000, 0x00000000, 0x0000a124, 0x0000a124, 0x0000a124 }, |
@@ -6352,7 +4465,7 @@ static const u_int32_t ar9287Modes_rx_gain_9287_1_1[][6] = { | |||
6352 | { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, | 4465 | { 0x0000a848, 0x00000000, 0x00000000, 0x00001067, 0x00001067, 0x00001067 }, |
6353 | }; | 4466 | }; |
6354 | 4467 | ||
6355 | static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { | 4468 | static const u32 ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { |
6356 | {0x00004040, 0x9248fd00 }, | 4469 | {0x00004040, 0x9248fd00 }, |
6357 | {0x00004040, 0x24924924 }, | 4470 | {0x00004040, 0x24924924 }, |
6358 | {0x00004040, 0xa8000019 }, | 4471 | {0x00004040, 0xa8000019 }, |
@@ -6365,7 +4478,7 @@ static const u_int32_t ar9287PciePhy_clkreq_always_on_L1_9287_1_1[][2] = { | |||
6365 | {0x00004044, 0x00000000 }, | 4478 | {0x00004044, 0x00000000 }, |
6366 | }; | 4479 | }; |
6367 | 4480 | ||
6368 | static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { | 4481 | static const u32 ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { |
6369 | {0x00004040, 0x9248fd00 }, | 4482 | {0x00004040, 0x9248fd00 }, |
6370 | {0x00004040, 0x24924924 }, | 4483 | {0x00004040, 0x24924924 }, |
6371 | {0x00004040, 0xa8000019 }, | 4484 | {0x00004040, 0xa8000019 }, |
@@ -6380,7 +4493,7 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = { | |||
6380 | 4493 | ||
6381 | 4494 | ||
6382 | /* AR9271 initialization values automaticaly created: 06/04/09 */ | 4495 | /* AR9271 initialization values automaticaly created: 06/04/09 */ |
6383 | static const u_int32_t ar9271Modes_9271[][6] = { | 4496 | static const u32 ar9271Modes_9271[][6] = { |
6384 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, | 4497 | { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, |
6385 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, | 4498 | { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, |
6386 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, | 4499 | { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, |
@@ -6441,7 +4554,7 @@ static const u_int32_t ar9271Modes_9271[][6] = { | |||
6441 | { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, | 4554 | { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, |
6442 | { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, | 4555 | { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, |
6443 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, | 4556 | { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, |
6444 | { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, | 4557 | { 0x00009a50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, |
6445 | { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, | 4558 | { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, |
6446 | { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, | 4559 | { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, |
6447 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, | 4560 | { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, |
@@ -6455,8 +4568,8 @@ static const u_int32_t ar9271Modes_9271[][6] = { | |||
6455 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | 4568 | { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, |
6456 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | 4569 | { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, |
6457 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | 4570 | { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, |
6458 | { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, | 4571 | { 0x00009a88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, |
6459 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 4572 | { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, |
6460 | { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 4573 | { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
6461 | { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, | 4574 | { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, |
6462 | { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, | 4575 | { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, |
@@ -6569,7 +4682,7 @@ static const u_int32_t ar9271Modes_9271[][6] = { | |||
6569 | { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, | 4682 | { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 }, |
6570 | { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, | 4683 | { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 }, |
6571 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, | 4684 | { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 }, |
6572 | { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 }, | 4685 | { 0x0000aa50, 0x00000000, 0x00000000, 0x00058224, 0x00058224, 0x00000000 }, |
6573 | { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, | 4686 | { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 }, |
6574 | { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, | 4687 | { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 }, |
6575 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, | 4688 | { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 }, |
@@ -6583,8 +4696,8 @@ static const u_int32_t ar9271Modes_9271[][6] = { | |||
6583 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, | 4696 | { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 }, |
6584 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, | 4697 | { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 }, |
6585 | { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, | 4698 | { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 }, |
6586 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, | 4699 | { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b00, 0x00078b00, 0x00000000 }, |
6587 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 4700 | { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 }, |
6588 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, | 4701 | { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 }, |
6589 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, | 4702 | { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 }, |
6590 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, | 4703 | { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 }, |
@@ -6683,29 +4796,10 @@ static const u_int32_t ar9271Modes_9271[][6] = { | |||
6683 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, | 4796 | { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, |
6684 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, | 4797 | { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, |
6685 | { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, | 4798 | { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, |
6686 | { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 }, | ||
6687 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
6688 | { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, | ||
6689 | { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 }, | ||
6690 | { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 }, | ||
6691 | { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 }, | ||
6692 | { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 }, | ||
6693 | { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 }, | ||
6694 | { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 }, | ||
6695 | { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 }, | ||
6696 | { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 }, | ||
6697 | { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 }, | ||
6698 | { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 }, | ||
6699 | { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 }, | ||
6700 | { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 }, | ||
6701 | { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, | ||
6702 | { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, | ||
6703 | { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
6704 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
6705 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, | 4799 | { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e }, |
6706 | }; | 4800 | }; |
6707 | 4801 | ||
6708 | static const u_int32_t ar9271Common_9271[][2] = { | 4802 | static const u32 ar9271Common_9271[][2] = { |
6709 | { 0x0000000c, 0x00000000 }, | 4803 | { 0x0000000c, 0x00000000 }, |
6710 | { 0x00000030, 0x00020045 }, | 4804 | { 0x00000030, 0x00020045 }, |
6711 | { 0x00000034, 0x00000005 }, | 4805 | { 0x00000034, 0x00000005 }, |
@@ -6910,13 +5004,10 @@ static const u_int32_t ar9271Common_9271[][2] = { | |||
6910 | { 0x00007810, 0x71c0d388 }, | 5004 | { 0x00007810, 0x71c0d388 }, |
6911 | { 0x00007814, 0x924934a8 }, | 5005 | { 0x00007814, 0x924934a8 }, |
6912 | { 0x0000781c, 0x00000000 }, | 5006 | { 0x0000781c, 0x00000000 }, |
6913 | { 0x00007820, 0x00000c04 }, | ||
6914 | { 0x00007824, 0x00d8abff }, | ||
6915 | { 0x00007828, 0x66964300 }, | 5007 | { 0x00007828, 0x66964300 }, |
6916 | { 0x0000782c, 0x8db6d961 }, | 5008 | { 0x0000782c, 0x8db6d961 }, |
6917 | { 0x00007830, 0x8db6d96c }, | 5009 | { 0x00007830, 0x8db6d96c }, |
6918 | { 0x00007834, 0x6140008b }, | 5010 | { 0x00007834, 0x6140008b }, |
6919 | { 0x00007838, 0x00000029 }, | ||
6920 | { 0x0000783c, 0x72ee0a72 }, | 5011 | { 0x0000783c, 0x72ee0a72 }, |
6921 | { 0x00007840, 0xbbfffffc }, | 5012 | { 0x00007840, 0xbbfffffc }, |
6922 | { 0x00007844, 0x000c0db6 }, | 5013 | { 0x00007844, 0x000c0db6 }, |
@@ -6929,7 +5020,6 @@ static const u_int32_t ar9271Common_9271[][2] = { | |||
6929 | { 0x00007860, 0x21084210 }, | 5020 | { 0x00007860, 0x21084210 }, |
6930 | { 0x00007864, 0xf7d7ffde }, | 5021 | { 0x00007864, 0xf7d7ffde }, |
6931 | { 0x00007868, 0xc2034080 }, | 5022 | { 0x00007868, 0xc2034080 }, |
6932 | { 0x0000786c, 0x48609eb4 }, | ||
6933 | { 0x00007870, 0x10142c00 }, | 5023 | { 0x00007870, 0x10142c00 }, |
6934 | { 0x00009808, 0x00000000 }, | 5024 | { 0x00009808, 0x00000000 }, |
6935 | { 0x0000980c, 0xafe68e30 }, | 5025 | { 0x0000980c, 0xafe68e30 }, |
@@ -6982,9 +5072,6 @@ static const u_int32_t ar9271Common_9271[][2] = { | |||
6982 | { 0x000099e8, 0x3c466478 }, | 5072 | { 0x000099e8, 0x3c466478 }, |
6983 | { 0x000099ec, 0x0cc80caa }, | 5073 | { 0x000099ec, 0x0cc80caa }, |
6984 | { 0x000099f0, 0x00000000 }, | 5074 | { 0x000099f0, 0x00000000 }, |
6985 | { 0x0000a1f4, 0x00000000 }, | ||
6986 | { 0x0000a1f8, 0x71733d01 }, | ||
6987 | { 0x0000a1fc, 0xd0ad5c12 }, | ||
6988 | { 0x0000a208, 0x803e68c8 }, | 5075 | { 0x0000a208, 0x803e68c8 }, |
6989 | { 0x0000a210, 0x4080a333 }, | 5076 | { 0x0000a210, 0x4080a333 }, |
6990 | { 0x0000a214, 0x00206c10 }, | 5077 | { 0x0000a214, 0x00206c10 }, |
@@ -7004,13 +5091,9 @@ static const u_int32_t ar9271Common_9271[][2] = { | |||
7004 | { 0x0000a260, 0xdfa90f01 }, | 5091 | { 0x0000a260, 0xdfa90f01 }, |
7005 | { 0x0000a268, 0x00000000 }, | 5092 | { 0x0000a268, 0x00000000 }, |
7006 | { 0x0000a26c, 0x0ebae9e6 }, | 5093 | { 0x0000a26c, 0x0ebae9e6 }, |
7007 | { 0x0000a278, 0x3bdef7bd }, | ||
7008 | { 0x0000a27c, 0x050e83bd }, | ||
7009 | { 0x0000a388, 0x0c000000 }, | 5094 | { 0x0000a388, 0x0c000000 }, |
7010 | { 0x0000a38c, 0x20202020 }, | 5095 | { 0x0000a38c, 0x20202020 }, |
7011 | { 0x0000a390, 0x20202020 }, | 5096 | { 0x0000a390, 0x20202020 }, |
7012 | { 0x0000a394, 0x3bdef7bd }, | ||
7013 | { 0x0000a398, 0x000003bd }, | ||
7014 | { 0x0000a39c, 0x00000001 }, | 5097 | { 0x0000a39c, 0x00000001 }, |
7015 | { 0x0000a3a0, 0x00000000 }, | 5098 | { 0x0000a3a0, 0x00000000 }, |
7016 | { 0x0000a3a4, 0x00000000 }, | 5099 | { 0x0000a3a4, 0x00000000 }, |
@@ -7025,8 +5108,6 @@ static const u_int32_t ar9271Common_9271[][2] = { | |||
7025 | { 0x0000a3cc, 0x20202020 }, | 5108 | { 0x0000a3cc, 0x20202020 }, |
7026 | { 0x0000a3d0, 0x20202020 }, | 5109 | { 0x0000a3d0, 0x20202020 }, |
7027 | { 0x0000a3d4, 0x20202020 }, | 5110 | { 0x0000a3d4, 0x20202020 }, |
7028 | { 0x0000a3dc, 0x3bdef7bd }, | ||
7029 | { 0x0000a3e0, 0x000003bd }, | ||
7030 | { 0x0000a3e4, 0x00000000 }, | 5111 | { 0x0000a3e4, 0x00000000 }, |
7031 | { 0x0000a3e8, 0x18c43433 }, | 5112 | { 0x0000a3e8, 0x18c43433 }, |
7032 | { 0x0000a3ec, 0x00f70081 }, | 5113 | { 0x0000a3ec, 0x00f70081 }, |
@@ -7046,7 +5127,104 @@ static const u_int32_t ar9271Common_9271[][2] = { | |||
7046 | { 0x0000d384, 0xf3307ff0 }, | 5127 | { 0x0000d384, 0xf3307ff0 }, |
7047 | }; | 5128 | }; |
7048 | 5129 | ||
7049 | static const u_int32_t ar9271Modes_9271_1_0_only[][6] = { | 5130 | static const u32 ar9271Common_normal_cck_fir_coeff_9271[][2] = { |
5131 | { 0x0000a1f4, 0x00fffeff }, | ||
5132 | { 0x0000a1f8, 0x00f5f9ff }, | ||
5133 | { 0x0000a1fc, 0xb79f6427 }, | ||
5134 | }; | ||
5135 | |||
5136 | static const u32 ar9271Common_japan_2484_cck_fir_coeff_9271[][2] = { | ||
5137 | { 0x0000a1f4, 0x00000000 }, | ||
5138 | { 0x0000a1f8, 0xefff0301 }, | ||
5139 | { 0x0000a1fc, 0xca9228ee }, | ||
5140 | }; | ||
5141 | |||
5142 | static const u32 ar9271Modes_9271_1_0_only[][6] = { | ||
7050 | { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 }, | 5143 | { 0x00009910, 0x30002311, 0x30002311, 0x30002311, 0x30002311, 0x30002311 }, |
7051 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, | 5144 | { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 }, |
7052 | }; | 5145 | }; |
5146 | |||
5147 | static const u32 ar9271Modes_9271_ANI_reg[][6] = { | ||
5148 | { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, | ||
5149 | { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e }, | ||
5150 | { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, | ||
5151 | { 0x0000986c, 0x06903881, 0x06903881, 0x06903881, 0x06903881, 0x06903881 }, | ||
5152 | { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 }, | ||
5153 | { 0x0000a208, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8, 0x803e68c8 }, | ||
5154 | { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d }, | ||
5155 | { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 }, | ||
5156 | }; | ||
5157 | |||
5158 | static const u32 ar9271Modes_normal_power_tx_gain_9271[][6] = { | ||
5159 | { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, | ||
5160 | { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 }, | ||
5161 | { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 }, | ||
5162 | { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 }, | ||
5163 | { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 }, | ||
5164 | { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 }, | ||
5165 | { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 }, | ||
5166 | { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 }, | ||
5167 | { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 }, | ||
5168 | { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 }, | ||
5169 | { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 }, | ||
5170 | { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 }, | ||
5171 | { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 }, | ||
5172 | { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 }, | ||
5173 | { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, | ||
5174 | { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, | ||
5175 | { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5176 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5177 | { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5178 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5179 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5180 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5181 | { 0x00007838, 0x00000029, 0x00000029, 0x00000029, 0x00000029, 0x00000029 }, | ||
5182 | { 0x00007824, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff, 0x00d8abff }, | ||
5183 | { 0x0000786c, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4, 0x48609eb4 }, | ||
5184 | { 0x00007820, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04, 0x00000c04 }, | ||
5185 | { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 }, | ||
5186 | { 0x0000a278, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd }, | ||
5187 | { 0x0000a27c, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd, 0x050e83bd }, | ||
5188 | { 0x0000a394, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd }, | ||
5189 | { 0x0000a398, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd }, | ||
5190 | { 0x0000a3dc, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd, 0x3bdef7bd }, | ||
5191 | { 0x0000a3e0, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd, 0x000003bd }, | ||
5192 | }; | ||
5193 | |||
5194 | static const u32 ar9271Modes_high_power_tx_gain_9271[][6] = { | ||
5195 | { 0x0000a300, 0x00000000, 0x00000000, 0x00010000, 0x00010000, 0x00000000 }, | ||
5196 | { 0x0000a304, 0x00000000, 0x00000000, 0x00016200, 0x00016200, 0x00000000 }, | ||
5197 | { 0x0000a308, 0x00000000, 0x00000000, 0x00018201, 0x00018201, 0x00000000 }, | ||
5198 | { 0x0000a30c, 0x00000000, 0x00000000, 0x0001b240, 0x0001b240, 0x00000000 }, | ||
5199 | { 0x0000a310, 0x00000000, 0x00000000, 0x0001d241, 0x0001d241, 0x00000000 }, | ||
5200 | { 0x0000a314, 0x00000000, 0x00000000, 0x0001f600, 0x0001f600, 0x00000000 }, | ||
5201 | { 0x0000a318, 0x00000000, 0x00000000, 0x00022800, 0x00022800, 0x00000000 }, | ||
5202 | { 0x0000a31c, 0x00000000, 0x00000000, 0x00026802, 0x00026802, 0x00000000 }, | ||
5203 | { 0x0000a320, 0x00000000, 0x00000000, 0x0002b805, 0x0002b805, 0x00000000 }, | ||
5204 | { 0x0000a324, 0x00000000, 0x00000000, 0x0002ea41, 0x0002ea41, 0x00000000 }, | ||
5205 | { 0x0000a328, 0x00000000, 0x00000000, 0x00038b00, 0x00038b00, 0x00000000 }, | ||
5206 | { 0x0000a32c, 0x00000000, 0x00000000, 0x0003ab40, 0x0003ab40, 0x00000000 }, | ||
5207 | { 0x0000a330, 0x00000000, 0x00000000, 0x0003cd80, 0x0003cd80, 0x00000000 }, | ||
5208 | { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 }, | ||
5209 | { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, | ||
5210 | { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, | ||
5211 | { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5212 | { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5213 | { 0x0000a348, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5214 | { 0x0000a34c, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5215 | { 0x0000a350, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5216 | { 0x0000a354, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 }, | ||
5217 | { 0x00007838, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b, 0x0000002b }, | ||
5218 | { 0x00007824, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff, 0x00d8a7ff }, | ||
5219 | { 0x0000786c, 0x08609eb6, 0x08609eb6, 0x08609eba, 0x08609eba, 0x08609eb6 }, | ||
5220 | { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, | ||
5221 | { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a212652, 0x0a212652, 0x0a22a652 }, | ||
5222 | { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 }, | ||
5223 | { 0x0000a27c, 0x05018063, 0x05038063, 0x05018063, 0x05018063, 0x05018063 }, | ||
5224 | { 0x0000a394, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 }, | ||
5225 | { 0x0000a398, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 }, | ||
5226 | { 0x0000a3dc, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63, 0x06318c63 }, | ||
5227 | { 0x0000a3e0, 0x00000063, 0x00000063, 0x00000063, 0x00000063, 0x00000063 }, | ||
5228 | }; | ||
5229 | |||
5230 | #endif /* INITVALS_9002_10_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c new file mode 100644 index 000000000000..2be20d2070c4 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | |||
19 | #define AR_BufLen 0x00000fff | ||
20 | |||
21 | static void ar9002_hw_rx_enable(struct ath_hw *ah) | ||
22 | { | ||
23 | REG_WRITE(ah, AR_CR, AR_CR_RXE); | ||
24 | } | ||
25 | |||
26 | static void ar9002_hw_set_desc_link(void *ds, u32 ds_link) | ||
27 | { | ||
28 | ((struct ath_desc*) ds)->ds_link = ds_link; | ||
29 | } | ||
30 | |||
31 | static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link) | ||
32 | { | ||
33 | *ds_link = &((struct ath_desc *)ds)->ds_link; | ||
34 | } | ||
35 | |||
36 | static bool ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | ||
37 | { | ||
38 | u32 isr = 0; | ||
39 | u32 mask2 = 0; | ||
40 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
41 | u32 sync_cause = 0; | ||
42 | bool fatal_int = false; | ||
43 | struct ath_common *common = ath9k_hw_common(ah); | ||
44 | |||
45 | if (!AR_SREV_9100(ah)) { | ||
46 | if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) { | ||
47 | if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) | ||
48 | == AR_RTC_STATUS_ON) { | ||
49 | isr = REG_READ(ah, AR_ISR); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & | ||
54 | AR_INTR_SYNC_DEFAULT; | ||
55 | |||
56 | *masked = 0; | ||
57 | |||
58 | if (!isr && !sync_cause) | ||
59 | return false; | ||
60 | } else { | ||
61 | *masked = 0; | ||
62 | isr = REG_READ(ah, AR_ISR); | ||
63 | } | ||
64 | |||
65 | if (isr) { | ||
66 | if (isr & AR_ISR_BCNMISC) { | ||
67 | u32 isr2; | ||
68 | isr2 = REG_READ(ah, AR_ISR_S2); | ||
69 | if (isr2 & AR_ISR_S2_TIM) | ||
70 | mask2 |= ATH9K_INT_TIM; | ||
71 | if (isr2 & AR_ISR_S2_DTIM) | ||
72 | mask2 |= ATH9K_INT_DTIM; | ||
73 | if (isr2 & AR_ISR_S2_DTIMSYNC) | ||
74 | mask2 |= ATH9K_INT_DTIMSYNC; | ||
75 | if (isr2 & (AR_ISR_S2_CABEND)) | ||
76 | mask2 |= ATH9K_INT_CABEND; | ||
77 | if (isr2 & AR_ISR_S2_GTT) | ||
78 | mask2 |= ATH9K_INT_GTT; | ||
79 | if (isr2 & AR_ISR_S2_CST) | ||
80 | mask2 |= ATH9K_INT_CST; | ||
81 | if (isr2 & AR_ISR_S2_TSFOOR) | ||
82 | mask2 |= ATH9K_INT_TSFOOR; | ||
83 | } | ||
84 | |||
85 | isr = REG_READ(ah, AR_ISR_RAC); | ||
86 | if (isr == 0xffffffff) { | ||
87 | *masked = 0; | ||
88 | return false; | ||
89 | } | ||
90 | |||
91 | *masked = isr & ATH9K_INT_COMMON; | ||
92 | |||
93 | if (ah->config.rx_intr_mitigation) { | ||
94 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) | ||
95 | *masked |= ATH9K_INT_RX; | ||
96 | } | ||
97 | |||
98 | if (isr & (AR_ISR_RXOK | AR_ISR_RXERR)) | ||
99 | *masked |= ATH9K_INT_RX; | ||
100 | if (isr & | ||
101 | (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | | ||
102 | AR_ISR_TXEOL)) { | ||
103 | u32 s0_s, s1_s; | ||
104 | |||
105 | *masked |= ATH9K_INT_TX; | ||
106 | |||
107 | s0_s = REG_READ(ah, AR_ISR_S0_S); | ||
108 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK); | ||
109 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC); | ||
110 | |||
111 | s1_s = REG_READ(ah, AR_ISR_S1_S); | ||
112 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR); | ||
113 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL); | ||
114 | } | ||
115 | |||
116 | if (isr & AR_ISR_RXORN) { | ||
117 | ath_print(common, ATH_DBG_INTERRUPT, | ||
118 | "receive FIFO overrun interrupt\n"); | ||
119 | } | ||
120 | |||
121 | if (!AR_SREV_9100(ah)) { | ||
122 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
123 | u32 isr5 = REG_READ(ah, AR_ISR_S5_S); | ||
124 | if (isr5 & AR_ISR_S5_TIM_TIMER) | ||
125 | *masked |= ATH9K_INT_TIM_TIMER; | ||
126 | } | ||
127 | } | ||
128 | |||
129 | *masked |= mask2; | ||
130 | } | ||
131 | |||
132 | if (AR_SREV_9100(ah)) | ||
133 | return true; | ||
134 | |||
135 | if (isr & AR_ISR_GENTMR) { | ||
136 | u32 s5_s; | ||
137 | |||
138 | s5_s = REG_READ(ah, AR_ISR_S5_S); | ||
139 | if (isr & AR_ISR_GENTMR) { | ||
140 | ah->intr_gen_timer_trigger = | ||
141 | MS(s5_s, AR_ISR_S5_GENTIMER_TRIG); | ||
142 | |||
143 | ah->intr_gen_timer_thresh = | ||
144 | MS(s5_s, AR_ISR_S5_GENTIMER_THRESH); | ||
145 | |||
146 | if (ah->intr_gen_timer_trigger) | ||
147 | *masked |= ATH9K_INT_GENTIMER; | ||
148 | |||
149 | } | ||
150 | } | ||
151 | |||
152 | if (sync_cause) { | ||
153 | fatal_int = | ||
154 | (sync_cause & | ||
155 | (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) | ||
156 | ? true : false; | ||
157 | |||
158 | if (fatal_int) { | ||
159 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { | ||
160 | ath_print(common, ATH_DBG_ANY, | ||
161 | "received PCI FATAL interrupt\n"); | ||
162 | } | ||
163 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { | ||
164 | ath_print(common, ATH_DBG_ANY, | ||
165 | "received PCI PERR interrupt\n"); | ||
166 | } | ||
167 | *masked |= ATH9K_INT_FATAL; | ||
168 | } | ||
169 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | ||
170 | ath_print(common, ATH_DBG_INTERRUPT, | ||
171 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); | ||
172 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | ||
173 | REG_WRITE(ah, AR_RC, 0); | ||
174 | *masked |= ATH9K_INT_FATAL; | ||
175 | } | ||
176 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { | ||
177 | ath_print(common, ATH_DBG_INTERRUPT, | ||
178 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); | ||
179 | } | ||
180 | |||
181 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); | ||
182 | (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR); | ||
183 | } | ||
184 | |||
185 | return true; | ||
186 | } | ||
187 | |||
188 | static void ar9002_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, | ||
189 | bool is_firstseg, bool is_lastseg, | ||
190 | const void *ds0, dma_addr_t buf_addr, | ||
191 | unsigned int qcu) | ||
192 | { | ||
193 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
194 | |||
195 | ads->ds_data = buf_addr; | ||
196 | |||
197 | if (is_firstseg) { | ||
198 | ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore); | ||
199 | } else if (is_lastseg) { | ||
200 | ads->ds_ctl0 = 0; | ||
201 | ads->ds_ctl1 = seglen; | ||
202 | ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; | ||
203 | ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; | ||
204 | } else { | ||
205 | ads->ds_ctl0 = 0; | ||
206 | ads->ds_ctl1 = seglen | AR_TxMore; | ||
207 | ads->ds_ctl2 = 0; | ||
208 | ads->ds_ctl3 = 0; | ||
209 | } | ||
210 | ads->ds_txstatus0 = ads->ds_txstatus1 = 0; | ||
211 | ads->ds_txstatus2 = ads->ds_txstatus3 = 0; | ||
212 | ads->ds_txstatus4 = ads->ds_txstatus5 = 0; | ||
213 | ads->ds_txstatus6 = ads->ds_txstatus7 = 0; | ||
214 | ads->ds_txstatus8 = ads->ds_txstatus9 = 0; | ||
215 | } | ||
216 | |||
217 | static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds, | ||
218 | struct ath_tx_status *ts) | ||
219 | { | ||
220 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
221 | |||
222 | if ((ads->ds_txstatus9 & AR_TxDone) == 0) | ||
223 | return -EINPROGRESS; | ||
224 | |||
225 | ts->ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum); | ||
226 | ts->ts_tstamp = ads->AR_SendTimestamp; | ||
227 | ts->ts_status = 0; | ||
228 | ts->ts_flags = 0; | ||
229 | |||
230 | if (ads->ds_txstatus1 & AR_FrmXmitOK) | ||
231 | ts->ts_status |= ATH9K_TX_ACKED; | ||
232 | if (ads->ds_txstatus1 & AR_ExcessiveRetries) | ||
233 | ts->ts_status |= ATH9K_TXERR_XRETRY; | ||
234 | if (ads->ds_txstatus1 & AR_Filtered) | ||
235 | ts->ts_status |= ATH9K_TXERR_FILT; | ||
236 | if (ads->ds_txstatus1 & AR_FIFOUnderrun) { | ||
237 | ts->ts_status |= ATH9K_TXERR_FIFO; | ||
238 | ath9k_hw_updatetxtriglevel(ah, true); | ||
239 | } | ||
240 | if (ads->ds_txstatus9 & AR_TxOpExceeded) | ||
241 | ts->ts_status |= ATH9K_TXERR_XTXOP; | ||
242 | if (ads->ds_txstatus1 & AR_TxTimerExpired) | ||
243 | ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; | ||
244 | |||
245 | if (ads->ds_txstatus1 & AR_DescCfgErr) | ||
246 | ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; | ||
247 | if (ads->ds_txstatus1 & AR_TxDataUnderrun) { | ||
248 | ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; | ||
249 | ath9k_hw_updatetxtriglevel(ah, true); | ||
250 | } | ||
251 | if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { | ||
252 | ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; | ||
253 | ath9k_hw_updatetxtriglevel(ah, true); | ||
254 | } | ||
255 | if (ads->ds_txstatus0 & AR_TxBaStatus) { | ||
256 | ts->ts_flags |= ATH9K_TX_BA; | ||
257 | ts->ba_low = ads->AR_BaBitmapLow; | ||
258 | ts->ba_high = ads->AR_BaBitmapHigh; | ||
259 | } | ||
260 | |||
261 | ts->ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); | ||
262 | switch (ts->ts_rateindex) { | ||
263 | case 0: | ||
264 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); | ||
265 | break; | ||
266 | case 1: | ||
267 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1); | ||
268 | break; | ||
269 | case 2: | ||
270 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2); | ||
271 | break; | ||
272 | case 3: | ||
273 | ts->ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3); | ||
274 | break; | ||
275 | } | ||
276 | |||
277 | ts->ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined); | ||
278 | ts->ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00); | ||
279 | ts->ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01); | ||
280 | ts->ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02); | ||
281 | ts->ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10); | ||
282 | ts->ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11); | ||
283 | ts->ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12); | ||
284 | ts->evm0 = ads->AR_TxEVM0; | ||
285 | ts->evm1 = ads->AR_TxEVM1; | ||
286 | ts->evm2 = ads->AR_TxEVM2; | ||
287 | ts->ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); | ||
288 | ts->ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); | ||
289 | ts->ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); | ||
290 | ts->ts_antenna = 0; | ||
291 | |||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | ||
296 | u32 pktLen, enum ath9k_pkt_type type, | ||
297 | u32 txPower, u32 keyIx, | ||
298 | enum ath9k_key_type keyType, u32 flags) | ||
299 | { | ||
300 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
301 | |||
302 | txPower += ah->txpower_indexoffset; | ||
303 | if (txPower > 63) | ||
304 | txPower = 63; | ||
305 | |||
306 | ads->ds_ctl0 = (pktLen & AR_FrameLen) | ||
307 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | ||
308 | | SM(txPower, AR_XmitPower) | ||
309 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | ||
310 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
311 | | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | ||
312 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); | ||
313 | |||
314 | ads->ds_ctl1 = | ||
315 | (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) | ||
316 | | SM(type, AR_FrameType) | ||
317 | | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) | ||
318 | | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) | ||
319 | | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); | ||
320 | |||
321 | ads->ds_ctl6 = SM(keyType, AR_EncrType); | ||
322 | |||
323 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { | ||
324 | ads->ds_ctl8 = 0; | ||
325 | ads->ds_ctl9 = 0; | ||
326 | ads->ds_ctl10 = 0; | ||
327 | ads->ds_ctl11 = 0; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, | ||
332 | void *lastds, | ||
333 | u32 durUpdateEn, u32 rtsctsRate, | ||
334 | u32 rtsctsDuration, | ||
335 | struct ath9k_11n_rate_series series[], | ||
336 | u32 nseries, u32 flags) | ||
337 | { | ||
338 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
339 | struct ar5416_desc *last_ads = AR5416DESC(lastds); | ||
340 | u32 ds_ctl0; | ||
341 | |||
342 | if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { | ||
343 | ds_ctl0 = ads->ds_ctl0; | ||
344 | |||
345 | if (flags & ATH9K_TXDESC_RTSENA) { | ||
346 | ds_ctl0 &= ~AR_CTSEnable; | ||
347 | ds_ctl0 |= AR_RTSEnable; | ||
348 | } else { | ||
349 | ds_ctl0 &= ~AR_RTSEnable; | ||
350 | ds_ctl0 |= AR_CTSEnable; | ||
351 | } | ||
352 | |||
353 | ads->ds_ctl0 = ds_ctl0; | ||
354 | } else { | ||
355 | ads->ds_ctl0 = | ||
356 | (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); | ||
357 | } | ||
358 | |||
359 | ads->ds_ctl2 = set11nTries(series, 0) | ||
360 | | set11nTries(series, 1) | ||
361 | | set11nTries(series, 2) | ||
362 | | set11nTries(series, 3) | ||
363 | | (durUpdateEn ? AR_DurUpdateEna : 0) | ||
364 | | SM(0, AR_BurstDur); | ||
365 | |||
366 | ads->ds_ctl3 = set11nRate(series, 0) | ||
367 | | set11nRate(series, 1) | ||
368 | | set11nRate(series, 2) | ||
369 | | set11nRate(series, 3); | ||
370 | |||
371 | ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) | ||
372 | | set11nPktDurRTSCTS(series, 1); | ||
373 | |||
374 | ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) | ||
375 | | set11nPktDurRTSCTS(series, 3); | ||
376 | |||
377 | ads->ds_ctl7 = set11nRateFlags(series, 0) | ||
378 | | set11nRateFlags(series, 1) | ||
379 | | set11nRateFlags(series, 2) | ||
380 | | set11nRateFlags(series, 3) | ||
381 | | SM(rtsctsRate, AR_RTSCTSRate); | ||
382 | last_ads->ds_ctl2 = ads->ds_ctl2; | ||
383 | last_ads->ds_ctl3 = ads->ds_ctl3; | ||
384 | } | ||
385 | |||
386 | static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, | ||
387 | u32 aggrLen) | ||
388 | { | ||
389 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
390 | |||
391 | ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); | ||
392 | ads->ds_ctl6 &= ~AR_AggrLen; | ||
393 | ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); | ||
394 | } | ||
395 | |||
396 | static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, | ||
397 | u32 numDelims) | ||
398 | { | ||
399 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
400 | unsigned int ctl6; | ||
401 | |||
402 | ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); | ||
403 | |||
404 | ctl6 = ads->ds_ctl6; | ||
405 | ctl6 &= ~AR_PadDelim; | ||
406 | ctl6 |= SM(numDelims, AR_PadDelim); | ||
407 | ads->ds_ctl6 = ctl6; | ||
408 | } | ||
409 | |||
410 | static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) | ||
411 | { | ||
412 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
413 | |||
414 | ads->ds_ctl1 |= AR_IsAggr; | ||
415 | ads->ds_ctl1 &= ~AR_MoreAggr; | ||
416 | ads->ds_ctl6 &= ~AR_PadDelim; | ||
417 | } | ||
418 | |||
419 | static void ar9002_hw_clr11n_aggr(struct ath_hw *ah, void *ds) | ||
420 | { | ||
421 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
422 | |||
423 | ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); | ||
424 | } | ||
425 | |||
426 | static void ar9002_hw_set11n_burstduration(struct ath_hw *ah, void *ds, | ||
427 | u32 burstDuration) | ||
428 | { | ||
429 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
430 | |||
431 | ads->ds_ctl2 &= ~AR_BurstDur; | ||
432 | ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); | ||
433 | } | ||
434 | |||
435 | static void ar9002_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, | ||
436 | u32 vmf) | ||
437 | { | ||
438 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
439 | |||
440 | if (vmf) | ||
441 | ads->ds_ctl0 |= AR_VirtMoreFrag; | ||
442 | else | ||
443 | ads->ds_ctl0 &= ~AR_VirtMoreFrag; | ||
444 | } | ||
445 | |||
446 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
447 | u32 size, u32 flags) | ||
448 | { | ||
449 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
450 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
451 | |||
452 | ads->ds_ctl1 = size & AR_BufLen; | ||
453 | if (flags & ATH9K_RXDESC_INTREQ) | ||
454 | ads->ds_ctl1 |= AR_RxIntrReq; | ||
455 | |||
456 | ads->ds_rxstatus8 &= ~AR_RxDone; | ||
457 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | ||
458 | memset(&(ads->u), 0, sizeof(ads->u)); | ||
459 | } | ||
460 | EXPORT_SYMBOL(ath9k_hw_setuprxdesc); | ||
461 | |||
462 | void ar9002_hw_attach_mac_ops(struct ath_hw *ah) | ||
463 | { | ||
464 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
465 | |||
466 | ops->rx_enable = ar9002_hw_rx_enable; | ||
467 | ops->set_desc_link = ar9002_hw_set_desc_link; | ||
468 | ops->get_desc_link = ar9002_hw_get_desc_link; | ||
469 | ops->get_isr = ar9002_hw_get_isr; | ||
470 | ops->fill_txdesc = ar9002_hw_fill_txdesc; | ||
471 | ops->proc_txdesc = ar9002_hw_proc_txdesc; | ||
472 | ops->set11n_txdesc = ar9002_hw_set11n_txdesc; | ||
473 | ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario; | ||
474 | ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first; | ||
475 | ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle; | ||
476 | ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last; | ||
477 | ops->clr11n_aggr = ar9002_hw_clr11n_aggr; | ||
478 | ops->set11n_burstduration = ar9002_hw_set11n_burstduration; | ||
479 | ops->set11n_virtualmorefrag = ar9002_hw_set11n_virtualmorefrag; | ||
480 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c new file mode 100644 index 000000000000..ed314e89bfe1 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c | |||
@@ -0,0 +1,535 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * DOC: Programming Atheros 802.11n analog front end radios | ||
19 | * | ||
20 | * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express | ||
21 | * devices have either an external AR2133 analog front end radio for single | ||
22 | * band 2.4 GHz communication or an AR5133 analog front end radio for dual | ||
23 | * band 2.4 GHz / 5 GHz communication. | ||
24 | * | ||
25 | * All devices after the AR5416 and AR5418 family starting with the AR9280 | ||
26 | * have their analog front radios, MAC/BB and host PCIe/USB interface embedded | ||
27 | * into a single-chip and require less programming. | ||
28 | * | ||
29 | * The following single-chips exist with a respective embedded radio: | ||
30 | * | ||
31 | * AR9280 - 11n dual-band 2x2 MIMO for PCIe | ||
32 | * AR9281 - 11n single-band 1x2 MIMO for PCIe | ||
33 | * AR9285 - 11n single-band 1x1 for PCIe | ||
34 | * AR9287 - 11n single-band 2x2 MIMO for PCIe | ||
35 | * | ||
36 | * AR9220 - 11n dual-band 2x2 MIMO for PCI | ||
37 | * AR9223 - 11n single-band 2x2 MIMO for PCI | ||
38 | * | ||
39 | * AR9287 - 11n single-band 1x1 MIMO for USB | ||
40 | */ | ||
41 | |||
42 | #include "hw.h" | ||
43 | #include "ar9002_phy.h" | ||
44 | |||
45 | /** | ||
46 | * ar9002_hw_set_channel - set channel on single-chip device | ||
47 | * @ah: atheros hardware structure | ||
48 | * @chan: | ||
49 | * | ||
50 | * This is the function to change channel on single-chip devices, that is | ||
51 | * all devices after ar9280. | ||
52 | * | ||
53 | * This function takes the channel value in MHz and sets | ||
54 | * hardware channel value. Assumes writes have been enabled to analog bus. | ||
55 | * | ||
56 | * Actual Expression, | ||
57 | * | ||
58 | * For 2GHz channel, | ||
59 | * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) | ||
60 | * (freq_ref = 40MHz) | ||
61 | * | ||
62 | * For 5GHz channel, | ||
63 | * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) | ||
64 | * (freq_ref = 40MHz/(24>>amodeRefSel)) | ||
65 | */ | ||
66 | static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
67 | { | ||
68 | u16 bMode, fracMode, aModeRefSel = 0; | ||
69 | u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; | ||
70 | struct chan_centers centers; | ||
71 | u32 refDivA = 24; | ||
72 | |||
73 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
74 | freq = centers.synth_center; | ||
75 | |||
76 | reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL); | ||
77 | reg32 &= 0xc0000000; | ||
78 | |||
79 | if (freq < 4800) { /* 2 GHz, fractional mode */ | ||
80 | u32 txctl; | ||
81 | int regWrites = 0; | ||
82 | |||
83 | bMode = 1; | ||
84 | fracMode = 1; | ||
85 | aModeRefSel = 0; | ||
86 | channelSel = CHANSEL_2G(freq); | ||
87 | |||
88 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
89 | if (freq == 2484) { | ||
90 | /* Enable channel spreading for channel 14 */ | ||
91 | REG_WRITE_ARRAY(&ah->iniCckfirJapan2484, | ||
92 | 1, regWrites); | ||
93 | } else { | ||
94 | REG_WRITE_ARRAY(&ah->iniCckfirNormal, | ||
95 | 1, regWrites); | ||
96 | } | ||
97 | } else { | ||
98 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
99 | if (freq == 2484) { | ||
100 | /* Enable channel spreading for channel 14 */ | ||
101 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
102 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
103 | } else { | ||
104 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
105 | txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); | ||
106 | } | ||
107 | } | ||
108 | } else { | ||
109 | bMode = 0; | ||
110 | fracMode = 0; | ||
111 | |||
112 | switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) { | ||
113 | case 0: | ||
114 | if ((freq % 20) == 0) | ||
115 | aModeRefSel = 3; | ||
116 | else if ((freq % 10) == 0) | ||
117 | aModeRefSel = 2; | ||
118 | if (aModeRefSel) | ||
119 | break; | ||
120 | case 1: | ||
121 | default: | ||
122 | aModeRefSel = 0; | ||
123 | /* | ||
124 | * Enable 2G (fractional) mode for channels | ||
125 | * which are 5MHz spaced. | ||
126 | */ | ||
127 | fracMode = 1; | ||
128 | refDivA = 1; | ||
129 | channelSel = CHANSEL_5G(freq); | ||
130 | |||
131 | /* RefDivA setting */ | ||
132 | REG_RMW_FIELD(ah, AR_AN_SYNTH9, | ||
133 | AR_AN_SYNTH9_REFDIVA, refDivA); | ||
134 | |||
135 | } | ||
136 | |||
137 | if (!fracMode) { | ||
138 | ndiv = (freq * (refDivA >> aModeRefSel)) / 60; | ||
139 | channelSel = ndiv & 0x1ff; | ||
140 | channelFrac = (ndiv & 0xfffffe00) * 2; | ||
141 | channelSel = (channelSel << 17) | channelFrac; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | reg32 = reg32 | | ||
146 | (bMode << 29) | | ||
147 | (fracMode << 28) | (aModeRefSel << 26) | (channelSel); | ||
148 | |||
149 | REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); | ||
150 | |||
151 | ah->curchan = chan; | ||
152 | ah->curchan_rad_index = -1; | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | /** | ||
158 | * ar9002_hw_spur_mitigate - convert baseband spur frequency | ||
159 | * @ah: atheros hardware structure | ||
160 | * @chan: | ||
161 | * | ||
162 | * For single-chip solutions. Converts to baseband spur frequency given the | ||
163 | * input channel frequency and compute register settings below. | ||
164 | */ | ||
165 | static void ar9002_hw_spur_mitigate(struct ath_hw *ah, | ||
166 | struct ath9k_channel *chan) | ||
167 | { | ||
168 | int bb_spur = AR_NO_SPUR; | ||
169 | int freq; | ||
170 | int bin, cur_bin; | ||
171 | int bb_spur_off, spur_subchannel_sd; | ||
172 | int spur_freq_sd; | ||
173 | int spur_delta_phase; | ||
174 | int denominator; | ||
175 | int upper, lower, cur_vit_mask; | ||
176 | int tmp, newVal; | ||
177 | int i; | ||
178 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
179 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
180 | }; | ||
181 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
182 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
183 | }; | ||
184 | int inc[4] = { 0, 100, 0, 0 }; | ||
185 | struct chan_centers centers; | ||
186 | |||
187 | int8_t mask_m[123]; | ||
188 | int8_t mask_p[123]; | ||
189 | int8_t mask_amt; | ||
190 | int tmp_mask; | ||
191 | int cur_bb_spur; | ||
192 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
193 | |||
194 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
195 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
196 | |||
197 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
198 | freq = centers.synth_center; | ||
199 | |||
200 | ah->config.spurmode = SPUR_ENABLE_EEPROM; | ||
201 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
202 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
203 | |||
204 | if (is2GHz) | ||
205 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; | ||
206 | else | ||
207 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; | ||
208 | |||
209 | if (AR_NO_SPUR == cur_bb_spur) | ||
210 | break; | ||
211 | cur_bb_spur = cur_bb_spur - freq; | ||
212 | |||
213 | if (IS_CHAN_HT40(chan)) { | ||
214 | if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && | ||
215 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { | ||
216 | bb_spur = cur_bb_spur; | ||
217 | break; | ||
218 | } | ||
219 | } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && | ||
220 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { | ||
221 | bb_spur = cur_bb_spur; | ||
222 | break; | ||
223 | } | ||
224 | } | ||
225 | |||
226 | if (AR_NO_SPUR == bb_spur) { | ||
227 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
228 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
229 | return; | ||
230 | } else { | ||
231 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
232 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
233 | } | ||
234 | |||
235 | bin = bb_spur * 320; | ||
236 | |||
237 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
238 | |||
239 | ENABLE_REGWRITE_BUFFER(ah); | ||
240 | |||
241 | newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
242 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
243 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
244 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
245 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal); | ||
246 | |||
247 | newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
248 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
249 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
250 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
251 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
252 | REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); | ||
253 | |||
254 | if (IS_CHAN_HT40(chan)) { | ||
255 | if (bb_spur < 0) { | ||
256 | spur_subchannel_sd = 1; | ||
257 | bb_spur_off = bb_spur + 10; | ||
258 | } else { | ||
259 | spur_subchannel_sd = 0; | ||
260 | bb_spur_off = bb_spur - 10; | ||
261 | } | ||
262 | } else { | ||
263 | spur_subchannel_sd = 0; | ||
264 | bb_spur_off = bb_spur; | ||
265 | } | ||
266 | |||
267 | if (IS_CHAN_HT40(chan)) | ||
268 | spur_delta_phase = | ||
269 | ((bb_spur * 262144) / | ||
270 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
271 | else | ||
272 | spur_delta_phase = | ||
273 | ((bb_spur * 524288) / | ||
274 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
275 | |||
276 | denominator = IS_CHAN_2GHZ(chan) ? 44 : 40; | ||
277 | spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; | ||
278 | |||
279 | newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
280 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
281 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
282 | REG_WRITE(ah, AR_PHY_TIMING11, newVal); | ||
283 | |||
284 | newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; | ||
285 | REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); | ||
286 | |||
287 | cur_bin = -6000; | ||
288 | upper = bin + 100; | ||
289 | lower = bin - 100; | ||
290 | |||
291 | for (i = 0; i < 4; i++) { | ||
292 | int pilot_mask = 0; | ||
293 | int chan_mask = 0; | ||
294 | int bp = 0; | ||
295 | for (bp = 0; bp < 30; bp++) { | ||
296 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
297 | pilot_mask = pilot_mask | 0x1 << bp; | ||
298 | chan_mask = chan_mask | 0x1 << bp; | ||
299 | } | ||
300 | cur_bin += 100; | ||
301 | } | ||
302 | cur_bin += inc[i]; | ||
303 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
304 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
305 | } | ||
306 | |||
307 | cur_vit_mask = 6100; | ||
308 | upper = bin + 120; | ||
309 | lower = bin - 120; | ||
310 | |||
311 | for (i = 0; i < 123; i++) { | ||
312 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
313 | |||
314 | /* workaround for gcc bug #37014 */ | ||
315 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
316 | |||
317 | if (tmp_v < 75) | ||
318 | mask_amt = 1; | ||
319 | else | ||
320 | mask_amt = 0; | ||
321 | if (cur_vit_mask < 0) | ||
322 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
323 | else | ||
324 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
325 | } | ||
326 | cur_vit_mask -= 100; | ||
327 | } | ||
328 | |||
329 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
330 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
331 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
332 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
333 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
334 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
335 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
336 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
337 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
338 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
339 | |||
340 | tmp_mask = (mask_m[31] << 28) | ||
341 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
342 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
343 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
344 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
345 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
346 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
347 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
348 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
349 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
350 | |||
351 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
352 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
353 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
354 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
355 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
356 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
357 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
358 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
359 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
360 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
361 | |||
362 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
363 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
364 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
365 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
366 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
367 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
368 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
369 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
370 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
371 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
372 | |||
373 | tmp_mask = (mask_p[15] << 28) | ||
374 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
375 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
376 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
377 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
378 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
379 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
380 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
381 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
382 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
383 | |||
384 | tmp_mask = (mask_p[30] << 28) | ||
385 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
386 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
387 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
388 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
389 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
390 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
391 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
392 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
393 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
394 | |||
395 | tmp_mask = (mask_p[45] << 28) | ||
396 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
397 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
398 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
399 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
400 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
401 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
402 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
403 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
404 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
405 | |||
406 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
407 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
408 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
409 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
410 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
411 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
412 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
413 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
414 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
415 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
416 | |||
417 | REGWRITE_BUFFER_FLUSH(ah); | ||
418 | DISABLE_REGWRITE_BUFFER(ah); | ||
419 | } | ||
420 | |||
421 | static void ar9002_olc_init(struct ath_hw *ah) | ||
422 | { | ||
423 | u32 i; | ||
424 | |||
425 | if (!OLC_FOR_AR9280_20_LATER) | ||
426 | return; | ||
427 | |||
428 | if (OLC_FOR_AR9287_10_LATER) { | ||
429 | REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9, | ||
430 | AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL); | ||
431 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0, | ||
432 | AR9287_AN_TXPC0_TXPCMODE, | ||
433 | AR9287_AN_TXPC0_TXPCMODE_S, | ||
434 | AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE); | ||
435 | udelay(100); | ||
436 | } else { | ||
437 | for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) | ||
438 | ah->originalGain[i] = | ||
439 | MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4), | ||
440 | AR_PHY_TX_GAIN); | ||
441 | ah->PDADCdelta = 0; | ||
442 | } | ||
443 | } | ||
444 | |||
445 | static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah, | ||
446 | struct ath9k_channel *chan) | ||
447 | { | ||
448 | u32 pll; | ||
449 | |||
450 | pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); | ||
451 | |||
452 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
453 | pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); | ||
454 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
455 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); | ||
456 | |||
457 | if (chan && IS_CHAN_5GHZ(chan)) { | ||
458 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | ||
459 | pll = 0x142c; | ||
460 | else if (AR_SREV_9280_20(ah)) | ||
461 | pll = 0x2850; | ||
462 | else | ||
463 | pll |= SM(0x28, AR_RTC_9160_PLL_DIV); | ||
464 | } else { | ||
465 | pll |= SM(0x2c, AR_RTC_9160_PLL_DIV); | ||
466 | } | ||
467 | |||
468 | return pll; | ||
469 | } | ||
470 | |||
471 | static void ar9002_hw_do_getnf(struct ath_hw *ah, | ||
472 | int16_t nfarray[NUM_NF_READINGS]) | ||
473 | { | ||
474 | struct ath_common *common = ath9k_hw_common(ah); | ||
475 | int16_t nf; | ||
476 | |||
477 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); | ||
478 | |||
479 | if (nf & 0x100) | ||
480 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
481 | ath_print(common, ATH_DBG_CALIBRATE, | ||
482 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | ||
483 | |||
484 | if (AR_SREV_9271(ah) && (nf >= -114)) | ||
485 | nf = -116; | ||
486 | |||
487 | nfarray[0] = nf; | ||
488 | |||
489 | if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) { | ||
490 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | ||
491 | AR9280_PHY_CH1_MINCCA_PWR); | ||
492 | |||
493 | if (nf & 0x100) | ||
494 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
495 | ath_print(common, ATH_DBG_CALIBRATE, | ||
496 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | ||
497 | nfarray[1] = nf; | ||
498 | } | ||
499 | |||
500 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR); | ||
501 | if (nf & 0x100) | ||
502 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
503 | ath_print(common, ATH_DBG_CALIBRATE, | ||
504 | "NF calibrated [ext] [chain 0] is %d\n", nf); | ||
505 | |||
506 | if (AR_SREV_9271(ah) && (nf >= -114)) | ||
507 | nf = -116; | ||
508 | |||
509 | nfarray[3] = nf; | ||
510 | |||
511 | if (!AR_SREV_9285(ah) && !AR_SREV_9271(ah)) { | ||
512 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | ||
513 | AR9280_PHY_CH1_EXT_MINCCA_PWR); | ||
514 | |||
515 | if (nf & 0x100) | ||
516 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
517 | ath_print(common, ATH_DBG_CALIBRATE, | ||
518 | "NF calibrated [ext] [chain 1] is %d\n", nf); | ||
519 | nfarray[4] = nf; | ||
520 | } | ||
521 | } | ||
522 | |||
523 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah) | ||
524 | { | ||
525 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
526 | |||
527 | priv_ops->set_rf_regs = NULL; | ||
528 | priv_ops->rf_alloc_ext_banks = NULL; | ||
529 | priv_ops->rf_free_ext_banks = NULL; | ||
530 | priv_ops->rf_set_freq = ar9002_hw_set_channel; | ||
531 | priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate; | ||
532 | priv_ops->olc_init = ar9002_olc_init; | ||
533 | priv_ops->compute_pll_control = ar9002_hw_compute_pll_control; | ||
534 | priv_ops->do_getnf = ar9002_hw_do_getnf; | ||
535 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.h b/drivers/net/wireless/ath/ath9k/ar9002_phy.h new file mode 100644 index 000000000000..81bf6e5840e1 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h | |||
@@ -0,0 +1,572 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | #ifndef AR9002_PHY_H | ||
17 | #define AR9002_PHY_H | ||
18 | |||
19 | #define AR_PHY_TEST 0x9800 | ||
20 | #define PHY_AGC_CLR 0x10000000 | ||
21 | #define RFSILENT_BB 0x00002000 | ||
22 | |||
23 | #define AR_PHY_TURBO 0x9804 | ||
24 | #define AR_PHY_FC_TURBO_MODE 0x00000001 | ||
25 | #define AR_PHY_FC_TURBO_SHORT 0x00000002 | ||
26 | #define AR_PHY_FC_DYN2040_EN 0x00000004 | ||
27 | #define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008 | ||
28 | #define AR_PHY_FC_DYN2040_PRI_CH 0x00000010 | ||
29 | /* For 25 MHz channel spacing -- not used but supported by hw */ | ||
30 | #define AR_PHY_FC_DYN2040_EXT_CH 0x00000020 | ||
31 | #define AR_PHY_FC_HT_EN 0x00000040 | ||
32 | #define AR_PHY_FC_SHORT_GI_40 0x00000080 | ||
33 | #define AR_PHY_FC_WALSH 0x00000100 | ||
34 | #define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 | ||
35 | #define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800 | ||
36 | |||
37 | #define AR_PHY_TEST2 0x9808 | ||
38 | |||
39 | #define AR_PHY_TIMING2 0x9810 | ||
40 | #define AR_PHY_TIMING3 0x9814 | ||
41 | #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 | ||
42 | #define AR_PHY_TIMING3_DSC_MAN_S 17 | ||
43 | #define AR_PHY_TIMING3_DSC_EXP 0x0001E000 | ||
44 | #define AR_PHY_TIMING3_DSC_EXP_S 13 | ||
45 | |||
46 | #define AR_PHY_CHIP_ID_REV_0 0x80 | ||
47 | #define AR_PHY_CHIP_ID_REV_1 0x81 | ||
48 | #define AR_PHY_CHIP_ID_9160_REV_0 0xb0 | ||
49 | |||
50 | #define AR_PHY_ACTIVE 0x981C | ||
51 | #define AR_PHY_ACTIVE_EN 0x00000001 | ||
52 | #define AR_PHY_ACTIVE_DIS 0x00000000 | ||
53 | |||
54 | #define AR_PHY_RF_CTL2 0x9824 | ||
55 | #define AR_PHY_TX_END_DATA_START 0x000000FF | ||
56 | #define AR_PHY_TX_END_DATA_START_S 0 | ||
57 | #define AR_PHY_TX_END_PA_ON 0x0000FF00 | ||
58 | #define AR_PHY_TX_END_PA_ON_S 8 | ||
59 | |||
60 | #define AR_PHY_RF_CTL3 0x9828 | ||
61 | #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 | ||
62 | #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 | ||
63 | |||
64 | #define AR_PHY_ADC_CTL 0x982C | ||
65 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 | ||
66 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 | ||
67 | #define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 | ||
68 | #define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 | ||
69 | #define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000 | ||
70 | #define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 | ||
71 | #define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16 | ||
72 | |||
73 | #define AR_PHY_ADC_SERIAL_CTL 0x9830 | ||
74 | #define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000 | ||
75 | #define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001 | ||
76 | |||
77 | #define AR_PHY_RF_CTL4 0x9834 | ||
78 | #define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000 | ||
79 | #define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 | ||
80 | #define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000 | ||
81 | #define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 | ||
82 | #define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00 | ||
83 | #define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 | ||
84 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF | ||
85 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 | ||
86 | |||
87 | #define AR_PHY_TSTDAC_CONST 0x983c | ||
88 | |||
89 | #define AR_PHY_SETTLING 0x9844 | ||
90 | #define AR_PHY_SETTLING_SWITCH 0x00003F80 | ||
91 | #define AR_PHY_SETTLING_SWITCH_S 7 | ||
92 | |||
93 | #define AR_PHY_RXGAIN 0x9848 | ||
94 | #define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000 | ||
95 | #define AR_PHY_RXGAIN_TXRX_ATTEN_S 12 | ||
96 | #define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000 | ||
97 | #define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18 | ||
98 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80 | ||
99 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7 | ||
100 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000 | ||
101 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14 | ||
102 | |||
103 | #define AR_PHY_DESIRED_SZ 0x9850 | ||
104 | #define AR_PHY_DESIRED_SZ_ADC 0x000000FF | ||
105 | #define AR_PHY_DESIRED_SZ_ADC_S 0 | ||
106 | #define AR_PHY_DESIRED_SZ_PGA 0x0000FF00 | ||
107 | #define AR_PHY_DESIRED_SZ_PGA_S 8 | ||
108 | #define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000 | ||
109 | #define AR_PHY_DESIRED_SZ_TOT_DES_S 20 | ||
110 | |||
111 | #define AR_PHY_FIND_SIG 0x9858 | ||
112 | #define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000 | ||
113 | #define AR_PHY_FIND_SIG_FIRSTEP_S 12 | ||
114 | #define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 | ||
115 | #define AR_PHY_FIND_SIG_FIRPWR_S 18 | ||
116 | |||
117 | #define AR_PHY_AGC_CTL1 0x985C | ||
118 | #define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80 | ||
119 | #define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 | ||
120 | #define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000 | ||
121 | #define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15 | ||
122 | |||
123 | #define AR_PHY_CCA 0x9864 | ||
124 | #define AR_PHY_MINCCA_PWR 0x0FF80000 | ||
125 | #define AR_PHY_MINCCA_PWR_S 19 | ||
126 | #define AR_PHY_CCA_THRESH62 0x0007F000 | ||
127 | #define AR_PHY_CCA_THRESH62_S 12 | ||
128 | #define AR9280_PHY_MINCCA_PWR 0x1FF00000 | ||
129 | #define AR9280_PHY_MINCCA_PWR_S 20 | ||
130 | #define AR9280_PHY_CCA_THRESH62 0x000FF000 | ||
131 | #define AR9280_PHY_CCA_THRESH62_S 12 | ||
132 | |||
133 | #define AR_PHY_SFCORR_LOW 0x986C | ||
134 | #define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 | ||
135 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00 | ||
136 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 | ||
137 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000 | ||
138 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 | ||
139 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000 | ||
140 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 | ||
141 | |||
142 | #define AR_PHY_SFCORR 0x9868 | ||
143 | #define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F | ||
144 | #define AR_PHY_SFCORR_M2COUNT_THR_S 0 | ||
145 | #define AR_PHY_SFCORR_M1_THRESH 0x00FE0000 | ||
146 | #define AR_PHY_SFCORR_M1_THRESH_S 17 | ||
147 | #define AR_PHY_SFCORR_M2_THRESH 0x7F000000 | ||
148 | #define AR_PHY_SFCORR_M2_THRESH_S 24 | ||
149 | |||
150 | #define AR_PHY_SLEEP_CTR_CONTROL 0x9870 | ||
151 | #define AR_PHY_SLEEP_CTR_LIMIT 0x9874 | ||
152 | #define AR_PHY_SYNTH_CONTROL 0x9874 | ||
153 | #define AR_PHY_SLEEP_SCAL 0x9878 | ||
154 | |||
155 | #define AR_PHY_PLL_CTL 0x987c | ||
156 | #define AR_PHY_PLL_CTL_40 0xaa | ||
157 | #define AR_PHY_PLL_CTL_40_5413 0x04 | ||
158 | #define AR_PHY_PLL_CTL_44 0xab | ||
159 | #define AR_PHY_PLL_CTL_44_2133 0xeb | ||
160 | #define AR_PHY_PLL_CTL_40_2133 0xea | ||
161 | |||
162 | #define AR_PHY_SPECTRAL_SCAN 0x9910 /* AR9280 spectral scan configuration register */ | ||
163 | #define AR_PHY_SPECTRAL_SCAN_ENABLE 0x1 | ||
164 | #define AR_PHY_SPECTRAL_SCAN_ENA 0x00000001 /* Enable spectral scan, reg 68, bit 0 */ | ||
165 | #define AR_PHY_SPECTRAL_SCAN_ENA_S 0 /* Enable spectral scan, reg 68, bit 0 */ | ||
166 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 /* Activate spectral scan reg 68, bit 1*/ | ||
167 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 /* Activate spectral scan reg 68, bit 1*/ | ||
168 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 /* Interval for FFT reports, reg 68, bits 4-7*/ | ||
169 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 | ||
170 | #define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 /* Interval for FFT reports, reg 68, bits 8-15*/ | ||
171 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 | ||
172 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/ | ||
173 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 | ||
174 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/ | ||
175 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/ | ||
176 | |||
177 | #define AR_PHY_RX_DELAY 0x9914 | ||
178 | #define AR_PHY_SEARCH_START_DELAY 0x9918 | ||
179 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF | ||
180 | |||
181 | #define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12)) | ||
182 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F | ||
183 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 | ||
184 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0 | ||
185 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 | ||
186 | #define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 | ||
187 | #define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000 | ||
188 | #define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 | ||
189 | #define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000 | ||
190 | |||
191 | #define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 | ||
192 | #define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 | ||
193 | #define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 | ||
194 | #define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 | ||
195 | |||
196 | #define AR_PHY_TIMING5 0x9924 | ||
197 | #define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE | ||
198 | #define AR_PHY_TIMING5_CYCPWR_THR1_S 1 | ||
199 | |||
200 | #define AR_PHY_POWER_TX_RATE1 0x9934 | ||
201 | #define AR_PHY_POWER_TX_RATE2 0x9938 | ||
202 | #define AR_PHY_POWER_TX_RATE_MAX 0x993c | ||
203 | #define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 | ||
204 | |||
205 | #define AR_PHY_FRAME_CTL 0x9944 | ||
206 | #define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038 | ||
207 | #define AR_PHY_FRAME_CTL_TX_CLIP_S 3 | ||
208 | |||
209 | #define AR_PHY_TXPWRADJ 0x994C | ||
210 | #define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0 | ||
211 | #define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6 | ||
212 | #define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000 | ||
213 | #define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18 | ||
214 | |||
215 | #define AR_PHY_RADAR_EXT 0x9940 | ||
216 | #define AR_PHY_RADAR_EXT_ENA 0x00004000 | ||
217 | |||
218 | #define AR_PHY_RADAR_0 0x9954 | ||
219 | #define AR_PHY_RADAR_0_ENA 0x00000001 | ||
220 | #define AR_PHY_RADAR_0_FFT_ENA 0x80000000 | ||
221 | #define AR_PHY_RADAR_0_INBAND 0x0000003e | ||
222 | #define AR_PHY_RADAR_0_INBAND_S 1 | ||
223 | #define AR_PHY_RADAR_0_PRSSI 0x00000FC0 | ||
224 | #define AR_PHY_RADAR_0_PRSSI_S 6 | ||
225 | #define AR_PHY_RADAR_0_HEIGHT 0x0003F000 | ||
226 | #define AR_PHY_RADAR_0_HEIGHT_S 12 | ||
227 | #define AR_PHY_RADAR_0_RRSSI 0x00FC0000 | ||
228 | #define AR_PHY_RADAR_0_RRSSI_S 18 | ||
229 | #define AR_PHY_RADAR_0_FIRPWR 0x7F000000 | ||
230 | #define AR_PHY_RADAR_0_FIRPWR_S 24 | ||
231 | |||
232 | #define AR_PHY_RADAR_1 0x9958 | ||
233 | #define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000 | ||
234 | #define AR_PHY_RADAR_1_USE_FIR128 0x00400000 | ||
235 | #define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000 | ||
236 | #define AR_PHY_RADAR_1_RELPWR_THRESH_S 16 | ||
237 | #define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000 | ||
238 | #define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000 | ||
239 | #define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 | ||
240 | #define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00 | ||
241 | #define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8 | ||
242 | #define AR_PHY_RADAR_1_MAXLEN 0x000000FF | ||
243 | #define AR_PHY_RADAR_1_MAXLEN_S 0 | ||
244 | |||
245 | #define AR_PHY_SWITCH_CHAIN_0 0x9960 | ||
246 | #define AR_PHY_SWITCH_COM 0x9964 | ||
247 | |||
248 | #define AR_PHY_SIGMA_DELTA 0x996C | ||
249 | #define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 | ||
250 | #define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0 | ||
251 | #define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8 | ||
252 | #define AR_PHY_SIGMA_DELTA_FILT2_S 3 | ||
253 | #define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00 | ||
254 | #define AR_PHY_SIGMA_DELTA_FILT1_S 8 | ||
255 | #define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000 | ||
256 | #define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13 | ||
257 | |||
258 | #define AR_PHY_RESTART 0x9970 | ||
259 | #define AR_PHY_RESTART_DIV_GC 0x001C0000 | ||
260 | #define AR_PHY_RESTART_DIV_GC_S 18 | ||
261 | |||
262 | #define AR_PHY_RFBUS_REQ 0x997C | ||
263 | #define AR_PHY_RFBUS_REQ_EN 0x00000001 | ||
264 | |||
265 | #define AR_PHY_TIMING7 0x9980 | ||
266 | #define AR_PHY_TIMING8 0x9984 | ||
267 | #define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF | ||
268 | #define AR_PHY_TIMING8_PILOT_MASK_2_S 0 | ||
269 | |||
270 | #define AR_PHY_BIN_MASK2_1 0x9988 | ||
271 | #define AR_PHY_BIN_MASK2_2 0x998c | ||
272 | #define AR_PHY_BIN_MASK2_3 0x9990 | ||
273 | #define AR_PHY_BIN_MASK2_4 0x9994 | ||
274 | |||
275 | #define AR_PHY_BIN_MASK_1 0x9900 | ||
276 | #define AR_PHY_BIN_MASK_2 0x9904 | ||
277 | #define AR_PHY_BIN_MASK_3 0x9908 | ||
278 | |||
279 | #define AR_PHY_MASK_CTL 0x990c | ||
280 | |||
281 | #define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF | ||
282 | #define AR_PHY_BIN_MASK2_4_MASK_4_S 0 | ||
283 | |||
284 | #define AR_PHY_TIMING9 0x9998 | ||
285 | #define AR_PHY_TIMING10 0x999c | ||
286 | #define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF | ||
287 | #define AR_PHY_TIMING10_PILOT_MASK_2_S 0 | ||
288 | |||
289 | #define AR_PHY_TIMING11 0x99a0 | ||
290 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF | ||
291 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 | ||
292 | #define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 | ||
293 | #define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 | ||
294 | |||
295 | #define AR_PHY_RX_CHAINMASK 0x99a4 | ||
296 | #define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12)) | ||
297 | #define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 | ||
298 | #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 | ||
299 | |||
300 | #define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac | ||
301 | #define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 | ||
302 | #define AR_PHY_9285_ANT_DIV_CTL 0x01000000 | ||
303 | #define AR_PHY_9285_ANT_DIV_CTL_S 24 | ||
304 | #define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000 | ||
305 | #define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25 | ||
306 | #define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000 | ||
307 | #define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27 | ||
308 | #define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000 | ||
309 | #define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29 | ||
310 | #define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000 | ||
311 | #define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30 | ||
312 | #define AR_PHY_9285_ANT_DIV_LNA1 2 | ||
313 | #define AR_PHY_9285_ANT_DIV_LNA2 1 | ||
314 | #define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3 | ||
315 | #define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0 | ||
316 | #define AR_PHY_9285_ANT_DIV_GAINTB_0 0 | ||
317 | #define AR_PHY_9285_ANT_DIV_GAINTB_1 1 | ||
318 | |||
319 | #define AR_PHY_EXT_CCA0 0x99b8 | ||
320 | #define AR_PHY_EXT_CCA0_THRESH62 0x000000FF | ||
321 | #define AR_PHY_EXT_CCA0_THRESH62_S 0 | ||
322 | |||
323 | #define AR_PHY_EXT_CCA 0x99bc | ||
324 | #define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00 | ||
325 | #define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9 | ||
326 | #define AR_PHY_EXT_CCA_THRESH62 0x007F0000 | ||
327 | #define AR_PHY_EXT_CCA_THRESH62_S 16 | ||
328 | #define AR_PHY_EXT_MINCCA_PWR 0xFF800000 | ||
329 | #define AR_PHY_EXT_MINCCA_PWR_S 23 | ||
330 | #define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 | ||
331 | #define AR9280_PHY_EXT_MINCCA_PWR_S 16 | ||
332 | |||
333 | #define AR_PHY_SFCORR_EXT 0x99c0 | ||
334 | #define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F | ||
335 | #define AR_PHY_SFCORR_EXT_M1_THRESH_S 0 | ||
336 | #define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80 | ||
337 | #define AR_PHY_SFCORR_EXT_M2_THRESH_S 7 | ||
338 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000 | ||
339 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 | ||
340 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000 | ||
341 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 | ||
342 | #define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 | ||
343 | |||
344 | #define AR_PHY_HALFGI 0x99D0 | ||
345 | #define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0 | ||
346 | #define AR_PHY_HALFGI_DSC_MAN_S 4 | ||
347 | #define AR_PHY_HALFGI_DSC_EXP 0x0000000F | ||
348 | #define AR_PHY_HALFGI_DSC_EXP_S 0 | ||
349 | |||
350 | #define AR_PHY_CHAN_INFO_MEMORY 0x99DC | ||
351 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 | ||
352 | |||
353 | #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 | ||
354 | |||
355 | #define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC | ||
356 | #define AR_PHY_RIFS_INIT_DELAY 0x03ff0000 | ||
357 | |||
358 | #define AR_PHY_M_SLEEP 0x99f0 | ||
359 | #define AR_PHY_REFCLKDLY 0x99f4 | ||
360 | #define AR_PHY_REFCLKPD 0x99f8 | ||
361 | |||
362 | #define AR_PHY_CALMODE 0x99f0 | ||
363 | |||
364 | #define AR_PHY_CALMODE_IQ 0x00000000 | ||
365 | #define AR_PHY_CALMODE_ADC_GAIN 0x00000001 | ||
366 | #define AR_PHY_CALMODE_ADC_DC_PER 0x00000002 | ||
367 | #define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003 | ||
368 | |||
369 | #define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12)) | ||
370 | #define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12)) | ||
371 | #define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12)) | ||
372 | #define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12)) | ||
373 | |||
374 | #define AR_PHY_CURRENT_RSSI 0x9c1c | ||
375 | #define AR9280_PHY_CURRENT_RSSI 0x9c3c | ||
376 | |||
377 | #define AR_PHY_RFBUS_GRANT 0x9C20 | ||
378 | #define AR_PHY_RFBUS_GRANT_EN 0x00000001 | ||
379 | |||
380 | #define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4 | ||
381 | #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 | ||
382 | |||
383 | #define AR_PHY_CHAN_INFO_GAIN 0x9CFC | ||
384 | |||
385 | #define AR_PHY_MODE 0xA200 | ||
386 | #define AR_PHY_MODE_ASYNCFIFO 0x80 | ||
387 | #define AR_PHY_MODE_AR2133 0x08 | ||
388 | #define AR_PHY_MODE_AR5111 0x00 | ||
389 | #define AR_PHY_MODE_AR5112 0x08 | ||
390 | #define AR_PHY_MODE_DYNAMIC 0x04 | ||
391 | #define AR_PHY_MODE_RF2GHZ 0x02 | ||
392 | #define AR_PHY_MODE_RF5GHZ 0x00 | ||
393 | #define AR_PHY_MODE_CCK 0x01 | ||
394 | #define AR_PHY_MODE_OFDM 0x00 | ||
395 | #define AR_PHY_MODE_DYN_CCK_DISABLE 0x100 | ||
396 | |||
397 | #define AR_PHY_CCK_TX_CTRL 0xA204 | ||
398 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 | ||
399 | #define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C | ||
400 | #define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 | ||
401 | |||
402 | #define AR_PHY_CCK_DETECT 0xA208 | ||
403 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F | ||
404 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 | ||
405 | /* [12:6] settling time for antenna switch */ | ||
406 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 | ||
407 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 | ||
408 | #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 | ||
409 | #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 | ||
410 | |||
411 | #define AR_PHY_GAIN_2GHZ 0xA20C | ||
412 | #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000 | ||
413 | #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 | ||
414 | #define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00 | ||
415 | #define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 | ||
416 | #define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F | ||
417 | #define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 | ||
418 | |||
419 | #define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000 | ||
420 | #define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 | ||
421 | #define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000 | ||
422 | #define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 | ||
423 | #define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0 | ||
424 | #define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 | ||
425 | #define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F | ||
426 | #define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 | ||
427 | |||
428 | #define AR_PHY_CCK_RXCTRL4 0xA21C | ||
429 | #define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000 | ||
430 | #define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 | ||
431 | |||
432 | #define AR_PHY_DAG_CTRLCCK 0xA228 | ||
433 | #define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 | ||
434 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00 | ||
435 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 | ||
436 | |||
437 | #define AR_PHY_FORCE_CLKEN_CCK 0xA22C | ||
438 | #define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 | ||
439 | |||
440 | #define AR_PHY_POWER_TX_RATE3 0xA234 | ||
441 | #define AR_PHY_POWER_TX_RATE4 0xA238 | ||
442 | |||
443 | #define AR_PHY_SCRM_SEQ_XR 0xA23C | ||
444 | #define AR_PHY_HEADER_DETECT_XR 0xA240 | ||
445 | #define AR_PHY_CHIRP_DETECTED_XR 0xA244 | ||
446 | #define AR_PHY_BLUETOOTH 0xA254 | ||
447 | |||
448 | #define AR_PHY_TPCRG1 0xA258 | ||
449 | #define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 | ||
450 | #define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14 | ||
451 | |||
452 | #define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000 | ||
453 | #define AR_PHY_TPCRG1_PD_GAIN_1_S 16 | ||
454 | #define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000 | ||
455 | #define AR_PHY_TPCRG1_PD_GAIN_2_S 18 | ||
456 | #define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000 | ||
457 | #define AR_PHY_TPCRG1_PD_GAIN_3_S 20 | ||
458 | |||
459 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 | ||
460 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22 | ||
461 | |||
462 | #define AR_PHY_TX_PWRCTRL4 0xa264 | ||
463 | #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 | ||
464 | #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 | ||
465 | #define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE | ||
466 | #define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 | ||
467 | |||
468 | #define AR_PHY_TX_PWRCTRL6_0 0xa270 | ||
469 | #define AR_PHY_TX_PWRCTRL6_1 0xb270 | ||
470 | #define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000 | ||
471 | #define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 | ||
472 | |||
473 | #define AR_PHY_TX_PWRCTRL7 0xa274 | ||
474 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 | ||
475 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 | ||
476 | |||
477 | #define AR_PHY_TX_PWRCTRL9 0xa27C | ||
478 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 | ||
479 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 | ||
480 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 | ||
481 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 | ||
482 | |||
483 | #define AR_PHY_TX_GAIN_TBL1 0xa300 | ||
484 | #define AR_PHY_TX_GAIN 0x0007F000 | ||
485 | #define AR_PHY_TX_GAIN_S 12 | ||
486 | |||
487 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 | ||
488 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 | ||
489 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 | ||
490 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 | ||
491 | |||
492 | #define AR_PHY_VIT_MASK2_M_46_61 0xa3a0 | ||
493 | #define AR_PHY_MASK2_M_31_45 0xa3a4 | ||
494 | #define AR_PHY_MASK2_M_16_30 0xa3a8 | ||
495 | #define AR_PHY_MASK2_M_00_15 0xa3ac | ||
496 | #define AR_PHY_MASK2_P_15_01 0xa3b8 | ||
497 | #define AR_PHY_MASK2_P_30_16 0xa3bc | ||
498 | #define AR_PHY_MASK2_P_45_31 0xa3c0 | ||
499 | #define AR_PHY_MASK2_P_61_45 0xa3c4 | ||
500 | #define AR_PHY_SPUR_REG 0x994c | ||
501 | |||
502 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18) | ||
503 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 | ||
504 | |||
505 | #define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 | ||
506 | #define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9) | ||
507 | #define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9 | ||
508 | #define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100 | ||
509 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F | ||
510 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 | ||
511 | |||
512 | #define AR_PHY_PILOT_MASK_01_30 0xa3b0 | ||
513 | #define AR_PHY_PILOT_MASK_31_60 0xa3b4 | ||
514 | |||
515 | #define AR_PHY_CHANNEL_MASK_01_30 0x99d4 | ||
516 | #define AR_PHY_CHANNEL_MASK_31_60 0x99d8 | ||
517 | |||
518 | #define AR_PHY_ANALOG_SWAP 0xa268 | ||
519 | #define AR_PHY_SWAP_ALT_CHAIN 0x00000040 | ||
520 | |||
521 | #define AR_PHY_TPCRG5 0xA26C | ||
522 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F | ||
523 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 | ||
524 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0 | ||
525 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 | ||
526 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00 | ||
527 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 | ||
528 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000 | ||
529 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 | ||
530 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000 | ||
531 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 | ||
532 | |||
533 | /* Carrier leak calibration control, do it after AGC calibration */ | ||
534 | #define AR_PHY_CL_CAL_CTL 0xA358 | ||
535 | #define AR_PHY_CL_CAL_ENABLE 0x00000002 | ||
536 | #define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001 | ||
537 | |||
538 | #define AR_PHY_POWER_TX_RATE5 0xA38C | ||
539 | #define AR_PHY_POWER_TX_RATE6 0xA390 | ||
540 | |||
541 | #define AR_PHY_CAL_CHAINMASK 0xA39C | ||
542 | |||
543 | #define AR_PHY_POWER_TX_SUB 0xA3C8 | ||
544 | #define AR_PHY_POWER_TX_RATE7 0xA3CC | ||
545 | #define AR_PHY_POWER_TX_RATE8 0xA3D0 | ||
546 | #define AR_PHY_POWER_TX_RATE9 0xA3D4 | ||
547 | |||
548 | #define AR_PHY_XPA_CFG 0xA3D8 | ||
549 | #define AR_PHY_FORCE_XPA_CFG 0x000000001 | ||
550 | #define AR_PHY_FORCE_XPA_CFG_S 0 | ||
551 | |||
552 | #define AR_PHY_CH1_CCA 0xa864 | ||
553 | #define AR_PHY_CH1_MINCCA_PWR 0x0FF80000 | ||
554 | #define AR_PHY_CH1_MINCCA_PWR_S 19 | ||
555 | #define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000 | ||
556 | #define AR9280_PHY_CH1_MINCCA_PWR_S 20 | ||
557 | |||
558 | #define AR_PHY_CH2_CCA 0xb864 | ||
559 | #define AR_PHY_CH2_MINCCA_PWR 0x0FF80000 | ||
560 | #define AR_PHY_CH2_MINCCA_PWR_S 19 | ||
561 | |||
562 | #define AR_PHY_CH1_EXT_CCA 0xa9bc | ||
563 | #define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000 | ||
564 | #define AR_PHY_CH1_EXT_MINCCA_PWR_S 23 | ||
565 | #define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000 | ||
566 | #define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16 | ||
567 | |||
568 | #define AR_PHY_CH2_EXT_CCA 0xb9bc | ||
569 | #define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000 | ||
570 | #define AR_PHY_CH2_EXT_MINCCA_PWR_S 23 | ||
571 | |||
572 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c new file mode 100644 index 000000000000..56a9e5fa6d66 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c | |||
@@ -0,0 +1,802 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | #include "hw-ops.h" | ||
19 | #include "ar9003_phy.h" | ||
20 | |||
21 | static void ar9003_hw_setup_calibration(struct ath_hw *ah, | ||
22 | struct ath9k_cal_list *currCal) | ||
23 | { | ||
24 | struct ath_common *common = ath9k_hw_common(ah); | ||
25 | |||
26 | /* Select calibration to run */ | ||
27 | switch (currCal->calData->calType) { | ||
28 | case IQ_MISMATCH_CAL: | ||
29 | /* | ||
30 | * Start calibration with | ||
31 | * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples | ||
32 | */ | ||
33 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
34 | AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX, | ||
35 | currCal->calData->calCountMax); | ||
36 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | ||
37 | |||
38 | ath_print(common, ATH_DBG_CALIBRATE, | ||
39 | "starting IQ Mismatch Calibration\n"); | ||
40 | |||
41 | /* Kick-off cal */ | ||
42 | REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL); | ||
43 | break; | ||
44 | case TEMP_COMP_CAL: | ||
45 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, | ||
46 | AR_PHY_65NM_CH0_THERM_LOCAL, 1); | ||
47 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM, | ||
48 | AR_PHY_65NM_CH0_THERM_START, 1); | ||
49 | |||
50 | ath_print(common, ATH_DBG_CALIBRATE, | ||
51 | "starting Temperature Compensation Calibration\n"); | ||
52 | break; | ||
53 | case ADC_DC_INIT_CAL: | ||
54 | case ADC_GAIN_CAL: | ||
55 | case ADC_DC_CAL: | ||
56 | /* Not yet */ | ||
57 | break; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * Generic calibration routine. | ||
63 | * Recalibrate the lower PHY chips to account for temperature/environment | ||
64 | * changes. | ||
65 | */ | ||
66 | static bool ar9003_hw_per_calibration(struct ath_hw *ah, | ||
67 | struct ath9k_channel *ichan, | ||
68 | u8 rxchainmask, | ||
69 | struct ath9k_cal_list *currCal) | ||
70 | { | ||
71 | /* Cal is assumed not done until explicitly set below */ | ||
72 | bool iscaldone = false; | ||
73 | |||
74 | /* Calibration in progress. */ | ||
75 | if (currCal->calState == CAL_RUNNING) { | ||
76 | /* Check to see if it has finished. */ | ||
77 | if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) { | ||
78 | /* | ||
79 | * Accumulate cal measures for active chains | ||
80 | */ | ||
81 | currCal->calData->calCollect(ah); | ||
82 | ah->cal_samples++; | ||
83 | |||
84 | if (ah->cal_samples >= | ||
85 | currCal->calData->calNumSamples) { | ||
86 | unsigned int i, numChains = 0; | ||
87 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
88 | if (rxchainmask & (1 << i)) | ||
89 | numChains++; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * Process accumulated data | ||
94 | */ | ||
95 | currCal->calData->calPostProc(ah, numChains); | ||
96 | |||
97 | /* Calibration has finished. */ | ||
98 | ichan->CalValid |= currCal->calData->calType; | ||
99 | currCal->calState = CAL_DONE; | ||
100 | iscaldone = true; | ||
101 | } else { | ||
102 | /* | ||
103 | * Set-up collection of another sub-sample until we | ||
104 | * get desired number | ||
105 | */ | ||
106 | ar9003_hw_setup_calibration(ah, currCal); | ||
107 | } | ||
108 | } | ||
109 | } else if (!(ichan->CalValid & currCal->calData->calType)) { | ||
110 | /* If current cal is marked invalid in channel, kick it off */ | ||
111 | ath9k_hw_reset_calibration(ah, currCal); | ||
112 | } | ||
113 | |||
114 | return iscaldone; | ||
115 | } | ||
116 | |||
117 | static bool ar9003_hw_calibrate(struct ath_hw *ah, | ||
118 | struct ath9k_channel *chan, | ||
119 | u8 rxchainmask, | ||
120 | bool longcal) | ||
121 | { | ||
122 | bool iscaldone = true; | ||
123 | struct ath9k_cal_list *currCal = ah->cal_list_curr; | ||
124 | |||
125 | /* | ||
126 | * For given calibration: | ||
127 | * 1. Call generic cal routine | ||
128 | * 2. When this cal is done (isCalDone) if we have more cals waiting | ||
129 | * (eg after reset), mask this to upper layers by not propagating | ||
130 | * isCalDone if it is set to TRUE. | ||
131 | * Instead, change isCalDone to FALSE and setup the waiting cal(s) | ||
132 | * to be run. | ||
133 | */ | ||
134 | if (currCal && | ||
135 | (currCal->calState == CAL_RUNNING || | ||
136 | currCal->calState == CAL_WAITING)) { | ||
137 | iscaldone = ar9003_hw_per_calibration(ah, chan, | ||
138 | rxchainmask, currCal); | ||
139 | if (iscaldone) { | ||
140 | ah->cal_list_curr = currCal = currCal->calNext; | ||
141 | |||
142 | if (currCal->calState == CAL_WAITING) { | ||
143 | iscaldone = false; | ||
144 | ath9k_hw_reset_calibration(ah, currCal); | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | /* Do NF cal only at longer intervals */ | ||
150 | if (longcal) { | ||
151 | /* | ||
152 | * Load the NF from history buffer of the current channel. | ||
153 | * NF is slow time-variant, so it is OK to use a historical | ||
154 | * value. | ||
155 | */ | ||
156 | ath9k_hw_loadnf(ah, ah->curchan); | ||
157 | |||
158 | /* start NF calibration, without updating BB NF register */ | ||
159 | ath9k_hw_start_nfcal(ah); | ||
160 | } | ||
161 | |||
162 | return iscaldone; | ||
163 | } | ||
164 | |||
165 | static void ar9003_hw_iqcal_collect(struct ath_hw *ah) | ||
166 | { | ||
167 | int i; | ||
168 | |||
169 | /* Accumulate IQ cal measures for active chains */ | ||
170 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
171 | ah->totalPowerMeasI[i] += | ||
172 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
173 | ah->totalPowerMeasQ[i] += | ||
174 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
175 | ah->totalIqCorrMeas[i] += | ||
176 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
177 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
178 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | ||
179 | ah->cal_samples, i, ah->totalPowerMeasI[i], | ||
180 | ah->totalPowerMeasQ[i], | ||
181 | ah->totalIqCorrMeas[i]); | ||
182 | } | ||
183 | } | ||
184 | |||
185 | static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | ||
186 | { | ||
187 | struct ath_common *common = ath9k_hw_common(ah); | ||
188 | u32 powerMeasQ, powerMeasI, iqCorrMeas; | ||
189 | u32 qCoffDenom, iCoffDenom; | ||
190 | int32_t qCoff, iCoff; | ||
191 | int iqCorrNeg, i; | ||
192 | const u_int32_t offset_array[3] = { | ||
193 | AR_PHY_RX_IQCAL_CORR_B0, | ||
194 | AR_PHY_RX_IQCAL_CORR_B1, | ||
195 | AR_PHY_RX_IQCAL_CORR_B2, | ||
196 | }; | ||
197 | |||
198 | for (i = 0; i < numChains; i++) { | ||
199 | powerMeasI = ah->totalPowerMeasI[i]; | ||
200 | powerMeasQ = ah->totalPowerMeasQ[i]; | ||
201 | iqCorrMeas = ah->totalIqCorrMeas[i]; | ||
202 | |||
203 | ath_print(common, ATH_DBG_CALIBRATE, | ||
204 | "Starting IQ Cal and Correction for Chain %d\n", | ||
205 | i); | ||
206 | |||
207 | ath_print(common, ATH_DBG_CALIBRATE, | ||
208 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | ||
209 | i, ah->totalIqCorrMeas[i]); | ||
210 | |||
211 | iqCorrNeg = 0; | ||
212 | |||
213 | if (iqCorrMeas > 0x80000000) { | ||
214 | iqCorrMeas = (0xffffffff - iqCorrMeas) + 1; | ||
215 | iqCorrNeg = 1; | ||
216 | } | ||
217 | |||
218 | ath_print(common, ATH_DBG_CALIBRATE, | ||
219 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | ||
220 | ath_print(common, ATH_DBG_CALIBRATE, | ||
221 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | ||
222 | ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | ||
223 | iqCorrNeg); | ||
224 | |||
225 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256; | ||
226 | qCoffDenom = powerMeasQ / 64; | ||
227 | |||
228 | if ((iCoffDenom != 0) && (qCoffDenom != 0)) { | ||
229 | iCoff = iqCorrMeas / iCoffDenom; | ||
230 | qCoff = powerMeasI / qCoffDenom - 64; | ||
231 | ath_print(common, ATH_DBG_CALIBRATE, | ||
232 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
233 | ath_print(common, ATH_DBG_CALIBRATE, | ||
234 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | ||
235 | |||
236 | /* Force bounds on iCoff */ | ||
237 | if (iCoff >= 63) | ||
238 | iCoff = 63; | ||
239 | else if (iCoff <= -63) | ||
240 | iCoff = -63; | ||
241 | |||
242 | /* Negate iCoff if iqCorrNeg == 0 */ | ||
243 | if (iqCorrNeg == 0x0) | ||
244 | iCoff = -iCoff; | ||
245 | |||
246 | /* Force bounds on qCoff */ | ||
247 | if (qCoff >= 63) | ||
248 | qCoff = 63; | ||
249 | else if (qCoff <= -63) | ||
250 | qCoff = -63; | ||
251 | |||
252 | iCoff = iCoff & 0x7f; | ||
253 | qCoff = qCoff & 0x7f; | ||
254 | |||
255 | ath_print(common, ATH_DBG_CALIBRATE, | ||
256 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | ||
257 | i, iCoff, qCoff); | ||
258 | ath_print(common, ATH_DBG_CALIBRATE, | ||
259 | "Register offset (0x%04x) " | ||
260 | "before update = 0x%x\n", | ||
261 | offset_array[i], | ||
262 | REG_READ(ah, offset_array[i])); | ||
263 | |||
264 | REG_RMW_FIELD(ah, offset_array[i], | ||
265 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, | ||
266 | iCoff); | ||
267 | REG_RMW_FIELD(ah, offset_array[i], | ||
268 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, | ||
269 | qCoff); | ||
270 | ath_print(common, ATH_DBG_CALIBRATE, | ||
271 | "Register offset (0x%04x) QI COFF " | ||
272 | "(bitfields 0x%08x) after update = 0x%x\n", | ||
273 | offset_array[i], | ||
274 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF, | ||
275 | REG_READ(ah, offset_array[i])); | ||
276 | ath_print(common, ATH_DBG_CALIBRATE, | ||
277 | "Register offset (0x%04x) QQ COFF " | ||
278 | "(bitfields 0x%08x) after update = 0x%x\n", | ||
279 | offset_array[i], | ||
280 | AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF, | ||
281 | REG_READ(ah, offset_array[i])); | ||
282 | |||
283 | ath_print(common, ATH_DBG_CALIBRATE, | ||
284 | "IQ Cal and Correction done for Chain %d\n", | ||
285 | i); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0, | ||
290 | AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE); | ||
291 | ath_print(common, ATH_DBG_CALIBRATE, | ||
292 | "IQ Cal and Correction (offset 0x%04x) enabled " | ||
293 | "(bit position 0x%08x). New Value 0x%08x\n", | ||
294 | (unsigned) (AR_PHY_RX_IQCAL_CORR_B0), | ||
295 | AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE, | ||
296 | REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0)); | ||
297 | } | ||
298 | |||
299 | static const struct ath9k_percal_data iq_cal_single_sample = { | ||
300 | IQ_MISMATCH_CAL, | ||
301 | MIN_CAL_SAMPLES, | ||
302 | PER_MAX_LOG_COUNT, | ||
303 | ar9003_hw_iqcal_collect, | ||
304 | ar9003_hw_iqcalibrate | ||
305 | }; | ||
306 | |||
307 | static void ar9003_hw_init_cal_settings(struct ath_hw *ah) | ||
308 | { | ||
309 | ah->iq_caldata.calData = &iq_cal_single_sample; | ||
310 | ah->supp_cals = IQ_MISMATCH_CAL; | ||
311 | } | ||
312 | |||
313 | static bool ar9003_hw_iscal_supported(struct ath_hw *ah, | ||
314 | enum ath9k_cal_types calType) | ||
315 | { | ||
316 | switch (calType & ah->supp_cals) { | ||
317 | case IQ_MISMATCH_CAL: | ||
318 | /* | ||
319 | * XXX: Run IQ Mismatch for non-CCK only | ||
320 | * Note that CHANNEL_B is never set though. | ||
321 | */ | ||
322 | return true; | ||
323 | case ADC_GAIN_CAL: | ||
324 | case ADC_DC_CAL: | ||
325 | return false; | ||
326 | case TEMP_COMP_CAL: | ||
327 | return true; | ||
328 | } | ||
329 | |||
330 | return false; | ||
331 | } | ||
332 | |||
333 | /* | ||
334 | * solve 4x4 linear equation used in loopback iq cal. | ||
335 | */ | ||
336 | static bool ar9003_hw_solve_iq_cal(struct ath_hw *ah, | ||
337 | s32 sin_2phi_1, | ||
338 | s32 cos_2phi_1, | ||
339 | s32 sin_2phi_2, | ||
340 | s32 cos_2phi_2, | ||
341 | s32 mag_a0_d0, | ||
342 | s32 phs_a0_d0, | ||
343 | s32 mag_a1_d0, | ||
344 | s32 phs_a1_d0, | ||
345 | s32 solved_eq[]) | ||
346 | { | ||
347 | s32 f1 = cos_2phi_1 - cos_2phi_2, | ||
348 | f3 = sin_2phi_1 - sin_2phi_2, | ||
349 | f2; | ||
350 | s32 mag_tx, phs_tx, mag_rx, phs_rx; | ||
351 | const s32 result_shift = 1 << 15; | ||
352 | struct ath_common *common = ath9k_hw_common(ah); | ||
353 | |||
354 | f2 = (f1 * f1 + f3 * f3) / result_shift; | ||
355 | |||
356 | if (!f2) { | ||
357 | ath_print(common, ATH_DBG_CALIBRATE, "Divide by 0\n"); | ||
358 | return false; | ||
359 | } | ||
360 | |||
361 | /* mag mismatch, tx */ | ||
362 | mag_tx = f1 * (mag_a0_d0 - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0); | ||
363 | /* phs mismatch, tx */ | ||
364 | phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0); | ||
365 | |||
366 | mag_tx = (mag_tx / f2); | ||
367 | phs_tx = (phs_tx / f2); | ||
368 | |||
369 | /* mag mismatch, rx */ | ||
370 | mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) / | ||
371 | result_shift; | ||
372 | /* phs mismatch, rx */ | ||
373 | phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) / | ||
374 | result_shift; | ||
375 | |||
376 | solved_eq[0] = mag_tx; | ||
377 | solved_eq[1] = phs_tx; | ||
378 | solved_eq[2] = mag_rx; | ||
379 | solved_eq[3] = phs_rx; | ||
380 | |||
381 | return true; | ||
382 | } | ||
383 | |||
384 | static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah, s32 in_re, s32 in_im) | ||
385 | { | ||
386 | s32 abs_i = abs(in_re), | ||
387 | abs_q = abs(in_im), | ||
388 | max_abs, min_abs; | ||
389 | |||
390 | if (abs_i > abs_q) { | ||
391 | max_abs = abs_i; | ||
392 | min_abs = abs_q; | ||
393 | } else { | ||
394 | max_abs = abs_q; | ||
395 | min_abs = abs_i; | ||
396 | } | ||
397 | |||
398 | return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4); | ||
399 | } | ||
400 | |||
401 | #define DELPT 32 | ||
402 | |||
403 | static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah, | ||
404 | s32 chain_idx, | ||
405 | const s32 iq_res[], | ||
406 | s32 iqc_coeff[]) | ||
407 | { | ||
408 | s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0, | ||
409 | i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1, | ||
410 | i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0, | ||
411 | i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1; | ||
412 | s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1, | ||
413 | phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1, | ||
414 | sin_2phi_1, cos_2phi_1, | ||
415 | sin_2phi_2, cos_2phi_2; | ||
416 | s32 mag_tx, phs_tx, mag_rx, phs_rx; | ||
417 | s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx, | ||
418 | q_q_coff, q_i_coff; | ||
419 | const s32 res_scale = 1 << 15; | ||
420 | const s32 delpt_shift = 1 << 8; | ||
421 | s32 mag1, mag2; | ||
422 | struct ath_common *common = ath9k_hw_common(ah); | ||
423 | |||
424 | i2_m_q2_a0_d0 = iq_res[0] & 0xfff; | ||
425 | i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff; | ||
426 | iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8); | ||
427 | |||
428 | if (i2_m_q2_a0_d0 > 0x800) | ||
429 | i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1); | ||
430 | |||
431 | if (i2_p_q2_a0_d0 > 0x800) | ||
432 | i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1); | ||
433 | |||
434 | if (iq_corr_a0_d0 > 0x800) | ||
435 | iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1); | ||
436 | |||
437 | i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff; | ||
438 | i2_p_q2_a0_d1 = (iq_res[2] & 0xfff); | ||
439 | iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff; | ||
440 | |||
441 | if (i2_m_q2_a0_d1 > 0x800) | ||
442 | i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1); | ||
443 | |||
444 | if (i2_p_q2_a0_d1 > 0x800) | ||
445 | i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1); | ||
446 | |||
447 | if (iq_corr_a0_d1 > 0x800) | ||
448 | iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1); | ||
449 | |||
450 | i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8); | ||
451 | i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff; | ||
452 | iq_corr_a1_d0 = iq_res[4] & 0xfff; | ||
453 | |||
454 | if (i2_m_q2_a1_d0 > 0x800) | ||
455 | i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1); | ||
456 | |||
457 | if (i2_p_q2_a1_d0 > 0x800) | ||
458 | i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1); | ||
459 | |||
460 | if (iq_corr_a1_d0 > 0x800) | ||
461 | iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1); | ||
462 | |||
463 | i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff; | ||
464 | i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8); | ||
465 | iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff; | ||
466 | |||
467 | if (i2_m_q2_a1_d1 > 0x800) | ||
468 | i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1); | ||
469 | |||
470 | if (i2_p_q2_a1_d1 > 0x800) | ||
471 | i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1); | ||
472 | |||
473 | if (iq_corr_a1_d1 > 0x800) | ||
474 | iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1); | ||
475 | |||
476 | if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) || | ||
477 | (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) { | ||
478 | ath_print(common, ATH_DBG_CALIBRATE, | ||
479 | "Divide by 0:\na0_d0=%d\n" | ||
480 | "a0_d1=%d\na2_d0=%d\na1_d1=%d\n", | ||
481 | i2_p_q2_a0_d0, i2_p_q2_a0_d1, | ||
482 | i2_p_q2_a1_d0, i2_p_q2_a1_d1); | ||
483 | return false; | ||
484 | } | ||
485 | |||
486 | mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0; | ||
487 | phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0; | ||
488 | |||
489 | mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1; | ||
490 | phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1; | ||
491 | |||
492 | mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0; | ||
493 | phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0; | ||
494 | |||
495 | mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1; | ||
496 | phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1; | ||
497 | |||
498 | /* w/o analog phase shift */ | ||
499 | sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT); | ||
500 | /* w/o analog phase shift */ | ||
501 | cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT); | ||
502 | /* w/ analog phase shift */ | ||
503 | sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT); | ||
504 | /* w/ analog phase shift */ | ||
505 | cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT); | ||
506 | |||
507 | /* | ||
508 | * force sin^2 + cos^2 = 1; | ||
509 | * find magnitude by approximation | ||
510 | */ | ||
511 | mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1); | ||
512 | mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2); | ||
513 | |||
514 | if ((mag1 == 0) || (mag2 == 0)) { | ||
515 | ath_print(common, ATH_DBG_CALIBRATE, | ||
516 | "Divide by 0: mag1=%d, mag2=%d\n", | ||
517 | mag1, mag2); | ||
518 | return false; | ||
519 | } | ||
520 | |||
521 | /* normalization sin and cos by mag */ | ||
522 | sin_2phi_1 = (sin_2phi_1 * res_scale / mag1); | ||
523 | cos_2phi_1 = (cos_2phi_1 * res_scale / mag1); | ||
524 | sin_2phi_2 = (sin_2phi_2 * res_scale / mag2); | ||
525 | cos_2phi_2 = (cos_2phi_2 * res_scale / mag2); | ||
526 | |||
527 | /* calculate IQ mismatch */ | ||
528 | if (!ar9003_hw_solve_iq_cal(ah, | ||
529 | sin_2phi_1, cos_2phi_1, | ||
530 | sin_2phi_2, cos_2phi_2, | ||
531 | mag_a0_d0, phs_a0_d0, | ||
532 | mag_a1_d0, | ||
533 | phs_a1_d0, solved_eq)) { | ||
534 | ath_print(common, ATH_DBG_CALIBRATE, | ||
535 | "Call to ar9003_hw_solve_iq_cal() failed.\n"); | ||
536 | return false; | ||
537 | } | ||
538 | |||
539 | mag_tx = solved_eq[0]; | ||
540 | phs_tx = solved_eq[1]; | ||
541 | mag_rx = solved_eq[2]; | ||
542 | phs_rx = solved_eq[3]; | ||
543 | |||
544 | ath_print(common, ATH_DBG_CALIBRATE, | ||
545 | "chain %d: mag mismatch=%d phase mismatch=%d\n", | ||
546 | chain_idx, mag_tx/res_scale, phs_tx/res_scale); | ||
547 | |||
548 | if (res_scale == mag_tx) { | ||
549 | ath_print(common, ATH_DBG_CALIBRATE, | ||
550 | "Divide by 0: mag_tx=%d, res_scale=%d\n", | ||
551 | mag_tx, res_scale); | ||
552 | return false; | ||
553 | } | ||
554 | |||
555 | /* calculate and quantize Tx IQ correction factor */ | ||
556 | mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx); | ||
557 | phs_corr_tx = -phs_tx; | ||
558 | |||
559 | q_q_coff = (mag_corr_tx * 128 / res_scale); | ||
560 | q_i_coff = (phs_corr_tx * 256 / res_scale); | ||
561 | |||
562 | ath_print(common, ATH_DBG_CALIBRATE, | ||
563 | "tx chain %d: mag corr=%d phase corr=%d\n", | ||
564 | chain_idx, q_q_coff, q_i_coff); | ||
565 | |||
566 | if (q_i_coff < -63) | ||
567 | q_i_coff = -63; | ||
568 | if (q_i_coff > 63) | ||
569 | q_i_coff = 63; | ||
570 | if (q_q_coff < -63) | ||
571 | q_q_coff = -63; | ||
572 | if (q_q_coff > 63) | ||
573 | q_q_coff = 63; | ||
574 | |||
575 | iqc_coeff[0] = (q_q_coff * 128) + q_i_coff; | ||
576 | |||
577 | ath_print(common, ATH_DBG_CALIBRATE, | ||
578 | "tx chain %d: iq corr coeff=%x\n", | ||
579 | chain_idx, iqc_coeff[0]); | ||
580 | |||
581 | if (-mag_rx == res_scale) { | ||
582 | ath_print(common, ATH_DBG_CALIBRATE, | ||
583 | "Divide by 0: mag_rx=%d, res_scale=%d\n", | ||
584 | mag_rx, res_scale); | ||
585 | return false; | ||
586 | } | ||
587 | |||
588 | /* calculate and quantize Rx IQ correction factors */ | ||
589 | mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx); | ||
590 | phs_corr_rx = -phs_rx; | ||
591 | |||
592 | q_q_coff = (mag_corr_rx * 128 / res_scale); | ||
593 | q_i_coff = (phs_corr_rx * 256 / res_scale); | ||
594 | |||
595 | ath_print(common, ATH_DBG_CALIBRATE, | ||
596 | "rx chain %d: mag corr=%d phase corr=%d\n", | ||
597 | chain_idx, q_q_coff, q_i_coff); | ||
598 | |||
599 | if (q_i_coff < -63) | ||
600 | q_i_coff = -63; | ||
601 | if (q_i_coff > 63) | ||
602 | q_i_coff = 63; | ||
603 | if (q_q_coff < -63) | ||
604 | q_q_coff = -63; | ||
605 | if (q_q_coff > 63) | ||
606 | q_q_coff = 63; | ||
607 | |||
608 | iqc_coeff[1] = (q_q_coff * 128) + q_i_coff; | ||
609 | |||
610 | ath_print(common, ATH_DBG_CALIBRATE, | ||
611 | "rx chain %d: iq corr coeff=%x\n", | ||
612 | chain_idx, iqc_coeff[1]); | ||
613 | |||
614 | return true; | ||
615 | } | ||
616 | |||
617 | static void ar9003_hw_tx_iq_cal(struct ath_hw *ah) | ||
618 | { | ||
619 | struct ath_common *common = ath9k_hw_common(ah); | ||
620 | const u32 txiqcal_status[AR9300_MAX_CHAINS] = { | ||
621 | AR_PHY_TX_IQCAL_STATUS_B0, | ||
622 | AR_PHY_TX_IQCAL_STATUS_B1, | ||
623 | AR_PHY_TX_IQCAL_STATUS_B2, | ||
624 | }; | ||
625 | const u32 tx_corr_coeff[AR9300_MAX_CHAINS] = { | ||
626 | AR_PHY_TX_IQCAL_CORR_COEFF_01_B0, | ||
627 | AR_PHY_TX_IQCAL_CORR_COEFF_01_B1, | ||
628 | AR_PHY_TX_IQCAL_CORR_COEFF_01_B2, | ||
629 | }; | ||
630 | const u32 rx_corr[AR9300_MAX_CHAINS] = { | ||
631 | AR_PHY_RX_IQCAL_CORR_B0, | ||
632 | AR_PHY_RX_IQCAL_CORR_B1, | ||
633 | AR_PHY_RX_IQCAL_CORR_B2, | ||
634 | }; | ||
635 | const u_int32_t chan_info_tab[] = { | ||
636 | AR_PHY_CHAN_INFO_TAB_0, | ||
637 | AR_PHY_CHAN_INFO_TAB_1, | ||
638 | AR_PHY_CHAN_INFO_TAB_2, | ||
639 | }; | ||
640 | s32 iq_res[6]; | ||
641 | s32 iqc_coeff[2]; | ||
642 | s32 i, j; | ||
643 | u32 num_chains = 0; | ||
644 | |||
645 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
646 | if (ah->txchainmask & (1 << i)) | ||
647 | num_chains++; | ||
648 | } | ||
649 | |||
650 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, | ||
651 | AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, | ||
652 | DELPT); | ||
653 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START, | ||
654 | AR_PHY_TX_IQCAL_START_DO_CAL, | ||
655 | AR_PHY_TX_IQCAL_START_DO_CAL); | ||
656 | |||
657 | if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START, | ||
658 | AR_PHY_TX_IQCAL_START_DO_CAL, | ||
659 | 0, AH_WAIT_TIMEOUT)) { | ||
660 | ath_print(common, ATH_DBG_CALIBRATE, | ||
661 | "Tx IQ Cal not complete.\n"); | ||
662 | goto TX_IQ_CAL_FAILED; | ||
663 | } | ||
664 | |||
665 | for (i = 0; i < num_chains; i++) { | ||
666 | ath_print(common, ATH_DBG_CALIBRATE, | ||
667 | "Doing Tx IQ Cal for chain %d.\n", i); | ||
668 | |||
669 | if (REG_READ(ah, txiqcal_status[i]) & | ||
670 | AR_PHY_TX_IQCAL_STATUS_FAILED) { | ||
671 | ath_print(common, ATH_DBG_CALIBRATE, | ||
672 | "Tx IQ Cal failed for chain %d.\n", i); | ||
673 | goto TX_IQ_CAL_FAILED; | ||
674 | } | ||
675 | |||
676 | for (j = 0; j < 3; j++) { | ||
677 | u_int8_t idx = 2 * j, | ||
678 | offset = 4 * j; | ||
679 | |||
680 | REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||
681 | AR_PHY_CHAN_INFO_TAB_S2_READ, 0); | ||
682 | |||
683 | /* 32 bits */ | ||
684 | iq_res[idx] = REG_READ(ah, chan_info_tab[i] + offset); | ||
685 | |||
686 | REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY, | ||
687 | AR_PHY_CHAN_INFO_TAB_S2_READ, 1); | ||
688 | |||
689 | /* 16 bits */ | ||
690 | iq_res[idx+1] = 0xffff & REG_READ(ah, | ||
691 | chan_info_tab[i] + | ||
692 | offset); | ||
693 | |||
694 | ath_print(common, ATH_DBG_CALIBRATE, | ||
695 | "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n", | ||
696 | idx, iq_res[idx], idx+1, iq_res[idx+1]); | ||
697 | } | ||
698 | |||
699 | if (!ar9003_hw_calc_iq_corr(ah, i, iq_res, iqc_coeff)) { | ||
700 | ath_print(common, ATH_DBG_CALIBRATE, | ||
701 | "Failed in calculation of IQ correction.\n"); | ||
702 | goto TX_IQ_CAL_FAILED; | ||
703 | } | ||
704 | |||
705 | ath_print(common, ATH_DBG_CALIBRATE, | ||
706 | "IQ_COEFF[0] = 0x%x IQ_COEFF[1] = 0x%x\n", | ||
707 | iqc_coeff[0], iqc_coeff[1]); | ||
708 | |||
709 | REG_RMW_FIELD(ah, tx_corr_coeff[i], | ||
710 | AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE, | ||
711 | iqc_coeff[0]); | ||
712 | REG_RMW_FIELD(ah, rx_corr[i], | ||
713 | AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF, | ||
714 | iqc_coeff[1] >> 7); | ||
715 | REG_RMW_FIELD(ah, rx_corr[i], | ||
716 | AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF, | ||
717 | iqc_coeff[1]); | ||
718 | } | ||
719 | |||
720 | REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3, | ||
721 | AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1); | ||
722 | REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0, | ||
723 | AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1); | ||
724 | |||
725 | return; | ||
726 | |||
727 | TX_IQ_CAL_FAILED: | ||
728 | ath_print(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n"); | ||
729 | } | ||
730 | |||
731 | static bool ar9003_hw_init_cal(struct ath_hw *ah, | ||
732 | struct ath9k_channel *chan) | ||
733 | { | ||
734 | struct ath_common *common = ath9k_hw_common(ah); | ||
735 | |||
736 | /* | ||
737 | * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain mode before | ||
738 | * running AGC/TxIQ cals | ||
739 | */ | ||
740 | ar9003_hw_set_chain_masks(ah, 0x7, 0x7); | ||
741 | |||
742 | /* Calibrate the AGC */ | ||
743 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
744 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
745 | AR_PHY_AGC_CONTROL_CAL); | ||
746 | |||
747 | /* Poll for offset calibration complete */ | ||
748 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | ||
749 | 0, AH_WAIT_TIMEOUT)) { | ||
750 | ath_print(common, ATH_DBG_CALIBRATE, | ||
751 | "offset calibration failed to " | ||
752 | "complete in 1ms; noisy environment?\n"); | ||
753 | return false; | ||
754 | } | ||
755 | |||
756 | /* Do Tx IQ Calibration */ | ||
757 | if (ah->config.tx_iq_calibration) | ||
758 | ar9003_hw_tx_iq_cal(ah); | ||
759 | |||
760 | /* Revert chainmasks to their original values before NF cal */ | ||
761 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | ||
762 | |||
763 | /* Initialize list pointers */ | ||
764 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | ||
765 | |||
766 | if (ar9003_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { | ||
767 | INIT_CAL(&ah->iq_caldata); | ||
768 | INSERT_CAL(ah, &ah->iq_caldata); | ||
769 | ath_print(common, ATH_DBG_CALIBRATE, | ||
770 | "enabling IQ Calibration.\n"); | ||
771 | } | ||
772 | |||
773 | if (ar9003_hw_iscal_supported(ah, TEMP_COMP_CAL)) { | ||
774 | INIT_CAL(&ah->tempCompCalData); | ||
775 | INSERT_CAL(ah, &ah->tempCompCalData); | ||
776 | ath_print(common, ATH_DBG_CALIBRATE, | ||
777 | "enabling Temperature Compensation Calibration.\n"); | ||
778 | } | ||
779 | |||
780 | /* Initialize current pointer to first element in list */ | ||
781 | ah->cal_list_curr = ah->cal_list; | ||
782 | |||
783 | if (ah->cal_list_curr) | ||
784 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | ||
785 | |||
786 | chan->CalValid = 0; | ||
787 | |||
788 | return true; | ||
789 | } | ||
790 | |||
791 | void ar9003_hw_attach_calib_ops(struct ath_hw *ah) | ||
792 | { | ||
793 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
794 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
795 | |||
796 | priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; | ||
797 | priv_ops->init_cal = ar9003_hw_init_cal; | ||
798 | priv_ops->setup_calibration = ar9003_hw_setup_calibration; | ||
799 | priv_ops->iscal_supported = ar9003_hw_iscal_supported; | ||
800 | |||
801 | ops->calibrate = ar9003_hw_calibrate; | ||
802 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c new file mode 100644 index 000000000000..23eb60ea5455 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -0,0 +1,1838 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | #include "ar9003_phy.h" | ||
19 | #include "ar9003_eeprom.h" | ||
20 | |||
21 | #define COMP_HDR_LEN 4 | ||
22 | #define COMP_CKSUM_LEN 2 | ||
23 | |||
24 | #define AR_CH0_TOP (0x00016288) | ||
25 | #define AR_CH0_TOP_XPABIASLVL (0x3) | ||
26 | #define AR_CH0_TOP_XPABIASLVL_S (8) | ||
27 | |||
28 | #define AR_CH0_THERM (0x00016290) | ||
29 | #define AR_CH0_THERM_SPARE (0x3f) | ||
30 | #define AR_CH0_THERM_SPARE_S (0) | ||
31 | |||
32 | #define AR_SWITCH_TABLE_COM_ALL (0xffff) | ||
33 | #define AR_SWITCH_TABLE_COM_ALL_S (0) | ||
34 | |||
35 | #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) | ||
36 | #define AR_SWITCH_TABLE_COM2_ALL_S (0) | ||
37 | |||
38 | #define AR_SWITCH_TABLE_ALL (0xfff) | ||
39 | #define AR_SWITCH_TABLE_ALL_S (0) | ||
40 | |||
41 | #define LE16(x) __constant_cpu_to_le16(x) | ||
42 | #define LE32(x) __constant_cpu_to_le32(x) | ||
43 | |||
44 | static const struct ar9300_eeprom ar9300_default = { | ||
45 | .eepromVersion = 2, | ||
46 | .templateVersion = 2, | ||
47 | .macAddr = {1, 2, 3, 4, 5, 6}, | ||
48 | .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
49 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | ||
50 | .baseEepHeader = { | ||
51 | .regDmn = { LE16(0), LE16(0x1f) }, | ||
52 | .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ | ||
53 | .opCapFlags = { | ||
54 | .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, | ||
55 | .eepMisc = 0, | ||
56 | }, | ||
57 | .rfSilent = 0, | ||
58 | .blueToothOptions = 0, | ||
59 | .deviceCap = 0, | ||
60 | .deviceType = 5, /* takes lower byte in eeprom location */ | ||
61 | .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, | ||
62 | .params_for_tuning_caps = {0, 0}, | ||
63 | .featureEnable = 0x0c, | ||
64 | /* | ||
65 | * bit0 - enable tx temp comp - disabled | ||
66 | * bit1 - enable tx volt comp - disabled | ||
67 | * bit2 - enable fastClock - enabled | ||
68 | * bit3 - enable doubling - enabled | ||
69 | * bit4 - enable internal regulator - disabled | ||
70 | */ | ||
71 | .miscConfiguration = 0, /* bit0 - turn down drivestrength */ | ||
72 | .eepromWriteEnableGpio = 3, | ||
73 | .wlanDisableGpio = 0, | ||
74 | .wlanLedGpio = 8, | ||
75 | .rxBandSelectGpio = 0xff, | ||
76 | .txrxgain = 0, | ||
77 | .swreg = 0, | ||
78 | }, | ||
79 | .modalHeader2G = { | ||
80 | /* ar9300_modal_eep_header 2g */ | ||
81 | /* 4 idle,t1,t2,b(4 bits per setting) */ | ||
82 | .antCtrlCommon = LE32(0x110), | ||
83 | /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ | ||
84 | .antCtrlCommon2 = LE32(0x22222), | ||
85 | |||
86 | /* | ||
87 | * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, | ||
88 | * rx1, rx12, b (2 bits each) | ||
89 | */ | ||
90 | .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) }, | ||
91 | |||
92 | /* | ||
93 | * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db | ||
94 | * for ar9280 (0xa20c/b20c 5:0) | ||
95 | */ | ||
96 | .xatten1DB = {0, 0, 0}, | ||
97 | |||
98 | /* | ||
99 | * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin | ||
100 | * for ar9280 (0xa20c/b20c 16:12 | ||
101 | */ | ||
102 | .xatten1Margin = {0, 0, 0}, | ||
103 | .tempSlope = 36, | ||
104 | .voltSlope = 0, | ||
105 | |||
106 | /* | ||
107 | * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur | ||
108 | * channels in usual fbin coding format | ||
109 | */ | ||
110 | .spurChans = {0, 0, 0, 0, 0}, | ||
111 | |||
112 | /* | ||
113 | * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check | ||
114 | * if the register is per chain | ||
115 | */ | ||
116 | .noiseFloorThreshCh = {-1, 0, 0}, | ||
117 | .ob = {1, 1, 1},/* 3 chain */ | ||
118 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | ||
119 | .db_stage3 = {0, 0, 0}, | ||
120 | .db_stage4 = {0, 0, 0}, | ||
121 | .xpaBiasLvl = 0, | ||
122 | .txFrameToDataStart = 0x0e, | ||
123 | .txFrameToPaOn = 0x0e, | ||
124 | .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ | ||
125 | .antennaGain = 0, | ||
126 | .switchSettling = 0x2c, | ||
127 | .adcDesiredSize = -30, | ||
128 | .txEndToXpaOff = 0, | ||
129 | .txEndToRxOn = 0x2, | ||
130 | .txFrameToXpaOn = 0xe, | ||
131 | .thresh62 = 28, | ||
132 | .futureModal = { /* [32] */ | ||
133 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
134 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
135 | }, | ||
136 | }, | ||
137 | .calFreqPier2G = { | ||
138 | FREQ2FBIN(2412, 1), | ||
139 | FREQ2FBIN(2437, 1), | ||
140 | FREQ2FBIN(2472, 1), | ||
141 | }, | ||
142 | /* ar9300_cal_data_per_freq_op_loop 2g */ | ||
143 | .calPierData2G = { | ||
144 | { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, | ||
145 | { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, | ||
146 | { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, | ||
147 | }, | ||
148 | .calTarget_freqbin_Cck = { | ||
149 | FREQ2FBIN(2412, 1), | ||
150 | FREQ2FBIN(2484, 1), | ||
151 | }, | ||
152 | .calTarget_freqbin_2G = { | ||
153 | FREQ2FBIN(2412, 1), | ||
154 | FREQ2FBIN(2437, 1), | ||
155 | FREQ2FBIN(2472, 1) | ||
156 | }, | ||
157 | .calTarget_freqbin_2GHT20 = { | ||
158 | FREQ2FBIN(2412, 1), | ||
159 | FREQ2FBIN(2437, 1), | ||
160 | FREQ2FBIN(2472, 1) | ||
161 | }, | ||
162 | .calTarget_freqbin_2GHT40 = { | ||
163 | FREQ2FBIN(2412, 1), | ||
164 | FREQ2FBIN(2437, 1), | ||
165 | FREQ2FBIN(2472, 1) | ||
166 | }, | ||
167 | .calTargetPowerCck = { | ||
168 | /* 1L-5L,5S,11L,11S */ | ||
169 | { {36, 36, 36, 36} }, | ||
170 | { {36, 36, 36, 36} }, | ||
171 | }, | ||
172 | .calTargetPower2G = { | ||
173 | /* 6-24,36,48,54 */ | ||
174 | { {32, 32, 28, 24} }, | ||
175 | { {32, 32, 28, 24} }, | ||
176 | { {32, 32, 28, 24} }, | ||
177 | }, | ||
178 | .calTargetPower2GHT20 = { | ||
179 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
180 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
181 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
182 | }, | ||
183 | .calTargetPower2GHT40 = { | ||
184 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
185 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
186 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
187 | }, | ||
188 | .ctlIndex_2G = { | ||
189 | 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, | ||
190 | 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, | ||
191 | }, | ||
192 | .ctl_freqbin_2G = { | ||
193 | { | ||
194 | FREQ2FBIN(2412, 1), | ||
195 | FREQ2FBIN(2417, 1), | ||
196 | FREQ2FBIN(2457, 1), | ||
197 | FREQ2FBIN(2462, 1) | ||
198 | }, | ||
199 | { | ||
200 | FREQ2FBIN(2412, 1), | ||
201 | FREQ2FBIN(2417, 1), | ||
202 | FREQ2FBIN(2462, 1), | ||
203 | 0xFF, | ||
204 | }, | ||
205 | |||
206 | { | ||
207 | FREQ2FBIN(2412, 1), | ||
208 | FREQ2FBIN(2417, 1), | ||
209 | FREQ2FBIN(2462, 1), | ||
210 | 0xFF, | ||
211 | }, | ||
212 | { | ||
213 | FREQ2FBIN(2422, 1), | ||
214 | FREQ2FBIN(2427, 1), | ||
215 | FREQ2FBIN(2447, 1), | ||
216 | FREQ2FBIN(2452, 1) | ||
217 | }, | ||
218 | |||
219 | { | ||
220 | /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
221 | /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
222 | /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
223 | /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), | ||
224 | }, | ||
225 | |||
226 | { | ||
227 | /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
228 | /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
229 | /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
230 | 0, | ||
231 | }, | ||
232 | |||
233 | { | ||
234 | /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
235 | /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
236 | FREQ2FBIN(2472, 1), | ||
237 | 0, | ||
238 | }, | ||
239 | |||
240 | { | ||
241 | /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), | ||
242 | /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), | ||
243 | /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), | ||
244 | /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), | ||
245 | }, | ||
246 | |||
247 | { | ||
248 | /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
249 | /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
250 | /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
251 | }, | ||
252 | |||
253 | { | ||
254 | /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
255 | /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
256 | /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
257 | 0 | ||
258 | }, | ||
259 | |||
260 | { | ||
261 | /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
262 | /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
263 | /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
264 | 0 | ||
265 | }, | ||
266 | |||
267 | { | ||
268 | /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), | ||
269 | /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), | ||
270 | /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), | ||
271 | /* Data[11].ctlEdges[3].bChannel */ | ||
272 | FREQ2FBIN(2462, 1), | ||
273 | } | ||
274 | }, | ||
275 | .ctlPowerData_2G = { | ||
276 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
277 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
278 | { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, | ||
279 | |||
280 | { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, | ||
281 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
282 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
283 | |||
284 | { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, | ||
285 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
286 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
287 | |||
288 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
289 | { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, | ||
290 | }, | ||
291 | .modalHeader5G = { | ||
292 | /* 4 idle,t1,t2,b (4 bits per setting) */ | ||
293 | .antCtrlCommon = LE32(0x110), | ||
294 | /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ | ||
295 | .antCtrlCommon2 = LE32(0x22222), | ||
296 | /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ | ||
297 | .antCtrlChain = { | ||
298 | LE16(0x000), LE16(0x000), LE16(0x000), | ||
299 | }, | ||
300 | /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ | ||
301 | .xatten1DB = {0, 0, 0}, | ||
302 | |||
303 | /* | ||
304 | * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin | ||
305 | * for merlin (0xa20c/b20c 16:12 | ||
306 | */ | ||
307 | .xatten1Margin = {0, 0, 0}, | ||
308 | .tempSlope = 68, | ||
309 | .voltSlope = 0, | ||
310 | /* spurChans spur channels in usual fbin coding format */ | ||
311 | .spurChans = {0, 0, 0, 0, 0}, | ||
312 | /* noiseFloorThreshCh Check if the register is per chain */ | ||
313 | .noiseFloorThreshCh = {-1, 0, 0}, | ||
314 | .ob = {3, 3, 3}, /* 3 chain */ | ||
315 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | ||
316 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
317 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
318 | .xpaBiasLvl = 0, | ||
319 | .txFrameToDataStart = 0x0e, | ||
320 | .txFrameToPaOn = 0x0e, | ||
321 | .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ | ||
322 | .antennaGain = 0, | ||
323 | .switchSettling = 0x2d, | ||
324 | .adcDesiredSize = -30, | ||
325 | .txEndToXpaOff = 0, | ||
326 | .txEndToRxOn = 0x2, | ||
327 | .txFrameToXpaOn = 0xe, | ||
328 | .thresh62 = 28, | ||
329 | .futureModal = { | ||
330 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
331 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
332 | }, | ||
333 | }, | ||
334 | .calFreqPier5G = { | ||
335 | FREQ2FBIN(5180, 0), | ||
336 | FREQ2FBIN(5220, 0), | ||
337 | FREQ2FBIN(5320, 0), | ||
338 | FREQ2FBIN(5400, 0), | ||
339 | FREQ2FBIN(5500, 0), | ||
340 | FREQ2FBIN(5600, 0), | ||
341 | FREQ2FBIN(5725, 0), | ||
342 | FREQ2FBIN(5825, 0) | ||
343 | }, | ||
344 | .calPierData5G = { | ||
345 | { | ||
346 | {0, 0, 0, 0, 0}, | ||
347 | {0, 0, 0, 0, 0}, | ||
348 | {0, 0, 0, 0, 0}, | ||
349 | {0, 0, 0, 0, 0}, | ||
350 | {0, 0, 0, 0, 0}, | ||
351 | {0, 0, 0, 0, 0}, | ||
352 | {0, 0, 0, 0, 0}, | ||
353 | {0, 0, 0, 0, 0}, | ||
354 | }, | ||
355 | { | ||
356 | {0, 0, 0, 0, 0}, | ||
357 | {0, 0, 0, 0, 0}, | ||
358 | {0, 0, 0, 0, 0}, | ||
359 | {0, 0, 0, 0, 0}, | ||
360 | {0, 0, 0, 0, 0}, | ||
361 | {0, 0, 0, 0, 0}, | ||
362 | {0, 0, 0, 0, 0}, | ||
363 | {0, 0, 0, 0, 0}, | ||
364 | }, | ||
365 | { | ||
366 | {0, 0, 0, 0, 0}, | ||
367 | {0, 0, 0, 0, 0}, | ||
368 | {0, 0, 0, 0, 0}, | ||
369 | {0, 0, 0, 0, 0}, | ||
370 | {0, 0, 0, 0, 0}, | ||
371 | {0, 0, 0, 0, 0}, | ||
372 | {0, 0, 0, 0, 0}, | ||
373 | {0, 0, 0, 0, 0}, | ||
374 | }, | ||
375 | |||
376 | }, | ||
377 | .calTarget_freqbin_5G = { | ||
378 | FREQ2FBIN(5180, 0), | ||
379 | FREQ2FBIN(5220, 0), | ||
380 | FREQ2FBIN(5320, 0), | ||
381 | FREQ2FBIN(5400, 0), | ||
382 | FREQ2FBIN(5500, 0), | ||
383 | FREQ2FBIN(5600, 0), | ||
384 | FREQ2FBIN(5725, 0), | ||
385 | FREQ2FBIN(5825, 0) | ||
386 | }, | ||
387 | .calTarget_freqbin_5GHT20 = { | ||
388 | FREQ2FBIN(5180, 0), | ||
389 | FREQ2FBIN(5240, 0), | ||
390 | FREQ2FBIN(5320, 0), | ||
391 | FREQ2FBIN(5500, 0), | ||
392 | FREQ2FBIN(5700, 0), | ||
393 | FREQ2FBIN(5745, 0), | ||
394 | FREQ2FBIN(5725, 0), | ||
395 | FREQ2FBIN(5825, 0) | ||
396 | }, | ||
397 | .calTarget_freqbin_5GHT40 = { | ||
398 | FREQ2FBIN(5180, 0), | ||
399 | FREQ2FBIN(5240, 0), | ||
400 | FREQ2FBIN(5320, 0), | ||
401 | FREQ2FBIN(5500, 0), | ||
402 | FREQ2FBIN(5700, 0), | ||
403 | FREQ2FBIN(5745, 0), | ||
404 | FREQ2FBIN(5725, 0), | ||
405 | FREQ2FBIN(5825, 0) | ||
406 | }, | ||
407 | .calTargetPower5G = { | ||
408 | /* 6-24,36,48,54 */ | ||
409 | { {20, 20, 20, 10} }, | ||
410 | { {20, 20, 20, 10} }, | ||
411 | { {20, 20, 20, 10} }, | ||
412 | { {20, 20, 20, 10} }, | ||
413 | { {20, 20, 20, 10} }, | ||
414 | { {20, 20, 20, 10} }, | ||
415 | { {20, 20, 20, 10} }, | ||
416 | { {20, 20, 20, 10} }, | ||
417 | }, | ||
418 | .calTargetPower5GHT20 = { | ||
419 | /* | ||
420 | * 0_8_16,1-3_9-11_17-19, | ||
421 | * 4,5,6,7,12,13,14,15,20,21,22,23 | ||
422 | */ | ||
423 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
424 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
425 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
426 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
427 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
428 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
429 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
430 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
431 | }, | ||
432 | .calTargetPower5GHT40 = { | ||
433 | /* | ||
434 | * 0_8_16,1-3_9-11_17-19, | ||
435 | * 4,5,6,7,12,13,14,15,20,21,22,23 | ||
436 | */ | ||
437 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
438 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
439 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
440 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
441 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
442 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
443 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
444 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
445 | }, | ||
446 | .ctlIndex_5G = { | ||
447 | 0x10, 0x16, 0x18, 0x40, 0x46, | ||
448 | 0x48, 0x30, 0x36, 0x38 | ||
449 | }, | ||
450 | .ctl_freqbin_5G = { | ||
451 | { | ||
452 | /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
453 | /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
454 | /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), | ||
455 | /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), | ||
456 | /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), | ||
457 | /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
458 | /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), | ||
459 | /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) | ||
460 | }, | ||
461 | { | ||
462 | /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
463 | /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
464 | /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), | ||
465 | /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), | ||
466 | /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), | ||
467 | /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
468 | /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), | ||
469 | /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) | ||
470 | }, | ||
471 | |||
472 | { | ||
473 | /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), | ||
474 | /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), | ||
475 | /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), | ||
476 | /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), | ||
477 | /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), | ||
478 | /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), | ||
479 | /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), | ||
480 | /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) | ||
481 | }, | ||
482 | |||
483 | { | ||
484 | /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
485 | /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), | ||
486 | /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), | ||
487 | /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), | ||
488 | /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), | ||
489 | /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
490 | /* Data[3].ctlEdges[6].bChannel */ 0xFF, | ||
491 | /* Data[3].ctlEdges[7].bChannel */ 0xFF, | ||
492 | }, | ||
493 | |||
494 | { | ||
495 | /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
496 | /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
497 | /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), | ||
498 | /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), | ||
499 | /* Data[4].ctlEdges[4].bChannel */ 0xFF, | ||
500 | /* Data[4].ctlEdges[5].bChannel */ 0xFF, | ||
501 | /* Data[4].ctlEdges[6].bChannel */ 0xFF, | ||
502 | /* Data[4].ctlEdges[7].bChannel */ 0xFF, | ||
503 | }, | ||
504 | |||
505 | { | ||
506 | /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), | ||
507 | /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), | ||
508 | /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), | ||
509 | /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), | ||
510 | /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), | ||
511 | /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), | ||
512 | /* Data[5].ctlEdges[6].bChannel */ 0xFF, | ||
513 | /* Data[5].ctlEdges[7].bChannel */ 0xFF | ||
514 | }, | ||
515 | |||
516 | { | ||
517 | /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
518 | /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), | ||
519 | /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), | ||
520 | /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), | ||
521 | /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), | ||
522 | /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), | ||
523 | /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), | ||
524 | /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) | ||
525 | }, | ||
526 | |||
527 | { | ||
528 | /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
529 | /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
530 | /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), | ||
531 | /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), | ||
532 | /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), | ||
533 | /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
534 | /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), | ||
535 | /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) | ||
536 | }, | ||
537 | |||
538 | { | ||
539 | /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), | ||
540 | /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), | ||
541 | /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), | ||
542 | /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), | ||
543 | /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), | ||
544 | /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), | ||
545 | /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), | ||
546 | /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) | ||
547 | } | ||
548 | }, | ||
549 | .ctlPowerData_5G = { | ||
550 | { | ||
551 | { | ||
552 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
553 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
554 | } | ||
555 | }, | ||
556 | { | ||
557 | { | ||
558 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
559 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
560 | } | ||
561 | }, | ||
562 | { | ||
563 | { | ||
564 | {60, 0}, {60, 1}, {60, 0}, {60, 1}, | ||
565 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
566 | } | ||
567 | }, | ||
568 | { | ||
569 | { | ||
570 | {60, 0}, {60, 1}, {60, 1}, {60, 0}, | ||
571 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | ||
572 | } | ||
573 | }, | ||
574 | { | ||
575 | { | ||
576 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
577 | {60, 0}, {60, 0}, {60, 0}, {60, 0}, | ||
578 | } | ||
579 | }, | ||
580 | { | ||
581 | { | ||
582 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
583 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | ||
584 | } | ||
585 | }, | ||
586 | { | ||
587 | { | ||
588 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
589 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
590 | } | ||
591 | }, | ||
592 | { | ||
593 | { | ||
594 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | ||
595 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
596 | } | ||
597 | }, | ||
598 | { | ||
599 | { | ||
600 | {60, 1}, {60, 0}, {60, 1}, {60, 1}, | ||
601 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | ||
602 | } | ||
603 | }, | ||
604 | } | ||
605 | }; | ||
606 | |||
607 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) | ||
608 | { | ||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, | ||
613 | enum eeprom_param param) | ||
614 | { | ||
615 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
616 | struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader; | ||
617 | |||
618 | switch (param) { | ||
619 | case EEP_MAC_LSW: | ||
620 | return eep->macAddr[0] << 8 | eep->macAddr[1]; | ||
621 | case EEP_MAC_MID: | ||
622 | return eep->macAddr[2] << 8 | eep->macAddr[3]; | ||
623 | case EEP_MAC_MSW: | ||
624 | return eep->macAddr[4] << 8 | eep->macAddr[5]; | ||
625 | case EEP_REG_0: | ||
626 | return le16_to_cpu(pBase->regDmn[0]); | ||
627 | case EEP_REG_1: | ||
628 | return le16_to_cpu(pBase->regDmn[1]); | ||
629 | case EEP_OP_CAP: | ||
630 | return pBase->deviceCap; | ||
631 | case EEP_OP_MODE: | ||
632 | return pBase->opCapFlags.opFlags; | ||
633 | case EEP_RF_SILENT: | ||
634 | return pBase->rfSilent; | ||
635 | case EEP_TX_MASK: | ||
636 | return (pBase->txrxMask >> 4) & 0xf; | ||
637 | case EEP_RX_MASK: | ||
638 | return pBase->txrxMask & 0xf; | ||
639 | case EEP_DRIVE_STRENGTH: | ||
640 | #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1 | ||
641 | return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH; | ||
642 | case EEP_INTERNAL_REGULATOR: | ||
643 | /* Bit 4 is internal regulator flag */ | ||
644 | return (pBase->featureEnable & 0x10) >> 4; | ||
645 | case EEP_SWREG: | ||
646 | return le32_to_cpu(pBase->swreg); | ||
647 | default: | ||
648 | return 0; | ||
649 | } | ||
650 | } | ||
651 | |||
652 | static bool ar9300_eeprom_read_byte(struct ath_common *common, int address, | ||
653 | u8 *buffer) | ||
654 | { | ||
655 | u16 val; | ||
656 | |||
657 | if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val))) | ||
658 | return false; | ||
659 | |||
660 | *buffer = (val >> (8 * (address % 2))) & 0xff; | ||
661 | return true; | ||
662 | } | ||
663 | |||
664 | static bool ar9300_eeprom_read_word(struct ath_common *common, int address, | ||
665 | u8 *buffer) | ||
666 | { | ||
667 | u16 val; | ||
668 | |||
669 | if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val))) | ||
670 | return false; | ||
671 | |||
672 | buffer[0] = val >> 8; | ||
673 | buffer[1] = val & 0xff; | ||
674 | |||
675 | return true; | ||
676 | } | ||
677 | |||
678 | static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer, | ||
679 | int count) | ||
680 | { | ||
681 | struct ath_common *common = ath9k_hw_common(ah); | ||
682 | int i; | ||
683 | |||
684 | if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) { | ||
685 | ath_print(common, ATH_DBG_EEPROM, | ||
686 | "eeprom address not in range\n"); | ||
687 | return false; | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * Since we're reading the bytes in reverse order from a little-endian | ||
692 | * word stream, an even address means we only use the lower half of | ||
693 | * the 16-bit word at that address | ||
694 | */ | ||
695 | if (address % 2 == 0) { | ||
696 | if (!ar9300_eeprom_read_byte(common, address--, buffer++)) | ||
697 | goto error; | ||
698 | |||
699 | count--; | ||
700 | } | ||
701 | |||
702 | for (i = 0; i < count / 2; i++) { | ||
703 | if (!ar9300_eeprom_read_word(common, address, buffer)) | ||
704 | goto error; | ||
705 | |||
706 | address -= 2; | ||
707 | buffer += 2; | ||
708 | } | ||
709 | |||
710 | if (count % 2) | ||
711 | if (!ar9300_eeprom_read_byte(common, address, buffer)) | ||
712 | goto error; | ||
713 | |||
714 | return true; | ||
715 | |||
716 | error: | ||
717 | ath_print(common, ATH_DBG_EEPROM, | ||
718 | "unable to read eeprom region at offset %d\n", address); | ||
719 | return false; | ||
720 | } | ||
721 | |||
722 | static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference, | ||
723 | int *length, int *major, int *minor) | ||
724 | { | ||
725 | unsigned long value[4]; | ||
726 | |||
727 | value[0] = best[0]; | ||
728 | value[1] = best[1]; | ||
729 | value[2] = best[2]; | ||
730 | value[3] = best[3]; | ||
731 | *code = ((value[0] >> 5) & 0x0007); | ||
732 | *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020); | ||
733 | *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f); | ||
734 | *major = (value[2] & 0x000f); | ||
735 | *minor = (value[3] & 0x00ff); | ||
736 | } | ||
737 | |||
738 | static u16 ar9300_comp_cksum(u8 *data, int dsize) | ||
739 | { | ||
740 | int it, checksum = 0; | ||
741 | |||
742 | for (it = 0; it < dsize; it++) { | ||
743 | checksum += data[it]; | ||
744 | checksum &= 0xffff; | ||
745 | } | ||
746 | |||
747 | return checksum; | ||
748 | } | ||
749 | |||
750 | static bool ar9300_uncompress_block(struct ath_hw *ah, | ||
751 | u8 *mptr, | ||
752 | int mdataSize, | ||
753 | u8 *block, | ||
754 | int size) | ||
755 | { | ||
756 | int it; | ||
757 | int spot; | ||
758 | int offset; | ||
759 | int length; | ||
760 | struct ath_common *common = ath9k_hw_common(ah); | ||
761 | |||
762 | spot = 0; | ||
763 | |||
764 | for (it = 0; it < size; it += (length+2)) { | ||
765 | offset = block[it]; | ||
766 | offset &= 0xff; | ||
767 | spot += offset; | ||
768 | length = block[it+1]; | ||
769 | length &= 0xff; | ||
770 | |||
771 | if (length > 0 && spot >= 0 && spot+length < mdataSize) { | ||
772 | ath_print(common, ATH_DBG_EEPROM, | ||
773 | "Restore at %d: spot=%d " | ||
774 | "offset=%d length=%d\n", | ||
775 | it, spot, offset, length); | ||
776 | memcpy(&mptr[spot], &block[it+2], length); | ||
777 | spot += length; | ||
778 | } else if (length > 0) { | ||
779 | ath_print(common, ATH_DBG_EEPROM, | ||
780 | "Bad restore at %d: spot=%d " | ||
781 | "offset=%d length=%d\n", | ||
782 | it, spot, offset, length); | ||
783 | return false; | ||
784 | } | ||
785 | } | ||
786 | return true; | ||
787 | } | ||
788 | |||
789 | static int ar9300_compress_decision(struct ath_hw *ah, | ||
790 | int it, | ||
791 | int code, | ||
792 | int reference, | ||
793 | u8 *mptr, | ||
794 | u8 *word, int length, int mdata_size) | ||
795 | { | ||
796 | struct ath_common *common = ath9k_hw_common(ah); | ||
797 | u8 *dptr; | ||
798 | |||
799 | switch (code) { | ||
800 | case _CompressNone: | ||
801 | if (length != mdata_size) { | ||
802 | ath_print(common, ATH_DBG_EEPROM, | ||
803 | "EEPROM structure size mismatch" | ||
804 | "memory=%d eeprom=%d\n", mdata_size, length); | ||
805 | return -1; | ||
806 | } | ||
807 | memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); | ||
808 | ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:" | ||
809 | " uncompressed, length %d\n", it, length); | ||
810 | break; | ||
811 | case _CompressBlock: | ||
812 | if (reference == 0) { | ||
813 | dptr = mptr; | ||
814 | } else { | ||
815 | if (reference != 2) { | ||
816 | ath_print(common, ATH_DBG_EEPROM, | ||
817 | "cant find reference eeprom" | ||
818 | "struct %d\n", reference); | ||
819 | return -1; | ||
820 | } | ||
821 | memcpy(mptr, &ar9300_default, mdata_size); | ||
822 | } | ||
823 | ath_print(common, ATH_DBG_EEPROM, | ||
824 | "restore eeprom %d: block, reference %d," | ||
825 | " length %d\n", it, reference, length); | ||
826 | ar9300_uncompress_block(ah, mptr, mdata_size, | ||
827 | (u8 *) (word + COMP_HDR_LEN), length); | ||
828 | break; | ||
829 | default: | ||
830 | ath_print(common, ATH_DBG_EEPROM, "unknown compression" | ||
831 | " code %d\n", code); | ||
832 | return -1; | ||
833 | } | ||
834 | return 0; | ||
835 | } | ||
836 | |||
837 | /* | ||
838 | * Read the configuration data from the eeprom. | ||
839 | * The data can be put in any specified memory buffer. | ||
840 | * | ||
841 | * Returns -1 on error. | ||
842 | * Returns address of next memory location on success. | ||
843 | */ | ||
844 | static int ar9300_eeprom_restore_internal(struct ath_hw *ah, | ||
845 | u8 *mptr, int mdata_size) | ||
846 | { | ||
847 | #define MDEFAULT 15 | ||
848 | #define MSTATE 100 | ||
849 | int cptr; | ||
850 | u8 *word; | ||
851 | int code; | ||
852 | int reference, length, major, minor; | ||
853 | int osize; | ||
854 | int it; | ||
855 | u16 checksum, mchecksum; | ||
856 | struct ath_common *common = ath9k_hw_common(ah); | ||
857 | |||
858 | word = kzalloc(2048, GFP_KERNEL); | ||
859 | if (!word) | ||
860 | return -1; | ||
861 | |||
862 | memcpy(mptr, &ar9300_default, mdata_size); | ||
863 | |||
864 | cptr = AR9300_BASE_ADDR; | ||
865 | for (it = 0; it < MSTATE; it++) { | ||
866 | if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN)) | ||
867 | goto fail; | ||
868 | |||
869 | if ((word[0] == 0 && word[1] == 0 && word[2] == 0 && | ||
870 | word[3] == 0) || (word[0] == 0xff && word[1] == 0xff | ||
871 | && word[2] == 0xff && word[3] == 0xff)) | ||
872 | break; | ||
873 | |||
874 | ar9300_comp_hdr_unpack(word, &code, &reference, | ||
875 | &length, &major, &minor); | ||
876 | ath_print(common, ATH_DBG_EEPROM, | ||
877 | "Found block at %x: code=%d ref=%d" | ||
878 | "length=%d major=%d minor=%d\n", cptr, code, | ||
879 | reference, length, major, minor); | ||
880 | if (length >= 1024) { | ||
881 | ath_print(common, ATH_DBG_EEPROM, | ||
882 | "Skipping bad header\n"); | ||
883 | cptr -= COMP_HDR_LEN; | ||
884 | continue; | ||
885 | } | ||
886 | |||
887 | osize = length; | ||
888 | ar9300_read_eeprom(ah, cptr, word, | ||
889 | COMP_HDR_LEN + osize + COMP_CKSUM_LEN); | ||
890 | checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); | ||
891 | mchecksum = word[COMP_HDR_LEN + osize] | | ||
892 | (word[COMP_HDR_LEN + osize + 1] << 8); | ||
893 | ath_print(common, ATH_DBG_EEPROM, | ||
894 | "checksum %x %x\n", checksum, mchecksum); | ||
895 | if (checksum == mchecksum) { | ||
896 | ar9300_compress_decision(ah, it, code, reference, mptr, | ||
897 | word, length, mdata_size); | ||
898 | } else { | ||
899 | ath_print(common, ATH_DBG_EEPROM, | ||
900 | "skipping block with bad checksum\n"); | ||
901 | } | ||
902 | cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN); | ||
903 | } | ||
904 | |||
905 | kfree(word); | ||
906 | return cptr; | ||
907 | |||
908 | fail: | ||
909 | kfree(word); | ||
910 | return -1; | ||
911 | } | ||
912 | |||
913 | /* | ||
914 | * Restore the configuration structure by reading the eeprom. | ||
915 | * This function destroys any existing in-memory structure | ||
916 | * content. | ||
917 | */ | ||
918 | static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah) | ||
919 | { | ||
920 | u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep; | ||
921 | |||
922 | if (ar9300_eeprom_restore_internal(ah, mptr, | ||
923 | sizeof(struct ar9300_eeprom)) < 0) | ||
924 | return false; | ||
925 | |||
926 | return true; | ||
927 | } | ||
928 | |||
929 | /* XXX: review hardware docs */ | ||
930 | static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah) | ||
931 | { | ||
932 | return ah->eeprom.ar9300_eep.eepromVersion; | ||
933 | } | ||
934 | |||
935 | /* XXX: could be read from the eepromVersion, not sure yet */ | ||
936 | static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) | ||
937 | { | ||
938 | return 0; | ||
939 | } | ||
940 | |||
941 | static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah, | ||
942 | enum ieee80211_band freq_band) | ||
943 | { | ||
944 | return 1; | ||
945 | } | ||
946 | |||
947 | static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah, | ||
948 | struct ath9k_channel *chan) | ||
949 | { | ||
950 | return -EINVAL; | ||
951 | } | ||
952 | |||
953 | static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) | ||
954 | { | ||
955 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
956 | |||
957 | if (is2ghz) | ||
958 | return eep->modalHeader2G.xpaBiasLvl; | ||
959 | else | ||
960 | return eep->modalHeader5G.xpaBiasLvl; | ||
961 | } | ||
962 | |||
963 | static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | ||
964 | { | ||
965 | int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); | ||
966 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3)); | ||
967 | REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE, | ||
968 | ((bias >> 2) & 0x3)); | ||
969 | } | ||
970 | |||
971 | static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) | ||
972 | { | ||
973 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
974 | __le32 val; | ||
975 | |||
976 | if (is2ghz) | ||
977 | val = eep->modalHeader2G.antCtrlCommon; | ||
978 | else | ||
979 | val = eep->modalHeader5G.antCtrlCommon; | ||
980 | return le32_to_cpu(val); | ||
981 | } | ||
982 | |||
983 | static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) | ||
984 | { | ||
985 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
986 | __le32 val; | ||
987 | |||
988 | if (is2ghz) | ||
989 | val = eep->modalHeader2G.antCtrlCommon2; | ||
990 | else | ||
991 | val = eep->modalHeader5G.antCtrlCommon2; | ||
992 | return le32_to_cpu(val); | ||
993 | } | ||
994 | |||
995 | static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, | ||
996 | int chain, | ||
997 | bool is2ghz) | ||
998 | { | ||
999 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1000 | __le16 val = 0; | ||
1001 | |||
1002 | if (chain >= 0 && chain < AR9300_MAX_CHAINS) { | ||
1003 | if (is2ghz) | ||
1004 | val = eep->modalHeader2G.antCtrlChain[chain]; | ||
1005 | else | ||
1006 | val = eep->modalHeader5G.antCtrlChain[chain]; | ||
1007 | } | ||
1008 | |||
1009 | return le16_to_cpu(val); | ||
1010 | } | ||
1011 | |||
1012 | static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | ||
1013 | { | ||
1014 | u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); | ||
1015 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); | ||
1016 | |||
1017 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); | ||
1018 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); | ||
1019 | |||
1020 | value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz); | ||
1021 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); | ||
1022 | |||
1023 | value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); | ||
1024 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value); | ||
1025 | |||
1026 | value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); | ||
1027 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value); | ||
1028 | } | ||
1029 | |||
1030 | static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) | ||
1031 | { | ||
1032 | int drive_strength; | ||
1033 | unsigned long reg; | ||
1034 | |||
1035 | drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH); | ||
1036 | |||
1037 | if (!drive_strength) | ||
1038 | return; | ||
1039 | |||
1040 | reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1); | ||
1041 | reg &= ~0x00ffffc0; | ||
1042 | reg |= 0x5 << 21; | ||
1043 | reg |= 0x5 << 18; | ||
1044 | reg |= 0x5 << 15; | ||
1045 | reg |= 0x5 << 12; | ||
1046 | reg |= 0x5 << 9; | ||
1047 | reg |= 0x5 << 6; | ||
1048 | REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg); | ||
1049 | |||
1050 | reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2); | ||
1051 | reg &= ~0xffffffe0; | ||
1052 | reg |= 0x5 << 29; | ||
1053 | reg |= 0x5 << 26; | ||
1054 | reg |= 0x5 << 23; | ||
1055 | reg |= 0x5 << 20; | ||
1056 | reg |= 0x5 << 17; | ||
1057 | reg |= 0x5 << 14; | ||
1058 | reg |= 0x5 << 11; | ||
1059 | reg |= 0x5 << 8; | ||
1060 | reg |= 0x5 << 5; | ||
1061 | REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg); | ||
1062 | |||
1063 | reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4); | ||
1064 | reg &= ~0xff800000; | ||
1065 | reg |= 0x5 << 29; | ||
1066 | reg |= 0x5 << 26; | ||
1067 | reg |= 0x5 << 23; | ||
1068 | REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg); | ||
1069 | } | ||
1070 | |||
1071 | static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | ||
1072 | { | ||
1073 | int internal_regulator = | ||
1074 | ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); | ||
1075 | |||
1076 | if (internal_regulator) { | ||
1077 | /* Internal regulator is ON. Write swreg register. */ | ||
1078 | int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); | ||
1079 | REG_WRITE(ah, AR_RTC_REG_CONTROL1, | ||
1080 | REG_READ(ah, AR_RTC_REG_CONTROL1) & | ||
1081 | (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); | ||
1082 | REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg); | ||
1083 | /* Set REG_CONTROL1.SWREG_PROGRAM */ | ||
1084 | REG_WRITE(ah, AR_RTC_REG_CONTROL1, | ||
1085 | REG_READ(ah, | ||
1086 | AR_RTC_REG_CONTROL1) | | ||
1087 | AR_RTC_REG_CONTROL1_SWREG_PROGRAM); | ||
1088 | } else { | ||
1089 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, | ||
1090 | (REG_READ(ah, | ||
1091 | AR_RTC_SLEEP_CLK) | | ||
1092 | AR_RTC_FORCE_SWREG_PRD)); | ||
1093 | } | ||
1094 | } | ||
1095 | |||
1096 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | ||
1097 | struct ath9k_channel *chan) | ||
1098 | { | ||
1099 | ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan)); | ||
1100 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | ||
1101 | ar9003_hw_drive_strength_apply(ah); | ||
1102 | ar9003_hw_internal_regulator_apply(ah); | ||
1103 | } | ||
1104 | |||
1105 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, | ||
1106 | struct ath9k_channel *chan) | ||
1107 | { | ||
1108 | } | ||
1109 | |||
1110 | /* | ||
1111 | * Returns the interpolated y value corresponding to the specified x value | ||
1112 | * from the np ordered pairs of data (px,py). | ||
1113 | * The pairs do not have to be in any order. | ||
1114 | * If the specified x value is less than any of the px, | ||
1115 | * the returned y value is equal to the py for the lowest px. | ||
1116 | * If the specified x value is greater than any of the px, | ||
1117 | * the returned y value is equal to the py for the highest px. | ||
1118 | */ | ||
1119 | static int ar9003_hw_power_interpolate(int32_t x, | ||
1120 | int32_t *px, int32_t *py, u_int16_t np) | ||
1121 | { | ||
1122 | int ip = 0; | ||
1123 | int lx = 0, ly = 0, lhave = 0; | ||
1124 | int hx = 0, hy = 0, hhave = 0; | ||
1125 | int dx = 0; | ||
1126 | int y = 0; | ||
1127 | |||
1128 | lhave = 0; | ||
1129 | hhave = 0; | ||
1130 | |||
1131 | /* identify best lower and higher x calibration measurement */ | ||
1132 | for (ip = 0; ip < np; ip++) { | ||
1133 | dx = x - px[ip]; | ||
1134 | |||
1135 | /* this measurement is higher than our desired x */ | ||
1136 | if (dx <= 0) { | ||
1137 | if (!hhave || dx > (x - hx)) { | ||
1138 | /* new best higher x measurement */ | ||
1139 | hx = px[ip]; | ||
1140 | hy = py[ip]; | ||
1141 | hhave = 1; | ||
1142 | } | ||
1143 | } | ||
1144 | /* this measurement is lower than our desired x */ | ||
1145 | if (dx >= 0) { | ||
1146 | if (!lhave || dx < (x - lx)) { | ||
1147 | /* new best lower x measurement */ | ||
1148 | lx = px[ip]; | ||
1149 | ly = py[ip]; | ||
1150 | lhave = 1; | ||
1151 | } | ||
1152 | } | ||
1153 | } | ||
1154 | |||
1155 | /* the low x is good */ | ||
1156 | if (lhave) { | ||
1157 | /* so is the high x */ | ||
1158 | if (hhave) { | ||
1159 | /* they're the same, so just pick one */ | ||
1160 | if (hx == lx) | ||
1161 | y = ly; | ||
1162 | else /* interpolate */ | ||
1163 | y = ly + (((x - lx) * (hy - ly)) / (hx - lx)); | ||
1164 | } else /* only low is good, use it */ | ||
1165 | y = ly; | ||
1166 | } else if (hhave) /* only high is good, use it */ | ||
1167 | y = hy; | ||
1168 | else /* nothing is good,this should never happen unless np=0, ???? */ | ||
1169 | y = -(1 << 30); | ||
1170 | return y; | ||
1171 | } | ||
1172 | |||
1173 | static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah, | ||
1174 | u16 rateIndex, u16 freq, bool is2GHz) | ||
1175 | { | ||
1176 | u16 numPiers, i; | ||
1177 | s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1178 | s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1179 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1180 | struct cal_tgt_pow_legacy *pEepromTargetPwr; | ||
1181 | u8 *pFreqBin; | ||
1182 | |||
1183 | if (is2GHz) { | ||
1184 | numPiers = AR9300_NUM_2G_20_TARGET_POWERS; | ||
1185 | pEepromTargetPwr = eep->calTargetPower2G; | ||
1186 | pFreqBin = eep->calTarget_freqbin_2G; | ||
1187 | } else { | ||
1188 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | ||
1189 | pEepromTargetPwr = eep->calTargetPower5G; | ||
1190 | pFreqBin = eep->calTarget_freqbin_5G; | ||
1191 | } | ||
1192 | |||
1193 | /* | ||
1194 | * create array of channels and targetpower from | ||
1195 | * targetpower piers stored on eeprom | ||
1196 | */ | ||
1197 | for (i = 0; i < numPiers; i++) { | ||
1198 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | ||
1199 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1200 | } | ||
1201 | |||
1202 | /* interpolate to get target power for given frequency */ | ||
1203 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1204 | freqArray, | ||
1205 | targetPowerArray, numPiers); | ||
1206 | } | ||
1207 | |||
1208 | static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah, | ||
1209 | u16 rateIndex, | ||
1210 | u16 freq, bool is2GHz) | ||
1211 | { | ||
1212 | u16 numPiers, i; | ||
1213 | s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1214 | s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1215 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1216 | struct cal_tgt_pow_ht *pEepromTargetPwr; | ||
1217 | u8 *pFreqBin; | ||
1218 | |||
1219 | if (is2GHz) { | ||
1220 | numPiers = AR9300_NUM_2G_20_TARGET_POWERS; | ||
1221 | pEepromTargetPwr = eep->calTargetPower2GHT20; | ||
1222 | pFreqBin = eep->calTarget_freqbin_2GHT20; | ||
1223 | } else { | ||
1224 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | ||
1225 | pEepromTargetPwr = eep->calTargetPower5GHT20; | ||
1226 | pFreqBin = eep->calTarget_freqbin_5GHT20; | ||
1227 | } | ||
1228 | |||
1229 | /* | ||
1230 | * create array of channels and targetpower | ||
1231 | * from targetpower piers stored on eeprom | ||
1232 | */ | ||
1233 | for (i = 0; i < numPiers; i++) { | ||
1234 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | ||
1235 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1236 | } | ||
1237 | |||
1238 | /* interpolate to get target power for given frequency */ | ||
1239 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1240 | freqArray, | ||
1241 | targetPowerArray, numPiers); | ||
1242 | } | ||
1243 | |||
1244 | static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah, | ||
1245 | u16 rateIndex, | ||
1246 | u16 freq, bool is2GHz) | ||
1247 | { | ||
1248 | u16 numPiers, i; | ||
1249 | s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
1250 | s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
1251 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1252 | struct cal_tgt_pow_ht *pEepromTargetPwr; | ||
1253 | u8 *pFreqBin; | ||
1254 | |||
1255 | if (is2GHz) { | ||
1256 | numPiers = AR9300_NUM_2G_40_TARGET_POWERS; | ||
1257 | pEepromTargetPwr = eep->calTargetPower2GHT40; | ||
1258 | pFreqBin = eep->calTarget_freqbin_2GHT40; | ||
1259 | } else { | ||
1260 | numPiers = AR9300_NUM_5G_40_TARGET_POWERS; | ||
1261 | pEepromTargetPwr = eep->calTargetPower5GHT40; | ||
1262 | pFreqBin = eep->calTarget_freqbin_5GHT40; | ||
1263 | } | ||
1264 | |||
1265 | /* | ||
1266 | * create array of channels and targetpower from | ||
1267 | * targetpower piers stored on eeprom | ||
1268 | */ | ||
1269 | for (i = 0; i < numPiers; i++) { | ||
1270 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | ||
1271 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1272 | } | ||
1273 | |||
1274 | /* interpolate to get target power for given frequency */ | ||
1275 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1276 | freqArray, | ||
1277 | targetPowerArray, numPiers); | ||
1278 | } | ||
1279 | |||
1280 | static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah, | ||
1281 | u16 rateIndex, u16 freq) | ||
1282 | { | ||
1283 | u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i; | ||
1284 | s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
1285 | s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
1286 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1287 | struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck; | ||
1288 | u8 *pFreqBin = eep->calTarget_freqbin_Cck; | ||
1289 | |||
1290 | /* | ||
1291 | * create array of channels and targetpower from | ||
1292 | * targetpower piers stored on eeprom | ||
1293 | */ | ||
1294 | for (i = 0; i < numPiers; i++) { | ||
1295 | freqArray[i] = FBIN2FREQ(pFreqBin[i], 1); | ||
1296 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1297 | } | ||
1298 | |||
1299 | /* interpolate to get target power for given frequency */ | ||
1300 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1301 | freqArray, | ||
1302 | targetPowerArray, numPiers); | ||
1303 | } | ||
1304 | |||
1305 | /* Set tx power registers to array of values passed in */ | ||
1306 | static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) | ||
1307 | { | ||
1308 | #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) | ||
1309 | /* make sure forced gain is not set */ | ||
1310 | REG_WRITE(ah, 0xa458, 0); | ||
1311 | |||
1312 | /* Write the OFDM power per rate set */ | ||
1313 | |||
1314 | /* 6 (LSB), 9, 12, 18 (MSB) */ | ||
1315 | REG_WRITE(ah, 0xa3c0, | ||
1316 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) | | ||
1317 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) | | ||
1318 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) | | ||
1319 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)); | ||
1320 | |||
1321 | /* 24 (LSB), 36, 48, 54 (MSB) */ | ||
1322 | REG_WRITE(ah, 0xa3c4, | ||
1323 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) | | ||
1324 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) | | ||
1325 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) | | ||
1326 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)); | ||
1327 | |||
1328 | /* Write the CCK power per rate set */ | ||
1329 | |||
1330 | /* 1L (LSB), reserved, 2L, 2S (MSB) */ | ||
1331 | REG_WRITE(ah, 0xa3c8, | ||
1332 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) | | ||
1333 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) | | ||
1334 | /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */ | ||
1335 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)); | ||
1336 | |||
1337 | /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */ | ||
1338 | REG_WRITE(ah, 0xa3cc, | ||
1339 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) | | ||
1340 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) | | ||
1341 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) | | ||
1342 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) | ||
1343 | ); | ||
1344 | |||
1345 | /* Write the HT20 power per rate set */ | ||
1346 | |||
1347 | /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ | ||
1348 | REG_WRITE(ah, 0xa3d0, | ||
1349 | POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) | | ||
1350 | POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) | | ||
1351 | POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) | | ||
1352 | POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0) | ||
1353 | ); | ||
1354 | |||
1355 | /* 6 (LSB), 7, 12, 13 (MSB) */ | ||
1356 | REG_WRITE(ah, 0xa3d4, | ||
1357 | POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) | | ||
1358 | POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) | | ||
1359 | POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) | | ||
1360 | POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0) | ||
1361 | ); | ||
1362 | |||
1363 | /* 14 (LSB), 15, 20, 21 */ | ||
1364 | REG_WRITE(ah, 0xa3e4, | ||
1365 | POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) | | ||
1366 | POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) | | ||
1367 | POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) | | ||
1368 | POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0) | ||
1369 | ); | ||
1370 | |||
1371 | /* Mixed HT20 and HT40 rates */ | ||
1372 | |||
1373 | /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */ | ||
1374 | REG_WRITE(ah, 0xa3e8, | ||
1375 | POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) | | ||
1376 | POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) | | ||
1377 | POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) | | ||
1378 | POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0) | ||
1379 | ); | ||
1380 | |||
1381 | /* | ||
1382 | * Write the HT40 power per rate set | ||
1383 | * correct PAR difference between HT40 and HT20/LEGACY | ||
1384 | * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) | ||
1385 | */ | ||
1386 | REG_WRITE(ah, 0xa3d8, | ||
1387 | POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) | | ||
1388 | POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) | | ||
1389 | POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) | | ||
1390 | POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0) | ||
1391 | ); | ||
1392 | |||
1393 | /* 6 (LSB), 7, 12, 13 (MSB) */ | ||
1394 | REG_WRITE(ah, 0xa3dc, | ||
1395 | POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) | | ||
1396 | POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) | | ||
1397 | POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) | | ||
1398 | POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0) | ||
1399 | ); | ||
1400 | |||
1401 | /* 14 (LSB), 15, 20, 21 */ | ||
1402 | REG_WRITE(ah, 0xa3ec, | ||
1403 | POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) | | ||
1404 | POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) | | ||
1405 | POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) | | ||
1406 | POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0) | ||
1407 | ); | ||
1408 | |||
1409 | return 0; | ||
1410 | #undef POW_SM | ||
1411 | } | ||
1412 | |||
1413 | static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq) | ||
1414 | { | ||
1415 | u8 targetPowerValT2[ar9300RateSize]; | ||
1416 | /* XXX: hard code for now, need to get from eeprom struct */ | ||
1417 | u8 ht40PowerIncForPdadc = 0; | ||
1418 | bool is2GHz = false; | ||
1419 | unsigned int i = 0; | ||
1420 | struct ath_common *common = ath9k_hw_common(ah); | ||
1421 | |||
1422 | if (freq < 4000) | ||
1423 | is2GHz = true; | ||
1424 | |||
1425 | targetPowerValT2[ALL_TARGET_LEGACY_6_24] = | ||
1426 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq, | ||
1427 | is2GHz); | ||
1428 | targetPowerValT2[ALL_TARGET_LEGACY_36] = | ||
1429 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq, | ||
1430 | is2GHz); | ||
1431 | targetPowerValT2[ALL_TARGET_LEGACY_48] = | ||
1432 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq, | ||
1433 | is2GHz); | ||
1434 | targetPowerValT2[ALL_TARGET_LEGACY_54] = | ||
1435 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq, | ||
1436 | is2GHz); | ||
1437 | targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] = | ||
1438 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L, | ||
1439 | freq); | ||
1440 | targetPowerValT2[ALL_TARGET_LEGACY_5S] = | ||
1441 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq); | ||
1442 | targetPowerValT2[ALL_TARGET_LEGACY_11L] = | ||
1443 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq); | ||
1444 | targetPowerValT2[ALL_TARGET_LEGACY_11S] = | ||
1445 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq); | ||
1446 | targetPowerValT2[ALL_TARGET_HT20_0_8_16] = | ||
1447 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, | ||
1448 | is2GHz); | ||
1449 | targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] = | ||
1450 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19, | ||
1451 | freq, is2GHz); | ||
1452 | targetPowerValT2[ALL_TARGET_HT20_4] = | ||
1453 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq, | ||
1454 | is2GHz); | ||
1455 | targetPowerValT2[ALL_TARGET_HT20_5] = | ||
1456 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq, | ||
1457 | is2GHz); | ||
1458 | targetPowerValT2[ALL_TARGET_HT20_6] = | ||
1459 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq, | ||
1460 | is2GHz); | ||
1461 | targetPowerValT2[ALL_TARGET_HT20_7] = | ||
1462 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq, | ||
1463 | is2GHz); | ||
1464 | targetPowerValT2[ALL_TARGET_HT20_12] = | ||
1465 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq, | ||
1466 | is2GHz); | ||
1467 | targetPowerValT2[ALL_TARGET_HT20_13] = | ||
1468 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq, | ||
1469 | is2GHz); | ||
1470 | targetPowerValT2[ALL_TARGET_HT20_14] = | ||
1471 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq, | ||
1472 | is2GHz); | ||
1473 | targetPowerValT2[ALL_TARGET_HT20_15] = | ||
1474 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq, | ||
1475 | is2GHz); | ||
1476 | targetPowerValT2[ALL_TARGET_HT20_20] = | ||
1477 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq, | ||
1478 | is2GHz); | ||
1479 | targetPowerValT2[ALL_TARGET_HT20_21] = | ||
1480 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq, | ||
1481 | is2GHz); | ||
1482 | targetPowerValT2[ALL_TARGET_HT20_22] = | ||
1483 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq, | ||
1484 | is2GHz); | ||
1485 | targetPowerValT2[ALL_TARGET_HT20_23] = | ||
1486 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq, | ||
1487 | is2GHz); | ||
1488 | targetPowerValT2[ALL_TARGET_HT40_0_8_16] = | ||
1489 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, | ||
1490 | is2GHz) + ht40PowerIncForPdadc; | ||
1491 | targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] = | ||
1492 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19, | ||
1493 | freq, | ||
1494 | is2GHz) + ht40PowerIncForPdadc; | ||
1495 | targetPowerValT2[ALL_TARGET_HT40_4] = | ||
1496 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq, | ||
1497 | is2GHz) + ht40PowerIncForPdadc; | ||
1498 | targetPowerValT2[ALL_TARGET_HT40_5] = | ||
1499 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq, | ||
1500 | is2GHz) + ht40PowerIncForPdadc; | ||
1501 | targetPowerValT2[ALL_TARGET_HT40_6] = | ||
1502 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq, | ||
1503 | is2GHz) + ht40PowerIncForPdadc; | ||
1504 | targetPowerValT2[ALL_TARGET_HT40_7] = | ||
1505 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq, | ||
1506 | is2GHz) + ht40PowerIncForPdadc; | ||
1507 | targetPowerValT2[ALL_TARGET_HT40_12] = | ||
1508 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq, | ||
1509 | is2GHz) + ht40PowerIncForPdadc; | ||
1510 | targetPowerValT2[ALL_TARGET_HT40_13] = | ||
1511 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq, | ||
1512 | is2GHz) + ht40PowerIncForPdadc; | ||
1513 | targetPowerValT2[ALL_TARGET_HT40_14] = | ||
1514 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq, | ||
1515 | is2GHz) + ht40PowerIncForPdadc; | ||
1516 | targetPowerValT2[ALL_TARGET_HT40_15] = | ||
1517 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq, | ||
1518 | is2GHz) + ht40PowerIncForPdadc; | ||
1519 | targetPowerValT2[ALL_TARGET_HT40_20] = | ||
1520 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq, | ||
1521 | is2GHz) + ht40PowerIncForPdadc; | ||
1522 | targetPowerValT2[ALL_TARGET_HT40_21] = | ||
1523 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq, | ||
1524 | is2GHz) + ht40PowerIncForPdadc; | ||
1525 | targetPowerValT2[ALL_TARGET_HT40_22] = | ||
1526 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq, | ||
1527 | is2GHz) + ht40PowerIncForPdadc; | ||
1528 | targetPowerValT2[ALL_TARGET_HT40_23] = | ||
1529 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq, | ||
1530 | is2GHz) + ht40PowerIncForPdadc; | ||
1531 | |||
1532 | while (i < ar9300RateSize) { | ||
1533 | ath_print(common, ATH_DBG_EEPROM, | ||
1534 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
1535 | i++; | ||
1536 | |||
1537 | ath_print(common, ATH_DBG_EEPROM, | ||
1538 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
1539 | i++; | ||
1540 | |||
1541 | ath_print(common, ATH_DBG_EEPROM, | ||
1542 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
1543 | i++; | ||
1544 | |||
1545 | ath_print(common, ATH_DBG_EEPROM, | ||
1546 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); | ||
1547 | i++; | ||
1548 | } | ||
1549 | |||
1550 | /* Write target power array to registers */ | ||
1551 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); | ||
1552 | } | ||
1553 | |||
1554 | static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | ||
1555 | int mode, | ||
1556 | int ipier, | ||
1557 | int ichain, | ||
1558 | int *pfrequency, | ||
1559 | int *pcorrection, | ||
1560 | int *ptemperature, int *pvoltage) | ||
1561 | { | ||
1562 | u8 *pCalPier; | ||
1563 | struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct; | ||
1564 | int is2GHz; | ||
1565 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1566 | struct ath_common *common = ath9k_hw_common(ah); | ||
1567 | |||
1568 | if (ichain >= AR9300_MAX_CHAINS) { | ||
1569 | ath_print(common, ATH_DBG_EEPROM, | ||
1570 | "Invalid chain index, must be less than %d\n", | ||
1571 | AR9300_MAX_CHAINS); | ||
1572 | return -1; | ||
1573 | } | ||
1574 | |||
1575 | if (mode) { /* 5GHz */ | ||
1576 | if (ipier >= AR9300_NUM_5G_CAL_PIERS) { | ||
1577 | ath_print(common, ATH_DBG_EEPROM, | ||
1578 | "Invalid 5GHz cal pier index, must " | ||
1579 | "be less than %d\n", | ||
1580 | AR9300_NUM_5G_CAL_PIERS); | ||
1581 | return -1; | ||
1582 | } | ||
1583 | pCalPier = &(eep->calFreqPier5G[ipier]); | ||
1584 | pCalPierStruct = &(eep->calPierData5G[ichain][ipier]); | ||
1585 | is2GHz = 0; | ||
1586 | } else { | ||
1587 | if (ipier >= AR9300_NUM_2G_CAL_PIERS) { | ||
1588 | ath_print(common, ATH_DBG_EEPROM, | ||
1589 | "Invalid 2GHz cal pier index, must " | ||
1590 | "be less than %d\n", AR9300_NUM_2G_CAL_PIERS); | ||
1591 | return -1; | ||
1592 | } | ||
1593 | |||
1594 | pCalPier = &(eep->calFreqPier2G[ipier]); | ||
1595 | pCalPierStruct = &(eep->calPierData2G[ichain][ipier]); | ||
1596 | is2GHz = 1; | ||
1597 | } | ||
1598 | |||
1599 | *pfrequency = FBIN2FREQ(*pCalPier, is2GHz); | ||
1600 | *pcorrection = pCalPierStruct->refPower; | ||
1601 | *ptemperature = pCalPierStruct->tempMeas; | ||
1602 | *pvoltage = pCalPierStruct->voltMeas; | ||
1603 | |||
1604 | return 0; | ||
1605 | } | ||
1606 | |||
1607 | static int ar9003_hw_power_control_override(struct ath_hw *ah, | ||
1608 | int frequency, | ||
1609 | int *correction, | ||
1610 | int *voltage, int *temperature) | ||
1611 | { | ||
1612 | int tempSlope = 0; | ||
1613 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1614 | |||
1615 | REG_RMW(ah, AR_PHY_TPC_11_B0, | ||
1616 | (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), | ||
1617 | AR_PHY_TPC_OLPC_GAIN_DELTA); | ||
1618 | REG_RMW(ah, AR_PHY_TPC_11_B1, | ||
1619 | (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), | ||
1620 | AR_PHY_TPC_OLPC_GAIN_DELTA); | ||
1621 | REG_RMW(ah, AR_PHY_TPC_11_B2, | ||
1622 | (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), | ||
1623 | AR_PHY_TPC_OLPC_GAIN_DELTA); | ||
1624 | |||
1625 | /* enable open loop power control on chip */ | ||
1626 | REG_RMW(ah, AR_PHY_TPC_6_B0, | ||
1627 | (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), | ||
1628 | AR_PHY_TPC_6_ERROR_EST_MODE); | ||
1629 | REG_RMW(ah, AR_PHY_TPC_6_B1, | ||
1630 | (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), | ||
1631 | AR_PHY_TPC_6_ERROR_EST_MODE); | ||
1632 | REG_RMW(ah, AR_PHY_TPC_6_B2, | ||
1633 | (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), | ||
1634 | AR_PHY_TPC_6_ERROR_EST_MODE); | ||
1635 | |||
1636 | /* | ||
1637 | * enable temperature compensation | ||
1638 | * Need to use register names | ||
1639 | */ | ||
1640 | if (frequency < 4000) | ||
1641 | tempSlope = eep->modalHeader2G.tempSlope; | ||
1642 | else | ||
1643 | tempSlope = eep->modalHeader5G.tempSlope; | ||
1644 | |||
1645 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); | ||
1646 | REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, | ||
1647 | temperature[0]); | ||
1648 | |||
1649 | return 0; | ||
1650 | } | ||
1651 | |||
1652 | /* Apply the recorded correction values. */ | ||
1653 | static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) | ||
1654 | { | ||
1655 | int ichain, ipier, npier; | ||
1656 | int mode; | ||
1657 | int lfrequency[AR9300_MAX_CHAINS], | ||
1658 | lcorrection[AR9300_MAX_CHAINS], | ||
1659 | ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS]; | ||
1660 | int hfrequency[AR9300_MAX_CHAINS], | ||
1661 | hcorrection[AR9300_MAX_CHAINS], | ||
1662 | htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS]; | ||
1663 | int fdiff; | ||
1664 | int correction[AR9300_MAX_CHAINS], | ||
1665 | voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS]; | ||
1666 | int pfrequency, pcorrection, ptemperature, pvoltage; | ||
1667 | struct ath_common *common = ath9k_hw_common(ah); | ||
1668 | |||
1669 | mode = (frequency >= 4000); | ||
1670 | if (mode) | ||
1671 | npier = AR9300_NUM_5G_CAL_PIERS; | ||
1672 | else | ||
1673 | npier = AR9300_NUM_2G_CAL_PIERS; | ||
1674 | |||
1675 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { | ||
1676 | lfrequency[ichain] = 0; | ||
1677 | hfrequency[ichain] = 100000; | ||
1678 | } | ||
1679 | /* identify best lower and higher frequency calibration measurement */ | ||
1680 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { | ||
1681 | for (ipier = 0; ipier < npier; ipier++) { | ||
1682 | if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain, | ||
1683 | &pfrequency, &pcorrection, | ||
1684 | &ptemperature, &pvoltage)) { | ||
1685 | fdiff = frequency - pfrequency; | ||
1686 | |||
1687 | /* | ||
1688 | * this measurement is higher than | ||
1689 | * our desired frequency | ||
1690 | */ | ||
1691 | if (fdiff <= 0) { | ||
1692 | if (hfrequency[ichain] <= 0 || | ||
1693 | hfrequency[ichain] >= 100000 || | ||
1694 | fdiff > | ||
1695 | (frequency - hfrequency[ichain])) { | ||
1696 | /* | ||
1697 | * new best higher | ||
1698 | * frequency measurement | ||
1699 | */ | ||
1700 | hfrequency[ichain] = pfrequency; | ||
1701 | hcorrection[ichain] = | ||
1702 | pcorrection; | ||
1703 | htemperature[ichain] = | ||
1704 | ptemperature; | ||
1705 | hvoltage[ichain] = pvoltage; | ||
1706 | } | ||
1707 | } | ||
1708 | if (fdiff >= 0) { | ||
1709 | if (lfrequency[ichain] <= 0 | ||
1710 | || fdiff < | ||
1711 | (frequency - lfrequency[ichain])) { | ||
1712 | /* | ||
1713 | * new best lower | ||
1714 | * frequency measurement | ||
1715 | */ | ||
1716 | lfrequency[ichain] = pfrequency; | ||
1717 | lcorrection[ichain] = | ||
1718 | pcorrection; | ||
1719 | ltemperature[ichain] = | ||
1720 | ptemperature; | ||
1721 | lvoltage[ichain] = pvoltage; | ||
1722 | } | ||
1723 | } | ||
1724 | } | ||
1725 | } | ||
1726 | } | ||
1727 | |||
1728 | /* interpolate */ | ||
1729 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { | ||
1730 | ath_print(common, ATH_DBG_EEPROM, | ||
1731 | "ch=%d f=%d low=%d %d h=%d %d\n", | ||
1732 | ichain, frequency, lfrequency[ichain], | ||
1733 | lcorrection[ichain], hfrequency[ichain], | ||
1734 | hcorrection[ichain]); | ||
1735 | /* they're the same, so just pick one */ | ||
1736 | if (hfrequency[ichain] == lfrequency[ichain]) { | ||
1737 | correction[ichain] = lcorrection[ichain]; | ||
1738 | voltage[ichain] = lvoltage[ichain]; | ||
1739 | temperature[ichain] = ltemperature[ichain]; | ||
1740 | } | ||
1741 | /* the low frequency is good */ | ||
1742 | else if (frequency - lfrequency[ichain] < 1000) { | ||
1743 | /* so is the high frequency, interpolate */ | ||
1744 | if (hfrequency[ichain] - frequency < 1000) { | ||
1745 | |||
1746 | correction[ichain] = lcorrection[ichain] + | ||
1747 | (((frequency - lfrequency[ichain]) * | ||
1748 | (hcorrection[ichain] - | ||
1749 | lcorrection[ichain])) / | ||
1750 | (hfrequency[ichain] - lfrequency[ichain])); | ||
1751 | |||
1752 | temperature[ichain] = ltemperature[ichain] + | ||
1753 | (((frequency - lfrequency[ichain]) * | ||
1754 | (htemperature[ichain] - | ||
1755 | ltemperature[ichain])) / | ||
1756 | (hfrequency[ichain] - lfrequency[ichain])); | ||
1757 | |||
1758 | voltage[ichain] = | ||
1759 | lvoltage[ichain] + | ||
1760 | (((frequency - | ||
1761 | lfrequency[ichain]) * (hvoltage[ichain] - | ||
1762 | lvoltage[ichain])) | ||
1763 | / (hfrequency[ichain] - | ||
1764 | lfrequency[ichain])); | ||
1765 | } | ||
1766 | /* only low is good, use it */ | ||
1767 | else { | ||
1768 | correction[ichain] = lcorrection[ichain]; | ||
1769 | temperature[ichain] = ltemperature[ichain]; | ||
1770 | voltage[ichain] = lvoltage[ichain]; | ||
1771 | } | ||
1772 | } | ||
1773 | /* only high is good, use it */ | ||
1774 | else if (hfrequency[ichain] - frequency < 1000) { | ||
1775 | correction[ichain] = hcorrection[ichain]; | ||
1776 | temperature[ichain] = htemperature[ichain]; | ||
1777 | voltage[ichain] = hvoltage[ichain]; | ||
1778 | } else { /* nothing is good, presume 0???? */ | ||
1779 | correction[ichain] = 0; | ||
1780 | temperature[ichain] = 0; | ||
1781 | voltage[ichain] = 0; | ||
1782 | } | ||
1783 | } | ||
1784 | |||
1785 | ar9003_hw_power_control_override(ah, frequency, correction, voltage, | ||
1786 | temperature); | ||
1787 | |||
1788 | ath_print(common, ATH_DBG_EEPROM, | ||
1789 | "for frequency=%d, calibration correction = %d %d %d\n", | ||
1790 | frequency, correction[0], correction[1], correction[2]); | ||
1791 | |||
1792 | return 0; | ||
1793 | } | ||
1794 | |||
1795 | static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | ||
1796 | struct ath9k_channel *chan, u16 cfgCtl, | ||
1797 | u8 twiceAntennaReduction, | ||
1798 | u8 twiceMaxRegulatoryPower, | ||
1799 | u8 powerLimit) | ||
1800 | { | ||
1801 | ah->txpower_limit = powerLimit; | ||
1802 | ar9003_hw_set_target_power_eeprom(ah, chan->channel); | ||
1803 | ar9003_hw_calibration_apply(ah, chan->channel); | ||
1804 | } | ||
1805 | |||
1806 | static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, | ||
1807 | u16 i, bool is2GHz) | ||
1808 | { | ||
1809 | return AR_NO_SPUR; | ||
1810 | } | ||
1811 | |||
1812 | s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah) | ||
1813 | { | ||
1814 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1815 | |||
1816 | return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */ | ||
1817 | } | ||
1818 | |||
1819 | s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah) | ||
1820 | { | ||
1821 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1822 | |||
1823 | return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */ | ||
1824 | } | ||
1825 | |||
1826 | const struct eeprom_ops eep_ar9300_ops = { | ||
1827 | .check_eeprom = ath9k_hw_ar9300_check_eeprom, | ||
1828 | .get_eeprom = ath9k_hw_ar9300_get_eeprom, | ||
1829 | .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, | ||
1830 | .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, | ||
1831 | .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, | ||
1832 | .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config, | ||
1833 | .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg, | ||
1834 | .set_board_values = ath9k_hw_ar9300_set_board_values, | ||
1835 | .set_addac = ath9k_hw_ar9300_set_addac, | ||
1836 | .set_txpower = ath9k_hw_ar9300_set_txpower, | ||
1837 | .get_spur_channel = ath9k_hw_ar9300_get_spur_channel | ||
1838 | }; | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h new file mode 100644 index 000000000000..23fb353c3bba --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -0,0 +1,323 @@ | |||
1 | #ifndef AR9003_EEPROM_H | ||
2 | #define AR9003_EEPROM_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | #define AR9300_EEP_VER 0xD000 | ||
7 | #define AR9300_EEP_VER_MINOR_MASK 0xFFF | ||
8 | #define AR9300_EEP_MINOR_VER_1 0x1 | ||
9 | #define AR9300_EEP_MINOR_VER AR9300_EEP_MINOR_VER_1 | ||
10 | |||
11 | /* 16-bit offset location start of calibration struct */ | ||
12 | #define AR9300_EEP_START_LOC 256 | ||
13 | #define AR9300_NUM_5G_CAL_PIERS 8 | ||
14 | #define AR9300_NUM_2G_CAL_PIERS 3 | ||
15 | #define AR9300_NUM_5G_20_TARGET_POWERS 8 | ||
16 | #define AR9300_NUM_5G_40_TARGET_POWERS 8 | ||
17 | #define AR9300_NUM_2G_CCK_TARGET_POWERS 2 | ||
18 | #define AR9300_NUM_2G_20_TARGET_POWERS 3 | ||
19 | #define AR9300_NUM_2G_40_TARGET_POWERS 3 | ||
20 | /* #define AR9300_NUM_CTLS 21 */ | ||
21 | #define AR9300_NUM_CTLS_5G 9 | ||
22 | #define AR9300_NUM_CTLS_2G 12 | ||
23 | #define AR9300_CTL_MODE_M 0xF | ||
24 | #define AR9300_NUM_BAND_EDGES_5G 8 | ||
25 | #define AR9300_NUM_BAND_EDGES_2G 4 | ||
26 | #define AR9300_NUM_PD_GAINS 4 | ||
27 | #define AR9300_PD_GAINS_IN_MASK 4 | ||
28 | #define AR9300_PD_GAIN_ICEPTS 5 | ||
29 | #define AR9300_EEPROM_MODAL_SPURS 5 | ||
30 | #define AR9300_MAX_RATE_POWER 63 | ||
31 | #define AR9300_NUM_PDADC_VALUES 128 | ||
32 | #define AR9300_NUM_RATES 16 | ||
33 | #define AR9300_BCHAN_UNUSED 0xFF | ||
34 | #define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64 | ||
35 | #define AR9300_OPFLAGS_11A 0x01 | ||
36 | #define AR9300_OPFLAGS_11G 0x02 | ||
37 | #define AR9300_OPFLAGS_5G_HT40 0x04 | ||
38 | #define AR9300_OPFLAGS_2G_HT40 0x08 | ||
39 | #define AR9300_OPFLAGS_5G_HT20 0x10 | ||
40 | #define AR9300_OPFLAGS_2G_HT20 0x20 | ||
41 | #define AR9300_EEPMISC_BIG_ENDIAN 0x01 | ||
42 | #define AR9300_EEPMISC_WOW 0x02 | ||
43 | #define AR9300_CUSTOMER_DATA_SIZE 20 | ||
44 | |||
45 | #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) | ||
46 | #define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x)) | ||
47 | #define AR9300_MAX_CHAINS 3 | ||
48 | #define AR9300_ANT_16S 25 | ||
49 | #define AR9300_FUTURE_MODAL_SZ 6 | ||
50 | |||
51 | #define AR9300_NUM_ANT_CHAIN_FIELDS 7 | ||
52 | #define AR9300_NUM_ANT_COMMON_FIELDS 4 | ||
53 | #define AR9300_SIZE_ANT_CHAIN_FIELD 3 | ||
54 | #define AR9300_SIZE_ANT_COMMON_FIELD 4 | ||
55 | #define AR9300_ANT_CHAIN_MASK 0x7 | ||
56 | #define AR9300_ANT_COMMON_MASK 0xf | ||
57 | #define AR9300_CHAIN_0_IDX 0 | ||
58 | #define AR9300_CHAIN_1_IDX 1 | ||
59 | #define AR9300_CHAIN_2_IDX 2 | ||
60 | |||
61 | #define AR928X_NUM_ANT_CHAIN_FIELDS 6 | ||
62 | #define AR928X_SIZE_ANT_CHAIN_FIELD 2 | ||
63 | #define AR928X_ANT_CHAIN_MASK 0x3 | ||
64 | |||
65 | /* Delta from which to start power to pdadc table */ | ||
66 | /* This offset is used in both open loop and closed loop power control | ||
67 | * schemes. In open loop power control, it is not really needed, but for | ||
68 | * the "sake of consistency" it was kept. For certain AP designs, this | ||
69 | * value is overwritten by the value in the flag "pwrTableOffset" just | ||
70 | * before writing the pdadc vs pwr into the chip registers. | ||
71 | */ | ||
72 | #define AR9300_PWR_TABLE_OFFSET 0 | ||
73 | |||
74 | /* enable flags for voltage and temp compensation */ | ||
75 | #define ENABLE_TEMP_COMPENSATION 0x01 | ||
76 | #define ENABLE_VOLT_COMPENSATION 0x02 | ||
77 | /* byte addressable */ | ||
78 | #define AR9300_EEPROM_SIZE (16*1024) | ||
79 | #define FIXED_CCA_THRESHOLD 15 | ||
80 | |||
81 | #define AR9300_BASE_ADDR 0x3ff | ||
82 | |||
83 | enum targetPowerHTRates { | ||
84 | HT_TARGET_RATE_0_8_16, | ||
85 | HT_TARGET_RATE_1_3_9_11_17_19, | ||
86 | HT_TARGET_RATE_4, | ||
87 | HT_TARGET_RATE_5, | ||
88 | HT_TARGET_RATE_6, | ||
89 | HT_TARGET_RATE_7, | ||
90 | HT_TARGET_RATE_12, | ||
91 | HT_TARGET_RATE_13, | ||
92 | HT_TARGET_RATE_14, | ||
93 | HT_TARGET_RATE_15, | ||
94 | HT_TARGET_RATE_20, | ||
95 | HT_TARGET_RATE_21, | ||
96 | HT_TARGET_RATE_22, | ||
97 | HT_TARGET_RATE_23 | ||
98 | }; | ||
99 | |||
100 | enum targetPowerLegacyRates { | ||
101 | LEGACY_TARGET_RATE_6_24, | ||
102 | LEGACY_TARGET_RATE_36, | ||
103 | LEGACY_TARGET_RATE_48, | ||
104 | LEGACY_TARGET_RATE_54 | ||
105 | }; | ||
106 | |||
107 | enum targetPowerCckRates { | ||
108 | LEGACY_TARGET_RATE_1L_5L, | ||
109 | LEGACY_TARGET_RATE_5S, | ||
110 | LEGACY_TARGET_RATE_11L, | ||
111 | LEGACY_TARGET_RATE_11S | ||
112 | }; | ||
113 | |||
114 | enum ar9300_Rates { | ||
115 | ALL_TARGET_LEGACY_6_24, | ||
116 | ALL_TARGET_LEGACY_36, | ||
117 | ALL_TARGET_LEGACY_48, | ||
118 | ALL_TARGET_LEGACY_54, | ||
119 | ALL_TARGET_LEGACY_1L_5L, | ||
120 | ALL_TARGET_LEGACY_5S, | ||
121 | ALL_TARGET_LEGACY_11L, | ||
122 | ALL_TARGET_LEGACY_11S, | ||
123 | ALL_TARGET_HT20_0_8_16, | ||
124 | ALL_TARGET_HT20_1_3_9_11_17_19, | ||
125 | ALL_TARGET_HT20_4, | ||
126 | ALL_TARGET_HT20_5, | ||
127 | ALL_TARGET_HT20_6, | ||
128 | ALL_TARGET_HT20_7, | ||
129 | ALL_TARGET_HT20_12, | ||
130 | ALL_TARGET_HT20_13, | ||
131 | ALL_TARGET_HT20_14, | ||
132 | ALL_TARGET_HT20_15, | ||
133 | ALL_TARGET_HT20_20, | ||
134 | ALL_TARGET_HT20_21, | ||
135 | ALL_TARGET_HT20_22, | ||
136 | ALL_TARGET_HT20_23, | ||
137 | ALL_TARGET_HT40_0_8_16, | ||
138 | ALL_TARGET_HT40_1_3_9_11_17_19, | ||
139 | ALL_TARGET_HT40_4, | ||
140 | ALL_TARGET_HT40_5, | ||
141 | ALL_TARGET_HT40_6, | ||
142 | ALL_TARGET_HT40_7, | ||
143 | ALL_TARGET_HT40_12, | ||
144 | ALL_TARGET_HT40_13, | ||
145 | ALL_TARGET_HT40_14, | ||
146 | ALL_TARGET_HT40_15, | ||
147 | ALL_TARGET_HT40_20, | ||
148 | ALL_TARGET_HT40_21, | ||
149 | ALL_TARGET_HT40_22, | ||
150 | ALL_TARGET_HT40_23, | ||
151 | ar9300RateSize, | ||
152 | }; | ||
153 | |||
154 | |||
155 | struct eepFlags { | ||
156 | u8 opFlags; | ||
157 | u8 eepMisc; | ||
158 | } __packed; | ||
159 | |||
160 | enum CompressAlgorithm { | ||
161 | _CompressNone = 0, | ||
162 | _CompressLzma, | ||
163 | _CompressPairs, | ||
164 | _CompressBlock, | ||
165 | _Compress4, | ||
166 | _Compress5, | ||
167 | _Compress6, | ||
168 | _Compress7, | ||
169 | }; | ||
170 | |||
171 | struct ar9300_base_eep_hdr { | ||
172 | __le16 regDmn[2]; | ||
173 | /* 4 bits tx and 4 bits rx */ | ||
174 | u8 txrxMask; | ||
175 | struct eepFlags opCapFlags; | ||
176 | u8 rfSilent; | ||
177 | u8 blueToothOptions; | ||
178 | u8 deviceCap; | ||
179 | /* takes lower byte in eeprom location */ | ||
180 | u8 deviceType; | ||
181 | /* offset in dB to be added to beginning | ||
182 | * of pdadc table in calibration | ||
183 | */ | ||
184 | int8_t pwrTableOffset; | ||
185 | u8 params_for_tuning_caps[2]; | ||
186 | /* | ||
187 | * bit0 - enable tx temp comp | ||
188 | * bit1 - enable tx volt comp | ||
189 | * bit2 - enable fastClock - default to 1 | ||
190 | * bit3 - enable doubling - default to 1 | ||
191 | * bit4 - enable internal regulator - default to 1 | ||
192 | */ | ||
193 | u8 featureEnable; | ||
194 | /* misc flags: bit0 - turn down drivestrength */ | ||
195 | u8 miscConfiguration; | ||
196 | u8 eepromWriteEnableGpio; | ||
197 | u8 wlanDisableGpio; | ||
198 | u8 wlanLedGpio; | ||
199 | u8 rxBandSelectGpio; | ||
200 | u8 txrxgain; | ||
201 | /* SW controlled internal regulator fields */ | ||
202 | __le32 swreg; | ||
203 | } __packed; | ||
204 | |||
205 | struct ar9300_modal_eep_header { | ||
206 | /* 4 idle, t1, t2, b (4 bits per setting) */ | ||
207 | __le32 antCtrlCommon; | ||
208 | /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ | ||
209 | __le32 antCtrlCommon2; | ||
210 | /* 6 idle, t, r, rx1, rx12, b (2 bits each) */ | ||
211 | __le16 antCtrlChain[AR9300_MAX_CHAINS]; | ||
212 | /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ | ||
213 | u8 xatten1DB[AR9300_MAX_CHAINS]; | ||
214 | /* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */ | ||
215 | u8 xatten1Margin[AR9300_MAX_CHAINS]; | ||
216 | int8_t tempSlope; | ||
217 | int8_t voltSlope; | ||
218 | /* spur channels in usual fbin coding format */ | ||
219 | u8 spurChans[AR9300_EEPROM_MODAL_SPURS]; | ||
220 | /* 3 Check if the register is per chain */ | ||
221 | int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; | ||
222 | u8 ob[AR9300_MAX_CHAINS]; | ||
223 | u8 db_stage2[AR9300_MAX_CHAINS]; | ||
224 | u8 db_stage3[AR9300_MAX_CHAINS]; | ||
225 | u8 db_stage4[AR9300_MAX_CHAINS]; | ||
226 | u8 xpaBiasLvl; | ||
227 | u8 txFrameToDataStart; | ||
228 | u8 txFrameToPaOn; | ||
229 | u8 txClip; | ||
230 | int8_t antennaGain; | ||
231 | u8 switchSettling; | ||
232 | int8_t adcDesiredSize; | ||
233 | u8 txEndToXpaOff; | ||
234 | u8 txEndToRxOn; | ||
235 | u8 txFrameToXpaOn; | ||
236 | u8 thresh62; | ||
237 | u8 futureModal[32]; | ||
238 | } __packed; | ||
239 | |||
240 | struct ar9300_cal_data_per_freq_op_loop { | ||
241 | int8_t refPower; | ||
242 | /* pdadc voltage at power measurement */ | ||
243 | u8 voltMeas; | ||
244 | /* pcdac used for power measurement */ | ||
245 | u8 tempMeas; | ||
246 | /* range is -60 to -127 create a mapping equation 1db resolution */ | ||
247 | int8_t rxNoisefloorCal; | ||
248 | /*range is same as noisefloor */ | ||
249 | int8_t rxNoisefloorPower; | ||
250 | /* temp measured when noisefloor cal was performed */ | ||
251 | u8 rxTempMeas; | ||
252 | } __packed; | ||
253 | |||
254 | struct cal_tgt_pow_legacy { | ||
255 | u8 tPow2x[4]; | ||
256 | } __packed; | ||
257 | |||
258 | struct cal_tgt_pow_ht { | ||
259 | u8 tPow2x[14]; | ||
260 | } __packed; | ||
261 | |||
262 | struct cal_ctl_edge_pwr { | ||
263 | u8 tPower:6, | ||
264 | flag:2; | ||
265 | } __packed; | ||
266 | |||
267 | struct cal_ctl_data_2g { | ||
268 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G]; | ||
269 | } __packed; | ||
270 | |||
271 | struct cal_ctl_data_5g { | ||
272 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; | ||
273 | } __packed; | ||
274 | |||
275 | struct ar9300_eeprom { | ||
276 | u8 eepromVersion; | ||
277 | u8 templateVersion; | ||
278 | u8 macAddr[6]; | ||
279 | u8 custData[AR9300_CUSTOMER_DATA_SIZE]; | ||
280 | |||
281 | struct ar9300_base_eep_hdr baseEepHeader; | ||
282 | |||
283 | struct ar9300_modal_eep_header modalHeader2G; | ||
284 | u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS]; | ||
285 | struct ar9300_cal_data_per_freq_op_loop | ||
286 | calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS]; | ||
287 | u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
288 | u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
289 | u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
290 | u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; | ||
291 | struct cal_tgt_pow_legacy | ||
292 | calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
293 | struct cal_tgt_pow_legacy | ||
294 | calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
295 | struct cal_tgt_pow_ht | ||
296 | calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
297 | struct cal_tgt_pow_ht | ||
298 | calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; | ||
299 | u8 ctlIndex_2G[AR9300_NUM_CTLS_2G]; | ||
300 | u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G]; | ||
301 | struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G]; | ||
302 | struct ar9300_modal_eep_header modalHeader5G; | ||
303 | u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS]; | ||
304 | struct ar9300_cal_data_per_freq_op_loop | ||
305 | calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS]; | ||
306 | u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
307 | u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
308 | u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
309 | struct cal_tgt_pow_legacy | ||
310 | calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
311 | struct cal_tgt_pow_ht | ||
312 | calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
313 | struct cal_tgt_pow_ht | ||
314 | calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
315 | u8 ctlIndex_5G[AR9300_NUM_CTLS_5G]; | ||
316 | u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G]; | ||
317 | struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G]; | ||
318 | } __packed; | ||
319 | |||
320 | s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah); | ||
321 | s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); | ||
322 | |||
323 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c new file mode 100644 index 000000000000..b15309caf1da --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | #include "ar9003_mac.h" | ||
19 | #include "ar9003_initvals.h" | ||
20 | |||
21 | /* General hardware code for the AR9003 hadware family */ | ||
22 | |||
23 | static bool ar9003_hw_macversion_supported(u32 macversion) | ||
24 | { | ||
25 | switch (macversion) { | ||
26 | case AR_SREV_VERSION_9300: | ||
27 | return true; | ||
28 | default: | ||
29 | break; | ||
30 | } | ||
31 | return false; | ||
32 | } | ||
33 | |||
34 | /* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */ | ||
35 | /* | ||
36 | * XXX: move TX/RX gain INI to its own init_mode_gain_regs after | ||
37 | * ensuring it does not affect hardware bring up | ||
38 | */ | ||
39 | static void ar9003_hw_init_mode_regs(struct ath_hw *ah) | ||
40 | { | ||
41 | /* mac */ | ||
42 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0); | ||
43 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], | ||
44 | ar9300_2p0_mac_core, | ||
45 | ARRAY_SIZE(ar9300_2p0_mac_core), 2); | ||
46 | INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], | ||
47 | ar9300_2p0_mac_postamble, | ||
48 | ARRAY_SIZE(ar9300_2p0_mac_postamble), 5); | ||
49 | |||
50 | /* bb */ | ||
51 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0); | ||
52 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], | ||
53 | ar9300_2p0_baseband_core, | ||
54 | ARRAY_SIZE(ar9300_2p0_baseband_core), 2); | ||
55 | INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], | ||
56 | ar9300_2p0_baseband_postamble, | ||
57 | ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5); | ||
58 | |||
59 | /* radio */ | ||
60 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0); | ||
61 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], | ||
62 | ar9300_2p0_radio_core, | ||
63 | ARRAY_SIZE(ar9300_2p0_radio_core), 2); | ||
64 | INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], | ||
65 | ar9300_2p0_radio_postamble, | ||
66 | ARRAY_SIZE(ar9300_2p0_radio_postamble), 5); | ||
67 | |||
68 | /* soc */ | ||
69 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], | ||
70 | ar9300_2p0_soc_preamble, | ||
71 | ARRAY_SIZE(ar9300_2p0_soc_preamble), 2); | ||
72 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0); | ||
73 | INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], | ||
74 | ar9300_2p0_soc_postamble, | ||
75 | ARRAY_SIZE(ar9300_2p0_soc_postamble), 5); | ||
76 | |||
77 | /* rx/tx gain */ | ||
78 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
79 | ar9300Common_rx_gain_table_2p0, | ||
80 | ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2); | ||
81 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
82 | ar9300Modes_lowest_ob_db_tx_gain_table_2p0, | ||
83 | ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), | ||
84 | 5); | ||
85 | |||
86 | /* Load PCIE SERDES settings from INI */ | ||
87 | |||
88 | /* Awake Setting */ | ||
89 | |||
90 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
91 | ar9300PciePhy_pll_on_clkreq_disable_L1_2p0, | ||
92 | ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0), | ||
93 | 2); | ||
94 | |||
95 | /* Sleep Setting */ | ||
96 | |||
97 | INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, | ||
98 | ar9300PciePhy_clkreq_enable_L1_2p0, | ||
99 | ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0), | ||
100 | 2); | ||
101 | |||
102 | /* Fast clock modal settings */ | ||
103 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
104 | ar9300Modes_fast_clock_2p0, | ||
105 | ARRAY_SIZE(ar9300Modes_fast_clock_2p0), | ||
106 | 3); | ||
107 | } | ||
108 | |||
109 | static void ar9003_tx_gain_table_apply(struct ath_hw *ah) | ||
110 | { | ||
111 | switch (ar9003_hw_get_tx_gain_idx(ah)) { | ||
112 | case 0: | ||
113 | default: | ||
114 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
115 | ar9300Modes_lowest_ob_db_tx_gain_table_2p0, | ||
116 | ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0), | ||
117 | 5); | ||
118 | break; | ||
119 | case 1: | ||
120 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
121 | ar9300Modes_high_ob_db_tx_gain_table_2p0, | ||
122 | ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0), | ||
123 | 5); | ||
124 | break; | ||
125 | case 2: | ||
126 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
127 | ar9300Modes_low_ob_db_tx_gain_table_2p0, | ||
128 | ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0), | ||
129 | 5); | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void ar9003_rx_gain_table_apply(struct ath_hw *ah) | ||
135 | { | ||
136 | switch (ar9003_hw_get_rx_gain_idx(ah)) { | ||
137 | case 0: | ||
138 | default: | ||
139 | INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0, | ||
140 | ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), | ||
141 | 2); | ||
142 | break; | ||
143 | case 1: | ||
144 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
145 | ar9300Common_wo_xlna_rx_gain_table_2p0, | ||
146 | ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0), | ||
147 | 2); | ||
148 | break; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | /* set gain table pointers according to values read from the eeprom */ | ||
153 | static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah) | ||
154 | { | ||
155 | ar9003_tx_gain_table_apply(ah); | ||
156 | ar9003_rx_gain_table_apply(ah); | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Helper for ASPM support. | ||
161 | * | ||
162 | * Disable PLL when in L0s as well as receiver clock when in L1. | ||
163 | * This power saving option must be enabled through the SerDes. | ||
164 | * | ||
165 | * Programming the SerDes must go through the same 288 bit serial shift | ||
166 | * register as the other analog registers. Hence the 9 writes. | ||
167 | */ | ||
168 | static void ar9003_hw_configpcipowersave(struct ath_hw *ah, | ||
169 | int restore, | ||
170 | int power_off) | ||
171 | { | ||
172 | if (ah->is_pciexpress != true) | ||
173 | return; | ||
174 | |||
175 | /* Do not touch SerDes registers */ | ||
176 | if (ah->config.pcie_powersave_enable == 2) | ||
177 | return; | ||
178 | |||
179 | /* Nothing to do on restore for 11N */ | ||
180 | if (!restore) { | ||
181 | /* set bit 19 to allow forcing of pcie core into L1 state */ | ||
182 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); | ||
183 | |||
184 | /* Several PCIe massages to ensure proper behaviour */ | ||
185 | if (ah->config.pcie_waen) | ||
186 | REG_WRITE(ah, AR_WA, ah->config.pcie_waen); | ||
187 | } | ||
188 | } | ||
189 | |||
190 | /* Sets up the AR9003 hardware familiy callbacks */ | ||
191 | void ar9003_hw_attach_ops(struct ath_hw *ah) | ||
192 | { | ||
193 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
194 | struct ath_hw_ops *ops = ath9k_hw_ops(ah); | ||
195 | |||
196 | priv_ops->init_mode_regs = ar9003_hw_init_mode_regs; | ||
197 | priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; | ||
198 | priv_ops->macversion_supported = ar9003_hw_macversion_supported; | ||
199 | |||
200 | ops->config_pci_powersave = ar9003_hw_configpcipowersave; | ||
201 | |||
202 | ar9003_hw_attach_phy_ops(ah); | ||
203 | ar9003_hw_attach_calib_ops(ah); | ||
204 | ar9003_hw_attach_mac_ops(ah); | ||
205 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h new file mode 100644 index 000000000000..db019dd220b7 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_initvals.h | |||
@@ -0,0 +1,1784 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef INITVALS_9003_H | ||
18 | #define INITVALS_9003_H | ||
19 | |||
20 | /* AR9003 2.0 */ | ||
21 | |||
22 | static const u32 ar9300_2p0_radio_postamble[][5] = { | ||
23 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
24 | {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, | ||
25 | {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, | ||
26 | {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, | ||
27 | {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, | ||
28 | {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, | ||
29 | {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, | ||
30 | {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, | ||
31 | {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, | ||
32 | {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, | ||
33 | }; | ||
34 | |||
35 | static const u32 ar9300Modes_lowest_ob_db_tx_gain_table_2p0[][5] = { | ||
36 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
37 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
38 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
39 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
40 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
41 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
42 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
43 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, | ||
44 | {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, | ||
45 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
46 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, | ||
47 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, | ||
48 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, | ||
49 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, | ||
50 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, | ||
51 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, | ||
52 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | ||
53 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | ||
54 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | ||
55 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | ||
56 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | ||
57 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, | ||
58 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, | ||
59 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, | ||
60 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, | ||
61 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, | ||
62 | {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, | ||
63 | {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
64 | {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
65 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
66 | {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
67 | {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
68 | {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
69 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
70 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
71 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
72 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
73 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
74 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
75 | {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, | ||
76 | {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, | ||
77 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
78 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, | ||
79 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, | ||
80 | {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, | ||
81 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, | ||
82 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, | ||
83 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, | ||
84 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | ||
85 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | ||
86 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | ||
87 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | ||
88 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | ||
89 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, | ||
90 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, | ||
91 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, | ||
92 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, | ||
93 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, | ||
94 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, | ||
95 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
96 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
97 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
98 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
99 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
100 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
101 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
102 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
103 | {0x00016048, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, | ||
104 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
105 | {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
106 | {0x00016448, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, | ||
107 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
108 | {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
109 | {0x00016848, 0x62480001, 0x62480001, 0x62480001, 0x62480001}, | ||
110 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
111 | }; | ||
112 | |||
113 | static const u32 ar9300Modes_fast_clock_2p0[][3] = { | ||
114 | /* Addr 5G_HT20 5G_HT40 */ | ||
115 | {0x00001030, 0x00000268, 0x000004d0}, | ||
116 | {0x00001070, 0x0000018c, 0x00000318}, | ||
117 | {0x000010b0, 0x00000fd0, 0x00001fa0}, | ||
118 | {0x00008014, 0x044c044c, 0x08980898}, | ||
119 | {0x0000801c, 0x148ec02b, 0x148ec057}, | ||
120 | {0x00008318, 0x000044c0, 0x00008980}, | ||
121 | {0x00009e00, 0x03721821, 0x03721821}, | ||
122 | {0x0000a230, 0x0000000b, 0x00000016}, | ||
123 | {0x0000a254, 0x00000898, 0x00001130}, | ||
124 | }; | ||
125 | |||
126 | static const u32 ar9300_2p0_radio_core[][2] = { | ||
127 | /* Addr allmodes */ | ||
128 | {0x00016000, 0x36db6db6}, | ||
129 | {0x00016004, 0x6db6db40}, | ||
130 | {0x00016008, 0x73f00000}, | ||
131 | {0x0001600c, 0x00000000}, | ||
132 | {0x00016040, 0x7f80fff8}, | ||
133 | {0x0001604c, 0x76d005b5}, | ||
134 | {0x00016050, 0x556cf031}, | ||
135 | {0x00016054, 0x13449440}, | ||
136 | {0x00016058, 0x0c51c92c}, | ||
137 | {0x0001605c, 0x3db7fffc}, | ||
138 | {0x00016060, 0xfffffffc}, | ||
139 | {0x00016064, 0x000f0278}, | ||
140 | {0x0001606c, 0x6db60000}, | ||
141 | {0x00016080, 0x00000000}, | ||
142 | {0x00016084, 0x0e48048c}, | ||
143 | {0x00016088, 0x54214514}, | ||
144 | {0x0001608c, 0x119f481e}, | ||
145 | {0x00016090, 0x24926490}, | ||
146 | {0x00016098, 0xd2888888}, | ||
147 | {0x000160a0, 0x0a108ffe}, | ||
148 | {0x000160a4, 0x812fc370}, | ||
149 | {0x000160a8, 0x423c8000}, | ||
150 | {0x000160b4, 0x92480080}, | ||
151 | {0x000160c0, 0x00adb6d0}, | ||
152 | {0x000160c4, 0x6db6db60}, | ||
153 | {0x000160c8, 0x6db6db6c}, | ||
154 | {0x000160cc, 0x01e6c000}, | ||
155 | {0x00016100, 0x3fffbe01}, | ||
156 | {0x00016104, 0xfff80000}, | ||
157 | {0x00016108, 0x00080010}, | ||
158 | {0x00016144, 0x02084080}, | ||
159 | {0x00016148, 0x00000000}, | ||
160 | {0x00016280, 0x058a0001}, | ||
161 | {0x00016284, 0x3d840208}, | ||
162 | {0x00016288, 0x05a20408}, | ||
163 | {0x0001628c, 0x00038c07}, | ||
164 | {0x00016290, 0x40000004}, | ||
165 | {0x00016294, 0x458aa14f}, | ||
166 | {0x00016380, 0x00000000}, | ||
167 | {0x00016384, 0x00000000}, | ||
168 | {0x00016388, 0x00800700}, | ||
169 | {0x0001638c, 0x00800700}, | ||
170 | {0x00016390, 0x00800700}, | ||
171 | {0x00016394, 0x00000000}, | ||
172 | {0x00016398, 0x00000000}, | ||
173 | {0x0001639c, 0x00000000}, | ||
174 | {0x000163a0, 0x00000001}, | ||
175 | {0x000163a4, 0x00000001}, | ||
176 | {0x000163a8, 0x00000000}, | ||
177 | {0x000163ac, 0x00000000}, | ||
178 | {0x000163b0, 0x00000000}, | ||
179 | {0x000163b4, 0x00000000}, | ||
180 | {0x000163b8, 0x00000000}, | ||
181 | {0x000163bc, 0x00000000}, | ||
182 | {0x000163c0, 0x000000a0}, | ||
183 | {0x000163c4, 0x000c0000}, | ||
184 | {0x000163c8, 0x14021402}, | ||
185 | {0x000163cc, 0x00001402}, | ||
186 | {0x000163d0, 0x00000000}, | ||
187 | {0x000163d4, 0x00000000}, | ||
188 | {0x00016400, 0x36db6db6}, | ||
189 | {0x00016404, 0x6db6db40}, | ||
190 | {0x00016408, 0x73f00000}, | ||
191 | {0x0001640c, 0x00000000}, | ||
192 | {0x00016440, 0x7f80fff8}, | ||
193 | {0x0001644c, 0x76d005b5}, | ||
194 | {0x00016450, 0x556cf031}, | ||
195 | {0x00016454, 0x13449440}, | ||
196 | {0x00016458, 0x0c51c92c}, | ||
197 | {0x0001645c, 0x3db7fffc}, | ||
198 | {0x00016460, 0xfffffffc}, | ||
199 | {0x00016464, 0x000f0278}, | ||
200 | {0x0001646c, 0x6db60000}, | ||
201 | {0x00016500, 0x3fffbe01}, | ||
202 | {0x00016504, 0xfff80000}, | ||
203 | {0x00016508, 0x00080010}, | ||
204 | {0x00016544, 0x02084080}, | ||
205 | {0x00016548, 0x00000000}, | ||
206 | {0x00016780, 0x00000000}, | ||
207 | {0x00016784, 0x00000000}, | ||
208 | {0x00016788, 0x00800700}, | ||
209 | {0x0001678c, 0x00800700}, | ||
210 | {0x00016790, 0x00800700}, | ||
211 | {0x00016794, 0x00000000}, | ||
212 | {0x00016798, 0x00000000}, | ||
213 | {0x0001679c, 0x00000000}, | ||
214 | {0x000167a0, 0x00000001}, | ||
215 | {0x000167a4, 0x00000001}, | ||
216 | {0x000167a8, 0x00000000}, | ||
217 | {0x000167ac, 0x00000000}, | ||
218 | {0x000167b0, 0x00000000}, | ||
219 | {0x000167b4, 0x00000000}, | ||
220 | {0x000167b8, 0x00000000}, | ||
221 | {0x000167bc, 0x00000000}, | ||
222 | {0x000167c0, 0x000000a0}, | ||
223 | {0x000167c4, 0x000c0000}, | ||
224 | {0x000167c8, 0x14021402}, | ||
225 | {0x000167cc, 0x00001402}, | ||
226 | {0x000167d0, 0x00000000}, | ||
227 | {0x000167d4, 0x00000000}, | ||
228 | {0x00016800, 0x36db6db6}, | ||
229 | {0x00016804, 0x6db6db40}, | ||
230 | {0x00016808, 0x73f00000}, | ||
231 | {0x0001680c, 0x00000000}, | ||
232 | {0x00016840, 0x7f80fff8}, | ||
233 | {0x0001684c, 0x76d005b5}, | ||
234 | {0x00016850, 0x556cf031}, | ||
235 | {0x00016854, 0x13449440}, | ||
236 | {0x00016858, 0x0c51c92c}, | ||
237 | {0x0001685c, 0x3db7fffc}, | ||
238 | {0x00016860, 0xfffffffc}, | ||
239 | {0x00016864, 0x000f0278}, | ||
240 | {0x0001686c, 0x6db60000}, | ||
241 | {0x00016900, 0x3fffbe01}, | ||
242 | {0x00016904, 0xfff80000}, | ||
243 | {0x00016908, 0x00080010}, | ||
244 | {0x00016944, 0x02084080}, | ||
245 | {0x00016948, 0x00000000}, | ||
246 | {0x00016b80, 0x00000000}, | ||
247 | {0x00016b84, 0x00000000}, | ||
248 | {0x00016b88, 0x00800700}, | ||
249 | {0x00016b8c, 0x00800700}, | ||
250 | {0x00016b90, 0x00800700}, | ||
251 | {0x00016b94, 0x00000000}, | ||
252 | {0x00016b98, 0x00000000}, | ||
253 | {0x00016b9c, 0x00000000}, | ||
254 | {0x00016ba0, 0x00000001}, | ||
255 | {0x00016ba4, 0x00000001}, | ||
256 | {0x00016ba8, 0x00000000}, | ||
257 | {0x00016bac, 0x00000000}, | ||
258 | {0x00016bb0, 0x00000000}, | ||
259 | {0x00016bb4, 0x00000000}, | ||
260 | {0x00016bb8, 0x00000000}, | ||
261 | {0x00016bbc, 0x00000000}, | ||
262 | {0x00016bc0, 0x000000a0}, | ||
263 | {0x00016bc4, 0x000c0000}, | ||
264 | {0x00016bc8, 0x14021402}, | ||
265 | {0x00016bcc, 0x00001402}, | ||
266 | {0x00016bd0, 0x00000000}, | ||
267 | {0x00016bd4, 0x00000000}, | ||
268 | }; | ||
269 | |||
270 | static const u32 ar9300Common_rx_gain_table_merlin_2p0[][2] = { | ||
271 | /* Addr allmodes */ | ||
272 | {0x0000a000, 0x02000101}, | ||
273 | {0x0000a004, 0x02000102}, | ||
274 | {0x0000a008, 0x02000103}, | ||
275 | {0x0000a00c, 0x02000104}, | ||
276 | {0x0000a010, 0x02000200}, | ||
277 | {0x0000a014, 0x02000201}, | ||
278 | {0x0000a018, 0x02000202}, | ||
279 | {0x0000a01c, 0x02000203}, | ||
280 | {0x0000a020, 0x02000204}, | ||
281 | {0x0000a024, 0x02000205}, | ||
282 | {0x0000a028, 0x02000208}, | ||
283 | {0x0000a02c, 0x02000302}, | ||
284 | {0x0000a030, 0x02000303}, | ||
285 | {0x0000a034, 0x02000304}, | ||
286 | {0x0000a038, 0x02000400}, | ||
287 | {0x0000a03c, 0x02010300}, | ||
288 | {0x0000a040, 0x02010301}, | ||
289 | {0x0000a044, 0x02010302}, | ||
290 | {0x0000a048, 0x02000500}, | ||
291 | {0x0000a04c, 0x02010400}, | ||
292 | {0x0000a050, 0x02020300}, | ||
293 | {0x0000a054, 0x02020301}, | ||
294 | {0x0000a058, 0x02020302}, | ||
295 | {0x0000a05c, 0x02020303}, | ||
296 | {0x0000a060, 0x02020400}, | ||
297 | {0x0000a064, 0x02030300}, | ||
298 | {0x0000a068, 0x02030301}, | ||
299 | {0x0000a06c, 0x02030302}, | ||
300 | {0x0000a070, 0x02030303}, | ||
301 | {0x0000a074, 0x02030400}, | ||
302 | {0x0000a078, 0x02040300}, | ||
303 | {0x0000a07c, 0x02040301}, | ||
304 | {0x0000a080, 0x02040302}, | ||
305 | {0x0000a084, 0x02040303}, | ||
306 | {0x0000a088, 0x02030500}, | ||
307 | {0x0000a08c, 0x02040400}, | ||
308 | {0x0000a090, 0x02050203}, | ||
309 | {0x0000a094, 0x02050204}, | ||
310 | {0x0000a098, 0x02050205}, | ||
311 | {0x0000a09c, 0x02040500}, | ||
312 | {0x0000a0a0, 0x02050301}, | ||
313 | {0x0000a0a4, 0x02050302}, | ||
314 | {0x0000a0a8, 0x02050303}, | ||
315 | {0x0000a0ac, 0x02050400}, | ||
316 | {0x0000a0b0, 0x02050401}, | ||
317 | {0x0000a0b4, 0x02050402}, | ||
318 | {0x0000a0b8, 0x02050403}, | ||
319 | {0x0000a0bc, 0x02050500}, | ||
320 | {0x0000a0c0, 0x02050501}, | ||
321 | {0x0000a0c4, 0x02050502}, | ||
322 | {0x0000a0c8, 0x02050503}, | ||
323 | {0x0000a0cc, 0x02050504}, | ||
324 | {0x0000a0d0, 0x02050600}, | ||
325 | {0x0000a0d4, 0x02050601}, | ||
326 | {0x0000a0d8, 0x02050602}, | ||
327 | {0x0000a0dc, 0x02050603}, | ||
328 | {0x0000a0e0, 0x02050604}, | ||
329 | {0x0000a0e4, 0x02050700}, | ||
330 | {0x0000a0e8, 0x02050701}, | ||
331 | {0x0000a0ec, 0x02050702}, | ||
332 | {0x0000a0f0, 0x02050703}, | ||
333 | {0x0000a0f4, 0x02050704}, | ||
334 | {0x0000a0f8, 0x02050705}, | ||
335 | {0x0000a0fc, 0x02050708}, | ||
336 | {0x0000a100, 0x02050709}, | ||
337 | {0x0000a104, 0x0205070a}, | ||
338 | {0x0000a108, 0x0205070b}, | ||
339 | {0x0000a10c, 0x0205070c}, | ||
340 | {0x0000a110, 0x0205070d}, | ||
341 | {0x0000a114, 0x02050710}, | ||
342 | {0x0000a118, 0x02050711}, | ||
343 | {0x0000a11c, 0x02050712}, | ||
344 | {0x0000a120, 0x02050713}, | ||
345 | {0x0000a124, 0x02050714}, | ||
346 | {0x0000a128, 0x02050715}, | ||
347 | {0x0000a12c, 0x02050730}, | ||
348 | {0x0000a130, 0x02050731}, | ||
349 | {0x0000a134, 0x02050732}, | ||
350 | {0x0000a138, 0x02050733}, | ||
351 | {0x0000a13c, 0x02050734}, | ||
352 | {0x0000a140, 0x02050735}, | ||
353 | {0x0000a144, 0x02050750}, | ||
354 | {0x0000a148, 0x02050751}, | ||
355 | {0x0000a14c, 0x02050752}, | ||
356 | {0x0000a150, 0x02050753}, | ||
357 | {0x0000a154, 0x02050754}, | ||
358 | {0x0000a158, 0x02050755}, | ||
359 | {0x0000a15c, 0x02050770}, | ||
360 | {0x0000a160, 0x02050771}, | ||
361 | {0x0000a164, 0x02050772}, | ||
362 | {0x0000a168, 0x02050773}, | ||
363 | {0x0000a16c, 0x02050774}, | ||
364 | {0x0000a170, 0x02050775}, | ||
365 | {0x0000a174, 0x00000776}, | ||
366 | {0x0000a178, 0x00000776}, | ||
367 | {0x0000a17c, 0x00000776}, | ||
368 | {0x0000a180, 0x00000776}, | ||
369 | {0x0000a184, 0x00000776}, | ||
370 | {0x0000a188, 0x00000776}, | ||
371 | {0x0000a18c, 0x00000776}, | ||
372 | {0x0000a190, 0x00000776}, | ||
373 | {0x0000a194, 0x00000776}, | ||
374 | {0x0000a198, 0x00000776}, | ||
375 | {0x0000a19c, 0x00000776}, | ||
376 | {0x0000a1a0, 0x00000776}, | ||
377 | {0x0000a1a4, 0x00000776}, | ||
378 | {0x0000a1a8, 0x00000776}, | ||
379 | {0x0000a1ac, 0x00000776}, | ||
380 | {0x0000a1b0, 0x00000776}, | ||
381 | {0x0000a1b4, 0x00000776}, | ||
382 | {0x0000a1b8, 0x00000776}, | ||
383 | {0x0000a1bc, 0x00000776}, | ||
384 | {0x0000a1c0, 0x00000776}, | ||
385 | {0x0000a1c4, 0x00000776}, | ||
386 | {0x0000a1c8, 0x00000776}, | ||
387 | {0x0000a1cc, 0x00000776}, | ||
388 | {0x0000a1d0, 0x00000776}, | ||
389 | {0x0000a1d4, 0x00000776}, | ||
390 | {0x0000a1d8, 0x00000776}, | ||
391 | {0x0000a1dc, 0x00000776}, | ||
392 | {0x0000a1e0, 0x00000776}, | ||
393 | {0x0000a1e4, 0x00000776}, | ||
394 | {0x0000a1e8, 0x00000776}, | ||
395 | {0x0000a1ec, 0x00000776}, | ||
396 | {0x0000a1f0, 0x00000776}, | ||
397 | {0x0000a1f4, 0x00000776}, | ||
398 | {0x0000a1f8, 0x00000776}, | ||
399 | {0x0000a1fc, 0x00000776}, | ||
400 | {0x0000b000, 0x02000101}, | ||
401 | {0x0000b004, 0x02000102}, | ||
402 | {0x0000b008, 0x02000103}, | ||
403 | {0x0000b00c, 0x02000104}, | ||
404 | {0x0000b010, 0x02000200}, | ||
405 | {0x0000b014, 0x02000201}, | ||
406 | {0x0000b018, 0x02000202}, | ||
407 | {0x0000b01c, 0x02000203}, | ||
408 | {0x0000b020, 0x02000204}, | ||
409 | {0x0000b024, 0x02000205}, | ||
410 | {0x0000b028, 0x02000208}, | ||
411 | {0x0000b02c, 0x02000302}, | ||
412 | {0x0000b030, 0x02000303}, | ||
413 | {0x0000b034, 0x02000304}, | ||
414 | {0x0000b038, 0x02000400}, | ||
415 | {0x0000b03c, 0x02010300}, | ||
416 | {0x0000b040, 0x02010301}, | ||
417 | {0x0000b044, 0x02010302}, | ||
418 | {0x0000b048, 0x02000500}, | ||
419 | {0x0000b04c, 0x02010400}, | ||
420 | {0x0000b050, 0x02020300}, | ||
421 | {0x0000b054, 0x02020301}, | ||
422 | {0x0000b058, 0x02020302}, | ||
423 | {0x0000b05c, 0x02020303}, | ||
424 | {0x0000b060, 0x02020400}, | ||
425 | {0x0000b064, 0x02030300}, | ||
426 | {0x0000b068, 0x02030301}, | ||
427 | {0x0000b06c, 0x02030302}, | ||
428 | {0x0000b070, 0x02030303}, | ||
429 | {0x0000b074, 0x02030400}, | ||
430 | {0x0000b078, 0x02040300}, | ||
431 | {0x0000b07c, 0x02040301}, | ||
432 | {0x0000b080, 0x02040302}, | ||
433 | {0x0000b084, 0x02040303}, | ||
434 | {0x0000b088, 0x02030500}, | ||
435 | {0x0000b08c, 0x02040400}, | ||
436 | {0x0000b090, 0x02050203}, | ||
437 | {0x0000b094, 0x02050204}, | ||
438 | {0x0000b098, 0x02050205}, | ||
439 | {0x0000b09c, 0x02040500}, | ||
440 | {0x0000b0a0, 0x02050301}, | ||
441 | {0x0000b0a4, 0x02050302}, | ||
442 | {0x0000b0a8, 0x02050303}, | ||
443 | {0x0000b0ac, 0x02050400}, | ||
444 | {0x0000b0b0, 0x02050401}, | ||
445 | {0x0000b0b4, 0x02050402}, | ||
446 | {0x0000b0b8, 0x02050403}, | ||
447 | {0x0000b0bc, 0x02050500}, | ||
448 | {0x0000b0c0, 0x02050501}, | ||
449 | {0x0000b0c4, 0x02050502}, | ||
450 | {0x0000b0c8, 0x02050503}, | ||
451 | {0x0000b0cc, 0x02050504}, | ||
452 | {0x0000b0d0, 0x02050600}, | ||
453 | {0x0000b0d4, 0x02050601}, | ||
454 | {0x0000b0d8, 0x02050602}, | ||
455 | {0x0000b0dc, 0x02050603}, | ||
456 | {0x0000b0e0, 0x02050604}, | ||
457 | {0x0000b0e4, 0x02050700}, | ||
458 | {0x0000b0e8, 0x02050701}, | ||
459 | {0x0000b0ec, 0x02050702}, | ||
460 | {0x0000b0f0, 0x02050703}, | ||
461 | {0x0000b0f4, 0x02050704}, | ||
462 | {0x0000b0f8, 0x02050705}, | ||
463 | {0x0000b0fc, 0x02050708}, | ||
464 | {0x0000b100, 0x02050709}, | ||
465 | {0x0000b104, 0x0205070a}, | ||
466 | {0x0000b108, 0x0205070b}, | ||
467 | {0x0000b10c, 0x0205070c}, | ||
468 | {0x0000b110, 0x0205070d}, | ||
469 | {0x0000b114, 0x02050710}, | ||
470 | {0x0000b118, 0x02050711}, | ||
471 | {0x0000b11c, 0x02050712}, | ||
472 | {0x0000b120, 0x02050713}, | ||
473 | {0x0000b124, 0x02050714}, | ||
474 | {0x0000b128, 0x02050715}, | ||
475 | {0x0000b12c, 0x02050730}, | ||
476 | {0x0000b130, 0x02050731}, | ||
477 | {0x0000b134, 0x02050732}, | ||
478 | {0x0000b138, 0x02050733}, | ||
479 | {0x0000b13c, 0x02050734}, | ||
480 | {0x0000b140, 0x02050735}, | ||
481 | {0x0000b144, 0x02050750}, | ||
482 | {0x0000b148, 0x02050751}, | ||
483 | {0x0000b14c, 0x02050752}, | ||
484 | {0x0000b150, 0x02050753}, | ||
485 | {0x0000b154, 0x02050754}, | ||
486 | {0x0000b158, 0x02050755}, | ||
487 | {0x0000b15c, 0x02050770}, | ||
488 | {0x0000b160, 0x02050771}, | ||
489 | {0x0000b164, 0x02050772}, | ||
490 | {0x0000b168, 0x02050773}, | ||
491 | {0x0000b16c, 0x02050774}, | ||
492 | {0x0000b170, 0x02050775}, | ||
493 | {0x0000b174, 0x00000776}, | ||
494 | {0x0000b178, 0x00000776}, | ||
495 | {0x0000b17c, 0x00000776}, | ||
496 | {0x0000b180, 0x00000776}, | ||
497 | {0x0000b184, 0x00000776}, | ||
498 | {0x0000b188, 0x00000776}, | ||
499 | {0x0000b18c, 0x00000776}, | ||
500 | {0x0000b190, 0x00000776}, | ||
501 | {0x0000b194, 0x00000776}, | ||
502 | {0x0000b198, 0x00000776}, | ||
503 | {0x0000b19c, 0x00000776}, | ||
504 | {0x0000b1a0, 0x00000776}, | ||
505 | {0x0000b1a4, 0x00000776}, | ||
506 | {0x0000b1a8, 0x00000776}, | ||
507 | {0x0000b1ac, 0x00000776}, | ||
508 | {0x0000b1b0, 0x00000776}, | ||
509 | {0x0000b1b4, 0x00000776}, | ||
510 | {0x0000b1b8, 0x00000776}, | ||
511 | {0x0000b1bc, 0x00000776}, | ||
512 | {0x0000b1c0, 0x00000776}, | ||
513 | {0x0000b1c4, 0x00000776}, | ||
514 | {0x0000b1c8, 0x00000776}, | ||
515 | {0x0000b1cc, 0x00000776}, | ||
516 | {0x0000b1d0, 0x00000776}, | ||
517 | {0x0000b1d4, 0x00000776}, | ||
518 | {0x0000b1d8, 0x00000776}, | ||
519 | {0x0000b1dc, 0x00000776}, | ||
520 | {0x0000b1e0, 0x00000776}, | ||
521 | {0x0000b1e4, 0x00000776}, | ||
522 | {0x0000b1e8, 0x00000776}, | ||
523 | {0x0000b1ec, 0x00000776}, | ||
524 | {0x0000b1f0, 0x00000776}, | ||
525 | {0x0000b1f4, 0x00000776}, | ||
526 | {0x0000b1f8, 0x00000776}, | ||
527 | {0x0000b1fc, 0x00000776}, | ||
528 | }; | ||
529 | |||
530 | static const u32 ar9300_2p0_mac_postamble[][5] = { | ||
531 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
532 | {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, | ||
533 | {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, | ||
534 | {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, | ||
535 | {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, | ||
536 | {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, | ||
537 | {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, | ||
538 | {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, | ||
539 | {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, | ||
540 | }; | ||
541 | |||
542 | static const u32 ar9300_2p0_soc_postamble[][5] = { | ||
543 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
544 | {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023}, | ||
545 | }; | ||
546 | |||
547 | static const u32 ar9200_merlin_2p0_radio_core[][2] = { | ||
548 | /* Addr allmodes */ | ||
549 | {0x00007800, 0x00040000}, | ||
550 | {0x00007804, 0xdb005012}, | ||
551 | {0x00007808, 0x04924914}, | ||
552 | {0x0000780c, 0x21084210}, | ||
553 | {0x00007810, 0x6d801300}, | ||
554 | {0x00007814, 0x0019beff}, | ||
555 | {0x00007818, 0x07e41000}, | ||
556 | {0x0000781c, 0x00392000}, | ||
557 | {0x00007820, 0x92592480}, | ||
558 | {0x00007824, 0x00040000}, | ||
559 | {0x00007828, 0xdb005012}, | ||
560 | {0x0000782c, 0x04924914}, | ||
561 | {0x00007830, 0x21084210}, | ||
562 | {0x00007834, 0x6d801300}, | ||
563 | {0x00007838, 0x0019beff}, | ||
564 | {0x0000783c, 0x07e40000}, | ||
565 | {0x00007840, 0x00392000}, | ||
566 | {0x00007844, 0x92592480}, | ||
567 | {0x00007848, 0x00100000}, | ||
568 | {0x0000784c, 0x773f0567}, | ||
569 | {0x00007850, 0x54214514}, | ||
570 | {0x00007854, 0x12035828}, | ||
571 | {0x00007858, 0x92592692}, | ||
572 | {0x0000785c, 0x00000000}, | ||
573 | {0x00007860, 0x56400000}, | ||
574 | {0x00007864, 0x0a8e370e}, | ||
575 | {0x00007868, 0xc0102850}, | ||
576 | {0x0000786c, 0x812d4000}, | ||
577 | {0x00007870, 0x807ec400}, | ||
578 | {0x00007874, 0x001b6db0}, | ||
579 | {0x00007878, 0x00376b63}, | ||
580 | {0x0000787c, 0x06db6db6}, | ||
581 | {0x00007880, 0x006d8000}, | ||
582 | {0x00007884, 0xffeffffe}, | ||
583 | {0x00007888, 0xffeffffe}, | ||
584 | {0x0000788c, 0x00010000}, | ||
585 | {0x00007890, 0x02060aeb}, | ||
586 | {0x00007894, 0x5a108000}, | ||
587 | }; | ||
588 | |||
589 | static const u32 ar9300_2p0_baseband_postamble[][5] = { | ||
590 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
591 | {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011}, | ||
592 | {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a012e}, | ||
593 | {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0}, | ||
594 | {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881}, | ||
595 | {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, | ||
596 | {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c}, | ||
597 | {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044}, | ||
598 | {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0}, | ||
599 | {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, | ||
600 | {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2}, | ||
601 | {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec84d2e}, | ||
602 | {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e}, | ||
603 | {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
604 | {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, | ||
605 | {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, | ||
606 | {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, | ||
607 | {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27}, | ||
608 | {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, | ||
609 | {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, | ||
610 | {0x0000a204, 0x000037c0, 0x000037c4, 0x000037c4, 0x000037c0}, | ||
611 | {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, | ||
612 | {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b}, | ||
613 | {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, | ||
614 | {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, | ||
615 | {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, | ||
616 | {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, | ||
617 | {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, | ||
618 | {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, | ||
619 | {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, | ||
620 | {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, | ||
621 | {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
622 | {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, | ||
623 | {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, | ||
624 | {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, | ||
625 | {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982}, | ||
626 | {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a}, | ||
627 | {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
628 | {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
629 | {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
630 | {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
631 | {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
632 | {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | ||
633 | {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
634 | {0x0000b830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
635 | {0x0000be04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
636 | {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
637 | {0x0000be1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, | ||
638 | {0x0000be20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, | ||
639 | {0x0000c284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, | ||
640 | }; | ||
641 | |||
642 | static const u32 ar9300_2p0_baseband_core[][2] = { | ||
643 | /* Addr allmodes */ | ||
644 | {0x00009800, 0xafe68e30}, | ||
645 | {0x00009804, 0xfd14e000}, | ||
646 | {0x00009808, 0x9c0a9f6b}, | ||
647 | {0x0000980c, 0x04900000}, | ||
648 | {0x00009814, 0x9280c00a}, | ||
649 | {0x00009818, 0x00000000}, | ||
650 | {0x0000981c, 0x00020028}, | ||
651 | {0x00009834, 0x5f3ca3de}, | ||
652 | {0x00009838, 0x0108ecff}, | ||
653 | {0x0000983c, 0x14750600}, | ||
654 | {0x00009880, 0x201fff00}, | ||
655 | {0x00009884, 0x00001042}, | ||
656 | {0x000098a4, 0x00200400}, | ||
657 | {0x000098b0, 0x52440bbe}, | ||
658 | {0x000098d0, 0x004b6a8e}, | ||
659 | {0x000098d4, 0x00000820}, | ||
660 | {0x000098dc, 0x00000000}, | ||
661 | {0x000098f0, 0x00000000}, | ||
662 | {0x000098f4, 0x00000000}, | ||
663 | {0x00009c04, 0xff55ff55}, | ||
664 | {0x00009c08, 0x0320ff55}, | ||
665 | {0x00009c0c, 0x00000000}, | ||
666 | {0x00009c10, 0x00000000}, | ||
667 | {0x00009c14, 0x00046384}, | ||
668 | {0x00009c18, 0x05b6b440}, | ||
669 | {0x00009c1c, 0x00b6b440}, | ||
670 | {0x00009d00, 0xc080a333}, | ||
671 | {0x00009d04, 0x40206c10}, | ||
672 | {0x00009d08, 0x009c4060}, | ||
673 | {0x00009d0c, 0x9883800a}, | ||
674 | {0x00009d10, 0x01834061}, | ||
675 | {0x00009d14, 0x00c0040b}, | ||
676 | {0x00009d18, 0x00000000}, | ||
677 | {0x00009e08, 0x0038230c}, | ||
678 | {0x00009e24, 0x990bb515}, | ||
679 | {0x00009e28, 0x0c6f0000}, | ||
680 | {0x00009e30, 0x06336f77}, | ||
681 | {0x00009e34, 0x6af6532f}, | ||
682 | {0x00009e38, 0x0cc80c00}, | ||
683 | {0x00009e3c, 0xcf946222}, | ||
684 | {0x00009e40, 0x0d261820}, | ||
685 | {0x00009e4c, 0x00001004}, | ||
686 | {0x00009e50, 0x00ff03f1}, | ||
687 | {0x00009e54, 0x00000000}, | ||
688 | {0x00009fc0, 0x803e4788}, | ||
689 | {0x00009fc4, 0x0001efb5}, | ||
690 | {0x00009fcc, 0x40000014}, | ||
691 | {0x00009fd0, 0x01193b93}, | ||
692 | {0x0000a20c, 0x00000000}, | ||
693 | {0x0000a220, 0x00000000}, | ||
694 | {0x0000a224, 0x00000000}, | ||
695 | {0x0000a228, 0x10002310}, | ||
696 | {0x0000a22c, 0x01036a1e}, | ||
697 | {0x0000a234, 0x10000fff}, | ||
698 | {0x0000a23c, 0x00000000}, | ||
699 | {0x0000a244, 0x0c000000}, | ||
700 | {0x0000a2a0, 0x00000001}, | ||
701 | {0x0000a2c0, 0x00000001}, | ||
702 | {0x0000a2c8, 0x00000000}, | ||
703 | {0x0000a2cc, 0x18c43433}, | ||
704 | {0x0000a2d4, 0x00000000}, | ||
705 | {0x0000a2dc, 0x00000000}, | ||
706 | {0x0000a2e0, 0x00000000}, | ||
707 | {0x0000a2e4, 0x00000000}, | ||
708 | {0x0000a2e8, 0x00000000}, | ||
709 | {0x0000a2ec, 0x00000000}, | ||
710 | {0x0000a2f0, 0x00000000}, | ||
711 | {0x0000a2f4, 0x00000000}, | ||
712 | {0x0000a2f8, 0x00000000}, | ||
713 | {0x0000a344, 0x00000000}, | ||
714 | {0x0000a34c, 0x00000000}, | ||
715 | {0x0000a350, 0x0000a000}, | ||
716 | {0x0000a364, 0x00000000}, | ||
717 | {0x0000a370, 0x00000000}, | ||
718 | {0x0000a390, 0x00000001}, | ||
719 | {0x0000a394, 0x00000444}, | ||
720 | {0x0000a398, 0x001f0e0f}, | ||
721 | {0x0000a39c, 0x0075393f}, | ||
722 | {0x0000a3a0, 0xb79f6427}, | ||
723 | {0x0000a3a4, 0x00000000}, | ||
724 | {0x0000a3a8, 0xaaaaaaaa}, | ||
725 | {0x0000a3ac, 0x3c466478}, | ||
726 | {0x0000a3c0, 0x20202020}, | ||
727 | {0x0000a3c4, 0x22222220}, | ||
728 | {0x0000a3c8, 0x20200020}, | ||
729 | {0x0000a3cc, 0x20202020}, | ||
730 | {0x0000a3d0, 0x20202020}, | ||
731 | {0x0000a3d4, 0x20202020}, | ||
732 | {0x0000a3d8, 0x20202020}, | ||
733 | {0x0000a3dc, 0x20202020}, | ||
734 | {0x0000a3e0, 0x20202020}, | ||
735 | {0x0000a3e4, 0x20202020}, | ||
736 | {0x0000a3e8, 0x20202020}, | ||
737 | {0x0000a3ec, 0x20202020}, | ||
738 | {0x0000a3f0, 0x00000000}, | ||
739 | {0x0000a3f4, 0x00000246}, | ||
740 | {0x0000a3f8, 0x0cdbd380}, | ||
741 | {0x0000a3fc, 0x000f0f01}, | ||
742 | {0x0000a400, 0x8fa91f01}, | ||
743 | {0x0000a404, 0x00000000}, | ||
744 | {0x0000a408, 0x0e79e5c6}, | ||
745 | {0x0000a40c, 0x00820820}, | ||
746 | {0x0000a414, 0x1ce739ce}, | ||
747 | {0x0000a418, 0x2d001dce}, | ||
748 | {0x0000a41c, 0x1ce739ce}, | ||
749 | {0x0000a420, 0x000001ce}, | ||
750 | {0x0000a424, 0x1ce739ce}, | ||
751 | {0x0000a428, 0x000001ce}, | ||
752 | {0x0000a42c, 0x1ce739ce}, | ||
753 | {0x0000a430, 0x1ce739ce}, | ||
754 | {0x0000a434, 0x00000000}, | ||
755 | {0x0000a438, 0x00001801}, | ||
756 | {0x0000a43c, 0x00000000}, | ||
757 | {0x0000a440, 0x00000000}, | ||
758 | {0x0000a444, 0x00000000}, | ||
759 | {0x0000a448, 0x04000080}, | ||
760 | {0x0000a44c, 0x00000001}, | ||
761 | {0x0000a450, 0x00010000}, | ||
762 | {0x0000a458, 0x00000000}, | ||
763 | {0x0000a600, 0x00000000}, | ||
764 | {0x0000a604, 0x00000000}, | ||
765 | {0x0000a608, 0x00000000}, | ||
766 | {0x0000a60c, 0x00000000}, | ||
767 | {0x0000a610, 0x00000000}, | ||
768 | {0x0000a614, 0x00000000}, | ||
769 | {0x0000a618, 0x00000000}, | ||
770 | {0x0000a61c, 0x00000000}, | ||
771 | {0x0000a620, 0x00000000}, | ||
772 | {0x0000a624, 0x00000000}, | ||
773 | {0x0000a628, 0x00000000}, | ||
774 | {0x0000a62c, 0x00000000}, | ||
775 | {0x0000a630, 0x00000000}, | ||
776 | {0x0000a634, 0x00000000}, | ||
777 | {0x0000a638, 0x00000000}, | ||
778 | {0x0000a63c, 0x00000000}, | ||
779 | {0x0000a640, 0x00000000}, | ||
780 | {0x0000a644, 0x3fad9d74}, | ||
781 | {0x0000a648, 0x0048060a}, | ||
782 | {0x0000a64c, 0x00000637}, | ||
783 | {0x0000a670, 0x03020100}, | ||
784 | {0x0000a674, 0x09080504}, | ||
785 | {0x0000a678, 0x0d0c0b0a}, | ||
786 | {0x0000a67c, 0x13121110}, | ||
787 | {0x0000a680, 0x31301514}, | ||
788 | {0x0000a684, 0x35343332}, | ||
789 | {0x0000a688, 0x00000036}, | ||
790 | {0x0000a690, 0x00000838}, | ||
791 | {0x0000a7c0, 0x00000000}, | ||
792 | {0x0000a7c4, 0xfffffffc}, | ||
793 | {0x0000a7c8, 0x00000000}, | ||
794 | {0x0000a7cc, 0x00000000}, | ||
795 | {0x0000a7d0, 0x00000000}, | ||
796 | {0x0000a7d4, 0x00000004}, | ||
797 | {0x0000a7dc, 0x00000001}, | ||
798 | {0x0000a8d0, 0x004b6a8e}, | ||
799 | {0x0000a8d4, 0x00000820}, | ||
800 | {0x0000a8dc, 0x00000000}, | ||
801 | {0x0000a8f0, 0x00000000}, | ||
802 | {0x0000a8f4, 0x00000000}, | ||
803 | {0x0000b2d0, 0x00000080}, | ||
804 | {0x0000b2d4, 0x00000000}, | ||
805 | {0x0000b2dc, 0x00000000}, | ||
806 | {0x0000b2e0, 0x00000000}, | ||
807 | {0x0000b2e4, 0x00000000}, | ||
808 | {0x0000b2e8, 0x00000000}, | ||
809 | {0x0000b2ec, 0x00000000}, | ||
810 | {0x0000b2f0, 0x00000000}, | ||
811 | {0x0000b2f4, 0x00000000}, | ||
812 | {0x0000b2f8, 0x00000000}, | ||
813 | {0x0000b408, 0x0e79e5c0}, | ||
814 | {0x0000b40c, 0x00820820}, | ||
815 | {0x0000b420, 0x00000000}, | ||
816 | {0x0000b8d0, 0x004b6a8e}, | ||
817 | {0x0000b8d4, 0x00000820}, | ||
818 | {0x0000b8dc, 0x00000000}, | ||
819 | {0x0000b8f0, 0x00000000}, | ||
820 | {0x0000b8f4, 0x00000000}, | ||
821 | {0x0000c2d0, 0x00000080}, | ||
822 | {0x0000c2d4, 0x00000000}, | ||
823 | {0x0000c2dc, 0x00000000}, | ||
824 | {0x0000c2e0, 0x00000000}, | ||
825 | {0x0000c2e4, 0x00000000}, | ||
826 | {0x0000c2e8, 0x00000000}, | ||
827 | {0x0000c2ec, 0x00000000}, | ||
828 | {0x0000c2f0, 0x00000000}, | ||
829 | {0x0000c2f4, 0x00000000}, | ||
830 | {0x0000c2f8, 0x00000000}, | ||
831 | {0x0000c408, 0x0e79e5c0}, | ||
832 | {0x0000c40c, 0x00820820}, | ||
833 | {0x0000c420, 0x00000000}, | ||
834 | }; | ||
835 | |||
836 | static const u32 ar9300Modes_high_power_tx_gain_table_2p0[][5] = { | ||
837 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
838 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
839 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
840 | {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, | ||
841 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, | ||
842 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, | ||
843 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, | ||
844 | {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, | ||
845 | {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, | ||
846 | {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, | ||
847 | {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, | ||
848 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, | ||
849 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, | ||
850 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, | ||
851 | {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, | ||
852 | {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, | ||
853 | {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, | ||
854 | {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, | ||
855 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, | ||
856 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, | ||
857 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, | ||
858 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
859 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, | ||
860 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, | ||
861 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, | ||
862 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, | ||
863 | {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, | ||
864 | {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
865 | {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
866 | {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
867 | {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
868 | {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
869 | {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
870 | {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
871 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
872 | {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, | ||
873 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, | ||
874 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, | ||
875 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, | ||
876 | {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, | ||
877 | {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, | ||
878 | {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, | ||
879 | {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, | ||
880 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, | ||
881 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, | ||
882 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, | ||
883 | {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, | ||
884 | {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, | ||
885 | {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, | ||
886 | {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, | ||
887 | {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, | ||
888 | {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, | ||
889 | {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, | ||
890 | {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, | ||
891 | {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, | ||
892 | {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, | ||
893 | {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, | ||
894 | {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, | ||
895 | {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, | ||
896 | {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
897 | {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
898 | {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
899 | {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
900 | {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
901 | {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
902 | {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
903 | {0x00016044, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | ||
904 | {0x00016048, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, | ||
905 | {0x00016068, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | ||
906 | {0x00016444, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | ||
907 | {0x00016448, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, | ||
908 | {0x00016468, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | ||
909 | {0x00016844, 0x056db2e6, 0x056db2e6, 0x056db2e6, 0x056db2e6}, | ||
910 | {0x00016848, 0xae480001, 0xae480001, 0xae480001, 0xae480001}, | ||
911 | {0x00016868, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c, 0x6eb6db6c}, | ||
912 | }; | ||
913 | |||
914 | static const u32 ar9300Modes_high_ob_db_tx_gain_table_2p0[][5] = { | ||
915 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
916 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
917 | {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, | ||
918 | {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, | ||
919 | {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, | ||
920 | {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, | ||
921 | {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, | ||
922 | {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, | ||
923 | {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, | ||
924 | {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, | ||
925 | {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, | ||
926 | {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, | ||
927 | {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, | ||
928 | {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, | ||
929 | {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, | ||
930 | {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, | ||
931 | {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, | ||
932 | {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, | ||
933 | {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, | ||
934 | {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, | ||
935 | {0x0000a548, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, | ||
936 | {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, | ||
937 | {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, | ||
938 | {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, | ||
939 | {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, | ||
940 | {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, | ||
941 | {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, | ||
942 | {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
943 | {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
944 | {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
945 | {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
946 | {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
947 | {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
948 | {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, | ||
949 | {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000}, | ||
950 | {0x0000a584, 0x06802223, 0x06802223, 0x04800002, 0x04800002}, | ||
951 | {0x0000a588, 0x0a822220, 0x0a822220, 0x08800004, 0x08800004}, | ||
952 | {0x0000a58c, 0x0f822223, 0x0f822223, 0x0b800200, 0x0b800200}, | ||
953 | {0x0000a590, 0x14822620, 0x14822620, 0x0f800202, 0x0f800202}, | ||
954 | {0x0000a594, 0x18822622, 0x18822622, 0x11800400, 0x11800400}, | ||
955 | {0x0000a598, 0x1b822822, 0x1b822822, 0x15800402, 0x15800402}, | ||
956 | {0x0000a59c, 0x20822842, 0x20822842, 0x19800404, 0x19800404}, | ||
957 | {0x0000a5a0, 0x22822c41, 0x22822c41, 0x1b800603, 0x1b800603}, | ||
958 | {0x0000a5a4, 0x28823042, 0x28823042, 0x1f800a02, 0x1f800a02}, | ||
959 | {0x0000a5a8, 0x2c823044, 0x2c823044, 0x23800a04, 0x23800a04}, | ||
960 | {0x0000a5ac, 0x2f823644, 0x2f823644, 0x26800a20, 0x26800a20}, | ||
961 | {0x0000a5b0, 0x34825643, 0x34825643, 0x2a800e20, 0x2a800e20}, | ||
962 | {0x0000a5b4, 0x38825a44, 0x38825a44, 0x2e800e22, 0x2e800e22}, | ||
963 | {0x0000a5b8, 0x3b825e45, 0x3b825e45, 0x31800e24, 0x31800e24}, | ||
964 | {0x0000a5bc, 0x41825e4a, 0x41825e4a, 0x34801640, 0x34801640}, | ||
965 | {0x0000a5c0, 0x48825e6c, 0x48825e6c, 0x38801660, 0x38801660}, | ||
966 | {0x0000a5c4, 0x4e825e8e, 0x4e825e8e, 0x3b801861, 0x3b801861}, | ||
967 | {0x0000a5c8, 0x53825eb2, 0x53825eb2, 0x3e801a81, 0x3e801a81}, | ||
968 | {0x0000a5cc, 0x59825eb5, 0x59825eb5, 0x42801a83, 0x42801a83}, | ||
969 | {0x0000a5d0, 0x5f825ef6, 0x5f825ef6, 0x44801c84, 0x44801c84}, | ||
970 | {0x0000a5d4, 0x62825f56, 0x62825f56, 0x48801ce3, 0x48801ce3}, | ||
971 | {0x0000a5d8, 0x66827f56, 0x66827f56, 0x4c801ce5, 0x4c801ce5}, | ||
972 | {0x0000a5dc, 0x6a829f56, 0x6a829f56, 0x50801ce9, 0x50801ce9}, | ||
973 | {0x0000a5e0, 0x70849f56, 0x70849f56, 0x54801ceb, 0x54801ceb}, | ||
974 | {0x0000a5e4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
975 | {0x0000a5e8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
976 | {0x0000a5ec, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
977 | {0x0000a5f0, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
978 | {0x0000a5f4, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
979 | {0x0000a5f8, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
980 | {0x0000a5fc, 0x7584ff56, 0x7584ff56, 0x56801eec, 0x56801eec}, | ||
981 | {0x00016044, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | ||
982 | {0x00016048, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, | ||
983 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
984 | {0x00016444, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | ||
985 | {0x00016448, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, | ||
986 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
987 | {0x00016844, 0x056db2e4, 0x056db2e4, 0x056db2e4, 0x056db2e4}, | ||
988 | {0x00016848, 0x8e480001, 0x8e480001, 0x8e480001, 0x8e480001}, | ||
989 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
990 | }; | ||
991 | |||
992 | static const u32 ar9300Common_rx_gain_table_2p0[][2] = { | ||
993 | /* Addr allmodes */ | ||
994 | {0x0000a000, 0x00010000}, | ||
995 | {0x0000a004, 0x00030002}, | ||
996 | {0x0000a008, 0x00050004}, | ||
997 | {0x0000a00c, 0x00810080}, | ||
998 | {0x0000a010, 0x00830082}, | ||
999 | {0x0000a014, 0x01810180}, | ||
1000 | {0x0000a018, 0x01830182}, | ||
1001 | {0x0000a01c, 0x01850184}, | ||
1002 | {0x0000a020, 0x01890188}, | ||
1003 | {0x0000a024, 0x018b018a}, | ||
1004 | {0x0000a028, 0x018d018c}, | ||
1005 | {0x0000a02c, 0x01910190}, | ||
1006 | {0x0000a030, 0x01930192}, | ||
1007 | {0x0000a034, 0x01950194}, | ||
1008 | {0x0000a038, 0x038a0196}, | ||
1009 | {0x0000a03c, 0x038c038b}, | ||
1010 | {0x0000a040, 0x0390038d}, | ||
1011 | {0x0000a044, 0x03920391}, | ||
1012 | {0x0000a048, 0x03940393}, | ||
1013 | {0x0000a04c, 0x03960395}, | ||
1014 | {0x0000a050, 0x00000000}, | ||
1015 | {0x0000a054, 0x00000000}, | ||
1016 | {0x0000a058, 0x00000000}, | ||
1017 | {0x0000a05c, 0x00000000}, | ||
1018 | {0x0000a060, 0x00000000}, | ||
1019 | {0x0000a064, 0x00000000}, | ||
1020 | {0x0000a068, 0x00000000}, | ||
1021 | {0x0000a06c, 0x00000000}, | ||
1022 | {0x0000a070, 0x00000000}, | ||
1023 | {0x0000a074, 0x00000000}, | ||
1024 | {0x0000a078, 0x00000000}, | ||
1025 | {0x0000a07c, 0x00000000}, | ||
1026 | {0x0000a080, 0x22222229}, | ||
1027 | {0x0000a084, 0x1d1d1d1d}, | ||
1028 | {0x0000a088, 0x1d1d1d1d}, | ||
1029 | {0x0000a08c, 0x1d1d1d1d}, | ||
1030 | {0x0000a090, 0x171d1d1d}, | ||
1031 | {0x0000a094, 0x11111717}, | ||
1032 | {0x0000a098, 0x00030311}, | ||
1033 | {0x0000a09c, 0x00000000}, | ||
1034 | {0x0000a0a0, 0x00000000}, | ||
1035 | {0x0000a0a4, 0x00000000}, | ||
1036 | {0x0000a0a8, 0x00000000}, | ||
1037 | {0x0000a0ac, 0x00000000}, | ||
1038 | {0x0000a0b0, 0x00000000}, | ||
1039 | {0x0000a0b4, 0x00000000}, | ||
1040 | {0x0000a0b8, 0x00000000}, | ||
1041 | {0x0000a0bc, 0x00000000}, | ||
1042 | {0x0000a0c0, 0x001f0000}, | ||
1043 | {0x0000a0c4, 0x01000101}, | ||
1044 | {0x0000a0c8, 0x011e011f}, | ||
1045 | {0x0000a0cc, 0x011c011d}, | ||
1046 | {0x0000a0d0, 0x02030204}, | ||
1047 | {0x0000a0d4, 0x02010202}, | ||
1048 | {0x0000a0d8, 0x021f0200}, | ||
1049 | {0x0000a0dc, 0x0302021e}, | ||
1050 | {0x0000a0e0, 0x03000301}, | ||
1051 | {0x0000a0e4, 0x031e031f}, | ||
1052 | {0x0000a0e8, 0x0402031d}, | ||
1053 | {0x0000a0ec, 0x04000401}, | ||
1054 | {0x0000a0f0, 0x041e041f}, | ||
1055 | {0x0000a0f4, 0x0502041d}, | ||
1056 | {0x0000a0f8, 0x05000501}, | ||
1057 | {0x0000a0fc, 0x051e051f}, | ||
1058 | {0x0000a100, 0x06010602}, | ||
1059 | {0x0000a104, 0x061f0600}, | ||
1060 | {0x0000a108, 0x061d061e}, | ||
1061 | {0x0000a10c, 0x07020703}, | ||
1062 | {0x0000a110, 0x07000701}, | ||
1063 | {0x0000a114, 0x00000000}, | ||
1064 | {0x0000a118, 0x00000000}, | ||
1065 | {0x0000a11c, 0x00000000}, | ||
1066 | {0x0000a120, 0x00000000}, | ||
1067 | {0x0000a124, 0x00000000}, | ||
1068 | {0x0000a128, 0x00000000}, | ||
1069 | {0x0000a12c, 0x00000000}, | ||
1070 | {0x0000a130, 0x00000000}, | ||
1071 | {0x0000a134, 0x00000000}, | ||
1072 | {0x0000a138, 0x00000000}, | ||
1073 | {0x0000a13c, 0x00000000}, | ||
1074 | {0x0000a140, 0x001f0000}, | ||
1075 | {0x0000a144, 0x01000101}, | ||
1076 | {0x0000a148, 0x011e011f}, | ||
1077 | {0x0000a14c, 0x011c011d}, | ||
1078 | {0x0000a150, 0x02030204}, | ||
1079 | {0x0000a154, 0x02010202}, | ||
1080 | {0x0000a158, 0x021f0200}, | ||
1081 | {0x0000a15c, 0x0302021e}, | ||
1082 | {0x0000a160, 0x03000301}, | ||
1083 | {0x0000a164, 0x031e031f}, | ||
1084 | {0x0000a168, 0x0402031d}, | ||
1085 | {0x0000a16c, 0x04000401}, | ||
1086 | {0x0000a170, 0x041e041f}, | ||
1087 | {0x0000a174, 0x0502041d}, | ||
1088 | {0x0000a178, 0x05000501}, | ||
1089 | {0x0000a17c, 0x051e051f}, | ||
1090 | {0x0000a180, 0x06010602}, | ||
1091 | {0x0000a184, 0x061f0600}, | ||
1092 | {0x0000a188, 0x061d061e}, | ||
1093 | {0x0000a18c, 0x07020703}, | ||
1094 | {0x0000a190, 0x07000701}, | ||
1095 | {0x0000a194, 0x00000000}, | ||
1096 | {0x0000a198, 0x00000000}, | ||
1097 | {0x0000a19c, 0x00000000}, | ||
1098 | {0x0000a1a0, 0x00000000}, | ||
1099 | {0x0000a1a4, 0x00000000}, | ||
1100 | {0x0000a1a8, 0x00000000}, | ||
1101 | {0x0000a1ac, 0x00000000}, | ||
1102 | {0x0000a1b0, 0x00000000}, | ||
1103 | {0x0000a1b4, 0x00000000}, | ||
1104 | {0x0000a1b8, 0x00000000}, | ||
1105 | {0x0000a1bc, 0x00000000}, | ||
1106 | {0x0000a1c0, 0x00000000}, | ||
1107 | {0x0000a1c4, 0x00000000}, | ||
1108 | {0x0000a1c8, 0x00000000}, | ||
1109 | {0x0000a1cc, 0x00000000}, | ||
1110 | {0x0000a1d0, 0x00000000}, | ||
1111 | {0x0000a1d4, 0x00000000}, | ||
1112 | {0x0000a1d8, 0x00000000}, | ||
1113 | {0x0000a1dc, 0x00000000}, | ||
1114 | {0x0000a1e0, 0x00000000}, | ||
1115 | {0x0000a1e4, 0x00000000}, | ||
1116 | {0x0000a1e8, 0x00000000}, | ||
1117 | {0x0000a1ec, 0x00000000}, | ||
1118 | {0x0000a1f0, 0x00000396}, | ||
1119 | {0x0000a1f4, 0x00000396}, | ||
1120 | {0x0000a1f8, 0x00000396}, | ||
1121 | {0x0000a1fc, 0x00000196}, | ||
1122 | {0x0000b000, 0x00010000}, | ||
1123 | {0x0000b004, 0x00030002}, | ||
1124 | {0x0000b008, 0x00050004}, | ||
1125 | {0x0000b00c, 0x00810080}, | ||
1126 | {0x0000b010, 0x00830082}, | ||
1127 | {0x0000b014, 0x01810180}, | ||
1128 | {0x0000b018, 0x01830182}, | ||
1129 | {0x0000b01c, 0x01850184}, | ||
1130 | {0x0000b020, 0x02810280}, | ||
1131 | {0x0000b024, 0x02830282}, | ||
1132 | {0x0000b028, 0x02850284}, | ||
1133 | {0x0000b02c, 0x02890288}, | ||
1134 | {0x0000b030, 0x028b028a}, | ||
1135 | {0x0000b034, 0x0388028c}, | ||
1136 | {0x0000b038, 0x038a0389}, | ||
1137 | {0x0000b03c, 0x038c038b}, | ||
1138 | {0x0000b040, 0x0390038d}, | ||
1139 | {0x0000b044, 0x03920391}, | ||
1140 | {0x0000b048, 0x03940393}, | ||
1141 | {0x0000b04c, 0x03960395}, | ||
1142 | {0x0000b050, 0x00000000}, | ||
1143 | {0x0000b054, 0x00000000}, | ||
1144 | {0x0000b058, 0x00000000}, | ||
1145 | {0x0000b05c, 0x00000000}, | ||
1146 | {0x0000b060, 0x00000000}, | ||
1147 | {0x0000b064, 0x00000000}, | ||
1148 | {0x0000b068, 0x00000000}, | ||
1149 | {0x0000b06c, 0x00000000}, | ||
1150 | {0x0000b070, 0x00000000}, | ||
1151 | {0x0000b074, 0x00000000}, | ||
1152 | {0x0000b078, 0x00000000}, | ||
1153 | {0x0000b07c, 0x00000000}, | ||
1154 | {0x0000b080, 0x32323232}, | ||
1155 | {0x0000b084, 0x2f2f3232}, | ||
1156 | {0x0000b088, 0x23282a2d}, | ||
1157 | {0x0000b08c, 0x1c1e2123}, | ||
1158 | {0x0000b090, 0x14171919}, | ||
1159 | {0x0000b094, 0x0e0e1214}, | ||
1160 | {0x0000b098, 0x03050707}, | ||
1161 | {0x0000b09c, 0x00030303}, | ||
1162 | {0x0000b0a0, 0x00000000}, | ||
1163 | {0x0000b0a4, 0x00000000}, | ||
1164 | {0x0000b0a8, 0x00000000}, | ||
1165 | {0x0000b0ac, 0x00000000}, | ||
1166 | {0x0000b0b0, 0x00000000}, | ||
1167 | {0x0000b0b4, 0x00000000}, | ||
1168 | {0x0000b0b8, 0x00000000}, | ||
1169 | {0x0000b0bc, 0x00000000}, | ||
1170 | {0x0000b0c0, 0x003f0020}, | ||
1171 | {0x0000b0c4, 0x00400041}, | ||
1172 | {0x0000b0c8, 0x0140005f}, | ||
1173 | {0x0000b0cc, 0x0160015f}, | ||
1174 | {0x0000b0d0, 0x017e017f}, | ||
1175 | {0x0000b0d4, 0x02410242}, | ||
1176 | {0x0000b0d8, 0x025f0240}, | ||
1177 | {0x0000b0dc, 0x027f0260}, | ||
1178 | {0x0000b0e0, 0x0341027e}, | ||
1179 | {0x0000b0e4, 0x035f0340}, | ||
1180 | {0x0000b0e8, 0x037f0360}, | ||
1181 | {0x0000b0ec, 0x04400441}, | ||
1182 | {0x0000b0f0, 0x0460045f}, | ||
1183 | {0x0000b0f4, 0x0541047f}, | ||
1184 | {0x0000b0f8, 0x055f0540}, | ||
1185 | {0x0000b0fc, 0x057f0560}, | ||
1186 | {0x0000b100, 0x06400641}, | ||
1187 | {0x0000b104, 0x0660065f}, | ||
1188 | {0x0000b108, 0x067e067f}, | ||
1189 | {0x0000b10c, 0x07410742}, | ||
1190 | {0x0000b110, 0x075f0740}, | ||
1191 | {0x0000b114, 0x077f0760}, | ||
1192 | {0x0000b118, 0x07800781}, | ||
1193 | {0x0000b11c, 0x07a0079f}, | ||
1194 | {0x0000b120, 0x07c107bf}, | ||
1195 | {0x0000b124, 0x000007c0}, | ||
1196 | {0x0000b128, 0x00000000}, | ||
1197 | {0x0000b12c, 0x00000000}, | ||
1198 | {0x0000b130, 0x00000000}, | ||
1199 | {0x0000b134, 0x00000000}, | ||
1200 | {0x0000b138, 0x00000000}, | ||
1201 | {0x0000b13c, 0x00000000}, | ||
1202 | {0x0000b140, 0x003f0020}, | ||
1203 | {0x0000b144, 0x00400041}, | ||
1204 | {0x0000b148, 0x0140005f}, | ||
1205 | {0x0000b14c, 0x0160015f}, | ||
1206 | {0x0000b150, 0x017e017f}, | ||
1207 | {0x0000b154, 0x02410242}, | ||
1208 | {0x0000b158, 0x025f0240}, | ||
1209 | {0x0000b15c, 0x027f0260}, | ||
1210 | {0x0000b160, 0x0341027e}, | ||
1211 | {0x0000b164, 0x035f0340}, | ||
1212 | {0x0000b168, 0x037f0360}, | ||
1213 | {0x0000b16c, 0x04400441}, | ||
1214 | {0x0000b170, 0x0460045f}, | ||
1215 | {0x0000b174, 0x0541047f}, | ||
1216 | {0x0000b178, 0x055f0540}, | ||
1217 | {0x0000b17c, 0x057f0560}, | ||
1218 | {0x0000b180, 0x06400641}, | ||
1219 | {0x0000b184, 0x0660065f}, | ||
1220 | {0x0000b188, 0x067e067f}, | ||
1221 | {0x0000b18c, 0x07410742}, | ||
1222 | {0x0000b190, 0x075f0740}, | ||
1223 | {0x0000b194, 0x077f0760}, | ||
1224 | {0x0000b198, 0x07800781}, | ||
1225 | {0x0000b19c, 0x07a0079f}, | ||
1226 | {0x0000b1a0, 0x07c107bf}, | ||
1227 | {0x0000b1a4, 0x000007c0}, | ||
1228 | {0x0000b1a8, 0x00000000}, | ||
1229 | {0x0000b1ac, 0x00000000}, | ||
1230 | {0x0000b1b0, 0x00000000}, | ||
1231 | {0x0000b1b4, 0x00000000}, | ||
1232 | {0x0000b1b8, 0x00000000}, | ||
1233 | {0x0000b1bc, 0x00000000}, | ||
1234 | {0x0000b1c0, 0x00000000}, | ||
1235 | {0x0000b1c4, 0x00000000}, | ||
1236 | {0x0000b1c8, 0x00000000}, | ||
1237 | {0x0000b1cc, 0x00000000}, | ||
1238 | {0x0000b1d0, 0x00000000}, | ||
1239 | {0x0000b1d4, 0x00000000}, | ||
1240 | {0x0000b1d8, 0x00000000}, | ||
1241 | {0x0000b1dc, 0x00000000}, | ||
1242 | {0x0000b1e0, 0x00000000}, | ||
1243 | {0x0000b1e4, 0x00000000}, | ||
1244 | {0x0000b1e8, 0x00000000}, | ||
1245 | {0x0000b1ec, 0x00000000}, | ||
1246 | {0x0000b1f0, 0x00000396}, | ||
1247 | {0x0000b1f4, 0x00000396}, | ||
1248 | {0x0000b1f8, 0x00000396}, | ||
1249 | {0x0000b1fc, 0x00000196}, | ||
1250 | }; | ||
1251 | |||
1252 | static const u32 ar9300Modes_low_ob_db_tx_gain_table_2p0[][5] = { | ||
1253 | /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ | ||
1254 | {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, | ||
1255 | {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, | ||
1256 | {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, | ||
1257 | {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, | ||
1258 | {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, | ||
1259 | {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, | ||
1260 | {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, | ||
1261 | {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, | ||
1262 | {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, | ||
1263 | {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, | ||
1264 | {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, | ||
1265 | {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, | ||
1266 | {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, | ||
1267 | {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, | ||
1268 | {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, | ||
1269 | {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, | ||
1270 | {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, | ||
1271 | {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, | ||
1272 | {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, | ||
1273 | {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, | ||
1274 | {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, | ||
1275 | {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, | ||
1276 | {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, | ||
1277 | {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, | ||
1278 | {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, | ||
1279 | {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, | ||
1280 | {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1281 | {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1282 | {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1283 | {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1284 | {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1285 | {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1286 | {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, | ||
1287 | {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, | ||
1288 | {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, | ||
1289 | {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, | ||
1290 | {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, | ||
1291 | {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, | ||
1292 | {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400}, | ||
1293 | {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402}, | ||
1294 | {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, | ||
1295 | {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603}, | ||
1296 | {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02}, | ||
1297 | {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04}, | ||
1298 | {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20}, | ||
1299 | {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20}, | ||
1300 | {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22}, | ||
1301 | {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24}, | ||
1302 | {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640}, | ||
1303 | {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660}, | ||
1304 | {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861}, | ||
1305 | {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81}, | ||
1306 | {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83}, | ||
1307 | {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84}, | ||
1308 | {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3}, | ||
1309 | {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5}, | ||
1310 | {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9}, | ||
1311 | {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb}, | ||
1312 | {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1313 | {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1314 | {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1315 | {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1316 | {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1317 | {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1318 | {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec}, | ||
1319 | {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
1320 | {0x00016048, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, | ||
1321 | {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
1322 | {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
1323 | {0x00016448, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, | ||
1324 | {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
1325 | {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, | ||
1326 | {0x00016848, 0x64000001, 0x64000001, 0x64000001, 0x64000001}, | ||
1327 | {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, | ||
1328 | }; | ||
1329 | |||
1330 | static const u32 ar9300_2p0_mac_core[][2] = { | ||
1331 | /* Addr allmodes */ | ||
1332 | {0x00000008, 0x00000000}, | ||
1333 | {0x00000030, 0x00020085}, | ||
1334 | {0x00000034, 0x00000005}, | ||
1335 | {0x00000040, 0x00000000}, | ||
1336 | {0x00000044, 0x00000000}, | ||
1337 | {0x00000048, 0x00000008}, | ||
1338 | {0x0000004c, 0x00000010}, | ||
1339 | {0x00000050, 0x00000000}, | ||
1340 | {0x00001040, 0x002ffc0f}, | ||
1341 | {0x00001044, 0x002ffc0f}, | ||
1342 | {0x00001048, 0x002ffc0f}, | ||
1343 | {0x0000104c, 0x002ffc0f}, | ||
1344 | {0x00001050, 0x002ffc0f}, | ||
1345 | {0x00001054, 0x002ffc0f}, | ||
1346 | {0x00001058, 0x002ffc0f}, | ||
1347 | {0x0000105c, 0x002ffc0f}, | ||
1348 | {0x00001060, 0x002ffc0f}, | ||
1349 | {0x00001064, 0x002ffc0f}, | ||
1350 | {0x000010f0, 0x00000100}, | ||
1351 | {0x00001270, 0x00000000}, | ||
1352 | {0x000012b0, 0x00000000}, | ||
1353 | {0x000012f0, 0x00000000}, | ||
1354 | {0x0000143c, 0x00000000}, | ||
1355 | {0x0000147c, 0x00000000}, | ||
1356 | {0x00008000, 0x00000000}, | ||
1357 | {0x00008004, 0x00000000}, | ||
1358 | {0x00008008, 0x00000000}, | ||
1359 | {0x0000800c, 0x00000000}, | ||
1360 | {0x00008018, 0x00000000}, | ||
1361 | {0x00008020, 0x00000000}, | ||
1362 | {0x00008038, 0x00000000}, | ||
1363 | {0x0000803c, 0x00000000}, | ||
1364 | {0x00008040, 0x00000000}, | ||
1365 | {0x00008044, 0x00000000}, | ||
1366 | {0x00008048, 0x00000000}, | ||
1367 | {0x0000804c, 0xffffffff}, | ||
1368 | {0x00008054, 0x00000000}, | ||
1369 | {0x00008058, 0x00000000}, | ||
1370 | {0x0000805c, 0x000fc78f}, | ||
1371 | {0x00008060, 0x0000000f}, | ||
1372 | {0x00008064, 0x00000000}, | ||
1373 | {0x00008070, 0x00000310}, | ||
1374 | {0x00008074, 0x00000020}, | ||
1375 | {0x00008078, 0x00000000}, | ||
1376 | {0x0000809c, 0x0000000f}, | ||
1377 | {0x000080a0, 0x00000000}, | ||
1378 | {0x000080a4, 0x02ff0000}, | ||
1379 | {0x000080a8, 0x0e070605}, | ||
1380 | {0x000080ac, 0x0000000d}, | ||
1381 | {0x000080b0, 0x00000000}, | ||
1382 | {0x000080b4, 0x00000000}, | ||
1383 | {0x000080b8, 0x00000000}, | ||
1384 | {0x000080bc, 0x00000000}, | ||
1385 | {0x000080c0, 0x2a800000}, | ||
1386 | {0x000080c4, 0x06900168}, | ||
1387 | {0x000080c8, 0x13881c20}, | ||
1388 | {0x000080cc, 0x01f40000}, | ||
1389 | {0x000080d0, 0x00252500}, | ||
1390 | {0x000080d4, 0x00a00000}, | ||
1391 | {0x000080d8, 0x00400000}, | ||
1392 | {0x000080dc, 0x00000000}, | ||
1393 | {0x000080e0, 0xffffffff}, | ||
1394 | {0x000080e4, 0x0000ffff}, | ||
1395 | {0x000080e8, 0x3f3f3f3f}, | ||
1396 | {0x000080ec, 0x00000000}, | ||
1397 | {0x000080f0, 0x00000000}, | ||
1398 | {0x000080f4, 0x00000000}, | ||
1399 | {0x000080fc, 0x00020000}, | ||
1400 | {0x00008100, 0x00000000}, | ||
1401 | {0x00008108, 0x00000052}, | ||
1402 | {0x0000810c, 0x00000000}, | ||
1403 | {0x00008110, 0x00000000}, | ||
1404 | {0x00008114, 0x000007ff}, | ||
1405 | {0x00008118, 0x000000aa}, | ||
1406 | {0x0000811c, 0x00003210}, | ||
1407 | {0x00008124, 0x00000000}, | ||
1408 | {0x00008128, 0x00000000}, | ||
1409 | {0x0000812c, 0x00000000}, | ||
1410 | {0x00008130, 0x00000000}, | ||
1411 | {0x00008134, 0x00000000}, | ||
1412 | {0x00008138, 0x00000000}, | ||
1413 | {0x0000813c, 0x0000ffff}, | ||
1414 | {0x00008144, 0xffffffff}, | ||
1415 | {0x00008168, 0x00000000}, | ||
1416 | {0x0000816c, 0x00000000}, | ||
1417 | {0x00008170, 0x18486200}, | ||
1418 | {0x00008174, 0x33332210}, | ||
1419 | {0x00008178, 0x00000000}, | ||
1420 | {0x0000817c, 0x00020000}, | ||
1421 | {0x000081c0, 0x00000000}, | ||
1422 | {0x000081c4, 0x33332210}, | ||
1423 | {0x000081c8, 0x00000000}, | ||
1424 | {0x000081cc, 0x00000000}, | ||
1425 | {0x000081d4, 0x00000000}, | ||
1426 | {0x000081ec, 0x00000000}, | ||
1427 | {0x000081f0, 0x00000000}, | ||
1428 | {0x000081f4, 0x00000000}, | ||
1429 | {0x000081f8, 0x00000000}, | ||
1430 | {0x000081fc, 0x00000000}, | ||
1431 | {0x00008240, 0x00100000}, | ||
1432 | {0x00008244, 0x0010f424}, | ||
1433 | {0x00008248, 0x00000800}, | ||
1434 | {0x0000824c, 0x0001e848}, | ||
1435 | {0x00008250, 0x00000000}, | ||
1436 | {0x00008254, 0x00000000}, | ||
1437 | {0x00008258, 0x00000000}, | ||
1438 | {0x0000825c, 0x40000000}, | ||
1439 | {0x00008260, 0x00080922}, | ||
1440 | {0x00008264, 0x98a00010}, | ||
1441 | {0x00008268, 0xffffffff}, | ||
1442 | {0x0000826c, 0x0000ffff}, | ||
1443 | {0x00008270, 0x00000000}, | ||
1444 | {0x00008274, 0x40000000}, | ||
1445 | {0x00008278, 0x003e4180}, | ||
1446 | {0x0000827c, 0x00000004}, | ||
1447 | {0x00008284, 0x0000002c}, | ||
1448 | {0x00008288, 0x0000002c}, | ||
1449 | {0x0000828c, 0x000000ff}, | ||
1450 | {0x00008294, 0x00000000}, | ||
1451 | {0x00008298, 0x00000000}, | ||
1452 | {0x0000829c, 0x00000000}, | ||
1453 | {0x00008300, 0x00000140}, | ||
1454 | {0x00008314, 0x00000000}, | ||
1455 | {0x0000831c, 0x0000010d}, | ||
1456 | {0x00008328, 0x00000000}, | ||
1457 | {0x0000832c, 0x00000007}, | ||
1458 | {0x00008330, 0x00000302}, | ||
1459 | {0x00008334, 0x00000700}, | ||
1460 | {0x00008338, 0x00ff0000}, | ||
1461 | {0x0000833c, 0x02400000}, | ||
1462 | {0x00008340, 0x000107ff}, | ||
1463 | {0x00008344, 0xaa48105b}, | ||
1464 | {0x00008348, 0x008f0000}, | ||
1465 | {0x0000835c, 0x00000000}, | ||
1466 | {0x00008360, 0xffffffff}, | ||
1467 | {0x00008364, 0xffffffff}, | ||
1468 | {0x00008368, 0x00000000}, | ||
1469 | {0x00008370, 0x00000000}, | ||
1470 | {0x00008374, 0x000000ff}, | ||
1471 | {0x00008378, 0x00000000}, | ||
1472 | {0x0000837c, 0x00000000}, | ||
1473 | {0x00008380, 0xffffffff}, | ||
1474 | {0x00008384, 0xffffffff}, | ||
1475 | {0x00008390, 0xffffffff}, | ||
1476 | {0x00008394, 0xffffffff}, | ||
1477 | {0x00008398, 0x00000000}, | ||
1478 | {0x0000839c, 0x00000000}, | ||
1479 | {0x000083a0, 0x00000000}, | ||
1480 | {0x000083a4, 0x0000fa14}, | ||
1481 | {0x000083a8, 0x000f0c00}, | ||
1482 | {0x000083ac, 0x33332210}, | ||
1483 | {0x000083b0, 0x33332210}, | ||
1484 | {0x000083b4, 0x33332210}, | ||
1485 | {0x000083b8, 0x33332210}, | ||
1486 | {0x000083bc, 0x00000000}, | ||
1487 | {0x000083c0, 0x00000000}, | ||
1488 | {0x000083c4, 0x00000000}, | ||
1489 | {0x000083c8, 0x00000000}, | ||
1490 | {0x000083cc, 0x00000200}, | ||
1491 | {0x000083d0, 0x000301ff}, | ||
1492 | }; | ||
1493 | |||
1494 | static const u32 ar9300Common_wo_xlna_rx_gain_table_2p0[][2] = { | ||
1495 | /* Addr allmodes */ | ||
1496 | {0x0000a000, 0x00010000}, | ||
1497 | {0x0000a004, 0x00030002}, | ||
1498 | {0x0000a008, 0x00050004}, | ||
1499 | {0x0000a00c, 0x00810080}, | ||
1500 | {0x0000a010, 0x00830082}, | ||
1501 | {0x0000a014, 0x01810180}, | ||
1502 | {0x0000a018, 0x01830182}, | ||
1503 | {0x0000a01c, 0x01850184}, | ||
1504 | {0x0000a020, 0x01890188}, | ||
1505 | {0x0000a024, 0x018b018a}, | ||
1506 | {0x0000a028, 0x018d018c}, | ||
1507 | {0x0000a02c, 0x03820190}, | ||
1508 | {0x0000a030, 0x03840383}, | ||
1509 | {0x0000a034, 0x03880385}, | ||
1510 | {0x0000a038, 0x038a0389}, | ||
1511 | {0x0000a03c, 0x038c038b}, | ||
1512 | {0x0000a040, 0x0390038d}, | ||
1513 | {0x0000a044, 0x03920391}, | ||
1514 | {0x0000a048, 0x03940393}, | ||
1515 | {0x0000a04c, 0x03960395}, | ||
1516 | {0x0000a050, 0x00000000}, | ||
1517 | {0x0000a054, 0x00000000}, | ||
1518 | {0x0000a058, 0x00000000}, | ||
1519 | {0x0000a05c, 0x00000000}, | ||
1520 | {0x0000a060, 0x00000000}, | ||
1521 | {0x0000a064, 0x00000000}, | ||
1522 | {0x0000a068, 0x00000000}, | ||
1523 | {0x0000a06c, 0x00000000}, | ||
1524 | {0x0000a070, 0x00000000}, | ||
1525 | {0x0000a074, 0x00000000}, | ||
1526 | {0x0000a078, 0x00000000}, | ||
1527 | {0x0000a07c, 0x00000000}, | ||
1528 | {0x0000a080, 0x29292929}, | ||
1529 | {0x0000a084, 0x29292929}, | ||
1530 | {0x0000a088, 0x29292929}, | ||
1531 | {0x0000a08c, 0x29292929}, | ||
1532 | {0x0000a090, 0x22292929}, | ||
1533 | {0x0000a094, 0x1d1d2222}, | ||
1534 | {0x0000a098, 0x0c111117}, | ||
1535 | {0x0000a09c, 0x00030303}, | ||
1536 | {0x0000a0a0, 0x00000000}, | ||
1537 | {0x0000a0a4, 0x00000000}, | ||
1538 | {0x0000a0a8, 0x00000000}, | ||
1539 | {0x0000a0ac, 0x00000000}, | ||
1540 | {0x0000a0b0, 0x00000000}, | ||
1541 | {0x0000a0b4, 0x00000000}, | ||
1542 | {0x0000a0b8, 0x00000000}, | ||
1543 | {0x0000a0bc, 0x00000000}, | ||
1544 | {0x0000a0c0, 0x001f0000}, | ||
1545 | {0x0000a0c4, 0x01000101}, | ||
1546 | {0x0000a0c8, 0x011e011f}, | ||
1547 | {0x0000a0cc, 0x011c011d}, | ||
1548 | {0x0000a0d0, 0x02030204}, | ||
1549 | {0x0000a0d4, 0x02010202}, | ||
1550 | {0x0000a0d8, 0x021f0200}, | ||
1551 | {0x0000a0dc, 0x0302021e}, | ||
1552 | {0x0000a0e0, 0x03000301}, | ||
1553 | {0x0000a0e4, 0x031e031f}, | ||
1554 | {0x0000a0e8, 0x0402031d}, | ||
1555 | {0x0000a0ec, 0x04000401}, | ||
1556 | {0x0000a0f0, 0x041e041f}, | ||
1557 | {0x0000a0f4, 0x0502041d}, | ||
1558 | {0x0000a0f8, 0x05000501}, | ||
1559 | {0x0000a0fc, 0x051e051f}, | ||
1560 | {0x0000a100, 0x06010602}, | ||
1561 | {0x0000a104, 0x061f0600}, | ||
1562 | {0x0000a108, 0x061d061e}, | ||
1563 | {0x0000a10c, 0x07020703}, | ||
1564 | {0x0000a110, 0x07000701}, | ||
1565 | {0x0000a114, 0x00000000}, | ||
1566 | {0x0000a118, 0x00000000}, | ||
1567 | {0x0000a11c, 0x00000000}, | ||
1568 | {0x0000a120, 0x00000000}, | ||
1569 | {0x0000a124, 0x00000000}, | ||
1570 | {0x0000a128, 0x00000000}, | ||
1571 | {0x0000a12c, 0x00000000}, | ||
1572 | {0x0000a130, 0x00000000}, | ||
1573 | {0x0000a134, 0x00000000}, | ||
1574 | {0x0000a138, 0x00000000}, | ||
1575 | {0x0000a13c, 0x00000000}, | ||
1576 | {0x0000a140, 0x001f0000}, | ||
1577 | {0x0000a144, 0x01000101}, | ||
1578 | {0x0000a148, 0x011e011f}, | ||
1579 | {0x0000a14c, 0x011c011d}, | ||
1580 | {0x0000a150, 0x02030204}, | ||
1581 | {0x0000a154, 0x02010202}, | ||
1582 | {0x0000a158, 0x021f0200}, | ||
1583 | {0x0000a15c, 0x0302021e}, | ||
1584 | {0x0000a160, 0x03000301}, | ||
1585 | {0x0000a164, 0x031e031f}, | ||
1586 | {0x0000a168, 0x0402031d}, | ||
1587 | {0x0000a16c, 0x04000401}, | ||
1588 | {0x0000a170, 0x041e041f}, | ||
1589 | {0x0000a174, 0x0502041d}, | ||
1590 | {0x0000a178, 0x05000501}, | ||
1591 | {0x0000a17c, 0x051e051f}, | ||
1592 | {0x0000a180, 0x06010602}, | ||
1593 | {0x0000a184, 0x061f0600}, | ||
1594 | {0x0000a188, 0x061d061e}, | ||
1595 | {0x0000a18c, 0x07020703}, | ||
1596 | {0x0000a190, 0x07000701}, | ||
1597 | {0x0000a194, 0x00000000}, | ||
1598 | {0x0000a198, 0x00000000}, | ||
1599 | {0x0000a19c, 0x00000000}, | ||
1600 | {0x0000a1a0, 0x00000000}, | ||
1601 | {0x0000a1a4, 0x00000000}, | ||
1602 | {0x0000a1a8, 0x00000000}, | ||
1603 | {0x0000a1ac, 0x00000000}, | ||
1604 | {0x0000a1b0, 0x00000000}, | ||
1605 | {0x0000a1b4, 0x00000000}, | ||
1606 | {0x0000a1b8, 0x00000000}, | ||
1607 | {0x0000a1bc, 0x00000000}, | ||
1608 | {0x0000a1c0, 0x00000000}, | ||
1609 | {0x0000a1c4, 0x00000000}, | ||
1610 | {0x0000a1c8, 0x00000000}, | ||
1611 | {0x0000a1cc, 0x00000000}, | ||
1612 | {0x0000a1d0, 0x00000000}, | ||
1613 | {0x0000a1d4, 0x00000000}, | ||
1614 | {0x0000a1d8, 0x00000000}, | ||
1615 | {0x0000a1dc, 0x00000000}, | ||
1616 | {0x0000a1e0, 0x00000000}, | ||
1617 | {0x0000a1e4, 0x00000000}, | ||
1618 | {0x0000a1e8, 0x00000000}, | ||
1619 | {0x0000a1ec, 0x00000000}, | ||
1620 | {0x0000a1f0, 0x00000396}, | ||
1621 | {0x0000a1f4, 0x00000396}, | ||
1622 | {0x0000a1f8, 0x00000396}, | ||
1623 | {0x0000a1fc, 0x00000196}, | ||
1624 | {0x0000b000, 0x00010000}, | ||
1625 | {0x0000b004, 0x00030002}, | ||
1626 | {0x0000b008, 0x00050004}, | ||
1627 | {0x0000b00c, 0x00810080}, | ||
1628 | {0x0000b010, 0x00830082}, | ||
1629 | {0x0000b014, 0x01810180}, | ||
1630 | {0x0000b018, 0x01830182}, | ||
1631 | {0x0000b01c, 0x01850184}, | ||
1632 | {0x0000b020, 0x02810280}, | ||
1633 | {0x0000b024, 0x02830282}, | ||
1634 | {0x0000b028, 0x02850284}, | ||
1635 | {0x0000b02c, 0x02890288}, | ||
1636 | {0x0000b030, 0x028b028a}, | ||
1637 | {0x0000b034, 0x0388028c}, | ||
1638 | {0x0000b038, 0x038a0389}, | ||
1639 | {0x0000b03c, 0x038c038b}, | ||
1640 | {0x0000b040, 0x0390038d}, | ||
1641 | {0x0000b044, 0x03920391}, | ||
1642 | {0x0000b048, 0x03940393}, | ||
1643 | {0x0000b04c, 0x03960395}, | ||
1644 | {0x0000b050, 0x00000000}, | ||
1645 | {0x0000b054, 0x00000000}, | ||
1646 | {0x0000b058, 0x00000000}, | ||
1647 | {0x0000b05c, 0x00000000}, | ||
1648 | {0x0000b060, 0x00000000}, | ||
1649 | {0x0000b064, 0x00000000}, | ||
1650 | {0x0000b068, 0x00000000}, | ||
1651 | {0x0000b06c, 0x00000000}, | ||
1652 | {0x0000b070, 0x00000000}, | ||
1653 | {0x0000b074, 0x00000000}, | ||
1654 | {0x0000b078, 0x00000000}, | ||
1655 | {0x0000b07c, 0x00000000}, | ||
1656 | {0x0000b080, 0x32323232}, | ||
1657 | {0x0000b084, 0x2f2f3232}, | ||
1658 | {0x0000b088, 0x23282a2d}, | ||
1659 | {0x0000b08c, 0x1c1e2123}, | ||
1660 | {0x0000b090, 0x14171919}, | ||
1661 | {0x0000b094, 0x0e0e1214}, | ||
1662 | {0x0000b098, 0x03050707}, | ||
1663 | {0x0000b09c, 0x00030303}, | ||
1664 | {0x0000b0a0, 0x00000000}, | ||
1665 | {0x0000b0a4, 0x00000000}, | ||
1666 | {0x0000b0a8, 0x00000000}, | ||
1667 | {0x0000b0ac, 0x00000000}, | ||
1668 | {0x0000b0b0, 0x00000000}, | ||
1669 | {0x0000b0b4, 0x00000000}, | ||
1670 | {0x0000b0b8, 0x00000000}, | ||
1671 | {0x0000b0bc, 0x00000000}, | ||
1672 | {0x0000b0c0, 0x003f0020}, | ||
1673 | {0x0000b0c4, 0x00400041}, | ||
1674 | {0x0000b0c8, 0x0140005f}, | ||
1675 | {0x0000b0cc, 0x0160015f}, | ||
1676 | {0x0000b0d0, 0x017e017f}, | ||
1677 | {0x0000b0d4, 0x02410242}, | ||
1678 | {0x0000b0d8, 0x025f0240}, | ||
1679 | {0x0000b0dc, 0x027f0260}, | ||
1680 | {0x0000b0e0, 0x0341027e}, | ||
1681 | {0x0000b0e4, 0x035f0340}, | ||
1682 | {0x0000b0e8, 0x037f0360}, | ||
1683 | {0x0000b0ec, 0x04400441}, | ||
1684 | {0x0000b0f0, 0x0460045f}, | ||
1685 | {0x0000b0f4, 0x0541047f}, | ||
1686 | {0x0000b0f8, 0x055f0540}, | ||
1687 | {0x0000b0fc, 0x057f0560}, | ||
1688 | {0x0000b100, 0x06400641}, | ||
1689 | {0x0000b104, 0x0660065f}, | ||
1690 | {0x0000b108, 0x067e067f}, | ||
1691 | {0x0000b10c, 0x07410742}, | ||
1692 | {0x0000b110, 0x075f0740}, | ||
1693 | {0x0000b114, 0x077f0760}, | ||
1694 | {0x0000b118, 0x07800781}, | ||
1695 | {0x0000b11c, 0x07a0079f}, | ||
1696 | {0x0000b120, 0x07c107bf}, | ||
1697 | {0x0000b124, 0x000007c0}, | ||
1698 | {0x0000b128, 0x00000000}, | ||
1699 | {0x0000b12c, 0x00000000}, | ||
1700 | {0x0000b130, 0x00000000}, | ||
1701 | {0x0000b134, 0x00000000}, | ||
1702 | {0x0000b138, 0x00000000}, | ||
1703 | {0x0000b13c, 0x00000000}, | ||
1704 | {0x0000b140, 0x003f0020}, | ||
1705 | {0x0000b144, 0x00400041}, | ||
1706 | {0x0000b148, 0x0140005f}, | ||
1707 | {0x0000b14c, 0x0160015f}, | ||
1708 | {0x0000b150, 0x017e017f}, | ||
1709 | {0x0000b154, 0x02410242}, | ||
1710 | {0x0000b158, 0x025f0240}, | ||
1711 | {0x0000b15c, 0x027f0260}, | ||
1712 | {0x0000b160, 0x0341027e}, | ||
1713 | {0x0000b164, 0x035f0340}, | ||
1714 | {0x0000b168, 0x037f0360}, | ||
1715 | {0x0000b16c, 0x04400441}, | ||
1716 | {0x0000b170, 0x0460045f}, | ||
1717 | {0x0000b174, 0x0541047f}, | ||
1718 | {0x0000b178, 0x055f0540}, | ||
1719 | {0x0000b17c, 0x057f0560}, | ||
1720 | {0x0000b180, 0x06400641}, | ||
1721 | {0x0000b184, 0x0660065f}, | ||
1722 | {0x0000b188, 0x067e067f}, | ||
1723 | {0x0000b18c, 0x07410742}, | ||
1724 | {0x0000b190, 0x075f0740}, | ||
1725 | {0x0000b194, 0x077f0760}, | ||
1726 | {0x0000b198, 0x07800781}, | ||
1727 | {0x0000b19c, 0x07a0079f}, | ||
1728 | {0x0000b1a0, 0x07c107bf}, | ||
1729 | {0x0000b1a4, 0x000007c0}, | ||
1730 | {0x0000b1a8, 0x00000000}, | ||
1731 | {0x0000b1ac, 0x00000000}, | ||
1732 | {0x0000b1b0, 0x00000000}, | ||
1733 | {0x0000b1b4, 0x00000000}, | ||
1734 | {0x0000b1b8, 0x00000000}, | ||
1735 | {0x0000b1bc, 0x00000000}, | ||
1736 | {0x0000b1c0, 0x00000000}, | ||
1737 | {0x0000b1c4, 0x00000000}, | ||
1738 | {0x0000b1c8, 0x00000000}, | ||
1739 | {0x0000b1cc, 0x00000000}, | ||
1740 | {0x0000b1d0, 0x00000000}, | ||
1741 | {0x0000b1d4, 0x00000000}, | ||
1742 | {0x0000b1d8, 0x00000000}, | ||
1743 | {0x0000b1dc, 0x00000000}, | ||
1744 | {0x0000b1e0, 0x00000000}, | ||
1745 | {0x0000b1e4, 0x00000000}, | ||
1746 | {0x0000b1e8, 0x00000000}, | ||
1747 | {0x0000b1ec, 0x00000000}, | ||
1748 | {0x0000b1f0, 0x00000396}, | ||
1749 | {0x0000b1f4, 0x00000396}, | ||
1750 | {0x0000b1f8, 0x00000396}, | ||
1751 | {0x0000b1fc, 0x00000196}, | ||
1752 | }; | ||
1753 | |||
1754 | static const u32 ar9300_2p0_soc_preamble[][2] = { | ||
1755 | /* Addr allmodes */ | ||
1756 | {0x000040a4, 0x00a0c1c9}, | ||
1757 | {0x00007008, 0x00000000}, | ||
1758 | {0x00007020, 0x00000000}, | ||
1759 | {0x00007034, 0x00000002}, | ||
1760 | {0x00007038, 0x000004c2}, | ||
1761 | }; | ||
1762 | |||
1763 | static const u32 ar9300PciePhy_pll_on_clkreq_disable_L1_2p0[][2] = { | ||
1764 | /* Addr allmodes */ | ||
1765 | {0x00004040, 0x08212e5e}, | ||
1766 | {0x00004040, 0x0008003b}, | ||
1767 | {0x00004044, 0x00000000}, | ||
1768 | }; | ||
1769 | |||
1770 | static const u32 ar9300PciePhy_clkreq_enable_L1_2p0[][2] = { | ||
1771 | /* Addr allmodes */ | ||
1772 | {0x00004040, 0x08253e5e}, | ||
1773 | {0x00004040, 0x0008003b}, | ||
1774 | {0x00004044, 0x00000000}, | ||
1775 | }; | ||
1776 | |||
1777 | static const u32 ar9300PciePhy_clkreq_disable_L1_2p0[][2] = { | ||
1778 | /* Addr allmodes */ | ||
1779 | {0x00004040, 0x08213e5e}, | ||
1780 | {0x00004040, 0x0008003b}, | ||
1781 | {0x00004044, 0x00000000}, | ||
1782 | }; | ||
1783 | |||
1784 | #endif /* INITVALS_9003_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c new file mode 100644 index 000000000000..37ba37481a47 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c | |||
@@ -0,0 +1,614 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | #include "hw.h" | ||
17 | #include "ar9003_mac.h" | ||
18 | |||
19 | static void ar9003_hw_rx_enable(struct ath_hw *hw) | ||
20 | { | ||
21 | REG_WRITE(hw, AR_CR, 0); | ||
22 | } | ||
23 | |||
24 | static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads) | ||
25 | { | ||
26 | int checksum; | ||
27 | |||
28 | checksum = ads->info + ads->link | ||
29 | + ads->data0 + ads->ctl3 | ||
30 | + ads->data1 + ads->ctl5 | ||
31 | + ads->data2 + ads->ctl7 | ||
32 | + ads->data3 + ads->ctl9; | ||
33 | |||
34 | return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum; | ||
35 | } | ||
36 | |||
37 | static void ar9003_hw_set_desc_link(void *ds, u32 ds_link) | ||
38 | { | ||
39 | struct ar9003_txc *ads = ds; | ||
40 | |||
41 | ads->link = ds_link; | ||
42 | ads->ctl10 &= ~AR_TxPtrChkSum; | ||
43 | ads->ctl10 |= ar9003_calc_ptr_chksum(ads); | ||
44 | } | ||
45 | |||
46 | static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link) | ||
47 | { | ||
48 | struct ar9003_txc *ads = ds; | ||
49 | |||
50 | *ds_link = &ads->link; | ||
51 | } | ||
52 | |||
53 | static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) | ||
54 | { | ||
55 | u32 isr = 0; | ||
56 | u32 mask2 = 0; | ||
57 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
58 | u32 sync_cause = 0; | ||
59 | struct ath_common *common = ath9k_hw_common(ah); | ||
60 | |||
61 | if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) { | ||
62 | if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) | ||
63 | == AR_RTC_STATUS_ON) | ||
64 | isr = REG_READ(ah, AR_ISR); | ||
65 | } | ||
66 | |||
67 | sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT; | ||
68 | |||
69 | *masked = 0; | ||
70 | |||
71 | if (!isr && !sync_cause) | ||
72 | return false; | ||
73 | |||
74 | if (isr) { | ||
75 | if (isr & AR_ISR_BCNMISC) { | ||
76 | u32 isr2; | ||
77 | isr2 = REG_READ(ah, AR_ISR_S2); | ||
78 | |||
79 | mask2 |= ((isr2 & AR_ISR_S2_TIM) >> | ||
80 | MAP_ISR_S2_TIM); | ||
81 | mask2 |= ((isr2 & AR_ISR_S2_DTIM) >> | ||
82 | MAP_ISR_S2_DTIM); | ||
83 | mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >> | ||
84 | MAP_ISR_S2_DTIMSYNC); | ||
85 | mask2 |= ((isr2 & AR_ISR_S2_CABEND) >> | ||
86 | MAP_ISR_S2_CABEND); | ||
87 | mask2 |= ((isr2 & AR_ISR_S2_GTT) << | ||
88 | MAP_ISR_S2_GTT); | ||
89 | mask2 |= ((isr2 & AR_ISR_S2_CST) << | ||
90 | MAP_ISR_S2_CST); | ||
91 | mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> | ||
92 | MAP_ISR_S2_TSFOOR); | ||
93 | |||
94 | if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { | ||
95 | REG_WRITE(ah, AR_ISR_S2, isr2); | ||
96 | isr &= ~AR_ISR_BCNMISC; | ||
97 | } | ||
98 | } | ||
99 | |||
100 | if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) | ||
101 | isr = REG_READ(ah, AR_ISR_RAC); | ||
102 | |||
103 | if (isr == 0xffffffff) { | ||
104 | *masked = 0; | ||
105 | return false; | ||
106 | } | ||
107 | |||
108 | *masked = isr & ATH9K_INT_COMMON; | ||
109 | |||
110 | if (ah->config.rx_intr_mitigation) | ||
111 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) | ||
112 | *masked |= ATH9K_INT_RXLP; | ||
113 | |||
114 | if (ah->config.tx_intr_mitigation) | ||
115 | if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) | ||
116 | *masked |= ATH9K_INT_TX; | ||
117 | |||
118 | if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) | ||
119 | *masked |= ATH9K_INT_RXLP; | ||
120 | |||
121 | if (isr & AR_ISR_HP_RXOK) | ||
122 | *masked |= ATH9K_INT_RXHP; | ||
123 | |||
124 | if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) { | ||
125 | *masked |= ATH9K_INT_TX; | ||
126 | |||
127 | if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { | ||
128 | u32 s0, s1; | ||
129 | s0 = REG_READ(ah, AR_ISR_S0); | ||
130 | REG_WRITE(ah, AR_ISR_S0, s0); | ||
131 | s1 = REG_READ(ah, AR_ISR_S1); | ||
132 | REG_WRITE(ah, AR_ISR_S1, s1); | ||
133 | |||
134 | isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR | | ||
135 | AR_ISR_TXEOL); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | if (isr & AR_ISR_GENTMR) { | ||
140 | u32 s5; | ||
141 | |||
142 | if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED) | ||
143 | s5 = REG_READ(ah, AR_ISR_S5_S); | ||
144 | else | ||
145 | s5 = REG_READ(ah, AR_ISR_S5); | ||
146 | |||
147 | ah->intr_gen_timer_trigger = | ||
148 | MS(s5, AR_ISR_S5_GENTIMER_TRIG); | ||
149 | |||
150 | ah->intr_gen_timer_thresh = | ||
151 | MS(s5, AR_ISR_S5_GENTIMER_THRESH); | ||
152 | |||
153 | if (ah->intr_gen_timer_trigger) | ||
154 | *masked |= ATH9K_INT_GENTIMER; | ||
155 | |||
156 | if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { | ||
157 | REG_WRITE(ah, AR_ISR_S5, s5); | ||
158 | isr &= ~AR_ISR_GENTMR; | ||
159 | } | ||
160 | |||
161 | } | ||
162 | |||
163 | *masked |= mask2; | ||
164 | |||
165 | if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) { | ||
166 | REG_WRITE(ah, AR_ISR, isr); | ||
167 | |||
168 | (void) REG_READ(ah, AR_ISR); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | if (sync_cause) { | ||
173 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | ||
174 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | ||
175 | REG_WRITE(ah, AR_RC, 0); | ||
176 | *masked |= ATH9K_INT_FATAL; | ||
177 | } | ||
178 | |||
179 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) | ||
180 | ath_print(common, ATH_DBG_INTERRUPT, | ||
181 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); | ||
182 | |||
183 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); | ||
184 | (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR); | ||
185 | |||
186 | } | ||
187 | return true; | ||
188 | } | ||
189 | |||
190 | static void ar9003_hw_fill_txdesc(struct ath_hw *ah, void *ds, u32 seglen, | ||
191 | bool is_firstseg, bool is_lastseg, | ||
192 | const void *ds0, dma_addr_t buf_addr, | ||
193 | unsigned int qcu) | ||
194 | { | ||
195 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
196 | unsigned int descid = 0; | ||
197 | |||
198 | ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) | | ||
199 | (1 << AR_TxRxDesc_S) | | ||
200 | (1 << AR_CtrlStat_S) | | ||
201 | (qcu << AR_TxQcuNum_S) | 0x17; | ||
202 | |||
203 | ads->data0 = buf_addr; | ||
204 | ads->data1 = 0; | ||
205 | ads->data2 = 0; | ||
206 | ads->data3 = 0; | ||
207 | |||
208 | ads->ctl3 = (seglen << AR_BufLen_S); | ||
209 | ads->ctl3 &= AR_BufLen; | ||
210 | |||
211 | /* Fill in pointer checksum and descriptor id */ | ||
212 | ads->ctl10 = ar9003_calc_ptr_chksum(ads); | ||
213 | ads->ctl10 |= (descid << AR_TxDescId_S); | ||
214 | |||
215 | if (is_firstseg) { | ||
216 | ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore); | ||
217 | } else if (is_lastseg) { | ||
218 | ads->ctl11 = 0; | ||
219 | ads->ctl12 = 0; | ||
220 | ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13; | ||
221 | ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14; | ||
222 | } else { | ||
223 | /* XXX Intermediate descriptor in a multi-descriptor frame.*/ | ||
224 | ads->ctl11 = 0; | ||
225 | ads->ctl12 = AR_TxMore; | ||
226 | ads->ctl13 = 0; | ||
227 | ads->ctl14 = 0; | ||
228 | } | ||
229 | } | ||
230 | |||
231 | static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds, | ||
232 | struct ath_tx_status *ts) | ||
233 | { | ||
234 | struct ar9003_txs *ads; | ||
235 | |||
236 | ads = &ah->ts_ring[ah->ts_tail]; | ||
237 | |||
238 | if ((ads->status8 & AR_TxDone) == 0) | ||
239 | return -EINPROGRESS; | ||
240 | |||
241 | ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size; | ||
242 | |||
243 | if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) || | ||
244 | (MS(ads->ds_info, AR_TxRxDesc) != 1)) { | ||
245 | ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT, | ||
246 | "Tx Descriptor error %x\n", ads->ds_info); | ||
247 | memset(ads, 0, sizeof(*ads)); | ||
248 | return -EIO; | ||
249 | } | ||
250 | |||
251 | ts->qid = MS(ads->ds_info, AR_TxQcuNum); | ||
252 | ts->desc_id = MS(ads->status1, AR_TxDescId); | ||
253 | ts->ts_seqnum = MS(ads->status8, AR_SeqNum); | ||
254 | ts->ts_tstamp = ads->status4; | ||
255 | ts->ts_status = 0; | ||
256 | ts->ts_flags = 0; | ||
257 | |||
258 | if (ads->status3 & AR_ExcessiveRetries) | ||
259 | ts->ts_status |= ATH9K_TXERR_XRETRY; | ||
260 | if (ads->status3 & AR_Filtered) | ||
261 | ts->ts_status |= ATH9K_TXERR_FILT; | ||
262 | if (ads->status3 & AR_FIFOUnderrun) { | ||
263 | ts->ts_status |= ATH9K_TXERR_FIFO; | ||
264 | ath9k_hw_updatetxtriglevel(ah, true); | ||
265 | } | ||
266 | if (ads->status8 & AR_TxOpExceeded) | ||
267 | ts->ts_status |= ATH9K_TXERR_XTXOP; | ||
268 | if (ads->status3 & AR_TxTimerExpired) | ||
269 | ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED; | ||
270 | |||
271 | if (ads->status3 & AR_DescCfgErr) | ||
272 | ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR; | ||
273 | if (ads->status3 & AR_TxDataUnderrun) { | ||
274 | ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN; | ||
275 | ath9k_hw_updatetxtriglevel(ah, true); | ||
276 | } | ||
277 | if (ads->status3 & AR_TxDelimUnderrun) { | ||
278 | ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN; | ||
279 | ath9k_hw_updatetxtriglevel(ah, true); | ||
280 | } | ||
281 | if (ads->status2 & AR_TxBaStatus) { | ||
282 | ts->ts_flags |= ATH9K_TX_BA; | ||
283 | ts->ba_low = ads->status5; | ||
284 | ts->ba_high = ads->status6; | ||
285 | } | ||
286 | |||
287 | ts->ts_rateindex = MS(ads->status8, AR_FinalTxIdx); | ||
288 | |||
289 | ts->ts_rssi = MS(ads->status7, AR_TxRSSICombined); | ||
290 | ts->ts_rssi_ctl0 = MS(ads->status2, AR_TxRSSIAnt00); | ||
291 | ts->ts_rssi_ctl1 = MS(ads->status2, AR_TxRSSIAnt01); | ||
292 | ts->ts_rssi_ctl2 = MS(ads->status2, AR_TxRSSIAnt02); | ||
293 | ts->ts_rssi_ext0 = MS(ads->status7, AR_TxRSSIAnt10); | ||
294 | ts->ts_rssi_ext1 = MS(ads->status7, AR_TxRSSIAnt11); | ||
295 | ts->ts_rssi_ext2 = MS(ads->status7, AR_TxRSSIAnt12); | ||
296 | ts->ts_shortretry = MS(ads->status3, AR_RTSFailCnt); | ||
297 | ts->ts_longretry = MS(ads->status3, AR_DataFailCnt); | ||
298 | ts->ts_virtcol = MS(ads->status3, AR_VirtRetryCnt); | ||
299 | ts->ts_antenna = 0; | ||
300 | |||
301 | ts->tid = MS(ads->status8, AR_TxTid); | ||
302 | |||
303 | memset(ads, 0, sizeof(*ads)); | ||
304 | |||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | ||
309 | u32 pktlen, enum ath9k_pkt_type type, u32 txpower, | ||
310 | u32 keyIx, enum ath9k_key_type keyType, u32 flags) | ||
311 | { | ||
312 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
313 | |||
314 | if (txpower > ah->txpower_limit) | ||
315 | txpower = ah->txpower_limit; | ||
316 | |||
317 | txpower += ah->txpower_indexoffset; | ||
318 | if (txpower > 63) | ||
319 | txpower = 63; | ||
320 | |||
321 | ads->ctl11 = (pktlen & AR_FrameLen) | ||
322 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | ||
323 | | SM(txpower, AR_XmitPower) | ||
324 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | ||
325 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
326 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0) | ||
327 | | (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0); | ||
328 | |||
329 | ads->ctl12 = | ||
330 | (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) | ||
331 | | SM(type, AR_FrameType) | ||
332 | | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) | ||
333 | | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) | ||
334 | | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); | ||
335 | |||
336 | ads->ctl17 = SM(keyType, AR_EncrType) | | ||
337 | (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0); | ||
338 | ads->ctl18 = 0; | ||
339 | ads->ctl19 = AR_Not_Sounding; | ||
340 | |||
341 | ads->ctl20 = 0; | ||
342 | ads->ctl21 = 0; | ||
343 | ads->ctl22 = 0; | ||
344 | } | ||
345 | |||
346 | static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, | ||
347 | void *lastds, | ||
348 | u32 durUpdateEn, u32 rtsctsRate, | ||
349 | u32 rtsctsDuration, | ||
350 | struct ath9k_11n_rate_series series[], | ||
351 | u32 nseries, u32 flags) | ||
352 | { | ||
353 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
354 | struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds; | ||
355 | u_int32_t ctl11; | ||
356 | |||
357 | if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { | ||
358 | ctl11 = ads->ctl11; | ||
359 | |||
360 | if (flags & ATH9K_TXDESC_RTSENA) { | ||
361 | ctl11 &= ~AR_CTSEnable; | ||
362 | ctl11 |= AR_RTSEnable; | ||
363 | } else { | ||
364 | ctl11 &= ~AR_RTSEnable; | ||
365 | ctl11 |= AR_CTSEnable; | ||
366 | } | ||
367 | |||
368 | ads->ctl11 = ctl11; | ||
369 | } else { | ||
370 | ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable)); | ||
371 | } | ||
372 | |||
373 | ads->ctl13 = set11nTries(series, 0) | ||
374 | | set11nTries(series, 1) | ||
375 | | set11nTries(series, 2) | ||
376 | | set11nTries(series, 3) | ||
377 | | (durUpdateEn ? AR_DurUpdateEna : 0) | ||
378 | | SM(0, AR_BurstDur); | ||
379 | |||
380 | ads->ctl14 = set11nRate(series, 0) | ||
381 | | set11nRate(series, 1) | ||
382 | | set11nRate(series, 2) | ||
383 | | set11nRate(series, 3); | ||
384 | |||
385 | ads->ctl15 = set11nPktDurRTSCTS(series, 0) | ||
386 | | set11nPktDurRTSCTS(series, 1); | ||
387 | |||
388 | ads->ctl16 = set11nPktDurRTSCTS(series, 2) | ||
389 | | set11nPktDurRTSCTS(series, 3); | ||
390 | |||
391 | ads->ctl18 = set11nRateFlags(series, 0) | ||
392 | | set11nRateFlags(series, 1) | ||
393 | | set11nRateFlags(series, 2) | ||
394 | | set11nRateFlags(series, 3) | ||
395 | | SM(rtsctsRate, AR_RTSCTSRate); | ||
396 | ads->ctl19 = AR_Not_Sounding; | ||
397 | |||
398 | last_ads->ctl13 = ads->ctl13; | ||
399 | last_ads->ctl14 = ads->ctl14; | ||
400 | } | ||
401 | |||
402 | static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, | ||
403 | u32 aggrLen) | ||
404 | { | ||
405 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
406 | |||
407 | ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); | ||
408 | |||
409 | ads->ctl17 &= ~AR_AggrLen; | ||
410 | ads->ctl17 |= SM(aggrLen, AR_AggrLen); | ||
411 | } | ||
412 | |||
413 | static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, | ||
414 | u32 numDelims) | ||
415 | { | ||
416 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
417 | unsigned int ctl17; | ||
418 | |||
419 | ads->ctl12 |= (AR_IsAggr | AR_MoreAggr); | ||
420 | |||
421 | /* | ||
422 | * We use a stack variable to manipulate ctl6 to reduce uncached | ||
423 | * read modify, modfiy, write. | ||
424 | */ | ||
425 | ctl17 = ads->ctl17; | ||
426 | ctl17 &= ~AR_PadDelim; | ||
427 | ctl17 |= SM(numDelims, AR_PadDelim); | ||
428 | ads->ctl17 = ctl17; | ||
429 | } | ||
430 | |||
431 | static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) | ||
432 | { | ||
433 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
434 | |||
435 | ads->ctl12 |= AR_IsAggr; | ||
436 | ads->ctl12 &= ~AR_MoreAggr; | ||
437 | ads->ctl17 &= ~AR_PadDelim; | ||
438 | } | ||
439 | |||
440 | static void ar9003_hw_clr11n_aggr(struct ath_hw *ah, void *ds) | ||
441 | { | ||
442 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
443 | |||
444 | ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr); | ||
445 | } | ||
446 | |||
447 | static void ar9003_hw_set11n_burstduration(struct ath_hw *ah, void *ds, | ||
448 | u32 burstDuration) | ||
449 | { | ||
450 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
451 | |||
452 | ads->ctl13 &= ~AR_BurstDur; | ||
453 | ads->ctl13 |= SM(burstDuration, AR_BurstDur); | ||
454 | |||
455 | } | ||
456 | |||
457 | static void ar9003_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, | ||
458 | u32 vmf) | ||
459 | { | ||
460 | struct ar9003_txc *ads = (struct ar9003_txc *) ds; | ||
461 | |||
462 | if (vmf) | ||
463 | ads->ctl11 |= AR_VirtMoreFrag; | ||
464 | else | ||
465 | ads->ctl11 &= ~AR_VirtMoreFrag; | ||
466 | } | ||
467 | |||
468 | void ar9003_hw_attach_mac_ops(struct ath_hw *hw) | ||
469 | { | ||
470 | struct ath_hw_ops *ops = ath9k_hw_ops(hw); | ||
471 | |||
472 | ops->rx_enable = ar9003_hw_rx_enable; | ||
473 | ops->set_desc_link = ar9003_hw_set_desc_link; | ||
474 | ops->get_desc_link = ar9003_hw_get_desc_link; | ||
475 | ops->get_isr = ar9003_hw_get_isr; | ||
476 | ops->fill_txdesc = ar9003_hw_fill_txdesc; | ||
477 | ops->proc_txdesc = ar9003_hw_proc_txdesc; | ||
478 | ops->set11n_txdesc = ar9003_hw_set11n_txdesc; | ||
479 | ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario; | ||
480 | ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first; | ||
481 | ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle; | ||
482 | ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last; | ||
483 | ops->clr11n_aggr = ar9003_hw_clr11n_aggr; | ||
484 | ops->set11n_burstduration = ar9003_hw_set11n_burstduration; | ||
485 | ops->set11n_virtualmorefrag = ar9003_hw_set11n_virtualmorefrag; | ||
486 | } | ||
487 | |||
488 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size) | ||
489 | { | ||
490 | REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK); | ||
491 | } | ||
492 | EXPORT_SYMBOL(ath9k_hw_set_rx_bufsize); | ||
493 | |||
494 | void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp, | ||
495 | enum ath9k_rx_qtype qtype) | ||
496 | { | ||
497 | if (qtype == ATH9K_RX_QUEUE_HP) | ||
498 | REG_WRITE(ah, AR_HP_RXDP, rxdp); | ||
499 | else | ||
500 | REG_WRITE(ah, AR_LP_RXDP, rxdp); | ||
501 | } | ||
502 | EXPORT_SYMBOL(ath9k_hw_addrxbuf_edma); | ||
503 | |||
504 | int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, | ||
505 | void *buf_addr) | ||
506 | { | ||
507 | struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr; | ||
508 | unsigned int phyerr; | ||
509 | |||
510 | /* TODO: byte swap on big endian for ar9300_10 */ | ||
511 | |||
512 | if ((rxsp->status11 & AR_RxDone) == 0) | ||
513 | return -EINPROGRESS; | ||
514 | |||
515 | if (MS(rxsp->ds_info, AR_DescId) != 0x168c) | ||
516 | return -EINVAL; | ||
517 | |||
518 | if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0) | ||
519 | return -EINPROGRESS; | ||
520 | |||
521 | if (!rxs) | ||
522 | return 0; | ||
523 | |||
524 | rxs->rs_status = 0; | ||
525 | rxs->rs_flags = 0; | ||
526 | |||
527 | rxs->rs_datalen = rxsp->status2 & AR_DataLen; | ||
528 | rxs->rs_tstamp = rxsp->status3; | ||
529 | |||
530 | /* XXX: Keycache */ | ||
531 | rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined); | ||
532 | rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00); | ||
533 | rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01); | ||
534 | rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02); | ||
535 | rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10); | ||
536 | rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11); | ||
537 | rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12); | ||
538 | |||
539 | if (rxsp->status11 & AR_RxKeyIdxValid) | ||
540 | rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx); | ||
541 | else | ||
542 | rxs->rs_keyix = ATH9K_RXKEYIX_INVALID; | ||
543 | |||
544 | rxs->rs_rate = MS(rxsp->status1, AR_RxRate); | ||
545 | rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0; | ||
546 | |||
547 | rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0; | ||
548 | rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0; | ||
549 | rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7); | ||
550 | rxs->rs_flags = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0; | ||
551 | rxs->rs_flags |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0; | ||
552 | |||
553 | rxs->evm0 = rxsp->status6; | ||
554 | rxs->evm1 = rxsp->status7; | ||
555 | rxs->evm2 = rxsp->status8; | ||
556 | rxs->evm3 = rxsp->status9; | ||
557 | rxs->evm4 = (rxsp->status10 & 0xffff); | ||
558 | |||
559 | if (rxsp->status11 & AR_PreDelimCRCErr) | ||
560 | rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE; | ||
561 | |||
562 | if (rxsp->status11 & AR_PostDelimCRCErr) | ||
563 | rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST; | ||
564 | |||
565 | if (rxsp->status11 & AR_DecryptBusyErr) | ||
566 | rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; | ||
567 | |||
568 | if ((rxsp->status11 & AR_RxFrameOK) == 0) { | ||
569 | if (rxsp->status11 & AR_CRCErr) { | ||
570 | rxs->rs_status |= ATH9K_RXERR_CRC; | ||
571 | } else if (rxsp->status11 & AR_PHYErr) { | ||
572 | rxs->rs_status |= ATH9K_RXERR_PHY; | ||
573 | phyerr = MS(rxsp->status11, AR_PHYErrCode); | ||
574 | rxs->rs_phyerr = phyerr; | ||
575 | } else if (rxsp->status11 & AR_DecryptCRCErr) { | ||
576 | rxs->rs_status |= ATH9K_RXERR_DECRYPT; | ||
577 | } else if (rxsp->status11 & AR_MichaelErr) { | ||
578 | rxs->rs_status |= ATH9K_RXERR_MIC; | ||
579 | } | ||
580 | } | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | EXPORT_SYMBOL(ath9k_hw_process_rxdesc_edma); | ||
585 | |||
586 | void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah) | ||
587 | { | ||
588 | ah->ts_tail = 0; | ||
589 | |||
590 | memset((void *) ah->ts_ring, 0, | ||
591 | ah->ts_size * sizeof(struct ar9003_txs)); | ||
592 | |||
593 | ath_print(ath9k_hw_common(ah), ATH_DBG_XMIT, | ||
594 | "TS Start 0x%x End 0x%x Virt %p, Size %d\n", | ||
595 | ah->ts_paddr_start, ah->ts_paddr_end, | ||
596 | ah->ts_ring, ah->ts_size); | ||
597 | |||
598 | REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start); | ||
599 | REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end); | ||
600 | } | ||
601 | |||
602 | void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start, | ||
603 | u32 ts_paddr_start, | ||
604 | u8 size) | ||
605 | { | ||
606 | |||
607 | ah->ts_paddr_start = ts_paddr_start; | ||
608 | ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs)); | ||
609 | ah->ts_size = size; | ||
610 | ah->ts_ring = (struct ar9003_txs *) ts_start; | ||
611 | |||
612 | ath9k_hw_reset_txstatus_ring(ah); | ||
613 | } | ||
614 | EXPORT_SYMBOL(ath9k_hw_setup_statusring); | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.h b/drivers/net/wireless/ath/ath9k/ar9003_mac.h new file mode 100644 index 000000000000..f17558b14539 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef AR9003_MAC_H | ||
18 | #define AR9003_MAC_H | ||
19 | |||
20 | #define AR_DescId 0xffff0000 | ||
21 | #define AR_DescId_S 16 | ||
22 | #define AR_CtrlStat 0x00004000 | ||
23 | #define AR_CtrlStat_S 14 | ||
24 | #define AR_TxRxDesc 0x00008000 | ||
25 | #define AR_TxRxDesc_S 15 | ||
26 | #define AR_TxQcuNum 0x00000f00 | ||
27 | #define AR_TxQcuNum_S 8 | ||
28 | |||
29 | #define AR_BufLen 0x0fff0000 | ||
30 | #define AR_BufLen_S 16 | ||
31 | |||
32 | #define AR_TxDescId 0xffff0000 | ||
33 | #define AR_TxDescId_S 16 | ||
34 | #define AR_TxPtrChkSum 0x0000ffff | ||
35 | |||
36 | #define AR_TxTid 0xf0000000 | ||
37 | #define AR_TxTid_S 28 | ||
38 | |||
39 | #define AR_LowRxChain 0x00004000 | ||
40 | |||
41 | #define AR_Not_Sounding 0x20000000 | ||
42 | |||
43 | #define MAP_ISR_S2_CST 6 | ||
44 | #define MAP_ISR_S2_GTT 6 | ||
45 | #define MAP_ISR_S2_TIM 3 | ||
46 | #define MAP_ISR_S2_CABEND 0 | ||
47 | #define MAP_ISR_S2_DTIMSYNC 7 | ||
48 | #define MAP_ISR_S2_DTIM 7 | ||
49 | #define MAP_ISR_S2_TSFOOR 4 | ||
50 | |||
51 | #define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds) | ||
52 | |||
53 | struct ar9003_rxs { | ||
54 | u32 ds_info; | ||
55 | u32 status1; | ||
56 | u32 status2; | ||
57 | u32 status3; | ||
58 | u32 status4; | ||
59 | u32 status5; | ||
60 | u32 status6; | ||
61 | u32 status7; | ||
62 | u32 status8; | ||
63 | u32 status9; | ||
64 | u32 status10; | ||
65 | u32 status11; | ||
66 | } __packed; | ||
67 | |||
68 | /* Transmit Control Descriptor */ | ||
69 | struct ar9003_txc { | ||
70 | u32 info; /* descriptor information */ | ||
71 | u32 link; /* link pointer */ | ||
72 | u32 data0; /* data pointer to 1st buffer */ | ||
73 | u32 ctl3; /* DMA control 3 */ | ||
74 | u32 data1; /* data pointer to 2nd buffer */ | ||
75 | u32 ctl5; /* DMA control 5 */ | ||
76 | u32 data2; /* data pointer to 3rd buffer */ | ||
77 | u32 ctl7; /* DMA control 7 */ | ||
78 | u32 data3; /* data pointer to 4th buffer */ | ||
79 | u32 ctl9; /* DMA control 9 */ | ||
80 | u32 ctl10; /* DMA control 10 */ | ||
81 | u32 ctl11; /* DMA control 11 */ | ||
82 | u32 ctl12; /* DMA control 12 */ | ||
83 | u32 ctl13; /* DMA control 13 */ | ||
84 | u32 ctl14; /* DMA control 14 */ | ||
85 | u32 ctl15; /* DMA control 15 */ | ||
86 | u32 ctl16; /* DMA control 16 */ | ||
87 | u32 ctl17; /* DMA control 17 */ | ||
88 | u32 ctl18; /* DMA control 18 */ | ||
89 | u32 ctl19; /* DMA control 19 */ | ||
90 | u32 ctl20; /* DMA control 20 */ | ||
91 | u32 ctl21; /* DMA control 21 */ | ||
92 | u32 ctl22; /* DMA control 22 */ | ||
93 | u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */ | ||
94 | } __packed; | ||
95 | |||
96 | struct ar9003_txs { | ||
97 | u32 ds_info; | ||
98 | u32 status1; | ||
99 | u32 status2; | ||
100 | u32 status3; | ||
101 | u32 status4; | ||
102 | u32 status5; | ||
103 | u32 status6; | ||
104 | u32 status7; | ||
105 | u32 status8; | ||
106 | } __packed; | ||
107 | |||
108 | void ar9003_hw_attach_mac_ops(struct ath_hw *hw); | ||
109 | void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size); | ||
110 | void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp, | ||
111 | enum ath9k_rx_qtype qtype); | ||
112 | |||
113 | int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, | ||
114 | struct ath_rx_status *rxs, | ||
115 | void *buf_addr); | ||
116 | void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah); | ||
117 | void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start, | ||
118 | u32 ts_paddr_start, | ||
119 | u8 size); | ||
120 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c new file mode 100644 index 000000000000..80431a2f6dc1 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c | |||
@@ -0,0 +1,1134 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "hw.h" | ||
18 | #include "ar9003_phy.h" | ||
19 | |||
20 | /** | ||
21 | * ar9003_hw_set_channel - set channel on single-chip device | ||
22 | * @ah: atheros hardware structure | ||
23 | * @chan: | ||
24 | * | ||
25 | * This is the function to change channel on single-chip devices, that is | ||
26 | * all devices after ar9280. | ||
27 | * | ||
28 | * This function takes the channel value in MHz and sets | ||
29 | * hardware channel value. Assumes writes have been enabled to analog bus. | ||
30 | * | ||
31 | * Actual Expression, | ||
32 | * | ||
33 | * For 2GHz channel, | ||
34 | * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) | ||
35 | * (freq_ref = 40MHz) | ||
36 | * | ||
37 | * For 5GHz channel, | ||
38 | * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) | ||
39 | * (freq_ref = 40MHz/(24>>amodeRefSel)) | ||
40 | * | ||
41 | * For 5GHz channels which are 5MHz spaced, | ||
42 | * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) | ||
43 | * (freq_ref = 40MHz) | ||
44 | */ | ||
45 | static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
46 | { | ||
47 | u16 bMode, fracMode = 0, aModeRefSel = 0; | ||
48 | u32 freq, channelSel = 0, reg32 = 0; | ||
49 | struct chan_centers centers; | ||
50 | int loadSynthChannel; | ||
51 | |||
52 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
53 | freq = centers.synth_center; | ||
54 | |||
55 | if (freq < 4800) { /* 2 GHz, fractional mode */ | ||
56 | channelSel = CHANSEL_2G(freq); | ||
57 | /* Set to 2G mode */ | ||
58 | bMode = 1; | ||
59 | } else { | ||
60 | channelSel = CHANSEL_5G(freq); | ||
61 | /* Doubler is ON, so, divide channelSel by 2. */ | ||
62 | channelSel >>= 1; | ||
63 | /* Set to 5G mode */ | ||
64 | bMode = 0; | ||
65 | } | ||
66 | |||
67 | /* Enable fractional mode for all channels */ | ||
68 | fracMode = 1; | ||
69 | aModeRefSel = 0; | ||
70 | loadSynthChannel = 0; | ||
71 | |||
72 | reg32 = (bMode << 29); | ||
73 | REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); | ||
74 | |||
75 | /* Enable Long shift Select for Synthesizer */ | ||
76 | REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH4, | ||
77 | AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1); | ||
78 | |||
79 | /* Program Synth. setting */ | ||
80 | reg32 = (channelSel << 2) | (fracMode << 30) | | ||
81 | (aModeRefSel << 28) | (loadSynthChannel << 31); | ||
82 | REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); | ||
83 | |||
84 | /* Toggle Load Synth channel bit */ | ||
85 | loadSynthChannel = 1; | ||
86 | reg32 = (channelSel << 2) | (fracMode << 30) | | ||
87 | (aModeRefSel << 28) | (loadSynthChannel << 31); | ||
88 | REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32); | ||
89 | |||
90 | ah->curchan = chan; | ||
91 | ah->curchan_rad_index = -1; | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | /** | ||
97 | * ar9003_hw_spur_mitigate - convert baseband spur frequency | ||
98 | * @ah: atheros hardware structure | ||
99 | * @chan: | ||
100 | * | ||
101 | * For single-chip solutions. Converts to baseband spur frequency given the | ||
102 | * input channel frequency and compute register settings below. | ||
103 | * | ||
104 | * Spur mitigation for MRC CCK | ||
105 | */ | ||
106 | static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, | ||
107 | struct ath9k_channel *chan) | ||
108 | { | ||
109 | u32 spur_freq[4] = { 2420, 2440, 2464, 2480 }; | ||
110 | int cur_bb_spur, negative = 0, cck_spur_freq; | ||
111 | int i; | ||
112 | |||
113 | /* | ||
114 | * Need to verify range +/- 10 MHz in control channel, otherwise spur | ||
115 | * is out-of-band and can be ignored. | ||
116 | */ | ||
117 | |||
118 | for (i = 0; i < 4; i++) { | ||
119 | negative = 0; | ||
120 | cur_bb_spur = spur_freq[i] - chan->channel; | ||
121 | |||
122 | if (cur_bb_spur < 0) { | ||
123 | negative = 1; | ||
124 | cur_bb_spur = -cur_bb_spur; | ||
125 | } | ||
126 | if (cur_bb_spur < 10) { | ||
127 | cck_spur_freq = (int)((cur_bb_spur << 19) / 11); | ||
128 | |||
129 | if (negative == 1) | ||
130 | cck_spur_freq = -cck_spur_freq; | ||
131 | |||
132 | cck_spur_freq = cck_spur_freq & 0xfffff; | ||
133 | |||
134 | REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, | ||
135 | AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7); | ||
136 | REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, | ||
137 | AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f); | ||
138 | REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, | ||
139 | AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE, | ||
140 | 0x2); | ||
141 | REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, | ||
142 | AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, | ||
143 | 0x1); | ||
144 | REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, | ||
145 | AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, | ||
146 | cck_spur_freq); | ||
147 | |||
148 | return; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL, | ||
153 | AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5); | ||
154 | REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, | ||
155 | AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0); | ||
156 | REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT, | ||
157 | AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0); | ||
158 | } | ||
159 | |||
160 | /* Clean all spur register fields */ | ||
161 | static void ar9003_hw_spur_ofdm_clear(struct ath_hw *ah) | ||
162 | { | ||
163 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
164 | AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0); | ||
165 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
166 | AR_PHY_TIMING11_SPUR_FREQ_SD, 0); | ||
167 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
168 | AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0); | ||
169 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
170 | AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0); | ||
171 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
172 | AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0); | ||
173 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
174 | AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0); | ||
175 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
176 | AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0); | ||
177 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
178 | AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0); | ||
179 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
180 | AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0); | ||
181 | |||
182 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
183 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0); | ||
184 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
185 | AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0); | ||
186 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
187 | AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0); | ||
188 | REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, | ||
189 | AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0); | ||
190 | REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, | ||
191 | AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0); | ||
192 | REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, | ||
193 | AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0); | ||
194 | REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, | ||
195 | AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0); | ||
196 | REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, | ||
197 | AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0); | ||
198 | REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, | ||
199 | AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0); | ||
200 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
201 | AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0); | ||
202 | } | ||
203 | |||
204 | static void ar9003_hw_spur_ofdm(struct ath_hw *ah, | ||
205 | int freq_offset, | ||
206 | int spur_freq_sd, | ||
207 | int spur_delta_phase, | ||
208 | int spur_subchannel_sd) | ||
209 | { | ||
210 | int mask_index = 0; | ||
211 | |||
212 | /* OFDM Spur mitigation */ | ||
213 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
214 | AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1); | ||
215 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
216 | AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd); | ||
217 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
218 | AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase); | ||
219 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
220 | AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd); | ||
221 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
222 | AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1); | ||
223 | REG_RMW_FIELD(ah, AR_PHY_TIMING11, | ||
224 | AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1); | ||
225 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
226 | AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1); | ||
227 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
228 | AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34); | ||
229 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
230 | AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1); | ||
231 | |||
232 | if (REG_READ_FIELD(ah, AR_PHY_MODE, | ||
233 | AR_PHY_MODE_DYNAMIC) == 0x1) | ||
234 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
235 | AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1); | ||
236 | |||
237 | mask_index = (freq_offset << 4) / 5; | ||
238 | if (mask_index < 0) | ||
239 | mask_index = mask_index - 1; | ||
240 | |||
241 | mask_index = mask_index & 0x7f; | ||
242 | |||
243 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
244 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1); | ||
245 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
246 | AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1); | ||
247 | REG_RMW_FIELD(ah, AR_PHY_TIMING4, | ||
248 | AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1); | ||
249 | REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, | ||
250 | AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index); | ||
251 | REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, | ||
252 | AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, mask_index); | ||
253 | REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, | ||
254 | AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index); | ||
255 | REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, | ||
256 | AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0xc); | ||
257 | REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, | ||
258 | AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0xc); | ||
259 | REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A, | ||
260 | AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0); | ||
261 | REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, | ||
262 | AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff); | ||
263 | } | ||
264 | |||
265 | static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, | ||
266 | struct ath9k_channel *chan, | ||
267 | int freq_offset) | ||
268 | { | ||
269 | int spur_freq_sd = 0; | ||
270 | int spur_subchannel_sd = 0; | ||
271 | int spur_delta_phase = 0; | ||
272 | |||
273 | if (IS_CHAN_HT40(chan)) { | ||
274 | if (freq_offset < 0) { | ||
275 | if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, | ||
276 | AR_PHY_GC_DYN2040_PRI_CH) == 0x0) | ||
277 | spur_subchannel_sd = 1; | ||
278 | else | ||
279 | spur_subchannel_sd = 0; | ||
280 | |||
281 | spur_freq_sd = ((freq_offset + 10) << 9) / 11; | ||
282 | |||
283 | } else { | ||
284 | if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, | ||
285 | AR_PHY_GC_DYN2040_PRI_CH) == 0x0) | ||
286 | spur_subchannel_sd = 0; | ||
287 | else | ||
288 | spur_subchannel_sd = 1; | ||
289 | |||
290 | spur_freq_sd = ((freq_offset - 10) << 9) / 11; | ||
291 | |||
292 | } | ||
293 | |||
294 | spur_delta_phase = (freq_offset << 17) / 5; | ||
295 | |||
296 | } else { | ||
297 | spur_subchannel_sd = 0; | ||
298 | spur_freq_sd = (freq_offset << 9) /11; | ||
299 | spur_delta_phase = (freq_offset << 18) / 5; | ||
300 | } | ||
301 | |||
302 | spur_freq_sd = spur_freq_sd & 0x3ff; | ||
303 | spur_delta_phase = spur_delta_phase & 0xfffff; | ||
304 | |||
305 | ar9003_hw_spur_ofdm(ah, | ||
306 | freq_offset, | ||
307 | spur_freq_sd, | ||
308 | spur_delta_phase, | ||
309 | spur_subchannel_sd); | ||
310 | } | ||
311 | |||
312 | /* Spur mitigation for OFDM */ | ||
313 | static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, | ||
314 | struct ath9k_channel *chan) | ||
315 | { | ||
316 | int synth_freq; | ||
317 | int range = 10; | ||
318 | int freq_offset = 0; | ||
319 | int mode; | ||
320 | u8* spurChansPtr; | ||
321 | unsigned int i; | ||
322 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
323 | |||
324 | if (IS_CHAN_5GHZ(chan)) { | ||
325 | spurChansPtr = &(eep->modalHeader5G.spurChans[0]); | ||
326 | mode = 0; | ||
327 | } | ||
328 | else { | ||
329 | spurChansPtr = &(eep->modalHeader2G.spurChans[0]); | ||
330 | mode = 1; | ||
331 | } | ||
332 | |||
333 | if (spurChansPtr[0] == 0) | ||
334 | return; /* No spur in the mode */ | ||
335 | |||
336 | if (IS_CHAN_HT40(chan)) { | ||
337 | range = 19; | ||
338 | if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL, | ||
339 | AR_PHY_GC_DYN2040_PRI_CH) == 0x0) | ||
340 | synth_freq = chan->channel - 10; | ||
341 | else | ||
342 | synth_freq = chan->channel + 10; | ||
343 | } else { | ||
344 | range = 10; | ||
345 | synth_freq = chan->channel; | ||
346 | } | ||
347 | |||
348 | ar9003_hw_spur_ofdm_clear(ah); | ||
349 | |||
350 | for (i = 0; spurChansPtr[i] && i < 5; i++) { | ||
351 | freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq; | ||
352 | if (abs(freq_offset) < range) { | ||
353 | ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); | ||
354 | break; | ||
355 | } | ||
356 | } | ||
357 | } | ||
358 | |||
359 | static void ar9003_hw_spur_mitigate(struct ath_hw *ah, | ||
360 | struct ath9k_channel *chan) | ||
361 | { | ||
362 | ar9003_hw_spur_mitigate_mrc_cck(ah, chan); | ||
363 | ar9003_hw_spur_mitigate_ofdm(ah, chan); | ||
364 | } | ||
365 | |||
366 | static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah, | ||
367 | struct ath9k_channel *chan) | ||
368 | { | ||
369 | u32 pll; | ||
370 | |||
371 | pll = SM(0x5, AR_RTC_9300_PLL_REFDIV); | ||
372 | |||
373 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
374 | pll |= SM(0x1, AR_RTC_9300_PLL_CLKSEL); | ||
375 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
376 | pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL); | ||
377 | |||
378 | pll |= SM(0x2c, AR_RTC_9300_PLL_DIV); | ||
379 | |||
380 | return pll; | ||
381 | } | ||
382 | |||
383 | static void ar9003_hw_set_channel_regs(struct ath_hw *ah, | ||
384 | struct ath9k_channel *chan) | ||
385 | { | ||
386 | u32 phymode; | ||
387 | u32 enableDacFifo = 0; | ||
388 | |||
389 | enableDacFifo = | ||
390 | (REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO); | ||
391 | |||
392 | /* Enable 11n HT, 20 MHz */ | ||
393 | phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH | | ||
394 | AR_PHY_GC_SHORT_GI_40 | enableDacFifo; | ||
395 | |||
396 | /* Configure baseband for dynamic 20/40 operation */ | ||
397 | if (IS_CHAN_HT40(chan)) { | ||
398 | phymode |= AR_PHY_GC_DYN2040_EN; | ||
399 | /* Configure control (primary) channel at +-10MHz */ | ||
400 | if ((chan->chanmode == CHANNEL_A_HT40PLUS) || | ||
401 | (chan->chanmode == CHANNEL_G_HT40PLUS)) | ||
402 | phymode |= AR_PHY_GC_DYN2040_PRI_CH; | ||
403 | |||
404 | } | ||
405 | |||
406 | /* make sure we preserve INI settings */ | ||
407 | phymode |= REG_READ(ah, AR_PHY_GEN_CTRL); | ||
408 | /* turn off Green Field detection for STA for now */ | ||
409 | phymode &= ~AR_PHY_GC_GF_DETECT_EN; | ||
410 | |||
411 | REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode); | ||
412 | |||
413 | /* Configure MAC for 20/40 operation */ | ||
414 | ath9k_hw_set11nmac2040(ah); | ||
415 | |||
416 | /* global transmit timeout (25 TUs default)*/ | ||
417 | REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); | ||
418 | /* carrier sense timeout */ | ||
419 | REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); | ||
420 | } | ||
421 | |||
422 | static void ar9003_hw_init_bb(struct ath_hw *ah, | ||
423 | struct ath9k_channel *chan) | ||
424 | { | ||
425 | u32 synthDelay; | ||
426 | |||
427 | /* | ||
428 | * Wait for the frequency synth to settle (synth goes on | ||
429 | * via AR_PHY_ACTIVE_EN). Read the phy active delay register. | ||
430 | * Value is in 100ns increments. | ||
431 | */ | ||
432 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | ||
433 | if (IS_CHAN_B(chan)) | ||
434 | synthDelay = (4 * synthDelay) / 22; | ||
435 | else | ||
436 | synthDelay /= 10; | ||
437 | |||
438 | /* Activate the PHY (includes baseband activate + synthesizer on) */ | ||
439 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | ||
440 | |||
441 | /* | ||
442 | * There is an issue if the AP starts the calibration before | ||
443 | * the base band timeout completes. This could result in the | ||
444 | * rx_clear false triggering. As a workaround we add delay an | ||
445 | * extra BASE_ACTIVATE_DELAY usecs to ensure this condition | ||
446 | * does not happen. | ||
447 | */ | ||
448 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
449 | } | ||
450 | |||
451 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) | ||
452 | { | ||
453 | switch (rx) { | ||
454 | case 0x5: | ||
455 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
456 | AR_PHY_SWAP_ALT_CHAIN); | ||
457 | case 0x3: | ||
458 | case 0x1: | ||
459 | case 0x2: | ||
460 | case 0x7: | ||
461 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx); | ||
462 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx); | ||
463 | break; | ||
464 | default: | ||
465 | break; | ||
466 | } | ||
467 | |||
468 | REG_WRITE(ah, AR_SELFGEN_MASK, tx); | ||
469 | if (tx == 0x5) { | ||
470 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
471 | AR_PHY_SWAP_ALT_CHAIN); | ||
472 | } | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * Override INI values with chip specific configuration. | ||
477 | */ | ||
478 | static void ar9003_hw_override_ini(struct ath_hw *ah) | ||
479 | { | ||
480 | u32 val; | ||
481 | |||
482 | /* | ||
483 | * Set the RX_ABORT and RX_DIS and clear it only after | ||
484 | * RXE is set for MAC. This prevents frames with | ||
485 | * corrupted descriptor status. | ||
486 | */ | ||
487 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
488 | |||
489 | /* | ||
490 | * For AR9280 and above, there is a new feature that allows | ||
491 | * Multicast search based on both MAC Address and Key ID. By default, | ||
492 | * this feature is enabled. But since the driver is not using this | ||
493 | * feature, we switch it off; otherwise multicast search based on | ||
494 | * MAC addr only will fail. | ||
495 | */ | ||
496 | val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE); | ||
497 | REG_WRITE(ah, AR_PCU_MISC_MODE2, | ||
498 | val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE); | ||
499 | } | ||
500 | |||
501 | static void ar9003_hw_prog_ini(struct ath_hw *ah, | ||
502 | struct ar5416IniArray *iniArr, | ||
503 | int column) | ||
504 | { | ||
505 | unsigned int i, regWrites = 0; | ||
506 | |||
507 | /* New INI format: Array may be undefined (pre, core, post arrays) */ | ||
508 | if (!iniArr->ia_array) | ||
509 | return; | ||
510 | |||
511 | /* | ||
512 | * New INI format: Pre, core, and post arrays for a given subsystem | ||
513 | * may be modal (> 2 columns) or non-modal (2 columns). Determine if | ||
514 | * the array is non-modal and force the column to 1. | ||
515 | */ | ||
516 | if (column >= iniArr->ia_columns) | ||
517 | column = 1; | ||
518 | |||
519 | for (i = 0; i < iniArr->ia_rows; i++) { | ||
520 | u32 reg = INI_RA(iniArr, i, 0); | ||
521 | u32 val = INI_RA(iniArr, i, column); | ||
522 | |||
523 | REG_WRITE(ah, reg, val); | ||
524 | |||
525 | /* | ||
526 | * Determine if this is a shift register value, and insert the | ||
527 | * configured delay if so. | ||
528 | */ | ||
529 | if (reg >= 0x16000 && reg < 0x17000 | ||
530 | && ah->config.analog_shiftreg) | ||
531 | udelay(100); | ||
532 | |||
533 | DO_DELAY(regWrites); | ||
534 | } | ||
535 | } | ||
536 | |||
537 | static int ar9003_hw_process_ini(struct ath_hw *ah, | ||
538 | struct ath9k_channel *chan) | ||
539 | { | ||
540 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | ||
541 | unsigned int regWrites = 0, i; | ||
542 | struct ieee80211_channel *channel = chan->chan; | ||
543 | u32 modesIndex, freqIndex; | ||
544 | |||
545 | switch (chan->chanmode) { | ||
546 | case CHANNEL_A: | ||
547 | case CHANNEL_A_HT20: | ||
548 | modesIndex = 1; | ||
549 | freqIndex = 1; | ||
550 | break; | ||
551 | case CHANNEL_A_HT40PLUS: | ||
552 | case CHANNEL_A_HT40MINUS: | ||
553 | modesIndex = 2; | ||
554 | freqIndex = 1; | ||
555 | break; | ||
556 | case CHANNEL_G: | ||
557 | case CHANNEL_G_HT20: | ||
558 | case CHANNEL_B: | ||
559 | modesIndex = 4; | ||
560 | freqIndex = 2; | ||
561 | break; | ||
562 | case CHANNEL_G_HT40PLUS: | ||
563 | case CHANNEL_G_HT40MINUS: | ||
564 | modesIndex = 3; | ||
565 | freqIndex = 2; | ||
566 | break; | ||
567 | |||
568 | default: | ||
569 | return -EINVAL; | ||
570 | } | ||
571 | |||
572 | for (i = 0; i < ATH_INI_NUM_SPLIT; i++) { | ||
573 | ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex); | ||
574 | ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); | ||
575 | ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); | ||
576 | ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); | ||
577 | } | ||
578 | |||
579 | REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); | ||
580 | REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); | ||
581 | |||
582 | /* | ||
583 | * For 5GHz channels requiring Fast Clock, apply | ||
584 | * different modal values. | ||
585 | */ | ||
586 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | ||
587 | REG_WRITE_ARRAY(&ah->iniModesAdditional, | ||
588 | modesIndex, regWrites); | ||
589 | |||
590 | ar9003_hw_override_ini(ah); | ||
591 | ar9003_hw_set_channel_regs(ah, chan); | ||
592 | ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); | ||
593 | |||
594 | /* Set TX power */ | ||
595 | ah->eep_ops->set_txpower(ah, chan, | ||
596 | ath9k_regd_get_ctl(regulatory, chan), | ||
597 | channel->max_antenna_gain * 2, | ||
598 | channel->max_power * 2, | ||
599 | min((u32) MAX_RATE_POWER, | ||
600 | (u32) regulatory->power_limit)); | ||
601 | |||
602 | return 0; | ||
603 | } | ||
604 | |||
605 | static void ar9003_hw_set_rfmode(struct ath_hw *ah, | ||
606 | struct ath9k_channel *chan) | ||
607 | { | ||
608 | u32 rfMode = 0; | ||
609 | |||
610 | if (chan == NULL) | ||
611 | return; | ||
612 | |||
613 | rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) | ||
614 | ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; | ||
615 | |||
616 | if (IS_CHAN_A_FAST_CLOCK(ah, chan)) | ||
617 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | ||
618 | |||
619 | REG_WRITE(ah, AR_PHY_MODE, rfMode); | ||
620 | } | ||
621 | |||
622 | static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah) | ||
623 | { | ||
624 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||
625 | } | ||
626 | |||
627 | static void ar9003_hw_set_delta_slope(struct ath_hw *ah, | ||
628 | struct ath9k_channel *chan) | ||
629 | { | ||
630 | u32 coef_scaled, ds_coef_exp, ds_coef_man; | ||
631 | u32 clockMhzScaled = 0x64000000; | ||
632 | struct chan_centers centers; | ||
633 | |||
634 | /* | ||
635 | * half and quarter rate can divide the scaled clock by 2 or 4 | ||
636 | * scale for selected channel bandwidth | ||
637 | */ | ||
638 | if (IS_CHAN_HALF_RATE(chan)) | ||
639 | clockMhzScaled = clockMhzScaled >> 1; | ||
640 | else if (IS_CHAN_QUARTER_RATE(chan)) | ||
641 | clockMhzScaled = clockMhzScaled >> 2; | ||
642 | |||
643 | /* | ||
644 | * ALGO -> coef = 1e8/fcarrier*fclock/40; | ||
645 | * scaled coef to provide precision for this floating calculation | ||
646 | */ | ||
647 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
648 | coef_scaled = clockMhzScaled / centers.synth_center; | ||
649 | |||
650 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
651 | &ds_coef_exp); | ||
652 | |||
653 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
654 | AR_PHY_TIMING3_DSC_MAN, ds_coef_man); | ||
655 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
656 | AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); | ||
657 | |||
658 | /* | ||
659 | * For Short GI, | ||
660 | * scaled coeff is 9/10 that of normal coeff | ||
661 | */ | ||
662 | coef_scaled = (9 * coef_scaled) / 10; | ||
663 | |||
664 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
665 | &ds_coef_exp); | ||
666 | |||
667 | /* for short gi */ | ||
668 | REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, | ||
669 | AR_PHY_SGI_DSC_MAN, ds_coef_man); | ||
670 | REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA, | ||
671 | AR_PHY_SGI_DSC_EXP, ds_coef_exp); | ||
672 | } | ||
673 | |||
674 | static bool ar9003_hw_rfbus_req(struct ath_hw *ah) | ||
675 | { | ||
676 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); | ||
677 | return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, | ||
678 | AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT); | ||
679 | } | ||
680 | |||
681 | /* | ||
682 | * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN). | ||
683 | * Read the phy active delay register. Value is in 100ns increments. | ||
684 | */ | ||
685 | static void ar9003_hw_rfbus_done(struct ath_hw *ah) | ||
686 | { | ||
687 | u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | ||
688 | if (IS_CHAN_B(ah->curchan)) | ||
689 | synthDelay = (4 * synthDelay) / 22; | ||
690 | else | ||
691 | synthDelay /= 10; | ||
692 | |||
693 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
694 | |||
695 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); | ||
696 | } | ||
697 | |||
698 | /* | ||
699 | * Set the interrupt and GPIO values so the ISR can disable RF | ||
700 | * on a switch signal. Assumes GPIO port and interrupt polarity | ||
701 | * are set prior to call. | ||
702 | */ | ||
703 | static void ar9003_hw_enable_rfkill(struct ath_hw *ah) | ||
704 | { | ||
705 | /* Connect rfsilent_bb_l to baseband */ | ||
706 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | ||
707 | AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); | ||
708 | /* Set input mux for rfsilent_bb_l to GPIO #0 */ | ||
709 | REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, | ||
710 | AR_GPIO_INPUT_MUX2_RFSILENT); | ||
711 | |||
712 | /* | ||
713 | * Configure the desired GPIO port for input and | ||
714 | * enable baseband rf silence. | ||
715 | */ | ||
716 | ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); | ||
717 | REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); | ||
718 | } | ||
719 | |||
720 | static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) | ||
721 | { | ||
722 | u32 v = REG_READ(ah, AR_PHY_CCK_DETECT); | ||
723 | if (value) | ||
724 | v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
725 | else | ||
726 | v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
727 | REG_WRITE(ah, AR_PHY_CCK_DETECT, v); | ||
728 | } | ||
729 | |||
730 | static bool ar9003_hw_ani_control(struct ath_hw *ah, | ||
731 | enum ath9k_ani_cmd cmd, int param) | ||
732 | { | ||
733 | struct ar5416AniState *aniState = ah->curani; | ||
734 | struct ath_common *common = ath9k_hw_common(ah); | ||
735 | |||
736 | switch (cmd & ah->ani_function) { | ||
737 | case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{ | ||
738 | u32 level = param; | ||
739 | |||
740 | if (level >= ARRAY_SIZE(ah->totalSizeDesired)) { | ||
741 | ath_print(common, ATH_DBG_ANI, | ||
742 | "level out of range (%u > %u)\n", | ||
743 | level, | ||
744 | (unsigned)ARRAY_SIZE(ah->totalSizeDesired)); | ||
745 | return false; | ||
746 | } | ||
747 | |||
748 | REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, | ||
749 | AR_PHY_DESIRED_SZ_TOT_DES, | ||
750 | ah->totalSizeDesired[level]); | ||
751 | REG_RMW_FIELD(ah, AR_PHY_AGC, | ||
752 | AR_PHY_AGC_COARSE_LOW, | ||
753 | ah->coarse_low[level]); | ||
754 | REG_RMW_FIELD(ah, AR_PHY_AGC, | ||
755 | AR_PHY_AGC_COARSE_HIGH, | ||
756 | ah->coarse_high[level]); | ||
757 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
758 | AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]); | ||
759 | |||
760 | if (level > aniState->noiseImmunityLevel) | ||
761 | ah->stats.ast_ani_niup++; | ||
762 | else if (level < aniState->noiseImmunityLevel) | ||
763 | ah->stats.ast_ani_nidown++; | ||
764 | aniState->noiseImmunityLevel = level; | ||
765 | break; | ||
766 | } | ||
767 | case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{ | ||
768 | const int m1ThreshLow[] = { 127, 50 }; | ||
769 | const int m2ThreshLow[] = { 127, 40 }; | ||
770 | const int m1Thresh[] = { 127, 0x4d }; | ||
771 | const int m2Thresh[] = { 127, 0x40 }; | ||
772 | const int m2CountThr[] = { 31, 16 }; | ||
773 | const int m2CountThrLow[] = { 63, 48 }; | ||
774 | u32 on = param ? 1 : 0; | ||
775 | |||
776 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
777 | AR_PHY_SFCORR_LOW_M1_THRESH_LOW, | ||
778 | m1ThreshLow[on]); | ||
779 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
780 | AR_PHY_SFCORR_LOW_M2_THRESH_LOW, | ||
781 | m2ThreshLow[on]); | ||
782 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
783 | AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]); | ||
784 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
785 | AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]); | ||
786 | REG_RMW_FIELD(ah, AR_PHY_SFCORR, | ||
787 | AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]); | ||
788 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW, | ||
789 | AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW, | ||
790 | m2CountThrLow[on]); | ||
791 | |||
792 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
793 | AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]); | ||
794 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
795 | AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]); | ||
796 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
797 | AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]); | ||
798 | REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT, | ||
799 | AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]); | ||
800 | |||
801 | if (on) | ||
802 | REG_SET_BIT(ah, AR_PHY_SFCORR_LOW, | ||
803 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
804 | else | ||
805 | REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW, | ||
806 | AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW); | ||
807 | |||
808 | if (!on != aniState->ofdmWeakSigDetectOff) { | ||
809 | if (on) | ||
810 | ah->stats.ast_ani_ofdmon++; | ||
811 | else | ||
812 | ah->stats.ast_ani_ofdmoff++; | ||
813 | aniState->ofdmWeakSigDetectOff = !on; | ||
814 | } | ||
815 | break; | ||
816 | } | ||
817 | case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{ | ||
818 | const int weakSigThrCck[] = { 8, 6 }; | ||
819 | u32 high = param ? 1 : 0; | ||
820 | |||
821 | REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT, | ||
822 | AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK, | ||
823 | weakSigThrCck[high]); | ||
824 | if (high != aniState->cckWeakSigThreshold) { | ||
825 | if (high) | ||
826 | ah->stats.ast_ani_cckhigh++; | ||
827 | else | ||
828 | ah->stats.ast_ani_ccklow++; | ||
829 | aniState->cckWeakSigThreshold = high; | ||
830 | } | ||
831 | break; | ||
832 | } | ||
833 | case ATH9K_ANI_FIRSTEP_LEVEL:{ | ||
834 | const int firstep[] = { 0, 4, 8 }; | ||
835 | u32 level = param; | ||
836 | |||
837 | if (level >= ARRAY_SIZE(firstep)) { | ||
838 | ath_print(common, ATH_DBG_ANI, | ||
839 | "level out of range (%u > %u)\n", | ||
840 | level, | ||
841 | (unsigned) ARRAY_SIZE(firstep)); | ||
842 | return false; | ||
843 | } | ||
844 | REG_RMW_FIELD(ah, AR_PHY_FIND_SIG, | ||
845 | AR_PHY_FIND_SIG_FIRSTEP, | ||
846 | firstep[level]); | ||
847 | if (level > aniState->firstepLevel) | ||
848 | ah->stats.ast_ani_stepup++; | ||
849 | else if (level < aniState->firstepLevel) | ||
850 | ah->stats.ast_ani_stepdown++; | ||
851 | aniState->firstepLevel = level; | ||
852 | break; | ||
853 | } | ||
854 | case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{ | ||
855 | const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 }; | ||
856 | u32 level = param; | ||
857 | |||
858 | if (level >= ARRAY_SIZE(cycpwrThr1)) { | ||
859 | ath_print(common, ATH_DBG_ANI, | ||
860 | "level out of range (%u > %u)\n", | ||
861 | level, | ||
862 | (unsigned) ARRAY_SIZE(cycpwrThr1)); | ||
863 | return false; | ||
864 | } | ||
865 | REG_RMW_FIELD(ah, AR_PHY_TIMING5, | ||
866 | AR_PHY_TIMING5_CYCPWR_THR1, | ||
867 | cycpwrThr1[level]); | ||
868 | if (level > aniState->spurImmunityLevel) | ||
869 | ah->stats.ast_ani_spurup++; | ||
870 | else if (level < aniState->spurImmunityLevel) | ||
871 | ah->stats.ast_ani_spurdown++; | ||
872 | aniState->spurImmunityLevel = level; | ||
873 | break; | ||
874 | } | ||
875 | case ATH9K_ANI_PRESENT: | ||
876 | break; | ||
877 | default: | ||
878 | ath_print(common, ATH_DBG_ANI, | ||
879 | "invalid cmd %u\n", cmd); | ||
880 | return false; | ||
881 | } | ||
882 | |||
883 | ath_print(common, ATH_DBG_ANI, "ANI parameters:\n"); | ||
884 | ath_print(common, ATH_DBG_ANI, | ||
885 | "noiseImmunityLevel=%d, spurImmunityLevel=%d, " | ||
886 | "ofdmWeakSigDetectOff=%d\n", | ||
887 | aniState->noiseImmunityLevel, | ||
888 | aniState->spurImmunityLevel, | ||
889 | !aniState->ofdmWeakSigDetectOff); | ||
890 | ath_print(common, ATH_DBG_ANI, | ||
891 | "cckWeakSigThreshold=%d, " | ||
892 | "firstepLevel=%d, listenTime=%d\n", | ||
893 | aniState->cckWeakSigThreshold, | ||
894 | aniState->firstepLevel, | ||
895 | aniState->listenTime); | ||
896 | ath_print(common, ATH_DBG_ANI, | ||
897 | "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n", | ||
898 | aniState->cycleCount, | ||
899 | aniState->ofdmPhyErrCount, | ||
900 | aniState->cckPhyErrCount); | ||
901 | |||
902 | return true; | ||
903 | } | ||
904 | |||
905 | static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf) | ||
906 | { | ||
907 | struct ath_common *common = ath9k_hw_common(ah); | ||
908 | |||
909 | if (*nf > ah->nf_2g_max) { | ||
910 | ath_print(common, ATH_DBG_CALIBRATE, | ||
911 | "2 GHz NF (%d) > MAX (%d), " | ||
912 | "correcting to MAX", | ||
913 | *nf, ah->nf_2g_max); | ||
914 | *nf = ah->nf_2g_max; | ||
915 | } else if (*nf < ah->nf_2g_min) { | ||
916 | ath_print(common, ATH_DBG_CALIBRATE, | ||
917 | "2 GHz NF (%d) < MIN (%d), " | ||
918 | "correcting to MIN", | ||
919 | *nf, ah->nf_2g_min); | ||
920 | *nf = ah->nf_2g_min; | ||
921 | } | ||
922 | } | ||
923 | |||
924 | static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf) | ||
925 | { | ||
926 | struct ath_common *common = ath9k_hw_common(ah); | ||
927 | |||
928 | if (*nf > ah->nf_5g_max) { | ||
929 | ath_print(common, ATH_DBG_CALIBRATE, | ||
930 | "5 GHz NF (%d) > MAX (%d), " | ||
931 | "correcting to MAX", | ||
932 | *nf, ah->nf_5g_max); | ||
933 | *nf = ah->nf_5g_max; | ||
934 | } else if (*nf < ah->nf_5g_min) { | ||
935 | ath_print(common, ATH_DBG_CALIBRATE, | ||
936 | "5 GHz NF (%d) < MIN (%d), " | ||
937 | "correcting to MIN", | ||
938 | *nf, ah->nf_5g_min); | ||
939 | *nf = ah->nf_5g_min; | ||
940 | } | ||
941 | } | ||
942 | |||
943 | static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf) | ||
944 | { | ||
945 | if (IS_CHAN_2GHZ(ah->curchan)) | ||
946 | ar9003_hw_nf_sanitize_2g(ah, nf); | ||
947 | else | ||
948 | ar9003_hw_nf_sanitize_5g(ah, nf); | ||
949 | } | ||
950 | |||
951 | static void ar9003_hw_do_getnf(struct ath_hw *ah, | ||
952 | int16_t nfarray[NUM_NF_READINGS]) | ||
953 | { | ||
954 | struct ath_common *common = ath9k_hw_common(ah); | ||
955 | int16_t nf; | ||
956 | |||
957 | nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR); | ||
958 | if (nf & 0x100) | ||
959 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
960 | ar9003_hw_nf_sanitize(ah, &nf); | ||
961 | ath_print(common, ATH_DBG_CALIBRATE, | ||
962 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | ||
963 | nfarray[0] = nf; | ||
964 | |||
965 | nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR); | ||
966 | if (nf & 0x100) | ||
967 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
968 | ar9003_hw_nf_sanitize(ah, &nf); | ||
969 | ath_print(common, ATH_DBG_CALIBRATE, | ||
970 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | ||
971 | nfarray[1] = nf; | ||
972 | |||
973 | nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR); | ||
974 | if (nf & 0x100) | ||
975 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
976 | ar9003_hw_nf_sanitize(ah, &nf); | ||
977 | ath_print(common, ATH_DBG_CALIBRATE, | ||
978 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | ||
979 | nfarray[2] = nf; | ||
980 | |||
981 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR); | ||
982 | if (nf & 0x100) | ||
983 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
984 | ar9003_hw_nf_sanitize(ah, &nf); | ||
985 | ath_print(common, ATH_DBG_CALIBRATE, | ||
986 | "NF calibrated [ext] [chain 0] is %d\n", nf); | ||
987 | nfarray[3] = nf; | ||
988 | |||
989 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR); | ||
990 | if (nf & 0x100) | ||
991 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
992 | ar9003_hw_nf_sanitize(ah, &nf); | ||
993 | ath_print(common, ATH_DBG_CALIBRATE, | ||
994 | "NF calibrated [ext] [chain 1] is %d\n", nf); | ||
995 | nfarray[4] = nf; | ||
996 | |||
997 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR); | ||
998 | if (nf & 0x100) | ||
999 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
1000 | ar9003_hw_nf_sanitize(ah, &nf); | ||
1001 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1002 | "NF calibrated [ext] [chain 2] is %d\n", nf); | ||
1003 | nfarray[5] = nf; | ||
1004 | } | ||
1005 | |||
1006 | void ar9003_hw_set_nf_limits(struct ath_hw *ah) | ||
1007 | { | ||
1008 | ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ; | ||
1009 | ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ; | ||
1010 | ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ; | ||
1011 | ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; | ||
1012 | } | ||
1013 | |||
1014 | /* | ||
1015 | * Find out which of the RX chains are enabled | ||
1016 | */ | ||
1017 | static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah) | ||
1018 | { | ||
1019 | u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK); | ||
1020 | /* | ||
1021 | * The bits [2:0] indicate the rx chain mask and are to be | ||
1022 | * interpreted as follows: | ||
1023 | * 00x => Only chain 0 is enabled | ||
1024 | * 01x => Chain 1 and 0 enabled | ||
1025 | * 1xx => Chain 2,1 and 0 enabled | ||
1026 | */ | ||
1027 | return chain & 0x7; | ||
1028 | } | ||
1029 | |||
1030 | static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1031 | { | ||
1032 | struct ath9k_nfcal_hist *h; | ||
1033 | unsigned i, j; | ||
1034 | int32_t val; | ||
1035 | const u32 ar9300_cca_regs[6] = { | ||
1036 | AR_PHY_CCA_0, | ||
1037 | AR_PHY_CCA_1, | ||
1038 | AR_PHY_CCA_2, | ||
1039 | AR_PHY_EXT_CCA, | ||
1040 | AR_PHY_EXT_CCA_1, | ||
1041 | AR_PHY_EXT_CCA_2, | ||
1042 | }; | ||
1043 | u8 chainmask, rx_chain_status; | ||
1044 | struct ath_common *common = ath9k_hw_common(ah); | ||
1045 | |||
1046 | rx_chain_status = ar9003_hw_get_rx_chainmask(ah); | ||
1047 | |||
1048 | chainmask = 0x3F; | ||
1049 | h = ah->nfCalHist; | ||
1050 | |||
1051 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
1052 | if (chainmask & (1 << i)) { | ||
1053 | val = REG_READ(ah, ar9300_cca_regs[i]); | ||
1054 | val &= 0xFFFFFE00; | ||
1055 | val |= (((u32) (h[i].privNF) << 1) & 0x1ff); | ||
1056 | REG_WRITE(ah, ar9300_cca_regs[i], val); | ||
1057 | } | ||
1058 | } | ||
1059 | |||
1060 | /* | ||
1061 | * Load software filtered NF value into baseband internal minCCApwr | ||
1062 | * variable. | ||
1063 | */ | ||
1064 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
1065 | AR_PHY_AGC_CONTROL_ENABLE_NF); | ||
1066 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
1067 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
1068 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | ||
1069 | |||
1070 | /* | ||
1071 | * Wait for load to complete, should be fast, a few 10s of us. | ||
1072 | * The max delay was changed from an original 250us to 10000us | ||
1073 | * since 250us often results in NF load timeout and causes deaf | ||
1074 | * condition during stress testing 12/12/2009 | ||
1075 | */ | ||
1076 | for (j = 0; j < 1000; j++) { | ||
1077 | if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
1078 | AR_PHY_AGC_CONTROL_NF) == 0) | ||
1079 | break; | ||
1080 | udelay(10); | ||
1081 | } | ||
1082 | |||
1083 | /* | ||
1084 | * We timed out waiting for the noisefloor to load, probably due to an | ||
1085 | * in-progress rx. Simply return here and allow the load plenty of time | ||
1086 | * to complete before the next calibration interval. We need to avoid | ||
1087 | * trying to load -50 (which happens below) while the previous load is | ||
1088 | * still in progress as this can cause rx deafness. Instead by returning | ||
1089 | * here, the baseband nf cal will just be capped by our present | ||
1090 | * noisefloor until the next calibration timer. | ||
1091 | */ | ||
1092 | if (j == 1000) { | ||
1093 | ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf " | ||
1094 | "to load: AR_PHY_AGC_CONTROL=0x%x\n", | ||
1095 | REG_READ(ah, AR_PHY_AGC_CONTROL)); | ||
1096 | return; | ||
1097 | } | ||
1098 | |||
1099 | /* | ||
1100 | * Restore maxCCAPower register parameter again so that we're not capped | ||
1101 | * by the median we just loaded. This will be initial (and max) value | ||
1102 | * of next noise floor calibration the baseband does. | ||
1103 | */ | ||
1104 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
1105 | if (chainmask & (1 << i)) { | ||
1106 | val = REG_READ(ah, ar9300_cca_regs[i]); | ||
1107 | val &= 0xFFFFFE00; | ||
1108 | val |= (((u32) (-50) << 1) & 0x1ff); | ||
1109 | REG_WRITE(ah, ar9300_cca_regs[i], val); | ||
1110 | } | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah) | ||
1115 | { | ||
1116 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
1117 | |||
1118 | priv_ops->rf_set_freq = ar9003_hw_set_channel; | ||
1119 | priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate; | ||
1120 | priv_ops->compute_pll_control = ar9003_hw_compute_pll_control; | ||
1121 | priv_ops->set_channel_regs = ar9003_hw_set_channel_regs; | ||
1122 | priv_ops->init_bb = ar9003_hw_init_bb; | ||
1123 | priv_ops->process_ini = ar9003_hw_process_ini; | ||
1124 | priv_ops->set_rfmode = ar9003_hw_set_rfmode; | ||
1125 | priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive; | ||
1126 | priv_ops->set_delta_slope = ar9003_hw_set_delta_slope; | ||
1127 | priv_ops->rfbus_req = ar9003_hw_rfbus_req; | ||
1128 | priv_ops->rfbus_done = ar9003_hw_rfbus_done; | ||
1129 | priv_ops->enable_rfkill = ar9003_hw_enable_rfkill; | ||
1130 | priv_ops->set_diversity = ar9003_hw_set_diversity; | ||
1131 | priv_ops->ani_control = ar9003_hw_ani_control; | ||
1132 | priv_ops->do_getnf = ar9003_hw_do_getnf; | ||
1133 | priv_ops->loadnf = ar9003_hw_loadnf; | ||
1134 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h new file mode 100644 index 000000000000..f08cc8bda005 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h | |||
@@ -0,0 +1,847 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2002-2010 Atheros Communications, Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef AR9003_PHY_H | ||
18 | #define AR9003_PHY_H | ||
19 | |||
20 | /* | ||
21 | * Channel Register Map | ||
22 | */ | ||
23 | #define AR_CHAN_BASE 0x9800 | ||
24 | |||
25 | #define AR_PHY_TIMING1 (AR_CHAN_BASE + 0x0) | ||
26 | #define AR_PHY_TIMING2 (AR_CHAN_BASE + 0x4) | ||
27 | #define AR_PHY_TIMING3 (AR_CHAN_BASE + 0x8) | ||
28 | #define AR_PHY_TIMING4 (AR_CHAN_BASE + 0xc) | ||
29 | #define AR_PHY_TIMING5 (AR_CHAN_BASE + 0x10) | ||
30 | #define AR_PHY_TIMING6 (AR_CHAN_BASE + 0x14) | ||
31 | #define AR_PHY_TIMING11 (AR_CHAN_BASE + 0x18) | ||
32 | #define AR_PHY_SPUR_REG (AR_CHAN_BASE + 0x1c) | ||
33 | #define AR_PHY_RX_IQCAL_CORR_B0 (AR_CHAN_BASE + 0xdc) | ||
34 | #define AR_PHY_TX_IQCAL_CONTROL_3 (AR_CHAN_BASE + 0xb0) | ||
35 | |||
36 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 | ||
37 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 | ||
38 | |||
39 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF | ||
40 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 | ||
41 | |||
42 | #define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC 0x40000000 | ||
43 | #define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC_S 30 | ||
44 | |||
45 | #define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR 0x80000000 | ||
46 | #define AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR_S 31 | ||
47 | |||
48 | #define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT 0x4000000 | ||
49 | #define AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT_S 26 | ||
50 | |||
51 | #define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 /* bins move with freq offset */ | ||
52 | #define AR_PHY_SPUR_REG_ENABLE_MASK_PPM_S 17 | ||
53 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x000000FF | ||
54 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 | ||
55 | #define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI 0x00000100 | ||
56 | #define AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI_S 8 | ||
57 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL 0x03FC0000 | ||
58 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 | ||
59 | |||
60 | #define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN 0x20000000 | ||
61 | #define AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN_S 29 | ||
62 | |||
63 | #define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN 0x80000000 | ||
64 | #define AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN_S 31 | ||
65 | |||
66 | #define AR_PHY_FIND_SIG_LOW (AR_CHAN_BASE + 0x20) | ||
67 | |||
68 | #define AR_PHY_SFCORR (AR_CHAN_BASE + 0x24) | ||
69 | #define AR_PHY_SFCORR_LOW (AR_CHAN_BASE + 0x28) | ||
70 | #define AR_PHY_SFCORR_EXT (AR_CHAN_BASE + 0x2c) | ||
71 | |||
72 | #define AR_PHY_EXT_CCA (AR_CHAN_BASE + 0x30) | ||
73 | #define AR_PHY_RADAR_0 (AR_CHAN_BASE + 0x34) | ||
74 | #define AR_PHY_RADAR_1 (AR_CHAN_BASE + 0x38) | ||
75 | #define AR_PHY_RADAR_EXT (AR_CHAN_BASE + 0x3c) | ||
76 | #define AR_PHY_MULTICHAIN_CTRL (AR_CHAN_BASE + 0x80) | ||
77 | #define AR_PHY_PERCHAIN_CSD (AR_CHAN_BASE + 0x84) | ||
78 | |||
79 | #define AR_PHY_TX_PHASE_RAMP_0 (AR_CHAN_BASE + 0xd0) | ||
80 | #define AR_PHY_ADC_GAIN_DC_CORR_0 (AR_CHAN_BASE + 0xd4) | ||
81 | #define AR_PHY_IQ_ADC_MEAS_0_B0 (AR_CHAN_BASE + 0xc0) | ||
82 | #define AR_PHY_IQ_ADC_MEAS_1_B0 (AR_CHAN_BASE + 0xc4) | ||
83 | #define AR_PHY_IQ_ADC_MEAS_2_B0 (AR_CHAN_BASE + 0xc8) | ||
84 | #define AR_PHY_IQ_ADC_MEAS_3_B0 (AR_CHAN_BASE + 0xcc) | ||
85 | |||
86 | /* The following registers changed position from AR9300 1.0 to AR9300 2.0 */ | ||
87 | #define AR_PHY_TX_PHASE_RAMP_0_9300_10 (AR_CHAN_BASE + 0xd0 - 0x10) | ||
88 | #define AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 (AR_CHAN_BASE + 0xd4 - 0x10) | ||
89 | #define AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 (AR_CHAN_BASE + 0xc0 + 0x8) | ||
90 | #define AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 (AR_CHAN_BASE + 0xc4 + 0x8) | ||
91 | #define AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 (AR_CHAN_BASE + 0xc8 + 0x8) | ||
92 | #define AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 (AR_CHAN_BASE + 0xcc + 0x8) | ||
93 | |||
94 | #define AR_PHY_TX_CRC (AR_CHAN_BASE + 0xa0) | ||
95 | #define AR_PHY_TST_DAC_CONST (AR_CHAN_BASE + 0xa4) | ||
96 | #define AR_PHY_SPUR_REPORT_0 (AR_CHAN_BASE + 0xa8) | ||
97 | #define AR_PHY_CHAN_INFO_TAB_0 (AR_CHAN_BASE + 0x300) | ||
98 | |||
99 | /* | ||
100 | * Channel Field Definitions | ||
101 | */ | ||
102 | #define AR_PHY_TIMING2_USE_FORCE_PPM 0x00001000 | ||
103 | #define AR_PHY_TIMING2_FORCE_PPM_VAL 0x00000fff | ||
104 | #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 | ||
105 | #define AR_PHY_TIMING3_DSC_MAN_S 17 | ||
106 | #define AR_PHY_TIMING3_DSC_EXP 0x0001E000 | ||
107 | #define AR_PHY_TIMING3_DSC_EXP_S 13 | ||
108 | #define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX 0xF000 | ||
109 | #define AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX_S 12 | ||
110 | #define AR_PHY_TIMING4_DO_CAL 0x10000 | ||
111 | |||
112 | #define AR_PHY_TIMING4_ENABLE_PILOT_MASK 0x10000000 | ||
113 | #define AR_PHY_TIMING4_ENABLE_PILOT_MASK_S 28 | ||
114 | #define AR_PHY_TIMING4_ENABLE_CHAN_MASK 0x20000000 | ||
115 | #define AR_PHY_TIMING4_ENABLE_CHAN_MASK_S 29 | ||
116 | |||
117 | #define AR_PHY_TIMING4_ENABLE_SPUR_FILTER 0x40000000 | ||
118 | #define AR_PHY_TIMING4_ENABLE_SPUR_FILTER_S 30 | ||
119 | #define AR_PHY_TIMING4_ENABLE_SPUR_RSSI 0x80000000 | ||
120 | #define AR_PHY_TIMING4_ENABLE_SPUR_RSSI_S 31 | ||
121 | |||
122 | #define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 | ||
123 | #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 | ||
124 | #define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 | ||
125 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00 | ||
126 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 | ||
127 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000 | ||
128 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 | ||
129 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000 | ||
130 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 | ||
131 | #define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F | ||
132 | #define AR_PHY_SFCORR_M2COUNT_THR_S 0 | ||
133 | #define AR_PHY_SFCORR_M1_THRESH 0x00FE0000 | ||
134 | #define AR_PHY_SFCORR_M1_THRESH_S 17 | ||
135 | #define AR_PHY_SFCORR_M2_THRESH 0x7F000000 | ||
136 | #define AR_PHY_SFCORR_M2_THRESH_S 24 | ||
137 | #define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F | ||
138 | #define AR_PHY_SFCORR_EXT_M1_THRESH_S 0 | ||
139 | #define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80 | ||
140 | #define AR_PHY_SFCORR_EXT_M2_THRESH_S 7 | ||
141 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000 | ||
142 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 | ||
143 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000 | ||
144 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 | ||
145 | #define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD 0x10000000 | ||
146 | #define AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD_S 28 | ||
147 | #define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 | ||
148 | #define AR_PHY_EXT_CCA_THRESH62 0x007F0000 | ||
149 | #define AR_PHY_EXT_CCA_THRESH62_S 16 | ||
150 | #define AR_PHY_EXT_MINCCA_PWR 0x01FF0000 | ||
151 | #define AR_PHY_EXT_MINCCA_PWR_S 16 | ||
152 | #define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE | ||
153 | #define AR_PHY_TIMING5_CYCPWR_THR1_S 1 | ||
154 | #define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE 0x00000001 | ||
155 | #define AR_PHY_TIMING5_CYCPWR_THR1_ENABLE_S 0 | ||
156 | #define AR_PHY_TIMING5_CYCPWR_THR1A 0x007F0000 | ||
157 | #define AR_PHY_TIMING5_CYCPWR_THR1A_S 16 | ||
158 | #define AR_PHY_TIMING5_RSSI_THR1A (0x7F << 16) | ||
159 | #define AR_PHY_TIMING5_RSSI_THR1A_S 16 | ||
160 | #define AR_PHY_TIMING5_RSSI_THR1A_ENA (0x1 << 15) | ||
161 | #define AR_PHY_RADAR_0_ENA 0x00000001 | ||
162 | #define AR_PHY_RADAR_0_FFT_ENA 0x80000000 | ||
163 | #define AR_PHY_RADAR_0_INBAND 0x0000003e | ||
164 | #define AR_PHY_RADAR_0_INBAND_S 1 | ||
165 | #define AR_PHY_RADAR_0_PRSSI 0x00000FC0 | ||
166 | #define AR_PHY_RADAR_0_PRSSI_S 6 | ||
167 | #define AR_PHY_RADAR_0_HEIGHT 0x0003F000 | ||
168 | #define AR_PHY_RADAR_0_HEIGHT_S 12 | ||
169 | #define AR_PHY_RADAR_0_RRSSI 0x00FC0000 | ||
170 | #define AR_PHY_RADAR_0_RRSSI_S 18 | ||
171 | #define AR_PHY_RADAR_0_FIRPWR 0x7F000000 | ||
172 | #define AR_PHY_RADAR_0_FIRPWR_S 24 | ||
173 | #define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000 | ||
174 | #define AR_PHY_RADAR_1_USE_FIR128 0x00400000 | ||
175 | #define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000 | ||
176 | #define AR_PHY_RADAR_1_RELPWR_THRESH_S 16 | ||
177 | #define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000 | ||
178 | #define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000 | ||
179 | #define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 | ||
180 | #define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00 | ||
181 | #define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8 | ||
182 | #define AR_PHY_RADAR_1_MAXLEN 0x000000FF | ||
183 | #define AR_PHY_RADAR_1_MAXLEN_S 0 | ||
184 | #define AR_PHY_RADAR_EXT_ENA 0x00004000 | ||
185 | #define AR_PHY_RADAR_DC_PWR_THRESH 0x007f8000 | ||
186 | #define AR_PHY_RADAR_DC_PWR_THRESH_S 15 | ||
187 | #define AR_PHY_RADAR_LB_DC_CAP 0x7f800000 | ||
188 | #define AR_PHY_RADAR_LB_DC_CAP_S 23 | ||
189 | #define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW (0x3f << 6) | ||
190 | #define AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW_S 6 | ||
191 | #define AR_PHY_FIND_SIG_LOW_FIRPWR (0x7f << 12) | ||
192 | #define AR_PHY_FIND_SIG_LOW_FIRPWR_S 12 | ||
193 | #define AR_PHY_FIND_SIG_LOW_FIRPWR_SIGN_BIT 19 | ||
194 | #define AR_PHY_FIND_SIG_LOW_RELSTEP 0x1f | ||
195 | #define AR_PHY_FIND_SIG_LOW_RELSTEP_S 0 | ||
196 | #define AR_PHY_FIND_SIG_LOW_RELSTEP_SIGN_BIT 5 | ||
197 | #define AR_PHY_CHAN_INFO_TAB_S2_READ 0x00000008 | ||
198 | #define AR_PHY_CHAN_INFO_TAB_S2_READ_S 3 | ||
199 | #define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF 0x0000007F | ||
200 | #define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF_S 0 | ||
201 | #define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF 0x00003F80 | ||
202 | #define AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF_S 7 | ||
203 | #define AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE 0x00004000 | ||
204 | #define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF 0x003f8000 | ||
205 | #define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_Q_COFF_S 15 | ||
206 | #define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF 0x1fc00000 | ||
207 | #define AR_PHY_RX_IQCAL_CORR_LOOPBACK_IQCORR_Q_I_COFF_S 22 | ||
208 | |||
209 | /* | ||
210 | * MRC Register Map | ||
211 | */ | ||
212 | #define AR_MRC_BASE 0x9c00 | ||
213 | |||
214 | #define AR_PHY_TIMING_3A (AR_MRC_BASE + 0x0) | ||
215 | #define AR_PHY_LDPC_CNTL1 (AR_MRC_BASE + 0x4) | ||
216 | #define AR_PHY_LDPC_CNTL2 (AR_MRC_BASE + 0x8) | ||
217 | #define AR_PHY_PILOT_SPUR_MASK (AR_MRC_BASE + 0xc) | ||
218 | #define AR_PHY_CHAN_SPUR_MASK (AR_MRC_BASE + 0x10) | ||
219 | #define AR_PHY_SGI_DELTA (AR_MRC_BASE + 0x14) | ||
220 | #define AR_PHY_ML_CNTL_1 (AR_MRC_BASE + 0x18) | ||
221 | #define AR_PHY_ML_CNTL_2 (AR_MRC_BASE + 0x1c) | ||
222 | #define AR_PHY_TST_ADC (AR_MRC_BASE + 0x20) | ||
223 | |||
224 | #define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0 | ||
225 | #define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S 5 | ||
226 | #define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F | ||
227 | #define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0 | ||
228 | |||
229 | #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A 0x00000FE0 | ||
230 | #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S 5 | ||
231 | #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A 0x1F | ||
232 | #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S 0 | ||
233 | |||
234 | /* | ||
235 | * MRC Feild Definitions | ||
236 | */ | ||
237 | #define AR_PHY_SGI_DSC_MAN 0x0007FFF0 | ||
238 | #define AR_PHY_SGI_DSC_MAN_S 4 | ||
239 | #define AR_PHY_SGI_DSC_EXP 0x0000000F | ||
240 | #define AR_PHY_SGI_DSC_EXP_S 0 | ||
241 | /* | ||
242 | * BBB Register Map | ||
243 | */ | ||
244 | #define AR_BBB_BASE 0x9d00 | ||
245 | |||
246 | /* | ||
247 | * AGC Register Map | ||
248 | */ | ||
249 | #define AR_AGC_BASE 0x9e00 | ||
250 | |||
251 | #define AR_PHY_SETTLING (AR_AGC_BASE + 0x0) | ||
252 | #define AR_PHY_FORCEMAX_GAINS_0 (AR_AGC_BASE + 0x4) | ||
253 | #define AR_PHY_GAINS_MINOFF0 (AR_AGC_BASE + 0x8) | ||
254 | #define AR_PHY_DESIRED_SZ (AR_AGC_BASE + 0xc) | ||
255 | #define AR_PHY_FIND_SIG (AR_AGC_BASE + 0x10) | ||
256 | #define AR_PHY_AGC (AR_AGC_BASE + 0x14) | ||
257 | #define AR_PHY_EXT_ATTEN_CTL_0 (AR_AGC_BASE + 0x18) | ||
258 | #define AR_PHY_CCA_0 (AR_AGC_BASE + 0x1c) | ||
259 | #define AR_PHY_EXT_CCA0 (AR_AGC_BASE + 0x20) | ||
260 | #define AR_PHY_RESTART (AR_AGC_BASE + 0x24) | ||
261 | #define AR_PHY_MC_GAIN_CTRL (AR_AGC_BASE + 0x28) | ||
262 | #define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c) | ||
263 | #define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30) | ||
264 | #define AR_PHY_20_40_DET_THR (AR_AGC_BASE + 0x34) | ||
265 | #define AR_PHY_RIFS_SRCH (AR_AGC_BASE + 0x38) | ||
266 | #define AR_PHY_PEAK_DET_CTRL_1 (AR_AGC_BASE + 0x3c) | ||
267 | #define AR_PHY_PEAK_DET_CTRL_2 (AR_AGC_BASE + 0x40) | ||
268 | #define AR_PHY_RX_GAIN_BOUNDS_1 (AR_AGC_BASE + 0x44) | ||
269 | #define AR_PHY_RX_GAIN_BOUNDS_2 (AR_AGC_BASE + 0x48) | ||
270 | #define AR_PHY_RSSI_0 (AR_AGC_BASE + 0x180) | ||
271 | #define AR_PHY_SPUR_CCK_REP0 (AR_AGC_BASE + 0x184) | ||
272 | #define AR_PHY_CCK_DETECT (AR_AGC_BASE + 0x1c0) | ||
273 | #define AR_PHY_DAG_CTRLCCK (AR_AGC_BASE + 0x1c4) | ||
274 | #define AR_PHY_IQCORR_CTRL_CCK (AR_AGC_BASE + 0x1c8) | ||
275 | |||
276 | #define AR_PHY_CCK_SPUR_MIT (AR_AGC_BASE + 0x1cc) | ||
277 | #define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR 0x000001fe | ||
278 | #define AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR_S 1 | ||
279 | #define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE 0x60000000 | ||
280 | #define AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE_S 29 | ||
281 | #define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT 0x00000001 | ||
282 | #define AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT_S 0 | ||
283 | #define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ 0x1ffffe00 | ||
284 | #define AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ_S 9 | ||
285 | |||
286 | #define AR_PHY_RX_OCGAIN (AR_AGC_BASE + 0x200) | ||
287 | |||
288 | #define AR_PHY_CCA_NOM_VAL_9300_2GHZ -110 | ||
289 | #define AR_PHY_CCA_NOM_VAL_9300_5GHZ -115 | ||
290 | #define AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ -125 | ||
291 | #define AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ -125 | ||
292 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ -95 | ||
293 | #define AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ -100 | ||
294 | |||
295 | /* | ||
296 | * AGC Field Definitions | ||
297 | */ | ||
298 | #define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN 0x00FC0000 | ||
299 | #define AR_PHY_EXT_ATTEN_CTL_RXTX_MARGIN_S 18 | ||
300 | #define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN 0x00003C00 | ||
301 | #define AR_PHY_EXT_ATTEN_CTL_BSW_MARGIN_S 10 | ||
302 | #define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN 0x0000001F | ||
303 | #define AR_PHY_EXT_ATTEN_CTL_BSW_ATTEN_S 0 | ||
304 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN 0x003E0000 | ||
305 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN2_MARGIN_S 17 | ||
306 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN 0x0001F000 | ||
307 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN_S 12 | ||
308 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB 0x00000FC0 | ||
309 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN2_DB_S 6 | ||
310 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB 0x0000003F | ||
311 | #define AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB_S 0 | ||
312 | #define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000 | ||
313 | #define AR_PHY_RXGAIN_TXRX_ATTEN_S 12 | ||
314 | #define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000 | ||
315 | #define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18 | ||
316 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80 | ||
317 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7 | ||
318 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000 | ||
319 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14 | ||
320 | #define AR_PHY_SETTLING_SWITCH 0x00003F80 | ||
321 | #define AR_PHY_SETTLING_SWITCH_S 7 | ||
322 | #define AR_PHY_DESIRED_SZ_ADC 0x000000FF | ||
323 | #define AR_PHY_DESIRED_SZ_ADC_S 0 | ||
324 | #define AR_PHY_DESIRED_SZ_PGA 0x0000FF00 | ||
325 | #define AR_PHY_DESIRED_SZ_PGA_S 8 | ||
326 | #define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000 | ||
327 | #define AR_PHY_DESIRED_SZ_TOT_DES_S 20 | ||
328 | #define AR_PHY_MINCCA_PWR 0x1FF00000 | ||
329 | #define AR_PHY_MINCCA_PWR_S 20 | ||
330 | #define AR_PHY_CCA_THRESH62 0x0007F000 | ||
331 | #define AR_PHY_CCA_THRESH62_S 12 | ||
332 | #define AR9280_PHY_MINCCA_PWR 0x1FF00000 | ||
333 | #define AR9280_PHY_MINCCA_PWR_S 20 | ||
334 | #define AR9280_PHY_CCA_THRESH62 0x000FF000 | ||
335 | #define AR9280_PHY_CCA_THRESH62_S 12 | ||
336 | #define AR_PHY_EXT_CCA0_THRESH62 0x000000FF | ||
337 | #define AR_PHY_EXT_CCA0_THRESH62_S 0 | ||
338 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F | ||
339 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 | ||
340 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 | ||
341 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 | ||
342 | #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 | ||
343 | |||
344 | #define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 | ||
345 | #define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR_S 9 | ||
346 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00 | ||
347 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 | ||
348 | |||
349 | #define AR_PHY_RIFS_INIT_DELAY 0x3ff0000 | ||
350 | #define AR_PHY_AGC_COARSE_LOW 0x00007F80 | ||
351 | #define AR_PHY_AGC_COARSE_LOW_S 7 | ||
352 | #define AR_PHY_AGC_COARSE_HIGH 0x003F8000 | ||
353 | #define AR_PHY_AGC_COARSE_HIGH_S 15 | ||
354 | #define AR_PHY_AGC_COARSE_PWR_CONST 0x0000007F | ||
355 | #define AR_PHY_AGC_COARSE_PWR_CONST_S 0 | ||
356 | #define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000 | ||
357 | #define AR_PHY_FIND_SIG_FIRSTEP_S 12 | ||
358 | #define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 | ||
359 | #define AR_PHY_FIND_SIG_FIRPWR_S 18 | ||
360 | #define AR_PHY_FIND_SIG_FIRPWR_SIGN_BIT 25 | ||
361 | #define AR_PHY_FIND_SIG_RELPWR (0x1f << 6) | ||
362 | #define AR_PHY_FIND_SIG_RELPWR_S 6 | ||
363 | #define AR_PHY_FIND_SIG_RELPWR_SIGN_BIT 11 | ||
364 | #define AR_PHY_FIND_SIG_RELSTEP 0x1f | ||
365 | #define AR_PHY_FIND_SIG_RELSTEP_S 0 | ||
366 | #define AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT 5 | ||
367 | #define AR_PHY_RESTART_DIV_GC 0x001C0000 | ||
368 | #define AR_PHY_RESTART_DIV_GC_S 18 | ||
369 | #define AR_PHY_RESTART_ENA 0x01 | ||
370 | #define AR_PHY_DC_RESTART_DIS 0x40000000 | ||
371 | |||
372 | #define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON 0xFF000000 | ||
373 | #define AR_PHY_TPC_OLPC_GAIN_DELTA_PAL_ON_S 24 | ||
374 | #define AR_PHY_TPC_OLPC_GAIN_DELTA 0x00FF0000 | ||
375 | #define AR_PHY_TPC_OLPC_GAIN_DELTA_S 16 | ||
376 | |||
377 | #define AR_PHY_TPC_6_ERROR_EST_MODE 0x03000000 | ||
378 | #define AR_PHY_TPC_6_ERROR_EST_MODE_S 24 | ||
379 | |||
380 | /* | ||
381 | * SM Register Map | ||
382 | */ | ||
383 | #define AR_SM_BASE 0xa200 | ||
384 | |||
385 | #define AR_PHY_D2_CHIP_ID (AR_SM_BASE + 0x0) | ||
386 | #define AR_PHY_GEN_CTRL (AR_SM_BASE + 0x4) | ||
387 | #define AR_PHY_MODE (AR_SM_BASE + 0x8) | ||
388 | #define AR_PHY_ACTIVE (AR_SM_BASE + 0xc) | ||
389 | #define AR_PHY_SPUR_MASK_A (AR_SM_BASE + 0x20) | ||
390 | #define AR_PHY_SPUR_MASK_B (AR_SM_BASE + 0x24) | ||
391 | #define AR_PHY_SPECTRAL_SCAN (AR_SM_BASE + 0x28) | ||
392 | #define AR_PHY_RADAR_BW_FILTER (AR_SM_BASE + 0x2c) | ||
393 | #define AR_PHY_SEARCH_START_DELAY (AR_SM_BASE + 0x30) | ||
394 | #define AR_PHY_MAX_RX_LEN (AR_SM_BASE + 0x34) | ||
395 | #define AR_PHY_FRAME_CTL (AR_SM_BASE + 0x38) | ||
396 | #define AR_PHY_RFBUS_REQ (AR_SM_BASE + 0x3c) | ||
397 | #define AR_PHY_RFBUS_GRANT (AR_SM_BASE + 0x40) | ||
398 | #define AR_PHY_RIFS (AR_SM_BASE + 0x44) | ||
399 | #define AR_PHY_RX_CLR_DELAY (AR_SM_BASE + 0x50) | ||
400 | #define AR_PHY_RX_DELAY (AR_SM_BASE + 0x54) | ||
401 | |||
402 | #define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64) | ||
403 | #define AR_PHY_MISC_PA_CTL (AR_SM_BASE + 0x80) | ||
404 | #define AR_PHY_SWITCH_CHAIN_0 (AR_SM_BASE + 0x84) | ||
405 | #define AR_PHY_SWITCH_COM (AR_SM_BASE + 0x88) | ||
406 | #define AR_PHY_SWITCH_COM_2 (AR_SM_BASE + 0x8c) | ||
407 | #define AR_PHY_RX_CHAINMASK (AR_SM_BASE + 0xa0) | ||
408 | #define AR_PHY_CAL_CHAINMASK (AR_SM_BASE + 0xc0) | ||
409 | #define AR_PHY_CALMODE (AR_SM_BASE + 0xc8) | ||
410 | #define AR_PHY_FCAL_1 (AR_SM_BASE + 0xcc) | ||
411 | #define AR_PHY_FCAL_2_0 (AR_SM_BASE + 0xd0) | ||
412 | #define AR_PHY_DFT_TONE_CTL_0 (AR_SM_BASE + 0xd4) | ||
413 | #define AR_PHY_CL_CAL_CTL (AR_SM_BASE + 0xd8) | ||
414 | #define AR_PHY_CL_TAB_0 (AR_SM_BASE + 0x100) | ||
415 | #define AR_PHY_SYNTH_CONTROL (AR_SM_BASE + 0x140) | ||
416 | #define AR_PHY_ADDAC_CLK_SEL (AR_SM_BASE + 0x144) | ||
417 | #define AR_PHY_PLL_CTL (AR_SM_BASE + 0x148) | ||
418 | #define AR_PHY_ANALOG_SWAP (AR_SM_BASE + 0x14c) | ||
419 | #define AR_PHY_ADDAC_PARA_CTL (AR_SM_BASE + 0x150) | ||
420 | #define AR_PHY_XPA_CFG (AR_SM_BASE + 0x158) | ||
421 | |||
422 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A 0x0001FC00 | ||
423 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A_S 10 | ||
424 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A 0x3FF | ||
425 | #define AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A_S 0 | ||
426 | |||
427 | #define AR_PHY_TEST (AR_SM_BASE + 0x160) | ||
428 | |||
429 | #define AR_PHY_TEST_BBB_OBS_SEL 0x780000 | ||
430 | #define AR_PHY_TEST_BBB_OBS_SEL_S 19 | ||
431 | |||
432 | #define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23 | ||
433 | #define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S) | ||
434 | |||
435 | #define AR_PHY_TEST_CHAIN_SEL 0xC0000000 | ||
436 | #define AR_PHY_TEST_CHAIN_SEL_S 30 | ||
437 | |||
438 | #define AR_PHY_TEST_CTL_STATUS (AR_SM_BASE + 0x164) | ||
439 | #define AR_PHY_TEST_CTL_TSTDAC_EN 0x1 | ||
440 | #define AR_PHY_TEST_CTL_TSTDAC_EN_S 0 | ||
441 | #define AR_PHY_TEST_CTL_TX_OBS_SEL 0x1C | ||
442 | #define AR_PHY_TEST_CTL_TX_OBS_SEL_S 2 | ||
443 | #define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL 0x60 | ||
444 | #define AR_PHY_TEST_CTL_TX_OBS_MUX_SEL_S 5 | ||
445 | #define AR_PHY_TEST_CTL_TSTADC_EN 0x100 | ||
446 | #define AR_PHY_TEST_CTL_TSTADC_EN_S 8 | ||
447 | #define AR_PHY_TEST_CTL_RX_OBS_SEL 0x3C00 | ||
448 | #define AR_PHY_TEST_CTL_RX_OBS_SEL_S 10 | ||
449 | |||
450 | |||
451 | #define AR_PHY_TSTDAC (AR_SM_BASE + 0x168) | ||
452 | |||
453 | #define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c) | ||
454 | #define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) | ||
455 | #define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174) | ||
456 | #define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178) | ||
457 | #define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c) | ||
458 | #define AR_PHY_CHAN_INFO_GAIN_0 (AR_SM_BASE + 0x180) | ||
459 | #define AR_PHY_SCRAMBLER_SEED (AR_SM_BASE + 0x190) | ||
460 | #define AR_PHY_CCK_TX_CTRL (AR_SM_BASE + 0x194) | ||
461 | |||
462 | #define AR_PHY_HEAVYCLIP_CTL (AR_SM_BASE + 0x1a4) | ||
463 | #define AR_PHY_HEAVYCLIP_20 (AR_SM_BASE + 0x1a8) | ||
464 | #define AR_PHY_HEAVYCLIP_40 (AR_SM_BASE + 0x1ac) | ||
465 | #define AR_PHY_ILLEGAL_TXRATE (AR_SM_BASE + 0x1b0) | ||
466 | |||
467 | #define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0) | ||
468 | #define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4) | ||
469 | |||
470 | #define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) | ||
471 | #define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) | ||
472 | #define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) | ||
473 | #define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) | ||
474 | #define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) | ||
475 | #define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) | ||
476 | |||
477 | #define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258) | ||
478 | |||
479 | #define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280) | ||
480 | |||
481 | #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) | ||
482 | #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) | ||
483 | #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) | ||
484 | #define AR_PHY_TX_IQCAL_CORR_COEFF_01_B0 (AR_SM_BASE + 0x450) | ||
485 | |||
486 | #define AR_PHY_PANIC_WD_STATUS (AR_SM_BASE + 0x5c0) | ||
487 | #define AR_PHY_PANIC_WD_CTL_1 (AR_SM_BASE + 0x5c4) | ||
488 | #define AR_PHY_PANIC_WD_CTL_2 (AR_SM_BASE + 0x5c8) | ||
489 | #define AR_PHY_BT_CTL (AR_SM_BASE + 0x5cc) | ||
490 | #define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0) | ||
491 | #define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4) | ||
492 | #define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc) | ||
493 | #define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) | ||
494 | |||
495 | #define AR_PHY_65NM_CH0_SYNTH4 0x1608c | ||
496 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 | ||
497 | #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S 1 | ||
498 | #define AR_PHY_65NM_CH0_SYNTH7 0x16098 | ||
499 | #define AR_PHY_65NM_CH0_BIAS1 0x160c0 | ||
500 | #define AR_PHY_65NM_CH0_BIAS2 0x160c4 | ||
501 | #define AR_PHY_65NM_CH0_BIAS4 0x160cc | ||
502 | #define AR_PHY_65NM_CH0_RXTX4 0x1610c | ||
503 | #define AR_PHY_65NM_CH0_THERM 0x16290 | ||
504 | |||
505 | #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 | ||
506 | #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 | ||
507 | #define AR_PHY_65NM_CH0_THERM_START 0x20000000 | ||
508 | #define AR_PHY_65NM_CH0_THERM_START_S 29 | ||
509 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT 0x0000ff00 | ||
510 | #define AR_PHY_65NM_CH0_THERM_SAR_ADC_OUT_S 8 | ||
511 | |||
512 | #define AR_PHY_65NM_CH0_RXTX1 0x16100 | ||
513 | #define AR_PHY_65NM_CH0_RXTX2 0x16104 | ||
514 | #define AR_PHY_65NM_CH1_RXTX1 0x16500 | ||
515 | #define AR_PHY_65NM_CH1_RXTX2 0x16504 | ||
516 | #define AR_PHY_65NM_CH2_RXTX1 0x16900 | ||
517 | #define AR_PHY_65NM_CH2_RXTX2 0x16904 | ||
518 | |||
519 | #define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT 0x00380000 | ||
520 | #define AR_PHY_RX1DB_BIQUAD_LONG_SHIFT_S 19 | ||
521 | #define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT 0x00c00000 | ||
522 | #define AR_PHY_RX6DB_BIQUAD_LONG_SHIFT_S 22 | ||
523 | #define AR_PHY_LNAGAIN_LONG_SHIFT 0xe0000000 | ||
524 | #define AR_PHY_LNAGAIN_LONG_SHIFT_S 29 | ||
525 | #define AR_PHY_MXRGAIN_LONG_SHIFT 0x03000000 | ||
526 | #define AR_PHY_MXRGAIN_LONG_SHIFT_S 24 | ||
527 | #define AR_PHY_VGAGAIN_LONG_SHIFT 0x1c000000 | ||
528 | #define AR_PHY_VGAGAIN_LONG_SHIFT_S 26 | ||
529 | #define AR_PHY_SCFIR_GAIN_LONG_SHIFT 0x00000001 | ||
530 | #define AR_PHY_SCFIR_GAIN_LONG_SHIFT_S 0 | ||
531 | #define AR_PHY_MANRXGAIN_LONG_SHIFT 0x00000002 | ||
532 | #define AR_PHY_MANRXGAIN_LONG_SHIFT_S 1 | ||
533 | |||
534 | /* | ||
535 | * SM Field Definitions | ||
536 | */ | ||
537 | #define AR_PHY_CL_CAL_ENABLE 0x00000002 | ||
538 | #define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001 | ||
539 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 | ||
540 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22 | ||
541 | |||
542 | #define AR_PHY_ADDAC_PARACTL_OFF_PWDADC 0x00008000 | ||
543 | |||
544 | #define AR_PHY_FCAL20_CAP_STATUS_0 0x01f00000 | ||
545 | #define AR_PHY_FCAL20_CAP_STATUS_0_S 20 | ||
546 | |||
547 | #define AR_PHY_RFBUS_REQ_EN 0x00000001 /* request for RF bus */ | ||
548 | #define AR_PHY_RFBUS_GRANT_EN 0x00000001 /* RF bus granted */ | ||
549 | #define AR_PHY_GC_TURBO_MODE 0x00000001 /* set turbo mode bits */ | ||
550 | #define AR_PHY_GC_TURBO_SHORT 0x00000002 /* set short symbols to turbo mode setting */ | ||
551 | #define AR_PHY_GC_DYN2040_EN 0x00000004 /* enable dyn 20/40 mode */ | ||
552 | #define AR_PHY_GC_DYN2040_PRI_ONLY 0x00000008 /* dyn 20/40 - primary only */ | ||
553 | #define AR_PHY_GC_DYN2040_PRI_CH 0x00000010 /* dyn 20/40 - primary ch offset (0=+10MHz, 1=-10MHz)*/ | ||
554 | #define AR_PHY_GC_DYN2040_PRI_CH_S 4 | ||
555 | #define AR_PHY_GC_DYN2040_EXT_CH 0x00000020 /* dyn 20/40 - ext ch spacing (0=20MHz/ 1=25MHz) */ | ||
556 | #define AR_PHY_GC_HT_EN 0x00000040 /* ht enable */ | ||
557 | #define AR_PHY_GC_SHORT_GI_40 0x00000080 /* allow short GI for HT 40 */ | ||
558 | #define AR_PHY_GC_WALSH 0x00000100 /* walsh spatial spreading for 2 chains,2 streams TX */ | ||
559 | #define AR_PHY_GC_SINGLE_HT_LTF1 0x00000200 /* single length (4us) 1st HT long training symbol */ | ||
560 | #define AR_PHY_GC_GF_DETECT_EN 0x00000400 /* enable Green Field detection. Only affects rx, not tx */ | ||
561 | #define AR_PHY_GC_ENABLE_DAC_FIFO 0x00000800 /* fifo between bb and dac */ | ||
562 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF /* delay from wakeup to rx ena */ | ||
563 | |||
564 | #define AR_PHY_CALMODE_IQ 0x00000000 | ||
565 | #define AR_PHY_CALMODE_ADC_GAIN 0x00000001 | ||
566 | #define AR_PHY_CALMODE_ADC_DC_PER 0x00000002 | ||
567 | #define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003 | ||
568 | #define AR_PHY_SWAP_ALT_CHAIN 0x00000040 | ||
569 | #define AR_PHY_MODE_OFDM 0x00000000 | ||
570 | #define AR_PHY_MODE_CCK 0x00000001 | ||
571 | #define AR_PHY_MODE_DYNAMIC 0x00000004 | ||
572 | #define AR_PHY_MODE_DYNAMIC_S 2 | ||
573 | #define AR_PHY_MODE_HALF 0x00000020 | ||
574 | #define AR_PHY_MODE_QUARTER 0x00000040 | ||
575 | #define AR_PHY_MAC_CLK_MODE 0x00000080 | ||
576 | #define AR_PHY_MODE_DYN_CCK_DISABLE 0x00000100 | ||
577 | #define AR_PHY_MODE_SVD_HALF 0x00000200 | ||
578 | #define AR_PHY_ACTIVE_EN 0x00000001 | ||
579 | #define AR_PHY_ACTIVE_DIS 0x00000000 | ||
580 | #define AR_PHY_FORCE_XPA_CFG 0x000000001 | ||
581 | #define AR_PHY_FORCE_XPA_CFG_S 0 | ||
582 | #define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF 0xFF000000 | ||
583 | #define AR_PHY_XPA_TIMING_CTL_TX_END_XPAB_OFF_S 24 | ||
584 | #define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF 0x00FF0000 | ||
585 | #define AR_PHY_XPA_TIMING_CTL_TX_END_XPAA_OFF_S 16 | ||
586 | #define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON 0x0000FF00 | ||
587 | #define AR_PHY_XPA_TIMING_CTL_FRAME_XPAB_ON_S 8 | ||
588 | #define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON 0x000000FF | ||
589 | #define AR_PHY_XPA_TIMING_CTL_FRAME_XPAA_ON_S 0 | ||
590 | #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 | ||
591 | #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 | ||
592 | #define AR_PHY_TX_END_DATA_START 0x000000FF | ||
593 | #define AR_PHY_TX_END_DATA_START_S 0 | ||
594 | #define AR_PHY_TX_END_PA_ON 0x0000FF00 | ||
595 | #define AR_PHY_TX_END_PA_ON_S 8 | ||
596 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F | ||
597 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 | ||
598 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0 | ||
599 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 | ||
600 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00 | ||
601 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 | ||
602 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000 | ||
603 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 | ||
604 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000 | ||
605 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 | ||
606 | #define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 | ||
607 | #define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14 | ||
608 | #define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000 | ||
609 | #define AR_PHY_TPCRG1_PD_GAIN_1_S 16 | ||
610 | #define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000 | ||
611 | #define AR_PHY_TPCRG1_PD_GAIN_2_S 18 | ||
612 | #define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000 | ||
613 | #define AR_PHY_TPCRG1_PD_GAIN_3_S 20 | ||
614 | #define AR_PHY_TPCGR1_FORCED_DAC_GAIN 0x0000003e | ||
615 | #define AR_PHY_TPCGR1_FORCED_DAC_GAIN_S 1 | ||
616 | #define AR_PHY_TPCGR1_FORCE_DAC_GAIN 0x00000001 | ||
617 | #define AR_PHY_TXGAIN_FORCE 0x00000001 | ||
618 | #define AR_PHY_TXGAIN_FORCED_PADVGNRA 0x00003c00 | ||
619 | #define AR_PHY_TXGAIN_FORCED_PADVGNRA_S 10 | ||
620 | #define AR_PHY_TXGAIN_FORCED_PADVGNRB 0x0003c000 | ||
621 | #define AR_PHY_TXGAIN_FORCED_PADVGNRB_S 14 | ||
622 | #define AR_PHY_TXGAIN_FORCED_PADVGNRD 0x00c00000 | ||
623 | #define AR_PHY_TXGAIN_FORCED_PADVGNRD_S 22 | ||
624 | #define AR_PHY_TXGAIN_FORCED_TXMXRGAIN 0x000003c0 | ||
625 | #define AR_PHY_TXGAIN_FORCED_TXMXRGAIN_S 6 | ||
626 | #define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN 0x0000000e | ||
627 | #define AR_PHY_TXGAIN_FORCED_TXBB1DBGAIN_S 1 | ||
628 | |||
629 | #define AR_PHY_POWER_TX_RATE1 0x9934 | ||
630 | #define AR_PHY_POWER_TX_RATE2 0x9938 | ||
631 | #define AR_PHY_POWER_TX_RATE_MAX 0x993c | ||
632 | #define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 | ||
633 | #define PHY_AGC_CLR 0x10000000 | ||
634 | #define RFSILENT_BB 0x00002000 | ||
635 | #define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_MASK 0xFFF | ||
636 | #define AR_PHY_CHAN_INFO_GAIN_DIFF_PPM_SIGNED_BIT 0x800 | ||
637 | #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 | ||
638 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 | ||
639 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF | ||
640 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 | ||
641 | #define AR_PHY_SPECTRAL_SCAN_ENABLE 0x00000001 | ||
642 | #define AR_PHY_SPECTRAL_SCAN_ENABLE_S 0 | ||
643 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 | ||
644 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 | ||
645 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 | ||
646 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 | ||
647 | #define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 | ||
648 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 | ||
649 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 | ||
650 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 | ||
651 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 | ||
652 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 | ||
653 | #define AR_PHY_CHANNEL_STATUS_RX_CLEAR 0x00000004 | ||
654 | #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT 0x01fc0000 | ||
655 | #define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S 18 | ||
656 | #define AR_PHY_TX_IQCAL_START_DO_CAL 0x00000001 | ||
657 | #define AR_PHY_TX_IQCAL_START_DO_CAL_S 0 | ||
658 | |||
659 | #define AR_PHY_TX_IQCAL_STATUS_FAILED 0x00000001 | ||
660 | #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff | ||
661 | #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0 | ||
662 | |||
663 | #define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff | ||
664 | #define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0 | ||
665 | #define AR_PHY_TPC_19_ALPHA_THERM 0xff | ||
666 | #define AR_PHY_TPC_19_ALPHA_THERM_S 0 | ||
667 | |||
668 | #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 | ||
669 | #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 | ||
670 | |||
671 | #define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff | ||
672 | #define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0 | ||
673 | |||
674 | /* | ||
675 | * Channel 1 Register Map | ||
676 | */ | ||
677 | #define AR_CHAN1_BASE 0xa800 | ||
678 | |||
679 | #define AR_PHY_EXT_CCA_1 (AR_CHAN1_BASE + 0x30) | ||
680 | #define AR_PHY_TX_PHASE_RAMP_1 (AR_CHAN1_BASE + 0xd0) | ||
681 | #define AR_PHY_ADC_GAIN_DC_CORR_1 (AR_CHAN1_BASE + 0xd4) | ||
682 | |||
683 | #define AR_PHY_SPUR_REPORT_1 (AR_CHAN1_BASE + 0xa8) | ||
684 | #define AR_PHY_CHAN_INFO_TAB_1 (AR_CHAN1_BASE + 0x300) | ||
685 | #define AR_PHY_RX_IQCAL_CORR_B1 (AR_CHAN1_BASE + 0xdc) | ||
686 | |||
687 | /* | ||
688 | * Channel 1 Field Definitions | ||
689 | */ | ||
690 | #define AR_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000 | ||
691 | #define AR_PHY_CH1_EXT_MINCCA_PWR_S 16 | ||
692 | |||
693 | /* | ||
694 | * AGC 1 Register Map | ||
695 | */ | ||
696 | #define AR_AGC1_BASE 0xae00 | ||
697 | |||
698 | #define AR_PHY_FORCEMAX_GAINS_1 (AR_AGC1_BASE + 0x4) | ||
699 | #define AR_PHY_EXT_ATTEN_CTL_1 (AR_AGC1_BASE + 0x18) | ||
700 | #define AR_PHY_CCA_1 (AR_AGC1_BASE + 0x1c) | ||
701 | #define AR_PHY_CCA_CTRL_1 (AR_AGC1_BASE + 0x20) | ||
702 | #define AR_PHY_RSSI_1 (AR_AGC1_BASE + 0x180) | ||
703 | #define AR_PHY_SPUR_CCK_REP_1 (AR_AGC1_BASE + 0x184) | ||
704 | #define AR_PHY_RX_OCGAIN_2 (AR_AGC1_BASE + 0x200) | ||
705 | |||
706 | /* | ||
707 | * AGC 1 Field Definitions | ||
708 | */ | ||
709 | #define AR_PHY_CH1_MINCCA_PWR 0x1FF00000 | ||
710 | #define AR_PHY_CH1_MINCCA_PWR_S 20 | ||
711 | |||
712 | /* | ||
713 | * SM 1 Register Map | ||
714 | */ | ||
715 | #define AR_SM1_BASE 0xb200 | ||
716 | |||
717 | #define AR_PHY_SWITCH_CHAIN_1 (AR_SM1_BASE + 0x84) | ||
718 | #define AR_PHY_FCAL_2_1 (AR_SM1_BASE + 0xd0) | ||
719 | #define AR_PHY_DFT_TONE_CTL_1 (AR_SM1_BASE + 0xd4) | ||
720 | #define AR_PHY_CL_TAB_1 (AR_SM1_BASE + 0x100) | ||
721 | #define AR_PHY_CHAN_INFO_GAIN_1 (AR_SM1_BASE + 0x180) | ||
722 | #define AR_PHY_TPC_4_B1 (AR_SM1_BASE + 0x204) | ||
723 | #define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) | ||
724 | #define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) | ||
725 | #define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) | ||
726 | #define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + 0x240) | ||
727 | #define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) | ||
728 | #define AR_PHY_TX_IQCAL_CORR_COEFF_01_B1 (AR_SM1_BASE + 0x450) | ||
729 | |||
730 | /* | ||
731 | * Channel 2 Register Map | ||
732 | */ | ||
733 | #define AR_CHAN2_BASE 0xb800 | ||
734 | |||
735 | #define AR_PHY_EXT_CCA_2 (AR_CHAN2_BASE + 0x30) | ||
736 | #define AR_PHY_TX_PHASE_RAMP_2 (AR_CHAN2_BASE + 0xd0) | ||
737 | #define AR_PHY_ADC_GAIN_DC_CORR_2 (AR_CHAN2_BASE + 0xd4) | ||
738 | |||
739 | #define AR_PHY_SPUR_REPORT_2 (AR_CHAN2_BASE + 0xa8) | ||
740 | #define AR_PHY_CHAN_INFO_TAB_2 (AR_CHAN2_BASE + 0x300) | ||
741 | #define AR_PHY_RX_IQCAL_CORR_B2 (AR_CHAN2_BASE + 0xdc) | ||
742 | |||
743 | /* | ||
744 | * Channel 2 Field Definitions | ||
745 | */ | ||
746 | #define AR_PHY_CH2_EXT_MINCCA_PWR 0x01FF0000 | ||
747 | #define AR_PHY_CH2_EXT_MINCCA_PWR_S 16 | ||
748 | /* | ||
749 | * AGC 2 Register Map | ||
750 | */ | ||
751 | #define AR_AGC2_BASE 0xbe00 | ||
752 | |||
753 | #define AR_PHY_FORCEMAX_GAINS_2 (AR_AGC2_BASE + 0x4) | ||
754 | #define AR_PHY_EXT_ATTEN_CTL_2 (AR_AGC2_BASE + 0x18) | ||
755 | #define AR_PHY_CCA_2 (AR_AGC2_BASE + 0x1c) | ||
756 | #define AR_PHY_CCA_CTRL_2 (AR_AGC2_BASE + 0x20) | ||
757 | #define AR_PHY_RSSI_2 (AR_AGC2_BASE + 0x180) | ||
758 | |||
759 | /* | ||
760 | * AGC 2 Field Definitions | ||
761 | */ | ||
762 | #define AR_PHY_CH2_MINCCA_PWR 0x1FF00000 | ||
763 | #define AR_PHY_CH2_MINCCA_PWR_S 20 | ||
764 | |||
765 | /* | ||
766 | * SM 2 Register Map | ||
767 | */ | ||
768 | #define AR_SM2_BASE 0xc200 | ||
769 | |||
770 | #define AR_PHY_SWITCH_CHAIN_2 (AR_SM2_BASE + 0x84) | ||
771 | #define AR_PHY_FCAL_2_2 (AR_SM2_BASE + 0xd0) | ||
772 | #define AR_PHY_DFT_TONE_CTL_2 (AR_SM2_BASE + 0xd4) | ||
773 | #define AR_PHY_CL_TAB_2 (AR_SM2_BASE + 0x100) | ||
774 | #define AR_PHY_CHAN_INFO_GAIN_2 (AR_SM2_BASE + 0x180) | ||
775 | #define AR_PHY_TPC_4_B2 (AR_SM2_BASE + 0x204) | ||
776 | #define AR_PHY_TPC_5_B2 (AR_SM2_BASE + 0x208) | ||
777 | #define AR_PHY_TPC_6_B2 (AR_SM2_BASE + 0x20c) | ||
778 | #define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220) | ||
779 | #define AR_PHY_PDADC_TAB_2 (AR_SM2_BASE + 0x240) | ||
780 | #define AR_PHY_TX_IQCAL_STATUS_B2 (AR_SM2_BASE + 0x48c) | ||
781 | #define AR_PHY_TX_IQCAL_CORR_COEFF_01_B2 (AR_SM2_BASE + 0x450) | ||
782 | |||
783 | #define AR_PHY_TX_IQCAL_STATUS_B2_FAILED 0x00000001 | ||
784 | |||
785 | /* | ||
786 | * AGC 3 Register Map | ||
787 | */ | ||
788 | #define AR_AGC3_BASE 0xce00 | ||
789 | |||
790 | #define AR_PHY_RSSI_3 (AR_AGC3_BASE + 0x180) | ||
791 | |||
792 | /* | ||
793 | * Misc helper defines | ||
794 | */ | ||
795 | #define AR_PHY_CHAIN_OFFSET (AR_CHAN1_BASE - AR_CHAN_BASE) | ||
796 | |||
797 | #define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (AR_PHY_ADC_GAIN_DC_CORR_0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
798 | #define AR_PHY_NEW_ADC_DC_GAIN_CORR_9300_10(_i) (AR_PHY_ADC_GAIN_DC_CORR_0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
799 | #define AR_PHY_SWITCH_CHAIN(_i) (AR_PHY_SWITCH_CHAIN_0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
800 | #define AR_PHY_EXT_ATTEN_CTL(_i) (AR_PHY_EXT_ATTEN_CTL_0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
801 | |||
802 | #define AR_PHY_RXGAIN(_i) (AR_PHY_FORCEMAX_GAINS_0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
803 | #define AR_PHY_TPCRG5(_i) (AR_PHY_TPC_5_B0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
804 | #define AR_PHY_PDADC_TAB(_i) (AR_PHY_PDADC_TAB_0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
805 | |||
806 | #define AR_PHY_CAL_MEAS_0(_i) (AR_PHY_IQ_ADC_MEAS_0_B0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
807 | #define AR_PHY_CAL_MEAS_1(_i) (AR_PHY_IQ_ADC_MEAS_1_B0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
808 | #define AR_PHY_CAL_MEAS_2(_i) (AR_PHY_IQ_ADC_MEAS_2_B0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
809 | #define AR_PHY_CAL_MEAS_3(_i) (AR_PHY_IQ_ADC_MEAS_3_B0 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
810 | #define AR_PHY_CAL_MEAS_0_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_0_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
811 | #define AR_PHY_CAL_MEAS_1_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_1_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
812 | #define AR_PHY_CAL_MEAS_2_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_2_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
813 | #define AR_PHY_CAL_MEAS_3_9300_10(_i) (AR_PHY_IQ_ADC_MEAS_3_B0_9300_10 + (AR_PHY_CHAIN_OFFSET * (_i))) | ||
814 | |||
815 | #define AR_PHY_BB_PANIC_NON_IDLE_ENABLE 0x00000001 | ||
816 | #define AR_PHY_BB_PANIC_IDLE_ENABLE 0x00000002 | ||
817 | #define AR_PHY_BB_PANIC_IDLE_MASK 0xFFFF0000 | ||
818 | #define AR_PHY_BB_PANIC_NON_IDLE_MASK 0x0000FFFC | ||
819 | |||
820 | #define AR_PHY_BB_PANIC_RST_ENABLE 0x00000002 | ||
821 | #define AR_PHY_BB_PANIC_IRQ_ENABLE 0x00000004 | ||
822 | #define AR_PHY_BB_PANIC_CNTL2_MASK 0xFFFFFFF9 | ||
823 | |||
824 | #define AR_PHY_BB_WD_STATUS 0x00000007 | ||
825 | #define AR_PHY_BB_WD_STATUS_S 0 | ||
826 | #define AR_PHY_BB_WD_DET_HANG 0x00000008 | ||
827 | #define AR_PHY_BB_WD_DET_HANG_S 3 | ||
828 | #define AR_PHY_BB_WD_RADAR_SM 0x000000F0 | ||
829 | #define AR_PHY_BB_WD_RADAR_SM_S 4 | ||
830 | #define AR_PHY_BB_WD_RX_OFDM_SM 0x00000F00 | ||
831 | #define AR_PHY_BB_WD_RX_OFDM_SM_S 8 | ||
832 | #define AR_PHY_BB_WD_RX_CCK_SM 0x0000F000 | ||
833 | #define AR_PHY_BB_WD_RX_CCK_SM_S 12 | ||
834 | #define AR_PHY_BB_WD_TX_OFDM_SM 0x000F0000 | ||
835 | #define AR_PHY_BB_WD_TX_OFDM_SM_S 16 | ||
836 | #define AR_PHY_BB_WD_TX_CCK_SM 0x00F00000 | ||
837 | #define AR_PHY_BB_WD_TX_CCK_SM_S 20 | ||
838 | #define AR_PHY_BB_WD_AGC_SM 0x0F000000 | ||
839 | #define AR_PHY_BB_WD_AGC_SM_S 24 | ||
840 | #define AR_PHY_BB_WD_SRCH_SM 0xF0000000 | ||
841 | #define AR_PHY_BB_WD_SRCH_SM_S 28 | ||
842 | |||
843 | #define AR_PHY_BB_WD_STATUS_CLR 0x00000008 | ||
844 | |||
845 | void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); | ||
846 | |||
847 | #endif /* AR9003_PHY_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 83c7ea4c007f..fbb7dec6ddeb 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -114,8 +114,10 @@ enum buffer_type { | |||
114 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) | 114 | #define bf_isretried(bf) (bf->bf_state.bf_type & BUF_RETRY) |
115 | #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) | 115 | #define bf_isxretried(bf) (bf->bf_state.bf_type & BUF_XRETRY) |
116 | 116 | ||
117 | #define ATH_TXSTATUS_RING_SIZE 64 | ||
118 | |||
117 | struct ath_descdma { | 119 | struct ath_descdma { |
118 | struct ath_desc *dd_desc; | 120 | void *dd_desc; |
119 | dma_addr_t dd_desc_paddr; | 121 | dma_addr_t dd_desc_paddr; |
120 | u32 dd_desc_len; | 122 | u32 dd_desc_len; |
121 | struct ath_buf *dd_bufptr; | 123 | struct ath_buf *dd_bufptr; |
@@ -123,7 +125,7 @@ struct ath_descdma { | |||
123 | 125 | ||
124 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | 126 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, |
125 | struct list_head *head, const char *name, | 127 | struct list_head *head, const char *name, |
126 | int nbuf, int ndesc); | 128 | int nbuf, int ndesc, bool is_tx); |
127 | void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | 129 | void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, |
128 | struct list_head *head); | 130 | struct list_head *head); |
129 | 131 | ||
@@ -178,9 +180,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, | |||
178 | #define BAW_WITHIN(_start, _bawsz, _seqno) \ | 180 | #define BAW_WITHIN(_start, _bawsz, _seqno) \ |
179 | ((((_seqno) - (_start)) & 4095) < (_bawsz)) | 181 | ((((_seqno) - (_start)) & 4095) < (_bawsz)) |
180 | 182 | ||
181 | #define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum) | ||
182 | #define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low) | ||
183 | #define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA) | ||
184 | #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) | 183 | #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) |
185 | 184 | ||
186 | #define ATH_TX_COMPLETE_POLL_INT 1000 | 185 | #define ATH_TX_COMPLETE_POLL_INT 1000 |
@@ -191,6 +190,7 @@ enum ATH_AGGR_STATUS { | |||
191 | ATH_AGGR_LIMITED, | 190 | ATH_AGGR_LIMITED, |
192 | }; | 191 | }; |
193 | 192 | ||
193 | #define ATH_TXFIFO_DEPTH 8 | ||
194 | struct ath_txq { | 194 | struct ath_txq { |
195 | u32 axq_qnum; | 195 | u32 axq_qnum; |
196 | u32 *axq_link; | 196 | u32 *axq_link; |
@@ -200,6 +200,10 @@ struct ath_txq { | |||
200 | bool stopped; | 200 | bool stopped; |
201 | bool axq_tx_inprogress; | 201 | bool axq_tx_inprogress; |
202 | struct list_head axq_acq; | 202 | struct list_head axq_acq; |
203 | struct list_head txq_fifo[ATH_TXFIFO_DEPTH]; | ||
204 | struct list_head txq_fifo_pending; | ||
205 | u8 txq_headidx; | ||
206 | u8 txq_tailidx; | ||
203 | }; | 207 | }; |
204 | 208 | ||
205 | #define AGGR_CLEANUP BIT(1) | 209 | #define AGGR_CLEANUP BIT(1) |
@@ -226,6 +230,12 @@ struct ath_tx { | |||
226 | struct ath_descdma txdma; | 230 | struct ath_descdma txdma; |
227 | }; | 231 | }; |
228 | 232 | ||
233 | struct ath_rx_edma { | ||
234 | struct sk_buff_head rx_fifo; | ||
235 | struct sk_buff_head rx_buffers; | ||
236 | u32 rx_fifo_hwsize; | ||
237 | }; | ||
238 | |||
229 | struct ath_rx { | 239 | struct ath_rx { |
230 | u8 defant; | 240 | u8 defant; |
231 | u8 rxotherant; | 241 | u8 rxotherant; |
@@ -235,6 +245,8 @@ struct ath_rx { | |||
235 | spinlock_t rxbuflock; | 245 | spinlock_t rxbuflock; |
236 | struct list_head rxbuf; | 246 | struct list_head rxbuf; |
237 | struct ath_descdma rxdma; | 247 | struct ath_descdma rxdma; |
248 | struct ath_buf *rx_bufptr; | ||
249 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; | ||
238 | }; | 250 | }; |
239 | 251 | ||
240 | int ath_startrecv(struct ath_softc *sc); | 252 | int ath_startrecv(struct ath_softc *sc); |
@@ -243,7 +255,7 @@ void ath_flushrecv(struct ath_softc *sc); | |||
243 | u32 ath_calcrxfilter(struct ath_softc *sc); | 255 | u32 ath_calcrxfilter(struct ath_softc *sc); |
244 | int ath_rx_init(struct ath_softc *sc, int nbufs); | 256 | int ath_rx_init(struct ath_softc *sc, int nbufs); |
245 | void ath_rx_cleanup(struct ath_softc *sc); | 257 | void ath_rx_cleanup(struct ath_softc *sc); |
246 | int ath_rx_tasklet(struct ath_softc *sc, int flush); | 258 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); |
247 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 259 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
248 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 260 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
249 | int ath_tx_setup(struct ath_softc *sc, int haltype); | 261 | int ath_tx_setup(struct ath_softc *sc, int haltype); |
@@ -261,6 +273,7 @@ int ath_txq_update(struct ath_softc *sc, int qnum, | |||
261 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | 273 | int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, |
262 | struct ath_tx_control *txctl); | 274 | struct ath_tx_control *txctl); |
263 | void ath_tx_tasklet(struct ath_softc *sc); | 275 | void ath_tx_tasklet(struct ath_softc *sc); |
276 | void ath_tx_edma_tasklet(struct ath_softc *sc); | ||
264 | void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); | 277 | void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb); |
265 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); | 278 | bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno); |
266 | void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | 279 | void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, |
@@ -483,7 +496,6 @@ struct ath_softc { | |||
483 | bool ps_enabled; | 496 | bool ps_enabled; |
484 | bool ps_idle; | 497 | bool ps_idle; |
485 | unsigned long ps_usecount; | 498 | unsigned long ps_usecount; |
486 | enum ath9k_int imask; | ||
487 | 499 | ||
488 | struct ath_config config; | 500 | struct ath_config config; |
489 | struct ath_rx rx; | 501 | struct ath_rx rx; |
@@ -511,6 +523,8 @@ struct ath_softc { | |||
511 | struct ath_beacon_config cur_beacon_conf; | 523 | struct ath_beacon_config cur_beacon_conf; |
512 | struct delayed_work tx_complete_work; | 524 | struct delayed_work tx_complete_work; |
513 | struct ath_btcoex btcoex; | 525 | struct ath_btcoex btcoex; |
526 | |||
527 | struct ath_descdma txsdma; | ||
514 | }; | 528 | }; |
515 | 529 | ||
516 | struct ath_wiphy { | 530 | struct ath_wiphy { |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index b4a31a43a62c..c8a4558f79ba 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -93,8 +93,6 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
93 | antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); | 93 | antenna = ((sc->beacon.ast_be_xmit / sc->nbcnvifs) & 1 ? 2 : 1); |
94 | } | 94 | } |
95 | 95 | ||
96 | ds->ds_data = bf->bf_buf_addr; | ||
97 | |||
98 | sband = &sc->sbands[common->hw->conf.channel->band]; | 96 | sband = &sc->sbands[common->hw->conf.channel->band]; |
99 | rate = sband->bitrates[rateidx].hw_value; | 97 | rate = sband->bitrates[rateidx].hw_value; |
100 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) | 98 | if (sc->sc_flags & SC_OP_PREAMBLE_SHORT) |
@@ -109,7 +107,8 @@ static void ath_beacon_setup(struct ath_softc *sc, struct ath_vif *avp, | |||
109 | 107 | ||
110 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ | 108 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ |
111 | ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), | 109 | ath9k_hw_filltxdesc(ah, ds, roundup(skb->len, 4), |
112 | true, true, ds); | 110 | true, true, ds, bf->bf_buf_addr, |
111 | sc->beacon.beaconq); | ||
113 | 112 | ||
114 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); | 113 | memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4); |
115 | series[0].Tries = 1; | 114 | series[0].Tries = 1; |
@@ -524,6 +523,7 @@ static void ath9k_beacon_init(struct ath_softc *sc, | |||
524 | static void ath_beacon_config_ap(struct ath_softc *sc, | 523 | static void ath_beacon_config_ap(struct ath_softc *sc, |
525 | struct ath_beacon_config *conf) | 524 | struct ath_beacon_config *conf) |
526 | { | 525 | { |
526 | struct ath_hw *ah = sc->sc_ah; | ||
527 | u32 nexttbtt, intval; | 527 | u32 nexttbtt, intval; |
528 | 528 | ||
529 | /* NB: the beacon interval is kept internally in TU's */ | 529 | /* NB: the beacon interval is kept internally in TU's */ |
@@ -539,15 +539,15 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
539 | * prepare beacon frames. | 539 | * prepare beacon frames. |
540 | */ | 540 | */ |
541 | intval |= ATH9K_BEACON_ENA; | 541 | intval |= ATH9K_BEACON_ENA; |
542 | sc->imask |= ATH9K_INT_SWBA; | 542 | ah->imask |= ATH9K_INT_SWBA; |
543 | ath_beaconq_config(sc); | 543 | ath_beaconq_config(sc); |
544 | 544 | ||
545 | /* Set the computed AP beacon timers */ | 545 | /* Set the computed AP beacon timers */ |
546 | 546 | ||
547 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | 547 | ath9k_hw_set_interrupts(ah, 0); |
548 | ath9k_beacon_init(sc, nexttbtt, intval); | 548 | ath9k_beacon_init(sc, nexttbtt, intval); |
549 | sc->beacon.bmisscnt = 0; | 549 | sc->beacon.bmisscnt = 0; |
550 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 550 | ath9k_hw_set_interrupts(ah, ah->imask); |
551 | 551 | ||
552 | /* Clear the reset TSF flag, so that subsequent beacon updation | 552 | /* Clear the reset TSF flag, so that subsequent beacon updation |
553 | will not reset the HW TSF. */ | 553 | will not reset the HW TSF. */ |
@@ -566,7 +566,8 @@ static void ath_beacon_config_ap(struct ath_softc *sc, | |||
566 | static void ath_beacon_config_sta(struct ath_softc *sc, | 566 | static void ath_beacon_config_sta(struct ath_softc *sc, |
567 | struct ath_beacon_config *conf) | 567 | struct ath_beacon_config *conf) |
568 | { | 568 | { |
569 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 569 | struct ath_hw *ah = sc->sc_ah; |
570 | struct ath_common *common = ath9k_hw_common(ah); | ||
570 | struct ath9k_beacon_state bs; | 571 | struct ath9k_beacon_state bs; |
571 | int dtimperiod, dtimcount, sleepduration; | 572 | int dtimperiod, dtimcount, sleepduration; |
572 | int cfpperiod, cfpcount; | 573 | int cfpperiod, cfpcount; |
@@ -605,7 +606,7 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
605 | * Pull nexttbtt forward to reflect the current | 606 | * Pull nexttbtt forward to reflect the current |
606 | * TSF and calculate dtim+cfp state for the result. | 607 | * TSF and calculate dtim+cfp state for the result. |
607 | */ | 608 | */ |
608 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | 609 | tsf = ath9k_hw_gettsf64(ah); |
609 | tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; | 610 | tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; |
610 | 611 | ||
611 | num_beacons = tsftu / intval + 1; | 612 | num_beacons = tsftu / intval + 1; |
@@ -678,17 +679,18 @@ static void ath_beacon_config_sta(struct ath_softc *sc, | |||
678 | 679 | ||
679 | /* Set the computed STA beacon timers */ | 680 | /* Set the computed STA beacon timers */ |
680 | 681 | ||
681 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | 682 | ath9k_hw_set_interrupts(ah, 0); |
682 | ath9k_hw_set_sta_beacon_timers(sc->sc_ah, &bs); | 683 | ath9k_hw_set_sta_beacon_timers(ah, &bs); |
683 | sc->imask |= ATH9K_INT_BMISS; | 684 | ah->imask |= ATH9K_INT_BMISS; |
684 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 685 | ath9k_hw_set_interrupts(ah, ah->imask); |
685 | } | 686 | } |
686 | 687 | ||
687 | static void ath_beacon_config_adhoc(struct ath_softc *sc, | 688 | static void ath_beacon_config_adhoc(struct ath_softc *sc, |
688 | struct ath_beacon_config *conf, | 689 | struct ath_beacon_config *conf, |
689 | struct ieee80211_vif *vif) | 690 | struct ieee80211_vif *vif) |
690 | { | 691 | { |
691 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 692 | struct ath_hw *ah = sc->sc_ah; |
693 | struct ath_common *common = ath9k_hw_common(ah); | ||
692 | u64 tsf; | 694 | u64 tsf; |
693 | u32 tsftu, intval, nexttbtt; | 695 | u32 tsftu, intval, nexttbtt; |
694 | 696 | ||
@@ -703,7 +705,7 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
703 | else if (intval) | 705 | else if (intval) |
704 | nexttbtt = roundup(nexttbtt, intval); | 706 | nexttbtt = roundup(nexttbtt, intval); |
705 | 707 | ||
706 | tsf = ath9k_hw_gettsf64(sc->sc_ah); | 708 | tsf = ath9k_hw_gettsf64(ah); |
707 | tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; | 709 | tsftu = TSF_TO_TU((u32)(tsf>>32), (u32)tsf) + FUDGE; |
708 | do { | 710 | do { |
709 | nexttbtt += intval; | 711 | nexttbtt += intval; |
@@ -719,20 +721,20 @@ static void ath_beacon_config_adhoc(struct ath_softc *sc, | |||
719 | * self-linked tx descriptor and let the hardware deal with things. | 721 | * self-linked tx descriptor and let the hardware deal with things. |
720 | */ | 722 | */ |
721 | intval |= ATH9K_BEACON_ENA; | 723 | intval |= ATH9K_BEACON_ENA; |
722 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) | 724 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_VEOL)) |
723 | sc->imask |= ATH9K_INT_SWBA; | 725 | ah->imask |= ATH9K_INT_SWBA; |
724 | 726 | ||
725 | ath_beaconq_config(sc); | 727 | ath_beaconq_config(sc); |
726 | 728 | ||
727 | /* Set the computed ADHOC beacon timers */ | 729 | /* Set the computed ADHOC beacon timers */ |
728 | 730 | ||
729 | ath9k_hw_set_interrupts(sc->sc_ah, 0); | 731 | ath9k_hw_set_interrupts(ah, 0); |
730 | ath9k_beacon_init(sc, nexttbtt, intval); | 732 | ath9k_beacon_init(sc, nexttbtt, intval); |
731 | sc->beacon.bmisscnt = 0; | 733 | sc->beacon.bmisscnt = 0; |
732 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 734 | ath9k_hw_set_interrupts(ah, ah->imask); |
733 | 735 | ||
734 | /* FIXME: Handle properly when vif is NULL */ | 736 | /* FIXME: Handle properly when vif is NULL */ |
735 | if (vif && sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_VEOL) | 737 | if (vif && ah->caps.hw_caps & ATH9K_HW_CAP_VEOL) |
736 | ath_beacon_start_adhoc(sc, vif); | 738 | ath_beacon_start_adhoc(sc, vif); |
737 | } | 739 | } |
738 | 740 | ||
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 238a5744d8e9..07b8fa6fb62f 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -15,6 +15,9 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "hw-ops.h" | ||
19 | |||
20 | /* Common calibration code */ | ||
18 | 21 | ||
19 | /* We can tune this as we go by monitoring really low values */ | 22 | /* We can tune this as we go by monitoring really low values */ |
20 | #define ATH9K_NF_TOO_LOW -60 | 23 | #define ATH9K_NF_TOO_LOW -60 |
@@ -83,93 +86,11 @@ static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h, | |||
83 | ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); | 86 | ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer); |
84 | } | 87 | } |
85 | } | 88 | } |
86 | return; | ||
87 | } | 89 | } |
88 | 90 | ||
89 | static void ath9k_hw_do_getnf(struct ath_hw *ah, | 91 | static bool ath9k_hw_get_nf_thresh(struct ath_hw *ah, |
90 | int16_t nfarray[NUM_NF_READINGS]) | 92 | enum ieee80211_band band, |
91 | { | 93 | int16_t *nft) |
92 | struct ath_common *common = ath9k_hw_common(ah); | ||
93 | int16_t nf; | ||
94 | |||
95 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
96 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR); | ||
97 | else | ||
98 | nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR); | ||
99 | |||
100 | if (nf & 0x100) | ||
101 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
102 | ath_print(common, ATH_DBG_CALIBRATE, | ||
103 | "NF calibrated [ctl] [chain 0] is %d\n", nf); | ||
104 | nfarray[0] = nf; | ||
105 | |||
106 | if (!AR_SREV_9285(ah)) { | ||
107 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
108 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | ||
109 | AR9280_PHY_CH1_MINCCA_PWR); | ||
110 | else | ||
111 | nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), | ||
112 | AR_PHY_CH1_MINCCA_PWR); | ||
113 | |||
114 | if (nf & 0x100) | ||
115 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
116 | ath_print(common, ATH_DBG_CALIBRATE, | ||
117 | "NF calibrated [ctl] [chain 1] is %d\n", nf); | ||
118 | nfarray[1] = nf; | ||
119 | |||
120 | if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { | ||
121 | nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), | ||
122 | AR_PHY_CH2_MINCCA_PWR); | ||
123 | if (nf & 0x100) | ||
124 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
125 | ath_print(common, ATH_DBG_CALIBRATE, | ||
126 | "NF calibrated [ctl] [chain 2] is %d\n", nf); | ||
127 | nfarray[2] = nf; | ||
128 | } | ||
129 | } | ||
130 | |||
131 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
132 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), | ||
133 | AR9280_PHY_EXT_MINCCA_PWR); | ||
134 | else | ||
135 | nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), | ||
136 | AR_PHY_EXT_MINCCA_PWR); | ||
137 | |||
138 | if (nf & 0x100) | ||
139 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
140 | ath_print(common, ATH_DBG_CALIBRATE, | ||
141 | "NF calibrated [ext] [chain 0] is %d\n", nf); | ||
142 | nfarray[3] = nf; | ||
143 | |||
144 | if (!AR_SREV_9285(ah)) { | ||
145 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
146 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | ||
147 | AR9280_PHY_CH1_EXT_MINCCA_PWR); | ||
148 | else | ||
149 | nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), | ||
150 | AR_PHY_CH1_EXT_MINCCA_PWR); | ||
151 | |||
152 | if (nf & 0x100) | ||
153 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
154 | ath_print(common, ATH_DBG_CALIBRATE, | ||
155 | "NF calibrated [ext] [chain 1] is %d\n", nf); | ||
156 | nfarray[4] = nf; | ||
157 | |||
158 | if (!AR_SREV_9280(ah) && !AR_SREV_9287(ah)) { | ||
159 | nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), | ||
160 | AR_PHY_CH2_EXT_MINCCA_PWR); | ||
161 | if (nf & 0x100) | ||
162 | nf = 0 - ((nf ^ 0x1ff) + 1); | ||
163 | ath_print(common, ATH_DBG_CALIBRATE, | ||
164 | "NF calibrated [ext] [chain 2] is %d\n", nf); | ||
165 | nfarray[5] = nf; | ||
166 | } | ||
167 | } | ||
168 | } | ||
169 | |||
170 | static bool getNoiseFloorThresh(struct ath_hw *ah, | ||
171 | enum ieee80211_band band, | ||
172 | int16_t *nft) | ||
173 | { | 94 | { |
174 | switch (band) { | 95 | switch (band) { |
175 | case IEEE80211_BAND_5GHZ: | 96 | case IEEE80211_BAND_5GHZ: |
@@ -186,44 +107,8 @@ static bool getNoiseFloorThresh(struct ath_hw *ah, | |||
186 | return true; | 107 | return true; |
187 | } | 108 | } |
188 | 109 | ||
189 | static void ath9k_hw_setup_calibration(struct ath_hw *ah, | 110 | void ath9k_hw_reset_calibration(struct ath_hw *ah, |
190 | struct ath9k_cal_list *currCal) | 111 | struct ath9k_cal_list *currCal) |
191 | { | ||
192 | struct ath_common *common = ath9k_hw_common(ah); | ||
193 | |||
194 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0), | ||
195 | AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX, | ||
196 | currCal->calData->calCountMax); | ||
197 | |||
198 | switch (currCal->calData->calType) { | ||
199 | case IQ_MISMATCH_CAL: | ||
200 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ); | ||
201 | ath_print(common, ATH_DBG_CALIBRATE, | ||
202 | "starting IQ Mismatch Calibration\n"); | ||
203 | break; | ||
204 | case ADC_GAIN_CAL: | ||
205 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN); | ||
206 | ath_print(common, ATH_DBG_CALIBRATE, | ||
207 | "starting ADC Gain Calibration\n"); | ||
208 | break; | ||
209 | case ADC_DC_CAL: | ||
210 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER); | ||
211 | ath_print(common, ATH_DBG_CALIBRATE, | ||
212 | "starting ADC DC Calibration\n"); | ||
213 | break; | ||
214 | case ADC_DC_INIT_CAL: | ||
215 | REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT); | ||
216 | ath_print(common, ATH_DBG_CALIBRATE, | ||
217 | "starting Init ADC DC Calibration\n"); | ||
218 | break; | ||
219 | } | ||
220 | |||
221 | REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), | ||
222 | AR_PHY_TIMING_CTRL4_DO_CAL); | ||
223 | } | ||
224 | |||
225 | static void ath9k_hw_reset_calibration(struct ath_hw *ah, | ||
226 | struct ath9k_cal_list *currCal) | ||
227 | { | 112 | { |
228 | int i; | 113 | int i; |
229 | 114 | ||
@@ -241,324 +126,6 @@ static void ath9k_hw_reset_calibration(struct ath_hw *ah, | |||
241 | ah->cal_samples = 0; | 126 | ah->cal_samples = 0; |
242 | } | 127 | } |
243 | 128 | ||
244 | static bool ath9k_hw_per_calibration(struct ath_hw *ah, | ||
245 | struct ath9k_channel *ichan, | ||
246 | u8 rxchainmask, | ||
247 | struct ath9k_cal_list *currCal) | ||
248 | { | ||
249 | bool iscaldone = false; | ||
250 | |||
251 | if (currCal->calState == CAL_RUNNING) { | ||
252 | if (!(REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & | ||
253 | AR_PHY_TIMING_CTRL4_DO_CAL)) { | ||
254 | |||
255 | currCal->calData->calCollect(ah); | ||
256 | ah->cal_samples++; | ||
257 | |||
258 | if (ah->cal_samples >= currCal->calData->calNumSamples) { | ||
259 | int i, numChains = 0; | ||
260 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
261 | if (rxchainmask & (1 << i)) | ||
262 | numChains++; | ||
263 | } | ||
264 | |||
265 | currCal->calData->calPostProc(ah, numChains); | ||
266 | ichan->CalValid |= currCal->calData->calType; | ||
267 | currCal->calState = CAL_DONE; | ||
268 | iscaldone = true; | ||
269 | } else { | ||
270 | ath9k_hw_setup_calibration(ah, currCal); | ||
271 | } | ||
272 | } | ||
273 | } else if (!(ichan->CalValid & currCal->calData->calType)) { | ||
274 | ath9k_hw_reset_calibration(ah, currCal); | ||
275 | } | ||
276 | |||
277 | return iscaldone; | ||
278 | } | ||
279 | |||
280 | /* Assumes you are talking about the currently configured channel */ | ||
281 | static bool ath9k_hw_iscal_supported(struct ath_hw *ah, | ||
282 | enum ath9k_cal_types calType) | ||
283 | { | ||
284 | struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; | ||
285 | |||
286 | switch (calType & ah->supp_cals) { | ||
287 | case IQ_MISMATCH_CAL: /* Both 2 GHz and 5 GHz support OFDM */ | ||
288 | return true; | ||
289 | case ADC_GAIN_CAL: | ||
290 | case ADC_DC_CAL: | ||
291 | if (!(conf->channel->band == IEEE80211_BAND_2GHZ && | ||
292 | conf_is_ht20(conf))) | ||
293 | return true; | ||
294 | break; | ||
295 | } | ||
296 | return false; | ||
297 | } | ||
298 | |||
299 | static void ath9k_hw_iqcal_collect(struct ath_hw *ah) | ||
300 | { | ||
301 | int i; | ||
302 | |||
303 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
304 | ah->totalPowerMeasI[i] += | ||
305 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
306 | ah->totalPowerMeasQ[i] += | ||
307 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
308 | ah->totalIqCorrMeas[i] += | ||
309 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
310 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
311 | "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n", | ||
312 | ah->cal_samples, i, ah->totalPowerMeasI[i], | ||
313 | ah->totalPowerMeasQ[i], | ||
314 | ah->totalIqCorrMeas[i]); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | static void ath9k_hw_adc_gaincal_collect(struct ath_hw *ah) | ||
319 | { | ||
320 | int i; | ||
321 | |||
322 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
323 | ah->totalAdcIOddPhase[i] += | ||
324 | REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
325 | ah->totalAdcIEvenPhase[i] += | ||
326 | REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
327 | ah->totalAdcQOddPhase[i] += | ||
328 | REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
329 | ah->totalAdcQEvenPhase[i] += | ||
330 | REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
331 | |||
332 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
333 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
334 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
335 | ah->cal_samples, i, | ||
336 | ah->totalAdcIOddPhase[i], | ||
337 | ah->totalAdcIEvenPhase[i], | ||
338 | ah->totalAdcQOddPhase[i], | ||
339 | ah->totalAdcQEvenPhase[i]); | ||
340 | } | ||
341 | } | ||
342 | |||
343 | static void ath9k_hw_adc_dccal_collect(struct ath_hw *ah) | ||
344 | { | ||
345 | int i; | ||
346 | |||
347 | for (i = 0; i < AR5416_MAX_CHAINS; i++) { | ||
348 | ah->totalAdcDcOffsetIOddPhase[i] += | ||
349 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i)); | ||
350 | ah->totalAdcDcOffsetIEvenPhase[i] += | ||
351 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i)); | ||
352 | ah->totalAdcDcOffsetQOddPhase[i] += | ||
353 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i)); | ||
354 | ah->totalAdcDcOffsetQEvenPhase[i] += | ||
355 | (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i)); | ||
356 | |||
357 | ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE, | ||
358 | "%d: Chn %d oddi=0x%08x; eveni=0x%08x; " | ||
359 | "oddq=0x%08x; evenq=0x%08x;\n", | ||
360 | ah->cal_samples, i, | ||
361 | ah->totalAdcDcOffsetIOddPhase[i], | ||
362 | ah->totalAdcDcOffsetIEvenPhase[i], | ||
363 | ah->totalAdcDcOffsetQOddPhase[i], | ||
364 | ah->totalAdcDcOffsetQEvenPhase[i]); | ||
365 | } | ||
366 | } | ||
367 | |||
368 | static void ath9k_hw_iqcalibrate(struct ath_hw *ah, u8 numChains) | ||
369 | { | ||
370 | struct ath_common *common = ath9k_hw_common(ah); | ||
371 | u32 powerMeasQ, powerMeasI, iqCorrMeas; | ||
372 | u32 qCoffDenom, iCoffDenom; | ||
373 | int32_t qCoff, iCoff; | ||
374 | int iqCorrNeg, i; | ||
375 | |||
376 | for (i = 0; i < numChains; i++) { | ||
377 | powerMeasI = ah->totalPowerMeasI[i]; | ||
378 | powerMeasQ = ah->totalPowerMeasQ[i]; | ||
379 | iqCorrMeas = ah->totalIqCorrMeas[i]; | ||
380 | |||
381 | ath_print(common, ATH_DBG_CALIBRATE, | ||
382 | "Starting IQ Cal and Correction for Chain %d\n", | ||
383 | i); | ||
384 | |||
385 | ath_print(common, ATH_DBG_CALIBRATE, | ||
386 | "Orignal: Chn %diq_corr_meas = 0x%08x\n", | ||
387 | i, ah->totalIqCorrMeas[i]); | ||
388 | |||
389 | iqCorrNeg = 0; | ||
390 | |||
391 | if (iqCorrMeas > 0x80000000) { | ||
392 | iqCorrMeas = (0xffffffff - iqCorrMeas) + 1; | ||
393 | iqCorrNeg = 1; | ||
394 | } | ||
395 | |||
396 | ath_print(common, ATH_DBG_CALIBRATE, | ||
397 | "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI); | ||
398 | ath_print(common, ATH_DBG_CALIBRATE, | ||
399 | "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ); | ||
400 | ath_print(common, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n", | ||
401 | iqCorrNeg); | ||
402 | |||
403 | iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128; | ||
404 | qCoffDenom = powerMeasQ / 64; | ||
405 | |||
406 | if ((powerMeasQ != 0) && (iCoffDenom != 0) && | ||
407 | (qCoffDenom != 0)) { | ||
408 | iCoff = iqCorrMeas / iCoffDenom; | ||
409 | qCoff = powerMeasI / qCoffDenom - 64; | ||
410 | ath_print(common, ATH_DBG_CALIBRATE, | ||
411 | "Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
412 | ath_print(common, ATH_DBG_CALIBRATE, | ||
413 | "Chn %d qCoff = 0x%08x\n", i, qCoff); | ||
414 | |||
415 | iCoff = iCoff & 0x3f; | ||
416 | ath_print(common, ATH_DBG_CALIBRATE, | ||
417 | "New: Chn %d iCoff = 0x%08x\n", i, iCoff); | ||
418 | if (iqCorrNeg == 0x0) | ||
419 | iCoff = 0x40 - iCoff; | ||
420 | |||
421 | if (qCoff > 15) | ||
422 | qCoff = 15; | ||
423 | else if (qCoff <= -16) | ||
424 | qCoff = 16; | ||
425 | |||
426 | ath_print(common, ATH_DBG_CALIBRATE, | ||
427 | "Chn %d : iCoff = 0x%x qCoff = 0x%x\n", | ||
428 | i, iCoff, qCoff); | ||
429 | |||
430 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
431 | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF, | ||
432 | iCoff); | ||
433 | REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i), | ||
434 | AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF, | ||
435 | qCoff); | ||
436 | ath_print(common, ATH_DBG_CALIBRATE, | ||
437 | "IQ Cal and Correction done for Chain %d\n", | ||
438 | i); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0), | ||
443 | AR_PHY_TIMING_CTRL4_IQCORR_ENABLE); | ||
444 | } | ||
445 | |||
446 | static void ath9k_hw_adc_gaincal_calibrate(struct ath_hw *ah, u8 numChains) | ||
447 | { | ||
448 | struct ath_common *common = ath9k_hw_common(ah); | ||
449 | u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset, qEvenMeasOffset; | ||
450 | u32 qGainMismatch, iGainMismatch, val, i; | ||
451 | |||
452 | for (i = 0; i < numChains; i++) { | ||
453 | iOddMeasOffset = ah->totalAdcIOddPhase[i]; | ||
454 | iEvenMeasOffset = ah->totalAdcIEvenPhase[i]; | ||
455 | qOddMeasOffset = ah->totalAdcQOddPhase[i]; | ||
456 | qEvenMeasOffset = ah->totalAdcQEvenPhase[i]; | ||
457 | |||
458 | ath_print(common, ATH_DBG_CALIBRATE, | ||
459 | "Starting ADC Gain Cal for Chain %d\n", i); | ||
460 | |||
461 | ath_print(common, ATH_DBG_CALIBRATE, | ||
462 | "Chn %d pwr_meas_odd_i = 0x%08x\n", i, | ||
463 | iOddMeasOffset); | ||
464 | ath_print(common, ATH_DBG_CALIBRATE, | ||
465 | "Chn %d pwr_meas_even_i = 0x%08x\n", i, | ||
466 | iEvenMeasOffset); | ||
467 | ath_print(common, ATH_DBG_CALIBRATE, | ||
468 | "Chn %d pwr_meas_odd_q = 0x%08x\n", i, | ||
469 | qOddMeasOffset); | ||
470 | ath_print(common, ATH_DBG_CALIBRATE, | ||
471 | "Chn %d pwr_meas_even_q = 0x%08x\n", i, | ||
472 | qEvenMeasOffset); | ||
473 | |||
474 | if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) { | ||
475 | iGainMismatch = | ||
476 | ((iEvenMeasOffset * 32) / | ||
477 | iOddMeasOffset) & 0x3f; | ||
478 | qGainMismatch = | ||
479 | ((qOddMeasOffset * 32) / | ||
480 | qEvenMeasOffset) & 0x3f; | ||
481 | |||
482 | ath_print(common, ATH_DBG_CALIBRATE, | ||
483 | "Chn %d gain_mismatch_i = 0x%08x\n", i, | ||
484 | iGainMismatch); | ||
485 | ath_print(common, ATH_DBG_CALIBRATE, | ||
486 | "Chn %d gain_mismatch_q = 0x%08x\n", i, | ||
487 | qGainMismatch); | ||
488 | |||
489 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
490 | val &= 0xfffff000; | ||
491 | val |= (qGainMismatch) | (iGainMismatch << 6); | ||
492 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
493 | |||
494 | ath_print(common, ATH_DBG_CALIBRATE, | ||
495 | "ADC Gain Cal done for Chain %d\n", i); | ||
496 | } | ||
497 | } | ||
498 | |||
499 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
500 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
501 | AR_PHY_NEW_ADC_GAIN_CORR_ENABLE); | ||
502 | } | ||
503 | |||
504 | static void ath9k_hw_adc_dccal_calibrate(struct ath_hw *ah, u8 numChains) | ||
505 | { | ||
506 | struct ath_common *common = ath9k_hw_common(ah); | ||
507 | u32 iOddMeasOffset, iEvenMeasOffset, val, i; | ||
508 | int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch; | ||
509 | const struct ath9k_percal_data *calData = | ||
510 | ah->cal_list_curr->calData; | ||
511 | u32 numSamples = | ||
512 | (1 << (calData->calCountMax + 5)) * calData->calNumSamples; | ||
513 | |||
514 | for (i = 0; i < numChains; i++) { | ||
515 | iOddMeasOffset = ah->totalAdcDcOffsetIOddPhase[i]; | ||
516 | iEvenMeasOffset = ah->totalAdcDcOffsetIEvenPhase[i]; | ||
517 | qOddMeasOffset = ah->totalAdcDcOffsetQOddPhase[i]; | ||
518 | qEvenMeasOffset = ah->totalAdcDcOffsetQEvenPhase[i]; | ||
519 | |||
520 | ath_print(common, ATH_DBG_CALIBRATE, | ||
521 | "Starting ADC DC Offset Cal for Chain %d\n", i); | ||
522 | |||
523 | ath_print(common, ATH_DBG_CALIBRATE, | ||
524 | "Chn %d pwr_meas_odd_i = %d\n", i, | ||
525 | iOddMeasOffset); | ||
526 | ath_print(common, ATH_DBG_CALIBRATE, | ||
527 | "Chn %d pwr_meas_even_i = %d\n", i, | ||
528 | iEvenMeasOffset); | ||
529 | ath_print(common, ATH_DBG_CALIBRATE, | ||
530 | "Chn %d pwr_meas_odd_q = %d\n", i, | ||
531 | qOddMeasOffset); | ||
532 | ath_print(common, ATH_DBG_CALIBRATE, | ||
533 | "Chn %d pwr_meas_even_q = %d\n", i, | ||
534 | qEvenMeasOffset); | ||
535 | |||
536 | iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) / | ||
537 | numSamples) & 0x1ff; | ||
538 | qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) / | ||
539 | numSamples) & 0x1ff; | ||
540 | |||
541 | ath_print(common, ATH_DBG_CALIBRATE, | ||
542 | "Chn %d dc_offset_mismatch_i = 0x%08x\n", i, | ||
543 | iDcMismatch); | ||
544 | ath_print(common, ATH_DBG_CALIBRATE, | ||
545 | "Chn %d dc_offset_mismatch_q = 0x%08x\n", i, | ||
546 | qDcMismatch); | ||
547 | |||
548 | val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i)); | ||
549 | val &= 0xc0000fff; | ||
550 | val |= (qDcMismatch << 12) | (iDcMismatch << 21); | ||
551 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val); | ||
552 | |||
553 | ath_print(common, ATH_DBG_CALIBRATE, | ||
554 | "ADC DC Offset Cal done for Chain %d\n", i); | ||
555 | } | ||
556 | |||
557 | REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0), | ||
558 | REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) | | ||
559 | AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE); | ||
560 | } | ||
561 | |||
562 | /* This is done for the currently configured channel */ | 129 | /* This is done for the currently configured channel */ |
563 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah) | 130 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah) |
564 | { | 131 | { |
@@ -605,72 +172,6 @@ void ath9k_hw_start_nfcal(struct ath_hw *ah) | |||
605 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | 172 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); |
606 | } | 173 | } |
607 | 174 | ||
608 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan) | ||
609 | { | ||
610 | struct ath9k_nfcal_hist *h; | ||
611 | int i, j; | ||
612 | int32_t val; | ||
613 | const u32 ar5416_cca_regs[6] = { | ||
614 | AR_PHY_CCA, | ||
615 | AR_PHY_CH1_CCA, | ||
616 | AR_PHY_CH2_CCA, | ||
617 | AR_PHY_EXT_CCA, | ||
618 | AR_PHY_CH1_EXT_CCA, | ||
619 | AR_PHY_CH2_EXT_CCA | ||
620 | }; | ||
621 | u8 chainmask, rx_chain_status; | ||
622 | |||
623 | rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK); | ||
624 | if (AR_SREV_9285(ah)) | ||
625 | chainmask = 0x9; | ||
626 | else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) { | ||
627 | if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4)) | ||
628 | chainmask = 0x1B; | ||
629 | else | ||
630 | chainmask = 0x09; | ||
631 | } else { | ||
632 | if (rx_chain_status & 0x4) | ||
633 | chainmask = 0x3F; | ||
634 | else if (rx_chain_status & 0x2) | ||
635 | chainmask = 0x1B; | ||
636 | else | ||
637 | chainmask = 0x09; | ||
638 | } | ||
639 | |||
640 | h = ah->nfCalHist; | ||
641 | |||
642 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
643 | if (chainmask & (1 << i)) { | ||
644 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
645 | val &= 0xFFFFFE00; | ||
646 | val |= (((u32) (h[i].privNF) << 1) & 0x1ff); | ||
647 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
648 | } | ||
649 | } | ||
650 | |||
651 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
652 | AR_PHY_AGC_CONTROL_ENABLE_NF); | ||
653 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
654 | AR_PHY_AGC_CONTROL_NO_UPDATE_NF); | ||
655 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); | ||
656 | |||
657 | for (j = 0; j < 5; j++) { | ||
658 | if ((REG_READ(ah, AR_PHY_AGC_CONTROL) & | ||
659 | AR_PHY_AGC_CONTROL_NF) == 0) | ||
660 | break; | ||
661 | udelay(50); | ||
662 | } | ||
663 | |||
664 | for (i = 0; i < NUM_NF_READINGS; i++) { | ||
665 | if (chainmask & (1 << i)) { | ||
666 | val = REG_READ(ah, ar5416_cca_regs[i]); | ||
667 | val &= 0xFFFFFE00; | ||
668 | val |= (((u32) (-50) << 1) & 0x1ff); | ||
669 | REG_WRITE(ah, ar5416_cca_regs[i], val); | ||
670 | } | ||
671 | } | ||
672 | } | ||
673 | |||
674 | int16_t ath9k_hw_getnf(struct ath_hw *ah, | 175 | int16_t ath9k_hw_getnf(struct ath_hw *ah, |
675 | struct ath9k_channel *chan) | 176 | struct ath9k_channel *chan) |
676 | { | 177 | { |
@@ -690,7 +191,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah, | |||
690 | } else { | 191 | } else { |
691 | ath9k_hw_do_getnf(ah, nfarray); | 192 | ath9k_hw_do_getnf(ah, nfarray); |
692 | nf = nfarray[0]; | 193 | nf = nfarray[0]; |
693 | if (getNoiseFloorThresh(ah, c->band, &nfThresh) | 194 | if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh) |
694 | && nf > nfThresh) { | 195 | && nf > nfThresh) { |
695 | ath_print(common, ATH_DBG_CALIBRATE, | 196 | ath_print(common, ATH_DBG_CALIBRATE, |
696 | "noise floor failed detected; " | 197 | "noise floor failed detected; " |
@@ -715,7 +216,7 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) | |||
715 | 216 | ||
716 | if (AR_SREV_9280(ah)) | 217 | if (AR_SREV_9280(ah)) |
717 | noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; | 218 | noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE; |
718 | else if (AR_SREV_9285(ah)) | 219 | else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) |
719 | noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; | 220 | noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE; |
720 | else if (AR_SREV_9287(ah)) | 221 | else if (AR_SREV_9287(ah)) |
721 | noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; | 222 | noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE; |
@@ -748,508 +249,3 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) | |||
748 | return nf; | 249 | return nf; |
749 | } | 250 | } |
750 | EXPORT_SYMBOL(ath9k_hw_getchan_noise); | 251 | EXPORT_SYMBOL(ath9k_hw_getchan_noise); |
751 | |||
752 | static void ath9k_olc_temp_compensation_9287(struct ath_hw *ah) | ||
753 | { | ||
754 | u32 rddata; | ||
755 | int32_t delta, currPDADC, slope; | ||
756 | |||
757 | rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); | ||
758 | currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); | ||
759 | |||
760 | if (ah->initPDADC == 0 || currPDADC == 0) { | ||
761 | /* | ||
762 | * Zero value indicates that no frames have been transmitted yet, | ||
763 | * can't do temperature compensation until frames are transmitted. | ||
764 | */ | ||
765 | return; | ||
766 | } else { | ||
767 | slope = ah->eep_ops->get_eeprom(ah, EEP_TEMPSENSE_SLOPE); | ||
768 | |||
769 | if (slope == 0) { /* to avoid divide by zero case */ | ||
770 | delta = 0; | ||
771 | } else { | ||
772 | delta = ((currPDADC - ah->initPDADC)*4) / slope; | ||
773 | } | ||
774 | REG_RMW_FIELD(ah, AR_PHY_CH0_TX_PWRCTRL11, | ||
775 | AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); | ||
776 | REG_RMW_FIELD(ah, AR_PHY_CH1_TX_PWRCTRL11, | ||
777 | AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP, delta); | ||
778 | } | ||
779 | } | ||
780 | |||
781 | static void ath9k_olc_temp_compensation(struct ath_hw *ah) | ||
782 | { | ||
783 | u32 rddata, i; | ||
784 | int delta, currPDADC, regval; | ||
785 | |||
786 | if (OLC_FOR_AR9287_10_LATER) { | ||
787 | ath9k_olc_temp_compensation_9287(ah); | ||
788 | } else { | ||
789 | rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); | ||
790 | currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); | ||
791 | |||
792 | if (ah->initPDADC == 0 || currPDADC == 0) { | ||
793 | return; | ||
794 | } else { | ||
795 | if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) | ||
796 | delta = (currPDADC - ah->initPDADC + 4) / 8; | ||
797 | else | ||
798 | delta = (currPDADC - ah->initPDADC + 5) / 10; | ||
799 | |||
800 | if (delta != ah->PDADCdelta) { | ||
801 | ah->PDADCdelta = delta; | ||
802 | for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { | ||
803 | regval = ah->originalGain[i] - delta; | ||
804 | if (regval < 0) | ||
805 | regval = 0; | ||
806 | |||
807 | REG_RMW_FIELD(ah, | ||
808 | AR_PHY_TX_GAIN_TBL1 + i * 4, | ||
809 | AR_PHY_TX_GAIN, regval); | ||
810 | } | ||
811 | } | ||
812 | } | ||
813 | } | ||
814 | } | ||
815 | |||
816 | static void ath9k_hw_9271_pa_cal(struct ath_hw *ah, bool is_reset) | ||
817 | { | ||
818 | u32 regVal; | ||
819 | unsigned int i; | ||
820 | u32 regList [][2] = { | ||
821 | { 0x786c, 0 }, | ||
822 | { 0x7854, 0 }, | ||
823 | { 0x7820, 0 }, | ||
824 | { 0x7824, 0 }, | ||
825 | { 0x7868, 0 }, | ||
826 | { 0x783c, 0 }, | ||
827 | { 0x7838, 0 } , | ||
828 | { 0x7828, 0 } , | ||
829 | }; | ||
830 | |||
831 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
832 | regList[i][1] = REG_READ(ah, regList[i][0]); | ||
833 | |||
834 | regVal = REG_READ(ah, 0x7834); | ||
835 | regVal &= (~(0x1)); | ||
836 | REG_WRITE(ah, 0x7834, regVal); | ||
837 | regVal = REG_READ(ah, 0x9808); | ||
838 | regVal |= (0x1 << 27); | ||
839 | REG_WRITE(ah, 0x9808, regVal); | ||
840 | |||
841 | /* 786c,b23,1, pwddac=1 */ | ||
842 | REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); | ||
843 | /* 7854, b5,1, pdrxtxbb=1 */ | ||
844 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); | ||
845 | /* 7854, b7,1, pdv2i=1 */ | ||
846 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); | ||
847 | /* 7854, b8,1, pddacinterface=1 */ | ||
848 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); | ||
849 | /* 7824,b12,0, offcal=0 */ | ||
850 | REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); | ||
851 | /* 7838, b1,0, pwddb=0 */ | ||
852 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); | ||
853 | /* 7820,b11,0, enpacal=0 */ | ||
854 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); | ||
855 | /* 7820,b25,1, pdpadrv1=0 */ | ||
856 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0); | ||
857 | /* 7820,b24,0, pdpadrv2=0 */ | ||
858 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0); | ||
859 | /* 7820,b23,0, pdpaout=0 */ | ||
860 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); | ||
861 | /* 783c,b14-16,7, padrvgn2tab_0=7 */ | ||
862 | REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7); | ||
863 | /* | ||
864 | * 7838,b29-31,0, padrvgn1tab_0=0 | ||
865 | * does not matter since we turn it off | ||
866 | */ | ||
867 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0); | ||
868 | |||
869 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff); | ||
870 | |||
871 | /* Set: | ||
872 | * localmode=1,bmode=1,bmoderxtx=1,synthon=1, | ||
873 | * txon=1,paon=1,oscon=1,synthon_force=1 | ||
874 | */ | ||
875 | REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); | ||
876 | udelay(30); | ||
877 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0); | ||
878 | |||
879 | /* find off_6_1; */ | ||
880 | for (i = 6; i > 0; i--) { | ||
881 | regVal = REG_READ(ah, 0x7834); | ||
882 | regVal |= (1 << (20 + i)); | ||
883 | REG_WRITE(ah, 0x7834, regVal); | ||
884 | udelay(1); | ||
885 | //regVal = REG_READ(ah, 0x7834); | ||
886 | regVal &= (~(0x1 << (20 + i))); | ||
887 | regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9) | ||
888 | << (20 + i)); | ||
889 | REG_WRITE(ah, 0x7834, regVal); | ||
890 | } | ||
891 | |||
892 | regVal = (regVal >>20) & 0x7f; | ||
893 | |||
894 | /* Update PA cal info */ | ||
895 | if ((!is_reset) && (ah->pacal_info.prev_offset == regVal)) { | ||
896 | if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT) | ||
897 | ah->pacal_info.max_skipcount = | ||
898 | 2 * ah->pacal_info.max_skipcount; | ||
899 | ah->pacal_info.skipcount = ah->pacal_info.max_skipcount; | ||
900 | } else { | ||
901 | ah->pacal_info.max_skipcount = 1; | ||
902 | ah->pacal_info.skipcount = 0; | ||
903 | ah->pacal_info.prev_offset = regVal; | ||
904 | } | ||
905 | |||
906 | regVal = REG_READ(ah, 0x7834); | ||
907 | regVal |= 0x1; | ||
908 | REG_WRITE(ah, 0x7834, regVal); | ||
909 | regVal = REG_READ(ah, 0x9808); | ||
910 | regVal &= (~(0x1 << 27)); | ||
911 | REG_WRITE(ah, 0x9808, regVal); | ||
912 | |||
913 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
914 | REG_WRITE(ah, regList[i][0], regList[i][1]); | ||
915 | } | ||
916 | |||
917 | static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset) | ||
918 | { | ||
919 | struct ath_common *common = ath9k_hw_common(ah); | ||
920 | u32 regVal; | ||
921 | int i, offset, offs_6_1, offs_0; | ||
922 | u32 ccomp_org, reg_field; | ||
923 | u32 regList[][2] = { | ||
924 | { 0x786c, 0 }, | ||
925 | { 0x7854, 0 }, | ||
926 | { 0x7820, 0 }, | ||
927 | { 0x7824, 0 }, | ||
928 | { 0x7868, 0 }, | ||
929 | { 0x783c, 0 }, | ||
930 | { 0x7838, 0 }, | ||
931 | }; | ||
932 | |||
933 | ath_print(common, ATH_DBG_CALIBRATE, "Running PA Calibration\n"); | ||
934 | |||
935 | /* PA CAL is not needed for high power solution */ | ||
936 | if (ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE) == | ||
937 | AR5416_EEP_TXGAIN_HIGH_POWER) | ||
938 | return; | ||
939 | |||
940 | if (AR_SREV_9285_11(ah)) { | ||
941 | REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); | ||
942 | udelay(10); | ||
943 | } | ||
944 | |||
945 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
946 | regList[i][1] = REG_READ(ah, regList[i][0]); | ||
947 | |||
948 | regVal = REG_READ(ah, 0x7834); | ||
949 | regVal &= (~(0x1)); | ||
950 | REG_WRITE(ah, 0x7834, regVal); | ||
951 | regVal = REG_READ(ah, 0x9808); | ||
952 | regVal |= (0x1 << 27); | ||
953 | REG_WRITE(ah, 0x9808, regVal); | ||
954 | |||
955 | REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); | ||
956 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); | ||
957 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); | ||
958 | REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); | ||
959 | REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); | ||
960 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); | ||
961 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); | ||
962 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0); | ||
963 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0); | ||
964 | REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); | ||
965 | REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); | ||
966 | REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); | ||
967 | ccomp_org = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_CCOMP); | ||
968 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, 0xf); | ||
969 | |||
970 | REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0); | ||
971 | udelay(30); | ||
972 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, 0); | ||
973 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 0); | ||
974 | |||
975 | for (i = 6; i > 0; i--) { | ||
976 | regVal = REG_READ(ah, 0x7834); | ||
977 | regVal |= (1 << (19 + i)); | ||
978 | REG_WRITE(ah, 0x7834, regVal); | ||
979 | udelay(1); | ||
980 | regVal = REG_READ(ah, 0x7834); | ||
981 | regVal &= (~(0x1 << (19 + i))); | ||
982 | reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9); | ||
983 | regVal |= (reg_field << (19 + i)); | ||
984 | REG_WRITE(ah, 0x7834, regVal); | ||
985 | } | ||
986 | |||
987 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, 1); | ||
988 | udelay(1); | ||
989 | reg_field = MS(REG_READ(ah, AR9285_AN_RF2G9), AR9285_AN_RXTXBB1_SPARE9); | ||
990 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, reg_field); | ||
991 | offs_6_1 = MS(REG_READ(ah, AR9285_AN_RF2G6), AR9285_AN_RF2G6_OFFS); | ||
992 | offs_0 = MS(REG_READ(ah, AR9285_AN_RF2G3), AR9285_AN_RF2G3_PDVCCOMP); | ||
993 | |||
994 | offset = (offs_6_1<<1) | offs_0; | ||
995 | offset = offset - 0; | ||
996 | offs_6_1 = offset>>1; | ||
997 | offs_0 = offset & 1; | ||
998 | |||
999 | if ((!is_reset) && (ah->pacal_info.prev_offset == offset)) { | ||
1000 | if (ah->pacal_info.max_skipcount < MAX_PACAL_SKIPCOUNT) | ||
1001 | ah->pacal_info.max_skipcount = | ||
1002 | 2 * ah->pacal_info.max_skipcount; | ||
1003 | ah->pacal_info.skipcount = ah->pacal_info.max_skipcount; | ||
1004 | } else { | ||
1005 | ah->pacal_info.max_skipcount = 1; | ||
1006 | ah->pacal_info.skipcount = 0; | ||
1007 | ah->pacal_info.prev_offset = offset; | ||
1008 | } | ||
1009 | |||
1010 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_OFFS, offs_6_1); | ||
1011 | REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9285_AN_RF2G3_PDVCCOMP, offs_0); | ||
1012 | |||
1013 | regVal = REG_READ(ah, 0x7834); | ||
1014 | regVal |= 0x1; | ||
1015 | REG_WRITE(ah, 0x7834, regVal); | ||
1016 | regVal = REG_READ(ah, 0x9808); | ||
1017 | regVal &= (~(0x1 << 27)); | ||
1018 | REG_WRITE(ah, 0x9808, regVal); | ||
1019 | |||
1020 | for (i = 0; i < ARRAY_SIZE(regList); i++) | ||
1021 | REG_WRITE(ah, regList[i][0], regList[i][1]); | ||
1022 | |||
1023 | REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9285_AN_RF2G6_CCOMP, ccomp_org); | ||
1024 | |||
1025 | if (AR_SREV_9285_11(ah)) | ||
1026 | REG_WRITE(ah, AR9285_AN_TOP4, AR9285_AN_TOP4_DEFAULT); | ||
1027 | |||
1028 | } | ||
1029 | |||
1030 | bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | ||
1031 | u8 rxchainmask, bool longcal) | ||
1032 | { | ||
1033 | bool iscaldone = true; | ||
1034 | struct ath9k_cal_list *currCal = ah->cal_list_curr; | ||
1035 | |||
1036 | if (currCal && | ||
1037 | (currCal->calState == CAL_RUNNING || | ||
1038 | currCal->calState == CAL_WAITING)) { | ||
1039 | iscaldone = ath9k_hw_per_calibration(ah, chan, | ||
1040 | rxchainmask, currCal); | ||
1041 | if (iscaldone) { | ||
1042 | ah->cal_list_curr = currCal = currCal->calNext; | ||
1043 | |||
1044 | if (currCal->calState == CAL_WAITING) { | ||
1045 | iscaldone = false; | ||
1046 | ath9k_hw_reset_calibration(ah, currCal); | ||
1047 | } | ||
1048 | } | ||
1049 | } | ||
1050 | |||
1051 | /* Do NF cal only at longer intervals */ | ||
1052 | if (longcal) { | ||
1053 | /* Do periodic PAOffset Cal */ | ||
1054 | if (AR_SREV_9271(ah)) | ||
1055 | ath9k_hw_9271_pa_cal(ah, false); | ||
1056 | else if (AR_SREV_9285_11_OR_LATER(ah)) { | ||
1057 | if (!ah->pacal_info.skipcount) | ||
1058 | ath9k_hw_9285_pa_cal(ah, false); | ||
1059 | else | ||
1060 | ah->pacal_info.skipcount--; | ||
1061 | } | ||
1062 | |||
1063 | if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER) | ||
1064 | ath9k_olc_temp_compensation(ah); | ||
1065 | |||
1066 | /* Get the value from the previous NF cal and update history buffer */ | ||
1067 | ath9k_hw_getnf(ah, chan); | ||
1068 | |||
1069 | /* | ||
1070 | * Load the NF from history buffer of the current channel. | ||
1071 | * NF is slow time-variant, so it is OK to use a historical value. | ||
1072 | */ | ||
1073 | ath9k_hw_loadnf(ah, ah->curchan); | ||
1074 | |||
1075 | ath9k_hw_start_nfcal(ah); | ||
1076 | } | ||
1077 | |||
1078 | return iscaldone; | ||
1079 | } | ||
1080 | EXPORT_SYMBOL(ath9k_hw_calibrate); | ||
1081 | |||
1082 | /* Carrier leakage Calibration fix */ | ||
1083 | static bool ar9285_clc(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1084 | { | ||
1085 | struct ath_common *common = ath9k_hw_common(ah); | ||
1086 | |||
1087 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
1088 | if (IS_CHAN_HT20(chan)) { | ||
1089 | REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); | ||
1090 | REG_SET_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); | ||
1091 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
1092 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
1093 | REG_CLR_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); | ||
1094 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | ||
1095 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, | ||
1096 | AR_PHY_AGC_CONTROL_CAL, 0, AH_WAIT_TIMEOUT)) { | ||
1097 | ath_print(common, ATH_DBG_CALIBRATE, "offset " | ||
1098 | "calibration failed to complete in " | ||
1099 | "1ms; noisy ??\n"); | ||
1100 | return false; | ||
1101 | } | ||
1102 | REG_CLR_BIT(ah, AR_PHY_TURBO, AR_PHY_FC_DYN2040_EN); | ||
1103 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_PARALLEL_CAL_ENABLE); | ||
1104 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
1105 | } | ||
1106 | REG_CLR_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
1107 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
1108 | REG_SET_BIT(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_CAL_ENABLE); | ||
1109 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL); | ||
1110 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | ||
1111 | 0, AH_WAIT_TIMEOUT)) { | ||
1112 | ath_print(common, ATH_DBG_CALIBRATE, "offset calibration " | ||
1113 | "failed to complete in 1ms; noisy ??\n"); | ||
1114 | return false; | ||
1115 | } | ||
1116 | |||
1117 | REG_SET_BIT(ah, AR_PHY_ADC_CTL, AR_PHY_ADC_CTL_OFF_PWDADC); | ||
1118 | REG_CLR_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); | ||
1119 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
1120 | |||
1121 | return true; | ||
1122 | } | ||
1123 | |||
1124 | bool ath9k_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1125 | { | ||
1126 | struct ath_common *common = ath9k_hw_common(ah); | ||
1127 | |||
1128 | if (AR_SREV_9271(ah) || AR_SREV_9285_12_OR_LATER(ah)) { | ||
1129 | if (!ar9285_clc(ah, chan)) | ||
1130 | return false; | ||
1131 | } else { | ||
1132 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1133 | if (!AR_SREV_9287_10_OR_LATER(ah)) | ||
1134 | REG_CLR_BIT(ah, AR_PHY_ADC_CTL, | ||
1135 | AR_PHY_ADC_CTL_OFF_PWDADC); | ||
1136 | REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, | ||
1137 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
1138 | } | ||
1139 | |||
1140 | /* Calibrate the AGC */ | ||
1141 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
1142 | REG_READ(ah, AR_PHY_AGC_CONTROL) | | ||
1143 | AR_PHY_AGC_CONTROL_CAL); | ||
1144 | |||
1145 | /* Poll for offset calibration complete */ | ||
1146 | if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, | ||
1147 | 0, AH_WAIT_TIMEOUT)) { | ||
1148 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1149 | "offset calibration failed to " | ||
1150 | "complete in 1ms; noisy environment?\n"); | ||
1151 | return false; | ||
1152 | } | ||
1153 | |||
1154 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1155 | if (!AR_SREV_9287_10_OR_LATER(ah)) | ||
1156 | REG_SET_BIT(ah, AR_PHY_ADC_CTL, | ||
1157 | AR_PHY_ADC_CTL_OFF_PWDADC); | ||
1158 | REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, | ||
1159 | AR_PHY_AGC_CONTROL_FLTR_CAL); | ||
1160 | } | ||
1161 | } | ||
1162 | |||
1163 | /* Do PA Calibration */ | ||
1164 | if (AR_SREV_9271(ah)) | ||
1165 | ath9k_hw_9271_pa_cal(ah, true); | ||
1166 | else if (AR_SREV_9285_11_OR_LATER(ah)) | ||
1167 | ath9k_hw_9285_pa_cal(ah, true); | ||
1168 | |||
1169 | /* Do NF Calibration after DC offset and other calibrations */ | ||
1170 | REG_WRITE(ah, AR_PHY_AGC_CONTROL, | ||
1171 | REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF); | ||
1172 | |||
1173 | ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; | ||
1174 | |||
1175 | /* Enable IQ, ADC Gain and ADC DC offset CALs */ | ||
1176 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { | ||
1177 | if (ath9k_hw_iscal_supported(ah, ADC_GAIN_CAL)) { | ||
1178 | INIT_CAL(&ah->adcgain_caldata); | ||
1179 | INSERT_CAL(ah, &ah->adcgain_caldata); | ||
1180 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1181 | "enabling ADC Gain Calibration.\n"); | ||
1182 | } | ||
1183 | if (ath9k_hw_iscal_supported(ah, ADC_DC_CAL)) { | ||
1184 | INIT_CAL(&ah->adcdc_caldata); | ||
1185 | INSERT_CAL(ah, &ah->adcdc_caldata); | ||
1186 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1187 | "enabling ADC DC Calibration.\n"); | ||
1188 | } | ||
1189 | if (ath9k_hw_iscal_supported(ah, IQ_MISMATCH_CAL)) { | ||
1190 | INIT_CAL(&ah->iq_caldata); | ||
1191 | INSERT_CAL(ah, &ah->iq_caldata); | ||
1192 | ath_print(common, ATH_DBG_CALIBRATE, | ||
1193 | "enabling IQ Calibration.\n"); | ||
1194 | } | ||
1195 | |||
1196 | ah->cal_list_curr = ah->cal_list; | ||
1197 | |||
1198 | if (ah->cal_list_curr) | ||
1199 | ath9k_hw_reset_calibration(ah, ah->cal_list_curr); | ||
1200 | } | ||
1201 | |||
1202 | chan->CalValid = 0; | ||
1203 | |||
1204 | return true; | ||
1205 | } | ||
1206 | |||
1207 | const struct ath9k_percal_data iq_cal_multi_sample = { | ||
1208 | IQ_MISMATCH_CAL, | ||
1209 | MAX_CAL_SAMPLES, | ||
1210 | PER_MIN_LOG_COUNT, | ||
1211 | ath9k_hw_iqcal_collect, | ||
1212 | ath9k_hw_iqcalibrate | ||
1213 | }; | ||
1214 | const struct ath9k_percal_data iq_cal_single_sample = { | ||
1215 | IQ_MISMATCH_CAL, | ||
1216 | MIN_CAL_SAMPLES, | ||
1217 | PER_MAX_LOG_COUNT, | ||
1218 | ath9k_hw_iqcal_collect, | ||
1219 | ath9k_hw_iqcalibrate | ||
1220 | }; | ||
1221 | const struct ath9k_percal_data adc_gain_cal_multi_sample = { | ||
1222 | ADC_GAIN_CAL, | ||
1223 | MAX_CAL_SAMPLES, | ||
1224 | PER_MIN_LOG_COUNT, | ||
1225 | ath9k_hw_adc_gaincal_collect, | ||
1226 | ath9k_hw_adc_gaincal_calibrate | ||
1227 | }; | ||
1228 | const struct ath9k_percal_data adc_gain_cal_single_sample = { | ||
1229 | ADC_GAIN_CAL, | ||
1230 | MIN_CAL_SAMPLES, | ||
1231 | PER_MAX_LOG_COUNT, | ||
1232 | ath9k_hw_adc_gaincal_collect, | ||
1233 | ath9k_hw_adc_gaincal_calibrate | ||
1234 | }; | ||
1235 | const struct ath9k_percal_data adc_dc_cal_multi_sample = { | ||
1236 | ADC_DC_CAL, | ||
1237 | MAX_CAL_SAMPLES, | ||
1238 | PER_MIN_LOG_COUNT, | ||
1239 | ath9k_hw_adc_dccal_collect, | ||
1240 | ath9k_hw_adc_dccal_calibrate | ||
1241 | }; | ||
1242 | const struct ath9k_percal_data adc_dc_cal_single_sample = { | ||
1243 | ADC_DC_CAL, | ||
1244 | MIN_CAL_SAMPLES, | ||
1245 | PER_MAX_LOG_COUNT, | ||
1246 | ath9k_hw_adc_dccal_collect, | ||
1247 | ath9k_hw_adc_dccal_calibrate | ||
1248 | }; | ||
1249 | const struct ath9k_percal_data adc_init_dc_cal = { | ||
1250 | ADC_DC_INIT_CAL, | ||
1251 | MIN_CAL_SAMPLES, | ||
1252 | INIT_LOG_COUNT, | ||
1253 | ath9k_hw_adc_dccal_collect, | ||
1254 | ath9k_hw_adc_dccal_calibrate | ||
1255 | }; | ||
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h index b2c873e97485..24538bdb9126 100644 --- a/drivers/net/wireless/ath/ath9k/calib.h +++ b/drivers/net/wireless/ath/ath9k/calib.h | |||
@@ -19,14 +19,6 @@ | |||
19 | 19 | ||
20 | #include "hw.h" | 20 | #include "hw.h" |
21 | 21 | ||
22 | extern const struct ath9k_percal_data iq_cal_multi_sample; | ||
23 | extern const struct ath9k_percal_data iq_cal_single_sample; | ||
24 | extern const struct ath9k_percal_data adc_gain_cal_multi_sample; | ||
25 | extern const struct ath9k_percal_data adc_gain_cal_single_sample; | ||
26 | extern const struct ath9k_percal_data adc_dc_cal_multi_sample; | ||
27 | extern const struct ath9k_percal_data adc_dc_cal_single_sample; | ||
28 | extern const struct ath9k_percal_data adc_init_dc_cal; | ||
29 | |||
30 | #define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85 | 22 | #define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85 |
31 | #define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112 | 23 | #define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112 |
32 | #define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118 | 24 | #define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118 |
@@ -76,7 +68,8 @@ enum ath9k_cal_types { | |||
76 | ADC_DC_INIT_CAL = 0x1, | 68 | ADC_DC_INIT_CAL = 0x1, |
77 | ADC_GAIN_CAL = 0x2, | 69 | ADC_GAIN_CAL = 0x2, |
78 | ADC_DC_CAL = 0x4, | 70 | ADC_DC_CAL = 0x4, |
79 | IQ_MISMATCH_CAL = 0x8 | 71 | IQ_MISMATCH_CAL = 0x8, |
72 | TEMP_COMP_CAL = 0x10, | ||
80 | }; | 73 | }; |
81 | 74 | ||
82 | enum ath9k_cal_state { | 75 | enum ath9k_cal_state { |
@@ -122,14 +115,12 @@ struct ath9k_pacal_info{ | |||
122 | 115 | ||
123 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah); | 116 | bool ath9k_hw_reset_calvalid(struct ath_hw *ah); |
124 | void ath9k_hw_start_nfcal(struct ath_hw *ah); | 117 | void ath9k_hw_start_nfcal(struct ath_hw *ah); |
125 | void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan); | ||
126 | int16_t ath9k_hw_getnf(struct ath_hw *ah, | 118 | int16_t ath9k_hw_getnf(struct ath_hw *ah, |
127 | struct ath9k_channel *chan); | 119 | struct ath9k_channel *chan); |
128 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); | 120 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah); |
129 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); | 121 | s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan); |
130 | bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, | 122 | void ath9k_hw_reset_calibration(struct ath_hw *ah, |
131 | u8 rxchainmask, bool longcal); | 123 | struct ath9k_cal_list *currCal); |
132 | bool ath9k_hw_init_cal(struct ath_hw *ah, | 124 | |
133 | struct ath9k_channel *chan); | ||
134 | 125 | ||
135 | #endif /* CALIB_H */ | 126 | #endif /* CALIB_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/common.c b/drivers/net/wireless/ath/ath9k/common.c index 4d775ae141db..7707341cd0d3 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,17 +215,22 @@ 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; |
215 | rx_status->noise = common->ani.noise_floor; | ||
216 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; | 234 | rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + rx_stats->rs_rssi; |
217 | rx_status->antenna = rx_stats->rs_antenna; | 235 | rx_status->antenna = rx_stats->rs_antenna; |
218 | rx_status->flag |= RX_FLAG_TSFT; | 236 | rx_status->flag |= RX_FLAG_TSFT; |
@@ -255,7 +273,8 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | |||
255 | 273 | ||
256 | keyix = rx_stats->rs_keyix; | 274 | keyix = rx_stats->rs_keyix; |
257 | 275 | ||
258 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error) { | 276 | if (!(keyix == ATH9K_RXKEYIX_INVALID) && !decrypt_error && |
277 | ieee80211_has_protected(fc)) { | ||
259 | rxs->flag |= RX_FLAG_DECRYPTED; | 278 | rxs->flag |= RX_FLAG_DECRYPTED; |
260 | } else if (ieee80211_has_protected(fc) | 279 | } else if (ieee80211_has_protected(fc) |
261 | && !decrypt_error && skb->len >= hdrlen + 4) { | 280 | && !decrypt_error && skb->len >= hdrlen + 4) { |
@@ -286,6 +305,345 @@ int ath9k_cmn_padpos(__le16 frame_control) | |||
286 | } | 305 | } |
287 | EXPORT_SYMBOL(ath9k_cmn_padpos); | 306 | EXPORT_SYMBOL(ath9k_cmn_padpos); |
288 | 307 | ||
308 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb) | ||
309 | { | ||
310 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
311 | |||
312 | if (tx_info->control.hw_key) { | ||
313 | if (tx_info->control.hw_key->alg == ALG_WEP) | ||
314 | return ATH9K_KEY_TYPE_WEP; | ||
315 | else if (tx_info->control.hw_key->alg == ALG_TKIP) | ||
316 | return ATH9K_KEY_TYPE_TKIP; | ||
317 | else if (tx_info->control.hw_key->alg == ALG_CCMP) | ||
318 | return ATH9K_KEY_TYPE_AES; | ||
319 | } | ||
320 | |||
321 | return ATH9K_KEY_TYPE_CLEAR; | ||
322 | } | ||
323 | EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_keytype); | ||
324 | |||
325 | static u32 ath9k_get_extchanmode(struct ieee80211_channel *chan, | ||
326 | enum nl80211_channel_type channel_type) | ||
327 | { | ||
328 | u32 chanmode = 0; | ||
329 | |||
330 | switch (chan->band) { | ||
331 | case IEEE80211_BAND_2GHZ: | ||
332 | switch (channel_type) { | ||
333 | case NL80211_CHAN_NO_HT: | ||
334 | case NL80211_CHAN_HT20: | ||
335 | chanmode = CHANNEL_G_HT20; | ||
336 | break; | ||
337 | case NL80211_CHAN_HT40PLUS: | ||
338 | chanmode = CHANNEL_G_HT40PLUS; | ||
339 | break; | ||
340 | case NL80211_CHAN_HT40MINUS: | ||
341 | chanmode = CHANNEL_G_HT40MINUS; | ||
342 | break; | ||
343 | } | ||
344 | break; | ||
345 | case IEEE80211_BAND_5GHZ: | ||
346 | switch (channel_type) { | ||
347 | case NL80211_CHAN_NO_HT: | ||
348 | case NL80211_CHAN_HT20: | ||
349 | chanmode = CHANNEL_A_HT20; | ||
350 | break; | ||
351 | case NL80211_CHAN_HT40PLUS: | ||
352 | chanmode = CHANNEL_A_HT40PLUS; | ||
353 | break; | ||
354 | case NL80211_CHAN_HT40MINUS: | ||
355 | chanmode = CHANNEL_A_HT40MINUS; | ||
356 | break; | ||
357 | } | ||
358 | break; | ||
359 | default: | ||
360 | break; | ||
361 | } | ||
362 | |||
363 | return chanmode; | ||
364 | } | ||
365 | |||
366 | /* | ||
367 | * Update internal channel flags. | ||
368 | */ | ||
369 | void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, | ||
370 | struct ath9k_channel *ichan) | ||
371 | { | ||
372 | struct ieee80211_channel *chan = hw->conf.channel; | ||
373 | struct ieee80211_conf *conf = &hw->conf; | ||
374 | |||
375 | ichan->channel = chan->center_freq; | ||
376 | ichan->chan = chan; | ||
377 | |||
378 | if (chan->band == IEEE80211_BAND_2GHZ) { | ||
379 | ichan->chanmode = CHANNEL_G; | ||
380 | ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM | CHANNEL_G; | ||
381 | } else { | ||
382 | ichan->chanmode = CHANNEL_A; | ||
383 | ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM; | ||
384 | } | ||
385 | |||
386 | if (conf_is_ht(conf)) | ||
387 | ichan->chanmode = ath9k_get_extchanmode(chan, | ||
388 | conf->channel_type); | ||
389 | } | ||
390 | EXPORT_SYMBOL(ath9k_cmn_update_ichannel); | ||
391 | |||
392 | /* | ||
393 | * Get the internal channel reference. | ||
394 | */ | ||
395 | struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, | ||
396 | struct ath_hw *ah) | ||
397 | { | ||
398 | struct ieee80211_channel *curchan = hw->conf.channel; | ||
399 | struct ath9k_channel *channel; | ||
400 | u8 chan_idx; | ||
401 | |||
402 | chan_idx = curchan->hw_value; | ||
403 | channel = &ah->channels[chan_idx]; | ||
404 | ath9k_cmn_update_ichannel(hw, channel); | ||
405 | |||
406 | return channel; | ||
407 | } | ||
408 | EXPORT_SYMBOL(ath9k_cmn_get_curchannel); | ||
409 | |||
410 | static int ath_setkey_tkip(struct ath_common *common, u16 keyix, const u8 *key, | ||
411 | struct ath9k_keyval *hk, const u8 *addr, | ||
412 | bool authenticator) | ||
413 | { | ||
414 | struct ath_hw *ah = common->ah; | ||
415 | const u8 *key_rxmic; | ||
416 | const u8 *key_txmic; | ||
417 | |||
418 | key_txmic = key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY; | ||
419 | key_rxmic = key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY; | ||
420 | |||
421 | if (addr == NULL) { | ||
422 | /* | ||
423 | * Group key installation - only two key cache entries are used | ||
424 | * regardless of splitmic capability since group key is only | ||
425 | * used either for TX or RX. | ||
426 | */ | ||
427 | if (authenticator) { | ||
428 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
429 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_mic)); | ||
430 | } else { | ||
431 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
432 | memcpy(hk->kv_txmic, key_rxmic, sizeof(hk->kv_mic)); | ||
433 | } | ||
434 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); | ||
435 | } | ||
436 | if (!common->splitmic) { | ||
437 | /* TX and RX keys share the same key cache entry. */ | ||
438 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
439 | memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic)); | ||
440 | return ath9k_hw_set_keycache_entry(ah, keyix, hk, addr); | ||
441 | } | ||
442 | |||
443 | /* Separate key cache entries for TX and RX */ | ||
444 | |||
445 | /* TX key goes at first index, RX key at +32. */ | ||
446 | memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic)); | ||
447 | if (!ath9k_hw_set_keycache_entry(ah, keyix, hk, NULL)) { | ||
448 | /* TX MIC entry failed. No need to proceed further */ | ||
449 | ath_print(common, ATH_DBG_FATAL, | ||
450 | "Setting TX MIC Key Failed\n"); | ||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic)); | ||
455 | /* XXX delete tx key on failure? */ | ||
456 | return ath9k_hw_set_keycache_entry(ah, keyix + 32, hk, addr); | ||
457 | } | ||
458 | |||
459 | static int ath_reserve_key_cache_slot_tkip(struct ath_common *common) | ||
460 | { | ||
461 | int i; | ||
462 | |||
463 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { | ||
464 | if (test_bit(i, common->keymap) || | ||
465 | test_bit(i + 64, common->keymap)) | ||
466 | continue; /* At least one part of TKIP key allocated */ | ||
467 | if (common->splitmic && | ||
468 | (test_bit(i + 32, common->keymap) || | ||
469 | test_bit(i + 64 + 32, common->keymap))) | ||
470 | continue; /* At least one part of TKIP key allocated */ | ||
471 | |||
472 | /* Found a free slot for a TKIP key */ | ||
473 | return i; | ||
474 | } | ||
475 | return -1; | ||
476 | } | ||
477 | |||
478 | static int ath_reserve_key_cache_slot(struct ath_common *common) | ||
479 | { | ||
480 | int i; | ||
481 | |||
482 | /* First, try to find slots that would not be available for TKIP. */ | ||
483 | if (common->splitmic) { | ||
484 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 4; i++) { | ||
485 | if (!test_bit(i, common->keymap) && | ||
486 | (test_bit(i + 32, common->keymap) || | ||
487 | test_bit(i + 64, common->keymap) || | ||
488 | test_bit(i + 64 + 32, common->keymap))) | ||
489 | return i; | ||
490 | if (!test_bit(i + 32, common->keymap) && | ||
491 | (test_bit(i, common->keymap) || | ||
492 | test_bit(i + 64, common->keymap) || | ||
493 | test_bit(i + 64 + 32, common->keymap))) | ||
494 | return i + 32; | ||
495 | if (!test_bit(i + 64, common->keymap) && | ||
496 | (test_bit(i , common->keymap) || | ||
497 | test_bit(i + 32, common->keymap) || | ||
498 | test_bit(i + 64 + 32, common->keymap))) | ||
499 | return i + 64; | ||
500 | if (!test_bit(i + 64 + 32, common->keymap) && | ||
501 | (test_bit(i, common->keymap) || | ||
502 | test_bit(i + 32, common->keymap) || | ||
503 | test_bit(i + 64, common->keymap))) | ||
504 | return i + 64 + 32; | ||
505 | } | ||
506 | } else { | ||
507 | for (i = IEEE80211_WEP_NKID; i < common->keymax / 2; i++) { | ||
508 | if (!test_bit(i, common->keymap) && | ||
509 | test_bit(i + 64, common->keymap)) | ||
510 | return i; | ||
511 | if (test_bit(i, common->keymap) && | ||
512 | !test_bit(i + 64, common->keymap)) | ||
513 | return i + 64; | ||
514 | } | ||
515 | } | ||
516 | |||
517 | /* No partially used TKIP slots, pick any available slot */ | ||
518 | for (i = IEEE80211_WEP_NKID; i < common->keymax; i++) { | ||
519 | /* Do not allow slots that could be needed for TKIP group keys | ||
520 | * to be used. This limitation could be removed if we know that | ||
521 | * TKIP will not be used. */ | ||
522 | if (i >= 64 && i < 64 + IEEE80211_WEP_NKID) | ||
523 | continue; | ||
524 | if (common->splitmic) { | ||
525 | if (i >= 32 && i < 32 + IEEE80211_WEP_NKID) | ||
526 | continue; | ||
527 | if (i >= 64 + 32 && i < 64 + 32 + IEEE80211_WEP_NKID) | ||
528 | continue; | ||
529 | } | ||
530 | |||
531 | if (!test_bit(i, common->keymap)) | ||
532 | return i; /* Found a free slot for a key */ | ||
533 | } | ||
534 | |||
535 | /* No free slot found */ | ||
536 | return -1; | ||
537 | } | ||
538 | |||
539 | /* | ||
540 | * Configure encryption in the HW. | ||
541 | */ | ||
542 | int ath9k_cmn_key_config(struct ath_common *common, | ||
543 | struct ieee80211_vif *vif, | ||
544 | struct ieee80211_sta *sta, | ||
545 | struct ieee80211_key_conf *key) | ||
546 | { | ||
547 | struct ath_hw *ah = common->ah; | ||
548 | struct ath9k_keyval hk; | ||
549 | const u8 *mac = NULL; | ||
550 | int ret = 0; | ||
551 | int idx; | ||
552 | |||
553 | memset(&hk, 0, sizeof(hk)); | ||
554 | |||
555 | switch (key->alg) { | ||
556 | case ALG_WEP: | ||
557 | hk.kv_type = ATH9K_CIPHER_WEP; | ||
558 | break; | ||
559 | case ALG_TKIP: | ||
560 | hk.kv_type = ATH9K_CIPHER_TKIP; | ||
561 | break; | ||
562 | case ALG_CCMP: | ||
563 | hk.kv_type = ATH9K_CIPHER_AES_CCM; | ||
564 | break; | ||
565 | default: | ||
566 | return -EOPNOTSUPP; | ||
567 | } | ||
568 | |||
569 | hk.kv_len = key->keylen; | ||
570 | memcpy(hk.kv_val, key->key, key->keylen); | ||
571 | |||
572 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | ||
573 | /* For now, use the default keys for broadcast keys. This may | ||
574 | * need to change with virtual interfaces. */ | ||
575 | idx = key->keyidx; | ||
576 | } else if (key->keyidx) { | ||
577 | if (WARN_ON(!sta)) | ||
578 | return -EOPNOTSUPP; | ||
579 | mac = sta->addr; | ||
580 | |||
581 | if (vif->type != NL80211_IFTYPE_AP) { | ||
582 | /* Only keyidx 0 should be used with unicast key, but | ||
583 | * allow this for client mode for now. */ | ||
584 | idx = key->keyidx; | ||
585 | } else | ||
586 | return -EIO; | ||
587 | } else { | ||
588 | if (WARN_ON(!sta)) | ||
589 | return -EOPNOTSUPP; | ||
590 | mac = sta->addr; | ||
591 | |||
592 | if (key->alg == ALG_TKIP) | ||
593 | idx = ath_reserve_key_cache_slot_tkip(common); | ||
594 | else | ||
595 | idx = ath_reserve_key_cache_slot(common); | ||
596 | if (idx < 0) | ||
597 | return -ENOSPC; /* no free key cache entries */ | ||
598 | } | ||
599 | |||
600 | if (key->alg == ALG_TKIP) | ||
601 | ret = ath_setkey_tkip(common, idx, key->key, &hk, mac, | ||
602 | vif->type == NL80211_IFTYPE_AP); | ||
603 | else | ||
604 | ret = ath9k_hw_set_keycache_entry(ah, idx, &hk, mac); | ||
605 | |||
606 | if (!ret) | ||
607 | return -EIO; | ||
608 | |||
609 | set_bit(idx, common->keymap); | ||
610 | if (key->alg == ALG_TKIP) { | ||
611 | set_bit(idx + 64, common->keymap); | ||
612 | if (common->splitmic) { | ||
613 | set_bit(idx + 32, common->keymap); | ||
614 | set_bit(idx + 64 + 32, common->keymap); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | return idx; | ||
619 | } | ||
620 | EXPORT_SYMBOL(ath9k_cmn_key_config); | ||
621 | |||
622 | /* | ||
623 | * Delete Key. | ||
624 | */ | ||
625 | void ath9k_cmn_key_delete(struct ath_common *common, | ||
626 | struct ieee80211_key_conf *key) | ||
627 | { | ||
628 | struct ath_hw *ah = common->ah; | ||
629 | |||
630 | ath9k_hw_keyreset(ah, key->hw_key_idx); | ||
631 | if (key->hw_key_idx < IEEE80211_WEP_NKID) | ||
632 | return; | ||
633 | |||
634 | clear_bit(key->hw_key_idx, common->keymap); | ||
635 | if (key->alg != ALG_TKIP) | ||
636 | return; | ||
637 | |||
638 | clear_bit(key->hw_key_idx + 64, common->keymap); | ||
639 | if (common->splitmic) { | ||
640 | ath9k_hw_keyreset(ah, key->hw_key_idx + 32); | ||
641 | clear_bit(key->hw_key_idx + 32, common->keymap); | ||
642 | clear_bit(key->hw_key_idx + 64 + 32, common->keymap); | ||
643 | } | ||
644 | } | ||
645 | EXPORT_SYMBOL(ath9k_cmn_key_delete); | ||
646 | |||
289 | static int __init ath9k_cmn_init(void) | 647 | static int __init ath9k_cmn_init(void) |
290 | { | 648 | { |
291 | return 0; | 649 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h index 042999c2fe9c..e08f7e5a26e0 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h | |||
@@ -20,9 +20,12 @@ | |||
20 | #include "../debug.h" | 20 | #include "../debug.h" |
21 | 21 | ||
22 | #include "hw.h" | 22 | #include "hw.h" |
23 | #include "hw-ops.h" | ||
23 | 24 | ||
24 | /* Common header for Atheros 802.11n base driver cores */ | 25 | /* Common header for Atheros 802.11n base driver cores */ |
25 | 26 | ||
27 | #define IEEE80211_WEP_NKID 4 | ||
28 | |||
26 | #define WME_NUM_TID 16 | 29 | #define WME_NUM_TID 16 |
27 | #define WME_BA_BMP_SIZE 64 | 30 | #define WME_BA_BMP_SIZE 64 |
28 | #define WME_MAX_BA WME_BA_BMP_SIZE | 31 | #define WME_MAX_BA WME_BA_BMP_SIZE |
@@ -74,11 +77,12 @@ struct ath_buf { | |||
74 | an aggregate) */ | 77 | an aggregate) */ |
75 | struct ath_buf *bf_next; /* next subframe in the aggregate */ | 78 | struct ath_buf *bf_next; /* next subframe in the aggregate */ |
76 | struct sk_buff *bf_mpdu; /* enclosing frame structure */ | 79 | struct sk_buff *bf_mpdu; /* enclosing frame structure */ |
77 | struct ath_desc *bf_desc; /* virtual addr of desc */ | 80 | void *bf_desc; /* virtual addr of desc */ |
78 | dma_addr_t bf_daddr; /* physical addr of desc */ | 81 | dma_addr_t bf_daddr; /* physical addr of desc */ |
79 | dma_addr_t bf_buf_addr; /* physical addr of data buffer */ | 82 | dma_addr_t bf_buf_addr; /* physical addr of data buffer */ |
80 | bool bf_stale; | 83 | bool bf_stale; |
81 | bool bf_isnullfunc; | 84 | bool bf_isnullfunc; |
85 | bool bf_tx_aborted; | ||
82 | u16 bf_flags; | 86 | u16 bf_flags; |
83 | struct ath_buf_state bf_state; | 87 | struct ath_buf_state bf_state; |
84 | dma_addr_t bf_dmacontext; | 88 | dma_addr_t bf_dmacontext; |
@@ -125,3 +129,14 @@ void ath9k_cmn_rx_skb_postprocess(struct ath_common *common, | |||
125 | bool decrypt_error); | 129 | bool decrypt_error); |
126 | 130 | ||
127 | int ath9k_cmn_padpos(__le16 frame_control); | 131 | int ath9k_cmn_padpos(__le16 frame_control); |
132 | int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb); | ||
133 | void ath9k_cmn_update_ichannel(struct ieee80211_hw *hw, | ||
134 | struct ath9k_channel *ichan); | ||
135 | struct ath9k_channel *ath9k_cmn_get_curchannel(struct ieee80211_hw *hw, | ||
136 | struct ath_hw *ah); | ||
137 | int ath9k_cmn_key_config(struct ath_common *common, | ||
138 | struct ieee80211_vif *vif, | ||
139 | struct ieee80211_sta *sta, | ||
140 | struct ieee80211_key_conf *key); | ||
141 | void ath9k_cmn_key_delete(struct ath_common *common, | ||
142 | struct ieee80211_key_conf *key); | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 081e0085ed4c..29898f8d1893 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c | |||
@@ -78,6 +78,90 @@ static const struct file_operations fops_debug = { | |||
78 | 78 | ||
79 | #define DMA_BUF_LEN 1024 | 79 | #define DMA_BUF_LEN 1024 |
80 | 80 | ||
81 | static ssize_t read_file_tx_chainmask(struct file *file, char __user *user_buf, | ||
82 | size_t count, loff_t *ppos) | ||
83 | { | ||
84 | struct ath_softc *sc = file->private_data; | ||
85 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
86 | char buf[32]; | ||
87 | unsigned int len; | ||
88 | |||
89 | len = snprintf(buf, sizeof(buf), "0x%08x\n", common->tx_chainmask); | ||
90 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
91 | } | ||
92 | |||
93 | static ssize_t write_file_tx_chainmask(struct file *file, const char __user *user_buf, | ||
94 | size_t count, loff_t *ppos) | ||
95 | { | ||
96 | struct ath_softc *sc = file->private_data; | ||
97 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
98 | unsigned long mask; | ||
99 | char buf[32]; | ||
100 | ssize_t len; | ||
101 | |||
102 | len = min(count, sizeof(buf) - 1); | ||
103 | if (copy_from_user(buf, user_buf, len)) | ||
104 | return -EINVAL; | ||
105 | |||
106 | buf[len] = '\0'; | ||
107 | if (strict_strtoul(buf, 0, &mask)) | ||
108 | return -EINVAL; | ||
109 | |||
110 | common->tx_chainmask = mask; | ||
111 | sc->sc_ah->caps.tx_chainmask = mask; | ||
112 | return count; | ||
113 | } | ||
114 | |||
115 | static const struct file_operations fops_tx_chainmask = { | ||
116 | .read = read_file_tx_chainmask, | ||
117 | .write = write_file_tx_chainmask, | ||
118 | .open = ath9k_debugfs_open, | ||
119 | .owner = THIS_MODULE | ||
120 | }; | ||
121 | |||
122 | |||
123 | static ssize_t read_file_rx_chainmask(struct file *file, char __user *user_buf, | ||
124 | size_t count, loff_t *ppos) | ||
125 | { | ||
126 | struct ath_softc *sc = file->private_data; | ||
127 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
128 | char buf[32]; | ||
129 | unsigned int len; | ||
130 | |||
131 | len = snprintf(buf, sizeof(buf), "0x%08x\n", common->rx_chainmask); | ||
132 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
133 | } | ||
134 | |||
135 | static ssize_t write_file_rx_chainmask(struct file *file, const char __user *user_buf, | ||
136 | size_t count, loff_t *ppos) | ||
137 | { | ||
138 | struct ath_softc *sc = file->private_data; | ||
139 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
140 | unsigned long mask; | ||
141 | char buf[32]; | ||
142 | ssize_t len; | ||
143 | |||
144 | len = min(count, sizeof(buf) - 1); | ||
145 | if (copy_from_user(buf, user_buf, len)) | ||
146 | return -EINVAL; | ||
147 | |||
148 | buf[len] = '\0'; | ||
149 | if (strict_strtoul(buf, 0, &mask)) | ||
150 | return -EINVAL; | ||
151 | |||
152 | common->rx_chainmask = mask; | ||
153 | sc->sc_ah->caps.rx_chainmask = mask; | ||
154 | return count; | ||
155 | } | ||
156 | |||
157 | static const struct file_operations fops_rx_chainmask = { | ||
158 | .read = read_file_rx_chainmask, | ||
159 | .write = write_file_rx_chainmask, | ||
160 | .open = ath9k_debugfs_open, | ||
161 | .owner = THIS_MODULE | ||
162 | }; | ||
163 | |||
164 | |||
81 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, | 165 | static ssize_t read_file_dma(struct file *file, char __user *user_buf, |
82 | size_t count, loff_t *ppos) | 166 | size_t count, loff_t *ppos) |
83 | { | 167 | { |
@@ -157,10 +241,10 @@ static ssize_t read_file_dma(struct file *file, char __user *user_buf, | |||
157 | "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", | 241 | "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n", |
158 | (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); | 242 | (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17); |
159 | 243 | ||
160 | len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x \n", | 244 | len += snprintf(buf + len, DMA_BUF_LEN - len, "pcu observe: 0x%x\n", |
161 | REG_READ_D(ah, AR_OBS_BUS_1)); | 245 | REG_READ_D(ah, AR_OBS_BUS_1)); |
162 | len += snprintf(buf + len, DMA_BUF_LEN - len, | 246 | len += snprintf(buf + len, DMA_BUF_LEN - len, |
163 | "AR_CR: 0x%x \n", REG_READ_D(ah, AR_CR)); | 247 | "AR_CR: 0x%x\n", REG_READ_D(ah, AR_CR)); |
164 | 248 | ||
165 | ath9k_ps_restore(sc); | 249 | ath9k_ps_restore(sc); |
166 | 250 | ||
@@ -180,8 +264,15 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) | |||
180 | { | 264 | { |
181 | if (status) | 265 | if (status) |
182 | sc->debug.stats.istats.total++; | 266 | sc->debug.stats.istats.total++; |
183 | if (status & ATH9K_INT_RX) | 267 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
184 | sc->debug.stats.istats.rxok++; | 268 | if (status & ATH9K_INT_RXLP) |
269 | sc->debug.stats.istats.rxlp++; | ||
270 | if (status & ATH9K_INT_RXHP) | ||
271 | sc->debug.stats.istats.rxhp++; | ||
272 | } else { | ||
273 | if (status & ATH9K_INT_RX) | ||
274 | sc->debug.stats.istats.rxok++; | ||
275 | } | ||
185 | if (status & ATH9K_INT_RXEOL) | 276 | if (status & ATH9K_INT_RXEOL) |
186 | sc->debug.stats.istats.rxeol++; | 277 | sc->debug.stats.istats.rxeol++; |
187 | if (status & ATH9K_INT_RXORN) | 278 | if (status & ATH9K_INT_RXORN) |
@@ -223,8 +314,15 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, | |||
223 | char buf[512]; | 314 | char buf[512]; |
224 | unsigned int len = 0; | 315 | unsigned int len = 0; |
225 | 316 | ||
226 | len += snprintf(buf + len, sizeof(buf) - len, | 317 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
227 | "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); | 318 | len += snprintf(buf + len, sizeof(buf) - len, |
319 | "%8s: %10u\n", "RXLP", sc->debug.stats.istats.rxlp); | ||
320 | len += snprintf(buf + len, sizeof(buf) - len, | ||
321 | "%8s: %10u\n", "RXHP", sc->debug.stats.istats.rxhp); | ||
322 | } else { | ||
323 | len += snprintf(buf + len, sizeof(buf) - len, | ||
324 | "%8s: %10u\n", "RX", sc->debug.stats.istats.rxok); | ||
325 | } | ||
228 | len += snprintf(buf + len, sizeof(buf) - len, | 326 | len += snprintf(buf + len, sizeof(buf) - len, |
229 | "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); | 327 | "%8s: %10u\n", "RXEOL", sc->debug.stats.istats.rxeol); |
230 | len += snprintf(buf + len, sizeof(buf) - len, | 328 | len += snprintf(buf + len, sizeof(buf) - len, |
@@ -557,10 +655,8 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | |||
557 | } | 655 | } |
558 | 656 | ||
559 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | 657 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, |
560 | struct ath_buf *bf) | 658 | struct ath_buf *bf, struct ath_tx_status *ts) |
561 | { | 659 | { |
562 | struct ath_desc *ds = bf->bf_desc; | ||
563 | |||
564 | if (bf_isampdu(bf)) { | 660 | if (bf_isampdu(bf)) { |
565 | if (bf_isxretried(bf)) | 661 | if (bf_isxretried(bf)) |
566 | TX_STAT_INC(txq->axq_qnum, a_xretries); | 662 | TX_STAT_INC(txq->axq_qnum, a_xretries); |
@@ -570,17 +666,17 @@ void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | |||
570 | TX_STAT_INC(txq->axq_qnum, completed); | 666 | TX_STAT_INC(txq->axq_qnum, completed); |
571 | } | 667 | } |
572 | 668 | ||
573 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO) | 669 | if (ts->ts_status & ATH9K_TXERR_FIFO) |
574 | TX_STAT_INC(txq->axq_qnum, fifo_underrun); | 670 | TX_STAT_INC(txq->axq_qnum, fifo_underrun); |
575 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_XTXOP) | 671 | if (ts->ts_status & ATH9K_TXERR_XTXOP) |
576 | TX_STAT_INC(txq->axq_qnum, xtxop); | 672 | TX_STAT_INC(txq->axq_qnum, xtxop); |
577 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_TIMER_EXPIRED) | 673 | if (ts->ts_status & ATH9K_TXERR_TIMER_EXPIRED) |
578 | TX_STAT_INC(txq->axq_qnum, timer_exp); | 674 | TX_STAT_INC(txq->axq_qnum, timer_exp); |
579 | if (ds->ds_txstat.ts_flags & ATH9K_TX_DESC_CFG_ERR) | 675 | if (ts->ts_flags & ATH9K_TX_DESC_CFG_ERR) |
580 | TX_STAT_INC(txq->axq_qnum, desc_cfg_err); | 676 | TX_STAT_INC(txq->axq_qnum, desc_cfg_err); |
581 | if (ds->ds_txstat.ts_flags & ATH9K_TX_DATA_UNDERRUN) | 677 | if (ts->ts_flags & ATH9K_TX_DATA_UNDERRUN) |
582 | TX_STAT_INC(txq->axq_qnum, data_underrun); | 678 | TX_STAT_INC(txq->axq_qnum, data_underrun); |
583 | if (ds->ds_txstat.ts_flags & ATH9K_TX_DELIM_UNDERRUN) | 679 | if (ts->ts_flags & ATH9K_TX_DELIM_UNDERRUN) |
584 | TX_STAT_INC(txq->axq_qnum, delim_underrun); | 680 | TX_STAT_INC(txq->axq_qnum, delim_underrun); |
585 | } | 681 | } |
586 | 682 | ||
@@ -663,30 +759,29 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf, | |||
663 | #undef PHY_ERR | 759 | #undef PHY_ERR |
664 | } | 760 | } |
665 | 761 | ||
666 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf) | 762 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) |
667 | { | 763 | { |
668 | #define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ | 764 | #define RX_STAT_INC(c) sc->debug.stats.rxstats.c++ |
669 | #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ | 765 | #define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ |
670 | 766 | ||
671 | struct ath_desc *ds = bf->bf_desc; | ||
672 | u32 phyerr; | 767 | u32 phyerr; |
673 | 768 | ||
674 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC) | 769 | if (rs->rs_status & ATH9K_RXERR_CRC) |
675 | RX_STAT_INC(crc_err); | 770 | RX_STAT_INC(crc_err); |
676 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) | 771 | if (rs->rs_status & ATH9K_RXERR_DECRYPT) |
677 | RX_STAT_INC(decrypt_crc_err); | 772 | RX_STAT_INC(decrypt_crc_err); |
678 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) | 773 | if (rs->rs_status & ATH9K_RXERR_MIC) |
679 | RX_STAT_INC(mic_err); | 774 | RX_STAT_INC(mic_err); |
680 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE) | 775 | if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE) |
681 | RX_STAT_INC(pre_delim_crc_err); | 776 | RX_STAT_INC(pre_delim_crc_err); |
682 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST) | 777 | if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST) |
683 | RX_STAT_INC(post_delim_crc_err); | 778 | RX_STAT_INC(post_delim_crc_err); |
684 | if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY) | 779 | if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY) |
685 | RX_STAT_INC(decrypt_busy_err); | 780 | RX_STAT_INC(decrypt_busy_err); |
686 | 781 | ||
687 | if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) { | 782 | if (rs->rs_status & ATH9K_RXERR_PHY) { |
688 | RX_STAT_INC(phy_err); | 783 | RX_STAT_INC(phy_err); |
689 | phyerr = ds->ds_rxstat.rs_phyerr & 0x24; | 784 | phyerr = rs->rs_phyerr & 0x24; |
690 | RX_PHY_ERR_INC(phyerr); | 785 | RX_PHY_ERR_INC(phyerr); |
691 | } | 786 | } |
692 | 787 | ||
@@ -700,6 +795,86 @@ static const struct file_operations fops_recv = { | |||
700 | .owner = THIS_MODULE | 795 | .owner = THIS_MODULE |
701 | }; | 796 | }; |
702 | 797 | ||
798 | static ssize_t read_file_regidx(struct file *file, char __user *user_buf, | ||
799 | size_t count, loff_t *ppos) | ||
800 | { | ||
801 | struct ath_softc *sc = file->private_data; | ||
802 | char buf[32]; | ||
803 | unsigned int len; | ||
804 | |||
805 | len = snprintf(buf, sizeof(buf), "0x%08x\n", sc->debug.regidx); | ||
806 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
807 | } | ||
808 | |||
809 | static ssize_t write_file_regidx(struct file *file, const char __user *user_buf, | ||
810 | size_t count, loff_t *ppos) | ||
811 | { | ||
812 | struct ath_softc *sc = file->private_data; | ||
813 | unsigned long regidx; | ||
814 | char buf[32]; | ||
815 | ssize_t len; | ||
816 | |||
817 | len = min(count, sizeof(buf) - 1); | ||
818 | if (copy_from_user(buf, user_buf, len)) | ||
819 | return -EINVAL; | ||
820 | |||
821 | buf[len] = '\0'; | ||
822 | if (strict_strtoul(buf, 0, ®idx)) | ||
823 | return -EINVAL; | ||
824 | |||
825 | sc->debug.regidx = regidx; | ||
826 | return count; | ||
827 | } | ||
828 | |||
829 | static const struct file_operations fops_regidx = { | ||
830 | .read = read_file_regidx, | ||
831 | .write = write_file_regidx, | ||
832 | .open = ath9k_debugfs_open, | ||
833 | .owner = THIS_MODULE | ||
834 | }; | ||
835 | |||
836 | static ssize_t read_file_regval(struct file *file, char __user *user_buf, | ||
837 | size_t count, loff_t *ppos) | ||
838 | { | ||
839 | struct ath_softc *sc = file->private_data; | ||
840 | struct ath_hw *ah = sc->sc_ah; | ||
841 | char buf[32]; | ||
842 | unsigned int len; | ||
843 | u32 regval; | ||
844 | |||
845 | regval = REG_READ_D(ah, sc->debug.regidx); | ||
846 | len = snprintf(buf, sizeof(buf), "0x%08x\n", regval); | ||
847 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
848 | } | ||
849 | |||
850 | static ssize_t write_file_regval(struct file *file, const char __user *user_buf, | ||
851 | size_t count, loff_t *ppos) | ||
852 | { | ||
853 | struct ath_softc *sc = file->private_data; | ||
854 | struct ath_hw *ah = sc->sc_ah; | ||
855 | unsigned long regval; | ||
856 | char buf[32]; | ||
857 | ssize_t len; | ||
858 | |||
859 | len = min(count, sizeof(buf) - 1); | ||
860 | if (copy_from_user(buf, user_buf, len)) | ||
861 | return -EINVAL; | ||
862 | |||
863 | buf[len] = '\0'; | ||
864 | if (strict_strtoul(buf, 0, ®val)) | ||
865 | return -EINVAL; | ||
866 | |||
867 | REG_WRITE_D(ah, sc->debug.regidx, regval); | ||
868 | return count; | ||
869 | } | ||
870 | |||
871 | static const struct file_operations fops_regval = { | ||
872 | .read = read_file_regval, | ||
873 | .write = write_file_regval, | ||
874 | .open = ath9k_debugfs_open, | ||
875 | .owner = THIS_MODULE | ||
876 | }; | ||
877 | |||
703 | int ath9k_init_debug(struct ath_hw *ah) | 878 | int ath9k_init_debug(struct ath_hw *ah) |
704 | { | 879 | { |
705 | struct ath_common *common = ath9k_hw_common(ah); | 880 | struct ath_common *common = ath9k_hw_common(ah); |
@@ -711,54 +886,55 @@ int ath9k_init_debug(struct ath_hw *ah) | |||
711 | sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), | 886 | sc->debug.debugfs_phy = debugfs_create_dir(wiphy_name(sc->hw->wiphy), |
712 | ath9k_debugfs_root); | 887 | ath9k_debugfs_root); |
713 | if (!sc->debug.debugfs_phy) | 888 | if (!sc->debug.debugfs_phy) |
714 | goto err; | 889 | return -ENOMEM; |
715 | 890 | ||
716 | #ifdef CONFIG_ATH_DEBUG | 891 | #ifdef CONFIG_ATH_DEBUG |
717 | sc->debug.debugfs_debug = debugfs_create_file("debug", | 892 | if (!debugfs_create_file("debug", S_IRUSR | S_IWUSR, |
718 | S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_debug); | 893 | sc->debug.debugfs_phy, sc, &fops_debug)) |
719 | if (!sc->debug.debugfs_debug) | ||
720 | goto err; | 894 | goto err; |
721 | #endif | 895 | #endif |
722 | 896 | ||
723 | sc->debug.debugfs_dma = debugfs_create_file("dma", S_IRUSR, | 897 | if (!debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, |
724 | sc->debug.debugfs_phy, sc, &fops_dma); | 898 | sc, &fops_dma)) |
725 | if (!sc->debug.debugfs_dma) | 899 | goto err; |
900 | |||
901 | if (!debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, | ||
902 | sc, &fops_interrupt)) | ||
903 | goto err; | ||
904 | |||
905 | if (!debugfs_create_file("rcstat", S_IRUSR, sc->debug.debugfs_phy, | ||
906 | sc, &fops_rcstat)) | ||
907 | goto err; | ||
908 | |||
909 | if (!debugfs_create_file("wiphy", S_IRUSR | S_IWUSR, | ||
910 | sc->debug.debugfs_phy, sc, &fops_wiphy)) | ||
911 | goto err; | ||
912 | |||
913 | if (!debugfs_create_file("xmit", S_IRUSR, sc->debug.debugfs_phy, | ||
914 | sc, &fops_xmit)) | ||
726 | goto err; | 915 | goto err; |
727 | 916 | ||
728 | sc->debug.debugfs_interrupt = debugfs_create_file("interrupt", | 917 | if (!debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, |
729 | S_IRUSR, | 918 | sc, &fops_recv)) |
730 | sc->debug.debugfs_phy, | ||
731 | sc, &fops_interrupt); | ||
732 | if (!sc->debug.debugfs_interrupt) | ||
733 | goto err; | 919 | goto err; |
734 | 920 | ||
735 | sc->debug.debugfs_rcstat = debugfs_create_file("rcstat", | 921 | if (!debugfs_create_file("rx_chainmask", S_IRUSR | S_IWUSR, |
736 | S_IRUSR, | 922 | sc->debug.debugfs_phy, sc, &fops_rx_chainmask)) |
737 | sc->debug.debugfs_phy, | ||
738 | sc, &fops_rcstat); | ||
739 | if (!sc->debug.debugfs_rcstat) | ||
740 | goto err; | 923 | goto err; |
741 | 924 | ||
742 | sc->debug.debugfs_wiphy = debugfs_create_file( | 925 | if (!debugfs_create_file("tx_chainmask", S_IRUSR | S_IWUSR, |
743 | "wiphy", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, | 926 | sc->debug.debugfs_phy, sc, &fops_tx_chainmask)) |
744 | &fops_wiphy); | ||
745 | if (!sc->debug.debugfs_wiphy) | ||
746 | goto err; | 927 | goto err; |
747 | 928 | ||
748 | sc->debug.debugfs_xmit = debugfs_create_file("xmit", | 929 | if (!debugfs_create_file("regidx", S_IRUSR | S_IWUSR, |
749 | S_IRUSR, | 930 | sc->debug.debugfs_phy, sc, &fops_regidx)) |
750 | sc->debug.debugfs_phy, | ||
751 | sc, &fops_xmit); | ||
752 | if (!sc->debug.debugfs_xmit) | ||
753 | goto err; | 931 | goto err; |
754 | 932 | ||
755 | sc->debug.debugfs_recv = debugfs_create_file("recv", | 933 | if (!debugfs_create_file("regval", S_IRUSR | S_IWUSR, |
756 | S_IRUSR, | 934 | sc->debug.debugfs_phy, sc, &fops_regval)) |
757 | sc->debug.debugfs_phy, | ||
758 | sc, &fops_recv); | ||
759 | if (!sc->debug.debugfs_recv) | ||
760 | goto err; | 935 | goto err; |
761 | 936 | ||
937 | sc->debug.regidx = 0; | ||
762 | return 0; | 938 | return 0; |
763 | err: | 939 | err: |
764 | ath9k_exit_debug(ah); | 940 | ath9k_exit_debug(ah); |
@@ -770,14 +946,7 @@ void ath9k_exit_debug(struct ath_hw *ah) | |||
770 | struct ath_common *common = ath9k_hw_common(ah); | 946 | struct ath_common *common = ath9k_hw_common(ah); |
771 | struct ath_softc *sc = (struct ath_softc *) common->priv; | 947 | struct ath_softc *sc = (struct ath_softc *) common->priv; |
772 | 948 | ||
773 | debugfs_remove(sc->debug.debugfs_recv); | 949 | debugfs_remove_recursive(sc->debug.debugfs_phy); |
774 | debugfs_remove(sc->debug.debugfs_xmit); | ||
775 | debugfs_remove(sc->debug.debugfs_wiphy); | ||
776 | debugfs_remove(sc->debug.debugfs_rcstat); | ||
777 | debugfs_remove(sc->debug.debugfs_interrupt); | ||
778 | debugfs_remove(sc->debug.debugfs_dma); | ||
779 | debugfs_remove(sc->debug.debugfs_debug); | ||
780 | debugfs_remove(sc->debug.debugfs_phy); | ||
781 | } | 950 | } |
782 | 951 | ||
783 | int ath9k_debug_create_root(void) | 952 | int ath9k_debug_create_root(void) |
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 86780e68b31e..5147b8709e10 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h | |||
@@ -35,6 +35,8 @@ struct ath_buf; | |||
35 | * struct ath_interrupt_stats - Contains statistics about interrupts | 35 | * struct ath_interrupt_stats - Contains statistics about interrupts |
36 | * @total: Total no. of interrupts generated so far | 36 | * @total: Total no. of interrupts generated so far |
37 | * @rxok: RX with no errors | 37 | * @rxok: RX with no errors |
38 | * @rxlp: RX with low priority RX | ||
39 | * @rxhp: RX with high priority, uapsd only | ||
38 | * @rxeol: RX with no more RXDESC available | 40 | * @rxeol: RX with no more RXDESC available |
39 | * @rxorn: RX FIFO overrun | 41 | * @rxorn: RX FIFO overrun |
40 | * @txok: TX completed at the requested rate | 42 | * @txok: TX completed at the requested rate |
@@ -55,6 +57,8 @@ struct ath_buf; | |||
55 | struct ath_interrupt_stats { | 57 | struct ath_interrupt_stats { |
56 | u32 total; | 58 | u32 total; |
57 | u32 rxok; | 59 | u32 rxok; |
60 | u32 rxlp; | ||
61 | u32 rxhp; | ||
58 | u32 rxeol; | 62 | u32 rxeol; |
59 | u32 rxorn; | 63 | u32 rxorn; |
60 | u32 txok; | 64 | u32 txok; |
@@ -149,13 +153,7 @@ struct ath_stats { | |||
149 | 153 | ||
150 | struct ath9k_debug { | 154 | struct ath9k_debug { |
151 | struct dentry *debugfs_phy; | 155 | struct dentry *debugfs_phy; |
152 | struct dentry *debugfs_debug; | 156 | u32 regidx; |
153 | struct dentry *debugfs_dma; | ||
154 | struct dentry *debugfs_interrupt; | ||
155 | struct dentry *debugfs_rcstat; | ||
156 | struct dentry *debugfs_wiphy; | ||
157 | struct dentry *debugfs_xmit; | ||
158 | struct dentry *debugfs_recv; | ||
159 | struct ath_stats stats; | 157 | struct ath_stats stats; |
160 | }; | 158 | }; |
161 | 159 | ||
@@ -167,8 +165,8 @@ void ath9k_debug_remove_root(void); | |||
167 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); | 165 | void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status); |
168 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); | 166 | void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); |
169 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, | 167 | void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, |
170 | struct ath_buf *bf); | 168 | struct ath_buf *bf, struct ath_tx_status *ts); |
171 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf); | 169 | void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs); |
172 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, | 170 | void ath_debug_stat_retries(struct ath_softc *sc, int rix, |
173 | int xretries, int retries, u8 per); | 171 | int xretries, int retries, u8 per); |
174 | 172 | ||
@@ -204,12 +202,13 @@ static inline void ath_debug_stat_rc(struct ath_softc *sc, | |||
204 | 202 | ||
205 | static inline void ath_debug_stat_tx(struct ath_softc *sc, | 203 | static inline void ath_debug_stat_tx(struct ath_softc *sc, |
206 | struct ath_txq *txq, | 204 | struct ath_txq *txq, |
207 | struct ath_buf *bf) | 205 | struct ath_buf *bf, |
206 | struct ath_tx_status *ts) | ||
208 | { | 207 | { |
209 | } | 208 | } |
210 | 209 | ||
211 | static inline void ath_debug_stat_rx(struct ath_softc *sc, | 210 | static inline void ath_debug_stat_rx(struct ath_softc *sc, |
212 | struct ath_buf *bf) | 211 | struct ath_rx_status *rs) |
213 | { | 212 | { |
214 | } | 213 | } |
215 | 214 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index dacaae934148..ca8704a9d7ac 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -36,8 +36,6 @@ void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, | |||
36 | 36 | ||
37 | if (ah->config.analog_shiftreg) | 37 | if (ah->config.analog_shiftreg) |
38 | udelay(100); | 38 | udelay(100); |
39 | |||
40 | return; | ||
41 | } | 39 | } |
42 | 40 | ||
43 | int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, | 41 | int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight, |
@@ -256,14 +254,13 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah) | |||
256 | { | 254 | { |
257 | int status; | 255 | int status; |
258 | 256 | ||
259 | if (AR_SREV_9287(ah)) { | 257 | if (AR_SREV_9300_20_OR_LATER(ah)) |
260 | ah->eep_map = EEP_MAP_AR9287; | 258 | ah->eep_ops = &eep_ar9300_ops; |
261 | ah->eep_ops = &eep_AR9287_ops; | 259 | else if (AR_SREV_9287(ah)) { |
260 | ah->eep_ops = &eep_ar9287_ops; | ||
262 | } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { | 261 | } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { |
263 | ah->eep_map = EEP_MAP_4KBITS; | ||
264 | ah->eep_ops = &eep_4k_ops; | 262 | ah->eep_ops = &eep_4k_ops; |
265 | } else { | 263 | } else { |
266 | ah->eep_map = EEP_MAP_DEFAULT; | ||
267 | ah->eep_ops = &eep_def_ops; | 264 | ah->eep_ops = &eep_def_ops; |
268 | } | 265 | } |
269 | 266 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 2f2993b50e2f..21354c15a9a9 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "../ath.h" | 20 | #include "../ath.h" |
21 | #include <net/cfg80211.h> | 21 | #include <net/cfg80211.h> |
22 | #include "ar9003_eeprom.h" | ||
22 | 23 | ||
23 | #define AH_USE_EEPROM 0x1 | 24 | #define AH_USE_EEPROM 0x1 |
24 | 25 | ||
@@ -93,7 +94,6 @@ | |||
93 | */ | 94 | */ |
94 | #define AR9285_RDEXT_DEFAULT 0x1F | 95 | #define AR9285_RDEXT_DEFAULT 0x1F |
95 | 96 | ||
96 | #define AR_EEPROM_MAC(i) (0x1d+(i)) | ||
97 | #define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) | 97 | #define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) |
98 | #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) | 98 | #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) |
99 | #define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM)) | 99 | #define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM)) |
@@ -155,6 +155,7 @@ | |||
155 | #define AR5416_BCHAN_UNUSED 0xFF | 155 | #define AR5416_BCHAN_UNUSED 0xFF |
156 | #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 | 156 | #define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64 |
157 | #define AR5416_MAX_CHAINS 3 | 157 | #define AR5416_MAX_CHAINS 3 |
158 | #define AR9300_MAX_CHAINS 3 | ||
158 | #define AR5416_PWR_TABLE_OFFSET_DB -5 | 159 | #define AR5416_PWR_TABLE_OFFSET_DB -5 |
159 | 160 | ||
160 | /* Rx gain type values */ | 161 | /* Rx gain type values */ |
@@ -249,16 +250,20 @@ enum eeprom_param { | |||
249 | EEP_MINOR_REV, | 250 | EEP_MINOR_REV, |
250 | EEP_TX_MASK, | 251 | EEP_TX_MASK, |
251 | EEP_RX_MASK, | 252 | EEP_RX_MASK, |
253 | EEP_FSTCLK_5G, | ||
252 | EEP_RXGAIN_TYPE, | 254 | EEP_RXGAIN_TYPE, |
253 | EEP_TXGAIN_TYPE, | ||
254 | EEP_OL_PWRCTRL, | 255 | EEP_OL_PWRCTRL, |
256 | EEP_TXGAIN_TYPE, | ||
255 | EEP_RC_CHAIN_MASK, | 257 | EEP_RC_CHAIN_MASK, |
256 | EEP_DAC_HPWR_5G, | 258 | EEP_DAC_HPWR_5G, |
257 | EEP_FRAC_N_5G, | 259 | EEP_FRAC_N_5G, |
258 | EEP_DEV_TYPE, | 260 | EEP_DEV_TYPE, |
259 | EEP_TEMPSENSE_SLOPE, | 261 | EEP_TEMPSENSE_SLOPE, |
260 | EEP_TEMPSENSE_SLOPE_PAL_ON, | 262 | EEP_TEMPSENSE_SLOPE_PAL_ON, |
261 | EEP_PWR_TABLE_OFFSET | 263 | EEP_PWR_TABLE_OFFSET, |
264 | EEP_DRIVE_STRENGTH, | ||
265 | EEP_INTERNAL_REGULATOR, | ||
266 | EEP_SWREG | ||
262 | }; | 267 | }; |
263 | 268 | ||
264 | enum ar5416_rates { | 269 | enum ar5416_rates { |
@@ -295,7 +300,8 @@ struct base_eep_header { | |||
295 | u32 binBuildNumber; | 300 | u32 binBuildNumber; |
296 | u8 deviceType; | 301 | u8 deviceType; |
297 | u8 pwdclkind; | 302 | u8 pwdclkind; |
298 | u8 futureBase_1[2]; | 303 | u8 fastClk5g; |
304 | u8 divChain; | ||
299 | u8 rxGainType; | 305 | u8 rxGainType; |
300 | u8 dacHiPwrMode_5G; | 306 | u8 dacHiPwrMode_5G; |
301 | u8 openLoopPwrCntl; | 307 | u8 openLoopPwrCntl; |
@@ -656,13 +662,6 @@ struct ath9k_country_entry { | |||
656 | u8 iso[3]; | 662 | u8 iso[3]; |
657 | }; | 663 | }; |
658 | 664 | ||
659 | enum ath9k_eep_map { | ||
660 | EEP_MAP_DEFAULT = 0x0, | ||
661 | EEP_MAP_4KBITS, | ||
662 | EEP_MAP_AR9287, | ||
663 | EEP_MAP_MAX | ||
664 | }; | ||
665 | |||
666 | struct eeprom_ops { | 665 | struct eeprom_ops { |
667 | int (*check_eeprom)(struct ath_hw *hw); | 666 | int (*check_eeprom)(struct ath_hw *hw); |
668 | u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param); | 667 | u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param); |
@@ -713,6 +712,8 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah); | |||
713 | 712 | ||
714 | extern const struct eeprom_ops eep_def_ops; | 713 | extern const struct eeprom_ops eep_def_ops; |
715 | extern const struct eeprom_ops eep_4k_ops; | 714 | extern const struct eeprom_ops eep_4k_ops; |
716 | extern const struct eeprom_ops eep_AR9287_ops; | 715 | extern const struct eeprom_ops eep_ar9287_ops; |
716 | extern const struct eeprom_ops eep_ar9287_ops; | ||
717 | extern const struct eeprom_ops eep_ar9300_ops; | ||
717 | 718 | ||
718 | #endif /* EEPROM_H */ | 719 | #endif /* EEPROM_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c index 68db16690abf..41a77d1bd439 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "ar9002_phy.h" | ||
18 | 19 | ||
19 | static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) | 20 | static int ath9k_hw_4k_get_eeprom_ver(struct ath_hw *ah) |
20 | { | 21 | { |
@@ -43,7 +44,7 @@ static bool ath9k_hw_4k_fill_eeprom(struct ath_hw *ah) | |||
43 | for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { | 44 | for (addr = 0; addr < SIZE_EEPROM_4K; addr++) { |
44 | if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { | 45 | if (!ath9k_hw_nvram_read(common, addr + eep_start_loc, eep_data)) { |
45 | ath_print(common, ATH_DBG_EEPROM, | 46 | ath_print(common, ATH_DBG_EEPROM, |
46 | "Unable to read eeprom region \n"); | 47 | "Unable to read eeprom region\n"); |
47 | return false; | 48 | return false; |
48 | } | 49 | } |
49 | eep_data++; | 50 | eep_data++; |
@@ -182,11 +183,11 @@ static u32 ath9k_hw_4k_get_eeprom(struct ath_hw *ah, | |||
182 | switch (param) { | 183 | switch (param) { |
183 | case EEP_NFTHRESH_2: | 184 | case EEP_NFTHRESH_2: |
184 | return pModal->noiseFloorThreshCh[0]; | 185 | return pModal->noiseFloorThreshCh[0]; |
185 | case AR_EEPROM_MAC(0): | 186 | case EEP_MAC_LSW: |
186 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; | 187 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; |
187 | case AR_EEPROM_MAC(1): | 188 | case EEP_MAC_MID: |
188 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; | 189 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; |
189 | case AR_EEPROM_MAC(2): | 190 | case EEP_MAC_MSW: |
190 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; | 191 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; |
191 | case EEP_REG_0: | 192 | case EEP_REG_0: |
192 | return pBase->regDmn[0]; | 193 | return pBase->regDmn[0]; |
@@ -453,6 +454,8 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, | |||
453 | &tMinCalPower, gainBoundaries, | 454 | &tMinCalPower, gainBoundaries, |
454 | pdadcValues, numXpdGain); | 455 | pdadcValues, numXpdGain); |
455 | 456 | ||
457 | ENABLE_REGWRITE_BUFFER(ah); | ||
458 | |||
456 | if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { | 459 | if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) { |
457 | REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, | 460 | REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, |
458 | SM(pdGainOverlap_t2, | 461 | SM(pdGainOverlap_t2, |
@@ -493,6 +496,9 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah, | |||
493 | 496 | ||
494 | regOffset += 4; | 497 | regOffset += 4; |
495 | } | 498 | } |
499 | |||
500 | REGWRITE_BUFFER_FLUSH(ah); | ||
501 | DISABLE_REGWRITE_BUFFER(ah); | ||
496 | } | 502 | } |
497 | } | 503 | } |
498 | 504 | ||
@@ -758,6 +764,8 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, | |||
758 | ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; | 764 | ratesArray[i] -= AR5416_PWR_TABLE_OFFSET_DB * 2; |
759 | } | 765 | } |
760 | 766 | ||
767 | ENABLE_REGWRITE_BUFFER(ah); | ||
768 | |||
761 | /* OFDM power per rate */ | 769 | /* OFDM power per rate */ |
762 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, | 770 | REG_WRITE(ah, AR_PHY_POWER_TX_RATE1, |
763 | ATH9K_POW_SM(ratesArray[rate18mb], 24) | 771 | ATH9K_POW_SM(ratesArray[rate18mb], 24) |
@@ -820,6 +828,9 @@ static void ath9k_hw_4k_set_txpower(struct ath_hw *ah, | |||
820 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | 828 | | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) |
821 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); | 829 | | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); |
822 | } | 830 | } |
831 | |||
832 | REGWRITE_BUFFER_FLUSH(ah); | ||
833 | DISABLE_REGWRITE_BUFFER(ah); | ||
823 | } | 834 | } |
824 | 835 | ||
825 | static void ath9k_hw_4k_set_addac(struct ath_hw *ah, | 836 | static void ath9k_hw_4k_set_addac(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_9287.c b/drivers/net/wireless/ath/ath9k/eeprom_9287.c index 839d05a1df29..b471db5fb82d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_9287.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_9287.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "ar9002_phy.h" | ||
18 | 19 | ||
19 | static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) | 20 | static int ath9k_hw_AR9287_get_eeprom_ver(struct ath_hw *ah) |
20 | { | 21 | { |
@@ -44,7 +45,7 @@ static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) | |||
44 | if (!ath9k_hw_nvram_read(common, | 45 | if (!ath9k_hw_nvram_read(common, |
45 | addr + eep_start_loc, eep_data)) { | 46 | addr + eep_start_loc, eep_data)) { |
46 | ath_print(common, ATH_DBG_EEPROM, | 47 | ath_print(common, ATH_DBG_EEPROM, |
47 | "Unable to read eeprom region \n"); | 48 | "Unable to read eeprom region\n"); |
48 | return false; | 49 | return false; |
49 | } | 50 | } |
50 | eep_data++; | 51 | eep_data++; |
@@ -172,11 +173,11 @@ static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, | |||
172 | switch (param) { | 173 | switch (param) { |
173 | case EEP_NFTHRESH_2: | 174 | case EEP_NFTHRESH_2: |
174 | return pModal->noiseFloorThreshCh[0]; | 175 | return pModal->noiseFloorThreshCh[0]; |
175 | case AR_EEPROM_MAC(0): | 176 | case EEP_MAC_LSW: |
176 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; | 177 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; |
177 | case AR_EEPROM_MAC(1): | 178 | case EEP_MAC_MID: |
178 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; | 179 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; |
179 | case AR_EEPROM_MAC(2): | 180 | case EEP_MAC_MSW: |
180 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; | 181 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; |
181 | case EEP_REG_0: | 182 | case EEP_REG_0: |
182 | return pBase->regDmn[0]; | 183 | return pBase->regDmn[0]; |
@@ -1169,7 +1170,7 @@ static u16 ath9k_hw_AR9287_get_spur_channel(struct ath_hw *ah, | |||
1169 | #undef EEP_MAP9287_SPURCHAN | 1170 | #undef EEP_MAP9287_SPURCHAN |
1170 | } | 1171 | } |
1171 | 1172 | ||
1172 | const struct eeprom_ops eep_AR9287_ops = { | 1173 | const struct eeprom_ops eep_ar9287_ops = { |
1173 | .check_eeprom = ath9k_hw_AR9287_check_eeprom, | 1174 | .check_eeprom = ath9k_hw_AR9287_check_eeprom, |
1174 | .get_eeprom = ath9k_hw_AR9287_get_eeprom, | 1175 | .get_eeprom = ath9k_hw_AR9287_get_eeprom, |
1175 | .fill_eeprom = ath9k_hw_AR9287_fill_eeprom, | 1176 | .fill_eeprom = ath9k_hw_AR9287_fill_eeprom, |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 404a0341242c..7e1ed78d0e64 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -15,6 +15,7 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "hw.h" | 17 | #include "hw.h" |
18 | #include "ar9002_phy.h" | ||
18 | 19 | ||
19 | static void ath9k_get_txgain_index(struct ath_hw *ah, | 20 | static void ath9k_get_txgain_index(struct ath_hw *ah, |
20 | struct ath9k_channel *chan, | 21 | struct ath9k_channel *chan, |
@@ -49,7 +50,6 @@ static void ath9k_get_txgain_index(struct ath_hw *ah, | |||
49 | i++; | 50 | i++; |
50 | 51 | ||
51 | *pcdacIdx = i; | 52 | *pcdacIdx = i; |
52 | return; | ||
53 | } | 53 | } |
54 | 54 | ||
55 | static void ath9k_olc_get_pdadcs(struct ath_hw *ah, | 55 | static void ath9k_olc_get_pdadcs(struct ath_hw *ah, |
@@ -222,6 +222,12 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah) | |||
222 | return -EINVAL; | 222 | return -EINVAL; |
223 | } | 223 | } |
224 | 224 | ||
225 | /* Enable fixup for AR_AN_TOP2 if necessary */ | ||
226 | if (AR_SREV_9280_10_OR_LATER(ah) && | ||
227 | (eep->baseEepHeader.version & 0xff) > 0x0a && | ||
228 | eep->baseEepHeader.pwdclkind == 0) | ||
229 | ah->need_an_top2_fixup = 1; | ||
230 | |||
225 | return 0; | 231 | return 0; |
226 | } | 232 | } |
227 | 233 | ||
@@ -237,11 +243,11 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, | |||
237 | return pModal[0].noiseFloorThreshCh[0]; | 243 | return pModal[0].noiseFloorThreshCh[0]; |
238 | case EEP_NFTHRESH_2: | 244 | case EEP_NFTHRESH_2: |
239 | return pModal[1].noiseFloorThreshCh[0]; | 245 | return pModal[1].noiseFloorThreshCh[0]; |
240 | case AR_EEPROM_MAC(0): | 246 | case EEP_MAC_LSW: |
241 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; | 247 | return pBase->macAddr[0] << 8 | pBase->macAddr[1]; |
242 | case AR_EEPROM_MAC(1): | 248 | case EEP_MAC_MID: |
243 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; | 249 | return pBase->macAddr[2] << 8 | pBase->macAddr[3]; |
244 | case AR_EEPROM_MAC(2): | 250 | case EEP_MAC_MSW: |
245 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; | 251 | return pBase->macAddr[4] << 8 | pBase->macAddr[5]; |
246 | case EEP_REG_0: | 252 | case EEP_REG_0: |
247 | return pBase->regDmn[0]; | 253 | return pBase->regDmn[0]; |
@@ -267,6 +273,8 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, | |||
267 | return pBase->txMask; | 273 | return pBase->txMask; |
268 | case EEP_RX_MASK: | 274 | case EEP_RX_MASK: |
269 | return pBase->rxMask; | 275 | return pBase->rxMask; |
276 | case EEP_FSTCLK_5G: | ||
277 | return pBase->fastClk5g; | ||
270 | case EEP_RXGAIN_TYPE: | 278 | case EEP_RXGAIN_TYPE: |
271 | return pBase->rxGainType; | 279 | return pBase->rxGainType; |
272 | case EEP_TXGAIN_TYPE: | 280 | case EEP_TXGAIN_TYPE: |
@@ -742,8 +750,6 @@ static void ath9k_hw_get_def_gain_boundaries_pdadcs(struct ath_hw *ah, | |||
742 | pPDADCValues[k] = pPDADCValues[k - 1]; | 750 | pPDADCValues[k] = pPDADCValues[k - 1]; |
743 | k++; | 751 | k++; |
744 | } | 752 | } |
745 | |||
746 | return; | ||
747 | } | 753 | } |
748 | 754 | ||
749 | static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, | 755 | static int16_t ath9k_change_gain_boundary_setting(struct ath_hw *ah, |
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index deab8beb0680..0ee75e79fe35 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -283,22 +283,17 @@ static void ath9k_gen_timer_start(struct ath_hw *ah, | |||
283 | u32 timer_next, | 283 | u32 timer_next, |
284 | u32 timer_period) | 284 | u32 timer_period) |
285 | { | 285 | { |
286 | struct ath_common *common = ath9k_hw_common(ah); | ||
287 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
288 | |||
289 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); | 286 | ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period); |
290 | 287 | ||
291 | if ((sc->imask & ATH9K_INT_GENTIMER) == 0) { | 288 | if ((ah->imask & ATH9K_INT_GENTIMER) == 0) { |
292 | ath9k_hw_set_interrupts(ah, 0); | 289 | ath9k_hw_set_interrupts(ah, 0); |
293 | sc->imask |= ATH9K_INT_GENTIMER; | 290 | ah->imask |= ATH9K_INT_GENTIMER; |
294 | ath9k_hw_set_interrupts(ah, sc->imask); | 291 | ath9k_hw_set_interrupts(ah, ah->imask); |
295 | } | 292 | } |
296 | } | 293 | } |
297 | 294 | ||
298 | static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | 295 | static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) |
299 | { | 296 | { |
300 | struct ath_common *common = ath9k_hw_common(ah); | ||
301 | struct ath_softc *sc = (struct ath_softc *) common->priv; | ||
302 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; | 297 | struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers; |
303 | 298 | ||
304 | ath9k_hw_gen_timer_stop(ah, timer); | 299 | ath9k_hw_gen_timer_stop(ah, timer); |
@@ -306,8 +301,8 @@ static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) | |||
306 | /* if no timer is enabled, turn off interrupt mask */ | 301 | /* if no timer is enabled, turn off interrupt mask */ |
307 | if (timer_table->timer_mask.val == 0) { | 302 | if (timer_table->timer_mask.val == 0) { |
308 | ath9k_hw_set_interrupts(ah, 0); | 303 | ath9k_hw_set_interrupts(ah, 0); |
309 | sc->imask &= ~ATH9K_INT_GENTIMER; | 304 | ah->imask &= ~ATH9K_INT_GENTIMER; |
310 | ath9k_hw_set_interrupts(ah, sc->imask); | 305 | ath9k_hw_set_interrupts(ah, ah->imask); |
311 | } | 306 | } |
312 | } | 307 | } |
313 | 308 | ||
@@ -364,7 +359,7 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
364 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 359 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; |
365 | 360 | ||
366 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, | 361 | ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX, |
367 | "no stomp timer running \n"); | 362 | "no stomp timer running\n"); |
368 | 363 | ||
369 | spin_lock_bh(&btcoex->btcoex_lock); | 364 | spin_lock_bh(&btcoex->btcoex_lock); |
370 | 365 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c new file mode 100644 index 000000000000..46dc41a16faa --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -0,0 +1,1008 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | #define ATH9K_FW_USB_DEV(devid, fw) \ | ||
20 | { USB_DEVICE(0x0cf3, devid), .driver_info = (unsigned long) fw } | ||
21 | |||
22 | static struct usb_device_id ath9k_hif_usb_ids[] = { | ||
23 | ATH9K_FW_USB_DEV(0x9271, "ar9271.fw"), | ||
24 | ATH9K_FW_USB_DEV(0x1006, "ar9271.fw"), | ||
25 | { }, | ||
26 | }; | ||
27 | |||
28 | MODULE_DEVICE_TABLE(usb, ath9k_hif_usb_ids); | ||
29 | |||
30 | static int __hif_usb_tx(struct hif_device_usb *hif_dev); | ||
31 | |||
32 | static void hif_usb_regout_cb(struct urb *urb) | ||
33 | { | ||
34 | struct cmd_buf *cmd = (struct cmd_buf *)urb->context; | ||
35 | |||
36 | switch (urb->status) { | ||
37 | case 0: | ||
38 | break; | ||
39 | case -ENOENT: | ||
40 | case -ECONNRESET: | ||
41 | case -ENODEV: | ||
42 | case -ESHUTDOWN: | ||
43 | goto free; | ||
44 | default: | ||
45 | break; | ||
46 | } | ||
47 | |||
48 | if (cmd) { | ||
49 | ath9k_htc_txcompletion_cb(cmd->hif_dev->htc_handle, | ||
50 | cmd->skb, 1); | ||
51 | kfree(cmd); | ||
52 | } | ||
53 | |||
54 | return; | ||
55 | free: | ||
56 | kfree_skb(cmd->skb); | ||
57 | kfree(cmd); | ||
58 | } | ||
59 | |||
60 | static int hif_usb_send_regout(struct hif_device_usb *hif_dev, | ||
61 | struct sk_buff *skb) | ||
62 | { | ||
63 | struct urb *urb; | ||
64 | struct cmd_buf *cmd; | ||
65 | int ret = 0; | ||
66 | |||
67 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
68 | if (urb == NULL) | ||
69 | return -ENOMEM; | ||
70 | |||
71 | cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); | ||
72 | if (cmd == NULL) { | ||
73 | usb_free_urb(urb); | ||
74 | return -ENOMEM; | ||
75 | } | ||
76 | |||
77 | cmd->skb = skb; | ||
78 | cmd->hif_dev = hif_dev; | ||
79 | |||
80 | usb_fill_int_urb(urb, hif_dev->udev, | ||
81 | usb_sndintpipe(hif_dev->udev, USB_REG_OUT_PIPE), | ||
82 | skb->data, skb->len, | ||
83 | hif_usb_regout_cb, cmd, 1); | ||
84 | |||
85 | usb_anchor_urb(urb, &hif_dev->regout_submitted); | ||
86 | ret = usb_submit_urb(urb, GFP_KERNEL); | ||
87 | if (ret) { | ||
88 | usb_unanchor_urb(urb); | ||
89 | kfree(cmd); | ||
90 | } | ||
91 | usb_free_urb(urb); | ||
92 | |||
93 | return ret; | ||
94 | } | ||
95 | |||
96 | static inline void ath9k_skb_queue_purge(struct hif_device_usb *hif_dev, | ||
97 | struct sk_buff_head *list) | ||
98 | { | ||
99 | struct sk_buff *skb; | ||
100 | |||
101 | while ((skb = __skb_dequeue(list)) != NULL) { | ||
102 | dev_kfree_skb_any(skb); | ||
103 | TX_STAT_INC(skb_dropped); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | static void hif_usb_tx_cb(struct urb *urb) | ||
108 | { | ||
109 | struct tx_buf *tx_buf = (struct tx_buf *) urb->context; | ||
110 | struct hif_device_usb *hif_dev = tx_buf->hif_dev; | ||
111 | struct sk_buff *skb; | ||
112 | |||
113 | if (!hif_dev || !tx_buf) | ||
114 | return; | ||
115 | |||
116 | switch (urb->status) { | ||
117 | case 0: | ||
118 | break; | ||
119 | case -ENOENT: | ||
120 | case -ECONNRESET: | ||
121 | case -ENODEV: | ||
122 | case -ESHUTDOWN: | ||
123 | /* | ||
124 | * The URB has been killed, free the SKBs | ||
125 | * and return. | ||
126 | */ | ||
127 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
128 | return; | ||
129 | default: | ||
130 | break; | ||
131 | } | ||
132 | |||
133 | /* Check if TX has been stopped */ | ||
134 | spin_lock(&hif_dev->tx.tx_lock); | ||
135 | if (hif_dev->tx.flags & HIF_USB_TX_STOP) { | ||
136 | spin_unlock(&hif_dev->tx.tx_lock); | ||
137 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
138 | goto add_free; | ||
139 | } | ||
140 | spin_unlock(&hif_dev->tx.tx_lock); | ||
141 | |||
142 | /* Complete the queued SKBs. */ | ||
143 | while ((skb = __skb_dequeue(&tx_buf->skb_queue)) != NULL) { | ||
144 | ath9k_htc_txcompletion_cb(hif_dev->htc_handle, | ||
145 | skb, 1); | ||
146 | TX_STAT_INC(skb_completed); | ||
147 | } | ||
148 | |||
149 | add_free: | ||
150 | /* Re-initialize the SKB queue */ | ||
151 | tx_buf->len = tx_buf->offset = 0; | ||
152 | __skb_queue_head_init(&tx_buf->skb_queue); | ||
153 | |||
154 | /* Add this TX buffer to the free list */ | ||
155 | spin_lock(&hif_dev->tx.tx_lock); | ||
156 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | ||
157 | hif_dev->tx.tx_buf_cnt++; | ||
158 | if (!(hif_dev->tx.flags & HIF_USB_TX_STOP)) | ||
159 | __hif_usb_tx(hif_dev); /* Check for pending SKBs */ | ||
160 | TX_STAT_INC(buf_completed); | ||
161 | spin_unlock(&hif_dev->tx.tx_lock); | ||
162 | } | ||
163 | |||
164 | /* TX lock has to be taken */ | ||
165 | static int __hif_usb_tx(struct hif_device_usb *hif_dev) | ||
166 | { | ||
167 | struct tx_buf *tx_buf = NULL; | ||
168 | struct sk_buff *nskb = NULL; | ||
169 | int ret = 0, i; | ||
170 | u16 *hdr, tx_skb_cnt = 0; | ||
171 | u8 *buf; | ||
172 | |||
173 | if (hif_dev->tx.tx_skb_cnt == 0) | ||
174 | return 0; | ||
175 | |||
176 | /* Check if a free TX buffer is available */ | ||
177 | if (list_empty(&hif_dev->tx.tx_buf)) | ||
178 | return 0; | ||
179 | |||
180 | tx_buf = list_first_entry(&hif_dev->tx.tx_buf, struct tx_buf, list); | ||
181 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_pending); | ||
182 | hif_dev->tx.tx_buf_cnt--; | ||
183 | |||
184 | tx_skb_cnt = min_t(u16, hif_dev->tx.tx_skb_cnt, MAX_TX_AGGR_NUM); | ||
185 | |||
186 | for (i = 0; i < tx_skb_cnt; i++) { | ||
187 | nskb = __skb_dequeue(&hif_dev->tx.tx_skb_queue); | ||
188 | |||
189 | /* Should never be NULL */ | ||
190 | BUG_ON(!nskb); | ||
191 | |||
192 | hif_dev->tx.tx_skb_cnt--; | ||
193 | |||
194 | buf = tx_buf->buf; | ||
195 | buf += tx_buf->offset; | ||
196 | hdr = (u16 *)buf; | ||
197 | *hdr++ = nskb->len; | ||
198 | *hdr++ = ATH_USB_TX_STREAM_MODE_TAG; | ||
199 | buf += 4; | ||
200 | memcpy(buf, nskb->data, nskb->len); | ||
201 | tx_buf->len = nskb->len + 4; | ||
202 | |||
203 | if (i < (tx_skb_cnt - 1)) | ||
204 | tx_buf->offset += (((tx_buf->len - 1) / 4) + 1) * 4; | ||
205 | |||
206 | if (i == (tx_skb_cnt - 1)) | ||
207 | tx_buf->len += tx_buf->offset; | ||
208 | |||
209 | __skb_queue_tail(&tx_buf->skb_queue, nskb); | ||
210 | TX_STAT_INC(skb_queued); | ||
211 | } | ||
212 | |||
213 | usb_fill_bulk_urb(tx_buf->urb, hif_dev->udev, | ||
214 | usb_sndbulkpipe(hif_dev->udev, USB_WLAN_TX_PIPE), | ||
215 | tx_buf->buf, tx_buf->len, | ||
216 | hif_usb_tx_cb, tx_buf); | ||
217 | |||
218 | ret = usb_submit_urb(tx_buf->urb, GFP_ATOMIC); | ||
219 | if (ret) { | ||
220 | tx_buf->len = tx_buf->offset = 0; | ||
221 | ath9k_skb_queue_purge(hif_dev, &tx_buf->skb_queue); | ||
222 | __skb_queue_head_init(&tx_buf->skb_queue); | ||
223 | list_move_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | ||
224 | hif_dev->tx.tx_buf_cnt++; | ||
225 | } | ||
226 | |||
227 | if (!ret) | ||
228 | TX_STAT_INC(buf_queued); | ||
229 | |||
230 | return ret; | ||
231 | } | ||
232 | |||
233 | static int hif_usb_send_tx(struct hif_device_usb *hif_dev, struct sk_buff *skb, | ||
234 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
235 | { | ||
236 | unsigned long flags; | ||
237 | |||
238 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
239 | |||
240 | if (hif_dev->tx.flags & HIF_USB_TX_STOP) { | ||
241 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
242 | return -ENODEV; | ||
243 | } | ||
244 | |||
245 | /* Check if the max queue count has been reached */ | ||
246 | if (hif_dev->tx.tx_skb_cnt > MAX_TX_BUF_NUM) { | ||
247 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
248 | return -ENOMEM; | ||
249 | } | ||
250 | |||
251 | __skb_queue_tail(&hif_dev->tx.tx_skb_queue, skb); | ||
252 | hif_dev->tx.tx_skb_cnt++; | ||
253 | |||
254 | /* Send normal frames immediately */ | ||
255 | if (!tx_ctl || (tx_ctl && (tx_ctl->type == ATH9K_HTC_NORMAL))) | ||
256 | __hif_usb_tx(hif_dev); | ||
257 | |||
258 | /* Check if AMPDUs have to be sent immediately */ | ||
259 | if (tx_ctl && (tx_ctl->type == ATH9K_HTC_AMPDU) && | ||
260 | (hif_dev->tx.tx_buf_cnt == MAX_TX_URB_NUM) && | ||
261 | (hif_dev->tx.tx_skb_cnt < 2)) { | ||
262 | __hif_usb_tx(hif_dev); | ||
263 | } | ||
264 | |||
265 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static void hif_usb_start(void *hif_handle, u8 pipe_id) | ||
271 | { | ||
272 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | ||
273 | unsigned long flags; | ||
274 | |||
275 | hif_dev->flags |= HIF_USB_START; | ||
276 | |||
277 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
278 | hif_dev->tx.flags &= ~HIF_USB_TX_STOP; | ||
279 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
280 | } | ||
281 | |||
282 | static void hif_usb_stop(void *hif_handle, u8 pipe_id) | ||
283 | { | ||
284 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | ||
285 | unsigned long flags; | ||
286 | |||
287 | spin_lock_irqsave(&hif_dev->tx.tx_lock, flags); | ||
288 | ath9k_skb_queue_purge(hif_dev, &hif_dev->tx.tx_skb_queue); | ||
289 | hif_dev->tx.tx_skb_cnt = 0; | ||
290 | hif_dev->tx.flags |= HIF_USB_TX_STOP; | ||
291 | spin_unlock_irqrestore(&hif_dev->tx.tx_lock, flags); | ||
292 | } | ||
293 | |||
294 | static int hif_usb_send(void *hif_handle, u8 pipe_id, struct sk_buff *skb, | ||
295 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
296 | { | ||
297 | struct hif_device_usb *hif_dev = (struct hif_device_usb *)hif_handle; | ||
298 | int ret = 0; | ||
299 | |||
300 | switch (pipe_id) { | ||
301 | case USB_WLAN_TX_PIPE: | ||
302 | ret = hif_usb_send_tx(hif_dev, skb, tx_ctl); | ||
303 | break; | ||
304 | case USB_REG_OUT_PIPE: | ||
305 | ret = hif_usb_send_regout(hif_dev, skb); | ||
306 | break; | ||
307 | default: | ||
308 | dev_err(&hif_dev->udev->dev, | ||
309 | "ath9k_htc: Invalid TX pipe: %d\n", pipe_id); | ||
310 | ret = -EINVAL; | ||
311 | break; | ||
312 | } | ||
313 | |||
314 | return ret; | ||
315 | } | ||
316 | |||
317 | static struct ath9k_htc_hif hif_usb = { | ||
318 | .transport = ATH9K_HIF_USB, | ||
319 | .name = "ath9k_hif_usb", | ||
320 | |||
321 | .control_ul_pipe = USB_REG_OUT_PIPE, | ||
322 | .control_dl_pipe = USB_REG_IN_PIPE, | ||
323 | |||
324 | .start = hif_usb_start, | ||
325 | .stop = hif_usb_stop, | ||
326 | .send = hif_usb_send, | ||
327 | }; | ||
328 | |||
329 | static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, | ||
330 | struct sk_buff *skb) | ||
331 | { | ||
332 | struct sk_buff *nskb, *skb_pool[MAX_PKT_NUM_IN_TRANSFER]; | ||
333 | int index = 0, i = 0, chk_idx, len = skb->len; | ||
334 | int rx_remain_len = 0, rx_pkt_len = 0; | ||
335 | u16 pkt_len, pkt_tag, pool_index = 0; | ||
336 | u8 *ptr; | ||
337 | |||
338 | spin_lock(&hif_dev->rx_lock); | ||
339 | |||
340 | rx_remain_len = hif_dev->rx_remain_len; | ||
341 | rx_pkt_len = hif_dev->rx_transfer_len; | ||
342 | |||
343 | if (rx_remain_len != 0) { | ||
344 | struct sk_buff *remain_skb = hif_dev->remain_skb; | ||
345 | |||
346 | if (remain_skb) { | ||
347 | ptr = (u8 *) remain_skb->data; | ||
348 | |||
349 | index = rx_remain_len; | ||
350 | rx_remain_len -= hif_dev->rx_pad_len; | ||
351 | ptr += rx_pkt_len; | ||
352 | |||
353 | memcpy(ptr, skb->data, rx_remain_len); | ||
354 | |||
355 | rx_pkt_len += rx_remain_len; | ||
356 | hif_dev->rx_remain_len = 0; | ||
357 | skb_put(remain_skb, rx_pkt_len); | ||
358 | |||
359 | skb_pool[pool_index++] = remain_skb; | ||
360 | |||
361 | } else { | ||
362 | index = rx_remain_len; | ||
363 | } | ||
364 | } | ||
365 | |||
366 | spin_unlock(&hif_dev->rx_lock); | ||
367 | |||
368 | while (index < len) { | ||
369 | ptr = (u8 *) skb->data; | ||
370 | |||
371 | pkt_len = ptr[index] + (ptr[index+1] << 8); | ||
372 | pkt_tag = ptr[index+2] + (ptr[index+3] << 8); | ||
373 | |||
374 | if (pkt_tag == ATH_USB_RX_STREAM_MODE_TAG) { | ||
375 | u16 pad_len; | ||
376 | |||
377 | pad_len = 4 - (pkt_len & 0x3); | ||
378 | if (pad_len == 4) | ||
379 | pad_len = 0; | ||
380 | |||
381 | chk_idx = index; | ||
382 | index = index + 4 + pkt_len + pad_len; | ||
383 | |||
384 | if (index > MAX_RX_BUF_SIZE) { | ||
385 | spin_lock(&hif_dev->rx_lock); | ||
386 | hif_dev->rx_remain_len = index - MAX_RX_BUF_SIZE; | ||
387 | hif_dev->rx_transfer_len = | ||
388 | MAX_RX_BUF_SIZE - chk_idx - 4; | ||
389 | hif_dev->rx_pad_len = pad_len; | ||
390 | |||
391 | nskb = __dev_alloc_skb(pkt_len + 32, | ||
392 | GFP_ATOMIC); | ||
393 | if (!nskb) { | ||
394 | dev_err(&hif_dev->udev->dev, | ||
395 | "ath9k_htc: RX memory allocation" | ||
396 | " error\n"); | ||
397 | spin_unlock(&hif_dev->rx_lock); | ||
398 | goto err; | ||
399 | } | ||
400 | skb_reserve(nskb, 32); | ||
401 | RX_STAT_INC(skb_allocated); | ||
402 | |||
403 | memcpy(nskb->data, &(skb->data[chk_idx+4]), | ||
404 | hif_dev->rx_transfer_len); | ||
405 | |||
406 | /* Record the buffer pointer */ | ||
407 | hif_dev->remain_skb = nskb; | ||
408 | spin_unlock(&hif_dev->rx_lock); | ||
409 | } else { | ||
410 | nskb = __dev_alloc_skb(pkt_len + 32, GFP_ATOMIC); | ||
411 | if (!nskb) { | ||
412 | dev_err(&hif_dev->udev->dev, | ||
413 | "ath9k_htc: RX memory allocation" | ||
414 | " error\n"); | ||
415 | goto err; | ||
416 | } | ||
417 | skb_reserve(nskb, 32); | ||
418 | RX_STAT_INC(skb_allocated); | ||
419 | |||
420 | memcpy(nskb->data, &(skb->data[chk_idx+4]), pkt_len); | ||
421 | skb_put(nskb, pkt_len); | ||
422 | skb_pool[pool_index++] = nskb; | ||
423 | } | ||
424 | } else { | ||
425 | RX_STAT_INC(skb_dropped); | ||
426 | return; | ||
427 | } | ||
428 | } | ||
429 | |||
430 | err: | ||
431 | for (i = 0; i < pool_index; i++) { | ||
432 | ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], | ||
433 | skb_pool[i]->len, USB_WLAN_RX_PIPE); | ||
434 | RX_STAT_INC(skb_completed); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | static void ath9k_hif_usb_rx_cb(struct urb *urb) | ||
439 | { | ||
440 | struct sk_buff *skb = (struct sk_buff *) urb->context; | ||
441 | struct hif_device_usb *hif_dev = (struct hif_device_usb *) | ||
442 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | ||
443 | int ret; | ||
444 | |||
445 | if (!skb) | ||
446 | return; | ||
447 | |||
448 | if (!hif_dev) | ||
449 | goto free; | ||
450 | |||
451 | switch (urb->status) { | ||
452 | case 0: | ||
453 | break; | ||
454 | case -ENOENT: | ||
455 | case -ECONNRESET: | ||
456 | case -ENODEV: | ||
457 | case -ESHUTDOWN: | ||
458 | goto free; | ||
459 | default: | ||
460 | goto resubmit; | ||
461 | } | ||
462 | |||
463 | if (likely(urb->actual_length != 0)) { | ||
464 | skb_put(skb, urb->actual_length); | ||
465 | ath9k_hif_usb_rx_stream(hif_dev, skb); | ||
466 | } | ||
467 | |||
468 | resubmit: | ||
469 | skb_reset_tail_pointer(skb); | ||
470 | skb_trim(skb, 0); | ||
471 | |||
472 | usb_anchor_urb(urb, &hif_dev->rx_submitted); | ||
473 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
474 | if (ret) { | ||
475 | usb_unanchor_urb(urb); | ||
476 | goto free; | ||
477 | } | ||
478 | |||
479 | return; | ||
480 | free: | ||
481 | kfree_skb(skb); | ||
482 | } | ||
483 | |||
484 | static void ath9k_hif_usb_reg_in_cb(struct urb *urb) | ||
485 | { | ||
486 | struct sk_buff *skb = (struct sk_buff *) urb->context; | ||
487 | struct sk_buff *nskb; | ||
488 | struct hif_device_usb *hif_dev = (struct hif_device_usb *) | ||
489 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | ||
490 | int ret; | ||
491 | |||
492 | if (!skb) | ||
493 | return; | ||
494 | |||
495 | if (!hif_dev) | ||
496 | goto free; | ||
497 | |||
498 | switch (urb->status) { | ||
499 | case 0: | ||
500 | break; | ||
501 | case -ENOENT: | ||
502 | case -ECONNRESET: | ||
503 | case -ENODEV: | ||
504 | case -ESHUTDOWN: | ||
505 | goto free; | ||
506 | default: | ||
507 | goto resubmit; | ||
508 | } | ||
509 | |||
510 | if (likely(urb->actual_length != 0)) { | ||
511 | skb_put(skb, urb->actual_length); | ||
512 | |||
513 | /* Process the command first */ | ||
514 | ath9k_htc_rx_msg(hif_dev->htc_handle, skb, | ||
515 | skb->len, USB_REG_IN_PIPE); | ||
516 | |||
517 | |||
518 | nskb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_ATOMIC); | ||
519 | if (!nskb) { | ||
520 | dev_err(&hif_dev->udev->dev, | ||
521 | "ath9k_htc: REG_IN memory allocation failure\n"); | ||
522 | urb->context = NULL; | ||
523 | return; | ||
524 | } | ||
525 | |||
526 | usb_fill_int_urb(urb, hif_dev->udev, | ||
527 | usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), | ||
528 | nskb->data, MAX_REG_IN_BUF_SIZE, | ||
529 | ath9k_hif_usb_reg_in_cb, nskb, 1); | ||
530 | |||
531 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
532 | if (ret) { | ||
533 | kfree_skb(nskb); | ||
534 | urb->context = NULL; | ||
535 | } | ||
536 | |||
537 | return; | ||
538 | } | ||
539 | |||
540 | resubmit: | ||
541 | skb_reset_tail_pointer(skb); | ||
542 | skb_trim(skb, 0); | ||
543 | |||
544 | ret = usb_submit_urb(urb, GFP_ATOMIC); | ||
545 | if (ret) | ||
546 | goto free; | ||
547 | |||
548 | return; | ||
549 | free: | ||
550 | kfree_skb(skb); | ||
551 | urb->context = NULL; | ||
552 | } | ||
553 | |||
554 | static void ath9k_hif_usb_dealloc_tx_urbs(struct hif_device_usb *hif_dev) | ||
555 | { | ||
556 | struct tx_buf *tx_buf = NULL, *tx_buf_tmp = NULL; | ||
557 | |||
558 | list_for_each_entry_safe(tx_buf, tx_buf_tmp, | ||
559 | &hif_dev->tx.tx_buf, list) { | ||
560 | usb_kill_urb(tx_buf->urb); | ||
561 | list_del(&tx_buf->list); | ||
562 | usb_free_urb(tx_buf->urb); | ||
563 | kfree(tx_buf->buf); | ||
564 | kfree(tx_buf); | ||
565 | } | ||
566 | |||
567 | list_for_each_entry_safe(tx_buf, tx_buf_tmp, | ||
568 | &hif_dev->tx.tx_pending, list) { | ||
569 | usb_kill_urb(tx_buf->urb); | ||
570 | list_del(&tx_buf->list); | ||
571 | usb_free_urb(tx_buf->urb); | ||
572 | kfree(tx_buf->buf); | ||
573 | kfree(tx_buf); | ||
574 | } | ||
575 | } | ||
576 | |||
577 | static int ath9k_hif_usb_alloc_tx_urbs(struct hif_device_usb *hif_dev) | ||
578 | { | ||
579 | struct tx_buf *tx_buf; | ||
580 | int i; | ||
581 | |||
582 | INIT_LIST_HEAD(&hif_dev->tx.tx_buf); | ||
583 | INIT_LIST_HEAD(&hif_dev->tx.tx_pending); | ||
584 | spin_lock_init(&hif_dev->tx.tx_lock); | ||
585 | __skb_queue_head_init(&hif_dev->tx.tx_skb_queue); | ||
586 | |||
587 | for (i = 0; i < MAX_TX_URB_NUM; i++) { | ||
588 | tx_buf = kzalloc(sizeof(struct tx_buf), GFP_KERNEL); | ||
589 | if (!tx_buf) | ||
590 | goto err; | ||
591 | |||
592 | tx_buf->buf = kzalloc(MAX_TX_BUF_SIZE, GFP_KERNEL); | ||
593 | if (!tx_buf->buf) | ||
594 | goto err; | ||
595 | |||
596 | tx_buf->urb = usb_alloc_urb(0, GFP_KERNEL); | ||
597 | if (!tx_buf->urb) | ||
598 | goto err; | ||
599 | |||
600 | tx_buf->hif_dev = hif_dev; | ||
601 | __skb_queue_head_init(&tx_buf->skb_queue); | ||
602 | |||
603 | list_add_tail(&tx_buf->list, &hif_dev->tx.tx_buf); | ||
604 | } | ||
605 | |||
606 | hif_dev->tx.tx_buf_cnt = MAX_TX_URB_NUM; | ||
607 | |||
608 | return 0; | ||
609 | err: | ||
610 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); | ||
611 | return -ENOMEM; | ||
612 | } | ||
613 | |||
614 | static void ath9k_hif_usb_dealloc_rx_urbs(struct hif_device_usb *hif_dev) | ||
615 | { | ||
616 | usb_kill_anchored_urbs(&hif_dev->rx_submitted); | ||
617 | } | ||
618 | |||
619 | static int ath9k_hif_usb_alloc_rx_urbs(struct hif_device_usb *hif_dev) | ||
620 | { | ||
621 | struct urb *urb = NULL; | ||
622 | struct sk_buff *skb = NULL; | ||
623 | int i, ret; | ||
624 | |||
625 | init_usb_anchor(&hif_dev->rx_submitted); | ||
626 | spin_lock_init(&hif_dev->rx_lock); | ||
627 | |||
628 | for (i = 0; i < MAX_RX_URB_NUM; i++) { | ||
629 | |||
630 | /* Allocate URB */ | ||
631 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
632 | if (urb == NULL) { | ||
633 | ret = -ENOMEM; | ||
634 | goto err_urb; | ||
635 | } | ||
636 | |||
637 | /* Allocate buffer */ | ||
638 | skb = alloc_skb(MAX_RX_BUF_SIZE, GFP_KERNEL); | ||
639 | if (!skb) { | ||
640 | ret = -ENOMEM; | ||
641 | goto err_skb; | ||
642 | } | ||
643 | |||
644 | usb_fill_bulk_urb(urb, hif_dev->udev, | ||
645 | usb_rcvbulkpipe(hif_dev->udev, | ||
646 | USB_WLAN_RX_PIPE), | ||
647 | skb->data, MAX_RX_BUF_SIZE, | ||
648 | ath9k_hif_usb_rx_cb, skb); | ||
649 | |||
650 | /* Anchor URB */ | ||
651 | usb_anchor_urb(urb, &hif_dev->rx_submitted); | ||
652 | |||
653 | /* Submit URB */ | ||
654 | ret = usb_submit_urb(urb, GFP_KERNEL); | ||
655 | if (ret) { | ||
656 | usb_unanchor_urb(urb); | ||
657 | goto err_submit; | ||
658 | } | ||
659 | |||
660 | /* | ||
661 | * Drop reference count. | ||
662 | * This ensures that the URB is freed when killing them. | ||
663 | */ | ||
664 | usb_free_urb(urb); | ||
665 | } | ||
666 | |||
667 | return 0; | ||
668 | |||
669 | err_submit: | ||
670 | kfree_skb(skb); | ||
671 | err_skb: | ||
672 | usb_free_urb(urb); | ||
673 | err_urb: | ||
674 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); | ||
675 | return ret; | ||
676 | } | ||
677 | |||
678 | static void ath9k_hif_usb_dealloc_reg_in_urb(struct hif_device_usb *hif_dev) | ||
679 | { | ||
680 | if (hif_dev->reg_in_urb) { | ||
681 | usb_kill_urb(hif_dev->reg_in_urb); | ||
682 | if (hif_dev->reg_in_urb->context) | ||
683 | kfree_skb((void *)hif_dev->reg_in_urb->context); | ||
684 | usb_free_urb(hif_dev->reg_in_urb); | ||
685 | hif_dev->reg_in_urb = NULL; | ||
686 | } | ||
687 | } | ||
688 | |||
689 | static int ath9k_hif_usb_alloc_reg_in_urb(struct hif_device_usb *hif_dev) | ||
690 | { | ||
691 | struct sk_buff *skb; | ||
692 | |||
693 | hif_dev->reg_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
694 | if (hif_dev->reg_in_urb == NULL) | ||
695 | return -ENOMEM; | ||
696 | |||
697 | skb = alloc_skb(MAX_REG_IN_BUF_SIZE, GFP_KERNEL); | ||
698 | if (!skb) | ||
699 | goto err; | ||
700 | |||
701 | usb_fill_int_urb(hif_dev->reg_in_urb, hif_dev->udev, | ||
702 | usb_rcvintpipe(hif_dev->udev, USB_REG_IN_PIPE), | ||
703 | skb->data, MAX_REG_IN_BUF_SIZE, | ||
704 | ath9k_hif_usb_reg_in_cb, skb, 1); | ||
705 | |||
706 | if (usb_submit_urb(hif_dev->reg_in_urb, GFP_KERNEL) != 0) | ||
707 | goto err; | ||
708 | |||
709 | return 0; | ||
710 | |||
711 | err: | ||
712 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | ||
713 | return -ENOMEM; | ||
714 | } | ||
715 | |||
716 | static int ath9k_hif_usb_alloc_urbs(struct hif_device_usb *hif_dev) | ||
717 | { | ||
718 | /* Register Write */ | ||
719 | init_usb_anchor(&hif_dev->regout_submitted); | ||
720 | |||
721 | /* TX */ | ||
722 | if (ath9k_hif_usb_alloc_tx_urbs(hif_dev) < 0) | ||
723 | goto err; | ||
724 | |||
725 | /* RX */ | ||
726 | if (ath9k_hif_usb_alloc_rx_urbs(hif_dev) < 0) | ||
727 | goto err; | ||
728 | |||
729 | /* Register Read */ | ||
730 | if (ath9k_hif_usb_alloc_reg_in_urb(hif_dev) < 0) | ||
731 | goto err; | ||
732 | |||
733 | return 0; | ||
734 | err: | ||
735 | return -ENOMEM; | ||
736 | } | ||
737 | |||
738 | static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) | ||
739 | { | ||
740 | usb_kill_anchored_urbs(&hif_dev->regout_submitted); | ||
741 | ath9k_hif_usb_dealloc_reg_in_urb(hif_dev); | ||
742 | ath9k_hif_usb_dealloc_tx_urbs(hif_dev); | ||
743 | ath9k_hif_usb_dealloc_rx_urbs(hif_dev); | ||
744 | } | ||
745 | |||
746 | static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) | ||
747 | { | ||
748 | int transfer, err; | ||
749 | const void *data = hif_dev->firmware->data; | ||
750 | size_t len = hif_dev->firmware->size; | ||
751 | u32 addr = AR9271_FIRMWARE; | ||
752 | u8 *buf = kzalloc(4096, GFP_KERNEL); | ||
753 | |||
754 | if (!buf) | ||
755 | return -ENOMEM; | ||
756 | |||
757 | while (len) { | ||
758 | transfer = min_t(int, len, 4096); | ||
759 | memcpy(buf, data, transfer); | ||
760 | |||
761 | err = usb_control_msg(hif_dev->udev, | ||
762 | usb_sndctrlpipe(hif_dev->udev, 0), | ||
763 | FIRMWARE_DOWNLOAD, 0x40 | USB_DIR_OUT, | ||
764 | addr >> 8, 0, buf, transfer, HZ); | ||
765 | if (err < 0) { | ||
766 | kfree(buf); | ||
767 | return err; | ||
768 | } | ||
769 | |||
770 | len -= transfer; | ||
771 | data += transfer; | ||
772 | addr += transfer; | ||
773 | } | ||
774 | kfree(buf); | ||
775 | |||
776 | /* | ||
777 | * Issue FW download complete command to firmware. | ||
778 | */ | ||
779 | err = usb_control_msg(hif_dev->udev, usb_sndctrlpipe(hif_dev->udev, 0), | ||
780 | FIRMWARE_DOWNLOAD_COMP, | ||
781 | 0x40 | USB_DIR_OUT, | ||
782 | AR9271_FIRMWARE_TEXT >> 8, 0, NULL, 0, HZ); | ||
783 | if (err) | ||
784 | return -EIO; | ||
785 | |||
786 | dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n", | ||
787 | "ar9271.fw", (unsigned long) hif_dev->firmware->size); | ||
788 | |||
789 | return 0; | ||
790 | } | ||
791 | |||
792 | static int ath9k_hif_usb_dev_init(struct hif_device_usb *hif_dev, | ||
793 | const char *fw_name) | ||
794 | { | ||
795 | int ret; | ||
796 | |||
797 | /* Request firmware */ | ||
798 | ret = request_firmware(&hif_dev->firmware, fw_name, &hif_dev->udev->dev); | ||
799 | if (ret) { | ||
800 | dev_err(&hif_dev->udev->dev, | ||
801 | "ath9k_htc: Firmware - %s not found\n", fw_name); | ||
802 | goto err_fw_req; | ||
803 | } | ||
804 | |||
805 | /* Alloc URBs */ | ||
806 | ret = ath9k_hif_usb_alloc_urbs(hif_dev); | ||
807 | if (ret) { | ||
808 | dev_err(&hif_dev->udev->dev, | ||
809 | "ath9k_htc: Unable to allocate URBs\n"); | ||
810 | goto err_urb; | ||
811 | } | ||
812 | |||
813 | /* Download firmware */ | ||
814 | ret = ath9k_hif_usb_download_fw(hif_dev); | ||
815 | if (ret) { | ||
816 | dev_err(&hif_dev->udev->dev, | ||
817 | "ath9k_htc: Firmware - %s download failed\n", fw_name); | ||
818 | goto err_fw_download; | ||
819 | } | ||
820 | |||
821 | return 0; | ||
822 | |||
823 | err_fw_download: | ||
824 | ath9k_hif_usb_dealloc_urbs(hif_dev); | ||
825 | err_urb: | ||
826 | release_firmware(hif_dev->firmware); | ||
827 | err_fw_req: | ||
828 | hif_dev->firmware = NULL; | ||
829 | return ret; | ||
830 | } | ||
831 | |||
832 | static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) | ||
833 | { | ||
834 | ath9k_hif_usb_dealloc_urbs(hif_dev); | ||
835 | if (hif_dev->firmware) | ||
836 | release_firmware(hif_dev->firmware); | ||
837 | } | ||
838 | |||
839 | static int ath9k_hif_usb_probe(struct usb_interface *interface, | ||
840 | const struct usb_device_id *id) | ||
841 | { | ||
842 | struct usb_device *udev = interface_to_usbdev(interface); | ||
843 | struct hif_device_usb *hif_dev; | ||
844 | const char *fw_name = (const char *) id->driver_info; | ||
845 | int ret = 0; | ||
846 | |||
847 | hif_dev = kzalloc(sizeof(struct hif_device_usb), GFP_KERNEL); | ||
848 | if (!hif_dev) { | ||
849 | ret = -ENOMEM; | ||
850 | goto err_alloc; | ||
851 | } | ||
852 | |||
853 | usb_get_dev(udev); | ||
854 | hif_dev->udev = udev; | ||
855 | hif_dev->interface = interface; | ||
856 | hif_dev->device_id = id->idProduct; | ||
857 | #ifdef CONFIG_PM | ||
858 | udev->reset_resume = 1; | ||
859 | #endif | ||
860 | usb_set_intfdata(interface, hif_dev); | ||
861 | |||
862 | hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, | ||
863 | &hif_dev->udev->dev); | ||
864 | if (hif_dev->htc_handle == NULL) { | ||
865 | ret = -ENOMEM; | ||
866 | goto err_htc_hw_alloc; | ||
867 | } | ||
868 | |||
869 | ret = ath9k_hif_usb_dev_init(hif_dev, fw_name); | ||
870 | if (ret) { | ||
871 | ret = -EINVAL; | ||
872 | goto err_hif_init_usb; | ||
873 | } | ||
874 | |||
875 | ret = ath9k_htc_hw_init(hif_dev->htc_handle, | ||
876 | &hif_dev->udev->dev, hif_dev->device_id); | ||
877 | if (ret) { | ||
878 | ret = -EINVAL; | ||
879 | goto err_htc_hw_init; | ||
880 | } | ||
881 | |||
882 | dev_info(&hif_dev->udev->dev, "ath9k_htc: USB layer initialized\n"); | ||
883 | |||
884 | return 0; | ||
885 | |||
886 | err_htc_hw_init: | ||
887 | ath9k_hif_usb_dev_deinit(hif_dev); | ||
888 | err_hif_init_usb: | ||
889 | ath9k_htc_hw_free(hif_dev->htc_handle); | ||
890 | err_htc_hw_alloc: | ||
891 | usb_set_intfdata(interface, NULL); | ||
892 | kfree(hif_dev); | ||
893 | usb_put_dev(udev); | ||
894 | err_alloc: | ||
895 | return ret; | ||
896 | } | ||
897 | |||
898 | static void ath9k_hif_usb_reboot(struct usb_device *udev) | ||
899 | { | ||
900 | u32 reboot_cmd = 0xffffffff; | ||
901 | void *buf; | ||
902 | int ret; | ||
903 | |||
904 | buf = kmalloc(4, GFP_KERNEL); | ||
905 | if (!buf) | ||
906 | return; | ||
907 | |||
908 | memcpy(buf, &reboot_cmd, 4); | ||
909 | |||
910 | ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, USB_REG_OUT_PIPE), | ||
911 | buf, 4, NULL, HZ); | ||
912 | if (ret) | ||
913 | dev_err(&udev->dev, "ath9k_htc: USB reboot failed\n"); | ||
914 | |||
915 | kfree(buf); | ||
916 | } | ||
917 | |||
918 | static void ath9k_hif_usb_disconnect(struct usb_interface *interface) | ||
919 | { | ||
920 | struct usb_device *udev = interface_to_usbdev(interface); | ||
921 | struct hif_device_usb *hif_dev = | ||
922 | (struct hif_device_usb *) usb_get_intfdata(interface); | ||
923 | |||
924 | if (hif_dev) { | ||
925 | ath9k_htc_hw_deinit(hif_dev->htc_handle, | ||
926 | (udev->state == USB_STATE_NOTATTACHED) ? true : false); | ||
927 | ath9k_htc_hw_free(hif_dev->htc_handle); | ||
928 | ath9k_hif_usb_dev_deinit(hif_dev); | ||
929 | usb_set_intfdata(interface, NULL); | ||
930 | } | ||
931 | |||
932 | if (hif_dev->flags & HIF_USB_START) | ||
933 | ath9k_hif_usb_reboot(udev); | ||
934 | |||
935 | kfree(hif_dev); | ||
936 | dev_info(&udev->dev, "ath9k_htc: USB layer deinitialized\n"); | ||
937 | usb_put_dev(udev); | ||
938 | } | ||
939 | |||
940 | #ifdef CONFIG_PM | ||
941 | static int ath9k_hif_usb_suspend(struct usb_interface *interface, | ||
942 | pm_message_t message) | ||
943 | { | ||
944 | struct hif_device_usb *hif_dev = | ||
945 | (struct hif_device_usb *) usb_get_intfdata(interface); | ||
946 | |||
947 | ath9k_hif_usb_dealloc_urbs(hif_dev); | ||
948 | |||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | static int ath9k_hif_usb_resume(struct usb_interface *interface) | ||
953 | { | ||
954 | struct hif_device_usb *hif_dev = | ||
955 | (struct hif_device_usb *) usb_get_intfdata(interface); | ||
956 | int ret; | ||
957 | |||
958 | ret = ath9k_hif_usb_alloc_urbs(hif_dev); | ||
959 | if (ret) | ||
960 | return ret; | ||
961 | |||
962 | if (hif_dev->firmware) { | ||
963 | ret = ath9k_hif_usb_download_fw(hif_dev); | ||
964 | if (ret) | ||
965 | goto fail_resume; | ||
966 | } else { | ||
967 | ath9k_hif_usb_dealloc_urbs(hif_dev); | ||
968 | return -EIO; | ||
969 | } | ||
970 | |||
971 | mdelay(100); | ||
972 | |||
973 | ret = ath9k_htc_resume(hif_dev->htc_handle); | ||
974 | |||
975 | if (ret) | ||
976 | goto fail_resume; | ||
977 | |||
978 | return 0; | ||
979 | |||
980 | fail_resume: | ||
981 | ath9k_hif_usb_dealloc_urbs(hif_dev); | ||
982 | |||
983 | return ret; | ||
984 | } | ||
985 | #endif | ||
986 | |||
987 | static struct usb_driver ath9k_hif_usb_driver = { | ||
988 | .name = "ath9k_hif_usb", | ||
989 | .probe = ath9k_hif_usb_probe, | ||
990 | .disconnect = ath9k_hif_usb_disconnect, | ||
991 | #ifdef CONFIG_PM | ||
992 | .suspend = ath9k_hif_usb_suspend, | ||
993 | .resume = ath9k_hif_usb_resume, | ||
994 | .reset_resume = ath9k_hif_usb_resume, | ||
995 | #endif | ||
996 | .id_table = ath9k_hif_usb_ids, | ||
997 | .soft_unbind = 1, | ||
998 | }; | ||
999 | |||
1000 | int ath9k_hif_usb_init(void) | ||
1001 | { | ||
1002 | return usb_register(&ath9k_hif_usb_driver); | ||
1003 | } | ||
1004 | |||
1005 | void ath9k_hif_usb_exit(void) | ||
1006 | { | ||
1007 | usb_deregister(&ath9k_hif_usb_driver); | ||
1008 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h new file mode 100644 index 000000000000..0aca49b6fcb6 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h | |||
@@ -0,0 +1,104 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef HTC_USB_H | ||
18 | #define HTC_USB_H | ||
19 | |||
20 | #define AR9271_FIRMWARE 0x501000 | ||
21 | #define AR9271_FIRMWARE_TEXT 0x903000 | ||
22 | |||
23 | #define FIRMWARE_DOWNLOAD 0x30 | ||
24 | #define FIRMWARE_DOWNLOAD_COMP 0x31 | ||
25 | |||
26 | #define ATH_USB_RX_STREAM_MODE_TAG 0x4e00 | ||
27 | #define ATH_USB_TX_STREAM_MODE_TAG 0x697e | ||
28 | |||
29 | /* FIXME: Verify these numbers (with Windows) */ | ||
30 | #define MAX_TX_URB_NUM 8 | ||
31 | #define MAX_TX_BUF_NUM 1024 | ||
32 | #define MAX_TX_BUF_SIZE 32768 | ||
33 | #define MAX_TX_AGGR_NUM 20 | ||
34 | |||
35 | #define MAX_RX_URB_NUM 8 | ||
36 | #define MAX_RX_BUF_SIZE 16384 | ||
37 | #define MAX_PKT_NUM_IN_TRANSFER 10 | ||
38 | |||
39 | #define MAX_REG_OUT_URB_NUM 1 | ||
40 | #define MAX_REG_OUT_BUF_NUM 8 | ||
41 | |||
42 | #define MAX_REG_IN_BUF_SIZE 64 | ||
43 | |||
44 | /* USB Endpoint definition */ | ||
45 | #define USB_WLAN_TX_PIPE 1 | ||
46 | #define USB_WLAN_RX_PIPE 2 | ||
47 | #define USB_REG_IN_PIPE 3 | ||
48 | #define USB_REG_OUT_PIPE 4 | ||
49 | |||
50 | #define HIF_USB_MAX_RXPIPES 2 | ||
51 | #define HIF_USB_MAX_TXPIPES 4 | ||
52 | |||
53 | struct tx_buf { | ||
54 | u8 *buf; | ||
55 | u16 len; | ||
56 | u16 offset; | ||
57 | struct urb *urb; | ||
58 | struct sk_buff_head skb_queue; | ||
59 | struct hif_device_usb *hif_dev; | ||
60 | struct list_head list; | ||
61 | }; | ||
62 | |||
63 | #define HIF_USB_TX_STOP BIT(0) | ||
64 | |||
65 | struct hif_usb_tx { | ||
66 | u8 flags; | ||
67 | u8 tx_buf_cnt; | ||
68 | u16 tx_skb_cnt; | ||
69 | struct sk_buff_head tx_skb_queue; | ||
70 | struct list_head tx_buf; | ||
71 | struct list_head tx_pending; | ||
72 | spinlock_t tx_lock; | ||
73 | }; | ||
74 | |||
75 | struct cmd_buf { | ||
76 | struct sk_buff *skb; | ||
77 | struct hif_device_usb *hif_dev; | ||
78 | }; | ||
79 | |||
80 | #define HIF_USB_START BIT(0) | ||
81 | |||
82 | struct hif_device_usb { | ||
83 | u16 device_id; | ||
84 | struct usb_device *udev; | ||
85 | struct usb_interface *interface; | ||
86 | const struct firmware *firmware; | ||
87 | struct htc_target *htc_handle; | ||
88 | struct hif_usb_tx tx; | ||
89 | struct urb *reg_in_urb; | ||
90 | struct usb_anchor regout_submitted; | ||
91 | struct usb_anchor rx_submitted; | ||
92 | struct sk_buff *remain_skb; | ||
93 | int rx_remain_len; | ||
94 | int rx_pkt_len; | ||
95 | int rx_transfer_len; | ||
96 | int rx_pad_len; | ||
97 | spinlock_t rx_lock; | ||
98 | u8 flags; /* HIF_USB_* */ | ||
99 | }; | ||
100 | |||
101 | int ath9k_hif_usb_init(void); | ||
102 | void ath9k_hif_usb_exit(void); | ||
103 | |||
104 | #endif /* HTC_USB_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h new file mode 100644 index 000000000000..ad556aa8da39 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -0,0 +1,464 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef HTC_H | ||
18 | #define HTC_H | ||
19 | |||
20 | #include <linux/module.h> | ||
21 | #include <linux/usb.h> | ||
22 | #include <linux/firmware.h> | ||
23 | #include <linux/skbuff.h> | ||
24 | #include <linux/netdevice.h> | ||
25 | #include <linux/leds.h> | ||
26 | #include <net/mac80211.h> | ||
27 | |||
28 | #include "common.h" | ||
29 | #include "htc_hst.h" | ||
30 | #include "hif_usb.h" | ||
31 | #include "wmi.h" | ||
32 | |||
33 | #define ATH_STA_SHORT_CALINTERVAL 1000 /* 1 second */ | ||
34 | #define ATH_ANI_POLLINTERVAL 100 /* 100 ms */ | ||
35 | #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ | ||
36 | #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ | ||
37 | |||
38 | #define ATH_DEFAULT_BMISS_LIMIT 10 | ||
39 | #define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024) | ||
40 | #define TSF_TO_TU(_h, _l) \ | ||
41 | ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10)) | ||
42 | |||
43 | extern struct ieee80211_ops ath9k_htc_ops; | ||
44 | extern int htc_modparam_nohwcrypt; | ||
45 | |||
46 | enum htc_phymode { | ||
47 | HTC_MODE_AUTO = 0, | ||
48 | HTC_MODE_11A = 1, | ||
49 | HTC_MODE_11B = 2, | ||
50 | HTC_MODE_11G = 3, | ||
51 | HTC_MODE_FH = 4, | ||
52 | HTC_MODE_TURBO_A = 5, | ||
53 | HTC_MODE_TURBO_G = 6, | ||
54 | HTC_MODE_11NA = 7, | ||
55 | HTC_MODE_11NG = 8 | ||
56 | }; | ||
57 | |||
58 | enum htc_opmode { | ||
59 | HTC_M_STA = 1, | ||
60 | HTC_M_IBSS = 0, | ||
61 | HTC_M_AHDEMO = 3, | ||
62 | HTC_M_HOSTAP = 6, | ||
63 | HTC_M_MONITOR = 8, | ||
64 | HTC_M_WDS = 2 | ||
65 | }; | ||
66 | |||
67 | #define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr) | ||
68 | #define ATH9K_HTC_AMPDU 1 | ||
69 | #define ATH9K_HTC_NORMAL 2 | ||
70 | |||
71 | #define ATH9K_HTC_TX_CTSONLY 0x1 | ||
72 | #define ATH9K_HTC_TX_RTSCTS 0x2 | ||
73 | #define ATH9K_HTC_TX_USE_MIN_RATE 0x100 | ||
74 | |||
75 | struct tx_frame_hdr { | ||
76 | u8 data_type; | ||
77 | u8 node_idx; | ||
78 | u8 vif_idx; | ||
79 | u8 tidno; | ||
80 | u32 flags; /* ATH9K_HTC_TX_* */ | ||
81 | u8 key_type; | ||
82 | u8 keyix; | ||
83 | u8 reserved[26]; | ||
84 | } __packed; | ||
85 | |||
86 | struct tx_mgmt_hdr { | ||
87 | u8 node_idx; | ||
88 | u8 vif_idx; | ||
89 | u8 tidno; | ||
90 | u8 flags; | ||
91 | u8 key_type; | ||
92 | u8 keyix; | ||
93 | u16 reserved; | ||
94 | } __packed; | ||
95 | |||
96 | struct tx_beacon_header { | ||
97 | u8 len_changed; | ||
98 | u8 vif_index; | ||
99 | u16 rev; | ||
100 | } __packed; | ||
101 | |||
102 | struct ath9k_htc_target_hw { | ||
103 | u32 flags; | ||
104 | u32 flags_ext; | ||
105 | u32 ampdu_limit; | ||
106 | u8 ampdu_subframes; | ||
107 | u8 tx_chainmask; | ||
108 | u8 tx_chainmask_legacy; | ||
109 | u8 rtscts_ratecode; | ||
110 | u8 protmode; | ||
111 | } __packed; | ||
112 | |||
113 | struct ath9k_htc_cap_target { | ||
114 | u32 flags; | ||
115 | u32 flags_ext; | ||
116 | u32 ampdu_limit; | ||
117 | u8 ampdu_subframes; | ||
118 | u8 tx_chainmask; | ||
119 | u8 tx_chainmask_legacy; | ||
120 | u8 rtscts_ratecode; | ||
121 | u8 protmode; | ||
122 | } __packed; | ||
123 | |||
124 | struct ath9k_htc_target_vif { | ||
125 | u8 index; | ||
126 | u8 des_bssid[ETH_ALEN]; | ||
127 | __be32 opmode; | ||
128 | u8 myaddr[ETH_ALEN]; | ||
129 | u8 bssid[ETH_ALEN]; | ||
130 | u32 flags; | ||
131 | u32 flags_ext; | ||
132 | u16 ps_sta; | ||
133 | __be16 rtsthreshold; | ||
134 | u8 ath_cap; | ||
135 | u8 node; | ||
136 | s8 mcast_rate; | ||
137 | } __packed; | ||
138 | |||
139 | #define ATH_HTC_STA_AUTH 0x0001 | ||
140 | #define ATH_HTC_STA_QOS 0x0002 | ||
141 | #define ATH_HTC_STA_ERP 0x0004 | ||
142 | #define ATH_HTC_STA_HT 0x0008 | ||
143 | |||
144 | /* FIXME: UAPSD variables */ | ||
145 | struct ath9k_htc_target_sta { | ||
146 | u16 associd; | ||
147 | u16 txpower; | ||
148 | u32 ucastkey; | ||
149 | u8 macaddr[ETH_ALEN]; | ||
150 | u8 bssid[ETH_ALEN]; | ||
151 | u8 sta_index; | ||
152 | u8 vif_index; | ||
153 | u8 vif_sta; | ||
154 | __be16 flags; /* ATH_HTC_STA_* */ | ||
155 | u16 htcap; | ||
156 | u8 valid; | ||
157 | u16 capinfo; | ||
158 | struct ath9k_htc_target_hw *hw; | ||
159 | struct ath9k_htc_target_vif *vif; | ||
160 | u16 txseqmgmt; | ||
161 | u8 is_vif_sta; | ||
162 | u16 maxampdu; | ||
163 | u16 iv16; | ||
164 | u32 iv32; | ||
165 | } __packed; | ||
166 | |||
167 | struct ath9k_htc_target_aggr { | ||
168 | u8 sta_index; | ||
169 | u8 tidno; | ||
170 | u8 aggr_enable; | ||
171 | u8 padding; | ||
172 | } __packed; | ||
173 | |||
174 | #define ATH_HTC_RATE_MAX 30 | ||
175 | |||
176 | #define WLAN_RC_DS_FLAG 0x01 | ||
177 | #define WLAN_RC_40_FLAG 0x02 | ||
178 | #define WLAN_RC_SGI_FLAG 0x04 | ||
179 | #define WLAN_RC_HT_FLAG 0x08 | ||
180 | |||
181 | struct ath9k_htc_rateset { | ||
182 | u8 rs_nrates; | ||
183 | u8 rs_rates[ATH_HTC_RATE_MAX]; | ||
184 | }; | ||
185 | |||
186 | struct ath9k_htc_rate { | ||
187 | struct ath9k_htc_rateset legacy_rates; | ||
188 | struct ath9k_htc_rateset ht_rates; | ||
189 | } __packed; | ||
190 | |||
191 | struct ath9k_htc_target_rate { | ||
192 | u8 sta_index; | ||
193 | u8 isnew; | ||
194 | __be32 capflags; | ||
195 | struct ath9k_htc_rate rates; | ||
196 | }; | ||
197 | |||
198 | struct ath9k_htc_target_stats { | ||
199 | __be32 tx_shortretry; | ||
200 | __be32 tx_longretry; | ||
201 | __be32 tx_xretries; | ||
202 | __be32 ht_txunaggr_xretry; | ||
203 | __be32 ht_tx_xretries; | ||
204 | } __packed; | ||
205 | |||
206 | struct ath9k_htc_vif { | ||
207 | u8 index; | ||
208 | }; | ||
209 | |||
210 | #define ATH9K_HTC_MAX_STA 8 | ||
211 | #define ATH9K_HTC_MAX_TID 8 | ||
212 | |||
213 | enum tid_aggr_state { | ||
214 | AGGR_STOP = 0, | ||
215 | AGGR_PROGRESS, | ||
216 | AGGR_START, | ||
217 | AGGR_OPERATIONAL | ||
218 | }; | ||
219 | |||
220 | struct ath9k_htc_sta { | ||
221 | u8 index; | ||
222 | enum tid_aggr_state tid_state[ATH9K_HTC_MAX_TID]; | ||
223 | }; | ||
224 | |||
225 | struct ath9k_htc_aggr_work { | ||
226 | u16 tid; | ||
227 | u8 sta_addr[ETH_ALEN]; | ||
228 | struct ieee80211_hw *hw; | ||
229 | struct ieee80211_vif *vif; | ||
230 | enum ieee80211_ampdu_mlme_action action; | ||
231 | struct mutex mutex; | ||
232 | }; | ||
233 | |||
234 | #define ATH9K_HTC_RXBUF 256 | ||
235 | #define HTC_RX_FRAME_HEADER_SIZE 40 | ||
236 | |||
237 | struct ath9k_htc_rxbuf { | ||
238 | bool in_process; | ||
239 | struct sk_buff *skb; | ||
240 | struct ath_htc_rx_status rxstatus; | ||
241 | struct list_head list; | ||
242 | }; | ||
243 | |||
244 | struct ath9k_htc_rx { | ||
245 | int last_rssi; /* FIXME: per-STA */ | ||
246 | struct list_head rxbuf; | ||
247 | spinlock_t rxbuflock; | ||
248 | }; | ||
249 | |||
250 | struct ath9k_htc_tx_ctl { | ||
251 | u8 type; /* ATH9K_HTC_* */ | ||
252 | }; | ||
253 | |||
254 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
255 | |||
256 | #define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) | ||
257 | #define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) | ||
258 | |||
259 | struct ath_tx_stats { | ||
260 | u32 buf_queued; | ||
261 | u32 buf_completed; | ||
262 | u32 skb_queued; | ||
263 | u32 skb_completed; | ||
264 | u32 skb_dropped; | ||
265 | }; | ||
266 | |||
267 | struct ath_rx_stats { | ||
268 | u32 skb_allocated; | ||
269 | u32 skb_completed; | ||
270 | u32 skb_dropped; | ||
271 | }; | ||
272 | |||
273 | struct ath9k_debug { | ||
274 | struct dentry *debugfs_phy; | ||
275 | struct dentry *debugfs_tgt_stats; | ||
276 | struct dentry *debugfs_xmit; | ||
277 | struct dentry *debugfs_recv; | ||
278 | struct ath_tx_stats tx_stats; | ||
279 | struct ath_rx_stats rx_stats; | ||
280 | u32 txrate; | ||
281 | }; | ||
282 | |||
283 | #else | ||
284 | |||
285 | #define TX_STAT_INC(c) do { } while (0) | ||
286 | #define RX_STAT_INC(c) do { } while (0) | ||
287 | |||
288 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | ||
289 | |||
290 | #define ATH_LED_PIN_DEF 1 | ||
291 | #define ATH_LED_PIN_9287 8 | ||
292 | #define ATH_LED_PIN_9271 15 | ||
293 | #define ATH_LED_ON_DURATION_IDLE 350 /* in msecs */ | ||
294 | #define ATH_LED_OFF_DURATION_IDLE 250 /* in msecs */ | ||
295 | |||
296 | enum ath_led_type { | ||
297 | ATH_LED_RADIO, | ||
298 | ATH_LED_ASSOC, | ||
299 | ATH_LED_TX, | ||
300 | ATH_LED_RX | ||
301 | }; | ||
302 | |||
303 | struct ath_led { | ||
304 | struct ath9k_htc_priv *priv; | ||
305 | struct led_classdev led_cdev; | ||
306 | enum ath_led_type led_type; | ||
307 | struct delayed_work brightness_work; | ||
308 | char name[32]; | ||
309 | bool registered; | ||
310 | int brightness; | ||
311 | }; | ||
312 | |||
313 | struct htc_beacon_config { | ||
314 | u16 beacon_interval; | ||
315 | u16 listen_interval; | ||
316 | u16 dtim_period; | ||
317 | u16 bmiss_timeout; | ||
318 | u8 dtim_count; | ||
319 | }; | ||
320 | |||
321 | #define OP_INVALID BIT(0) | ||
322 | #define OP_SCANNING BIT(1) | ||
323 | #define OP_FULL_RESET BIT(2) | ||
324 | #define OP_LED_ASSOCIATED BIT(3) | ||
325 | #define OP_LED_ON BIT(4) | ||
326 | #define OP_PREAMBLE_SHORT BIT(5) | ||
327 | #define OP_PROTECT_ENABLE BIT(6) | ||
328 | #define OP_TXAGGR BIT(7) | ||
329 | #define OP_ASSOCIATED BIT(8) | ||
330 | #define OP_ENABLE_BEACON BIT(9) | ||
331 | #define OP_LED_DEINIT BIT(10) | ||
332 | #define OP_UNPLUGGED BIT(11) | ||
333 | |||
334 | struct ath9k_htc_priv { | ||
335 | struct device *dev; | ||
336 | struct ieee80211_hw *hw; | ||
337 | struct ath_hw *ah; | ||
338 | struct htc_target *htc; | ||
339 | struct wmi *wmi; | ||
340 | |||
341 | enum htc_endpoint_id wmi_cmd_ep; | ||
342 | enum htc_endpoint_id beacon_ep; | ||
343 | enum htc_endpoint_id cab_ep; | ||
344 | enum htc_endpoint_id uapsd_ep; | ||
345 | enum htc_endpoint_id mgmt_ep; | ||
346 | enum htc_endpoint_id data_be_ep; | ||
347 | enum htc_endpoint_id data_bk_ep; | ||
348 | enum htc_endpoint_id data_vi_ep; | ||
349 | enum htc_endpoint_id data_vo_ep; | ||
350 | |||
351 | u16 op_flags; | ||
352 | u16 curtxpow; | ||
353 | u16 txpowlimit; | ||
354 | u16 nvifs; | ||
355 | u16 nstations; | ||
356 | u16 seq_no; | ||
357 | u32 bmiss_cnt; | ||
358 | |||
359 | spinlock_t beacon_lock; | ||
360 | |||
361 | bool tx_queues_stop; | ||
362 | spinlock_t tx_lock; | ||
363 | |||
364 | struct ieee80211_vif *vif; | ||
365 | struct htc_beacon_config cur_beacon_conf; | ||
366 | unsigned int rxfilter; | ||
367 | struct tasklet_struct wmi_tasklet; | ||
368 | struct tasklet_struct rx_tasklet; | ||
369 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | ||
370 | struct ath9k_htc_rx rx; | ||
371 | struct tasklet_struct tx_tasklet; | ||
372 | struct sk_buff_head tx_queue; | ||
373 | struct ath9k_htc_aggr_work aggr_work; | ||
374 | struct delayed_work ath9k_aggr_work; | ||
375 | struct delayed_work ath9k_ani_work; | ||
376 | struct work_struct ps_work; | ||
377 | |||
378 | struct mutex htc_pm_lock; | ||
379 | unsigned long ps_usecount; | ||
380 | bool ps_enabled; | ||
381 | bool ps_idle; | ||
382 | |||
383 | struct ath_led radio_led; | ||
384 | struct ath_led assoc_led; | ||
385 | struct ath_led tx_led; | ||
386 | struct ath_led rx_led; | ||
387 | struct delayed_work ath9k_led_blink_work; | ||
388 | int led_on_duration; | ||
389 | int led_off_duration; | ||
390 | int led_on_cnt; | ||
391 | int led_off_cnt; | ||
392 | int hwq_map[ATH9K_WME_AC_VO+1]; | ||
393 | |||
394 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
395 | struct ath9k_debug debug; | ||
396 | #endif | ||
397 | struct ath9k_htc_target_rate tgt_rate; | ||
398 | |||
399 | struct mutex mutex; | ||
400 | }; | ||
401 | |||
402 | static inline void ath_read_cachesize(struct ath_common *common, int *csz) | ||
403 | { | ||
404 | common->bus_ops->read_cachesize(common, csz); | ||
405 | } | ||
406 | |||
407 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | ||
408 | struct ieee80211_vif *vif); | ||
409 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending); | ||
410 | |||
411 | void ath9k_htc_rxep(void *priv, struct sk_buff *skb, | ||
412 | enum htc_endpoint_id ep_id); | ||
413 | void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id, | ||
414 | bool txok); | ||
415 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | ||
416 | enum htc_endpoint_id ep_id, bool txok); | ||
417 | |||
418 | void ath9k_htc_station_work(struct work_struct *work); | ||
419 | void ath9k_htc_aggr_work(struct work_struct *work); | ||
420 | void ath9k_ani_work(struct work_struct *work);; | ||
421 | |||
422 | int ath9k_tx_init(struct ath9k_htc_priv *priv); | ||
423 | void ath9k_tx_tasklet(unsigned long data); | ||
424 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb); | ||
425 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv); | ||
426 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, | ||
427 | enum ath9k_tx_queue_subtype qtype); | ||
428 | int get_hw_qnum(u16 queue, int *hwq_map); | ||
429 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | ||
430 | struct ath9k_tx_queue_info *qinfo); | ||
431 | |||
432 | int ath9k_rx_init(struct ath9k_htc_priv *priv); | ||
433 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv); | ||
434 | void ath9k_host_rx_init(struct ath9k_htc_priv *priv); | ||
435 | void ath9k_rx_tasklet(unsigned long data); | ||
436 | u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv); | ||
437 | |||
438 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); | ||
439 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); | ||
440 | void ath9k_ps_work(struct work_struct *work); | ||
441 | |||
442 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | ||
443 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | ||
444 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv); | ||
445 | |||
446 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | ||
447 | u16 devid); | ||
448 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); | ||
449 | #ifdef CONFIG_PM | ||
450 | int ath9k_htc_resume(struct htc_target *htc_handle); | ||
451 | #endif | ||
452 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
453 | int ath9k_htc_debug_create_root(void); | ||
454 | void ath9k_htc_debug_remove_root(void); | ||
455 | int ath9k_htc_init_debug(struct ath_hw *ah); | ||
456 | void ath9k_htc_exit_debug(struct ath_hw *ah); | ||
457 | #else | ||
458 | static inline int ath9k_htc_debug_create_root(void) { return 0; }; | ||
459 | static inline void ath9k_htc_debug_remove_root(void) {}; | ||
460 | static inline int ath9k_htc_init_debug(struct ath_hw *ah) { return 0; }; | ||
461 | static inline void ath9k_htc_exit_debug(struct ath_hw *ah) {}; | ||
462 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | ||
463 | |||
464 | #endif /* HTC_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c new file mode 100644 index 000000000000..c10c7d002eb7 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c | |||
@@ -0,0 +1,255 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | #define FUDGE 2 | ||
20 | |||
21 | static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv, | ||
22 | struct htc_beacon_config *bss_conf) | ||
23 | { | ||
24 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
25 | struct ath9k_beacon_state bs; | ||
26 | enum ath9k_int imask = 0; | ||
27 | int dtimperiod, dtimcount, sleepduration; | ||
28 | int cfpperiod, cfpcount, bmiss_timeout; | ||
29 | u32 nexttbtt = 0, intval, tsftu; | ||
30 | __be32 htc_imask = 0; | ||
31 | u64 tsf; | ||
32 | int num_beacons, offset, dtim_dec_count, cfp_dec_count; | ||
33 | int ret; | ||
34 | u8 cmd_rsp; | ||
35 | |||
36 | memset(&bs, 0, sizeof(bs)); | ||
37 | |||
38 | intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; | ||
39 | bmiss_timeout = (ATH_DEFAULT_BMISS_LIMIT * bss_conf->beacon_interval); | ||
40 | |||
41 | /* | ||
42 | * Setup dtim and cfp parameters according to | ||
43 | * last beacon we received (which may be none). | ||
44 | */ | ||
45 | dtimperiod = bss_conf->dtim_period; | ||
46 | if (dtimperiod <= 0) /* NB: 0 if not known */ | ||
47 | dtimperiod = 1; | ||
48 | dtimcount = 1; | ||
49 | if (dtimcount >= dtimperiod) /* NB: sanity check */ | ||
50 | dtimcount = 0; | ||
51 | cfpperiod = 1; /* NB: no PCF support yet */ | ||
52 | cfpcount = 0; | ||
53 | |||
54 | sleepduration = intval; | ||
55 | if (sleepduration <= 0) | ||
56 | sleepduration = intval; | ||
57 | |||
58 | /* | ||
59 | * Pull nexttbtt forward to reflect the current | ||
60 | * TSF and calculate dtim+cfp state for the result. | ||
61 | */ | ||
62 | tsf = ath9k_hw_gettsf64(priv->ah); | ||
63 | tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE; | ||
64 | |||
65 | num_beacons = tsftu / intval + 1; | ||
66 | offset = tsftu % intval; | ||
67 | nexttbtt = tsftu - offset; | ||
68 | if (offset) | ||
69 | nexttbtt += intval; | ||
70 | |||
71 | /* DTIM Beacon every dtimperiod Beacon */ | ||
72 | dtim_dec_count = num_beacons % dtimperiod; | ||
73 | /* CFP every cfpperiod DTIM Beacon */ | ||
74 | cfp_dec_count = (num_beacons / dtimperiod) % cfpperiod; | ||
75 | if (dtim_dec_count) | ||
76 | cfp_dec_count++; | ||
77 | |||
78 | dtimcount -= dtim_dec_count; | ||
79 | if (dtimcount < 0) | ||
80 | dtimcount += dtimperiod; | ||
81 | |||
82 | cfpcount -= cfp_dec_count; | ||
83 | if (cfpcount < 0) | ||
84 | cfpcount += cfpperiod; | ||
85 | |||
86 | bs.bs_intval = intval; | ||
87 | bs.bs_nexttbtt = nexttbtt; | ||
88 | bs.bs_dtimperiod = dtimperiod*intval; | ||
89 | bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval; | ||
90 | bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod; | ||
91 | bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod; | ||
92 | bs.bs_cfpmaxduration = 0; | ||
93 | |||
94 | /* | ||
95 | * Calculate the number of consecutive beacons to miss* before taking | ||
96 | * a BMISS interrupt. The configuration is specified in TU so we only | ||
97 | * need calculate based on the beacon interval. Note that we clamp the | ||
98 | * result to at most 15 beacons. | ||
99 | */ | ||
100 | if (sleepduration > intval) { | ||
101 | bs.bs_bmissthreshold = ATH_DEFAULT_BMISS_LIMIT / 2; | ||
102 | } else { | ||
103 | bs.bs_bmissthreshold = DIV_ROUND_UP(bmiss_timeout, intval); | ||
104 | if (bs.bs_bmissthreshold > 15) | ||
105 | bs.bs_bmissthreshold = 15; | ||
106 | else if (bs.bs_bmissthreshold <= 0) | ||
107 | bs.bs_bmissthreshold = 1; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Calculate sleep duration. The configuration is given in ms. | ||
112 | * We ensure a multiple of the beacon period is used. Also, if the sleep | ||
113 | * duration is greater than the DTIM period then it makes senses | ||
114 | * to make it a multiple of that. | ||
115 | * | ||
116 | * XXX fixed at 100ms | ||
117 | */ | ||
118 | |||
119 | bs.bs_sleepduration = roundup(IEEE80211_MS_TO_TU(100), sleepduration); | ||
120 | if (bs.bs_sleepduration > bs.bs_dtimperiod) | ||
121 | bs.bs_sleepduration = bs.bs_dtimperiod; | ||
122 | |||
123 | /* TSF out of range threshold fixed at 1 second */ | ||
124 | bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; | ||
125 | |||
126 | ath_print(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); | ||
127 | ath_print(common, ATH_DBG_BEACON, | ||
128 | "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", | ||
129 | bs.bs_bmissthreshold, bs.bs_sleepduration, | ||
130 | bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); | ||
131 | |||
132 | /* Set the computed STA beacon timers */ | ||
133 | |||
134 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | ||
135 | ath9k_hw_set_sta_beacon_timers(priv->ah, &bs); | ||
136 | imask |= ATH9K_INT_BMISS; | ||
137 | htc_imask = cpu_to_be32(imask); | ||
138 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | ||
139 | } | ||
140 | |||
141 | static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv, | ||
142 | struct htc_beacon_config *bss_conf) | ||
143 | { | ||
144 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
145 | enum ath9k_int imask = 0; | ||
146 | u32 nexttbtt, intval; | ||
147 | __be32 htc_imask = 0; | ||
148 | int ret; | ||
149 | u8 cmd_rsp; | ||
150 | |||
151 | intval = bss_conf->beacon_interval & ATH9K_BEACON_PERIOD; | ||
152 | nexttbtt = intval; | ||
153 | intval |= ATH9K_BEACON_ENA; | ||
154 | if (priv->op_flags & OP_ENABLE_BEACON) | ||
155 | imask |= ATH9K_INT_SWBA; | ||
156 | |||
157 | ath_print(common, ATH_DBG_BEACON, | ||
158 | "IBSS Beacon config, intval: %d, imask: 0x%x\n", | ||
159 | bss_conf->beacon_interval, imask); | ||
160 | |||
161 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | ||
162 | ath9k_hw_beaconinit(priv->ah, nexttbtt, intval); | ||
163 | priv->bmiss_cnt = 0; | ||
164 | htc_imask = cpu_to_be32(imask); | ||
165 | WMI_CMD_BUF(WMI_ENABLE_INTR_CMDID, &htc_imask); | ||
166 | } | ||
167 | |||
168 | void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb, | ||
169 | enum htc_endpoint_id ep_id, bool txok) | ||
170 | { | ||
171 | dev_kfree_skb_any(skb); | ||
172 | } | ||
173 | |||
174 | void ath9k_htc_swba(struct ath9k_htc_priv *priv, u8 beacon_pending) | ||
175 | { | ||
176 | struct ath9k_htc_vif *avp = (void *)priv->vif->drv_priv; | ||
177 | struct tx_beacon_header beacon_hdr; | ||
178 | struct ath9k_htc_tx_ctl tx_ctl; | ||
179 | struct ieee80211_tx_info *info; | ||
180 | struct sk_buff *beacon; | ||
181 | u8 *tx_fhdr; | ||
182 | |||
183 | memset(&beacon_hdr, 0, sizeof(struct tx_beacon_header)); | ||
184 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | ||
185 | |||
186 | /* FIXME: Handle BMISS */ | ||
187 | if (beacon_pending != 0) { | ||
188 | priv->bmiss_cnt++; | ||
189 | return; | ||
190 | } | ||
191 | |||
192 | spin_lock_bh(&priv->beacon_lock); | ||
193 | |||
194 | if (unlikely(priv->op_flags & OP_SCANNING)) { | ||
195 | spin_unlock_bh(&priv->beacon_lock); | ||
196 | return; | ||
197 | } | ||
198 | |||
199 | /* Get a new beacon */ | ||
200 | beacon = ieee80211_beacon_get(priv->hw, priv->vif); | ||
201 | if (!beacon) { | ||
202 | spin_unlock_bh(&priv->beacon_lock); | ||
203 | return; | ||
204 | } | ||
205 | |||
206 | info = IEEE80211_SKB_CB(beacon); | ||
207 | if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { | ||
208 | struct ieee80211_hdr *hdr = | ||
209 | (struct ieee80211_hdr *) beacon->data; | ||
210 | priv->seq_no += 0x10; | ||
211 | hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); | ||
212 | hdr->seq_ctrl |= cpu_to_le16(priv->seq_no); | ||
213 | } | ||
214 | |||
215 | tx_ctl.type = ATH9K_HTC_NORMAL; | ||
216 | beacon_hdr.vif_index = avp->index; | ||
217 | tx_fhdr = skb_push(beacon, sizeof(beacon_hdr)); | ||
218 | memcpy(tx_fhdr, (u8 *) &beacon_hdr, sizeof(beacon_hdr)); | ||
219 | |||
220 | htc_send(priv->htc, beacon, priv->beacon_ep, &tx_ctl); | ||
221 | |||
222 | spin_unlock_bh(&priv->beacon_lock); | ||
223 | } | ||
224 | |||
225 | |||
226 | void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, | ||
227 | struct ieee80211_vif *vif) | ||
228 | { | ||
229 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
230 | struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; | ||
231 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
232 | |||
233 | cur_conf->beacon_interval = bss_conf->beacon_int; | ||
234 | if (cur_conf->beacon_interval == 0) | ||
235 | cur_conf->beacon_interval = 100; | ||
236 | |||
237 | cur_conf->dtim_period = bss_conf->dtim_period; | ||
238 | cur_conf->listen_interval = 1; | ||
239 | cur_conf->dtim_count = 1; | ||
240 | cur_conf->bmiss_timeout = | ||
241 | ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval; | ||
242 | |||
243 | switch (vif->type) { | ||
244 | case NL80211_IFTYPE_STATION: | ||
245 | ath9k_htc_beacon_config_sta(priv, cur_conf); | ||
246 | break; | ||
247 | case NL80211_IFTYPE_ADHOC: | ||
248 | ath9k_htc_beacon_config_adhoc(priv, cur_conf); | ||
249 | break; | ||
250 | default: | ||
251 | ath_print(common, ATH_DBG_CONFIG, | ||
252 | "Unsupported beaconing mode\n"); | ||
253 | return; | ||
254 | } | ||
255 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c new file mode 100644 index 000000000000..dc015077a8d9 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -0,0 +1,834 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | MODULE_AUTHOR("Atheros Communications"); | ||
20 | MODULE_LICENSE("Dual BSD/GPL"); | ||
21 | MODULE_DESCRIPTION("Atheros driver 802.11n HTC based wireless devices"); | ||
22 | |||
23 | static unsigned int ath9k_debug = ATH_DBG_DEFAULT; | ||
24 | module_param_named(debug, ath9k_debug, uint, 0); | ||
25 | MODULE_PARM_DESC(debug, "Debugging mask"); | ||
26 | |||
27 | int htc_modparam_nohwcrypt; | ||
28 | module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444); | ||
29 | MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); | ||
30 | |||
31 | #define CHAN2G(_freq, _idx) { \ | ||
32 | .center_freq = (_freq), \ | ||
33 | .hw_value = (_idx), \ | ||
34 | .max_power = 20, \ | ||
35 | } | ||
36 | |||
37 | static struct ieee80211_channel ath9k_2ghz_channels[] = { | ||
38 | CHAN2G(2412, 0), /* Channel 1 */ | ||
39 | CHAN2G(2417, 1), /* Channel 2 */ | ||
40 | CHAN2G(2422, 2), /* Channel 3 */ | ||
41 | CHAN2G(2427, 3), /* Channel 4 */ | ||
42 | CHAN2G(2432, 4), /* Channel 5 */ | ||
43 | CHAN2G(2437, 5), /* Channel 6 */ | ||
44 | CHAN2G(2442, 6), /* Channel 7 */ | ||
45 | CHAN2G(2447, 7), /* Channel 8 */ | ||
46 | CHAN2G(2452, 8), /* Channel 9 */ | ||
47 | CHAN2G(2457, 9), /* Channel 10 */ | ||
48 | CHAN2G(2462, 10), /* Channel 11 */ | ||
49 | CHAN2G(2467, 11), /* Channel 12 */ | ||
50 | CHAN2G(2472, 12), /* Channel 13 */ | ||
51 | CHAN2G(2484, 13), /* Channel 14 */ | ||
52 | }; | ||
53 | |||
54 | /* Atheros hardware rate code addition for short premble */ | ||
55 | #define SHPCHECK(__hw_rate, __flags) \ | ||
56 | ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04) : 0) | ||
57 | |||
58 | #define RATE(_bitrate, _hw_rate, _flags) { \ | ||
59 | .bitrate = (_bitrate), \ | ||
60 | .flags = (_flags), \ | ||
61 | .hw_value = (_hw_rate), \ | ||
62 | .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \ | ||
63 | } | ||
64 | |||
65 | static struct ieee80211_rate ath9k_legacy_rates[] = { | ||
66 | RATE(10, 0x1b, 0), | ||
67 | RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp : 0x1e */ | ||
68 | RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE), /* shortp: 0x1d */ | ||
69 | RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE), /* short: 0x1c */ | ||
70 | RATE(60, 0x0b, 0), | ||
71 | RATE(90, 0x0f, 0), | ||
72 | RATE(120, 0x0a, 0), | ||
73 | RATE(180, 0x0e, 0), | ||
74 | RATE(240, 0x09, 0), | ||
75 | RATE(360, 0x0d, 0), | ||
76 | RATE(480, 0x08, 0), | ||
77 | RATE(540, 0x0c, 0), | ||
78 | }; | ||
79 | |||
80 | static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv) | ||
81 | { | ||
82 | int time_left; | ||
83 | |||
84 | if (atomic_read(&priv->htc->tgt_ready) > 0) { | ||
85 | atomic_dec(&priv->htc->tgt_ready); | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | /* Firmware can take up to 50ms to get ready, to be safe use 1 second */ | ||
90 | time_left = wait_for_completion_timeout(&priv->htc->target_wait, HZ); | ||
91 | if (!time_left) { | ||
92 | dev_err(priv->dev, "ath9k_htc: Target is unresponsive\n"); | ||
93 | return -ETIMEDOUT; | ||
94 | } | ||
95 | |||
96 | atomic_dec(&priv->htc->tgt_ready); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static void ath9k_deinit_priv(struct ath9k_htc_priv *priv) | ||
102 | { | ||
103 | ath9k_htc_exit_debug(priv->ah); | ||
104 | ath9k_hw_deinit(priv->ah); | ||
105 | tasklet_kill(&priv->wmi_tasklet); | ||
106 | tasklet_kill(&priv->rx_tasklet); | ||
107 | tasklet_kill(&priv->tx_tasklet); | ||
108 | kfree(priv->ah); | ||
109 | priv->ah = NULL; | ||
110 | } | ||
111 | |||
112 | static void ath9k_deinit_device(struct ath9k_htc_priv *priv) | ||
113 | { | ||
114 | struct ieee80211_hw *hw = priv->hw; | ||
115 | |||
116 | wiphy_rfkill_stop_polling(hw->wiphy); | ||
117 | ath9k_deinit_leds(priv); | ||
118 | ieee80211_unregister_hw(hw); | ||
119 | ath9k_rx_cleanup(priv); | ||
120 | ath9k_tx_cleanup(priv); | ||
121 | ath9k_deinit_priv(priv); | ||
122 | } | ||
123 | |||
124 | static inline int ath9k_htc_connect_svc(struct ath9k_htc_priv *priv, | ||
125 | u16 service_id, | ||
126 | void (*tx) (void *, | ||
127 | struct sk_buff *, | ||
128 | enum htc_endpoint_id, | ||
129 | bool txok), | ||
130 | enum htc_endpoint_id *ep_id) | ||
131 | { | ||
132 | struct htc_service_connreq req; | ||
133 | |||
134 | memset(&req, 0, sizeof(struct htc_service_connreq)); | ||
135 | |||
136 | req.service_id = service_id; | ||
137 | req.ep_callbacks.priv = priv; | ||
138 | req.ep_callbacks.rx = ath9k_htc_rxep; | ||
139 | req.ep_callbacks.tx = tx; | ||
140 | |||
141 | return htc_connect_service(priv->htc, &req, ep_id); | ||
142 | } | ||
143 | |||
144 | static int ath9k_init_htc_services(struct ath9k_htc_priv *priv) | ||
145 | { | ||
146 | int ret; | ||
147 | |||
148 | /* WMI CMD*/ | ||
149 | ret = ath9k_wmi_connect(priv->htc, priv->wmi, &priv->wmi_cmd_ep); | ||
150 | if (ret) | ||
151 | goto err; | ||
152 | |||
153 | /* Beacon */ | ||
154 | ret = ath9k_htc_connect_svc(priv, WMI_BEACON_SVC, ath9k_htc_beaconep, | ||
155 | &priv->beacon_ep); | ||
156 | if (ret) | ||
157 | goto err; | ||
158 | |||
159 | /* CAB */ | ||
160 | ret = ath9k_htc_connect_svc(priv, WMI_CAB_SVC, ath9k_htc_txep, | ||
161 | &priv->cab_ep); | ||
162 | if (ret) | ||
163 | goto err; | ||
164 | |||
165 | |||
166 | /* UAPSD */ | ||
167 | ret = ath9k_htc_connect_svc(priv, WMI_UAPSD_SVC, ath9k_htc_txep, | ||
168 | &priv->uapsd_ep); | ||
169 | if (ret) | ||
170 | goto err; | ||
171 | |||
172 | /* MGMT */ | ||
173 | ret = ath9k_htc_connect_svc(priv, WMI_MGMT_SVC, ath9k_htc_txep, | ||
174 | &priv->mgmt_ep); | ||
175 | if (ret) | ||
176 | goto err; | ||
177 | |||
178 | /* DATA BE */ | ||
179 | ret = ath9k_htc_connect_svc(priv, WMI_DATA_BE_SVC, ath9k_htc_txep, | ||
180 | &priv->data_be_ep); | ||
181 | if (ret) | ||
182 | goto err; | ||
183 | |||
184 | /* DATA BK */ | ||
185 | ret = ath9k_htc_connect_svc(priv, WMI_DATA_BK_SVC, ath9k_htc_txep, | ||
186 | &priv->data_bk_ep); | ||
187 | if (ret) | ||
188 | goto err; | ||
189 | |||
190 | /* DATA VI */ | ||
191 | ret = ath9k_htc_connect_svc(priv, WMI_DATA_VI_SVC, ath9k_htc_txep, | ||
192 | &priv->data_vi_ep); | ||
193 | if (ret) | ||
194 | goto err; | ||
195 | |||
196 | /* DATA VO */ | ||
197 | ret = ath9k_htc_connect_svc(priv, WMI_DATA_VO_SVC, ath9k_htc_txep, | ||
198 | &priv->data_vo_ep); | ||
199 | if (ret) | ||
200 | goto err; | ||
201 | |||
202 | ret = htc_init(priv->htc); | ||
203 | if (ret) | ||
204 | goto err; | ||
205 | |||
206 | return 0; | ||
207 | |||
208 | err: | ||
209 | dev_err(priv->dev, "ath9k_htc: Unable to initialize HTC services\n"); | ||
210 | return ret; | ||
211 | } | ||
212 | |||
213 | static int ath9k_reg_notifier(struct wiphy *wiphy, | ||
214 | struct regulatory_request *request) | ||
215 | { | ||
216 | struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); | ||
217 | struct ath9k_htc_priv *priv = hw->priv; | ||
218 | |||
219 | return ath_reg_notifier_apply(wiphy, request, | ||
220 | ath9k_hw_regulatory(priv->ah)); | ||
221 | } | ||
222 | |||
223 | static unsigned int ath9k_regread(void *hw_priv, u32 reg_offset) | ||
224 | { | ||
225 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
226 | struct ath_common *common = ath9k_hw_common(ah); | ||
227 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
228 | __be32 val, reg = cpu_to_be32(reg_offset); | ||
229 | int r; | ||
230 | |||
231 | r = ath9k_wmi_cmd(priv->wmi, WMI_REG_READ_CMDID, | ||
232 | (u8 *) ®, sizeof(reg), | ||
233 | (u8 *) &val, sizeof(val), | ||
234 | 100); | ||
235 | if (unlikely(r)) { | ||
236 | ath_print(common, ATH_DBG_WMI, | ||
237 | "REGISTER READ FAILED: (0x%04x, %d)\n", | ||
238 | reg_offset, r); | ||
239 | return -EIO; | ||
240 | } | ||
241 | |||
242 | return be32_to_cpu(val); | ||
243 | } | ||
244 | |||
245 | static void ath9k_regwrite_single(void *hw_priv, u32 val, u32 reg_offset) | ||
246 | { | ||
247 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
248 | struct ath_common *common = ath9k_hw_common(ah); | ||
249 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
250 | __be32 buf[2] = { | ||
251 | cpu_to_be32(reg_offset), | ||
252 | cpu_to_be32(val), | ||
253 | }; | ||
254 | int r; | ||
255 | |||
256 | r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, | ||
257 | (u8 *) &buf, sizeof(buf), | ||
258 | (u8 *) &val, sizeof(val), | ||
259 | 100); | ||
260 | if (unlikely(r)) { | ||
261 | ath_print(common, ATH_DBG_WMI, | ||
262 | "REGISTER WRITE FAILED:(0x%04x, %d)\n", | ||
263 | reg_offset, r); | ||
264 | } | ||
265 | } | ||
266 | |||
267 | static void ath9k_regwrite_buffer(void *hw_priv, u32 val, u32 reg_offset) | ||
268 | { | ||
269 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
270 | struct ath_common *common = ath9k_hw_common(ah); | ||
271 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
272 | u32 rsp_status; | ||
273 | int r; | ||
274 | |||
275 | mutex_lock(&priv->wmi->multi_write_mutex); | ||
276 | |||
277 | /* Store the register/value */ | ||
278 | priv->wmi->multi_write[priv->wmi->multi_write_idx].reg = | ||
279 | cpu_to_be32(reg_offset); | ||
280 | priv->wmi->multi_write[priv->wmi->multi_write_idx].val = | ||
281 | cpu_to_be32(val); | ||
282 | |||
283 | priv->wmi->multi_write_idx++; | ||
284 | |||
285 | /* If the buffer is full, send it out. */ | ||
286 | if (priv->wmi->multi_write_idx == MAX_CMD_NUMBER) { | ||
287 | r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, | ||
288 | (u8 *) &priv->wmi->multi_write, | ||
289 | sizeof(struct register_write) * priv->wmi->multi_write_idx, | ||
290 | (u8 *) &rsp_status, sizeof(rsp_status), | ||
291 | 100); | ||
292 | if (unlikely(r)) { | ||
293 | ath_print(common, ATH_DBG_WMI, | ||
294 | "REGISTER WRITE FAILED, multi len: %d\n", | ||
295 | priv->wmi->multi_write_idx); | ||
296 | } | ||
297 | priv->wmi->multi_write_idx = 0; | ||
298 | } | ||
299 | |||
300 | mutex_unlock(&priv->wmi->multi_write_mutex); | ||
301 | } | ||
302 | |||
303 | static void ath9k_regwrite(void *hw_priv, u32 val, u32 reg_offset) | ||
304 | { | ||
305 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
306 | struct ath_common *common = ath9k_hw_common(ah); | ||
307 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
308 | |||
309 | if (atomic_read(&priv->wmi->mwrite_cnt)) | ||
310 | ath9k_regwrite_buffer(hw_priv, val, reg_offset); | ||
311 | else | ||
312 | ath9k_regwrite_single(hw_priv, val, reg_offset); | ||
313 | } | ||
314 | |||
315 | static void ath9k_enable_regwrite_buffer(void *hw_priv) | ||
316 | { | ||
317 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
318 | struct ath_common *common = ath9k_hw_common(ah); | ||
319 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
320 | |||
321 | atomic_inc(&priv->wmi->mwrite_cnt); | ||
322 | } | ||
323 | |||
324 | static void ath9k_disable_regwrite_buffer(void *hw_priv) | ||
325 | { | ||
326 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
327 | struct ath_common *common = ath9k_hw_common(ah); | ||
328 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
329 | |||
330 | atomic_dec(&priv->wmi->mwrite_cnt); | ||
331 | } | ||
332 | |||
333 | static void ath9k_regwrite_flush(void *hw_priv) | ||
334 | { | ||
335 | struct ath_hw *ah = (struct ath_hw *) hw_priv; | ||
336 | struct ath_common *common = ath9k_hw_common(ah); | ||
337 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
338 | u32 rsp_status; | ||
339 | int r; | ||
340 | |||
341 | mutex_lock(&priv->wmi->multi_write_mutex); | ||
342 | |||
343 | if (priv->wmi->multi_write_idx) { | ||
344 | r = ath9k_wmi_cmd(priv->wmi, WMI_REG_WRITE_CMDID, | ||
345 | (u8 *) &priv->wmi->multi_write, | ||
346 | sizeof(struct register_write) * priv->wmi->multi_write_idx, | ||
347 | (u8 *) &rsp_status, sizeof(rsp_status), | ||
348 | 100); | ||
349 | if (unlikely(r)) { | ||
350 | ath_print(common, ATH_DBG_WMI, | ||
351 | "REGISTER WRITE FAILED, multi len: %d\n", | ||
352 | priv->wmi->multi_write_idx); | ||
353 | } | ||
354 | priv->wmi->multi_write_idx = 0; | ||
355 | } | ||
356 | |||
357 | mutex_unlock(&priv->wmi->multi_write_mutex); | ||
358 | } | ||
359 | |||
360 | static const struct ath_ops ath9k_common_ops = { | ||
361 | .read = ath9k_regread, | ||
362 | .write = ath9k_regwrite, | ||
363 | .enable_write_buffer = ath9k_enable_regwrite_buffer, | ||
364 | .disable_write_buffer = ath9k_disable_regwrite_buffer, | ||
365 | .write_flush = ath9k_regwrite_flush, | ||
366 | }; | ||
367 | |||
368 | static void ath_usb_read_cachesize(struct ath_common *common, int *csz) | ||
369 | { | ||
370 | *csz = L1_CACHE_BYTES >> 2; | ||
371 | } | ||
372 | |||
373 | static bool ath_usb_eeprom_read(struct ath_common *common, u32 off, u16 *data) | ||
374 | { | ||
375 | struct ath_hw *ah = (struct ath_hw *) common->ah; | ||
376 | |||
377 | (void)REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S)); | ||
378 | |||
379 | if (!ath9k_hw_wait(ah, | ||
380 | AR_EEPROM_STATUS_DATA, | ||
381 | AR_EEPROM_STATUS_DATA_BUSY | | ||
382 | AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0, | ||
383 | AH_WAIT_TIMEOUT)) | ||
384 | return false; | ||
385 | |||
386 | *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA), | ||
387 | AR_EEPROM_STATUS_DATA_VAL); | ||
388 | |||
389 | return true; | ||
390 | } | ||
391 | |||
392 | static const struct ath_bus_ops ath9k_usb_bus_ops = { | ||
393 | .ath_bus_type = ATH_USB, | ||
394 | .read_cachesize = ath_usb_read_cachesize, | ||
395 | .eeprom_read = ath_usb_eeprom_read, | ||
396 | }; | ||
397 | |||
398 | static void setup_ht_cap(struct ath9k_htc_priv *priv, | ||
399 | struct ieee80211_sta_ht_cap *ht_info) | ||
400 | { | ||
401 | ht_info->ht_supported = true; | ||
402 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | ||
403 | IEEE80211_HT_CAP_SM_PS | | ||
404 | IEEE80211_HT_CAP_SGI_40 | | ||
405 | IEEE80211_HT_CAP_DSSSCCK40; | ||
406 | |||
407 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | ||
408 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | ||
409 | |||
410 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | ||
411 | ht_info->mcs.rx_mask[0] = 0xff; | ||
412 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | ||
413 | } | ||
414 | |||
415 | static int ath9k_init_queues(struct ath9k_htc_priv *priv) | ||
416 | { | ||
417 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
418 | int i; | ||
419 | |||
420 | for (i = 0; i < ARRAY_SIZE(priv->hwq_map); i++) | ||
421 | priv->hwq_map[i] = -1; | ||
422 | |||
423 | if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) { | ||
424 | ath_print(common, ATH_DBG_FATAL, | ||
425 | "Unable to setup xmit queue for BE traffic\n"); | ||
426 | goto err; | ||
427 | } | ||
428 | |||
429 | if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) { | ||
430 | ath_print(common, ATH_DBG_FATAL, | ||
431 | "Unable to setup xmit queue for BK traffic\n"); | ||
432 | goto err; | ||
433 | } | ||
434 | if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) { | ||
435 | ath_print(common, ATH_DBG_FATAL, | ||
436 | "Unable to setup xmit queue for VI traffic\n"); | ||
437 | goto err; | ||
438 | } | ||
439 | if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) { | ||
440 | ath_print(common, ATH_DBG_FATAL, | ||
441 | "Unable to setup xmit queue for VO traffic\n"); | ||
442 | goto err; | ||
443 | } | ||
444 | |||
445 | return 0; | ||
446 | |||
447 | err: | ||
448 | return -EINVAL; | ||
449 | } | ||
450 | |||
451 | static void ath9k_init_crypto(struct ath9k_htc_priv *priv) | ||
452 | { | ||
453 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
454 | int i = 0; | ||
455 | |||
456 | /* Get the hardware key cache size. */ | ||
457 | common->keymax = priv->ah->caps.keycache_size; | ||
458 | if (common->keymax > ATH_KEYMAX) { | ||
459 | ath_print(common, ATH_DBG_ANY, | ||
460 | "Warning, using only %u entries in %u key cache\n", | ||
461 | ATH_KEYMAX, common->keymax); | ||
462 | common->keymax = ATH_KEYMAX; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * Reset the key cache since some parts do not | ||
467 | * reset the contents on initial power up. | ||
468 | */ | ||
469 | for (i = 0; i < common->keymax; i++) | ||
470 | ath9k_hw_keyreset(priv->ah, (u16) i); | ||
471 | |||
472 | if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER, | ||
473 | ATH9K_CIPHER_TKIP, NULL)) { | ||
474 | /* | ||
475 | * Whether we should enable h/w TKIP MIC. | ||
476 | * XXX: if we don't support WME TKIP MIC, then we wouldn't | ||
477 | * report WMM capable, so it's always safe to turn on | ||
478 | * TKIP MIC in this case. | ||
479 | */ | ||
480 | ath9k_hw_setcapability(priv->ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL); | ||
481 | } | ||
482 | |||
483 | /* | ||
484 | * Check whether the separate key cache entries | ||
485 | * are required to handle both tx+rx MIC keys. | ||
486 | * With split mic keys the number of stations is limited | ||
487 | * to 27 otherwise 59. | ||
488 | */ | ||
489 | if (ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER, | ||
490 | ATH9K_CIPHER_TKIP, NULL) | ||
491 | && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_CIPHER, | ||
492 | ATH9K_CIPHER_MIC, NULL) | ||
493 | && ath9k_hw_getcapability(priv->ah, ATH9K_CAP_TKIP_SPLIT, | ||
494 | 0, NULL)) | ||
495 | common->splitmic = 1; | ||
496 | |||
497 | /* turn on mcast key search if possible */ | ||
498 | if (!ath9k_hw_getcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL)) | ||
499 | (void)ath9k_hw_setcapability(priv->ah, ATH9K_CAP_MCAST_KEYSRCH, | ||
500 | 1, 1, NULL); | ||
501 | } | ||
502 | |||
503 | static void ath9k_init_channels_rates(struct ath9k_htc_priv *priv) | ||
504 | { | ||
505 | if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) { | ||
506 | priv->sbands[IEEE80211_BAND_2GHZ].channels = | ||
507 | ath9k_2ghz_channels; | ||
508 | priv->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; | ||
509 | priv->sbands[IEEE80211_BAND_2GHZ].n_channels = | ||
510 | ARRAY_SIZE(ath9k_2ghz_channels); | ||
511 | priv->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates; | ||
512 | priv->sbands[IEEE80211_BAND_2GHZ].n_bitrates = | ||
513 | ARRAY_SIZE(ath9k_legacy_rates); | ||
514 | } | ||
515 | } | ||
516 | |||
517 | static void ath9k_init_misc(struct ath9k_htc_priv *priv) | ||
518 | { | ||
519 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
520 | |||
521 | common->tx_chainmask = priv->ah->caps.tx_chainmask; | ||
522 | common->rx_chainmask = priv->ah->caps.rx_chainmask; | ||
523 | |||
524 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
525 | memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN); | ||
526 | |||
527 | priv->op_flags |= OP_TXAGGR; | ||
528 | priv->ah->opmode = NL80211_IFTYPE_STATION; | ||
529 | } | ||
530 | |||
531 | static int ath9k_init_priv(struct ath9k_htc_priv *priv, u16 devid) | ||
532 | { | ||
533 | struct ath_hw *ah = NULL; | ||
534 | struct ath_common *common; | ||
535 | int ret = 0, csz = 0; | ||
536 | |||
537 | priv->op_flags |= OP_INVALID; | ||
538 | |||
539 | ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL); | ||
540 | if (!ah) | ||
541 | return -ENOMEM; | ||
542 | |||
543 | ah->hw_version.devid = devid; | ||
544 | ah->hw_version.subsysid = 0; /* FIXME */ | ||
545 | priv->ah = ah; | ||
546 | |||
547 | common = ath9k_hw_common(ah); | ||
548 | common->ops = &ath9k_common_ops; | ||
549 | common->bus_ops = &ath9k_usb_bus_ops; | ||
550 | common->ah = ah; | ||
551 | common->hw = priv->hw; | ||
552 | common->priv = priv; | ||
553 | common->debug_mask = ath9k_debug; | ||
554 | |||
555 | spin_lock_init(&priv->wmi->wmi_lock); | ||
556 | spin_lock_init(&priv->beacon_lock); | ||
557 | spin_lock_init(&priv->tx_lock); | ||
558 | mutex_init(&priv->mutex); | ||
559 | mutex_init(&priv->aggr_work.mutex); | ||
560 | mutex_init(&priv->htc_pm_lock); | ||
561 | tasklet_init(&priv->wmi_tasklet, ath9k_wmi_tasklet, | ||
562 | (unsigned long)priv); | ||
563 | tasklet_init(&priv->rx_tasklet, ath9k_rx_tasklet, | ||
564 | (unsigned long)priv); | ||
565 | tasklet_init(&priv->tx_tasklet, ath9k_tx_tasklet, (unsigned long)priv); | ||
566 | INIT_DELAYED_WORK(&priv->ath9k_aggr_work, ath9k_htc_aggr_work); | ||
567 | INIT_DELAYED_WORK(&priv->ath9k_ani_work, ath9k_ani_work); | ||
568 | INIT_WORK(&priv->ps_work, ath9k_ps_work); | ||
569 | |||
570 | /* | ||
571 | * Cache line size is used to size and align various | ||
572 | * structures used to communicate with the hardware. | ||
573 | */ | ||
574 | ath_read_cachesize(common, &csz); | ||
575 | common->cachelsz = csz << 2; /* convert to bytes */ | ||
576 | |||
577 | ret = ath9k_hw_init(ah); | ||
578 | if (ret) { | ||
579 | ath_print(common, ATH_DBG_FATAL, | ||
580 | "Unable to initialize hardware; " | ||
581 | "initialization status: %d\n", ret); | ||
582 | goto err_hw; | ||
583 | } | ||
584 | |||
585 | ret = ath9k_htc_init_debug(ah); | ||
586 | if (ret) { | ||
587 | ath_print(common, ATH_DBG_FATAL, | ||
588 | "Unable to create debugfs files\n"); | ||
589 | goto err_debug; | ||
590 | } | ||
591 | |||
592 | ret = ath9k_init_queues(priv); | ||
593 | if (ret) | ||
594 | goto err_queues; | ||
595 | |||
596 | ath9k_init_crypto(priv); | ||
597 | ath9k_init_channels_rates(priv); | ||
598 | ath9k_init_misc(priv); | ||
599 | |||
600 | return 0; | ||
601 | |||
602 | err_queues: | ||
603 | ath9k_htc_exit_debug(ah); | ||
604 | err_debug: | ||
605 | ath9k_hw_deinit(ah); | ||
606 | err_hw: | ||
607 | |||
608 | kfree(ah); | ||
609 | priv->ah = NULL; | ||
610 | |||
611 | return ret; | ||
612 | } | ||
613 | |||
614 | static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv, | ||
615 | struct ieee80211_hw *hw) | ||
616 | { | ||
617 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
618 | |||
619 | hw->flags = IEEE80211_HW_SIGNAL_DBM | | ||
620 | IEEE80211_HW_AMPDU_AGGREGATION | | ||
621 | IEEE80211_HW_SPECTRUM_MGMT | | ||
622 | IEEE80211_HW_HAS_RATE_CONTROL | | ||
623 | IEEE80211_HW_RX_INCLUDES_FCS | | ||
624 | IEEE80211_HW_SUPPORTS_PS | | ||
625 | IEEE80211_HW_PS_NULLFUNC_STACK; | ||
626 | |||
627 | hw->wiphy->interface_modes = | ||
628 | BIT(NL80211_IFTYPE_STATION) | | ||
629 | BIT(NL80211_IFTYPE_ADHOC); | ||
630 | |||
631 | hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; | ||
632 | |||
633 | hw->queues = 4; | ||
634 | hw->channel_change_time = 5000; | ||
635 | hw->max_listen_interval = 10; | ||
636 | hw->vif_data_size = sizeof(struct ath9k_htc_vif); | ||
637 | hw->sta_data_size = sizeof(struct ath9k_htc_sta); | ||
638 | |||
639 | /* tx_frame_hdr is larger than tx_mgmt_hdr anyway */ | ||
640 | hw->extra_tx_headroom = sizeof(struct tx_frame_hdr) + | ||
641 | sizeof(struct htc_frame_hdr) + 4; | ||
642 | |||
643 | if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) | ||
644 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = | ||
645 | &priv->sbands[IEEE80211_BAND_2GHZ]; | ||
646 | |||
647 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_HT) { | ||
648 | if (test_bit(ATH9K_MODE_11G, priv->ah->caps.wireless_modes)) | ||
649 | setup_ht_cap(priv, | ||
650 | &priv->sbands[IEEE80211_BAND_2GHZ].ht_cap); | ||
651 | } | ||
652 | |||
653 | SET_IEEE80211_PERM_ADDR(hw, common->macaddr); | ||
654 | } | ||
655 | |||
656 | static int ath9k_init_device(struct ath9k_htc_priv *priv, u16 devid) | ||
657 | { | ||
658 | struct ieee80211_hw *hw = priv->hw; | ||
659 | struct ath_common *common; | ||
660 | struct ath_hw *ah; | ||
661 | int error = 0; | ||
662 | struct ath_regulatory *reg; | ||
663 | |||
664 | /* Bring up device */ | ||
665 | error = ath9k_init_priv(priv, devid); | ||
666 | if (error != 0) | ||
667 | goto err_init; | ||
668 | |||
669 | ah = priv->ah; | ||
670 | common = ath9k_hw_common(ah); | ||
671 | ath9k_set_hw_capab(priv, hw); | ||
672 | |||
673 | /* Initialize regulatory */ | ||
674 | error = ath_regd_init(&common->regulatory, priv->hw->wiphy, | ||
675 | ath9k_reg_notifier); | ||
676 | if (error) | ||
677 | goto err_regd; | ||
678 | |||
679 | reg = &common->regulatory; | ||
680 | |||
681 | /* Setup TX */ | ||
682 | error = ath9k_tx_init(priv); | ||
683 | if (error != 0) | ||
684 | goto err_tx; | ||
685 | |||
686 | /* Setup RX */ | ||
687 | error = ath9k_rx_init(priv); | ||
688 | if (error != 0) | ||
689 | goto err_rx; | ||
690 | |||
691 | /* Register with mac80211 */ | ||
692 | error = ieee80211_register_hw(hw); | ||
693 | if (error) | ||
694 | goto err_register; | ||
695 | |||
696 | /* Handle world regulatory */ | ||
697 | if (!ath_is_world_regd(reg)) { | ||
698 | error = regulatory_hint(hw->wiphy, reg->alpha2); | ||
699 | if (error) | ||
700 | goto err_world; | ||
701 | } | ||
702 | |||
703 | ath9k_init_leds(priv); | ||
704 | ath9k_start_rfkill_poll(priv); | ||
705 | |||
706 | return 0; | ||
707 | |||
708 | err_world: | ||
709 | ieee80211_unregister_hw(hw); | ||
710 | err_register: | ||
711 | ath9k_rx_cleanup(priv); | ||
712 | err_rx: | ||
713 | ath9k_tx_cleanup(priv); | ||
714 | err_tx: | ||
715 | /* Nothing */ | ||
716 | err_regd: | ||
717 | ath9k_deinit_priv(priv); | ||
718 | err_init: | ||
719 | return error; | ||
720 | } | ||
721 | |||
722 | int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | ||
723 | u16 devid) | ||
724 | { | ||
725 | struct ieee80211_hw *hw; | ||
726 | struct ath9k_htc_priv *priv; | ||
727 | int ret; | ||
728 | |||
729 | hw = ieee80211_alloc_hw(sizeof(struct ath9k_htc_priv), &ath9k_htc_ops); | ||
730 | if (!hw) | ||
731 | return -ENOMEM; | ||
732 | |||
733 | priv = hw->priv; | ||
734 | priv->hw = hw; | ||
735 | priv->htc = htc_handle; | ||
736 | priv->dev = dev; | ||
737 | htc_handle->drv_priv = priv; | ||
738 | SET_IEEE80211_DEV(hw, priv->dev); | ||
739 | |||
740 | ret = ath9k_htc_wait_for_target(priv); | ||
741 | if (ret) | ||
742 | goto err_free; | ||
743 | |||
744 | priv->wmi = ath9k_init_wmi(priv); | ||
745 | if (!priv->wmi) { | ||
746 | ret = -EINVAL; | ||
747 | goto err_free; | ||
748 | } | ||
749 | |||
750 | ret = ath9k_init_htc_services(priv); | ||
751 | if (ret) | ||
752 | goto err_init; | ||
753 | |||
754 | /* The device may have been unplugged earlier. */ | ||
755 | priv->op_flags &= ~OP_UNPLUGGED; | ||
756 | |||
757 | ret = ath9k_init_device(priv, devid); | ||
758 | if (ret) | ||
759 | goto err_init; | ||
760 | |||
761 | return 0; | ||
762 | |||
763 | err_init: | ||
764 | ath9k_deinit_wmi(priv); | ||
765 | err_free: | ||
766 | ieee80211_free_hw(hw); | ||
767 | return ret; | ||
768 | } | ||
769 | |||
770 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) | ||
771 | { | ||
772 | if (htc_handle->drv_priv) { | ||
773 | |||
774 | /* Check if the device has been yanked out. */ | ||
775 | if (hotunplug) | ||
776 | htc_handle->drv_priv->op_flags |= OP_UNPLUGGED; | ||
777 | |||
778 | ath9k_deinit_device(htc_handle->drv_priv); | ||
779 | ath9k_deinit_wmi(htc_handle->drv_priv); | ||
780 | ieee80211_free_hw(htc_handle->drv_priv->hw); | ||
781 | } | ||
782 | } | ||
783 | |||
784 | #ifdef CONFIG_PM | ||
785 | int ath9k_htc_resume(struct htc_target *htc_handle) | ||
786 | { | ||
787 | int ret; | ||
788 | |||
789 | ret = ath9k_htc_wait_for_target(htc_handle->drv_priv); | ||
790 | if (ret) | ||
791 | return ret; | ||
792 | |||
793 | ret = ath9k_init_htc_services(htc_handle->drv_priv); | ||
794 | return ret; | ||
795 | } | ||
796 | #endif | ||
797 | |||
798 | static int __init ath9k_htc_init(void) | ||
799 | { | ||
800 | int error; | ||
801 | |||
802 | error = ath9k_htc_debug_create_root(); | ||
803 | if (error < 0) { | ||
804 | printk(KERN_ERR | ||
805 | "ath9k_htc: Unable to create debugfs root: %d\n", | ||
806 | error); | ||
807 | goto err_dbg; | ||
808 | } | ||
809 | |||
810 | error = ath9k_hif_usb_init(); | ||
811 | if (error < 0) { | ||
812 | printk(KERN_ERR | ||
813 | "ath9k_htc: No USB devices found," | ||
814 | " driver not installed.\n"); | ||
815 | error = -ENODEV; | ||
816 | goto err_usb; | ||
817 | } | ||
818 | |||
819 | return 0; | ||
820 | |||
821 | err_usb: | ||
822 | ath9k_htc_debug_remove_root(); | ||
823 | err_dbg: | ||
824 | return error; | ||
825 | } | ||
826 | module_init(ath9k_htc_init); | ||
827 | |||
828 | static void __exit ath9k_htc_exit(void) | ||
829 | { | ||
830 | ath9k_hif_usb_exit(); | ||
831 | ath9k_htc_debug_remove_root(); | ||
832 | printk(KERN_INFO "ath9k_htc: Driver unloaded\n"); | ||
833 | } | ||
834 | module_exit(ath9k_htc_exit); | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c new file mode 100644 index 000000000000..9d371c18eb41 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -0,0 +1,1775 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
20 | static struct dentry *ath9k_debugfs_root; | ||
21 | #endif | ||
22 | |||
23 | /*************/ | ||
24 | /* Utilities */ | ||
25 | /*************/ | ||
26 | |||
27 | static void ath_update_txpow(struct ath9k_htc_priv *priv) | ||
28 | { | ||
29 | struct ath_hw *ah = priv->ah; | ||
30 | u32 txpow; | ||
31 | |||
32 | if (priv->curtxpow != priv->txpowlimit) { | ||
33 | ath9k_hw_set_txpowerlimit(ah, priv->txpowlimit); | ||
34 | /* read back in case value is clamped */ | ||
35 | ath9k_hw_getcapability(ah, ATH9K_CAP_TXPOW, 1, &txpow); | ||
36 | priv->curtxpow = txpow; | ||
37 | } | ||
38 | } | ||
39 | |||
40 | /* HACK Alert: Use 11NG for 2.4, use 11NA for 5 */ | ||
41 | static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | ||
42 | struct ath9k_channel *ichan) | ||
43 | { | ||
44 | enum htc_phymode mode; | ||
45 | |||
46 | mode = HTC_MODE_AUTO; | ||
47 | |||
48 | switch (ichan->chanmode) { | ||
49 | case CHANNEL_G: | ||
50 | case CHANNEL_G_HT20: | ||
51 | case CHANNEL_G_HT40PLUS: | ||
52 | case CHANNEL_G_HT40MINUS: | ||
53 | mode = HTC_MODE_11NG; | ||
54 | break; | ||
55 | case CHANNEL_A: | ||
56 | case CHANNEL_A_HT20: | ||
57 | case CHANNEL_A_HT40PLUS: | ||
58 | case CHANNEL_A_HT40MINUS: | ||
59 | mode = HTC_MODE_11NA; | ||
60 | break; | ||
61 | default: | ||
62 | break; | ||
63 | } | ||
64 | |||
65 | return mode; | ||
66 | } | ||
67 | |||
68 | static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | ||
69 | enum ath9k_power_mode mode) | ||
70 | { | ||
71 | bool ret; | ||
72 | |||
73 | mutex_lock(&priv->htc_pm_lock); | ||
74 | ret = ath9k_hw_setpower(priv->ah, mode); | ||
75 | mutex_unlock(&priv->htc_pm_lock); | ||
76 | |||
77 | return ret; | ||
78 | } | ||
79 | |||
80 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv) | ||
81 | { | ||
82 | mutex_lock(&priv->htc_pm_lock); | ||
83 | if (++priv->ps_usecount != 1) | ||
84 | goto unlock; | ||
85 | ath9k_hw_setpower(priv->ah, ATH9K_PM_AWAKE); | ||
86 | |||
87 | unlock: | ||
88 | mutex_unlock(&priv->htc_pm_lock); | ||
89 | } | ||
90 | |||
91 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv) | ||
92 | { | ||
93 | mutex_lock(&priv->htc_pm_lock); | ||
94 | if (--priv->ps_usecount != 0) | ||
95 | goto unlock; | ||
96 | |||
97 | if (priv->ps_idle) | ||
98 | ath9k_hw_setpower(priv->ah, ATH9K_PM_FULL_SLEEP); | ||
99 | else if (priv->ps_enabled) | ||
100 | ath9k_hw_setpower(priv->ah, ATH9K_PM_NETWORK_SLEEP); | ||
101 | |||
102 | unlock: | ||
103 | mutex_unlock(&priv->htc_pm_lock); | ||
104 | } | ||
105 | |||
106 | void ath9k_ps_work(struct work_struct *work) | ||
107 | { | ||
108 | struct ath9k_htc_priv *priv = | ||
109 | container_of(work, struct ath9k_htc_priv, | ||
110 | ps_work); | ||
111 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | ||
112 | |||
113 | /* The chip wakes up after receiving the first beacon | ||
114 | while network sleep is enabled. For the driver to | ||
115 | be in sync with the hw, set the chip to awake and | ||
116 | only then set it to sleep. | ||
117 | */ | ||
118 | ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); | ||
119 | } | ||
120 | |||
121 | static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv, | ||
122 | struct ieee80211_hw *hw, | ||
123 | struct ath9k_channel *hchan) | ||
124 | { | ||
125 | struct ath_hw *ah = priv->ah; | ||
126 | struct ath_common *common = ath9k_hw_common(ah); | ||
127 | struct ieee80211_conf *conf = &common->hw->conf; | ||
128 | bool fastcc = true; | ||
129 | struct ieee80211_channel *channel = hw->conf.channel; | ||
130 | enum htc_phymode mode; | ||
131 | __be16 htc_mode; | ||
132 | u8 cmd_rsp; | ||
133 | int ret; | ||
134 | |||
135 | if (priv->op_flags & OP_INVALID) | ||
136 | return -EIO; | ||
137 | |||
138 | if (priv->op_flags & OP_FULL_RESET) | ||
139 | fastcc = false; | ||
140 | |||
141 | /* Fiddle around with fastcc later on, for now just use full reset */ | ||
142 | fastcc = false; | ||
143 | ath9k_htc_ps_wakeup(priv); | ||
144 | htc_stop(priv->htc); | ||
145 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | ||
146 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | ||
147 | WMI_CMD(WMI_STOP_RECV_CMDID); | ||
148 | |||
149 | ath_print(common, ATH_DBG_CONFIG, | ||
150 | "(%u MHz) -> (%u MHz), HT: %d, HT40: %d\n", | ||
151 | priv->ah->curchan->channel, | ||
152 | channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf)); | ||
153 | |||
154 | ret = ath9k_hw_reset(ah, hchan, fastcc); | ||
155 | if (ret) { | ||
156 | ath_print(common, ATH_DBG_FATAL, | ||
157 | "Unable to reset channel (%u Mhz) " | ||
158 | "reset status %d\n", channel->center_freq, ret); | ||
159 | goto err; | ||
160 | } | ||
161 | |||
162 | ath_update_txpow(priv); | ||
163 | |||
164 | WMI_CMD(WMI_START_RECV_CMDID); | ||
165 | if (ret) | ||
166 | goto err; | ||
167 | |||
168 | ath9k_host_rx_init(priv); | ||
169 | |||
170 | mode = ath9k_htc_get_curmode(priv, hchan); | ||
171 | htc_mode = cpu_to_be16(mode); | ||
172 | WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); | ||
173 | if (ret) | ||
174 | goto err; | ||
175 | |||
176 | WMI_CMD(WMI_ENABLE_INTR_CMDID); | ||
177 | if (ret) | ||
178 | goto err; | ||
179 | |||
180 | htc_start(priv->htc); | ||
181 | |||
182 | priv->op_flags &= ~OP_FULL_RESET; | ||
183 | err: | ||
184 | ath9k_htc_ps_restore(priv); | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static int ath9k_htc_add_monitor_interface(struct ath9k_htc_priv *priv) | ||
189 | { | ||
190 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
191 | struct ath9k_htc_target_vif hvif; | ||
192 | int ret = 0; | ||
193 | u8 cmd_rsp; | ||
194 | |||
195 | if (priv->nvifs > 0) | ||
196 | return -ENOBUFS; | ||
197 | |||
198 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | ||
199 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | ||
200 | |||
201 | hvif.opmode = cpu_to_be32(HTC_M_MONITOR); | ||
202 | priv->ah->opmode = NL80211_IFTYPE_MONITOR; | ||
203 | hvif.index = priv->nvifs; | ||
204 | |||
205 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); | ||
206 | if (ret) | ||
207 | return ret; | ||
208 | |||
209 | priv->nvifs++; | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | static int ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv) | ||
214 | { | ||
215 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
216 | struct ath9k_htc_target_vif hvif; | ||
217 | int ret = 0; | ||
218 | u8 cmd_rsp; | ||
219 | |||
220 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | ||
221 | memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN); | ||
222 | hvif.index = 0; /* Should do for now */ | ||
223 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | ||
224 | priv->nvifs--; | ||
225 | |||
226 | return ret; | ||
227 | } | ||
228 | |||
229 | static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, | ||
230 | struct ieee80211_vif *vif, | ||
231 | struct ieee80211_sta *sta) | ||
232 | { | ||
233 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
234 | struct ath9k_htc_target_sta tsta; | ||
235 | struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv; | ||
236 | struct ath9k_htc_sta *ista; | ||
237 | int ret; | ||
238 | u8 cmd_rsp; | ||
239 | |||
240 | if (priv->nstations >= ATH9K_HTC_MAX_STA) | ||
241 | return -ENOBUFS; | ||
242 | |||
243 | memset(&tsta, 0, sizeof(struct ath9k_htc_target_sta)); | ||
244 | |||
245 | if (sta) { | ||
246 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
247 | memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); | ||
248 | memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); | ||
249 | tsta.associd = common->curaid; | ||
250 | tsta.is_vif_sta = 0; | ||
251 | tsta.valid = true; | ||
252 | ista->index = priv->nstations; | ||
253 | } else { | ||
254 | memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); | ||
255 | tsta.is_vif_sta = 1; | ||
256 | } | ||
257 | |||
258 | tsta.sta_index = priv->nstations; | ||
259 | tsta.vif_index = avp->index; | ||
260 | tsta.maxampdu = 0xffff; | ||
261 | if (sta && sta->ht_cap.ht_supported) | ||
262 | tsta.flags = cpu_to_be16(ATH_HTC_STA_HT); | ||
263 | |||
264 | WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); | ||
265 | if (ret) { | ||
266 | if (sta) | ||
267 | ath_print(common, ATH_DBG_FATAL, | ||
268 | "Unable to add station entry for: %pM\n", sta->addr); | ||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | if (sta) | ||
273 | ath_print(common, ATH_DBG_CONFIG, | ||
274 | "Added a station entry for: %pM (idx: %d)\n", | ||
275 | sta->addr, tsta.sta_index); | ||
276 | |||
277 | priv->nstations++; | ||
278 | return 0; | ||
279 | } | ||
280 | |||
281 | static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv, | ||
282 | struct ieee80211_vif *vif, | ||
283 | struct ieee80211_sta *sta) | ||
284 | { | ||
285 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
286 | struct ath9k_htc_sta *ista; | ||
287 | int ret; | ||
288 | u8 cmd_rsp, sta_idx; | ||
289 | |||
290 | if (sta) { | ||
291 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
292 | sta_idx = ista->index; | ||
293 | } else { | ||
294 | sta_idx = 0; | ||
295 | } | ||
296 | |||
297 | WMI_CMD_BUF(WMI_NODE_REMOVE_CMDID, &sta_idx); | ||
298 | if (ret) { | ||
299 | if (sta) | ||
300 | ath_print(common, ATH_DBG_FATAL, | ||
301 | "Unable to remove station entry for: %pM\n", | ||
302 | sta->addr); | ||
303 | return ret; | ||
304 | } | ||
305 | |||
306 | if (sta) | ||
307 | ath_print(common, ATH_DBG_CONFIG, | ||
308 | "Removed a station entry for: %pM (idx: %d)\n", | ||
309 | sta->addr, sta_idx); | ||
310 | |||
311 | priv->nstations--; | ||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv) | ||
316 | { | ||
317 | struct ath9k_htc_cap_target tcap; | ||
318 | int ret; | ||
319 | u8 cmd_rsp; | ||
320 | |||
321 | memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target)); | ||
322 | |||
323 | /* FIXME: Values are hardcoded */ | ||
324 | tcap.flags = 0x240c40; | ||
325 | tcap.flags_ext = 0x80601000; | ||
326 | tcap.ampdu_limit = 0xffff0000; | ||
327 | tcap.ampdu_subframes = 20; | ||
328 | tcap.tx_chainmask_legacy = 1; | ||
329 | tcap.protmode = 1; | ||
330 | tcap.tx_chainmask = 1; | ||
331 | |||
332 | WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap); | ||
333 | |||
334 | return ret; | ||
335 | } | ||
336 | |||
337 | static int ath9k_htc_init_rate(struct ath9k_htc_priv *priv, | ||
338 | struct ieee80211_vif *vif, | ||
339 | struct ieee80211_sta *sta) | ||
340 | { | ||
341 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
342 | struct ath9k_htc_sta *ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
343 | struct ieee80211_supported_band *sband; | ||
344 | struct ath9k_htc_target_rate trate; | ||
345 | u32 caps = 0; | ||
346 | u8 cmd_rsp; | ||
347 | int i, j, ret; | ||
348 | |||
349 | memset(&trate, 0, sizeof(trate)); | ||
350 | |||
351 | /* Only 2GHz is supported */ | ||
352 | sband = priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ]; | ||
353 | |||
354 | for (i = 0, j = 0; i < sband->n_bitrates; i++) { | ||
355 | if (sta->supp_rates[sband->band] & BIT(i)) { | ||
356 | priv->tgt_rate.rates.legacy_rates.rs_rates[j] | ||
357 | = (sband->bitrates[i].bitrate * 2) / 10; | ||
358 | j++; | ||
359 | } | ||
360 | } | ||
361 | priv->tgt_rate.rates.legacy_rates.rs_nrates = j; | ||
362 | |||
363 | if (sta->ht_cap.ht_supported) { | ||
364 | for (i = 0, j = 0; i < 77; i++) { | ||
365 | if (sta->ht_cap.mcs.rx_mask[i/8] & (1<<(i%8))) | ||
366 | priv->tgt_rate.rates.ht_rates.rs_rates[j++] = i; | ||
367 | if (j == ATH_HTC_RATE_MAX) | ||
368 | break; | ||
369 | } | ||
370 | priv->tgt_rate.rates.ht_rates.rs_nrates = j; | ||
371 | |||
372 | caps = WLAN_RC_HT_FLAG; | ||
373 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) | ||
374 | caps |= WLAN_RC_40_FLAG; | ||
375 | if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) | ||
376 | caps |= WLAN_RC_SGI_FLAG; | ||
377 | |||
378 | } | ||
379 | |||
380 | priv->tgt_rate.sta_index = ista->index; | ||
381 | priv->tgt_rate.isnew = 1; | ||
382 | trate = priv->tgt_rate; | ||
383 | priv->tgt_rate.capflags = cpu_to_be32(caps); | ||
384 | trate.capflags = cpu_to_be32(caps); | ||
385 | |||
386 | WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); | ||
387 | if (ret) { | ||
388 | ath_print(common, ATH_DBG_FATAL, | ||
389 | "Unable to initialize Rate information on target\n"); | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | ath_print(common, ATH_DBG_CONFIG, | ||
394 | "Updated target STA: %pM (caps: 0x%x)\n", sta->addr, caps); | ||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static bool check_rc_update(struct ieee80211_hw *hw, bool *cw40) | ||
399 | { | ||
400 | struct ath9k_htc_priv *priv = hw->priv; | ||
401 | struct ieee80211_conf *conf = &hw->conf; | ||
402 | |||
403 | if (!conf_is_ht(conf)) | ||
404 | return false; | ||
405 | |||
406 | if (!(priv->op_flags & OP_ASSOCIATED) || | ||
407 | (priv->op_flags & OP_SCANNING)) | ||
408 | return false; | ||
409 | |||
410 | if (conf_is_ht40(conf)) { | ||
411 | if (priv->ah->curchan->chanmode & | ||
412 | (CHANNEL_HT40PLUS | CHANNEL_HT40MINUS)) { | ||
413 | return false; | ||
414 | } else { | ||
415 | *cw40 = true; | ||
416 | return true; | ||
417 | } | ||
418 | } else { /* ht20 */ | ||
419 | if (priv->ah->curchan->chanmode & CHANNEL_HT20) | ||
420 | return false; | ||
421 | else | ||
422 | return true; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | static void ath9k_htc_rc_update(struct ath9k_htc_priv *priv, bool is_cw40) | ||
427 | { | ||
428 | struct ath9k_htc_target_rate trate; | ||
429 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
430 | int ret; | ||
431 | u32 caps = be32_to_cpu(priv->tgt_rate.capflags); | ||
432 | u8 cmd_rsp; | ||
433 | |||
434 | memset(&trate, 0, sizeof(trate)); | ||
435 | |||
436 | trate = priv->tgt_rate; | ||
437 | |||
438 | if (is_cw40) | ||
439 | caps |= WLAN_RC_40_FLAG; | ||
440 | else | ||
441 | caps &= ~WLAN_RC_40_FLAG; | ||
442 | |||
443 | priv->tgt_rate.capflags = cpu_to_be32(caps); | ||
444 | trate.capflags = cpu_to_be32(caps); | ||
445 | |||
446 | WMI_CMD_BUF(WMI_RC_RATE_UPDATE_CMDID, &trate); | ||
447 | if (ret) { | ||
448 | ath_print(common, ATH_DBG_FATAL, | ||
449 | "Unable to update Rate information on target\n"); | ||
450 | return; | ||
451 | } | ||
452 | |||
453 | ath_print(common, ATH_DBG_CONFIG, "Rate control updated with " | ||
454 | "caps:0x%x on target\n", priv->tgt_rate.capflags); | ||
455 | } | ||
456 | |||
457 | static int ath9k_htc_aggr_oper(struct ath9k_htc_priv *priv, | ||
458 | struct ieee80211_vif *vif, | ||
459 | u8 *sta_addr, u8 tid, bool oper) | ||
460 | { | ||
461 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
462 | struct ath9k_htc_target_aggr aggr; | ||
463 | struct ieee80211_sta *sta = NULL; | ||
464 | struct ath9k_htc_sta *ista; | ||
465 | int ret = 0; | ||
466 | u8 cmd_rsp; | ||
467 | |||
468 | if (tid >= ATH9K_HTC_MAX_TID) | ||
469 | return -EINVAL; | ||
470 | |||
471 | memset(&aggr, 0, sizeof(struct ath9k_htc_target_aggr)); | ||
472 | |||
473 | rcu_read_lock(); | ||
474 | |||
475 | /* Check if we are able to retrieve the station */ | ||
476 | sta = ieee80211_find_sta(vif, sta_addr); | ||
477 | if (!sta) { | ||
478 | rcu_read_unlock(); | ||
479 | return -EINVAL; | ||
480 | } | ||
481 | |||
482 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
483 | |||
484 | if (oper) | ||
485 | ista->tid_state[tid] = AGGR_START; | ||
486 | else | ||
487 | ista->tid_state[tid] = AGGR_STOP; | ||
488 | |||
489 | aggr.sta_index = ista->index; | ||
490 | |||
491 | rcu_read_unlock(); | ||
492 | |||
493 | aggr.tidno = tid; | ||
494 | aggr.aggr_enable = oper; | ||
495 | |||
496 | WMI_CMD_BUF(WMI_TX_AGGR_ENABLE_CMDID, &aggr); | ||
497 | if (ret) | ||
498 | ath_print(common, ATH_DBG_CONFIG, | ||
499 | "Unable to %s TX aggregation for (%pM, %d)\n", | ||
500 | (oper) ? "start" : "stop", sta->addr, tid); | ||
501 | else | ||
502 | ath_print(common, ATH_DBG_CONFIG, | ||
503 | "%s aggregation for (%pM, %d)\n", | ||
504 | (oper) ? "Starting" : "Stopping", sta->addr, tid); | ||
505 | |||
506 | return ret; | ||
507 | } | ||
508 | |||
509 | void ath9k_htc_aggr_work(struct work_struct *work) | ||
510 | { | ||
511 | int ret = 0; | ||
512 | struct ath9k_htc_priv *priv = | ||
513 | container_of(work, struct ath9k_htc_priv, | ||
514 | ath9k_aggr_work.work); | ||
515 | struct ath9k_htc_aggr_work *wk = &priv->aggr_work; | ||
516 | |||
517 | mutex_lock(&wk->mutex); | ||
518 | |||
519 | switch (wk->action) { | ||
520 | case IEEE80211_AMPDU_TX_START: | ||
521 | ret = ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr, | ||
522 | wk->tid, true); | ||
523 | if (!ret) | ||
524 | ieee80211_start_tx_ba_cb(wk->vif, wk->sta_addr, | ||
525 | wk->tid); | ||
526 | break; | ||
527 | case IEEE80211_AMPDU_TX_STOP: | ||
528 | ath9k_htc_aggr_oper(priv, wk->vif, wk->sta_addr, | ||
529 | wk->tid, false); | ||
530 | ieee80211_stop_tx_ba_cb(wk->vif, wk->sta_addr, wk->tid); | ||
531 | break; | ||
532 | default: | ||
533 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, | ||
534 | "Unknown AMPDU action\n"); | ||
535 | } | ||
536 | |||
537 | mutex_unlock(&wk->mutex); | ||
538 | } | ||
539 | |||
540 | /*********/ | ||
541 | /* DEBUG */ | ||
542 | /*********/ | ||
543 | |||
544 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
545 | |||
546 | static int ath9k_debugfs_open(struct inode *inode, struct file *file) | ||
547 | { | ||
548 | file->private_data = inode->i_private; | ||
549 | return 0; | ||
550 | } | ||
551 | |||
552 | static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf, | ||
553 | size_t count, loff_t *ppos) | ||
554 | { | ||
555 | struct ath9k_htc_priv *priv = | ||
556 | (struct ath9k_htc_priv *) file->private_data; | ||
557 | struct ath9k_htc_target_stats cmd_rsp; | ||
558 | char buf[512]; | ||
559 | unsigned int len = 0; | ||
560 | int ret = 0; | ||
561 | |||
562 | memset(&cmd_rsp, 0, sizeof(cmd_rsp)); | ||
563 | |||
564 | WMI_CMD(WMI_TGT_STATS_CMDID); | ||
565 | if (ret) | ||
566 | return -EINVAL; | ||
567 | |||
568 | |||
569 | len += snprintf(buf + len, sizeof(buf) - len, | ||
570 | "%19s : %10u\n", "TX Short Retries", | ||
571 | be32_to_cpu(cmd_rsp.tx_shortretry)); | ||
572 | len += snprintf(buf + len, sizeof(buf) - len, | ||
573 | "%19s : %10u\n", "TX Long Retries", | ||
574 | be32_to_cpu(cmd_rsp.tx_longretry)); | ||
575 | len += snprintf(buf + len, sizeof(buf) - len, | ||
576 | "%19s : %10u\n", "TX Xretries", | ||
577 | be32_to_cpu(cmd_rsp.tx_xretries)); | ||
578 | len += snprintf(buf + len, sizeof(buf) - len, | ||
579 | "%19s : %10u\n", "TX Unaggr. Xretries", | ||
580 | be32_to_cpu(cmd_rsp.ht_txunaggr_xretry)); | ||
581 | len += snprintf(buf + len, sizeof(buf) - len, | ||
582 | "%19s : %10u\n", "TX Xretries (HT)", | ||
583 | be32_to_cpu(cmd_rsp.ht_tx_xretries)); | ||
584 | len += snprintf(buf + len, sizeof(buf) - len, | ||
585 | "%19s : %10u\n", "TX Rate", priv->debug.txrate); | ||
586 | |||
587 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
588 | } | ||
589 | |||
590 | static const struct file_operations fops_tgt_stats = { | ||
591 | .read = read_file_tgt_stats, | ||
592 | .open = ath9k_debugfs_open, | ||
593 | .owner = THIS_MODULE | ||
594 | }; | ||
595 | |||
596 | static ssize_t read_file_xmit(struct file *file, char __user *user_buf, | ||
597 | size_t count, loff_t *ppos) | ||
598 | { | ||
599 | struct ath9k_htc_priv *priv = | ||
600 | (struct ath9k_htc_priv *) file->private_data; | ||
601 | char buf[512]; | ||
602 | unsigned int len = 0; | ||
603 | |||
604 | len += snprintf(buf + len, sizeof(buf) - len, | ||
605 | "%20s : %10u\n", "Buffers queued", | ||
606 | priv->debug.tx_stats.buf_queued); | ||
607 | len += snprintf(buf + len, sizeof(buf) - len, | ||
608 | "%20s : %10u\n", "Buffers completed", | ||
609 | priv->debug.tx_stats.buf_completed); | ||
610 | len += snprintf(buf + len, sizeof(buf) - len, | ||
611 | "%20s : %10u\n", "SKBs queued", | ||
612 | priv->debug.tx_stats.skb_queued); | ||
613 | len += snprintf(buf + len, sizeof(buf) - len, | ||
614 | "%20s : %10u\n", "SKBs completed", | ||
615 | priv->debug.tx_stats.skb_completed); | ||
616 | len += snprintf(buf + len, sizeof(buf) - len, | ||
617 | "%20s : %10u\n", "SKBs dropped", | ||
618 | priv->debug.tx_stats.skb_dropped); | ||
619 | |||
620 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
621 | } | ||
622 | |||
623 | static const struct file_operations fops_xmit = { | ||
624 | .read = read_file_xmit, | ||
625 | .open = ath9k_debugfs_open, | ||
626 | .owner = THIS_MODULE | ||
627 | }; | ||
628 | |||
629 | static ssize_t read_file_recv(struct file *file, char __user *user_buf, | ||
630 | size_t count, loff_t *ppos) | ||
631 | { | ||
632 | struct ath9k_htc_priv *priv = | ||
633 | (struct ath9k_htc_priv *) file->private_data; | ||
634 | char buf[512]; | ||
635 | unsigned int len = 0; | ||
636 | |||
637 | len += snprintf(buf + len, sizeof(buf) - len, | ||
638 | "%20s : %10u\n", "SKBs allocated", | ||
639 | priv->debug.rx_stats.skb_allocated); | ||
640 | len += snprintf(buf + len, sizeof(buf) - len, | ||
641 | "%20s : %10u\n", "SKBs completed", | ||
642 | priv->debug.rx_stats.skb_completed); | ||
643 | len += snprintf(buf + len, sizeof(buf) - len, | ||
644 | "%20s : %10u\n", "SKBs Dropped", | ||
645 | priv->debug.rx_stats.skb_dropped); | ||
646 | |||
647 | return simple_read_from_buffer(user_buf, count, ppos, buf, len); | ||
648 | } | ||
649 | |||
650 | static const struct file_operations fops_recv = { | ||
651 | .read = read_file_recv, | ||
652 | .open = ath9k_debugfs_open, | ||
653 | .owner = THIS_MODULE | ||
654 | }; | ||
655 | |||
656 | int ath9k_htc_init_debug(struct ath_hw *ah) | ||
657 | { | ||
658 | struct ath_common *common = ath9k_hw_common(ah); | ||
659 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
660 | |||
661 | if (!ath9k_debugfs_root) | ||
662 | return -ENOENT; | ||
663 | |||
664 | priv->debug.debugfs_phy = debugfs_create_dir(wiphy_name(priv->hw->wiphy), | ||
665 | ath9k_debugfs_root); | ||
666 | if (!priv->debug.debugfs_phy) | ||
667 | goto err; | ||
668 | |||
669 | priv->debug.debugfs_tgt_stats = debugfs_create_file("tgt_stats", S_IRUSR, | ||
670 | priv->debug.debugfs_phy, | ||
671 | priv, &fops_tgt_stats); | ||
672 | if (!priv->debug.debugfs_tgt_stats) | ||
673 | goto err; | ||
674 | |||
675 | |||
676 | priv->debug.debugfs_xmit = debugfs_create_file("xmit", S_IRUSR, | ||
677 | priv->debug.debugfs_phy, | ||
678 | priv, &fops_xmit); | ||
679 | if (!priv->debug.debugfs_xmit) | ||
680 | goto err; | ||
681 | |||
682 | priv->debug.debugfs_recv = debugfs_create_file("recv", S_IRUSR, | ||
683 | priv->debug.debugfs_phy, | ||
684 | priv, &fops_recv); | ||
685 | if (!priv->debug.debugfs_recv) | ||
686 | goto err; | ||
687 | |||
688 | return 0; | ||
689 | |||
690 | err: | ||
691 | ath9k_htc_exit_debug(ah); | ||
692 | return -ENOMEM; | ||
693 | } | ||
694 | |||
695 | void ath9k_htc_exit_debug(struct ath_hw *ah) | ||
696 | { | ||
697 | struct ath_common *common = ath9k_hw_common(ah); | ||
698 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv; | ||
699 | |||
700 | debugfs_remove(priv->debug.debugfs_recv); | ||
701 | debugfs_remove(priv->debug.debugfs_xmit); | ||
702 | debugfs_remove(priv->debug.debugfs_tgt_stats); | ||
703 | debugfs_remove(priv->debug.debugfs_phy); | ||
704 | } | ||
705 | |||
706 | int ath9k_htc_debug_create_root(void) | ||
707 | { | ||
708 | ath9k_debugfs_root = debugfs_create_dir(KBUILD_MODNAME, NULL); | ||
709 | if (!ath9k_debugfs_root) | ||
710 | return -ENOENT; | ||
711 | |||
712 | return 0; | ||
713 | } | ||
714 | |||
715 | void ath9k_htc_debug_remove_root(void) | ||
716 | { | ||
717 | debugfs_remove(ath9k_debugfs_root); | ||
718 | ath9k_debugfs_root = NULL; | ||
719 | } | ||
720 | |||
721 | #endif /* CONFIG_ATH9K_HTC_DEBUGFS */ | ||
722 | |||
723 | /*******/ | ||
724 | /* ANI */ | ||
725 | /*******/ | ||
726 | |||
727 | static void ath_start_ani(struct ath9k_htc_priv *priv) | ||
728 | { | ||
729 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
730 | unsigned long timestamp = jiffies_to_msecs(jiffies); | ||
731 | |||
732 | common->ani.longcal_timer = timestamp; | ||
733 | common->ani.shortcal_timer = timestamp; | ||
734 | common->ani.checkani_timer = timestamp; | ||
735 | |||
736 | ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, | ||
737 | msecs_to_jiffies(ATH_ANI_POLLINTERVAL)); | ||
738 | } | ||
739 | |||
740 | void ath9k_ani_work(struct work_struct *work) | ||
741 | { | ||
742 | struct ath9k_htc_priv *priv = | ||
743 | container_of(work, struct ath9k_htc_priv, | ||
744 | ath9k_ani_work.work); | ||
745 | struct ath_hw *ah = priv->ah; | ||
746 | struct ath_common *common = ath9k_hw_common(ah); | ||
747 | bool longcal = false; | ||
748 | bool shortcal = false; | ||
749 | bool aniflag = false; | ||
750 | unsigned int timestamp = jiffies_to_msecs(jiffies); | ||
751 | u32 cal_interval, short_cal_interval; | ||
752 | |||
753 | short_cal_interval = ATH_STA_SHORT_CALINTERVAL; | ||
754 | |||
755 | /* Only calibrate if awake */ | ||
756 | if (ah->power_mode != ATH9K_PM_AWAKE) | ||
757 | goto set_timer; | ||
758 | |||
759 | /* Long calibration runs independently of short calibration. */ | ||
760 | if ((timestamp - common->ani.longcal_timer) >= ATH_LONG_CALINTERVAL) { | ||
761 | longcal = true; | ||
762 | ath_print(common, ATH_DBG_ANI, "longcal @%lu\n", jiffies); | ||
763 | common->ani.longcal_timer = timestamp; | ||
764 | } | ||
765 | |||
766 | /* Short calibration applies only while caldone is false */ | ||
767 | if (!common->ani.caldone) { | ||
768 | if ((timestamp - common->ani.shortcal_timer) >= | ||
769 | short_cal_interval) { | ||
770 | shortcal = true; | ||
771 | ath_print(common, ATH_DBG_ANI, | ||
772 | "shortcal @%lu\n", jiffies); | ||
773 | common->ani.shortcal_timer = timestamp; | ||
774 | common->ani.resetcal_timer = timestamp; | ||
775 | } | ||
776 | } else { | ||
777 | if ((timestamp - common->ani.resetcal_timer) >= | ||
778 | ATH_RESTART_CALINTERVAL) { | ||
779 | common->ani.caldone = ath9k_hw_reset_calvalid(ah); | ||
780 | if (common->ani.caldone) | ||
781 | common->ani.resetcal_timer = timestamp; | ||
782 | } | ||
783 | } | ||
784 | |||
785 | /* Verify whether we must check ANI */ | ||
786 | if ((timestamp - common->ani.checkani_timer) >= ATH_ANI_POLLINTERVAL) { | ||
787 | aniflag = true; | ||
788 | common->ani.checkani_timer = timestamp; | ||
789 | } | ||
790 | |||
791 | /* Skip all processing if there's nothing to do. */ | ||
792 | if (longcal || shortcal || aniflag) { | ||
793 | |||
794 | ath9k_htc_ps_wakeup(priv); | ||
795 | |||
796 | /* Call ANI routine if necessary */ | ||
797 | if (aniflag) | ||
798 | ath9k_hw_ani_monitor(ah, ah->curchan); | ||
799 | |||
800 | /* Perform calibration if necessary */ | ||
801 | if (longcal || shortcal) { | ||
802 | common->ani.caldone = | ||
803 | ath9k_hw_calibrate(ah, ah->curchan, | ||
804 | common->rx_chainmask, | ||
805 | longcal); | ||
806 | |||
807 | if (longcal) | ||
808 | common->ani.noise_floor = | ||
809 | ath9k_hw_getchan_noise(ah, ah->curchan); | ||
810 | |||
811 | ath_print(common, ATH_DBG_ANI, | ||
812 | " calibrate chan %u/%x nf: %d\n", | ||
813 | ah->curchan->channel, | ||
814 | ah->curchan->channelFlags, | ||
815 | common->ani.noise_floor); | ||
816 | } | ||
817 | |||
818 | ath9k_htc_ps_restore(priv); | ||
819 | } | ||
820 | |||
821 | set_timer: | ||
822 | /* | ||
823 | * Set timer interval based on previous results. | ||
824 | * The interval must be the shortest necessary to satisfy ANI, | ||
825 | * short calibration and long calibration. | ||
826 | */ | ||
827 | cal_interval = ATH_LONG_CALINTERVAL; | ||
828 | if (priv->ah->config.enable_ani) | ||
829 | cal_interval = min(cal_interval, (u32)ATH_ANI_POLLINTERVAL); | ||
830 | if (!common->ani.caldone) | ||
831 | cal_interval = min(cal_interval, (u32)short_cal_interval); | ||
832 | |||
833 | ieee80211_queue_delayed_work(common->hw, &priv->ath9k_ani_work, | ||
834 | msecs_to_jiffies(cal_interval)); | ||
835 | } | ||
836 | |||
837 | /*******/ | ||
838 | /* LED */ | ||
839 | /*******/ | ||
840 | |||
841 | static void ath9k_led_blink_work(struct work_struct *work) | ||
842 | { | ||
843 | struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv, | ||
844 | ath9k_led_blink_work.work); | ||
845 | |||
846 | if (!(priv->op_flags & OP_LED_ASSOCIATED)) | ||
847 | return; | ||
848 | |||
849 | if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) || | ||
850 | (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE)) | ||
851 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||
852 | else | ||
853 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||
854 | (priv->op_flags & OP_LED_ON) ? 1 : 0); | ||
855 | |||
856 | ieee80211_queue_delayed_work(priv->hw, | ||
857 | &priv->ath9k_led_blink_work, | ||
858 | (priv->op_flags & OP_LED_ON) ? | ||
859 | msecs_to_jiffies(priv->led_off_duration) : | ||
860 | msecs_to_jiffies(priv->led_on_duration)); | ||
861 | |||
862 | priv->led_on_duration = priv->led_on_cnt ? | ||
863 | max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) : | ||
864 | ATH_LED_ON_DURATION_IDLE; | ||
865 | priv->led_off_duration = priv->led_off_cnt ? | ||
866 | max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) : | ||
867 | ATH_LED_OFF_DURATION_IDLE; | ||
868 | priv->led_on_cnt = priv->led_off_cnt = 0; | ||
869 | |||
870 | if (priv->op_flags & OP_LED_ON) | ||
871 | priv->op_flags &= ~OP_LED_ON; | ||
872 | else | ||
873 | priv->op_flags |= OP_LED_ON; | ||
874 | } | ||
875 | |||
876 | static void ath9k_led_brightness_work(struct work_struct *work) | ||
877 | { | ||
878 | struct ath_led *led = container_of(work, struct ath_led, | ||
879 | brightness_work.work); | ||
880 | struct ath9k_htc_priv *priv = led->priv; | ||
881 | |||
882 | switch (led->brightness) { | ||
883 | case LED_OFF: | ||
884 | if (led->led_type == ATH_LED_ASSOC || | ||
885 | led->led_type == ATH_LED_RADIO) { | ||
886 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, | ||
887 | (led->led_type == ATH_LED_RADIO)); | ||
888 | priv->op_flags &= ~OP_LED_ASSOCIATED; | ||
889 | if (led->led_type == ATH_LED_RADIO) | ||
890 | priv->op_flags &= ~OP_LED_ON; | ||
891 | } else { | ||
892 | priv->led_off_cnt++; | ||
893 | } | ||
894 | break; | ||
895 | case LED_FULL: | ||
896 | if (led->led_type == ATH_LED_ASSOC) { | ||
897 | priv->op_flags |= OP_LED_ASSOCIATED; | ||
898 | ieee80211_queue_delayed_work(priv->hw, | ||
899 | &priv->ath9k_led_blink_work, 0); | ||
900 | } else if (led->led_type == ATH_LED_RADIO) { | ||
901 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0); | ||
902 | priv->op_flags |= OP_LED_ON; | ||
903 | } else { | ||
904 | priv->led_on_cnt++; | ||
905 | } | ||
906 | break; | ||
907 | default: | ||
908 | break; | ||
909 | } | ||
910 | } | ||
911 | |||
912 | static void ath9k_led_brightness(struct led_classdev *led_cdev, | ||
913 | enum led_brightness brightness) | ||
914 | { | ||
915 | struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev); | ||
916 | struct ath9k_htc_priv *priv = led->priv; | ||
917 | |||
918 | led->brightness = brightness; | ||
919 | if (!(priv->op_flags & OP_LED_DEINIT)) | ||
920 | ieee80211_queue_delayed_work(priv->hw, | ||
921 | &led->brightness_work, 0); | ||
922 | } | ||
923 | |||
924 | static void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv) | ||
925 | { | ||
926 | cancel_delayed_work_sync(&priv->radio_led.brightness_work); | ||
927 | cancel_delayed_work_sync(&priv->assoc_led.brightness_work); | ||
928 | cancel_delayed_work_sync(&priv->tx_led.brightness_work); | ||
929 | cancel_delayed_work_sync(&priv->rx_led.brightness_work); | ||
930 | } | ||
931 | |||
932 | static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led, | ||
933 | char *trigger) | ||
934 | { | ||
935 | int ret; | ||
936 | |||
937 | led->priv = priv; | ||
938 | led->led_cdev.name = led->name; | ||
939 | led->led_cdev.default_trigger = trigger; | ||
940 | led->led_cdev.brightness_set = ath9k_led_brightness; | ||
941 | |||
942 | ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev); | ||
943 | if (ret) | ||
944 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, | ||
945 | "Failed to register led:%s", led->name); | ||
946 | else | ||
947 | led->registered = 1; | ||
948 | |||
949 | INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work); | ||
950 | |||
951 | return ret; | ||
952 | } | ||
953 | |||
954 | static void ath9k_unregister_led(struct ath_led *led) | ||
955 | { | ||
956 | if (led->registered) { | ||
957 | led_classdev_unregister(&led->led_cdev); | ||
958 | led->registered = 0; | ||
959 | } | ||
960 | } | ||
961 | |||
962 | void ath9k_deinit_leds(struct ath9k_htc_priv *priv) | ||
963 | { | ||
964 | priv->op_flags |= OP_LED_DEINIT; | ||
965 | ath9k_unregister_led(&priv->assoc_led); | ||
966 | priv->op_flags &= ~OP_LED_ASSOCIATED; | ||
967 | ath9k_unregister_led(&priv->tx_led); | ||
968 | ath9k_unregister_led(&priv->rx_led); | ||
969 | ath9k_unregister_led(&priv->radio_led); | ||
970 | } | ||
971 | |||
972 | void ath9k_init_leds(struct ath9k_htc_priv *priv) | ||
973 | { | ||
974 | char *trigger; | ||
975 | int ret; | ||
976 | |||
977 | if (AR_SREV_9287(priv->ah)) | ||
978 | priv->ah->led_pin = ATH_LED_PIN_9287; | ||
979 | else if (AR_SREV_9271(priv->ah)) | ||
980 | priv->ah->led_pin = ATH_LED_PIN_9271; | ||
981 | else | ||
982 | priv->ah->led_pin = ATH_LED_PIN_DEF; | ||
983 | |||
984 | /* Configure gpio 1 for output */ | ||
985 | ath9k_hw_cfg_output(priv->ah, priv->ah->led_pin, | ||
986 | AR_GPIO_OUTPUT_MUX_AS_OUTPUT); | ||
987 | /* LED off, active low */ | ||
988 | ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1); | ||
989 | |||
990 | INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work); | ||
991 | |||
992 | trigger = ieee80211_get_radio_led_name(priv->hw); | ||
993 | snprintf(priv->radio_led.name, sizeof(priv->radio_led.name), | ||
994 | "ath9k-%s::radio", wiphy_name(priv->hw->wiphy)); | ||
995 | ret = ath9k_register_led(priv, &priv->radio_led, trigger); | ||
996 | priv->radio_led.led_type = ATH_LED_RADIO; | ||
997 | if (ret) | ||
998 | goto fail; | ||
999 | |||
1000 | trigger = ieee80211_get_assoc_led_name(priv->hw); | ||
1001 | snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name), | ||
1002 | "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy)); | ||
1003 | ret = ath9k_register_led(priv, &priv->assoc_led, trigger); | ||
1004 | priv->assoc_led.led_type = ATH_LED_ASSOC; | ||
1005 | if (ret) | ||
1006 | goto fail; | ||
1007 | |||
1008 | trigger = ieee80211_get_tx_led_name(priv->hw); | ||
1009 | snprintf(priv->tx_led.name, sizeof(priv->tx_led.name), | ||
1010 | "ath9k-%s::tx", wiphy_name(priv->hw->wiphy)); | ||
1011 | ret = ath9k_register_led(priv, &priv->tx_led, trigger); | ||
1012 | priv->tx_led.led_type = ATH_LED_TX; | ||
1013 | if (ret) | ||
1014 | goto fail; | ||
1015 | |||
1016 | trigger = ieee80211_get_rx_led_name(priv->hw); | ||
1017 | snprintf(priv->rx_led.name, sizeof(priv->rx_led.name), | ||
1018 | "ath9k-%s::rx", wiphy_name(priv->hw->wiphy)); | ||
1019 | ret = ath9k_register_led(priv, &priv->rx_led, trigger); | ||
1020 | priv->rx_led.led_type = ATH_LED_RX; | ||
1021 | if (ret) | ||
1022 | goto fail; | ||
1023 | |||
1024 | priv->op_flags &= ~OP_LED_DEINIT; | ||
1025 | |||
1026 | return; | ||
1027 | |||
1028 | fail: | ||
1029 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
1030 | ath9k_deinit_leds(priv); | ||
1031 | } | ||
1032 | |||
1033 | /*******************/ | ||
1034 | /* Rfkill */ | ||
1035 | /*******************/ | ||
1036 | |||
1037 | static bool ath_is_rfkill_set(struct ath9k_htc_priv *priv) | ||
1038 | { | ||
1039 | return ath9k_hw_gpio_get(priv->ah, priv->ah->rfkill_gpio) == | ||
1040 | priv->ah->rfkill_polarity; | ||
1041 | } | ||
1042 | |||
1043 | static void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw) | ||
1044 | { | ||
1045 | struct ath9k_htc_priv *priv = hw->priv; | ||
1046 | bool blocked = !!ath_is_rfkill_set(priv); | ||
1047 | |||
1048 | wiphy_rfkill_set_hw_state(hw->wiphy, blocked); | ||
1049 | } | ||
1050 | |||
1051 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv) | ||
1052 | { | ||
1053 | if (priv->ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) | ||
1054 | wiphy_rfkill_start_polling(priv->hw->wiphy); | ||
1055 | } | ||
1056 | |||
1057 | /**********************/ | ||
1058 | /* mac80211 Callbacks */ | ||
1059 | /**********************/ | ||
1060 | |||
1061 | static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
1062 | { | ||
1063 | struct ieee80211_hdr *hdr; | ||
1064 | struct ath9k_htc_priv *priv = hw->priv; | ||
1065 | int padpos, padsize, ret; | ||
1066 | |||
1067 | hdr = (struct ieee80211_hdr *) skb->data; | ||
1068 | |||
1069 | /* Add the padding after the header if this is not already done */ | ||
1070 | padpos = ath9k_cmn_padpos(hdr->frame_control); | ||
1071 | padsize = padpos & 3; | ||
1072 | if (padsize && skb->len > padpos) { | ||
1073 | if (skb_headroom(skb) < padsize) | ||
1074 | return -1; | ||
1075 | skb_push(skb, padsize); | ||
1076 | memmove(skb->data, skb->data + padsize, padpos); | ||
1077 | } | ||
1078 | |||
1079 | ret = ath9k_htc_tx_start(priv, skb); | ||
1080 | if (ret != 0) { | ||
1081 | if (ret == -ENOMEM) { | ||
1082 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1083 | "Stopping TX queues\n"); | ||
1084 | ieee80211_stop_queues(hw); | ||
1085 | spin_lock_bh(&priv->tx_lock); | ||
1086 | priv->tx_queues_stop = true; | ||
1087 | spin_unlock_bh(&priv->tx_lock); | ||
1088 | } else { | ||
1089 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
1090 | "Tx failed"); | ||
1091 | } | ||
1092 | goto fail_tx; | ||
1093 | } | ||
1094 | |||
1095 | return 0; | ||
1096 | |||
1097 | fail_tx: | ||
1098 | dev_kfree_skb_any(skb); | ||
1099 | return 0; | ||
1100 | } | ||
1101 | |||
1102 | static int ath9k_htc_radio_enable(struct ieee80211_hw *hw, bool led) | ||
1103 | { | ||
1104 | struct ath9k_htc_priv *priv = hw->priv; | ||
1105 | struct ath_hw *ah = priv->ah; | ||
1106 | struct ath_common *common = ath9k_hw_common(ah); | ||
1107 | struct ieee80211_channel *curchan = hw->conf.channel; | ||
1108 | struct ath9k_channel *init_channel; | ||
1109 | int ret = 0; | ||
1110 | enum htc_phymode mode; | ||
1111 | __be16 htc_mode; | ||
1112 | u8 cmd_rsp; | ||
1113 | |||
1114 | ath_print(common, ATH_DBG_CONFIG, | ||
1115 | "Starting driver with initial channel: %d MHz\n", | ||
1116 | curchan->center_freq); | ||
1117 | |||
1118 | /* setup initial channel */ | ||
1119 | init_channel = ath9k_cmn_get_curchannel(hw, ah); | ||
1120 | |||
1121 | /* Reset SERDES registers */ | ||
1122 | ath9k_hw_configpcipowersave(ah, 0, 0); | ||
1123 | |||
1124 | ath9k_hw_htc_resetinit(ah); | ||
1125 | ret = ath9k_hw_reset(ah, init_channel, false); | ||
1126 | if (ret) { | ||
1127 | ath_print(common, ATH_DBG_FATAL, | ||
1128 | "Unable to reset hardware; reset status %d " | ||
1129 | "(freq %u MHz)\n", ret, curchan->center_freq); | ||
1130 | return ret; | ||
1131 | } | ||
1132 | |||
1133 | ath_update_txpow(priv); | ||
1134 | |||
1135 | mode = ath9k_htc_get_curmode(priv, init_channel); | ||
1136 | htc_mode = cpu_to_be16(mode); | ||
1137 | WMI_CMD_BUF(WMI_SET_MODE_CMDID, &htc_mode); | ||
1138 | WMI_CMD(WMI_ATH_INIT_CMDID); | ||
1139 | WMI_CMD(WMI_START_RECV_CMDID); | ||
1140 | |||
1141 | ath9k_host_rx_init(priv); | ||
1142 | |||
1143 | priv->op_flags &= ~OP_INVALID; | ||
1144 | htc_start(priv->htc); | ||
1145 | |||
1146 | spin_lock_bh(&priv->tx_lock); | ||
1147 | priv->tx_queues_stop = false; | ||
1148 | spin_unlock_bh(&priv->tx_lock); | ||
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 | |||
1157 | ieee80211_wake_queues(hw); | ||
1158 | |||
1159 | return ret; | ||
1160 | } | ||
1161 | |||
1162 | static int ath9k_htc_start(struct ieee80211_hw *hw) | ||
1163 | { | ||
1164 | struct ath9k_htc_priv *priv = hw->priv; | ||
1165 | int ret = 0; | ||
1166 | |||
1167 | mutex_lock(&priv->mutex); | ||
1168 | ret = ath9k_htc_radio_enable(hw, false); | ||
1169 | mutex_unlock(&priv->mutex); | ||
1170 | |||
1171 | return ret; | ||
1172 | } | ||
1173 | |||
1174 | static void ath9k_htc_radio_disable(struct ieee80211_hw *hw, bool led) | ||
1175 | { | ||
1176 | struct ath9k_htc_priv *priv = hw->priv; | ||
1177 | struct ath_hw *ah = priv->ah; | ||
1178 | struct ath_common *common = ath9k_hw_common(ah); | ||
1179 | int ret = 0; | ||
1180 | u8 cmd_rsp; | ||
1181 | |||
1182 | if (priv->op_flags & OP_INVALID) { | ||
1183 | ath_print(common, ATH_DBG_ANY, "Device not present\n"); | ||
1184 | return; | ||
1185 | } | ||
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 | |||
1193 | /* Cancel all the running timers/work .. */ | ||
1194 | cancel_work_sync(&priv->ps_work); | ||
1195 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | ||
1196 | cancel_delayed_work_sync(&priv->ath9k_aggr_work); | ||
1197 | cancel_delayed_work_sync(&priv->ath9k_led_blink_work); | ||
1198 | ath9k_led_stop_brightness(priv); | ||
1199 | |||
1200 | ath9k_htc_ps_wakeup(priv); | ||
1201 | htc_stop(priv->htc); | ||
1202 | WMI_CMD(WMI_DISABLE_INTR_CMDID); | ||
1203 | WMI_CMD(WMI_DRAIN_TXQ_ALL_CMDID); | ||
1204 | WMI_CMD(WMI_STOP_RECV_CMDID); | ||
1205 | ath9k_hw_phy_disable(ah); | ||
1206 | ath9k_hw_disable(ah); | ||
1207 | ath9k_hw_configpcipowersave(ah, 1, 1); | ||
1208 | ath9k_htc_ps_restore(priv); | ||
1209 | ath9k_htc_setpower(priv, ATH9K_PM_FULL_SLEEP); | ||
1210 | |||
1211 | skb_queue_purge(&priv->tx_queue); | ||
1212 | |||
1213 | /* Remove monitor interface here */ | ||
1214 | if (ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
1215 | if (ath9k_htc_remove_monitor_interface(priv)) | ||
1216 | ath_print(common, ATH_DBG_FATAL, | ||
1217 | "Unable to remove monitor interface\n"); | ||
1218 | else | ||
1219 | ath_print(common, ATH_DBG_CONFIG, | ||
1220 | "Monitor interface removed\n"); | ||
1221 | } | ||
1222 | |||
1223 | priv->op_flags |= OP_INVALID; | ||
1224 | |||
1225 | ath_print(common, ATH_DBG_CONFIG, "Driver halt\n"); | ||
1226 | } | ||
1227 | |||
1228 | static void ath9k_htc_stop(struct ieee80211_hw *hw) | ||
1229 | { | ||
1230 | struct ath9k_htc_priv *priv = hw->priv; | ||
1231 | |||
1232 | mutex_lock(&priv->mutex); | ||
1233 | ath9k_htc_radio_disable(hw, false); | ||
1234 | mutex_unlock(&priv->mutex); | ||
1235 | } | ||
1236 | |||
1237 | |||
1238 | static int ath9k_htc_add_interface(struct ieee80211_hw *hw, | ||
1239 | struct ieee80211_vif *vif) | ||
1240 | { | ||
1241 | struct ath9k_htc_priv *priv = hw->priv; | ||
1242 | struct ath9k_htc_vif *avp = (void *)vif->drv_priv; | ||
1243 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1244 | struct ath9k_htc_target_vif hvif; | ||
1245 | int ret = 0; | ||
1246 | u8 cmd_rsp; | ||
1247 | |||
1248 | mutex_lock(&priv->mutex); | ||
1249 | |||
1250 | /* Only one interface for now */ | ||
1251 | if (priv->nvifs > 0) { | ||
1252 | ret = -ENOBUFS; | ||
1253 | goto out; | ||
1254 | } | ||
1255 | |||
1256 | ath9k_htc_ps_wakeup(priv); | ||
1257 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | ||
1258 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); | ||
1259 | |||
1260 | switch (vif->type) { | ||
1261 | case NL80211_IFTYPE_STATION: | ||
1262 | hvif.opmode = cpu_to_be32(HTC_M_STA); | ||
1263 | break; | ||
1264 | case NL80211_IFTYPE_ADHOC: | ||
1265 | hvif.opmode = cpu_to_be32(HTC_M_IBSS); | ||
1266 | break; | ||
1267 | default: | ||
1268 | ath_print(common, ATH_DBG_FATAL, | ||
1269 | "Interface type %d not yet supported\n", vif->type); | ||
1270 | ret = -EOPNOTSUPP; | ||
1271 | goto out; | ||
1272 | } | ||
1273 | |||
1274 | ath_print(common, ATH_DBG_CONFIG, | ||
1275 | "Attach a VIF of type: %d\n", vif->type); | ||
1276 | |||
1277 | priv->ah->opmode = vif->type; | ||
1278 | |||
1279 | /* Index starts from zero on the target */ | ||
1280 | avp->index = hvif.index = priv->nvifs; | ||
1281 | hvif.rtsthreshold = cpu_to_be16(2304); | ||
1282 | WMI_CMD_BUF(WMI_VAP_CREATE_CMDID, &hvif); | ||
1283 | if (ret) | ||
1284 | goto out; | ||
1285 | |||
1286 | priv->nvifs++; | ||
1287 | |||
1288 | /* | ||
1289 | * We need a node in target to tx mgmt frames | ||
1290 | * before association. | ||
1291 | */ | ||
1292 | ret = ath9k_htc_add_station(priv, vif, NULL); | ||
1293 | if (ret) | ||
1294 | goto out; | ||
1295 | |||
1296 | ret = ath9k_htc_update_cap_target(priv); | ||
1297 | if (ret) | ||
1298 | ath_print(common, ATH_DBG_CONFIG, "Failed to update" | ||
1299 | " capability in target \n"); | ||
1300 | |||
1301 | priv->vif = vif; | ||
1302 | out: | ||
1303 | ath9k_htc_ps_restore(priv); | ||
1304 | mutex_unlock(&priv->mutex); | ||
1305 | return ret; | ||
1306 | } | ||
1307 | |||
1308 | static void ath9k_htc_remove_interface(struct ieee80211_hw *hw, | ||
1309 | struct ieee80211_vif *vif) | ||
1310 | { | ||
1311 | struct ath9k_htc_priv *priv = hw->priv; | ||
1312 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1313 | struct ath9k_htc_vif *avp = (void *)vif->drv_priv; | ||
1314 | struct ath9k_htc_target_vif hvif; | ||
1315 | int ret = 0; | ||
1316 | u8 cmd_rsp; | ||
1317 | |||
1318 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); | ||
1319 | |||
1320 | mutex_lock(&priv->mutex); | ||
1321 | |||
1322 | memset(&hvif, 0, sizeof(struct ath9k_htc_target_vif)); | ||
1323 | memcpy(&hvif.myaddr, vif->addr, ETH_ALEN); | ||
1324 | hvif.index = avp->index; | ||
1325 | WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif); | ||
1326 | priv->nvifs--; | ||
1327 | |||
1328 | ath9k_htc_remove_station(priv, vif, NULL); | ||
1329 | priv->vif = NULL; | ||
1330 | |||
1331 | mutex_unlock(&priv->mutex); | ||
1332 | } | ||
1333 | |||
1334 | static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed) | ||
1335 | { | ||
1336 | struct ath9k_htc_priv *priv = hw->priv; | ||
1337 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1338 | struct ieee80211_conf *conf = &hw->conf; | ||
1339 | |||
1340 | mutex_lock(&priv->mutex); | ||
1341 | |||
1342 | if (changed & IEEE80211_CONF_CHANGE_IDLE) { | ||
1343 | bool enable_radio = false; | ||
1344 | bool idle = !!(conf->flags & IEEE80211_CONF_IDLE); | ||
1345 | |||
1346 | if (!idle && priv->ps_idle) | ||
1347 | enable_radio = true; | ||
1348 | |||
1349 | priv->ps_idle = idle; | ||
1350 | |||
1351 | if (enable_radio) { | ||
1352 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | ||
1353 | ath9k_htc_radio_enable(hw, true); | ||
1354 | ath_print(common, ATH_DBG_CONFIG, | ||
1355 | "not-idle: enabling radio\n"); | ||
1356 | } | ||
1357 | } | ||
1358 | |||
1359 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | ||
1360 | struct ieee80211_channel *curchan = hw->conf.channel; | ||
1361 | int pos = curchan->hw_value; | ||
1362 | bool is_cw40 = false; | ||
1363 | |||
1364 | ath_print(common, ATH_DBG_CONFIG, "Set channel: %d MHz\n", | ||
1365 | curchan->center_freq); | ||
1366 | |||
1367 | if (check_rc_update(hw, &is_cw40)) | ||
1368 | ath9k_htc_rc_update(priv, is_cw40); | ||
1369 | |||
1370 | ath9k_cmn_update_ichannel(hw, &priv->ah->channels[pos]); | ||
1371 | |||
1372 | if (ath9k_htc_set_channel(priv, hw, &priv->ah->channels[pos]) < 0) { | ||
1373 | ath_print(common, ATH_DBG_FATAL, | ||
1374 | "Unable to set channel\n"); | ||
1375 | mutex_unlock(&priv->mutex); | ||
1376 | return -EINVAL; | ||
1377 | } | ||
1378 | |||
1379 | } | ||
1380 | if (changed & IEEE80211_CONF_CHANGE_PS) { | ||
1381 | if (conf->flags & IEEE80211_CONF_PS) { | ||
1382 | ath9k_htc_setpower(priv, ATH9K_PM_NETWORK_SLEEP); | ||
1383 | priv->ps_enabled = true; | ||
1384 | } else { | ||
1385 | priv->ps_enabled = false; | ||
1386 | cancel_work_sync(&priv->ps_work); | ||
1387 | ath9k_htc_setpower(priv, ATH9K_PM_AWAKE); | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | if (changed & IEEE80211_CONF_CHANGE_MONITOR) { | ||
1392 | if (conf->flags & IEEE80211_CONF_MONITOR) { | ||
1393 | if (ath9k_htc_add_monitor_interface(priv)) | ||
1394 | ath_print(common, ATH_DBG_FATAL, | ||
1395 | "Failed to set monitor mode\n"); | ||
1396 | else | ||
1397 | ath_print(common, ATH_DBG_CONFIG, | ||
1398 | "HW opmode set to Monitor mode\n"); | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | if (priv->ps_idle) { | ||
1403 | ath_print(common, ATH_DBG_CONFIG, | ||
1404 | "idle: disabling radio\n"); | ||
1405 | ath9k_htc_radio_disable(hw, true); | ||
1406 | } | ||
1407 | |||
1408 | mutex_unlock(&priv->mutex); | ||
1409 | |||
1410 | return 0; | ||
1411 | } | ||
1412 | |||
1413 | #define SUPPORTED_FILTERS \ | ||
1414 | (FIF_PROMISC_IN_BSS | \ | ||
1415 | FIF_ALLMULTI | \ | ||
1416 | FIF_CONTROL | \ | ||
1417 | FIF_PSPOLL | \ | ||
1418 | FIF_OTHER_BSS | \ | ||
1419 | FIF_BCN_PRBRESP_PROMISC | \ | ||
1420 | FIF_FCSFAIL) | ||
1421 | |||
1422 | static void ath9k_htc_configure_filter(struct ieee80211_hw *hw, | ||
1423 | unsigned int changed_flags, | ||
1424 | unsigned int *total_flags, | ||
1425 | u64 multicast) | ||
1426 | { | ||
1427 | struct ath9k_htc_priv *priv = hw->priv; | ||
1428 | u32 rfilt; | ||
1429 | |||
1430 | mutex_lock(&priv->mutex); | ||
1431 | |||
1432 | ath9k_htc_ps_wakeup(priv); | ||
1433 | changed_flags &= SUPPORTED_FILTERS; | ||
1434 | *total_flags &= SUPPORTED_FILTERS; | ||
1435 | |||
1436 | priv->rxfilter = *total_flags; | ||
1437 | rfilt = ath9k_htc_calcrxfilter(priv); | ||
1438 | ath9k_hw_setrxfilter(priv->ah, rfilt); | ||
1439 | |||
1440 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_CONFIG, | ||
1441 | "Set HW RX filter: 0x%x\n", rfilt); | ||
1442 | |||
1443 | ath9k_htc_ps_restore(priv); | ||
1444 | mutex_unlock(&priv->mutex); | ||
1445 | } | ||
1446 | |||
1447 | static void ath9k_htc_sta_notify(struct ieee80211_hw *hw, | ||
1448 | struct ieee80211_vif *vif, | ||
1449 | enum sta_notify_cmd cmd, | ||
1450 | struct ieee80211_sta *sta) | ||
1451 | { | ||
1452 | struct ath9k_htc_priv *priv = hw->priv; | ||
1453 | int ret; | ||
1454 | |||
1455 | mutex_lock(&priv->mutex); | ||
1456 | |||
1457 | switch (cmd) { | ||
1458 | case STA_NOTIFY_ADD: | ||
1459 | ret = ath9k_htc_add_station(priv, vif, sta); | ||
1460 | if (!ret) | ||
1461 | ath9k_htc_init_rate(priv, vif, sta); | ||
1462 | break; | ||
1463 | case STA_NOTIFY_REMOVE: | ||
1464 | ath9k_htc_remove_station(priv, vif, sta); | ||
1465 | break; | ||
1466 | default: | ||
1467 | break; | ||
1468 | } | ||
1469 | |||
1470 | mutex_unlock(&priv->mutex); | ||
1471 | } | ||
1472 | |||
1473 | static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, u16 queue, | ||
1474 | const struct ieee80211_tx_queue_params *params) | ||
1475 | { | ||
1476 | struct ath9k_htc_priv *priv = hw->priv; | ||
1477 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1478 | struct ath9k_tx_queue_info qi; | ||
1479 | int ret = 0, qnum; | ||
1480 | |||
1481 | if (queue >= WME_NUM_AC) | ||
1482 | return 0; | ||
1483 | |||
1484 | mutex_lock(&priv->mutex); | ||
1485 | |||
1486 | memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); | ||
1487 | |||
1488 | qi.tqi_aifs = params->aifs; | ||
1489 | qi.tqi_cwmin = params->cw_min; | ||
1490 | qi.tqi_cwmax = params->cw_max; | ||
1491 | qi.tqi_burstTime = params->txop; | ||
1492 | |||
1493 | qnum = get_hw_qnum(queue, priv->hwq_map); | ||
1494 | |||
1495 | ath_print(common, ATH_DBG_CONFIG, | ||
1496 | "Configure tx [queue/hwq] [%d/%d], " | ||
1497 | "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", | ||
1498 | queue, qnum, params->aifs, params->cw_min, | ||
1499 | params->cw_max, params->txop); | ||
1500 | |||
1501 | ret = ath_htc_txq_update(priv, qnum, &qi); | ||
1502 | if (ret) | ||
1503 | ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); | ||
1504 | |||
1505 | mutex_unlock(&priv->mutex); | ||
1506 | |||
1507 | return ret; | ||
1508 | } | ||
1509 | |||
1510 | static int ath9k_htc_set_key(struct ieee80211_hw *hw, | ||
1511 | enum set_key_cmd cmd, | ||
1512 | struct ieee80211_vif *vif, | ||
1513 | struct ieee80211_sta *sta, | ||
1514 | struct ieee80211_key_conf *key) | ||
1515 | { | ||
1516 | struct ath9k_htc_priv *priv = hw->priv; | ||
1517 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1518 | int ret = 0; | ||
1519 | |||
1520 | if (htc_modparam_nohwcrypt) | ||
1521 | return -ENOSPC; | ||
1522 | |||
1523 | mutex_lock(&priv->mutex); | ||
1524 | ath_print(common, ATH_DBG_CONFIG, "Set HW Key\n"); | ||
1525 | ath9k_htc_ps_wakeup(priv); | ||
1526 | |||
1527 | switch (cmd) { | ||
1528 | case SET_KEY: | ||
1529 | ret = ath9k_cmn_key_config(common, vif, sta, key); | ||
1530 | if (ret >= 0) { | ||
1531 | key->hw_key_idx = ret; | ||
1532 | /* push IV and Michael MIC generation to stack */ | ||
1533 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; | ||
1534 | if (key->alg == ALG_TKIP) | ||
1535 | key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; | ||
1536 | if (priv->ah->sw_mgmt_crypto && key->alg == ALG_CCMP) | ||
1537 | key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; | ||
1538 | ret = 0; | ||
1539 | } | ||
1540 | break; | ||
1541 | case DISABLE_KEY: | ||
1542 | ath9k_cmn_key_delete(common, key); | ||
1543 | break; | ||
1544 | default: | ||
1545 | ret = -EINVAL; | ||
1546 | } | ||
1547 | |||
1548 | ath9k_htc_ps_restore(priv); | ||
1549 | mutex_unlock(&priv->mutex); | ||
1550 | |||
1551 | return ret; | ||
1552 | } | ||
1553 | |||
1554 | static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | ||
1555 | struct ieee80211_vif *vif, | ||
1556 | struct ieee80211_bss_conf *bss_conf, | ||
1557 | u32 changed) | ||
1558 | { | ||
1559 | struct ath9k_htc_priv *priv = hw->priv; | ||
1560 | struct ath_hw *ah = priv->ah; | ||
1561 | struct ath_common *common = ath9k_hw_common(ah); | ||
1562 | |||
1563 | mutex_lock(&priv->mutex); | ||
1564 | ath9k_htc_ps_wakeup(priv); | ||
1565 | |||
1566 | if (changed & BSS_CHANGED_ASSOC) { | ||
1567 | common->curaid = bss_conf->assoc ? | ||
1568 | bss_conf->aid : 0; | ||
1569 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | ||
1570 | bss_conf->assoc); | ||
1571 | |||
1572 | if (bss_conf->assoc) { | ||
1573 | priv->op_flags |= OP_ASSOCIATED; | ||
1574 | ath_start_ani(priv); | ||
1575 | } else { | ||
1576 | priv->op_flags &= ~OP_ASSOCIATED; | ||
1577 | cancel_work_sync(&priv->ps_work); | ||
1578 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | ||
1579 | } | ||
1580 | } | ||
1581 | |||
1582 | if (changed & BSS_CHANGED_BSSID) { | ||
1583 | /* Set BSSID */ | ||
1584 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1585 | ath9k_hw_write_associd(ah); | ||
1586 | |||
1587 | ath_print(common, ATH_DBG_CONFIG, | ||
1588 | "BSSID: %pM aid: 0x%x\n", | ||
1589 | common->curbssid, common->curaid); | ||
1590 | } | ||
1591 | |||
1592 | if ((changed & BSS_CHANGED_BEACON_INT) || | ||
1593 | (changed & BSS_CHANGED_BEACON) || | ||
1594 | ((changed & BSS_CHANGED_BEACON_ENABLED) && | ||
1595 | bss_conf->enable_beacon)) { | ||
1596 | priv->op_flags |= OP_ENABLE_BEACON; | ||
1597 | ath9k_htc_beacon_config(priv, vif); | ||
1598 | } | ||
1599 | |||
1600 | if ((changed & BSS_CHANGED_BEACON_ENABLED) && | ||
1601 | !bss_conf->enable_beacon) { | ||
1602 | priv->op_flags &= ~OP_ENABLE_BEACON; | ||
1603 | ath9k_htc_beacon_config(priv, vif); | ||
1604 | } | ||
1605 | |||
1606 | if (changed & BSS_CHANGED_ERP_PREAMBLE) { | ||
1607 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed PREAMBLE %d\n", | ||
1608 | bss_conf->use_short_preamble); | ||
1609 | if (bss_conf->use_short_preamble) | ||
1610 | priv->op_flags |= OP_PREAMBLE_SHORT; | ||
1611 | else | ||
1612 | priv->op_flags &= ~OP_PREAMBLE_SHORT; | ||
1613 | } | ||
1614 | |||
1615 | if (changed & BSS_CHANGED_ERP_CTS_PROT) { | ||
1616 | ath_print(common, ATH_DBG_CONFIG, "BSS Changed CTS PROT %d\n", | ||
1617 | bss_conf->use_cts_prot); | ||
1618 | if (bss_conf->use_cts_prot && | ||
1619 | hw->conf.channel->band != IEEE80211_BAND_5GHZ) | ||
1620 | priv->op_flags |= OP_PROTECT_ENABLE; | ||
1621 | else | ||
1622 | priv->op_flags &= ~OP_PROTECT_ENABLE; | ||
1623 | } | ||
1624 | |||
1625 | if (changed & BSS_CHANGED_ERP_SLOT) { | ||
1626 | if (bss_conf->use_short_slot) | ||
1627 | ah->slottime = 9; | ||
1628 | else | ||
1629 | ah->slottime = 20; | ||
1630 | |||
1631 | ath9k_hw_init_global_settings(ah); | ||
1632 | } | ||
1633 | |||
1634 | ath9k_htc_ps_restore(priv); | ||
1635 | mutex_unlock(&priv->mutex); | ||
1636 | } | ||
1637 | |||
1638 | static u64 ath9k_htc_get_tsf(struct ieee80211_hw *hw) | ||
1639 | { | ||
1640 | struct ath9k_htc_priv *priv = hw->priv; | ||
1641 | u64 tsf; | ||
1642 | |||
1643 | mutex_lock(&priv->mutex); | ||
1644 | tsf = ath9k_hw_gettsf64(priv->ah); | ||
1645 | mutex_unlock(&priv->mutex); | ||
1646 | |||
1647 | return tsf; | ||
1648 | } | ||
1649 | |||
1650 | static void ath9k_htc_set_tsf(struct ieee80211_hw *hw, u64 tsf) | ||
1651 | { | ||
1652 | struct ath9k_htc_priv *priv = hw->priv; | ||
1653 | |||
1654 | mutex_lock(&priv->mutex); | ||
1655 | ath9k_hw_settsf64(priv->ah, tsf); | ||
1656 | mutex_unlock(&priv->mutex); | ||
1657 | } | ||
1658 | |||
1659 | static void ath9k_htc_reset_tsf(struct ieee80211_hw *hw) | ||
1660 | { | ||
1661 | struct ath9k_htc_priv *priv = hw->priv; | ||
1662 | |||
1663 | ath9k_htc_ps_wakeup(priv); | ||
1664 | mutex_lock(&priv->mutex); | ||
1665 | ath9k_hw_reset_tsf(priv->ah); | ||
1666 | mutex_unlock(&priv->mutex); | ||
1667 | ath9k_htc_ps_restore(priv); | ||
1668 | } | ||
1669 | |||
1670 | static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw, | ||
1671 | struct ieee80211_vif *vif, | ||
1672 | enum ieee80211_ampdu_mlme_action action, | ||
1673 | struct ieee80211_sta *sta, | ||
1674 | u16 tid, u16 *ssn) | ||
1675 | { | ||
1676 | struct ath9k_htc_priv *priv = hw->priv; | ||
1677 | struct ath9k_htc_aggr_work *work = &priv->aggr_work; | ||
1678 | struct ath9k_htc_sta *ista; | ||
1679 | |||
1680 | switch (action) { | ||
1681 | case IEEE80211_AMPDU_RX_START: | ||
1682 | break; | ||
1683 | case IEEE80211_AMPDU_RX_STOP: | ||
1684 | break; | ||
1685 | case IEEE80211_AMPDU_TX_START: | ||
1686 | case IEEE80211_AMPDU_TX_STOP: | ||
1687 | if (!(priv->op_flags & OP_TXAGGR)) | ||
1688 | return -ENOTSUPP; | ||
1689 | memcpy(work->sta_addr, sta->addr, ETH_ALEN); | ||
1690 | work->hw = hw; | ||
1691 | work->vif = vif; | ||
1692 | work->action = action; | ||
1693 | work->tid = tid; | ||
1694 | ieee80211_queue_delayed_work(hw, &priv->ath9k_aggr_work, 0); | ||
1695 | break; | ||
1696 | case IEEE80211_AMPDU_TX_OPERATIONAL: | ||
1697 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
1698 | ista->tid_state[tid] = AGGR_OPERATIONAL; | ||
1699 | break; | ||
1700 | default: | ||
1701 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_FATAL, | ||
1702 | "Unknown AMPDU action\n"); | ||
1703 | } | ||
1704 | |||
1705 | return 0; | ||
1706 | } | ||
1707 | |||
1708 | static void ath9k_htc_sw_scan_start(struct ieee80211_hw *hw) | ||
1709 | { | ||
1710 | struct ath9k_htc_priv *priv = hw->priv; | ||
1711 | |||
1712 | mutex_lock(&priv->mutex); | ||
1713 | spin_lock_bh(&priv->beacon_lock); | ||
1714 | priv->op_flags |= OP_SCANNING; | ||
1715 | spin_unlock_bh(&priv->beacon_lock); | ||
1716 | cancel_work_sync(&priv->ps_work); | ||
1717 | cancel_delayed_work_sync(&priv->ath9k_ani_work); | ||
1718 | mutex_unlock(&priv->mutex); | ||
1719 | } | ||
1720 | |||
1721 | static void ath9k_htc_sw_scan_complete(struct ieee80211_hw *hw) | ||
1722 | { | ||
1723 | struct ath9k_htc_priv *priv = hw->priv; | ||
1724 | |||
1725 | ath9k_htc_ps_wakeup(priv); | ||
1726 | mutex_lock(&priv->mutex); | ||
1727 | spin_lock_bh(&priv->beacon_lock); | ||
1728 | priv->op_flags &= ~OP_SCANNING; | ||
1729 | spin_unlock_bh(&priv->beacon_lock); | ||
1730 | priv->op_flags |= OP_FULL_RESET; | ||
1731 | if (priv->op_flags & OP_ASSOCIATED) | ||
1732 | ath9k_htc_beacon_config(priv, priv->vif); | ||
1733 | ath_start_ani(priv); | ||
1734 | mutex_unlock(&priv->mutex); | ||
1735 | ath9k_htc_ps_restore(priv); | ||
1736 | } | ||
1737 | |||
1738 | static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value) | ||
1739 | { | ||
1740 | return 0; | ||
1741 | } | ||
1742 | |||
1743 | static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, | ||
1744 | u8 coverage_class) | ||
1745 | { | ||
1746 | struct ath9k_htc_priv *priv = hw->priv; | ||
1747 | |||
1748 | mutex_lock(&priv->mutex); | ||
1749 | priv->ah->coverage_class = coverage_class; | ||
1750 | ath9k_hw_init_global_settings(priv->ah); | ||
1751 | mutex_unlock(&priv->mutex); | ||
1752 | } | ||
1753 | |||
1754 | struct ieee80211_ops ath9k_htc_ops = { | ||
1755 | .tx = ath9k_htc_tx, | ||
1756 | .start = ath9k_htc_start, | ||
1757 | .stop = ath9k_htc_stop, | ||
1758 | .add_interface = ath9k_htc_add_interface, | ||
1759 | .remove_interface = ath9k_htc_remove_interface, | ||
1760 | .config = ath9k_htc_config, | ||
1761 | .configure_filter = ath9k_htc_configure_filter, | ||
1762 | .sta_notify = ath9k_htc_sta_notify, | ||
1763 | .conf_tx = ath9k_htc_conf_tx, | ||
1764 | .bss_info_changed = ath9k_htc_bss_info_changed, | ||
1765 | .set_key = ath9k_htc_set_key, | ||
1766 | .get_tsf = ath9k_htc_get_tsf, | ||
1767 | .set_tsf = ath9k_htc_set_tsf, | ||
1768 | .reset_tsf = ath9k_htc_reset_tsf, | ||
1769 | .ampdu_action = ath9k_htc_ampdu_action, | ||
1770 | .sw_scan_start = ath9k_htc_sw_scan_start, | ||
1771 | .sw_scan_complete = ath9k_htc_sw_scan_complete, | ||
1772 | .set_rts_threshold = ath9k_htc_set_rts_threshold, | ||
1773 | .rfkill_poll = ath9k_htc_rfkill_poll_state, | ||
1774 | .set_coverage_class = ath9k_htc_set_coverage_class, | ||
1775 | }; | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c new file mode 100644 index 000000000000..2571b443ac82 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | |||
@@ -0,0 +1,707 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | /******/ | ||
20 | /* TX */ | ||
21 | /******/ | ||
22 | |||
23 | int get_hw_qnum(u16 queue, int *hwq_map) | ||
24 | { | ||
25 | switch (queue) { | ||
26 | case 0: | ||
27 | return hwq_map[ATH9K_WME_AC_VO]; | ||
28 | case 1: | ||
29 | return hwq_map[ATH9K_WME_AC_VI]; | ||
30 | case 2: | ||
31 | return hwq_map[ATH9K_WME_AC_BE]; | ||
32 | case 3: | ||
33 | return hwq_map[ATH9K_WME_AC_BK]; | ||
34 | default: | ||
35 | return hwq_map[ATH9K_WME_AC_BE]; | ||
36 | } | ||
37 | } | ||
38 | |||
39 | int ath_htc_txq_update(struct ath9k_htc_priv *priv, int qnum, | ||
40 | struct ath9k_tx_queue_info *qinfo) | ||
41 | { | ||
42 | struct ath_hw *ah = priv->ah; | ||
43 | int error = 0; | ||
44 | struct ath9k_tx_queue_info qi; | ||
45 | |||
46 | ath9k_hw_get_txq_props(ah, qnum, &qi); | ||
47 | |||
48 | qi.tqi_aifs = qinfo->tqi_aifs; | ||
49 | qi.tqi_cwmin = qinfo->tqi_cwmin / 2; /* XXX */ | ||
50 | qi.tqi_cwmax = qinfo->tqi_cwmax; | ||
51 | qi.tqi_burstTime = qinfo->tqi_burstTime; | ||
52 | qi.tqi_readyTime = qinfo->tqi_readyTime; | ||
53 | |||
54 | if (!ath9k_hw_set_txq_props(ah, qnum, &qi)) { | ||
55 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
56 | "Unable to update hardware queue %u!\n", qnum); | ||
57 | error = -EIO; | ||
58 | } else { | ||
59 | ath9k_hw_resettxqueue(ah, qnum); | ||
60 | } | ||
61 | |||
62 | return error; | ||
63 | } | ||
64 | |||
65 | int ath9k_htc_tx_start(struct ath9k_htc_priv *priv, struct sk_buff *skb) | ||
66 | { | ||
67 | struct ieee80211_hdr *hdr; | ||
68 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | ||
69 | struct ieee80211_sta *sta = tx_info->control.sta; | ||
70 | struct ath9k_htc_sta *ista; | ||
71 | struct ath9k_htc_vif *avp; | ||
72 | struct ath9k_htc_tx_ctl tx_ctl; | ||
73 | enum htc_endpoint_id epid; | ||
74 | u16 qnum, hw_qnum; | ||
75 | __le16 fc; | ||
76 | u8 *tx_fhdr; | ||
77 | u8 sta_idx; | ||
78 | |||
79 | hdr = (struct ieee80211_hdr *) skb->data; | ||
80 | fc = hdr->frame_control; | ||
81 | |||
82 | avp = (struct ath9k_htc_vif *) tx_info->control.vif->drv_priv; | ||
83 | if (sta) { | ||
84 | ista = (struct ath9k_htc_sta *) sta->drv_priv; | ||
85 | sta_idx = ista->index; | ||
86 | } else { | ||
87 | sta_idx = 0; | ||
88 | } | ||
89 | |||
90 | memset(&tx_ctl, 0, sizeof(struct ath9k_htc_tx_ctl)); | ||
91 | |||
92 | if (ieee80211_is_data(fc)) { | ||
93 | struct tx_frame_hdr tx_hdr; | ||
94 | u8 *qc; | ||
95 | |||
96 | memset(&tx_hdr, 0, sizeof(struct tx_frame_hdr)); | ||
97 | |||
98 | tx_hdr.node_idx = sta_idx; | ||
99 | tx_hdr.vif_idx = avp->index; | ||
100 | |||
101 | if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { | ||
102 | tx_ctl.type = ATH9K_HTC_AMPDU; | ||
103 | tx_hdr.data_type = ATH9K_HTC_AMPDU; | ||
104 | } else { | ||
105 | tx_ctl.type = ATH9K_HTC_NORMAL; | ||
106 | tx_hdr.data_type = ATH9K_HTC_NORMAL; | ||
107 | } | ||
108 | |||
109 | if (ieee80211_is_data(fc)) { | ||
110 | qc = ieee80211_get_qos_ctl(hdr); | ||
111 | tx_hdr.tidno = qc[0] & IEEE80211_QOS_CTL_TID_MASK; | ||
112 | } | ||
113 | |||
114 | /* Check for RTS protection */ | ||
115 | if (priv->hw->wiphy->rts_threshold != (u32) -1) | ||
116 | if (skb->len > priv->hw->wiphy->rts_threshold) | ||
117 | tx_hdr.flags |= ATH9K_HTC_TX_RTSCTS; | ||
118 | |||
119 | /* CTS-to-self */ | ||
120 | if (!(tx_hdr.flags & ATH9K_HTC_TX_RTSCTS) && | ||
121 | (priv->op_flags & OP_PROTECT_ENABLE)) | ||
122 | tx_hdr.flags |= ATH9K_HTC_TX_CTSONLY; | ||
123 | |||
124 | tx_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
125 | if (tx_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
126 | tx_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
127 | else | ||
128 | tx_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
129 | |||
130 | tx_fhdr = skb_push(skb, sizeof(tx_hdr)); | ||
131 | memcpy(tx_fhdr, (u8 *) &tx_hdr, sizeof(tx_hdr)); | ||
132 | |||
133 | qnum = skb_get_queue_mapping(skb); | ||
134 | hw_qnum = get_hw_qnum(qnum, priv->hwq_map); | ||
135 | |||
136 | switch (hw_qnum) { | ||
137 | case 0: | ||
138 | epid = priv->data_be_ep; | ||
139 | break; | ||
140 | case 2: | ||
141 | epid = priv->data_vi_ep; | ||
142 | break; | ||
143 | case 3: | ||
144 | epid = priv->data_vo_ep; | ||
145 | break; | ||
146 | case 1: | ||
147 | default: | ||
148 | epid = priv->data_bk_ep; | ||
149 | break; | ||
150 | } | ||
151 | } else { | ||
152 | struct tx_mgmt_hdr mgmt_hdr; | ||
153 | |||
154 | memset(&mgmt_hdr, 0, sizeof(struct tx_mgmt_hdr)); | ||
155 | |||
156 | tx_ctl.type = ATH9K_HTC_NORMAL; | ||
157 | |||
158 | mgmt_hdr.node_idx = sta_idx; | ||
159 | mgmt_hdr.vif_idx = avp->index; | ||
160 | mgmt_hdr.tidno = 0; | ||
161 | mgmt_hdr.flags = 0; | ||
162 | |||
163 | mgmt_hdr.key_type = ath9k_cmn_get_hw_crypto_keytype(skb); | ||
164 | if (mgmt_hdr.key_type == ATH9K_KEY_TYPE_CLEAR) | ||
165 | mgmt_hdr.keyix = (u8) ATH9K_TXKEYIX_INVALID; | ||
166 | else | ||
167 | mgmt_hdr.keyix = tx_info->control.hw_key->hw_key_idx; | ||
168 | |||
169 | tx_fhdr = skb_push(skb, sizeof(mgmt_hdr)); | ||
170 | memcpy(tx_fhdr, (u8 *) &mgmt_hdr, sizeof(mgmt_hdr)); | ||
171 | epid = priv->mgmt_ep; | ||
172 | } | ||
173 | |||
174 | return htc_send(priv->htc, skb, epid, &tx_ctl); | ||
175 | } | ||
176 | |||
177 | void ath9k_tx_tasklet(unsigned long data) | ||
178 | { | ||
179 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | ||
180 | struct ieee80211_sta *sta; | ||
181 | struct ieee80211_hdr *hdr; | ||
182 | struct ieee80211_tx_info *tx_info; | ||
183 | struct sk_buff *skb = NULL; | ||
184 | __le16 fc; | ||
185 | |||
186 | while ((skb = skb_dequeue(&priv->tx_queue)) != NULL) { | ||
187 | |||
188 | hdr = (struct ieee80211_hdr *) skb->data; | ||
189 | fc = hdr->frame_control; | ||
190 | tx_info = IEEE80211_SKB_CB(skb); | ||
191 | |||
192 | memset(&tx_info->status, 0, sizeof(tx_info->status)); | ||
193 | |||
194 | rcu_read_lock(); | ||
195 | |||
196 | sta = ieee80211_find_sta(priv->vif, hdr->addr1); | ||
197 | if (!sta) { | ||
198 | rcu_read_unlock(); | ||
199 | ieee80211_tx_status(priv->hw, skb); | ||
200 | continue; | ||
201 | } | ||
202 | |||
203 | /* Check if we need to start aggregation */ | ||
204 | |||
205 | if (sta && conf_is_ht(&priv->hw->conf) && | ||
206 | (priv->op_flags & OP_TXAGGR) | ||
207 | && !(skb->protocol == cpu_to_be16(ETH_P_PAE))) { | ||
208 | if (ieee80211_is_data_qos(fc)) { | ||
209 | u8 *qc, tid; | ||
210 | struct ath9k_htc_sta *ista; | ||
211 | |||
212 | qc = ieee80211_get_qos_ctl(hdr); | ||
213 | tid = qc[0] & 0xf; | ||
214 | ista = (struct ath9k_htc_sta *)sta->drv_priv; | ||
215 | |||
216 | if ((tid < ATH9K_HTC_MAX_TID) && | ||
217 | ista->tid_state[tid] == AGGR_STOP) { | ||
218 | ieee80211_start_tx_ba_session(sta, tid); | ||
219 | ista->tid_state[tid] = AGGR_PROGRESS; | ||
220 | } | ||
221 | } | ||
222 | } | ||
223 | |||
224 | rcu_read_unlock(); | ||
225 | |||
226 | /* Send status to mac80211 */ | ||
227 | ieee80211_tx_status(priv->hw, skb); | ||
228 | } | ||
229 | |||
230 | /* Wake TX queues if needed */ | ||
231 | spin_lock_bh(&priv->tx_lock); | ||
232 | if (priv->tx_queues_stop) { | ||
233 | priv->tx_queues_stop = false; | ||
234 | spin_unlock_bh(&priv->tx_lock); | ||
235 | ath_print(ath9k_hw_common(priv->ah), ATH_DBG_XMIT, | ||
236 | "Waking up TX queues\n"); | ||
237 | ieee80211_wake_queues(priv->hw); | ||
238 | return; | ||
239 | } | ||
240 | spin_unlock_bh(&priv->tx_lock); | ||
241 | } | ||
242 | |||
243 | void ath9k_htc_txep(void *drv_priv, struct sk_buff *skb, | ||
244 | enum htc_endpoint_id ep_id, bool txok) | ||
245 | { | ||
246 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) drv_priv; | ||
247 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
248 | struct ieee80211_tx_info *tx_info; | ||
249 | |||
250 | if (!skb) | ||
251 | return; | ||
252 | |||
253 | if (ep_id == priv->mgmt_ep) { | ||
254 | skb_pull(skb, sizeof(struct tx_mgmt_hdr)); | ||
255 | } else if ((ep_id == priv->data_bk_ep) || | ||
256 | (ep_id == priv->data_be_ep) || | ||
257 | (ep_id == priv->data_vi_ep) || | ||
258 | (ep_id == priv->data_vo_ep)) { | ||
259 | skb_pull(skb, sizeof(struct tx_frame_hdr)); | ||
260 | } else { | ||
261 | ath_print(common, ATH_DBG_FATAL, | ||
262 | "Unsupported TX EPID: %d\n", ep_id); | ||
263 | dev_kfree_skb_any(skb); | ||
264 | return; | ||
265 | } | ||
266 | |||
267 | tx_info = IEEE80211_SKB_CB(skb); | ||
268 | |||
269 | if (txok) | ||
270 | tx_info->flags |= IEEE80211_TX_STAT_ACK; | ||
271 | |||
272 | skb_queue_tail(&priv->tx_queue, skb); | ||
273 | tasklet_schedule(&priv->tx_tasklet); | ||
274 | } | ||
275 | |||
276 | int ath9k_tx_init(struct ath9k_htc_priv *priv) | ||
277 | { | ||
278 | skb_queue_head_init(&priv->tx_queue); | ||
279 | return 0; | ||
280 | } | ||
281 | |||
282 | void ath9k_tx_cleanup(struct ath9k_htc_priv *priv) | ||
283 | { | ||
284 | |||
285 | } | ||
286 | |||
287 | bool ath9k_htc_txq_setup(struct ath9k_htc_priv *priv, | ||
288 | enum ath9k_tx_queue_subtype subtype) | ||
289 | { | ||
290 | struct ath_hw *ah = priv->ah; | ||
291 | struct ath_common *common = ath9k_hw_common(ah); | ||
292 | struct ath9k_tx_queue_info qi; | ||
293 | int qnum; | ||
294 | |||
295 | memset(&qi, 0, sizeof(qi)); | ||
296 | |||
297 | qi.tqi_subtype = subtype; | ||
298 | qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT; | ||
299 | qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT; | ||
300 | qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT; | ||
301 | qi.tqi_physCompBuf = 0; | ||
302 | qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | TXQ_FLAG_TXDESCINT_ENABLE; | ||
303 | |||
304 | qnum = ath9k_hw_setuptxqueue(priv->ah, ATH9K_TX_QUEUE_DATA, &qi); | ||
305 | if (qnum == -1) | ||
306 | return false; | ||
307 | |||
308 | if (qnum >= ARRAY_SIZE(priv->hwq_map)) { | ||
309 | ath_print(common, ATH_DBG_FATAL, | ||
310 | "qnum %u out of range, max %u!\n", | ||
311 | qnum, (unsigned int)ARRAY_SIZE(priv->hwq_map)); | ||
312 | ath9k_hw_releasetxqueue(ah, qnum); | ||
313 | return false; | ||
314 | } | ||
315 | |||
316 | priv->hwq_map[subtype] = qnum; | ||
317 | return true; | ||
318 | } | ||
319 | |||
320 | /******/ | ||
321 | /* RX */ | ||
322 | /******/ | ||
323 | |||
324 | /* | ||
325 | * Calculate the RX filter to be set in the HW. | ||
326 | */ | ||
327 | u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv) | ||
328 | { | ||
329 | #define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR) | ||
330 | |||
331 | struct ath_hw *ah = priv->ah; | ||
332 | u32 rfilt; | ||
333 | |||
334 | rfilt = (ath9k_hw_getrxfilter(ah) & RX_FILTER_PRESERVE) | ||
335 | | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST | ||
336 | | ATH9K_RX_FILTER_MCAST; | ||
337 | |||
338 | /* If not a STA, enable processing of Probe Requests */ | ||
339 | if (ah->opmode != NL80211_IFTYPE_STATION) | ||
340 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; | ||
341 | |||
342 | /* | ||
343 | * Set promiscuous mode when FIF_PROMISC_IN_BSS is enabled for station | ||
344 | * mode interface or when in monitor mode. AP mode does not need this | ||
345 | * since it receives all in-BSS frames anyway. | ||
346 | */ | ||
347 | if (((ah->opmode != NL80211_IFTYPE_AP) && | ||
348 | (priv->rxfilter & FIF_PROMISC_IN_BSS)) || | ||
349 | (ah->opmode == NL80211_IFTYPE_MONITOR)) | ||
350 | rfilt |= ATH9K_RX_FILTER_PROM; | ||
351 | |||
352 | if (priv->rxfilter & FIF_CONTROL) | ||
353 | rfilt |= ATH9K_RX_FILTER_CONTROL; | ||
354 | |||
355 | if ((ah->opmode == NL80211_IFTYPE_STATION) && | ||
356 | !(priv->rxfilter & FIF_BCN_PRBRESP_PROMISC)) | ||
357 | rfilt |= ATH9K_RX_FILTER_MYBEACON; | ||
358 | else | ||
359 | rfilt |= ATH9K_RX_FILTER_BEACON; | ||
360 | |||
361 | if (conf_is_ht(&priv->hw->conf)) | ||
362 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; | ||
363 | |||
364 | return rfilt; | ||
365 | |||
366 | #undef RX_FILTER_PRESERVE | ||
367 | } | ||
368 | |||
369 | /* | ||
370 | * Recv initialization for opmode change. | ||
371 | */ | ||
372 | static void ath9k_htc_opmode_init(struct ath9k_htc_priv *priv) | ||
373 | { | ||
374 | struct ath_hw *ah = priv->ah; | ||
375 | struct ath_common *common = ath9k_hw_common(ah); | ||
376 | |||
377 | u32 rfilt, mfilt[2]; | ||
378 | |||
379 | /* configure rx filter */ | ||
380 | rfilt = ath9k_htc_calcrxfilter(priv); | ||
381 | ath9k_hw_setrxfilter(ah, rfilt); | ||
382 | |||
383 | /* configure bssid mask */ | ||
384 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | ||
385 | ath_hw_setbssidmask(common); | ||
386 | |||
387 | /* configure operational mode */ | ||
388 | ath9k_hw_setopmode(ah); | ||
389 | |||
390 | /* Handle any link-level address change. */ | ||
391 | ath9k_hw_setmac(ah, common->macaddr); | ||
392 | |||
393 | /* calculate and install multicast filter */ | ||
394 | mfilt[0] = mfilt[1] = ~0; | ||
395 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); | ||
396 | } | ||
397 | |||
398 | void ath9k_host_rx_init(struct ath9k_htc_priv *priv) | ||
399 | { | ||
400 | ath9k_hw_rxena(priv->ah); | ||
401 | ath9k_htc_opmode_init(priv); | ||
402 | ath9k_hw_startpcureceive(priv->ah); | ||
403 | priv->rx.last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
404 | } | ||
405 | |||
406 | static void ath9k_process_rate(struct ieee80211_hw *hw, | ||
407 | struct ieee80211_rx_status *rxs, | ||
408 | u8 rx_rate, u8 rs_flags) | ||
409 | { | ||
410 | struct ieee80211_supported_band *sband; | ||
411 | enum ieee80211_band band; | ||
412 | unsigned int i = 0; | ||
413 | |||
414 | if (rx_rate & 0x80) { | ||
415 | /* HT rate */ | ||
416 | rxs->flag |= RX_FLAG_HT; | ||
417 | if (rs_flags & ATH9K_RX_2040) | ||
418 | rxs->flag |= RX_FLAG_40MHZ; | ||
419 | if (rs_flags & ATH9K_RX_GI) | ||
420 | rxs->flag |= RX_FLAG_SHORT_GI; | ||
421 | rxs->rate_idx = rx_rate & 0x7f; | ||
422 | return; | ||
423 | } | ||
424 | |||
425 | band = hw->conf.channel->band; | ||
426 | sband = hw->wiphy->bands[band]; | ||
427 | |||
428 | for (i = 0; i < sband->n_bitrates; i++) { | ||
429 | if (sband->bitrates[i].hw_value == rx_rate) { | ||
430 | rxs->rate_idx = i; | ||
431 | return; | ||
432 | } | ||
433 | if (sband->bitrates[i].hw_value_short == rx_rate) { | ||
434 | rxs->rate_idx = i; | ||
435 | rxs->flag |= RX_FLAG_SHORTPRE; | ||
436 | return; | ||
437 | } | ||
438 | } | ||
439 | |||
440 | } | ||
441 | |||
442 | static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, | ||
443 | struct ath9k_htc_rxbuf *rxbuf, | ||
444 | struct ieee80211_rx_status *rx_status) | ||
445 | |||
446 | { | ||
447 | struct ieee80211_hdr *hdr; | ||
448 | struct ieee80211_hw *hw = priv->hw; | ||
449 | struct sk_buff *skb = rxbuf->skb; | ||
450 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
451 | struct ath_htc_rx_status *rxstatus; | ||
452 | int hdrlen, padpos, padsize; | ||
453 | int last_rssi = ATH_RSSI_DUMMY_MARKER; | ||
454 | __le16 fc; | ||
455 | |||
456 | if (skb->len <= HTC_RX_FRAME_HEADER_SIZE) { | ||
457 | ath_print(common, ATH_DBG_FATAL, | ||
458 | "Corrupted RX frame, dropping\n"); | ||
459 | goto rx_next; | ||
460 | } | ||
461 | |||
462 | rxstatus = (struct ath_htc_rx_status *)skb->data; | ||
463 | |||
464 | if (be16_to_cpu(rxstatus->rs_datalen) - | ||
465 | (skb->len - HTC_RX_FRAME_HEADER_SIZE) != 0) { | ||
466 | ath_print(common, ATH_DBG_FATAL, | ||
467 | "Corrupted RX data len, dropping " | ||
468 | "(dlen: %d, skblen: %d)\n", | ||
469 | rxstatus->rs_datalen, skb->len); | ||
470 | goto rx_next; | ||
471 | } | ||
472 | |||
473 | /* Get the RX status information */ | ||
474 | memcpy(&rxbuf->rxstatus, rxstatus, HTC_RX_FRAME_HEADER_SIZE); | ||
475 | skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); | ||
476 | |||
477 | hdr = (struct ieee80211_hdr *)skb->data; | ||
478 | fc = hdr->frame_control; | ||
479 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | ||
480 | |||
481 | padpos = ath9k_cmn_padpos(fc); | ||
482 | |||
483 | padsize = padpos & 3; | ||
484 | if (padsize && skb->len >= padpos+padsize+FCS_LEN) { | ||
485 | memmove(skb->data + padsize, skb->data, padpos); | ||
486 | skb_pull(skb, padsize); | ||
487 | } | ||
488 | |||
489 | memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); | ||
490 | |||
491 | if (rxbuf->rxstatus.rs_status != 0) { | ||
492 | if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_CRC) | ||
493 | rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; | ||
494 | if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_PHY) | ||
495 | goto rx_next; | ||
496 | |||
497 | if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT) { | ||
498 | /* FIXME */ | ||
499 | } else if (rxbuf->rxstatus.rs_status & ATH9K_RXERR_MIC) { | ||
500 | if (ieee80211_is_ctl(fc)) | ||
501 | /* | ||
502 | * Sometimes, we get invalid | ||
503 | * MIC failures on valid control frames. | ||
504 | * Remove these mic errors. | ||
505 | */ | ||
506 | rxbuf->rxstatus.rs_status &= ~ATH9K_RXERR_MIC; | ||
507 | else | ||
508 | rx_status->flag |= RX_FLAG_MMIC_ERROR; | ||
509 | } | ||
510 | |||
511 | /* | ||
512 | * Reject error frames with the exception of | ||
513 | * decryption and MIC failures. For monitor mode, | ||
514 | * we also ignore the CRC error. | ||
515 | */ | ||
516 | if (priv->ah->opmode == NL80211_IFTYPE_MONITOR) { | ||
517 | if (rxbuf->rxstatus.rs_status & | ||
518 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC | | ||
519 | ATH9K_RXERR_CRC)) | ||
520 | goto rx_next; | ||
521 | } else { | ||
522 | if (rxbuf->rxstatus.rs_status & | ||
523 | ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) { | ||
524 | goto rx_next; | ||
525 | } | ||
526 | } | ||
527 | } | ||
528 | |||
529 | if (!(rxbuf->rxstatus.rs_status & ATH9K_RXERR_DECRYPT)) { | ||
530 | u8 keyix; | ||
531 | keyix = rxbuf->rxstatus.rs_keyix; | ||
532 | if (keyix != ATH9K_RXKEYIX_INVALID) { | ||
533 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
534 | } else if (ieee80211_has_protected(fc) && | ||
535 | skb->len >= hdrlen + 4) { | ||
536 | keyix = skb->data[hdrlen + 3] >> 6; | ||
537 | if (test_bit(keyix, common->keymap)) | ||
538 | rx_status->flag |= RX_FLAG_DECRYPTED; | ||
539 | } | ||
540 | } | ||
541 | |||
542 | ath9k_process_rate(hw, rx_status, rxbuf->rxstatus.rs_rate, | ||
543 | rxbuf->rxstatus.rs_flags); | ||
544 | |||
545 | if (priv->op_flags & OP_ASSOCIATED) { | ||
546 | if (rxbuf->rxstatus.rs_rssi != ATH9K_RSSI_BAD && | ||
547 | !rxbuf->rxstatus.rs_moreaggr) | ||
548 | ATH_RSSI_LPF(priv->rx.last_rssi, | ||
549 | rxbuf->rxstatus.rs_rssi); | ||
550 | |||
551 | last_rssi = priv->rx.last_rssi; | ||
552 | |||
553 | if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) | ||
554 | rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, | ||
555 | ATH_RSSI_EP_MULTIPLIER); | ||
556 | |||
557 | if (rxbuf->rxstatus.rs_rssi < 0) | ||
558 | rxbuf->rxstatus.rs_rssi = 0; | ||
559 | |||
560 | if (ieee80211_is_beacon(fc)) | ||
561 | priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; | ||
562 | } | ||
563 | |||
564 | rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); | ||
565 | rx_status->band = hw->conf.channel->band; | ||
566 | rx_status->freq = hw->conf.channel->center_freq; | ||
567 | rx_status->signal = rxbuf->rxstatus.rs_rssi + ATH_DEFAULT_NOISE_FLOOR; | ||
568 | rx_status->antenna = rxbuf->rxstatus.rs_antenna; | ||
569 | rx_status->flag |= RX_FLAG_TSFT; | ||
570 | |||
571 | return true; | ||
572 | |||
573 | rx_next: | ||
574 | return false; | ||
575 | } | ||
576 | |||
577 | /* | ||
578 | * FIXME: Handle FLUSH later on. | ||
579 | */ | ||
580 | void ath9k_rx_tasklet(unsigned long data) | ||
581 | { | ||
582 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | ||
583 | struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; | ||
584 | struct ieee80211_rx_status rx_status; | ||
585 | struct sk_buff *skb; | ||
586 | unsigned long flags; | ||
587 | struct ieee80211_hdr *hdr; | ||
588 | |||
589 | do { | ||
590 | spin_lock_irqsave(&priv->rx.rxbuflock, flags); | ||
591 | list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { | ||
592 | if (tmp_buf->in_process) { | ||
593 | rxbuf = tmp_buf; | ||
594 | break; | ||
595 | } | ||
596 | } | ||
597 | |||
598 | if (rxbuf == NULL) { | ||
599 | spin_unlock_irqrestore(&priv->rx.rxbuflock, flags); | ||
600 | break; | ||
601 | } | ||
602 | |||
603 | if (!rxbuf->skb) | ||
604 | goto requeue; | ||
605 | |||
606 | if (!ath9k_rx_prepare(priv, rxbuf, &rx_status)) { | ||
607 | dev_kfree_skb_any(rxbuf->skb); | ||
608 | goto requeue; | ||
609 | } | ||
610 | |||
611 | memcpy(IEEE80211_SKB_RXCB(rxbuf->skb), &rx_status, | ||
612 | sizeof(struct ieee80211_rx_status)); | ||
613 | skb = rxbuf->skb; | ||
614 | hdr = (struct ieee80211_hdr *) skb->data; | ||
615 | |||
616 | if (ieee80211_is_beacon(hdr->frame_control) && priv->ps_enabled) | ||
617 | ieee80211_queue_work(priv->hw, &priv->ps_work); | ||
618 | |||
619 | spin_unlock_irqrestore(&priv->rx.rxbuflock, flags); | ||
620 | |||
621 | ieee80211_rx(priv->hw, skb); | ||
622 | |||
623 | spin_lock_irqsave(&priv->rx.rxbuflock, flags); | ||
624 | requeue: | ||
625 | rxbuf->in_process = false; | ||
626 | rxbuf->skb = NULL; | ||
627 | list_move_tail(&rxbuf->list, &priv->rx.rxbuf); | ||
628 | rxbuf = NULL; | ||
629 | spin_unlock_irqrestore(&priv->rx.rxbuflock, flags); | ||
630 | } while (1); | ||
631 | |||
632 | } | ||
633 | |||
634 | void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, | ||
635 | enum htc_endpoint_id ep_id) | ||
636 | { | ||
637 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)drv_priv; | ||
638 | struct ath_hw *ah = priv->ah; | ||
639 | struct ath_common *common = ath9k_hw_common(ah); | ||
640 | struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; | ||
641 | |||
642 | spin_lock(&priv->rx.rxbuflock); | ||
643 | list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { | ||
644 | if (!tmp_buf->in_process) { | ||
645 | rxbuf = tmp_buf; | ||
646 | break; | ||
647 | } | ||
648 | } | ||
649 | spin_unlock(&priv->rx.rxbuflock); | ||
650 | |||
651 | if (rxbuf == NULL) { | ||
652 | ath_print(common, ATH_DBG_ANY, | ||
653 | "No free RX buffer\n"); | ||
654 | goto err; | ||
655 | } | ||
656 | |||
657 | spin_lock(&priv->rx.rxbuflock); | ||
658 | rxbuf->skb = skb; | ||
659 | rxbuf->in_process = true; | ||
660 | spin_unlock(&priv->rx.rxbuflock); | ||
661 | |||
662 | tasklet_schedule(&priv->rx_tasklet); | ||
663 | return; | ||
664 | err: | ||
665 | dev_kfree_skb_any(skb); | ||
666 | } | ||
667 | |||
668 | /* FIXME: Locking for cleanup/init */ | ||
669 | |||
670 | void ath9k_rx_cleanup(struct ath9k_htc_priv *priv) | ||
671 | { | ||
672 | struct ath9k_htc_rxbuf *rxbuf, *tbuf; | ||
673 | |||
674 | list_for_each_entry_safe(rxbuf, tbuf, &priv->rx.rxbuf, list) { | ||
675 | list_del(&rxbuf->list); | ||
676 | if (rxbuf->skb) | ||
677 | dev_kfree_skb_any(rxbuf->skb); | ||
678 | kfree(rxbuf); | ||
679 | } | ||
680 | } | ||
681 | |||
682 | int ath9k_rx_init(struct ath9k_htc_priv *priv) | ||
683 | { | ||
684 | struct ath_hw *ah = priv->ah; | ||
685 | struct ath_common *common = ath9k_hw_common(ah); | ||
686 | struct ath9k_htc_rxbuf *rxbuf; | ||
687 | int i = 0; | ||
688 | |||
689 | INIT_LIST_HEAD(&priv->rx.rxbuf); | ||
690 | spin_lock_init(&priv->rx.rxbuflock); | ||
691 | |||
692 | for (i = 0; i < ATH9K_HTC_RXBUF; i++) { | ||
693 | rxbuf = kzalloc(sizeof(struct ath9k_htc_rxbuf), GFP_KERNEL); | ||
694 | if (rxbuf == NULL) { | ||
695 | ath_print(common, ATH_DBG_FATAL, | ||
696 | "Unable to allocate RX buffers\n"); | ||
697 | goto err; | ||
698 | } | ||
699 | list_add_tail(&rxbuf->list, &priv->rx.rxbuf); | ||
700 | } | ||
701 | |||
702 | return 0; | ||
703 | |||
704 | err: | ||
705 | ath9k_rx_cleanup(priv); | ||
706 | return -ENOMEM; | ||
707 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.c b/drivers/net/wireless/ath/ath9k/htc_hst.c new file mode 100644 index 000000000000..064397fd738e --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_hst.c | |||
@@ -0,0 +1,480 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | static int htc_issue_send(struct htc_target *target, struct sk_buff* skb, | ||
20 | u16 len, u8 flags, u8 epid, | ||
21 | struct ath9k_htc_tx_ctl *tx_ctl) | ||
22 | { | ||
23 | struct htc_frame_hdr *hdr; | ||
24 | struct htc_endpoint *endpoint = &target->endpoint[epid]; | ||
25 | int status; | ||
26 | |||
27 | hdr = (struct htc_frame_hdr *) | ||
28 | skb_push(skb, sizeof(struct htc_frame_hdr)); | ||
29 | hdr->endpoint_id = epid; | ||
30 | hdr->flags = flags; | ||
31 | hdr->payload_len = cpu_to_be16(len); | ||
32 | |||
33 | status = target->hif->send(target->hif_dev, endpoint->ul_pipeid, skb, | ||
34 | tx_ctl); | ||
35 | return status; | ||
36 | } | ||
37 | |||
38 | static struct htc_endpoint *get_next_avail_ep(struct htc_endpoint *endpoint) | ||
39 | { | ||
40 | enum htc_endpoint_id avail_epid; | ||
41 | |||
42 | for (avail_epid = (ENDPOINT_MAX - 1); avail_epid > ENDPOINT0; avail_epid--) | ||
43 | if (endpoint[avail_epid].service_id == 0) | ||
44 | return &endpoint[avail_epid]; | ||
45 | return NULL; | ||
46 | } | ||
47 | |||
48 | static u8 service_to_ulpipe(u16 service_id) | ||
49 | { | ||
50 | switch (service_id) { | ||
51 | case WMI_CONTROL_SVC: | ||
52 | return 4; | ||
53 | case WMI_BEACON_SVC: | ||
54 | case WMI_CAB_SVC: | ||
55 | case WMI_UAPSD_SVC: | ||
56 | case WMI_MGMT_SVC: | ||
57 | case WMI_DATA_VO_SVC: | ||
58 | case WMI_DATA_VI_SVC: | ||
59 | case WMI_DATA_BE_SVC: | ||
60 | case WMI_DATA_BK_SVC: | ||
61 | return 1; | ||
62 | default: | ||
63 | return 0; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | static u8 service_to_dlpipe(u16 service_id) | ||
68 | { | ||
69 | switch (service_id) { | ||
70 | case WMI_CONTROL_SVC: | ||
71 | return 3; | ||
72 | case WMI_BEACON_SVC: | ||
73 | case WMI_CAB_SVC: | ||
74 | case WMI_UAPSD_SVC: | ||
75 | case WMI_MGMT_SVC: | ||
76 | case WMI_DATA_VO_SVC: | ||
77 | case WMI_DATA_VI_SVC: | ||
78 | case WMI_DATA_BE_SVC: | ||
79 | case WMI_DATA_BK_SVC: | ||
80 | return 2; | ||
81 | default: | ||
82 | return 0; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | static void htc_process_target_rdy(struct htc_target *target, | ||
87 | void *buf) | ||
88 | { | ||
89 | struct htc_endpoint *endpoint; | ||
90 | struct htc_ready_msg *htc_ready_msg = (struct htc_ready_msg *) buf; | ||
91 | |||
92 | target->credits = be16_to_cpu(htc_ready_msg->credits); | ||
93 | target->credit_size = be16_to_cpu(htc_ready_msg->credit_size); | ||
94 | |||
95 | endpoint = &target->endpoint[ENDPOINT0]; | ||
96 | endpoint->service_id = HTC_CTRL_RSVD_SVC; | ||
97 | endpoint->max_msglen = HTC_MAX_CONTROL_MESSAGE_LENGTH; | ||
98 | atomic_inc(&target->tgt_ready); | ||
99 | complete(&target->target_wait); | ||
100 | } | ||
101 | |||
102 | static void htc_process_conn_rsp(struct htc_target *target, | ||
103 | struct htc_frame_hdr *htc_hdr) | ||
104 | { | ||
105 | struct htc_conn_svc_rspmsg *svc_rspmsg; | ||
106 | struct htc_endpoint *endpoint, *tmp_endpoint = NULL; | ||
107 | u16 service_id; | ||
108 | u16 max_msglen; | ||
109 | enum htc_endpoint_id epid, tepid; | ||
110 | |||
111 | svc_rspmsg = (struct htc_conn_svc_rspmsg *) | ||
112 | ((void *) htc_hdr + sizeof(struct htc_frame_hdr)); | ||
113 | |||
114 | if (svc_rspmsg->status == HTC_SERVICE_SUCCESS) { | ||
115 | epid = svc_rspmsg->endpoint_id; | ||
116 | service_id = be16_to_cpu(svc_rspmsg->service_id); | ||
117 | max_msglen = be16_to_cpu(svc_rspmsg->max_msg_len); | ||
118 | endpoint = &target->endpoint[epid]; | ||
119 | |||
120 | for (tepid = (ENDPOINT_MAX - 1); tepid > ENDPOINT0; tepid--) { | ||
121 | tmp_endpoint = &target->endpoint[tepid]; | ||
122 | if (tmp_endpoint->service_id == service_id) { | ||
123 | tmp_endpoint->service_id = 0; | ||
124 | break; | ||
125 | } | ||
126 | } | ||
127 | |||
128 | if (tepid == ENDPOINT0) | ||
129 | return; | ||
130 | |||
131 | endpoint->service_id = service_id; | ||
132 | endpoint->max_txqdepth = tmp_endpoint->max_txqdepth; | ||
133 | endpoint->ep_callbacks = tmp_endpoint->ep_callbacks; | ||
134 | endpoint->ul_pipeid = tmp_endpoint->ul_pipeid; | ||
135 | endpoint->dl_pipeid = tmp_endpoint->dl_pipeid; | ||
136 | endpoint->max_msglen = max_msglen; | ||
137 | target->conn_rsp_epid = epid; | ||
138 | complete(&target->cmd_wait); | ||
139 | } else { | ||
140 | target->conn_rsp_epid = ENDPOINT_UNUSED; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | static int htc_config_pipe_credits(struct htc_target *target) | ||
145 | { | ||
146 | struct sk_buff *skb; | ||
147 | struct htc_config_pipe_msg *cp_msg; | ||
148 | int ret, time_left; | ||
149 | |||
150 | skb = alloc_skb(50 + sizeof(struct htc_frame_hdr), GFP_ATOMIC); | ||
151 | if (!skb) { | ||
152 | dev_err(target->dev, "failed to allocate send buffer\n"); | ||
153 | return -ENOMEM; | ||
154 | } | ||
155 | skb_reserve(skb, sizeof(struct htc_frame_hdr)); | ||
156 | |||
157 | cp_msg = (struct htc_config_pipe_msg *) | ||
158 | skb_put(skb, sizeof(struct htc_config_pipe_msg)); | ||
159 | |||
160 | cp_msg->message_id = cpu_to_be16(HTC_MSG_CONFIG_PIPE_ID); | ||
161 | cp_msg->pipe_id = USB_WLAN_TX_PIPE; | ||
162 | cp_msg->credits = 28; | ||
163 | |||
164 | target->htc_flags |= HTC_OP_CONFIG_PIPE_CREDITS; | ||
165 | |||
166 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | ||
167 | if (ret) | ||
168 | goto err; | ||
169 | |||
170 | time_left = wait_for_completion_timeout(&target->cmd_wait, HZ); | ||
171 | if (!time_left) { | ||
172 | dev_err(target->dev, "HTC credit config timeout\n"); | ||
173 | return -ETIMEDOUT; | ||
174 | } | ||
175 | |||
176 | return 0; | ||
177 | err: | ||
178 | kfree_skb(skb); | ||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | static int htc_setup_complete(struct htc_target *target) | ||
183 | { | ||
184 | struct sk_buff *skb; | ||
185 | struct htc_comp_msg *comp_msg; | ||
186 | int ret = 0, time_left; | ||
187 | |||
188 | skb = alloc_skb(50 + sizeof(struct htc_frame_hdr), GFP_ATOMIC); | ||
189 | if (!skb) { | ||
190 | dev_err(target->dev, "failed to allocate send buffer\n"); | ||
191 | return -ENOMEM; | ||
192 | } | ||
193 | skb_reserve(skb, sizeof(struct htc_frame_hdr)); | ||
194 | |||
195 | comp_msg = (struct htc_comp_msg *) | ||
196 | skb_put(skb, sizeof(struct htc_comp_msg)); | ||
197 | comp_msg->msg_id = cpu_to_be16(HTC_MSG_SETUP_COMPLETE_ID); | ||
198 | |||
199 | target->htc_flags |= HTC_OP_START_WAIT; | ||
200 | |||
201 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | ||
202 | if (ret) | ||
203 | goto err; | ||
204 | |||
205 | time_left = wait_for_completion_timeout(&target->cmd_wait, HZ); | ||
206 | if (!time_left) { | ||
207 | dev_err(target->dev, "HTC start timeout\n"); | ||
208 | return -ETIMEDOUT; | ||
209 | } | ||
210 | |||
211 | return 0; | ||
212 | |||
213 | err: | ||
214 | kfree_skb(skb); | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | /* HTC APIs */ | ||
219 | |||
220 | int htc_init(struct htc_target *target) | ||
221 | { | ||
222 | int ret; | ||
223 | |||
224 | ret = htc_config_pipe_credits(target); | ||
225 | if (ret) | ||
226 | return ret; | ||
227 | |||
228 | return htc_setup_complete(target); | ||
229 | } | ||
230 | |||
231 | int htc_connect_service(struct htc_target *target, | ||
232 | struct htc_service_connreq *service_connreq, | ||
233 | enum htc_endpoint_id *conn_rsp_epid) | ||
234 | { | ||
235 | struct sk_buff *skb; | ||
236 | struct htc_endpoint *endpoint; | ||
237 | struct htc_conn_svc_msg *conn_msg; | ||
238 | int ret, time_left; | ||
239 | |||
240 | /* Find an available endpoint */ | ||
241 | endpoint = get_next_avail_ep(target->endpoint); | ||
242 | if (!endpoint) { | ||
243 | dev_err(target->dev, "Endpoint is not available for" | ||
244 | "service %d\n", service_connreq->service_id); | ||
245 | return -EINVAL; | ||
246 | } | ||
247 | |||
248 | endpoint->service_id = service_connreq->service_id; | ||
249 | endpoint->max_txqdepth = service_connreq->max_send_qdepth; | ||
250 | endpoint->ul_pipeid = service_to_ulpipe(service_connreq->service_id); | ||
251 | endpoint->dl_pipeid = service_to_dlpipe(service_connreq->service_id); | ||
252 | endpoint->ep_callbacks = service_connreq->ep_callbacks; | ||
253 | |||
254 | skb = alloc_skb(sizeof(struct htc_conn_svc_msg) + | ||
255 | sizeof(struct htc_frame_hdr), GFP_ATOMIC); | ||
256 | if (!skb) { | ||
257 | dev_err(target->dev, "Failed to allocate buf to send" | ||
258 | "service connect req\n"); | ||
259 | return -ENOMEM; | ||
260 | } | ||
261 | |||
262 | skb_reserve(skb, sizeof(struct htc_frame_hdr)); | ||
263 | |||
264 | conn_msg = (struct htc_conn_svc_msg *) | ||
265 | skb_put(skb, sizeof(struct htc_conn_svc_msg)); | ||
266 | conn_msg->service_id = cpu_to_be16(service_connreq->service_id); | ||
267 | conn_msg->msg_id = cpu_to_be16(HTC_MSG_CONNECT_SERVICE_ID); | ||
268 | conn_msg->con_flags = cpu_to_be16(service_connreq->con_flags); | ||
269 | conn_msg->dl_pipeid = endpoint->dl_pipeid; | ||
270 | conn_msg->ul_pipeid = endpoint->ul_pipeid; | ||
271 | |||
272 | ret = htc_issue_send(target, skb, skb->len, 0, ENDPOINT0, NULL); | ||
273 | if (ret) | ||
274 | goto err; | ||
275 | |||
276 | time_left = wait_for_completion_timeout(&target->cmd_wait, HZ); | ||
277 | if (!time_left) { | ||
278 | dev_err(target->dev, "Service connection timeout for: %d\n", | ||
279 | service_connreq->service_id); | ||
280 | return -ETIMEDOUT; | ||
281 | } | ||
282 | |||
283 | *conn_rsp_epid = target->conn_rsp_epid; | ||
284 | return 0; | ||
285 | err: | ||
286 | kfree_skb(skb); | ||
287 | return ret; | ||
288 | } | ||
289 | |||
290 | int htc_send(struct htc_target *target, struct sk_buff *skb, | ||
291 | enum htc_endpoint_id epid, struct ath9k_htc_tx_ctl *tx_ctl) | ||
292 | { | ||
293 | return htc_issue_send(target, skb, skb->len, 0, epid, tx_ctl); | ||
294 | } | ||
295 | |||
296 | void htc_stop(struct htc_target *target) | ||
297 | { | ||
298 | enum htc_endpoint_id epid; | ||
299 | struct htc_endpoint *endpoint; | ||
300 | |||
301 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | ||
302 | endpoint = &target->endpoint[epid]; | ||
303 | if (endpoint->service_id != 0) | ||
304 | target->hif->stop(target->hif_dev, endpoint->ul_pipeid); | ||
305 | } | ||
306 | } | ||
307 | |||
308 | void htc_start(struct htc_target *target) | ||
309 | { | ||
310 | enum htc_endpoint_id epid; | ||
311 | struct htc_endpoint *endpoint; | ||
312 | |||
313 | for (epid = ENDPOINT0; epid < ENDPOINT_MAX; epid++) { | ||
314 | endpoint = &target->endpoint[epid]; | ||
315 | if (endpoint->service_id != 0) | ||
316 | target->hif->start(target->hif_dev, | ||
317 | endpoint->ul_pipeid); | ||
318 | } | ||
319 | } | ||
320 | |||
321 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | ||
322 | struct sk_buff *skb, bool txok) | ||
323 | { | ||
324 | struct htc_endpoint *endpoint; | ||
325 | struct htc_frame_hdr *htc_hdr = NULL; | ||
326 | |||
327 | if (htc_handle->htc_flags & HTC_OP_CONFIG_PIPE_CREDITS) { | ||
328 | complete(&htc_handle->cmd_wait); | ||
329 | htc_handle->htc_flags &= ~HTC_OP_CONFIG_PIPE_CREDITS; | ||
330 | goto ret; | ||
331 | } | ||
332 | |||
333 | if (htc_handle->htc_flags & HTC_OP_START_WAIT) { | ||
334 | complete(&htc_handle->cmd_wait); | ||
335 | htc_handle->htc_flags &= ~HTC_OP_START_WAIT; | ||
336 | goto ret; | ||
337 | } | ||
338 | |||
339 | if (skb) { | ||
340 | htc_hdr = (struct htc_frame_hdr *) skb->data; | ||
341 | endpoint = &htc_handle->endpoint[htc_hdr->endpoint_id]; | ||
342 | skb_pull(skb, sizeof(struct htc_frame_hdr)); | ||
343 | |||
344 | if (endpoint->ep_callbacks.tx) { | ||
345 | endpoint->ep_callbacks.tx(endpoint->ep_callbacks.priv, | ||
346 | skb, htc_hdr->endpoint_id, | ||
347 | txok); | ||
348 | } | ||
349 | } | ||
350 | |||
351 | return; | ||
352 | ret: | ||
353 | /* HTC-generated packets are freed here. */ | ||
354 | if (htc_hdr && htc_hdr->endpoint_id != ENDPOINT0) | ||
355 | dev_kfree_skb_any(skb); | ||
356 | else | ||
357 | kfree_skb(skb); | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | * HTC Messages are handled directly here and the obtained SKB | ||
362 | * is freed. | ||
363 | * | ||
364 | * Sevice messages (Data, WMI) passed to the corresponding | ||
365 | * endpoint RX handlers, which have to free the SKB. | ||
366 | */ | ||
367 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, | ||
368 | struct sk_buff *skb, u32 len, u8 pipe_id) | ||
369 | { | ||
370 | struct htc_frame_hdr *htc_hdr; | ||
371 | enum htc_endpoint_id epid; | ||
372 | struct htc_endpoint *endpoint; | ||
373 | __be16 *msg_id; | ||
374 | |||
375 | if (!htc_handle || !skb) | ||
376 | return; | ||
377 | |||
378 | htc_hdr = (struct htc_frame_hdr *) skb->data; | ||
379 | epid = htc_hdr->endpoint_id; | ||
380 | |||
381 | if (epid >= ENDPOINT_MAX) { | ||
382 | if (pipe_id != USB_REG_IN_PIPE) | ||
383 | dev_kfree_skb_any(skb); | ||
384 | else | ||
385 | kfree_skb(skb); | ||
386 | return; | ||
387 | } | ||
388 | |||
389 | if (epid == ENDPOINT0) { | ||
390 | |||
391 | /* Handle trailer */ | ||
392 | if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) { | ||
393 | if (be32_to_cpu(*(__be32 *) skb->data) == 0x00C60000) | ||
394 | /* Move past the Watchdog pattern */ | ||
395 | htc_hdr = (struct htc_frame_hdr *)(skb->data + 4); | ||
396 | } | ||
397 | |||
398 | /* Get the message ID */ | ||
399 | msg_id = (__be16 *) ((void *) htc_hdr + | ||
400 | sizeof(struct htc_frame_hdr)); | ||
401 | |||
402 | /* Now process HTC messages */ | ||
403 | switch (be16_to_cpu(*msg_id)) { | ||
404 | case HTC_MSG_READY_ID: | ||
405 | htc_process_target_rdy(htc_handle, htc_hdr); | ||
406 | break; | ||
407 | case HTC_MSG_CONNECT_SERVICE_RESPONSE_ID: | ||
408 | htc_process_conn_rsp(htc_handle, htc_hdr); | ||
409 | break; | ||
410 | default: | ||
411 | break; | ||
412 | } | ||
413 | |||
414 | kfree_skb(skb); | ||
415 | |||
416 | } else { | ||
417 | if (htc_hdr->flags & HTC_FLAGS_RECV_TRAILER) | ||
418 | skb_trim(skb, len - htc_hdr->control[0]); | ||
419 | |||
420 | skb_pull(skb, sizeof(struct htc_frame_hdr)); | ||
421 | |||
422 | endpoint = &htc_handle->endpoint[epid]; | ||
423 | if (endpoint->ep_callbacks.rx) | ||
424 | endpoint->ep_callbacks.rx(endpoint->ep_callbacks.priv, | ||
425 | skb, epid); | ||
426 | } | ||
427 | } | ||
428 | |||
429 | struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, | ||
430 | struct ath9k_htc_hif *hif, | ||
431 | struct device *dev) | ||
432 | { | ||
433 | struct htc_endpoint *endpoint; | ||
434 | struct htc_target *target; | ||
435 | |||
436 | target = kzalloc(sizeof(struct htc_target), GFP_KERNEL); | ||
437 | if (!target) { | ||
438 | printk(KERN_ERR "Unable to allocate memory for" | ||
439 | "target device\n"); | ||
440 | return NULL; | ||
441 | } | ||
442 | |||
443 | init_completion(&target->target_wait); | ||
444 | init_completion(&target->cmd_wait); | ||
445 | |||
446 | target->hif = hif; | ||
447 | target->hif_dev = hif_handle; | ||
448 | target->dev = dev; | ||
449 | |||
450 | /* Assign control endpoint pipe IDs */ | ||
451 | endpoint = &target->endpoint[ENDPOINT0]; | ||
452 | endpoint->ul_pipeid = hif->control_ul_pipe; | ||
453 | endpoint->dl_pipeid = hif->control_dl_pipe; | ||
454 | |||
455 | atomic_set(&target->tgt_ready, 0); | ||
456 | |||
457 | return target; | ||
458 | } | ||
459 | |||
460 | void ath9k_htc_hw_free(struct htc_target *htc) | ||
461 | { | ||
462 | kfree(htc); | ||
463 | } | ||
464 | |||
465 | int ath9k_htc_hw_init(struct htc_target *target, | ||
466 | struct device *dev, u16 devid) | ||
467 | { | ||
468 | if (ath9k_htc_probe_device(target, dev, devid)) { | ||
469 | printk(KERN_ERR "Failed to initialize the device\n"); | ||
470 | return -ENODEV; | ||
471 | } | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug) | ||
477 | { | ||
478 | if (target) | ||
479 | ath9k_htc_disconnect_device(target, hot_unplug); | ||
480 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/htc_hst.h b/drivers/net/wireless/ath/ath9k/htc_hst.h new file mode 100644 index 000000000000..faba6790328b --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/htc_hst.h | |||
@@ -0,0 +1,245 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef HTC_HST_H | ||
18 | #define HTC_HST_H | ||
19 | |||
20 | struct ath9k_htc_priv; | ||
21 | struct htc_target; | ||
22 | struct ath9k_htc_tx_ctl; | ||
23 | |||
24 | enum ath9k_hif_transports { | ||
25 | ATH9K_HIF_USB, | ||
26 | }; | ||
27 | |||
28 | struct ath9k_htc_hif { | ||
29 | struct list_head list; | ||
30 | const enum ath9k_hif_transports transport; | ||
31 | const char *name; | ||
32 | |||
33 | u8 control_dl_pipe; | ||
34 | u8 control_ul_pipe; | ||
35 | |||
36 | void (*start) (void *hif_handle, u8 pipe); | ||
37 | void (*stop) (void *hif_handle, u8 pipe); | ||
38 | int (*send) (void *hif_handle, u8 pipe, struct sk_buff *buf, | ||
39 | struct ath9k_htc_tx_ctl *tx_ctl); | ||
40 | }; | ||
41 | |||
42 | enum htc_endpoint_id { | ||
43 | ENDPOINT_UNUSED = -1, | ||
44 | ENDPOINT0 = 0, | ||
45 | ENDPOINT1 = 1, | ||
46 | ENDPOINT2 = 2, | ||
47 | ENDPOINT3 = 3, | ||
48 | ENDPOINT4 = 4, | ||
49 | ENDPOINT5 = 5, | ||
50 | ENDPOINT6 = 6, | ||
51 | ENDPOINT7 = 7, | ||
52 | ENDPOINT8 = 8, | ||
53 | ENDPOINT_MAX = 22 | ||
54 | }; | ||
55 | |||
56 | /* Htc frame hdr flags */ | ||
57 | #define HTC_FLAGS_RECV_TRAILER (1 << 1) | ||
58 | |||
59 | struct htc_frame_hdr { | ||
60 | u8 endpoint_id; | ||
61 | u8 flags; | ||
62 | __be16 payload_len; | ||
63 | u8 control[4]; | ||
64 | } __packed; | ||
65 | |||
66 | struct htc_ready_msg { | ||
67 | __be16 message_id; | ||
68 | __be16 credits; | ||
69 | __be16 credit_size; | ||
70 | u8 max_endpoints; | ||
71 | u8 pad; | ||
72 | } __packed; | ||
73 | |||
74 | struct htc_config_pipe_msg { | ||
75 | __be16 message_id; | ||
76 | u8 pipe_id; | ||
77 | u8 credits; | ||
78 | } __packed; | ||
79 | |||
80 | struct htc_packet { | ||
81 | void *pktcontext; | ||
82 | u8 *buf; | ||
83 | u8 *buf_payload; | ||
84 | u32 buflen; | ||
85 | u32 payload_len; | ||
86 | |||
87 | int endpoint; | ||
88 | int status; | ||
89 | |||
90 | void *context; | ||
91 | u32 reserved; | ||
92 | }; | ||
93 | |||
94 | struct htc_ep_callbacks { | ||
95 | void *priv; | ||
96 | void (*tx) (void *, struct sk_buff *, enum htc_endpoint_id, bool txok); | ||
97 | void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id); | ||
98 | }; | ||
99 | |||
100 | #define HTC_TX_QUEUE_SIZE 256 | ||
101 | |||
102 | struct htc_txq { | ||
103 | struct sk_buff *buf[HTC_TX_QUEUE_SIZE]; | ||
104 | u32 txqdepth; | ||
105 | u16 txbuf_cnt; | ||
106 | u16 txq_head; | ||
107 | u16 txq_tail; | ||
108 | }; | ||
109 | |||
110 | struct htc_endpoint { | ||
111 | u16 service_id; | ||
112 | |||
113 | struct htc_ep_callbacks ep_callbacks; | ||
114 | struct htc_txq htc_txq; | ||
115 | u32 max_txqdepth; | ||
116 | int max_msglen; | ||
117 | |||
118 | u8 ul_pipeid; | ||
119 | u8 dl_pipeid; | ||
120 | }; | ||
121 | |||
122 | #define HTC_MAX_CONTROL_MESSAGE_LENGTH 255 | ||
123 | #define HTC_CONTROL_BUFFER_SIZE \ | ||
124 | (HTC_MAX_CONTROL_MESSAGE_LENGTH + sizeof(struct htc_frame_hdr)) | ||
125 | |||
126 | struct htc_control_buf { | ||
127 | struct htc_packet htc_pkt; | ||
128 | u8 buf[HTC_CONTROL_BUFFER_SIZE]; | ||
129 | }; | ||
130 | |||
131 | #define HTC_OP_START_WAIT BIT(0) | ||
132 | #define HTC_OP_CONFIG_PIPE_CREDITS BIT(1) | ||
133 | |||
134 | struct htc_target { | ||
135 | void *hif_dev; | ||
136 | struct ath9k_htc_priv *drv_priv; | ||
137 | struct device *dev; | ||
138 | struct ath9k_htc_hif *hif; | ||
139 | struct htc_endpoint endpoint[ENDPOINT_MAX]; | ||
140 | struct completion target_wait; | ||
141 | struct completion cmd_wait; | ||
142 | struct list_head list; | ||
143 | enum htc_endpoint_id conn_rsp_epid; | ||
144 | u16 credits; | ||
145 | u16 credit_size; | ||
146 | u8 htc_flags; | ||
147 | atomic_t tgt_ready; | ||
148 | }; | ||
149 | |||
150 | enum htc_msg_id { | ||
151 | HTC_MSG_READY_ID = 1, | ||
152 | HTC_MSG_CONNECT_SERVICE_ID, | ||
153 | HTC_MSG_CONNECT_SERVICE_RESPONSE_ID, | ||
154 | HTC_MSG_SETUP_COMPLETE_ID, | ||
155 | HTC_MSG_CONFIG_PIPE_ID, | ||
156 | HTC_MSG_CONFIG_PIPE_RESPONSE_ID, | ||
157 | }; | ||
158 | |||
159 | struct htc_service_connreq { | ||
160 | u16 service_id; | ||
161 | u16 con_flags; | ||
162 | u32 max_send_qdepth; | ||
163 | struct htc_ep_callbacks ep_callbacks; | ||
164 | }; | ||
165 | |||
166 | /* Current service IDs */ | ||
167 | |||
168 | enum htc_service_group_ids{ | ||
169 | RSVD_SERVICE_GROUP = 0, | ||
170 | WMI_SERVICE_GROUP = 1, | ||
171 | |||
172 | HTC_SERVICE_GROUP_LAST = 255 | ||
173 | }; | ||
174 | |||
175 | #define MAKE_SERVICE_ID(group, index) \ | ||
176 | (int)(((int)group << 8) | (int)(index)) | ||
177 | |||
178 | /* NOTE: service ID of 0x0000 is reserved and should never be used */ | ||
179 | #define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1) | ||
180 | #define HTC_LOOPBACK_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 2) | ||
181 | |||
182 | #define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0) | ||
183 | #define WMI_BEACON_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1) | ||
184 | #define WMI_CAB_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2) | ||
185 | #define WMI_UAPSD_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3) | ||
186 | #define WMI_MGMT_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) | ||
187 | #define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 5) | ||
188 | #define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 6) | ||
189 | #define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 7) | ||
190 | #define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 8) | ||
191 | |||
192 | struct htc_conn_svc_msg { | ||
193 | __be16 msg_id; | ||
194 | __be16 service_id; | ||
195 | __be16 con_flags; | ||
196 | u8 dl_pipeid; | ||
197 | u8 ul_pipeid; | ||
198 | u8 svc_meta_len; | ||
199 | u8 pad; | ||
200 | } __packed; | ||
201 | |||
202 | /* connect response status codes */ | ||
203 | #define HTC_SERVICE_SUCCESS 0 | ||
204 | #define HTC_SERVICE_NOT_FOUND 1 | ||
205 | #define HTC_SERVICE_FAILED 2 | ||
206 | #define HTC_SERVICE_NO_RESOURCES 3 | ||
207 | #define HTC_SERVICE_NO_MORE_EP 4 | ||
208 | |||
209 | struct htc_conn_svc_rspmsg { | ||
210 | __be16 msg_id; | ||
211 | __be16 service_id; | ||
212 | u8 status; | ||
213 | u8 endpoint_id; | ||
214 | __be16 max_msg_len; | ||
215 | u8 svc_meta_len; | ||
216 | u8 pad; | ||
217 | } __packed; | ||
218 | |||
219 | struct htc_comp_msg { | ||
220 | __be16 msg_id; | ||
221 | } __packed; | ||
222 | |||
223 | int htc_init(struct htc_target *target); | ||
224 | int htc_connect_service(struct htc_target *target, | ||
225 | struct htc_service_connreq *service_connreq, | ||
226 | enum htc_endpoint_id *conn_rsp_eid); | ||
227 | int htc_send(struct htc_target *target, struct sk_buff *skb, | ||
228 | enum htc_endpoint_id eid, struct ath9k_htc_tx_ctl *tx_ctl); | ||
229 | void htc_stop(struct htc_target *target); | ||
230 | void htc_start(struct htc_target *target); | ||
231 | |||
232 | void ath9k_htc_rx_msg(struct htc_target *htc_handle, | ||
233 | struct sk_buff *skb, u32 len, u8 pipe_id); | ||
234 | void ath9k_htc_txcompletion_cb(struct htc_target *htc_handle, | ||
235 | struct sk_buff *skb, bool txok); | ||
236 | |||
237 | struct htc_target *ath9k_htc_hw_alloc(void *hif_handle, | ||
238 | struct ath9k_htc_hif *hif, | ||
239 | struct device *dev); | ||
240 | void ath9k_htc_hw_free(struct htc_target *htc); | ||
241 | int ath9k_htc_hw_init(struct htc_target *target, | ||
242 | struct device *dev, u16 devid); | ||
243 | void ath9k_htc_hw_deinit(struct htc_target *target, bool hot_unplug); | ||
244 | |||
245 | #endif /* HTC_HST_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h new file mode 100644 index 000000000000..624422a8169e --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef ATH9K_HW_OPS_H | ||
18 | #define ATH9K_HW_OPS_H | ||
19 | |||
20 | #include "hw.h" | ||
21 | |||
22 | /* Hardware core and driver accessible callbacks */ | ||
23 | |||
24 | static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah, | ||
25 | int restore, | ||
26 | int power_off) | ||
27 | { | ||
28 | ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off); | ||
29 | } | ||
30 | |||
31 | static inline void ath9k_hw_rxena(struct ath_hw *ah) | ||
32 | { | ||
33 | ath9k_hw_ops(ah)->rx_enable(ah); | ||
34 | } | ||
35 | |||
36 | static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds, | ||
37 | u32 link) | ||
38 | { | ||
39 | ath9k_hw_ops(ah)->set_desc_link(ds, link); | ||
40 | } | ||
41 | |||
42 | static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds, | ||
43 | u32 **link) | ||
44 | { | ||
45 | ath9k_hw_ops(ah)->get_desc_link(ds, link); | ||
46 | } | ||
47 | static inline bool ath9k_hw_calibrate(struct ath_hw *ah, | ||
48 | struct ath9k_channel *chan, | ||
49 | u8 rxchainmask, | ||
50 | bool longcal) | ||
51 | { | ||
52 | return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal); | ||
53 | } | ||
54 | |||
55 | static inline bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | ||
56 | { | ||
57 | return ath9k_hw_ops(ah)->get_isr(ah, masked); | ||
58 | } | ||
59 | |||
60 | static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen, | ||
61 | bool is_firstseg, bool is_lastseg, | ||
62 | const void *ds0, dma_addr_t buf_addr, | ||
63 | unsigned int qcu) | ||
64 | { | ||
65 | ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg, | ||
66 | ds0, buf_addr, qcu); | ||
67 | } | ||
68 | |||
69 | static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds, | ||
70 | struct ath_tx_status *ts) | ||
71 | { | ||
72 | return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts); | ||
73 | } | ||
74 | |||
75 | static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds, | ||
76 | u32 pktLen, enum ath9k_pkt_type type, | ||
77 | u32 txPower, u32 keyIx, | ||
78 | enum ath9k_key_type keyType, | ||
79 | u32 flags) | ||
80 | { | ||
81 | ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx, | ||
82 | keyType, flags); | ||
83 | } | ||
84 | |||
85 | static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds, | ||
86 | void *lastds, | ||
87 | u32 durUpdateEn, u32 rtsctsRate, | ||
88 | u32 rtsctsDuration, | ||
89 | struct ath9k_11n_rate_series series[], | ||
90 | u32 nseries, u32 flags) | ||
91 | { | ||
92 | ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn, | ||
93 | rtsctsRate, rtsctsDuration, series, | ||
94 | nseries, flags); | ||
95 | } | ||
96 | |||
97 | static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds, | ||
98 | u32 aggrLen) | ||
99 | { | ||
100 | ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen); | ||
101 | } | ||
102 | |||
103 | static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds, | ||
104 | u32 numDelims) | ||
105 | { | ||
106 | ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims); | ||
107 | } | ||
108 | |||
109 | static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds) | ||
110 | { | ||
111 | ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds); | ||
112 | } | ||
113 | |||
114 | static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds) | ||
115 | { | ||
116 | ath9k_hw_ops(ah)->clr11n_aggr(ah, ds); | ||
117 | } | ||
118 | |||
119 | static inline void ath9k_hw_set11n_burstduration(struct ath_hw *ah, void *ds, | ||
120 | u32 burstDuration) | ||
121 | { | ||
122 | ath9k_hw_ops(ah)->set11n_burstduration(ah, ds, burstDuration); | ||
123 | } | ||
124 | |||
125 | static inline void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, void *ds, | ||
126 | u32 vmf) | ||
127 | { | ||
128 | ath9k_hw_ops(ah)->set11n_virtualmorefrag(ah, ds, vmf); | ||
129 | } | ||
130 | |||
131 | /* Private hardware call ops */ | ||
132 | |||
133 | /* PHY ops */ | ||
134 | |||
135 | static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah, | ||
136 | struct ath9k_channel *chan) | ||
137 | { | ||
138 | return ath9k_hw_private_ops(ah)->rf_set_freq(ah, chan); | ||
139 | } | ||
140 | |||
141 | static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah, | ||
142 | struct ath9k_channel *chan) | ||
143 | { | ||
144 | ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan); | ||
145 | } | ||
146 | |||
147 | static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah) | ||
148 | { | ||
149 | if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks) | ||
150 | return 0; | ||
151 | |||
152 | return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah); | ||
153 | } | ||
154 | |||
155 | static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah) | ||
156 | { | ||
157 | if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks) | ||
158 | return; | ||
159 | |||
160 | ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah); | ||
161 | } | ||
162 | |||
163 | static inline bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | ||
164 | struct ath9k_channel *chan, | ||
165 | u16 modesIndex) | ||
166 | { | ||
167 | if (!ath9k_hw_private_ops(ah)->set_rf_regs) | ||
168 | return true; | ||
169 | |||
170 | return ath9k_hw_private_ops(ah)->set_rf_regs(ah, chan, modesIndex); | ||
171 | } | ||
172 | |||
173 | static inline void ath9k_hw_init_bb(struct ath_hw *ah, | ||
174 | struct ath9k_channel *chan) | ||
175 | { | ||
176 | return ath9k_hw_private_ops(ah)->init_bb(ah, chan); | ||
177 | } | ||
178 | |||
179 | static inline void ath9k_hw_set_channel_regs(struct ath_hw *ah, | ||
180 | struct ath9k_channel *chan) | ||
181 | { | ||
182 | return ath9k_hw_private_ops(ah)->set_channel_regs(ah, chan); | ||
183 | } | ||
184 | |||
185 | static inline int ath9k_hw_process_ini(struct ath_hw *ah, | ||
186 | struct ath9k_channel *chan) | ||
187 | { | ||
188 | return ath9k_hw_private_ops(ah)->process_ini(ah, chan); | ||
189 | } | ||
190 | |||
191 | static inline void ath9k_olc_init(struct ath_hw *ah) | ||
192 | { | ||
193 | if (!ath9k_hw_private_ops(ah)->olc_init) | ||
194 | return; | ||
195 | |||
196 | return ath9k_hw_private_ops(ah)->olc_init(ah); | ||
197 | } | ||
198 | |||
199 | static inline void ath9k_hw_set_rfmode(struct ath_hw *ah, | ||
200 | struct ath9k_channel *chan) | ||
201 | { | ||
202 | return ath9k_hw_private_ops(ah)->set_rfmode(ah, chan); | ||
203 | } | ||
204 | |||
205 | static inline void ath9k_hw_mark_phy_inactive(struct ath_hw *ah) | ||
206 | { | ||
207 | return ath9k_hw_private_ops(ah)->mark_phy_inactive(ah); | ||
208 | } | ||
209 | |||
210 | static inline void ath9k_hw_set_delta_slope(struct ath_hw *ah, | ||
211 | struct ath9k_channel *chan) | ||
212 | { | ||
213 | return ath9k_hw_private_ops(ah)->set_delta_slope(ah, chan); | ||
214 | } | ||
215 | |||
216 | static inline bool ath9k_hw_rfbus_req(struct ath_hw *ah) | ||
217 | { | ||
218 | return ath9k_hw_private_ops(ah)->rfbus_req(ah); | ||
219 | } | ||
220 | |||
221 | static inline void ath9k_hw_rfbus_done(struct ath_hw *ah) | ||
222 | { | ||
223 | return ath9k_hw_private_ops(ah)->rfbus_done(ah); | ||
224 | } | ||
225 | |||
226 | static inline void ath9k_enable_rfkill(struct ath_hw *ah) | ||
227 | { | ||
228 | return ath9k_hw_private_ops(ah)->enable_rfkill(ah); | ||
229 | } | ||
230 | |||
231 | static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah) | ||
232 | { | ||
233 | if (!ath9k_hw_private_ops(ah)->restore_chainmask) | ||
234 | return; | ||
235 | |||
236 | return ath9k_hw_private_ops(ah)->restore_chainmask(ah); | ||
237 | } | ||
238 | |||
239 | static inline void ath9k_hw_set_diversity(struct ath_hw *ah, bool value) | ||
240 | { | ||
241 | return ath9k_hw_private_ops(ah)->set_diversity(ah, value); | ||
242 | } | ||
243 | |||
244 | static inline bool ath9k_hw_ani_control(struct ath_hw *ah, | ||
245 | enum ath9k_ani_cmd cmd, int param) | ||
246 | { | ||
247 | return ath9k_hw_private_ops(ah)->ani_control(ah, cmd, param); | ||
248 | } | ||
249 | |||
250 | static inline void ath9k_hw_do_getnf(struct ath_hw *ah, | ||
251 | int16_t nfarray[NUM_NF_READINGS]) | ||
252 | { | ||
253 | ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray); | ||
254 | } | ||
255 | |||
256 | static inline void ath9k_hw_loadnf(struct ath_hw *ah, | ||
257 | struct ath9k_channel *chan) | ||
258 | { | ||
259 | ath9k_hw_private_ops(ah)->loadnf(ah, chan); | ||
260 | } | ||
261 | |||
262 | static inline bool ath9k_hw_init_cal(struct ath_hw *ah, | ||
263 | struct ath9k_channel *chan) | ||
264 | { | ||
265 | return ath9k_hw_private_ops(ah)->init_cal(ah, chan); | ||
266 | } | ||
267 | |||
268 | static inline void ath9k_hw_setup_calibration(struct ath_hw *ah, | ||
269 | struct ath9k_cal_list *currCal) | ||
270 | { | ||
271 | ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal); | ||
272 | } | ||
273 | |||
274 | static inline bool ath9k_hw_iscal_supported(struct ath_hw *ah, | ||
275 | enum ath9k_cal_types calType) | ||
276 | { | ||
277 | return ath9k_hw_private_ops(ah)->iscal_supported(ah, calType); | ||
278 | } | ||
279 | |||
280 | #endif /* ATH9K_HW_OPS_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 78b571129c92..c33f17dbe6f1 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2010 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -19,18 +19,16 @@ | |||
19 | #include <asm/unaligned.h> | 19 | #include <asm/unaligned.h> |
20 | 20 | ||
21 | #include "hw.h" | 21 | #include "hw.h" |
22 | #include "hw-ops.h" | ||
22 | #include "rc.h" | 23 | #include "rc.h" |
23 | #include "initvals.h" | 24 | #include "ar9003_mac.h" |
24 | 25 | ||
25 | #define ATH9K_CLOCK_RATE_CCK 22 | 26 | #define ATH9K_CLOCK_RATE_CCK 22 |
26 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 | 27 | #define ATH9K_CLOCK_RATE_5GHZ_OFDM 40 |
27 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 | 28 | #define ATH9K_CLOCK_RATE_2GHZ_OFDM 44 |
29 | #define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44 | ||
28 | 30 | ||
29 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); | 31 | static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); |
30 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan); | ||
31 | static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, | ||
32 | struct ar5416_eeprom_def *pEepData, | ||
33 | u32 reg, u32 value); | ||
34 | 32 | ||
35 | MODULE_AUTHOR("Atheros Communications"); | 33 | MODULE_AUTHOR("Atheros Communications"); |
36 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); | 34 | MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); |
@@ -49,6 +47,39 @@ static void __exit ath9k_exit(void) | |||
49 | } | 47 | } |
50 | module_exit(ath9k_exit); | 48 | module_exit(ath9k_exit); |
51 | 49 | ||
50 | /* Private hardware callbacks */ | ||
51 | |||
52 | static void ath9k_hw_init_cal_settings(struct ath_hw *ah) | ||
53 | { | ||
54 | ath9k_hw_private_ops(ah)->init_cal_settings(ah); | ||
55 | } | ||
56 | |||
57 | static void ath9k_hw_init_mode_regs(struct ath_hw *ah) | ||
58 | { | ||
59 | ath9k_hw_private_ops(ah)->init_mode_regs(ah); | ||
60 | } | ||
61 | |||
62 | static bool ath9k_hw_macversion_supported(struct ath_hw *ah) | ||
63 | { | ||
64 | struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); | ||
65 | |||
66 | return priv_ops->macversion_supported(ah->hw_version.macVersion); | ||
67 | } | ||
68 | |||
69 | static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah, | ||
70 | struct ath9k_channel *chan) | ||
71 | { | ||
72 | return ath9k_hw_private_ops(ah)->compute_pll_control(ah, chan); | ||
73 | } | ||
74 | |||
75 | static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) | ||
76 | { | ||
77 | if (!ath9k_hw_private_ops(ah)->init_mode_gain_regs) | ||
78 | return; | ||
79 | |||
80 | ath9k_hw_private_ops(ah)->init_mode_gain_regs(ah); | ||
81 | } | ||
82 | |||
52 | /********************/ | 83 | /********************/ |
53 | /* Helper Functions */ | 84 | /* Helper Functions */ |
54 | /********************/ | 85 | /********************/ |
@@ -61,7 +92,11 @@ static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) | |||
61 | return usecs *ATH9K_CLOCK_RATE_CCK; | 92 | return usecs *ATH9K_CLOCK_RATE_CCK; |
62 | if (conf->channel->band == IEEE80211_BAND_2GHZ) | 93 | if (conf->channel->band == IEEE80211_BAND_2GHZ) |
63 | return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; | 94 | return usecs *ATH9K_CLOCK_RATE_2GHZ_OFDM; |
64 | return usecs *ATH9K_CLOCK_RATE_5GHZ_OFDM; | 95 | |
96 | if (ah->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK) | ||
97 | return usecs * ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM; | ||
98 | else | ||
99 | return usecs * ATH9K_CLOCK_RATE_5GHZ_OFDM; | ||
65 | } | 100 | } |
66 | 101 | ||
67 | static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) | 102 | static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs) |
@@ -236,21 +271,6 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) | |||
236 | } | 271 | } |
237 | } | 272 | } |
238 | 273 | ||
239 | static int ath9k_hw_get_radiorev(struct ath_hw *ah) | ||
240 | { | ||
241 | u32 val; | ||
242 | int i; | ||
243 | |||
244 | REG_WRITE(ah, AR_PHY(0x36), 0x00007058); | ||
245 | |||
246 | for (i = 0; i < 8; i++) | ||
247 | REG_WRITE(ah, AR_PHY(0x20), 0x00010000); | ||
248 | val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff; | ||
249 | val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4); | ||
250 | |||
251 | return ath9k_hw_reverse_bits(val, 8); | ||
252 | } | ||
253 | |||
254 | /************************************/ | 274 | /************************************/ |
255 | /* HW Attach, Detach, Init Routines */ | 275 | /* HW Attach, Detach, Init Routines */ |
256 | /************************************/ | 276 | /************************************/ |
@@ -260,6 +280,8 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) | |||
260 | if (AR_SREV_9100(ah)) | 280 | if (AR_SREV_9100(ah)) |
261 | return; | 281 | return; |
262 | 282 | ||
283 | ENABLE_REGWRITE_BUFFER(ah); | ||
284 | |||
263 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); | 285 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); |
264 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | 286 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); |
265 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029); | 287 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029); |
@@ -271,20 +293,30 @@ static void ath9k_hw_disablepcie(struct ath_hw *ah) | |||
271 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007); | 293 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007); |
272 | 294 | ||
273 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | 295 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); |
296 | |||
297 | REGWRITE_BUFFER_FLUSH(ah); | ||
298 | DISABLE_REGWRITE_BUFFER(ah); | ||
274 | } | 299 | } |
275 | 300 | ||
301 | /* This should work for all families including legacy */ | ||
276 | static bool ath9k_hw_chip_test(struct ath_hw *ah) | 302 | static bool ath9k_hw_chip_test(struct ath_hw *ah) |
277 | { | 303 | { |
278 | struct ath_common *common = ath9k_hw_common(ah); | 304 | struct ath_common *common = ath9k_hw_common(ah); |
279 | u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) }; | 305 | u32 regAddr[2] = { AR_STA_ID0 }; |
280 | u32 regHold[2]; | 306 | u32 regHold[2]; |
281 | u32 patternData[4] = { 0x55555555, | 307 | u32 patternData[4] = { 0x55555555, |
282 | 0xaaaaaaaa, | 308 | 0xaaaaaaaa, |
283 | 0x66666666, | 309 | 0x66666666, |
284 | 0x99999999 }; | 310 | 0x99999999 }; |
285 | int i, j; | 311 | int i, j, loop_max; |
312 | |||
313 | if (!AR_SREV_9300_20_OR_LATER(ah)) { | ||
314 | loop_max = 2; | ||
315 | regAddr[1] = AR_PHY_BASE + (8 << 2); | ||
316 | } else | ||
317 | loop_max = 1; | ||
286 | 318 | ||
287 | for (i = 0; i < 2; i++) { | 319 | for (i = 0; i < loop_max; i++) { |
288 | u32 addr = regAddr[i]; | 320 | u32 addr = regAddr[i]; |
289 | u32 wrData, rdData; | 321 | u32 wrData, rdData; |
290 | 322 | ||
@@ -339,7 +371,13 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
339 | ah->config.ofdm_trig_high = 500; | 371 | ah->config.ofdm_trig_high = 500; |
340 | ah->config.cck_trig_high = 200; | 372 | ah->config.cck_trig_high = 200; |
341 | ah->config.cck_trig_low = 100; | 373 | ah->config.cck_trig_low = 100; |
342 | ah->config.enable_ani = 1; | 374 | |
375 | /* | ||
376 | * For now ANI is disabled for AR9003, it is still | ||
377 | * being tested. | ||
378 | */ | ||
379 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
380 | ah->config.enable_ani = 1; | ||
343 | 381 | ||
344 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | 382 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { |
345 | ah->config.spurchans[i][0] = AR_NO_SPUR; | 383 | ah->config.spurchans[i][0] = AR_NO_SPUR; |
@@ -354,6 +392,12 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
354 | ah->config.rx_intr_mitigation = true; | 392 | ah->config.rx_intr_mitigation = true; |
355 | 393 | ||
356 | /* | 394 | /* |
395 | * Tx IQ Calibration (ah->config.tx_iq_calibration) is only | ||
396 | * used by AR9003, but it is showing reliability issues. | ||
397 | * It will take a while to fix so this is currently disabled. | ||
398 | */ | ||
399 | |||
400 | /* | ||
357 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) | 401 | * We need this for PCI devices only (Cardbus, PCI, miniPCI) |
358 | * _and_ if on non-uniprocessor systems (Multiprocessor/HT). | 402 | * _and_ if on non-uniprocessor systems (Multiprocessor/HT). |
359 | * This means we use it for all AR5416 devices, and the few | 403 | * This means we use it for all AR5416 devices, and the few |
@@ -372,7 +416,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) | |||
372 | if (num_possible_cpus() > 1) | 416 | if (num_possible_cpus() > 1) |
373 | ah->config.serialize_regmode = SER_REG_MODE_AUTO; | 417 | ah->config.serialize_regmode = SER_REG_MODE_AUTO; |
374 | } | 418 | } |
375 | EXPORT_SYMBOL(ath9k_hw_init); | ||
376 | 419 | ||
377 | static void ath9k_hw_init_defaults(struct ath_hw *ah) | 420 | static void ath9k_hw_init_defaults(struct ath_hw *ah) |
378 | { | 421 | { |
@@ -386,8 +429,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
386 | ah->hw_version.subvendorid = 0; | 429 | ah->hw_version.subvendorid = 0; |
387 | 430 | ||
388 | ah->ah_flags = 0; | 431 | ah->ah_flags = 0; |
389 | if (ah->hw_version.devid == AR5416_AR9100_DEVID) | ||
390 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; | ||
391 | if (!AR_SREV_9100(ah)) | 432 | if (!AR_SREV_9100(ah)) |
392 | ah->ah_flags = AH_USE_EEPROM; | 433 | ah->ah_flags = AH_USE_EEPROM; |
393 | 434 | ||
@@ -400,44 +441,17 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah) | |||
400 | ah->power_mode = ATH9K_PM_UNDEFINED; | 441 | ah->power_mode = ATH9K_PM_UNDEFINED; |
401 | } | 442 | } |
402 | 443 | ||
403 | static int ath9k_hw_rf_claim(struct ath_hw *ah) | ||
404 | { | ||
405 | u32 val; | ||
406 | |||
407 | REG_WRITE(ah, AR_PHY(0), 0x00000007); | ||
408 | |||
409 | val = ath9k_hw_get_radiorev(ah); | ||
410 | switch (val & AR_RADIO_SREV_MAJOR) { | ||
411 | case 0: | ||
412 | val = AR_RAD5133_SREV_MAJOR; | ||
413 | break; | ||
414 | case AR_RAD5133_SREV_MAJOR: | ||
415 | case AR_RAD5122_SREV_MAJOR: | ||
416 | case AR_RAD2133_SREV_MAJOR: | ||
417 | case AR_RAD2122_SREV_MAJOR: | ||
418 | break; | ||
419 | default: | ||
420 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
421 | "Radio Chip Rev 0x%02X not supported\n", | ||
422 | val & AR_RADIO_SREV_MAJOR); | ||
423 | return -EOPNOTSUPP; | ||
424 | } | ||
425 | |||
426 | ah->hw_version.analog5GhzRev = val; | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) | 444 | static int ath9k_hw_init_macaddr(struct ath_hw *ah) |
432 | { | 445 | { |
433 | struct ath_common *common = ath9k_hw_common(ah); | 446 | struct ath_common *common = ath9k_hw_common(ah); |
434 | u32 sum; | 447 | u32 sum; |
435 | int i; | 448 | int i; |
436 | u16 eeval; | 449 | u16 eeval; |
450 | u32 EEP_MAC[] = { EEP_MAC_LSW, EEP_MAC_MID, EEP_MAC_MSW }; | ||
437 | 451 | ||
438 | sum = 0; | 452 | sum = 0; |
439 | for (i = 0; i < 3; i++) { | 453 | for (i = 0; i < 3; i++) { |
440 | eeval = ah->eep_ops->get_eeprom(ah, AR_EEPROM_MAC(i)); | 454 | eeval = ah->eep_ops->get_eeprom(ah, EEP_MAC[i]); |
441 | sum += eeval; | 455 | sum += eeval; |
442 | common->macaddr[2 * i] = eeval >> 8; | 456 | common->macaddr[2 * i] = eeval >> 8; |
443 | common->macaddr[2 * i + 1] = eeval & 0xff; | 457 | common->macaddr[2 * i + 1] = eeval & 0xff; |
@@ -448,64 +462,20 @@ static int ath9k_hw_init_macaddr(struct ath_hw *ah) | |||
448 | return 0; | 462 | return 0; |
449 | } | 463 | } |
450 | 464 | ||
451 | static void ath9k_hw_init_rxgain_ini(struct ath_hw *ah) | ||
452 | { | ||
453 | u32 rxgain_type; | ||
454 | |||
455 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_17) { | ||
456 | rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE); | ||
457 | |||
458 | if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF) | ||
459 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
460 | ar9280Modes_backoff_13db_rxgain_9280_2, | ||
461 | ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6); | ||
462 | else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF) | ||
463 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
464 | ar9280Modes_backoff_23db_rxgain_9280_2, | ||
465 | ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6); | ||
466 | else | ||
467 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
468 | ar9280Modes_original_rxgain_9280_2, | ||
469 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); | ||
470 | } else { | ||
471 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
472 | ar9280Modes_original_rxgain_9280_2, | ||
473 | ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6); | ||
474 | } | ||
475 | } | ||
476 | |||
477 | static void ath9k_hw_init_txgain_ini(struct ath_hw *ah) | ||
478 | { | ||
479 | u32 txgain_type; | ||
480 | |||
481 | if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_19) { | ||
482 | txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
483 | |||
484 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) | ||
485 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
486 | ar9280Modes_high_power_tx_gain_9280_2, | ||
487 | ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6); | ||
488 | else | ||
489 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
490 | ar9280Modes_original_tx_gain_9280_2, | ||
491 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); | ||
492 | } else { | ||
493 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
494 | ar9280Modes_original_tx_gain_9280_2, | ||
495 | ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6); | ||
496 | } | ||
497 | } | ||
498 | |||
499 | static int ath9k_hw_post_init(struct ath_hw *ah) | 465 | static int ath9k_hw_post_init(struct ath_hw *ah) |
500 | { | 466 | { |
501 | int ecode; | 467 | int ecode; |
502 | 468 | ||
503 | if (!ath9k_hw_chip_test(ah)) | 469 | if (!AR_SREV_9271(ah)) { |
504 | return -ENODEV; | 470 | if (!ath9k_hw_chip_test(ah)) |
471 | return -ENODEV; | ||
472 | } | ||
505 | 473 | ||
506 | ecode = ath9k_hw_rf_claim(ah); | 474 | if (!AR_SREV_9300_20_OR_LATER(ah)) { |
507 | if (ecode != 0) | 475 | ecode = ar9002_hw_rf_claim(ah); |
508 | return ecode; | 476 | if (ecode != 0) |
477 | return ecode; | ||
478 | } | ||
509 | 479 | ||
510 | ecode = ath9k_hw_eeprom_init(ah); | 480 | ecode = ath9k_hw_eeprom_init(ah); |
511 | if (ecode != 0) | 481 | if (ecode != 0) |
@@ -516,14 +486,12 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
516 | ah->eep_ops->get_eeprom_ver(ah), | 486 | ah->eep_ops->get_eeprom_ver(ah), |
517 | ah->eep_ops->get_eeprom_rev(ah)); | 487 | ah->eep_ops->get_eeprom_rev(ah)); |
518 | 488 | ||
519 | if (!AR_SREV_9280_10_OR_LATER(ah)) { | 489 | ecode = ath9k_hw_rf_alloc_ext_banks(ah); |
520 | ecode = ath9k_hw_rf_alloc_ext_banks(ah); | 490 | if (ecode) { |
521 | if (ecode) { | 491 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, |
522 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | 492 | "Failed allocating banks for " |
523 | "Failed allocating banks for " | 493 | "external radio\n"); |
524 | "external radio\n"); | 494 | return ecode; |
525 | return ecode; | ||
526 | } | ||
527 | } | 495 | } |
528 | 496 | ||
529 | if (!AR_SREV_9100(ah)) { | 497 | if (!AR_SREV_9100(ah)) { |
@@ -534,321 +502,22 @@ static int ath9k_hw_post_init(struct ath_hw *ah) | |||
534 | return 0; | 502 | return 0; |
535 | } | 503 | } |
536 | 504 | ||
537 | static bool ath9k_hw_devid_supported(u16 devid) | 505 | static void ath9k_hw_attach_ops(struct ath_hw *ah) |
538 | { | 506 | { |
539 | switch (devid) { | 507 | if (AR_SREV_9300_20_OR_LATER(ah)) |
540 | case AR5416_DEVID_PCI: | 508 | ar9003_hw_attach_ops(ah); |
541 | case AR5416_DEVID_PCIE: | 509 | else |
542 | case AR5416_AR9100_DEVID: | 510 | ar9002_hw_attach_ops(ah); |
543 | case AR9160_DEVID_PCI: | ||
544 | case AR9280_DEVID_PCI: | ||
545 | case AR9280_DEVID_PCIE: | ||
546 | case AR9285_DEVID_PCIE: | ||
547 | case AR5416_DEVID_AR9287_PCI: | ||
548 | case AR5416_DEVID_AR9287_PCIE: | ||
549 | case AR9271_USB: | ||
550 | case AR2427_DEVID_PCIE: | ||
551 | return true; | ||
552 | default: | ||
553 | break; | ||
554 | } | ||
555 | return false; | ||
556 | } | ||
557 | |||
558 | static bool ath9k_hw_macversion_supported(u32 macversion) | ||
559 | { | ||
560 | switch (macversion) { | ||
561 | case AR_SREV_VERSION_5416_PCI: | ||
562 | case AR_SREV_VERSION_5416_PCIE: | ||
563 | case AR_SREV_VERSION_9160: | ||
564 | case AR_SREV_VERSION_9100: | ||
565 | case AR_SREV_VERSION_9280: | ||
566 | case AR_SREV_VERSION_9285: | ||
567 | case AR_SREV_VERSION_9287: | ||
568 | case AR_SREV_VERSION_9271: | ||
569 | return true; | ||
570 | default: | ||
571 | break; | ||
572 | } | ||
573 | return false; | ||
574 | } | ||
575 | |||
576 | static void ath9k_hw_init_cal_settings(struct ath_hw *ah) | ||
577 | { | ||
578 | if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
579 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
580 | ah->iq_caldata.calData = &iq_cal_single_sample; | ||
581 | ah->adcgain_caldata.calData = | ||
582 | &adc_gain_cal_single_sample; | ||
583 | ah->adcdc_caldata.calData = | ||
584 | &adc_dc_cal_single_sample; | ||
585 | ah->adcdc_calinitdata.calData = | ||
586 | &adc_init_dc_cal; | ||
587 | } else { | ||
588 | ah->iq_caldata.calData = &iq_cal_multi_sample; | ||
589 | ah->adcgain_caldata.calData = | ||
590 | &adc_gain_cal_multi_sample; | ||
591 | ah->adcdc_caldata.calData = | ||
592 | &adc_dc_cal_multi_sample; | ||
593 | ah->adcdc_calinitdata.calData = | ||
594 | &adc_init_dc_cal; | ||
595 | } | ||
596 | ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; | ||
597 | } | ||
598 | } | ||
599 | |||
600 | static void ath9k_hw_init_mode_regs(struct ath_hw *ah) | ||
601 | { | ||
602 | if (AR_SREV_9271(ah)) { | ||
603 | INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271, | ||
604 | ARRAY_SIZE(ar9271Modes_9271), 6); | ||
605 | INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271, | ||
606 | ARRAY_SIZE(ar9271Common_9271), 2); | ||
607 | INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only, | ||
608 | ar9271Modes_9271_1_0_only, | ||
609 | ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6); | ||
610 | return; | ||
611 | } | ||
612 | |||
613 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
614 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, | ||
615 | ARRAY_SIZE(ar9287Modes_9287_1_1), 6); | ||
616 | INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1, | ||
617 | ARRAY_SIZE(ar9287Common_9287_1_1), 2); | ||
618 | if (ah->config.pcie_clock_req) | ||
619 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
620 | ar9287PciePhy_clkreq_off_L1_9287_1_1, | ||
621 | ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2); | ||
622 | else | ||
623 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
624 | ar9287PciePhy_clkreq_always_on_L1_9287_1_1, | ||
625 | ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1), | ||
626 | 2); | ||
627 | } else if (AR_SREV_9287_10_OR_LATER(ah)) { | ||
628 | INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_0, | ||
629 | ARRAY_SIZE(ar9287Modes_9287_1_0), 6); | ||
630 | INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_0, | ||
631 | ARRAY_SIZE(ar9287Common_9287_1_0), 2); | ||
632 | |||
633 | if (ah->config.pcie_clock_req) | ||
634 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
635 | ar9287PciePhy_clkreq_off_L1_9287_1_0, | ||
636 | ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_0), 2); | ||
637 | else | ||
638 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
639 | ar9287PciePhy_clkreq_always_on_L1_9287_1_0, | ||
640 | ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_0), | ||
641 | 2); | ||
642 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | ||
643 | |||
644 | |||
645 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2, | ||
646 | ARRAY_SIZE(ar9285Modes_9285_1_2), 6); | ||
647 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2, | ||
648 | ARRAY_SIZE(ar9285Common_9285_1_2), 2); | ||
649 | |||
650 | if (ah->config.pcie_clock_req) { | ||
651 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
652 | ar9285PciePhy_clkreq_off_L1_9285_1_2, | ||
653 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2); | ||
654 | } else { | ||
655 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
656 | ar9285PciePhy_clkreq_always_on_L1_9285_1_2, | ||
657 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2), | ||
658 | 2); | ||
659 | } | ||
660 | } else if (AR_SREV_9285_10_OR_LATER(ah)) { | ||
661 | INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285, | ||
662 | ARRAY_SIZE(ar9285Modes_9285), 6); | ||
663 | INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285, | ||
664 | ARRAY_SIZE(ar9285Common_9285), 2); | ||
665 | |||
666 | if (ah->config.pcie_clock_req) { | ||
667 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
668 | ar9285PciePhy_clkreq_off_L1_9285, | ||
669 | ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285), 2); | ||
670 | } else { | ||
671 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
672 | ar9285PciePhy_clkreq_always_on_L1_9285, | ||
673 | ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285), 2); | ||
674 | } | ||
675 | } else if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
676 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2, | ||
677 | ARRAY_SIZE(ar9280Modes_9280_2), 6); | ||
678 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2, | ||
679 | ARRAY_SIZE(ar9280Common_9280_2), 2); | ||
680 | |||
681 | if (ah->config.pcie_clock_req) { | ||
682 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
683 | ar9280PciePhy_clkreq_off_L1_9280, | ||
684 | ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280),2); | ||
685 | } else { | ||
686 | INIT_INI_ARRAY(&ah->iniPcieSerdes, | ||
687 | ar9280PciePhy_clkreq_always_on_L1_9280, | ||
688 | ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2); | ||
689 | } | ||
690 | INIT_INI_ARRAY(&ah->iniModesAdditional, | ||
691 | ar9280Modes_fast_clock_9280_2, | ||
692 | ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3); | ||
693 | } else if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
694 | INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280, | ||
695 | ARRAY_SIZE(ar9280Modes_9280), 6); | ||
696 | INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280, | ||
697 | ARRAY_SIZE(ar9280Common_9280), 2); | ||
698 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
699 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160, | ||
700 | ARRAY_SIZE(ar5416Modes_9160), 6); | ||
701 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160, | ||
702 | ARRAY_SIZE(ar5416Common_9160), 2); | ||
703 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160, | ||
704 | ARRAY_SIZE(ar5416Bank0_9160), 2); | ||
705 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160, | ||
706 | ARRAY_SIZE(ar5416BB_RfGain_9160), 3); | ||
707 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160, | ||
708 | ARRAY_SIZE(ar5416Bank1_9160), 2); | ||
709 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160, | ||
710 | ARRAY_SIZE(ar5416Bank2_9160), 2); | ||
711 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160, | ||
712 | ARRAY_SIZE(ar5416Bank3_9160), 3); | ||
713 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160, | ||
714 | ARRAY_SIZE(ar5416Bank6_9160), 3); | ||
715 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160, | ||
716 | ARRAY_SIZE(ar5416Bank6TPC_9160), 3); | ||
717 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160, | ||
718 | ARRAY_SIZE(ar5416Bank7_9160), 2); | ||
719 | if (AR_SREV_9160_11(ah)) { | ||
720 | INIT_INI_ARRAY(&ah->iniAddac, | ||
721 | ar5416Addac_91601_1, | ||
722 | ARRAY_SIZE(ar5416Addac_91601_1), 2); | ||
723 | } else { | ||
724 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160, | ||
725 | ARRAY_SIZE(ar5416Addac_9160), 2); | ||
726 | } | ||
727 | } else if (AR_SREV_9100_OR_LATER(ah)) { | ||
728 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100, | ||
729 | ARRAY_SIZE(ar5416Modes_9100), 6); | ||
730 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100, | ||
731 | ARRAY_SIZE(ar5416Common_9100), 2); | ||
732 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100, | ||
733 | ARRAY_SIZE(ar5416Bank0_9100), 2); | ||
734 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100, | ||
735 | ARRAY_SIZE(ar5416BB_RfGain_9100), 3); | ||
736 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100, | ||
737 | ARRAY_SIZE(ar5416Bank1_9100), 2); | ||
738 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100, | ||
739 | ARRAY_SIZE(ar5416Bank2_9100), 2); | ||
740 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100, | ||
741 | ARRAY_SIZE(ar5416Bank3_9100), 3); | ||
742 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100, | ||
743 | ARRAY_SIZE(ar5416Bank6_9100), 3); | ||
744 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100, | ||
745 | ARRAY_SIZE(ar5416Bank6TPC_9100), 3); | ||
746 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100, | ||
747 | ARRAY_SIZE(ar5416Bank7_9100), 2); | ||
748 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100, | ||
749 | ARRAY_SIZE(ar5416Addac_9100), 2); | ||
750 | } else { | ||
751 | INIT_INI_ARRAY(&ah->iniModes, ar5416Modes, | ||
752 | ARRAY_SIZE(ar5416Modes), 6); | ||
753 | INIT_INI_ARRAY(&ah->iniCommon, ar5416Common, | ||
754 | ARRAY_SIZE(ar5416Common), 2); | ||
755 | INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0, | ||
756 | ARRAY_SIZE(ar5416Bank0), 2); | ||
757 | INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain, | ||
758 | ARRAY_SIZE(ar5416BB_RfGain), 3); | ||
759 | INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1, | ||
760 | ARRAY_SIZE(ar5416Bank1), 2); | ||
761 | INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2, | ||
762 | ARRAY_SIZE(ar5416Bank2), 2); | ||
763 | INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3, | ||
764 | ARRAY_SIZE(ar5416Bank3), 3); | ||
765 | INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6, | ||
766 | ARRAY_SIZE(ar5416Bank6), 3); | ||
767 | INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC, | ||
768 | ARRAY_SIZE(ar5416Bank6TPC), 3); | ||
769 | INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7, | ||
770 | ARRAY_SIZE(ar5416Bank7), 2); | ||
771 | INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, | ||
772 | ARRAY_SIZE(ar5416Addac), 2); | ||
773 | } | ||
774 | } | ||
775 | |||
776 | static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah) | ||
777 | { | ||
778 | if (AR_SREV_9287_11_OR_LATER(ah)) | ||
779 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
780 | ar9287Modes_rx_gain_9287_1_1, | ||
781 | ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6); | ||
782 | else if (AR_SREV_9287_10(ah)) | ||
783 | INIT_INI_ARRAY(&ah->iniModesRxGain, | ||
784 | ar9287Modes_rx_gain_9287_1_0, | ||
785 | ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_0), 6); | ||
786 | else if (AR_SREV_9280_20(ah)) | ||
787 | ath9k_hw_init_rxgain_ini(ah); | ||
788 | |||
789 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
790 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
791 | ar9287Modes_tx_gain_9287_1_1, | ||
792 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6); | ||
793 | } else if (AR_SREV_9287_10(ah)) { | ||
794 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
795 | ar9287Modes_tx_gain_9287_1_0, | ||
796 | ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_0), 6); | ||
797 | } else if (AR_SREV_9280_20(ah)) { | ||
798 | ath9k_hw_init_txgain_ini(ah); | ||
799 | } else if (AR_SREV_9285_12_OR_LATER(ah)) { | ||
800 | u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE); | ||
801 | |||
802 | /* txgain table */ | ||
803 | if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) { | ||
804 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
805 | ar9285Modes_high_power_tx_gain_9285_1_2, | ||
806 | ARRAY_SIZE(ar9285Modes_high_power_tx_gain_9285_1_2), 6); | ||
807 | } else { | ||
808 | INIT_INI_ARRAY(&ah->iniModesTxGain, | ||
809 | ar9285Modes_original_tx_gain_9285_1_2, | ||
810 | ARRAY_SIZE(ar9285Modes_original_tx_gain_9285_1_2), 6); | ||
811 | } | ||
812 | |||
813 | } | ||
814 | } | ||
815 | |||
816 | static void ath9k_hw_init_eeprom_fix(struct ath_hw *ah) | ||
817 | { | ||
818 | u32 i, j; | ||
819 | |||
820 | if (ah->hw_version.devid == AR9280_DEVID_PCI) { | ||
821 | |||
822 | /* EEPROM Fixup */ | ||
823 | for (i = 0; i < ah->iniModes.ia_rows; i++) { | ||
824 | u32 reg = INI_RA(&ah->iniModes, i, 0); | ||
825 | |||
826 | for (j = 1; j < ah->iniModes.ia_columns; j++) { | ||
827 | u32 val = INI_RA(&ah->iniModes, i, j); | ||
828 | |||
829 | INI_RA(&ah->iniModes, i, j) = | ||
830 | ath9k_hw_ini_fixup(ah, | ||
831 | &ah->eeprom.def, | ||
832 | reg, val); | ||
833 | } | ||
834 | } | ||
835 | } | ||
836 | } | 511 | } |
837 | 512 | ||
838 | int ath9k_hw_init(struct ath_hw *ah) | 513 | /* Called for all hardware families */ |
514 | static int __ath9k_hw_init(struct ath_hw *ah) | ||
839 | { | 515 | { |
840 | struct ath_common *common = ath9k_hw_common(ah); | 516 | struct ath_common *common = ath9k_hw_common(ah); |
841 | int r = 0; | 517 | int r = 0; |
842 | 518 | ||
843 | if (!ath9k_hw_devid_supported(ah->hw_version.devid)) { | 519 | if (ah->hw_version.devid == AR5416_AR9100_DEVID) |
844 | ath_print(common, ATH_DBG_FATAL, | 520 | ah->hw_version.macVersion = AR_SREV_VERSION_9100; |
845 | "Unsupported device ID: 0x%0x\n", | ||
846 | ah->hw_version.devid); | ||
847 | return -EOPNOTSUPP; | ||
848 | } | ||
849 | |||
850 | ath9k_hw_init_defaults(ah); | ||
851 | ath9k_hw_init_config(ah); | ||
852 | 521 | ||
853 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { | 522 | if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { |
854 | ath_print(common, ATH_DBG_FATAL, | 523 | ath_print(common, ATH_DBG_FATAL, |
@@ -856,6 +525,11 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
856 | return -EIO; | 525 | return -EIO; |
857 | } | 526 | } |
858 | 527 | ||
528 | ath9k_hw_init_defaults(ah); | ||
529 | ath9k_hw_init_config(ah); | ||
530 | |||
531 | ath9k_hw_attach_ops(ah); | ||
532 | |||
859 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { | 533 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) { |
860 | ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); | 534 | ath_print(common, ATH_DBG_FATAL, "Couldn't wakeup chip\n"); |
861 | return -EIO; | 535 | return -EIO; |
@@ -880,7 +554,7 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
880 | else | 554 | else |
881 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; | 555 | ah->config.max_txtrig_level = MAX_TX_FIFO_THRESHOLD; |
882 | 556 | ||
883 | if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) { | 557 | if (!ath9k_hw_macversion_supported(ah)) { |
884 | ath_print(common, ATH_DBG_FATAL, | 558 | ath_print(common, ATH_DBG_FATAL, |
885 | "Mac Chip Rev 0x%02x.%x is not supported by " | 559 | "Mac Chip Rev 0x%02x.%x is not supported by " |
886 | "this driver\n", ah->hw_version.macVersion, | 560 | "this driver\n", ah->hw_version.macVersion, |
@@ -888,45 +562,45 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
888 | return -EOPNOTSUPP; | 562 | return -EOPNOTSUPP; |
889 | } | 563 | } |
890 | 564 | ||
891 | if (AR_SREV_9100(ah)) { | 565 | if (AR_SREV_9271(ah) || AR_SREV_9100(ah)) |
892 | ah->iq_caldata.calData = &iq_cal_multi_sample; | ||
893 | ah->supp_cals = IQ_MISMATCH_CAL; | ||
894 | ah->is_pciexpress = false; | ||
895 | } | ||
896 | |||
897 | if (AR_SREV_9271(ah)) | ||
898 | ah->is_pciexpress = false; | 566 | ah->is_pciexpress = false; |
899 | 567 | ||
900 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); | 568 | ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); |
901 | |||
902 | ath9k_hw_init_cal_settings(ah); | 569 | ath9k_hw_init_cal_settings(ah); |
903 | 570 | ||
904 | ah->ani_function = ATH9K_ANI_ALL; | 571 | ah->ani_function = ATH9K_ANI_ALL; |
905 | if (AR_SREV_9280_10_OR_LATER(ah)) { | 572 | if (AR_SREV_9280_10_OR_LATER(ah) && !AR_SREV_9300_20_OR_LATER(ah)) |
906 | ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; | 573 | ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL; |
907 | ah->ath9k_hw_rf_set_freq = &ath9k_hw_ar9280_set_channel; | ||
908 | ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_9280_spur_mitigate; | ||
909 | } else { | ||
910 | ah->ath9k_hw_rf_set_freq = &ath9k_hw_set_channel; | ||
911 | ah->ath9k_hw_spur_mitigate_freq = &ath9k_hw_spur_mitigate; | ||
912 | } | ||
913 | 574 | ||
914 | ath9k_hw_init_mode_regs(ah); | 575 | ath9k_hw_init_mode_regs(ah); |
915 | 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 | |||
916 | if (ah->is_pciexpress) | 597 | if (ah->is_pciexpress) |
917 | ath9k_hw_configpcipowersave(ah, 0, 0); | 598 | ath9k_hw_configpcipowersave(ah, 0, 0); |
918 | else | 599 | else |
919 | ath9k_hw_disablepcie(ah); | 600 | ath9k_hw_disablepcie(ah); |
920 | 601 | ||
921 | /* Support for Japan ch.14 (2484) spread */ | 602 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
922 | if (AR_SREV_9287_11_OR_LATER(ah)) { | 603 | ar9002_hw_cck_chan14_spread(ah); |
923 | INIT_INI_ARRAY(&ah->iniCckfirNormal, | ||
924 | ar9287Common_normal_cck_fir_coeff_92871_1, | ||
925 | ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_92871_1), 2); | ||
926 | INIT_INI_ARRAY(&ah->iniCckfirJapan2484, | ||
927 | ar9287Common_japan_2484_cck_fir_coeff_92871_1, | ||
928 | ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_92871_1), 2); | ||
929 | } | ||
930 | 604 | ||
931 | r = ath9k_hw_post_init(ah); | 605 | r = ath9k_hw_post_init(ah); |
932 | if (r) | 606 | if (r) |
@@ -937,8 +611,6 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
937 | if (r) | 611 | if (r) |
938 | return r; | 612 | return r; |
939 | 613 | ||
940 | ath9k_hw_init_eeprom_fix(ah); | ||
941 | |||
942 | r = ath9k_hw_init_macaddr(ah); | 614 | r = ath9k_hw_init_macaddr(ah); |
943 | if (r) { | 615 | if (r) { |
944 | ath_print(common, ATH_DBG_FATAL, | 616 | ath_print(common, ATH_DBG_FATAL, |
@@ -951,6 +623,9 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
951 | else | 623 | else |
952 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); | 624 | ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); |
953 | 625 | ||
626 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
627 | ar9003_hw_set_nf_limits(ah); | ||
628 | |||
954 | ath9k_init_nfcal_hist_buffer(ah); | 629 | ath9k_init_nfcal_hist_buffer(ah); |
955 | 630 | ||
956 | common->state = ATH_HW_INITIALIZED; | 631 | common->state = ATH_HW_INITIALIZED; |
@@ -958,24 +633,50 @@ int ath9k_hw_init(struct ath_hw *ah) | |||
958 | return 0; | 633 | return 0; |
959 | } | 634 | } |
960 | 635 | ||
961 | static void ath9k_hw_init_bb(struct ath_hw *ah, | 636 | int ath9k_hw_init(struct ath_hw *ah) |
962 | struct ath9k_channel *chan) | ||
963 | { | 637 | { |
964 | u32 synthDelay; | 638 | int ret; |
639 | struct ath_common *common = ath9k_hw_common(ah); | ||
965 | 640 | ||
966 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | 641 | /* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */ |
967 | if (IS_CHAN_B(chan)) | 642 | switch (ah->hw_version.devid) { |
968 | synthDelay = (4 * synthDelay) / 22; | 643 | case AR5416_DEVID_PCI: |
969 | else | 644 | case AR5416_DEVID_PCIE: |
970 | synthDelay /= 10; | 645 | case AR5416_AR9100_DEVID: |
646 | case AR9160_DEVID_PCI: | ||
647 | case AR9280_DEVID_PCI: | ||
648 | case AR9280_DEVID_PCIE: | ||
649 | case AR9285_DEVID_PCIE: | ||
650 | case AR9287_DEVID_PCI: | ||
651 | case AR9287_DEVID_PCIE: | ||
652 | case AR2427_DEVID_PCIE: | ||
653 | case AR9300_DEVID_PCIE: | ||
654 | break; | ||
655 | default: | ||
656 | if (common->bus_ops->ath_bus_type == ATH_USB) | ||
657 | break; | ||
658 | ath_print(common, ATH_DBG_FATAL, | ||
659 | "Hardware device ID 0x%04x not supported\n", | ||
660 | ah->hw_version.devid); | ||
661 | return -EOPNOTSUPP; | ||
662 | } | ||
971 | 663 | ||
972 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); | 664 | ret = __ath9k_hw_init(ah); |
665 | if (ret) { | ||
666 | ath_print(common, ATH_DBG_FATAL, | ||
667 | "Unable to initialize hardware; " | ||
668 | "initialization status: %d\n", ret); | ||
669 | return ret; | ||
670 | } | ||
973 | 671 | ||
974 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | 672 | return 0; |
975 | } | 673 | } |
674 | EXPORT_SYMBOL(ath9k_hw_init); | ||
976 | 675 | ||
977 | static void ath9k_hw_init_qos(struct ath_hw *ah) | 676 | static void ath9k_hw_init_qos(struct ath_hw *ah) |
978 | { | 677 | { |
678 | ENABLE_REGWRITE_BUFFER(ah); | ||
679 | |||
979 | REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); | 680 | REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa); |
980 | REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); | 681 | REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210); |
981 | 682 | ||
@@ -989,105 +690,22 @@ static void ath9k_hw_init_qos(struct ath_hw *ah) | |||
989 | REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); | 690 | REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF); |
990 | REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); | 691 | REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF); |
991 | REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); | 692 | REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF); |
992 | } | ||
993 | |||
994 | static void ath9k_hw_change_target_baud(struct ath_hw *ah, u32 freq, u32 baud) | ||
995 | { | ||
996 | u32 lcr; | ||
997 | u32 baud_divider = freq * 1000 * 1000 / 16 / baud; | ||
998 | |||
999 | lcr = REG_READ(ah , 0x5100c); | ||
1000 | lcr |= 0x80; | ||
1001 | 693 | ||
1002 | REG_WRITE(ah, 0x5100c, lcr); | 694 | REGWRITE_BUFFER_FLUSH(ah); |
1003 | REG_WRITE(ah, 0x51004, (baud_divider >> 8)); | 695 | DISABLE_REGWRITE_BUFFER(ah); |
1004 | REG_WRITE(ah, 0x51000, (baud_divider & 0xff)); | ||
1005 | |||
1006 | lcr &= ~0x80; | ||
1007 | REG_WRITE(ah, 0x5100c, lcr); | ||
1008 | } | 696 | } |
1009 | 697 | ||
1010 | static void ath9k_hw_init_pll(struct ath_hw *ah, | 698 | static void ath9k_hw_init_pll(struct ath_hw *ah, |
1011 | struct ath9k_channel *chan) | 699 | struct ath9k_channel *chan) |
1012 | { | 700 | { |
1013 | u32 pll; | 701 | u32 pll = ath9k_hw_compute_pll_control(ah, chan); |
1014 | |||
1015 | if (AR_SREV_9100(ah)) { | ||
1016 | if (chan && IS_CHAN_5GHZ(chan)) | ||
1017 | pll = 0x1450; | ||
1018 | else | ||
1019 | pll = 0x1458; | ||
1020 | } else { | ||
1021 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1022 | pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); | ||
1023 | |||
1024 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
1025 | pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); | ||
1026 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
1027 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); | ||
1028 | |||
1029 | if (chan && IS_CHAN_5GHZ(chan)) { | ||
1030 | pll |= SM(0x28, AR_RTC_9160_PLL_DIV); | ||
1031 | |||
1032 | |||
1033 | if (AR_SREV_9280_20(ah)) { | ||
1034 | if (((chan->channel % 20) == 0) | ||
1035 | || ((chan->channel % 10) == 0)) | ||
1036 | pll = 0x2850; | ||
1037 | else | ||
1038 | pll = 0x142c; | ||
1039 | } | ||
1040 | } else { | ||
1041 | pll |= SM(0x2c, AR_RTC_9160_PLL_DIV); | ||
1042 | } | ||
1043 | |||
1044 | } else if (AR_SREV_9160_10_OR_LATER(ah)) { | ||
1045 | |||
1046 | pll = SM(0x5, AR_RTC_9160_PLL_REFDIV); | ||
1047 | |||
1048 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
1049 | pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL); | ||
1050 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
1051 | pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL); | ||
1052 | |||
1053 | if (chan && IS_CHAN_5GHZ(chan)) | ||
1054 | pll |= SM(0x50, AR_RTC_9160_PLL_DIV); | ||
1055 | else | ||
1056 | pll |= SM(0x58, AR_RTC_9160_PLL_DIV); | ||
1057 | } else { | ||
1058 | pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2; | ||
1059 | |||
1060 | if (chan && IS_CHAN_HALF_RATE(chan)) | ||
1061 | pll |= SM(0x1, AR_RTC_PLL_CLKSEL); | ||
1062 | else if (chan && IS_CHAN_QUARTER_RATE(chan)) | ||
1063 | pll |= SM(0x2, AR_RTC_PLL_CLKSEL); | ||
1064 | 702 | ||
1065 | if (chan && IS_CHAN_5GHZ(chan)) | ||
1066 | pll |= SM(0xa, AR_RTC_PLL_DIV); | ||
1067 | else | ||
1068 | pll |= SM(0xb, AR_RTC_PLL_DIV); | ||
1069 | } | ||
1070 | } | ||
1071 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); | 703 | REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); |
1072 | 704 | ||
1073 | /* Switch the core clock for ar9271 to 117Mhz */ | 705 | /* Switch the core clock for ar9271 to 117Mhz */ |
1074 | if (AR_SREV_9271(ah)) { | 706 | if (AR_SREV_9271(ah)) { |
1075 | if ((pll == 0x142c) || (pll == 0x2850) ) { | 707 | udelay(500); |
1076 | udelay(500); | 708 | REG_WRITE(ah, 0x50040, 0x304); |
1077 | /* set CLKOBS to output AHB clock */ | ||
1078 | REG_WRITE(ah, 0x7020, 0xe); | ||
1079 | /* | ||
1080 | * 0x304: 117Mhz, ahb_ratio: 1x1 | ||
1081 | * 0x306: 40Mhz, ahb_ratio: 1x1 | ||
1082 | */ | ||
1083 | REG_WRITE(ah, 0x50040, 0x304); | ||
1084 | /* | ||
1085 | * makes adjustments for the baud dividor to keep the | ||
1086 | * targetted baud rate based on the used core clock. | ||
1087 | */ | ||
1088 | ath9k_hw_change_target_baud(ah, AR9271_CORE_CLOCK, | ||
1089 | AR9271_TARGET_BAUD_RATE); | ||
1090 | } | ||
1091 | } | 709 | } |
1092 | 710 | ||
1093 | udelay(RTC_PLL_SETTLE_DELAY); | 711 | udelay(RTC_PLL_SETTLE_DELAY); |
@@ -1095,70 +713,58 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, | |||
1095 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); | 713 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK); |
1096 | } | 714 | } |
1097 | 715 | ||
1098 | static void ath9k_hw_init_chain_masks(struct ath_hw *ah) | ||
1099 | { | ||
1100 | int rx_chainmask, tx_chainmask; | ||
1101 | |||
1102 | rx_chainmask = ah->rxchainmask; | ||
1103 | tx_chainmask = ah->txchainmask; | ||
1104 | |||
1105 | switch (rx_chainmask) { | ||
1106 | case 0x5: | ||
1107 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
1108 | AR_PHY_SWAP_ALT_CHAIN); | ||
1109 | case 0x3: | ||
1110 | if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) { | ||
1111 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7); | ||
1112 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7); | ||
1113 | break; | ||
1114 | } | ||
1115 | case 0x1: | ||
1116 | case 0x2: | ||
1117 | case 0x7: | ||
1118 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); | ||
1119 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); | ||
1120 | break; | ||
1121 | default: | ||
1122 | break; | ||
1123 | } | ||
1124 | |||
1125 | REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask); | ||
1126 | if (tx_chainmask == 0x5) { | ||
1127 | REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP, | ||
1128 | AR_PHY_SWAP_ALT_CHAIN); | ||
1129 | } | ||
1130 | if (AR_SREV_9100(ah)) | ||
1131 | REG_WRITE(ah, AR_PHY_ANALOG_SWAP, | ||
1132 | REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001); | ||
1133 | } | ||
1134 | |||
1135 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, | 716 | static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, |
1136 | enum nl80211_iftype opmode) | 717 | enum nl80211_iftype opmode) |
1137 | { | 718 | { |
1138 | ah->mask_reg = AR_IMR_TXERR | | 719 | u32 imr_reg = AR_IMR_TXERR | |
1139 | AR_IMR_TXURN | | 720 | AR_IMR_TXURN | |
1140 | AR_IMR_RXERR | | 721 | AR_IMR_RXERR | |
1141 | AR_IMR_RXORN | | 722 | AR_IMR_RXORN | |
1142 | AR_IMR_BCNMISC; | 723 | AR_IMR_BCNMISC; |
1143 | 724 | ||
1144 | if (ah->config.rx_intr_mitigation) | 725 | if (AR_SREV_9300_20_OR_LATER(ah)) { |
1145 | ah->mask_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; | 726 | imr_reg |= AR_IMR_RXOK_HP; |
1146 | else | 727 | if (ah->config.rx_intr_mitigation) |
1147 | ah->mask_reg |= AR_IMR_RXOK; | 728 | imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; |
729 | else | ||
730 | imr_reg |= AR_IMR_RXOK_LP; | ||
1148 | 731 | ||
1149 | ah->mask_reg |= AR_IMR_TXOK; | 732 | } else { |
733 | if (ah->config.rx_intr_mitigation) | ||
734 | imr_reg |= AR_IMR_RXINTM | AR_IMR_RXMINTR; | ||
735 | else | ||
736 | imr_reg |= AR_IMR_RXOK; | ||
737 | } | ||
738 | |||
739 | if (ah->config.tx_intr_mitigation) | ||
740 | imr_reg |= AR_IMR_TXINTM | AR_IMR_TXMINTR; | ||
741 | else | ||
742 | imr_reg |= AR_IMR_TXOK; | ||
1150 | 743 | ||
1151 | if (opmode == NL80211_IFTYPE_AP) | 744 | if (opmode == NL80211_IFTYPE_AP) |
1152 | ah->mask_reg |= AR_IMR_MIB; | 745 | imr_reg |= AR_IMR_MIB; |
746 | |||
747 | ENABLE_REGWRITE_BUFFER(ah); | ||
1153 | 748 | ||
1154 | REG_WRITE(ah, AR_IMR, ah->mask_reg); | 749 | REG_WRITE(ah, AR_IMR, imr_reg); |
1155 | REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT); | 750 | ah->imrs2_reg |= AR_IMR_S2_GTT; |
751 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); | ||
1156 | 752 | ||
1157 | if (!AR_SREV_9100(ah)) { | 753 | if (!AR_SREV_9100(ah)) { |
1158 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); | 754 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF); |
1159 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); | 755 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT); |
1160 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); | 756 | REG_WRITE(ah, AR_INTR_SYNC_MASK, 0); |
1161 | } | 757 | } |
758 | |||
759 | REGWRITE_BUFFER_FLUSH(ah); | ||
760 | DISABLE_REGWRITE_BUFFER(ah); | ||
761 | |||
762 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
763 | REG_WRITE(ah, AR_INTR_PRIO_ASYNC_ENABLE, 0); | ||
764 | REG_WRITE(ah, AR_INTR_PRIO_ASYNC_MASK, 0); | ||
765 | REG_WRITE(ah, AR_INTR_PRIO_SYNC_ENABLE, 0); | ||
766 | REG_WRITE(ah, AR_INTR_PRIO_SYNC_MASK, 0); | ||
767 | } | ||
1162 | } | 768 | } |
1163 | 769 | ||
1164 | static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) | 770 | static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) |
@@ -1241,19 +847,13 @@ void ath9k_hw_deinit(struct ath_hw *ah) | |||
1241 | { | 847 | { |
1242 | struct ath_common *common = ath9k_hw_common(ah); | 848 | struct ath_common *common = ath9k_hw_common(ah); |
1243 | 849 | ||
1244 | if (common->state <= ATH_HW_INITIALIZED) | 850 | if (common->state < ATH_HW_INITIALIZED) |
1245 | goto free_hw; | 851 | goto free_hw; |
1246 | 852 | ||
1247 | if (!AR_SREV_9100(ah)) | ||
1248 | ath9k_hw_ani_disable(ah); | ||
1249 | |||
1250 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); | 853 | ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); |
1251 | 854 | ||
1252 | free_hw: | 855 | free_hw: |
1253 | if (!AR_SREV_9280_10_OR_LATER(ah)) | 856 | ath9k_hw_rf_free_ext_banks(ah); |
1254 | ath9k_hw_rf_free_ext_banks(ah); | ||
1255 | kfree(ah); | ||
1256 | ah = NULL; | ||
1257 | } | 857 | } |
1258 | EXPORT_SYMBOL(ath9k_hw_deinit); | 858 | EXPORT_SYMBOL(ath9k_hw_deinit); |
1259 | 859 | ||
@@ -1261,136 +861,7 @@ EXPORT_SYMBOL(ath9k_hw_deinit); | |||
1261 | /* INI */ | 861 | /* INI */ |
1262 | /*******/ | 862 | /*******/ |
1263 | 863 | ||
1264 | static void ath9k_hw_override_ini(struct ath_hw *ah, | 864 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan) |
1265 | struct ath9k_channel *chan) | ||
1266 | { | ||
1267 | u32 val; | ||
1268 | |||
1269 | if (AR_SREV_9271(ah)) { | ||
1270 | /* | ||
1271 | * Enable spectral scan to solution for issues with stuck | ||
1272 | * beacons on AR9271 1.0. The beacon stuck issue is not seeon on | ||
1273 | * AR9271 1.1 | ||
1274 | */ | ||
1275 | if (AR_SREV_9271_10(ah)) { | ||
1276 | val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) | | ||
1277 | AR_PHY_SPECTRAL_SCAN_ENABLE; | ||
1278 | REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val); | ||
1279 | } | ||
1280 | else if (AR_SREV_9271_11(ah)) | ||
1281 | /* | ||
1282 | * change AR_PHY_RF_CTL3 setting to fix MAC issue | ||
1283 | * present on AR9271 1.1 | ||
1284 | */ | ||
1285 | REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001); | ||
1286 | return; | ||
1287 | } | ||
1288 | |||
1289 | /* | ||
1290 | * Set the RX_ABORT and RX_DIS and clear if off only after | ||
1291 | * RXE is set for MAC. This prevents frames with corrupted | ||
1292 | * descriptor status. | ||
1293 | */ | ||
1294 | REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT)); | ||
1295 | |||
1296 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
1297 | val = REG_READ(ah, AR_PCU_MISC_MODE2) & | ||
1298 | (~AR_PCU_MISC_MODE2_HWWAR1); | ||
1299 | |||
1300 | if (AR_SREV_9287_10_OR_LATER(ah)) | ||
1301 | val = val & (~AR_PCU_MISC_MODE2_HWWAR2); | ||
1302 | |||
1303 | REG_WRITE(ah, AR_PCU_MISC_MODE2, val); | ||
1304 | } | ||
1305 | |||
1306 | if (!AR_SREV_5416_20_OR_LATER(ah) || | ||
1307 | AR_SREV_9280_10_OR_LATER(ah)) | ||
1308 | return; | ||
1309 | /* | ||
1310 | * Disable BB clock gating | ||
1311 | * Necessary to avoid issues on AR5416 2.0 | ||
1312 | */ | ||
1313 | REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); | ||
1314 | |||
1315 | /* | ||
1316 | * Disable RIFS search on some chips to avoid baseband | ||
1317 | * hang issues. | ||
1318 | */ | ||
1319 | if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) { | ||
1320 | val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS); | ||
1321 | val &= ~AR_PHY_RIFS_INIT_DELAY; | ||
1322 | REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val); | ||
1323 | } | ||
1324 | } | ||
1325 | |||
1326 | static u32 ath9k_hw_def_ini_fixup(struct ath_hw *ah, | ||
1327 | struct ar5416_eeprom_def *pEepData, | ||
1328 | u32 reg, u32 value) | ||
1329 | { | ||
1330 | struct base_eep_header *pBase = &(pEepData->baseEepHeader); | ||
1331 | struct ath_common *common = ath9k_hw_common(ah); | ||
1332 | |||
1333 | switch (ah->hw_version.devid) { | ||
1334 | case AR9280_DEVID_PCI: | ||
1335 | if (reg == 0x7894) { | ||
1336 | ath_print(common, ATH_DBG_EEPROM, | ||
1337 | "ini VAL: %x EEPROM: %x\n", value, | ||
1338 | (pBase->version & 0xff)); | ||
1339 | |||
1340 | if ((pBase->version & 0xff) > 0x0a) { | ||
1341 | ath_print(common, ATH_DBG_EEPROM, | ||
1342 | "PWDCLKIND: %d\n", | ||
1343 | pBase->pwdclkind); | ||
1344 | value &= ~AR_AN_TOP2_PWDCLKIND; | ||
1345 | value |= AR_AN_TOP2_PWDCLKIND & | ||
1346 | (pBase->pwdclkind << AR_AN_TOP2_PWDCLKIND_S); | ||
1347 | } else { | ||
1348 | ath_print(common, ATH_DBG_EEPROM, | ||
1349 | "PWDCLKIND Earlier Rev\n"); | ||
1350 | } | ||
1351 | |||
1352 | ath_print(common, ATH_DBG_EEPROM, | ||
1353 | "final ini VAL: %x\n", value); | ||
1354 | } | ||
1355 | break; | ||
1356 | } | ||
1357 | |||
1358 | return value; | ||
1359 | } | ||
1360 | |||
1361 | static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, | ||
1362 | struct ar5416_eeprom_def *pEepData, | ||
1363 | u32 reg, u32 value) | ||
1364 | { | ||
1365 | if (ah->eep_map == EEP_MAP_4KBITS) | ||
1366 | return value; | ||
1367 | else | ||
1368 | return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value); | ||
1369 | } | ||
1370 | |||
1371 | static void ath9k_olc_init(struct ath_hw *ah) | ||
1372 | { | ||
1373 | u32 i; | ||
1374 | |||
1375 | if (OLC_FOR_AR9287_10_LATER) { | ||
1376 | REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9, | ||
1377 | AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL); | ||
1378 | ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0, | ||
1379 | AR9287_AN_TXPC0_TXPCMODE, | ||
1380 | AR9287_AN_TXPC0_TXPCMODE_S, | ||
1381 | AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE); | ||
1382 | udelay(100); | ||
1383 | } else { | ||
1384 | for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) | ||
1385 | ah->originalGain[i] = | ||
1386 | MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4), | ||
1387 | AR_PHY_TX_GAIN); | ||
1388 | ah->PDADCdelta = 0; | ||
1389 | } | ||
1390 | } | ||
1391 | |||
1392 | static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, | ||
1393 | struct ath9k_channel *chan) | ||
1394 | { | 865 | { |
1395 | u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band); | 866 | u32 ctl = ath_regd_get_band_ctl(reg, chan->chan->band); |
1396 | 867 | ||
@@ -1404,173 +875,24 @@ static u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, | |||
1404 | return ctl; | 875 | return ctl; |
1405 | } | 876 | } |
1406 | 877 | ||
1407 | static int ath9k_hw_process_ini(struct ath_hw *ah, | ||
1408 | struct ath9k_channel *chan) | ||
1409 | { | ||
1410 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | ||
1411 | int i, regWrites = 0; | ||
1412 | struct ieee80211_channel *channel = chan->chan; | ||
1413 | u32 modesIndex, freqIndex; | ||
1414 | |||
1415 | switch (chan->chanmode) { | ||
1416 | case CHANNEL_A: | ||
1417 | case CHANNEL_A_HT20: | ||
1418 | modesIndex = 1; | ||
1419 | freqIndex = 1; | ||
1420 | break; | ||
1421 | case CHANNEL_A_HT40PLUS: | ||
1422 | case CHANNEL_A_HT40MINUS: | ||
1423 | modesIndex = 2; | ||
1424 | freqIndex = 1; | ||
1425 | break; | ||
1426 | case CHANNEL_G: | ||
1427 | case CHANNEL_G_HT20: | ||
1428 | case CHANNEL_B: | ||
1429 | modesIndex = 4; | ||
1430 | freqIndex = 2; | ||
1431 | break; | ||
1432 | case CHANNEL_G_HT40PLUS: | ||
1433 | case CHANNEL_G_HT40MINUS: | ||
1434 | modesIndex = 3; | ||
1435 | freqIndex = 2; | ||
1436 | break; | ||
1437 | |||
1438 | default: | ||
1439 | return -EINVAL; | ||
1440 | } | ||
1441 | |||
1442 | REG_WRITE(ah, AR_PHY(0), 0x00000007); | ||
1443 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO); | ||
1444 | ah->eep_ops->set_addac(ah, chan); | ||
1445 | |||
1446 | if (AR_SREV_5416_22_OR_LATER(ah)) { | ||
1447 | REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites); | ||
1448 | } else { | ||
1449 | struct ar5416IniArray temp; | ||
1450 | u32 addacSize = | ||
1451 | sizeof(u32) * ah->iniAddac.ia_rows * | ||
1452 | ah->iniAddac.ia_columns; | ||
1453 | |||
1454 | memcpy(ah->addac5416_21, | ||
1455 | ah->iniAddac.ia_array, addacSize); | ||
1456 | |||
1457 | (ah->addac5416_21)[31 * ah->iniAddac.ia_columns + 1] = 0; | ||
1458 | |||
1459 | temp.ia_array = ah->addac5416_21; | ||
1460 | temp.ia_columns = ah->iniAddac.ia_columns; | ||
1461 | temp.ia_rows = ah->iniAddac.ia_rows; | ||
1462 | REG_WRITE_ARRAY(&temp, 1, regWrites); | ||
1463 | } | ||
1464 | |||
1465 | REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC); | ||
1466 | |||
1467 | for (i = 0; i < ah->iniModes.ia_rows; i++) { | ||
1468 | u32 reg = INI_RA(&ah->iniModes, i, 0); | ||
1469 | u32 val = INI_RA(&ah->iniModes, i, modesIndex); | ||
1470 | |||
1471 | REG_WRITE(ah, reg, val); | ||
1472 | |||
1473 | if (reg >= 0x7800 && reg < 0x78a0 | ||
1474 | && ah->config.analog_shiftreg) { | ||
1475 | udelay(100); | ||
1476 | } | ||
1477 | |||
1478 | DO_DELAY(regWrites); | ||
1479 | } | ||
1480 | |||
1481 | if (AR_SREV_9280(ah) || AR_SREV_9287_10_OR_LATER(ah)) | ||
1482 | REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites); | ||
1483 | |||
1484 | if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) || | ||
1485 | AR_SREV_9287_10_OR_LATER(ah)) | ||
1486 | REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); | ||
1487 | |||
1488 | for (i = 0; i < ah->iniCommon.ia_rows; i++) { | ||
1489 | u32 reg = INI_RA(&ah->iniCommon, i, 0); | ||
1490 | u32 val = INI_RA(&ah->iniCommon, i, 1); | ||
1491 | |||
1492 | REG_WRITE(ah, reg, val); | ||
1493 | |||
1494 | if (reg >= 0x7800 && reg < 0x78a0 | ||
1495 | && ah->config.analog_shiftreg) { | ||
1496 | udelay(100); | ||
1497 | } | ||
1498 | |||
1499 | DO_DELAY(regWrites); | ||
1500 | } | ||
1501 | |||
1502 | ath9k_hw_write_regs(ah, freqIndex, regWrites); | ||
1503 | |||
1504 | if (AR_SREV_9271_10(ah)) | ||
1505 | REG_WRITE_ARRAY(&ah->iniModes_9271_1_0_only, | ||
1506 | modesIndex, regWrites); | ||
1507 | |||
1508 | if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) { | ||
1509 | REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, | ||
1510 | regWrites); | ||
1511 | } | ||
1512 | |||
1513 | ath9k_hw_override_ini(ah, chan); | ||
1514 | ath9k_hw_set_regs(ah, chan); | ||
1515 | ath9k_hw_init_chain_masks(ah); | ||
1516 | |||
1517 | if (OLC_FOR_AR9280_20_LATER) | ||
1518 | ath9k_olc_init(ah); | ||
1519 | |||
1520 | ah->eep_ops->set_txpower(ah, chan, | ||
1521 | ath9k_regd_get_ctl(regulatory, chan), | ||
1522 | channel->max_antenna_gain * 2, | ||
1523 | channel->max_power * 2, | ||
1524 | min((u32) MAX_RATE_POWER, | ||
1525 | (u32) regulatory->power_limit)); | ||
1526 | |||
1527 | if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) { | ||
1528 | ath_print(ath9k_hw_common(ah), ATH_DBG_FATAL, | ||
1529 | "ar5416SetRfRegs failed\n"); | ||
1530 | return -EIO; | ||
1531 | } | ||
1532 | |||
1533 | return 0; | ||
1534 | } | ||
1535 | |||
1536 | /****************************************/ | 878 | /****************************************/ |
1537 | /* Reset and Channel Switching Routines */ | 879 | /* Reset and Channel Switching Routines */ |
1538 | /****************************************/ | 880 | /****************************************/ |
1539 | 881 | ||
1540 | static void ath9k_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1541 | { | ||
1542 | u32 rfMode = 0; | ||
1543 | |||
1544 | if (chan == NULL) | ||
1545 | return; | ||
1546 | |||
1547 | rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan)) | ||
1548 | ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM; | ||
1549 | |||
1550 | if (!AR_SREV_9280_10_OR_LATER(ah)) | ||
1551 | rfMode |= (IS_CHAN_5GHZ(chan)) ? | ||
1552 | AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ; | ||
1553 | |||
1554 | if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) | ||
1555 | rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE); | ||
1556 | |||
1557 | REG_WRITE(ah, AR_PHY_MODE, rfMode); | ||
1558 | } | ||
1559 | |||
1560 | static void ath9k_hw_mark_phy_inactive(struct ath_hw *ah) | ||
1561 | { | ||
1562 | REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); | ||
1563 | } | ||
1564 | |||
1565 | static inline void ath9k_hw_set_dma(struct ath_hw *ah) | 882 | static inline void ath9k_hw_set_dma(struct ath_hw *ah) |
1566 | { | 883 | { |
884 | struct ath_common *common = ath9k_hw_common(ah); | ||
1567 | u32 regval; | 885 | u32 regval; |
1568 | 886 | ||
887 | ENABLE_REGWRITE_BUFFER(ah); | ||
888 | |||
1569 | /* | 889 | /* |
1570 | * set AHB_MODE not to do cacheline prefetches | 890 | * set AHB_MODE not to do cacheline prefetches |
1571 | */ | 891 | */ |
1572 | regval = REG_READ(ah, AR_AHB_MODE); | 892 | if (!AR_SREV_9300_20_OR_LATER(ah)) { |
1573 | REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); | 893 | regval = REG_READ(ah, AR_AHB_MODE); |
894 | REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); | ||
895 | } | ||
1574 | 896 | ||
1575 | /* | 897 | /* |
1576 | * let mac dma reads be in 128 byte chunks | 898 | * let mac dma reads be in 128 byte chunks |
@@ -1578,12 +900,18 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) | |||
1578 | regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; | 900 | regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; |
1579 | REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); | 901 | REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); |
1580 | 902 | ||
903 | REGWRITE_BUFFER_FLUSH(ah); | ||
904 | DISABLE_REGWRITE_BUFFER(ah); | ||
905 | |||
1581 | /* | 906 | /* |
1582 | * Restore TX Trigger Level to its pre-reset value. | 907 | * Restore TX Trigger Level to its pre-reset value. |
1583 | * The initial value depends on whether aggregation is enabled, and is | 908 | * The initial value depends on whether aggregation is enabled, and is |
1584 | * adjusted whenever underruns are detected. | 909 | * adjusted whenever underruns are detected. |
1585 | */ | 910 | */ |
1586 | REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); | 911 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
912 | REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); | ||
913 | |||
914 | ENABLE_REGWRITE_BUFFER(ah); | ||
1587 | 915 | ||
1588 | /* | 916 | /* |
1589 | * let mac dma writes be in 128 byte chunks | 917 | * let mac dma writes be in 128 byte chunks |
@@ -1596,6 +924,14 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) | |||
1596 | */ | 924 | */ |
1597 | REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); | 925 | REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); |
1598 | 926 | ||
927 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
928 | REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_HP, 0x1); | ||
929 | REG_RMW_FIELD(ah, AR_RXBP_THRESH, AR_RXBP_THRESH_LP, 0x1); | ||
930 | |||
931 | ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize - | ||
932 | ah->caps.rx_status_len); | ||
933 | } | ||
934 | |||
1599 | /* | 935 | /* |
1600 | * reduce the number of usable entries in PCU TXBUF to avoid | 936 | * reduce the number of usable entries in PCU TXBUF to avoid |
1601 | * wrap around issues. | 937 | * wrap around issues. |
@@ -1611,6 +947,12 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah) | |||
1611 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, | 947 | REG_WRITE(ah, AR_PCU_TXBUF_CTRL, |
1612 | AR_PCU_TXBUF_CTRL_USABLE_SIZE); | 948 | AR_PCU_TXBUF_CTRL_USABLE_SIZE); |
1613 | } | 949 | } |
950 | |||
951 | REGWRITE_BUFFER_FLUSH(ah); | ||
952 | DISABLE_REGWRITE_BUFFER(ah); | ||
953 | |||
954 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
955 | ath9k_hw_reset_txstatus_ring(ah); | ||
1614 | } | 956 | } |
1615 | 957 | ||
1616 | static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) | 958 | static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) |
@@ -1638,10 +980,8 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode) | |||
1638 | } | 980 | } |
1639 | } | 981 | } |
1640 | 982 | ||
1641 | static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, | 983 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, |
1642 | u32 coef_scaled, | 984 | u32 *coef_mantissa, u32 *coef_exponent) |
1643 | u32 *coef_mantissa, | ||
1644 | u32 *coef_exponent) | ||
1645 | { | 985 | { |
1646 | u32 coef_exp, coef_man; | 986 | u32 coef_exp, coef_man; |
1647 | 987 | ||
@@ -1657,40 +997,6 @@ static inline void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, | |||
1657 | *coef_exponent = coef_exp - 16; | 997 | *coef_exponent = coef_exp - 16; |
1658 | } | 998 | } |
1659 | 999 | ||
1660 | static void ath9k_hw_set_delta_slope(struct ath_hw *ah, | ||
1661 | struct ath9k_channel *chan) | ||
1662 | { | ||
1663 | u32 coef_scaled, ds_coef_exp, ds_coef_man; | ||
1664 | u32 clockMhzScaled = 0x64000000; | ||
1665 | struct chan_centers centers; | ||
1666 | |||
1667 | if (IS_CHAN_HALF_RATE(chan)) | ||
1668 | clockMhzScaled = clockMhzScaled >> 1; | ||
1669 | else if (IS_CHAN_QUARTER_RATE(chan)) | ||
1670 | clockMhzScaled = clockMhzScaled >> 2; | ||
1671 | |||
1672 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
1673 | coef_scaled = clockMhzScaled / centers.synth_center; | ||
1674 | |||
1675 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
1676 | &ds_coef_exp); | ||
1677 | |||
1678 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
1679 | AR_PHY_TIMING3_DSC_MAN, ds_coef_man); | ||
1680 | REG_RMW_FIELD(ah, AR_PHY_TIMING3, | ||
1681 | AR_PHY_TIMING3_DSC_EXP, ds_coef_exp); | ||
1682 | |||
1683 | coef_scaled = (9 * coef_scaled) / 10; | ||
1684 | |||
1685 | ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man, | ||
1686 | &ds_coef_exp); | ||
1687 | |||
1688 | REG_RMW_FIELD(ah, AR_PHY_HALFGI, | ||
1689 | AR_PHY_HALFGI_DSC_MAN, ds_coef_man); | ||
1690 | REG_RMW_FIELD(ah, AR_PHY_HALFGI, | ||
1691 | AR_PHY_HALFGI_DSC_EXP, ds_coef_exp); | ||
1692 | } | ||
1693 | |||
1694 | static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | 1000 | static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) |
1695 | { | 1001 | { |
1696 | u32 rst_flags; | 1002 | u32 rst_flags; |
@@ -1704,6 +1010,8 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1704 | (void)REG_READ(ah, AR_RTC_DERIVED_CLK); | 1010 | (void)REG_READ(ah, AR_RTC_DERIVED_CLK); |
1705 | } | 1011 | } |
1706 | 1012 | ||
1013 | ENABLE_REGWRITE_BUFFER(ah); | ||
1014 | |||
1707 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | | 1015 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | |
1708 | AR_RTC_FORCE_WAKE_ON_INT); | 1016 | AR_RTC_FORCE_WAKE_ON_INT); |
1709 | 1017 | ||
@@ -1715,11 +1023,16 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1715 | if (tmpReg & | 1023 | if (tmpReg & |
1716 | (AR_INTR_SYNC_LOCAL_TIMEOUT | | 1024 | (AR_INTR_SYNC_LOCAL_TIMEOUT | |
1717 | AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { | 1025 | AR_INTR_SYNC_RADM_CPL_TIMEOUT)) { |
1026 | u32 val; | ||
1718 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); | 1027 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); |
1719 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | 1028 | |
1720 | } else { | 1029 | val = AR_RC_HOSTIF; |
1030 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
1031 | val |= AR_RC_AHB; | ||
1032 | REG_WRITE(ah, AR_RC, val); | ||
1033 | |||
1034 | } else if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
1721 | REG_WRITE(ah, AR_RC, AR_RC_AHB); | 1035 | REG_WRITE(ah, AR_RC, AR_RC_AHB); |
1722 | } | ||
1723 | 1036 | ||
1724 | rst_flags = AR_RTC_RC_MAC_WARM; | 1037 | rst_flags = AR_RTC_RC_MAC_WARM; |
1725 | if (type == ATH9K_RESET_COLD) | 1038 | if (type == ATH9K_RESET_COLD) |
@@ -1727,6 +1040,10 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1727 | } | 1040 | } |
1728 | 1041 | ||
1729 | REG_WRITE(ah, AR_RTC_RC, rst_flags); | 1042 | REG_WRITE(ah, AR_RTC_RC, rst_flags); |
1043 | |||
1044 | REGWRITE_BUFFER_FLUSH(ah); | ||
1045 | DISABLE_REGWRITE_BUFFER(ah); | ||
1046 | |||
1730 | udelay(50); | 1047 | udelay(50); |
1731 | 1048 | ||
1732 | REG_WRITE(ah, AR_RTC_RC, 0); | 1049 | REG_WRITE(ah, AR_RTC_RC, 0); |
@@ -1747,16 +1064,23 @@ static bool ath9k_hw_set_reset(struct ath_hw *ah, int type) | |||
1747 | 1064 | ||
1748 | static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) | 1065 | static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) |
1749 | { | 1066 | { |
1067 | ENABLE_REGWRITE_BUFFER(ah); | ||
1068 | |||
1750 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | | 1069 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN | |
1751 | AR_RTC_FORCE_WAKE_ON_INT); | 1070 | AR_RTC_FORCE_WAKE_ON_INT); |
1752 | 1071 | ||
1753 | if (!AR_SREV_9100(ah)) | 1072 | if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) |
1754 | REG_WRITE(ah, AR_RC, AR_RC_AHB); | 1073 | REG_WRITE(ah, AR_RC, AR_RC_AHB); |
1755 | 1074 | ||
1756 | REG_WRITE(ah, AR_RTC_RESET, 0); | 1075 | REG_WRITE(ah, AR_RTC_RESET, 0); |
1757 | udelay(2); | ||
1758 | 1076 | ||
1759 | if (!AR_SREV_9100(ah)) | 1077 | REGWRITE_BUFFER_FLUSH(ah); |
1078 | DISABLE_REGWRITE_BUFFER(ah); | ||
1079 | |||
1080 | if (!AR_SREV_9300_20_OR_LATER(ah)) | ||
1081 | udelay(2); | ||
1082 | |||
1083 | if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) | ||
1760 | REG_WRITE(ah, AR_RC, 0); | 1084 | REG_WRITE(ah, AR_RC, 0); |
1761 | 1085 | ||
1762 | REG_WRITE(ah, AR_RTC_RESET, 1); | 1086 | REG_WRITE(ah, AR_RTC_RESET, 1); |
@@ -1792,34 +1116,6 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type) | |||
1792 | } | 1116 | } |
1793 | } | 1117 | } |
1794 | 1118 | ||
1795 | static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan) | ||
1796 | { | ||
1797 | u32 phymode; | ||
1798 | u32 enableDacFifo = 0; | ||
1799 | |||
1800 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
1801 | enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) & | ||
1802 | AR_PHY_FC_ENABLE_DAC_FIFO); | ||
1803 | |||
1804 | phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40 | ||
1805 | | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo; | ||
1806 | |||
1807 | if (IS_CHAN_HT40(chan)) { | ||
1808 | phymode |= AR_PHY_FC_DYN2040_EN; | ||
1809 | |||
1810 | if ((chan->chanmode == CHANNEL_A_HT40PLUS) || | ||
1811 | (chan->chanmode == CHANNEL_G_HT40PLUS)) | ||
1812 | phymode |= AR_PHY_FC_DYN2040_PRI_CH; | ||
1813 | |||
1814 | } | ||
1815 | REG_WRITE(ah, AR_PHY_TURBO, phymode); | ||
1816 | |||
1817 | ath9k_hw_set11nmac2040(ah); | ||
1818 | |||
1819 | REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); | ||
1820 | REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); | ||
1821 | } | ||
1822 | |||
1823 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, | 1119 | static bool ath9k_hw_chip_reset(struct ath_hw *ah, |
1824 | struct ath9k_channel *chan) | 1120 | struct ath9k_channel *chan) |
1825 | { | 1121 | { |
@@ -1845,7 +1141,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1845 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); | 1141 | struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah); |
1846 | struct ath_common *common = ath9k_hw_common(ah); | 1142 | struct ath_common *common = ath9k_hw_common(ah); |
1847 | struct ieee80211_channel *channel = chan->chan; | 1143 | struct ieee80211_channel *channel = chan->chan; |
1848 | u32 synthDelay, qnum; | 1144 | u32 qnum; |
1849 | int r; | 1145 | int r; |
1850 | 1146 | ||
1851 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { | 1147 | for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { |
@@ -1857,17 +1153,15 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1857 | } | 1153 | } |
1858 | } | 1154 | } |
1859 | 1155 | ||
1860 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN); | 1156 | if (!ath9k_hw_rfbus_req(ah)) { |
1861 | if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN, | ||
1862 | AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT)) { | ||
1863 | ath_print(common, ATH_DBG_FATAL, | 1157 | ath_print(common, ATH_DBG_FATAL, |
1864 | "Could not kill baseband RX\n"); | 1158 | "Could not kill baseband RX\n"); |
1865 | return false; | 1159 | return false; |
1866 | } | 1160 | } |
1867 | 1161 | ||
1868 | ath9k_hw_set_regs(ah, chan); | 1162 | ath9k_hw_set_channel_regs(ah, chan); |
1869 | 1163 | ||
1870 | r = ah->ath9k_hw_rf_set_freq(ah, chan); | 1164 | r = ath9k_hw_rf_set_freq(ah, chan); |
1871 | if (r) { | 1165 | if (r) { |
1872 | ath_print(common, ATH_DBG_FATAL, | 1166 | ath_print(common, ATH_DBG_FATAL, |
1873 | "Failed to set channel\n"); | 1167 | "Failed to set channel\n"); |
@@ -1881,20 +1175,12 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1881 | min((u32) MAX_RATE_POWER, | 1175 | min((u32) MAX_RATE_POWER, |
1882 | (u32) regulatory->power_limit)); | 1176 | (u32) regulatory->power_limit)); |
1883 | 1177 | ||
1884 | synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY; | 1178 | ath9k_hw_rfbus_done(ah); |
1885 | if (IS_CHAN_B(chan)) | ||
1886 | synthDelay = (4 * synthDelay) / 22; | ||
1887 | else | ||
1888 | synthDelay /= 10; | ||
1889 | |||
1890 | udelay(synthDelay + BASE_ACTIVATE_DELAY); | ||
1891 | |||
1892 | REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0); | ||
1893 | 1179 | ||
1894 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | 1180 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) |
1895 | ath9k_hw_set_delta_slope(ah, chan); | 1181 | ath9k_hw_set_delta_slope(ah, chan); |
1896 | 1182 | ||
1897 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); | 1183 | ath9k_hw_spur_mitigate_freq(ah, chan); |
1898 | 1184 | ||
1899 | if (!chan->oneTimeCalsDone) | 1185 | if (!chan->oneTimeCalsDone) |
1900 | chan->oneTimeCalsDone = true; | 1186 | chan->oneTimeCalsDone = true; |
@@ -1902,17 +1188,33 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, | |||
1902 | return true; | 1188 | return true; |
1903 | } | 1189 | } |
1904 | 1190 | ||
1905 | static void ath9k_enable_rfkill(struct ath_hw *ah) | 1191 | bool ath9k_hw_check_alive(struct ath_hw *ah) |
1906 | { | 1192 | { |
1907 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, | 1193 | int count = 50; |
1908 | AR_GPIO_INPUT_EN_VAL_RFSILENT_BB); | 1194 | u32 reg; |
1195 | |||
1196 | if (AR_SREV_9285_10_OR_LATER(ah)) | ||
1197 | return true; | ||
1198 | |||
1199 | do { | ||
1200 | reg = REG_READ(ah, AR_OBS_BUS_1); | ||
1909 | 1201 | ||
1910 | REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2, | 1202 | if ((reg & 0x7E7FFFEF) == 0x00702400) |
1911 | AR_GPIO_INPUT_MUX2_RFSILENT); | 1203 | continue; |
1912 | 1204 | ||
1913 | ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio); | 1205 | switch (reg & 0x7E000B00) { |
1914 | REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB); | 1206 | case 0x1E000000: |
1207 | case 0x52000B00: | ||
1208 | case 0x18000B00: | ||
1209 | continue; | ||
1210 | default: | ||
1211 | return true; | ||
1212 | } | ||
1213 | } while (count-- > 0); | ||
1214 | |||
1215 | return false; | ||
1915 | } | 1216 | } |
1217 | EXPORT_SYMBOL(ath9k_hw_check_alive); | ||
1916 | 1218 | ||
1917 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 1219 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
1918 | bool bChannelChange) | 1220 | bool bChannelChange) |
@@ -1923,11 +1225,18 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1923 | u32 saveDefAntenna; | 1225 | u32 saveDefAntenna; |
1924 | u32 macStaId1; | 1226 | u32 macStaId1; |
1925 | u64 tsf = 0; | 1227 | u64 tsf = 0; |
1926 | int i, rx_chainmask, r; | 1228 | int i, r; |
1927 | 1229 | ||
1928 | ah->txchainmask = common->tx_chainmask; | 1230 | ah->txchainmask = common->tx_chainmask; |
1929 | ah->rxchainmask = common->rx_chainmask; | 1231 | ah->rxchainmask = common->rx_chainmask; |
1930 | 1232 | ||
1233 | if (!ah->chip_fullsleep) { | ||
1234 | ath9k_hw_abortpcurecv(ah); | ||
1235 | if (!ath9k_hw_stopdmarecv(ah)) | ||
1236 | ath_print(common, ATH_DBG_XMIT, | ||
1237 | "Failed to stop receive dma\n"); | ||
1238 | } | ||
1239 | |||
1931 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) | 1240 | if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) |
1932 | return -EIO; | 1241 | return -EIO; |
1933 | 1242 | ||
@@ -1940,8 +1249,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1940 | (chan->channel != ah->curchan->channel) && | 1249 | (chan->channel != ah->curchan->channel) && |
1941 | ((chan->channelFlags & CHANNEL_ALL) == | 1250 | ((chan->channelFlags & CHANNEL_ALL) == |
1942 | (ah->curchan->channelFlags & CHANNEL_ALL)) && | 1251 | (ah->curchan->channelFlags & CHANNEL_ALL)) && |
1943 | !(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) || | 1252 | !AR_SREV_9280(ah)) { |
1944 | IS_CHAN_A_5MHZ_SPACED(ah->curchan))) { | ||
1945 | 1253 | ||
1946 | if (ath9k_hw_channel_change(ah, chan)) { | 1254 | if (ath9k_hw_channel_change(ah, chan)) { |
1947 | ath9k_hw_loadnf(ah, ah->curchan); | 1255 | ath9k_hw_loadnf(ah, ah->curchan); |
@@ -1966,6 +1274,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1966 | 1274 | ||
1967 | ath9k_hw_mark_phy_inactive(ah); | 1275 | ath9k_hw_mark_phy_inactive(ah); |
1968 | 1276 | ||
1277 | /* Only required on the first reset */ | ||
1969 | if (AR_SREV_9271(ah) && ah->htc_reset_init) { | 1278 | if (AR_SREV_9271(ah) && ah->htc_reset_init) { |
1970 | REG_WRITE(ah, | 1279 | REG_WRITE(ah, |
1971 | AR9271_RESET_POWER_DOWN_CONTROL, | 1280 | AR9271_RESET_POWER_DOWN_CONTROL, |
@@ -1978,6 +1287,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1978 | return -EINVAL; | 1287 | return -EINVAL; |
1979 | } | 1288 | } |
1980 | 1289 | ||
1290 | /* Only required on the first reset */ | ||
1981 | if (AR_SREV_9271(ah) && ah->htc_reset_init) { | 1291 | if (AR_SREV_9271(ah) && ah->htc_reset_init) { |
1982 | ah->htc_reset_init = false; | 1292 | ah->htc_reset_init = false; |
1983 | REG_WRITE(ah, | 1293 | REG_WRITE(ah, |
@@ -1993,16 +1303,6 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
1993 | if (AR_SREV_9280_10_OR_LATER(ah)) | 1303 | if (AR_SREV_9280_10_OR_LATER(ah)) |
1994 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); | 1304 | REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); |
1995 | 1305 | ||
1996 | if (AR_SREV_9287_12_OR_LATER(ah)) { | ||
1997 | /* Enable ASYNC FIFO */ | ||
1998 | REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, | ||
1999 | AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL); | ||
2000 | REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO); | ||
2001 | REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, | ||
2002 | AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); | ||
2003 | REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3, | ||
2004 | AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET); | ||
2005 | } | ||
2006 | r = ath9k_hw_process_ini(ah, chan); | 1306 | r = ath9k_hw_process_ini(ah, chan); |
2007 | if (r) | 1307 | if (r) |
2008 | return r; | 1308 | return r; |
@@ -2027,9 +1327,13 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2027 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) | 1327 | if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan)) |
2028 | ath9k_hw_set_delta_slope(ah, chan); | 1328 | ath9k_hw_set_delta_slope(ah, chan); |
2029 | 1329 | ||
2030 | ah->ath9k_hw_spur_mitigate_freq(ah, chan); | 1330 | ath9k_hw_spur_mitigate_freq(ah, chan); |
2031 | ah->eep_ops->set_board_values(ah, chan); | 1331 | ah->eep_ops->set_board_values(ah, chan); |
2032 | 1332 | ||
1333 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
1334 | |||
1335 | ENABLE_REGWRITE_BUFFER(ah); | ||
1336 | |||
2033 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); | 1337 | REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(common->macaddr)); |
2034 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) | 1338 | REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(common->macaddr + 4) |
2035 | | macStaId1 | 1339 | | macStaId1 |
@@ -2037,25 +1341,27 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2037 | | (ah->config. | 1341 | | (ah->config. |
2038 | ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) | 1342 | ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0) |
2039 | | ah->sta_id1_defaults); | 1343 | | ah->sta_id1_defaults); |
2040 | ath9k_hw_set_operating_mode(ah, ah->opmode); | ||
2041 | |||
2042 | ath_hw_setbssidmask(common); | 1344 | ath_hw_setbssidmask(common); |
2043 | |||
2044 | REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); | 1345 | REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna); |
2045 | |||
2046 | ath9k_hw_write_associd(ah); | 1346 | ath9k_hw_write_associd(ah); |
2047 | |||
2048 | REG_WRITE(ah, AR_ISR, ~0); | 1347 | REG_WRITE(ah, AR_ISR, ~0); |
2049 | |||
2050 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); | 1348 | REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); |
2051 | 1349 | ||
2052 | r = ah->ath9k_hw_rf_set_freq(ah, chan); | 1350 | REGWRITE_BUFFER_FLUSH(ah); |
1351 | DISABLE_REGWRITE_BUFFER(ah); | ||
1352 | |||
1353 | r = ath9k_hw_rf_set_freq(ah, chan); | ||
2053 | if (r) | 1354 | if (r) |
2054 | return r; | 1355 | return r; |
2055 | 1356 | ||
1357 | ENABLE_REGWRITE_BUFFER(ah); | ||
1358 | |||
2056 | for (i = 0; i < AR_NUM_DCU; i++) | 1359 | for (i = 0; i < AR_NUM_DCU; i++) |
2057 | REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); | 1360 | REG_WRITE(ah, AR_DQCUMASK(i), 1 << i); |
2058 | 1361 | ||
1362 | REGWRITE_BUFFER_FLUSH(ah); | ||
1363 | DISABLE_REGWRITE_BUFFER(ah); | ||
1364 | |||
2059 | ah->intr_txqs = 0; | 1365 | ah->intr_txqs = 0; |
2060 | for (i = 0; i < ah->caps.total_queues; i++) | 1366 | for (i = 0; i < ah->caps.total_queues; i++) |
2061 | ath9k_hw_resettxqueue(ah, i); | 1367 | ath9k_hw_resettxqueue(ah, i); |
@@ -2068,25 +1374,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2068 | 1374 | ||
2069 | ath9k_hw_init_global_settings(ah); | 1375 | ath9k_hw_init_global_settings(ah); |
2070 | 1376 | ||
2071 | if (AR_SREV_9287_12_OR_LATER(ah)) { | 1377 | if (!AR_SREV_9300_20_OR_LATER(ah)) { |
2072 | REG_WRITE(ah, AR_D_GBL_IFS_SIFS, | 1378 | ar9002_hw_enable_async_fifo(ah); |
2073 | AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR); | 1379 | ar9002_hw_enable_wep_aggregation(ah); |
2074 | REG_WRITE(ah, AR_D_GBL_IFS_SLOT, | ||
2075 | AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR); | ||
2076 | REG_WRITE(ah, AR_D_GBL_IFS_EIFS, | ||
2077 | AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR); | ||
2078 | |||
2079 | REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR); | ||
2080 | REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR); | ||
2081 | |||
2082 | REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER, | ||
2083 | AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768); | ||
2084 | REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN, | ||
2085 | AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL); | ||
2086 | } | ||
2087 | if (AR_SREV_9287_12_OR_LATER(ah)) { | ||
2088 | REG_SET_BIT(ah, AR_PCU_MISC_MODE2, | ||
2089 | AR_PCU_MISC_MODE2_ENABLE_AGGWEP); | ||
2090 | } | 1380 | } |
2091 | 1381 | ||
2092 | REG_WRITE(ah, AR_STA_ID1, | 1382 | REG_WRITE(ah, AR_STA_ID1, |
@@ -2101,19 +1391,24 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2101 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); | 1391 | REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000); |
2102 | } | 1392 | } |
2103 | 1393 | ||
1394 | if (ah->config.tx_intr_mitigation) { | ||
1395 | REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300); | ||
1396 | REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750); | ||
1397 | } | ||
1398 | |||
2104 | ath9k_hw_init_bb(ah, chan); | 1399 | ath9k_hw_init_bb(ah, chan); |
2105 | 1400 | ||
2106 | if (!ath9k_hw_init_cal(ah, chan)) | 1401 | if (!ath9k_hw_init_cal(ah, chan)) |
2107 | return -EIO; | 1402 | return -EIO; |
2108 | 1403 | ||
2109 | rx_chainmask = ah->rxchainmask; | 1404 | ENABLE_REGWRITE_BUFFER(ah); |
2110 | if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) { | ||
2111 | REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask); | ||
2112 | REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask); | ||
2113 | } | ||
2114 | 1405 | ||
1406 | ath9k_hw_restore_chainmask(ah); | ||
2115 | REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); | 1407 | REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); |
2116 | 1408 | ||
1409 | REGWRITE_BUFFER_FLUSH(ah); | ||
1410 | DISABLE_REGWRITE_BUFFER(ah); | ||
1411 | |||
2117 | /* | 1412 | /* |
2118 | * For big endian systems turn on swapping for descriptors | 1413 | * For big endian systems turn on swapping for descriptors |
2119 | */ | 1414 | */ |
@@ -2143,6 +1438,11 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | |||
2143 | if (ah->btcoex_hw.enabled) | 1438 | if (ah->btcoex_hw.enabled) |
2144 | ath9k_hw_btcoex_enable(ah); | 1439 | ath9k_hw_btcoex_enable(ah); |
2145 | 1440 | ||
1441 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
1442 | ath9k_hw_loadnf(ah, curchan); | ||
1443 | ath9k_hw_start_nfcal(ah); | ||
1444 | } | ||
1445 | |||
2146 | return 0; | 1446 | return 0; |
2147 | } | 1447 | } |
2148 | EXPORT_SYMBOL(ath9k_hw_reset); | 1448 | EXPORT_SYMBOL(ath9k_hw_reset); |
@@ -2429,21 +1729,35 @@ EXPORT_SYMBOL(ath9k_hw_keyisvalid); | |||
2429 | /* Power Management (Chipset) */ | 1729 | /* Power Management (Chipset) */ |
2430 | /******************************/ | 1730 | /******************************/ |
2431 | 1731 | ||
1732 | /* | ||
1733 | * Notify Power Mgt is disabled in self-generated frames. | ||
1734 | * If requested, force chip to sleep. | ||
1735 | */ | ||
2432 | static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) | 1736 | static void ath9k_set_power_sleep(struct ath_hw *ah, int setChip) |
2433 | { | 1737 | { |
2434 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 1738 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
2435 | if (setChip) { | 1739 | if (setChip) { |
1740 | /* | ||
1741 | * Clear the RTC force wake bit to allow the | ||
1742 | * mac to go to sleep. | ||
1743 | */ | ||
2436 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, | 1744 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, |
2437 | AR_RTC_FORCE_WAKE_EN); | 1745 | AR_RTC_FORCE_WAKE_EN); |
2438 | if (!AR_SREV_9100(ah)) | 1746 | if (!AR_SREV_9100(ah) && !AR_SREV_9300_20_OR_LATER(ah)) |
2439 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); | 1747 | REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF); |
2440 | 1748 | ||
2441 | if(!AR_SREV_5416(ah)) | 1749 | /* Shutdown chip. Active low */ |
1750 | if (!AR_SREV_5416(ah) && !AR_SREV_9271(ah)) | ||
2442 | REG_CLR_BIT(ah, (AR_RTC_RESET), | 1751 | REG_CLR_BIT(ah, (AR_RTC_RESET), |
2443 | AR_RTC_RESET_EN); | 1752 | AR_RTC_RESET_EN); |
2444 | } | 1753 | } |
2445 | } | 1754 | } |
2446 | 1755 | ||
1756 | /* | ||
1757 | * Notify Power Management is enabled in self-generating | ||
1758 | * frames. If request, set power mode of chip to | ||
1759 | * auto/normal. Duration in units of 128us (1/8 TU). | ||
1760 | */ | ||
2447 | static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | 1761 | static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) |
2448 | { | 1762 | { |
2449 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); | 1763 | REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); |
@@ -2451,9 +1765,14 @@ static void ath9k_set_power_network_sleep(struct ath_hw *ah, int setChip) | |||
2451 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 1765 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
2452 | 1766 | ||
2453 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | 1767 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { |
1768 | /* Set WakeOnInterrupt bit; clear ForceWake bit */ | ||
2454 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, | 1769 | REG_WRITE(ah, AR_RTC_FORCE_WAKE, |
2455 | AR_RTC_FORCE_WAKE_ON_INT); | 1770 | AR_RTC_FORCE_WAKE_ON_INT); |
2456 | } else { | 1771 | } else { |
1772 | /* | ||
1773 | * Clear the RTC force wake bit to allow the | ||
1774 | * mac to go to sleep. | ||
1775 | */ | ||
2457 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, | 1776 | REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE, |
2458 | AR_RTC_FORCE_WAKE_EN); | 1777 | AR_RTC_FORCE_WAKE_EN); |
2459 | } | 1778 | } |
@@ -2472,7 +1791,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip) | |||
2472 | ATH9K_RESET_POWER_ON) != true) { | 1791 | ATH9K_RESET_POWER_ON) != true) { |
2473 | return false; | 1792 | return false; |
2474 | } | 1793 | } |
2475 | ath9k_hw_init_pll(ah, NULL); | 1794 | if (!AR_SREV_9300_20_OR_LATER(ah)) |
1795 | ath9k_hw_init_pll(ah, NULL); | ||
2476 | } | 1796 | } |
2477 | if (AR_SREV_9100(ah)) | 1797 | if (AR_SREV_9100(ah)) |
2478 | REG_SET_BIT(ah, AR_RTC_RESET, | 1798 | REG_SET_BIT(ah, AR_RTC_RESET, |
@@ -2542,424 +1862,6 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) | |||
2542 | } | 1862 | } |
2543 | EXPORT_SYMBOL(ath9k_hw_setpower); | 1863 | EXPORT_SYMBOL(ath9k_hw_setpower); |
2544 | 1864 | ||
2545 | /* | ||
2546 | * Helper for ASPM support. | ||
2547 | * | ||
2548 | * Disable PLL when in L0s as well as receiver clock when in L1. | ||
2549 | * This power saving option must be enabled through the SerDes. | ||
2550 | * | ||
2551 | * Programming the SerDes must go through the same 288 bit serial shift | ||
2552 | * register as the other analog registers. Hence the 9 writes. | ||
2553 | */ | ||
2554 | void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off) | ||
2555 | { | ||
2556 | u8 i; | ||
2557 | u32 val; | ||
2558 | |||
2559 | if (ah->is_pciexpress != true) | ||
2560 | return; | ||
2561 | |||
2562 | /* Do not touch SerDes registers */ | ||
2563 | if (ah->config.pcie_powersave_enable == 2) | ||
2564 | return; | ||
2565 | |||
2566 | /* Nothing to do on restore for 11N */ | ||
2567 | if (!restore) { | ||
2568 | if (AR_SREV_9280_20_OR_LATER(ah)) { | ||
2569 | /* | ||
2570 | * AR9280 2.0 or later chips use SerDes values from the | ||
2571 | * initvals.h initialized depending on chipset during | ||
2572 | * ath9k_hw_init() | ||
2573 | */ | ||
2574 | for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { | ||
2575 | REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), | ||
2576 | INI_RA(&ah->iniPcieSerdes, i, 1)); | ||
2577 | } | ||
2578 | } else if (AR_SREV_9280(ah) && | ||
2579 | (ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) { | ||
2580 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00); | ||
2581 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
2582 | |||
2583 | /* RX shut off when elecidle is asserted */ | ||
2584 | REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019); | ||
2585 | REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820); | ||
2586 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560); | ||
2587 | |||
2588 | /* Shut off CLKREQ active in L1 */ | ||
2589 | if (ah->config.pcie_clock_req) | ||
2590 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc); | ||
2591 | else | ||
2592 | REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd); | ||
2593 | |||
2594 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
2595 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
2596 | REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007); | ||
2597 | |||
2598 | /* Load the new settings */ | ||
2599 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | ||
2600 | |||
2601 | } else { | ||
2602 | REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00); | ||
2603 | REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924); | ||
2604 | |||
2605 | /* RX shut off when elecidle is asserted */ | ||
2606 | REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039); | ||
2607 | REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824); | ||
2608 | REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579); | ||
2609 | |||
2610 | /* | ||
2611 | * Ignore ah->ah_config.pcie_clock_req setting for | ||
2612 | * pre-AR9280 11n | ||
2613 | */ | ||
2614 | REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff); | ||
2615 | |||
2616 | REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40); | ||
2617 | REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554); | ||
2618 | REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007); | ||
2619 | |||
2620 | /* Load the new settings */ | ||
2621 | REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000); | ||
2622 | } | ||
2623 | |||
2624 | udelay(1000); | ||
2625 | |||
2626 | /* set bit 19 to allow forcing of pcie core into L1 state */ | ||
2627 | REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA); | ||
2628 | |||
2629 | /* Several PCIe massages to ensure proper behaviour */ | ||
2630 | if (ah->config.pcie_waen) { | ||
2631 | val = ah->config.pcie_waen; | ||
2632 | if (!power_off) | ||
2633 | val &= (~AR_WA_D3_L1_DISABLE); | ||
2634 | } else { | ||
2635 | if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || | ||
2636 | AR_SREV_9287(ah)) { | ||
2637 | val = AR9285_WA_DEFAULT; | ||
2638 | if (!power_off) | ||
2639 | val &= (~AR_WA_D3_L1_DISABLE); | ||
2640 | } else if (AR_SREV_9280(ah)) { | ||
2641 | /* | ||
2642 | * On AR9280 chips bit 22 of 0x4004 needs to be | ||
2643 | * set otherwise card may disappear. | ||
2644 | */ | ||
2645 | val = AR9280_WA_DEFAULT; | ||
2646 | if (!power_off) | ||
2647 | val &= (~AR_WA_D3_L1_DISABLE); | ||
2648 | } else | ||
2649 | val = AR_WA_DEFAULT; | ||
2650 | } | ||
2651 | |||
2652 | REG_WRITE(ah, AR_WA, val); | ||
2653 | } | ||
2654 | |||
2655 | if (power_off) { | ||
2656 | /* | ||
2657 | * Set PCIe workaround bits | ||
2658 | * bit 14 in WA register (disable L1) should only | ||
2659 | * be set when device enters D3 and be cleared | ||
2660 | * when device comes back to D0. | ||
2661 | */ | ||
2662 | if (ah->config.pcie_waen) { | ||
2663 | if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE) | ||
2664 | REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); | ||
2665 | } else { | ||
2666 | if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) || | ||
2667 | AR_SREV_9287(ah)) && | ||
2668 | (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) || | ||
2669 | (AR_SREV_9280(ah) && | ||
2670 | (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) { | ||
2671 | REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE); | ||
2672 | } | ||
2673 | } | ||
2674 | } | ||
2675 | } | ||
2676 | EXPORT_SYMBOL(ath9k_hw_configpcipowersave); | ||
2677 | |||
2678 | /**********************/ | ||
2679 | /* Interrupt Handling */ | ||
2680 | /**********************/ | ||
2681 | |||
2682 | bool ath9k_hw_intrpend(struct ath_hw *ah) | ||
2683 | { | ||
2684 | u32 host_isr; | ||
2685 | |||
2686 | if (AR_SREV_9100(ah)) | ||
2687 | return true; | ||
2688 | |||
2689 | host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE); | ||
2690 | if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS)) | ||
2691 | return true; | ||
2692 | |||
2693 | host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE); | ||
2694 | if ((host_isr & AR_INTR_SYNC_DEFAULT) | ||
2695 | && (host_isr != AR_INTR_SPURIOUS)) | ||
2696 | return true; | ||
2697 | |||
2698 | return false; | ||
2699 | } | ||
2700 | EXPORT_SYMBOL(ath9k_hw_intrpend); | ||
2701 | |||
2702 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked) | ||
2703 | { | ||
2704 | u32 isr = 0; | ||
2705 | u32 mask2 = 0; | ||
2706 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
2707 | u32 sync_cause = 0; | ||
2708 | bool fatal_int = false; | ||
2709 | struct ath_common *common = ath9k_hw_common(ah); | ||
2710 | |||
2711 | if (!AR_SREV_9100(ah)) { | ||
2712 | if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) { | ||
2713 | if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) | ||
2714 | == AR_RTC_STATUS_ON) { | ||
2715 | isr = REG_READ(ah, AR_ISR); | ||
2716 | } | ||
2717 | } | ||
2718 | |||
2719 | sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & | ||
2720 | AR_INTR_SYNC_DEFAULT; | ||
2721 | |||
2722 | *masked = 0; | ||
2723 | |||
2724 | if (!isr && !sync_cause) | ||
2725 | return false; | ||
2726 | } else { | ||
2727 | *masked = 0; | ||
2728 | isr = REG_READ(ah, AR_ISR); | ||
2729 | } | ||
2730 | |||
2731 | if (isr) { | ||
2732 | if (isr & AR_ISR_BCNMISC) { | ||
2733 | u32 isr2; | ||
2734 | isr2 = REG_READ(ah, AR_ISR_S2); | ||
2735 | if (isr2 & AR_ISR_S2_TIM) | ||
2736 | mask2 |= ATH9K_INT_TIM; | ||
2737 | if (isr2 & AR_ISR_S2_DTIM) | ||
2738 | mask2 |= ATH9K_INT_DTIM; | ||
2739 | if (isr2 & AR_ISR_S2_DTIMSYNC) | ||
2740 | mask2 |= ATH9K_INT_DTIMSYNC; | ||
2741 | if (isr2 & (AR_ISR_S2_CABEND)) | ||
2742 | mask2 |= ATH9K_INT_CABEND; | ||
2743 | if (isr2 & AR_ISR_S2_GTT) | ||
2744 | mask2 |= ATH9K_INT_GTT; | ||
2745 | if (isr2 & AR_ISR_S2_CST) | ||
2746 | mask2 |= ATH9K_INT_CST; | ||
2747 | if (isr2 & AR_ISR_S2_TSFOOR) | ||
2748 | mask2 |= ATH9K_INT_TSFOOR; | ||
2749 | } | ||
2750 | |||
2751 | isr = REG_READ(ah, AR_ISR_RAC); | ||
2752 | if (isr == 0xffffffff) { | ||
2753 | *masked = 0; | ||
2754 | return false; | ||
2755 | } | ||
2756 | |||
2757 | *masked = isr & ATH9K_INT_COMMON; | ||
2758 | |||
2759 | if (ah->config.rx_intr_mitigation) { | ||
2760 | if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) | ||
2761 | *masked |= ATH9K_INT_RX; | ||
2762 | } | ||
2763 | |||
2764 | if (isr & (AR_ISR_RXOK | AR_ISR_RXERR)) | ||
2765 | *masked |= ATH9K_INT_RX; | ||
2766 | if (isr & | ||
2767 | (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | | ||
2768 | AR_ISR_TXEOL)) { | ||
2769 | u32 s0_s, s1_s; | ||
2770 | |||
2771 | *masked |= ATH9K_INT_TX; | ||
2772 | |||
2773 | s0_s = REG_READ(ah, AR_ISR_S0_S); | ||
2774 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK); | ||
2775 | ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC); | ||
2776 | |||
2777 | s1_s = REG_READ(ah, AR_ISR_S1_S); | ||
2778 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR); | ||
2779 | ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL); | ||
2780 | } | ||
2781 | |||
2782 | if (isr & AR_ISR_RXORN) { | ||
2783 | ath_print(common, ATH_DBG_INTERRUPT, | ||
2784 | "receive FIFO overrun interrupt\n"); | ||
2785 | } | ||
2786 | |||
2787 | if (!AR_SREV_9100(ah)) { | ||
2788 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
2789 | u32 isr5 = REG_READ(ah, AR_ISR_S5_S); | ||
2790 | if (isr5 & AR_ISR_S5_TIM_TIMER) | ||
2791 | *masked |= ATH9K_INT_TIM_TIMER; | ||
2792 | } | ||
2793 | } | ||
2794 | |||
2795 | *masked |= mask2; | ||
2796 | } | ||
2797 | |||
2798 | if (AR_SREV_9100(ah)) | ||
2799 | return true; | ||
2800 | |||
2801 | if (isr & AR_ISR_GENTMR) { | ||
2802 | u32 s5_s; | ||
2803 | |||
2804 | s5_s = REG_READ(ah, AR_ISR_S5_S); | ||
2805 | if (isr & AR_ISR_GENTMR) { | ||
2806 | ah->intr_gen_timer_trigger = | ||
2807 | MS(s5_s, AR_ISR_S5_GENTIMER_TRIG); | ||
2808 | |||
2809 | ah->intr_gen_timer_thresh = | ||
2810 | MS(s5_s, AR_ISR_S5_GENTIMER_THRESH); | ||
2811 | |||
2812 | if (ah->intr_gen_timer_trigger) | ||
2813 | *masked |= ATH9K_INT_GENTIMER; | ||
2814 | |||
2815 | } | ||
2816 | } | ||
2817 | |||
2818 | if (sync_cause) { | ||
2819 | fatal_int = | ||
2820 | (sync_cause & | ||
2821 | (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) | ||
2822 | ? true : false; | ||
2823 | |||
2824 | if (fatal_int) { | ||
2825 | if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { | ||
2826 | ath_print(common, ATH_DBG_ANY, | ||
2827 | "received PCI FATAL interrupt\n"); | ||
2828 | } | ||
2829 | if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { | ||
2830 | ath_print(common, ATH_DBG_ANY, | ||
2831 | "received PCI PERR interrupt\n"); | ||
2832 | } | ||
2833 | *masked |= ATH9K_INT_FATAL; | ||
2834 | } | ||
2835 | if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { | ||
2836 | ath_print(common, ATH_DBG_INTERRUPT, | ||
2837 | "AR_INTR_SYNC_RADM_CPL_TIMEOUT\n"); | ||
2838 | REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); | ||
2839 | REG_WRITE(ah, AR_RC, 0); | ||
2840 | *masked |= ATH9K_INT_FATAL; | ||
2841 | } | ||
2842 | if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) { | ||
2843 | ath_print(common, ATH_DBG_INTERRUPT, | ||
2844 | "AR_INTR_SYNC_LOCAL_TIMEOUT\n"); | ||
2845 | } | ||
2846 | |||
2847 | REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause); | ||
2848 | (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR); | ||
2849 | } | ||
2850 | |||
2851 | return true; | ||
2852 | } | ||
2853 | EXPORT_SYMBOL(ath9k_hw_getisr); | ||
2854 | |||
2855 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | ||
2856 | { | ||
2857 | u32 omask = ah->mask_reg; | ||
2858 | u32 mask, mask2; | ||
2859 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
2860 | struct ath_common *common = ath9k_hw_common(ah); | ||
2861 | |||
2862 | ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); | ||
2863 | |||
2864 | if (omask & ATH9K_INT_GLOBAL) { | ||
2865 | ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n"); | ||
2866 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | ||
2867 | (void) REG_READ(ah, AR_IER); | ||
2868 | if (!AR_SREV_9100(ah)) { | ||
2869 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0); | ||
2870 | (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE); | ||
2871 | |||
2872 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); | ||
2873 | (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); | ||
2874 | } | ||
2875 | } | ||
2876 | |||
2877 | mask = ints & ATH9K_INT_COMMON; | ||
2878 | mask2 = 0; | ||
2879 | |||
2880 | if (ints & ATH9K_INT_TX) { | ||
2881 | if (ah->txok_interrupt_mask) | ||
2882 | mask |= AR_IMR_TXOK; | ||
2883 | if (ah->txdesc_interrupt_mask) | ||
2884 | mask |= AR_IMR_TXDESC; | ||
2885 | if (ah->txerr_interrupt_mask) | ||
2886 | mask |= AR_IMR_TXERR; | ||
2887 | if (ah->txeol_interrupt_mask) | ||
2888 | mask |= AR_IMR_TXEOL; | ||
2889 | } | ||
2890 | if (ints & ATH9K_INT_RX) { | ||
2891 | mask |= AR_IMR_RXERR; | ||
2892 | if (ah->config.rx_intr_mitigation) | ||
2893 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; | ||
2894 | else | ||
2895 | mask |= AR_IMR_RXOK | AR_IMR_RXDESC; | ||
2896 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | ||
2897 | mask |= AR_IMR_GENTMR; | ||
2898 | } | ||
2899 | |||
2900 | if (ints & (ATH9K_INT_BMISC)) { | ||
2901 | mask |= AR_IMR_BCNMISC; | ||
2902 | if (ints & ATH9K_INT_TIM) | ||
2903 | mask2 |= AR_IMR_S2_TIM; | ||
2904 | if (ints & ATH9K_INT_DTIM) | ||
2905 | mask2 |= AR_IMR_S2_DTIM; | ||
2906 | if (ints & ATH9K_INT_DTIMSYNC) | ||
2907 | mask2 |= AR_IMR_S2_DTIMSYNC; | ||
2908 | if (ints & ATH9K_INT_CABEND) | ||
2909 | mask2 |= AR_IMR_S2_CABEND; | ||
2910 | if (ints & ATH9K_INT_TSFOOR) | ||
2911 | mask2 |= AR_IMR_S2_TSFOOR; | ||
2912 | } | ||
2913 | |||
2914 | if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) { | ||
2915 | mask |= AR_IMR_BCNMISC; | ||
2916 | if (ints & ATH9K_INT_GTT) | ||
2917 | mask2 |= AR_IMR_S2_GTT; | ||
2918 | if (ints & ATH9K_INT_CST) | ||
2919 | mask2 |= AR_IMR_S2_CST; | ||
2920 | } | ||
2921 | |||
2922 | ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); | ||
2923 | REG_WRITE(ah, AR_IMR, mask); | ||
2924 | mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM | | ||
2925 | AR_IMR_S2_DTIM | | ||
2926 | AR_IMR_S2_DTIMSYNC | | ||
2927 | AR_IMR_S2_CABEND | | ||
2928 | AR_IMR_S2_CABTO | | ||
2929 | AR_IMR_S2_TSFOOR | | ||
2930 | AR_IMR_S2_GTT | AR_IMR_S2_CST); | ||
2931 | REG_WRITE(ah, AR_IMR_S2, mask | mask2); | ||
2932 | ah->mask_reg = ints; | ||
2933 | |||
2934 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
2935 | if (ints & ATH9K_INT_TIM_TIMER) | ||
2936 | REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); | ||
2937 | else | ||
2938 | REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); | ||
2939 | } | ||
2940 | |||
2941 | if (ints & ATH9K_INT_GLOBAL) { | ||
2942 | ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); | ||
2943 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | ||
2944 | if (!AR_SREV_9100(ah)) { | ||
2945 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, | ||
2946 | AR_INTR_MAC_IRQ); | ||
2947 | REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); | ||
2948 | |||
2949 | |||
2950 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, | ||
2951 | AR_INTR_SYNC_DEFAULT); | ||
2952 | REG_WRITE(ah, AR_INTR_SYNC_MASK, | ||
2953 | AR_INTR_SYNC_DEFAULT); | ||
2954 | } | ||
2955 | ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | ||
2956 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | ||
2957 | } | ||
2958 | |||
2959 | return omask; | ||
2960 | } | ||
2961 | EXPORT_SYMBOL(ath9k_hw_set_interrupts); | ||
2962 | |||
2963 | /*******************/ | 1865 | /*******************/ |
2964 | /* Beacon Handling */ | 1866 | /* Beacon Handling */ |
2965 | /*******************/ | 1867 | /*******************/ |
@@ -2970,6 +1872,8 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | |||
2970 | 1872 | ||
2971 | ah->beacon_interval = beacon_period; | 1873 | ah->beacon_interval = beacon_period; |
2972 | 1874 | ||
1875 | ENABLE_REGWRITE_BUFFER(ah); | ||
1876 | |||
2973 | switch (ah->opmode) { | 1877 | switch (ah->opmode) { |
2974 | case NL80211_IFTYPE_STATION: | 1878 | case NL80211_IFTYPE_STATION: |
2975 | case NL80211_IFTYPE_MONITOR: | 1879 | case NL80211_IFTYPE_MONITOR: |
@@ -3013,6 +1917,9 @@ void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period) | |||
3013 | REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); | 1917 | REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period)); |
3014 | REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); | 1918 | REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period)); |
3015 | 1919 | ||
1920 | REGWRITE_BUFFER_FLUSH(ah); | ||
1921 | DISABLE_REGWRITE_BUFFER(ah); | ||
1922 | |||
3016 | beacon_period &= ~ATH9K_BEACON_ENA; | 1923 | beacon_period &= ~ATH9K_BEACON_ENA; |
3017 | if (beacon_period & ATH9K_BEACON_RESET_TSF) { | 1924 | if (beacon_period & ATH9K_BEACON_RESET_TSF) { |
3018 | ath9k_hw_reset_tsf(ah); | 1925 | ath9k_hw_reset_tsf(ah); |
@@ -3029,6 +1936,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
3029 | struct ath9k_hw_capabilities *pCap = &ah->caps; | 1936 | struct ath9k_hw_capabilities *pCap = &ah->caps; |
3030 | struct ath_common *common = ath9k_hw_common(ah); | 1937 | struct ath_common *common = ath9k_hw_common(ah); |
3031 | 1938 | ||
1939 | ENABLE_REGWRITE_BUFFER(ah); | ||
1940 | |||
3032 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); | 1941 | REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt)); |
3033 | 1942 | ||
3034 | REG_WRITE(ah, AR_BEACON_PERIOD, | 1943 | REG_WRITE(ah, AR_BEACON_PERIOD, |
@@ -3036,6 +1945,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
3036 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, | 1945 | REG_WRITE(ah, AR_DMA_BEACON_PERIOD, |
3037 | TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); | 1946 | TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD)); |
3038 | 1947 | ||
1948 | REGWRITE_BUFFER_FLUSH(ah); | ||
1949 | DISABLE_REGWRITE_BUFFER(ah); | ||
1950 | |||
3039 | REG_RMW_FIELD(ah, AR_RSSI_THR, | 1951 | REG_RMW_FIELD(ah, AR_RSSI_THR, |
3040 | AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); | 1952 | AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold); |
3041 | 1953 | ||
@@ -3058,6 +1970,8 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
3058 | ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); | 1970 | ath_print(common, ATH_DBG_BEACON, "beacon period %d\n", beaconintval); |
3059 | ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); | 1971 | ath_print(common, ATH_DBG_BEACON, "DTIM period %d\n", dtimperiod); |
3060 | 1972 | ||
1973 | ENABLE_REGWRITE_BUFFER(ah); | ||
1974 | |||
3061 | REG_WRITE(ah, AR_NEXT_DTIM, | 1975 | REG_WRITE(ah, AR_NEXT_DTIM, |
3062 | TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); | 1976 | TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP)); |
3063 | REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP)); | 1977 | REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP)); |
@@ -3077,6 +1991,9 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | |||
3077 | REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval)); | 1991 | REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval)); |
3078 | REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); | 1992 | REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod)); |
3079 | 1993 | ||
1994 | REGWRITE_BUFFER_FLUSH(ah); | ||
1995 | DISABLE_REGWRITE_BUFFER(ah); | ||
1996 | |||
3080 | REG_SET_BIT(ah, AR_TIMER_MODE, | 1997 | REG_SET_BIT(ah, AR_TIMER_MODE, |
3081 | AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | | 1998 | AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN | |
3082 | AR_DTIM_TIMER_EN); | 1999 | AR_DTIM_TIMER_EN); |
@@ -3219,7 +2136,9 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3219 | else | 2136 | else |
3220 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; | 2137 | pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD; |
3221 | 2138 | ||
3222 | if (AR_SREV_9285_10_OR_LATER(ah)) | 2139 | if (AR_SREV_9271(ah)) |
2140 | pCap->num_gpio_pins = AR9271_NUM_GPIO; | ||
2141 | else if (AR_SREV_9285_10_OR_LATER(ah)) | ||
3223 | pCap->num_gpio_pins = AR9285_NUM_GPIO; | 2142 | pCap->num_gpio_pins = AR9285_NUM_GPIO; |
3224 | else if (AR_SREV_9280_10_OR_LATER(ah)) | 2143 | else if (AR_SREV_9280_10_OR_LATER(ah)) |
3225 | pCap->num_gpio_pins = AR928X_NUM_GPIO; | 2144 | pCap->num_gpio_pins = AR928X_NUM_GPIO; |
@@ -3246,8 +2165,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3246 | pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; | 2165 | pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT; |
3247 | } | 2166 | } |
3248 | #endif | 2167 | #endif |
3249 | 2168 | if (AR_SREV_9271(ah)) | |
3250 | pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; | 2169 | pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP; |
2170 | else | ||
2171 | pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP; | ||
3251 | 2172 | ||
3252 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) | 2173 | if (AR_SREV_9280(ah) || AR_SREV_9285(ah)) |
3253 | pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; | 2174 | pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS; |
@@ -3291,6 +2212,26 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) | |||
3291 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; | 2212 | btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; |
3292 | } | 2213 | } |
3293 | 2214 | ||
2215 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
2216 | pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_LDPC | | ||
2217 | ATH9K_HW_CAP_FASTCLOCK; | ||
2218 | pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; | ||
2219 | pCap->rx_lp_qdepth = ATH9K_HW_RX_LP_QDEPTH; | ||
2220 | pCap->rx_status_len = sizeof(struct ar9003_rxs); | ||
2221 | pCap->tx_desc_len = sizeof(struct ar9003_txc); | ||
2222 | pCap->txs_len = sizeof(struct ar9003_txs); | ||
2223 | } else { | ||
2224 | pCap->tx_desc_len = sizeof(struct ath_desc); | ||
2225 | if (AR_SREV_9280_20(ah) && | ||
2226 | ((ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) <= | ||
2227 | AR5416_EEP_MINOR_VER_16) || | ||
2228 | ah->eep_ops->get_eeprom(ah, EEP_FSTCLK_5G))) | ||
2229 | pCap->hw_caps |= ATH9K_HW_CAP_FASTCLOCK; | ||
2230 | } | ||
2231 | |||
2232 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
2233 | pCap->hw_caps |= ATH9K_HW_CAP_RAC_SUPPORTED; | ||
2234 | |||
3294 | return 0; | 2235 | return 0; |
3295 | } | 2236 | } |
3296 | 2237 | ||
@@ -3323,10 +2264,6 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, | |||
3323 | case ATH9K_CAP_TKIP_SPLIT: | 2264 | case ATH9K_CAP_TKIP_SPLIT: |
3324 | return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ? | 2265 | return (ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA) ? |
3325 | false : true; | 2266 | false : true; |
3326 | case ATH9K_CAP_DIVERSITY: | ||
3327 | return (REG_READ(ah, AR_PHY_CCK_DETECT) & | ||
3328 | AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ? | ||
3329 | true : false; | ||
3330 | case ATH9K_CAP_MCAST_KEYSRCH: | 2267 | case ATH9K_CAP_MCAST_KEYSRCH: |
3331 | switch (capability) { | 2268 | switch (capability) { |
3332 | case 0: | 2269 | case 0: |
@@ -3369,8 +2306,6 @@ EXPORT_SYMBOL(ath9k_hw_getcapability); | |||
3369 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, | 2306 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, |
3370 | u32 capability, u32 setting, int *status) | 2307 | u32 capability, u32 setting, int *status) |
3371 | { | 2308 | { |
3372 | u32 v; | ||
3373 | |||
3374 | switch (type) { | 2309 | switch (type) { |
3375 | case ATH9K_CAP_TKIP_MIC: | 2310 | case ATH9K_CAP_TKIP_MIC: |
3376 | if (setting) | 2311 | if (setting) |
@@ -3380,14 +2315,6 @@ bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, | |||
3380 | ah->sta_id1_defaults &= | 2315 | ah->sta_id1_defaults &= |
3381 | ~AR_STA_ID1_CRPT_MIC_ENABLE; | 2316 | ~AR_STA_ID1_CRPT_MIC_ENABLE; |
3382 | return true; | 2317 | return true; |
3383 | case ATH9K_CAP_DIVERSITY: | ||
3384 | v = REG_READ(ah, AR_PHY_CCK_DETECT); | ||
3385 | if (setting) | ||
3386 | v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
3387 | else | ||
3388 | v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV; | ||
3389 | REG_WRITE(ah, AR_PHY_CCK_DETECT, v); | ||
3390 | return true; | ||
3391 | case ATH9K_CAP_MCAST_KEYSRCH: | 2318 | case ATH9K_CAP_MCAST_KEYSRCH: |
3392 | if (setting) | 2319 | if (setting) |
3393 | ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH; | 2320 | ah->sta_id1_defaults |= AR_STA_ID1_MCAST_KSRCH; |
@@ -3455,7 +2382,11 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) | |||
3455 | if (gpio >= ah->caps.num_gpio_pins) | 2382 | if (gpio >= ah->caps.num_gpio_pins) |
3456 | return 0xffffffff; | 2383 | return 0xffffffff; |
3457 | 2384 | ||
3458 | if (AR_SREV_9287_10_OR_LATER(ah)) | 2385 | if (AR_SREV_9300_20_OR_LATER(ah)) |
2386 | return MS_REG_READ(AR9300, gpio) != 0; | ||
2387 | else if (AR_SREV_9271(ah)) | ||
2388 | return MS_REG_READ(AR9271, gpio) != 0; | ||
2389 | else if (AR_SREV_9287_10_OR_LATER(ah)) | ||
3459 | return MS_REG_READ(AR9287, gpio) != 0; | 2390 | return MS_REG_READ(AR9287, gpio) != 0; |
3460 | else if (AR_SREV_9285_10_OR_LATER(ah)) | 2391 | else if (AR_SREV_9285_10_OR_LATER(ah)) |
3461 | return MS_REG_READ(AR9285, gpio) != 0; | 2392 | return MS_REG_READ(AR9285, gpio) != 0; |
@@ -3484,6 +2415,9 @@ EXPORT_SYMBOL(ath9k_hw_cfg_output); | |||
3484 | 2415 | ||
3485 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) | 2416 | void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val) |
3486 | { | 2417 | { |
2418 | if (AR_SREV_9271(ah)) | ||
2419 | val = ~val; | ||
2420 | |||
3487 | REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), | 2421 | REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio), |
3488 | AR_GPIO_BIT(gpio)); | 2422 | AR_GPIO_BIT(gpio)); |
3489 | } | 2423 | } |
@@ -3523,6 +2457,8 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) | |||
3523 | { | 2457 | { |
3524 | u32 phybits; | 2458 | u32 phybits; |
3525 | 2459 | ||
2460 | ENABLE_REGWRITE_BUFFER(ah); | ||
2461 | |||
3526 | REG_WRITE(ah, AR_RX_FILTER, bits); | 2462 | REG_WRITE(ah, AR_RX_FILTER, bits); |
3527 | 2463 | ||
3528 | phybits = 0; | 2464 | phybits = 0; |
@@ -3538,6 +2474,9 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) | |||
3538 | else | 2474 | else |
3539 | REG_WRITE(ah, AR_RXCFG, | 2475 | REG_WRITE(ah, AR_RXCFG, |
3540 | REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); | 2476 | REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA); |
2477 | |||
2478 | REGWRITE_BUFFER_FLUSH(ah); | ||
2479 | DISABLE_REGWRITE_BUFFER(ah); | ||
3541 | } | 2480 | } |
3542 | EXPORT_SYMBOL(ath9k_hw_setrxfilter); | 2481 | EXPORT_SYMBOL(ath9k_hw_setrxfilter); |
3543 | 2482 | ||
@@ -3610,14 +2549,25 @@ void ath9k_hw_write_associd(struct ath_hw *ah) | |||
3610 | } | 2549 | } |
3611 | EXPORT_SYMBOL(ath9k_hw_write_associd); | 2550 | EXPORT_SYMBOL(ath9k_hw_write_associd); |
3612 | 2551 | ||
2552 | #define ATH9K_MAX_TSF_READ 10 | ||
2553 | |||
3613 | u64 ath9k_hw_gettsf64(struct ath_hw *ah) | 2554 | u64 ath9k_hw_gettsf64(struct ath_hw *ah) |
3614 | { | 2555 | { |
3615 | u64 tsf; | 2556 | u32 tsf_lower, tsf_upper1, tsf_upper2; |
2557 | int i; | ||
2558 | |||
2559 | tsf_upper1 = REG_READ(ah, AR_TSF_U32); | ||
2560 | for (i = 0; i < ATH9K_MAX_TSF_READ; i++) { | ||
2561 | tsf_lower = REG_READ(ah, AR_TSF_L32); | ||
2562 | tsf_upper2 = REG_READ(ah, AR_TSF_U32); | ||
2563 | if (tsf_upper2 == tsf_upper1) | ||
2564 | break; | ||
2565 | tsf_upper1 = tsf_upper2; | ||
2566 | } | ||
3616 | 2567 | ||
3617 | tsf = REG_READ(ah, AR_TSF_U32); | 2568 | WARN_ON( i == ATH9K_MAX_TSF_READ ); |
3618 | tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32); | ||
3619 | 2569 | ||
3620 | return tsf; | 2570 | return (((u64)tsf_upper1 << 32) | tsf_lower); |
3621 | } | 2571 | } |
3622 | EXPORT_SYMBOL(ath9k_hw_gettsf64); | 2572 | EXPORT_SYMBOL(ath9k_hw_gettsf64); |
3623 | 2573 | ||
@@ -3868,6 +2818,16 @@ void ath_gen_timer_isr(struct ath_hw *ah) | |||
3868 | } | 2818 | } |
3869 | EXPORT_SYMBOL(ath_gen_timer_isr); | 2819 | EXPORT_SYMBOL(ath_gen_timer_isr); |
3870 | 2820 | ||
2821 | /********/ | ||
2822 | /* HTC */ | ||
2823 | /********/ | ||
2824 | |||
2825 | void ath9k_hw_htc_resetinit(struct ath_hw *ah) | ||
2826 | { | ||
2827 | ah->htc_reset_init = true; | ||
2828 | } | ||
2829 | EXPORT_SYMBOL(ath9k_hw_htc_resetinit); | ||
2830 | |||
3871 | static struct { | 2831 | static struct { |
3872 | u32 version; | 2832 | u32 version; |
3873 | const char * name; | 2833 | const char * name; |
@@ -3882,6 +2842,7 @@ static struct { | |||
3882 | { AR_SREV_VERSION_9285, "9285" }, | 2842 | { AR_SREV_VERSION_9285, "9285" }, |
3883 | { AR_SREV_VERSION_9287, "9287" }, | 2843 | { AR_SREV_VERSION_9287, "9287" }, |
3884 | { AR_SREV_VERSION_9271, "9271" }, | 2844 | { AR_SREV_VERSION_9271, "9271" }, |
2845 | { AR_SREV_VERSION_9300, "9300" }, | ||
3885 | }; | 2846 | }; |
3886 | 2847 | ||
3887 | /* For devices with external radios */ | 2848 | /* For devices with external radios */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index dbbf7ca5f97d..77245dff5993 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | 2 | * Copyright (c) 2008-2010 Atheros Communications Inc. |
3 | * | 3 | * |
4 | * Permission to use, copy, modify, and/or distribute this software for any | 4 | * Permission to use, copy, modify, and/or distribute this software for any |
5 | * purpose with or without fee is hereby granted, provided that the above | 5 | * purpose with or without fee is hereby granted, provided that the above |
@@ -41,18 +41,16 @@ | |||
41 | #define AR9280_DEVID_PCIE 0x002a | 41 | #define AR9280_DEVID_PCIE 0x002a |
42 | #define AR9285_DEVID_PCIE 0x002b | 42 | #define AR9285_DEVID_PCIE 0x002b |
43 | #define AR2427_DEVID_PCIE 0x002c | 43 | #define AR2427_DEVID_PCIE 0x002c |
44 | #define AR9287_DEVID_PCI 0x002d | ||
45 | #define AR9287_DEVID_PCIE 0x002e | ||
46 | #define AR9300_DEVID_PCIE 0x0030 | ||
44 | 47 | ||
45 | #define AR5416_AR9100_DEVID 0x000b | 48 | #define AR5416_AR9100_DEVID 0x000b |
46 | 49 | ||
47 | #define AR9271_USB 0x9271 | ||
48 | |||
49 | #define AR_SUBVENDOR_ID_NOG 0x0e11 | 50 | #define AR_SUBVENDOR_ID_NOG 0x0e11 |
50 | #define AR_SUBVENDOR_ID_NEW_A 0x7065 | 51 | #define AR_SUBVENDOR_ID_NEW_A 0x7065 |
51 | #define AR5416_MAGIC 0x19641014 | 52 | #define AR5416_MAGIC 0x19641014 |
52 | 53 | ||
53 | #define AR5416_DEVID_AR9287_PCI 0x002D | ||
54 | #define AR5416_DEVID_AR9287_PCIE 0x002E | ||
55 | |||
56 | #define AR9280_COEX2WIRE_SUBSYSID 0x309b | 54 | #define AR9280_COEX2WIRE_SUBSYSID 0x309b |
57 | #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa | 55 | #define AT9285_COEX3WIRE_SA_SUBSYSID 0x30aa |
58 | #define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab | 56 | #define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab |
@@ -70,6 +68,24 @@ | |||
70 | #define REG_READ(_ah, _reg) \ | 68 | #define REG_READ(_ah, _reg) \ |
71 | ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) | 69 | ath9k_hw_common(_ah)->ops->read((_ah), (_reg)) |
72 | 70 | ||
71 | #define ENABLE_REGWRITE_BUFFER(_ah) \ | ||
72 | do { \ | ||
73 | if (AR_SREV_9271(_ah)) \ | ||
74 | ath9k_hw_common(_ah)->ops->enable_write_buffer((_ah)); \ | ||
75 | } while (0) | ||
76 | |||
77 | #define DISABLE_REGWRITE_BUFFER(_ah) \ | ||
78 | do { \ | ||
79 | if (AR_SREV_9271(_ah)) \ | ||
80 | ath9k_hw_common(_ah)->ops->disable_write_buffer((_ah)); \ | ||
81 | } while (0) | ||
82 | |||
83 | #define REGWRITE_BUFFER_FLUSH(_ah) \ | ||
84 | do { \ | ||
85 | if (AR_SREV_9271(_ah)) \ | ||
86 | ath9k_hw_common(_ah)->ops->write_flush((_ah)); \ | ||
87 | } while (0) | ||
88 | |||
73 | #define SM(_v, _f) (((_v) << _f##_S) & _f) | 89 | #define SM(_v, _f) (((_v) << _f##_S) & _f) |
74 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) | 90 | #define MS(_v, _f) (((_v) & _f) >> _f##_S) |
75 | #define REG_RMW(_a, _r, _set, _clr) \ | 91 | #define REG_RMW(_a, _r, _set, _clr) \ |
@@ -77,6 +93,8 @@ | |||
77 | #define REG_RMW_FIELD(_a, _r, _f, _v) \ | 93 | #define REG_RMW_FIELD(_a, _r, _f, _v) \ |
78 | REG_WRITE(_a, _r, \ | 94 | REG_WRITE(_a, _r, \ |
79 | (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f)) | 95 | (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f)) |
96 | #define REG_READ_FIELD(_a, _r, _f) \ | ||
97 | (((REG_READ(_a, _r) & _f) >> _f##_S)) | ||
80 | #define REG_SET_BIT(_a, _r, _f) \ | 98 | #define REG_SET_BIT(_a, _r, _f) \ |
81 | REG_WRITE(_a, _r, REG_READ(_a, _r) | _f) | 99 | REG_WRITE(_a, _r, REG_READ(_a, _r) | _f) |
82 | #define REG_CLR_BIT(_a, _r, _f) \ | 100 | #define REG_CLR_BIT(_a, _r, _f) \ |
@@ -137,6 +155,16 @@ | |||
137 | 155 | ||
138 | #define TU_TO_USEC(_tu) ((_tu) << 10) | 156 | #define TU_TO_USEC(_tu) ((_tu) << 10) |
139 | 157 | ||
158 | #define ATH9K_HW_RX_HP_QDEPTH 16 | ||
159 | #define ATH9K_HW_RX_LP_QDEPTH 128 | ||
160 | |||
161 | enum ath_ini_subsys { | ||
162 | ATH_INI_PRE = 0, | ||
163 | ATH_INI_CORE, | ||
164 | ATH_INI_POST, | ||
165 | ATH_INI_NUM_SPLIT, | ||
166 | }; | ||
167 | |||
140 | enum wireless_mode { | 168 | enum wireless_mode { |
141 | ATH9K_MODE_11A = 0, | 169 | ATH9K_MODE_11A = 0, |
142 | ATH9K_MODE_11G, | 170 | ATH9K_MODE_11G, |
@@ -167,13 +195,16 @@ enum ath9k_hw_caps { | |||
167 | ATH9K_HW_CAP_ENHANCEDPM = BIT(14), | 195 | ATH9K_HW_CAP_ENHANCEDPM = BIT(14), |
168 | ATH9K_HW_CAP_AUTOSLEEP = BIT(15), | 196 | ATH9K_HW_CAP_AUTOSLEEP = BIT(15), |
169 | ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16), | 197 | ATH9K_HW_CAP_4KB_SPLITTRANS = BIT(16), |
198 | ATH9K_HW_CAP_EDMA = BIT(17), | ||
199 | ATH9K_HW_CAP_RAC_SUPPORTED = BIT(18), | ||
200 | ATH9K_HW_CAP_LDPC = BIT(19), | ||
201 | ATH9K_HW_CAP_FASTCLOCK = BIT(20), | ||
170 | }; | 202 | }; |
171 | 203 | ||
172 | enum ath9k_capability_type { | 204 | enum ath9k_capability_type { |
173 | ATH9K_CAP_CIPHER = 0, | 205 | ATH9K_CAP_CIPHER = 0, |
174 | ATH9K_CAP_TKIP_MIC, | 206 | ATH9K_CAP_TKIP_MIC, |
175 | ATH9K_CAP_TKIP_SPLIT, | 207 | ATH9K_CAP_TKIP_SPLIT, |
176 | ATH9K_CAP_DIVERSITY, | ||
177 | ATH9K_CAP_TXPOW, | 208 | ATH9K_CAP_TXPOW, |
178 | ATH9K_CAP_MCAST_KEYSRCH, | 209 | ATH9K_CAP_MCAST_KEYSRCH, |
179 | ATH9K_CAP_DS | 210 | ATH9K_CAP_DS |
@@ -194,6 +225,11 @@ struct ath9k_hw_capabilities { | |||
194 | u8 num_gpio_pins; | 225 | u8 num_gpio_pins; |
195 | u8 num_antcfg_2ghz; | 226 | u8 num_antcfg_2ghz; |
196 | u8 num_antcfg_5ghz; | 227 | u8 num_antcfg_5ghz; |
228 | u8 rx_hp_qdepth; | ||
229 | u8 rx_lp_qdepth; | ||
230 | u8 rx_status_len; | ||
231 | u8 tx_desc_len; | ||
232 | u8 txs_len; | ||
197 | }; | 233 | }; |
198 | 234 | ||
199 | struct ath9k_ops_config { | 235 | struct ath9k_ops_config { |
@@ -214,6 +250,7 @@ struct ath9k_ops_config { | |||
214 | u32 enable_ani; | 250 | u32 enable_ani; |
215 | int serialize_regmode; | 251 | int serialize_regmode; |
216 | bool rx_intr_mitigation; | 252 | bool rx_intr_mitigation; |
253 | bool tx_intr_mitigation; | ||
217 | #define SPUR_DISABLE 0 | 254 | #define SPUR_DISABLE 0 |
218 | #define SPUR_ENABLE_IOCTL 1 | 255 | #define SPUR_ENABLE_IOCTL 1 |
219 | #define SPUR_ENABLE_EEPROM 2 | 256 | #define SPUR_ENABLE_EEPROM 2 |
@@ -225,6 +262,7 @@ struct ath9k_ops_config { | |||
225 | #define AR_BASE_FREQ_5GHZ 4900 | 262 | #define AR_BASE_FREQ_5GHZ 4900 |
226 | #define AR_SPUR_FEEQ_BOUND_HT40 19 | 263 | #define AR_SPUR_FEEQ_BOUND_HT40 19 |
227 | #define AR_SPUR_FEEQ_BOUND_HT20 10 | 264 | #define AR_SPUR_FEEQ_BOUND_HT20 10 |
265 | bool tx_iq_calibration; /* Only available for >= AR9003 */ | ||
228 | int spurmode; | 266 | int spurmode; |
229 | u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; | 267 | u16 spurchans[AR_EEPROM_MODAL_SPURS][2]; |
230 | u8 max_txtrig_level; | 268 | u8 max_txtrig_level; |
@@ -233,6 +271,8 @@ struct ath9k_ops_config { | |||
233 | enum ath9k_int { | 271 | enum ath9k_int { |
234 | ATH9K_INT_RX = 0x00000001, | 272 | ATH9K_INT_RX = 0x00000001, |
235 | ATH9K_INT_RXDESC = 0x00000002, | 273 | ATH9K_INT_RXDESC = 0x00000002, |
274 | ATH9K_INT_RXHP = 0x00000001, | ||
275 | ATH9K_INT_RXLP = 0x00000002, | ||
236 | ATH9K_INT_RXNOFRM = 0x00000008, | 276 | ATH9K_INT_RXNOFRM = 0x00000008, |
237 | ATH9K_INT_RXEOL = 0x00000010, | 277 | ATH9K_INT_RXEOL = 0x00000010, |
238 | ATH9K_INT_RXORN = 0x00000020, | 278 | ATH9K_INT_RXORN = 0x00000020, |
@@ -329,10 +369,9 @@ struct ath9k_channel { | |||
329 | #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) | 369 | #define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0) |
330 | #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) | 370 | #define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0) |
331 | #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) | 371 | #define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0) |
332 | #define IS_CHAN_A_5MHZ_SPACED(_c) \ | 372 | #define IS_CHAN_A_FAST_CLOCK(_ah, _c) \ |
333 | ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ | 373 | ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ |
334 | (((_c)->channel % 20) != 0) && \ | 374 | ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK)) |
335 | (((_c)->channel % 10) != 0)) | ||
336 | 375 | ||
337 | /* These macros check chanmode and not channelFlags */ | 376 | /* These macros check chanmode and not channelFlags */ |
338 | #define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) | 377 | #define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B) |
@@ -365,6 +404,12 @@ enum ser_reg_mode { | |||
365 | SER_REG_MODE_AUTO = 2, | 404 | SER_REG_MODE_AUTO = 2, |
366 | }; | 405 | }; |
367 | 406 | ||
407 | enum ath9k_rx_qtype { | ||
408 | ATH9K_RX_QUEUE_HP, | ||
409 | ATH9K_RX_QUEUE_LP, | ||
410 | ATH9K_RX_QUEUE_MAX, | ||
411 | }; | ||
412 | |||
368 | struct ath9k_beacon_state { | 413 | struct ath9k_beacon_state { |
369 | u32 bs_nexttbtt; | 414 | u32 bs_nexttbtt; |
370 | u32 bs_nextdtim; | 415 | u32 bs_nextdtim; |
@@ -442,6 +487,124 @@ struct ath_gen_timer_table { | |||
442 | } timer_mask; | 487 | } timer_mask; |
443 | }; | 488 | }; |
444 | 489 | ||
490 | /** | ||
491 | * struct ath_hw_private_ops - callbacks used internally by hardware code | ||
492 | * | ||
493 | * This structure contains private callbacks designed to only be used internally | ||
494 | * by the hardware core. | ||
495 | * | ||
496 | * @init_cal_settings: setup types of calibrations supported | ||
497 | * @init_cal: starts actual calibration | ||
498 | * | ||
499 | * @init_mode_regs: Initializes mode registers | ||
500 | * @init_mode_gain_regs: Initialize TX/RX gain registers | ||
501 | * @macversion_supported: If this specific mac revision is supported | ||
502 | * | ||
503 | * @rf_set_freq: change frequency | ||
504 | * @spur_mitigate_freq: spur mitigation | ||
505 | * @rf_alloc_ext_banks: | ||
506 | * @rf_free_ext_banks: | ||
507 | * @set_rf_regs: | ||
508 | * @compute_pll_control: compute the PLL control value to use for | ||
509 | * AR_RTC_PLL_CONTROL for a given channel | ||
510 | * @setup_calibration: set up calibration | ||
511 | * @iscal_supported: used to query if a type of calibration is supported | ||
512 | * @loadnf: load noise floor read from each chain on the CCA registers | ||
513 | */ | ||
514 | struct ath_hw_private_ops { | ||
515 | /* Calibration ops */ | ||
516 | void (*init_cal_settings)(struct ath_hw *ah); | ||
517 | bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan); | ||
518 | |||
519 | void (*init_mode_regs)(struct ath_hw *ah); | ||
520 | void (*init_mode_gain_regs)(struct ath_hw *ah); | ||
521 | bool (*macversion_supported)(u32 macversion); | ||
522 | void (*setup_calibration)(struct ath_hw *ah, | ||
523 | struct ath9k_cal_list *currCal); | ||
524 | bool (*iscal_supported)(struct ath_hw *ah, | ||
525 | enum ath9k_cal_types calType); | ||
526 | |||
527 | /* PHY ops */ | ||
528 | int (*rf_set_freq)(struct ath_hw *ah, | ||
529 | struct ath9k_channel *chan); | ||
530 | void (*spur_mitigate_freq)(struct ath_hw *ah, | ||
531 | struct ath9k_channel *chan); | ||
532 | int (*rf_alloc_ext_banks)(struct ath_hw *ah); | ||
533 | void (*rf_free_ext_banks)(struct ath_hw *ah); | ||
534 | bool (*set_rf_regs)(struct ath_hw *ah, | ||
535 | struct ath9k_channel *chan, | ||
536 | u16 modesIndex); | ||
537 | void (*set_channel_regs)(struct ath_hw *ah, struct ath9k_channel *chan); | ||
538 | void (*init_bb)(struct ath_hw *ah, | ||
539 | struct ath9k_channel *chan); | ||
540 | int (*process_ini)(struct ath_hw *ah, struct ath9k_channel *chan); | ||
541 | void (*olc_init)(struct ath_hw *ah); | ||
542 | void (*set_rfmode)(struct ath_hw *ah, struct ath9k_channel *chan); | ||
543 | void (*mark_phy_inactive)(struct ath_hw *ah); | ||
544 | void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan); | ||
545 | bool (*rfbus_req)(struct ath_hw *ah); | ||
546 | void (*rfbus_done)(struct ath_hw *ah); | ||
547 | void (*enable_rfkill)(struct ath_hw *ah); | ||
548 | void (*restore_chainmask)(struct ath_hw *ah); | ||
549 | void (*set_diversity)(struct ath_hw *ah, bool value); | ||
550 | u32 (*compute_pll_control)(struct ath_hw *ah, | ||
551 | struct ath9k_channel *chan); | ||
552 | bool (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd, | ||
553 | int param); | ||
554 | void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]); | ||
555 | void (*loadnf)(struct ath_hw *ah, struct ath9k_channel *chan); | ||
556 | }; | ||
557 | |||
558 | /** | ||
559 | * struct ath_hw_ops - callbacks used by hardware code and driver code | ||
560 | * | ||
561 | * This structure contains callbacks designed to to be used internally by | ||
562 | * hardware code and also by the lower level driver. | ||
563 | * | ||
564 | * @config_pci_powersave: | ||
565 | * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC | ||
566 | */ | ||
567 | struct ath_hw_ops { | ||
568 | void (*config_pci_powersave)(struct ath_hw *ah, | ||
569 | int restore, | ||
570 | int power_off); | ||
571 | void (*rx_enable)(struct ath_hw *ah); | ||
572 | void (*set_desc_link)(void *ds, u32 link); | ||
573 | void (*get_desc_link)(void *ds, u32 **link); | ||
574 | bool (*calibrate)(struct ath_hw *ah, | ||
575 | struct ath9k_channel *chan, | ||
576 | u8 rxchainmask, | ||
577 | bool longcal); | ||
578 | bool (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked); | ||
579 | void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen, | ||
580 | bool is_firstseg, bool is_is_lastseg, | ||
581 | const void *ds0, dma_addr_t buf_addr, | ||
582 | unsigned int qcu); | ||
583 | int (*proc_txdesc)(struct ath_hw *ah, void *ds, | ||
584 | struct ath_tx_status *ts); | ||
585 | void (*set11n_txdesc)(struct ath_hw *ah, void *ds, | ||
586 | u32 pktLen, enum ath9k_pkt_type type, | ||
587 | u32 txPower, u32 keyIx, | ||
588 | enum ath9k_key_type keyType, | ||
589 | u32 flags); | ||
590 | void (*set11n_ratescenario)(struct ath_hw *ah, void *ds, | ||
591 | void *lastds, | ||
592 | u32 durUpdateEn, u32 rtsctsRate, | ||
593 | u32 rtsctsDuration, | ||
594 | struct ath9k_11n_rate_series series[], | ||
595 | u32 nseries, u32 flags); | ||
596 | void (*set11n_aggr_first)(struct ath_hw *ah, void *ds, | ||
597 | u32 aggrLen); | ||
598 | void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds, | ||
599 | u32 numDelims); | ||
600 | void (*set11n_aggr_last)(struct ath_hw *ah, void *ds); | ||
601 | void (*clr11n_aggr)(struct ath_hw *ah, void *ds); | ||
602 | void (*set11n_burstduration)(struct ath_hw *ah, void *ds, | ||
603 | u32 burstDuration); | ||
604 | void (*set11n_virtualmorefrag)(struct ath_hw *ah, void *ds, | ||
605 | u32 vmf); | ||
606 | }; | ||
607 | |||
445 | struct ath_hw { | 608 | struct ath_hw { |
446 | struct ieee80211_hw *hw; | 609 | struct ieee80211_hw *hw; |
447 | struct ath_common common; | 610 | struct ath_common common; |
@@ -455,13 +618,18 @@ struct ath_hw { | |||
455 | struct ar5416_eeprom_def def; | 618 | struct ar5416_eeprom_def def; |
456 | struct ar5416_eeprom_4k map4k; | 619 | struct ar5416_eeprom_4k map4k; |
457 | struct ar9287_eeprom map9287; | 620 | struct ar9287_eeprom map9287; |
621 | struct ar9300_eeprom ar9300_eep; | ||
458 | } eeprom; | 622 | } eeprom; |
459 | const struct eeprom_ops *eep_ops; | 623 | const struct eeprom_ops *eep_ops; |
460 | enum ath9k_eep_map eep_map; | ||
461 | 624 | ||
462 | bool sw_mgmt_crypto; | 625 | bool sw_mgmt_crypto; |
463 | bool is_pciexpress; | 626 | bool is_pciexpress; |
627 | bool need_an_top2_fixup; | ||
464 | u16 tx_trig_level; | 628 | u16 tx_trig_level; |
629 | s16 nf_2g_max; | ||
630 | s16 nf_2g_min; | ||
631 | s16 nf_5g_max; | ||
632 | s16 nf_5g_min; | ||
465 | u16 rfsilent; | 633 | u16 rfsilent; |
466 | u32 rfkill_gpio; | 634 | u32 rfkill_gpio; |
467 | u32 rfkill_polarity; | 635 | u32 rfkill_polarity; |
@@ -478,7 +646,8 @@ struct ath_hw { | |||
478 | struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; | 646 | struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; |
479 | 647 | ||
480 | int16_t curchan_rad_index; | 648 | int16_t curchan_rad_index; |
481 | u32 mask_reg; | 649 | enum ath9k_int imask; |
650 | u32 imrs2_reg; | ||
482 | u32 txok_interrupt_mask; | 651 | u32 txok_interrupt_mask; |
483 | u32 txerr_interrupt_mask; | 652 | u32 txerr_interrupt_mask; |
484 | u32 txdesc_interrupt_mask; | 653 | u32 txdesc_interrupt_mask; |
@@ -493,6 +662,7 @@ struct ath_hw { | |||
493 | struct ath9k_cal_list adcgain_caldata; | 662 | struct ath9k_cal_list adcgain_caldata; |
494 | struct ath9k_cal_list adcdc_calinitdata; | 663 | struct ath9k_cal_list adcdc_calinitdata; |
495 | struct ath9k_cal_list adcdc_caldata; | 664 | struct ath9k_cal_list adcdc_caldata; |
665 | struct ath9k_cal_list tempCompCalData; | ||
496 | struct ath9k_cal_list *cal_list; | 666 | struct ath9k_cal_list *cal_list; |
497 | struct ath9k_cal_list *cal_list_last; | 667 | struct ath9k_cal_list *cal_list_last; |
498 | struct ath9k_cal_list *cal_list_curr; | 668 | struct ath9k_cal_list *cal_list_curr; |
@@ -533,12 +703,10 @@ struct ath_hw { | |||
533 | DONT_USE_32KHZ, | 703 | DONT_USE_32KHZ, |
534 | } enable_32kHz_clock; | 704 | } enable_32kHz_clock; |
535 | 705 | ||
536 | /* Callback for radio frequency change */ | 706 | /* Private to hardware code */ |
537 | int (*ath9k_hw_rf_set_freq)(struct ath_hw *ah, struct ath9k_channel *chan); | 707 | struct ath_hw_private_ops private_ops; |
538 | 708 | /* Accessed by the lower level driver */ | |
539 | /* Callback for baseband spur frequency */ | 709 | struct ath_hw_ops ops; |
540 | void (*ath9k_hw_spur_mitigate_freq)(struct ath_hw *ah, | ||
541 | struct ath9k_channel *chan); | ||
542 | 710 | ||
543 | /* Used to program the radio on non single-chip devices */ | 711 | /* Used to program the radio on non single-chip devices */ |
544 | u32 *analogBank0Data; | 712 | u32 *analogBank0Data; |
@@ -551,6 +719,7 @@ struct ath_hw { | |||
551 | u32 *addac5416_21; | 719 | u32 *addac5416_21; |
552 | u32 *bank6Temp; | 720 | u32 *bank6Temp; |
553 | 721 | ||
722 | u8 txpower_limit; | ||
554 | int16_t txpower_indexoffset; | 723 | int16_t txpower_indexoffset; |
555 | int coverage_class; | 724 | int coverage_class; |
556 | u32 beacon_interval; | 725 | u32 beacon_interval; |
@@ -592,16 +761,34 @@ struct ath_hw { | |||
592 | struct ar5416IniArray iniBank7; | 761 | struct ar5416IniArray iniBank7; |
593 | struct ar5416IniArray iniAddac; | 762 | struct ar5416IniArray iniAddac; |
594 | struct ar5416IniArray iniPcieSerdes; | 763 | struct ar5416IniArray iniPcieSerdes; |
764 | struct ar5416IniArray iniPcieSerdesLowPower; | ||
595 | struct ar5416IniArray iniModesAdditional; | 765 | struct ar5416IniArray iniModesAdditional; |
596 | struct ar5416IniArray iniModesRxGain; | 766 | struct ar5416IniArray iniModesRxGain; |
597 | struct ar5416IniArray iniModesTxGain; | 767 | struct ar5416IniArray iniModesTxGain; |
598 | struct ar5416IniArray iniModes_9271_1_0_only; | 768 | struct ar5416IniArray iniModes_9271_1_0_only; |
599 | struct ar5416IniArray iniCckfirNormal; | 769 | struct ar5416IniArray iniCckfirNormal; |
600 | struct ar5416IniArray iniCckfirJapan2484; | 770 | struct ar5416IniArray iniCckfirJapan2484; |
771 | struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271; | ||
772 | struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271; | ||
773 | struct ar5416IniArray iniModes_9271_ANI_reg; | ||
774 | struct ar5416IniArray iniModes_high_power_tx_gain_9271; | ||
775 | struct ar5416IniArray iniModes_normal_power_tx_gain_9271; | ||
776 | |||
777 | struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT]; | ||
778 | struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT]; | ||
779 | struct ar5416IniArray iniRadio[ATH_INI_NUM_SPLIT]; | ||
780 | struct ar5416IniArray iniSOC[ATH_INI_NUM_SPLIT]; | ||
601 | 781 | ||
602 | u32 intr_gen_timer_trigger; | 782 | u32 intr_gen_timer_trigger; |
603 | u32 intr_gen_timer_thresh; | 783 | u32 intr_gen_timer_thresh; |
604 | struct ath_gen_timer_table hw_gen_timers; | 784 | struct ath_gen_timer_table hw_gen_timers; |
785 | |||
786 | struct ar9003_txs *ts_ring; | ||
787 | void *ts_start; | ||
788 | u32 ts_paddr_start; | ||
789 | u32 ts_paddr_end; | ||
790 | u16 ts_tail; | ||
791 | u8 ts_size; | ||
605 | }; | 792 | }; |
606 | 793 | ||
607 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) | 794 | static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) |
@@ -614,6 +801,16 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah) | |||
614 | return &(ath9k_hw_common(ah)->regulatory); | 801 | return &(ath9k_hw_common(ah)->regulatory); |
615 | } | 802 | } |
616 | 803 | ||
804 | static inline struct ath_hw_private_ops *ath9k_hw_private_ops(struct ath_hw *ah) | ||
805 | { | ||
806 | return &ah->private_ops; | ||
807 | } | ||
808 | |||
809 | static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah) | ||
810 | { | ||
811 | return &ah->ops; | ||
812 | } | ||
813 | |||
617 | /* Initialization, Detach, Reset */ | 814 | /* Initialization, Detach, Reset */ |
618 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | 815 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); |
619 | void ath9k_hw_deinit(struct ath_hw *ah); | 816 | void ath9k_hw_deinit(struct ath_hw *ah); |
@@ -625,6 +822,7 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, | |||
625 | u32 capability, u32 *result); | 822 | u32 capability, u32 *result); |
626 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, | 823 | bool ath9k_hw_setcapability(struct ath_hw *ah, enum ath9k_capability_type type, |
627 | u32 capability, u32 setting, int *status); | 824 | u32 capability, u32 setting, int *status); |
825 | u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan); | ||
628 | 826 | ||
629 | /* Key Cache Management */ | 827 | /* Key Cache Management */ |
630 | bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); | 828 | bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry); |
@@ -673,16 +871,10 @@ void ath9k_hw_set11nmac2040(struct ath_hw *ah); | |||
673 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); | 871 | void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); |
674 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, | 872 | void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, |
675 | const struct ath9k_beacon_state *bs); | 873 | const struct ath9k_beacon_state *bs); |
874 | bool ath9k_hw_check_alive(struct ath_hw *ah); | ||
676 | 875 | ||
677 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); | 876 | bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode); |
678 | 877 | ||
679 | void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off); | ||
680 | |||
681 | /* Interrupt Handling */ | ||
682 | bool ath9k_hw_intrpend(struct ath_hw *ah); | ||
683 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked); | ||
684 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); | ||
685 | |||
686 | /* Generic hw timer primitives */ | 878 | /* Generic hw timer primitives */ |
687 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, | 879 | struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, |
688 | void (*trigger)(void *), | 880 | void (*trigger)(void *), |
@@ -701,6 +893,39 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah); | |||
701 | 893 | ||
702 | void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); | 894 | void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len); |
703 | 895 | ||
896 | /* HTC */ | ||
897 | void ath9k_hw_htc_resetinit(struct ath_hw *ah); | ||
898 | |||
899 | /* PHY */ | ||
900 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, | ||
901 | u32 *coef_mantissa, u32 *coef_exponent); | ||
902 | |||
903 | /* | ||
904 | * Code Specific to AR5008, AR9001 or AR9002, | ||
905 | * we stuff these here to avoid callbacks for AR9003. | ||
906 | */ | ||
907 | void ar9002_hw_cck_chan14_spread(struct ath_hw *ah); | ||
908 | int ar9002_hw_rf_claim(struct ath_hw *ah); | ||
909 | void ar9002_hw_enable_async_fifo(struct ath_hw *ah); | ||
910 | void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah); | ||
911 | |||
912 | /* | ||
913 | * Code specifric to AR9003, we stuff these here to avoid callbacks | ||
914 | * for older families | ||
915 | */ | ||
916 | void ar9003_hw_set_nf_limits(struct ath_hw *ah); | ||
917 | |||
918 | /* Hardware family op attach helpers */ | ||
919 | void ar5008_hw_attach_phy_ops(struct ath_hw *ah); | ||
920 | void ar9002_hw_attach_phy_ops(struct ath_hw *ah); | ||
921 | void ar9003_hw_attach_phy_ops(struct ath_hw *ah); | ||
922 | |||
923 | void ar9002_hw_attach_calib_ops(struct ath_hw *ah); | ||
924 | void ar9003_hw_attach_calib_ops(struct ath_hw *ah); | ||
925 | |||
926 | void ar9002_hw_attach_ops(struct ath_hw *ah); | ||
927 | void ar9003_hw_attach_ops(struct ath_hw *ah); | ||
928 | |||
704 | #define ATH_PCIE_CAP_LINK_CTRL 0x70 | 929 | #define ATH_PCIE_CAP_LINK_CTRL 0x70 |
705 | #define ATH_PCIE_CAP_LINK_L0S 1 | 930 | #define ATH_PCIE_CAP_LINK_L0S 1 |
706 | #define ATH_PCIE_CAP_LINK_L1 2 | 931 | #define ATH_PCIE_CAP_LINK_L1 2 |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 3d4d897add6d..d457cb3bd772 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -175,6 +175,18 @@ static const struct ath_ops ath9k_common_ops = { | |||
175 | .write = ath9k_iowrite32, | 175 | .write = ath9k_iowrite32, |
176 | }; | 176 | }; |
177 | 177 | ||
178 | static int count_streams(unsigned int chainmask, int max) | ||
179 | { | ||
180 | int streams = 0; | ||
181 | |||
182 | do { | ||
183 | if (++streams == max) | ||
184 | break; | ||
185 | } while ((chainmask = chainmask & (chainmask - 1))); | ||
186 | |||
187 | return streams; | ||
188 | } | ||
189 | |||
178 | /**************************/ | 190 | /**************************/ |
179 | /* Initialization */ | 191 | /* Initialization */ |
180 | /**************************/ | 192 | /**************************/ |
@@ -182,8 +194,10 @@ static const struct ath_ops ath9k_common_ops = { | |||
182 | static void setup_ht_cap(struct ath_softc *sc, | 194 | static void setup_ht_cap(struct ath_softc *sc, |
183 | struct ieee80211_sta_ht_cap *ht_info) | 195 | struct ieee80211_sta_ht_cap *ht_info) |
184 | { | 196 | { |
185 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 197 | struct ath_hw *ah = sc->sc_ah; |
198 | struct ath_common *common = ath9k_hw_common(ah); | ||
186 | u8 tx_streams, rx_streams; | 199 | u8 tx_streams, rx_streams; |
200 | int i, max_streams; | ||
187 | 201 | ||
188 | ht_info->ht_supported = true; | 202 | ht_info->ht_supported = true; |
189 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | | 203 | ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | |
@@ -191,28 +205,40 @@ static void setup_ht_cap(struct ath_softc *sc, | |||
191 | IEEE80211_HT_CAP_SGI_40 | | 205 | IEEE80211_HT_CAP_SGI_40 | |
192 | IEEE80211_HT_CAP_DSSSCCK40; | 206 | IEEE80211_HT_CAP_DSSSCCK40; |
193 | 207 | ||
208 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_LDPC) | ||
209 | ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING; | ||
210 | |||
194 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; | 211 | ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; |
195 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; | 212 | ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; |
196 | 213 | ||
214 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
215 | max_streams = 3; | ||
216 | else | ||
217 | max_streams = 2; | ||
218 | |||
219 | if (AR_SREV_9280_10_OR_LATER(ah)) { | ||
220 | if (max_streams >= 2) | ||
221 | ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; | ||
222 | ht_info->cap |= (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT); | ||
223 | } | ||
224 | |||
197 | /* set up supported mcs set */ | 225 | /* set up supported mcs set */ |
198 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); | 226 | memset(&ht_info->mcs, 0, sizeof(ht_info->mcs)); |
199 | tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ? | 227 | tx_streams = count_streams(common->tx_chainmask, max_streams); |
200 | 1 : 2; | 228 | rx_streams = count_streams(common->rx_chainmask, max_streams); |
201 | rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ? | 229 | |
202 | 1 : 2; | 230 | ath_print(common, ATH_DBG_CONFIG, |
231 | "TX streams %d, RX streams: %d\n", | ||
232 | tx_streams, rx_streams); | ||
203 | 233 | ||
204 | if (tx_streams != rx_streams) { | 234 | if (tx_streams != rx_streams) { |
205 | ath_print(common, ATH_DBG_CONFIG, | ||
206 | "TX streams %d, RX streams: %d\n", | ||
207 | tx_streams, rx_streams); | ||
208 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; | 235 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF; |
209 | ht_info->mcs.tx_params |= ((tx_streams - 1) << | 236 | ht_info->mcs.tx_params |= ((tx_streams - 1) << |
210 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); | 237 | IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT); |
211 | } | 238 | } |
212 | 239 | ||
213 | ht_info->mcs.rx_mask[0] = 0xff; | 240 | for (i = 0; i < rx_streams; i++) |
214 | if (rx_streams >= 2) | 241 | ht_info->mcs.rx_mask[i] = 0xff; |
215 | ht_info->mcs.rx_mask[1] = 0xff; | ||
216 | 242 | ||
217 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; | 243 | ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED; |
218 | } | 244 | } |
@@ -235,31 +261,37 @@ static int ath9k_reg_notifier(struct wiphy *wiphy, | |||
235 | */ | 261 | */ |
236 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | 262 | int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, |
237 | struct list_head *head, const char *name, | 263 | struct list_head *head, const char *name, |
238 | int nbuf, int ndesc) | 264 | int nbuf, int ndesc, bool is_tx) |
239 | { | 265 | { |
240 | #define DS2PHYS(_dd, _ds) \ | 266 | #define DS2PHYS(_dd, _ds) \ |
241 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) | 267 | ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc)) |
242 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) | 268 | #define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0) |
243 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) | 269 | #define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096) |
244 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 270 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
245 | struct ath_desc *ds; | 271 | u8 *ds; |
246 | struct ath_buf *bf; | 272 | struct ath_buf *bf; |
247 | int i, bsize, error; | 273 | int i, bsize, error, desc_len; |
248 | 274 | ||
249 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", | 275 | ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n", |
250 | name, nbuf, ndesc); | 276 | name, nbuf, ndesc); |
251 | 277 | ||
252 | INIT_LIST_HEAD(head); | 278 | INIT_LIST_HEAD(head); |
279 | |||
280 | if (is_tx) | ||
281 | desc_len = sc->sc_ah->caps.tx_desc_len; | ||
282 | else | ||
283 | desc_len = sizeof(struct ath_desc); | ||
284 | |||
253 | /* ath_desc must be a multiple of DWORDs */ | 285 | /* ath_desc must be a multiple of DWORDs */ |
254 | if ((sizeof(struct ath_desc) % 4) != 0) { | 286 | if ((desc_len % 4) != 0) { |
255 | ath_print(common, ATH_DBG_FATAL, | 287 | ath_print(common, ATH_DBG_FATAL, |
256 | "ath_desc not DWORD aligned\n"); | 288 | "ath_desc not DWORD aligned\n"); |
257 | BUG_ON((sizeof(struct ath_desc) % 4) != 0); | 289 | BUG_ON((desc_len % 4) != 0); |
258 | error = -ENOMEM; | 290 | error = -ENOMEM; |
259 | goto fail; | 291 | goto fail; |
260 | } | 292 | } |
261 | 293 | ||
262 | dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc; | 294 | dd->dd_desc_len = desc_len * nbuf * ndesc; |
263 | 295 | ||
264 | /* | 296 | /* |
265 | * Need additional DMA memory because we can't use | 297 | * Need additional DMA memory because we can't use |
@@ -272,11 +304,11 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
272 | u32 dma_len; | 304 | u32 dma_len; |
273 | 305 | ||
274 | while (ndesc_skipped) { | 306 | while (ndesc_skipped) { |
275 | dma_len = ndesc_skipped * sizeof(struct ath_desc); | 307 | dma_len = ndesc_skipped * desc_len; |
276 | dd->dd_desc_len += dma_len; | 308 | dd->dd_desc_len += dma_len; |
277 | 309 | ||
278 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); | 310 | ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len); |
279 | }; | 311 | } |
280 | } | 312 | } |
281 | 313 | ||
282 | /* allocate descriptors */ | 314 | /* allocate descriptors */ |
@@ -286,7 +318,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
286 | error = -ENOMEM; | 318 | error = -ENOMEM; |
287 | goto fail; | 319 | goto fail; |
288 | } | 320 | } |
289 | ds = dd->dd_desc; | 321 | ds = (u8 *) dd->dd_desc; |
290 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", | 322 | ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n", |
291 | name, ds, (u32) dd->dd_desc_len, | 323 | name, ds, (u32) dd->dd_desc_len, |
292 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); | 324 | ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len); |
@@ -300,7 +332,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
300 | } | 332 | } |
301 | dd->dd_bufptr = bf; | 333 | dd->dd_bufptr = bf; |
302 | 334 | ||
303 | for (i = 0; i < nbuf; i++, bf++, ds += ndesc) { | 335 | for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) { |
304 | bf->bf_desc = ds; | 336 | bf->bf_desc = ds; |
305 | bf->bf_daddr = DS2PHYS(dd, ds); | 337 | bf->bf_daddr = DS2PHYS(dd, ds); |
306 | 338 | ||
@@ -316,7 +348,7 @@ int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd, | |||
316 | ((caddr_t) dd->dd_desc + | 348 | ((caddr_t) dd->dd_desc + |
317 | dd->dd_desc_len)); | 349 | dd->dd_desc_len)); |
318 | 350 | ||
319 | ds += ndesc; | 351 | ds += (desc_len * ndesc); |
320 | bf->bf_desc = ds; | 352 | bf->bf_desc = ds; |
321 | bf->bf_daddr = DS2PHYS(dd, ds); | 353 | bf->bf_daddr = DS2PHYS(dd, ds); |
322 | } | 354 | } |
@@ -514,7 +546,7 @@ static void ath9k_init_misc(struct ath_softc *sc) | |||
514 | common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; | 546 | common->tx_chainmask = sc->sc_ah->caps.tx_chainmask; |
515 | common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; | 547 | common->rx_chainmask = sc->sc_ah->caps.rx_chainmask; |
516 | 548 | ||
517 | ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL); | 549 | ath9k_hw_set_diversity(sc->sc_ah, true); |
518 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); | 550 | sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah); |
519 | 551 | ||
520 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | 552 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) |
@@ -568,13 +600,10 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
568 | ath_read_cachesize(common, &csz); | 600 | ath_read_cachesize(common, &csz); |
569 | common->cachelsz = csz << 2; /* convert to bytes */ | 601 | common->cachelsz = csz << 2; /* convert to bytes */ |
570 | 602 | ||
603 | /* Initializes the hardware for all supported chipsets */ | ||
571 | ret = ath9k_hw_init(ah); | 604 | ret = ath9k_hw_init(ah); |
572 | if (ret) { | 605 | if (ret) |
573 | ath_print(common, ATH_DBG_FATAL, | ||
574 | "Unable to initialize hardware; " | ||
575 | "initialization status: %d\n", ret); | ||
576 | goto err_hw; | 606 | goto err_hw; |
577 | } | ||
578 | 607 | ||
579 | ret = ath9k_init_debug(ah); | 608 | ret = ath9k_init_debug(ah); |
580 | if (ret) { | 609 | if (ret) { |
@@ -760,6 +789,9 @@ static void ath9k_deinit_softc(struct ath_softc *sc) | |||
760 | 789 | ||
761 | tasklet_kill(&sc->intr_tq); | 790 | tasklet_kill(&sc->intr_tq); |
762 | tasklet_kill(&sc->bcon_tasklet); | 791 | tasklet_kill(&sc->bcon_tasklet); |
792 | |||
793 | kfree(sc->sc_ah); | ||
794 | sc->sc_ah = NULL; | ||
763 | } | 795 | } |
764 | 796 | ||
765 | void ath9k_deinit_device(struct ath_softc *sc) | 797 | void ath9k_deinit_device(struct ath_softc *sc) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index efc420cd42bf..0e425cb4bbb1 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -25,14 +25,21 @@ static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah, | |||
25 | ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, | 25 | ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask, |
26 | ah->txurn_interrupt_mask); | 26 | ah->txurn_interrupt_mask); |
27 | 27 | ||
28 | ENABLE_REGWRITE_BUFFER(ah); | ||
29 | |||
28 | REG_WRITE(ah, AR_IMR_S0, | 30 | REG_WRITE(ah, AR_IMR_S0, |
29 | SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK) | 31 | SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK) |
30 | | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC)); | 32 | | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC)); |
31 | REG_WRITE(ah, AR_IMR_S1, | 33 | REG_WRITE(ah, AR_IMR_S1, |
32 | SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) | 34 | SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR) |
33 | | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); | 35 | | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL)); |
34 | REG_RMW_FIELD(ah, AR_IMR_S2, | 36 | |
35 | AR_IMR_S2_QCU_TXURN, ah->txurn_interrupt_mask); | 37 | ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN; |
38 | ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN); | ||
39 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); | ||
40 | |||
41 | REGWRITE_BUFFER_FLUSH(ah); | ||
42 | DISABLE_REGWRITE_BUFFER(ah); | ||
36 | } | 43 | } |
37 | 44 | ||
38 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) | 45 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q) |
@@ -55,6 +62,18 @@ void ath9k_hw_txstart(struct ath_hw *ah, u32 q) | |||
55 | } | 62 | } |
56 | EXPORT_SYMBOL(ath9k_hw_txstart); | 63 | EXPORT_SYMBOL(ath9k_hw_txstart); |
57 | 64 | ||
65 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds) | ||
66 | { | ||
67 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
68 | |||
69 | ads->ds_txstatus0 = ads->ds_txstatus1 = 0; | ||
70 | ads->ds_txstatus2 = ads->ds_txstatus3 = 0; | ||
71 | ads->ds_txstatus4 = ads->ds_txstatus5 = 0; | ||
72 | ads->ds_txstatus6 = ads->ds_txstatus7 = 0; | ||
73 | ads->ds_txstatus8 = ads->ds_txstatus9 = 0; | ||
74 | } | ||
75 | EXPORT_SYMBOL(ath9k_hw_cleartxdesc); | ||
76 | |||
58 | u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) | 77 | u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q) |
59 | { | 78 | { |
60 | u32 npend; | 79 | u32 npend; |
@@ -103,7 +122,7 @@ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel) | |||
103 | if (ah->tx_trig_level >= ah->config.max_txtrig_level) | 122 | if (ah->tx_trig_level >= ah->config.max_txtrig_level) |
104 | return false; | 123 | return false; |
105 | 124 | ||
106 | omask = ath9k_hw_set_interrupts(ah, ah->mask_reg & ~ATH9K_INT_GLOBAL); | 125 | omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL); |
107 | 126 | ||
108 | txcfg = REG_READ(ah, AR_TXCFG); | 127 | txcfg = REG_READ(ah, AR_TXCFG); |
109 | curLevel = MS(txcfg, AR_FTRIG); | 128 | curLevel = MS(txcfg, AR_FTRIG); |
@@ -205,280 +224,6 @@ bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q) | |||
205 | } | 224 | } |
206 | EXPORT_SYMBOL(ath9k_hw_stoptxdma); | 225 | EXPORT_SYMBOL(ath9k_hw_stoptxdma); |
207 | 226 | ||
208 | void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
209 | u32 segLen, bool firstSeg, | ||
210 | bool lastSeg, const struct ath_desc *ds0) | ||
211 | { | ||
212 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
213 | |||
214 | if (firstSeg) { | ||
215 | ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore); | ||
216 | } else if (lastSeg) { | ||
217 | ads->ds_ctl0 = 0; | ||
218 | ads->ds_ctl1 = segLen; | ||
219 | ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2; | ||
220 | ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3; | ||
221 | } else { | ||
222 | ads->ds_ctl0 = 0; | ||
223 | ads->ds_ctl1 = segLen | AR_TxMore; | ||
224 | ads->ds_ctl2 = 0; | ||
225 | ads->ds_ctl3 = 0; | ||
226 | } | ||
227 | ads->ds_txstatus0 = ads->ds_txstatus1 = 0; | ||
228 | ads->ds_txstatus2 = ads->ds_txstatus3 = 0; | ||
229 | ads->ds_txstatus4 = ads->ds_txstatus5 = 0; | ||
230 | ads->ds_txstatus6 = ads->ds_txstatus7 = 0; | ||
231 | ads->ds_txstatus8 = ads->ds_txstatus9 = 0; | ||
232 | } | ||
233 | EXPORT_SYMBOL(ath9k_hw_filltxdesc); | ||
234 | |||
235 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds) | ||
236 | { | ||
237 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
238 | |||
239 | ads->ds_txstatus0 = ads->ds_txstatus1 = 0; | ||
240 | ads->ds_txstatus2 = ads->ds_txstatus3 = 0; | ||
241 | ads->ds_txstatus4 = ads->ds_txstatus5 = 0; | ||
242 | ads->ds_txstatus6 = ads->ds_txstatus7 = 0; | ||
243 | ads->ds_txstatus8 = ads->ds_txstatus9 = 0; | ||
244 | } | ||
245 | EXPORT_SYMBOL(ath9k_hw_cleartxdesc); | ||
246 | |||
247 | int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds) | ||
248 | { | ||
249 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
250 | |||
251 | if ((ads->ds_txstatus9 & AR_TxDone) == 0) | ||
252 | return -EINPROGRESS; | ||
253 | |||
254 | ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum); | ||
255 | ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp; | ||
256 | ds->ds_txstat.ts_status = 0; | ||
257 | ds->ds_txstat.ts_flags = 0; | ||
258 | |||
259 | if (ads->ds_txstatus1 & AR_FrmXmitOK) | ||
260 | ds->ds_txstat.ts_status |= ATH9K_TX_ACKED; | ||
261 | if (ads->ds_txstatus1 & AR_ExcessiveRetries) | ||
262 | ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY; | ||
263 | if (ads->ds_txstatus1 & AR_Filtered) | ||
264 | ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT; | ||
265 | if (ads->ds_txstatus1 & AR_FIFOUnderrun) { | ||
266 | ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO; | ||
267 | ath9k_hw_updatetxtriglevel(ah, true); | ||
268 | } | ||
269 | if (ads->ds_txstatus9 & AR_TxOpExceeded) | ||
270 | ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP; | ||
271 | if (ads->ds_txstatus1 & AR_TxTimerExpired) | ||
272 | ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED; | ||
273 | |||
274 | if (ads->ds_txstatus1 & AR_DescCfgErr) | ||
275 | ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR; | ||
276 | if (ads->ds_txstatus1 & AR_TxDataUnderrun) { | ||
277 | ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN; | ||
278 | ath9k_hw_updatetxtriglevel(ah, true); | ||
279 | } | ||
280 | if (ads->ds_txstatus1 & AR_TxDelimUnderrun) { | ||
281 | ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN; | ||
282 | ath9k_hw_updatetxtriglevel(ah, true); | ||
283 | } | ||
284 | if (ads->ds_txstatus0 & AR_TxBaStatus) { | ||
285 | ds->ds_txstat.ts_flags |= ATH9K_TX_BA; | ||
286 | ds->ds_txstat.ba_low = ads->AR_BaBitmapLow; | ||
287 | ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh; | ||
288 | } | ||
289 | |||
290 | ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx); | ||
291 | switch (ds->ds_txstat.ts_rateindex) { | ||
292 | case 0: | ||
293 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0); | ||
294 | break; | ||
295 | case 1: | ||
296 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1); | ||
297 | break; | ||
298 | case 2: | ||
299 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2); | ||
300 | break; | ||
301 | case 3: | ||
302 | ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3); | ||
303 | break; | ||
304 | } | ||
305 | |||
306 | ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined); | ||
307 | ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00); | ||
308 | ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01); | ||
309 | ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02); | ||
310 | ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10); | ||
311 | ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11); | ||
312 | ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12); | ||
313 | ds->ds_txstat.evm0 = ads->AR_TxEVM0; | ||
314 | ds->ds_txstat.evm1 = ads->AR_TxEVM1; | ||
315 | ds->ds_txstat.evm2 = ads->AR_TxEVM2; | ||
316 | ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt); | ||
317 | ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt); | ||
318 | ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt); | ||
319 | ds->ds_txstat.ts_antenna = 0; | ||
320 | |||
321 | return 0; | ||
322 | } | ||
323 | EXPORT_SYMBOL(ath9k_hw_txprocdesc); | ||
324 | |||
325 | void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
326 | u32 pktLen, enum ath9k_pkt_type type, u32 txPower, | ||
327 | u32 keyIx, enum ath9k_key_type keyType, u32 flags) | ||
328 | { | ||
329 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
330 | |||
331 | txPower += ah->txpower_indexoffset; | ||
332 | if (txPower > 63) | ||
333 | txPower = 63; | ||
334 | |||
335 | ads->ds_ctl0 = (pktLen & AR_FrameLen) | ||
336 | | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0) | ||
337 | | SM(txPower, AR_XmitPower) | ||
338 | | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0) | ||
339 | | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0) | ||
340 | | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0) | ||
341 | | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0); | ||
342 | |||
343 | ads->ds_ctl1 = | ||
344 | (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0) | ||
345 | | SM(type, AR_FrameType) | ||
346 | | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0) | ||
347 | | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0) | ||
348 | | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0); | ||
349 | |||
350 | ads->ds_ctl6 = SM(keyType, AR_EncrType); | ||
351 | |||
352 | if (AR_SREV_9285(ah)) { | ||
353 | ads->ds_ctl8 = 0; | ||
354 | ads->ds_ctl9 = 0; | ||
355 | ads->ds_ctl10 = 0; | ||
356 | ads->ds_ctl11 = 0; | ||
357 | } | ||
358 | } | ||
359 | EXPORT_SYMBOL(ath9k_hw_set11n_txdesc); | ||
360 | |||
361 | void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds, | ||
362 | struct ath_desc *lastds, | ||
363 | u32 durUpdateEn, u32 rtsctsRate, | ||
364 | u32 rtsctsDuration, | ||
365 | struct ath9k_11n_rate_series series[], | ||
366 | u32 nseries, u32 flags) | ||
367 | { | ||
368 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
369 | struct ar5416_desc *last_ads = AR5416DESC(lastds); | ||
370 | u32 ds_ctl0; | ||
371 | |||
372 | if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) { | ||
373 | ds_ctl0 = ads->ds_ctl0; | ||
374 | |||
375 | if (flags & ATH9K_TXDESC_RTSENA) { | ||
376 | ds_ctl0 &= ~AR_CTSEnable; | ||
377 | ds_ctl0 |= AR_RTSEnable; | ||
378 | } else { | ||
379 | ds_ctl0 &= ~AR_RTSEnable; | ||
380 | ds_ctl0 |= AR_CTSEnable; | ||
381 | } | ||
382 | |||
383 | ads->ds_ctl0 = ds_ctl0; | ||
384 | } else { | ||
385 | ads->ds_ctl0 = | ||
386 | (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable)); | ||
387 | } | ||
388 | |||
389 | ads->ds_ctl2 = set11nTries(series, 0) | ||
390 | | set11nTries(series, 1) | ||
391 | | set11nTries(series, 2) | ||
392 | | set11nTries(series, 3) | ||
393 | | (durUpdateEn ? AR_DurUpdateEna : 0) | ||
394 | | SM(0, AR_BurstDur); | ||
395 | |||
396 | ads->ds_ctl3 = set11nRate(series, 0) | ||
397 | | set11nRate(series, 1) | ||
398 | | set11nRate(series, 2) | ||
399 | | set11nRate(series, 3); | ||
400 | |||
401 | ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0) | ||
402 | | set11nPktDurRTSCTS(series, 1); | ||
403 | |||
404 | ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2) | ||
405 | | set11nPktDurRTSCTS(series, 3); | ||
406 | |||
407 | ads->ds_ctl7 = set11nRateFlags(series, 0) | ||
408 | | set11nRateFlags(series, 1) | ||
409 | | set11nRateFlags(series, 2) | ||
410 | | set11nRateFlags(series, 3) | ||
411 | | SM(rtsctsRate, AR_RTSCTSRate); | ||
412 | last_ads->ds_ctl2 = ads->ds_ctl2; | ||
413 | last_ads->ds_ctl3 = ads->ds_ctl3; | ||
414 | } | ||
415 | EXPORT_SYMBOL(ath9k_hw_set11n_ratescenario); | ||
416 | |||
417 | void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds, | ||
418 | u32 aggrLen) | ||
419 | { | ||
420 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
421 | |||
422 | ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); | ||
423 | ads->ds_ctl6 &= ~AR_AggrLen; | ||
424 | ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen); | ||
425 | } | ||
426 | EXPORT_SYMBOL(ath9k_hw_set11n_aggr_first); | ||
427 | |||
428 | void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds, | ||
429 | u32 numDelims) | ||
430 | { | ||
431 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
432 | unsigned int ctl6; | ||
433 | |||
434 | ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr); | ||
435 | |||
436 | ctl6 = ads->ds_ctl6; | ||
437 | ctl6 &= ~AR_PadDelim; | ||
438 | ctl6 |= SM(numDelims, AR_PadDelim); | ||
439 | ads->ds_ctl6 = ctl6; | ||
440 | } | ||
441 | EXPORT_SYMBOL(ath9k_hw_set11n_aggr_middle); | ||
442 | |||
443 | void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds) | ||
444 | { | ||
445 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
446 | |||
447 | ads->ds_ctl1 |= AR_IsAggr; | ||
448 | ads->ds_ctl1 &= ~AR_MoreAggr; | ||
449 | ads->ds_ctl6 &= ~AR_PadDelim; | ||
450 | } | ||
451 | EXPORT_SYMBOL(ath9k_hw_set11n_aggr_last); | ||
452 | |||
453 | void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds) | ||
454 | { | ||
455 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
456 | |||
457 | ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr); | ||
458 | } | ||
459 | EXPORT_SYMBOL(ath9k_hw_clr11n_aggr); | ||
460 | |||
461 | void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds, | ||
462 | u32 burstDuration) | ||
463 | { | ||
464 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
465 | |||
466 | ads->ds_ctl2 &= ~AR_BurstDur; | ||
467 | ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur); | ||
468 | } | ||
469 | EXPORT_SYMBOL(ath9k_hw_set11n_burstduration); | ||
470 | |||
471 | void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds, | ||
472 | u32 vmf) | ||
473 | { | ||
474 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
475 | |||
476 | if (vmf) | ||
477 | ads->ds_ctl0 |= AR_VirtMoreFrag; | ||
478 | else | ||
479 | ads->ds_ctl0 &= ~AR_VirtMoreFrag; | ||
480 | } | ||
481 | |||
482 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) | 227 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs) |
483 | { | 228 | { |
484 | *txqs &= ah->intr_txqs; | 229 | *txqs &= ah->intr_txqs; |
@@ -730,6 +475,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
730 | } else | 475 | } else |
731 | cwMin = qi->tqi_cwmin; | 476 | cwMin = qi->tqi_cwmin; |
732 | 477 | ||
478 | ENABLE_REGWRITE_BUFFER(ah); | ||
479 | |||
733 | REG_WRITE(ah, AR_DLCL_IFS(q), | 480 | REG_WRITE(ah, AR_DLCL_IFS(q), |
734 | SM(cwMin, AR_D_LCL_IFS_CWMIN) | | 481 | SM(cwMin, AR_D_LCL_IFS_CWMIN) | |
735 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) | | 482 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) | |
@@ -744,6 +491,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
744 | REG_WRITE(ah, AR_DMISC(q), | 491 | REG_WRITE(ah, AR_DMISC(q), |
745 | AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); | 492 | AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2); |
746 | 493 | ||
494 | REGWRITE_BUFFER_FLUSH(ah); | ||
495 | |||
747 | if (qi->tqi_cbrPeriod) { | 496 | if (qi->tqi_cbrPeriod) { |
748 | REG_WRITE(ah, AR_QCBRCFG(q), | 497 | REG_WRITE(ah, AR_QCBRCFG(q), |
749 | SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | | 498 | SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) | |
@@ -759,6 +508,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
759 | AR_Q_RDYTIMECFG_EN); | 508 | AR_Q_RDYTIMECFG_EN); |
760 | } | 509 | } |
761 | 510 | ||
511 | REGWRITE_BUFFER_FLUSH(ah); | ||
512 | |||
762 | REG_WRITE(ah, AR_DCHNTIME(q), | 513 | REG_WRITE(ah, AR_DCHNTIME(q), |
763 | SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | | 514 | SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) | |
764 | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); | 515 | (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0)); |
@@ -776,6 +527,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
776 | REG_READ(ah, AR_DMISC(q)) | | 527 | REG_READ(ah, AR_DMISC(q)) | |
777 | AR_D_MISC_POST_FR_BKOFF_DIS); | 528 | AR_D_MISC_POST_FR_BKOFF_DIS); |
778 | } | 529 | } |
530 | |||
531 | REGWRITE_BUFFER_FLUSH(ah); | ||
532 | DISABLE_REGWRITE_BUFFER(ah); | ||
533 | |||
779 | if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { | 534 | if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) { |
780 | REG_WRITE(ah, AR_DMISC(q), | 535 | REG_WRITE(ah, AR_DMISC(q), |
781 | REG_READ(ah, AR_DMISC(q)) | | 536 | REG_READ(ah, AR_DMISC(q)) | |
@@ -783,6 +538,8 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
783 | } | 538 | } |
784 | switch (qi->tqi_type) { | 539 | switch (qi->tqi_type) { |
785 | case ATH9K_TX_QUEUE_BEACON: | 540 | case ATH9K_TX_QUEUE_BEACON: |
541 | ENABLE_REGWRITE_BUFFER(ah); | ||
542 | |||
786 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) | 543 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) |
787 | | AR_Q_MISC_FSP_DBA_GATED | 544 | | AR_Q_MISC_FSP_DBA_GATED |
788 | | AR_Q_MISC_BEACON_USE | 545 | | AR_Q_MISC_BEACON_USE |
@@ -793,8 +550,20 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
793 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S) | 550 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S) |
794 | | AR_D_MISC_BEACON_USE | 551 | | AR_D_MISC_BEACON_USE |
795 | | AR_D_MISC_POST_FR_BKOFF_DIS); | 552 | | AR_D_MISC_POST_FR_BKOFF_DIS); |
553 | |||
554 | REGWRITE_BUFFER_FLUSH(ah); | ||
555 | DISABLE_REGWRITE_BUFFER(ah); | ||
556 | |||
557 | /* cwmin and cwmax should be 0 for beacon queue */ | ||
558 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
559 | REG_WRITE(ah, AR_DLCL_IFS(q), SM(0, AR_D_LCL_IFS_CWMIN) | ||
560 | | SM(0, AR_D_LCL_IFS_CWMAX) | ||
561 | | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS)); | ||
562 | } | ||
796 | break; | 563 | break; |
797 | case ATH9K_TX_QUEUE_CAB: | 564 | case ATH9K_TX_QUEUE_CAB: |
565 | ENABLE_REGWRITE_BUFFER(ah); | ||
566 | |||
798 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) | 567 | REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q)) |
799 | | AR_Q_MISC_FSP_DBA_GATED | 568 | | AR_Q_MISC_FSP_DBA_GATED |
800 | | AR_Q_MISC_CBR_INCR_DIS1 | 569 | | AR_Q_MISC_CBR_INCR_DIS1 |
@@ -808,6 +577,10 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
808 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) | 577 | REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q)) |
809 | | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << | 578 | | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL << |
810 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); | 579 | AR_D_MISC_ARB_LOCKOUT_CNTRL_S)); |
580 | |||
581 | REGWRITE_BUFFER_FLUSH(ah); | ||
582 | DISABLE_REGWRITE_BUFFER(ah); | ||
583 | |||
811 | break; | 584 | break; |
812 | case ATH9K_TX_QUEUE_PSPOLL: | 585 | case ATH9K_TX_QUEUE_PSPOLL: |
813 | REG_WRITE(ah, AR_QMISC(q), | 586 | REG_WRITE(ah, AR_QMISC(q), |
@@ -829,6 +602,9 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
829 | AR_D_MISC_POST_FR_BKOFF_DIS); | 602 | AR_D_MISC_POST_FR_BKOFF_DIS); |
830 | } | 603 | } |
831 | 604 | ||
605 | if (AR_SREV_9300_20_OR_LATER(ah)) | ||
606 | REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN); | ||
607 | |||
832 | if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) | 608 | if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE) |
833 | ah->txok_interrupt_mask |= 1 << q; | 609 | ah->txok_interrupt_mask |= 1 << q; |
834 | else | 610 | else |
@@ -856,7 +632,7 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) | |||
856 | EXPORT_SYMBOL(ath9k_hw_resettxqueue); | 632 | EXPORT_SYMBOL(ath9k_hw_resettxqueue); |
857 | 633 | ||
858 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | 634 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, |
859 | u32 pa, struct ath_desc *nds, u64 tsf) | 635 | struct ath_rx_status *rs, u64 tsf) |
860 | { | 636 | { |
861 | struct ar5416_desc ads; | 637 | struct ar5416_desc ads; |
862 | struct ar5416_desc *adsp = AR5416DESC(ds); | 638 | struct ar5416_desc *adsp = AR5416DESC(ds); |
@@ -867,92 +643,76 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
867 | 643 | ||
868 | ads.u.rx = adsp->u.rx; | 644 | ads.u.rx = adsp->u.rx; |
869 | 645 | ||
870 | ds->ds_rxstat.rs_status = 0; | 646 | rs->rs_status = 0; |
871 | ds->ds_rxstat.rs_flags = 0; | 647 | rs->rs_flags = 0; |
872 | 648 | ||
873 | ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen; | 649 | rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen; |
874 | ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp; | 650 | rs->rs_tstamp = ads.AR_RcvTimestamp; |
875 | 651 | ||
876 | if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { | 652 | if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) { |
877 | ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD; | 653 | rs->rs_rssi = ATH9K_RSSI_BAD; |
878 | ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD; | 654 | rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD; |
879 | ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD; | 655 | rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD; |
880 | ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD; | 656 | rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD; |
881 | ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD; | 657 | rs->rs_rssi_ext0 = ATH9K_RSSI_BAD; |
882 | ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD; | 658 | rs->rs_rssi_ext1 = ATH9K_RSSI_BAD; |
883 | ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD; | 659 | rs->rs_rssi_ext2 = ATH9K_RSSI_BAD; |
884 | } else { | 660 | } else { |
885 | ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); | 661 | rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); |
886 | ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, | 662 | rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0, |
887 | AR_RxRSSIAnt00); | 663 | AR_RxRSSIAnt00); |
888 | ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, | 664 | rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0, |
889 | AR_RxRSSIAnt01); | 665 | AR_RxRSSIAnt01); |
890 | ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, | 666 | rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0, |
891 | AR_RxRSSIAnt02); | 667 | AR_RxRSSIAnt02); |
892 | ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, | 668 | rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4, |
893 | AR_RxRSSIAnt10); | 669 | AR_RxRSSIAnt10); |
894 | ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, | 670 | rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4, |
895 | AR_RxRSSIAnt11); | 671 | AR_RxRSSIAnt11); |
896 | ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, | 672 | rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4, |
897 | AR_RxRSSIAnt12); | 673 | AR_RxRSSIAnt12); |
898 | } | 674 | } |
899 | if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) | 675 | if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) |
900 | ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); | 676 | rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); |
901 | else | 677 | else |
902 | ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID; | 678 | rs->rs_keyix = ATH9K_RXKEYIX_INVALID; |
903 | 679 | ||
904 | ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads)); | 680 | rs->rs_rate = RXSTATUS_RATE(ah, (&ads)); |
905 | ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; | 681 | rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0; |
906 | 682 | ||
907 | ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; | 683 | rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0; |
908 | ds->ds_rxstat.rs_moreaggr = | 684 | rs->rs_moreaggr = |
909 | (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; | 685 | (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0; |
910 | ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); | 686 | rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna); |
911 | ds->ds_rxstat.rs_flags = | 687 | rs->rs_flags = |
912 | (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; | 688 | (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0; |
913 | ds->ds_rxstat.rs_flags |= | 689 | rs->rs_flags |= |
914 | (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; | 690 | (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0; |
915 | 691 | ||
916 | if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) | 692 | if (ads.ds_rxstatus8 & AR_PreDelimCRCErr) |
917 | ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE; | 693 | rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE; |
918 | if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) | 694 | if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) |
919 | ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST; | 695 | rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST; |
920 | if (ads.ds_rxstatus8 & AR_DecryptBusyErr) | 696 | if (ads.ds_rxstatus8 & AR_DecryptBusyErr) |
921 | ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY; | 697 | rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY; |
922 | 698 | ||
923 | if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { | 699 | if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) { |
924 | if (ads.ds_rxstatus8 & AR_CRCErr) | 700 | if (ads.ds_rxstatus8 & AR_CRCErr) |
925 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC; | 701 | rs->rs_status |= ATH9K_RXERR_CRC; |
926 | else if (ads.ds_rxstatus8 & AR_PHYErr) { | 702 | else if (ads.ds_rxstatus8 & AR_PHYErr) { |
927 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY; | 703 | rs->rs_status |= ATH9K_RXERR_PHY; |
928 | phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); | 704 | phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); |
929 | ds->ds_rxstat.rs_phyerr = phyerr; | 705 | rs->rs_phyerr = phyerr; |
930 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) | 706 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) |
931 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT; | 707 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
932 | else if (ads.ds_rxstatus8 & AR_MichaelErr) | 708 | else if (ads.ds_rxstatus8 & AR_MichaelErr) |
933 | ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC; | 709 | rs->rs_status |= ATH9K_RXERR_MIC; |
934 | } | 710 | } |
935 | 711 | ||
936 | return 0; | 712 | return 0; |
937 | } | 713 | } |
938 | EXPORT_SYMBOL(ath9k_hw_rxprocdesc); | 714 | EXPORT_SYMBOL(ath9k_hw_rxprocdesc); |
939 | 715 | ||
940 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
941 | u32 size, u32 flags) | ||
942 | { | ||
943 | struct ar5416_desc *ads = AR5416DESC(ds); | ||
944 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
945 | |||
946 | ads->ds_ctl1 = size & AR_BufLen; | ||
947 | if (flags & ATH9K_RXDESC_INTREQ) | ||
948 | ads->ds_ctl1 |= AR_RxIntrReq; | ||
949 | |||
950 | ads->ds_rxstatus8 &= ~AR_RxDone; | ||
951 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | ||
952 | memset(&(ads->u), 0, sizeof(ads->u)); | ||
953 | } | ||
954 | EXPORT_SYMBOL(ath9k_hw_setuprxdesc); | ||
955 | |||
956 | /* | 716 | /* |
957 | * This can stop or re-enables RX. | 717 | * This can stop or re-enables RX. |
958 | * | 718 | * |
@@ -996,12 +756,6 @@ void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp) | |||
996 | } | 756 | } |
997 | EXPORT_SYMBOL(ath9k_hw_putrxbuf); | 757 | EXPORT_SYMBOL(ath9k_hw_putrxbuf); |
998 | 758 | ||
999 | void ath9k_hw_rxena(struct ath_hw *ah) | ||
1000 | { | ||
1001 | REG_WRITE(ah, AR_CR, AR_CR_RXE); | ||
1002 | } | ||
1003 | EXPORT_SYMBOL(ath9k_hw_rxena); | ||
1004 | |||
1005 | void ath9k_hw_startpcureceive(struct ath_hw *ah) | 759 | void ath9k_hw_startpcureceive(struct ath_hw *ah) |
1006 | { | 760 | { |
1007 | ath9k_enable_mib_counters(ah); | 761 | ath9k_enable_mib_counters(ah); |
@@ -1020,6 +774,14 @@ void ath9k_hw_stoppcurecv(struct ath_hw *ah) | |||
1020 | } | 774 | } |
1021 | EXPORT_SYMBOL(ath9k_hw_stoppcurecv); | 775 | EXPORT_SYMBOL(ath9k_hw_stoppcurecv); |
1022 | 776 | ||
777 | void ath9k_hw_abortpcurecv(struct ath_hw *ah) | ||
778 | { | ||
779 | REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS); | ||
780 | |||
781 | ath9k_hw_disable_mib_counters(ah); | ||
782 | } | ||
783 | EXPORT_SYMBOL(ath9k_hw_abortpcurecv); | ||
784 | |||
1023 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah) | 785 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah) |
1024 | { | 786 | { |
1025 | #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ | 787 | #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */ |
@@ -1065,3 +827,142 @@ int ath9k_hw_beaconq_setup(struct ath_hw *ah) | |||
1065 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); | 827 | return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi); |
1066 | } | 828 | } |
1067 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); | 829 | EXPORT_SYMBOL(ath9k_hw_beaconq_setup); |
830 | |||
831 | bool ath9k_hw_intrpend(struct ath_hw *ah) | ||
832 | { | ||
833 | u32 host_isr; | ||
834 | |||
835 | if (AR_SREV_9100(ah)) | ||
836 | return true; | ||
837 | |||
838 | host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE); | ||
839 | if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS)) | ||
840 | return true; | ||
841 | |||
842 | host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE); | ||
843 | if ((host_isr & AR_INTR_SYNC_DEFAULT) | ||
844 | && (host_isr != AR_INTR_SPURIOUS)) | ||
845 | return true; | ||
846 | |||
847 | return false; | ||
848 | } | ||
849 | EXPORT_SYMBOL(ath9k_hw_intrpend); | ||
850 | |||
851 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, | ||
852 | enum ath9k_int ints) | ||
853 | { | ||
854 | enum ath9k_int omask = ah->imask; | ||
855 | u32 mask, mask2; | ||
856 | struct ath9k_hw_capabilities *pCap = &ah->caps; | ||
857 | struct ath_common *common = ath9k_hw_common(ah); | ||
858 | |||
859 | ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints); | ||
860 | |||
861 | if (omask & ATH9K_INT_GLOBAL) { | ||
862 | ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n"); | ||
863 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | ||
864 | (void) REG_READ(ah, AR_IER); | ||
865 | if (!AR_SREV_9100(ah)) { | ||
866 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0); | ||
867 | (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE); | ||
868 | |||
869 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0); | ||
870 | (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); | ||
871 | } | ||
872 | } | ||
873 | |||
874 | /* TODO: global int Ref count */ | ||
875 | mask = ints & ATH9K_INT_COMMON; | ||
876 | mask2 = 0; | ||
877 | |||
878 | if (ints & ATH9K_INT_TX) { | ||
879 | if (ah->config.tx_intr_mitigation) | ||
880 | mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM; | ||
881 | else { | ||
882 | if (ah->txok_interrupt_mask) | ||
883 | mask |= AR_IMR_TXOK; | ||
884 | if (ah->txdesc_interrupt_mask) | ||
885 | mask |= AR_IMR_TXDESC; | ||
886 | } | ||
887 | if (ah->txerr_interrupt_mask) | ||
888 | mask |= AR_IMR_TXERR; | ||
889 | if (ah->txeol_interrupt_mask) | ||
890 | mask |= AR_IMR_TXEOL; | ||
891 | } | ||
892 | if (ints & ATH9K_INT_RX) { | ||
893 | if (AR_SREV_9300_20_OR_LATER(ah)) { | ||
894 | mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP; | ||
895 | if (ah->config.rx_intr_mitigation) { | ||
896 | mask &= ~AR_IMR_RXOK_LP; | ||
897 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; | ||
898 | } else { | ||
899 | mask |= AR_IMR_RXOK_LP; | ||
900 | } | ||
901 | } else { | ||
902 | if (ah->config.rx_intr_mitigation) | ||
903 | mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM; | ||
904 | else | ||
905 | mask |= AR_IMR_RXOK | AR_IMR_RXDESC; | ||
906 | } | ||
907 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | ||
908 | mask |= AR_IMR_GENTMR; | ||
909 | } | ||
910 | |||
911 | if (ints & (ATH9K_INT_BMISC)) { | ||
912 | mask |= AR_IMR_BCNMISC; | ||
913 | if (ints & ATH9K_INT_TIM) | ||
914 | mask2 |= AR_IMR_S2_TIM; | ||
915 | if (ints & ATH9K_INT_DTIM) | ||
916 | mask2 |= AR_IMR_S2_DTIM; | ||
917 | if (ints & ATH9K_INT_DTIMSYNC) | ||
918 | mask2 |= AR_IMR_S2_DTIMSYNC; | ||
919 | if (ints & ATH9K_INT_CABEND) | ||
920 | mask2 |= AR_IMR_S2_CABEND; | ||
921 | if (ints & ATH9K_INT_TSFOOR) | ||
922 | mask2 |= AR_IMR_S2_TSFOOR; | ||
923 | } | ||
924 | |||
925 | if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) { | ||
926 | mask |= AR_IMR_BCNMISC; | ||
927 | if (ints & ATH9K_INT_GTT) | ||
928 | mask2 |= AR_IMR_S2_GTT; | ||
929 | if (ints & ATH9K_INT_CST) | ||
930 | mask2 |= AR_IMR_S2_CST; | ||
931 | } | ||
932 | |||
933 | ath_print(common, ATH_DBG_INTERRUPT, "new IMR 0x%x\n", mask); | ||
934 | REG_WRITE(ah, AR_IMR, mask); | ||
935 | ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | | ||
936 | AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | | ||
937 | AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST); | ||
938 | ah->imrs2_reg |= mask2; | ||
939 | REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg); | ||
940 | |||
941 | if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | ||
942 | if (ints & ATH9K_INT_TIM_TIMER) | ||
943 | REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); | ||
944 | else | ||
945 | REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER); | ||
946 | } | ||
947 | |||
948 | if (ints & ATH9K_INT_GLOBAL) { | ||
949 | ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n"); | ||
950 | REG_WRITE(ah, AR_IER, AR_IER_ENABLE); | ||
951 | if (!AR_SREV_9100(ah)) { | ||
952 | REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, | ||
953 | AR_INTR_MAC_IRQ); | ||
954 | REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ); | ||
955 | |||
956 | |||
957 | REG_WRITE(ah, AR_INTR_SYNC_ENABLE, | ||
958 | AR_INTR_SYNC_DEFAULT); | ||
959 | REG_WRITE(ah, AR_INTR_SYNC_MASK, | ||
960 | AR_INTR_SYNC_DEFAULT); | ||
961 | } | ||
962 | ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n", | ||
963 | REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER)); | ||
964 | } | ||
965 | |||
966 | return omask; | ||
967 | } | ||
968 | EXPORT_SYMBOL(ath9k_hw_set_interrupts); | ||
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 29851e6376a9..00f3e0c7528a 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -37,6 +37,8 @@ | |||
37 | AR_2040_##_index : 0) \ | 37 | AR_2040_##_index : 0) \ |
38 | |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ | 38 | |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \ |
39 | AR_GI##_index : 0) \ | 39 | AR_GI##_index : 0) \ |
40 | |((_series)[_index].RateFlags & ATH9K_RATESERIES_STBC ? \ | ||
41 | AR_STBC##_index : 0) \ | ||
40 | |SM((_series)[_index].ChSel, AR_ChainSel##_index)) | 42 | |SM((_series)[_index].ChSel, AR_ChainSel##_index)) |
41 | 43 | ||
42 | #define CCK_SIFS_TIME 10 | 44 | #define CCK_SIFS_TIME 10 |
@@ -86,7 +88,6 @@ | |||
86 | #define ATH9K_TX_DESC_CFG_ERR 0x04 | 88 | #define ATH9K_TX_DESC_CFG_ERR 0x04 |
87 | #define ATH9K_TX_DATA_UNDERRUN 0x08 | 89 | #define ATH9K_TX_DATA_UNDERRUN 0x08 |
88 | #define ATH9K_TX_DELIM_UNDERRUN 0x10 | 90 | #define ATH9K_TX_DELIM_UNDERRUN 0x10 |
89 | #define ATH9K_TX_SW_ABORTED 0x40 | ||
90 | #define ATH9K_TX_SW_FILTERED 0x80 | 91 | #define ATH9K_TX_SW_FILTERED 0x80 |
91 | 92 | ||
92 | /* 64 bytes */ | 93 | /* 64 bytes */ |
@@ -117,7 +118,10 @@ struct ath_tx_status { | |||
117 | int8_t ts_rssi_ext0; | 118 | int8_t ts_rssi_ext0; |
118 | int8_t ts_rssi_ext1; | 119 | int8_t ts_rssi_ext1; |
119 | int8_t ts_rssi_ext2; | 120 | int8_t ts_rssi_ext2; |
120 | u8 pad[3]; | 121 | u8 qid; |
122 | u16 desc_id; | ||
123 | u8 tid; | ||
124 | u8 pad[2]; | ||
121 | u32 ba_low; | 125 | u32 ba_low; |
122 | u32 ba_high; | 126 | u32 ba_high; |
123 | u32 evm0; | 127 | u32 evm0; |
@@ -148,6 +152,34 @@ struct ath_rx_status { | |||
148 | u32 evm0; | 152 | u32 evm0; |
149 | u32 evm1; | 153 | u32 evm1; |
150 | u32 evm2; | 154 | u32 evm2; |
155 | u32 evm3; | ||
156 | u32 evm4; | ||
157 | }; | ||
158 | |||
159 | struct ath_htc_rx_status { | ||
160 | __be64 rs_tstamp; | ||
161 | __be16 rs_datalen; | ||
162 | u8 rs_status; | ||
163 | u8 rs_phyerr; | ||
164 | int8_t rs_rssi; | ||
165 | int8_t rs_rssi_ctl0; | ||
166 | int8_t rs_rssi_ctl1; | ||
167 | int8_t rs_rssi_ctl2; | ||
168 | int8_t rs_rssi_ext0; | ||
169 | int8_t rs_rssi_ext1; | ||
170 | int8_t rs_rssi_ext2; | ||
171 | u8 rs_keyix; | ||
172 | u8 rs_rate; | ||
173 | u8 rs_antenna; | ||
174 | u8 rs_more; | ||
175 | u8 rs_isaggr; | ||
176 | u8 rs_moreaggr; | ||
177 | u8 rs_num_delims; | ||
178 | u8 rs_flags; | ||
179 | u8 rs_dummy; | ||
180 | __be32 evm0; | ||
181 | __be32 evm1; | ||
182 | __be32 evm2; | ||
151 | }; | 183 | }; |
152 | 184 | ||
153 | #define ATH9K_RXERR_CRC 0x01 | 185 | #define ATH9K_RXERR_CRC 0x01 |
@@ -207,18 +239,9 @@ struct ath_desc { | |||
207 | u32 ds_ctl0; | 239 | u32 ds_ctl0; |
208 | u32 ds_ctl1; | 240 | u32 ds_ctl1; |
209 | u32 ds_hw[20]; | 241 | u32 ds_hw[20]; |
210 | union { | ||
211 | struct ath_tx_status tx; | ||
212 | struct ath_rx_status rx; | ||
213 | void *stats; | ||
214 | } ds_us; | ||
215 | void *ds_vdata; | 242 | void *ds_vdata; |
216 | } __packed; | 243 | } __packed; |
217 | 244 | ||
218 | #define ds_txstat ds_us.tx | ||
219 | #define ds_rxstat ds_us.rx | ||
220 | #define ds_stat ds_us.stats | ||
221 | |||
222 | #define ATH9K_TXDESC_CLRDMASK 0x0001 | 245 | #define ATH9K_TXDESC_CLRDMASK 0x0001 |
223 | #define ATH9K_TXDESC_NOACK 0x0002 | 246 | #define ATH9K_TXDESC_NOACK 0x0002 |
224 | #define ATH9K_TXDESC_RTSENA 0x0004 | 247 | #define ATH9K_TXDESC_RTSENA 0x0004 |
@@ -242,7 +265,8 @@ struct ath_desc { | |||
242 | #define ATH9K_TXDESC_EXT_AND_CTL 0x0080 | 265 | #define ATH9K_TXDESC_EXT_AND_CTL 0x0080 |
243 | #define ATH9K_TXDESC_VMF 0x0100 | 266 | #define ATH9K_TXDESC_VMF 0x0100 |
244 | #define ATH9K_TXDESC_FRAG_IS_ON 0x0200 | 267 | #define ATH9K_TXDESC_FRAG_IS_ON 0x0200 |
245 | #define ATH9K_TXDESC_CAB 0x0400 | 268 | #define ATH9K_TXDESC_LOWRXCHAIN 0x0400 |
269 | #define ATH9K_TXDESC_LDPC 0x00010000 | ||
246 | 270 | ||
247 | #define ATH9K_RXDESC_INTREQ 0x0020 | 271 | #define ATH9K_RXDESC_INTREQ 0x0020 |
248 | 272 | ||
@@ -336,7 +360,6 @@ struct ar5416_desc { | |||
336 | #define AR_DestIdxValid 0x40000000 | 360 | #define AR_DestIdxValid 0x40000000 |
337 | #define AR_CTSEnable 0x80000000 | 361 | #define AR_CTSEnable 0x80000000 |
338 | 362 | ||
339 | #define AR_BufLen 0x00000fff | ||
340 | #define AR_TxMore 0x00001000 | 363 | #define AR_TxMore 0x00001000 |
341 | #define AR_DestIdx 0x000fe000 | 364 | #define AR_DestIdx 0x000fe000 |
342 | #define AR_DestIdx_S 13 | 365 | #define AR_DestIdx_S 13 |
@@ -393,6 +416,7 @@ struct ar5416_desc { | |||
393 | #define AR_EncrType 0x0c000000 | 416 | #define AR_EncrType 0x0c000000 |
394 | #define AR_EncrType_S 26 | 417 | #define AR_EncrType_S 26 |
395 | #define AR_TxCtlRsvd61 0xf0000000 | 418 | #define AR_TxCtlRsvd61 0xf0000000 |
419 | #define AR_LDPC 0x80000000 | ||
396 | 420 | ||
397 | #define AR_2040_0 0x00000001 | 421 | #define AR_2040_0 0x00000001 |
398 | #define AR_GI0 0x00000002 | 422 | #define AR_GI0 0x00000002 |
@@ -412,7 +436,10 @@ struct ar5416_desc { | |||
412 | #define AR_ChainSel3_S 17 | 436 | #define AR_ChainSel3_S 17 |
413 | #define AR_RTSCTSRate 0x0ff00000 | 437 | #define AR_RTSCTSRate 0x0ff00000 |
414 | #define AR_RTSCTSRate_S 20 | 438 | #define AR_RTSCTSRate_S 20 |
415 | #define AR_TxCtlRsvd70 0xf0000000 | 439 | #define AR_STBC0 0x10000000 |
440 | #define AR_STBC1 0x20000000 | ||
441 | #define AR_STBC2 0x40000000 | ||
442 | #define AR_STBC3 0x80000000 | ||
416 | 443 | ||
417 | #define AR_TxRSSIAnt00 0x000000ff | 444 | #define AR_TxRSSIAnt00 0x000000ff |
418 | #define AR_TxRSSIAnt00_S 0 | 445 | #define AR_TxRSSIAnt00_S 0 |
@@ -476,7 +503,6 @@ struct ar5416_desc { | |||
476 | 503 | ||
477 | #define AR_RxCTLRsvd00 0xffffffff | 504 | #define AR_RxCTLRsvd00 0xffffffff |
478 | 505 | ||
479 | #define AR_BufLen 0x00000fff | ||
480 | #define AR_RxCtlRsvd00 0x00001000 | 506 | #define AR_RxCtlRsvd00 0x00001000 |
481 | #define AR_RxIntrReq 0x00002000 | 507 | #define AR_RxIntrReq 0x00002000 |
482 | #define AR_RxCtlRsvd01 0xffffc000 | 508 | #define AR_RxCtlRsvd01 0xffffc000 |
@@ -626,6 +652,7 @@ enum ath9k_rx_filter { | |||
626 | #define ATH9K_RATESERIES_RTS_CTS 0x0001 | 652 | #define ATH9K_RATESERIES_RTS_CTS 0x0001 |
627 | #define ATH9K_RATESERIES_2040 0x0002 | 653 | #define ATH9K_RATESERIES_2040 0x0002 |
628 | #define ATH9K_RATESERIES_HALFGI 0x0004 | 654 | #define ATH9K_RATESERIES_HALFGI 0x0004 |
655 | #define ATH9K_RATESERIES_STBC 0x0008 | ||
629 | 656 | ||
630 | struct ath9k_11n_rate_series { | 657 | struct ath9k_11n_rate_series { |
631 | u32 Tries; | 658 | u32 Tries; |
@@ -669,33 +696,10 @@ struct ath9k_channel; | |||
669 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); | 696 | u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q); |
670 | void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); | 697 | void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp); |
671 | void ath9k_hw_txstart(struct ath_hw *ah, u32 q); | 698 | void ath9k_hw_txstart(struct ath_hw *ah, u32 q); |
699 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds); | ||
672 | u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); | 700 | u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q); |
673 | bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); | 701 | bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel); |
674 | bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); | 702 | bool ath9k_hw_stoptxdma(struct ath_hw *ah, u32 q); |
675 | void ath9k_hw_filltxdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
676 | u32 segLen, bool firstSeg, | ||
677 | bool lastSeg, const struct ath_desc *ds0); | ||
678 | void ath9k_hw_cleartxdesc(struct ath_hw *ah, struct ath_desc *ds); | ||
679 | int ath9k_hw_txprocdesc(struct ath_hw *ah, struct ath_desc *ds); | ||
680 | void ath9k_hw_set11n_txdesc(struct ath_hw *ah, struct ath_desc *ds, | ||
681 | u32 pktLen, enum ath9k_pkt_type type, u32 txPower, | ||
682 | u32 keyIx, enum ath9k_key_type keyType, u32 flags); | ||
683 | void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, struct ath_desc *ds, | ||
684 | struct ath_desc *lastds, | ||
685 | u32 durUpdateEn, u32 rtsctsRate, | ||
686 | u32 rtsctsDuration, | ||
687 | struct ath9k_11n_rate_series series[], | ||
688 | u32 nseries, u32 flags); | ||
689 | void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, struct ath_desc *ds, | ||
690 | u32 aggrLen); | ||
691 | void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, struct ath_desc *ds, | ||
692 | u32 numDelims); | ||
693 | void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, struct ath_desc *ds); | ||
694 | void ath9k_hw_clr11n_aggr(struct ath_hw *ah, struct ath_desc *ds); | ||
695 | void ath9k_hw_set11n_burstduration(struct ath_hw *ah, struct ath_desc *ds, | ||
696 | u32 burstDuration); | ||
697 | void ath9k_hw_set11n_virtualmorefrag(struct ath_hw *ah, struct ath_desc *ds, | ||
698 | u32 vmf); | ||
699 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); | 703 | void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs); |
700 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, | 704 | bool ath9k_hw_set_txq_props(struct ath_hw *ah, int q, |
701 | const struct ath9k_tx_queue_info *qinfo); | 705 | const struct ath9k_tx_queue_info *qinfo); |
@@ -706,15 +710,22 @@ int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type, | |||
706 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); | 710 | bool ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q); |
707 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); | 711 | bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q); |
708 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | 712 | int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, |
709 | u32 pa, struct ath_desc *nds, u64 tsf); | 713 | struct ath_rx_status *rs, u64 tsf); |
710 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, | 714 | void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds, |
711 | u32 size, u32 flags); | 715 | u32 size, u32 flags); |
712 | bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); | 716 | bool ath9k_hw_setrxabort(struct ath_hw *ah, bool set); |
713 | void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); | 717 | void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp); |
714 | void ath9k_hw_rxena(struct ath_hw *ah); | ||
715 | void ath9k_hw_startpcureceive(struct ath_hw *ah); | 718 | void ath9k_hw_startpcureceive(struct ath_hw *ah); |
716 | void ath9k_hw_stoppcurecv(struct ath_hw *ah); | 719 | void ath9k_hw_stoppcurecv(struct ath_hw *ah); |
720 | void ath9k_hw_abortpcurecv(struct ath_hw *ah); | ||
717 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah); | 721 | bool ath9k_hw_stopdmarecv(struct ath_hw *ah); |
718 | int ath9k_hw_beaconq_setup(struct ath_hw *ah); | 722 | int ath9k_hw_beaconq_setup(struct ath_hw *ah); |
719 | 723 | ||
724 | /* Interrupt Handling */ | ||
725 | bool ath9k_hw_intrpend(struct ath_hw *ah); | ||
726 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, | ||
727 | enum ath9k_int ints); | ||
728 | |||
729 | void ar9002_hw_attach_mac_ops(struct ath_hw *ah); | ||
730 | |||
720 | #endif /* MAC_H */ | 731 | #endif /* MAC_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 115e1aeedb59..893b552981a0 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -225,7 +225,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
225 | 225 | ||
226 | ath_cache_conf_rate(sc, &hw->conf); | 226 | ath_cache_conf_rate(sc, &hw->conf); |
227 | ath_update_txpow(sc); | 227 | ath_update_txpow(sc); |
228 | ath9k_hw_set_interrupts(ah, sc->imask); | 228 | ath9k_hw_set_interrupts(ah, ah->imask); |
229 | 229 | ||
230 | ps_restore: | 230 | ps_restore: |
231 | ath9k_ps_restore(sc); | 231 | ath9k_ps_restore(sc); |
@@ -401,23 +401,41 @@ void ath9k_tasklet(unsigned long data) | |||
401 | struct ath_common *common = ath9k_hw_common(ah); | 401 | struct ath_common *common = ath9k_hw_common(ah); |
402 | 402 | ||
403 | u32 status = sc->intrstatus; | 403 | u32 status = sc->intrstatus; |
404 | u32 rxmask; | ||
404 | 405 | ||
405 | ath9k_ps_wakeup(sc); | 406 | ath9k_ps_wakeup(sc); |
406 | 407 | ||
407 | if (status & ATH9K_INT_FATAL) { | 408 | if ((status & ATH9K_INT_FATAL) || |
409 | !ath9k_hw_check_alive(ah)) { | ||
408 | ath_reset(sc, false); | 410 | ath_reset(sc, false); |
409 | ath9k_ps_restore(sc); | 411 | ath9k_ps_restore(sc); |
410 | return; | 412 | return; |
411 | } | 413 | } |
412 | 414 | ||
413 | if (status & (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) { | 415 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
416 | rxmask = (ATH9K_INT_RXHP | ATH9K_INT_RXLP | ATH9K_INT_RXEOL | | ||
417 | ATH9K_INT_RXORN); | ||
418 | else | ||
419 | rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | ||
420 | |||
421 | if (status & rxmask) { | ||
414 | spin_lock_bh(&sc->rx.rxflushlock); | 422 | spin_lock_bh(&sc->rx.rxflushlock); |
415 | ath_rx_tasklet(sc, 0); | 423 | |
424 | /* Check for high priority Rx first */ | ||
425 | if ((ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && | ||
426 | (status & ATH9K_INT_RXHP)) | ||
427 | ath_rx_tasklet(sc, 0, true); | ||
428 | |||
429 | ath_rx_tasklet(sc, 0, false); | ||
416 | spin_unlock_bh(&sc->rx.rxflushlock); | 430 | spin_unlock_bh(&sc->rx.rxflushlock); |
417 | } | 431 | } |
418 | 432 | ||
419 | if (status & ATH9K_INT_TX) | 433 | if (status & ATH9K_INT_TX) { |
420 | ath_tx_tasklet(sc); | 434 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
435 | ath_tx_edma_tasklet(sc); | ||
436 | else | ||
437 | ath_tx_tasklet(sc); | ||
438 | } | ||
421 | 439 | ||
422 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { | 440 | if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) { |
423 | /* | 441 | /* |
@@ -434,7 +452,7 @@ void ath9k_tasklet(unsigned long data) | |||
434 | ath_gen_timer_isr(sc->sc_ah); | 452 | ath_gen_timer_isr(sc->sc_ah); |
435 | 453 | ||
436 | /* re-enable hardware interrupt */ | 454 | /* re-enable hardware interrupt */ |
437 | ath9k_hw_set_interrupts(ah, sc->imask); | 455 | ath9k_hw_set_interrupts(ah, ah->imask); |
438 | ath9k_ps_restore(sc); | 456 | ath9k_ps_restore(sc); |
439 | } | 457 | } |
440 | 458 | ||
@@ -445,6 +463,8 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
445 | ATH9K_INT_RXORN | \ | 463 | ATH9K_INT_RXORN | \ |
446 | ATH9K_INT_RXEOL | \ | 464 | ATH9K_INT_RXEOL | \ |
447 | ATH9K_INT_RX | \ | 465 | ATH9K_INT_RX | \ |
466 | ATH9K_INT_RXLP | \ | ||
467 | ATH9K_INT_RXHP | \ | ||
448 | ATH9K_INT_TX | \ | 468 | ATH9K_INT_TX | \ |
449 | ATH9K_INT_BMISS | \ | 469 | ATH9K_INT_BMISS | \ |
450 | ATH9K_INT_CST | \ | 470 | ATH9K_INT_CST | \ |
@@ -477,7 +497,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
477 | * value to insure we only process bits we requested. | 497 | * value to insure we only process bits we requested. |
478 | */ | 498 | */ |
479 | ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ | 499 | ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */ |
480 | status &= sc->imask; /* discard unasked-for bits */ | 500 | status &= ah->imask; /* discard unasked-for bits */ |
481 | 501 | ||
482 | /* | 502 | /* |
483 | * If there are no status bits set, then this interrupt was not | 503 | * If there are no status bits set, then this interrupt was not |
@@ -496,7 +516,8 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
496 | * If a FATAL or RXORN interrupt is received, we have to reset the | 516 | * If a FATAL or RXORN interrupt is received, we have to reset the |
497 | * chip immediately. | 517 | * chip immediately. |
498 | */ | 518 | */ |
499 | if (status & (ATH9K_INT_FATAL | ATH9K_INT_RXORN)) | 519 | if ((status & ATH9K_INT_FATAL) || ((status & ATH9K_INT_RXORN) && |
520 | !(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA))) | ||
500 | goto chip_reset; | 521 | goto chip_reset; |
501 | 522 | ||
502 | if (status & ATH9K_INT_SWBA) | 523 | if (status & ATH9K_INT_SWBA) |
@@ -505,6 +526,13 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
505 | if (status & ATH9K_INT_TXURN) | 526 | if (status & ATH9K_INT_TXURN) |
506 | ath9k_hw_updatetxtriglevel(ah, true); | 527 | ath9k_hw_updatetxtriglevel(ah, true); |
507 | 528 | ||
529 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
530 | if (status & ATH9K_INT_RXEOL) { | ||
531 | ah->imask &= ~(ATH9K_INT_RXEOL | ATH9K_INT_RXORN); | ||
532 | ath9k_hw_set_interrupts(ah, ah->imask); | ||
533 | } | ||
534 | } | ||
535 | |||
508 | if (status & ATH9K_INT_MIB) { | 536 | if (status & ATH9K_INT_MIB) { |
509 | /* | 537 | /* |
510 | * Disable interrupts until we service the MIB | 538 | * Disable interrupts until we service the MIB |
@@ -518,7 +546,7 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
518 | * the interrupt. | 546 | * the interrupt. |
519 | */ | 547 | */ |
520 | ath9k_hw_procmibevent(ah); | 548 | ath9k_hw_procmibevent(ah); |
521 | ath9k_hw_set_interrupts(ah, sc->imask); | 549 | ath9k_hw_set_interrupts(ah, ah->imask); |
522 | } | 550 | } |
523 | 551 | ||
524 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) | 552 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) |
@@ -536,7 +564,7 @@ chip_reset: | |||
536 | 564 | ||
537 | if (sched) { | 565 | if (sched) { |
538 | /* turn off every interrupt except SWBA */ | 566 | /* turn off every interrupt except SWBA */ |
539 | ath9k_hw_set_interrupts(ah, (sc->imask & ATH9K_INT_SWBA)); | 567 | ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA)); |
540 | tasklet_schedule(&sc->intr_tq); | 568 | tasklet_schedule(&sc->intr_tq); |
541 | } | 569 | } |
542 | 570 | ||
@@ -724,6 +752,7 @@ static int ath_key_config(struct ath_common *common, | |||
724 | struct ath_hw *ah = common->ah; | 752 | struct ath_hw *ah = common->ah; |
725 | struct ath9k_keyval hk; | 753 | struct ath9k_keyval hk; |
726 | const u8 *mac = NULL; | 754 | const u8 *mac = NULL; |
755 | u8 gmac[ETH_ALEN]; | ||
727 | int ret = 0; | 756 | int ret = 0; |
728 | int idx; | 757 | int idx; |
729 | 758 | ||
@@ -747,9 +776,30 @@ static int ath_key_config(struct ath_common *common, | |||
747 | memcpy(hk.kv_val, key->key, key->keylen); | 776 | memcpy(hk.kv_val, key->key, key->keylen); |
748 | 777 | ||
749 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { | 778 | if (!(key->flags & IEEE80211_KEY_FLAG_PAIRWISE)) { |
750 | /* For now, use the default keys for broadcast keys. This may | 779 | |
751 | * need to change with virtual interfaces. */ | 780 | if (key->ap_addr) { |
752 | idx = key->keyidx; | 781 | /* |
782 | * Group keys on hardware that supports multicast frame | ||
783 | * key search use a mac that is the sender's address with | ||
784 | * the high bit set instead of the app-specified address. | ||
785 | */ | ||
786 | memcpy(gmac, key->ap_addr, ETH_ALEN); | ||
787 | gmac[0] |= 0x80; | ||
788 | mac = gmac; | ||
789 | |||
790 | if (key->alg == ALG_TKIP) | ||
791 | idx = ath_reserve_key_cache_slot_tkip(common); | ||
792 | else | ||
793 | idx = ath_reserve_key_cache_slot(common); | ||
794 | if (idx < 0) | ||
795 | mac = NULL; /* no free key cache entries */ | ||
796 | } | ||
797 | |||
798 | if (!mac) { | ||
799 | /* For now, use the default keys for broadcast keys. This may | ||
800 | * need to change with virtual interfaces. */ | ||
801 | idx = key->keyidx; | ||
802 | } | ||
753 | } else if (key->keyidx) { | 803 | } else if (key->keyidx) { |
754 | if (WARN_ON(!sta)) | 804 | if (WARN_ON(!sta)) |
755 | return -EOPNOTSUPP; | 805 | return -EOPNOTSUPP; |
@@ -887,7 +937,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
887 | ath_beacon_config(sc, NULL); /* restart beacons */ | 937 | ath_beacon_config(sc, NULL); /* restart beacons */ |
888 | 938 | ||
889 | /* Re-Enable interrupts */ | 939 | /* Re-Enable interrupts */ |
890 | ath9k_hw_set_interrupts(ah, sc->imask); | 940 | ath9k_hw_set_interrupts(ah, ah->imask); |
891 | 941 | ||
892 | /* Enable LED */ | 942 | /* Enable LED */ |
893 | ath9k_hw_cfg_output(ah, ah->led_pin, | 943 | ath9k_hw_cfg_output(ah, ah->led_pin, |
@@ -977,7 +1027,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx) | |||
977 | if (sc->sc_flags & SC_OP_BEACONS) | 1027 | if (sc->sc_flags & SC_OP_BEACONS) |
978 | ath_beacon_config(sc, NULL); /* restart beacons */ | 1028 | ath_beacon_config(sc, NULL); /* restart beacons */ |
979 | 1029 | ||
980 | ath9k_hw_set_interrupts(ah, sc->imask); | 1030 | ath9k_hw_set_interrupts(ah, ah->imask); |
981 | 1031 | ||
982 | if (retry_tx) { | 1032 | if (retry_tx) { |
983 | int i; | 1033 | int i; |
@@ -1162,23 +1212,28 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1162 | } | 1212 | } |
1163 | 1213 | ||
1164 | /* Setup our intr mask. */ | 1214 | /* Setup our intr mask. */ |
1165 | sc->imask = ATH9K_INT_RX | ATH9K_INT_TX | 1215 | ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL | |
1166 | | ATH9K_INT_RXEOL | ATH9K_INT_RXORN | 1216 | ATH9K_INT_RXORN | ATH9K_INT_FATAL | |
1167 | | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL; | 1217 | ATH9K_INT_GLOBAL; |
1218 | |||
1219 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
1220 | ah->imask |= ATH9K_INT_RXHP | ATH9K_INT_RXLP; | ||
1221 | else | ||
1222 | ah->imask |= ATH9K_INT_RX; | ||
1168 | 1223 | ||
1169 | if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) | 1224 | if (ah->caps.hw_caps & ATH9K_HW_CAP_GTT) |
1170 | sc->imask |= ATH9K_INT_GTT; | 1225 | ah->imask |= ATH9K_INT_GTT; |
1171 | 1226 | ||
1172 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) | 1227 | if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) |
1173 | sc->imask |= ATH9K_INT_CST; | 1228 | ah->imask |= ATH9K_INT_CST; |
1174 | 1229 | ||
1175 | ath_cache_conf_rate(sc, &hw->conf); | 1230 | ath_cache_conf_rate(sc, &hw->conf); |
1176 | 1231 | ||
1177 | sc->sc_flags &= ~SC_OP_INVALID; | 1232 | sc->sc_flags &= ~SC_OP_INVALID; |
1178 | 1233 | ||
1179 | /* Disable BMISS interrupt when we're not associated */ | 1234 | /* Disable BMISS interrupt when we're not associated */ |
1180 | sc->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); | 1235 | ah->imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS); |
1181 | ath9k_hw_set_interrupts(ah, sc->imask); | 1236 | ath9k_hw_set_interrupts(ah, ah->imask); |
1182 | 1237 | ||
1183 | ieee80211_wake_queues(hw); | 1238 | ieee80211_wake_queues(hw); |
1184 | 1239 | ||
@@ -1372,14 +1427,15 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1372 | { | 1427 | { |
1373 | struct ath_wiphy *aphy = hw->priv; | 1428 | struct ath_wiphy *aphy = hw->priv; |
1374 | struct ath_softc *sc = aphy->sc; | 1429 | struct ath_softc *sc = aphy->sc; |
1375 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1430 | struct ath_hw *ah = sc->sc_ah; |
1431 | struct ath_common *common = ath9k_hw_common(ah); | ||
1376 | struct ath_vif *avp = (void *)vif->drv_priv; | 1432 | struct ath_vif *avp = (void *)vif->drv_priv; |
1377 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; | 1433 | enum nl80211_iftype ic_opmode = NL80211_IFTYPE_UNSPECIFIED; |
1378 | int ret = 0; | 1434 | int ret = 0; |
1379 | 1435 | ||
1380 | mutex_lock(&sc->mutex); | 1436 | mutex_lock(&sc->mutex); |
1381 | 1437 | ||
1382 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) && | 1438 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) && |
1383 | sc->nvifs > 0) { | 1439 | sc->nvifs > 0) { |
1384 | ret = -ENOBUFS; | 1440 | ret = -ENOBUFS; |
1385 | goto out; | 1441 | goto out; |
@@ -1414,19 +1470,19 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1414 | 1470 | ||
1415 | sc->nvifs++; | 1471 | sc->nvifs++; |
1416 | 1472 | ||
1417 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) | 1473 | if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK) |
1418 | ath9k_set_bssid_mask(hw); | 1474 | ath9k_set_bssid_mask(hw); |
1419 | 1475 | ||
1420 | if (sc->nvifs > 1) | 1476 | if (sc->nvifs > 1) |
1421 | goto out; /* skip global settings for secondary vif */ | 1477 | goto out; /* skip global settings for secondary vif */ |
1422 | 1478 | ||
1423 | if (ic_opmode == NL80211_IFTYPE_AP) { | 1479 | if (ic_opmode == NL80211_IFTYPE_AP) { |
1424 | ath9k_hw_set_tsfadjust(sc->sc_ah, 1); | 1480 | ath9k_hw_set_tsfadjust(ah, 1); |
1425 | sc->sc_flags |= SC_OP_TSF_RESET; | 1481 | sc->sc_flags |= SC_OP_TSF_RESET; |
1426 | } | 1482 | } |
1427 | 1483 | ||
1428 | /* Set the device opmode */ | 1484 | /* Set the device opmode */ |
1429 | sc->sc_ah->opmode = ic_opmode; | 1485 | ah->opmode = ic_opmode; |
1430 | 1486 | ||
1431 | /* | 1487 | /* |
1432 | * Enable MIB interrupts when there are hardware phy counters. | 1488 | * Enable MIB interrupts when there are hardware phy counters. |
@@ -1435,11 +1491,12 @@ static int ath9k_add_interface(struct ieee80211_hw *hw, | |||
1435 | if ((vif->type == NL80211_IFTYPE_STATION) || | 1491 | if ((vif->type == NL80211_IFTYPE_STATION) || |
1436 | (vif->type == NL80211_IFTYPE_ADHOC) || | 1492 | (vif->type == NL80211_IFTYPE_ADHOC) || |
1437 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { | 1493 | (vif->type == NL80211_IFTYPE_MESH_POINT)) { |
1438 | sc->imask |= ATH9K_INT_MIB; | 1494 | if (ah->config.enable_ani) |
1439 | sc->imask |= ATH9K_INT_TSFOOR; | 1495 | ah->imask |= ATH9K_INT_MIB; |
1496 | ah->imask |= ATH9K_INT_TSFOOR; | ||
1440 | } | 1497 | } |
1441 | 1498 | ||
1442 | ath9k_hw_set_interrupts(sc->sc_ah, sc->imask); | 1499 | ath9k_hw_set_interrupts(ah, ah->imask); |
1443 | 1500 | ||
1444 | if (vif->type == NL80211_IFTYPE_AP || | 1501 | if (vif->type == NL80211_IFTYPE_AP || |
1445 | vif->type == NL80211_IFTYPE_ADHOC || | 1502 | vif->type == NL80211_IFTYPE_ADHOC || |
@@ -1495,15 +1552,16 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1495 | 1552 | ||
1496 | void ath9k_enable_ps(struct ath_softc *sc) | 1553 | void ath9k_enable_ps(struct ath_softc *sc) |
1497 | { | 1554 | { |
1555 | struct ath_hw *ah = sc->sc_ah; | ||
1556 | |||
1498 | sc->ps_enabled = true; | 1557 | sc->ps_enabled = true; |
1499 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { | 1558 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) { |
1500 | if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { | 1559 | if ((ah->imask & ATH9K_INT_TIM_TIMER) == 0) { |
1501 | sc->imask |= ATH9K_INT_TIM_TIMER; | 1560 | ah->imask |= ATH9K_INT_TIM_TIMER; |
1502 | ath9k_hw_set_interrupts(sc->sc_ah, | 1561 | ath9k_hw_set_interrupts(ah, ah->imask); |
1503 | sc->imask); | ||
1504 | } | 1562 | } |
1505 | } | 1563 | } |
1506 | ath9k_hw_setrxabort(sc->sc_ah, 1); | 1564 | ath9k_hw_setrxabort(ah, 1); |
1507 | } | 1565 | } |
1508 | 1566 | ||
1509 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | 1567 | static int ath9k_config(struct ieee80211_hw *hw, u32 changed) |
@@ -1579,10 +1637,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1579 | PS_WAIT_FOR_CAB | | 1637 | PS_WAIT_FOR_CAB | |
1580 | PS_WAIT_FOR_PSPOLL_DATA | | 1638 | PS_WAIT_FOR_PSPOLL_DATA | |
1581 | PS_WAIT_FOR_TX_ACK); | 1639 | PS_WAIT_FOR_TX_ACK); |
1582 | if (sc->imask & ATH9K_INT_TIM_TIMER) { | 1640 | if (ah->imask & ATH9K_INT_TIM_TIMER) { |
1583 | sc->imask &= ~ATH9K_INT_TIM_TIMER; | 1641 | ah->imask &= ~ATH9K_INT_TIM_TIMER; |
1584 | ath9k_hw_set_interrupts(sc->sc_ah, | 1642 | ath9k_hw_set_interrupts(sc->sc_ah, |
1585 | sc->imask); | 1643 | ah->imask); |
1586 | } | 1644 | } |
1587 | } | 1645 | } |
1588 | } | 1646 | } |
@@ -1986,6 +2044,25 @@ static int ath9k_ampdu_action(struct ieee80211_hw *hw, | |||
1986 | return ret; | 2044 | return ret; |
1987 | } | 2045 | } |
1988 | 2046 | ||
2047 | static int ath9k_get_survey(struct ieee80211_hw *hw, int idx, | ||
2048 | struct survey_info *survey) | ||
2049 | { | ||
2050 | struct ath_wiphy *aphy = hw->priv; | ||
2051 | struct ath_softc *sc = aphy->sc; | ||
2052 | struct ath_hw *ah = sc->sc_ah; | ||
2053 | struct ath_common *common = ath9k_hw_common(ah); | ||
2054 | struct ieee80211_conf *conf = &hw->conf; | ||
2055 | |||
2056 | if (idx != 0) | ||
2057 | return -ENOENT; | ||
2058 | |||
2059 | survey->channel = conf->channel; | ||
2060 | survey->filled = SURVEY_INFO_NOISE_DBM; | ||
2061 | survey->noise = common->ani.noise_floor; | ||
2062 | |||
2063 | return 0; | ||
2064 | } | ||
2065 | |||
1989 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) | 2066 | static void ath9k_sw_scan_start(struct ieee80211_hw *hw) |
1990 | { | 2067 | { |
1991 | struct ath_wiphy *aphy = hw->priv; | 2068 | struct ath_wiphy *aphy = hw->priv; |
@@ -2057,6 +2134,7 @@ struct ieee80211_ops ath9k_ops = { | |||
2057 | .set_tsf = ath9k_set_tsf, | 2134 | .set_tsf = ath9k_set_tsf, |
2058 | .reset_tsf = ath9k_reset_tsf, | 2135 | .reset_tsf = ath9k_reset_tsf, |
2059 | .ampdu_action = ath9k_ampdu_action, | 2136 | .ampdu_action = ath9k_ampdu_action, |
2137 | .get_survey = ath9k_get_survey, | ||
2060 | .sw_scan_start = ath9k_sw_scan_start, | 2138 | .sw_scan_start = ath9k_sw_scan_start, |
2061 | .sw_scan_complete = ath9k_sw_scan_complete, | 2139 | .sw_scan_complete = ath9k_sw_scan_complete, |
2062 | .rfkill_poll = ath9k_rfkill_poll_state, | 2140 | .rfkill_poll = ath9k_rfkill_poll_state, |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 9441c6718a30..257b10ba6f57 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -28,6 +28,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { | |||
28 | { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ | 28 | { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ |
29 | { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ | 29 | { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ |
30 | { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ | 30 | { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ |
31 | { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ | ||
31 | { 0 } | 32 | { 0 } |
32 | }; | 33 | }; |
33 | 34 | ||
@@ -88,6 +89,7 @@ static void ath_pci_bt_coex_prep(struct ath_common *common) | |||
88 | } | 89 | } |
89 | 90 | ||
90 | static const struct ath_bus_ops ath_pci_bus_ops = { | 91 | static const struct ath_bus_ops ath_pci_bus_ops = { |
92 | .ath_bus_type = ATH_PCI, | ||
91 | .read_cachesize = ath_pci_read_cachesize, | 93 | .read_cachesize = ath_pci_read_cachesize, |
92 | .eeprom_read = ath_pci_eeprom_read, | 94 | .eeprom_read = ath_pci_eeprom_read, |
93 | .bt_coex_prep = ath_pci_bt_coex_prep, | 95 | .bt_coex_prep = ath_pci_bt_coex_prep, |
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c deleted file mode 100644 index 2547b3c4a26c..000000000000 --- a/drivers/net/wireless/ath/ath9k/phy.c +++ /dev/null | |||
@@ -1,978 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2008-2009 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * DOC: Programming Atheros 802.11n analog front end radios | ||
19 | * | ||
20 | * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express | ||
21 | * devices have either an external AR2133 analog front end radio for single | ||
22 | * band 2.4 GHz communication or an AR5133 analog front end radio for dual | ||
23 | * band 2.4 GHz / 5 GHz communication. | ||
24 | * | ||
25 | * All devices after the AR5416 and AR5418 family starting with the AR9280 | ||
26 | * have their analog front radios, MAC/BB and host PCIe/USB interface embedded | ||
27 | * into a single-chip and require less programming. | ||
28 | * | ||
29 | * The following single-chips exist with a respective embedded radio: | ||
30 | * | ||
31 | * AR9280 - 11n dual-band 2x2 MIMO for PCIe | ||
32 | * AR9281 - 11n single-band 1x2 MIMO for PCIe | ||
33 | * AR9285 - 11n single-band 1x1 for PCIe | ||
34 | * AR9287 - 11n single-band 2x2 MIMO for PCIe | ||
35 | * | ||
36 | * AR9220 - 11n dual-band 2x2 MIMO for PCI | ||
37 | * AR9223 - 11n single-band 2x2 MIMO for PCI | ||
38 | * | ||
39 | * AR9287 - 11n single-band 1x1 MIMO for USB | ||
40 | */ | ||
41 | |||
42 | #include <linux/slab.h> | ||
43 | |||
44 | #include "hw.h" | ||
45 | |||
46 | /** | ||
47 | * ath9k_hw_write_regs - ?? | ||
48 | * | ||
49 | * @ah: atheros hardware structure | ||
50 | * @freqIndex: | ||
51 | * @regWrites: | ||
52 | * | ||
53 | * Used for both the chipsets with an external AR2133/AR5133 radios and | ||
54 | * single-chip devices. | ||
55 | */ | ||
56 | void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites) | ||
57 | { | ||
58 | REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites); | ||
59 | } | ||
60 | |||
61 | /** | ||
62 | * ath9k_hw_ar9280_set_channel - set channel on single-chip device | ||
63 | * @ah: atheros hardware structure | ||
64 | * @chan: | ||
65 | * | ||
66 | * This is the function to change channel on single-chip devices, that is | ||
67 | * all devices after ar9280. | ||
68 | * | ||
69 | * This function takes the channel value in MHz and sets | ||
70 | * hardware channel value. Assumes writes have been enabled to analog bus. | ||
71 | * | ||
72 | * Actual Expression, | ||
73 | * | ||
74 | * For 2GHz channel, | ||
75 | * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17) | ||
76 | * (freq_ref = 40MHz) | ||
77 | * | ||
78 | * For 5GHz channel, | ||
79 | * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10) | ||
80 | * (freq_ref = 40MHz/(24>>amodeRefSel)) | ||
81 | */ | ||
82 | int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
83 | { | ||
84 | u16 bMode, fracMode, aModeRefSel = 0; | ||
85 | u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0; | ||
86 | struct chan_centers centers; | ||
87 | u32 refDivA = 24; | ||
88 | |||
89 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
90 | freq = centers.synth_center; | ||
91 | |||
92 | reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL); | ||
93 | reg32 &= 0xc0000000; | ||
94 | |||
95 | if (freq < 4800) { /* 2 GHz, fractional mode */ | ||
96 | u32 txctl; | ||
97 | int regWrites = 0; | ||
98 | |||
99 | bMode = 1; | ||
100 | fracMode = 1; | ||
101 | aModeRefSel = 0; | ||
102 | channelSel = (freq * 0x10000) / 15; | ||
103 | |||
104 | if (AR_SREV_9287_11_OR_LATER(ah)) { | ||
105 | if (freq == 2484) { | ||
106 | /* Enable channel spreading for channel 14 */ | ||
107 | REG_WRITE_ARRAY(&ah->iniCckfirJapan2484, | ||
108 | 1, regWrites); | ||
109 | } else { | ||
110 | REG_WRITE_ARRAY(&ah->iniCckfirNormal, | ||
111 | 1, regWrites); | ||
112 | } | ||
113 | } else { | ||
114 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
115 | if (freq == 2484) { | ||
116 | /* Enable channel spreading for channel 14 */ | ||
117 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
118 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
119 | } else { | ||
120 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
121 | txctl &~ AR_PHY_CCK_TX_CTRL_JAPAN); | ||
122 | } | ||
123 | } | ||
124 | } else { | ||
125 | bMode = 0; | ||
126 | fracMode = 0; | ||
127 | |||
128 | switch(ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) { | ||
129 | case 0: | ||
130 | if ((freq % 20) == 0) { | ||
131 | aModeRefSel = 3; | ||
132 | } else if ((freq % 10) == 0) { | ||
133 | aModeRefSel = 2; | ||
134 | } | ||
135 | if (aModeRefSel) | ||
136 | break; | ||
137 | case 1: | ||
138 | default: | ||
139 | aModeRefSel = 0; | ||
140 | /* | ||
141 | * Enable 2G (fractional) mode for channels | ||
142 | * which are 5MHz spaced. | ||
143 | */ | ||
144 | fracMode = 1; | ||
145 | refDivA = 1; | ||
146 | channelSel = (freq * 0x8000) / 15; | ||
147 | |||
148 | /* RefDivA setting */ | ||
149 | REG_RMW_FIELD(ah, AR_AN_SYNTH9, | ||
150 | AR_AN_SYNTH9_REFDIVA, refDivA); | ||
151 | |||
152 | } | ||
153 | |||
154 | if (!fracMode) { | ||
155 | ndiv = (freq * (refDivA >> aModeRefSel)) / 60; | ||
156 | channelSel = ndiv & 0x1ff; | ||
157 | channelFrac = (ndiv & 0xfffffe00) * 2; | ||
158 | channelSel = (channelSel << 17) | channelFrac; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | reg32 = reg32 | | ||
163 | (bMode << 29) | | ||
164 | (fracMode << 28) | (aModeRefSel << 26) | (channelSel); | ||
165 | |||
166 | REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32); | ||
167 | |||
168 | ah->curchan = chan; | ||
169 | ah->curchan_rad_index = -1; | ||
170 | |||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency | ||
176 | * @ah: atheros hardware structure | ||
177 | * @chan: | ||
178 | * | ||
179 | * For single-chip solutions. Converts to baseband spur frequency given the | ||
180 | * input channel frequency and compute register settings below. | ||
181 | */ | ||
182 | void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
183 | { | ||
184 | int bb_spur = AR_NO_SPUR; | ||
185 | int freq; | ||
186 | int bin, cur_bin; | ||
187 | int bb_spur_off, spur_subchannel_sd; | ||
188 | int spur_freq_sd; | ||
189 | int spur_delta_phase; | ||
190 | int denominator; | ||
191 | int upper, lower, cur_vit_mask; | ||
192 | int tmp, newVal; | ||
193 | int i; | ||
194 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
195 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
196 | }; | ||
197 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
198 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
199 | }; | ||
200 | int inc[4] = { 0, 100, 0, 0 }; | ||
201 | struct chan_centers centers; | ||
202 | |||
203 | int8_t mask_m[123]; | ||
204 | int8_t mask_p[123]; | ||
205 | int8_t mask_amt; | ||
206 | int tmp_mask; | ||
207 | int cur_bb_spur; | ||
208 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
209 | |||
210 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
211 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
212 | |||
213 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
214 | freq = centers.synth_center; | ||
215 | |||
216 | ah->config.spurmode = SPUR_ENABLE_EEPROM; | ||
217 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
218 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
219 | |||
220 | if (is2GHz) | ||
221 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ; | ||
222 | else | ||
223 | cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ; | ||
224 | |||
225 | if (AR_NO_SPUR == cur_bb_spur) | ||
226 | break; | ||
227 | cur_bb_spur = cur_bb_spur - freq; | ||
228 | |||
229 | if (IS_CHAN_HT40(chan)) { | ||
230 | if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) && | ||
231 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) { | ||
232 | bb_spur = cur_bb_spur; | ||
233 | break; | ||
234 | } | ||
235 | } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) && | ||
236 | (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) { | ||
237 | bb_spur = cur_bb_spur; | ||
238 | break; | ||
239 | } | ||
240 | } | ||
241 | |||
242 | if (AR_NO_SPUR == bb_spur) { | ||
243 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
244 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
245 | return; | ||
246 | } else { | ||
247 | REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK, | ||
248 | AR_PHY_FORCE_CLKEN_CCK_MRC_MUX); | ||
249 | } | ||
250 | |||
251 | bin = bb_spur * 320; | ||
252 | |||
253 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
254 | |||
255 | newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
256 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
257 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
258 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
259 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal); | ||
260 | |||
261 | newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
262 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
263 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
264 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
265 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
266 | REG_WRITE(ah, AR_PHY_SPUR_REG, newVal); | ||
267 | |||
268 | if (IS_CHAN_HT40(chan)) { | ||
269 | if (bb_spur < 0) { | ||
270 | spur_subchannel_sd = 1; | ||
271 | bb_spur_off = bb_spur + 10; | ||
272 | } else { | ||
273 | spur_subchannel_sd = 0; | ||
274 | bb_spur_off = bb_spur - 10; | ||
275 | } | ||
276 | } else { | ||
277 | spur_subchannel_sd = 0; | ||
278 | bb_spur_off = bb_spur; | ||
279 | } | ||
280 | |||
281 | if (IS_CHAN_HT40(chan)) | ||
282 | spur_delta_phase = | ||
283 | ((bb_spur * 262144) / | ||
284 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
285 | else | ||
286 | spur_delta_phase = | ||
287 | ((bb_spur * 524288) / | ||
288 | 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
289 | |||
290 | denominator = IS_CHAN_2GHZ(chan) ? 44 : 40; | ||
291 | spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff; | ||
292 | |||
293 | newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
294 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
295 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
296 | REG_WRITE(ah, AR_PHY_TIMING11, newVal); | ||
297 | |||
298 | newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S; | ||
299 | REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal); | ||
300 | |||
301 | cur_bin = -6000; | ||
302 | upper = bin + 100; | ||
303 | lower = bin - 100; | ||
304 | |||
305 | for (i = 0; i < 4; i++) { | ||
306 | int pilot_mask = 0; | ||
307 | int chan_mask = 0; | ||
308 | int bp = 0; | ||
309 | for (bp = 0; bp < 30; bp++) { | ||
310 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
311 | pilot_mask = pilot_mask | 0x1 << bp; | ||
312 | chan_mask = chan_mask | 0x1 << bp; | ||
313 | } | ||
314 | cur_bin += 100; | ||
315 | } | ||
316 | cur_bin += inc[i]; | ||
317 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
318 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
319 | } | ||
320 | |||
321 | cur_vit_mask = 6100; | ||
322 | upper = bin + 120; | ||
323 | lower = bin - 120; | ||
324 | |||
325 | for (i = 0; i < 123; i++) { | ||
326 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
327 | |||
328 | /* workaround for gcc bug #37014 */ | ||
329 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
330 | |||
331 | if (tmp_v < 75) | ||
332 | mask_amt = 1; | ||
333 | else | ||
334 | mask_amt = 0; | ||
335 | if (cur_vit_mask < 0) | ||
336 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
337 | else | ||
338 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
339 | } | ||
340 | cur_vit_mask -= 100; | ||
341 | } | ||
342 | |||
343 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
344 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
345 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
346 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
347 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
348 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
349 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
350 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
351 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
352 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
353 | |||
354 | tmp_mask = (mask_m[31] << 28) | ||
355 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
356 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
357 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
358 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
359 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
360 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
361 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
362 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
363 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
364 | |||
365 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
366 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
367 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
368 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
369 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
370 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
371 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
372 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
373 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
374 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
375 | |||
376 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
377 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
378 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
379 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
380 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
381 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
382 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
383 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
384 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
385 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
386 | |||
387 | tmp_mask = (mask_p[15] << 28) | ||
388 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
389 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
390 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
391 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
392 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
393 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
394 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
395 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
396 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
397 | |||
398 | tmp_mask = (mask_p[30] << 28) | ||
399 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
400 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
401 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
402 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
403 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
404 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
405 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
406 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
407 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
408 | |||
409 | tmp_mask = (mask_p[45] << 28) | ||
410 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
411 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
412 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
413 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
414 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
415 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
416 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
417 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
418 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
419 | |||
420 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
421 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
422 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
423 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
424 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
425 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
426 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
427 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
428 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
429 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
430 | } | ||
431 | |||
432 | /* All code below is for non single-chip solutions */ | ||
433 | |||
434 | /** | ||
435 | * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters | ||
436 | * @rfbuf: | ||
437 | * @reg32: | ||
438 | * @numBits: | ||
439 | * @firstBit: | ||
440 | * @column: | ||
441 | * | ||
442 | * Performs analog "swizzling" of parameters into their location. | ||
443 | * Used on external AR2133/AR5133 radios. | ||
444 | */ | ||
445 | static void ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32, | ||
446 | u32 numBits, u32 firstBit, | ||
447 | u32 column) | ||
448 | { | ||
449 | u32 tmp32, mask, arrayEntry, lastBit; | ||
450 | int32_t bitPosition, bitsLeft; | ||
451 | |||
452 | tmp32 = ath9k_hw_reverse_bits(reg32, numBits); | ||
453 | arrayEntry = (firstBit - 1) / 8; | ||
454 | bitPosition = (firstBit - 1) % 8; | ||
455 | bitsLeft = numBits; | ||
456 | while (bitsLeft > 0) { | ||
457 | lastBit = (bitPosition + bitsLeft > 8) ? | ||
458 | 8 : bitPosition + bitsLeft; | ||
459 | mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) << | ||
460 | (column * 8); | ||
461 | rfBuf[arrayEntry] &= ~mask; | ||
462 | rfBuf[arrayEntry] |= ((tmp32 << bitPosition) << | ||
463 | (column * 8)) & mask; | ||
464 | bitsLeft -= 8 - bitPosition; | ||
465 | tmp32 = tmp32 >> (8 - bitPosition); | ||
466 | bitPosition = 0; | ||
467 | arrayEntry++; | ||
468 | } | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Fix on 2.4 GHz band for orientation sensitivity issue by increasing | ||
473 | * rf_pwd_icsyndiv. | ||
474 | * | ||
475 | * Theoretical Rules: | ||
476 | * if 2 GHz band | ||
477 | * if forceBiasAuto | ||
478 | * if synth_freq < 2412 | ||
479 | * bias = 0 | ||
480 | * else if 2412 <= synth_freq <= 2422 | ||
481 | * bias = 1 | ||
482 | * else // synth_freq > 2422 | ||
483 | * bias = 2 | ||
484 | * else if forceBias > 0 | ||
485 | * bias = forceBias & 7 | ||
486 | * else | ||
487 | * no change, use value from ini file | ||
488 | * else | ||
489 | * no change, invalid band | ||
490 | * | ||
491 | * 1st Mod: | ||
492 | * 2422 also uses value of 2 | ||
493 | * <approved> | ||
494 | * | ||
495 | * 2nd Mod: | ||
496 | * Less than 2412 uses value of 0, 2412 and above uses value of 2 | ||
497 | */ | ||
498 | static void ath9k_hw_force_bias(struct ath_hw *ah, u16 synth_freq) | ||
499 | { | ||
500 | struct ath_common *common = ath9k_hw_common(ah); | ||
501 | u32 tmp_reg; | ||
502 | int reg_writes = 0; | ||
503 | u32 new_bias = 0; | ||
504 | |||
505 | if (!AR_SREV_5416(ah) || synth_freq >= 3000) { | ||
506 | return; | ||
507 | } | ||
508 | |||
509 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
510 | |||
511 | if (synth_freq < 2412) | ||
512 | new_bias = 0; | ||
513 | else if (synth_freq < 2422) | ||
514 | new_bias = 1; | ||
515 | else | ||
516 | new_bias = 2; | ||
517 | |||
518 | /* pre-reverse this field */ | ||
519 | tmp_reg = ath9k_hw_reverse_bits(new_bias, 3); | ||
520 | |||
521 | ath_print(common, ATH_DBG_CONFIG, | ||
522 | "Force rf_pwd_icsyndiv to %1d on %4d\n", | ||
523 | new_bias, synth_freq); | ||
524 | |||
525 | /* swizzle rf_pwd_icsyndiv */ | ||
526 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3); | ||
527 | |||
528 | /* write Bank 6 with new params */ | ||
529 | REG_WRITE_RF_ARRAY(&ah->iniBank6, ah->analogBank6Data, reg_writes); | ||
530 | } | ||
531 | |||
532 | /** | ||
533 | * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios | ||
534 | * @ah: atheros hardware stucture | ||
535 | * @chan: | ||
536 | * | ||
537 | * For the external AR2133/AR5133 radios, takes the MHz channel value and set | ||
538 | * the channel value. Assumes writes enabled to analog bus and bank6 register | ||
539 | * cache in ah->analogBank6Data. | ||
540 | */ | ||
541 | int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) | ||
542 | { | ||
543 | struct ath_common *common = ath9k_hw_common(ah); | ||
544 | u32 channelSel = 0; | ||
545 | u32 bModeSynth = 0; | ||
546 | u32 aModeRefSel = 0; | ||
547 | u32 reg32 = 0; | ||
548 | u16 freq; | ||
549 | struct chan_centers centers; | ||
550 | |||
551 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); | ||
552 | freq = centers.synth_center; | ||
553 | |||
554 | if (freq < 4800) { | ||
555 | u32 txctl; | ||
556 | |||
557 | if (((freq - 2192) % 5) == 0) { | ||
558 | channelSel = ((freq - 672) * 2 - 3040) / 10; | ||
559 | bModeSynth = 0; | ||
560 | } else if (((freq - 2224) % 5) == 0) { | ||
561 | channelSel = ((freq - 704) * 2 - 3040) / 10; | ||
562 | bModeSynth = 1; | ||
563 | } else { | ||
564 | ath_print(common, ATH_DBG_FATAL, | ||
565 | "Invalid channel %u MHz\n", freq); | ||
566 | return -EINVAL; | ||
567 | } | ||
568 | |||
569 | channelSel = (channelSel << 2) & 0xff; | ||
570 | channelSel = ath9k_hw_reverse_bits(channelSel, 8); | ||
571 | |||
572 | txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL); | ||
573 | if (freq == 2484) { | ||
574 | |||
575 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
576 | txctl | AR_PHY_CCK_TX_CTRL_JAPAN); | ||
577 | } else { | ||
578 | REG_WRITE(ah, AR_PHY_CCK_TX_CTRL, | ||
579 | txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN); | ||
580 | } | ||
581 | |||
582 | } else if ((freq % 20) == 0 && freq >= 5120) { | ||
583 | channelSel = | ||
584 | ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8); | ||
585 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
586 | } else if ((freq % 10) == 0) { | ||
587 | channelSel = | ||
588 | ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8); | ||
589 | if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) | ||
590 | aModeRefSel = ath9k_hw_reverse_bits(2, 2); | ||
591 | else | ||
592 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
593 | } else if ((freq % 5) == 0) { | ||
594 | channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8); | ||
595 | aModeRefSel = ath9k_hw_reverse_bits(1, 2); | ||
596 | } else { | ||
597 | ath_print(common, ATH_DBG_FATAL, | ||
598 | "Invalid channel %u MHz\n", freq); | ||
599 | return -EINVAL; | ||
600 | } | ||
601 | |||
602 | ath9k_hw_force_bias(ah, freq); | ||
603 | |||
604 | reg32 = | ||
605 | (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) | | ||
606 | (1 << 5) | 0x1; | ||
607 | |||
608 | REG_WRITE(ah, AR_PHY(0x37), reg32); | ||
609 | |||
610 | ah->curchan = chan; | ||
611 | ah->curchan_rad_index = -1; | ||
612 | |||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | /** | ||
617 | * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios | ||
618 | * @ah: atheros hardware structure | ||
619 | * @chan: | ||
620 | * | ||
621 | * For non single-chip solutions. Converts to baseband spur frequency given the | ||
622 | * input channel frequency and compute register settings below. | ||
623 | */ | ||
624 | void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) | ||
625 | { | ||
626 | int bb_spur = AR_NO_SPUR; | ||
627 | int bin, cur_bin; | ||
628 | int spur_freq_sd; | ||
629 | int spur_delta_phase; | ||
630 | int denominator; | ||
631 | int upper, lower, cur_vit_mask; | ||
632 | int tmp, new; | ||
633 | int i; | ||
634 | int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8, | ||
635 | AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60 | ||
636 | }; | ||
637 | int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10, | ||
638 | AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60 | ||
639 | }; | ||
640 | int inc[4] = { 0, 100, 0, 0 }; | ||
641 | |||
642 | int8_t mask_m[123]; | ||
643 | int8_t mask_p[123]; | ||
644 | int8_t mask_amt; | ||
645 | int tmp_mask; | ||
646 | int cur_bb_spur; | ||
647 | bool is2GHz = IS_CHAN_2GHZ(chan); | ||
648 | |||
649 | memset(&mask_m, 0, sizeof(int8_t) * 123); | ||
650 | memset(&mask_p, 0, sizeof(int8_t) * 123); | ||
651 | |||
652 | for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) { | ||
653 | cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz); | ||
654 | if (AR_NO_SPUR == cur_bb_spur) | ||
655 | break; | ||
656 | cur_bb_spur = cur_bb_spur - (chan->channel * 10); | ||
657 | if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) { | ||
658 | bb_spur = cur_bb_spur; | ||
659 | break; | ||
660 | } | ||
661 | } | ||
662 | |||
663 | if (AR_NO_SPUR == bb_spur) | ||
664 | return; | ||
665 | |||
666 | bin = bb_spur * 32; | ||
667 | |||
668 | tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0)); | ||
669 | new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI | | ||
670 | AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER | | ||
671 | AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK | | ||
672 | AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK); | ||
673 | |||
674 | REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new); | ||
675 | |||
676 | new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL | | ||
677 | AR_PHY_SPUR_REG_ENABLE_MASK_PPM | | ||
678 | AR_PHY_SPUR_REG_MASK_RATE_SELECT | | ||
679 | AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI | | ||
680 | SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH)); | ||
681 | REG_WRITE(ah, AR_PHY_SPUR_REG, new); | ||
682 | |||
683 | spur_delta_phase = ((bb_spur * 524288) / 100) & | ||
684 | AR_PHY_TIMING11_SPUR_DELTA_PHASE; | ||
685 | |||
686 | denominator = IS_CHAN_2GHZ(chan) ? 440 : 400; | ||
687 | spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff; | ||
688 | |||
689 | new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC | | ||
690 | SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) | | ||
691 | SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE)); | ||
692 | REG_WRITE(ah, AR_PHY_TIMING11, new); | ||
693 | |||
694 | cur_bin = -6000; | ||
695 | upper = bin + 100; | ||
696 | lower = bin - 100; | ||
697 | |||
698 | for (i = 0; i < 4; i++) { | ||
699 | int pilot_mask = 0; | ||
700 | int chan_mask = 0; | ||
701 | int bp = 0; | ||
702 | for (bp = 0; bp < 30; bp++) { | ||
703 | if ((cur_bin > lower) && (cur_bin < upper)) { | ||
704 | pilot_mask = pilot_mask | 0x1 << bp; | ||
705 | chan_mask = chan_mask | 0x1 << bp; | ||
706 | } | ||
707 | cur_bin += 100; | ||
708 | } | ||
709 | cur_bin += inc[i]; | ||
710 | REG_WRITE(ah, pilot_mask_reg[i], pilot_mask); | ||
711 | REG_WRITE(ah, chan_mask_reg[i], chan_mask); | ||
712 | } | ||
713 | |||
714 | cur_vit_mask = 6100; | ||
715 | upper = bin + 120; | ||
716 | lower = bin - 120; | ||
717 | |||
718 | for (i = 0; i < 123; i++) { | ||
719 | if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) { | ||
720 | |||
721 | /* workaround for gcc bug #37014 */ | ||
722 | volatile int tmp_v = abs(cur_vit_mask - bin); | ||
723 | |||
724 | if (tmp_v < 75) | ||
725 | mask_amt = 1; | ||
726 | else | ||
727 | mask_amt = 0; | ||
728 | if (cur_vit_mask < 0) | ||
729 | mask_m[abs(cur_vit_mask / 100)] = mask_amt; | ||
730 | else | ||
731 | mask_p[cur_vit_mask / 100] = mask_amt; | ||
732 | } | ||
733 | cur_vit_mask -= 100; | ||
734 | } | ||
735 | |||
736 | tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28) | ||
737 | | (mask_m[48] << 26) | (mask_m[49] << 24) | ||
738 | | (mask_m[50] << 22) | (mask_m[51] << 20) | ||
739 | | (mask_m[52] << 18) | (mask_m[53] << 16) | ||
740 | | (mask_m[54] << 14) | (mask_m[55] << 12) | ||
741 | | (mask_m[56] << 10) | (mask_m[57] << 8) | ||
742 | | (mask_m[58] << 6) | (mask_m[59] << 4) | ||
743 | | (mask_m[60] << 2) | (mask_m[61] << 0); | ||
744 | REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask); | ||
745 | REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask); | ||
746 | |||
747 | tmp_mask = (mask_m[31] << 28) | ||
748 | | (mask_m[32] << 26) | (mask_m[33] << 24) | ||
749 | | (mask_m[34] << 22) | (mask_m[35] << 20) | ||
750 | | (mask_m[36] << 18) | (mask_m[37] << 16) | ||
751 | | (mask_m[48] << 14) | (mask_m[39] << 12) | ||
752 | | (mask_m[40] << 10) | (mask_m[41] << 8) | ||
753 | | (mask_m[42] << 6) | (mask_m[43] << 4) | ||
754 | | (mask_m[44] << 2) | (mask_m[45] << 0); | ||
755 | REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask); | ||
756 | REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask); | ||
757 | |||
758 | tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28) | ||
759 | | (mask_m[18] << 26) | (mask_m[18] << 24) | ||
760 | | (mask_m[20] << 22) | (mask_m[20] << 20) | ||
761 | | (mask_m[22] << 18) | (mask_m[22] << 16) | ||
762 | | (mask_m[24] << 14) | (mask_m[24] << 12) | ||
763 | | (mask_m[25] << 10) | (mask_m[26] << 8) | ||
764 | | (mask_m[27] << 6) | (mask_m[28] << 4) | ||
765 | | (mask_m[29] << 2) | (mask_m[30] << 0); | ||
766 | REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask); | ||
767 | REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask); | ||
768 | |||
769 | tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28) | ||
770 | | (mask_m[2] << 26) | (mask_m[3] << 24) | ||
771 | | (mask_m[4] << 22) | (mask_m[5] << 20) | ||
772 | | (mask_m[6] << 18) | (mask_m[7] << 16) | ||
773 | | (mask_m[8] << 14) | (mask_m[9] << 12) | ||
774 | | (mask_m[10] << 10) | (mask_m[11] << 8) | ||
775 | | (mask_m[12] << 6) | (mask_m[13] << 4) | ||
776 | | (mask_m[14] << 2) | (mask_m[15] << 0); | ||
777 | REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask); | ||
778 | REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask); | ||
779 | |||
780 | tmp_mask = (mask_p[15] << 28) | ||
781 | | (mask_p[14] << 26) | (mask_p[13] << 24) | ||
782 | | (mask_p[12] << 22) | (mask_p[11] << 20) | ||
783 | | (mask_p[10] << 18) | (mask_p[9] << 16) | ||
784 | | (mask_p[8] << 14) | (mask_p[7] << 12) | ||
785 | | (mask_p[6] << 10) | (mask_p[5] << 8) | ||
786 | | (mask_p[4] << 6) | (mask_p[3] << 4) | ||
787 | | (mask_p[2] << 2) | (mask_p[1] << 0); | ||
788 | REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask); | ||
789 | REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask); | ||
790 | |||
791 | tmp_mask = (mask_p[30] << 28) | ||
792 | | (mask_p[29] << 26) | (mask_p[28] << 24) | ||
793 | | (mask_p[27] << 22) | (mask_p[26] << 20) | ||
794 | | (mask_p[25] << 18) | (mask_p[24] << 16) | ||
795 | | (mask_p[23] << 14) | (mask_p[22] << 12) | ||
796 | | (mask_p[21] << 10) | (mask_p[20] << 8) | ||
797 | | (mask_p[19] << 6) | (mask_p[18] << 4) | ||
798 | | (mask_p[17] << 2) | (mask_p[16] << 0); | ||
799 | REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask); | ||
800 | REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask); | ||
801 | |||
802 | tmp_mask = (mask_p[45] << 28) | ||
803 | | (mask_p[44] << 26) | (mask_p[43] << 24) | ||
804 | | (mask_p[42] << 22) | (mask_p[41] << 20) | ||
805 | | (mask_p[40] << 18) | (mask_p[39] << 16) | ||
806 | | (mask_p[38] << 14) | (mask_p[37] << 12) | ||
807 | | (mask_p[36] << 10) | (mask_p[35] << 8) | ||
808 | | (mask_p[34] << 6) | (mask_p[33] << 4) | ||
809 | | (mask_p[32] << 2) | (mask_p[31] << 0); | ||
810 | REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask); | ||
811 | REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask); | ||
812 | |||
813 | tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28) | ||
814 | | (mask_p[59] << 26) | (mask_p[58] << 24) | ||
815 | | (mask_p[57] << 22) | (mask_p[56] << 20) | ||
816 | | (mask_p[55] << 18) | (mask_p[54] << 16) | ||
817 | | (mask_p[53] << 14) | (mask_p[52] << 12) | ||
818 | | (mask_p[51] << 10) | (mask_p[50] << 8) | ||
819 | | (mask_p[49] << 6) | (mask_p[48] << 4) | ||
820 | | (mask_p[47] << 2) | (mask_p[46] << 0); | ||
821 | REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask); | ||
822 | REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask); | ||
823 | } | ||
824 | |||
825 | /** | ||
826 | * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming | ||
827 | * @ah: atheros hardware structure | ||
828 | * | ||
829 | * Only required for older devices with external AR2133/AR5133 radios. | ||
830 | */ | ||
831 | int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah) | ||
832 | { | ||
833 | #define ATH_ALLOC_BANK(bank, size) do { \ | ||
834 | bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \ | ||
835 | if (!bank) { \ | ||
836 | ath_print(common, ATH_DBG_FATAL, \ | ||
837 | "Cannot allocate RF banks\n"); \ | ||
838 | return -ENOMEM; \ | ||
839 | } \ | ||
840 | } while (0); | ||
841 | |||
842 | struct ath_common *common = ath9k_hw_common(ah); | ||
843 | |||
844 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
845 | |||
846 | ATH_ALLOC_BANK(ah->analogBank0Data, ah->iniBank0.ia_rows); | ||
847 | ATH_ALLOC_BANK(ah->analogBank1Data, ah->iniBank1.ia_rows); | ||
848 | ATH_ALLOC_BANK(ah->analogBank2Data, ah->iniBank2.ia_rows); | ||
849 | ATH_ALLOC_BANK(ah->analogBank3Data, ah->iniBank3.ia_rows); | ||
850 | ATH_ALLOC_BANK(ah->analogBank6Data, ah->iniBank6.ia_rows); | ||
851 | ATH_ALLOC_BANK(ah->analogBank6TPCData, ah->iniBank6TPC.ia_rows); | ||
852 | ATH_ALLOC_BANK(ah->analogBank7Data, ah->iniBank7.ia_rows); | ||
853 | ATH_ALLOC_BANK(ah->addac5416_21, | ||
854 | ah->iniAddac.ia_rows * ah->iniAddac.ia_columns); | ||
855 | ATH_ALLOC_BANK(ah->bank6Temp, ah->iniBank6.ia_rows); | ||
856 | |||
857 | return 0; | ||
858 | #undef ATH_ALLOC_BANK | ||
859 | } | ||
860 | |||
861 | |||
862 | /** | ||
863 | * ath9k_hw_rf_free_ext_banks - Free memory for analog bank scratch buffers | ||
864 | * @ah: atheros hardware struture | ||
865 | * For the external AR2133/AR5133 radios banks. | ||
866 | */ | ||
867 | void | ||
868 | ath9k_hw_rf_free_ext_banks(struct ath_hw *ah) | ||
869 | { | ||
870 | #define ATH_FREE_BANK(bank) do { \ | ||
871 | kfree(bank); \ | ||
872 | bank = NULL; \ | ||
873 | } while (0); | ||
874 | |||
875 | BUG_ON(AR_SREV_9280_10_OR_LATER(ah)); | ||
876 | |||
877 | ATH_FREE_BANK(ah->analogBank0Data); | ||
878 | ATH_FREE_BANK(ah->analogBank1Data); | ||
879 | ATH_FREE_BANK(ah->analogBank2Data); | ||
880 | ATH_FREE_BANK(ah->analogBank3Data); | ||
881 | ATH_FREE_BANK(ah->analogBank6Data); | ||
882 | ATH_FREE_BANK(ah->analogBank6TPCData); | ||
883 | ATH_FREE_BANK(ah->analogBank7Data); | ||
884 | ATH_FREE_BANK(ah->addac5416_21); | ||
885 | ATH_FREE_BANK(ah->bank6Temp); | ||
886 | |||
887 | #undef ATH_FREE_BANK | ||
888 | } | ||
889 | |||
890 | /* * | ||
891 | * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM | ||
892 | * @ah: atheros hardware structure | ||
893 | * @chan: | ||
894 | * @modesIndex: | ||
895 | * | ||
896 | * Used for the external AR2133/AR5133 radios. | ||
897 | * | ||
898 | * Reads the EEPROM header info from the device structure and programs | ||
899 | * all rf registers. This routine requires access to the analog | ||
900 | * rf device. This is not required for single-chip devices. | ||
901 | */ | ||
902 | bool ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan, | ||
903 | u16 modesIndex) | ||
904 | { | ||
905 | u32 eepMinorRev; | ||
906 | u32 ob5GHz = 0, db5GHz = 0; | ||
907 | u32 ob2GHz = 0, db2GHz = 0; | ||
908 | int regWrites = 0; | ||
909 | |||
910 | /* | ||
911 | * Software does not need to program bank data | ||
912 | * for single chip devices, that is AR9280 or anything | ||
913 | * after that. | ||
914 | */ | ||
915 | if (AR_SREV_9280_10_OR_LATER(ah)) | ||
916 | return true; | ||
917 | |||
918 | /* Setup rf parameters */ | ||
919 | eepMinorRev = ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV); | ||
920 | |||
921 | /* Setup Bank 0 Write */ | ||
922 | RF_BANK_SETUP(ah->analogBank0Data, &ah->iniBank0, 1); | ||
923 | |||
924 | /* Setup Bank 1 Write */ | ||
925 | RF_BANK_SETUP(ah->analogBank1Data, &ah->iniBank1, 1); | ||
926 | |||
927 | /* Setup Bank 2 Write */ | ||
928 | RF_BANK_SETUP(ah->analogBank2Data, &ah->iniBank2, 1); | ||
929 | |||
930 | /* Setup Bank 6 Write */ | ||
931 | RF_BANK_SETUP(ah->analogBank3Data, &ah->iniBank3, | ||
932 | modesIndex); | ||
933 | { | ||
934 | int i; | ||
935 | for (i = 0; i < ah->iniBank6TPC.ia_rows; i++) { | ||
936 | ah->analogBank6Data[i] = | ||
937 | INI_RA(&ah->iniBank6TPC, i, modesIndex); | ||
938 | } | ||
939 | } | ||
940 | |||
941 | /* Only the 5 or 2 GHz OB/DB need to be set for a mode */ | ||
942 | if (eepMinorRev >= 2) { | ||
943 | if (IS_CHAN_2GHZ(chan)) { | ||
944 | ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2); | ||
945 | db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2); | ||
946 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
947 | ob2GHz, 3, 197, 0); | ||
948 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
949 | db2GHz, 3, 194, 0); | ||
950 | } else { | ||
951 | ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5); | ||
952 | db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5); | ||
953 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
954 | ob5GHz, 3, 203, 0); | ||
955 | ath9k_phy_modify_rx_buffer(ah->analogBank6Data, | ||
956 | db5GHz, 3, 200, 0); | ||
957 | } | ||
958 | } | ||
959 | |||
960 | /* Setup Bank 7 Setup */ | ||
961 | RF_BANK_SETUP(ah->analogBank7Data, &ah->iniBank7, 1); | ||
962 | |||
963 | /* Write Analog registers */ | ||
964 | REG_WRITE_RF_ARRAY(&ah->iniBank0, ah->analogBank0Data, | ||
965 | regWrites); | ||
966 | REG_WRITE_RF_ARRAY(&ah->iniBank1, ah->analogBank1Data, | ||
967 | regWrites); | ||
968 | REG_WRITE_RF_ARRAY(&ah->iniBank2, ah->analogBank2Data, | ||
969 | regWrites); | ||
970 | REG_WRITE_RF_ARRAY(&ah->iniBank3, ah->analogBank3Data, | ||
971 | regWrites); | ||
972 | REG_WRITE_RF_ARRAY(&ah->iniBank6TPC, ah->analogBank6Data, | ||
973 | regWrites); | ||
974 | REG_WRITE_RF_ARRAY(&ah->iniBank7, ah->analogBank7Data, | ||
975 | regWrites); | ||
976 | |||
977 | return true; | ||
978 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h index 0999a495fd46..e724c2c1ae2a 100644 --- a/drivers/net/wireless/ath/ath9k/phy.h +++ b/drivers/net/wireless/ath/ath9k/phy.h | |||
@@ -17,589 +17,25 @@ | |||
17 | #ifndef PHY_H | 17 | #ifndef PHY_H |
18 | #define PHY_H | 18 | #define PHY_H |
19 | 19 | ||
20 | /* Common between single chip and non single-chip solutions */ | 20 | #define CHANSEL_DIV 15 |
21 | void ath9k_hw_write_regs(struct ath_hw *ah, u32 freqIndex, int regWrites); | 21 | #define CHANSEL_2G(_freq) (((_freq) * 0x10000) / CHANSEL_DIV) |
22 | 22 | #define CHANSEL_5G(_freq) (((_freq) * 0x8000) / CHANSEL_DIV) | |
23 | /* Single chip radio settings */ | ||
24 | int ath9k_hw_ar9280_set_channel(struct ath_hw *ah, struct ath9k_channel *chan); | ||
25 | void ath9k_hw_9280_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan); | ||
26 | |||
27 | /* Routines below are for non single-chip solutions */ | ||
28 | int ath9k_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan); | ||
29 | void ath9k_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan); | ||
30 | |||
31 | int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah); | ||
32 | void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah); | ||
33 | |||
34 | bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | ||
35 | struct ath9k_channel *chan, | ||
36 | u16 modesIndex); | ||
37 | 23 | ||
38 | #define AR_PHY_BASE 0x9800 | 24 | #define AR_PHY_BASE 0x9800 |
39 | #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) | 25 | #define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2)) |
40 | 26 | ||
41 | #define AR_PHY_TEST 0x9800 | 27 | #define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX 0x0007E000 |
42 | #define PHY_AGC_CLR 0x10000000 | 28 | #define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13 |
43 | #define RFSILENT_BB 0x00002000 | 29 | #define AR_PHY_TX_GAIN_CLC 0x0000001E |
44 | 30 | #define AR_PHY_TX_GAIN_CLC_S 1 | |
45 | #define AR_PHY_TURBO 0x9804 | 31 | #define AR_PHY_TX_GAIN 0x0007F000 |
46 | #define AR_PHY_FC_TURBO_MODE 0x00000001 | 32 | #define AR_PHY_TX_GAIN_S 12 |
47 | #define AR_PHY_FC_TURBO_SHORT 0x00000002 | ||
48 | #define AR_PHY_FC_DYN2040_EN 0x00000004 | ||
49 | #define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008 | ||
50 | #define AR_PHY_FC_DYN2040_PRI_CH 0x00000010 | ||
51 | /* For 25 MHz channel spacing -- not used but supported by hw */ | ||
52 | #define AR_PHY_FC_DYN2040_EXT_CH 0x00000020 | ||
53 | #define AR_PHY_FC_HT_EN 0x00000040 | ||
54 | #define AR_PHY_FC_SHORT_GI_40 0x00000080 | ||
55 | #define AR_PHY_FC_WALSH 0x00000100 | ||
56 | #define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200 | ||
57 | #define AR_PHY_FC_ENABLE_DAC_FIFO 0x00000800 | ||
58 | |||
59 | #define AR_PHY_TEST2 0x9808 | ||
60 | |||
61 | #define AR_PHY_TIMING2 0x9810 | ||
62 | #define AR_PHY_TIMING3 0x9814 | ||
63 | #define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000 | ||
64 | #define AR_PHY_TIMING3_DSC_MAN_S 17 | ||
65 | #define AR_PHY_TIMING3_DSC_EXP 0x0001E000 | ||
66 | #define AR_PHY_TIMING3_DSC_EXP_S 13 | ||
67 | |||
68 | #define AR_PHY_CHIP_ID 0x9818 | ||
69 | #define AR_PHY_CHIP_ID_REV_0 0x80 | ||
70 | #define AR_PHY_CHIP_ID_REV_1 0x81 | ||
71 | #define AR_PHY_CHIP_ID_9160_REV_0 0xb0 | ||
72 | |||
73 | #define AR_PHY_ACTIVE 0x981C | ||
74 | #define AR_PHY_ACTIVE_EN 0x00000001 | ||
75 | #define AR_PHY_ACTIVE_DIS 0x00000000 | ||
76 | |||
77 | #define AR_PHY_RF_CTL2 0x9824 | ||
78 | #define AR_PHY_TX_END_DATA_START 0x000000FF | ||
79 | #define AR_PHY_TX_END_DATA_START_S 0 | ||
80 | #define AR_PHY_TX_END_PA_ON 0x0000FF00 | ||
81 | #define AR_PHY_TX_END_PA_ON_S 8 | ||
82 | |||
83 | #define AR_PHY_RF_CTL3 0x9828 | ||
84 | #define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000 | ||
85 | #define AR_PHY_TX_END_TO_A2_RX_ON_S 16 | ||
86 | |||
87 | #define AR_PHY_ADC_CTL 0x982C | ||
88 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003 | ||
89 | #define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0 | ||
90 | #define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000 | ||
91 | #define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000 | ||
92 | #define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000 | ||
93 | #define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000 | ||
94 | #define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16 | ||
95 | |||
96 | #define AR_PHY_ADC_SERIAL_CTL 0x9830 | ||
97 | #define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000 | ||
98 | #define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001 | ||
99 | |||
100 | #define AR_PHY_RF_CTL4 0x9834 | ||
101 | #define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000 | ||
102 | #define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24 | ||
103 | #define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000 | ||
104 | #define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16 | ||
105 | #define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00 | ||
106 | #define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8 | ||
107 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF | ||
108 | #define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0 | ||
109 | |||
110 | #define AR_PHY_TSTDAC_CONST 0x983c | ||
111 | |||
112 | #define AR_PHY_SETTLING 0x9844 | ||
113 | #define AR_PHY_SETTLING_SWITCH 0x00003F80 | ||
114 | #define AR_PHY_SETTLING_SWITCH_S 7 | ||
115 | |||
116 | #define AR_PHY_RXGAIN 0x9848 | ||
117 | #define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000 | ||
118 | #define AR_PHY_RXGAIN_TXRX_ATTEN_S 12 | ||
119 | #define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000 | ||
120 | #define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18 | ||
121 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80 | ||
122 | #define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7 | ||
123 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000 | ||
124 | #define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14 | ||
125 | |||
126 | #define AR_PHY_DESIRED_SZ 0x9850 | ||
127 | #define AR_PHY_DESIRED_SZ_ADC 0x000000FF | ||
128 | #define AR_PHY_DESIRED_SZ_ADC_S 0 | ||
129 | #define AR_PHY_DESIRED_SZ_PGA 0x0000FF00 | ||
130 | #define AR_PHY_DESIRED_SZ_PGA_S 8 | ||
131 | #define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000 | ||
132 | #define AR_PHY_DESIRED_SZ_TOT_DES_S 20 | ||
133 | |||
134 | #define AR_PHY_FIND_SIG 0x9858 | ||
135 | #define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000 | ||
136 | #define AR_PHY_FIND_SIG_FIRSTEP_S 12 | ||
137 | #define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000 | ||
138 | #define AR_PHY_FIND_SIG_FIRPWR_S 18 | ||
139 | |||
140 | #define AR_PHY_AGC_CTL1 0x985C | ||
141 | #define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80 | ||
142 | #define AR_PHY_AGC_CTL1_COARSE_LOW_S 7 | ||
143 | #define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000 | ||
144 | #define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15 | ||
145 | |||
146 | #define AR_PHY_AGC_CONTROL 0x9860 | ||
147 | #define AR_PHY_AGC_CONTROL_CAL 0x00000001 | ||
148 | #define AR_PHY_AGC_CONTROL_NF 0x00000002 | ||
149 | #define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 | ||
150 | #define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 | ||
151 | #define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 | ||
152 | |||
153 | #define AR_PHY_CCA 0x9864 | ||
154 | #define AR_PHY_MINCCA_PWR 0x0FF80000 | ||
155 | #define AR_PHY_MINCCA_PWR_S 19 | ||
156 | #define AR_PHY_CCA_THRESH62 0x0007F000 | ||
157 | #define AR_PHY_CCA_THRESH62_S 12 | ||
158 | #define AR9280_PHY_MINCCA_PWR 0x1FF00000 | ||
159 | #define AR9280_PHY_MINCCA_PWR_S 20 | ||
160 | #define AR9280_PHY_CCA_THRESH62 0x000FF000 | ||
161 | #define AR9280_PHY_CCA_THRESH62_S 12 | ||
162 | |||
163 | #define AR_PHY_SFCORR_LOW 0x986C | ||
164 | #define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001 | ||
165 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00 | ||
166 | #define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8 | ||
167 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000 | ||
168 | #define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14 | ||
169 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000 | ||
170 | #define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21 | ||
171 | |||
172 | #define AR_PHY_SFCORR 0x9868 | ||
173 | #define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F | ||
174 | #define AR_PHY_SFCORR_M2COUNT_THR_S 0 | ||
175 | #define AR_PHY_SFCORR_M1_THRESH 0x00FE0000 | ||
176 | #define AR_PHY_SFCORR_M1_THRESH_S 17 | ||
177 | #define AR_PHY_SFCORR_M2_THRESH 0x7F000000 | ||
178 | #define AR_PHY_SFCORR_M2_THRESH_S 24 | ||
179 | |||
180 | #define AR_PHY_SLEEP_CTR_CONTROL 0x9870 | ||
181 | #define AR_PHY_SLEEP_CTR_LIMIT 0x9874 | ||
182 | #define AR_PHY_SYNTH_CONTROL 0x9874 | ||
183 | #define AR_PHY_SLEEP_SCAL 0x9878 | ||
184 | |||
185 | #define AR_PHY_PLL_CTL 0x987c | ||
186 | #define AR_PHY_PLL_CTL_40 0xaa | ||
187 | #define AR_PHY_PLL_CTL_40_5413 0x04 | ||
188 | #define AR_PHY_PLL_CTL_44 0xab | ||
189 | #define AR_PHY_PLL_CTL_44_2133 0xeb | ||
190 | #define AR_PHY_PLL_CTL_40_2133 0xea | ||
191 | |||
192 | #define AR_PHY_SPECTRAL_SCAN 0x9910 /* AR9280 spectral scan configuration register */ | ||
193 | #define AR_PHY_SPECTRAL_SCAN_ENABLE 0x1 | ||
194 | #define AR_PHY_SPECTRAL_SCAN_ENA 0x00000001 /* Enable spectral scan, reg 68, bit 0 */ | ||
195 | #define AR_PHY_SPECTRAL_SCAN_ENA_S 0 /* Enable spectral scan, reg 68, bit 0 */ | ||
196 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE 0x00000002 /* Activate spectral scan reg 68, bit 1*/ | ||
197 | #define AR_PHY_SPECTRAL_SCAN_ACTIVE_S 1 /* Activate spectral scan reg 68, bit 1*/ | ||
198 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD 0x000000F0 /* Interval for FFT reports, reg 68, bits 4-7*/ | ||
199 | #define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S 4 | ||
200 | #define AR_PHY_SPECTRAL_SCAN_PERIOD 0x0000FF00 /* Interval for FFT reports, reg 68, bits 8-15*/ | ||
201 | #define AR_PHY_SPECTRAL_SCAN_PERIOD_S 8 | ||
202 | #define AR_PHY_SPECTRAL_SCAN_COUNT 0x00FF0000 /* Number of reports, reg 68, bits 16-23*/ | ||
203 | #define AR_PHY_SPECTRAL_SCAN_COUNT_S 16 | ||
204 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT 0x01000000 /* Short repeat, reg 68, bit 24*/ | ||
205 | #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24 /* Short repeat, reg 68, bit 24*/ | ||
206 | |||
207 | #define AR_PHY_RX_DELAY 0x9914 | ||
208 | #define AR_PHY_SEARCH_START_DELAY 0x9918 | ||
209 | #define AR_PHY_RX_DELAY_DELAY 0x00003FFF | ||
210 | |||
211 | #define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12)) | ||
212 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F | ||
213 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0 | ||
214 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0 | ||
215 | #define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5 | ||
216 | #define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800 | ||
217 | #define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000 | ||
218 | #define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12 | ||
219 | #define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000 | ||
220 | |||
221 | #define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000 | ||
222 | #define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000 | ||
223 | #define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000 | ||
224 | #define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000 | ||
225 | |||
226 | #define AR_PHY_TIMING5 0x9924 | ||
227 | #define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE | ||
228 | #define AR_PHY_TIMING5_CYCPWR_THR1_S 1 | ||
229 | |||
230 | #define AR_PHY_POWER_TX_RATE1 0x9934 | ||
231 | #define AR_PHY_POWER_TX_RATE2 0x9938 | ||
232 | #define AR_PHY_POWER_TX_RATE_MAX 0x993c | ||
233 | #define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040 | ||
234 | |||
235 | #define AR_PHY_FRAME_CTL 0x9944 | ||
236 | #define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038 | ||
237 | #define AR_PHY_FRAME_CTL_TX_CLIP_S 3 | ||
238 | |||
239 | #define AR_PHY_TXPWRADJ 0x994C | ||
240 | #define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0 | ||
241 | #define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6 | ||
242 | #define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000 | ||
243 | #define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18 | ||
244 | |||
245 | #define AR_PHY_RADAR_EXT 0x9940 | ||
246 | #define AR_PHY_RADAR_EXT_ENA 0x00004000 | ||
247 | |||
248 | #define AR_PHY_RADAR_0 0x9954 | ||
249 | #define AR_PHY_RADAR_0_ENA 0x00000001 | ||
250 | #define AR_PHY_RADAR_0_FFT_ENA 0x80000000 | ||
251 | #define AR_PHY_RADAR_0_INBAND 0x0000003e | ||
252 | #define AR_PHY_RADAR_0_INBAND_S 1 | ||
253 | #define AR_PHY_RADAR_0_PRSSI 0x00000FC0 | ||
254 | #define AR_PHY_RADAR_0_PRSSI_S 6 | ||
255 | #define AR_PHY_RADAR_0_HEIGHT 0x0003F000 | ||
256 | #define AR_PHY_RADAR_0_HEIGHT_S 12 | ||
257 | #define AR_PHY_RADAR_0_RRSSI 0x00FC0000 | ||
258 | #define AR_PHY_RADAR_0_RRSSI_S 18 | ||
259 | #define AR_PHY_RADAR_0_FIRPWR 0x7F000000 | ||
260 | #define AR_PHY_RADAR_0_FIRPWR_S 24 | ||
261 | |||
262 | #define AR_PHY_RADAR_1 0x9958 | ||
263 | #define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000 | ||
264 | #define AR_PHY_RADAR_1_USE_FIR128 0x00400000 | ||
265 | #define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000 | ||
266 | #define AR_PHY_RADAR_1_RELPWR_THRESH_S 16 | ||
267 | #define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000 | ||
268 | #define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000 | ||
269 | #define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000 | ||
270 | #define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00 | ||
271 | #define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8 | ||
272 | #define AR_PHY_RADAR_1_MAXLEN 0x000000FF | ||
273 | #define AR_PHY_RADAR_1_MAXLEN_S 0 | ||
274 | |||
275 | #define AR_PHY_SWITCH_CHAIN_0 0x9960 | ||
276 | #define AR_PHY_SWITCH_COM 0x9964 | ||
277 | |||
278 | #define AR_PHY_SIGMA_DELTA 0x996C | ||
279 | #define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 | ||
280 | #define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0 | ||
281 | #define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8 | ||
282 | #define AR_PHY_SIGMA_DELTA_FILT2_S 3 | ||
283 | #define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00 | ||
284 | #define AR_PHY_SIGMA_DELTA_FILT1_S 8 | ||
285 | #define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000 | ||
286 | #define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13 | ||
287 | |||
288 | #define AR_PHY_RESTART 0x9970 | ||
289 | #define AR_PHY_RESTART_DIV_GC 0x001C0000 | ||
290 | #define AR_PHY_RESTART_DIV_GC_S 18 | ||
291 | |||
292 | #define AR_PHY_RFBUS_REQ 0x997C | ||
293 | #define AR_PHY_RFBUS_REQ_EN 0x00000001 | ||
294 | |||
295 | #define AR_PHY_TIMING7 0x9980 | ||
296 | #define AR_PHY_TIMING8 0x9984 | ||
297 | #define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF | ||
298 | #define AR_PHY_TIMING8_PILOT_MASK_2_S 0 | ||
299 | |||
300 | #define AR_PHY_BIN_MASK2_1 0x9988 | ||
301 | #define AR_PHY_BIN_MASK2_2 0x998c | ||
302 | #define AR_PHY_BIN_MASK2_3 0x9990 | ||
303 | #define AR_PHY_BIN_MASK2_4 0x9994 | ||
304 | |||
305 | #define AR_PHY_BIN_MASK_1 0x9900 | ||
306 | #define AR_PHY_BIN_MASK_2 0x9904 | ||
307 | #define AR_PHY_BIN_MASK_3 0x9908 | ||
308 | |||
309 | #define AR_PHY_MASK_CTL 0x990c | ||
310 | |||
311 | #define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF | ||
312 | #define AR_PHY_BIN_MASK2_4_MASK_4_S 0 | ||
313 | |||
314 | #define AR_PHY_TIMING9 0x9998 | ||
315 | #define AR_PHY_TIMING10 0x999c | ||
316 | #define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF | ||
317 | #define AR_PHY_TIMING10_PILOT_MASK_2_S 0 | ||
318 | |||
319 | #define AR_PHY_TIMING11 0x99a0 | ||
320 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF | ||
321 | #define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0 | ||
322 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 | ||
323 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 | ||
324 | #define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000 | ||
325 | #define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000 | ||
326 | |||
327 | #define AR_PHY_RX_CHAINMASK 0x99a4 | ||
328 | #define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12)) | ||
329 | #define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000 | ||
330 | #define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000 | ||
331 | |||
332 | #define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac | ||
333 | #define AR_PHY_9285_ANT_DIV_CTL_ALL 0x7f000000 | ||
334 | #define AR_PHY_9285_ANT_DIV_CTL 0x01000000 | ||
335 | #define AR_PHY_9285_ANT_DIV_CTL_S 24 | ||
336 | #define AR_PHY_9285_ANT_DIV_ALT_LNACONF 0x06000000 | ||
337 | #define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S 25 | ||
338 | #define AR_PHY_9285_ANT_DIV_MAIN_LNACONF 0x18000000 | ||
339 | #define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S 27 | ||
340 | #define AR_PHY_9285_ANT_DIV_ALT_GAINTB 0x20000000 | ||
341 | #define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S 29 | ||
342 | #define AR_PHY_9285_ANT_DIV_MAIN_GAINTB 0x40000000 | ||
343 | #define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S 30 | ||
344 | #define AR_PHY_9285_ANT_DIV_LNA1 2 | ||
345 | #define AR_PHY_9285_ANT_DIV_LNA2 1 | ||
346 | #define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2 3 | ||
347 | #define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0 | ||
348 | #define AR_PHY_9285_ANT_DIV_GAINTB_0 0 | ||
349 | #define AR_PHY_9285_ANT_DIV_GAINTB_1 1 | ||
350 | 33 | ||
351 | #define AR_PHY_EXT_CCA0 0x99b8 | 34 | #define AR_PHY_CLC_TBL1 0xa35c |
352 | #define AR_PHY_EXT_CCA0_THRESH62 0x000000FF | 35 | #define AR_PHY_CLC_I0 0x07ff0000 |
353 | #define AR_PHY_EXT_CCA0_THRESH62_S 0 | 36 | #define AR_PHY_CLC_I0_S 16 |
354 | 37 | #define AR_PHY_CLC_Q0 0x0000ffd0 | |
355 | #define AR_PHY_EXT_CCA 0x99bc | 38 | #define AR_PHY_CLC_Q0_S 5 |
356 | #define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00 | ||
357 | #define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9 | ||
358 | #define AR_PHY_EXT_CCA_THRESH62 0x007F0000 | ||
359 | #define AR_PHY_EXT_CCA_THRESH62_S 16 | ||
360 | #define AR_PHY_EXT_MINCCA_PWR 0xFF800000 | ||
361 | #define AR_PHY_EXT_MINCCA_PWR_S 23 | ||
362 | #define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000 | ||
363 | #define AR9280_PHY_EXT_MINCCA_PWR_S 16 | ||
364 | |||
365 | #define AR_PHY_SFCORR_EXT 0x99c0 | ||
366 | #define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F | ||
367 | #define AR_PHY_SFCORR_EXT_M1_THRESH_S 0 | ||
368 | #define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80 | ||
369 | #define AR_PHY_SFCORR_EXT_M2_THRESH_S 7 | ||
370 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000 | ||
371 | #define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14 | ||
372 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000 | ||
373 | #define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21 | ||
374 | #define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28 | ||
375 | |||
376 | #define AR_PHY_HALFGI 0x99D0 | ||
377 | #define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0 | ||
378 | #define AR_PHY_HALFGI_DSC_MAN_S 4 | ||
379 | #define AR_PHY_HALFGI_DSC_EXP 0x0000000F | ||
380 | #define AR_PHY_HALFGI_DSC_EXP_S 0 | ||
381 | |||
382 | #define AR_PHY_CHAN_INFO_MEMORY 0x99DC | ||
383 | #define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001 | ||
384 | |||
385 | #define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0 | ||
386 | |||
387 | #define AR_PHY_HEAVY_CLIP_FACTOR_RIFS 0x99EC | ||
388 | #define AR_PHY_RIFS_INIT_DELAY 0x03ff0000 | ||
389 | |||
390 | #define AR_PHY_M_SLEEP 0x99f0 | ||
391 | #define AR_PHY_REFCLKDLY 0x99f4 | ||
392 | #define AR_PHY_REFCLKPD 0x99f8 | ||
393 | |||
394 | #define AR_PHY_CALMODE 0x99f0 | ||
395 | |||
396 | #define AR_PHY_CALMODE_IQ 0x00000000 | ||
397 | #define AR_PHY_CALMODE_ADC_GAIN 0x00000001 | ||
398 | #define AR_PHY_CALMODE_ADC_DC_PER 0x00000002 | ||
399 | #define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003 | ||
400 | |||
401 | #define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12)) | ||
402 | #define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12)) | ||
403 | #define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12)) | ||
404 | #define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12)) | ||
405 | |||
406 | #define AR_PHY_CURRENT_RSSI 0x9c1c | ||
407 | #define AR9280_PHY_CURRENT_RSSI 0x9c3c | ||
408 | |||
409 | #define AR_PHY_RFBUS_GRANT 0x9C20 | ||
410 | #define AR_PHY_RFBUS_GRANT_EN 0x00000001 | ||
411 | |||
412 | #define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4 | ||
413 | #define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320 | ||
414 | |||
415 | #define AR_PHY_CHAN_INFO_GAIN 0x9CFC | ||
416 | |||
417 | #define AR_PHY_MODE 0xA200 | ||
418 | #define AR_PHY_MODE_ASYNCFIFO 0x80 | ||
419 | #define AR_PHY_MODE_AR2133 0x08 | ||
420 | #define AR_PHY_MODE_AR5111 0x00 | ||
421 | #define AR_PHY_MODE_AR5112 0x08 | ||
422 | #define AR_PHY_MODE_DYNAMIC 0x04 | ||
423 | #define AR_PHY_MODE_RF2GHZ 0x02 | ||
424 | #define AR_PHY_MODE_RF5GHZ 0x00 | ||
425 | #define AR_PHY_MODE_CCK 0x01 | ||
426 | #define AR_PHY_MODE_OFDM 0x00 | ||
427 | #define AR_PHY_MODE_DYN_CCK_DISABLE 0x100 | ||
428 | |||
429 | #define AR_PHY_CCK_TX_CTRL 0xA204 | ||
430 | #define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010 | ||
431 | #define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK 0x0000000C | ||
432 | #define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S 2 | ||
433 | |||
434 | #define AR_PHY_CCK_DETECT 0xA208 | ||
435 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F | ||
436 | #define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0 | ||
437 | /* [12:6] settling time for antenna switch */ | ||
438 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0 | ||
439 | #define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6 | ||
440 | #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000 | ||
441 | #define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S 13 | ||
442 | |||
443 | #define AR_PHY_GAIN_2GHZ 0xA20C | ||
444 | #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000 | ||
445 | #define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18 | ||
446 | #define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00 | ||
447 | #define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10 | ||
448 | #define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F | ||
449 | #define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0 | ||
450 | |||
451 | #define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000 | ||
452 | #define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17 | ||
453 | #define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000 | ||
454 | #define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12 | ||
455 | #define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0 | ||
456 | #define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6 | ||
457 | #define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F | ||
458 | #define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0 | ||
459 | |||
460 | #define AR_PHY_CCK_RXCTRL4 0xA21C | ||
461 | #define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000 | ||
462 | #define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19 | ||
463 | |||
464 | #define AR_PHY_DAG_CTRLCCK 0xA228 | ||
465 | #define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200 | ||
466 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00 | ||
467 | #define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10 | ||
468 | |||
469 | #define AR_PHY_FORCE_CLKEN_CCK 0xA22C | ||
470 | #define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040 | ||
471 | |||
472 | #define AR_PHY_POWER_TX_RATE3 0xA234 | ||
473 | #define AR_PHY_POWER_TX_RATE4 0xA238 | ||
474 | |||
475 | #define AR_PHY_SCRM_SEQ_XR 0xA23C | ||
476 | #define AR_PHY_HEADER_DETECT_XR 0xA240 | ||
477 | #define AR_PHY_CHIRP_DETECTED_XR 0xA244 | ||
478 | #define AR_PHY_BLUETOOTH 0xA254 | ||
479 | |||
480 | #define AR_PHY_TPCRG1 0xA258 | ||
481 | #define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000 | ||
482 | #define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14 | ||
483 | |||
484 | #define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000 | ||
485 | #define AR_PHY_TPCRG1_PD_GAIN_1_S 16 | ||
486 | #define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000 | ||
487 | #define AR_PHY_TPCRG1_PD_GAIN_2_S 18 | ||
488 | #define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000 | ||
489 | #define AR_PHY_TPCRG1_PD_GAIN_3_S 20 | ||
490 | |||
491 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE 0x00400000 | ||
492 | #define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22 | ||
493 | |||
494 | #define AR_PHY_TX_PWRCTRL4 0xa264 | ||
495 | #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID 0x00000001 | ||
496 | #define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S 0 | ||
497 | #define AR_PHY_TX_PWRCTRL_PD_AVG_OUT 0x000001FE | ||
498 | #define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S 1 | ||
499 | |||
500 | #define AR_PHY_TX_PWRCTRL6_0 0xa270 | ||
501 | #define AR_PHY_TX_PWRCTRL6_1 0xb270 | ||
502 | #define AR_PHY_TX_PWRCTRL_ERR_EST_MODE 0x03000000 | ||
503 | #define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S 24 | ||
504 | |||
505 | #define AR_PHY_TX_PWRCTRL7 0xa274 | ||
506 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN 0x01F80000 | ||
507 | #define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S 19 | ||
508 | |||
509 | #define AR_PHY_TX_PWRCTRL9 0xa27C | ||
510 | #define AR_PHY_TX_DESIRED_SCALE_CCK 0x00007C00 | ||
511 | #define AR_PHY_TX_DESIRED_SCALE_CCK_S 10 | ||
512 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL 0x80000000 | ||
513 | #define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31 | ||
514 | |||
515 | #define AR_PHY_TX_GAIN_TBL1 0xa300 | ||
516 | #define AR_PHY_TX_GAIN 0x0007F000 | ||
517 | #define AR_PHY_TX_GAIN_S 12 | ||
518 | |||
519 | #define AR_PHY_CH0_TX_PWRCTRL11 0xa398 | ||
520 | #define AR_PHY_CH1_TX_PWRCTRL11 0xb398 | ||
521 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP 0x0000FC00 | ||
522 | #define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10 | ||
523 | |||
524 | #define AR_PHY_VIT_MASK2_M_46_61 0xa3a0 | ||
525 | #define AR_PHY_MASK2_M_31_45 0xa3a4 | ||
526 | #define AR_PHY_MASK2_M_16_30 0xa3a8 | ||
527 | #define AR_PHY_MASK2_M_00_15 0xa3ac | ||
528 | #define AR_PHY_MASK2_P_15_01 0xa3b8 | ||
529 | #define AR_PHY_MASK2_P_30_16 0xa3bc | ||
530 | #define AR_PHY_MASK2_P_45_31 0xa3c0 | ||
531 | #define AR_PHY_MASK2_P_61_45 0xa3c4 | ||
532 | #define AR_PHY_SPUR_REG 0x994c | ||
533 | |||
534 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18) | ||
535 | #define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18 | ||
536 | |||
537 | #define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000 | ||
538 | #define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9) | ||
539 | #define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9 | ||
540 | #define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100 | ||
541 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F | ||
542 | #define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0 | ||
543 | |||
544 | #define AR_PHY_PILOT_MASK_01_30 0xa3b0 | ||
545 | #define AR_PHY_PILOT_MASK_31_60 0xa3b4 | ||
546 | |||
547 | #define AR_PHY_CHANNEL_MASK_01_30 0x99d4 | ||
548 | #define AR_PHY_CHANNEL_MASK_31_60 0x99d8 | ||
549 | |||
550 | #define AR_PHY_ANALOG_SWAP 0xa268 | ||
551 | #define AR_PHY_SWAP_ALT_CHAIN 0x00000040 | ||
552 | |||
553 | #define AR_PHY_TPCRG5 0xA26C | ||
554 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F | ||
555 | #define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0 | ||
556 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0 | ||
557 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4 | ||
558 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00 | ||
559 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10 | ||
560 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000 | ||
561 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16 | ||
562 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000 | ||
563 | #define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22 | ||
564 | |||
565 | /* Carrier leak calibration control, do it after AGC calibration */ | ||
566 | #define AR_PHY_CL_CAL_CTL 0xA358 | ||
567 | #define AR_PHY_CL_CAL_ENABLE 0x00000002 | ||
568 | #define AR_PHY_PARALLEL_CAL_ENABLE 0x00000001 | ||
569 | |||
570 | #define AR_PHY_POWER_TX_RATE5 0xA38C | ||
571 | #define AR_PHY_POWER_TX_RATE6 0xA390 | ||
572 | |||
573 | #define AR_PHY_CAL_CHAINMASK 0xA39C | ||
574 | |||
575 | #define AR_PHY_POWER_TX_SUB 0xA3C8 | ||
576 | #define AR_PHY_POWER_TX_RATE7 0xA3CC | ||
577 | #define AR_PHY_POWER_TX_RATE8 0xA3D0 | ||
578 | #define AR_PHY_POWER_TX_RATE9 0xA3D4 | ||
579 | |||
580 | #define AR_PHY_XPA_CFG 0xA3D8 | ||
581 | #define AR_PHY_FORCE_XPA_CFG 0x000000001 | ||
582 | #define AR_PHY_FORCE_XPA_CFG_S 0 | ||
583 | |||
584 | #define AR_PHY_CH1_CCA 0xa864 | ||
585 | #define AR_PHY_CH1_MINCCA_PWR 0x0FF80000 | ||
586 | #define AR_PHY_CH1_MINCCA_PWR_S 19 | ||
587 | #define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000 | ||
588 | #define AR9280_PHY_CH1_MINCCA_PWR_S 20 | ||
589 | |||
590 | #define AR_PHY_CH2_CCA 0xb864 | ||
591 | #define AR_PHY_CH2_MINCCA_PWR 0x0FF80000 | ||
592 | #define AR_PHY_CH2_MINCCA_PWR_S 19 | ||
593 | |||
594 | #define AR_PHY_CH1_EXT_CCA 0xa9bc | ||
595 | #define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000 | ||
596 | #define AR_PHY_CH1_EXT_MINCCA_PWR_S 23 | ||
597 | #define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000 | ||
598 | #define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16 | ||
599 | |||
600 | #define AR_PHY_CH2_EXT_CCA 0xb9bc | ||
601 | #define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000 | ||
602 | #define AR_PHY_CH2_EXT_MINCCA_PWR_S 23 | ||
603 | 39 | ||
604 | #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \ | 40 | #define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \ |
605 | int r; \ | 41 | int r; \ |
@@ -615,6 +51,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | |||
615 | #define ANTSWAP_AB 0x0001 | 51 | #define ANTSWAP_AB 0x0001 |
616 | #define REDUCE_CHAIN_0 0x00000050 | 52 | #define REDUCE_CHAIN_0 0x00000050 |
617 | #define REDUCE_CHAIN_1 0x00000051 | 53 | #define REDUCE_CHAIN_1 0x00000051 |
54 | #define AR_PHY_CHIP_ID 0x9818 | ||
618 | 55 | ||
619 | #define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ | 56 | #define RF_BANK_SETUP(_bank, _iniarray, _col) do { \ |
620 | int i; \ | 57 | int i; \ |
@@ -622,4 +59,7 @@ bool ath9k_hw_set_rf_regs(struct ath_hw *ah, | |||
622 | (_bank)[i] = INI_RA((_iniarray), i, _col);; \ | 59 | (_bank)[i] = INI_RA((_iniarray), i, _col);; \ |
623 | } while (0) | 60 | } while (0) |
624 | 61 | ||
62 | #define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000 | ||
63 | #define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20 | ||
64 | |||
625 | #endif | 65 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 244e1c629177..8519452c95f1 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c | |||
@@ -691,6 +691,19 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
691 | rate_table = sc->cur_rate_table; | 691 | rate_table = sc->cur_rate_table; |
692 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); | 692 | rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe); |
693 | 693 | ||
694 | /* | ||
695 | * If we're in HT mode and both us and our peer supports LDPC. | ||
696 | * We don't need to check our own device's capabilities as our own | ||
697 | * ht capabilities would have already been intersected with our peer's. | ||
698 | */ | ||
699 | if (conf_is_ht(&sc->hw->conf) && | ||
700 | (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING)) | ||
701 | tx_info->flags |= IEEE80211_TX_CTL_LDPC; | ||
702 | |||
703 | if (conf_is_ht(&sc->hw->conf) && | ||
704 | (sta->ht_cap.cap & IEEE80211_HT_CAP_TX_STBC)) | ||
705 | tx_info->flags |= (1 << IEEE80211_TX_CTL_STBC_SHIFT); | ||
706 | |||
694 | if (is_probe) { | 707 | if (is_probe) { |
695 | /* set one try for probe rates. For the | 708 | /* set one try for probe rates. For the |
696 | * probes don't enable rts */ | 709 | * probes don't enable rts */ |
@@ -1228,8 +1241,12 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband, | |||
1228 | long_retry = rate->count - 1; | 1241 | long_retry = rate->count - 1; |
1229 | } | 1242 | } |
1230 | 1243 | ||
1231 | if (!priv_sta || !ieee80211_is_data(fc) || | 1244 | if (!priv_sta || !ieee80211_is_data(fc)) |
1232 | !(tx_info->pad[0] & ATH_TX_INFO_UPDATE_RC)) | 1245 | return; |
1246 | |||
1247 | /* This packet was aggregated but doesn't carry status info */ | ||
1248 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && | ||
1249 | !(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) | ||
1233 | return; | 1250 | return; |
1234 | 1251 | ||
1235 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) | 1252 | if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) |
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h index 4f6d6fd442f4..3d8d40cdc99e 100644 --- a/drivers/net/wireless/ath/ath9k/rc.h +++ b/drivers/net/wireless/ath/ath9k/rc.h | |||
@@ -110,8 +110,8 @@ struct ath_rate_table { | |||
110 | int rate_cnt; | 110 | int rate_cnt; |
111 | int mcs_start; | 111 | int mcs_start; |
112 | struct { | 112 | struct { |
113 | int valid; | 113 | u8 valid; |
114 | int valid_single_stream; | 114 | u8 valid_single_stream; |
115 | u8 phy; | 115 | u8 phy; |
116 | u32 ratekbps; | 116 | u32 ratekbps; |
117 | u32 user_ratekbps; | 117 | u32 user_ratekbps; |
@@ -172,14 +172,13 @@ struct ath_rate_priv { | |||
172 | 172 | ||
173 | #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) | 173 | #define ATH_TX_INFO_FRAME_TYPE_INTERNAL (1 << 0) |
174 | #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) | 174 | #define ATH_TX_INFO_FRAME_TYPE_PAUSE (1 << 1) |
175 | #define ATH_TX_INFO_UPDATE_RC (1 << 2) | ||
176 | #define ATH_TX_INFO_XRETRY (1 << 3) | 175 | #define ATH_TX_INFO_XRETRY (1 << 3) |
177 | #define ATH_TX_INFO_UNDERRUN (1 << 4) | 176 | #define ATH_TX_INFO_UNDERRUN (1 << 4) |
178 | 177 | ||
179 | enum ath9k_internal_frame_type { | 178 | enum ath9k_internal_frame_type { |
180 | ATH9K_NOT_INTERNAL, | 179 | ATH9K_IFT_NOT_INTERNAL, |
181 | ATH9K_INT_PAUSE, | 180 | ATH9K_IFT_PAUSE, |
182 | ATH9K_INT_UNPAUSE | 181 | ATH9K_IFT_UNPAUSE |
183 | }; | 182 | }; |
184 | 183 | ||
185 | int ath_rate_control_register(void); | 184 | int ath_rate_control_register(void); |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1ca42e5148c8..ba139132c85f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -15,6 +15,9 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "ath9k.h" | 17 | #include "ath9k.h" |
18 | #include "ar9003_mac.h" | ||
19 | |||
20 | #define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb)) | ||
18 | 21 | ||
19 | static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, | 22 | static struct ieee80211_hw * ath_get_virt_hw(struct ath_softc *sc, |
20 | struct ieee80211_hdr *hdr) | 23 | struct ieee80211_hdr *hdr) |
@@ -115,56 +118,244 @@ static void ath_opmode_init(struct ath_softc *sc) | |||
115 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); | 118 | ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]); |
116 | } | 119 | } |
117 | 120 | ||
118 | int ath_rx_init(struct ath_softc *sc, int nbufs) | 121 | static bool ath_rx_edma_buf_link(struct ath_softc *sc, |
122 | enum ath9k_rx_qtype qtype) | ||
119 | { | 123 | { |
120 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 124 | struct ath_hw *ah = sc->sc_ah; |
125 | struct ath_rx_edma *rx_edma; | ||
121 | struct sk_buff *skb; | 126 | struct sk_buff *skb; |
122 | struct ath_buf *bf; | 127 | struct ath_buf *bf; |
123 | int error = 0; | ||
124 | 128 | ||
125 | spin_lock_init(&sc->rx.rxflushlock); | 129 | rx_edma = &sc->rx.rx_edma[qtype]; |
126 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 130 | if (skb_queue_len(&rx_edma->rx_fifo) >= rx_edma->rx_fifo_hwsize) |
127 | spin_lock_init(&sc->rx.rxbuflock); | 131 | return false; |
128 | 132 | ||
129 | common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN, | 133 | bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); |
130 | min(common->cachelsz, (u16)64)); | 134 | list_del_init(&bf->list); |
131 | 135 | ||
132 | ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", | 136 | skb = bf->bf_mpdu; |
133 | common->cachelsz, common->rx_bufsize); | 137 | |
138 | ATH_RXBUF_RESET(bf); | ||
139 | memset(skb->data, 0, ah->caps.rx_status_len); | ||
140 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | ||
141 | ah->caps.rx_status_len, DMA_TO_DEVICE); | ||
134 | 142 | ||
135 | /* Initialize rx descriptors */ | 143 | SKB_CB_ATHBUF(skb) = bf; |
144 | ath9k_hw_addrxbuf_edma(ah, bf->bf_buf_addr, qtype); | ||
145 | skb_queue_tail(&rx_edma->rx_fifo, skb); | ||
136 | 146 | ||
137 | error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, | 147 | return true; |
138 | "rx", nbufs, 1); | 148 | } |
139 | if (error != 0) { | 149 | |
140 | ath_print(common, ATH_DBG_FATAL, | 150 | static void ath_rx_addbuffer_edma(struct ath_softc *sc, |
141 | "failed to allocate rx descriptors: %d\n", error); | 151 | enum ath9k_rx_qtype qtype, int size) |
142 | goto err; | 152 | { |
153 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
154 | u32 nbuf = 0; | ||
155 | |||
156 | if (list_empty(&sc->rx.rxbuf)) { | ||
157 | ath_print(common, ATH_DBG_QUEUE, "No free rx buf available\n"); | ||
158 | return; | ||
143 | } | 159 | } |
144 | 160 | ||
161 | while (!list_empty(&sc->rx.rxbuf)) { | ||
162 | nbuf++; | ||
163 | |||
164 | if (!ath_rx_edma_buf_link(sc, qtype)) | ||
165 | break; | ||
166 | |||
167 | if (nbuf >= size) | ||
168 | break; | ||
169 | } | ||
170 | } | ||
171 | |||
172 | static void ath_rx_remove_buffer(struct ath_softc *sc, | ||
173 | enum ath9k_rx_qtype qtype) | ||
174 | { | ||
175 | struct ath_buf *bf; | ||
176 | struct ath_rx_edma *rx_edma; | ||
177 | struct sk_buff *skb; | ||
178 | |||
179 | rx_edma = &sc->rx.rx_edma[qtype]; | ||
180 | |||
181 | while ((skb = skb_dequeue(&rx_edma->rx_fifo)) != NULL) { | ||
182 | bf = SKB_CB_ATHBUF(skb); | ||
183 | BUG_ON(!bf); | ||
184 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | static void ath_rx_edma_cleanup(struct ath_softc *sc) | ||
189 | { | ||
190 | struct ath_buf *bf; | ||
191 | |||
192 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); | ||
193 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); | ||
194 | |||
145 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | 195 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { |
196 | if (bf->bf_mpdu) | ||
197 | dev_kfree_skb_any(bf->bf_mpdu); | ||
198 | } | ||
199 | |||
200 | INIT_LIST_HEAD(&sc->rx.rxbuf); | ||
201 | |||
202 | kfree(sc->rx.rx_bufptr); | ||
203 | sc->rx.rx_bufptr = NULL; | ||
204 | } | ||
205 | |||
206 | static void ath_rx_edma_init_queue(struct ath_rx_edma *rx_edma, int size) | ||
207 | { | ||
208 | skb_queue_head_init(&rx_edma->rx_fifo); | ||
209 | skb_queue_head_init(&rx_edma->rx_buffers); | ||
210 | rx_edma->rx_fifo_hwsize = size; | ||
211 | } | ||
212 | |||
213 | static int ath_rx_edma_init(struct ath_softc *sc, int nbufs) | ||
214 | { | ||
215 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
216 | struct ath_hw *ah = sc->sc_ah; | ||
217 | struct sk_buff *skb; | ||
218 | struct ath_buf *bf; | ||
219 | int error = 0, i; | ||
220 | u32 size; | ||
221 | |||
222 | |||
223 | common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN + | ||
224 | ah->caps.rx_status_len, | ||
225 | min(common->cachelsz, (u16)64)); | ||
226 | |||
227 | ath9k_hw_set_rx_bufsize(ah, common->rx_bufsize - | ||
228 | ah->caps.rx_status_len); | ||
229 | |||
230 | ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_LP], | ||
231 | ah->caps.rx_lp_qdepth); | ||
232 | ath_rx_edma_init_queue(&sc->rx.rx_edma[ATH9K_RX_QUEUE_HP], | ||
233 | ah->caps.rx_hp_qdepth); | ||
234 | |||
235 | size = sizeof(struct ath_buf) * nbufs; | ||
236 | bf = kzalloc(size, GFP_KERNEL); | ||
237 | if (!bf) | ||
238 | return -ENOMEM; | ||
239 | |||
240 | INIT_LIST_HEAD(&sc->rx.rxbuf); | ||
241 | sc->rx.rx_bufptr = bf; | ||
242 | |||
243 | for (i = 0; i < nbufs; i++, bf++) { | ||
146 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL); | 244 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_KERNEL); |
147 | if (skb == NULL) { | 245 | if (!skb) { |
148 | error = -ENOMEM; | 246 | error = -ENOMEM; |
149 | goto err; | 247 | goto rx_init_fail; |
150 | } | 248 | } |
151 | 249 | ||
250 | memset(skb->data, 0, common->rx_bufsize); | ||
152 | bf->bf_mpdu = skb; | 251 | bf->bf_mpdu = skb; |
252 | |||
153 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | 253 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, |
154 | common->rx_bufsize, | 254 | common->rx_bufsize, |
155 | DMA_FROM_DEVICE); | 255 | DMA_BIDIRECTIONAL); |
156 | if (unlikely(dma_mapping_error(sc->dev, | 256 | if (unlikely(dma_mapping_error(sc->dev, |
157 | bf->bf_buf_addr))) { | 257 | bf->bf_buf_addr))) { |
158 | dev_kfree_skb_any(skb); | 258 | dev_kfree_skb_any(skb); |
159 | bf->bf_mpdu = NULL; | 259 | bf->bf_mpdu = NULL; |
260 | ath_print(common, ATH_DBG_FATAL, | ||
261 | "dma_mapping_error() on RX init\n"); | ||
262 | error = -ENOMEM; | ||
263 | goto rx_init_fail; | ||
264 | } | ||
265 | |||
266 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
267 | } | ||
268 | |||
269 | return 0; | ||
270 | |||
271 | rx_init_fail: | ||
272 | ath_rx_edma_cleanup(sc); | ||
273 | return error; | ||
274 | } | ||
275 | |||
276 | static void ath_edma_start_recv(struct ath_softc *sc) | ||
277 | { | ||
278 | spin_lock_bh(&sc->rx.rxbuflock); | ||
279 | |||
280 | ath9k_hw_rxena(sc->sc_ah); | ||
281 | |||
282 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_HP, | ||
283 | sc->rx.rx_edma[ATH9K_RX_QUEUE_HP].rx_fifo_hwsize); | ||
284 | |||
285 | ath_rx_addbuffer_edma(sc, ATH9K_RX_QUEUE_LP, | ||
286 | sc->rx.rx_edma[ATH9K_RX_QUEUE_LP].rx_fifo_hwsize); | ||
287 | |||
288 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
289 | |||
290 | ath_opmode_init(sc); | ||
291 | |||
292 | ath9k_hw_startpcureceive(sc->sc_ah); | ||
293 | } | ||
294 | |||
295 | static void ath_edma_stop_recv(struct ath_softc *sc) | ||
296 | { | ||
297 | spin_lock_bh(&sc->rx.rxbuflock); | ||
298 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_HP); | ||
299 | ath_rx_remove_buffer(sc, ATH9K_RX_QUEUE_LP); | ||
300 | spin_unlock_bh(&sc->rx.rxbuflock); | ||
301 | } | ||
302 | |||
303 | int ath_rx_init(struct ath_softc *sc, int nbufs) | ||
304 | { | ||
305 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
306 | struct sk_buff *skb; | ||
307 | struct ath_buf *bf; | ||
308 | int error = 0; | ||
309 | |||
310 | spin_lock_init(&sc->rx.rxflushlock); | ||
311 | sc->sc_flags &= ~SC_OP_RXFLUSH; | ||
312 | spin_lock_init(&sc->rx.rxbuflock); | ||
313 | |||
314 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
315 | return ath_rx_edma_init(sc, nbufs); | ||
316 | } else { | ||
317 | common->rx_bufsize = roundup(IEEE80211_MAX_MPDU_LEN, | ||
318 | min(common->cachelsz, (u16)64)); | ||
319 | |||
320 | ath_print(common, ATH_DBG_CONFIG, "cachelsz %u rxbufsize %u\n", | ||
321 | common->cachelsz, common->rx_bufsize); | ||
322 | |||
323 | /* Initialize rx descriptors */ | ||
324 | |||
325 | error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf, | ||
326 | "rx", nbufs, 1, 0); | ||
327 | if (error != 0) { | ||
160 | ath_print(common, ATH_DBG_FATAL, | 328 | ath_print(common, ATH_DBG_FATAL, |
161 | "dma_mapping_error() on RX init\n"); | 329 | "failed to allocate rx descriptors: %d\n", |
162 | error = -ENOMEM; | 330 | error); |
163 | goto err; | 331 | goto err; |
164 | } | 332 | } |
165 | bf->bf_dmacontext = bf->bf_buf_addr; | 333 | |
334 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | ||
335 | skb = ath_rxbuf_alloc(common, common->rx_bufsize, | ||
336 | GFP_KERNEL); | ||
337 | if (skb == NULL) { | ||
338 | error = -ENOMEM; | ||
339 | goto err; | ||
340 | } | ||
341 | |||
342 | bf->bf_mpdu = skb; | ||
343 | bf->bf_buf_addr = dma_map_single(sc->dev, skb->data, | ||
344 | common->rx_bufsize, | ||
345 | DMA_FROM_DEVICE); | ||
346 | if (unlikely(dma_mapping_error(sc->dev, | ||
347 | bf->bf_buf_addr))) { | ||
348 | dev_kfree_skb_any(skb); | ||
349 | bf->bf_mpdu = NULL; | ||
350 | ath_print(common, ATH_DBG_FATAL, | ||
351 | "dma_mapping_error() on RX init\n"); | ||
352 | error = -ENOMEM; | ||
353 | goto err; | ||
354 | } | ||
355 | bf->bf_dmacontext = bf->bf_buf_addr; | ||
356 | } | ||
357 | sc->rx.rxlink = NULL; | ||
166 | } | 358 | } |
167 | sc->rx.rxlink = NULL; | ||
168 | 359 | ||
169 | err: | 360 | err: |
170 | if (error) | 361 | if (error) |
@@ -180,17 +371,23 @@ void ath_rx_cleanup(struct ath_softc *sc) | |||
180 | struct sk_buff *skb; | 371 | struct sk_buff *skb; |
181 | struct ath_buf *bf; | 372 | struct ath_buf *bf; |
182 | 373 | ||
183 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { | 374 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
184 | skb = bf->bf_mpdu; | 375 | ath_rx_edma_cleanup(sc); |
185 | if (skb) { | 376 | return; |
186 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 377 | } else { |
187 | common->rx_bufsize, DMA_FROM_DEVICE); | 378 | list_for_each_entry(bf, &sc->rx.rxbuf, list) { |
188 | dev_kfree_skb(skb); | 379 | skb = bf->bf_mpdu; |
380 | if (skb) { | ||
381 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | ||
382 | common->rx_bufsize, | ||
383 | DMA_FROM_DEVICE); | ||
384 | dev_kfree_skb(skb); | ||
385 | } | ||
189 | } | 386 | } |
190 | } | ||
191 | 387 | ||
192 | if (sc->rx.rxdma.dd_desc_len != 0) | 388 | if (sc->rx.rxdma.dd_desc_len != 0) |
193 | ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf); | 389 | ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf); |
390 | } | ||
194 | } | 391 | } |
195 | 392 | ||
196 | /* | 393 | /* |
@@ -273,6 +470,11 @@ int ath_startrecv(struct ath_softc *sc) | |||
273 | struct ath_hw *ah = sc->sc_ah; | 470 | struct ath_hw *ah = sc->sc_ah; |
274 | struct ath_buf *bf, *tbf; | 471 | struct ath_buf *bf, *tbf; |
275 | 472 | ||
473 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
474 | ath_edma_start_recv(sc); | ||
475 | return 0; | ||
476 | } | ||
477 | |||
276 | spin_lock_bh(&sc->rx.rxbuflock); | 478 | spin_lock_bh(&sc->rx.rxbuflock); |
277 | if (list_empty(&sc->rx.rxbuf)) | 479 | if (list_empty(&sc->rx.rxbuf)) |
278 | goto start_recv; | 480 | goto start_recv; |
@@ -306,7 +508,11 @@ bool ath_stoprecv(struct ath_softc *sc) | |||
306 | ath9k_hw_stoppcurecv(ah); | 508 | ath9k_hw_stoppcurecv(ah); |
307 | ath9k_hw_setrxfilter(ah, 0); | 509 | ath9k_hw_setrxfilter(ah, 0); |
308 | stopped = ath9k_hw_stopdmarecv(ah); | 510 | stopped = ath9k_hw_stopdmarecv(ah); |
309 | sc->rx.rxlink = NULL; | 511 | |
512 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
513 | ath_edma_stop_recv(sc); | ||
514 | else | ||
515 | sc->rx.rxlink = NULL; | ||
310 | 516 | ||
311 | return stopped; | 517 | return stopped; |
312 | } | 518 | } |
@@ -315,7 +521,9 @@ void ath_flushrecv(struct ath_softc *sc) | |||
315 | { | 521 | { |
316 | spin_lock_bh(&sc->rx.rxflushlock); | 522 | spin_lock_bh(&sc->rx.rxflushlock); |
317 | sc->sc_flags |= SC_OP_RXFLUSH; | 523 | sc->sc_flags |= SC_OP_RXFLUSH; |
318 | ath_rx_tasklet(sc, 1); | 524 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) |
525 | ath_rx_tasklet(sc, 1, true); | ||
526 | ath_rx_tasklet(sc, 1, false); | ||
319 | sc->sc_flags &= ~SC_OP_RXFLUSH; | 527 | sc->sc_flags &= ~SC_OP_RXFLUSH; |
320 | spin_unlock_bh(&sc->rx.rxflushlock); | 528 | spin_unlock_bh(&sc->rx.rxflushlock); |
321 | } | 529 | } |
@@ -469,15 +677,148 @@ static void ath_rx_send_to_mac80211(struct ieee80211_hw *hw, | |||
469 | ieee80211_rx(hw, skb); | 677 | ieee80211_rx(hw, skb); |
470 | } | 678 | } |
471 | 679 | ||
472 | int ath_rx_tasklet(struct ath_softc *sc, int flush) | 680 | static bool ath_edma_get_buffers(struct ath_softc *sc, |
681 | enum ath9k_rx_qtype qtype) | ||
473 | { | 682 | { |
474 | #define PA2DESC(_sc, _pa) \ | 683 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; |
475 | ((struct ath_desc *)((caddr_t)(_sc)->rx.rxdma.dd_desc + \ | 684 | struct ath_hw *ah = sc->sc_ah; |
476 | ((_pa) - (_sc)->rx.rxdma.dd_desc_paddr))) | 685 | struct ath_common *common = ath9k_hw_common(ah); |
686 | struct sk_buff *skb; | ||
687 | struct ath_buf *bf; | ||
688 | int ret; | ||
689 | |||
690 | skb = skb_peek(&rx_edma->rx_fifo); | ||
691 | if (!skb) | ||
692 | return false; | ||
693 | |||
694 | bf = SKB_CB_ATHBUF(skb); | ||
695 | BUG_ON(!bf); | ||
696 | |||
697 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | ||
698 | common->rx_bufsize, DMA_FROM_DEVICE); | ||
699 | |||
700 | ret = ath9k_hw_process_rxdesc_edma(ah, NULL, skb->data); | ||
701 | if (ret == -EINPROGRESS) | ||
702 | return false; | ||
703 | |||
704 | __skb_unlink(skb, &rx_edma->rx_fifo); | ||
705 | if (ret == -EINVAL) { | ||
706 | /* corrupt descriptor, skip this one and the following one */ | ||
707 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
708 | ath_rx_edma_buf_link(sc, qtype); | ||
709 | skb = skb_peek(&rx_edma->rx_fifo); | ||
710 | if (!skb) | ||
711 | return true; | ||
712 | |||
713 | bf = SKB_CB_ATHBUF(skb); | ||
714 | BUG_ON(!bf); | ||
715 | |||
716 | __skb_unlink(skb, &rx_edma->rx_fifo); | ||
717 | list_add_tail(&bf->list, &sc->rx.rxbuf); | ||
718 | ath_rx_edma_buf_link(sc, qtype); | ||
719 | return true; | ||
720 | } | ||
721 | skb_queue_tail(&rx_edma->rx_buffers, skb); | ||
722 | |||
723 | return true; | ||
724 | } | ||
477 | 725 | ||
726 | static struct ath_buf *ath_edma_get_next_rx_buf(struct ath_softc *sc, | ||
727 | struct ath_rx_status *rs, | ||
728 | enum ath9k_rx_qtype qtype) | ||
729 | { | ||
730 | struct ath_rx_edma *rx_edma = &sc->rx.rx_edma[qtype]; | ||
731 | struct sk_buff *skb; | ||
478 | struct ath_buf *bf; | 732 | struct ath_buf *bf; |
733 | |||
734 | while (ath_edma_get_buffers(sc, qtype)); | ||
735 | skb = __skb_dequeue(&rx_edma->rx_buffers); | ||
736 | if (!skb) | ||
737 | return NULL; | ||
738 | |||
739 | bf = SKB_CB_ATHBUF(skb); | ||
740 | ath9k_hw_process_rxdesc_edma(sc->sc_ah, rs, skb->data); | ||
741 | return bf; | ||
742 | } | ||
743 | |||
744 | static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc, | ||
745 | struct ath_rx_status *rs) | ||
746 | { | ||
747 | struct ath_hw *ah = sc->sc_ah; | ||
748 | struct ath_common *common = ath9k_hw_common(ah); | ||
479 | struct ath_desc *ds; | 749 | struct ath_desc *ds; |
480 | struct ath_rx_status *rx_stats; | 750 | struct ath_buf *bf; |
751 | int ret; | ||
752 | |||
753 | if (list_empty(&sc->rx.rxbuf)) { | ||
754 | sc->rx.rxlink = NULL; | ||
755 | return NULL; | ||
756 | } | ||
757 | |||
758 | bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); | ||
759 | ds = bf->bf_desc; | ||
760 | |||
761 | /* | ||
762 | * Must provide the virtual address of the current | ||
763 | * descriptor, the physical address, and the virtual | ||
764 | * address of the next descriptor in the h/w chain. | ||
765 | * This allows the HAL to look ahead to see if the | ||
766 | * hardware is done with a descriptor by checking the | ||
767 | * done bit in the following descriptor and the address | ||
768 | * of the current descriptor the DMA engine is working | ||
769 | * on. All this is necessary because of our use of | ||
770 | * a self-linked list to avoid rx overruns. | ||
771 | */ | ||
772 | ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0); | ||
773 | if (ret == -EINPROGRESS) { | ||
774 | struct ath_rx_status trs; | ||
775 | struct ath_buf *tbf; | ||
776 | struct ath_desc *tds; | ||
777 | |||
778 | memset(&trs, 0, sizeof(trs)); | ||
779 | if (list_is_last(&bf->list, &sc->rx.rxbuf)) { | ||
780 | sc->rx.rxlink = NULL; | ||
781 | return NULL; | ||
782 | } | ||
783 | |||
784 | tbf = list_entry(bf->list.next, struct ath_buf, list); | ||
785 | |||
786 | /* | ||
787 | * On some hardware the descriptor status words could | ||
788 | * get corrupted, including the done bit. Because of | ||
789 | * this, check if the next descriptor's done bit is | ||
790 | * set or not. | ||
791 | * | ||
792 | * If the next descriptor's done bit is set, the current | ||
793 | * descriptor has been corrupted. Force s/w to discard | ||
794 | * this descriptor and continue... | ||
795 | */ | ||
796 | |||
797 | tds = tbf->bf_desc; | ||
798 | ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0); | ||
799 | if (ret == -EINPROGRESS) | ||
800 | return NULL; | ||
801 | } | ||
802 | |||
803 | if (!bf->bf_mpdu) | ||
804 | return bf; | ||
805 | |||
806 | /* | ||
807 | * Synchronize the DMA transfer with CPU before | ||
808 | * 1. accessing the frame | ||
809 | * 2. requeueing the same buffer to h/w | ||
810 | */ | ||
811 | dma_sync_single_for_device(sc->dev, bf->bf_buf_addr, | ||
812 | common->rx_bufsize, | ||
813 | DMA_FROM_DEVICE); | ||
814 | |||
815 | return bf; | ||
816 | } | ||
817 | |||
818 | |||
819 | int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | ||
820 | { | ||
821 | struct ath_buf *bf; | ||
481 | struct sk_buff *skb = NULL, *requeue_skb; | 822 | struct sk_buff *skb = NULL, *requeue_skb; |
482 | struct ieee80211_rx_status *rxs; | 823 | struct ieee80211_rx_status *rxs; |
483 | struct ath_hw *ah = sc->sc_ah; | 824 | struct ath_hw *ah = sc->sc_ah; |
@@ -491,7 +832,17 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
491 | struct ieee80211_hdr *hdr; | 832 | struct ieee80211_hdr *hdr; |
492 | int retval; | 833 | int retval; |
493 | bool decrypt_error = false; | 834 | bool decrypt_error = false; |
835 | struct ath_rx_status rs; | ||
836 | enum ath9k_rx_qtype qtype; | ||
837 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | ||
838 | int dma_type; | ||
494 | 839 | ||
840 | if (edma) | ||
841 | dma_type = DMA_FROM_DEVICE; | ||
842 | else | ||
843 | dma_type = DMA_BIDIRECTIONAL; | ||
844 | |||
845 | qtype = hp ? ATH9K_RX_QUEUE_HP : ATH9K_RX_QUEUE_LP; | ||
495 | spin_lock_bh(&sc->rx.rxbuflock); | 846 | spin_lock_bh(&sc->rx.rxbuflock); |
496 | 847 | ||
497 | do { | 848 | do { |
@@ -499,79 +850,25 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
499 | if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) | 850 | if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0)) |
500 | break; | 851 | break; |
501 | 852 | ||
502 | if (list_empty(&sc->rx.rxbuf)) { | 853 | memset(&rs, 0, sizeof(rs)); |
503 | sc->rx.rxlink = NULL; | 854 | if (edma) |
504 | break; | 855 | bf = ath_edma_get_next_rx_buf(sc, &rs, qtype); |
505 | } | 856 | else |
506 | 857 | bf = ath_get_next_rx_buf(sc, &rs); | |
507 | bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list); | ||
508 | ds = bf->bf_desc; | ||
509 | |||
510 | /* | ||
511 | * Must provide the virtual address of the current | ||
512 | * descriptor, the physical address, and the virtual | ||
513 | * address of the next descriptor in the h/w chain. | ||
514 | * This allows the HAL to look ahead to see if the | ||
515 | * hardware is done with a descriptor by checking the | ||
516 | * done bit in the following descriptor and the address | ||
517 | * of the current descriptor the DMA engine is working | ||
518 | * on. All this is necessary because of our use of | ||
519 | * a self-linked list to avoid rx overruns. | ||
520 | */ | ||
521 | retval = ath9k_hw_rxprocdesc(ah, ds, | ||
522 | bf->bf_daddr, | ||
523 | PA2DESC(sc, ds->ds_link), | ||
524 | 0); | ||
525 | if (retval == -EINPROGRESS) { | ||
526 | struct ath_buf *tbf; | ||
527 | struct ath_desc *tds; | ||
528 | |||
529 | if (list_is_last(&bf->list, &sc->rx.rxbuf)) { | ||
530 | sc->rx.rxlink = NULL; | ||
531 | break; | ||
532 | } | ||
533 | 858 | ||
534 | tbf = list_entry(bf->list.next, struct ath_buf, list); | 859 | if (!bf) |
535 | 860 | break; | |
536 | /* | ||
537 | * On some hardware the descriptor status words could | ||
538 | * get corrupted, including the done bit. Because of | ||
539 | * this, check if the next descriptor's done bit is | ||
540 | * set or not. | ||
541 | * | ||
542 | * If the next descriptor's done bit is set, the current | ||
543 | * descriptor has been corrupted. Force s/w to discard | ||
544 | * this descriptor and continue... | ||
545 | */ | ||
546 | |||
547 | tds = tbf->bf_desc; | ||
548 | retval = ath9k_hw_rxprocdesc(ah, tds, tbf->bf_daddr, | ||
549 | PA2DESC(sc, tds->ds_link), 0); | ||
550 | if (retval == -EINPROGRESS) { | ||
551 | break; | ||
552 | } | ||
553 | } | ||
554 | 861 | ||
555 | skb = bf->bf_mpdu; | 862 | skb = bf->bf_mpdu; |
556 | if (!skb) | 863 | if (!skb) |
557 | continue; | 864 | continue; |
558 | 865 | ||
559 | /* | ||
560 | * Synchronize the DMA transfer with CPU before | ||
561 | * 1. accessing the frame | ||
562 | * 2. requeueing the same buffer to h/w | ||
563 | */ | ||
564 | dma_sync_single_for_cpu(sc->dev, bf->bf_buf_addr, | ||
565 | common->rx_bufsize, | ||
566 | DMA_FROM_DEVICE); | ||
567 | |||
568 | hdr = (struct ieee80211_hdr *) skb->data; | 866 | hdr = (struct ieee80211_hdr *) skb->data; |
569 | rxs = IEEE80211_SKB_RXCB(skb); | 867 | rxs = IEEE80211_SKB_RXCB(skb); |
570 | 868 | ||
571 | hw = ath_get_virt_hw(sc, hdr); | 869 | hw = ath_get_virt_hw(sc, hdr); |
572 | rx_stats = &ds->ds_rxstat; | ||
573 | 870 | ||
574 | ath_debug_stat_rx(sc, bf); | 871 | ath_debug_stat_rx(sc, &rs); |
575 | 872 | ||
576 | /* | 873 | /* |
577 | * If we're asked to flush receive queue, directly | 874 | * If we're asked to flush receive queue, directly |
@@ -580,7 +877,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
580 | if (flush) | 877 | if (flush) |
581 | goto requeue; | 878 | goto requeue; |
582 | 879 | ||
583 | retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, rx_stats, | 880 | retval = ath9k_cmn_rx_skb_preprocess(common, hw, skb, &rs, |
584 | rxs, &decrypt_error); | 881 | rxs, &decrypt_error); |
585 | if (retval) | 882 | if (retval) |
586 | goto requeue; | 883 | goto requeue; |
@@ -599,18 +896,20 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
599 | /* Unmap the frame */ | 896 | /* Unmap the frame */ |
600 | dma_unmap_single(sc->dev, bf->bf_buf_addr, | 897 | dma_unmap_single(sc->dev, bf->bf_buf_addr, |
601 | common->rx_bufsize, | 898 | common->rx_bufsize, |
602 | DMA_FROM_DEVICE); | 899 | dma_type); |
603 | 900 | ||
604 | skb_put(skb, rx_stats->rs_datalen); | 901 | skb_put(skb, rs.rs_datalen + ah->caps.rx_status_len); |
902 | if (ah->caps.rx_status_len) | ||
903 | skb_pull(skb, ah->caps.rx_status_len); | ||
605 | 904 | ||
606 | ath9k_cmn_rx_skb_postprocess(common, skb, rx_stats, | 905 | ath9k_cmn_rx_skb_postprocess(common, skb, &rs, |
607 | rxs, decrypt_error); | 906 | rxs, decrypt_error); |
608 | 907 | ||
609 | /* We will now give hardware our shiny new allocated skb */ | 908 | /* We will now give hardware our shiny new allocated skb */ |
610 | bf->bf_mpdu = requeue_skb; | 909 | bf->bf_mpdu = requeue_skb; |
611 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, | 910 | bf->bf_buf_addr = dma_map_single(sc->dev, requeue_skb->data, |
612 | common->rx_bufsize, | 911 | common->rx_bufsize, |
613 | DMA_FROM_DEVICE); | 912 | dma_type); |
614 | if (unlikely(dma_mapping_error(sc->dev, | 913 | if (unlikely(dma_mapping_error(sc->dev, |
615 | bf->bf_buf_addr))) { | 914 | bf->bf_buf_addr))) { |
616 | dev_kfree_skb_any(requeue_skb); | 915 | dev_kfree_skb_any(requeue_skb); |
@@ -626,9 +925,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
626 | * change the default rx antenna if rx diversity chooses the | 925 | * change the default rx antenna if rx diversity chooses the |
627 | * other antenna 3 times in a row. | 926 | * other antenna 3 times in a row. |
628 | */ | 927 | */ |
629 | if (sc->rx.defant != ds->ds_rxstat.rs_antenna) { | 928 | if (sc->rx.defant != rs.rs_antenna) { |
630 | if (++sc->rx.rxotherant >= 3) | 929 | if (++sc->rx.rxotherant >= 3) |
631 | ath_setdefantenna(sc, rx_stats->rs_antenna); | 930 | ath_setdefantenna(sc, rs.rs_antenna); |
632 | } else { | 931 | } else { |
633 | sc->rx.rxotherant = 0; | 932 | sc->rx.rxotherant = 0; |
634 | } | 933 | } |
@@ -641,12 +940,16 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush) | |||
641 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); | 940 | ath_rx_send_to_mac80211(hw, sc, skb, rxs); |
642 | 941 | ||
643 | requeue: | 942 | requeue: |
644 | list_move_tail(&bf->list, &sc->rx.rxbuf); | 943 | if (edma) { |
645 | ath_rx_buf_link(sc, bf); | 944 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
945 | ath_rx_edma_buf_link(sc, qtype); | ||
946 | } else { | ||
947 | list_move_tail(&bf->list, &sc->rx.rxbuf); | ||
948 | ath_rx_buf_link(sc, bf); | ||
949 | } | ||
646 | } while (1); | 950 | } while (1); |
647 | 951 | ||
648 | spin_unlock_bh(&sc->rx.rxbuflock); | 952 | spin_unlock_bh(&sc->rx.rxbuflock); |
649 | 953 | ||
650 | return 0; | 954 | return 0; |
651 | #undef PA2DESC | ||
652 | } | 955 | } |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 72cfa8ebd9ae..d4371a43bdaa 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -20,7 +20,7 @@ | |||
20 | #include "../reg.h" | 20 | #include "../reg.h" |
21 | 21 | ||
22 | #define AR_CR 0x0008 | 22 | #define AR_CR 0x0008 |
23 | #define AR_CR_RXE 0x00000004 | 23 | #define AR_CR_RXE (AR_SREV_9300_20_OR_LATER(ah) ? 0x0000000c : 0x00000004) |
24 | #define AR_CR_RXD 0x00000020 | 24 | #define AR_CR_RXD 0x00000020 |
25 | #define AR_CR_SWI 0x00000040 | 25 | #define AR_CR_SWI 0x00000040 |
26 | 26 | ||
@@ -39,6 +39,12 @@ | |||
39 | #define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000 | 39 | #define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000 |
40 | #define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17 | 40 | #define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17 |
41 | 41 | ||
42 | #define AR_RXBP_THRESH 0x0018 | ||
43 | #define AR_RXBP_THRESH_HP 0x0000000f | ||
44 | #define AR_RXBP_THRESH_HP_S 0 | ||
45 | #define AR_RXBP_THRESH_LP 0x00003f00 | ||
46 | #define AR_RXBP_THRESH_LP_S 8 | ||
47 | |||
42 | #define AR_MIRT 0x0020 | 48 | #define AR_MIRT 0x0020 |
43 | #define AR_MIRT_VAL 0x0000ffff | 49 | #define AR_MIRT_VAL 0x0000ffff |
44 | #define AR_MIRT_VAL_S 16 | 50 | #define AR_MIRT_VAL_S 16 |
@@ -144,6 +150,9 @@ | |||
144 | #define AR_MACMISC_MISC_OBS_BUS_MSB_S 15 | 150 | #define AR_MACMISC_MISC_OBS_BUS_MSB_S 15 |
145 | #define AR_MACMISC_MISC_OBS_BUS_1 1 | 151 | #define AR_MACMISC_MISC_OBS_BUS_1 1 |
146 | 152 | ||
153 | #define AR_DATABUF_SIZE 0x0060 | ||
154 | #define AR_DATABUF_SIZE_MASK 0x00000FFF | ||
155 | |||
147 | #define AR_GTXTO 0x0064 | 156 | #define AR_GTXTO 0x0064 |
148 | #define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF | 157 | #define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF |
149 | #define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000 | 158 | #define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000 |
@@ -160,9 +169,14 @@ | |||
160 | #define AR_CST_TIMEOUT_LIMIT 0xFFFF0000 | 169 | #define AR_CST_TIMEOUT_LIMIT 0xFFFF0000 |
161 | #define AR_CST_TIMEOUT_LIMIT_S 16 | 170 | #define AR_CST_TIMEOUT_LIMIT_S 16 |
162 | 171 | ||
172 | #define AR_HP_RXDP 0x0074 | ||
173 | #define AR_LP_RXDP 0x0078 | ||
174 | |||
163 | #define AR_ISR 0x0080 | 175 | #define AR_ISR 0x0080 |
164 | #define AR_ISR_RXOK 0x00000001 | 176 | #define AR_ISR_RXOK 0x00000001 |
165 | #define AR_ISR_RXDESC 0x00000002 | 177 | #define AR_ISR_RXDESC 0x00000002 |
178 | #define AR_ISR_HP_RXOK 0x00000001 | ||
179 | #define AR_ISR_LP_RXOK 0x00000002 | ||
166 | #define AR_ISR_RXERR 0x00000004 | 180 | #define AR_ISR_RXERR 0x00000004 |
167 | #define AR_ISR_RXNOPKT 0x00000008 | 181 | #define AR_ISR_RXNOPKT 0x00000008 |
168 | #define AR_ISR_RXEOL 0x00000010 | 182 | #define AR_ISR_RXEOL 0x00000010 |
@@ -232,7 +246,6 @@ | |||
232 | #define AR_ISR_S5_TIMER_THRESH 0x0007FE00 | 246 | #define AR_ISR_S5_TIMER_THRESH 0x0007FE00 |
233 | #define AR_ISR_S5_TIM_TIMER 0x00000010 | 247 | #define AR_ISR_S5_TIM_TIMER 0x00000010 |
234 | #define AR_ISR_S5_DTIM_TIMER 0x00000020 | 248 | #define AR_ISR_S5_DTIM_TIMER 0x00000020 |
235 | #define AR_ISR_S5_S 0x00d8 | ||
236 | #define AR_IMR_S5 0x00b8 | 249 | #define AR_IMR_S5 0x00b8 |
237 | #define AR_IMR_S5_TIM_TIMER 0x00000010 | 250 | #define AR_IMR_S5_TIM_TIMER 0x00000010 |
238 | #define AR_IMR_S5_DTIM_TIMER 0x00000020 | 251 | #define AR_IMR_S5_DTIM_TIMER 0x00000020 |
@@ -240,7 +253,6 @@ | |||
240 | #define AR_ISR_S5_GENTIMER_TRIG_S 0 | 253 | #define AR_ISR_S5_GENTIMER_TRIG_S 0 |
241 | #define AR_ISR_S5_GENTIMER_THRESH 0xFF800000 | 254 | #define AR_ISR_S5_GENTIMER_THRESH 0xFF800000 |
242 | #define AR_ISR_S5_GENTIMER_THRESH_S 16 | 255 | #define AR_ISR_S5_GENTIMER_THRESH_S 16 |
243 | #define AR_ISR_S5_S 0x00d8 | ||
244 | #define AR_IMR_S5_GENTIMER_TRIG 0x0000FF80 | 256 | #define AR_IMR_S5_GENTIMER_TRIG 0x0000FF80 |
245 | #define AR_IMR_S5_GENTIMER_TRIG_S 0 | 257 | #define AR_IMR_S5_GENTIMER_TRIG_S 0 |
246 | #define AR_IMR_S5_GENTIMER_THRESH 0xFF800000 | 258 | #define AR_IMR_S5_GENTIMER_THRESH 0xFF800000 |
@@ -249,6 +261,8 @@ | |||
249 | #define AR_IMR 0x00a0 | 261 | #define AR_IMR 0x00a0 |
250 | #define AR_IMR_RXOK 0x00000001 | 262 | #define AR_IMR_RXOK 0x00000001 |
251 | #define AR_IMR_RXDESC 0x00000002 | 263 | #define AR_IMR_RXDESC 0x00000002 |
264 | #define AR_IMR_RXOK_HP 0x00000001 | ||
265 | #define AR_IMR_RXOK_LP 0x00000002 | ||
252 | #define AR_IMR_RXERR 0x00000004 | 266 | #define AR_IMR_RXERR 0x00000004 |
253 | #define AR_IMR_RXNOPKT 0x00000008 | 267 | #define AR_IMR_RXNOPKT 0x00000008 |
254 | #define AR_IMR_RXEOL 0x00000010 | 268 | #define AR_IMR_RXEOL 0x00000010 |
@@ -332,10 +346,10 @@ | |||
332 | #define AR_ISR_S1_QCU_TXEOL 0x03FF0000 | 346 | #define AR_ISR_S1_QCU_TXEOL 0x03FF0000 |
333 | #define AR_ISR_S1_QCU_TXEOL_S 16 | 347 | #define AR_ISR_S1_QCU_TXEOL_S 16 |
334 | 348 | ||
335 | #define AR_ISR_S2_S 0x00cc | 349 | #define AR_ISR_S2_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d0 : 0x00cc) |
336 | #define AR_ISR_S3_S 0x00d0 | 350 | #define AR_ISR_S3_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d4 : 0x00d0) |
337 | #define AR_ISR_S4_S 0x00d4 | 351 | #define AR_ISR_S4_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00d8 : 0x00d4) |
338 | #define AR_ISR_S5_S 0x00d8 | 352 | #define AR_ISR_S5_S (AR_SREV_9300_20_OR_LATER(ah) ? 0x00dc : 0x00d8) |
339 | #define AR_DMADBG_0 0x00e0 | 353 | #define AR_DMADBG_0 0x00e0 |
340 | #define AR_DMADBG_1 0x00e4 | 354 | #define AR_DMADBG_1 0x00e4 |
341 | #define AR_DMADBG_2 0x00e8 | 355 | #define AR_DMADBG_2 0x00e8 |
@@ -369,6 +383,9 @@ | |||
369 | #define AR_Q9_TXDP 0x0824 | 383 | #define AR_Q9_TXDP 0x0824 |
370 | #define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2)) | 384 | #define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2)) |
371 | 385 | ||
386 | #define AR_Q_STATUS_RING_START 0x830 | ||
387 | #define AR_Q_STATUS_RING_END 0x834 | ||
388 | |||
372 | #define AR_Q_TXE 0x0840 | 389 | #define AR_Q_TXE 0x0840 |
373 | #define AR_Q_TXE_M 0x000003FF | 390 | #define AR_Q_TXE_M 0x000003FF |
374 | 391 | ||
@@ -461,6 +478,10 @@ | |||
461 | #define AR_Q_RDYTIMESHDN 0x0a40 | 478 | #define AR_Q_RDYTIMESHDN 0x0a40 |
462 | #define AR_Q_RDYTIMESHDN_M 0x000003FF | 479 | #define AR_Q_RDYTIMESHDN_M 0x000003FF |
463 | 480 | ||
481 | /* MAC Descriptor CRC check */ | ||
482 | #define AR_Q_DESC_CRCCHK 0xa44 | ||
483 | /* Enable CRC check on the descriptor fetched from host */ | ||
484 | #define AR_Q_DESC_CRCCHK_EN 1 | ||
464 | 485 | ||
465 | #define AR_NUM_DCU 10 | 486 | #define AR_NUM_DCU 10 |
466 | #define AR_DCU_0 0x0001 | 487 | #define AR_DCU_0 0x0001 |
@@ -679,7 +700,7 @@ | |||
679 | 700 | ||
680 | #define AR_WA 0x4004 | 701 | #define AR_WA 0x4004 |
681 | #define AR_WA_D3_L1_DISABLE (1 << 14) | 702 | #define AR_WA_D3_L1_DISABLE (1 << 14) |
682 | #define AR9285_WA_DEFAULT 0x004a05cb | 703 | #define AR9285_WA_DEFAULT 0x004a050b |
683 | #define AR9280_WA_DEFAULT 0x0040073b | 704 | #define AR9280_WA_DEFAULT 0x0040073b |
684 | #define AR_WA_DEFAULT 0x0000073f | 705 | #define AR_WA_DEFAULT 0x0000073f |
685 | 706 | ||
@@ -759,6 +780,8 @@ | |||
759 | #define AR_SREV_VERSION_9271 0x140 | 780 | #define AR_SREV_VERSION_9271 0x140 |
760 | #define AR_SREV_REVISION_9271_10 0 | 781 | #define AR_SREV_REVISION_9271_10 0 |
761 | #define AR_SREV_REVISION_9271_11 1 | 782 | #define AR_SREV_REVISION_9271_11 1 |
783 | #define AR_SREV_VERSION_9300 0x1c0 | ||
784 | #define AR_SREV_REVISION_9300_20 2 /* 2.0 and 2.1 */ | ||
762 | 785 | ||
763 | #define AR_SREV_5416(_ah) \ | 786 | #define AR_SREV_5416(_ah) \ |
764 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ | 787 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ |
@@ -844,6 +867,19 @@ | |||
844 | #define AR_SREV_9271_11(_ah) \ | 867 | #define AR_SREV_9271_11(_ah) \ |
845 | (AR_SREV_9271(_ah) && \ | 868 | (AR_SREV_9271(_ah) && \ |
846 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11)) | 869 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11)) |
870 | #define AR_SREV_9300(_ah) \ | ||
871 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300)) | ||
872 | #define AR_SREV_9300_20(_ah) \ | ||
873 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ | ||
874 | ((_ah)->hw_version.macRev == AR_SREV_REVISION_9300_20)) | ||
875 | #define AR_SREV_9300_20_OR_LATER(_ah) \ | ||
876 | (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9300) || \ | ||
877 | (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9300) && \ | ||
878 | ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9300_20))) | ||
879 | |||
880 | #define AR_SREV_9285E_20(_ah) \ | ||
881 | (AR_SREV_9285_12_OR_LATER(_ah) && \ | ||
882 | ((REG_READ(_ah, AR_AN_SYNTH9) & 0x7) == 0x1)) | ||
847 | 883 | ||
848 | #define AR_RADIO_SREV_MAJOR 0xf0 | 884 | #define AR_RADIO_SREV_MAJOR 0xf0 |
849 | #define AR_RAD5133_SREV_MAJOR 0xc0 | 885 | #define AR_RAD5133_SREV_MAJOR 0xc0 |
@@ -940,6 +976,8 @@ enum { | |||
940 | #define AR928X_NUM_GPIO 10 | 976 | #define AR928X_NUM_GPIO 10 |
941 | #define AR9285_NUM_GPIO 12 | 977 | #define AR9285_NUM_GPIO 12 |
942 | #define AR9287_NUM_GPIO 11 | 978 | #define AR9287_NUM_GPIO 11 |
979 | #define AR9271_NUM_GPIO 16 | ||
980 | #define AR9300_NUM_GPIO 17 | ||
943 | 981 | ||
944 | #define AR_GPIO_IN_OUT 0x4048 | 982 | #define AR_GPIO_IN_OUT 0x4048 |
945 | #define AR_GPIO_IN_VAL 0x0FFFC000 | 983 | #define AR_GPIO_IN_VAL 0x0FFFC000 |
@@ -950,19 +988,23 @@ enum { | |||
950 | #define AR9285_GPIO_IN_VAL_S 12 | 988 | #define AR9285_GPIO_IN_VAL_S 12 |
951 | #define AR9287_GPIO_IN_VAL 0x003FF800 | 989 | #define AR9287_GPIO_IN_VAL 0x003FF800 |
952 | #define AR9287_GPIO_IN_VAL_S 11 | 990 | #define AR9287_GPIO_IN_VAL_S 11 |
991 | #define AR9271_GPIO_IN_VAL 0xFFFF0000 | ||
992 | #define AR9271_GPIO_IN_VAL_S 16 | ||
993 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | ||
994 | #define AR9300_GPIO_IN_VAL_S 0 | ||
953 | 995 | ||
954 | #define AR_GPIO_OE_OUT 0x404c | 996 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) |
955 | #define AR_GPIO_OE_OUT_DRV 0x3 | 997 | #define AR_GPIO_OE_OUT_DRV 0x3 |
956 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | 998 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 |
957 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 | 999 | #define AR_GPIO_OE_OUT_DRV_LOW 0x1 |
958 | #define AR_GPIO_OE_OUT_DRV_HI 0x2 | 1000 | #define AR_GPIO_OE_OUT_DRV_HI 0x2 |
959 | #define AR_GPIO_OE_OUT_DRV_ALL 0x3 | 1001 | #define AR_GPIO_OE_OUT_DRV_ALL 0x3 |
960 | 1002 | ||
961 | #define AR_GPIO_INTR_POL 0x4050 | 1003 | #define AR_GPIO_INTR_POL (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050) |
962 | #define AR_GPIO_INTR_POL_VAL 0x00001FFF | 1004 | #define AR_GPIO_INTR_POL_VAL 0x0001FFFF |
963 | #define AR_GPIO_INTR_POL_VAL_S 0 | 1005 | #define AR_GPIO_INTR_POL_VAL_S 0 |
964 | 1006 | ||
965 | #define AR_GPIO_INPUT_EN_VAL 0x4054 | 1007 | #define AR_GPIO_INPUT_EN_VAL (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054) |
966 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 | 1008 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF 0x00000004 |
967 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 | 1009 | #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S 2 |
968 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 | 1010 | #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF 0x00000008 |
@@ -980,13 +1022,13 @@ enum { | |||
980 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 | 1022 | #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000 |
981 | #define AR_GPIO_JTAG_DISABLE 0x00020000 | 1023 | #define AR_GPIO_JTAG_DISABLE 0x00020000 |
982 | 1024 | ||
983 | #define AR_GPIO_INPUT_MUX1 0x4058 | 1025 | #define AR_GPIO_INPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058) |
984 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 | 1026 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE 0x000f0000 |
985 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 | 1027 | #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S 16 |
986 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 | 1028 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY 0x00000f00 |
987 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 | 1029 | #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S 8 |
988 | 1030 | ||
989 | #define AR_GPIO_INPUT_MUX2 0x405c | 1031 | #define AR_GPIO_INPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c) |
990 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f | 1032 | #define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f |
991 | #define AR_GPIO_INPUT_MUX2_CLK25_S 0 | 1033 | #define AR_GPIO_INPUT_MUX2_CLK25_S 0 |
992 | #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 | 1034 | #define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0 |
@@ -994,13 +1036,13 @@ enum { | |||
994 | #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 | 1036 | #define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00 |
995 | #define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 | 1037 | #define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8 |
996 | 1038 | ||
997 | #define AR_GPIO_OUTPUT_MUX1 0x4060 | 1039 | #define AR_GPIO_OUTPUT_MUX1 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060) |
998 | #define AR_GPIO_OUTPUT_MUX2 0x4064 | 1040 | #define AR_GPIO_OUTPUT_MUX2 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064) |
999 | #define AR_GPIO_OUTPUT_MUX3 0x4068 | 1041 | #define AR_GPIO_OUTPUT_MUX3 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068) |
1000 | 1042 | ||
1001 | #define AR_INPUT_STATE 0x406c | 1043 | #define AR_INPUT_STATE (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c) |
1002 | 1044 | ||
1003 | #define AR_EEPROM_STATUS_DATA 0x407c | 1045 | #define AR_EEPROM_STATUS_DATA (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c) |
1004 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff | 1046 | #define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff |
1005 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 | 1047 | #define AR_EEPROM_STATUS_DATA_VAL_S 0 |
1006 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 | 1048 | #define AR_EEPROM_STATUS_DATA_BUSY 0x00010000 |
@@ -1008,13 +1050,24 @@ enum { | |||
1008 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 | 1050 | #define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000 |
1009 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 | 1051 | #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000 |
1010 | 1052 | ||
1011 | #define AR_OBS 0x4080 | 1053 | #define AR_OBS (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080) |
1012 | 1054 | ||
1013 | #define AR_GPIO_PDPU 0x4088 | 1055 | #define AR_GPIO_PDPU (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088) |
1014 | 1056 | ||
1015 | #define AR_PCIE_MSI 0x4094 | 1057 | #define AR_PCIE_MSI (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094) |
1016 | #define AR_PCIE_MSI_ENABLE 0x00000001 | 1058 | #define AR_PCIE_MSI_ENABLE 0x00000001 |
1017 | 1059 | ||
1060 | #define AR_INTR_PRIO_SYNC_ENABLE 0x40c4 | ||
1061 | #define AR_INTR_PRIO_ASYNC_MASK 0x40c8 | ||
1062 | #define AR_INTR_PRIO_SYNC_MASK 0x40cc | ||
1063 | #define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4 | ||
1064 | |||
1065 | #define AR_RTC_9300_PLL_DIV 0x000003ff | ||
1066 | #define AR_RTC_9300_PLL_DIV_S 0 | ||
1067 | #define AR_RTC_9300_PLL_REFDIV 0x00003C00 | ||
1068 | #define AR_RTC_9300_PLL_REFDIV_S 10 | ||
1069 | #define AR_RTC_9300_PLL_CLKSEL 0x0000C000 | ||
1070 | #define AR_RTC_9300_PLL_CLKSEL_S 14 | ||
1018 | 1071 | ||
1019 | #define AR_RTC_9160_PLL_DIV 0x000003ff | 1072 | #define AR_RTC_9160_PLL_DIV 0x000003ff |
1020 | #define AR_RTC_9160_PLL_DIV_S 0 | 1073 | #define AR_RTC_9160_PLL_DIV_S 0 |
@@ -1032,6 +1085,16 @@ enum { | |||
1032 | #define AR_RTC_RC_COLD_RESET 0x00000004 | 1085 | #define AR_RTC_RC_COLD_RESET 0x00000004 |
1033 | #define AR_RTC_RC_WARM_RESET 0x00000008 | 1086 | #define AR_RTC_RC_WARM_RESET 0x00000008 |
1034 | 1087 | ||
1088 | /* Crystal Control */ | ||
1089 | #define AR_RTC_XTAL_CONTROL 0x7004 | ||
1090 | |||
1091 | /* Reg Control 0 */ | ||
1092 | #define AR_RTC_REG_CONTROL0 0x7008 | ||
1093 | |||
1094 | /* Reg Control 1 */ | ||
1095 | #define AR_RTC_REG_CONTROL1 0x700c | ||
1096 | #define AR_RTC_REG_CONTROL1_SWREG_PROGRAM 0x00000001 | ||
1097 | |||
1035 | #define AR_RTC_PLL_CONTROL \ | 1098 | #define AR_RTC_PLL_CONTROL \ |
1036 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) | 1099 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) |
1037 | 1100 | ||
@@ -1062,6 +1125,7 @@ enum { | |||
1062 | #define AR_RTC_SLEEP_CLK \ | 1125 | #define AR_RTC_SLEEP_CLK \ |
1063 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048) | 1126 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048) |
1064 | #define AR_RTC_FORCE_DERIVED_CLK 0x2 | 1127 | #define AR_RTC_FORCE_DERIVED_CLK 0x2 |
1128 | #define AR_RTC_FORCE_SWREG_PRD 0x00000004 | ||
1065 | 1129 | ||
1066 | #define AR_RTC_FORCE_WAKE \ | 1130 | #define AR_RTC_FORCE_WAKE \ |
1067 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c) | 1131 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c) |
@@ -1178,6 +1242,13 @@ enum { | |||
1178 | #define AR9285_AN_RF2G4_DB2_4 0x00003800 | 1242 | #define AR9285_AN_RF2G4_DB2_4 0x00003800 |
1179 | #define AR9285_AN_RF2G4_DB2_4_S 11 | 1243 | #define AR9285_AN_RF2G4_DB2_4_S 11 |
1180 | 1244 | ||
1245 | #define AR9285_RF2G5 0x7830 | ||
1246 | #define AR9285_RF2G5_IC50TX 0xfffff8ff | ||
1247 | #define AR9285_RF2G5_IC50TX_SET 0x00000400 | ||
1248 | #define AR9285_RF2G5_IC50TX_XE_SET 0x00000500 | ||
1249 | #define AR9285_RF2G5_IC50TX_CLEAR 0x00000700 | ||
1250 | #define AR9285_RF2G5_IC50TX_CLEAR_S 8 | ||
1251 | |||
1181 | /* AR9271 : 0x7828, 0x782c different setting from AR9285 */ | 1252 | /* AR9271 : 0x7828, 0x782c different setting from AR9285 */ |
1182 | #define AR9271_AN_RF2G3_OB_cck 0x001C0000 | 1253 | #define AR9271_AN_RF2G3_OB_cck 0x001C0000 |
1183 | #define AR9271_AN_RF2G3_OB_cck_S 18 | 1254 | #define AR9271_AN_RF2G3_OB_cck_S 18 |
@@ -1519,7 +1590,7 @@ enum { | |||
1519 | #define AR_TSFOOR_THRESHOLD 0x813c | 1590 | #define AR_TSFOOR_THRESHOLD 0x813c |
1520 | #define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF | 1591 | #define AR_TSFOOR_THRESHOLD_VAL 0x0000FFFF |
1521 | 1592 | ||
1522 | #define AR_PHY_ERR_EIFS_MASK 8144 | 1593 | #define AR_PHY_ERR_EIFS_MASK 0x8144 |
1523 | 1594 | ||
1524 | #define AR_PHY_ERR_3 0x8168 | 1595 | #define AR_PHY_ERR_3 0x8168 |
1525 | #define AR_PHY_ERR_3_COUNT 0x00FFFFFF | 1596 | #define AR_PHY_ERR_3_COUNT 0x00FFFFFF |
@@ -1585,24 +1656,26 @@ enum { | |||
1585 | #define AR_FIRST_NDP_TIMER 7 | 1656 | #define AR_FIRST_NDP_TIMER 7 |
1586 | #define AR_NDP2_PERIOD 0x81a0 | 1657 | #define AR_NDP2_PERIOD 0x81a0 |
1587 | #define AR_NDP2_TIMER_MODE 0x81c0 | 1658 | #define AR_NDP2_TIMER_MODE 0x81c0 |
1588 | #define AR_NEXT_TBTT_TIMER 0x8200 | 1659 | |
1589 | #define AR_NEXT_DMA_BEACON_ALERT 0x8204 | 1660 | #define AR_GEN_TIMERS(_i) (0x8200 + ((_i) << 2)) |
1590 | #define AR_NEXT_SWBA 0x8208 | 1661 | #define AR_NEXT_TBTT_TIMER AR_GEN_TIMERS(0) |
1591 | #define AR_NEXT_CFP 0x8208 | 1662 | #define AR_NEXT_DMA_BEACON_ALERT AR_GEN_TIMERS(1) |
1592 | #define AR_NEXT_HCF 0x820C | 1663 | #define AR_NEXT_SWBA AR_GEN_TIMERS(2) |
1593 | #define AR_NEXT_TIM 0x8210 | 1664 | #define AR_NEXT_CFP AR_GEN_TIMERS(2) |
1594 | #define AR_NEXT_DTIM 0x8214 | 1665 | #define AR_NEXT_HCF AR_GEN_TIMERS(3) |
1595 | #define AR_NEXT_QUIET_TIMER 0x8218 | 1666 | #define AR_NEXT_TIM AR_GEN_TIMERS(4) |
1596 | #define AR_NEXT_NDP_TIMER 0x821C | 1667 | #define AR_NEXT_DTIM AR_GEN_TIMERS(5) |
1597 | 1668 | #define AR_NEXT_QUIET_TIMER AR_GEN_TIMERS(6) | |
1598 | #define AR_BEACON_PERIOD 0x8220 | 1669 | #define AR_NEXT_NDP_TIMER AR_GEN_TIMERS(7) |
1599 | #define AR_DMA_BEACON_PERIOD 0x8224 | 1670 | |
1600 | #define AR_SWBA_PERIOD 0x8228 | 1671 | #define AR_BEACON_PERIOD AR_GEN_TIMERS(8) |
1601 | #define AR_HCF_PERIOD 0x822C | 1672 | #define AR_DMA_BEACON_PERIOD AR_GEN_TIMERS(9) |
1602 | #define AR_TIM_PERIOD 0x8230 | 1673 | #define AR_SWBA_PERIOD AR_GEN_TIMERS(10) |
1603 | #define AR_DTIM_PERIOD 0x8234 | 1674 | #define AR_HCF_PERIOD AR_GEN_TIMERS(11) |
1604 | #define AR_QUIET_PERIOD 0x8238 | 1675 | #define AR_TIM_PERIOD AR_GEN_TIMERS(12) |
1605 | #define AR_NDP_PERIOD 0x823C | 1676 | #define AR_DTIM_PERIOD AR_GEN_TIMERS(13) |
1677 | #define AR_QUIET_PERIOD AR_GEN_TIMERS(14) | ||
1678 | #define AR_NDP_PERIOD AR_GEN_TIMERS(15) | ||
1606 | 1679 | ||
1607 | #define AR_TIMER_MODE 0x8240 | 1680 | #define AR_TIMER_MODE 0x8240 |
1608 | #define AR_TBTT_TIMER_EN 0x00000001 | 1681 | #define AR_TBTT_TIMER_EN 0x00000001 |
@@ -1716,4 +1789,32 @@ enum { | |||
1716 | #define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ | 1789 | #define AR9271_CORE_CLOCK 117 /* clock to 117Mhz */ |
1717 | #define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ | 1790 | #define AR9271_TARGET_BAUD_RATE 19200 /* 115200 */ |
1718 | 1791 | ||
1792 | #define AR_AGG_WEP_ENABLE_FIX 0x00000008 /* This allows the use of AR_AGG_WEP_ENABLE */ | ||
1793 | #define AR_ADHOC_MCAST_KEYID_ENABLE 0x00000040 /* This bit enables the Multicast search | ||
1794 | * based on both MAC Address and Key ID. | ||
1795 | * If bit is 0, then Multicast search is | ||
1796 | * based on MAC address only. | ||
1797 | * For Merlin and above only. | ||
1798 | */ | ||
1799 | #define AR_AGG_WEP_ENABLE 0x00020000 /* This field enables AGG_WEP feature, | ||
1800 | * when it is enable, AGG_WEP would takes | ||
1801 | * charge of the encryption interface of | ||
1802 | * pcu_txsm. | ||
1803 | */ | ||
1804 | |||
1805 | #define AR9300_SM_BASE 0xa200 | ||
1806 | #define AR9002_PHY_AGC_CONTROL 0x9860 | ||
1807 | #define AR9003_PHY_AGC_CONTROL AR9300_SM_BASE + 0xc4 | ||
1808 | #define AR_PHY_AGC_CONTROL (AR_SREV_9300_20_OR_LATER(ah) ? AR9003_PHY_AGC_CONTROL : AR9002_PHY_AGC_CONTROL) | ||
1809 | #define AR_PHY_AGC_CONTROL_CAL 0x00000001 /* do internal calibration */ | ||
1810 | #define AR_PHY_AGC_CONTROL_NF 0x00000002 /* do noise-floor calibration */ | ||
1811 | #define AR_PHY_AGC_CONTROL_OFFSET_CAL 0x00000800 /* allow offset calibration */ | ||
1812 | #define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000 /* enable noise floor calibration to happen */ | ||
1813 | #define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000 /* allow tx filter calibration */ | ||
1814 | #define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000 /* don't update noise floor automatically */ | ||
1815 | #define AR_PHY_AGC_CONTROL_EXT_NF_PWR_MEAS 0x00040000 /* extend noise floor power measurement */ | ||
1816 | #define AR_PHY_AGC_CONTROL_CLC_SUCCESS 0x00080000 /* carrier leak calibration done */ | ||
1817 | #define AR_PHY_AGC_CONTROL_YCOK_MAX 0x000003c0 | ||
1818 | #define AR_PHY_AGC_CONTROL_YCOK_MAX_S 6 | ||
1819 | |||
1719 | #endif | 1820 | #endif |
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c index 00c0e21a4af7..105ad40968f6 100644 --- a/drivers/net/wireless/ath/ath9k/virtual.c +++ b/drivers/net/wireless/ath/ath9k/virtual.c | |||
@@ -220,7 +220,7 @@ static int ath9k_send_nullfunc(struct ath_wiphy *aphy, | |||
220 | 220 | ||
221 | memset(&txctl, 0, sizeof(struct ath_tx_control)); | 221 | memset(&txctl, 0, sizeof(struct ath_tx_control)); |
222 | txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; | 222 | txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; |
223 | txctl.frame_type = ps ? ATH9K_INT_PAUSE : ATH9K_INT_UNPAUSE; | 223 | txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; |
224 | 224 | ||
225 | if (ath_tx_start(aphy->hw, skb, &txctl) != 0) | 225 | if (ath_tx_start(aphy->hw, skb, &txctl) != 0) |
226 | goto exit; | 226 | goto exit; |
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c new file mode 100644 index 000000000000..e23172c9caaf --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/wmi.c | |||
@@ -0,0 +1,336 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #include "htc.h" | ||
18 | |||
19 | static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd) | ||
20 | { | ||
21 | switch (wmi_cmd) { | ||
22 | case WMI_ECHO_CMDID: | ||
23 | return "WMI_ECHO_CMDID"; | ||
24 | case WMI_ACCESS_MEMORY_CMDID: | ||
25 | return "WMI_ACCESS_MEMORY_CMDID"; | ||
26 | case WMI_DISABLE_INTR_CMDID: | ||
27 | return "WMI_DISABLE_INTR_CMDID"; | ||
28 | case WMI_ENABLE_INTR_CMDID: | ||
29 | return "WMI_ENABLE_INTR_CMDID"; | ||
30 | case WMI_RX_LINK_CMDID: | ||
31 | return "WMI_RX_LINK_CMDID"; | ||
32 | case WMI_ATH_INIT_CMDID: | ||
33 | return "WMI_ATH_INIT_CMDID"; | ||
34 | case WMI_ABORT_TXQ_CMDID: | ||
35 | return "WMI_ABORT_TXQ_CMDID"; | ||
36 | case WMI_STOP_TX_DMA_CMDID: | ||
37 | return "WMI_STOP_TX_DMA_CMDID"; | ||
38 | case WMI_STOP_DMA_RECV_CMDID: | ||
39 | return "WMI_STOP_DMA_RECV_CMDID"; | ||
40 | case WMI_ABORT_TX_DMA_CMDID: | ||
41 | return "WMI_ABORT_TX_DMA_CMDID"; | ||
42 | case WMI_DRAIN_TXQ_CMDID: | ||
43 | return "WMI_DRAIN_TXQ_CMDID"; | ||
44 | case WMI_DRAIN_TXQ_ALL_CMDID: | ||
45 | return "WMI_DRAIN_TXQ_ALL_CMDID"; | ||
46 | case WMI_START_RECV_CMDID: | ||
47 | return "WMI_START_RECV_CMDID"; | ||
48 | case WMI_STOP_RECV_CMDID: | ||
49 | return "WMI_STOP_RECV_CMDID"; | ||
50 | case WMI_FLUSH_RECV_CMDID: | ||
51 | return "WMI_FLUSH_RECV_CMDID"; | ||
52 | case WMI_SET_MODE_CMDID: | ||
53 | return "WMI_SET_MODE_CMDID"; | ||
54 | case WMI_RESET_CMDID: | ||
55 | return "WMI_RESET_CMDID"; | ||
56 | case WMI_NODE_CREATE_CMDID: | ||
57 | return "WMI_NODE_CREATE_CMDID"; | ||
58 | case WMI_NODE_REMOVE_CMDID: | ||
59 | return "WMI_NODE_REMOVE_CMDID"; | ||
60 | case WMI_VAP_REMOVE_CMDID: | ||
61 | return "WMI_VAP_REMOVE_CMDID"; | ||
62 | case WMI_VAP_CREATE_CMDID: | ||
63 | return "WMI_VAP_CREATE_CMDID"; | ||
64 | case WMI_BEACON_UPDATE_CMDID: | ||
65 | return "WMI_BEACON_UPDATE_CMDID"; | ||
66 | case WMI_REG_READ_CMDID: | ||
67 | return "WMI_REG_READ_CMDID"; | ||
68 | case WMI_REG_WRITE_CMDID: | ||
69 | return "WMI_REG_WRITE_CMDID"; | ||
70 | case WMI_RC_STATE_CHANGE_CMDID: | ||
71 | return "WMI_RC_STATE_CHANGE_CMDID"; | ||
72 | case WMI_RC_RATE_UPDATE_CMDID: | ||
73 | return "WMI_RC_RATE_UPDATE_CMDID"; | ||
74 | case WMI_DEBUG_INFO_CMDID: | ||
75 | return "WMI_DEBUG_INFO_CMDID"; | ||
76 | case WMI_HOST_ATTACH: | ||
77 | return "WMI_HOST_ATTACH"; | ||
78 | case WMI_TARGET_IC_UPDATE_CMDID: | ||
79 | return "WMI_TARGET_IC_UPDATE_CMDID"; | ||
80 | case WMI_TGT_STATS_CMDID: | ||
81 | return "WMI_TGT_STATS_CMDID"; | ||
82 | case WMI_TX_AGGR_ENABLE_CMDID: | ||
83 | return "WMI_TX_AGGR_ENABLE_CMDID"; | ||
84 | case WMI_TGT_DETACH_CMDID: | ||
85 | return "WMI_TGT_DETACH_CMDID"; | ||
86 | case WMI_TGT_TXQ_ENABLE_CMDID: | ||
87 | return "WMI_TGT_TXQ_ENABLE_CMDID"; | ||
88 | } | ||
89 | |||
90 | return "Bogus"; | ||
91 | } | ||
92 | |||
93 | struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv) | ||
94 | { | ||
95 | struct wmi *wmi; | ||
96 | |||
97 | wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL); | ||
98 | if (!wmi) | ||
99 | return NULL; | ||
100 | |||
101 | wmi->drv_priv = priv; | ||
102 | wmi->stopped = false; | ||
103 | mutex_init(&wmi->op_mutex); | ||
104 | mutex_init(&wmi->multi_write_mutex); | ||
105 | init_completion(&wmi->cmd_wait); | ||
106 | |||
107 | return wmi; | ||
108 | } | ||
109 | |||
110 | void ath9k_deinit_wmi(struct ath9k_htc_priv *priv) | ||
111 | { | ||
112 | struct wmi *wmi = priv->wmi; | ||
113 | |||
114 | mutex_lock(&wmi->op_mutex); | ||
115 | wmi->stopped = true; | ||
116 | mutex_unlock(&wmi->op_mutex); | ||
117 | |||
118 | kfree(priv->wmi); | ||
119 | } | ||
120 | |||
121 | void ath9k_wmi_tasklet(unsigned long data) | ||
122 | { | ||
123 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | ||
124 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
125 | struct wmi_cmd_hdr *hdr; | ||
126 | struct wmi_swba *swba_hdr; | ||
127 | enum wmi_event_id event; | ||
128 | struct sk_buff *skb; | ||
129 | void *wmi_event; | ||
130 | unsigned long flags; | ||
131 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
132 | __be32 txrate; | ||
133 | #endif | ||
134 | |||
135 | spin_lock_irqsave(&priv->wmi->wmi_lock, flags); | ||
136 | skb = priv->wmi->wmi_skb; | ||
137 | spin_unlock_irqrestore(&priv->wmi->wmi_lock, flags); | ||
138 | |||
139 | hdr = (struct wmi_cmd_hdr *) skb->data; | ||
140 | event = be16_to_cpu(hdr->command_id); | ||
141 | wmi_event = skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | ||
142 | |||
143 | ath_print(common, ATH_DBG_WMI, | ||
144 | "WMI Event: 0x%x\n", event); | ||
145 | |||
146 | switch (event) { | ||
147 | case WMI_TGT_RDY_EVENTID: | ||
148 | break; | ||
149 | case WMI_SWBA_EVENTID: | ||
150 | swba_hdr = (struct wmi_swba *) wmi_event; | ||
151 | ath9k_htc_swba(priv, swba_hdr->beacon_pending); | ||
152 | break; | ||
153 | case WMI_FATAL_EVENTID: | ||
154 | break; | ||
155 | case WMI_TXTO_EVENTID: | ||
156 | break; | ||
157 | case WMI_BMISS_EVENTID: | ||
158 | break; | ||
159 | case WMI_WLAN_TXCOMP_EVENTID: | ||
160 | break; | ||
161 | case WMI_DELBA_EVENTID: | ||
162 | break; | ||
163 | case WMI_TXRATE_EVENTID: | ||
164 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | ||
165 | txrate = ((struct wmi_event_txrate *)wmi_event)->txrate; | ||
166 | priv->debug.txrate = be32_to_cpu(txrate); | ||
167 | #endif | ||
168 | break; | ||
169 | default: | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | kfree_skb(skb); | ||
174 | } | ||
175 | |||
176 | static void ath9k_wmi_rsp_callback(struct wmi *wmi, struct sk_buff *skb) | ||
177 | { | ||
178 | skb_pull(skb, sizeof(struct wmi_cmd_hdr)); | ||
179 | |||
180 | if (wmi->cmd_rsp_buf != NULL && wmi->cmd_rsp_len != 0) | ||
181 | memcpy(wmi->cmd_rsp_buf, skb->data, wmi->cmd_rsp_len); | ||
182 | |||
183 | complete(&wmi->cmd_wait); | ||
184 | } | ||
185 | |||
186 | static void ath9k_wmi_ctrl_rx(void *priv, struct sk_buff *skb, | ||
187 | enum htc_endpoint_id epid) | ||
188 | { | ||
189 | struct wmi *wmi = (struct wmi *) priv; | ||
190 | struct wmi_cmd_hdr *hdr; | ||
191 | u16 cmd_id; | ||
192 | |||
193 | if (unlikely(wmi->stopped)) | ||
194 | goto free_skb; | ||
195 | |||
196 | hdr = (struct wmi_cmd_hdr *) skb->data; | ||
197 | cmd_id = be16_to_cpu(hdr->command_id); | ||
198 | |||
199 | if (cmd_id & 0x1000) { | ||
200 | spin_lock(&wmi->wmi_lock); | ||
201 | wmi->wmi_skb = skb; | ||
202 | spin_unlock(&wmi->wmi_lock); | ||
203 | tasklet_schedule(&wmi->drv_priv->wmi_tasklet); | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | /* Check if there has been a timeout. */ | ||
208 | spin_lock(&wmi->wmi_lock); | ||
209 | if (cmd_id != wmi->last_cmd_id) { | ||
210 | spin_unlock(&wmi->wmi_lock); | ||
211 | goto free_skb; | ||
212 | } | ||
213 | spin_unlock(&wmi->wmi_lock); | ||
214 | |||
215 | /* WMI command response */ | ||
216 | ath9k_wmi_rsp_callback(wmi, skb); | ||
217 | |||
218 | free_skb: | ||
219 | kfree_skb(skb); | ||
220 | } | ||
221 | |||
222 | static void ath9k_wmi_ctrl_tx(void *priv, struct sk_buff *skb, | ||
223 | enum htc_endpoint_id epid, bool txok) | ||
224 | { | ||
225 | kfree_skb(skb); | ||
226 | } | ||
227 | |||
228 | int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi, | ||
229 | enum htc_endpoint_id *wmi_ctrl_epid) | ||
230 | { | ||
231 | struct htc_service_connreq connect; | ||
232 | int ret; | ||
233 | |||
234 | wmi->htc = htc; | ||
235 | |||
236 | memset(&connect, 0, sizeof(connect)); | ||
237 | |||
238 | connect.ep_callbacks.priv = wmi; | ||
239 | connect.ep_callbacks.tx = ath9k_wmi_ctrl_tx; | ||
240 | connect.ep_callbacks.rx = ath9k_wmi_ctrl_rx; | ||
241 | connect.service_id = WMI_CONTROL_SVC; | ||
242 | |||
243 | ret = htc_connect_service(htc, &connect, &wmi->ctrl_epid); | ||
244 | if (ret) | ||
245 | return ret; | ||
246 | |||
247 | *wmi_ctrl_epid = wmi->ctrl_epid; | ||
248 | |||
249 | return 0; | ||
250 | } | ||
251 | |||
252 | static int ath9k_wmi_cmd_issue(struct wmi *wmi, | ||
253 | struct sk_buff *skb, | ||
254 | enum wmi_cmd_id cmd, u16 len) | ||
255 | { | ||
256 | struct wmi_cmd_hdr *hdr; | ||
257 | |||
258 | hdr = (struct wmi_cmd_hdr *) skb_push(skb, sizeof(struct wmi_cmd_hdr)); | ||
259 | hdr->command_id = cpu_to_be16(cmd); | ||
260 | hdr->seq_no = cpu_to_be16(++wmi->tx_seq_id); | ||
261 | |||
262 | return htc_send(wmi->htc, skb, wmi->ctrl_epid, NULL); | ||
263 | } | ||
264 | |||
265 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | ||
266 | u8 *cmd_buf, u32 cmd_len, | ||
267 | u8 *rsp_buf, u32 rsp_len, | ||
268 | u32 timeout) | ||
269 | { | ||
270 | struct ath_hw *ah = wmi->drv_priv->ah; | ||
271 | struct ath_common *common = ath9k_hw_common(ah); | ||
272 | u16 headroom = sizeof(struct htc_frame_hdr) + | ||
273 | sizeof(struct wmi_cmd_hdr); | ||
274 | struct sk_buff *skb; | ||
275 | u8 *data; | ||
276 | int time_left, ret = 0; | ||
277 | unsigned long flags; | ||
278 | |||
279 | if (wmi->drv_priv->op_flags & OP_UNPLUGGED) | ||
280 | return 0; | ||
281 | |||
282 | if (!wmi) | ||
283 | return -EINVAL; | ||
284 | |||
285 | skb = alloc_skb(headroom + cmd_len, GFP_ATOMIC); | ||
286 | if (!skb) | ||
287 | return -ENOMEM; | ||
288 | |||
289 | skb_reserve(skb, headroom); | ||
290 | |||
291 | if (cmd_len != 0 && cmd_buf != NULL) { | ||
292 | data = (u8 *) skb_put(skb, cmd_len); | ||
293 | memcpy(data, cmd_buf, cmd_len); | ||
294 | } | ||
295 | |||
296 | mutex_lock(&wmi->op_mutex); | ||
297 | |||
298 | /* check if wmi stopped flag is set */ | ||
299 | if (unlikely(wmi->stopped)) { | ||
300 | ret = -EPROTO; | ||
301 | goto out; | ||
302 | } | ||
303 | |||
304 | /* record the rsp buffer and length */ | ||
305 | wmi->cmd_rsp_buf = rsp_buf; | ||
306 | wmi->cmd_rsp_len = rsp_len; | ||
307 | |||
308 | spin_lock_irqsave(&wmi->wmi_lock, flags); | ||
309 | wmi->last_cmd_id = cmd_id; | ||
310 | spin_unlock_irqrestore(&wmi->wmi_lock, flags); | ||
311 | |||
312 | ret = ath9k_wmi_cmd_issue(wmi, skb, cmd_id, cmd_len); | ||
313 | if (ret) | ||
314 | goto out; | ||
315 | |||
316 | time_left = wait_for_completion_timeout(&wmi->cmd_wait, timeout); | ||
317 | if (!time_left) { | ||
318 | ath_print(common, ATH_DBG_WMI, | ||
319 | "Timeout waiting for WMI command: %s\n", | ||
320 | wmi_cmd_to_name(cmd_id)); | ||
321 | mutex_unlock(&wmi->op_mutex); | ||
322 | return -ETIMEDOUT; | ||
323 | } | ||
324 | |||
325 | mutex_unlock(&wmi->op_mutex); | ||
326 | |||
327 | return 0; | ||
328 | |||
329 | out: | ||
330 | ath_print(common, ATH_DBG_WMI, | ||
331 | "WMI failure for: %s\n", wmi_cmd_to_name(cmd_id)); | ||
332 | mutex_unlock(&wmi->op_mutex); | ||
333 | kfree_skb(skb); | ||
334 | |||
335 | return ret; | ||
336 | } | ||
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h new file mode 100644 index 000000000000..765db5faa2d3 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/wmi.h | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Atheros Communications Inc. | ||
3 | * | ||
4 | * Permission to use, copy, modify, and/or distribute this software for any | ||
5 | * purpose with or without fee is hereby granted, provided that the above | ||
6 | * copyright notice and this permission notice appear in all copies. | ||
7 | * | ||
8 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
9 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
10 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
11 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
12 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
13 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
15 | */ | ||
16 | |||
17 | #ifndef WMI_H | ||
18 | #define WMI_H | ||
19 | |||
20 | |||
21 | struct wmi_event_txrate { | ||
22 | __be32 txrate; | ||
23 | struct { | ||
24 | u8 rssi_thresh; | ||
25 | u8 per; | ||
26 | } rc_stats; | ||
27 | } __packed; | ||
28 | |||
29 | struct wmi_cmd_hdr { | ||
30 | __be16 command_id; | ||
31 | __be16 seq_no; | ||
32 | } __packed; | ||
33 | |||
34 | struct wmi_swba { | ||
35 | u8 beacon_pending; | ||
36 | } __packed; | ||
37 | |||
38 | enum wmi_cmd_id { | ||
39 | WMI_ECHO_CMDID = 0x0001, | ||
40 | WMI_ACCESS_MEMORY_CMDID, | ||
41 | |||
42 | /* Commands to Target */ | ||
43 | WMI_DISABLE_INTR_CMDID, | ||
44 | WMI_ENABLE_INTR_CMDID, | ||
45 | WMI_RX_LINK_CMDID, | ||
46 | WMI_ATH_INIT_CMDID, | ||
47 | WMI_ABORT_TXQ_CMDID, | ||
48 | WMI_STOP_TX_DMA_CMDID, | ||
49 | WMI_STOP_DMA_RECV_CMDID, | ||
50 | WMI_ABORT_TX_DMA_CMDID, | ||
51 | WMI_DRAIN_TXQ_CMDID, | ||
52 | WMI_DRAIN_TXQ_ALL_CMDID, | ||
53 | WMI_START_RECV_CMDID, | ||
54 | WMI_STOP_RECV_CMDID, | ||
55 | WMI_FLUSH_RECV_CMDID, | ||
56 | WMI_SET_MODE_CMDID, | ||
57 | WMI_RESET_CMDID, | ||
58 | WMI_NODE_CREATE_CMDID, | ||
59 | WMI_NODE_REMOVE_CMDID, | ||
60 | WMI_VAP_REMOVE_CMDID, | ||
61 | WMI_VAP_CREATE_CMDID, | ||
62 | WMI_BEACON_UPDATE_CMDID, | ||
63 | WMI_REG_READ_CMDID, | ||
64 | WMI_REG_WRITE_CMDID, | ||
65 | WMI_RC_STATE_CHANGE_CMDID, | ||
66 | WMI_RC_RATE_UPDATE_CMDID, | ||
67 | WMI_DEBUG_INFO_CMDID, | ||
68 | WMI_HOST_ATTACH, | ||
69 | WMI_TARGET_IC_UPDATE_CMDID, | ||
70 | WMI_TGT_STATS_CMDID, | ||
71 | WMI_TX_AGGR_ENABLE_CMDID, | ||
72 | WMI_TGT_DETACH_CMDID, | ||
73 | WMI_TGT_TXQ_ENABLE_CMDID, | ||
74 | }; | ||
75 | |||
76 | enum wmi_event_id { | ||
77 | WMI_TGT_RDY_EVENTID = 0x1001, | ||
78 | WMI_SWBA_EVENTID, | ||
79 | WMI_FATAL_EVENTID, | ||
80 | WMI_TXTO_EVENTID, | ||
81 | WMI_BMISS_EVENTID, | ||
82 | WMI_WLAN_TXCOMP_EVENTID, | ||
83 | WMI_DELBA_EVENTID, | ||
84 | WMI_TXRATE_EVENTID, | ||
85 | }; | ||
86 | |||
87 | #define MAX_CMD_NUMBER 62 | ||
88 | |||
89 | struct register_write { | ||
90 | __be32 reg; | ||
91 | __be32 val; | ||
92 | }; | ||
93 | |||
94 | struct wmi { | ||
95 | struct ath9k_htc_priv *drv_priv; | ||
96 | struct htc_target *htc; | ||
97 | enum htc_endpoint_id ctrl_epid; | ||
98 | struct mutex op_mutex; | ||
99 | struct completion cmd_wait; | ||
100 | enum wmi_cmd_id last_cmd_id; | ||
101 | u16 tx_seq_id; | ||
102 | u8 *cmd_rsp_buf; | ||
103 | u32 cmd_rsp_len; | ||
104 | bool stopped; | ||
105 | |||
106 | struct sk_buff *wmi_skb; | ||
107 | spinlock_t wmi_lock; | ||
108 | |||
109 | atomic_t mwrite_cnt; | ||
110 | struct register_write multi_write[MAX_CMD_NUMBER]; | ||
111 | u32 multi_write_idx; | ||
112 | struct mutex multi_write_mutex; | ||
113 | }; | ||
114 | |||
115 | struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv); | ||
116 | void ath9k_deinit_wmi(struct ath9k_htc_priv *priv); | ||
117 | int ath9k_wmi_connect(struct htc_target *htc, struct wmi *wmi, | ||
118 | enum htc_endpoint_id *wmi_ctrl_epid); | ||
119 | int ath9k_wmi_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id, | ||
120 | u8 *cmd_buf, u32 cmd_len, | ||
121 | u8 *rsp_buf, u32 rsp_len, | ||
122 | u32 timeout); | ||
123 | void ath9k_wmi_tasklet(unsigned long data); | ||
124 | |||
125 | #define WMI_CMD(_wmi_cmd) \ | ||
126 | do { \ | ||
127 | ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, NULL, 0, \ | ||
128 | (u8 *) &cmd_rsp, \ | ||
129 | sizeof(cmd_rsp), HZ*2); \ | ||
130 | } while (0) | ||
131 | |||
132 | #define WMI_CMD_BUF(_wmi_cmd, _buf) \ | ||
133 | do { \ | ||
134 | ret = ath9k_wmi_cmd(priv->wmi, _wmi_cmd, \ | ||
135 | (u8 *) _buf, sizeof(*_buf), \ | ||
136 | &cmd_rsp, sizeof(cmd_rsp), HZ*2); \ | ||
137 | } while (0) | ||
138 | |||
139 | #endif /* WMI_H */ | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 294b486bc3ed..3db19172b43b 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -15,10 +15,11 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include "ath9k.h" | 17 | #include "ath9k.h" |
18 | #include "ar9003_mac.h" | ||
18 | 19 | ||
19 | #define BITS_PER_BYTE 8 | 20 | #define BITS_PER_BYTE 8 |
20 | #define OFDM_PLCP_BITS 22 | 21 | #define OFDM_PLCP_BITS 22 |
21 | #define HT_RC_2_MCS(_rc) ((_rc) & 0x0f) | 22 | #define HT_RC_2_MCS(_rc) ((_rc) & 0x1f) |
22 | #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) | 23 | #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) |
23 | #define L_STF 8 | 24 | #define L_STF 8 |
24 | #define L_LTF 8 | 25 | #define L_LTF 8 |
@@ -33,7 +34,7 @@ | |||
33 | 34 | ||
34 | #define OFDM_SIFS_TIME 16 | 35 | #define OFDM_SIFS_TIME 16 |
35 | 36 | ||
36 | static u32 bits_per_symbol[][2] = { | 37 | static u16 bits_per_symbol[][2] = { |
37 | /* 20MHz 40MHz */ | 38 | /* 20MHz 40MHz */ |
38 | { 26, 54 }, /* 0: BPSK */ | 39 | { 26, 54 }, /* 0: BPSK */ |
39 | { 52, 108 }, /* 1: QPSK 1/2 */ | 40 | { 52, 108 }, /* 1: QPSK 1/2 */ |
@@ -43,14 +44,6 @@ static u32 bits_per_symbol[][2] = { | |||
43 | { 208, 432 }, /* 5: 64-QAM 2/3 */ | 44 | { 208, 432 }, /* 5: 64-QAM 2/3 */ |
44 | { 234, 486 }, /* 6: 64-QAM 3/4 */ | 45 | { 234, 486 }, /* 6: 64-QAM 3/4 */ |
45 | { 260, 540 }, /* 7: 64-QAM 5/6 */ | 46 | { 260, 540 }, /* 7: 64-QAM 5/6 */ |
46 | { 52, 108 }, /* 8: BPSK */ | ||
47 | { 104, 216 }, /* 9: QPSK 1/2 */ | ||
48 | { 156, 324 }, /* 10: QPSK 3/4 */ | ||
49 | { 208, 432 }, /* 11: 16-QAM 1/2 */ | ||
50 | { 312, 648 }, /* 12: 16-QAM 3/4 */ | ||
51 | { 416, 864 }, /* 13: 64-QAM 2/3 */ | ||
52 | { 468, 972 }, /* 14: 64-QAM 3/4 */ | ||
53 | { 520, 1080 }, /* 15: 64-QAM 5/6 */ | ||
54 | }; | 47 | }; |
55 | 48 | ||
56 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) | 49 | #define IS_HT_RATE(_rate) ((_rate) & 0x80) |
@@ -59,40 +52,50 @@ static void ath_tx_send_ht_normal(struct ath_softc *sc, struct ath_txq *txq, | |||
59 | struct ath_atx_tid *tid, | 52 | struct ath_atx_tid *tid, |
60 | struct list_head *bf_head); | 53 | struct list_head *bf_head); |
61 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 54 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
62 | struct ath_txq *txq, | 55 | struct ath_txq *txq, struct list_head *bf_q, |
63 | struct list_head *bf_q, | 56 | struct ath_tx_status *ts, int txok, int sendbar); |
64 | int txok, int sendbar); | ||
65 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | 57 | static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, |
66 | struct list_head *head); | 58 | struct list_head *head); |
67 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); | 59 | static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf); |
68 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | 60 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, |
69 | int txok); | 61 | struct ath_tx_status *ts, int txok); |
70 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | 62 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, |
71 | int nbad, int txok, bool update_rc); | 63 | int nbad, int txok, bool update_rc); |
72 | 64 | ||
73 | enum { | 65 | enum { |
74 | MCS_DEFAULT, | 66 | MCS_HT20, |
67 | MCS_HT20_SGI, | ||
75 | MCS_HT40, | 68 | MCS_HT40, |
76 | MCS_HT40_SGI, | 69 | MCS_HT40_SGI, |
77 | }; | 70 | }; |
78 | 71 | ||
79 | static int ath_max_4ms_framelen[3][16] = { | 72 | static int ath_max_4ms_framelen[4][32] = { |
80 | [MCS_DEFAULT] = { | 73 | [MCS_HT20] = { |
81 | 3216, 6434, 9650, 12868, 19304, 25740, 28956, 32180, | 74 | 3212, 6432, 9648, 12864, 19300, 25736, 28952, 32172, |
82 | 6430, 12860, 19300, 25736, 38600, 51472, 57890, 64320, | 75 | 6424, 12852, 19280, 25708, 38568, 51424, 57852, 64280, |
76 | 9628, 19260, 28896, 38528, 57792, 65532, 65532, 65532, | ||
77 | 12828, 25656, 38488, 51320, 65532, 65532, 65532, 65532, | ||
78 | }, | ||
79 | [MCS_HT20_SGI] = { | ||
80 | 3572, 7144, 10720, 14296, 21444, 28596, 32172, 35744, | ||
81 | 7140, 14284, 21428, 28568, 42856, 57144, 64288, 65532, | ||
82 | 10700, 21408, 32112, 42816, 64228, 65532, 65532, 65532, | ||
83 | 14256, 28516, 42780, 57040, 65532, 65532, 65532, 65532, | ||
83 | }, | 84 | }, |
84 | [MCS_HT40] = { | 85 | [MCS_HT40] = { |
85 | 6684, 13368, 20052, 26738, 40104, 53476, 60156, 66840, | 86 | 6680, 13360, 20044, 26724, 40092, 53456, 60140, 65532, |
86 | 13360, 26720, 40080, 53440, 80160, 106880, 120240, 133600, | 87 | 13348, 26700, 40052, 53400, 65532, 65532, 65532, 65532, |
88 | 20004, 40008, 60016, 65532, 65532, 65532, 65532, 65532, | ||
89 | 26644, 53292, 65532, 65532, 65532, 65532, 65532, 65532, | ||
87 | }, | 90 | }, |
88 | [MCS_HT40_SGI] = { | 91 | [MCS_HT40_SGI] = { |
89 | /* TODO: Only MCS 7 and 15 updated, recalculate the rest */ | 92 | 7420, 14844, 22272, 29696, 44544, 59396, 65532, 65532, |
90 | 6684, 13368, 20052, 26738, 40104, 53476, 60156, 74200, | 93 | 14832, 29668, 44504, 59340, 65532, 65532, 65532, 65532, |
91 | 13360, 26720, 40080, 53440, 80160, 106880, 120240, 148400, | 94 | 22232, 44464, 65532, 65532, 65532, 65532, 65532, 65532, |
95 | 29616, 59232, 65532, 65532, 65532, 65532, 65532, 65532, | ||
92 | } | 96 | } |
93 | }; | 97 | }; |
94 | 98 | ||
95 | |||
96 | /*********************/ | 99 | /*********************/ |
97 | /* Aggregation logic */ | 100 | /* Aggregation logic */ |
98 | /*********************/ | 101 | /*********************/ |
@@ -223,6 +226,9 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | |||
223 | { | 226 | { |
224 | struct ath_buf *bf; | 227 | struct ath_buf *bf; |
225 | struct list_head bf_head; | 228 | struct list_head bf_head; |
229 | struct ath_tx_status ts; | ||
230 | |||
231 | memset(&ts, 0, sizeof(ts)); | ||
226 | INIT_LIST_HEAD(&bf_head); | 232 | INIT_LIST_HEAD(&bf_head); |
227 | 233 | ||
228 | for (;;) { | 234 | for (;;) { |
@@ -236,7 +242,7 @@ static void ath_tid_drain(struct ath_softc *sc, struct ath_txq *txq, | |||
236 | ath_tx_update_baw(sc, tid, bf->bf_seqno); | 242 | ath_tx_update_baw(sc, tid, bf->bf_seqno); |
237 | 243 | ||
238 | spin_unlock(&txq->axq_lock); | 244 | spin_unlock(&txq->axq_lock); |
239 | ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); | 245 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
240 | spin_lock(&txq->axq_lock); | 246 | spin_lock(&txq->axq_lock); |
241 | } | 247 | } |
242 | 248 | ||
@@ -259,25 +265,46 @@ static void ath_tx_set_retry(struct ath_softc *sc, struct ath_txq *txq, | |||
259 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); | 265 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY); |
260 | } | 266 | } |
261 | 267 | ||
262 | static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | 268 | static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) |
263 | { | 269 | { |
264 | struct ath_buf *tbf; | 270 | struct ath_buf *bf = NULL; |
265 | 271 | ||
266 | spin_lock_bh(&sc->tx.txbuflock); | 272 | spin_lock_bh(&sc->tx.txbuflock); |
267 | if (WARN_ON(list_empty(&sc->tx.txbuf))) { | 273 | |
274 | if (unlikely(list_empty(&sc->tx.txbuf))) { | ||
268 | spin_unlock_bh(&sc->tx.txbuflock); | 275 | spin_unlock_bh(&sc->tx.txbuflock); |
269 | return NULL; | 276 | return NULL; |
270 | } | 277 | } |
271 | tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | 278 | |
272 | list_del(&tbf->list); | 279 | bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); |
280 | list_del(&bf->list); | ||
281 | |||
273 | spin_unlock_bh(&sc->tx.txbuflock); | 282 | spin_unlock_bh(&sc->tx.txbuflock); |
274 | 283 | ||
284 | return bf; | ||
285 | } | ||
286 | |||
287 | static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf) | ||
288 | { | ||
289 | spin_lock_bh(&sc->tx.txbuflock); | ||
290 | list_add_tail(&bf->list, &sc->tx.txbuf); | ||
291 | spin_unlock_bh(&sc->tx.txbuflock); | ||
292 | } | ||
293 | |||
294 | static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | ||
295 | { | ||
296 | struct ath_buf *tbf; | ||
297 | |||
298 | tbf = ath_tx_get_buffer(sc); | ||
299 | if (WARN_ON(!tbf)) | ||
300 | return NULL; | ||
301 | |||
275 | ATH_TXBUF_RESET(tbf); | 302 | ATH_TXBUF_RESET(tbf); |
276 | 303 | ||
277 | tbf->aphy = bf->aphy; | 304 | tbf->aphy = bf->aphy; |
278 | tbf->bf_mpdu = bf->bf_mpdu; | 305 | tbf->bf_mpdu = bf->bf_mpdu; |
279 | tbf->bf_buf_addr = bf->bf_buf_addr; | 306 | tbf->bf_buf_addr = bf->bf_buf_addr; |
280 | *(tbf->bf_desc) = *(bf->bf_desc); | 307 | memcpy(tbf->bf_desc, bf->bf_desc, sc->sc_ah->caps.tx_desc_len); |
281 | tbf->bf_state = bf->bf_state; | 308 | tbf->bf_state = bf->bf_state; |
282 | tbf->bf_dmacontext = bf->bf_dmacontext; | 309 | tbf->bf_dmacontext = bf->bf_dmacontext; |
283 | 310 | ||
@@ -286,7 +313,7 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf) | |||
286 | 313 | ||
287 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | 314 | static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, |
288 | struct ath_buf *bf, struct list_head *bf_q, | 315 | struct ath_buf *bf, struct list_head *bf_q, |
289 | int txok) | 316 | struct ath_tx_status *ts, int txok) |
290 | { | 317 | { |
291 | struct ath_node *an = NULL; | 318 | struct ath_node *an = NULL; |
292 | struct sk_buff *skb; | 319 | struct sk_buff *skb; |
@@ -296,7 +323,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
296 | struct ieee80211_tx_info *tx_info; | 323 | struct ieee80211_tx_info *tx_info; |
297 | struct ath_atx_tid *tid = NULL; | 324 | struct ath_atx_tid *tid = NULL; |
298 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; | 325 | struct ath_buf *bf_next, *bf_last = bf->bf_lastbf; |
299 | struct ath_desc *ds = bf_last->bf_desc; | ||
300 | struct list_head bf_head, bf_pending; | 326 | struct list_head bf_head, bf_pending; |
301 | u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; | 327 | u16 seq_st = 0, acked_cnt = 0, txfail_cnt = 0; |
302 | u32 ba[WME_BA_BMP_SIZE >> 5]; | 328 | u32 ba[WME_BA_BMP_SIZE >> 5]; |
@@ -325,10 +351,9 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
325 | memset(ba, 0, WME_BA_BMP_SIZE >> 3); | 351 | memset(ba, 0, WME_BA_BMP_SIZE >> 3); |
326 | 352 | ||
327 | if (isaggr && txok) { | 353 | if (isaggr && txok) { |
328 | if (ATH_DS_TX_BA(ds)) { | 354 | if (ts->ts_flags & ATH9K_TX_BA) { |
329 | seq_st = ATH_DS_BA_SEQ(ds); | 355 | seq_st = ts->ts_seqnum; |
330 | memcpy(ba, ATH_DS_BA_BITMAP(ds), | 356 | memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); |
331 | WME_BA_BMP_SIZE >> 3); | ||
332 | } else { | 357 | } else { |
333 | /* | 358 | /* |
334 | * AR5416 can become deaf/mute when BA | 359 | * AR5416 can become deaf/mute when BA |
@@ -345,7 +370,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
345 | INIT_LIST_HEAD(&bf_pending); | 370 | INIT_LIST_HEAD(&bf_pending); |
346 | INIT_LIST_HEAD(&bf_head); | 371 | INIT_LIST_HEAD(&bf_head); |
347 | 372 | ||
348 | nbad = ath_tx_num_badfrms(sc, bf, txok); | 373 | nbad = ath_tx_num_badfrms(sc, bf, ts, txok); |
349 | while (bf) { | 374 | while (bf) { |
350 | txfail = txpending = 0; | 375 | txfail = txpending = 0; |
351 | bf_next = bf->bf_next; | 376 | bf_next = bf->bf_next; |
@@ -359,7 +384,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
359 | acked_cnt++; | 384 | acked_cnt++; |
360 | } else { | 385 | } else { |
361 | if (!(tid->state & AGGR_CLEANUP) && | 386 | if (!(tid->state & AGGR_CLEANUP) && |
362 | ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) { | 387 | !bf_last->bf_tx_aborted) { |
363 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { | 388 | if (bf->bf_retries < ATH_MAX_SW_RETRIES) { |
364 | ath_tx_set_retry(sc, txq, bf); | 389 | ath_tx_set_retry(sc, txq, bf); |
365 | txpending = 1; | 390 | txpending = 1; |
@@ -378,7 +403,8 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
378 | } | 403 | } |
379 | } | 404 | } |
380 | 405 | ||
381 | if (bf_next == NULL) { | 406 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) && |
407 | bf_next == NULL) { | ||
382 | /* | 408 | /* |
383 | * Make sure the last desc is reclaimed if it | 409 | * Make sure the last desc is reclaimed if it |
384 | * not a holding desc. | 410 | * not a holding desc. |
@@ -402,45 +428,53 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, | |||
402 | spin_unlock_bh(&txq->axq_lock); | 428 | spin_unlock_bh(&txq->axq_lock); |
403 | 429 | ||
404 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { | 430 | if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { |
405 | ath_tx_rc_status(bf, ds, nbad, txok, true); | 431 | ath_tx_rc_status(bf, ts, nbad, txok, true); |
406 | rc_update = false; | 432 | rc_update = false; |
407 | } else { | 433 | } else { |
408 | ath_tx_rc_status(bf, ds, nbad, txok, false); | 434 | ath_tx_rc_status(bf, ts, nbad, txok, false); |
409 | } | 435 | } |
410 | 436 | ||
411 | ath_tx_complete_buf(sc, bf, txq, &bf_head, !txfail, sendbar); | 437 | ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, |
438 | !txfail, sendbar); | ||
412 | } else { | 439 | } else { |
413 | /* retry the un-acked ones */ | 440 | /* retry the un-acked ones */ |
414 | if (bf->bf_next == NULL && bf_last->bf_stale) { | 441 | if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) { |
415 | struct ath_buf *tbf; | 442 | if (bf->bf_next == NULL && bf_last->bf_stale) { |
416 | 443 | struct ath_buf *tbf; | |
417 | tbf = ath_clone_txbuf(sc, bf_last); | 444 | |
418 | /* | 445 | tbf = ath_clone_txbuf(sc, bf_last); |
419 | * Update tx baw and complete the frame with | 446 | /* |
420 | * failed status if we run out of tx buf | 447 | * Update tx baw and complete the |
421 | */ | 448 | * frame with failed status if we |
422 | if (!tbf) { | 449 | * run out of tx buf. |
423 | spin_lock_bh(&txq->axq_lock); | 450 | */ |
424 | ath_tx_update_baw(sc, tid, | 451 | if (!tbf) { |
425 | bf->bf_seqno); | 452 | spin_lock_bh(&txq->axq_lock); |
426 | spin_unlock_bh(&txq->axq_lock); | 453 | ath_tx_update_baw(sc, tid, |
427 | 454 | bf->bf_seqno); | |
428 | bf->bf_state.bf_type |= BUF_XRETRY; | 455 | spin_unlock_bh(&txq->axq_lock); |
429 | ath_tx_rc_status(bf, ds, nbad, | 456 | |
430 | 0, false); | 457 | bf->bf_state.bf_type |= |
431 | ath_tx_complete_buf(sc, bf, txq, | 458 | BUF_XRETRY; |
432 | &bf_head, 0, 0); | 459 | ath_tx_rc_status(bf, ts, nbad, |
433 | break; | 460 | 0, false); |
461 | ath_tx_complete_buf(sc, bf, txq, | ||
462 | &bf_head, | ||
463 | ts, 0, 0); | ||
464 | break; | ||
465 | } | ||
466 | |||
467 | ath9k_hw_cleartxdesc(sc->sc_ah, | ||
468 | tbf->bf_desc); | ||
469 | list_add_tail(&tbf->list, &bf_head); | ||
470 | } else { | ||
471 | /* | ||
472 | * Clear descriptor status words for | ||
473 | * software retry | ||
474 | */ | ||
475 | ath9k_hw_cleartxdesc(sc->sc_ah, | ||
476 | bf->bf_desc); | ||
434 | } | 477 | } |
435 | |||
436 | ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc); | ||
437 | list_add_tail(&tbf->list, &bf_head); | ||
438 | } else { | ||
439 | /* | ||
440 | * Clear descriptor status words for | ||
441 | * software retry | ||
442 | */ | ||
443 | ath9k_hw_cleartxdesc(sc->sc_ah, bf->bf_desc); | ||
444 | } | 478 | } |
445 | 479 | ||
446 | /* | 480 | /* |
@@ -508,12 +542,13 @@ static u32 ath_lookup_rate(struct ath_softc *sc, struct ath_buf *bf, | |||
508 | break; | 542 | break; |
509 | } | 543 | } |
510 | 544 | ||
511 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) | 545 | if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) |
512 | modeidx = MCS_HT40_SGI; | ||
513 | else if (rates[i].flags & IEEE80211_TX_RC_40_MHZ_WIDTH) | ||
514 | modeidx = MCS_HT40; | 546 | modeidx = MCS_HT40; |
515 | else | 547 | else |
516 | modeidx = MCS_DEFAULT; | 548 | modeidx = MCS_HT20; |
549 | |||
550 | if (rates[i].flags & IEEE80211_TX_RC_SHORT_GI) | ||
551 | modeidx++; | ||
517 | 552 | ||
518 | frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx]; | 553 | frmlen = ath_max_4ms_framelen[modeidx][rates[i].idx]; |
519 | max_4ms_framelen = min(max_4ms_framelen, frmlen); | 554 | max_4ms_framelen = min(max_4ms_framelen, frmlen); |
@@ -558,7 +593,7 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
558 | u32 nsymbits, nsymbols; | 593 | u32 nsymbits, nsymbols; |
559 | u16 minlen; | 594 | u16 minlen; |
560 | u8 flags, rix; | 595 | u8 flags, rix; |
561 | int width, half_gi, ndelim, mindelim; | 596 | int width, streams, half_gi, ndelim, mindelim; |
562 | 597 | ||
563 | /* Select standard number of delimiters based on frame length alone */ | 598 | /* Select standard number of delimiters based on frame length alone */ |
564 | ndelim = ATH_AGGR_GET_NDELIM(frmlen); | 599 | ndelim = ATH_AGGR_GET_NDELIM(frmlen); |
@@ -598,7 +633,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
598 | if (nsymbols == 0) | 633 | if (nsymbols == 0) |
599 | nsymbols = 1; | 634 | nsymbols = 1; |
600 | 635 | ||
601 | nsymbits = bits_per_symbol[rix][width]; | 636 | streams = HT_RC_2_STREAMS(rix); |
637 | nsymbits = bits_per_symbol[rix % 8][width] * streams; | ||
602 | minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; | 638 | minlen = (nsymbols * nsymbits) / BITS_PER_BYTE; |
603 | 639 | ||
604 | if (frmlen < minlen) { | 640 | if (frmlen < minlen) { |
@@ -664,7 +700,7 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
664 | bpad = PADBYTES(al_delta) + (ndelim << 2); | 700 | bpad = PADBYTES(al_delta) + (ndelim << 2); |
665 | 701 | ||
666 | bf->bf_next = NULL; | 702 | bf->bf_next = NULL; |
667 | bf->bf_desc->ds_link = 0; | 703 | ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, 0); |
668 | 704 | ||
669 | /* link buffers of this frame to the aggregate */ | 705 | /* link buffers of this frame to the aggregate */ |
670 | ath_tx_addto_baw(sc, tid, bf); | 706 | ath_tx_addto_baw(sc, tid, bf); |
@@ -672,7 +708,8 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc, | |||
672 | list_move_tail(&bf->list, bf_q); | 708 | list_move_tail(&bf->list, bf_q); |
673 | if (bf_prev) { | 709 | if (bf_prev) { |
674 | bf_prev->bf_next = bf; | 710 | bf_prev->bf_next = bf; |
675 | bf_prev->bf_desc->ds_link = bf->bf_daddr; | 711 | ath9k_hw_set_desc_link(sc->sc_ah, bf_prev->bf_desc, |
712 | bf->bf_daddr); | ||
676 | } | 713 | } |
677 | bf_prev = bf; | 714 | bf_prev = bf; |
678 | 715 | ||
@@ -752,8 +789,11 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
752 | struct ath_node *an = (struct ath_node *)sta->drv_priv; | 789 | struct ath_node *an = (struct ath_node *)sta->drv_priv; |
753 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); | 790 | struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid); |
754 | struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; | 791 | struct ath_txq *txq = &sc->tx.txq[txtid->ac->qnum]; |
792 | struct ath_tx_status ts; | ||
755 | struct ath_buf *bf; | 793 | struct ath_buf *bf; |
756 | struct list_head bf_head; | 794 | struct list_head bf_head; |
795 | |||
796 | memset(&ts, 0, sizeof(ts)); | ||
757 | INIT_LIST_HEAD(&bf_head); | 797 | INIT_LIST_HEAD(&bf_head); |
758 | 798 | ||
759 | if (txtid->state & AGGR_CLEANUP) | 799 | if (txtid->state & AGGR_CLEANUP) |
@@ -780,7 +820,7 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
780 | } | 820 | } |
781 | list_move_tail(&bf->list, &bf_head); | 821 | list_move_tail(&bf->list, &bf_head); |
782 | ath_tx_update_baw(sc, txtid, bf->bf_seqno); | 822 | ath_tx_update_baw(sc, txtid, bf->bf_seqno); |
783 | ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); | 823 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
784 | } | 824 | } |
785 | spin_unlock_bh(&txq->axq_lock); | 825 | spin_unlock_bh(&txq->axq_lock); |
786 | 826 | ||
@@ -849,7 +889,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
849 | struct ath_hw *ah = sc->sc_ah; | 889 | struct ath_hw *ah = sc->sc_ah; |
850 | struct ath_common *common = ath9k_hw_common(ah); | 890 | struct ath_common *common = ath9k_hw_common(ah); |
851 | struct ath9k_tx_queue_info qi; | 891 | struct ath9k_tx_queue_info qi; |
852 | int qnum; | 892 | int qnum, i; |
853 | 893 | ||
854 | memset(&qi, 0, sizeof(qi)); | 894 | memset(&qi, 0, sizeof(qi)); |
855 | qi.tqi_subtype = subtype; | 895 | qi.tqi_subtype = subtype; |
@@ -873,11 +913,16 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
873 | * The UAPSD queue is an exception, since we take a desc- | 913 | * The UAPSD queue is an exception, since we take a desc- |
874 | * based intr on the EOSP frames. | 914 | * based intr on the EOSP frames. |
875 | */ | 915 | */ |
876 | if (qtype == ATH9K_TX_QUEUE_UAPSD) | 916 | if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
877 | qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; | 917 | qi.tqi_qflags = TXQ_FLAG_TXOKINT_ENABLE | |
878 | else | 918 | TXQ_FLAG_TXERRINT_ENABLE; |
879 | qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | | 919 | } else { |
880 | TXQ_FLAG_TXDESCINT_ENABLE; | 920 | if (qtype == ATH9K_TX_QUEUE_UAPSD) |
921 | qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE; | ||
922 | else | ||
923 | qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE | | ||
924 | TXQ_FLAG_TXDESCINT_ENABLE; | ||
925 | } | ||
881 | qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi); | 926 | qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi); |
882 | if (qnum == -1) { | 927 | if (qnum == -1) { |
883 | /* | 928 | /* |
@@ -904,6 +949,11 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype) | |||
904 | txq->axq_depth = 0; | 949 | txq->axq_depth = 0; |
905 | txq->axq_tx_inprogress = false; | 950 | txq->axq_tx_inprogress = false; |
906 | sc->tx.txqsetup |= 1<<qnum; | 951 | sc->tx.txqsetup |= 1<<qnum; |
952 | |||
953 | txq->txq_headidx = txq->txq_tailidx = 0; | ||
954 | for (i = 0; i < ATH_TXFIFO_DEPTH; i++) | ||
955 | INIT_LIST_HEAD(&txq->txq_fifo[i]); | ||
956 | INIT_LIST_HEAD(&txq->txq_fifo_pending); | ||
907 | } | 957 | } |
908 | return &sc->tx.txq[qnum]; | 958 | return &sc->tx.txq[qnum]; |
909 | } | 959 | } |
@@ -1028,45 +1078,63 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1028 | { | 1078 | { |
1029 | struct ath_buf *bf, *lastbf; | 1079 | struct ath_buf *bf, *lastbf; |
1030 | struct list_head bf_head; | 1080 | struct list_head bf_head; |
1081 | struct ath_tx_status ts; | ||
1031 | 1082 | ||
1083 | memset(&ts, 0, sizeof(ts)); | ||
1032 | INIT_LIST_HEAD(&bf_head); | 1084 | INIT_LIST_HEAD(&bf_head); |
1033 | 1085 | ||
1034 | for (;;) { | 1086 | for (;;) { |
1035 | spin_lock_bh(&txq->axq_lock); | 1087 | spin_lock_bh(&txq->axq_lock); |
1036 | 1088 | ||
1037 | if (list_empty(&txq->axq_q)) { | 1089 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
1038 | txq->axq_link = NULL; | 1090 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { |
1039 | spin_unlock_bh(&txq->axq_lock); | 1091 | txq->txq_headidx = txq->txq_tailidx = 0; |
1040 | break; | 1092 | spin_unlock_bh(&txq->axq_lock); |
1041 | } | 1093 | break; |
1042 | 1094 | } else { | |
1043 | bf = list_first_entry(&txq->axq_q, struct ath_buf, list); | 1095 | bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], |
1096 | struct ath_buf, list); | ||
1097 | } | ||
1098 | } else { | ||
1099 | if (list_empty(&txq->axq_q)) { | ||
1100 | txq->axq_link = NULL; | ||
1101 | spin_unlock_bh(&txq->axq_lock); | ||
1102 | break; | ||
1103 | } | ||
1104 | bf = list_first_entry(&txq->axq_q, struct ath_buf, | ||
1105 | list); | ||
1044 | 1106 | ||
1045 | if (bf->bf_stale) { | 1107 | if (bf->bf_stale) { |
1046 | list_del(&bf->list); | 1108 | list_del(&bf->list); |
1047 | spin_unlock_bh(&txq->axq_lock); | 1109 | spin_unlock_bh(&txq->axq_lock); |
1048 | 1110 | ||
1049 | spin_lock_bh(&sc->tx.txbuflock); | 1111 | ath_tx_return_buffer(sc, bf); |
1050 | list_add_tail(&bf->list, &sc->tx.txbuf); | 1112 | continue; |
1051 | spin_unlock_bh(&sc->tx.txbuflock); | 1113 | } |
1052 | continue; | ||
1053 | } | 1114 | } |
1054 | 1115 | ||
1055 | lastbf = bf->bf_lastbf; | 1116 | lastbf = bf->bf_lastbf; |
1056 | if (!retry_tx) | 1117 | if (!retry_tx) |
1057 | lastbf->bf_desc->ds_txstat.ts_flags = | 1118 | lastbf->bf_tx_aborted = true; |
1058 | ATH9K_TX_SW_ABORTED; | 1119 | |
1120 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
1121 | list_cut_position(&bf_head, | ||
1122 | &txq->txq_fifo[txq->txq_tailidx], | ||
1123 | &lastbf->list); | ||
1124 | INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); | ||
1125 | } else { | ||
1126 | /* remove ath_buf's of the same mpdu from txq */ | ||
1127 | list_cut_position(&bf_head, &txq->axq_q, &lastbf->list); | ||
1128 | } | ||
1059 | 1129 | ||
1060 | /* remove ath_buf's of the same mpdu from txq */ | ||
1061 | list_cut_position(&bf_head, &txq->axq_q, &lastbf->list); | ||
1062 | txq->axq_depth--; | 1130 | txq->axq_depth--; |
1063 | 1131 | ||
1064 | spin_unlock_bh(&txq->axq_lock); | 1132 | spin_unlock_bh(&txq->axq_lock); |
1065 | 1133 | ||
1066 | if (bf_isampdu(bf)) | 1134 | if (bf_isampdu(bf)) |
1067 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, 0); | 1135 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, 0); |
1068 | else | 1136 | else |
1069 | ath_tx_complete_buf(sc, bf, txq, &bf_head, 0, 0); | 1137 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0); |
1070 | } | 1138 | } |
1071 | 1139 | ||
1072 | spin_lock_bh(&txq->axq_lock); | 1140 | spin_lock_bh(&txq->axq_lock); |
@@ -1081,6 +1149,27 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1081 | spin_unlock_bh(&txq->axq_lock); | 1149 | spin_unlock_bh(&txq->axq_lock); |
1082 | } | 1150 | } |
1083 | } | 1151 | } |
1152 | |||
1153 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
1154 | spin_lock_bh(&txq->axq_lock); | ||
1155 | while (!list_empty(&txq->txq_fifo_pending)) { | ||
1156 | bf = list_first_entry(&txq->txq_fifo_pending, | ||
1157 | struct ath_buf, list); | ||
1158 | list_cut_position(&bf_head, | ||
1159 | &txq->txq_fifo_pending, | ||
1160 | &bf->bf_lastbf->list); | ||
1161 | spin_unlock_bh(&txq->axq_lock); | ||
1162 | |||
1163 | if (bf_isampdu(bf)) | ||
1164 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, | ||
1165 | &ts, 0); | ||
1166 | else | ||
1167 | ath_tx_complete_buf(sc, bf, txq, &bf_head, | ||
1168 | &ts, 0, 0); | ||
1169 | spin_lock_bh(&txq->axq_lock); | ||
1170 | } | ||
1171 | spin_unlock_bh(&txq->axq_lock); | ||
1172 | } | ||
1084 | } | 1173 | } |
1085 | 1174 | ||
1086 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1175 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
@@ -1218,44 +1307,47 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq, | |||
1218 | 1307 | ||
1219 | bf = list_first_entry(head, struct ath_buf, list); | 1308 | bf = list_first_entry(head, struct ath_buf, list); |
1220 | 1309 | ||
1221 | list_splice_tail_init(head, &txq->axq_q); | ||
1222 | txq->axq_depth++; | ||
1223 | |||
1224 | ath_print(common, ATH_DBG_QUEUE, | 1310 | ath_print(common, ATH_DBG_QUEUE, |
1225 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); | 1311 | "qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth); |
1226 | 1312 | ||
1227 | if (txq->axq_link == NULL) { | 1313 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { |
1314 | if (txq->axq_depth >= ATH_TXFIFO_DEPTH) { | ||
1315 | list_splice_tail_init(head, &txq->txq_fifo_pending); | ||
1316 | return; | ||
1317 | } | ||
1318 | if (!list_empty(&txq->txq_fifo[txq->txq_headidx])) | ||
1319 | ath_print(common, ATH_DBG_XMIT, | ||
1320 | "Initializing tx fifo %d which " | ||
1321 | "is non-empty\n", | ||
1322 | txq->txq_headidx); | ||
1323 | INIT_LIST_HEAD(&txq->txq_fifo[txq->txq_headidx]); | ||
1324 | list_splice_init(head, &txq->txq_fifo[txq->txq_headidx]); | ||
1325 | INCR(txq->txq_headidx, ATH_TXFIFO_DEPTH); | ||
1228 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); | 1326 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); |
1229 | ath_print(common, ATH_DBG_XMIT, | 1327 | ath_print(common, ATH_DBG_XMIT, |
1230 | "TXDP[%u] = %llx (%p)\n", | 1328 | "TXDP[%u] = %llx (%p)\n", |
1231 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); | 1329 | txq->axq_qnum, ito64(bf->bf_daddr), bf->bf_desc); |
1232 | } else { | 1330 | } else { |
1233 | *txq->axq_link = bf->bf_daddr; | 1331 | list_splice_tail_init(head, &txq->axq_q); |
1234 | ath_print(common, ATH_DBG_XMIT, "link[%u] (%p)=%llx (%p)\n", | ||
1235 | txq->axq_qnum, txq->axq_link, | ||
1236 | ito64(bf->bf_daddr), bf->bf_desc); | ||
1237 | } | ||
1238 | txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link); | ||
1239 | ath9k_hw_txstart(ah, txq->axq_qnum); | ||
1240 | } | ||
1241 | 1332 | ||
1242 | static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc) | 1333 | if (txq->axq_link == NULL) { |
1243 | { | 1334 | ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); |
1244 | struct ath_buf *bf = NULL; | 1335 | ath_print(common, ATH_DBG_XMIT, |
1245 | 1336 | "TXDP[%u] = %llx (%p)\n", | |
1246 | spin_lock_bh(&sc->tx.txbuflock); | 1337 | txq->axq_qnum, ito64(bf->bf_daddr), |
1247 | 1338 | bf->bf_desc); | |
1248 | if (unlikely(list_empty(&sc->tx.txbuf))) { | 1339 | } else { |
1249 | spin_unlock_bh(&sc->tx.txbuflock); | 1340 | *txq->axq_link = bf->bf_daddr; |
1250 | return NULL; | 1341 | ath_print(common, ATH_DBG_XMIT, |
1342 | "link[%u] (%p)=%llx (%p)\n", | ||
1343 | txq->axq_qnum, txq->axq_link, | ||
1344 | ito64(bf->bf_daddr), bf->bf_desc); | ||
1345 | } | ||
1346 | ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc, | ||
1347 | &txq->axq_link); | ||
1348 | ath9k_hw_txstart(ah, txq->axq_qnum); | ||
1251 | } | 1349 | } |
1252 | 1350 | txq->axq_depth++; | |
1253 | bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); | ||
1254 | list_del(&bf->list); | ||
1255 | |||
1256 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1257 | |||
1258 | return bf; | ||
1259 | } | 1351 | } |
1260 | 1352 | ||
1261 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, | 1353 | static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid, |
@@ -1402,8 +1494,7 @@ static void assign_aggr_tid_seqno(struct sk_buff *skb, | |||
1402 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); | 1494 | INCR(tid->seq_next, IEEE80211_SEQ_MAX); |
1403 | } | 1495 | } |
1404 | 1496 | ||
1405 | static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, | 1497 | static int setup_tx_flags(struct sk_buff *skb, bool use_ldpc) |
1406 | struct ath_txq *txq) | ||
1407 | { | 1498 | { |
1408 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1499 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1409 | int flags = 0; | 1500 | int flags = 0; |
@@ -1414,6 +1505,9 @@ static int setup_tx_flags(struct ath_softc *sc, struct sk_buff *skb, | |||
1414 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) | 1505 | if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) |
1415 | flags |= ATH9K_TXDESC_NOACK; | 1506 | flags |= ATH9K_TXDESC_NOACK; |
1416 | 1507 | ||
1508 | if (use_ldpc) | ||
1509 | flags |= ATH9K_TXDESC_LDPC; | ||
1510 | |||
1417 | return flags; | 1511 | return flags; |
1418 | } | 1512 | } |
1419 | 1513 | ||
@@ -1432,8 +1526,9 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | |||
1432 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; | 1526 | pktlen = bf_isaggr(bf) ? bf->bf_al : bf->bf_frmlen; |
1433 | 1527 | ||
1434 | /* find number of symbols: PLCP + data */ | 1528 | /* find number of symbols: PLCP + data */ |
1529 | streams = HT_RC_2_STREAMS(rix); | ||
1435 | nbits = (pktlen << 3) + OFDM_PLCP_BITS; | 1530 | nbits = (pktlen << 3) + OFDM_PLCP_BITS; |
1436 | nsymbits = bits_per_symbol[rix][width]; | 1531 | nsymbits = bits_per_symbol[rix % 8][width] * streams; |
1437 | nsymbols = (nbits + nsymbits - 1) / nsymbits; | 1532 | nsymbols = (nbits + nsymbits - 1) / nsymbits; |
1438 | 1533 | ||
1439 | if (!half_gi) | 1534 | if (!half_gi) |
@@ -1442,7 +1537,6 @@ static u32 ath_pkt_duration(struct ath_softc *sc, u8 rix, struct ath_buf *bf, | |||
1442 | duration = SYMBOL_TIME_HALFGI(nsymbols); | 1537 | duration = SYMBOL_TIME_HALFGI(nsymbols); |
1443 | 1538 | ||
1444 | /* addup duration for legacy/ht training and signal fields */ | 1539 | /* addup duration for legacy/ht training and signal fields */ |
1445 | streams = HT_RC_2_STREAMS(rix); | ||
1446 | duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); | 1540 | duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams); |
1447 | 1541 | ||
1448 | return duration; | 1542 | return duration; |
@@ -1513,6 +1607,8 @@ static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf) | |||
1513 | series[i].Rate = rix | 0x80; | 1607 | series[i].Rate = rix | 0x80; |
1514 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, | 1608 | series[i].PktDuration = ath_pkt_duration(sc, rix, bf, |
1515 | is_40, is_sgi, is_sp); | 1609 | is_40, is_sgi, is_sp); |
1610 | if (rix < 8 && (tx_info->flags & IEEE80211_TX_CTL_STBC)) | ||
1611 | series[i].RateFlags |= ATH9K_RATESERIES_STBC; | ||
1516 | continue; | 1612 | continue; |
1517 | } | 1613 | } |
1518 | 1614 | ||
@@ -1565,15 +1661,16 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1565 | int hdrlen; | 1661 | int hdrlen; |
1566 | __le16 fc; | 1662 | __le16 fc; |
1567 | int padpos, padsize; | 1663 | int padpos, padsize; |
1664 | bool use_ldpc = false; | ||
1568 | 1665 | ||
1569 | tx_info->pad[0] = 0; | 1666 | tx_info->pad[0] = 0; |
1570 | switch (txctl->frame_type) { | 1667 | switch (txctl->frame_type) { |
1571 | case ATH9K_NOT_INTERNAL: | 1668 | case ATH9K_IFT_NOT_INTERNAL: |
1572 | break; | 1669 | break; |
1573 | case ATH9K_INT_PAUSE: | 1670 | case ATH9K_IFT_PAUSE: |
1574 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; | 1671 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_PAUSE; |
1575 | /* fall through */ | 1672 | /* fall through */ |
1576 | case ATH9K_INT_UNPAUSE: | 1673 | case ATH9K_IFT_UNPAUSE: |
1577 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; | 1674 | tx_info->pad[0] |= ATH_TX_INFO_FRAME_TYPE_INTERNAL; |
1578 | break; | 1675 | break; |
1579 | } | 1676 | } |
@@ -1591,10 +1688,13 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf, | |||
1591 | bf->bf_frmlen -= padsize; | 1688 | bf->bf_frmlen -= padsize; |
1592 | } | 1689 | } |
1593 | 1690 | ||
1594 | if (conf_is_ht(&hw->conf)) | 1691 | if (conf_is_ht(&hw->conf)) { |
1595 | bf->bf_state.bf_type |= BUF_HT; | 1692 | bf->bf_state.bf_type |= BUF_HT; |
1693 | if (tx_info->flags & IEEE80211_TX_CTL_LDPC) | ||
1694 | use_ldpc = true; | ||
1695 | } | ||
1596 | 1696 | ||
1597 | bf->bf_flags = setup_tx_flags(sc, skb, txctl->txq); | 1697 | bf->bf_flags = setup_tx_flags(skb, use_ldpc); |
1598 | 1698 | ||
1599 | bf->bf_keytype = get_hw_crypto_keytype(skb); | 1699 | bf->bf_keytype = get_hw_crypto_keytype(skb); |
1600 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { | 1700 | if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR) { |
@@ -1653,8 +1753,7 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1653 | list_add_tail(&bf->list, &bf_head); | 1753 | list_add_tail(&bf->list, &bf_head); |
1654 | 1754 | ||
1655 | ds = bf->bf_desc; | 1755 | ds = bf->bf_desc; |
1656 | ds->ds_link = 0; | 1756 | ath9k_hw_set_desc_link(ah, ds, 0); |
1657 | ds->ds_data = bf->bf_buf_addr; | ||
1658 | 1757 | ||
1659 | ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, | 1758 | ath9k_hw_set11n_txdesc(ah, ds, bf->bf_frmlen, frm_type, MAX_RATE_POWER, |
1660 | bf->bf_keyix, bf->bf_keytype, bf->bf_flags); | 1759 | bf->bf_keyix, bf->bf_keytype, bf->bf_flags); |
@@ -1663,7 +1762,9 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf, | |||
1663 | skb->len, /* segment length */ | 1762 | skb->len, /* segment length */ |
1664 | true, /* first segment */ | 1763 | true, /* first segment */ |
1665 | true, /* last segment */ | 1764 | true, /* last segment */ |
1666 | ds); /* first descriptor */ | 1765 | ds, /* first descriptor */ |
1766 | bf->bf_buf_addr, | ||
1767 | txctl->txq->axq_qnum); | ||
1667 | 1768 | ||
1668 | spin_lock_bh(&txctl->txq->axq_lock); | 1769 | spin_lock_bh(&txctl->txq->axq_lock); |
1669 | 1770 | ||
@@ -1732,9 +1833,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1732 | } | 1833 | } |
1733 | spin_unlock_bh(&txq->axq_lock); | 1834 | spin_unlock_bh(&txq->axq_lock); |
1734 | 1835 | ||
1735 | spin_lock_bh(&sc->tx.txbuflock); | 1836 | ath_tx_return_buffer(sc, bf); |
1736 | list_add_tail(&bf->list, &sc->tx.txbuf); | ||
1737 | spin_unlock_bh(&sc->tx.txbuflock); | ||
1738 | 1837 | ||
1739 | return r; | 1838 | return r; |
1740 | } | 1839 | } |
@@ -1852,9 +1951,8 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, | |||
1852 | } | 1951 | } |
1853 | 1952 | ||
1854 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | 1953 | static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, |
1855 | struct ath_txq *txq, | 1954 | struct ath_txq *txq, struct list_head *bf_q, |
1856 | struct list_head *bf_q, | 1955 | struct ath_tx_status *ts, int txok, int sendbar) |
1857 | int txok, int sendbar) | ||
1858 | { | 1956 | { |
1859 | struct sk_buff *skb = bf->bf_mpdu; | 1957 | struct sk_buff *skb = bf->bf_mpdu; |
1860 | unsigned long flags; | 1958 | unsigned long flags; |
@@ -1872,7 +1970,7 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1872 | 1970 | ||
1873 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); | 1971 | dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); |
1874 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); | 1972 | ath_tx_complete(sc, skb, bf->aphy, tx_flags); |
1875 | ath_debug_stat_tx(sc, txq, bf); | 1973 | ath_debug_stat_tx(sc, txq, bf, ts); |
1876 | 1974 | ||
1877 | /* | 1975 | /* |
1878 | * Return the list of ath_buf of this mpdu to free queue | 1976 | * Return the list of ath_buf of this mpdu to free queue |
@@ -1883,23 +1981,21 @@ static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, | |||
1883 | } | 1981 | } |
1884 | 1982 | ||
1885 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | 1983 | static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, |
1886 | int txok) | 1984 | struct ath_tx_status *ts, int txok) |
1887 | { | 1985 | { |
1888 | struct ath_buf *bf_last = bf->bf_lastbf; | ||
1889 | struct ath_desc *ds = bf_last->bf_desc; | ||
1890 | u16 seq_st = 0; | 1986 | u16 seq_st = 0; |
1891 | u32 ba[WME_BA_BMP_SIZE >> 5]; | 1987 | u32 ba[WME_BA_BMP_SIZE >> 5]; |
1892 | int ba_index; | 1988 | int ba_index; |
1893 | int nbad = 0; | 1989 | int nbad = 0; |
1894 | int isaggr = 0; | 1990 | int isaggr = 0; |
1895 | 1991 | ||
1896 | if (ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED) | 1992 | if (bf->bf_tx_aborted) |
1897 | return 0; | 1993 | return 0; |
1898 | 1994 | ||
1899 | isaggr = bf_isaggr(bf); | 1995 | isaggr = bf_isaggr(bf); |
1900 | if (isaggr) { | 1996 | if (isaggr) { |
1901 | seq_st = ATH_DS_BA_SEQ(ds); | 1997 | seq_st = ts->ts_seqnum; |
1902 | memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3); | 1998 | memcpy(ba, &ts->ba_low, WME_BA_BMP_SIZE >> 3); |
1903 | } | 1999 | } |
1904 | 2000 | ||
1905 | while (bf) { | 2001 | while (bf) { |
@@ -1913,7 +2009,7 @@ static int ath_tx_num_badfrms(struct ath_softc *sc, struct ath_buf *bf, | |||
1913 | return nbad; | 2009 | return nbad; |
1914 | } | 2010 | } |
1915 | 2011 | ||
1916 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | 2012 | static void ath_tx_rc_status(struct ath_buf *bf, struct ath_tx_status *ts, |
1917 | int nbad, int txok, bool update_rc) | 2013 | int nbad, int txok, bool update_rc) |
1918 | { | 2014 | { |
1919 | struct sk_buff *skb = bf->bf_mpdu; | 2015 | struct sk_buff *skb = bf->bf_mpdu; |
@@ -1923,24 +2019,24 @@ static void ath_tx_rc_status(struct ath_buf *bf, struct ath_desc *ds, | |||
1923 | u8 i, tx_rateindex; | 2019 | u8 i, tx_rateindex; |
1924 | 2020 | ||
1925 | if (txok) | 2021 | if (txok) |
1926 | tx_info->status.ack_signal = ds->ds_txstat.ts_rssi; | 2022 | tx_info->status.ack_signal = ts->ts_rssi; |
1927 | 2023 | ||
1928 | tx_rateindex = ds->ds_txstat.ts_rateindex; | 2024 | tx_rateindex = ts->ts_rateindex; |
1929 | WARN_ON(tx_rateindex >= hw->max_rates); | 2025 | WARN_ON(tx_rateindex >= hw->max_rates); |
1930 | 2026 | ||
1931 | if (update_rc) | 2027 | if (ts->ts_status & ATH9K_TXERR_FILT) |
1932 | tx_info->pad[0] |= ATH_TX_INFO_UPDATE_RC; | ||
1933 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) | ||
1934 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; | 2028 | tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED; |
2029 | if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && update_rc) | ||
2030 | tx_info->flags |= IEEE80211_TX_STAT_AMPDU; | ||
1935 | 2031 | ||
1936 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 && | 2032 | if ((ts->ts_status & ATH9K_TXERR_FILT) == 0 && |
1937 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { | 2033 | (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0 && update_rc) { |
1938 | if (ieee80211_is_data(hdr->frame_control)) { | 2034 | if (ieee80211_is_data(hdr->frame_control)) { |
1939 | if (ds->ds_txstat.ts_flags & | 2035 | if (ts->ts_flags & |
1940 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) | 2036 | (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN)) |
1941 | tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; | 2037 | tx_info->pad[0] |= ATH_TX_INFO_UNDERRUN; |
1942 | if ((ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) || | 2038 | if ((ts->ts_status & ATH9K_TXERR_XRETRY) || |
1943 | (ds->ds_txstat.ts_status & ATH9K_TXERR_FIFO)) | 2039 | (ts->ts_status & ATH9K_TXERR_FIFO)) |
1944 | tx_info->pad[0] |= ATH_TX_INFO_XRETRY; | 2040 | tx_info->pad[0] |= ATH_TX_INFO_XRETRY; |
1945 | tx_info->status.ampdu_len = bf->bf_nframes; | 2041 | tx_info->status.ampdu_len = bf->bf_nframes; |
1946 | tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; | 2042 | tx_info->status.ampdu_ack_len = bf->bf_nframes - nbad; |
@@ -1978,6 +2074,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
1978 | struct ath_buf *bf, *lastbf, *bf_held = NULL; | 2074 | struct ath_buf *bf, *lastbf, *bf_held = NULL; |
1979 | struct list_head bf_head; | 2075 | struct list_head bf_head; |
1980 | struct ath_desc *ds; | 2076 | struct ath_desc *ds; |
2077 | struct ath_tx_status ts; | ||
1981 | int txok; | 2078 | int txok; |
1982 | int status; | 2079 | int status; |
1983 | 2080 | ||
@@ -2017,7 +2114,8 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2017 | lastbf = bf->bf_lastbf; | 2114 | lastbf = bf->bf_lastbf; |
2018 | ds = lastbf->bf_desc; | 2115 | ds = lastbf->bf_desc; |
2019 | 2116 | ||
2020 | status = ath9k_hw_txprocdesc(ah, ds); | 2117 | memset(&ts, 0, sizeof(ts)); |
2118 | status = ath9k_hw_txprocdesc(ah, ds, &ts); | ||
2021 | if (status == -EINPROGRESS) { | 2119 | if (status == -EINPROGRESS) { |
2022 | spin_unlock_bh(&txq->axq_lock); | 2120 | spin_unlock_bh(&txq->axq_lock); |
2023 | break; | 2121 | break; |
@@ -2028,7 +2126,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2028 | * can disable RX. | 2126 | * can disable RX. |
2029 | */ | 2127 | */ |
2030 | if (bf->bf_isnullfunc && | 2128 | if (bf->bf_isnullfunc && |
2031 | (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { | 2129 | (ts.ts_status & ATH9K_TX_ACKED)) { |
2032 | if ((sc->ps_flags & PS_ENABLED)) | 2130 | if ((sc->ps_flags & PS_ENABLED)) |
2033 | ath9k_enable_ps(sc); | 2131 | ath9k_enable_ps(sc); |
2034 | else | 2132 | else |
@@ -2047,31 +2145,30 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) | |||
2047 | &txq->axq_q, lastbf->list.prev); | 2145 | &txq->axq_q, lastbf->list.prev); |
2048 | 2146 | ||
2049 | txq->axq_depth--; | 2147 | txq->axq_depth--; |
2050 | txok = !(ds->ds_txstat.ts_status & ATH9K_TXERR_MASK); | 2148 | txok = !(ts.ts_status & ATH9K_TXERR_MASK); |
2051 | txq->axq_tx_inprogress = false; | 2149 | txq->axq_tx_inprogress = false; |
2150 | if (bf_held) | ||
2151 | list_del(&bf_held->list); | ||
2052 | spin_unlock_bh(&txq->axq_lock); | 2152 | spin_unlock_bh(&txq->axq_lock); |
2053 | 2153 | ||
2054 | if (bf_held) { | 2154 | if (bf_held) |
2055 | spin_lock_bh(&sc->tx.txbuflock); | 2155 | ath_tx_return_buffer(sc, bf_held); |
2056 | list_move_tail(&bf_held->list, &sc->tx.txbuf); | ||
2057 | spin_unlock_bh(&sc->tx.txbuflock); | ||
2058 | } | ||
2059 | 2156 | ||
2060 | if (!bf_isampdu(bf)) { | 2157 | if (!bf_isampdu(bf)) { |
2061 | /* | 2158 | /* |
2062 | * This frame is sent out as a single frame. | 2159 | * This frame is sent out as a single frame. |
2063 | * Use hardware retry status for this frame. | 2160 | * Use hardware retry status for this frame. |
2064 | */ | 2161 | */ |
2065 | bf->bf_retries = ds->ds_txstat.ts_longretry; | 2162 | bf->bf_retries = ts.ts_longretry; |
2066 | if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY) | 2163 | if (ts.ts_status & ATH9K_TXERR_XRETRY) |
2067 | bf->bf_state.bf_type |= BUF_XRETRY; | 2164 | bf->bf_state.bf_type |= BUF_XRETRY; |
2068 | ath_tx_rc_status(bf, ds, 0, txok, true); | 2165 | ath_tx_rc_status(bf, &ts, 0, txok, true); |
2069 | } | 2166 | } |
2070 | 2167 | ||
2071 | if (bf_isampdu(bf)) | 2168 | if (bf_isampdu(bf)) |
2072 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, txok); | 2169 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &ts, txok); |
2073 | else | 2170 | else |
2074 | ath_tx_complete_buf(sc, bf, txq, &bf_head, txok, 0); | 2171 | ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0); |
2075 | 2172 | ||
2076 | ath_wake_mac80211_queue(sc, txq); | 2173 | ath_wake_mac80211_queue(sc, txq); |
2077 | 2174 | ||
@@ -2133,10 +2230,121 @@ void ath_tx_tasklet(struct ath_softc *sc) | |||
2133 | } | 2230 | } |
2134 | } | 2231 | } |
2135 | 2232 | ||
2233 | void ath_tx_edma_tasklet(struct ath_softc *sc) | ||
2234 | { | ||
2235 | struct ath_tx_status txs; | ||
2236 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | ||
2237 | struct ath_hw *ah = sc->sc_ah; | ||
2238 | struct ath_txq *txq; | ||
2239 | struct ath_buf *bf, *lastbf; | ||
2240 | struct list_head bf_head; | ||
2241 | int status; | ||
2242 | int txok; | ||
2243 | |||
2244 | for (;;) { | ||
2245 | status = ath9k_hw_txprocdesc(ah, NULL, (void *)&txs); | ||
2246 | if (status == -EINPROGRESS) | ||
2247 | break; | ||
2248 | if (status == -EIO) { | ||
2249 | ath_print(common, ATH_DBG_XMIT, | ||
2250 | "Error processing tx status\n"); | ||
2251 | break; | ||
2252 | } | ||
2253 | |||
2254 | /* Skip beacon completions */ | ||
2255 | if (txs.qid == sc->beacon.beaconq) | ||
2256 | continue; | ||
2257 | |||
2258 | txq = &sc->tx.txq[txs.qid]; | ||
2259 | |||
2260 | spin_lock_bh(&txq->axq_lock); | ||
2261 | if (list_empty(&txq->txq_fifo[txq->txq_tailidx])) { | ||
2262 | spin_unlock_bh(&txq->axq_lock); | ||
2263 | return; | ||
2264 | } | ||
2265 | |||
2266 | bf = list_first_entry(&txq->txq_fifo[txq->txq_tailidx], | ||
2267 | struct ath_buf, list); | ||
2268 | lastbf = bf->bf_lastbf; | ||
2269 | |||
2270 | INIT_LIST_HEAD(&bf_head); | ||
2271 | list_cut_position(&bf_head, &txq->txq_fifo[txq->txq_tailidx], | ||
2272 | &lastbf->list); | ||
2273 | INCR(txq->txq_tailidx, ATH_TXFIFO_DEPTH); | ||
2274 | txq->axq_depth--; | ||
2275 | txq->axq_tx_inprogress = false; | ||
2276 | spin_unlock_bh(&txq->axq_lock); | ||
2277 | |||
2278 | txok = !(txs.ts_status & ATH9K_TXERR_MASK); | ||
2279 | |||
2280 | if (!bf_isampdu(bf)) { | ||
2281 | bf->bf_retries = txs.ts_longretry; | ||
2282 | if (txs.ts_status & ATH9K_TXERR_XRETRY) | ||
2283 | bf->bf_state.bf_type |= BUF_XRETRY; | ||
2284 | ath_tx_rc_status(bf, &txs, 0, txok, true); | ||
2285 | } | ||
2286 | |||
2287 | if (bf_isampdu(bf)) | ||
2288 | ath_tx_complete_aggr(sc, txq, bf, &bf_head, &txs, txok); | ||
2289 | else | ||
2290 | ath_tx_complete_buf(sc, bf, txq, &bf_head, | ||
2291 | &txs, txok, 0); | ||
2292 | |||
2293 | ath_wake_mac80211_queue(sc, txq); | ||
2294 | |||
2295 | spin_lock_bh(&txq->axq_lock); | ||
2296 | if (!list_empty(&txq->txq_fifo_pending)) { | ||
2297 | INIT_LIST_HEAD(&bf_head); | ||
2298 | bf = list_first_entry(&txq->txq_fifo_pending, | ||
2299 | struct ath_buf, list); | ||
2300 | list_cut_position(&bf_head, &txq->txq_fifo_pending, | ||
2301 | &bf->bf_lastbf->list); | ||
2302 | ath_tx_txqaddbuf(sc, txq, &bf_head); | ||
2303 | } else if (sc->sc_flags & SC_OP_TXAGGR) | ||
2304 | ath_txq_schedule(sc, txq); | ||
2305 | spin_unlock_bh(&txq->axq_lock); | ||
2306 | } | ||
2307 | } | ||
2308 | |||
2136 | /*****************/ | 2309 | /*****************/ |
2137 | /* Init, Cleanup */ | 2310 | /* Init, Cleanup */ |
2138 | /*****************/ | 2311 | /*****************/ |
2139 | 2312 | ||
2313 | static int ath_txstatus_setup(struct ath_softc *sc, int size) | ||
2314 | { | ||
2315 | struct ath_descdma *dd = &sc->txsdma; | ||
2316 | u8 txs_len = sc->sc_ah->caps.txs_len; | ||
2317 | |||
2318 | dd->dd_desc_len = size * txs_len; | ||
2319 | dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len, | ||
2320 | &dd->dd_desc_paddr, GFP_KERNEL); | ||
2321 | if (!dd->dd_desc) | ||
2322 | return -ENOMEM; | ||
2323 | |||
2324 | return 0; | ||
2325 | } | ||
2326 | |||
2327 | static int ath_tx_edma_init(struct ath_softc *sc) | ||
2328 | { | ||
2329 | int err; | ||
2330 | |||
2331 | err = ath_txstatus_setup(sc, ATH_TXSTATUS_RING_SIZE); | ||
2332 | if (!err) | ||
2333 | ath9k_hw_setup_statusring(sc->sc_ah, sc->txsdma.dd_desc, | ||
2334 | sc->txsdma.dd_desc_paddr, | ||
2335 | ATH_TXSTATUS_RING_SIZE); | ||
2336 | |||
2337 | return err; | ||
2338 | } | ||
2339 | |||
2340 | static void ath_tx_edma_cleanup(struct ath_softc *sc) | ||
2341 | { | ||
2342 | struct ath_descdma *dd = &sc->txsdma; | ||
2343 | |||
2344 | dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc, | ||
2345 | dd->dd_desc_paddr); | ||
2346 | } | ||
2347 | |||
2140 | int ath_tx_init(struct ath_softc *sc, int nbufs) | 2348 | int ath_tx_init(struct ath_softc *sc, int nbufs) |
2141 | { | 2349 | { |
2142 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 2350 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -2145,7 +2353,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2145 | spin_lock_init(&sc->tx.txbuflock); | 2353 | spin_lock_init(&sc->tx.txbuflock); |
2146 | 2354 | ||
2147 | error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, | 2355 | error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf, |
2148 | "tx", nbufs, 1); | 2356 | "tx", nbufs, 1, 1); |
2149 | if (error != 0) { | 2357 | if (error != 0) { |
2150 | ath_print(common, ATH_DBG_FATAL, | 2358 | ath_print(common, ATH_DBG_FATAL, |
2151 | "Failed to allocate tx descriptors: %d\n", error); | 2359 | "Failed to allocate tx descriptors: %d\n", error); |
@@ -2153,7 +2361,7 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2153 | } | 2361 | } |
2154 | 2362 | ||
2155 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, | 2363 | error = ath_descdma_setup(sc, &sc->beacon.bdma, &sc->beacon.bbuf, |
2156 | "beacon", ATH_BCBUF, 1); | 2364 | "beacon", ATH_BCBUF, 1, 1); |
2157 | if (error != 0) { | 2365 | if (error != 0) { |
2158 | ath_print(common, ATH_DBG_FATAL, | 2366 | ath_print(common, ATH_DBG_FATAL, |
2159 | "Failed to allocate beacon descriptors: %d\n", error); | 2367 | "Failed to allocate beacon descriptors: %d\n", error); |
@@ -2162,6 +2370,12 @@ int ath_tx_init(struct ath_softc *sc, int nbufs) | |||
2162 | 2370 | ||
2163 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); | 2371 | INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work); |
2164 | 2372 | ||
2373 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { | ||
2374 | error = ath_tx_edma_init(sc); | ||
2375 | if (error) | ||
2376 | goto err; | ||
2377 | } | ||
2378 | |||
2165 | err: | 2379 | err: |
2166 | if (error != 0) | 2380 | if (error != 0) |
2167 | ath_tx_cleanup(sc); | 2381 | ath_tx_cleanup(sc); |
@@ -2176,6 +2390,9 @@ void ath_tx_cleanup(struct ath_softc *sc) | |||
2176 | 2390 | ||
2177 | if (sc->tx.txdma.dd_desc_len != 0) | 2391 | if (sc->tx.txdma.dd_desc_len != 0) |
2178 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); | 2392 | ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf); |
2393 | |||
2394 | if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) | ||
2395 | ath_tx_edma_cleanup(sc); | ||
2179 | } | 2396 | } |
2180 | 2397 | ||
2181 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | 2398 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) |
diff --git a/drivers/net/wireless/ath/debug.h b/drivers/net/wireless/ath/debug.h index 8263633c003c..873bf526e11f 100644 --- a/drivers/net/wireless/ath/debug.h +++ b/drivers/net/wireless/ath/debug.h | |||
@@ -59,6 +59,7 @@ enum ATH_DEBUG { | |||
59 | ATH_DBG_PS = 0x00000800, | 59 | ATH_DBG_PS = 0x00000800, |
60 | ATH_DBG_HWTIMER = 0x00001000, | 60 | ATH_DBG_HWTIMER = 0x00001000, |
61 | ATH_DBG_BTCOEX = 0x00002000, | 61 | ATH_DBG_BTCOEX = 0x00002000, |
62 | ATH_DBG_WMI = 0x00004000, | ||
62 | ATH_DBG_ANY = 0xffffffff | 63 | ATH_DBG_ANY = 0xffffffff |
63 | }; | 64 | }; |
64 | 65 | ||
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c index ecc9eb01f4fa..a8f81ea09f14 100644 --- a/drivers/net/wireless/ath/hw.c +++ b/drivers/net/wireless/ath/hw.c | |||
@@ -19,8 +19,8 @@ | |||
19 | #include "ath.h" | 19 | #include "ath.h" |
20 | #include "reg.h" | 20 | #include "reg.h" |
21 | 21 | ||
22 | #define REG_READ common->ops->read | 22 | #define REG_READ (common->ops->read) |
23 | #define REG_WRITE common->ops->write | 23 | #define REG_WRITE (common->ops->write) |
24 | 24 | ||
25 | /** | 25 | /** |
26 | * ath_hw_set_bssid_mask - filter out bssids we listen | 26 | * ath_hw_set_bssid_mask - filter out bssids we listen |
diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 00489c40be0c..3f4244f56ce5 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c | |||
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | #define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ | 51 | #define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ |
52 | ATH9K_5GHZ_5470_5850 | 52 | ATH9K_5GHZ_5470_5850 |
53 | |||
53 | /* This one skips what we call "mid band" */ | 54 | /* This one skips what we call "mid band" */ |
54 | #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ | 55 | #define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ |
55 | ATH9K_5GHZ_5725_5850 | 56 | ATH9K_5GHZ_5725_5850 |
@@ -332,7 +333,6 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, | |||
332 | ath_reg_apply_active_scan_flags(wiphy, initiator); | 333 | ath_reg_apply_active_scan_flags(wiphy, initiator); |
333 | break; | 334 | break; |
334 | } | 335 | } |
335 | return; | ||
336 | } | 336 | } |
337 | 337 | ||
338 | int ath_reg_notifier_apply(struct wiphy *wiphy, | 338 | int ath_reg_notifier_apply(struct wiphy *wiphy, |
@@ -360,7 +360,7 @@ EXPORT_SYMBOL(ath_reg_notifier_apply); | |||
360 | 360 | ||
361 | static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) | 361 | static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) |
362 | { | 362 | { |
363 | u16 rd = ath_regd_get_eepromRD(reg); | 363 | u16 rd = ath_regd_get_eepromRD(reg); |
364 | int i; | 364 | int i; |
365 | 365 | ||
366 | if (rd & COUNTRY_ERD_FLAG) { | 366 | if (rd & COUNTRY_ERD_FLAG) { |