2 * Copyright (c) 2008-2011 Atheros Communications Inc.
4 * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5 * Original from Linux kernel 3.0.1
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.
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.
21 #include "ar9003_mac.h"
22 #include "ar9003_2p2_initvals.h"
23 #include "ar9485_initvals.h"
24 #include "ar9340_initvals.h"
26 /* General hardware code for the AR9003 hadware family */
29 * The AR9003 family uses a new INI format (pre, core, post
30 * arrays per subsystem). This provides support for the
31 * AR9003 2.2 chipsets.
33 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
35 if (AR_SREV_9340(ah)) {
37 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
38 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
40 ARRAY_SIZE(ar9340_1p0_mac_core), 2);
41 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
42 ar9340_1p0_mac_postamble,
43 ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
46 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
47 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
48 ar9340_1p0_baseband_core,
49 ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
50 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
51 ar9340_1p0_baseband_postamble,
52 ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
55 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
56 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
57 ar9340_1p0_radio_core,
58 ARRAY_SIZE(ar9340_1p0_radio_core), 2);
59 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
60 ar9340_1p0_radio_postamble,
61 ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
64 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
65 ar9340_1p0_soc_preamble,
66 ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
67 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
68 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
69 ar9340_1p0_soc_postamble,
70 ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
73 INIT_INI_ARRAY(&ah->iniModesRxGain,
74 ar9340Common_wo_xlna_rx_gain_table_1p0,
75 ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
77 INIT_INI_ARRAY(&ah->iniModesTxGain,
78 ar9340Modes_high_ob_db_tx_gain_table_1p0,
79 ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
82 INIT_INI_ARRAY(&ah->iniModesAdditional,
83 ar9340Modes_fast_clock_1p0,
84 ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
87 INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
88 ar9340_1p0_radio_core_40M,
89 ARRAY_SIZE(ar9340_1p0_radio_core_40M),
91 } else if (AR_SREV_9485_11(ah)) {
93 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
94 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
96 ARRAY_SIZE(ar9485_1_1_mac_core), 2);
97 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
98 ar9485_1_1_mac_postamble,
99 ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
102 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
103 ARRAY_SIZE(ar9485_1_1), 2);
104 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
105 ar9485_1_1_baseband_core,
106 ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
107 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
108 ar9485_1_1_baseband_postamble,
109 ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
112 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
113 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
114 ar9485_1_1_radio_core,
115 ARRAY_SIZE(ar9485_1_1_radio_core), 2);
116 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
117 ar9485_1_1_radio_postamble,
118 ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
121 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
122 ar9485_1_1_soc_preamble,
123 ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
124 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
125 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
128 INIT_INI_ARRAY(&ah->iniModesRxGain,
129 ar9485Common_wo_xlna_rx_gain_1_1,
130 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
131 INIT_INI_ARRAY(&ah->iniModesTxGain,
132 ar9485_modes_lowest_ob_db_tx_gain_1_1,
133 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
136 /* Load PCIE SERDES settings from INI */
140 INIT_INI_ARRAY(&ah->iniPcieSerdes,
141 ar9485_1_1_pcie_phy_clkreq_disable_L1,
142 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
147 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
148 ar9485_1_1_pcie_phy_clkreq_disable_L1,
149 ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
153 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
154 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
156 ARRAY_SIZE(ar9300_2p2_mac_core), 2);
157 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
158 ar9300_2p2_mac_postamble,
159 ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
162 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
163 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
164 ar9300_2p2_baseband_core,
165 ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
166 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
167 ar9300_2p2_baseband_postamble,
168 ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
171 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
172 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
173 ar9300_2p2_radio_core,
174 ARRAY_SIZE(ar9300_2p2_radio_core), 2);
175 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
176 ar9300_2p2_radio_postamble,
177 ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
180 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
181 ar9300_2p2_soc_preamble,
182 ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
183 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
184 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
185 ar9300_2p2_soc_postamble,
186 ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
189 INIT_INI_ARRAY(&ah->iniModesRxGain,
190 ar9300Common_rx_gain_table_2p2,
191 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
192 INIT_INI_ARRAY(&ah->iniModesTxGain,
193 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
194 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
197 /* Load PCIE SERDES settings from INI */
201 INIT_INI_ARRAY(&ah->iniPcieSerdes,
202 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
203 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
208 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
209 ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
210 ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
213 /* Fast clock modal settings */
214 INIT_INI_ARRAY(&ah->iniModesAdditional,
215 ar9300Modes_fast_clock_2p2,
216 ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
221 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
223 switch (ar9003_hw_get_tx_gain_idx(ah)) {
226 if (AR_SREV_9340(ah))
227 INIT_INI_ARRAY(&ah->iniModesTxGain,
228 ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
229 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
231 else if (AR_SREV_9485_11(ah))
232 INIT_INI_ARRAY(&ah->iniModesTxGain,
233 ar9485_modes_lowest_ob_db_tx_gain_1_1,
234 ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
237 INIT_INI_ARRAY(&ah->iniModesTxGain,
238 ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
239 ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
243 if (AR_SREV_9340(ah))
244 INIT_INI_ARRAY(&ah->iniModesTxGain,
245 ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
246 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
248 else if (AR_SREV_9485_11(ah))
249 INIT_INI_ARRAY(&ah->iniModesTxGain,
250 ar9485Modes_high_ob_db_tx_gain_1_1,
251 ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
254 INIT_INI_ARRAY(&ah->iniModesTxGain,
255 ar9300Modes_high_ob_db_tx_gain_table_2p2,
256 ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
260 if (AR_SREV_9340(ah))
261 INIT_INI_ARRAY(&ah->iniModesTxGain,
262 ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
263 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
265 else if (AR_SREV_9485_11(ah))
266 INIT_INI_ARRAY(&ah->iniModesTxGain,
267 ar9485Modes_low_ob_db_tx_gain_1_1,
268 ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
271 INIT_INI_ARRAY(&ah->iniModesTxGain,
272 ar9300Modes_low_ob_db_tx_gain_table_2p2,
273 ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
277 if (AR_SREV_9340(ah))
278 INIT_INI_ARRAY(&ah->iniModesTxGain,
279 ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
280 ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
282 else if (AR_SREV_9485_11(ah))
283 INIT_INI_ARRAY(&ah->iniModesTxGain,
284 ar9485Modes_high_power_tx_gain_1_1,
285 ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
288 INIT_INI_ARRAY(&ah->iniModesTxGain,
289 ar9300Modes_high_power_tx_gain_table_2p2,
290 ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
296 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
298 switch (ar9003_hw_get_rx_gain_idx(ah)) {
301 if (AR_SREV_9340(ah))
302 INIT_INI_ARRAY(&ah->iniModesRxGain,
303 ar9340Common_rx_gain_table_1p0,
304 ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
306 else if (AR_SREV_9485_11(ah))
307 INIT_INI_ARRAY(&ah->iniModesRxGain,
308 ar9485Common_wo_xlna_rx_gain_1_1,
309 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
312 INIT_INI_ARRAY(&ah->iniModesRxGain,
313 ar9300Common_rx_gain_table_2p2,
314 ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
318 if (AR_SREV_9340(ah))
319 INIT_INI_ARRAY(&ah->iniModesRxGain,
320 ar9340Common_wo_xlna_rx_gain_table_1p0,
321 ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
323 else if (AR_SREV_9485_11(ah))
324 INIT_INI_ARRAY(&ah->iniModesRxGain,
325 ar9485Common_wo_xlna_rx_gain_1_1,
326 ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
329 INIT_INI_ARRAY(&ah->iniModesRxGain,
330 ar9300Common_wo_xlna_rx_gain_table_2p2,
331 ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
337 /* set gain table pointers according to values read from the eeprom */
338 static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
340 ar9003_tx_gain_table_apply(ah);
341 ar9003_rx_gain_table_apply(ah);
345 * Helper for ASPM support.
347 * Disable PLL when in L0s as well as receiver clock when in L1.
348 * This power saving option must be enabled through the SerDes.
350 * Programming the SerDes must go through the same 288 bit serial shift
351 * register as the other analog registers. Hence the 9 writes.
353 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
357 if (ah->is_pciexpress != 1)
360 /* Do not touch SerDes registers */
361 if (ah->config.pcie_powersave_enable == 2)
364 /* Nothing to do on restore for 11N */
366 /* set bit 19 to allow forcing of pcie core into L1 state */
367 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
369 /* Several PCIe massages to ensure proper behaviour */
370 if (ah->config.pcie_waen)
371 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
373 REG_WRITE(ah, AR_WA, ah->WARegVal);
377 * Configire PCIE after Ini init. SERDES values now come from ini file
378 * This enables PCIe low power mode.
380 if (ah->config.pcieSerDesWrite) {
382 struct ar5416IniArray *array;
384 array = power_off ? &ah->iniPcieSerdes :
385 &ah->iniPcieSerdesLowPower;
387 for (i = 0; i < array->ia_rows; i++) {
390 INI_RA(array, i, 1));
395 /* Sets up the AR9003 hardware familiy callbacks */
396 void ar9003_hw_attach_ops(struct ath_hw *ah)
398 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
399 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
401 priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
402 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
404 ops->config_pci_powersave = ar9003_hw_configpcipowersave;
406 ar9003_hw_attach_phy_ops(ah);
407 ar9003_hw_attach_calib_ops(ah);
408 ar9003_hw_attach_mac_ops(ah);