0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <asm/unaligned.h>
0028
0029 #include "ath5k.h"
0030 #include "reg.h"
0031 #include "debug.h"
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 static const unsigned int ack_rates_high[] =
0083
0084 { 0,
0085 1,
0086 1,
0087 1,
0088 4,
0089 4,
0090 6,
0091 6,
0092 8,
0093 8,
0094 8,
0095 8 };
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113 int
0114 ath5k_hw_get_frame_duration(struct ath5k_hw *ah, enum nl80211_band band,
0115 int len, struct ieee80211_rate *rate, bool shortpre)
0116 {
0117 int sifs, preamble, plcp_bits, sym_time;
0118 int bitrate, bits, symbols, symbol_bits;
0119 int dur;
0120
0121
0122 if (!ah->ah_bwmode) {
0123 __le16 raw_dur = ieee80211_generic_frame_duration(ah->hw,
0124 NULL, band, len, rate);
0125
0126
0127 dur = le16_to_cpu(raw_dur);
0128 if (shortpre)
0129 dur -= 96;
0130
0131 return dur;
0132 }
0133
0134 bitrate = rate->bitrate;
0135 preamble = AR5K_INIT_OFDM_PREAMPLE_TIME;
0136 plcp_bits = AR5K_INIT_OFDM_PLCP_BITS;
0137 sym_time = AR5K_INIT_OFDM_SYMBOL_TIME;
0138
0139 switch (ah->ah_bwmode) {
0140 case AR5K_BWMODE_40MHZ:
0141 sifs = AR5K_INIT_SIFS_TURBO;
0142 preamble = AR5K_INIT_OFDM_PREAMBLE_TIME_MIN;
0143 break;
0144 case AR5K_BWMODE_10MHZ:
0145 sifs = AR5K_INIT_SIFS_HALF_RATE;
0146 preamble *= 2;
0147 sym_time *= 2;
0148 bitrate = DIV_ROUND_UP(bitrate, 2);
0149 break;
0150 case AR5K_BWMODE_5MHZ:
0151 sifs = AR5K_INIT_SIFS_QUARTER_RATE;
0152 preamble *= 4;
0153 sym_time *= 4;
0154 bitrate = DIV_ROUND_UP(bitrate, 4);
0155 break;
0156 default:
0157 sifs = AR5K_INIT_SIFS_DEFAULT_BG;
0158 break;
0159 }
0160
0161 bits = plcp_bits + (len << 3);
0162
0163 symbol_bits = bitrate * sym_time;
0164 symbols = DIV_ROUND_UP(bits * 10, symbol_bits);
0165
0166 dur = sifs + preamble + (sym_time * symbols);
0167
0168 return dur;
0169 }
0170
0171
0172
0173
0174
0175 unsigned int
0176 ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
0177 {
0178 struct ieee80211_channel *channel = ah->ah_current_channel;
0179 unsigned int slot_time;
0180
0181 switch (ah->ah_bwmode) {
0182 case AR5K_BWMODE_40MHZ:
0183 slot_time = AR5K_INIT_SLOT_TIME_TURBO;
0184 break;
0185 case AR5K_BWMODE_10MHZ:
0186 slot_time = AR5K_INIT_SLOT_TIME_HALF_RATE;
0187 break;
0188 case AR5K_BWMODE_5MHZ:
0189 slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE;
0190 break;
0191 case AR5K_BWMODE_DEFAULT:
0192 default:
0193 slot_time = AR5K_INIT_SLOT_TIME_DEFAULT;
0194 if ((channel->hw_value == AR5K_MODE_11B) && !ah->ah_short_slot)
0195 slot_time = AR5K_INIT_SLOT_TIME_B;
0196 break;
0197 }
0198
0199 return slot_time;
0200 }
0201
0202
0203
0204
0205
0206 unsigned int
0207 ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
0208 {
0209 struct ieee80211_channel *channel = ah->ah_current_channel;
0210 unsigned int sifs;
0211
0212 switch (ah->ah_bwmode) {
0213 case AR5K_BWMODE_40MHZ:
0214 sifs = AR5K_INIT_SIFS_TURBO;
0215 break;
0216 case AR5K_BWMODE_10MHZ:
0217 sifs = AR5K_INIT_SIFS_HALF_RATE;
0218 break;
0219 case AR5K_BWMODE_5MHZ:
0220 sifs = AR5K_INIT_SIFS_QUARTER_RATE;
0221 break;
0222 case AR5K_BWMODE_DEFAULT:
0223 default:
0224 sifs = AR5K_INIT_SIFS_DEFAULT_BG;
0225 if (channel->band == NL80211_BAND_5GHZ)
0226 sifs = AR5K_INIT_SIFS_DEFAULT_A;
0227 break;
0228 }
0229
0230 return sifs;
0231 }
0232
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243 void
0244 ath5k_hw_update_mib_counters(struct ath5k_hw *ah)
0245 {
0246 struct ath5k_statistics *stats = &ah->stats;
0247
0248
0249 stats->ack_fail += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
0250 stats->rts_fail += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
0251 stats->rts_ok += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
0252 stats->fcs_error += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
0253 stats->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 static inline void
0278 ath5k_hw_write_rate_duration(struct ath5k_hw *ah)
0279 {
0280 struct ieee80211_rate *rate;
0281 unsigned int i;
0282
0283 u8 band = NL80211_BAND_2GHZ;
0284
0285
0286 for (i = 0; i < ah->sbands[band].n_bitrates; i++) {
0287 u32 reg;
0288 u16 tx_time;
0289
0290 if (ah->ah_ack_bitrate_high)
0291 rate = &ah->sbands[band].bitrates[ack_rates_high[i]];
0292
0293 else if (i < 4)
0294 rate = &ah->sbands[band].bitrates[0];
0295
0296 else
0297 rate = &ah->sbands[band].bitrates[4];
0298
0299
0300 reg = AR5K_RATE_DUR(rate->hw_value);
0301
0302
0303
0304
0305
0306
0307
0308 tx_time = ath5k_hw_get_frame_duration(ah, band, 10,
0309 rate, false);
0310
0311 ath5k_hw_reg_write(ah, tx_time, reg);
0312
0313 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
0314 continue;
0315
0316 tx_time = ath5k_hw_get_frame_duration(ah, band, 10, rate, true);
0317 ath5k_hw_reg_write(ah, tx_time,
0318 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
0319 }
0320 }
0321
0322
0323
0324
0325
0326
0327 static int
0328 ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
0329 {
0330 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
0331 <= timeout)
0332 return -EINVAL;
0333
0334 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
0335 ath5k_hw_htoclock(ah, timeout));
0336
0337 return 0;
0338 }
0339
0340
0341
0342
0343
0344
0345 static int
0346 ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
0347 {
0348 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
0349 <= timeout)
0350 return -EINVAL;
0351
0352 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
0353 ath5k_hw_htoclock(ah, timeout));
0354
0355 return 0;
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370 int
0371 ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
0372 {
0373 struct ath_common *common = ath5k_hw_common(ah);
0374 u32 low_id, high_id;
0375 u32 pcu_reg;
0376
0377
0378 memcpy(common->macaddr, mac, ETH_ALEN);
0379
0380 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
0381
0382 low_id = get_unaligned_le32(mac);
0383 high_id = get_unaligned_le16(mac + 4);
0384
0385 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
0386 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
0387
0388 return 0;
0389 }
0390
0391
0392
0393
0394
0395
0396
0397
0398 void
0399 ath5k_hw_set_bssid(struct ath5k_hw *ah)
0400 {
0401 struct ath_common *common = ath5k_hw_common(ah);
0402 u16 tim_offset = 0;
0403
0404
0405
0406
0407 if (ah->ah_version == AR5K_AR5212)
0408 ath_hw_setbssidmask(common);
0409
0410
0411
0412
0413 ath5k_hw_reg_write(ah,
0414 get_unaligned_le32(common->curbssid),
0415 AR5K_BSS_ID0);
0416 ath5k_hw_reg_write(ah,
0417 get_unaligned_le16(common->curbssid + 4) |
0418 ((common->curaid & 0x3fff) << AR5K_BSS_ID1_AID_S),
0419 AR5K_BSS_ID1);
0420
0421 if (common->curaid == 0) {
0422 ath5k_hw_disable_pspoll(ah);
0423 return;
0424 }
0425
0426 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
0427 tim_offset ? tim_offset + 4 : 0);
0428
0429 ath5k_hw_enable_pspoll(ah, NULL, 0);
0430 }
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441
0442
0443
0444
0445
0446
0447 void
0448 ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
0449 {
0450 struct ath_common *common = ath5k_hw_common(ah);
0451
0452
0453
0454 memcpy(common->bssidmask, mask, ETH_ALEN);
0455 if (ah->ah_version == AR5K_AR5212)
0456 ath_hw_setbssidmask(common);
0457 }
0458
0459
0460
0461
0462
0463
0464
0465 void
0466 ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
0467 {
0468 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
0469 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
0470 }
0471
0472
0473
0474
0475
0476
0477
0478
0479
0480
0481
0482 u32
0483 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
0484 {
0485 u32 data, filter = 0;
0486
0487 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
0488
0489
0490 if (ah->ah_version == AR5K_AR5212) {
0491 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
0492
0493 if (data & AR5K_PHY_ERR_FIL_RADAR)
0494 filter |= AR5K_RX_FILTER_RADARERR;
0495 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
0496 filter |= AR5K_RX_FILTER_PHYERR;
0497 }
0498
0499 return filter;
0500 }
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510
0511 void
0512 ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
0513 {
0514 u32 data = 0;
0515
0516
0517 if (ah->ah_version == AR5K_AR5212) {
0518 if (filter & AR5K_RX_FILTER_RADARERR)
0519 data |= AR5K_PHY_ERR_FIL_RADAR;
0520 if (filter & AR5K_RX_FILTER_PHYERR)
0521 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
0522 }
0523
0524
0525
0526
0527 if (ah->ah_version == AR5K_AR5210 &&
0528 (filter & AR5K_RX_FILTER_RADARERR)) {
0529 filter &= ~AR5K_RX_FILTER_RADARERR;
0530 filter |= AR5K_RX_FILTER_PROM;
0531 }
0532
0533
0534 if (data)
0535 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
0536 else
0537 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
0538
0539
0540 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
0541
0542
0543 if (ah->ah_version == AR5K_AR5212)
0544 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
0545
0546 }
0547
0548
0549
0550
0551
0552
0553 #define ATH5K_MAX_TSF_READ 10
0554
0555
0556
0557
0558
0559
0560
0561 u64
0562 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
0563 {
0564 u32 tsf_lower, tsf_upper1, tsf_upper2;
0565 int i;
0566 unsigned long flags;
0567
0568
0569 local_irq_save(flags);
0570
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583 tsf_upper1 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
0584 for (i = 0; i < ATH5K_MAX_TSF_READ; i++) {
0585 tsf_lower = ath5k_hw_reg_read(ah, AR5K_TSF_L32);
0586 tsf_upper2 = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
0587 if (tsf_upper2 == tsf_upper1)
0588 break;
0589 tsf_upper1 = tsf_upper2;
0590 }
0591
0592 local_irq_restore(flags);
0593
0594 WARN_ON(i == ATH5K_MAX_TSF_READ);
0595
0596 return ((u64)tsf_upper1 << 32) | tsf_lower;
0597 }
0598
0599 #undef ATH5K_MAX_TSF_READ
0600
0601
0602
0603
0604
0605
0606
0607
0608 void
0609 ath5k_hw_set_tsf64(struct ath5k_hw *ah, u64 tsf64)
0610 {
0611 ath5k_hw_reg_write(ah, tsf64 & 0xffffffff, AR5K_TSF_L32);
0612 ath5k_hw_reg_write(ah, (tsf64 >> 32) & 0xffffffff, AR5K_TSF_U32);
0613 }
0614
0615
0616
0617
0618
0619
0620
0621 void
0622 ath5k_hw_reset_tsf(struct ath5k_hw *ah)
0623 {
0624 u32 val;
0625
0626 val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF;
0627
0628
0629
0630
0631
0632
0633
0634 ath5k_hw_reg_write(ah, val, AR5K_BEACON);
0635 ath5k_hw_reg_write(ah, val, AR5K_BEACON);
0636 }
0637
0638
0639
0640
0641
0642
0643
0644
0645
0646
0647 void
0648 ath5k_hw_init_beacon_timers(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
0649 {
0650 u32 timer1, timer2, timer3;
0651
0652
0653
0654
0655 switch (ah->opmode) {
0656 case NL80211_IFTYPE_MONITOR:
0657 case NL80211_IFTYPE_STATION:
0658
0659
0660
0661
0662 if (ah->ah_version == AR5K_AR5210) {
0663 timer1 = 0xffffffff;
0664 timer2 = 0xffffffff;
0665 } else {
0666 timer1 = 0x0000ffff;
0667 timer2 = 0x0007ffff;
0668 }
0669
0670 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PCF);
0671 break;
0672 case NL80211_IFTYPE_ADHOC:
0673 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_ADHOC_BCN_ATIM);
0674 fallthrough;
0675 default:
0676
0677
0678
0679 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3;
0680 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3;
0681 break;
0682 }
0683
0684
0685
0686
0687 timer3 = next_beacon + 1;
0688
0689
0690
0691
0692
0693 if (ah->opmode == NL80211_IFTYPE_AP ||
0694 ah->opmode == NL80211_IFTYPE_MESH_POINT)
0695 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
0696
0697 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
0698 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
0699 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
0700 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
0701
0702
0703 if (interval & AR5K_BEACON_RESET_TSF)
0704 ath5k_hw_reset_tsf(ah);
0705
0706 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
0707 AR5K_BEACON_ENABLE),
0708 AR5K_BEACON);
0709
0710
0711
0712
0713
0714
0715 if (ah->ah_version == AR5K_AR5210)
0716 ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_ISR);
0717 else
0718 ath5k_hw_reg_write(ah, AR5K_ISR_BMISS, AR5K_PISR);
0719
0720
0721
0722
0723 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, AR5K_STA_ID1_PWR_SV);
0724
0725 }
0726
0727
0728
0729
0730
0731
0732
0733
0734
0735
0736
0737
0738
0739
0740 static inline bool
0741 ath5k_check_timer_win(int a, int b, int window, int intval)
0742 {
0743
0744
0745
0746
0747
0748
0749 if ((b - a == window) ||
0750 (a - b == intval - window) ||
0751 ((a | 0x10000) - b == intval - window) ||
0752 ((b | 0x10000) - a == window))
0753 return true;
0754 return false;
0755 }
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777
0778
0779
0780
0781
0782
0783
0784
0785
0786
0787
0788
0789
0790
0791
0792
0793
0794
0795
0796 bool
0797 ath5k_hw_check_beacon_timers(struct ath5k_hw *ah, int intval)
0798 {
0799 unsigned int nbtt, atim, dma;
0800
0801 nbtt = ath5k_hw_reg_read(ah, AR5K_TIMER0);
0802 atim = ath5k_hw_reg_read(ah, AR5K_TIMER3);
0803 dma = ath5k_hw_reg_read(ah, AR5K_TIMER1) >> 3;
0804
0805
0806
0807
0808
0809 if (ath5k_check_timer_win(nbtt, atim, 1, intval) &&
0810 ath5k_check_timer_win(dma, nbtt, AR5K_TUNE_DMA_BEACON_RESP,
0811 intval))
0812 return true;
0813 return false;
0814 }
0815
0816
0817
0818
0819
0820
0821
0822
0823 void
0824 ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
0825 {
0826
0827 int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
0828 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
0829 int cts_timeout = ack_timeout;
0830
0831 ath5k_hw_set_ifs_intervals(ah, slot_time);
0832 ath5k_hw_set_ack_timeout(ah, ack_timeout);
0833 ath5k_hw_set_cts_timeout(ah, cts_timeout);
0834
0835 ah->ah_coverage_class = coverage_class;
0836 }
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850
0851 void
0852 ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
0853 {
0854 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
0855 }
0856
0857
0858
0859
0860
0861
0862
0863 void
0864 ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah)
0865 {
0866 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
0867 }
0868
0869
0870
0871
0872
0873
0874
0875
0876 int
0877 ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
0878 {
0879 struct ath_common *common = ath5k_hw_common(ah);
0880 u32 pcu_reg, beacon_reg, low_id, high_id;
0881
0882 ATH5K_DBG(ah, ATH5K_DEBUG_MODE, "mode %d\n", op_mode);
0883
0884
0885 pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
0886 pcu_reg &= ~(AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_AP
0887 | AR5K_STA_ID1_KEYSRCH_MODE
0888 | (ah->ah_version == AR5K_AR5210 ?
0889 (AR5K_STA_ID1_PWR_SV | AR5K_STA_ID1_NO_PSPOLL) : 0));
0890
0891 beacon_reg = 0;
0892
0893 switch (op_mode) {
0894 case NL80211_IFTYPE_ADHOC:
0895 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_KEYSRCH_MODE;
0896 beacon_reg |= AR5K_BCR_ADHOC;
0897 if (ah->ah_version == AR5K_AR5210)
0898 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
0899 else
0900 AR5K_REG_ENABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
0901 break;
0902
0903 case NL80211_IFTYPE_AP:
0904 case NL80211_IFTYPE_MESH_POINT:
0905 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_KEYSRCH_MODE;
0906 beacon_reg |= AR5K_BCR_AP;
0907 if (ah->ah_version == AR5K_AR5210)
0908 pcu_reg |= AR5K_STA_ID1_NO_PSPOLL;
0909 else
0910 AR5K_REG_DISABLE_BITS(ah, AR5K_CFG, AR5K_CFG_IBSS);
0911 break;
0912
0913 case NL80211_IFTYPE_STATION:
0914 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
0915 | (ah->ah_version == AR5K_AR5210 ?
0916 AR5K_STA_ID1_PWR_SV : 0);
0917 fallthrough;
0918 case NL80211_IFTYPE_MONITOR:
0919 pcu_reg |= AR5K_STA_ID1_KEYSRCH_MODE
0920 | (ah->ah_version == AR5K_AR5210 ?
0921 AR5K_STA_ID1_NO_PSPOLL : 0);
0922 break;
0923
0924 default:
0925 return -EINVAL;
0926 }
0927
0928
0929
0930
0931 low_id = get_unaligned_le32(common->macaddr);
0932 high_id = get_unaligned_le16(common->macaddr + 4);
0933 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
0934 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
0935
0936
0937
0938
0939 if (ah->ah_version == AR5K_AR5210)
0940 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
0941
0942 return 0;
0943 }
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953 void
0954 ath5k_hw_pcu_init(struct ath5k_hw *ah, enum nl80211_iftype op_mode)
0955 {
0956
0957 ath5k_hw_set_bssid(ah);
0958
0959
0960 ath5k_hw_set_opmode(ah, op_mode);
0961
0962
0963
0964
0965
0966 if (ah->ah_version == AR5K_AR5212 &&
0967 ah->nvifs)
0968 ath5k_hw_write_rate_duration(ah);
0969
0970
0971
0972
0973
0974
0975
0976
0977
0978 ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES |
0979 AR5K_TUNE_BMISS_THRES <<
0980 AR5K_RSSI_THR_BMISS_S),
0981 AR5K_RSSI_THR);
0982
0983
0984 if (ah->ah_mac_srev >= AR5K_SREV_AR2413) {
0985 ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL);
0986 ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL);
0987 }
0988
0989
0990 if (ah->ah_version == AR5K_AR5212) {
0991 ath5k_hw_reg_write(ah,
0992 AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) |
0993 AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) |
0994 AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET),
0995 AR5K_QOS_NOACK);
0996 }
0997
0998
0999 if (ah->ah_coverage_class > 0)
1000 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
1001
1002
1003 if (ah->ah_version == AR5K_AR5212) {
1004 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
1005 if (ah->ah_ack_bitrate_high)
1006 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
1007 else
1008 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
1009 }
1010 return;
1011 }