diff options
author | Senthil Balasubramanian <senthilkumar@atheros.com> | 2010-04-15 17:39:14 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-04-16 15:43:37 -0400 |
commit | 15c9ee7af8a3527a82013ea447da2d8c491aabfe (patch) | |
tree | 01ddec2e3724a2fea801eafab59c3c82d4cb8a73 | |
parent | 49101676b2f1a66e0043509423e876414c73b5aa (diff) |
ath9k_hw: Implement AR9003 eeprom callbacks
Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 1842 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | 319 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/eeprom.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/eeprom.h | 11 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/reg.h | 11 |
7 files changed, 2187 insertions, 4 deletions
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile index ee8f7e87e9ce..b0702fc84651 100644 --- a/drivers/net/wireless/ath/ath9k/Makefile +++ b/drivers/net/wireless/ath/ath9k/Makefile | |||
@@ -30,7 +30,8 @@ ath9k_hw-y:= \ | |||
30 | ani.o \ | 30 | ani.o \ |
31 | btcoex.o \ | 31 | btcoex.o \ |
32 | mac.o \ | 32 | mac.o \ |
33 | ar9003_mac.o | 33 | ar9003_mac.o \ |
34 | ar9003_eeprom.o | ||
34 | 35 | ||
35 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o | 36 | obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o |
36 | 37 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c new file mode 100644 index 000000000000..fb39e392d9f7 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -0,0 +1,1842 @@ | |||
1 | /* | ||
2 | * Copyright (c) 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_phy.h" | ||
19 | #include "ar9003_eeprom.h" | ||
20 | |||
21 | #define COMP_HDR_LEN 4 | ||
22 | #define COMP_CKSUM_LEN 2 | ||
23 | |||
24 | #define AR_CH0_TOP (0x00016288) | ||
25 | #define AR_CH0_TOP_XPABIASLVL (0x3) | ||
26 | #define AR_CH0_TOP_XPABIASLVL_S (8) | ||
27 | |||
28 | #define AR_CH0_THERM (0x00016290) | ||
29 | #define AR_CH0_THERM_SPARE (0x3f) | ||
30 | #define AR_CH0_THERM_SPARE_S (0) | ||
31 | |||
32 | #define AR_SWITCH_TABLE_COM_ALL (0xffff) | ||
33 | #define AR_SWITCH_TABLE_COM_ALL_S (0) | ||
34 | |||
35 | #define AR_SWITCH_TABLE_COM2_ALL (0xffffff) | ||
36 | #define AR_SWITCH_TABLE_COM2_ALL_S (0) | ||
37 | |||
38 | #define AR_SWITCH_TABLE_ALL (0xfff) | ||
39 | #define AR_SWITCH_TABLE_ALL_S (0) | ||
40 | |||
41 | static const struct ar9300_eeprom ar9300_default = { | ||
42 | .eepromVersion = 2, | ||
43 | .templateVersion = 2, | ||
44 | .macAddr = {1, 2, 3, 4, 5, 6}, | ||
45 | .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
46 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, | ||
47 | .baseEepHeader = { | ||
48 | .regDmn = {0, 0x1f}, | ||
49 | .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */ | ||
50 | .opCapFlags = { | ||
51 | .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A, | ||
52 | .eepMisc = 0, | ||
53 | }, | ||
54 | .rfSilent = 0, | ||
55 | .blueToothOptions = 0, | ||
56 | .deviceCap = 0, | ||
57 | .deviceType = 5, /* takes lower byte in eeprom location */ | ||
58 | .pwrTableOffset = AR9300_PWR_TABLE_OFFSET, | ||
59 | .params_for_tuning_caps = {0, 0}, | ||
60 | .featureEnable = 0x0c, | ||
61 | /* | ||
62 | * bit0 - enable tx temp comp - disabled | ||
63 | * bit1 - enable tx volt comp - disabled | ||
64 | * bit2 - enable fastClock - enabled | ||
65 | * bit3 - enable doubling - enabled | ||
66 | * bit4 - enable internal regulator - disabled | ||
67 | */ | ||
68 | .miscConfiguration = 0, /* bit0 - turn down drivestrength */ | ||
69 | .eepromWriteEnableGpio = 3, | ||
70 | .wlanDisableGpio = 0, | ||
71 | .wlanLedGpio = 8, | ||
72 | .rxBandSelectGpio = 0xff, | ||
73 | .txrxgain = 0, | ||
74 | .swreg = 0, | ||
75 | }, | ||
76 | .modalHeader2G = { | ||
77 | /* ar9300_modal_eep_header 2g */ | ||
78 | /* 4 idle,t1,t2,b(4 bits per setting) */ | ||
79 | .antCtrlCommon = 0x110, | ||
80 | /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ | ||
81 | .antCtrlCommon2 = 0x22222, | ||
82 | |||
83 | /* | ||
84 | * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r, | ||
85 | * rx1, rx12, b (2 bits each) | ||
86 | */ | ||
87 | .antCtrlChain = {0x150, 0x150, 0x150}, | ||
88 | |||
89 | /* | ||
90 | * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db | ||
91 | * for ar9280 (0xa20c/b20c 5:0) | ||
92 | */ | ||
93 | .xatten1DB = {0, 0, 0}, | ||
94 | |||
95 | /* | ||
96 | * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin | ||
97 | * for ar9280 (0xa20c/b20c 16:12 | ||
98 | */ | ||
99 | .xatten1Margin = {0, 0, 0}, | ||
100 | .tempSlope = 36, | ||
101 | .voltSlope = 0, | ||
102 | |||
103 | /* | ||
104 | * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur | ||
105 | * channels in usual fbin coding format | ||
106 | */ | ||
107 | .spurChans = {0, 0, 0, 0, 0}, | ||
108 | |||
109 | /* | ||
110 | * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check | ||
111 | * if the register is per chain | ||
112 | */ | ||
113 | .noiseFloorThreshCh = {-1, 0, 0}, | ||
114 | .ob = {1, 1, 1},/* 3 chain */ | ||
115 | .db_stage2 = {1, 1, 1}, /* 3 chain */ | ||
116 | .db_stage3 = {0, 0, 0}, | ||
117 | .db_stage4 = {0, 0, 0}, | ||
118 | .xpaBiasLvl = 0, | ||
119 | .txFrameToDataStart = 0x0e, | ||
120 | .txFrameToPaOn = 0x0e, | ||
121 | .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ | ||
122 | .antennaGain = 0, | ||
123 | .switchSettling = 0x2c, | ||
124 | .adcDesiredSize = -30, | ||
125 | .txEndToXpaOff = 0, | ||
126 | .txEndToRxOn = 0x2, | ||
127 | .txFrameToXpaOn = 0xe, | ||
128 | .thresh62 = 28, | ||
129 | .futureModal = { /* [32] */ | ||
130 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
131 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
132 | }, | ||
133 | }, | ||
134 | .calFreqPier2G = { | ||
135 | FREQ2FBIN(2412, 1), | ||
136 | FREQ2FBIN(2437, 1), | ||
137 | FREQ2FBIN(2472, 1), | ||
138 | }, | ||
139 | /* ar9300_cal_data_per_freq_op_loop 2g */ | ||
140 | .calPierData2G = { | ||
141 | { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, | ||
142 | { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, | ||
143 | { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} }, | ||
144 | }, | ||
145 | .calTarget_freqbin_Cck = { | ||
146 | FREQ2FBIN(2412, 1), | ||
147 | FREQ2FBIN(2484, 1), | ||
148 | }, | ||
149 | .calTarget_freqbin_2G = { | ||
150 | FREQ2FBIN(2412, 1), | ||
151 | FREQ2FBIN(2437, 1), | ||
152 | FREQ2FBIN(2472, 1) | ||
153 | }, | ||
154 | .calTarget_freqbin_2GHT20 = { | ||
155 | FREQ2FBIN(2412, 1), | ||
156 | FREQ2FBIN(2437, 1), | ||
157 | FREQ2FBIN(2472, 1) | ||
158 | }, | ||
159 | .calTarget_freqbin_2GHT40 = { | ||
160 | FREQ2FBIN(2412, 1), | ||
161 | FREQ2FBIN(2437, 1), | ||
162 | FREQ2FBIN(2472, 1) | ||
163 | }, | ||
164 | .calTargetPowerCck = { | ||
165 | /* 1L-5L,5S,11L,11S */ | ||
166 | { {36, 36, 36, 36} }, | ||
167 | { {36, 36, 36, 36} }, | ||
168 | }, | ||
169 | .calTargetPower2G = { | ||
170 | /* 6-24,36,48,54 */ | ||
171 | { {32, 32, 28, 24} }, | ||
172 | { {32, 32, 28, 24} }, | ||
173 | { {32, 32, 28, 24} }, | ||
174 | }, | ||
175 | .calTargetPower2GHT20 = { | ||
176 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
177 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
178 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
179 | }, | ||
180 | .calTargetPower2GHT40 = { | ||
181 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
182 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
183 | { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} }, | ||
184 | }, | ||
185 | .ctlIndex_2G = { | ||
186 | 0x11, 0x12, 0x15, 0x17, 0x41, 0x42, | ||
187 | 0x45, 0x47, 0x31, 0x32, 0x35, 0x37, | ||
188 | }, | ||
189 | .ctl_freqbin_2G = { | ||
190 | { | ||
191 | FREQ2FBIN(2412, 1), | ||
192 | FREQ2FBIN(2417, 1), | ||
193 | FREQ2FBIN(2457, 1), | ||
194 | FREQ2FBIN(2462, 1) | ||
195 | }, | ||
196 | { | ||
197 | FREQ2FBIN(2412, 1), | ||
198 | FREQ2FBIN(2417, 1), | ||
199 | FREQ2FBIN(2462, 1), | ||
200 | 0xFF, | ||
201 | }, | ||
202 | |||
203 | { | ||
204 | FREQ2FBIN(2412, 1), | ||
205 | FREQ2FBIN(2417, 1), | ||
206 | FREQ2FBIN(2462, 1), | ||
207 | 0xFF, | ||
208 | }, | ||
209 | { | ||
210 | FREQ2FBIN(2422, 1), | ||
211 | FREQ2FBIN(2427, 1), | ||
212 | FREQ2FBIN(2447, 1), | ||
213 | FREQ2FBIN(2452, 1) | ||
214 | }, | ||
215 | |||
216 | { | ||
217 | /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
218 | /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
219 | /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
220 | /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1), | ||
221 | }, | ||
222 | |||
223 | { | ||
224 | /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
225 | /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
226 | /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
227 | 0, | ||
228 | }, | ||
229 | |||
230 | { | ||
231 | /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
232 | /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
233 | FREQ2FBIN(2472, 1), | ||
234 | 0, | ||
235 | }, | ||
236 | |||
237 | { | ||
238 | /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), | ||
239 | /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), | ||
240 | /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), | ||
241 | /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1), | ||
242 | }, | ||
243 | |||
244 | { | ||
245 | /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
246 | /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
247 | /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
248 | }, | ||
249 | |||
250 | { | ||
251 | /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
252 | /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
253 | /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
254 | 0 | ||
255 | }, | ||
256 | |||
257 | { | ||
258 | /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1), | ||
259 | /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1), | ||
260 | /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1), | ||
261 | 0 | ||
262 | }, | ||
263 | |||
264 | { | ||
265 | /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1), | ||
266 | /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1), | ||
267 | /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1), | ||
268 | /* Data[11].ctlEdges[3].bChannel */ | ||
269 | FREQ2FBIN(2462, 1), | ||
270 | } | ||
271 | }, | ||
272 | .ctlPowerData_2G = { | ||
273 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
274 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
275 | { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, | ||
276 | |||
277 | { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, | ||
278 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
279 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
280 | |||
281 | { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, | ||
282 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
283 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
284 | |||
285 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | ||
286 | { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, | ||
287 | }, | ||
288 | .modalHeader5G = { | ||
289 | /* 4 idle,t1,t2,b (4 bits per setting) */ | ||
290 | .antCtrlCommon = 0x110, | ||
291 | /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */ | ||
292 | .antCtrlCommon2 = 0x22222, | ||
293 | /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */ | ||
294 | .antCtrlChain = { | ||
295 | 0x000, 0x000, 0x000, | ||
296 | }, | ||
297 | /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ | ||
298 | .xatten1DB = {0, 0, 0}, | ||
299 | |||
300 | /* | ||
301 | * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin | ||
302 | * for merlin (0xa20c/b20c 16:12 | ||
303 | */ | ||
304 | .xatten1Margin = {0, 0, 0}, | ||
305 | .tempSlope = 68, | ||
306 | .voltSlope = 0, | ||
307 | /* spurChans spur channels in usual fbin coding format */ | ||
308 | .spurChans = {0, 0, 0, 0, 0}, | ||
309 | /* noiseFloorThreshCh Check if the register is per chain */ | ||
310 | .noiseFloorThreshCh = {-1, 0, 0}, | ||
311 | .ob = {3, 3, 3}, /* 3 chain */ | ||
312 | .db_stage2 = {3, 3, 3}, /* 3 chain */ | ||
313 | .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */ | ||
314 | .db_stage4 = {3, 3, 3}, /* don't exist for 2G */ | ||
315 | .xpaBiasLvl = 0, | ||
316 | .txFrameToDataStart = 0x0e, | ||
317 | .txFrameToPaOn = 0x0e, | ||
318 | .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */ | ||
319 | .antennaGain = 0, | ||
320 | .switchSettling = 0x2d, | ||
321 | .adcDesiredSize = -30, | ||
322 | .txEndToXpaOff = 0, | ||
323 | .txEndToRxOn = 0x2, | ||
324 | .txFrameToXpaOn = 0xe, | ||
325 | .thresh62 = 28, | ||
326 | .futureModal = { | ||
327 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
328 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
329 | }, | ||
330 | }, | ||
331 | .calFreqPier5G = { | ||
332 | FREQ2FBIN(5180, 0), | ||
333 | FREQ2FBIN(5220, 0), | ||
334 | FREQ2FBIN(5320, 0), | ||
335 | FREQ2FBIN(5400, 0), | ||
336 | FREQ2FBIN(5500, 0), | ||
337 | FREQ2FBIN(5600, 0), | ||
338 | FREQ2FBIN(5725, 0), | ||
339 | FREQ2FBIN(5825, 0) | ||
340 | }, | ||
341 | .calPierData5G = { | ||
342 | { | ||
343 | {0, 0, 0, 0, 0}, | ||
344 | {0, 0, 0, 0, 0}, | ||
345 | {0, 0, 0, 0, 0}, | ||
346 | {0, 0, 0, 0, 0}, | ||
347 | {0, 0, 0, 0, 0}, | ||
348 | {0, 0, 0, 0, 0}, | ||
349 | {0, 0, 0, 0, 0}, | ||
350 | {0, 0, 0, 0, 0}, | ||
351 | }, | ||
352 | { | ||
353 | {0, 0, 0, 0, 0}, | ||
354 | {0, 0, 0, 0, 0}, | ||
355 | {0, 0, 0, 0, 0}, | ||
356 | {0, 0, 0, 0, 0}, | ||
357 | {0, 0, 0, 0, 0}, | ||
358 | {0, 0, 0, 0, 0}, | ||
359 | {0, 0, 0, 0, 0}, | ||
360 | {0, 0, 0, 0, 0}, | ||
361 | }, | ||
362 | { | ||
363 | {0, 0, 0, 0, 0}, | ||
364 | {0, 0, 0, 0, 0}, | ||
365 | {0, 0, 0, 0, 0}, | ||
366 | {0, 0, 0, 0, 0}, | ||
367 | {0, 0, 0, 0, 0}, | ||
368 | {0, 0, 0, 0, 0}, | ||
369 | {0, 0, 0, 0, 0}, | ||
370 | {0, 0, 0, 0, 0}, | ||
371 | }, | ||
372 | |||
373 | }, | ||
374 | .calTarget_freqbin_5G = { | ||
375 | FREQ2FBIN(5180, 0), | ||
376 | FREQ2FBIN(5220, 0), | ||
377 | FREQ2FBIN(5320, 0), | ||
378 | FREQ2FBIN(5400, 0), | ||
379 | FREQ2FBIN(5500, 0), | ||
380 | FREQ2FBIN(5600, 0), | ||
381 | FREQ2FBIN(5725, 0), | ||
382 | FREQ2FBIN(5825, 0) | ||
383 | }, | ||
384 | .calTarget_freqbin_5GHT20 = { | ||
385 | FREQ2FBIN(5180, 0), | ||
386 | FREQ2FBIN(5240, 0), | ||
387 | FREQ2FBIN(5320, 0), | ||
388 | FREQ2FBIN(5500, 0), | ||
389 | FREQ2FBIN(5700, 0), | ||
390 | FREQ2FBIN(5745, 0), | ||
391 | FREQ2FBIN(5725, 0), | ||
392 | FREQ2FBIN(5825, 0) | ||
393 | }, | ||
394 | .calTarget_freqbin_5GHT40 = { | ||
395 | FREQ2FBIN(5180, 0), | ||
396 | FREQ2FBIN(5240, 0), | ||
397 | FREQ2FBIN(5320, 0), | ||
398 | FREQ2FBIN(5500, 0), | ||
399 | FREQ2FBIN(5700, 0), | ||
400 | FREQ2FBIN(5745, 0), | ||
401 | FREQ2FBIN(5725, 0), | ||
402 | FREQ2FBIN(5825, 0) | ||
403 | }, | ||
404 | .calTargetPower5G = { | ||
405 | /* 6-24,36,48,54 */ | ||
406 | { {20, 20, 20, 10} }, | ||
407 | { {20, 20, 20, 10} }, | ||
408 | { {20, 20, 20, 10} }, | ||
409 | { {20, 20, 20, 10} }, | ||
410 | { {20, 20, 20, 10} }, | ||
411 | { {20, 20, 20, 10} }, | ||
412 | { {20, 20, 20, 10} }, | ||
413 | { {20, 20, 20, 10} }, | ||
414 | }, | ||
415 | .calTargetPower5GHT20 = { | ||
416 | /* | ||
417 | * 0_8_16,1-3_9-11_17-19, | ||
418 | * 4,5,6,7,12,13,14,15,20,21,22,23 | ||
419 | */ | ||
420 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
421 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
422 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
423 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
424 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
425 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
426 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
427 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
428 | }, | ||
429 | .calTargetPower5GHT40 = { | ||
430 | /* | ||
431 | * 0_8_16,1-3_9-11_17-19, | ||
432 | * 4,5,6,7,12,13,14,15,20,21,22,23 | ||
433 | */ | ||
434 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
435 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
436 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
437 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
438 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
439 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
440 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
441 | { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} }, | ||
442 | }, | ||
443 | .ctlIndex_5G = { | ||
444 | 0x10, 0x16, 0x18, 0x40, 0x46, | ||
445 | 0x48, 0x30, 0x36, 0x38 | ||
446 | }, | ||
447 | .ctl_freqbin_5G = { | ||
448 | { | ||
449 | /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
450 | /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
451 | /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), | ||
452 | /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), | ||
453 | /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0), | ||
454 | /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
455 | /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), | ||
456 | /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) | ||
457 | }, | ||
458 | { | ||
459 | /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
460 | /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
461 | /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0), | ||
462 | /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), | ||
463 | /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0), | ||
464 | /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
465 | /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), | ||
466 | /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) | ||
467 | }, | ||
468 | |||
469 | { | ||
470 | /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), | ||
471 | /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), | ||
472 | /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), | ||
473 | /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0), | ||
474 | /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0), | ||
475 | /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0), | ||
476 | /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0), | ||
477 | /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0) | ||
478 | }, | ||
479 | |||
480 | { | ||
481 | /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
482 | /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), | ||
483 | /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0), | ||
484 | /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0), | ||
485 | /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), | ||
486 | /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
487 | /* Data[3].ctlEdges[6].bChannel */ 0xFF, | ||
488 | /* Data[3].ctlEdges[7].bChannel */ 0xFF, | ||
489 | }, | ||
490 | |||
491 | { | ||
492 | /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
493 | /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
494 | /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0), | ||
495 | /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0), | ||
496 | /* Data[4].ctlEdges[4].bChannel */ 0xFF, | ||
497 | /* Data[4].ctlEdges[5].bChannel */ 0xFF, | ||
498 | /* Data[4].ctlEdges[6].bChannel */ 0xFF, | ||
499 | /* Data[4].ctlEdges[7].bChannel */ 0xFF, | ||
500 | }, | ||
501 | |||
502 | { | ||
503 | /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), | ||
504 | /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0), | ||
505 | /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0), | ||
506 | /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), | ||
507 | /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0), | ||
508 | /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), | ||
509 | /* Data[5].ctlEdges[6].bChannel */ 0xFF, | ||
510 | /* Data[5].ctlEdges[7].bChannel */ 0xFF | ||
511 | }, | ||
512 | |||
513 | { | ||
514 | /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
515 | /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0), | ||
516 | /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0), | ||
517 | /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0), | ||
518 | /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0), | ||
519 | /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0), | ||
520 | /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0), | ||
521 | /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0) | ||
522 | }, | ||
523 | |||
524 | { | ||
525 | /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0), | ||
526 | /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0), | ||
527 | /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0), | ||
528 | /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0), | ||
529 | /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0), | ||
530 | /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0), | ||
531 | /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0), | ||
532 | /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0) | ||
533 | }, | ||
534 | |||
535 | { | ||
536 | /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0), | ||
537 | /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0), | ||
538 | /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0), | ||
539 | /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0), | ||
540 | /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0), | ||
541 | /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0), | ||
542 | /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0), | ||
543 | /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0) | ||
544 | } | ||
545 | }, | ||
546 | .ctlPowerData_5G = { | ||
547 | { | ||
548 | { | ||
549 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
550 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
551 | } | ||
552 | }, | ||
553 | { | ||
554 | { | ||
555 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
556 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
557 | } | ||
558 | }, | ||
559 | { | ||
560 | { | ||
561 | {60, 0}, {60, 1}, {60, 0}, {60, 1}, | ||
562 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
563 | } | ||
564 | }, | ||
565 | { | ||
566 | { | ||
567 | {60, 0}, {60, 1}, {60, 1}, {60, 0}, | ||
568 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | ||
569 | } | ||
570 | }, | ||
571 | { | ||
572 | { | ||
573 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
574 | {60, 0}, {60, 0}, {60, 0}, {60, 0}, | ||
575 | } | ||
576 | }, | ||
577 | { | ||
578 | { | ||
579 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
580 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | ||
581 | } | ||
582 | }, | ||
583 | { | ||
584 | { | ||
585 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
586 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | ||
587 | } | ||
588 | }, | ||
589 | { | ||
590 | { | ||
591 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | ||
592 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | ||
593 | } | ||
594 | }, | ||
595 | { | ||
596 | { | ||
597 | {60, 1}, {60, 0}, {60, 1}, {60, 1}, | ||
598 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | ||
599 | } | ||
600 | }, | ||
601 | } | ||
602 | }; | ||
603 | |||
604 | static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah) | ||
605 | { | ||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, | ||
610 | enum eeprom_param param) | ||
611 | { | ||
612 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
613 | struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader; | ||
614 | |||
615 | switch (param) { | ||
616 | case EEP_MAC_LSW: | ||
617 | return eep->macAddr[0] << 8 | eep->macAddr[1]; | ||
618 | case EEP_MAC_MID: | ||
619 | return eep->macAddr[2] << 8 | eep->macAddr[3]; | ||
620 | case EEP_MAC_MSW: | ||
621 | return eep->macAddr[4] << 8 | eep->macAddr[5]; | ||
622 | case EEP_REG_0: | ||
623 | return pBase->regDmn[0]; | ||
624 | case EEP_REG_1: | ||
625 | return pBase->regDmn[1]; | ||
626 | case EEP_OP_CAP: | ||
627 | return pBase->deviceCap; | ||
628 | case EEP_OP_MODE: | ||
629 | return pBase->opCapFlags.opFlags; | ||
630 | case EEP_RF_SILENT: | ||
631 | return pBase->rfSilent; | ||
632 | case EEP_TX_MASK: | ||
633 | return (pBase->txrxMask >> 4) & 0xf; | ||
634 | case EEP_RX_MASK: | ||
635 | return pBase->txrxMask & 0xf; | ||
636 | case EEP_DRIVE_STRENGTH: | ||
637 | #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1 | ||
638 | return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH; | ||
639 | case EEP_INTERNAL_REGULATOR: | ||
640 | /* Bit 4 is internal regulator flag */ | ||
641 | return (pBase->featureEnable & 0x10) >> 4; | ||
642 | case EEP_SWREG: | ||
643 | return pBase->swreg; | ||
644 | default: | ||
645 | return 0; | ||
646 | } | ||
647 | } | ||
648 | |||
649 | #ifdef __BIG_ENDIAN | ||
650 | static void ar9300_swap_eeprom(struct ar9300_eeprom *eep) | ||
651 | { | ||
652 | u32 dword; | ||
653 | u16 word; | ||
654 | int i; | ||
655 | |||
656 | word = swab16(eep->baseEepHeader.regDmn[0]); | ||
657 | eep->baseEepHeader.regDmn[0] = word; | ||
658 | |||
659 | word = swab16(eep->baseEepHeader.regDmn[1]); | ||
660 | eep->baseEepHeader.regDmn[1] = word; | ||
661 | |||
662 | dword = swab32(eep->modalHeader2G.antCtrlCommon); | ||
663 | eep->modalHeader2G.antCtrlCommon = dword; | ||
664 | |||
665 | dword = swab32(eep->modalHeader2G.antCtrlCommon2); | ||
666 | eep->modalHeader2G.antCtrlCommon2 = dword; | ||
667 | |||
668 | dword = swab32(eep->modalHeader5G.antCtrlCommon); | ||
669 | eep->modalHeader5G.antCtrlCommon = dword; | ||
670 | |||
671 | dword = swab32(eep->modalHeader5G.antCtrlCommon2); | ||
672 | eep->modalHeader5G.antCtrlCommon2 = dword; | ||
673 | |||
674 | for (i = 0; i < AR9300_MAX_CHAINS; i++) { | ||
675 | word = swab16(eep->modalHeader2G.antCtrlChain[i]); | ||
676 | eep->modalHeader2G.antCtrlChain[i] = word; | ||
677 | |||
678 | word = swab16(eep->modalHeader5G.antCtrlChain[i]); | ||
679 | eep->modalHeader5G.antCtrlChain[i] = word; | ||
680 | } | ||
681 | } | ||
682 | #endif | ||
683 | |||
684 | static bool ar9300_hw_read_eeprom(struct ath_hw *ah, | ||
685 | long address, u8 *buffer, int many) | ||
686 | { | ||
687 | int i; | ||
688 | u8 value[2]; | ||
689 | unsigned long eepAddr; | ||
690 | unsigned long byteAddr; | ||
691 | u16 *svalue; | ||
692 | struct ath_common *common = ath9k_hw_common(ah); | ||
693 | |||
694 | if ((address < 0) || ((address + many) > AR9300_EEPROM_SIZE - 1)) { | ||
695 | ath_print(common, ATH_DBG_EEPROM, | ||
696 | "eeprom address not in range\n"); | ||
697 | return false; | ||
698 | } | ||
699 | |||
700 | for (i = 0; i < many; i++) { | ||
701 | eepAddr = (u16) (address + i) / 2; | ||
702 | byteAddr = (u16) (address + i) % 2; | ||
703 | svalue = (u16 *) value; | ||
704 | if (!ath9k_hw_nvram_read(common, eepAddr, svalue)) { | ||
705 | ath_print(common, ATH_DBG_EEPROM, | ||
706 | "unable to read eeprom region\n"); | ||
707 | return false; | ||
708 | } | ||
709 | *svalue = le16_to_cpu(*svalue); | ||
710 | buffer[i] = value[byteAddr]; | ||
711 | } | ||
712 | |||
713 | return true; | ||
714 | } | ||
715 | |||
716 | static bool ar9300_read_eeprom(struct ath_hw *ah, | ||
717 | int address, u8 *buffer, int many) | ||
718 | { | ||
719 | int it; | ||
720 | |||
721 | for (it = 0; it < many; it++) | ||
722 | if (!ar9300_hw_read_eeprom(ah, | ||
723 | (address - it), | ||
724 | (buffer + it), 1)) | ||
725 | return false; | ||
726 | return true; | ||
727 | } | ||
728 | |||
729 | static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference, | ||
730 | int *length, int *major, int *minor) | ||
731 | { | ||
732 | unsigned long value[4]; | ||
733 | |||
734 | value[0] = best[0]; | ||
735 | value[1] = best[1]; | ||
736 | value[2] = best[2]; | ||
737 | value[3] = best[3]; | ||
738 | *code = ((value[0] >> 5) & 0x0007); | ||
739 | *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020); | ||
740 | *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f); | ||
741 | *major = (value[2] & 0x000f); | ||
742 | *minor = (value[3] & 0x00ff); | ||
743 | } | ||
744 | |||
745 | static u16 ar9300_comp_cksum(u8 *data, int dsize) | ||
746 | { | ||
747 | int it, checksum = 0; | ||
748 | |||
749 | for (it = 0; it < dsize; it++) { | ||
750 | checksum += data[it]; | ||
751 | checksum &= 0xffff; | ||
752 | } | ||
753 | |||
754 | return checksum; | ||
755 | } | ||
756 | |||
757 | static bool ar9300_uncompress_block(struct ath_hw *ah, | ||
758 | u8 *mptr, | ||
759 | int mdataSize, | ||
760 | u8 *block, | ||
761 | int size) | ||
762 | { | ||
763 | int it; | ||
764 | int spot; | ||
765 | int offset; | ||
766 | int length; | ||
767 | struct ath_common *common = ath9k_hw_common(ah); | ||
768 | |||
769 | spot = 0; | ||
770 | |||
771 | for (it = 0; it < size; it += (length+2)) { | ||
772 | offset = block[it]; | ||
773 | offset &= 0xff; | ||
774 | spot += offset; | ||
775 | length = block[it+1]; | ||
776 | length &= 0xff; | ||
777 | |||
778 | if (length > 0 && spot >= 0 && spot+length < mdataSize) { | ||
779 | ath_print(common, ATH_DBG_EEPROM, | ||
780 | "Restore at %d: spot=%d " | ||
781 | "offset=%d length=%d\n", | ||
782 | it, spot, offset, length); | ||
783 | memcpy(&mptr[spot], &block[it+2], length); | ||
784 | spot += length; | ||
785 | } else if (length > 0) { | ||
786 | ath_print(common, ATH_DBG_EEPROM, | ||
787 | "Bad restore at %d: spot=%d " | ||
788 | "offset=%d length=%d\n", | ||
789 | it, spot, offset, length); | ||
790 | return false; | ||
791 | } | ||
792 | } | ||
793 | return true; | ||
794 | } | ||
795 | |||
796 | static int ar9300_compress_decision(struct ath_hw *ah, | ||
797 | int it, | ||
798 | int code, | ||
799 | int reference, | ||
800 | u8 *mptr, | ||
801 | u8 *word, int length, int mdata_size) | ||
802 | { | ||
803 | struct ath_common *common = ath9k_hw_common(ah); | ||
804 | u8 *dptr; | ||
805 | |||
806 | switch (code) { | ||
807 | case _CompressNone: | ||
808 | if (length != mdata_size) { | ||
809 | ath_print(common, ATH_DBG_EEPROM, | ||
810 | "EEPROM structure size mismatch" | ||
811 | "memory=%d eeprom=%d\n", mdata_size, length); | ||
812 | return -1; | ||
813 | } | ||
814 | memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length); | ||
815 | ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:" | ||
816 | " uncompressed, length %d\n", it, length); | ||
817 | break; | ||
818 | case _CompressBlock: | ||
819 | if (reference == 0) { | ||
820 | dptr = mptr; | ||
821 | } else { | ||
822 | if (reference != 2) { | ||
823 | ath_print(common, ATH_DBG_EEPROM, | ||
824 | "cant find reference eeprom" | ||
825 | "struct %d\n", reference); | ||
826 | return -1; | ||
827 | } | ||
828 | memcpy(mptr, &ar9300_default, mdata_size); | ||
829 | } | ||
830 | ath_print(common, ATH_DBG_EEPROM, | ||
831 | "restore eeprom %d: block, reference %d," | ||
832 | " length %d\n", it, reference, length); | ||
833 | ar9300_uncompress_block(ah, mptr, mdata_size, | ||
834 | (u8 *) (word + COMP_HDR_LEN), length); | ||
835 | break; | ||
836 | default: | ||
837 | ath_print(common, ATH_DBG_EEPROM, "unknown compression" | ||
838 | " code %d\n", code); | ||
839 | return -1; | ||
840 | } | ||
841 | return 0; | ||
842 | } | ||
843 | |||
844 | /* | ||
845 | * Read the configuration data from the eeprom. | ||
846 | * The data can be put in any specified memory buffer. | ||
847 | * | ||
848 | * Returns -1 on error. | ||
849 | * Returns address of next memory location on success. | ||
850 | */ | ||
851 | static int ar9300_eeprom_restore_internal(struct ath_hw *ah, | ||
852 | u8 *mptr, int mdata_size) | ||
853 | { | ||
854 | #define MDEFAULT 15 | ||
855 | #define MSTATE 100 | ||
856 | int cptr; | ||
857 | u8 *word; | ||
858 | int code; | ||
859 | int reference, length, major, minor; | ||
860 | int osize; | ||
861 | int it; | ||
862 | u16 checksum, mchecksum; | ||
863 | struct ath_common *common = ath9k_hw_common(ah); | ||
864 | |||
865 | word = kzalloc(2048, GFP_KERNEL); | ||
866 | if (!word) | ||
867 | return -1; | ||
868 | |||
869 | memcpy(mptr, &ar9300_default, mdata_size); | ||
870 | |||
871 | cptr = AR9300_BASE_ADDR; | ||
872 | for (it = 0; it < MSTATE; it++) { | ||
873 | if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN)) | ||
874 | goto fail; | ||
875 | |||
876 | if ((word[0] == 0 && word[1] == 0 && word[2] == 0 && | ||
877 | word[3] == 0) || (word[0] == 0xff && word[1] == 0xff | ||
878 | && word[2] == 0xff && word[3] == 0xff)) | ||
879 | break; | ||
880 | |||
881 | ar9300_comp_hdr_unpack(word, &code, &reference, | ||
882 | &length, &major, &minor); | ||
883 | ath_print(common, ATH_DBG_EEPROM, | ||
884 | "Found block at %x: code=%d ref=%d" | ||
885 | "length=%d major=%d minor=%d\n", cptr, code, | ||
886 | reference, length, major, minor); | ||
887 | if (length >= 1024) { | ||
888 | ath_print(common, ATH_DBG_EEPROM, | ||
889 | "Skipping bad header\n"); | ||
890 | cptr -= COMP_HDR_LEN; | ||
891 | continue; | ||
892 | } | ||
893 | |||
894 | osize = length; | ||
895 | ar9300_read_eeprom(ah, cptr, word, | ||
896 | COMP_HDR_LEN + osize + COMP_CKSUM_LEN); | ||
897 | checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length); | ||
898 | mchecksum = word[COMP_HDR_LEN + osize] | | ||
899 | (word[COMP_HDR_LEN + osize + 1] << 8); | ||
900 | ath_print(common, ATH_DBG_EEPROM, | ||
901 | "checksum %x %x\n", checksum, mchecksum); | ||
902 | if (checksum == mchecksum) { | ||
903 | ar9300_compress_decision(ah, it, code, reference, mptr, | ||
904 | word, length, mdata_size); | ||
905 | } else { | ||
906 | ath_print(common, ATH_DBG_EEPROM, | ||
907 | "skipping block with bad checksum\n"); | ||
908 | } | ||
909 | cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN); | ||
910 | } | ||
911 | |||
912 | kfree(word); | ||
913 | return cptr; | ||
914 | |||
915 | fail: | ||
916 | kfree(word); | ||
917 | return -1; | ||
918 | } | ||
919 | |||
920 | /* | ||
921 | * Restore the configuration structure by reading the eeprom. | ||
922 | * This function destroys any existing in-memory structure | ||
923 | * content. | ||
924 | */ | ||
925 | static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah) | ||
926 | { | ||
927 | u8 *mptr = NULL; | ||
928 | int mdata_size; | ||
929 | |||
930 | mptr = (u8 *) &ah->eeprom.ar9300_eep; | ||
931 | mdata_size = sizeof(struct ar9300_eeprom); | ||
932 | |||
933 | if (mptr && mdata_size > 0) { | ||
934 | /* At this point, mptr points to the eeprom data structure | ||
935 | * in it's "default" state. If this is big endian, swap the | ||
936 | * data structures back to "little endian" | ||
937 | */ | ||
938 | /* First swap, default to Little Endian */ | ||
939 | #ifdef __BIG_ENDIAN | ||
940 | ar9300_swap_eeprom((struct ar9300_eeprom *)mptr); | ||
941 | #endif | ||
942 | if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) >= 0) | ||
943 | return true; | ||
944 | |||
945 | /* Second Swap, back to Big Endian */ | ||
946 | #ifdef __BIG_ENDIAN | ||
947 | ar9300_swap_eeprom((struct ar9300_eeprom *)mptr); | ||
948 | #endif | ||
949 | } | ||
950 | return false; | ||
951 | } | ||
952 | |||
953 | /* XXX: review hardware docs */ | ||
954 | static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah) | ||
955 | { | ||
956 | return ah->eeprom.ar9300_eep.eepromVersion; | ||
957 | } | ||
958 | |||
959 | /* XXX: could be read from the eepromVersion, not sure yet */ | ||
960 | static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) | ||
961 | { | ||
962 | return 0; | ||
963 | } | ||
964 | |||
965 | static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah, | ||
966 | enum ieee80211_band freq_band) | ||
967 | { | ||
968 | return 1; | ||
969 | } | ||
970 | |||
971 | static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah, | ||
972 | struct ath9k_channel *chan) | ||
973 | { | ||
974 | return -EINVAL; | ||
975 | } | ||
976 | |||
977 | static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz) | ||
978 | { | ||
979 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
980 | |||
981 | if (is2ghz) | ||
982 | return eep->modalHeader2G.xpaBiasLvl; | ||
983 | else | ||
984 | return eep->modalHeader5G.xpaBiasLvl; | ||
985 | } | ||
986 | |||
987 | static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) | ||
988 | { | ||
989 | int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz); | ||
990 | REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3)); | ||
991 | REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE, | ||
992 | ((bias >> 2) & 0x3)); | ||
993 | } | ||
994 | |||
995 | static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) | ||
996 | { | ||
997 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
998 | |||
999 | if (is2ghz) | ||
1000 | return eep->modalHeader2G.antCtrlCommon; | ||
1001 | else | ||
1002 | return eep->modalHeader5G.antCtrlCommon; | ||
1003 | } | ||
1004 | |||
1005 | static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) | ||
1006 | { | ||
1007 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1008 | |||
1009 | if (is2ghz) | ||
1010 | return eep->modalHeader2G.antCtrlCommon2; | ||
1011 | else | ||
1012 | return eep->modalHeader5G.antCtrlCommon2; | ||
1013 | } | ||
1014 | |||
1015 | static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, | ||
1016 | int chain, | ||
1017 | bool is2ghz) | ||
1018 | { | ||
1019 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1020 | |||
1021 | if (chain >= 0 && chain < AR9300_MAX_CHAINS) { | ||
1022 | if (is2ghz) | ||
1023 | return eep->modalHeader2G.antCtrlChain[chain]; | ||
1024 | else | ||
1025 | return eep->modalHeader5G.antCtrlChain[chain]; | ||
1026 | } | ||
1027 | |||
1028 | return 0; | ||
1029 | } | ||
1030 | |||
1031 | static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) | ||
1032 | { | ||
1033 | u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); | ||
1034 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value); | ||
1035 | |||
1036 | value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz); | ||
1037 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value); | ||
1038 | |||
1039 | value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz); | ||
1040 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value); | ||
1041 | |||
1042 | value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz); | ||
1043 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value); | ||
1044 | |||
1045 | value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz); | ||
1046 | REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value); | ||
1047 | } | ||
1048 | |||
1049 | static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) | ||
1050 | { | ||
1051 | int drive_strength; | ||
1052 | unsigned long reg; | ||
1053 | |||
1054 | drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH); | ||
1055 | |||
1056 | if (!drive_strength) | ||
1057 | return; | ||
1058 | |||
1059 | reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1); | ||
1060 | reg &= ~0x00ffffc0; | ||
1061 | reg |= 0x5 << 21; | ||
1062 | reg |= 0x5 << 18; | ||
1063 | reg |= 0x5 << 15; | ||
1064 | reg |= 0x5 << 12; | ||
1065 | reg |= 0x5 << 9; | ||
1066 | reg |= 0x5 << 6; | ||
1067 | REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg); | ||
1068 | |||
1069 | reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2); | ||
1070 | reg &= ~0xffffffe0; | ||
1071 | reg |= 0x5 << 29; | ||
1072 | reg |= 0x5 << 26; | ||
1073 | reg |= 0x5 << 23; | ||
1074 | reg |= 0x5 << 20; | ||
1075 | reg |= 0x5 << 17; | ||
1076 | reg |= 0x5 << 14; | ||
1077 | reg |= 0x5 << 11; | ||
1078 | reg |= 0x5 << 8; | ||
1079 | reg |= 0x5 << 5; | ||
1080 | REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg); | ||
1081 | |||
1082 | reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4); | ||
1083 | reg &= ~0xff800000; | ||
1084 | reg |= 0x5 << 29; | ||
1085 | reg |= 0x5 << 26; | ||
1086 | reg |= 0x5 << 23; | ||
1087 | REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg); | ||
1088 | } | ||
1089 | |||
1090 | static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) | ||
1091 | { | ||
1092 | int internal_regulator = | ||
1093 | ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR); | ||
1094 | |||
1095 | if (internal_regulator) { | ||
1096 | /* Internal regulator is ON. Write swreg register. */ | ||
1097 | int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG); | ||
1098 | REG_WRITE(ah, AR_RTC_REG_CONTROL1, | ||
1099 | REG_READ(ah, AR_RTC_REG_CONTROL1) & | ||
1100 | (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM)); | ||
1101 | REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg); | ||
1102 | /* Set REG_CONTROL1.SWREG_PROGRAM */ | ||
1103 | REG_WRITE(ah, AR_RTC_REG_CONTROL1, | ||
1104 | REG_READ(ah, | ||
1105 | AR_RTC_REG_CONTROL1) | | ||
1106 | AR_RTC_REG_CONTROL1_SWREG_PROGRAM); | ||
1107 | } else { | ||
1108 | REG_WRITE(ah, AR_RTC_SLEEP_CLK, | ||
1109 | (REG_READ(ah, | ||
1110 | AR_RTC_SLEEP_CLK) | | ||
1111 | AR_RTC_FORCE_SWREG_PRD)); | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, | ||
1116 | struct ath9k_channel *chan) | ||
1117 | { | ||
1118 | ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan)); | ||
1119 | ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan)); | ||
1120 | ar9003_hw_drive_strength_apply(ah); | ||
1121 | ar9003_hw_internal_regulator_apply(ah); | ||
1122 | } | ||
1123 | |||
1124 | static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, | ||
1125 | struct ath9k_channel *chan) | ||
1126 | { | ||
1127 | } | ||
1128 | |||
1129 | /* | ||
1130 | * Returns the interpolated y value corresponding to the specified x value | ||
1131 | * from the np ordered pairs of data (px,py). | ||
1132 | * The pairs do not have to be in any order. | ||
1133 | * If the specified x value is less than any of the px, | ||
1134 | * the returned y value is equal to the py for the lowest px. | ||
1135 | * If the specified x value is greater than any of the px, | ||
1136 | * the returned y value is equal to the py for the highest px. | ||
1137 | */ | ||
1138 | static int ar9003_hw_power_interpolate(int32_t x, | ||
1139 | int32_t *px, int32_t *py, u_int16_t np) | ||
1140 | { | ||
1141 | int ip = 0; | ||
1142 | int lx = 0, ly = 0, lhave = 0; | ||
1143 | int hx = 0, hy = 0, hhave = 0; | ||
1144 | int dx = 0; | ||
1145 | int y = 0; | ||
1146 | |||
1147 | lhave = 0; | ||
1148 | hhave = 0; | ||
1149 | |||
1150 | /* identify best lower and higher x calibration measurement */ | ||
1151 | for (ip = 0; ip < np; ip++) { | ||
1152 | dx = x - px[ip]; | ||
1153 | |||
1154 | /* this measurement is higher than our desired x */ | ||
1155 | if (dx <= 0) { | ||
1156 | if (!hhave || dx > (x - hx)) { | ||
1157 | /* new best higher x measurement */ | ||
1158 | hx = px[ip]; | ||
1159 | hy = py[ip]; | ||
1160 | hhave = 1; | ||
1161 | } | ||
1162 | } | ||
1163 | /* this measurement is lower than our desired x */ | ||
1164 | if (dx >= 0) { | ||
1165 | if (!lhave || dx < (x - lx)) { | ||
1166 | /* new best lower x measurement */ | ||
1167 | lx = px[ip]; | ||
1168 | ly = py[ip]; | ||
1169 | lhave = 1; | ||
1170 | } | ||
1171 | } | ||
1172 | } | ||
1173 | |||
1174 | /* the low x is good */ | ||
1175 | if (lhave) { | ||
1176 | /* so is the high x */ | ||
1177 | if (hhave) { | ||
1178 | /* they're the same, so just pick one */ | ||
1179 | if (hx == lx) | ||
1180 | y = ly; | ||
1181 | else /* interpolate */ | ||
1182 | y = ly + (((x - lx) * (hy - ly)) / (hx - lx)); | ||
1183 | } else /* only low is good, use it */ | ||
1184 | y = ly; | ||
1185 | } else if (hhave) /* only high is good, use it */ | ||
1186 | y = hy; | ||
1187 | else /* nothing is good,this should never happen unless np=0, ???? */ | ||
1188 | y = -(1 << 30); | ||
1189 | return y; | ||
1190 | } | ||
1191 | |||
1192 | static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah, | ||
1193 | u16 rateIndex, u16 freq, bool is2GHz) | ||
1194 | { | ||
1195 | u16 numPiers, i; | ||
1196 | s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1197 | s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1198 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1199 | struct cal_tgt_pow_legacy *pEepromTargetPwr; | ||
1200 | u8 *pFreqBin; | ||
1201 | |||
1202 | if (is2GHz) { | ||
1203 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | ||
1204 | pEepromTargetPwr = eep->calTargetPower2G; | ||
1205 | pFreqBin = eep->calTarget_freqbin_2G; | ||
1206 | } else { | ||
1207 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | ||
1208 | pEepromTargetPwr = eep->calTargetPower5G; | ||
1209 | pFreqBin = eep->calTarget_freqbin_5G; | ||
1210 | } | ||
1211 | |||
1212 | /* | ||
1213 | * create array of channels and targetpower from | ||
1214 | * targetpower piers stored on eeprom | ||
1215 | */ | ||
1216 | for (i = 0; i < numPiers; i++) { | ||
1217 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | ||
1218 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1219 | } | ||
1220 | |||
1221 | /* interpolate to get target power for given frequency */ | ||
1222 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1223 | freqArray, | ||
1224 | targetPowerArray, numPiers); | ||
1225 | } | ||
1226 | |||
1227 | static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah, | ||
1228 | u16 rateIndex, | ||
1229 | u16 freq, bool is2GHz) | ||
1230 | { | ||
1231 | u16 numPiers, i; | ||
1232 | s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1233 | s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
1234 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1235 | struct cal_tgt_pow_ht *pEepromTargetPwr; | ||
1236 | u8 *pFreqBin; | ||
1237 | |||
1238 | if (is2GHz) { | ||
1239 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | ||
1240 | pEepromTargetPwr = eep->calTargetPower2GHT20; | ||
1241 | pFreqBin = eep->calTarget_freqbin_2GHT20; | ||
1242 | } else { | ||
1243 | numPiers = AR9300_NUM_5G_20_TARGET_POWERS; | ||
1244 | pEepromTargetPwr = eep->calTargetPower5GHT20; | ||
1245 | pFreqBin = eep->calTarget_freqbin_5GHT20; | ||
1246 | } | ||
1247 | |||
1248 | /* | ||
1249 | * create array of channels and targetpower | ||
1250 | * from targetpower piers stored on eeprom | ||
1251 | */ | ||
1252 | for (i = 0; i < numPiers; i++) { | ||
1253 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | ||
1254 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1255 | } | ||
1256 | |||
1257 | /* interpolate to get target power for given frequency */ | ||
1258 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1259 | freqArray, | ||
1260 | targetPowerArray, numPiers); | ||
1261 | } | ||
1262 | |||
1263 | static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah, | ||
1264 | u16 rateIndex, | ||
1265 | u16 freq, bool is2GHz) | ||
1266 | { | ||
1267 | u16 numPiers, i; | ||
1268 | s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
1269 | s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
1270 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1271 | struct cal_tgt_pow_ht *pEepromTargetPwr; | ||
1272 | u8 *pFreqBin; | ||
1273 | |||
1274 | if (is2GHz) { | ||
1275 | numPiers = AR9300_NUM_2G_40_TARGET_POWERS; | ||
1276 | pEepromTargetPwr = eep->calTargetPower2GHT40; | ||
1277 | pFreqBin = eep->calTarget_freqbin_2GHT40; | ||
1278 | } else { | ||
1279 | numPiers = AR9300_NUM_5G_40_TARGET_POWERS; | ||
1280 | pEepromTargetPwr = eep->calTargetPower5GHT40; | ||
1281 | pFreqBin = eep->calTarget_freqbin_5GHT40; | ||
1282 | } | ||
1283 | |||
1284 | /* | ||
1285 | * create array of channels and targetpower from | ||
1286 | * targetpower piers stored on eeprom | ||
1287 | */ | ||
1288 | for (i = 0; i < numPiers; i++) { | ||
1289 | freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz); | ||
1290 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1291 | } | ||
1292 | |||
1293 | /* interpolate to get target power for given frequency */ | ||
1294 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1295 | freqArray, | ||
1296 | targetPowerArray, numPiers); | ||
1297 | } | ||
1298 | |||
1299 | static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah, | ||
1300 | u16 rateIndex, u16 freq) | ||
1301 | { | ||
1302 | u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i; | ||
1303 | s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
1304 | s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
1305 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1306 | struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck; | ||
1307 | u8 *pFreqBin = eep->calTarget_freqbin_Cck; | ||
1308 | |||
1309 | /* | ||
1310 | * create array of channels and targetpower from | ||
1311 | * targetpower piers stored on eeprom | ||
1312 | */ | ||
1313 | for (i = 0; i < numPiers; i++) { | ||
1314 | freqArray[i] = FBIN2FREQ(pFreqBin[i], 1); | ||
1315 | targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex]; | ||
1316 | } | ||
1317 | |||
1318 | /* interpolate to get target power for given frequency */ | ||
1319 | return (u8) ar9003_hw_power_interpolate((s32) freq, | ||
1320 | freqArray, | ||
1321 | targetPowerArray, numPiers); | ||
1322 | } | ||
1323 | |||
1324 | /* Set tx power registers to array of values passed in */ | ||
1325 | static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray) | ||
1326 | { | ||
1327 | #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) | ||
1328 | /* make sure forced gain is not set */ | ||
1329 | REG_WRITE(ah, 0xa458, 0); | ||
1330 | |||
1331 | /* Write the OFDM power per rate set */ | ||
1332 | |||
1333 | /* 6 (LSB), 9, 12, 18 (MSB) */ | ||
1334 | REG_WRITE(ah, 0xa3c0, | ||
1335 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) | | ||
1336 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) | | ||
1337 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) | | ||
1338 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)); | ||
1339 | |||
1340 | /* 24 (LSB), 36, 48, 54 (MSB) */ | ||
1341 | REG_WRITE(ah, 0xa3c4, | ||
1342 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) | | ||
1343 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) | | ||
1344 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) | | ||
1345 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0)); | ||
1346 | |||
1347 | /* Write the CCK power per rate set */ | ||
1348 | |||
1349 | /* 1L (LSB), reserved, 2L, 2S (MSB) */ | ||
1350 | REG_WRITE(ah, 0xa3c8, | ||
1351 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) | | ||
1352 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) | | ||
1353 | /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */ | ||
1354 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)); | ||
1355 | |||
1356 | /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */ | ||
1357 | REG_WRITE(ah, 0xa3cc, | ||
1358 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) | | ||
1359 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) | | ||
1360 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) | | ||
1361 | POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0) | ||
1362 | ); | ||
1363 | |||
1364 | /* Write the HT20 power per rate set */ | ||
1365 | |||
1366 | /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */ | ||
1367 | REG_WRITE(ah, 0xa3d0, | ||
1368 | POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) | | ||
1369 | POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) | | ||
1370 | POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) | | ||
1371 | POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0) | ||
1372 | ); | ||
1373 | |||
1374 | /* 6 (LSB), 7, 12, 13 (MSB) */ | ||
1375 | REG_WRITE(ah, 0xa3d4, | ||
1376 | POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) | | ||
1377 | POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) | | ||
1378 | POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) | | ||
1379 | POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0) | ||
1380 | ); | ||
1381 | |||
1382 | /* 14 (LSB), 15, 20, 21 */ | ||
1383 | REG_WRITE(ah, 0xa3e4, | ||
1384 | POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) | | ||
1385 | POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) | | ||
1386 | POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) | | ||
1387 | POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0) | ||
1388 | ); | ||
1389 | |||
1390 | /* Mixed HT20 and HT40 rates */ | ||
1391 | |||
1392 | /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */ | ||
1393 | REG_WRITE(ah, 0xa3e8, | ||
1394 | POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) | | ||
1395 | POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) | | ||
1396 | POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) | | ||
1397 | POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0) | ||
1398 | ); | ||
1399 | |||
1400 | /* | ||
1401 | * Write the HT40 power per rate set | ||
1402 | * correct PAR difference between HT40 and HT20/LEGACY | ||
1403 | * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) | ||
1404 | */ | ||
1405 | REG_WRITE(ah, 0xa3d8, | ||
1406 | POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) | | ||
1407 | POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) | | ||
1408 | POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) | | ||
1409 | POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0) | ||
1410 | ); | ||
1411 | |||
1412 | /* 6 (LSB), 7, 12, 13 (MSB) */ | ||
1413 | REG_WRITE(ah, 0xa3dc, | ||
1414 | POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) | | ||
1415 | POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) | | ||
1416 | POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) | | ||
1417 | POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0) | ||
1418 | ); | ||
1419 | |||
1420 | /* 14 (LSB), 15, 20, 21 */ | ||
1421 | REG_WRITE(ah, 0xa3ec, | ||
1422 | POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) | | ||
1423 | POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) | | ||
1424 | POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) | | ||
1425 | POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0) | ||
1426 | ); | ||
1427 | |||
1428 | return 0; | ||
1429 | #undef POW_SM | ||
1430 | } | ||
1431 | |||
1432 | static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq) | ||
1433 | { | ||
1434 | u8 targetPowerValT2[ar9300RateSize]; | ||
1435 | /* XXX: hard code for now, need to get from eeprom struct */ | ||
1436 | u8 ht40PowerIncForPdadc = 0; | ||
1437 | bool is2GHz = false; | ||
1438 | unsigned int i = 0; | ||
1439 | struct ath_common *common = ath9k_hw_common(ah); | ||
1440 | |||
1441 | if (freq < 4000) | ||
1442 | is2GHz = true; | ||
1443 | |||
1444 | targetPowerValT2[ALL_TARGET_LEGACY_6_24] = | ||
1445 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq, | ||
1446 | is2GHz); | ||
1447 | targetPowerValT2[ALL_TARGET_LEGACY_36] = | ||
1448 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq, | ||
1449 | is2GHz); | ||
1450 | targetPowerValT2[ALL_TARGET_LEGACY_48] = | ||
1451 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq, | ||
1452 | is2GHz); | ||
1453 | targetPowerValT2[ALL_TARGET_LEGACY_54] = | ||
1454 | ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq, | ||
1455 | is2GHz); | ||
1456 | targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] = | ||
1457 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L, | ||
1458 | freq); | ||
1459 | targetPowerValT2[ALL_TARGET_LEGACY_5S] = | ||
1460 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq); | ||
1461 | targetPowerValT2[ALL_TARGET_LEGACY_11L] = | ||
1462 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq); | ||
1463 | targetPowerValT2[ALL_TARGET_LEGACY_11S] = | ||
1464 | ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq); | ||
1465 | targetPowerValT2[ALL_TARGET_HT20_0_8_16] = | ||
1466 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, | ||
1467 | is2GHz); | ||
1468 | targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] = | ||
1469 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19, | ||
1470 | freq, is2GHz); | ||
1471 | targetPowerValT2[ALL_TARGET_HT20_4] = | ||
1472 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq, | ||
1473 | is2GHz); | ||
1474 | targetPowerValT2[ALL_TARGET_HT20_5] = | ||
1475 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq, | ||
1476 | is2GHz); | ||
1477 | targetPowerValT2[ALL_TARGET_HT20_6] = | ||
1478 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq, | ||
1479 | is2GHz); | ||
1480 | targetPowerValT2[ALL_TARGET_HT20_7] = | ||
1481 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq, | ||
1482 | is2GHz); | ||
1483 | targetPowerValT2[ALL_TARGET_HT20_12] = | ||
1484 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq, | ||
1485 | is2GHz); | ||
1486 | targetPowerValT2[ALL_TARGET_HT20_13] = | ||
1487 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq, | ||
1488 | is2GHz); | ||
1489 | targetPowerValT2[ALL_TARGET_HT20_14] = | ||
1490 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq, | ||
1491 | is2GHz); | ||
1492 | targetPowerValT2[ALL_TARGET_HT20_15] = | ||
1493 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq, | ||
1494 | is2GHz); | ||
1495 | targetPowerValT2[ALL_TARGET_HT20_20] = | ||
1496 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq, | ||
1497 | is2GHz); | ||
1498 | targetPowerValT2[ALL_TARGET_HT20_21] = | ||
1499 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq, | ||
1500 | is2GHz); | ||
1501 | targetPowerValT2[ALL_TARGET_HT20_22] = | ||
1502 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq, | ||
1503 | is2GHz); | ||
1504 | targetPowerValT2[ALL_TARGET_HT20_23] = | ||
1505 | ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq, | ||
1506 | is2GHz); | ||
1507 | targetPowerValT2[ALL_TARGET_HT40_0_8_16] = | ||
1508 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq, | ||
1509 | is2GHz) + ht40PowerIncForPdadc; | ||
1510 | targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] = | ||
1511 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19, | ||
1512 | freq, | ||
1513 | is2GHz) + ht40PowerIncForPdadc; | ||
1514 | targetPowerValT2[ALL_TARGET_HT40_4] = | ||
1515 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq, | ||
1516 | is2GHz) + ht40PowerIncForPdadc; | ||
1517 | targetPowerValT2[ALL_TARGET_HT40_5] = | ||
1518 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq, | ||
1519 | is2GHz) + ht40PowerIncForPdadc; | ||
1520 | targetPowerValT2[ALL_TARGET_HT40_6] = | ||
1521 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq, | ||
1522 | is2GHz) + ht40PowerIncForPdadc; | ||
1523 | targetPowerValT2[ALL_TARGET_HT40_7] = | ||
1524 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq, | ||
1525 | is2GHz) + ht40PowerIncForPdadc; | ||
1526 | targetPowerValT2[ALL_TARGET_HT40_12] = | ||
1527 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq, | ||
1528 | is2GHz) + ht40PowerIncForPdadc; | ||
1529 | targetPowerValT2[ALL_TARGET_HT40_13] = | ||
1530 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq, | ||
1531 | is2GHz) + ht40PowerIncForPdadc; | ||
1532 | targetPowerValT2[ALL_TARGET_HT40_14] = | ||
1533 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq, | ||
1534 | is2GHz) + ht40PowerIncForPdadc; | ||
1535 | targetPowerValT2[ALL_TARGET_HT40_15] = | ||
1536 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq, | ||
1537 | is2GHz) + ht40PowerIncForPdadc; | ||
1538 | targetPowerValT2[ALL_TARGET_HT40_20] = | ||
1539 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq, | ||
1540 | is2GHz) + ht40PowerIncForPdadc; | ||
1541 | targetPowerValT2[ALL_TARGET_HT40_21] = | ||
1542 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq, | ||
1543 | is2GHz) + ht40PowerIncForPdadc; | ||
1544 | targetPowerValT2[ALL_TARGET_HT40_22] = | ||
1545 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq, | ||
1546 | is2GHz) + ht40PowerIncForPdadc; | ||
1547 | targetPowerValT2[ALL_TARGET_HT40_23] = | ||
1548 | ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq, | ||
1549 | is2GHz) + ht40PowerIncForPdadc; | ||
1550 | |||
1551 | while (i < ar9300RateSize) { | ||
1552 | ath_print(common, ATH_DBG_EEPROM, | ||
1553 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
1554 | i++; | ||
1555 | |||
1556 | ath_print(common, ATH_DBG_EEPROM, | ||
1557 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
1558 | i++; | ||
1559 | |||
1560 | ath_print(common, ATH_DBG_EEPROM, | ||
1561 | "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]); | ||
1562 | i++; | ||
1563 | |||
1564 | ath_print(common, ATH_DBG_EEPROM, | ||
1565 | "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]); | ||
1566 | i++; | ||
1567 | } | ||
1568 | |||
1569 | /* Write target power array to registers */ | ||
1570 | ar9003_hw_tx_power_regwrite(ah, targetPowerValT2); | ||
1571 | } | ||
1572 | |||
1573 | static int ar9003_hw_cal_pier_get(struct ath_hw *ah, | ||
1574 | int mode, | ||
1575 | int ipier, | ||
1576 | int ichain, | ||
1577 | int *pfrequency, | ||
1578 | int *pcorrection, | ||
1579 | int *ptemperature, int *pvoltage) | ||
1580 | { | ||
1581 | u8 *pCalPier; | ||
1582 | struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct; | ||
1583 | int is2GHz; | ||
1584 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1585 | struct ath_common *common = ath9k_hw_common(ah); | ||
1586 | |||
1587 | if (ichain >= AR9300_MAX_CHAINS) { | ||
1588 | ath_print(common, ATH_DBG_EEPROM, | ||
1589 | "Invalid chain index, must be less than %d\n", | ||
1590 | AR9300_MAX_CHAINS); | ||
1591 | return -1; | ||
1592 | } | ||
1593 | |||
1594 | if (mode) { /* 5GHz */ | ||
1595 | if (ipier >= AR9300_NUM_5G_CAL_PIERS) { | ||
1596 | ath_print(common, ATH_DBG_EEPROM, | ||
1597 | "Invalid 5GHz cal pier index, must " | ||
1598 | "be less than %d\n", | ||
1599 | AR9300_NUM_5G_CAL_PIERS); | ||
1600 | return -1; | ||
1601 | } | ||
1602 | pCalPier = &(eep->calFreqPier5G[ipier]); | ||
1603 | pCalPierStruct = &(eep->calPierData5G[ichain][ipier]); | ||
1604 | is2GHz = 0; | ||
1605 | } else { | ||
1606 | if (ipier >= AR9300_NUM_2G_CAL_PIERS) { | ||
1607 | ath_print(common, ATH_DBG_EEPROM, | ||
1608 | "Invalid 2GHz cal pier index, must " | ||
1609 | "be less than %d\n", AR9300_NUM_2G_CAL_PIERS); | ||
1610 | return -1; | ||
1611 | } | ||
1612 | |||
1613 | pCalPier = &(eep->calFreqPier2G[ipier]); | ||
1614 | pCalPierStruct = &(eep->calPierData2G[ichain][ipier]); | ||
1615 | is2GHz = 1; | ||
1616 | } | ||
1617 | |||
1618 | *pfrequency = FBIN2FREQ(*pCalPier, is2GHz); | ||
1619 | *pcorrection = pCalPierStruct->refPower; | ||
1620 | *ptemperature = pCalPierStruct->tempMeas; | ||
1621 | *pvoltage = pCalPierStruct->voltMeas; | ||
1622 | |||
1623 | return 0; | ||
1624 | } | ||
1625 | |||
1626 | static int ar9003_hw_power_control_override(struct ath_hw *ah, | ||
1627 | int frequency, | ||
1628 | int *correction, | ||
1629 | int *voltage, int *temperature) | ||
1630 | { | ||
1631 | int tempSlope = 0; | ||
1632 | struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; | ||
1633 | |||
1634 | REG_RMW(ah, AR_PHY_TPC_11_B0, | ||
1635 | (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), | ||
1636 | AR_PHY_TPC_OLPC_GAIN_DELTA); | ||
1637 | REG_RMW(ah, AR_PHY_TPC_11_B1, | ||
1638 | (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), | ||
1639 | AR_PHY_TPC_OLPC_GAIN_DELTA); | ||
1640 | REG_RMW(ah, AR_PHY_TPC_11_B2, | ||
1641 | (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), | ||
1642 | AR_PHY_TPC_OLPC_GAIN_DELTA); | ||
1643 | |||
1644 | /* enable open loop power control on chip */ | ||
1645 | REG_RMW(ah, AR_PHY_TPC_6_B0, | ||
1646 | (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), | ||
1647 | AR_PHY_TPC_6_ERROR_EST_MODE); | ||
1648 | REG_RMW(ah, AR_PHY_TPC_6_B1, | ||
1649 | (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), | ||
1650 | AR_PHY_TPC_6_ERROR_EST_MODE); | ||
1651 | REG_RMW(ah, AR_PHY_TPC_6_B2, | ||
1652 | (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S), | ||
1653 | AR_PHY_TPC_6_ERROR_EST_MODE); | ||
1654 | |||
1655 | /* | ||
1656 | * enable temperature compensation | ||
1657 | * Need to use register names | ||
1658 | */ | ||
1659 | if (frequency < 4000) | ||
1660 | tempSlope = eep->modalHeader2G.tempSlope; | ||
1661 | else | ||
1662 | tempSlope = eep->modalHeader5G.tempSlope; | ||
1663 | |||
1664 | REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope); | ||
1665 | REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE, | ||
1666 | temperature[0]); | ||
1667 | |||
1668 | return 0; | ||
1669 | } | ||
1670 | |||
1671 | /* Apply the recorded correction values. */ | ||
1672 | static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) | ||
1673 | { | ||
1674 | int ichain, ipier, npier; | ||
1675 | int mode; | ||
1676 | int lfrequency[AR9300_MAX_CHAINS], | ||
1677 | lcorrection[AR9300_MAX_CHAINS], | ||
1678 | ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS]; | ||
1679 | int hfrequency[AR9300_MAX_CHAINS], | ||
1680 | hcorrection[AR9300_MAX_CHAINS], | ||
1681 | htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS]; | ||
1682 | int fdiff; | ||
1683 | int correction[AR9300_MAX_CHAINS], | ||
1684 | voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS]; | ||
1685 | int pfrequency, pcorrection, ptemperature, pvoltage; | ||
1686 | struct ath_common *common = ath9k_hw_common(ah); | ||
1687 | |||
1688 | mode = (frequency >= 4000); | ||
1689 | if (mode) | ||
1690 | npier = AR9300_NUM_5G_CAL_PIERS; | ||
1691 | else | ||
1692 | npier = AR9300_NUM_2G_CAL_PIERS; | ||
1693 | |||
1694 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { | ||
1695 | lfrequency[ichain] = 0; | ||
1696 | hfrequency[ichain] = 100000; | ||
1697 | } | ||
1698 | /* identify best lower and higher frequency calibration measurement */ | ||
1699 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { | ||
1700 | for (ipier = 0; ipier < npier; ipier++) { | ||
1701 | if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain, | ||
1702 | &pfrequency, &pcorrection, | ||
1703 | &ptemperature, &pvoltage)) { | ||
1704 | fdiff = frequency - pfrequency; | ||
1705 | |||
1706 | /* | ||
1707 | * this measurement is higher than | ||
1708 | * our desired frequency | ||
1709 | */ | ||
1710 | if (fdiff <= 0) { | ||
1711 | if (hfrequency[ichain] <= 0 || | ||
1712 | hfrequency[ichain] >= 100000 || | ||
1713 | fdiff > | ||
1714 | (frequency - hfrequency[ichain])) { | ||
1715 | /* | ||
1716 | * new best higher | ||
1717 | * frequency measurement | ||
1718 | */ | ||
1719 | hfrequency[ichain] = pfrequency; | ||
1720 | hcorrection[ichain] = | ||
1721 | pcorrection; | ||
1722 | htemperature[ichain] = | ||
1723 | ptemperature; | ||
1724 | hvoltage[ichain] = pvoltage; | ||
1725 | } | ||
1726 | } | ||
1727 | if (fdiff >= 0) { | ||
1728 | if (lfrequency[ichain] <= 0 | ||
1729 | || fdiff < | ||
1730 | (frequency - lfrequency[ichain])) { | ||
1731 | /* | ||
1732 | * new best lower | ||
1733 | * frequency measurement | ||
1734 | */ | ||
1735 | lfrequency[ichain] = pfrequency; | ||
1736 | lcorrection[ichain] = | ||
1737 | pcorrection; | ||
1738 | ltemperature[ichain] = | ||
1739 | ptemperature; | ||
1740 | lvoltage[ichain] = pvoltage; | ||
1741 | } | ||
1742 | } | ||
1743 | } | ||
1744 | } | ||
1745 | } | ||
1746 | |||
1747 | /* interpolate */ | ||
1748 | for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { | ||
1749 | ath_print(common, ATH_DBG_EEPROM, | ||
1750 | "ch=%d f=%d low=%d %d h=%d %d\n", | ||
1751 | ichain, frequency, lfrequency[ichain], | ||
1752 | lcorrection[ichain], hfrequency[ichain], | ||
1753 | hcorrection[ichain]); | ||
1754 | /* they're the same, so just pick one */ | ||
1755 | if (hfrequency[ichain] == lfrequency[ichain]) { | ||
1756 | correction[ichain] = lcorrection[ichain]; | ||
1757 | voltage[ichain] = lvoltage[ichain]; | ||
1758 | temperature[ichain] = ltemperature[ichain]; | ||
1759 | } | ||
1760 | /* the low frequency is good */ | ||
1761 | else if (frequency - lfrequency[ichain] < 1000) { | ||
1762 | /* so is the high frequency, interpolate */ | ||
1763 | if (hfrequency[ichain] - frequency < 1000) { | ||
1764 | |||
1765 | correction[ichain] = lcorrection[ichain] + | ||
1766 | (((frequency - lfrequency[ichain]) * | ||
1767 | (hcorrection[ichain] - | ||
1768 | lcorrection[ichain])) / | ||
1769 | (hfrequency[ichain] - lfrequency[ichain])); | ||
1770 | |||
1771 | temperature[ichain] = ltemperature[ichain] + | ||
1772 | (((frequency - lfrequency[ichain]) * | ||
1773 | (htemperature[ichain] - | ||
1774 | ltemperature[ichain])) / | ||
1775 | (hfrequency[ichain] - lfrequency[ichain])); | ||
1776 | |||
1777 | voltage[ichain] = | ||
1778 | lvoltage[ichain] + | ||
1779 | (((frequency - | ||
1780 | lfrequency[ichain]) * (hvoltage[ichain] - | ||
1781 | lvoltage[ichain])) | ||
1782 | / (hfrequency[ichain] - | ||
1783 | lfrequency[ichain])); | ||
1784 | } | ||
1785 | /* only low is good, use it */ | ||
1786 | else { | ||
1787 | correction[ichain] = lcorrection[ichain]; | ||
1788 | temperature[ichain] = ltemperature[ichain]; | ||
1789 | voltage[ichain] = lvoltage[ichain]; | ||
1790 | } | ||
1791 | } | ||
1792 | /* only high is good, use it */ | ||
1793 | else if (hfrequency[ichain] - frequency < 1000) { | ||
1794 | correction[ichain] = hcorrection[ichain]; | ||
1795 | temperature[ichain] = htemperature[ichain]; | ||
1796 | voltage[ichain] = hvoltage[ichain]; | ||
1797 | } else { /* nothing is good, presume 0???? */ | ||
1798 | correction[ichain] = 0; | ||
1799 | temperature[ichain] = 0; | ||
1800 | voltage[ichain] = 0; | ||
1801 | } | ||
1802 | } | ||
1803 | |||
1804 | ar9003_hw_power_control_override(ah, frequency, correction, voltage, | ||
1805 | temperature); | ||
1806 | |||
1807 | ath_print(common, ATH_DBG_EEPROM, | ||
1808 | "for frequency=%d, calibration correction = %d %d %d\n", | ||
1809 | frequency, correction[0], correction[1], correction[2]); | ||
1810 | |||
1811 | return 0; | ||
1812 | } | ||
1813 | |||
1814 | static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah, | ||
1815 | struct ath9k_channel *chan, u16 cfgCtl, | ||
1816 | u8 twiceAntennaReduction, | ||
1817 | u8 twiceMaxRegulatoryPower, | ||
1818 | u8 powerLimit) | ||
1819 | { | ||
1820 | ar9003_hw_set_target_power_eeprom(ah, chan->channel); | ||
1821 | ar9003_hw_calibration_apply(ah, chan->channel); | ||
1822 | } | ||
1823 | |||
1824 | static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah, | ||
1825 | u16 i, bool is2GHz) | ||
1826 | { | ||
1827 | return AR_NO_SPUR; | ||
1828 | } | ||
1829 | |||
1830 | const struct eeprom_ops eep_ar9300_ops = { | ||
1831 | .check_eeprom = ath9k_hw_ar9300_check_eeprom, | ||
1832 | .get_eeprom = ath9k_hw_ar9300_get_eeprom, | ||
1833 | .fill_eeprom = ath9k_hw_ar9300_fill_eeprom, | ||
1834 | .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver, | ||
1835 | .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev, | ||
1836 | .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config, | ||
1837 | .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg, | ||
1838 | .set_board_values = ath9k_hw_ar9300_set_board_values, | ||
1839 | .set_addac = ath9k_hw_ar9300_set_addac, | ||
1840 | .set_txpower = ath9k_hw_ar9300_set_txpower, | ||
1841 | .get_spur_channel = ath9k_hw_ar9300_get_spur_channel | ||
1842 | }; | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h new file mode 100644 index 000000000000..3ca520c4b6a3 --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -0,0 +1,319 @@ | |||
1 | #ifndef AR9003_EEPROM_H | ||
2 | #define AR9003_EEPROM_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | #define AR9300_EEP_VER 0xD000 | ||
7 | #define AR9300_EEP_VER_MINOR_MASK 0xFFF | ||
8 | #define AR9300_EEP_MINOR_VER_1 0x1 | ||
9 | #define AR9300_EEP_MINOR_VER AR9300_EEP_MINOR_VER_1 | ||
10 | |||
11 | /* 16-bit offset location start of calibration struct */ | ||
12 | #define AR9300_EEP_START_LOC 256 | ||
13 | #define AR9300_NUM_5G_CAL_PIERS 8 | ||
14 | #define AR9300_NUM_2G_CAL_PIERS 3 | ||
15 | #define AR9300_NUM_5G_20_TARGET_POWERS 8 | ||
16 | #define AR9300_NUM_5G_40_TARGET_POWERS 8 | ||
17 | #define AR9300_NUM_2G_CCK_TARGET_POWERS 2 | ||
18 | #define AR9300_NUM_2G_20_TARGET_POWERS 3 | ||
19 | #define AR9300_NUM_2G_40_TARGET_POWERS 3 | ||
20 | /* #define AR9300_NUM_CTLS 21 */ | ||
21 | #define AR9300_NUM_CTLS_5G 9 | ||
22 | #define AR9300_NUM_CTLS_2G 12 | ||
23 | #define AR9300_CTL_MODE_M 0xF | ||
24 | #define AR9300_NUM_BAND_EDGES_5G 8 | ||
25 | #define AR9300_NUM_BAND_EDGES_2G 4 | ||
26 | #define AR9300_NUM_PD_GAINS 4 | ||
27 | #define AR9300_PD_GAINS_IN_MASK 4 | ||
28 | #define AR9300_PD_GAIN_ICEPTS 5 | ||
29 | #define AR9300_EEPROM_MODAL_SPURS 5 | ||
30 | #define AR9300_MAX_RATE_POWER 63 | ||
31 | #define AR9300_NUM_PDADC_VALUES 128 | ||
32 | #define AR9300_NUM_RATES 16 | ||
33 | #define AR9300_BCHAN_UNUSED 0xFF | ||
34 | #define AR9300_MAX_PWR_RANGE_IN_HALF_DB 64 | ||
35 | #define AR9300_OPFLAGS_11A 0x01 | ||
36 | #define AR9300_OPFLAGS_11G 0x02 | ||
37 | #define AR9300_OPFLAGS_5G_HT40 0x04 | ||
38 | #define AR9300_OPFLAGS_2G_HT40 0x08 | ||
39 | #define AR9300_OPFLAGS_5G_HT20 0x10 | ||
40 | #define AR9300_OPFLAGS_2G_HT20 0x20 | ||
41 | #define AR9300_EEPMISC_BIG_ENDIAN 0x01 | ||
42 | #define AR9300_EEPMISC_WOW 0x02 | ||
43 | #define AR9300_CUSTOMER_DATA_SIZE 20 | ||
44 | |||
45 | #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) | ||
46 | #define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x)) | ||
47 | #define AR9300_MAX_CHAINS 3 | ||
48 | #define AR9300_ANT_16S 25 | ||
49 | #define AR9300_FUTURE_MODAL_SZ 6 | ||
50 | |||
51 | #define AR9300_NUM_ANT_CHAIN_FIELDS 7 | ||
52 | #define AR9300_NUM_ANT_COMMON_FIELDS 4 | ||
53 | #define AR9300_SIZE_ANT_CHAIN_FIELD 3 | ||
54 | #define AR9300_SIZE_ANT_COMMON_FIELD 4 | ||
55 | #define AR9300_ANT_CHAIN_MASK 0x7 | ||
56 | #define AR9300_ANT_COMMON_MASK 0xf | ||
57 | #define AR9300_CHAIN_0_IDX 0 | ||
58 | #define AR9300_CHAIN_1_IDX 1 | ||
59 | #define AR9300_CHAIN_2_IDX 2 | ||
60 | |||
61 | #define AR928X_NUM_ANT_CHAIN_FIELDS 6 | ||
62 | #define AR928X_SIZE_ANT_CHAIN_FIELD 2 | ||
63 | #define AR928X_ANT_CHAIN_MASK 0x3 | ||
64 | |||
65 | /* Delta from which to start power to pdadc table */ | ||
66 | /* This offset is used in both open loop and closed loop power control | ||
67 | * schemes. In open loop power control, it is not really needed, but for | ||
68 | * the "sake of consistency" it was kept. For certain AP designs, this | ||
69 | * value is overwritten by the value in the flag "pwrTableOffset" just | ||
70 | * before writing the pdadc vs pwr into the chip registers. | ||
71 | */ | ||
72 | #define AR9300_PWR_TABLE_OFFSET 0 | ||
73 | |||
74 | /* enable flags for voltage and temp compensation */ | ||
75 | #define ENABLE_TEMP_COMPENSATION 0x01 | ||
76 | #define ENABLE_VOLT_COMPENSATION 0x02 | ||
77 | /* byte addressable */ | ||
78 | #define AR9300_EEPROM_SIZE (16*1024) | ||
79 | #define FIXED_CCA_THRESHOLD 15 | ||
80 | |||
81 | #define AR9300_BASE_ADDR 0x3ff | ||
82 | |||
83 | enum targetPowerHTRates { | ||
84 | HT_TARGET_RATE_0_8_16, | ||
85 | HT_TARGET_RATE_1_3_9_11_17_19, | ||
86 | HT_TARGET_RATE_4, | ||
87 | HT_TARGET_RATE_5, | ||
88 | HT_TARGET_RATE_6, | ||
89 | HT_TARGET_RATE_7, | ||
90 | HT_TARGET_RATE_12, | ||
91 | HT_TARGET_RATE_13, | ||
92 | HT_TARGET_RATE_14, | ||
93 | HT_TARGET_RATE_15, | ||
94 | HT_TARGET_RATE_20, | ||
95 | HT_TARGET_RATE_21, | ||
96 | HT_TARGET_RATE_22, | ||
97 | HT_TARGET_RATE_23 | ||
98 | }; | ||
99 | |||
100 | enum targetPowerLegacyRates { | ||
101 | LEGACY_TARGET_RATE_6_24, | ||
102 | LEGACY_TARGET_RATE_36, | ||
103 | LEGACY_TARGET_RATE_48, | ||
104 | LEGACY_TARGET_RATE_54 | ||
105 | }; | ||
106 | |||
107 | enum targetPowerCckRates { | ||
108 | LEGACY_TARGET_RATE_1L_5L, | ||
109 | LEGACY_TARGET_RATE_5S, | ||
110 | LEGACY_TARGET_RATE_11L, | ||
111 | LEGACY_TARGET_RATE_11S | ||
112 | }; | ||
113 | |||
114 | enum ar9300_Rates { | ||
115 | ALL_TARGET_LEGACY_6_24, | ||
116 | ALL_TARGET_LEGACY_36, | ||
117 | ALL_TARGET_LEGACY_48, | ||
118 | ALL_TARGET_LEGACY_54, | ||
119 | ALL_TARGET_LEGACY_1L_5L, | ||
120 | ALL_TARGET_LEGACY_5S, | ||
121 | ALL_TARGET_LEGACY_11L, | ||
122 | ALL_TARGET_LEGACY_11S, | ||
123 | ALL_TARGET_HT20_0_8_16, | ||
124 | ALL_TARGET_HT20_1_3_9_11_17_19, | ||
125 | ALL_TARGET_HT20_4, | ||
126 | ALL_TARGET_HT20_5, | ||
127 | ALL_TARGET_HT20_6, | ||
128 | ALL_TARGET_HT20_7, | ||
129 | ALL_TARGET_HT20_12, | ||
130 | ALL_TARGET_HT20_13, | ||
131 | ALL_TARGET_HT20_14, | ||
132 | ALL_TARGET_HT20_15, | ||
133 | ALL_TARGET_HT20_20, | ||
134 | ALL_TARGET_HT20_21, | ||
135 | ALL_TARGET_HT20_22, | ||
136 | ALL_TARGET_HT20_23, | ||
137 | ALL_TARGET_HT40_0_8_16, | ||
138 | ALL_TARGET_HT40_1_3_9_11_17_19, | ||
139 | ALL_TARGET_HT40_4, | ||
140 | ALL_TARGET_HT40_5, | ||
141 | ALL_TARGET_HT40_6, | ||
142 | ALL_TARGET_HT40_7, | ||
143 | ALL_TARGET_HT40_12, | ||
144 | ALL_TARGET_HT40_13, | ||
145 | ALL_TARGET_HT40_14, | ||
146 | ALL_TARGET_HT40_15, | ||
147 | ALL_TARGET_HT40_20, | ||
148 | ALL_TARGET_HT40_21, | ||
149 | ALL_TARGET_HT40_22, | ||
150 | ALL_TARGET_HT40_23, | ||
151 | ar9300RateSize, | ||
152 | }; | ||
153 | |||
154 | |||
155 | struct eepFlags { | ||
156 | u8 opFlags; | ||
157 | u8 eepMisc; | ||
158 | } __packed; | ||
159 | |||
160 | enum CompressAlgorithm { | ||
161 | _CompressNone = 0, | ||
162 | _CompressLzma, | ||
163 | _CompressPairs, | ||
164 | _CompressBlock, | ||
165 | _Compress4, | ||
166 | _Compress5, | ||
167 | _Compress6, | ||
168 | _Compress7, | ||
169 | }; | ||
170 | |||
171 | struct ar9300_base_eep_hdr { | ||
172 | u16 regDmn[2]; | ||
173 | /* 4 bits tx and 4 bits rx */ | ||
174 | u8 txrxMask; | ||
175 | struct eepFlags opCapFlags; | ||
176 | u8 rfSilent; | ||
177 | u8 blueToothOptions; | ||
178 | u8 deviceCap; | ||
179 | /* takes lower byte in eeprom location */ | ||
180 | u8 deviceType; | ||
181 | /* offset in dB to be added to beginning | ||
182 | * of pdadc table in calibration | ||
183 | */ | ||
184 | int8_t pwrTableOffset; | ||
185 | u8 params_for_tuning_caps[2]; | ||
186 | /* | ||
187 | * bit0 - enable tx temp comp | ||
188 | * bit1 - enable tx volt comp | ||
189 | * bit2 - enable fastClock - default to 1 | ||
190 | * bit3 - enable doubling - default to 1 | ||
191 | * bit4 - enable internal regulator - default to 1 | ||
192 | */ | ||
193 | u8 featureEnable; | ||
194 | /* misc flags: bit0 - turn down drivestrength */ | ||
195 | u8 miscConfiguration; | ||
196 | u8 eepromWriteEnableGpio; | ||
197 | u8 wlanDisableGpio; | ||
198 | u8 wlanLedGpio; | ||
199 | u8 rxBandSelectGpio; | ||
200 | u8 txrxgain; | ||
201 | /* SW controlled internal regulator fields */ | ||
202 | u32 swreg; | ||
203 | } __packed; | ||
204 | |||
205 | struct ar9300_modal_eep_header { | ||
206 | /* 4 idle, t1, t2, b (4 bits per setting) */ | ||
207 | u32 antCtrlCommon; | ||
208 | /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ | ||
209 | u32 antCtrlCommon2; | ||
210 | /* 6 idle, t, r, rx1, rx12, b (2 bits each) */ | ||
211 | u16 antCtrlChain[AR9300_MAX_CHAINS]; | ||
212 | /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ | ||
213 | u8 xatten1DB[AR9300_MAX_CHAINS]; | ||
214 | /* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */ | ||
215 | u8 xatten1Margin[AR9300_MAX_CHAINS]; | ||
216 | int8_t tempSlope; | ||
217 | int8_t voltSlope; | ||
218 | /* spur channels in usual fbin coding format */ | ||
219 | u8 spurChans[AR9300_EEPROM_MODAL_SPURS]; | ||
220 | /* 3 Check if the register is per chain */ | ||
221 | int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS]; | ||
222 | u8 ob[AR9300_MAX_CHAINS]; | ||
223 | u8 db_stage2[AR9300_MAX_CHAINS]; | ||
224 | u8 db_stage3[AR9300_MAX_CHAINS]; | ||
225 | u8 db_stage4[AR9300_MAX_CHAINS]; | ||
226 | u8 xpaBiasLvl; | ||
227 | u8 txFrameToDataStart; | ||
228 | u8 txFrameToPaOn; | ||
229 | u8 txClip; | ||
230 | int8_t antennaGain; | ||
231 | u8 switchSettling; | ||
232 | int8_t adcDesiredSize; | ||
233 | u8 txEndToXpaOff; | ||
234 | u8 txEndToRxOn; | ||
235 | u8 txFrameToXpaOn; | ||
236 | u8 thresh62; | ||
237 | u8 futureModal[32]; | ||
238 | } __packed; | ||
239 | |||
240 | struct ar9300_cal_data_per_freq_op_loop { | ||
241 | int8_t refPower; | ||
242 | /* pdadc voltage at power measurement */ | ||
243 | u8 voltMeas; | ||
244 | /* pcdac used for power measurement */ | ||
245 | u8 tempMeas; | ||
246 | /* range is -60 to -127 create a mapping equation 1db resolution */ | ||
247 | int8_t rxNoisefloorCal; | ||
248 | /*range is same as noisefloor */ | ||
249 | int8_t rxNoisefloorPower; | ||
250 | /* temp measured when noisefloor cal was performed */ | ||
251 | u8 rxTempMeas; | ||
252 | } __packed; | ||
253 | |||
254 | struct cal_tgt_pow_legacy { | ||
255 | u8 tPow2x[4]; | ||
256 | } __packed; | ||
257 | |||
258 | struct cal_tgt_pow_ht { | ||
259 | u8 tPow2x[14]; | ||
260 | } __packed; | ||
261 | |||
262 | struct cal_ctl_edge_pwr { | ||
263 | u8 tPower:6, | ||
264 | flag:2; | ||
265 | } __packed; | ||
266 | |||
267 | struct cal_ctl_data_2g { | ||
268 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; | ||
269 | } __packed; | ||
270 | |||
271 | struct cal_ctl_data_5g { | ||
272 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; | ||
273 | } __packed; | ||
274 | |||
275 | struct ar9300_eeprom { | ||
276 | u8 eepromVersion; | ||
277 | u8 templateVersion; | ||
278 | u8 macAddr[6]; | ||
279 | u8 custData[AR9300_CUSTOMER_DATA_SIZE]; | ||
280 | |||
281 | struct ar9300_base_eep_hdr baseEepHeader; | ||
282 | |||
283 | struct ar9300_modal_eep_header modalHeader2G; | ||
284 | u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS]; | ||
285 | struct ar9300_cal_data_per_freq_op_loop | ||
286 | calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS]; | ||
287 | u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
288 | u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
289 | u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
290 | u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; | ||
291 | struct cal_tgt_pow_legacy | ||
292 | calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS]; | ||
293 | struct cal_tgt_pow_legacy | ||
294 | calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
295 | struct cal_tgt_pow_ht | ||
296 | calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; | ||
297 | struct cal_tgt_pow_ht | ||
298 | calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; | ||
299 | u8 ctlIndex_2G[AR9300_NUM_CTLS_2G]; | ||
300 | u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G]; | ||
301 | struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G]; | ||
302 | struct ar9300_modal_eep_header modalHeader5G; | ||
303 | u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS]; | ||
304 | struct ar9300_cal_data_per_freq_op_loop | ||
305 | calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS]; | ||
306 | u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
307 | u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
308 | u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
309 | struct cal_tgt_pow_legacy | ||
310 | calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
311 | struct cal_tgt_pow_ht | ||
312 | calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; | ||
313 | struct cal_tgt_pow_ht | ||
314 | calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; | ||
315 | u8 ctlIndex_5G[AR9300_NUM_CTLS_5G]; | ||
316 | u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G]; | ||
317 | struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G]; | ||
318 | } __packed; | ||
319 | #endif | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index aec6ebbb6584..bd9dff3293dc 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -256,7 +256,9 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah) | |||
256 | { | 256 | { |
257 | int status; | 257 | int status; |
258 | 258 | ||
259 | if (AR_SREV_9287(ah)) { | 259 | if (AR_SREV_9300_20_OR_LATER(ah)) |
260 | ah->eep_ops = &eep_ar9300_ops; | ||
261 | else if (AR_SREV_9287(ah)) { | ||
260 | ah->eep_ops = &eep_ar9287_ops; | 262 | ah->eep_ops = &eep_ar9287_ops; |
261 | } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { | 263 | } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) { |
262 | ah->eep_ops = &eep_4k_ops; | 264 | ah->eep_ops = &eep_4k_ops; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 289084c71527..fb9c8c92eabe 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -19,6 +19,7 @@ | |||
19 | 19 | ||
20 | #include "../ath.h" | 20 | #include "../ath.h" |
21 | #include <net/cfg80211.h> | 21 | #include <net/cfg80211.h> |
22 | #include "ar9003_eeprom.h" | ||
22 | 23 | ||
23 | #define AH_USE_EEPROM 0x1 | 24 | #define AH_USE_EEPROM 0x1 |
24 | 25 | ||
@@ -249,16 +250,20 @@ enum eeprom_param { | |||
249 | EEP_MINOR_REV, | 250 | EEP_MINOR_REV, |
250 | EEP_TX_MASK, | 251 | EEP_TX_MASK, |
251 | EEP_RX_MASK, | 252 | EEP_RX_MASK, |
253 | EEP_FSTCLK_5G, | ||
252 | EEP_RXGAIN_TYPE, | 254 | EEP_RXGAIN_TYPE, |
253 | EEP_TXGAIN_TYPE, | ||
254 | EEP_OL_PWRCTRL, | 255 | EEP_OL_PWRCTRL, |
256 | EEP_TXGAIN_TYPE, | ||
255 | EEP_RC_CHAIN_MASK, | 257 | EEP_RC_CHAIN_MASK, |
256 | EEP_DAC_HPWR_5G, | 258 | EEP_DAC_HPWR_5G, |
257 | EEP_FRAC_N_5G, | 259 | EEP_FRAC_N_5G, |
258 | EEP_DEV_TYPE, | 260 | EEP_DEV_TYPE, |
259 | EEP_TEMPSENSE_SLOPE, | 261 | EEP_TEMPSENSE_SLOPE, |
260 | EEP_TEMPSENSE_SLOPE_PAL_ON, | 262 | EEP_TEMPSENSE_SLOPE_PAL_ON, |
261 | EEP_PWR_TABLE_OFFSET | 263 | EEP_PWR_TABLE_OFFSET, |
264 | EEP_DRIVE_STRENGTH, | ||
265 | EEP_INTERNAL_REGULATOR, | ||
266 | EEP_SWREG | ||
262 | }; | 267 | }; |
263 | 268 | ||
264 | enum ar5416_rates { | 269 | enum ar5416_rates { |
@@ -707,5 +712,7 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah); | |||
707 | extern const struct eeprom_ops eep_def_ops; | 712 | extern const struct eeprom_ops eep_def_ops; |
708 | extern const struct eeprom_ops eep_4k_ops; | 713 | extern const struct eeprom_ops eep_4k_ops; |
709 | extern const struct eeprom_ops eep_ar9287_ops; | 714 | extern const struct eeprom_ops eep_ar9287_ops; |
715 | extern const struct eeprom_ops eep_ar9287_ops; | ||
716 | extern const struct eeprom_ops eep_ar9300_ops; | ||
710 | 717 | ||
711 | #endif /* EEPROM_H */ | 718 | #endif /* EEPROM_H */ |
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index cb0421a910d2..d1b9940b2ae5 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h | |||
@@ -568,6 +568,7 @@ struct ath_hw { | |||
568 | struct ar5416_eeprom_def def; | 568 | struct ar5416_eeprom_def def; |
569 | struct ar5416_eeprom_4k map4k; | 569 | struct ar5416_eeprom_4k map4k; |
570 | struct ar9287_eeprom map9287; | 570 | struct ar9287_eeprom map9287; |
571 | struct ar9300_eeprom ar9300_eep; | ||
571 | } eeprom; | 572 | } eeprom; |
572 | const struct eeprom_ops *eep_ops; | 573 | const struct eeprom_ops *eep_ops; |
573 | 574 | ||
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index aacc29a5ad71..12de95ea7631 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -1070,6 +1070,16 @@ enum { | |||
1070 | #define AR_RTC_RC_COLD_RESET 0x00000004 | 1070 | #define AR_RTC_RC_COLD_RESET 0x00000004 |
1071 | #define AR_RTC_RC_WARM_RESET 0x00000008 | 1071 | #define AR_RTC_RC_WARM_RESET 0x00000008 |
1072 | 1072 | ||
1073 | /* Crystal Control */ | ||
1074 | #define AR_RTC_XTAL_CONTROL 0x7004 | ||
1075 | |||
1076 | /* Reg Control 0 */ | ||
1077 | #define AR_RTC_REG_CONTROL0 0x7008 | ||
1078 | |||
1079 | /* Reg Control 1 */ | ||
1080 | #define AR_RTC_REG_CONTROL1 0x700c | ||
1081 | #define AR_RTC_REG_CONTROL1_SWREG_PROGRAM 0x00000001 | ||
1082 | |||
1073 | #define AR_RTC_PLL_CONTROL \ | 1083 | #define AR_RTC_PLL_CONTROL \ |
1074 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) | 1084 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014) |
1075 | 1085 | ||
@@ -1100,6 +1110,7 @@ enum { | |||
1100 | #define AR_RTC_SLEEP_CLK \ | 1110 | #define AR_RTC_SLEEP_CLK \ |
1101 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048) | 1111 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048) |
1102 | #define AR_RTC_FORCE_DERIVED_CLK 0x2 | 1112 | #define AR_RTC_FORCE_DERIVED_CLK 0x2 |
1113 | #define AR_RTC_FORCE_SWREG_PRD 0x00000004 | ||
1103 | 1114 | ||
1104 | #define AR_RTC_FORCE_WAKE \ | 1115 | #define AR_RTC_FORCE_WAKE \ |
1105 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c) | 1116 | ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c) |