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.
17 #include <linux/moduleparam.h>
19 #include "ar5008_initvals.h"
20 #include "ar9001_initvals.h"
21 #include "ar9002_initvals.h"
22 #include "ar9002_phy.h"
24 int modparam_force_new_ani
;
25 module_param_named(force_new_ani
, modparam_force_new_ani
, int, 0444);
26 MODULE_PARM_DESC(force_new_ani
, "Force new ANI for AR5008, AR9001, AR9002");
28 /* General hardware code for the A5008/AR9001/AR9002 hadware families */
30 static void ar9002_hw_init_mode_regs(struct ath_hw
*ah
)
32 if (AR_SREV_9271(ah
)) {
33 INIT_INI_ARRAY(&ah
->iniModes
, ar9271Modes_9271
,
34 ARRAY_SIZE(ar9271Modes_9271
), 5);
35 INIT_INI_ARRAY(&ah
->iniCommon
, ar9271Common_9271
,
36 ARRAY_SIZE(ar9271Common_9271
), 2);
37 INIT_INI_ARRAY(&ah
->iniCommon_normal_cck_fir_coeff_9271
,
38 ar9271Common_normal_cck_fir_coeff_9271
,
39 ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271
), 2);
40 INIT_INI_ARRAY(&ah
->iniCommon_japan_2484_cck_fir_coeff_9271
,
41 ar9271Common_japan_2484_cck_fir_coeff_9271
,
42 ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271
), 2);
43 INIT_INI_ARRAY(&ah
->iniModes_9271_1_0_only
,
44 ar9271Modes_9271_1_0_only
,
45 ARRAY_SIZE(ar9271Modes_9271_1_0_only
), 5);
46 INIT_INI_ARRAY(&ah
->iniModes_9271_ANI_reg
, ar9271Modes_9271_ANI_reg
,
47 ARRAY_SIZE(ar9271Modes_9271_ANI_reg
), 5);
48 INIT_INI_ARRAY(&ah
->iniModes_high_power_tx_gain_9271
,
49 ar9271Modes_high_power_tx_gain_9271
,
50 ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271
), 5);
51 INIT_INI_ARRAY(&ah
->iniModes_normal_power_tx_gain_9271
,
52 ar9271Modes_normal_power_tx_gain_9271
,
53 ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271
), 5);
57 if (AR_SREV_9287_11_OR_LATER(ah
)) {
58 INIT_INI_ARRAY(&ah
->iniModes
, ar9287Modes_9287_1_1
,
59 ARRAY_SIZE(ar9287Modes_9287_1_1
), 5);
60 INIT_INI_ARRAY(&ah
->iniCommon
, ar9287Common_9287_1_1
,
61 ARRAY_SIZE(ar9287Common_9287_1_1
), 2);
62 if (ah
->config
.pcie_clock_req
)
63 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
64 ar9287PciePhy_clkreq_off_L1_9287_1_1
,
65 ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1
), 2);
67 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
68 ar9287PciePhy_clkreq_always_on_L1_9287_1_1
,
69 ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1
),
71 } else if (AR_SREV_9285_12_OR_LATER(ah
)) {
74 INIT_INI_ARRAY(&ah
->iniModes
, ar9285Modes_9285_1_2
,
75 ARRAY_SIZE(ar9285Modes_9285_1_2
), 5);
76 INIT_INI_ARRAY(&ah
->iniCommon
, ar9285Common_9285_1_2
,
77 ARRAY_SIZE(ar9285Common_9285_1_2
), 2);
79 if (ah
->config
.pcie_clock_req
) {
80 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
81 ar9285PciePhy_clkreq_off_L1_9285_1_2
,
82 ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2
), 2);
84 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
85 ar9285PciePhy_clkreq_always_on_L1_9285_1_2
,
86 ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2
),
89 } else if (AR_SREV_9280_20_OR_LATER(ah
)) {
90 INIT_INI_ARRAY(&ah
->iniModes
, ar9280Modes_9280_2
,
91 ARRAY_SIZE(ar9280Modes_9280_2
), 5);
92 INIT_INI_ARRAY(&ah
->iniCommon
, ar9280Common_9280_2
,
93 ARRAY_SIZE(ar9280Common_9280_2
), 2);
95 if (ah
->config
.pcie_clock_req
) {
96 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
97 ar9280PciePhy_clkreq_off_L1_9280
,
98 ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280
), 2);
100 INIT_INI_ARRAY(&ah
->iniPcieSerdes
,
101 ar9280PciePhy_clkreq_always_on_L1_9280
,
102 ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280
), 2);
104 INIT_INI_ARRAY(&ah
->iniModesAdditional
,
105 ar9280Modes_fast_clock_9280_2
,
106 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2
), 3);
107 } else if (AR_SREV_9160_10_OR_LATER(ah
)) {
108 INIT_INI_ARRAY(&ah
->iniModes
, ar5416Modes_9160
,
109 ARRAY_SIZE(ar5416Modes_9160
), 5);
110 INIT_INI_ARRAY(&ah
->iniCommon
, ar5416Common_9160
,
111 ARRAY_SIZE(ar5416Common_9160
), 2);
112 INIT_INI_ARRAY(&ah
->iniBank0
, ar5416Bank0_9160
,
113 ARRAY_SIZE(ar5416Bank0_9160
), 2);
114 INIT_INI_ARRAY(&ah
->iniBB_RfGain
, ar5416BB_RfGain_9160
,
115 ARRAY_SIZE(ar5416BB_RfGain_9160
), 3);
116 INIT_INI_ARRAY(&ah
->iniBank1
, ar5416Bank1_9160
,
117 ARRAY_SIZE(ar5416Bank1_9160
), 2);
118 INIT_INI_ARRAY(&ah
->iniBank2
, ar5416Bank2_9160
,
119 ARRAY_SIZE(ar5416Bank2_9160
), 2);
120 INIT_INI_ARRAY(&ah
->iniBank3
, ar5416Bank3_9160
,
121 ARRAY_SIZE(ar5416Bank3_9160
), 3);
122 INIT_INI_ARRAY(&ah
->iniBank6
, ar5416Bank6_9160
,
123 ARRAY_SIZE(ar5416Bank6_9160
), 3);
124 INIT_INI_ARRAY(&ah
->iniBank6TPC
, ar5416Bank6TPC_9160
,
125 ARRAY_SIZE(ar5416Bank6TPC_9160
), 3);
126 INIT_INI_ARRAY(&ah
->iniBank7
, ar5416Bank7_9160
,
127 ARRAY_SIZE(ar5416Bank7_9160
), 2);
128 if (AR_SREV_9160_11(ah
)) {
129 INIT_INI_ARRAY(&ah
->iniAddac
,
130 ar5416Addac_9160_1_1
,
131 ARRAY_SIZE(ar5416Addac_9160_1_1
), 2);
133 INIT_INI_ARRAY(&ah
->iniAddac
, ar5416Addac_9160
,
134 ARRAY_SIZE(ar5416Addac_9160
), 2);
136 } else if (AR_SREV_9100_OR_LATER(ah
)) {
137 INIT_INI_ARRAY(&ah
->iniModes
, ar5416Modes_9100
,
138 ARRAY_SIZE(ar5416Modes_9100
), 5);
139 INIT_INI_ARRAY(&ah
->iniCommon
, ar5416Common_9100
,
140 ARRAY_SIZE(ar5416Common_9100
), 2);
141 INIT_INI_ARRAY(&ah
->iniBank0
, ar5416Bank0_9100
,
142 ARRAY_SIZE(ar5416Bank0_9100
), 2);
143 INIT_INI_ARRAY(&ah
->iniBB_RfGain
, ar5416BB_RfGain_9100
,
144 ARRAY_SIZE(ar5416BB_RfGain_9100
), 3);
145 INIT_INI_ARRAY(&ah
->iniBank1
, ar5416Bank1_9100
,
146 ARRAY_SIZE(ar5416Bank1_9100
), 2);
147 INIT_INI_ARRAY(&ah
->iniBank2
, ar5416Bank2_9100
,
148 ARRAY_SIZE(ar5416Bank2_9100
), 2);
149 INIT_INI_ARRAY(&ah
->iniBank3
, ar5416Bank3_9100
,
150 ARRAY_SIZE(ar5416Bank3_9100
), 3);
151 INIT_INI_ARRAY(&ah
->iniBank6
, ar5416Bank6_9100
,
152 ARRAY_SIZE(ar5416Bank6_9100
), 3);
153 INIT_INI_ARRAY(&ah
->iniBank6TPC
, ar5416Bank6TPC_9100
,
154 ARRAY_SIZE(ar5416Bank6TPC_9100
), 3);
155 INIT_INI_ARRAY(&ah
->iniBank7
, ar5416Bank7_9100
,
156 ARRAY_SIZE(ar5416Bank7_9100
), 2);
157 INIT_INI_ARRAY(&ah
->iniAddac
, ar5416Addac_9100
,
158 ARRAY_SIZE(ar5416Addac_9100
), 2);
160 INIT_INI_ARRAY(&ah
->iniModes
, ar5416Modes
,
161 ARRAY_SIZE(ar5416Modes
), 5);
162 INIT_INI_ARRAY(&ah
->iniCommon
, ar5416Common
,
163 ARRAY_SIZE(ar5416Common
), 2);
164 INIT_INI_ARRAY(&ah
->iniBank0
, ar5416Bank0
,
165 ARRAY_SIZE(ar5416Bank0
), 2);
166 INIT_INI_ARRAY(&ah
->iniBB_RfGain
, ar5416BB_RfGain
,
167 ARRAY_SIZE(ar5416BB_RfGain
), 3);
168 INIT_INI_ARRAY(&ah
->iniBank1
, ar5416Bank1
,
169 ARRAY_SIZE(ar5416Bank1
), 2);
170 INIT_INI_ARRAY(&ah
->iniBank2
, ar5416Bank2
,
171 ARRAY_SIZE(ar5416Bank2
), 2);
172 INIT_INI_ARRAY(&ah
->iniBank3
, ar5416Bank3
,
173 ARRAY_SIZE(ar5416Bank3
), 3);
174 INIT_INI_ARRAY(&ah
->iniBank6
, ar5416Bank6
,
175 ARRAY_SIZE(ar5416Bank6
), 3);
176 INIT_INI_ARRAY(&ah
->iniBank6TPC
, ar5416Bank6TPC
,
177 ARRAY_SIZE(ar5416Bank6TPC
), 3);
178 INIT_INI_ARRAY(&ah
->iniBank7
, ar5416Bank7
,
179 ARRAY_SIZE(ar5416Bank7
), 2);
180 INIT_INI_ARRAY(&ah
->iniAddac
, ar5416Addac
,
181 ARRAY_SIZE(ar5416Addac
), 2);
184 /* iniAddac needs to be modified for these chips */
185 if (AR_SREV_9160(ah
) || !AR_SREV_5416_22_OR_LATER(ah
)) {
186 struct ar5416IniArray
*addac
= &ah
->iniAddac
;
187 u32 size
= sizeof(u32
) * addac
->ia_rows
* addac
->ia_columns
;
190 data
= kmalloc(size
, GFP_KERNEL
);
194 memcpy(data
, addac
->ia_array
, size
);
195 addac
->ia_array
= data
;
197 if (!AR_SREV_5416_22_OR_LATER(ah
)) {
198 /* override CLKDRV value */
199 INI_RA(addac
, 31,1) = 0;
204 /* Support for Japan ch.14 (2484) spread */
205 void ar9002_hw_cck_chan14_spread(struct ath_hw
*ah
)
207 if (AR_SREV_9287_11_OR_LATER(ah
)) {
208 INIT_INI_ARRAY(&ah
->iniCckfirNormal
,
209 ar9287Common_normal_cck_fir_coeff_9287_1_1
,
210 ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1
),
212 INIT_INI_ARRAY(&ah
->iniCckfirJapan2484
,
213 ar9287Common_japan_2484_cck_fir_coeff_9287_1_1
,
214 ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1
),
219 static void ar9280_20_hw_init_rxgain_ini(struct ath_hw
*ah
)
223 if (ah
->eep_ops
->get_eeprom(ah
, EEP_MINOR_REV
) >=
224 AR5416_EEP_MINOR_VER_17
) {
225 rxgain_type
= ah
->eep_ops
->get_eeprom(ah
, EEP_RXGAIN_TYPE
);
227 if (rxgain_type
== AR5416_EEP_RXGAIN_13DB_BACKOFF
)
228 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
229 ar9280Modes_backoff_13db_rxgain_9280_2
,
230 ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2
), 5);
231 else if (rxgain_type
== AR5416_EEP_RXGAIN_23DB_BACKOFF
)
232 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
233 ar9280Modes_backoff_23db_rxgain_9280_2
,
234 ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2
), 5);
236 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
237 ar9280Modes_original_rxgain_9280_2
,
238 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2
), 5);
240 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
241 ar9280Modes_original_rxgain_9280_2
,
242 ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2
), 5);
246 static void ar9280_20_hw_init_txgain_ini(struct ath_hw
*ah
)
250 if (ah
->eep_ops
->get_eeprom(ah
, EEP_MINOR_REV
) >=
251 AR5416_EEP_MINOR_VER_19
) {
252 txgain_type
= ah
->eep_ops
->get_eeprom(ah
, EEP_TXGAIN_TYPE
);
254 if (txgain_type
== AR5416_EEP_TXGAIN_HIGH_POWER
)
255 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
256 ar9280Modes_high_power_tx_gain_9280_2
,
257 ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2
), 5);
259 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
260 ar9280Modes_original_tx_gain_9280_2
,
261 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2
), 5);
263 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
264 ar9280Modes_original_tx_gain_9280_2
,
265 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2
), 5);
269 static void ar9002_hw_init_mode_gain_regs(struct ath_hw
*ah
)
271 if (AR_SREV_9287_11_OR_LATER(ah
))
272 INIT_INI_ARRAY(&ah
->iniModesRxGain
,
273 ar9287Modes_rx_gain_9287_1_1
,
274 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1
), 5);
275 else if (AR_SREV_9280_20(ah
))
276 ar9280_20_hw_init_rxgain_ini(ah
);
278 if (AR_SREV_9287_11_OR_LATER(ah
)) {
279 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
280 ar9287Modes_tx_gain_9287_1_1
,
281 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1
), 5);
282 } else if (AR_SREV_9280_20(ah
)) {
283 ar9280_20_hw_init_txgain_ini(ah
);
284 } else if (AR_SREV_9285_12_OR_LATER(ah
)) {
285 u32 txgain_type
= ah
->eep_ops
->get_eeprom(ah
, EEP_TXGAIN_TYPE
);
288 if (txgain_type
== AR5416_EEP_TXGAIN_HIGH_POWER
) {
289 if (AR_SREV_9285E_20(ah
)) {
290 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
291 ar9285Modes_XE2_0_high_power
,
293 ar9285Modes_XE2_0_high_power
), 5);
295 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
296 ar9285Modes_high_power_tx_gain_9285_1_2
,
298 ar9285Modes_high_power_tx_gain_9285_1_2
), 5);
301 if (AR_SREV_9285E_20(ah
)) {
302 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
303 ar9285Modes_XE2_0_normal_power
,
305 ar9285Modes_XE2_0_normal_power
), 5);
307 INIT_INI_ARRAY(&ah
->iniModesTxGain
,
308 ar9285Modes_original_tx_gain_9285_1_2
,
310 ar9285Modes_original_tx_gain_9285_1_2
), 5);
317 * Helper for ASPM support.
319 * Disable PLL when in L0s as well as receiver clock when in L1.
320 * This power saving option must be enabled through the SerDes.
322 * Programming the SerDes must go through the same 288 bit serial shift
323 * register as the other analog registers. Hence the 9 writes.
325 static void ar9002_hw_configpcipowersave(struct ath_hw
*ah
,
331 /* Nothing to do on restore for 11N */
332 if (!power_off
/* !restore */) {
333 if (AR_SREV_9280_20_OR_LATER(ah
)) {
335 * AR9280 2.0 or later chips use SerDes values from the
336 * initvals.h initialized depending on chipset during
339 for (i
= 0; i
< ah
->iniPcieSerdes
.ia_rows
; i
++) {
340 REG_WRITE(ah
, INI_RA(&ah
->iniPcieSerdes
, i
, 0),
341 INI_RA(&ah
->iniPcieSerdes
, i
, 1));
344 ENABLE_REGWRITE_BUFFER(ah
);
346 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x9248fc00);
347 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x24924924);
349 /* RX shut off when elecidle is asserted */
350 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x28000039);
351 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x53160824);
352 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xe5980579);
355 * Ignore ah->ah_config.pcie_clock_req setting for
358 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x001defff);
360 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x1aaabe40);
361 REG_WRITE(ah
, AR_PCIE_SERDES
, 0xbe105554);
362 REG_WRITE(ah
, AR_PCIE_SERDES
, 0x000e3007);
364 /* Load the new settings */
365 REG_WRITE(ah
, AR_PCIE_SERDES2
, 0x00000000);
367 REGWRITE_BUFFER_FLUSH(ah
);
374 /* clear bit 19 to disable L1 */
375 REG_CLR_BIT(ah
, AR_PCIE_PM_CTRL
, AR_PCIE_PM_CTRL_ENA
);
377 val
= REG_READ(ah
, AR_WA
);
380 * Set PCIe workaround bits
381 * In AR9280 and AR9285, bit 14 in WA register (disable L1)
382 * should only be set when device enters D3 and be
383 * cleared when device comes back to D0.
385 if (ah
->config
.pcie_waen
) {
386 if (ah
->config
.pcie_waen
& AR_WA_D3_L1_DISABLE
)
387 val
|= AR_WA_D3_L1_DISABLE
;
389 if (((AR_SREV_9285(ah
) ||
392 (AR9285_WA_DEFAULT
& AR_WA_D3_L1_DISABLE
)) ||
394 (AR9280_WA_DEFAULT
& AR_WA_D3_L1_DISABLE
))) {
395 val
|= AR_WA_D3_L1_DISABLE
;
399 if (AR_SREV_9280(ah
) || AR_SREV_9285(ah
) || AR_SREV_9287(ah
)) {
401 * Disable bit 6 and 7 before entering D3 to
402 * prevent system hang.
404 val
&= ~(AR_WA_BIT6
| AR_WA_BIT7
);
407 if (AR_SREV_9280(ah
))
410 if (AR_SREV_9285E_20(ah
))
413 REG_WRITE(ah
, AR_WA
, val
);
415 if (ah
->config
.pcie_waen
) {
416 val
= ah
->config
.pcie_waen
;
418 val
&= (~AR_WA_D3_L1_DISABLE
);
420 if (AR_SREV_9285(ah
) ||
423 val
= AR9285_WA_DEFAULT
;
425 val
&= (~AR_WA_D3_L1_DISABLE
);
427 else if (AR_SREV_9280(ah
)) {
429 * For AR9280 chips, bit 22 of 0x4004
432 val
= AR9280_WA_DEFAULT
;
434 val
&= (~AR_WA_D3_L1_DISABLE
);
440 /* WAR for ASPM system hang */
441 if (AR_SREV_9285(ah
) || AR_SREV_9287(ah
))
442 val
|= (AR_WA_BIT6
| AR_WA_BIT7
);
444 if (AR_SREV_9285E_20(ah
))
447 REG_WRITE(ah
, AR_WA
, val
);
449 /* set bit 19 to allow forcing of pcie core into L1 state */
450 REG_SET_BIT(ah
, AR_PCIE_PM_CTRL
, AR_PCIE_PM_CTRL_ENA
);
454 static int ar9002_hw_get_radiorev(struct ath_hw
*ah
)
459 ENABLE_REGWRITE_BUFFER(ah
);
461 REG_WRITE(ah
, AR_PHY(0x36), 0x00007058);
462 for (i
= 0; i
< 8; i
++)
463 REG_WRITE(ah
, AR_PHY(0x20), 0x00010000);
465 REGWRITE_BUFFER_FLUSH(ah
);
467 val
= (REG_READ(ah
, AR_PHY(256)) >> 24) & 0xff;
468 val
= ((val
& 0xf0) >> 4) | ((val
& 0x0f) << 4);
470 return ath9k_hw_reverse_bits(val
, 8);
473 int ar9002_hw_rf_claim(struct ath_hw
*ah
)
477 REG_WRITE(ah
, AR_PHY(0), 0x00000007);
479 val
= ar9002_hw_get_radiorev(ah
);
480 switch (val
& AR_RADIO_SREV_MAJOR
) {
482 val
= AR_RAD5133_SREV_MAJOR
;
484 case AR_RAD5133_SREV_MAJOR
:
485 case AR_RAD5122_SREV_MAJOR
:
486 case AR_RAD2133_SREV_MAJOR
:
487 case AR_RAD2122_SREV_MAJOR
:
490 ath_err(ath9k_hw_common(ah
),
491 "Radio Chip Rev 0x%02X not supported\n",
492 val
& AR_RADIO_SREV_MAJOR
);
496 ah
->hw_version
.analog5GhzRev
= val
;
501 void ar9002_hw_enable_async_fifo(struct ath_hw
*ah
)
503 if (AR_SREV_9287_13_OR_LATER(ah
)) {
504 REG_SET_BIT(ah
, AR_MAC_PCU_ASYNC_FIFO_REG3
,
505 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL
);
506 REG_SET_BIT(ah
, AR_PHY_MODE
, AR_PHY_MODE_ASYNCFIFO
);
507 REG_CLR_BIT(ah
, AR_MAC_PCU_ASYNC_FIFO_REG3
,
508 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET
);
509 REG_SET_BIT(ah
, AR_MAC_PCU_ASYNC_FIFO_REG3
,
510 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET
);
514 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
515 void ar9002_hw_attach_ops(struct ath_hw
*ah
)
517 struct ath_hw_private_ops
*priv_ops
= ath9k_hw_private_ops(ah
);
518 struct ath_hw_ops
*ops
= ath9k_hw_ops(ah
);
520 priv_ops
->init_mode_regs
= ar9002_hw_init_mode_regs
;
521 priv_ops
->init_mode_gain_regs
= ar9002_hw_init_mode_gain_regs
;
523 ops
->config_pci_powersave
= ar9002_hw_configpcipowersave
;
525 ar5008_hw_attach_phy_ops(ah
);
526 if (AR_SREV_9280_20_OR_LATER(ah
))
527 ar9002_hw_attach_phy_ops(ah
);
529 ar9002_hw_attach_calib_ops(ah
);
530 ar9002_hw_attach_mac_ops(ah
);
533 void ar9002_hw_load_ani_reg(struct ath_hw
*ah
, struct ath9k_channel
*chan
)
538 switch (chan
->chanmode
) {
543 case CHANNEL_A_HT40PLUS
:
544 case CHANNEL_A_HT40MINUS
:
552 case CHANNEL_G_HT40PLUS
:
553 case CHANNEL_G_HT40MINUS
:
561 ENABLE_REGWRITE_BUFFER(ah
);
563 for (i
= 0; i
< ah
->iniModes_9271_ANI_reg
.ia_rows
; i
++) {
564 u32 reg
= INI_RA(&ah
->iniModes_9271_ANI_reg
, i
, 0);
565 u32 val
= INI_RA(&ah
->iniModes_9271_ANI_reg
, i
, modesIndex
);
568 if (reg
== AR_PHY_CCK_DETECT
) {
569 val_orig
= REG_READ(ah
, reg
);
570 val
&= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK
;
571 val_orig
&= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK
;
573 REG_WRITE(ah
, reg
, val
|val_orig
);
575 REG_WRITE(ah
, reg
, val
);
578 REGWRITE_BUFFER_FLUSH(ah
);