aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSenthil Balasubramanian <senthilkumar@atheros.com>2010-04-15 17:39:14 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-16 15:43:37 -0400
commit15c9ee7af8a3527a82013ea447da2d8c491aabfe (patch)
tree01ddec2e3724a2fea801eafab59c3c82d4cb8a73
parent49101676b2f1a66e0043509423e876414c73b5aa (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/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c1842
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.h319
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h11
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
35obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 36obj-$(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
41static 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
604static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
605{
606 return 0;
607}
608
609static 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
650static 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
684static 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
716static 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
729static 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
745static 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
757static 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
796static 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 */
851static 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
915fail:
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 */
925static 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 */
954static 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 */
960static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
961{
962 return 0;
963}
964
965static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
966 enum ieee80211_band freq_band)
967{
968 return 1;
969}
970
971static u16 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
972 struct ath9k_channel *chan)
973{
974 return -EINVAL;
975}
976
977static 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
987static 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
995static 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
1005static 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
1015static 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
1031static 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
1049static 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
1090static 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
1115static 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
1124static 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 */
1138static 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
1192static 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
1227static 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
1263static 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
1299static 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 */
1325static 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
1432static 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
1573static 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
1626static 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. */
1672static 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
1814static 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
1824static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
1825 u16 i, bool is2GHz)
1826{
1827 return AR_NO_SPUR;
1828}
1829
1830const 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
83enum 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
100enum targetPowerLegacyRates {
101 LEGACY_TARGET_RATE_6_24,
102 LEGACY_TARGET_RATE_36,
103 LEGACY_TARGET_RATE_48,
104 LEGACY_TARGET_RATE_54
105};
106
107enum targetPowerCckRates {
108 LEGACY_TARGET_RATE_1L_5L,
109 LEGACY_TARGET_RATE_5S,
110 LEGACY_TARGET_RATE_11L,
111 LEGACY_TARGET_RATE_11S
112};
113
114enum 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
155struct eepFlags {
156 u8 opFlags;
157 u8 eepMisc;
158} __packed;
159
160enum CompressAlgorithm {
161 _CompressNone = 0,
162 _CompressLzma,
163 _CompressPairs,
164 _CompressBlock,
165 _Compress4,
166 _Compress5,
167 _Compress6,
168 _Compress7,
169};
170
171struct 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
205struct 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
240struct 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
254struct cal_tgt_pow_legacy {
255 u8 tPow2x[4];
256} __packed;
257
258struct cal_tgt_pow_ht {
259 u8 tPow2x[14];
260} __packed;
261
262struct cal_ctl_edge_pwr {
263 u8 tPower:6,
264 flag:2;
265} __packed;
266
267struct cal_ctl_data_2g {
268 struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
269} __packed;
270
271struct cal_ctl_data_5g {
272 struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G];
273} __packed;
274
275struct 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
264enum ar5416_rates { 269enum ar5416_rates {
@@ -707,5 +712,7 @@ int ath9k_hw_eeprom_init(struct ath_hw *ah);
707extern const struct eeprom_ops eep_def_ops; 712extern const struct eeprom_ops eep_def_ops;
708extern const struct eeprom_ops eep_4k_ops; 713extern const struct eeprom_ops eep_4k_ops;
709extern const struct eeprom_ops eep_ar9287_ops; 714extern const struct eeprom_ops eep_ar9287_ops;
715extern const struct eeprom_ops eep_ar9287_ops;
716extern 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)