1 /*
2  * Copyright (c) 2008-2011 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 "ar9003_mac.h"
19 #include "ar9003_2p2_initvals.h"
20 #include "ar9485_initvals.h"
21 #include "ar9340_initvals.h"
22 #include "ar9330_1p1_initvals.h"
23 #include "ar9330_1p2_initvals.h"
24 
25 /* General hardware code for the AR9003 hadware family */
26 
27 /*
28  * The AR9003 family uses a new INI format (pre, core, post
29  * arrays per subsystem). This provides support for the
30  * AR9003 2.2 chipsets.
31  */
32 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
33 {
34 	if (AR_SREV_9330_11(ah)) {
35 		/* mac */
36 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
37 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
38 				ar9331_1p1_mac_core,
39 				ARRAY_SIZE(ar9331_1p1_mac_core), 2);
40 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
41 				ar9331_1p1_mac_postamble,
42 				ARRAY_SIZE(ar9331_1p1_mac_postamble), 5);
43 
44 		/* bb */
45 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
46 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
47 				ar9331_1p1_baseband_core,
48 				ARRAY_SIZE(ar9331_1p1_baseband_core), 2);
49 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
50 				ar9331_1p1_baseband_postamble,
51 				ARRAY_SIZE(ar9331_1p1_baseband_postamble), 5);
52 
53 		/* radio */
54 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
55 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
56 				ar9331_1p1_radio_core,
57 				ARRAY_SIZE(ar9331_1p1_radio_core), 2);
58 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0);
59 
60 		/* soc */
61 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
62 				ar9331_1p1_soc_preamble,
63 				ARRAY_SIZE(ar9331_1p1_soc_preamble), 2);
64 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
65 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
66 				ar9331_1p1_soc_postamble,
67 				ARRAY_SIZE(ar9331_1p1_soc_postamble), 2);
68 
69 		/* rx/tx gain */
70 		INIT_INI_ARRAY(&ah->iniModesRxGain,
71 				ar9331_common_rx_gain_1p1,
72 				ARRAY_SIZE(ar9331_common_rx_gain_1p1), 2);
73 		INIT_INI_ARRAY(&ah->iniModesTxGain,
74 			ar9331_modes_lowest_ob_db_tx_gain_1p1,
75 			ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
76 			5);
77 
78 		/* additional clock settings */
79 		if (ah->is_clk_25mhz)
80 			INIT_INI_ARRAY(&ah->iniModesAdditional,
81 					ar9331_1p1_xtal_25M,
82 					ARRAY_SIZE(ar9331_1p1_xtal_25M), 2);
83 		else
84 			INIT_INI_ARRAY(&ah->iniModesAdditional,
85 					ar9331_1p1_xtal_40M,
86 					ARRAY_SIZE(ar9331_1p1_xtal_40M), 2);
87 	} else if (AR_SREV_9330_12(ah)) {
88 		/* mac */
89 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
90 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
91 				ar9331_1p2_mac_core,
92 				ARRAY_SIZE(ar9331_1p2_mac_core), 2);
93 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
94 				ar9331_1p2_mac_postamble,
95 				ARRAY_SIZE(ar9331_1p2_mac_postamble), 5);
96 
97 		/* bb */
98 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
99 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
100 				ar9331_1p2_baseband_core,
101 				ARRAY_SIZE(ar9331_1p2_baseband_core), 2);
102 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
103 				ar9331_1p2_baseband_postamble,
104 				ARRAY_SIZE(ar9331_1p2_baseband_postamble), 5);
105 
106 		/* radio */
107 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
108 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
109 				ar9331_1p2_radio_core,
110 				ARRAY_SIZE(ar9331_1p2_radio_core), 2);
111 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], NULL, 0, 0);
112 
113 		/* soc */
114 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
115 				ar9331_1p2_soc_preamble,
116 				ARRAY_SIZE(ar9331_1p2_soc_preamble), 2);
117 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
118 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
119 				ar9331_1p2_soc_postamble,
120 				ARRAY_SIZE(ar9331_1p2_soc_postamble), 2);
121 
122 		/* rx/tx gain */
123 		INIT_INI_ARRAY(&ah->iniModesRxGain,
124 				ar9331_common_rx_gain_1p2,
125 				ARRAY_SIZE(ar9331_common_rx_gain_1p2), 2);
126 		INIT_INI_ARRAY(&ah->iniModesTxGain,
127 			ar9331_modes_lowest_ob_db_tx_gain_1p2,
128 			ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
129 			5);
130 
131 		/* additional clock settings */
132 		if (ah->is_clk_25mhz)
133 			INIT_INI_ARRAY(&ah->iniModesAdditional,
134 					ar9331_1p2_xtal_25M,
135 					ARRAY_SIZE(ar9331_1p2_xtal_25M), 2);
136 		else
137 			INIT_INI_ARRAY(&ah->iniModesAdditional,
138 					ar9331_1p2_xtal_40M,
139 					ARRAY_SIZE(ar9331_1p2_xtal_40M), 2);
140 	} else if (AR_SREV_9340(ah)) {
141 		/* mac */
142 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
143 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
144 				ar9340_1p0_mac_core,
145 				ARRAY_SIZE(ar9340_1p0_mac_core), 2);
146 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
147 				ar9340_1p0_mac_postamble,
148 				ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
149 
150 		/* bb */
151 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
152 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
153 				ar9340_1p0_baseband_core,
154 				ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
155 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
156 				ar9340_1p0_baseband_postamble,
157 				ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
158 
159 		/* radio */
160 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
161 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
162 				ar9340_1p0_radio_core,
163 				ARRAY_SIZE(ar9340_1p0_radio_core), 2);
164 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
165 				ar9340_1p0_radio_postamble,
166 				ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
167 
168 		/* soc */
169 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
170 				ar9340_1p0_soc_preamble,
171 				ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
172 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
173 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
174 				ar9340_1p0_soc_postamble,
175 				ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
176 
177 		/* rx/tx gain */
178 		INIT_INI_ARRAY(&ah->iniModesRxGain,
179 				ar9340Common_wo_xlna_rx_gain_table_1p0,
180 				ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
181 				5);
182 		INIT_INI_ARRAY(&ah->iniModesTxGain,
183 				ar9340Modes_high_ob_db_tx_gain_table_1p0,
184 				ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
185 				5);
186 
187 		INIT_INI_ARRAY(&ah->iniModesAdditional,
188 				ar9340Modes_fast_clock_1p0,
189 				ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
190 				3);
191 
192 		INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
193 				ar9340_1p0_radio_core_40M,
194 				ARRAY_SIZE(ar9340_1p0_radio_core_40M),
195 				2);
196 	} else if (AR_SREV_9485_11(ah)) {
197 		/* mac */
198 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
199 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
200 				ar9485_1_1_mac_core,
201 				ARRAY_SIZE(ar9485_1_1_mac_core), 2);
202 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
203 				ar9485_1_1_mac_postamble,
204 				ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
205 
206 		/* bb */
207 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
208 				ARRAY_SIZE(ar9485_1_1), 2);
209 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
210 				ar9485_1_1_baseband_core,
211 				ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
212 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
213 				ar9485_1_1_baseband_postamble,
214 				ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
215 
216 		/* radio */
217 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
218 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
219 				ar9485_1_1_radio_core,
220 				ARRAY_SIZE(ar9485_1_1_radio_core), 2);
221 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
222 				ar9485_1_1_radio_postamble,
223 				ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
224 
225 		/* soc */
226 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
227 				ar9485_1_1_soc_preamble,
228 				ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
229 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
230 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
231 
232 		/* rx/tx gain */
233 		INIT_INI_ARRAY(&ah->iniModesRxGain,
234 				ar9485Common_wo_xlna_rx_gain_1_1,
235 				ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
236 		INIT_INI_ARRAY(&ah->iniModesTxGain,
237 				ar9485_modes_lowest_ob_db_tx_gain_1_1,
238 				ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
239 				5);
240 
241 		/* Load PCIE SERDES settings from INI */
242 
243 		/* Awake Setting */
244 
245 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
246 				ar9485_1_1_pcie_phy_clkreq_disable_L1,
247 				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
248 				2);
249 
250 		/* Sleep Setting */
251 
252 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
253 				ar9485_1_1_pcie_phy_clkreq_disable_L1,
254 				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
255 				2);
256 	} else {
257 		/* mac */
258 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
259 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
260 				ar9300_2p2_mac_core,
261 				ARRAY_SIZE(ar9300_2p2_mac_core), 2);
262 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
263 				ar9300_2p2_mac_postamble,
264 				ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
265 
266 		/* bb */
267 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
268 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
269 				ar9300_2p2_baseband_core,
270 				ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
271 		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
272 				ar9300_2p2_baseband_postamble,
273 				ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
274 
275 		/* radio */
276 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
277 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
278 				ar9300_2p2_radio_core,
279 				ARRAY_SIZE(ar9300_2p2_radio_core), 2);
280 		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
281 				ar9300_2p2_radio_postamble,
282 				ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
283 
284 		/* soc */
285 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
286 				ar9300_2p2_soc_preamble,
287 				ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
288 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
289 		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
290 				ar9300_2p2_soc_postamble,
291 				ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
292 
293 		/* rx/tx gain */
294 		INIT_INI_ARRAY(&ah->iniModesRxGain,
295 				ar9300Common_rx_gain_table_2p2,
296 				ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
297 		INIT_INI_ARRAY(&ah->iniModesTxGain,
298 				ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
299 				ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
300 				5);
301 
302 		/* Load PCIE SERDES settings from INI */
303 
304 		/* Awake Setting */
305 
306 		INIT_INI_ARRAY(&ah->iniPcieSerdes,
307 				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
308 				ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
309 				2);
310 
311 		/* Sleep Setting */
312 
313 		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
314 				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
315 				ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
316 				2);
317 
318 		/* Fast clock modal settings */
319 		INIT_INI_ARRAY(&ah->iniModesAdditional,
320 				ar9300Modes_fast_clock_2p2,
321 				ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
322 				3);
323 	}
324 }
325 
326 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
327 {
328 	switch (ar9003_hw_get_tx_gain_idx(ah)) {
329 	case 0:
330 	default:
331 		if (AR_SREV_9330_12(ah))
332 			INIT_INI_ARRAY(&ah->iniModesTxGain,
333 				ar9331_modes_lowest_ob_db_tx_gain_1p2,
334 				ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p2),
335 				5);
336 		else if (AR_SREV_9330_11(ah))
337 			INIT_INI_ARRAY(&ah->iniModesTxGain,
338 				ar9331_modes_lowest_ob_db_tx_gain_1p1,
339 				ARRAY_SIZE(ar9331_modes_lowest_ob_db_tx_gain_1p1),
340 				5);
341 		else if (AR_SREV_9340(ah))
342 			INIT_INI_ARRAY(&ah->iniModesTxGain,
343 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
344 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
345 				       5);
346 		else if (AR_SREV_9485_11(ah))
347 			INIT_INI_ARRAY(&ah->iniModesTxGain,
348 				       ar9485_modes_lowest_ob_db_tx_gain_1_1,
349 				       ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
350 				       5);
351 		else
352 			INIT_INI_ARRAY(&ah->iniModesTxGain,
353 				       ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
354 				       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
355 				       5);
356 		break;
357 	case 1:
358 		if (AR_SREV_9330_12(ah))
359 			INIT_INI_ARRAY(&ah->iniModesTxGain,
360 				ar9331_modes_high_ob_db_tx_gain_1p2,
361 				ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p2),
362 				5);
363 		else if (AR_SREV_9330_11(ah))
364 			INIT_INI_ARRAY(&ah->iniModesTxGain,
365 				ar9331_modes_high_ob_db_tx_gain_1p1,
366 				ARRAY_SIZE(ar9331_modes_high_ob_db_tx_gain_1p1),
367 				5);
368 		else if (AR_SREV_9340(ah))
369 			INIT_INI_ARRAY(&ah->iniModesTxGain,
370 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
371 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
372 				       5);
373 		else if (AR_SREV_9485_11(ah))
374 			INIT_INI_ARRAY(&ah->iniModesTxGain,
375 				       ar9485Modes_high_ob_db_tx_gain_1_1,
376 				       ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
377 				       5);
378 		else
379 			INIT_INI_ARRAY(&ah->iniModesTxGain,
380 				       ar9300Modes_high_ob_db_tx_gain_table_2p2,
381 				       ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
382 				       5);
383 		break;
384 	case 2:
385 		if (AR_SREV_9330_12(ah))
386 			INIT_INI_ARRAY(&ah->iniModesTxGain,
387 				ar9331_modes_low_ob_db_tx_gain_1p2,
388 				ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p2),
389 				5);
390 		else if (AR_SREV_9330_11(ah))
391 			INIT_INI_ARRAY(&ah->iniModesTxGain,
392 				ar9331_modes_low_ob_db_tx_gain_1p1,
393 				ARRAY_SIZE(ar9331_modes_low_ob_db_tx_gain_1p1),
394 				5);
395 		else if (AR_SREV_9340(ah))
396 			INIT_INI_ARRAY(&ah->iniModesTxGain,
397 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
398 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
399 				       5);
400 		else if (AR_SREV_9485_11(ah))
401 			INIT_INI_ARRAY(&ah->iniModesTxGain,
402 				       ar9485Modes_low_ob_db_tx_gain_1_1,
403 				       ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
404 				       5);
405 		else
406 			INIT_INI_ARRAY(&ah->iniModesTxGain,
407 				       ar9300Modes_low_ob_db_tx_gain_table_2p2,
408 				       ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
409 				       5);
410 		break;
411 	case 3:
412 		if (AR_SREV_9330_12(ah))
413 			INIT_INI_ARRAY(&ah->iniModesTxGain,
414 				ar9331_modes_high_power_tx_gain_1p2,
415 				ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p2),
416 				5);
417 		else if (AR_SREV_9330_11(ah))
418 			INIT_INI_ARRAY(&ah->iniModesTxGain,
419 				ar9331_modes_high_power_tx_gain_1p1,
420 				ARRAY_SIZE(ar9331_modes_high_power_tx_gain_1p1),
421 				5);
422 		else if (AR_SREV_9340(ah))
423 			INIT_INI_ARRAY(&ah->iniModesTxGain,
424 					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
425 				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
426 				       5);
427 		else if (AR_SREV_9485_11(ah))
428 			INIT_INI_ARRAY(&ah->iniModesTxGain,
429 				       ar9485Modes_high_power_tx_gain_1_1,
430 				       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
431 				       5);
432 		else
433 			INIT_INI_ARRAY(&ah->iniModesTxGain,
434 				       ar9300Modes_high_power_tx_gain_table_2p2,
435 				       ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
436 				       5);
437 		break;
438 	}
439 }
440 
441 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
442 {
443 	switch (ar9003_hw_get_rx_gain_idx(ah)) {
444 	case 0:
445 	default:
446 		if (AR_SREV_9330_12(ah))
447 			INIT_INI_ARRAY(&ah->iniModesRxGain,
448 					ar9331_common_rx_gain_1p2,
449 					ARRAY_SIZE(ar9331_common_rx_gain_1p2),
450 					2);
451 		else if (AR_SREV_9330_11(ah))
452 			INIT_INI_ARRAY(&ah->iniModesRxGain,
453 					ar9331_common_rx_gain_1p1,
454 					ARRAY_SIZE(ar9331_common_rx_gain_1p1),
455 					2);
456 		else if (AR_SREV_9340(ah))
457 			INIT_INI_ARRAY(&ah->iniModesRxGain,
458 				       ar9340Common_rx_gain_table_1p0,
459 				       ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
460 				       2);
461 		else if (AR_SREV_9485_11(ah))
462 			INIT_INI_ARRAY(&ah->iniModesRxGain,
463 				       ar9485Common_wo_xlna_rx_gain_1_1,
464 				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
465 				       2);
466 		else
467 			INIT_INI_ARRAY(&ah->iniModesRxGain,
468 				       ar9300Common_rx_gain_table_2p2,
469 				       ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
470 				       2);
471 		break;
472 	case 1:
473 		if (AR_SREV_9330_12(ah))
474 			INIT_INI_ARRAY(&ah->iniModesRxGain,
475 				ar9331_common_wo_xlna_rx_gain_1p2,
476 				ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p2),
477 				2);
478 		else if (AR_SREV_9330_11(ah))
479 			INIT_INI_ARRAY(&ah->iniModesRxGain,
480 				ar9331_common_wo_xlna_rx_gain_1p1,
481 				ARRAY_SIZE(ar9331_common_wo_xlna_rx_gain_1p1),
482 				2);
483 		else if (AR_SREV_9340(ah))
484 			INIT_INI_ARRAY(&ah->iniModesRxGain,
485 				       ar9340Common_wo_xlna_rx_gain_table_1p0,
486 				       ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
487 				       2);
488 		else if (AR_SREV_9485_11(ah))
489 			INIT_INI_ARRAY(&ah->iniModesRxGain,
490 				       ar9485Common_wo_xlna_rx_gain_1_1,
491 				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
492 				       2);
493 		else
494 			INIT_INI_ARRAY(&ah->iniModesRxGain,
495 				       ar9300Common_wo_xlna_rx_gain_table_2p2,
496 				       ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
497 				       2);
498 		break;
499 	}
500 }
501 
502 /* set gain table pointers according to values read from the eeprom */
503 static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
504 {
505 	ar9003_tx_gain_table_apply(ah);
506 	ar9003_rx_gain_table_apply(ah);
507 }
508 
509 /*
510  * Helper for ASPM support.
511  *
512  * Disable PLL when in L0s as well as receiver clock when in L1.
513  * This power saving option must be enabled through the SerDes.
514  *
515  * Programming the SerDes must go through the same 288 bit serial shift
516  * register as the other analog registers.  Hence the 9 writes.
517  */
518 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
519 					 int restore,
520 					 int power_off)
521 {
522 	if (ah->is_pciexpress != true)
523 		return;
524 
525 	/* Do not touch SerDes registers */
526 	if (ah->config.pcie_powersave_enable == 2)
527 		return;
528 
529 	/* Nothing to do on restore for 11N */
530 	if (!restore) {
531 		/* set bit 19 to allow forcing of pcie core into L1 state */
532 		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
533 
534 		/* Several PCIe massages to ensure proper behaviour */
535 		if (ah->config.pcie_waen)
536 			REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
537 		else
538 			REG_WRITE(ah, AR_WA, ah->WARegVal);
539 	}
540 
541 	/*
542 	 * Configire PCIE after Ini init. SERDES values now come from ini file
543 	 * This enables PCIe low power mode.
544 	 */
545 	if (ah->config.pcieSerDesWrite) {
546 		unsigned int i;
547 		struct ar5416IniArray *array;
548 
549 		array = power_off ? &ah->iniPcieSerdes :
550 				    &ah->iniPcieSerdesLowPower;
551 
552 		for (i = 0; i < array->ia_rows; i++) {
553 			REG_WRITE(ah,
554 				  INI_RA(array, i, 0),
555 				  INI_RA(array, i, 1));
556 		}
557 	}
558 }
559 
560 /* Sets up the AR9003 hardware familiy callbacks */
561 void ar9003_hw_attach_ops(struct ath_hw *ah)
562 {
563 	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
564 	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
565 
566 	priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
567 	priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
568 
569 	ops->config_pci_powersave = ar9003_hw_configpcipowersave;
570 
571 	ar9003_hw_attach_phy_ops(ah);
572 	ar9003_hw_attach_calib_ops(ah);
573 	ar9003_hw_attach_mac_ops(ah);
574 }
575