1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <asm/unaligned.h>
28
29#include "ath5k.h"
30#include "reg.h"
31#include "debug.h"
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82static const unsigned int ack_rates_high[] =
83
84 { 0,
85 1,
86 1,
87 1,
88 4,
89 4,
90 6,
91 6,
92 8,
93 8,
94 8,
95 8 };
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112int
113ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum ieee80211_band band,
114 int len, struct ieee80211_rate *rate, bool shortpre)
115{
116 int sifs, preamble, plcp_bits, sym_time;
117 int bitrate, bits, symbols, symbol_bits;
118 int dur;
119
120
121 if (!ah->ah_bwmode) {
122 __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw,
123 NULL, band, len, rate);
124
125
126 dur = le16_to_cpu(raw_dur);
127 if (shortpre)
128 dur -= 96;
129
130 return dur;
131 }
132
133 bitrate = rate->bitrate;
134 preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;
135 plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;
136 sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;
137
138 switch (ah->ah_bwmode) {
139 case AR5K_BWMODE_40MHZ:
140 sifs = AR5K_INIT_SIFS_TURBO;
141 preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;
142 break;
143 case AR5K_BWMODE_10MHZ:
144 sifs = AR5K_INIT_SIFS_HALF_RATE;
145 preamble *= 2;
146 sym_time *= 2;
147 break;
148 case AR5K_BWMODE_5MHZ:
149 sifs = AR5K_INIT_SIFS_QUARTER_RATE;
150 preamble *= 4;
151 sym_time *= 4;
152 break;
153 default:
154 sifs = AR5K_INIT_SIFS_DEFAULT_BG;
155 break;
156 }
157
158 bits = plcp_bits + (len << 3);
159
160 symbol_bits = bitrate * sym_time;
161 symbols = DIV_ROUND_UP(bits * 10, symbol_bits);
162
163 dur = sifs + preamble + (sym_time * symbols);
164
165 return dur;
166}
167
168
169
170
171
172unsigned int
173ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
174{
175 struct ieee80211_channel *channel = ah->ah_current_channel;
176 unsigned int slot_time;
177
178 switch (ah->ah_bwmode) {
179 case AR5K_BWMODE_40MHZ:
180 slot_time = AR5K_INIT_SLOT_TIME_TURBO;
181 break;
182 case AR5K_BWMODE_10MHZ:
183 slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;
184 break;
185 case AR5K_BWMODE_5MHZ:
186 slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
187 break;
188 case AR5K_BWMODE_DEFAULT:
189 default:
190 slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
191 if ((channel->hw_value == AR5K_MODE_11B) && !ah->ah_short_slot)
192 slot_time = AR5K_INIT_SLOT_TIME_B;
193 break;
194 }
195
196 return slot_time;
197}
198
199
200
201
202
203unsigned int
204ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
205{
206 struct ieee80211_channel *channel = ah->ah_current_channel;
207 unsigned int sifs;
208
209 switch (ah->ah_bwmode) {
210 case AR5K_BWMODE_40MHZ:
211 sifs = AR5K_INIT_SIFS_TURBO;
212 break;
213 case AR5K_BWMODE_10MHZ:
214 sifs = AR5K_INIT_SIFS_HALF_RATE;
215 break;
216 case AR5K_BWMODE_5MHZ:
217 sifs = AR5K_INIT_SIFS_QUARTER_RATE;
218 break;
219 case AR5K_BWMODE_DEFAULT:
220 sifs = AR5K_INIT_SIFS_DEFAULT_BG;
221 default:
222 if (channel->band == IEEE80211_BAND_5GHZ)
223 sifs = AR5K_INIT_SIFS_DEFAULT_A;
224 break;
225 }
226
227 return sifs;
228}
229
230
231
232
233
234
235
236
237
238
239
240void
241ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
242{
243 struct ath5k_statistics *stats = &ah->stats;
244
245
246 stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
247 stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
248 stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
249 stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
250 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
251}
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274static inline void
275ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
276{
277 struct ieee80211_rate *rate;
278 unsigned int i;
279
280 u8 band = IEEE80211_BAND_2GHZ;
281
282
283 for (i = 0; i < ah->sbands[band].n_bitrates; i++) {
284 u32 reg;
285 u16 tx_time;
286
287 if (ah->ah_ack_bitrate_high)
288 rate = &ah->sbands[band].bitrates[ack_rates_high[i]];
289
290 else if (i < 4)
291 rate = &ah->sbands[band].bitrates[0];
292
293 else
294 rate = &ah->sbands[band].bitrates[4];
295
296
297 reg = AR5K_RATE_DUR(rate->hw_value);
298
299
300
301
302
303
304
305 tx_time = ath5k_hw_get_frame_duration(ah, band, 10,
306 rate, false);
307
308 ath5k_hw_reg_write(ah, tx_time, reg);
309
310 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
311 continue;
312
313 tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, true);
314 ath5k_hw_reg_write(ah, tx_time,
315 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
316 }
317}
318
319
320
321
322
323
324static int
325ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
326{
327 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
328 <= timeout)
329 return -EINVAL;
330
331 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
332 ath5k_hw_htoclock(ah, timeout));
333
334 return 0;
335}
336
337
338
339
340
341
342static int
343ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
344{
345 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
346 <= timeout)
347 return -EINVAL;
348
349 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
350 ath5k_hw_htoclock(ah, timeout));
351
352 return 0;
353}
354
355
356
357
358
359
360
361
362
363
364
365
366
367int
368ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
369{
370 struct ath_common *common = ath5k_hw_common(ah);
371 u32 low_id, high_id;
372 u32 pcu_reg;
373
374
375 memcpy(common->macaddr, mac, ETH_ALEN);
376
377 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
378
379 low_id = get_unaligned_le32(mac);
380 high_id = get_unaligned_le16(mac + 4);
381
382 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
383 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
384
385 return 0;
386}
387
388
389
390
391
392
393
394
395void
396ath5k_hw_set_bssid(struct ath5k_hw *ah)
397{
398 struct ath_common *common = ath5k_hw_common(ah);
399 u16 tim_offset = 0;
400
401
402
403
404 if (ah->ah_version == AR5K_AR5212)
405 ath_hw_setbssidmask(common);
406
407
408
409
410 ath5k_hw_reg_write(ah,
411 get_unaligned_le32(common->curbssid),
412 AR5K_BSS_ID0);
413 ath5k_hw_reg_write(ah,
414 get_unaligned_le16(common->curbssid + 4) |
415 ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
416 AR5K_BSS_ID1);
417
418 if (common->curaid == 0) {
419 ath5k_hw_disable_pspoll(ah);
420 return;
421 }
422
423 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
424 tim_offset ? tim_offset + 4 : 0);
425
426 ath5k_hw_enable_pspoll(ah, NULL, 0);
427}
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444void
445ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
446{
447 struct ath_common *common = ath5k_hw_common(ah);
448
449
450
451 memcpy(common->bssidmask, mask, ETH_ALEN);
452 if (ah->ah_version == AR5K_AR5212)
453 ath_hw_setbssidmask(common);
454}
455
456
457
458
459
460
461
462void
463ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
464{
465 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
466 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
467}
468
469
470
471
472
473
474
475
476
477
478
479u32
480ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
481{
482 u32 data, filter = 0;
483
484 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
485
486
487 if (ah->ah_version == AR5K_AR5212) {
488 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
489
490 if (data & AR5K_PHY_ERR_FIL_RADAR)
491 filter |= AR5K_RX_FILTER_RADARERR;
492 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
493 filter |= AR5K_RX_FILTER_PHYERR;
494 }
495
496 return filter;
497}
498
499
500
501
502
503
504
505
506
507
508void
509ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
510{
511 u32 data = 0;
512
513
514 if (ah->ah_version == AR5K_AR5212) {
515 if (filter & AR5K_RX_FILTER_RADARERR)
516 data |= AR5K_PHY_ERR_FIL_RADAR;
517 if (filter & AR5K_RX_FILTER_PHYERR)
518 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
519 }
520
521
522
523
524 if (ah->ah_version == AR5K_AR5210 &&
525 (filter & AR5K_RX_FILTER_RADARERR)) {
526 filter &= ~AR5K_RX_FILTER_RADARERR;
527 filter |= AR5K_RX_FILTER_PROM;
528 }
529
530
531 if (data)
532 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
533 else
534 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
535
536
537 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
538
539
540 if (ah->ah_version == AR5K_AR5212)
541 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
542
543}
544
545
546
547
548
549
550#define ATH5K_MAX_TSF_READ 10
551
552
553
554
555
556
557
558u64
559ath5k_hw_get_tsf64(struct ath5k_hw *ah)
560{
561 u32 tsf_lower, tsf_upper1, tsf_upper2;
562 int i;
563 unsigned long flags;
564
565
566 local_irq_save(flags);
567
568
569
570
571
572
573
574
575
576
577
578
579
580 tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
581 for (i = 0; i < ATH5K_MAX_TSF_READ; i++) {
582 tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
583 tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
584 if (tsf_upper2 == tsf_upper1)
585 break;
586 tsf_upper1 = tsf_upper2;
587 }
588
589 local_irq_restore(flags);
590
591 WARN_ON(i == ATH5K_MAX_TSF_READ);
592
593 return ((u64)tsf_upper1 << 32) | tsf_lower;
594}
595
596#undef ATH5K_MAX_TSF_READ
597
598
599
600
601
602
603
604
605void
606ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
607{
608 ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
609 ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
610}
611
612
613
614
615
616
617
618void
619ath5k_hw_reset_tsf(struct ath5k_hw *ah)
620{
621 u32 val;
622
623 val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
624
625
626
627
628
629
630
631 ath5k_hw_reg_write(ah, val, AR5K_BEACON);
632 ath5k_hw_reg_write(ah, val, AR5K_BEACON);
633}
634
635
636
637
638
639
640
641
642
643
644void
645ath5k_hw_init_beacon_timers(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
646{
647 u32 timer1, timer2, timer3;
648
649
650
651
652 switch (ah->opmode) {
653 case NL80211_IFTYPE_MONITOR:
654 case NL80211_IFTYPE_STATION:
655
656
657
658
659 if (ah->ah_version == AR5K_AR5210) {
660 timer1 = 0xffffffff;
661 timer2 = 0xffffffff;
662 } else {
663 timer1 = 0x0000ffff;
664 timer2 = 0x0007ffff;
665 }
666
667 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
668 break;
669 case NL80211_IFTYPE_ADHOC:
670 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
671 default:
672
673
674
675 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
676 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
677 break;
678 }
679
680
681
682
683 timer3 = next_beacon + 1;
684
685
686
687
688
689 if (ah->opmode == NL80211_IFTYPE_AP ||
690 ah->opmode == NL80211_IFTYPE_MESH_POINT)
691 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
692
693 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
694 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
695 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
696 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
697
698
699 if (interval & AR5K_BEACON_RESET_TSF)
700 ath5k_hw_reset_tsf(ah);
701
702 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
703 AR5K_BEACON_ENABLE),
704 AR5K_BEACON);
705
706
707
708
709
710
711 if (ah->ah_version == AR5K_AR5210)
712 ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
713 else
714 ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
715
716
717
718
719 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
720
721}
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736static inline bool
737ath5k_check_timer_win(int a, int b, int window, int intval)
738{
739
740
741
742
743
744
745 if ((b - a == window) ||
746 (a - b == intval - window) ||
747 ((a | 0x10000) - b == intval - window) ||
748 ((b | 0x10000) - a == window))
749 return true;
750 return false;
751}
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792bool
793ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
794{
795 unsigned int nbtt, atim, dma;
796
797 nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0);
798 atim = ath5k_hw_reg_read(ah, AR5K_TIMER3);
799 dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3;
800
801
802
803
804
805 if (ath5k_check_timer_win(nbtt, atim, 1, intval) &&
806 ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP,
807 intval))
808 return true;
809 return false;
810}
811
812
813
814
815
816
817
818
819void
820ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
821{
822
823 int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
824 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
825 int cts_timeout = ack_timeout;
826
827 ath5k_hw_set_ifs_intervals(ah, slot_time);
828 ath5k_hw_set_ack_timeout(ah, ack_timeout);
829 ath5k_hw_set_cts_timeout(ah, cts_timeout);
830
831 ah->ah_coverage_class = coverage_class;
832}
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847void
848ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
849{
850 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
851}
852
853
854
855
856
857
858
859void
860ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
861{
862 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
863}
864
865
866
867
868
869
870
871
872int
873ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
874{
875 struct ath_common *common = ath5k_hw_common(ah);
876 u32 pcu_reg, beacon_reg, low_id, high_id;
877
878 ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
879
880
881 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
882 pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
883 | AR5K_STA_ID1_KEYSRCH_MODE
884 | (ah->ah_version == AR5K_AR5210 ?
885 (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
886
887 beacon_reg = 0;
888
889 switch (op_mode) {
890 case NL80211_IFTYPE_ADHOC:
891 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
892 beacon_reg |= AR5K_BCR_ADHOC;
893 if (ah->ah_version == AR5K_AR5210)
894 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
895 else
896 AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
897 break;
898
899 case NL80211_IFTYPE_AP:
900 case NL80211_IFTYPE_MESH_POINT:
901 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
902 beacon_reg |= AR5K_BCR_AP;
903 if (ah->ah_version == AR5K_AR5210)
904 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
905 else
906 AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
907 break;
908
909 case NL80211_IFTYPE_STATION:
910 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
911 | (ah->ah_version == AR5K_AR5210 ?
912 AR5K_STA_ID1_PWR_SV : 0);
913 case NL80211_IFTYPE_MONITOR:
914 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
915 | (ah->ah_version == AR5K_AR5210 ?
916 AR5K_STA_ID1_NO_PSPOLL : 0);
917 break;
918
919 default:
920 return -EINVAL;
921 }
922
923
924
925
926 low_id = get_unaligned_le32(common->macaddr);
927 high_id = get_unaligned_le16(common->macaddr + 4);
928 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
929 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
930
931
932
933
934 if (ah->ah_version == AR5K_AR5210)
935 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
936
937 return 0;
938}
939
940
941
942
943
944
945
946
947
948
949void
950ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
951{
952
953 ath5k_hw_set_bssid(ah);
954
955
956 ath5k_hw_set_opmode(ah, op_mode);
957
958
959
960
961
962 if (ah->ah_version == AR5K_AR5212 &&
963 ah->nvifs)
964 ath5k_hw_write_rate_duration(ah);
965
966
967
968
969
970
971
972
973
974 ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
975 AR5K_TUNE_BMISS_THRES <<
976 AR5K_RSSI_THR_BMISS_S),
977 AR5K_RSSI_THR);
978
979
980 if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
981 ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
982 ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
983 }
984
985
986 if (ah->ah_version == AR5K_AR5212) {
987 ath5k_hw_reg_write(ah,
988 AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
989 AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
990 AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
991 AR5K_QOS_NOACK);
992 }
993
994
995 if (ah->ah_coverage_class > 0)
996 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
997
998
999 if (ah->ah_version == AR5K_AR5212) {
1000 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
1001 if (ah->ah_ack_bitrate_high)
1002 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
1003 else
1004 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
1005 }
1006 return;
1007}
1008