Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / ath / ath9k / ath9k_ar9002_hw.c
1 /*
2  * Copyright (c) 2008-2011 Atheros Communications Inc.
3  *
4  * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5  * Original from Linux kernel 3.0.1
6  *
7  * Permission to use, copy, modify, and/or distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19
20 FILE_LICENCE ( BSD2 );
21
22 #include "hw.h"
23 #include "ar5008_initvals.h"
24 #include "ar9001_initvals.h"
25 #include "ar9002_initvals.h"
26 #include "ar9002_phy.h"
27
28 int modparam_force_new_ani;
29
30 /* General hardware code for the A5008/AR9001/AR9002 hadware families */
31
32 static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
33 {
34         if (AR_SREV_9271(ah)) {
35                 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
36                                ARRAY_SIZE(ar9271Modes_9271), 6);
37                 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
38                                ARRAY_SIZE(ar9271Common_9271), 2);
39                 INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
40                                ar9271Common_normal_cck_fir_coeff_9271,
41                                ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
42                 INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
43                                ar9271Common_japan_2484_cck_fir_coeff_9271,
44                                ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
45                 INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
46                                ar9271Modes_9271_1_0_only,
47                                ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
48                 INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
49                                ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
50                 INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
51                                ar9271Modes_high_power_tx_gain_9271,
52                                ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
53                 INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
54                                ar9271Modes_normal_power_tx_gain_9271,
55                                ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
56                 return;
57         }
58
59         if (AR_SREV_9287_11_OR_LATER(ah)) {
60                 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
61                                 ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
62                 INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
63                                 ARRAY_SIZE(ar9287Common_9287_1_1), 2);
64                 if (ah->config.pcie_clock_req)
65                         INIT_INI_ARRAY(&ah->iniPcieSerdes,
66                         ar9287PciePhy_clkreq_off_L1_9287_1_1,
67                         ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
68                 else
69                         INIT_INI_ARRAY(&ah->iniPcieSerdes,
70                         ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
71                         ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
72                                         2);
73         } else if (AR_SREV_9285_12_OR_LATER(ah)) {
74
75
76                 INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
77                                ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
78                 INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
79                                ARRAY_SIZE(ar9285Common_9285_1_2), 2);
80
81                 if (ah->config.pcie_clock_req) {
82                         INIT_INI_ARRAY(&ah->iniPcieSerdes,
83                         ar9285PciePhy_clkreq_off_L1_9285_1_2,
84                         ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
85                 } else {
86                         INIT_INI_ARRAY(&ah->iniPcieSerdes,
87                         ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
88                         ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
89                                   2);
90                 }
91         } else if (AR_SREV_9280_20_OR_LATER(ah)) {
92                 INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
93                                ARRAY_SIZE(ar9280Modes_9280_2), 6);
94                 INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
95                                ARRAY_SIZE(ar9280Common_9280_2), 2);
96
97                 if (ah->config.pcie_clock_req) {
98                         INIT_INI_ARRAY(&ah->iniPcieSerdes,
99                                ar9280PciePhy_clkreq_off_L1_9280,
100                                ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
101                 } else {
102                         INIT_INI_ARRAY(&ah->iniPcieSerdes,
103                                ar9280PciePhy_clkreq_always_on_L1_9280,
104                                ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
105                 }
106                 INIT_INI_ARRAY(&ah->iniModesAdditional,
107                                ar9280Modes_fast_clock_9280_2,
108                                ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
109         } else if (AR_SREV_9160_10_OR_LATER(ah)) {
110                 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
111                                ARRAY_SIZE(ar5416Modes_9160), 6);
112                 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
113                                ARRAY_SIZE(ar5416Common_9160), 2);
114                 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
115                                ARRAY_SIZE(ar5416Bank0_9160), 2);
116                 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
117                                ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
118                 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
119                                ARRAY_SIZE(ar5416Bank1_9160), 2);
120                 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
121                                ARRAY_SIZE(ar5416Bank2_9160), 2);
122                 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
123                                ARRAY_SIZE(ar5416Bank3_9160), 3);
124                 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
125                                ARRAY_SIZE(ar5416Bank6_9160), 3);
126                 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
127                                ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
128                 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
129                                ARRAY_SIZE(ar5416Bank7_9160), 2);
130                 if (AR_SREV_9160_11(ah)) {
131                         INIT_INI_ARRAY(&ah->iniAddac,
132                                        ar5416Addac_9160_1_1,
133                                        ARRAY_SIZE(ar5416Addac_9160_1_1), 2);
134                 } else {
135                         INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
136                                        ARRAY_SIZE(ar5416Addac_9160), 2);
137                 }
138         } else if (AR_SREV_9100_OR_LATER(ah)) {
139                 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
140                                ARRAY_SIZE(ar5416Modes_9100), 6);
141                 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
142                                ARRAY_SIZE(ar5416Common_9100), 2);
143                 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
144                                ARRAY_SIZE(ar5416Bank0_9100), 2);
145                 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
146                                ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
147                 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
148                                ARRAY_SIZE(ar5416Bank1_9100), 2);
149                 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
150                                ARRAY_SIZE(ar5416Bank2_9100), 2);
151                 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
152                                ARRAY_SIZE(ar5416Bank3_9100), 3);
153                 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
154                                ARRAY_SIZE(ar5416Bank6_9100), 3);
155                 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
156                                ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
157                 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
158                                ARRAY_SIZE(ar5416Bank7_9100), 2);
159                 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
160                                ARRAY_SIZE(ar5416Addac_9100), 2);
161         } else {
162                 INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
163                                ARRAY_SIZE(ar5416Modes), 6);
164                 INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
165                                ARRAY_SIZE(ar5416Common), 2);
166                 INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
167                                ARRAY_SIZE(ar5416Bank0), 2);
168                 INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
169                                ARRAY_SIZE(ar5416BB_RfGain), 3);
170                 INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
171                                ARRAY_SIZE(ar5416Bank1), 2);
172                 INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
173                                ARRAY_SIZE(ar5416Bank2), 2);
174                 INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
175                                ARRAY_SIZE(ar5416Bank3), 3);
176                 INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
177                                ARRAY_SIZE(ar5416Bank6), 3);
178                 INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
179                                ARRAY_SIZE(ar5416Bank6TPC), 3);
180                 INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
181                                ARRAY_SIZE(ar5416Bank7), 2);
182                 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
183                                ARRAY_SIZE(ar5416Addac), 2);
184         }
185 }
186
187 /* Support for Japan ch.14 (2484) spread */
188 void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
189 {
190         if (AR_SREV_9287_11_OR_LATER(ah)) {
191                 INIT_INI_ARRAY(&ah->iniCckfirNormal,
192                        ar9287Common_normal_cck_fir_coeff_9287_1_1,
193                        ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1),
194                        2);
195                 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
196                        ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
197                        ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1),
198                        2);
199         }
200 }
201
202 static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
203 {
204         u32 rxgain_type;
205
206         if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
207             AR5416_EEP_MINOR_VER_17) {
208                 rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
209
210                 if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
211                         INIT_INI_ARRAY(&ah->iniModesRxGain,
212                         ar9280Modes_backoff_13db_rxgain_9280_2,
213                         ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
214                 else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
215                         INIT_INI_ARRAY(&ah->iniModesRxGain,
216                         ar9280Modes_backoff_23db_rxgain_9280_2,
217                         ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
218                 else
219                         INIT_INI_ARRAY(&ah->iniModesRxGain,
220                         ar9280Modes_original_rxgain_9280_2,
221                         ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
222         } else {
223                 INIT_INI_ARRAY(&ah->iniModesRxGain,
224                         ar9280Modes_original_rxgain_9280_2,
225                         ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
226         }
227 }
228
229 static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
230 {
231         u32 txgain_type;
232
233         if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
234             AR5416_EEP_MINOR_VER_19) {
235                 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
236
237                 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
238                         INIT_INI_ARRAY(&ah->iniModesTxGain,
239                         ar9280Modes_high_power_tx_gain_9280_2,
240                         ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
241                 else
242                         INIT_INI_ARRAY(&ah->iniModesTxGain,
243                         ar9280Modes_original_tx_gain_9280_2,
244                         ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
245         } else {
246                 INIT_INI_ARRAY(&ah->iniModesTxGain,
247                 ar9280Modes_original_tx_gain_9280_2,
248                 ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
249         }
250 }
251
252 static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
253 {
254         if (AR_SREV_9287_11_OR_LATER(ah))
255                 INIT_INI_ARRAY(&ah->iniModesRxGain,
256                 ar9287Modes_rx_gain_9287_1_1,
257                 ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
258         else if (AR_SREV_9280_20(ah))
259                 ar9280_20_hw_init_rxgain_ini(ah);
260
261         if (AR_SREV_9287_11_OR_LATER(ah)) {
262                 INIT_INI_ARRAY(&ah->iniModesTxGain,
263                 ar9287Modes_tx_gain_9287_1_1,
264                 ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
265         } else if (AR_SREV_9280_20(ah)) {
266                 ar9280_20_hw_init_txgain_ini(ah);
267         } else if (AR_SREV_9285_12_OR_LATER(ah)) {
268                 u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
269
270                 /* txgain table */
271                 if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
272                         if (AR_SREV_9285E_20(ah)) {
273                                 INIT_INI_ARRAY(&ah->iniModesTxGain,
274                                 ar9285Modes_XE2_0_high_power,
275                                 ARRAY_SIZE(
276                                   ar9285Modes_XE2_0_high_power), 6);
277                         } else {
278                                 INIT_INI_ARRAY(&ah->iniModesTxGain,
279                                 ar9285Modes_high_power_tx_gain_9285_1_2,
280                                 ARRAY_SIZE(
281                                   ar9285Modes_high_power_tx_gain_9285_1_2), 6);
282                         }
283                 } else {
284                         if (AR_SREV_9285E_20(ah)) {
285                                 INIT_INI_ARRAY(&ah->iniModesTxGain,
286                                 ar9285Modes_XE2_0_normal_power,
287                                 ARRAY_SIZE(
288                                   ar9285Modes_XE2_0_normal_power), 6);
289                         } else {
290                                 INIT_INI_ARRAY(&ah->iniModesTxGain,
291                                 ar9285Modes_original_tx_gain_9285_1_2,
292                                 ARRAY_SIZE(
293                                   ar9285Modes_original_tx_gain_9285_1_2), 6);
294                         }
295                 }
296         }
297 }
298
299 /*
300  * Helper for ASPM support.
301  *
302  * Disable PLL when in L0s as well as receiver clock when in L1.
303  * This power saving option must be enabled through the SerDes.
304  *
305  * Programming the SerDes must go through the same 288 bit serial shift
306  * register as the other analog registers.  Hence the 9 writes.
307  */
308 static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
309                                          int restore,
310                                          int power_off)
311 {
312         u8 i;
313         u32 val;
314
315         if (ah->is_pciexpress != 1)
316                 return;
317
318         /* Do not touch SerDes registers */
319         if (ah->config.pcie_powersave_enable == 2)
320                 return;
321
322         /* Nothing to do on restore for 11N */
323         if (!restore) {
324                 if (AR_SREV_9280_20_OR_LATER(ah)) {
325                         /*
326                          * AR9280 2.0 or later chips use SerDes values from the
327                          * initvals.h initialized depending on chipset during
328                          * __ath9k_hw_init()
329                          */
330                         for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
331                                 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
332                                           INI_RA(&ah->iniPcieSerdes, i, 1));
333                         }
334                 } else {
335                         ENABLE_REGWRITE_BUFFER(ah);
336
337                         REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
338                         REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
339
340                         /* RX shut off when elecidle is asserted */
341                         REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
342                         REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
343                         REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
344
345                         /*
346                          * Ignore ah->ah_config.pcie_clock_req setting for
347                          * pre-AR9280 11n
348                          */
349                         REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
350
351                         REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
352                         REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
353                         REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
354
355                         /* Load the new settings */
356                         REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
357
358                         REGWRITE_BUFFER_FLUSH(ah);
359                 }
360
361                 udelay(1000);
362         }
363
364         if (power_off) {
365                 /* clear bit 19 to disable L1 */
366                 REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
367
368                 val = REG_READ(ah, AR_WA);
369
370                 /*
371                  * Set PCIe workaround bits
372                  * In AR9280 and AR9285, bit 14 in WA register (disable L1)
373                  * should only  be set when device enters D3 and be
374                  * cleared when device comes back to D0.
375                  */
376                 if (ah->config.pcie_waen) {
377                         if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
378                                 val |= AR_WA_D3_L1_DISABLE;
379                 } else {
380                         if (((AR_SREV_9285(ah) ||
381                               AR_SREV_9271(ah) ||
382                               AR_SREV_9287(ah)) &&
383                              (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
384                             (AR_SREV_9280(ah) &&
385                              (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
386                                 val |= AR_WA_D3_L1_DISABLE;
387                         }
388                 }
389
390                 if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
391                         /*
392                          * Disable bit 6 and 7 before entering D3 to
393                          * prevent system hang.
394                          */
395                         val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
396                 }
397
398                 if (AR_SREV_9280(ah))
399                         val |= AR_WA_BIT22;
400
401                 if (AR_SREV_9285E_20(ah))
402                         val |= AR_WA_BIT23;
403
404                 REG_WRITE(ah, AR_WA, val);
405         } else {
406                 if (ah->config.pcie_waen) {
407                         val = ah->config.pcie_waen;
408                         if (!power_off)
409                                 val &= (~AR_WA_D3_L1_DISABLE);
410                 } else {
411                         if (AR_SREV_9285(ah) ||
412                             AR_SREV_9271(ah) ||
413                             AR_SREV_9287(ah)) {
414                                 val = AR9285_WA_DEFAULT;
415                                 if (!power_off)
416                                         val &= (~AR_WA_D3_L1_DISABLE);
417                         }
418                         else if (AR_SREV_9280(ah)) {
419                                 /*
420                                  * For AR9280 chips, bit 22 of 0x4004
421                                  * needs to be set.
422                                  */
423                                 val = AR9280_WA_DEFAULT;
424                                 if (!power_off)
425                                         val &= (~AR_WA_D3_L1_DISABLE);
426                         } else {
427                                 val = AR_WA_DEFAULT;
428                         }
429                 }
430
431                 /* WAR for ASPM system hang */
432                 if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
433                         val |= (AR_WA_BIT6 | AR_WA_BIT7);
434
435                 if (AR_SREV_9285E_20(ah))
436                         val |= AR_WA_BIT23;
437
438                 REG_WRITE(ah, AR_WA, val);
439
440                 /* set bit 19 to allow forcing of pcie core into L1 state */
441                 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
442         }
443 }
444
445 static int ar9002_hw_get_radiorev(struct ath_hw *ah)
446 {
447         u32 val;
448         int i;
449
450         ENABLE_REGWRITE_BUFFER(ah);
451
452         REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
453         for (i = 0; i < 8; i++)
454                 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
455
456         REGWRITE_BUFFER_FLUSH(ah);
457
458         val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
459         val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
460
461         return ath9k_hw_reverse_bits(val, 8);
462 }
463
464 int ar9002_hw_rf_claim(struct ath_hw *ah)
465 {
466         u32 val;
467
468         REG_WRITE(ah, AR_PHY(0), 0x00000007);
469
470         val = ar9002_hw_get_radiorev(ah);
471         switch (val & AR_RADIO_SREV_MAJOR) {
472         case 0:
473                 val = AR_RAD5133_SREV_MAJOR;
474                 break;
475         case AR_RAD5133_SREV_MAJOR:
476         case AR_RAD5122_SREV_MAJOR:
477         case AR_RAD2133_SREV_MAJOR:
478         case AR_RAD2122_SREV_MAJOR:
479                 break;
480         default:
481                 DBG("ath9k: "
482                         "Radio Chip Rev 0x%02X not supported\n",
483                         val & AR_RADIO_SREV_MAJOR);
484                 return -EOPNOTSUPP;
485         }
486
487         ah->hw_version.analog5GhzRev = val;
488
489         return 0;
490 }
491
492 void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
493 {
494         if (AR_SREV_9287_13_OR_LATER(ah)) {
495                 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
496                                 AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
497                 REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
498                 REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
499                                 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
500                 REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
501                                 AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
502         }
503 }
504
505 /*
506  * If Async FIFO is enabled, the following counters change as MAC now runs
507  * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
508  *
509  * The values below tested for ht40 2 chain.
510  * Overwrite the delay/timeouts initialized in process ini.
511  */
512 void ar9002_hw_update_async_fifo(struct ath_hw *ah)
513 {
514         if (AR_SREV_9287_13_OR_LATER(ah)) {
515                 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
516                           AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
517                 REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
518                           AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
519                 REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
520                           AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
521
522                 REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
523                 REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
524
525                 REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
526                             AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
527                 REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
528                               AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
529         }
530 }
531
532 /*
533  * We don't enable WEP aggregation on mac80211 but we keep this
534  * around for HAL unification purposes.
535  */
536 void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
537 {
538         if (AR_SREV_9287_13_OR_LATER(ah)) {
539                 REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
540                             AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
541         }
542 }
543
544 /* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
545 void ar9002_hw_attach_ops(struct ath_hw *ah)
546 {
547         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
548         struct ath_hw_ops *ops = ath9k_hw_ops(ah);
549
550         priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
551         priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
552
553         ops->config_pci_powersave = ar9002_hw_configpcipowersave;
554
555         ar5008_hw_attach_phy_ops(ah);
556         if (AR_SREV_9280_20_OR_LATER(ah))
557                 ar9002_hw_attach_phy_ops(ah);
558
559         ar9002_hw_attach_calib_ops(ah);
560         ar9002_hw_attach_mac_ops(ah);
561 }
562
563 void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
564 {
565         u32 modesIndex;
566         unsigned int i;
567
568         switch (chan->chanmode) {
569         case CHANNEL_A:
570         case CHANNEL_A_HT20:
571                 modesIndex = 1;
572                 break;
573         case CHANNEL_A_HT40PLUS:
574         case CHANNEL_A_HT40MINUS:
575                 modesIndex = 2;
576                 break;
577         case CHANNEL_G:
578         case CHANNEL_G_HT20:
579         case CHANNEL_B:
580                 modesIndex = 4;
581                 break;
582         case CHANNEL_G_HT40PLUS:
583         case CHANNEL_G_HT40MINUS:
584                 modesIndex = 3;
585                 break;
586
587         default:
588                 return;
589         }
590
591         ENABLE_REGWRITE_BUFFER(ah);
592
593         for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) {
594                 u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0);
595                 u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex);
596                 u32 val_orig;
597
598                 if (reg == AR_PHY_CCK_DETECT) {
599                         val_orig = REG_READ(ah, reg);
600                         val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
601                         val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
602
603                         REG_WRITE(ah, reg, val|val_orig);
604                 } else
605                         REG_WRITE(ah, reg, val);
606         }
607
608         REGWRITE_BUFFER_FLUSH(ah);
609 }