2 * Copyright (c) 2008-2011 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
43 #include "ar9002_phy.h"
46 * ar9002_hw_set_channel - set channel on single-chip device
47 * @ah: atheros hardware structure
50 * This is the function to change channel on single-chip devices, that is
51 * all devices after ar9280.
53 * This function takes the channel value in MHz and sets
54 * hardware channel value. Assumes writes have been enabled to analog bus.
59 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
63 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
64 * (freq_ref = 40MHz/(24>>amodeRefSel))
66 static int ar9002_hw_set_channel(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
68 u16 bMode
, fracMode
, aModeRefSel
= 0;
69 u32 freq
, ndiv
, channelSel
= 0, channelFrac
= 0, reg32
= 0;
70 struct chan_centers centers
;
73 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
74 freq
= centers
.synth_center
;
76 reg32
= REG_READ(ah
, AR_PHY_SYNTH_CONTROL
);
79 if (freq
< 4800) { /* 2 GHz, fractional mode */
86 channelSel
= CHANSEL_2G(freq
);
88 if (AR_SREV_9287_11_OR_LATER(ah
)) {
90 /* Enable channel spreading for channel 14 */
91 REG_WRITE_ARRAY(&ah
->iniCckfirJapan2484
,
94 REG_WRITE_ARRAY(&ah
->iniCckfirNormal
,
98 txctl
= REG_READ(ah
, AR_PHY_CCK_TX_CTRL
);
100 /* Enable channel spreading for channel 14 */
101 REG_WRITE(ah
, AR_PHY_CCK_TX_CTRL
,
102 txctl
| AR_PHY_CCK_TX_CTRL_JAPAN
);
104 REG_WRITE(ah
, AR_PHY_CCK_TX_CTRL
,
105 txctl
& ~AR_PHY_CCK_TX_CTRL_JAPAN
);
112 switch (ah
->eep_ops
->get_eeprom(ah
, EEP_FRAC_N_5G
)) {
114 if (IS_CHAN_HALF_RATE(chan
) || IS_CHAN_QUARTER_RATE(chan
))
116 else if ((freq
% 20) == 0)
118 else if ((freq
% 10) == 0)
126 * Enable 2G (fractional) mode for channels
127 * which are 5MHz spaced.
131 channelSel
= CHANSEL_5G(freq
);
133 /* RefDivA setting */
134 ath9k_hw_analog_shift_rmw(ah
, AR_AN_SYNTH9
,
135 AR_AN_SYNTH9_REFDIVA
,
136 AR_AN_SYNTH9_REFDIVA_S
, refDivA
);
141 ndiv
= (freq
* (refDivA
>> aModeRefSel
)) / 60;
142 channelSel
= ndiv
& 0x1ff;
143 channelFrac
= (ndiv
& 0xfffffe00) * 2;
144 channelSel
= (channelSel
<< 17) | channelFrac
;
150 (fracMode
<< 28) | (aModeRefSel
<< 26) | (channelSel
);
152 REG_WRITE(ah
, AR_PHY_SYNTH_CONTROL
, reg32
);
155 ah
->curchan_rad_index
= -1;
161 * ar9002_hw_spur_mitigate - convert baseband spur frequency
162 * @ah: atheros hardware structure
165 * For single-chip solutions. Converts to baseband spur frequency given the
166 * input channel frequency and compute register settings below.
168 static void ar9002_hw_spur_mitigate(struct ath_hw
*ah
,
169 struct ath9k_channel
*chan
)
171 int bb_spur
= AR_NO_SPUR
;
174 int bb_spur_off
, spur_subchannel_sd
;
176 int spur_delta_phase
;
178 int upper
, lower
, cur_vit_mask
;
181 static const int pilot_mask_reg
[4] = {
182 AR_PHY_TIMING7
, AR_PHY_TIMING8
,
183 AR_PHY_PILOT_MASK_01_30
, AR_PHY_PILOT_MASK_31_60
185 static const int chan_mask_reg
[4] = {
186 AR_PHY_TIMING9
, AR_PHY_TIMING10
,
187 AR_PHY_CHANNEL_MASK_01_30
, AR_PHY_CHANNEL_MASK_31_60
189 static const int inc
[4] = { 0, 100, 0, 0 };
190 struct chan_centers centers
;
197 bool is2GHz
= IS_CHAN_2GHZ(chan
);
199 memset(&mask_m
, 0, sizeof(int8_t) * 123);
200 memset(&mask_p
, 0, sizeof(int8_t) * 123);
202 ath9k_hw_get_channel_centers(ah
, chan
, ¢ers
);
203 freq
= centers
.synth_center
;
205 ah
->config
.spurmode
= SPUR_ENABLE_EEPROM
;
206 for (i
= 0; i
< AR_EEPROM_MODAL_SPURS
; i
++) {
207 cur_bb_spur
= ah
->eep_ops
->get_spur_channel(ah
, i
, is2GHz
);
209 if (AR_NO_SPUR
== cur_bb_spur
)
213 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_2GHZ
;
215 cur_bb_spur
= (cur_bb_spur
/ 10) + AR_BASE_FREQ_5GHZ
;
217 cur_bb_spur
= cur_bb_spur
- freq
;
219 if (IS_CHAN_HT40(chan
)) {
220 if ((cur_bb_spur
> -AR_SPUR_FEEQ_BOUND_HT40
) &&
221 (cur_bb_spur
< AR_SPUR_FEEQ_BOUND_HT40
)) {
222 bb_spur
= cur_bb_spur
;
225 } else if ((cur_bb_spur
> -AR_SPUR_FEEQ_BOUND_HT20
) &&
226 (cur_bb_spur
< AR_SPUR_FEEQ_BOUND_HT20
)) {
227 bb_spur
= cur_bb_spur
;
232 if (AR_NO_SPUR
== bb_spur
) {
233 REG_CLR_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
,
234 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
237 REG_CLR_BIT(ah
, AR_PHY_FORCE_CLKEN_CCK
,
238 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX
);
243 tmp
= REG_READ(ah
, AR_PHY_TIMING_CTRL4(0));
245 ENABLE_REGWRITE_BUFFER(ah
);
247 newVal
= tmp
| (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI
|
248 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER
|
249 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK
|
250 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK
);
251 REG_WRITE(ah
, AR_PHY_TIMING_CTRL4(0), newVal
);
253 newVal
= (AR_PHY_SPUR_REG_MASK_RATE_CNTL
|
254 AR_PHY_SPUR_REG_ENABLE_MASK_PPM
|
255 AR_PHY_SPUR_REG_MASK_RATE_SELECT
|
256 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI
|
257 SM(SPUR_RSSI_THRESH
, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH
));
258 REG_WRITE(ah
, AR_PHY_SPUR_REG
, newVal
);
260 if (IS_CHAN_HT40(chan
)) {
262 spur_subchannel_sd
= 1;
263 bb_spur_off
= bb_spur
+ 10;
265 spur_subchannel_sd
= 0;
266 bb_spur_off
= bb_spur
- 10;
269 spur_subchannel_sd
= 0;
270 bb_spur_off
= bb_spur
;
273 if (IS_CHAN_HT40(chan
))
275 ((bb_spur
* 262144) /
276 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
279 ((bb_spur
* 524288) /
280 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE
;
282 denominator
= IS_CHAN_2GHZ(chan
) ? 44 : 40;
283 spur_freq_sd
= ((bb_spur_off
* 2048) / denominator
) & 0x3ff;
285 newVal
= (AR_PHY_TIMING11_USE_SPUR_IN_AGC
|
286 SM(spur_freq_sd
, AR_PHY_TIMING11_SPUR_FREQ_SD
) |
287 SM(spur_delta_phase
, AR_PHY_TIMING11_SPUR_DELTA_PHASE
));
288 REG_WRITE(ah
, AR_PHY_TIMING11
, newVal
);
290 newVal
= spur_subchannel_sd
<< AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S
;
291 REG_WRITE(ah
, AR_PHY_SFCORR_EXT
, newVal
);
297 for (i
= 0; i
< 4; i
++) {
301 for (bp
= 0; bp
< 30; bp
++) {
302 if ((cur_bin
> lower
) && (cur_bin
< upper
)) {
303 pilot_mask
= pilot_mask
| 0x1 << bp
;
304 chan_mask
= chan_mask
| 0x1 << bp
;
309 REG_WRITE(ah
, pilot_mask_reg
[i
], pilot_mask
);
310 REG_WRITE(ah
, chan_mask_reg
[i
], chan_mask
);
317 for (i
= 0; i
< 123; i
++) {
318 if ((cur_vit_mask
> lower
) && (cur_vit_mask
< upper
)) {
320 /* workaround for gcc bug #37014 */
321 volatile int tmp_v
= abs(cur_vit_mask
- bin
);
327 if (cur_vit_mask
< 0)
328 mask_m
[abs(cur_vit_mask
/ 100)] = mask_amt
;
330 mask_p
[cur_vit_mask
/ 100] = mask_amt
;
335 tmp_mask
= (mask_m
[46] << 30) | (mask_m
[47] << 28)
336 | (mask_m
[48] << 26) | (mask_m
[49] << 24)
337 | (mask_m
[50] << 22) | (mask_m
[51] << 20)
338 | (mask_m
[52] << 18) | (mask_m
[53] << 16)
339 | (mask_m
[54] << 14) | (mask_m
[55] << 12)
340 | (mask_m
[56] << 10) | (mask_m
[57] << 8)
341 | (mask_m
[58] << 6) | (mask_m
[59] << 4)
342 | (mask_m
[60] << 2) | (mask_m
[61] << 0);
343 REG_WRITE(ah
, AR_PHY_BIN_MASK_1
, tmp_mask
);
344 REG_WRITE(ah
, AR_PHY_VIT_MASK2_M_46_61
, tmp_mask
);
346 tmp_mask
= (mask_m
[31] << 28)
347 | (mask_m
[32] << 26) | (mask_m
[33] << 24)
348 | (mask_m
[34] << 22) | (mask_m
[35] << 20)
349 | (mask_m
[36] << 18) | (mask_m
[37] << 16)
350 | (mask_m
[48] << 14) | (mask_m
[39] << 12)
351 | (mask_m
[40] << 10) | (mask_m
[41] << 8)
352 | (mask_m
[42] << 6) | (mask_m
[43] << 4)
353 | (mask_m
[44] << 2) | (mask_m
[45] << 0);
354 REG_WRITE(ah
, AR_PHY_BIN_MASK_2
, tmp_mask
);
355 REG_WRITE(ah
, AR_PHY_MASK2_M_31_45
, tmp_mask
);
357 tmp_mask
= (mask_m
[16] << 30) | (mask_m
[16] << 28)
358 | (mask_m
[18] << 26) | (mask_m
[18] << 24)
359 | (mask_m
[20] << 22) | (mask_m
[20] << 20)
360 | (mask_m
[22] << 18) | (mask_m
[22] << 16)
361 | (mask_m
[24] << 14) | (mask_m
[24] << 12)
362 | (mask_m
[25] << 10) | (mask_m
[26] << 8)
363 | (mask_m
[27] << 6) | (mask_m
[28] << 4)
364 | (mask_m
[29] << 2) | (mask_m
[30] << 0);
365 REG_WRITE(ah
, AR_PHY_BIN_MASK_3
, tmp_mask
);
366 REG_WRITE(ah
, AR_PHY_MASK2_M_16_30
, tmp_mask
);
368 tmp_mask
= (mask_m
[0] << 30) | (mask_m
[1] << 28)
369 | (mask_m
[2] << 26) | (mask_m
[3] << 24)
370 | (mask_m
[4] << 22) | (mask_m
[5] << 20)
371 | (mask_m
[6] << 18) | (mask_m
[7] << 16)
372 | (mask_m
[8] << 14) | (mask_m
[9] << 12)
373 | (mask_m
[10] << 10) | (mask_m
[11] << 8)
374 | (mask_m
[12] << 6) | (mask_m
[13] << 4)
375 | (mask_m
[14] << 2) | (mask_m
[15] << 0);
376 REG_WRITE(ah
, AR_PHY_MASK_CTL
, tmp_mask
);
377 REG_WRITE(ah
, AR_PHY_MASK2_M_00_15
, tmp_mask
);
379 tmp_mask
= (mask_p
[15] << 28)
380 | (mask_p
[14] << 26) | (mask_p
[13] << 24)
381 | (mask_p
[12] << 22) | (mask_p
[11] << 20)
382 | (mask_p
[10] << 18) | (mask_p
[9] << 16)
383 | (mask_p
[8] << 14) | (mask_p
[7] << 12)
384 | (mask_p
[6] << 10) | (mask_p
[5] << 8)
385 | (mask_p
[4] << 6) | (mask_p
[3] << 4)
386 | (mask_p
[2] << 2) | (mask_p
[1] << 0);
387 REG_WRITE(ah
, AR_PHY_BIN_MASK2_1
, tmp_mask
);
388 REG_WRITE(ah
, AR_PHY_MASK2_P_15_01
, tmp_mask
);
390 tmp_mask
= (mask_p
[30] << 28)
391 | (mask_p
[29] << 26) | (mask_p
[28] << 24)
392 | (mask_p
[27] << 22) | (mask_p
[26] << 20)
393 | (mask_p
[25] << 18) | (mask_p
[24] << 16)
394 | (mask_p
[23] << 14) | (mask_p
[22] << 12)
395 | (mask_p
[21] << 10) | (mask_p
[20] << 8)
396 | (mask_p
[19] << 6) | (mask_p
[18] << 4)
397 | (mask_p
[17] << 2) | (mask_p
[16] << 0);
398 REG_WRITE(ah
, AR_PHY_BIN_MASK2_2
, tmp_mask
);
399 REG_WRITE(ah
, AR_PHY_MASK2_P_30_16
, tmp_mask
);
401 tmp_mask
= (mask_p
[45] << 28)
402 | (mask_p
[44] << 26) | (mask_p
[43] << 24)
403 | (mask_p
[42] << 22) | (mask_p
[41] << 20)
404 | (mask_p
[40] << 18) | (mask_p
[39] << 16)
405 | (mask_p
[38] << 14) | (mask_p
[37] << 12)
406 | (mask_p
[36] << 10) | (mask_p
[35] << 8)
407 | (mask_p
[34] << 6) | (mask_p
[33] << 4)
408 | (mask_p
[32] << 2) | (mask_p
[31] << 0);
409 REG_WRITE(ah
, AR_PHY_BIN_MASK2_3
, tmp_mask
);
410 REG_WRITE(ah
, AR_PHY_MASK2_P_45_31
, tmp_mask
);
412 tmp_mask
= (mask_p
[61] << 30) | (mask_p
[60] << 28)
413 | (mask_p
[59] << 26) | (mask_p
[58] << 24)
414 | (mask_p
[57] << 22) | (mask_p
[56] << 20)
415 | (mask_p
[55] << 18) | (mask_p
[54] << 16)
416 | (mask_p
[53] << 14) | (mask_p
[52] << 12)
417 | (mask_p
[51] << 10) | (mask_p
[50] << 8)
418 | (mask_p
[49] << 6) | (mask_p
[48] << 4)
419 | (mask_p
[47] << 2) | (mask_p
[46] << 0);
420 REG_WRITE(ah
, AR_PHY_BIN_MASK2_4
, tmp_mask
);
421 REG_WRITE(ah
, AR_PHY_MASK2_P_61_45
, tmp_mask
);
423 REGWRITE_BUFFER_FLUSH(ah
);
426 static void ar9002_olc_init(struct ath_hw
*ah
)
430 if (!OLC_FOR_AR9280_20_LATER
)
433 if (OLC_FOR_AR9287_10_LATER
) {
434 REG_SET_BIT(ah
, AR_PHY_TX_PWRCTRL9
,
435 AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL
);
436 ath9k_hw_analog_shift_rmw(ah
, AR9287_AN_TXPC0
,
437 AR9287_AN_TXPC0_TXPCMODE
,
438 AR9287_AN_TXPC0_TXPCMODE_S
,
439 AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE
);
442 for (i
= 0; i
< AR9280_TX_GAIN_TABLE_SIZE
; i
++)
443 ah
->originalGain
[i
] =
444 MS(REG_READ(ah
, AR_PHY_TX_GAIN_TBL1
+ i
* 4),
450 static u32
ar9002_hw_compute_pll_control(struct ath_hw
*ah
,
451 struct ath9k_channel
*chan
)
457 if (chan
&& IS_CHAN_5GHZ(chan
) && !IS_CHAN_A_FAST_CLOCK(ah
, chan
)) {
458 if (AR_SREV_9280_20(ah
)) {
466 pll
= SM(ref_div
, AR_RTC_9160_PLL_REFDIV
);
467 pll
|= SM(pll_div
, AR_RTC_9160_PLL_DIV
);
469 if (chan
&& IS_CHAN_HALF_RATE(chan
))
470 pll
|= SM(0x1, AR_RTC_9160_PLL_CLKSEL
);
471 else if (chan
&& IS_CHAN_QUARTER_RATE(chan
))
472 pll
|= SM(0x2, AR_RTC_9160_PLL_CLKSEL
);
477 static void ar9002_hw_do_getnf(struct ath_hw
*ah
,
478 int16_t nfarray
[NUM_NF_READINGS
])
482 nf
= MS(REG_READ(ah
, AR_PHY_CCA
), AR9280_PHY_MINCCA_PWR
);
483 nfarray
[0] = sign_extend32(nf
, 8);
485 nf
= MS(REG_READ(ah
, AR_PHY_EXT_CCA
), AR9280_PHY_EXT_MINCCA_PWR
);
486 if (IS_CHAN_HT40(ah
->curchan
))
487 nfarray
[3] = sign_extend32(nf
, 8);
489 if (AR_SREV_9285(ah
) || AR_SREV_9271(ah
))
492 nf
= MS(REG_READ(ah
, AR_PHY_CH1_CCA
), AR9280_PHY_CH1_MINCCA_PWR
);
493 nfarray
[1] = sign_extend32(nf
, 8);
495 nf
= MS(REG_READ(ah
, AR_PHY_CH1_EXT_CCA
), AR9280_PHY_CH1_EXT_MINCCA_PWR
);
496 if (IS_CHAN_HT40(ah
->curchan
))
497 nfarray
[4] = sign_extend32(nf
, 8);
500 static void ar9002_hw_set_nf_limits(struct ath_hw
*ah
)
502 if (AR_SREV_9285(ah
)) {
503 ah
->nf_2g
.max
= AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ
;
504 ah
->nf_2g
.min
= AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ
;
505 ah
->nf_2g
.nominal
= AR_PHY_CCA_NOM_VAL_9285_2GHZ
;
506 } else if (AR_SREV_9287(ah
)) {
507 ah
->nf_2g
.max
= AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ
;
508 ah
->nf_2g
.min
= AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ
;
509 ah
->nf_2g
.nominal
= AR_PHY_CCA_NOM_VAL_9287_2GHZ
;
510 } else if (AR_SREV_9271(ah
)) {
511 ah
->nf_2g
.max
= AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ
;
512 ah
->nf_2g
.min
= AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ
;
513 ah
->nf_2g
.nominal
= AR_PHY_CCA_NOM_VAL_9271_2GHZ
;
515 ah
->nf_2g
.max
= AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ
;
516 ah
->nf_2g
.min
= AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ
;
517 ah
->nf_2g
.nominal
= AR_PHY_CCA_NOM_VAL_9280_2GHZ
;
518 ah
->nf_5g
.max
= AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ
;
519 ah
->nf_5g
.min
= AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ
;
520 ah
->nf_5g
.nominal
= AR_PHY_CCA_NOM_VAL_9280_5GHZ
;
524 static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw
*ah
,
525 struct ath_hw_antcomb_conf
*antconf
)
529 regval
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
530 antconf
->main_lna_conf
= (regval
& AR_PHY_9285_ANT_DIV_MAIN_LNACONF
) >>
531 AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S
;
532 antconf
->alt_lna_conf
= (regval
& AR_PHY_9285_ANT_DIV_ALT_LNACONF
) >>
533 AR_PHY_9285_ANT_DIV_ALT_LNACONF_S
;
534 antconf
->fast_div_bias
= (regval
& AR_PHY_9285_FAST_DIV_BIAS
) >>
535 AR_PHY_9285_FAST_DIV_BIAS_S
;
536 antconf
->lna1_lna2_delta
= -3;
537 antconf
->div_group
= 0;
540 static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw
*ah
,
541 struct ath_hw_antcomb_conf
*antconf
)
545 regval
= REG_READ(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
);
546 regval
&= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF
|
547 AR_PHY_9285_ANT_DIV_ALT_LNACONF
|
548 AR_PHY_9285_FAST_DIV_BIAS
);
549 regval
|= ((antconf
->main_lna_conf
<< AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S
)
550 & AR_PHY_9285_ANT_DIV_MAIN_LNACONF
);
551 regval
|= ((antconf
->alt_lna_conf
<< AR_PHY_9285_ANT_DIV_ALT_LNACONF_S
)
552 & AR_PHY_9285_ANT_DIV_ALT_LNACONF
);
553 regval
|= ((antconf
->fast_div_bias
<< AR_PHY_9285_FAST_DIV_BIAS_S
)
554 & AR_PHY_9285_FAST_DIV_BIAS
);
556 REG_WRITE(ah
, AR_PHY_MULTICHAIN_GAIN_CTL
, regval
);
559 void ar9002_hw_attach_phy_ops(struct ath_hw
*ah
)
561 struct ath_hw_private_ops
*priv_ops
= ath9k_hw_private_ops(ah
);
562 struct ath_hw_ops
*ops
= ath9k_hw_ops(ah
);
564 priv_ops
->set_rf_regs
= NULL
;
565 priv_ops
->rf_alloc_ext_banks
= NULL
;
566 priv_ops
->rf_free_ext_banks
= NULL
;
567 priv_ops
->rf_set_freq
= ar9002_hw_set_channel
;
568 priv_ops
->spur_mitigate_freq
= ar9002_hw_spur_mitigate
;
569 priv_ops
->olc_init
= ar9002_olc_init
;
570 priv_ops
->compute_pll_control
= ar9002_hw_compute_pll_control
;
571 priv_ops
->do_getnf
= ar9002_hw_do_getnf
;
573 ops
->antdiv_comb_conf_get
= ar9002_hw_antdiv_comb_conf_get
;
574 ops
->antdiv_comb_conf_set
= ar9002_hw_antdiv_comb_conf_set
;
576 ar9002_hw_set_nf_limits(ah
);