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