Merge branch 'master' into for-2.6.35
[pandora-kernel.git] / drivers / net / wireless / ath / ath9k / ar9003_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 "ar9003_mac.h"
19 #include "ar9003_initvals.h"
20
21 /* General hardware code for the AR9003 hadware family */
22
23 static bool ar9003_hw_macversion_supported(u32 macversion)
24 {
25         switch (macversion) {
26         case AR_SREV_VERSION_9300:
27                 return true;
28         default:
29                 break;
30         }
31         return false;
32 }
33
34 /* AR9003 2.0 - new INI format (pre, core, post arrays per subsystem) */
35 /*
36  * XXX: move TX/RX gain INI to its own init_mode_gain_regs after
37  * ensuring it does not affect hardware bring up
38  */
39 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
40 {
41         /* mac */
42         INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
43         INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
44                        ar9300_2p0_mac_core,
45                        ARRAY_SIZE(ar9300_2p0_mac_core), 2);
46         INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
47                        ar9300_2p0_mac_postamble,
48                        ARRAY_SIZE(ar9300_2p0_mac_postamble), 5);
49
50         /* bb */
51         INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
52         INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
53                        ar9300_2p0_baseband_core,
54                        ARRAY_SIZE(ar9300_2p0_baseband_core), 2);
55         INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
56                        ar9300_2p0_baseband_postamble,
57                        ARRAY_SIZE(ar9300_2p0_baseband_postamble), 5);
58
59         /* radio */
60         INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
61         INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
62                        ar9300_2p0_radio_core,
63                        ARRAY_SIZE(ar9300_2p0_radio_core), 2);
64         INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
65                        ar9300_2p0_radio_postamble,
66                        ARRAY_SIZE(ar9300_2p0_radio_postamble), 5);
67
68         /* soc */
69         INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
70                        ar9300_2p0_soc_preamble,
71                        ARRAY_SIZE(ar9300_2p0_soc_preamble), 2);
72         INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
73         INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
74                        ar9300_2p0_soc_postamble,
75                        ARRAY_SIZE(ar9300_2p0_soc_postamble), 5);
76
77         /* rx/tx gain */
78         INIT_INI_ARRAY(&ah->iniModesRxGain,
79                        ar9300Common_rx_gain_table_2p0,
80                        ARRAY_SIZE(ar9300Common_rx_gain_table_2p0), 2);
81         INIT_INI_ARRAY(&ah->iniModesTxGain,
82                        ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
83                        ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
84                        5);
85
86         /* Load PCIE SERDES settings from INI */
87
88         /* Awake Setting */
89
90         INIT_INI_ARRAY(&ah->iniPcieSerdes,
91                        ar9300PciePhy_pll_on_clkreq_disable_L1_2p0,
92                        ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p0),
93                        2);
94
95         /* Sleep Setting */
96
97         INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
98                        ar9300PciePhy_clkreq_enable_L1_2p0,
99                        ARRAY_SIZE(ar9300PciePhy_clkreq_enable_L1_2p0),
100                        2);
101
102         /* Fast clock modal settings */
103         INIT_INI_ARRAY(&ah->iniModesAdditional,
104                        ar9300Modes_fast_clock_2p0,
105                        ARRAY_SIZE(ar9300Modes_fast_clock_2p0),
106                        3);
107 }
108
109 static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
110 {
111         switch (ar9003_hw_get_tx_gain_idx(ah)) {
112         case 0:
113         default:
114                 INIT_INI_ARRAY(&ah->iniModesTxGain,
115                                ar9300Modes_lowest_ob_db_tx_gain_table_2p0,
116                                ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p0),
117                                5);
118                 break;
119         case 1:
120                 INIT_INI_ARRAY(&ah->iniModesTxGain,
121                                ar9300Modes_high_ob_db_tx_gain_table_2p0,
122                                ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p0),
123                                5);
124                 break;
125         case 2:
126                 INIT_INI_ARRAY(&ah->iniModesTxGain,
127                                ar9300Modes_low_ob_db_tx_gain_table_2p0,
128                                ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p0),
129                                5);
130                 break;
131         }
132 }
133
134 static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
135 {
136         switch (ar9003_hw_get_rx_gain_idx(ah)) {
137         case 0:
138         default:
139                 INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_rx_gain_table_2p0,
140                                ARRAY_SIZE(ar9300Common_rx_gain_table_2p0),
141                                2);
142                 break;
143         case 1:
144                 INIT_INI_ARRAY(&ah->iniModesRxGain,
145                                ar9300Common_wo_xlna_rx_gain_table_2p0,
146                                ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p0),
147                                2);
148                 break;
149         }
150 }
151
152 /* set gain table pointers according to values read from the eeprom */
153 static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
154 {
155         ar9003_tx_gain_table_apply(ah);
156         ar9003_rx_gain_table_apply(ah);
157 }
158
159 /*
160  * Helper for ASPM support.
161  *
162  * Disable PLL when in L0s as well as receiver clock when in L1.
163  * This power saving option must be enabled through the SerDes.
164  *
165  * Programming the SerDes must go through the same 288 bit serial shift
166  * register as the other analog registers.  Hence the 9 writes.
167  */
168 static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
169                                          int restore,
170                                          int power_off)
171 {
172         if (ah->is_pciexpress != true)
173                 return;
174
175         /* Do not touch SerDes registers */
176         if (ah->config.pcie_powersave_enable == 2)
177                 return;
178
179         /* Nothing to do on restore for 11N */
180         if (!restore) {
181                 /* set bit 19 to allow forcing of pcie core into L1 state */
182                 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
183
184                 /* Several PCIe massages to ensure proper behaviour */
185                 if (ah->config.pcie_waen)
186                         REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
187         }
188 }
189
190 /* Sets up the AR9003 hardware familiy callbacks */
191 void ar9003_hw_attach_ops(struct ath_hw *ah)
192 {
193         struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
194         struct ath_hw_ops *ops = ath9k_hw_ops(ah);
195
196         priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
197         priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
198         priv_ops->macversion_supported = ar9003_hw_macversion_supported;
199
200         ops->config_pci_powersave = ar9003_hw_configpcipowersave;
201
202         ar9003_hw_attach_phy_ops(ah);
203         ar9003_hw_attach_calib_ops(ah);
204         ar9003_hw_attach_mac_ops(ah);
205 }