2 * Copyright (c) 2008-2009 Atheros Communications Inc.
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.
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.
18 * DOC: Programming Atheros 802.11n analog front end radios
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.
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.
29 * The following single-chips exist with a respective embedded radio:
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
36 * AR9220 - 11n dual-band 2x2 MIMO for PCI
37 * AR9223 - 11n single-band 2x2 MIMO for PCI
39 * AR9287 - 11n single-band 1x1 MIMO for USB
42 #include <linux/slab.h>
47 * ath9k_hw_write_regs - ??
49 * @ah: atheros hardware structure
53 * Used for both the chipsets with an external AR2133/AR5133 radios and
54 * single-chip devices.
56 void ath9k_hw_write_regs(struct ath_hw
*ah
, u32 freqIndex
, int regWrites
)
58 REG_WRITE_ARRAY(&ah
->iniBB_RfGain
, freqIndex
, regWrites
);
62 * ath9k_hw_ar9280_set_channel - set channel on single-chip device
63 * @ah: atheros hardware structure
66 * This is the function to change channel on single-chip devices, that is
67 * all devices after ar9280.
69 * This function takes the channel value in MHz and sets
70 * hardware channel value. Assumes writes have been enabled to analog bus.
75 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
79 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
80 * (freq_ref = 40MHz/(24>>amodeRefSel))
82 int ath9k_hw_ar9280_set_channel(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
84 u16 bMode
, fracMode
, aModeRefSel
= 0;
85 u32 freq
, ndiv
, channelSel
= 0, channelFrac
= 0, reg32
= 0;
86 struct chan_centers centers
;
89 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
90 freq
= centers
.synth_center
;
92 reg32
= REG_READ(ah
, AR_PHY_SYNTH_CONTROL
);
95 if (freq
< 4800) { /* 2 GHz, fractional mode */
102 channelSel
= (freq
* 0x10000) / 15;
104 if (AR_SREV_9287_11_OR_LATER(ah
)) {
106 /* Enable channel spreading for channel 14 */
107 REG_WRITE_ARRAY(&ah
->iniCckfirJapan2484
,
110 REG_WRITE_ARRAY(&ah
->iniCckfirNormal
,
114 txctl
= REG_READ(ah
, AR_PHY_CCK_TX_CTRL
);
116 /* Enable channel spreading for channel 14 */
117 REG_WRITE(ah
, AR_PHY_CCK_TX_CTRL
,
118 txctl
| AR_PHY_CCK_TX_CTRL_JAPAN
);
120 REG_WRITE(ah
, AR_PHY_CCK_TX_CTRL
,
121 txctl
&~ AR_PHY_CCK_TX_CTRL_JAPAN
);
128 switch(ah
->eep_ops
->get_eeprom(ah
, EEP_FRAC_N_5G
)) {
130 if ((freq
% 20) == 0) {
132 } else if ((freq
% 10) == 0) {
141 * Enable 2G (fractional) mode for channels
142 * which are 5MHz spaced.
146 channelSel
= (freq
* 0x8000) / 15;
148 /* RefDivA setting */
149 REG_RMW_FIELD(ah
, AR_AN_SYNTH9
,
150 AR_AN_SYNTH9_REFDIVA
, refDivA
);
155 ndiv
= (freq
* (refDivA
>> aModeRefSel
)) / 60;
156 channelSel
= ndiv
& 0x1ff;
157 channelFrac
= (ndiv
& 0xfffffe00) * 2;
158 channelSel
= (channelSel
<< 17) | channelFrac
;
164 (fracMode
<< 28) | (aModeRefSel
<< 26) | (channelSel
);
166 REG_WRITE(ah
, AR_PHY_SYNTH_CONTROL
, reg32
);
169 ah
->curchan_rad_index
= -1;
175 * ath9k_hw_9280_spur_mitigate - convert baseband spur frequency
176 * @ah: atheros hardware structure
179 * For single-chip solutions. Converts to baseband spur frequency given the
180 * input channel frequency and compute register settings below.
182 void ath9k_hw_9280_spur_mitigate(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
184 int bb_spur
= AR_NO_SPUR
;
187 int bb_spur_off
, spur_subchannel_sd
;
189 int spur_delta_phase
;
191 int upper
, lower
, cur_vit_mask
;
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
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
200 int inc
[4] = { 0, 100, 0, 0 };
201 struct chan_centers centers
;
208 bool is2GHz
= IS_CHAN_2GHZ(chan
);
210 memset(&mask_m
, 0, sizeof(int8_t) * 123);
211 memset(&mask_p
, 0, sizeof(int8_t) * 123);
213 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
214 freq
= centers
.synth_center
;
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
);
221 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_2GHZ
;
223 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_5GHZ
;
225 if (AR_NO_SPUR
== cur_bb_spur
)
227 cur_bb_spur
= cur_bb_spur
- freq
;
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
;
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
;
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
);
247 REG_CLR_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
,
248 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
253 tmp
= REG_READ(ah
, AR_PHY_TIMING_CTRL4(0));
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
);
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
);
268 if (IS_CHAN_HT40(chan
)) {
270 spur_subchannel_sd
= 1;
271 bb_spur_off
= bb_spur
+ 10;
273 spur_subchannel_sd
= 0;
274 bb_spur_off
= bb_spur
- 10;
277 spur_subchannel_sd
= 0;
278 bb_spur_off
= bb_spur
;
281 if (IS_CHAN_HT40(chan
))
283 ((bb_spur
* 262144) /
284 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
287 ((bb_spur
* 524288) /
288 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
290 denominator
= IS_CHAN_2GHZ(chan
) ? 44 : 40;
291 spur_freq_sd
= ((bb_spur_off
* 2048) / denominator
) & 0x3ff;
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
);
298 newVal
= spur_subchannel_sd
<< AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S
;
299 REG_WRITE(ah
, AR_PHY_SFCORR_EXT
, newVal
);
305 for (i
= 0; i
< 4; i
++) {
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
;
317 REG_WRITE(ah
, pilot_mask_reg
[i
], pilot_mask
);
318 REG_WRITE(ah
, chan_mask_reg
[i
], chan_mask
);
325 for (i
= 0; i
< 123; i
++) {
326 if ((cur_vit_mask
> lower
) && (cur_vit_mask
< upper
)) {
328 /* workaround for gcc bug #37014 */
329 volatile int tmp_v
= abs(cur_vit_mask
- bin
);
335 if (cur_vit_mask
< 0)
336 mask_m
[abs(cur_vit_mask
/ 100)] = mask_amt
;
338 mask_p
[cur_vit_mask
/ 100] = mask_amt
;
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
432 /* All code below is for non single-chip solutions */
435 * ath9k_phy_modify_rx_buffer() - perform analog swizzling of parameters
442 * Performs analog "swizzling" of parameters into their location.
443 * Used on external AR2133/AR5133 radios.
445 static void ath9k_phy_modify_rx_buffer(u32
*rfBuf
, u32 reg32
,
446 u32 numBits
, u32 firstBit
,
449 u32 tmp32
, mask
, arrayEntry
, lastBit
;
450 int32_t bitPosition
, bitsLeft
;
452 tmp32
= ath9k_hw_reverse_bits(reg32
, numBits
);
453 arrayEntry
= (firstBit
- 1) / 8;
454 bitPosition
= (firstBit
- 1) % 8;
456 while (bitsLeft
> 0) {
457 lastBit
= (bitPosition
+ bitsLeft
> 8) ?
458 8 : bitPosition
+ bitsLeft
;
459 mask
= (((1 << lastBit
) - 1) ^ ((1 << bitPosition
) - 1)) <<
461 rfBuf
[arrayEntry
] &= ~mask
;
462 rfBuf
[arrayEntry
] |= ((tmp32
<< bitPosition
) <<
463 (column
* 8)) & mask
;
464 bitsLeft
-= 8 - bitPosition
;
465 tmp32
= tmp32
>> (8 - bitPosition
);
472 * Fix on 2.4 GHz band for orientation sensitivity issue by increasing
478 * if synth_freq < 2412
480 * else if 2412 <= synth_freq <= 2422
482 * else // synth_freq > 2422
484 * else if forceBias > 0
485 * bias = forceBias & 7
487 * no change, use value from ini file
489 * no change, invalid band
492 * 2422 also uses value of 2
496 * Less than 2412 uses value of 0, 2412 and above uses value of 2
498 static void ath9k_hw_force_bias(struct ath_hw
*ah
, u16 synth_freq
)
500 struct ath_common
*common
= ath9k_hw_common(ah
);
505 if (!AR_SREV_5416(ah
) || synth_freq
>= 3000) {
509 BUG_ON(AR_SREV_9280_10_OR_LATER(ah
));
511 if (synth_freq
< 2412)
513 else if (synth_freq
< 2422)
518 /* pre-reverse this field */
519 tmp_reg
= ath9k_hw_reverse_bits(new_bias
, 3);
521 ath_print(common
, ATH_DBG_CONFIG
,
522 "Force rf_pwd_icsyndiv to %1d on %4d\n",
523 new_bias
, synth_freq
);
525 /* swizzle rf_pwd_icsyndiv */
526 ath9k_phy_modify_rx_buffer(ah
->analogBank6Data
, tmp_reg
, 3, 181, 3);
528 /* write Bank 6 with new params */
529 REG_WRITE_RF_ARRAY(&ah
->iniBank6
, ah
->analogBank6Data
, reg_writes
);
533 * ath9k_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios
534 * @ah: atheros hardware stucture
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.
541 int ath9k_hw_set_channel(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
543 struct ath_common
*common
= ath9k_hw_common(ah
);
549 struct chan_centers centers
;
551 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
552 freq
= centers
.synth_center
;
557 if (((freq
- 2192) % 5) == 0) {
558 channelSel
= ((freq
- 672) * 2 - 3040) / 10;
560 } else if (((freq
- 2224) % 5) == 0) {
561 channelSel
= ((freq
- 704) * 2 - 3040) / 10;
564 ath_print(common
, ATH_DBG_FATAL
,
565 "Invalid channel %u MHz\n", freq
);
569 channelSel
= (channelSel
<< 2) & 0xff;
570 channelSel
= ath9k_hw_reverse_bits(channelSel
, 8);
572 txctl
= REG_READ(ah
, AR_PHY_CCK_TX_CTRL
);
575 REG_WRITE(ah
, AR_PHY_CCK_TX_CTRL
,
576 txctl
| AR_PHY_CCK_TX_CTRL_JAPAN
);
578 REG_WRITE(ah
, AR_PHY_CCK_TX_CTRL
,
579 txctl
& ~AR_PHY_CCK_TX_CTRL_JAPAN
);
582 } else if ((freq
% 20) == 0 && freq
>= 5120) {
584 ath9k_hw_reverse_bits(((freq
- 4800) / 20 << 2), 8);
585 aModeRefSel
= ath9k_hw_reverse_bits(1, 2);
586 } else if ((freq
% 10) == 0) {
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);
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);
597 ath_print(common
, ATH_DBG_FATAL
,
598 "Invalid channel %u MHz\n", freq
);
602 ath9k_hw_force_bias(ah
, freq
);
605 (channelSel
<< 8) | (aModeRefSel
<< 2) | (bModeSynth
<< 1) |
608 REG_WRITE(ah
, AR_PHY(0x37), reg32
);
611 ah
->curchan_rad_index
= -1;
617 * ath9k_hw_spur_mitigate - convert baseband spur frequency for external radios
618 * @ah: atheros hardware structure
621 * For non single-chip solutions. Converts to baseband spur frequency given the
622 * input channel frequency and compute register settings below.
624 void ath9k_hw_spur_mitigate(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
626 int bb_spur
= AR_NO_SPUR
;
629 int spur_delta_phase
;
631 int upper
, lower
, cur_vit_mask
;
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
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
640 int inc
[4] = { 0, 100, 0, 0 };
647 bool is2GHz
= IS_CHAN_2GHZ(chan
);
649 memset(&mask_m
, 0, sizeof(int8_t) * 123);
650 memset(&mask_p
, 0, sizeof(int8_t) * 123);
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
)
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
;
663 if (AR_NO_SPUR
== bb_spur
)
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
);
674 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0), new);
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);
683 spur_delta_phase
= ((bb_spur
* 524288) / 100) &
684 AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
686 denominator
= IS_CHAN_2GHZ(chan
) ? 440 : 400;
687 spur_freq_sd
= ((bb_spur
* 2048) / denominator
) & 0x3ff;
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);
698 for (i
= 0; i
< 4; i
++) {
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
;
710 REG_WRITE(ah
, pilot_mask_reg
[i
], pilot_mask
);
711 REG_WRITE(ah
, chan_mask_reg
[i
], chan_mask
);
718 for (i
= 0; i
< 123; i
++) {
719 if ((cur_vit_mask
> lower
) && (cur_vit_mask
< upper
)) {
721 /* workaround for gcc bug #37014 */
722 volatile int tmp_v
= abs(cur_vit_mask
- bin
);
728 if (cur_vit_mask
< 0)
729 mask_m
[abs(cur_vit_mask
/ 100)] = mask_amt
;
731 mask_p
[cur_vit_mask
/ 100] = mask_amt
;
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
826 * ath9k_hw_rf_alloc_ext_banks - allocates banks for external radio programming
827 * @ah: atheros hardware structure
829 * Only required for older devices with external AR2133/AR5133 radios.
831 int ath9k_hw_rf_alloc_ext_banks(struct ath_hw
*ah
)
833 #define ATH_ALLOC_BANK(bank, size) do { \
834 bank = kzalloc((sizeof(u32) * size), GFP_KERNEL); \
836 ath_print(common, ATH_DBG_FATAL, \
837 "Cannot allocate RF banks\n"); \
842 struct ath_common
*common
= ath9k_hw_common(ah
);
844 BUG_ON(AR_SREV_9280_10_OR_LATER(ah
));
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
);
858 #undef ATH_ALLOC_BANK
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.
868 ath9k_hw_rf_free_ext_banks(struct ath_hw
*ah
)
870 #define ATH_FREE_BANK(bank) do { \
875 BUG_ON(AR_SREV_9280_10_OR_LATER(ah
));
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
);
891 * ath9k_hw_set_rf_regs - programs rf registers based on EEPROM
892 * @ah: atheros hardware structure
896 * Used for the external AR2133/AR5133 radios.
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.
902 bool ath9k_hw_set_rf_regs(struct ath_hw
*ah
, struct ath9k_channel
*chan
,
906 u32 ob5GHz
= 0, db5GHz
= 0;
907 u32 ob2GHz
= 0, db2GHz
= 0;
911 * Software does not need to program bank data
912 * for single chip devices, that is AR9280 or anything
915 if (AR_SREV_9280_10_OR_LATER(ah
))
918 /* Setup rf parameters */
919 eepMinorRev
= ah
->eep_ops
->get_eeprom(ah
, EEP_MINOR_REV
);
921 /* Setup Bank 0 Write */
922 RF_BANK_SETUP(ah
->analogBank0Data
, &ah
->iniBank0
, 1);
924 /* Setup Bank 1 Write */
925 RF_BANK_SETUP(ah
->analogBank1Data
, &ah
->iniBank1
, 1);
927 /* Setup Bank 2 Write */
928 RF_BANK_SETUP(ah
->analogBank2Data
, &ah
->iniBank2
, 1);
930 /* Setup Bank 6 Write */
931 RF_BANK_SETUP(ah
->analogBank3Data
, &ah
->iniBank3
,
935 for (i
= 0; i
< ah
->iniBank6TPC
.ia_rows
; i
++) {
936 ah
->analogBank6Data
[i
] =
937 INI_RA(&ah
->iniBank6TPC
, i
, modesIndex
);
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
,
948 ath9k_phy_modify_rx_buffer(ah
->analogBank6Data
,
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
,
955 ath9k_phy_modify_rx_buffer(ah
->analogBank6Data
,
960 /* Setup Bank 7 Setup */
961 RF_BANK_SETUP(ah
->analogBank7Data
, &ah
->iniBank7
, 1);
963 /* Write Analog registers */
964 REG_WRITE_RF_ARRAY(&ah
->iniBank0
, ah
->analogBank0Data
,
966 REG_WRITE_RF_ARRAY(&ah
->iniBank1
, ah
->analogBank1Data
,
968 REG_WRITE_RF_ARRAY(&ah
->iniBank2
, ah
->analogBank2Data
,
970 REG_WRITE_RF_ARRAY(&ah
->iniBank3
, ah
->analogBank3Data
,
972 REG_WRITE_RF_ARRAY(&ah
->iniBank6TPC
, ah
->analogBank6Data
,
974 REG_WRITE_RF_ARRAY(&ah
->iniBank7
, ah
->analogBank7Data
,