]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blob - drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
Revert "ath9k: Fix STA disconnect issue due to received MIC failed bcast frames"
[mirror_ubuntu-bionic-kernel.git] / drivers / net / wireless / ath / ath9k / ar9003_eeprom.c
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 #define LE16(x) __constant_cpu_to_le16(x)
42 #define LE32(x) __constant_cpu_to_le32(x)
43
44 /* Local defines to distinguish between extension and control CTL's */
45 #define EXT_ADDITIVE (0x8000)
46 #define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
47 #define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
48 #define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
49 #define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
50 #define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
51 #define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
52 #define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
53 #define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
54
55 #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
56 #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
57
58 #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
59
60 static const struct ar9300_eeprom ar9300_default = {
61 .eepromVersion = 2,
62 .templateVersion = 2,
63 .macAddr = {1, 2, 3, 4, 5, 6},
64 .custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
66 .baseEepHeader = {
67 .regDmn = { LE16(0), LE16(0x1f) },
68 .txrxMask = 0x77, /* 4 bits tx and 4 bits rx */
69 .opCapFlags = {
70 .opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
71 .eepMisc = 0,
72 },
73 .rfSilent = 0,
74 .blueToothOptions = 0,
75 .deviceCap = 0,
76 .deviceType = 5, /* takes lower byte in eeprom location */
77 .pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
78 .params_for_tuning_caps = {0, 0},
79 .featureEnable = 0x0c,
80 /*
81 * bit0 - enable tx temp comp - disabled
82 * bit1 - enable tx volt comp - disabled
83 * bit2 - enable fastClock - enabled
84 * bit3 - enable doubling - enabled
85 * bit4 - enable internal regulator - disabled
86 * bit5 - enable pa predistortion - disabled
87 */
88 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
89 .eepromWriteEnableGpio = 3,
90 .wlanDisableGpio = 0,
91 .wlanLedGpio = 8,
92 .rxBandSelectGpio = 0xff,
93 .txrxgain = 0,
94 .swreg = 0,
95 },
96 .modalHeader2G = {
97 /* ar9300_modal_eep_header 2g */
98 /* 4 idle,t1,t2,b(4 bits per setting) */
99 .antCtrlCommon = LE32(0x110),
100 /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
101 .antCtrlCommon2 = LE32(0x22222),
102
103 /*
104 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
105 * rx1, rx12, b (2 bits each)
106 */
107 .antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
108
109 /*
110 * xatten1DB[AR9300_MAX_CHAINS]; 3 xatten1_db
111 * for ar9280 (0xa20c/b20c 5:0)
112 */
113 .xatten1DB = {0, 0, 0},
114
115 /*
116 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
117 * for ar9280 (0xa20c/b20c 16:12
118 */
119 .xatten1Margin = {0, 0, 0},
120 .tempSlope = 36,
121 .voltSlope = 0,
122
123 /*
124 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
125 * channels in usual fbin coding format
126 */
127 .spurChans = {0, 0, 0, 0, 0},
128
129 /*
130 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
131 * if the register is per chain
132 */
133 .noiseFloorThreshCh = {-1, 0, 0},
134 .ob = {1, 1, 1},/* 3 chain */
135 .db_stage2 = {1, 1, 1}, /* 3 chain */
136 .db_stage3 = {0, 0, 0},
137 .db_stage4 = {0, 0, 0},
138 .xpaBiasLvl = 0,
139 .txFrameToDataStart = 0x0e,
140 .txFrameToPaOn = 0x0e,
141 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
142 .antennaGain = 0,
143 .switchSettling = 0x2c,
144 .adcDesiredSize = -30,
145 .txEndToXpaOff = 0,
146 .txEndToRxOn = 0x2,
147 .txFrameToXpaOn = 0xe,
148 .thresh62 = 28,
149 .papdRateMaskHt20 = LE32(0x80c080),
150 .papdRateMaskHt40 = LE32(0x80c080),
151 .futureModal = {
152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
153 0, 0, 0, 0, 0, 0, 0, 0
154 },
155 },
156 .calFreqPier2G = {
157 FREQ2FBIN(2412, 1),
158 FREQ2FBIN(2437, 1),
159 FREQ2FBIN(2472, 1),
160 },
161 /* ar9300_cal_data_per_freq_op_loop 2g */
162 .calPierData2G = {
163 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
164 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
165 { {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
166 },
167 .calTarget_freqbin_Cck = {
168 FREQ2FBIN(2412, 1),
169 FREQ2FBIN(2484, 1),
170 },
171 .calTarget_freqbin_2G = {
172 FREQ2FBIN(2412, 1),
173 FREQ2FBIN(2437, 1),
174 FREQ2FBIN(2472, 1)
175 },
176 .calTarget_freqbin_2GHT20 = {
177 FREQ2FBIN(2412, 1),
178 FREQ2FBIN(2437, 1),
179 FREQ2FBIN(2472, 1)
180 },
181 .calTarget_freqbin_2GHT40 = {
182 FREQ2FBIN(2412, 1),
183 FREQ2FBIN(2437, 1),
184 FREQ2FBIN(2472, 1)
185 },
186 .calTargetPowerCck = {
187 /* 1L-5L,5S,11L,11S */
188 { {36, 36, 36, 36} },
189 { {36, 36, 36, 36} },
190 },
191 .calTargetPower2G = {
192 /* 6-24,36,48,54 */
193 { {32, 32, 28, 24} },
194 { {32, 32, 28, 24} },
195 { {32, 32, 28, 24} },
196 },
197 .calTargetPower2GHT20 = {
198 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
199 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
200 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
201 },
202 .calTargetPower2GHT40 = {
203 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
204 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
205 { {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
206 },
207 .ctlIndex_2G = {
208 0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
209 0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
210 },
211 .ctl_freqbin_2G = {
212 {
213 FREQ2FBIN(2412, 1),
214 FREQ2FBIN(2417, 1),
215 FREQ2FBIN(2457, 1),
216 FREQ2FBIN(2462, 1)
217 },
218 {
219 FREQ2FBIN(2412, 1),
220 FREQ2FBIN(2417, 1),
221 FREQ2FBIN(2462, 1),
222 0xFF,
223 },
224
225 {
226 FREQ2FBIN(2412, 1),
227 FREQ2FBIN(2417, 1),
228 FREQ2FBIN(2462, 1),
229 0xFF,
230 },
231 {
232 FREQ2FBIN(2422, 1),
233 FREQ2FBIN(2427, 1),
234 FREQ2FBIN(2447, 1),
235 FREQ2FBIN(2452, 1)
236 },
237
238 {
239 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
240 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
241 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
242 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
243 },
244
245 {
246 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
247 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
248 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
249 0,
250 },
251
252 {
253 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
254 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
255 FREQ2FBIN(2472, 1),
256 0,
257 },
258
259 {
260 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
261 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
262 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
263 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
264 },
265
266 {
267 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
268 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
269 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
270 },
271
272 {
273 /* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
274 /* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
275 /* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
276 0
277 },
278
279 {
280 /* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
281 /* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
282 /* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
283 0
284 },
285
286 {
287 /* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
288 /* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
289 /* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
290 /* Data[11].ctlEdges[3].bChannel */
291 FREQ2FBIN(2462, 1),
292 }
293 },
294 .ctlPowerData_2G = {
295 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
296 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
297 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
298
299 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
300 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
301 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
302
303 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
304 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
305 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
306
307 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
308 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
309 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
310 },
311 .modalHeader5G = {
312 /* 4 idle,t1,t2,b (4 bits per setting) */
313 .antCtrlCommon = LE32(0x110),
314 /* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
315 .antCtrlCommon2 = LE32(0x22222),
316 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
317 .antCtrlChain = {
318 LE16(0x000), LE16(0x000), LE16(0x000),
319 },
320 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
321 .xatten1DB = {0, 0, 0},
322
323 /*
324 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
325 * for merlin (0xa20c/b20c 16:12
326 */
327 .xatten1Margin = {0, 0, 0},
328 .tempSlope = 68,
329 .voltSlope = 0,
330 /* spurChans spur channels in usual fbin coding format */
331 .spurChans = {0, 0, 0, 0, 0},
332 /* noiseFloorThreshCh Check if the register is per chain */
333 .noiseFloorThreshCh = {-1, 0, 0},
334 .ob = {3, 3, 3}, /* 3 chain */
335 .db_stage2 = {3, 3, 3}, /* 3 chain */
336 .db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
337 .db_stage4 = {3, 3, 3}, /* don't exist for 2G */
338 .xpaBiasLvl = 0,
339 .txFrameToDataStart = 0x0e,
340 .txFrameToPaOn = 0x0e,
341 .txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
342 .antennaGain = 0,
343 .switchSettling = 0x2d,
344 .adcDesiredSize = -30,
345 .txEndToXpaOff = 0,
346 .txEndToRxOn = 0x2,
347 .txFrameToXpaOn = 0xe,
348 .thresh62 = 28,
349 .papdRateMaskHt20 = LE32(0xf0e0e0),
350 .papdRateMaskHt40 = LE32(0xf0e0e0),
351 .futureModal = {
352 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
353 0, 0, 0, 0, 0, 0, 0, 0
354 },
355 },
356 .calFreqPier5G = {
357 FREQ2FBIN(5180, 0),
358 FREQ2FBIN(5220, 0),
359 FREQ2FBIN(5320, 0),
360 FREQ2FBIN(5400, 0),
361 FREQ2FBIN(5500, 0),
362 FREQ2FBIN(5600, 0),
363 FREQ2FBIN(5725, 0),
364 FREQ2FBIN(5825, 0)
365 },
366 .calPierData5G = {
367 {
368 {0, 0, 0, 0, 0},
369 {0, 0, 0, 0, 0},
370 {0, 0, 0, 0, 0},
371 {0, 0, 0, 0, 0},
372 {0, 0, 0, 0, 0},
373 {0, 0, 0, 0, 0},
374 {0, 0, 0, 0, 0},
375 {0, 0, 0, 0, 0},
376 },
377 {
378 {0, 0, 0, 0, 0},
379 {0, 0, 0, 0, 0},
380 {0, 0, 0, 0, 0},
381 {0, 0, 0, 0, 0},
382 {0, 0, 0, 0, 0},
383 {0, 0, 0, 0, 0},
384 {0, 0, 0, 0, 0},
385 {0, 0, 0, 0, 0},
386 },
387 {
388 {0, 0, 0, 0, 0},
389 {0, 0, 0, 0, 0},
390 {0, 0, 0, 0, 0},
391 {0, 0, 0, 0, 0},
392 {0, 0, 0, 0, 0},
393 {0, 0, 0, 0, 0},
394 {0, 0, 0, 0, 0},
395 {0, 0, 0, 0, 0},
396 },
397
398 },
399 .calTarget_freqbin_5G = {
400 FREQ2FBIN(5180, 0),
401 FREQ2FBIN(5220, 0),
402 FREQ2FBIN(5320, 0),
403 FREQ2FBIN(5400, 0),
404 FREQ2FBIN(5500, 0),
405 FREQ2FBIN(5600, 0),
406 FREQ2FBIN(5725, 0),
407 FREQ2FBIN(5825, 0)
408 },
409 .calTarget_freqbin_5GHT20 = {
410 FREQ2FBIN(5180, 0),
411 FREQ2FBIN(5240, 0),
412 FREQ2FBIN(5320, 0),
413 FREQ2FBIN(5500, 0),
414 FREQ2FBIN(5700, 0),
415 FREQ2FBIN(5745, 0),
416 FREQ2FBIN(5725, 0),
417 FREQ2FBIN(5825, 0)
418 },
419 .calTarget_freqbin_5GHT40 = {
420 FREQ2FBIN(5180, 0),
421 FREQ2FBIN(5240, 0),
422 FREQ2FBIN(5320, 0),
423 FREQ2FBIN(5500, 0),
424 FREQ2FBIN(5700, 0),
425 FREQ2FBIN(5745, 0),
426 FREQ2FBIN(5725, 0),
427 FREQ2FBIN(5825, 0)
428 },
429 .calTargetPower5G = {
430 /* 6-24,36,48,54 */
431 { {20, 20, 20, 10} },
432 { {20, 20, 20, 10} },
433 { {20, 20, 20, 10} },
434 { {20, 20, 20, 10} },
435 { {20, 20, 20, 10} },
436 { {20, 20, 20, 10} },
437 { {20, 20, 20, 10} },
438 { {20, 20, 20, 10} },
439 },
440 .calTargetPower5GHT20 = {
441 /*
442 * 0_8_16,1-3_9-11_17-19,
443 * 4,5,6,7,12,13,14,15,20,21,22,23
444 */
445 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
446 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
447 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
448 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
449 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
450 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
451 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
452 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
453 },
454 .calTargetPower5GHT40 = {
455 /*
456 * 0_8_16,1-3_9-11_17-19,
457 * 4,5,6,7,12,13,14,15,20,21,22,23
458 */
459 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
460 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
461 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
462 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
463 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
464 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
465 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
466 { {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
467 },
468 .ctlIndex_5G = {
469 0x10, 0x16, 0x18, 0x40, 0x46,
470 0x48, 0x30, 0x36, 0x38
471 },
472 .ctl_freqbin_5G = {
473 {
474 /* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
475 /* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
476 /* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
477 /* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
478 /* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
479 /* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
480 /* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
481 /* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
482 },
483 {
484 /* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
485 /* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
486 /* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
487 /* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
488 /* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
489 /* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
490 /* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
491 /* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
492 },
493
494 {
495 /* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
496 /* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
497 /* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
498 /* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
499 /* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
500 /* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
501 /* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
502 /* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
503 },
504
505 {
506 /* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
507 /* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
508 /* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
509 /* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
510 /* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
511 /* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
512 /* Data[3].ctlEdges[6].bChannel */ 0xFF,
513 /* Data[3].ctlEdges[7].bChannel */ 0xFF,
514 },
515
516 {
517 /* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
518 /* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
519 /* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
520 /* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
521 /* Data[4].ctlEdges[4].bChannel */ 0xFF,
522 /* Data[4].ctlEdges[5].bChannel */ 0xFF,
523 /* Data[4].ctlEdges[6].bChannel */ 0xFF,
524 /* Data[4].ctlEdges[7].bChannel */ 0xFF,
525 },
526
527 {
528 /* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
529 /* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
530 /* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
531 /* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
532 /* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
533 /* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
534 /* Data[5].ctlEdges[6].bChannel */ 0xFF,
535 /* Data[5].ctlEdges[7].bChannel */ 0xFF
536 },
537
538 {
539 /* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
540 /* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
541 /* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
542 /* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
543 /* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
544 /* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
545 /* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
546 /* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
547 },
548
549 {
550 /* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
551 /* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
552 /* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
553 /* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
554 /* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
555 /* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
556 /* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
557 /* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
558 },
559
560 {
561 /* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
562 /* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
563 /* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
564 /* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
565 /* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
566 /* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
567 /* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
568 /* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
569 }
570 },
571 .ctlPowerData_5G = {
572 {
573 {
574 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
575 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
576 }
577 },
578 {
579 {
580 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
581 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
582 }
583 },
584 {
585 {
586 CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
587 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
588 }
589 },
590 {
591 {
592 CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
593 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
594 }
595 },
596 {
597 {
598 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
599 CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
600 }
601 },
602 {
603 {
604 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
605 CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
606 }
607 },
608 {
609 {
610 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
611 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
612 }
613 },
614 {
615 {
616 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
617 CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
618 }
619 },
620 {
621 {
622 CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
623 CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
624 }
625 },
626 }
627 };
628
629 static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
630 {
631 if (fbin == AR9300_BCHAN_UNUSED)
632 return fbin;
633
634 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
635 }
636
637 static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
638 {
639 return 0;
640 }
641
642 static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
643 enum eeprom_param param)
644 {
645 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
646 struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
647
648 switch (param) {
649 case EEP_MAC_LSW:
650 return eep->macAddr[0] << 8 | eep->macAddr[1];
651 case EEP_MAC_MID:
652 return eep->macAddr[2] << 8 | eep->macAddr[3];
653 case EEP_MAC_MSW:
654 return eep->macAddr[4] << 8 | eep->macAddr[5];
655 case EEP_REG_0:
656 return le16_to_cpu(pBase->regDmn[0]);
657 case EEP_REG_1:
658 return le16_to_cpu(pBase->regDmn[1]);
659 case EEP_OP_CAP:
660 return pBase->deviceCap;
661 case EEP_OP_MODE:
662 return pBase->opCapFlags.opFlags;
663 case EEP_RF_SILENT:
664 return pBase->rfSilent;
665 case EEP_TX_MASK:
666 return (pBase->txrxMask >> 4) & 0xf;
667 case EEP_RX_MASK:
668 return pBase->txrxMask & 0xf;
669 case EEP_DRIVE_STRENGTH:
670 #define AR9300_EEP_BASE_DRIV_STRENGTH 0x1
671 return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
672 case EEP_INTERNAL_REGULATOR:
673 /* Bit 4 is internal regulator flag */
674 return (pBase->featureEnable & 0x10) >> 4;
675 case EEP_SWREG:
676 return le32_to_cpu(pBase->swreg);
677 case EEP_PAPRD:
678 return !!(pBase->featureEnable & BIT(5));
679 default:
680 return 0;
681 }
682 }
683
684 static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
685 u8 *buffer)
686 {
687 u16 val;
688
689 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
690 return false;
691
692 *buffer = (val >> (8 * (address % 2))) & 0xff;
693 return true;
694 }
695
696 static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
697 u8 *buffer)
698 {
699 u16 val;
700
701 if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
702 return false;
703
704 buffer[0] = val >> 8;
705 buffer[1] = val & 0xff;
706
707 return true;
708 }
709
710 static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
711 int count)
712 {
713 struct ath_common *common = ath9k_hw_common(ah);
714 int i;
715
716 if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
717 ath_print(common, ATH_DBG_EEPROM,
718 "eeprom address not in range\n");
719 return false;
720 }
721
722 /*
723 * Since we're reading the bytes in reverse order from a little-endian
724 * word stream, an even address means we only use the lower half of
725 * the 16-bit word at that address
726 */
727 if (address % 2 == 0) {
728 if (!ar9300_eeprom_read_byte(common, address--, buffer++))
729 goto error;
730
731 count--;
732 }
733
734 for (i = 0; i < count / 2; i++) {
735 if (!ar9300_eeprom_read_word(common, address, buffer))
736 goto error;
737
738 address -= 2;
739 buffer += 2;
740 }
741
742 if (count % 2)
743 if (!ar9300_eeprom_read_byte(common, address, buffer))
744 goto error;
745
746 return true;
747
748 error:
749 ath_print(common, ATH_DBG_EEPROM,
750 "unable to read eeprom region at offset %d\n", address);
751 return false;
752 }
753
754 static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
755 int *length, int *major, int *minor)
756 {
757 unsigned long value[4];
758
759 value[0] = best[0];
760 value[1] = best[1];
761 value[2] = best[2];
762 value[3] = best[3];
763 *code = ((value[0] >> 5) & 0x0007);
764 *reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
765 *length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
766 *major = (value[2] & 0x000f);
767 *minor = (value[3] & 0x00ff);
768 }
769
770 static u16 ar9300_comp_cksum(u8 *data, int dsize)
771 {
772 int it, checksum = 0;
773
774 for (it = 0; it < dsize; it++) {
775 checksum += data[it];
776 checksum &= 0xffff;
777 }
778
779 return checksum;
780 }
781
782 static bool ar9300_uncompress_block(struct ath_hw *ah,
783 u8 *mptr,
784 int mdataSize,
785 u8 *block,
786 int size)
787 {
788 int it;
789 int spot;
790 int offset;
791 int length;
792 struct ath_common *common = ath9k_hw_common(ah);
793
794 spot = 0;
795
796 for (it = 0; it < size; it += (length+2)) {
797 offset = block[it];
798 offset &= 0xff;
799 spot += offset;
800 length = block[it+1];
801 length &= 0xff;
802
803 if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
804 ath_print(common, ATH_DBG_EEPROM,
805 "Restore at %d: spot=%d "
806 "offset=%d length=%d\n",
807 it, spot, offset, length);
808 memcpy(&mptr[spot], &block[it+2], length);
809 spot += length;
810 } else if (length > 0) {
811 ath_print(common, ATH_DBG_EEPROM,
812 "Bad restore at %d: spot=%d "
813 "offset=%d length=%d\n",
814 it, spot, offset, length);
815 return false;
816 }
817 }
818 return true;
819 }
820
821 static int ar9300_compress_decision(struct ath_hw *ah,
822 int it,
823 int code,
824 int reference,
825 u8 *mptr,
826 u8 *word, int length, int mdata_size)
827 {
828 struct ath_common *common = ath9k_hw_common(ah);
829 u8 *dptr;
830
831 switch (code) {
832 case _CompressNone:
833 if (length != mdata_size) {
834 ath_print(common, ATH_DBG_EEPROM,
835 "EEPROM structure size mismatch"
836 "memory=%d eeprom=%d\n", mdata_size, length);
837 return -1;
838 }
839 memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
840 ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
841 " uncompressed, length %d\n", it, length);
842 break;
843 case _CompressBlock:
844 if (reference == 0) {
845 dptr = mptr;
846 } else {
847 if (reference != 2) {
848 ath_print(common, ATH_DBG_EEPROM,
849 "cant find reference eeprom"
850 "struct %d\n", reference);
851 return -1;
852 }
853 memcpy(mptr, &ar9300_default, mdata_size);
854 }
855 ath_print(common, ATH_DBG_EEPROM,
856 "restore eeprom %d: block, reference %d,"
857 " length %d\n", it, reference, length);
858 ar9300_uncompress_block(ah, mptr, mdata_size,
859 (u8 *) (word + COMP_HDR_LEN), length);
860 break;
861 default:
862 ath_print(common, ATH_DBG_EEPROM, "unknown compression"
863 " code %d\n", code);
864 return -1;
865 }
866 return 0;
867 }
868
869 /*
870 * Read the configuration data from the eeprom.
871 * The data can be put in any specified memory buffer.
872 *
873 * Returns -1 on error.
874 * Returns address of next memory location on success.
875 */
876 static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
877 u8 *mptr, int mdata_size)
878 {
879 #define MDEFAULT 15
880 #define MSTATE 100
881 int cptr;
882 u8 *word;
883 int code;
884 int reference, length, major, minor;
885 int osize;
886 int it;
887 u16 checksum, mchecksum;
888 struct ath_common *common = ath9k_hw_common(ah);
889
890 word = kzalloc(2048, GFP_KERNEL);
891 if (!word)
892 return -1;
893
894 memcpy(mptr, &ar9300_default, mdata_size);
895
896 cptr = AR9300_BASE_ADDR;
897 for (it = 0; it < MSTATE; it++) {
898 if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
899 goto fail;
900
901 if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
902 word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
903 && word[2] == 0xff && word[3] == 0xff))
904 break;
905
906 ar9300_comp_hdr_unpack(word, &code, &reference,
907 &length, &major, &minor);
908 ath_print(common, ATH_DBG_EEPROM,
909 "Found block at %x: code=%d ref=%d"
910 "length=%d major=%d minor=%d\n", cptr, code,
911 reference, length, major, minor);
912 if (length >= 1024) {
913 ath_print(common, ATH_DBG_EEPROM,
914 "Skipping bad header\n");
915 cptr -= COMP_HDR_LEN;
916 continue;
917 }
918
919 osize = length;
920 ar9300_read_eeprom(ah, cptr, word,
921 COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
922 checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
923 mchecksum = word[COMP_HDR_LEN + osize] |
924 (word[COMP_HDR_LEN + osize + 1] << 8);
925 ath_print(common, ATH_DBG_EEPROM,
926 "checksum %x %x\n", checksum, mchecksum);
927 if (checksum == mchecksum) {
928 ar9300_compress_decision(ah, it, code, reference, mptr,
929 word, length, mdata_size);
930 } else {
931 ath_print(common, ATH_DBG_EEPROM,
932 "skipping block with bad checksum\n");
933 }
934 cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
935 }
936
937 kfree(word);
938 return cptr;
939
940 fail:
941 kfree(word);
942 return -1;
943 }
944
945 /*
946 * Restore the configuration structure by reading the eeprom.
947 * This function destroys any existing in-memory structure
948 * content.
949 */
950 static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
951 {
952 u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
953
954 if (ar9300_eeprom_restore_internal(ah, mptr,
955 sizeof(struct ar9300_eeprom)) < 0)
956 return false;
957
958 return true;
959 }
960
961 /* XXX: review hardware docs */
962 static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
963 {
964 return ah->eeprom.ar9300_eep.eepromVersion;
965 }
966
967 /* XXX: could be read from the eepromVersion, not sure yet */
968 static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
969 {
970 return 0;
971 }
972
973 static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
974 enum ath9k_hal_freq_band freq_band)
975 {
976 return 1;
977 }
978
979 static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
980 struct ath9k_channel *chan)
981 {
982 return -EINVAL;
983 }
984
985 static s32 ar9003_hw_xpa_bias_level_get(struct ath_hw *ah, bool is2ghz)
986 {
987 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
988
989 if (is2ghz)
990 return eep->modalHeader2G.xpaBiasLvl;
991 else
992 return eep->modalHeader5G.xpaBiasLvl;
993 }
994
995 static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
996 {
997 int bias = ar9003_hw_xpa_bias_level_get(ah, is2ghz);
998 REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, (bias & 0x3));
999 REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_SPARE,
1000 ((bias >> 2) & 0x3));
1001 }
1002
1003 static u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz)
1004 {
1005 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1006 __le32 val;
1007
1008 if (is2ghz)
1009 val = eep->modalHeader2G.antCtrlCommon;
1010 else
1011 val = eep->modalHeader5G.antCtrlCommon;
1012 return le32_to_cpu(val);
1013 }
1014
1015 static u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz)
1016 {
1017 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1018 __le32 val;
1019
1020 if (is2ghz)
1021 val = eep->modalHeader2G.antCtrlCommon2;
1022 else
1023 val = eep->modalHeader5G.antCtrlCommon2;
1024 return le32_to_cpu(val);
1025 }
1026
1027 static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
1028 int chain,
1029 bool is2ghz)
1030 {
1031 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1032 __le16 val = 0;
1033
1034 if (chain >= 0 && chain < AR9300_MAX_CHAINS) {
1035 if (is2ghz)
1036 val = eep->modalHeader2G.antCtrlChain[chain];
1037 else
1038 val = eep->modalHeader5G.antCtrlChain[chain];
1039 }
1040
1041 return le16_to_cpu(val);
1042 }
1043
1044 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
1045 {
1046 u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
1047 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
1048
1049 value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
1050 REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
1051
1052 value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
1053 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
1054
1055 value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
1056 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL, value);
1057
1058 value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
1059 REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL, value);
1060 }
1061
1062 static void ar9003_hw_drive_strength_apply(struct ath_hw *ah)
1063 {
1064 int drive_strength;
1065 unsigned long reg;
1066
1067 drive_strength = ath9k_hw_ar9300_get_eeprom(ah, EEP_DRIVE_STRENGTH);
1068
1069 if (!drive_strength)
1070 return;
1071
1072 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS1);
1073 reg &= ~0x00ffffc0;
1074 reg |= 0x5 << 21;
1075 reg |= 0x5 << 18;
1076 reg |= 0x5 << 15;
1077 reg |= 0x5 << 12;
1078 reg |= 0x5 << 9;
1079 reg |= 0x5 << 6;
1080 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS1, reg);
1081
1082 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS2);
1083 reg &= ~0xffffffe0;
1084 reg |= 0x5 << 29;
1085 reg |= 0x5 << 26;
1086 reg |= 0x5 << 23;
1087 reg |= 0x5 << 20;
1088 reg |= 0x5 << 17;
1089 reg |= 0x5 << 14;
1090 reg |= 0x5 << 11;
1091 reg |= 0x5 << 8;
1092 reg |= 0x5 << 5;
1093 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS2, reg);
1094
1095 reg = REG_READ(ah, AR_PHY_65NM_CH0_BIAS4);
1096 reg &= ~0xff800000;
1097 reg |= 0x5 << 29;
1098 reg |= 0x5 << 26;
1099 reg |= 0x5 << 23;
1100 REG_WRITE(ah, AR_PHY_65NM_CH0_BIAS4, reg);
1101 }
1102
1103 static void ar9003_hw_internal_regulator_apply(struct ath_hw *ah)
1104 {
1105 int internal_regulator =
1106 ath9k_hw_ar9300_get_eeprom(ah, EEP_INTERNAL_REGULATOR);
1107
1108 if (internal_regulator) {
1109 /* Internal regulator is ON. Write swreg register. */
1110 int swreg = ath9k_hw_ar9300_get_eeprom(ah, EEP_SWREG);
1111 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1112 REG_READ(ah, AR_RTC_REG_CONTROL1) &
1113 (~AR_RTC_REG_CONTROL1_SWREG_PROGRAM));
1114 REG_WRITE(ah, AR_RTC_REG_CONTROL0, swreg);
1115 /* Set REG_CONTROL1.SWREG_PROGRAM */
1116 REG_WRITE(ah, AR_RTC_REG_CONTROL1,
1117 REG_READ(ah,
1118 AR_RTC_REG_CONTROL1) |
1119 AR_RTC_REG_CONTROL1_SWREG_PROGRAM);
1120 } else {
1121 REG_WRITE(ah, AR_RTC_SLEEP_CLK,
1122 (REG_READ(ah,
1123 AR_RTC_SLEEP_CLK) |
1124 AR_RTC_FORCE_SWREG_PRD));
1125 }
1126 }
1127
1128 static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
1129 struct ath9k_channel *chan)
1130 {
1131 ar9003_hw_xpa_bias_level_apply(ah, IS_CHAN_2GHZ(chan));
1132 ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
1133 ar9003_hw_drive_strength_apply(ah);
1134 ar9003_hw_internal_regulator_apply(ah);
1135 }
1136
1137 static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah,
1138 struct ath9k_channel *chan)
1139 {
1140 }
1141
1142 /*
1143 * Returns the interpolated y value corresponding to the specified x value
1144 * from the np ordered pairs of data (px,py).
1145 * The pairs do not have to be in any order.
1146 * If the specified x value is less than any of the px,
1147 * the returned y value is equal to the py for the lowest px.
1148 * If the specified x value is greater than any of the px,
1149 * the returned y value is equal to the py for the highest px.
1150 */
1151 static int ar9003_hw_power_interpolate(int32_t x,
1152 int32_t *px, int32_t *py, u_int16_t np)
1153 {
1154 int ip = 0;
1155 int lx = 0, ly = 0, lhave = 0;
1156 int hx = 0, hy = 0, hhave = 0;
1157 int dx = 0;
1158 int y = 0;
1159
1160 lhave = 0;
1161 hhave = 0;
1162
1163 /* identify best lower and higher x calibration measurement */
1164 for (ip = 0; ip < np; ip++) {
1165 dx = x - px[ip];
1166
1167 /* this measurement is higher than our desired x */
1168 if (dx <= 0) {
1169 if (!hhave || dx > (x - hx)) {
1170 /* new best higher x measurement */
1171 hx = px[ip];
1172 hy = py[ip];
1173 hhave = 1;
1174 }
1175 }
1176 /* this measurement is lower than our desired x */
1177 if (dx >= 0) {
1178 if (!lhave || dx < (x - lx)) {
1179 /* new best lower x measurement */
1180 lx = px[ip];
1181 ly = py[ip];
1182 lhave = 1;
1183 }
1184 }
1185 }
1186
1187 /* the low x is good */
1188 if (lhave) {
1189 /* so is the high x */
1190 if (hhave) {
1191 /* they're the same, so just pick one */
1192 if (hx == lx)
1193 y = ly;
1194 else /* interpolate */
1195 y = ly + (((x - lx) * (hy - ly)) / (hx - lx));
1196 } else /* only low is good, use it */
1197 y = ly;
1198 } else if (hhave) /* only high is good, use it */
1199 y = hy;
1200 else /* nothing is good,this should never happen unless np=0, ???? */
1201 y = -(1 << 30);
1202 return y;
1203 }
1204
1205 static u8 ar9003_hw_eeprom_get_tgt_pwr(struct ath_hw *ah,
1206 u16 rateIndex, u16 freq, bool is2GHz)
1207 {
1208 u16 numPiers, i;
1209 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1210 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1211 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1212 struct cal_tgt_pow_legacy *pEepromTargetPwr;
1213 u8 *pFreqBin;
1214
1215 if (is2GHz) {
1216 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1217 pEepromTargetPwr = eep->calTargetPower2G;
1218 pFreqBin = eep->calTarget_freqbin_2G;
1219 } else {
1220 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1221 pEepromTargetPwr = eep->calTargetPower5G;
1222 pFreqBin = eep->calTarget_freqbin_5G;
1223 }
1224
1225 /*
1226 * create array of channels and targetpower from
1227 * targetpower piers stored on eeprom
1228 */
1229 for (i = 0; i < numPiers; i++) {
1230 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1231 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1232 }
1233
1234 /* interpolate to get target power for given frequency */
1235 return (u8) ar9003_hw_power_interpolate((s32) freq,
1236 freqArray,
1237 targetPowerArray, numPiers);
1238 }
1239
1240 static u8 ar9003_hw_eeprom_get_ht20_tgt_pwr(struct ath_hw *ah,
1241 u16 rateIndex,
1242 u16 freq, bool is2GHz)
1243 {
1244 u16 numPiers, i;
1245 s32 targetPowerArray[AR9300_NUM_5G_20_TARGET_POWERS];
1246 s32 freqArray[AR9300_NUM_5G_20_TARGET_POWERS];
1247 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1248 struct cal_tgt_pow_ht *pEepromTargetPwr;
1249 u8 *pFreqBin;
1250
1251 if (is2GHz) {
1252 numPiers = AR9300_NUM_2G_20_TARGET_POWERS;
1253 pEepromTargetPwr = eep->calTargetPower2GHT20;
1254 pFreqBin = eep->calTarget_freqbin_2GHT20;
1255 } else {
1256 numPiers = AR9300_NUM_5G_20_TARGET_POWERS;
1257 pEepromTargetPwr = eep->calTargetPower5GHT20;
1258 pFreqBin = eep->calTarget_freqbin_5GHT20;
1259 }
1260
1261 /*
1262 * create array of channels and targetpower
1263 * from targetpower piers stored on eeprom
1264 */
1265 for (i = 0; i < numPiers; i++) {
1266 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1267 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1268 }
1269
1270 /* interpolate to get target power for given frequency */
1271 return (u8) ar9003_hw_power_interpolate((s32) freq,
1272 freqArray,
1273 targetPowerArray, numPiers);
1274 }
1275
1276 static u8 ar9003_hw_eeprom_get_ht40_tgt_pwr(struct ath_hw *ah,
1277 u16 rateIndex,
1278 u16 freq, bool is2GHz)
1279 {
1280 u16 numPiers, i;
1281 s32 targetPowerArray[AR9300_NUM_5G_40_TARGET_POWERS];
1282 s32 freqArray[AR9300_NUM_5G_40_TARGET_POWERS];
1283 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1284 struct cal_tgt_pow_ht *pEepromTargetPwr;
1285 u8 *pFreqBin;
1286
1287 if (is2GHz) {
1288 numPiers = AR9300_NUM_2G_40_TARGET_POWERS;
1289 pEepromTargetPwr = eep->calTargetPower2GHT40;
1290 pFreqBin = eep->calTarget_freqbin_2GHT40;
1291 } else {
1292 numPiers = AR9300_NUM_5G_40_TARGET_POWERS;
1293 pEepromTargetPwr = eep->calTargetPower5GHT40;
1294 pFreqBin = eep->calTarget_freqbin_5GHT40;
1295 }
1296
1297 /*
1298 * create array of channels and targetpower from
1299 * targetpower piers stored on eeprom
1300 */
1301 for (i = 0; i < numPiers; i++) {
1302 freqArray[i] = FBIN2FREQ(pFreqBin[i], is2GHz);
1303 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1304 }
1305
1306 /* interpolate to get target power for given frequency */
1307 return (u8) ar9003_hw_power_interpolate((s32) freq,
1308 freqArray,
1309 targetPowerArray, numPiers);
1310 }
1311
1312 static u8 ar9003_hw_eeprom_get_cck_tgt_pwr(struct ath_hw *ah,
1313 u16 rateIndex, u16 freq)
1314 {
1315 u16 numPiers = AR9300_NUM_2G_CCK_TARGET_POWERS, i;
1316 s32 targetPowerArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1317 s32 freqArray[AR9300_NUM_2G_CCK_TARGET_POWERS];
1318 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1319 struct cal_tgt_pow_legacy *pEepromTargetPwr = eep->calTargetPowerCck;
1320 u8 *pFreqBin = eep->calTarget_freqbin_Cck;
1321
1322 /*
1323 * create array of channels and targetpower from
1324 * targetpower piers stored on eeprom
1325 */
1326 for (i = 0; i < numPiers; i++) {
1327 freqArray[i] = FBIN2FREQ(pFreqBin[i], 1);
1328 targetPowerArray[i] = pEepromTargetPwr[i].tPow2x[rateIndex];
1329 }
1330
1331 /* interpolate to get target power for given frequency */
1332 return (u8) ar9003_hw_power_interpolate((s32) freq,
1333 freqArray,
1334 targetPowerArray, numPiers);
1335 }
1336
1337 /* Set tx power registers to array of values passed in */
1338 static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
1339 {
1340 #define POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
1341 /* make sure forced gain is not set */
1342 REG_WRITE(ah, 0xa458, 0);
1343
1344 /* Write the OFDM power per rate set */
1345
1346 /* 6 (LSB), 9, 12, 18 (MSB) */
1347 REG_WRITE(ah, 0xa3c0,
1348 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 24) |
1349 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 16) |
1350 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 8) |
1351 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1352
1353 /* 24 (LSB), 36, 48, 54 (MSB) */
1354 REG_WRITE(ah, 0xa3c4,
1355 POW_SM(pPwrArray[ALL_TARGET_LEGACY_54], 24) |
1356 POW_SM(pPwrArray[ALL_TARGET_LEGACY_48], 16) |
1357 POW_SM(pPwrArray[ALL_TARGET_LEGACY_36], 8) |
1358 POW_SM(pPwrArray[ALL_TARGET_LEGACY_6_24], 0));
1359
1360 /* Write the CCK power per rate set */
1361
1362 /* 1L (LSB), reserved, 2L, 2S (MSB) */
1363 REG_WRITE(ah, 0xa3c8,
1364 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 24) |
1365 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 16) |
1366 /* POW_SM(txPowerTimes2, 8) | this is reserved for AR9003 */
1367 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0));
1368
1369 /* 5.5L (LSB), 5.5S, 11L, 11S (MSB) */
1370 REG_WRITE(ah, 0xa3cc,
1371 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11S], 24) |
1372 POW_SM(pPwrArray[ALL_TARGET_LEGACY_11L], 16) |
1373 POW_SM(pPwrArray[ALL_TARGET_LEGACY_5S], 8) |
1374 POW_SM(pPwrArray[ALL_TARGET_LEGACY_1L_5L], 0)
1375 );
1376
1377 /* Write the HT20 power per rate set */
1378
1379 /* 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB) */
1380 REG_WRITE(ah, 0xa3d0,
1381 POW_SM(pPwrArray[ALL_TARGET_HT20_5], 24) |
1382 POW_SM(pPwrArray[ALL_TARGET_HT20_4], 16) |
1383 POW_SM(pPwrArray[ALL_TARGET_HT20_1_3_9_11_17_19], 8) |
1384 POW_SM(pPwrArray[ALL_TARGET_HT20_0_8_16], 0)
1385 );
1386
1387 /* 6 (LSB), 7, 12, 13 (MSB) */
1388 REG_WRITE(ah, 0xa3d4,
1389 POW_SM(pPwrArray[ALL_TARGET_HT20_13], 24) |
1390 POW_SM(pPwrArray[ALL_TARGET_HT20_12], 16) |
1391 POW_SM(pPwrArray[ALL_TARGET_HT20_7], 8) |
1392 POW_SM(pPwrArray[ALL_TARGET_HT20_6], 0)
1393 );
1394
1395 /* 14 (LSB), 15, 20, 21 */
1396 REG_WRITE(ah, 0xa3e4,
1397 POW_SM(pPwrArray[ALL_TARGET_HT20_21], 24) |
1398 POW_SM(pPwrArray[ALL_TARGET_HT20_20], 16) |
1399 POW_SM(pPwrArray[ALL_TARGET_HT20_15], 8) |
1400 POW_SM(pPwrArray[ALL_TARGET_HT20_14], 0)
1401 );
1402
1403 /* Mixed HT20 and HT40 rates */
1404
1405 /* HT20 22 (LSB), HT20 23, HT40 22, HT40 23 (MSB) */
1406 REG_WRITE(ah, 0xa3e8,
1407 POW_SM(pPwrArray[ALL_TARGET_HT40_23], 24) |
1408 POW_SM(pPwrArray[ALL_TARGET_HT40_22], 16) |
1409 POW_SM(pPwrArray[ALL_TARGET_HT20_23], 8) |
1410 POW_SM(pPwrArray[ALL_TARGET_HT20_22], 0)
1411 );
1412
1413 /*
1414 * Write the HT40 power per rate set
1415 * correct PAR difference between HT40 and HT20/LEGACY
1416 * 0/8/16 (LSB), 1-3/9-11/17-19, 4, 5 (MSB)
1417 */
1418 REG_WRITE(ah, 0xa3d8,
1419 POW_SM(pPwrArray[ALL_TARGET_HT40_5], 24) |
1420 POW_SM(pPwrArray[ALL_TARGET_HT40_4], 16) |
1421 POW_SM(pPwrArray[ALL_TARGET_HT40_1_3_9_11_17_19], 8) |
1422 POW_SM(pPwrArray[ALL_TARGET_HT40_0_8_16], 0)
1423 );
1424
1425 /* 6 (LSB), 7, 12, 13 (MSB) */
1426 REG_WRITE(ah, 0xa3dc,
1427 POW_SM(pPwrArray[ALL_TARGET_HT40_13], 24) |
1428 POW_SM(pPwrArray[ALL_TARGET_HT40_12], 16) |
1429 POW_SM(pPwrArray[ALL_TARGET_HT40_7], 8) |
1430 POW_SM(pPwrArray[ALL_TARGET_HT40_6], 0)
1431 );
1432
1433 /* 14 (LSB), 15, 20, 21 */
1434 REG_WRITE(ah, 0xa3ec,
1435 POW_SM(pPwrArray[ALL_TARGET_HT40_21], 24) |
1436 POW_SM(pPwrArray[ALL_TARGET_HT40_20], 16) |
1437 POW_SM(pPwrArray[ALL_TARGET_HT40_15], 8) |
1438 POW_SM(pPwrArray[ALL_TARGET_HT40_14], 0)
1439 );
1440
1441 return 0;
1442 #undef POW_SM
1443 }
1444
1445 static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
1446 u8 *targetPowerValT2)
1447 {
1448 /* XXX: hard code for now, need to get from eeprom struct */
1449 u8 ht40PowerIncForPdadc = 0;
1450 bool is2GHz = false;
1451 unsigned int i = 0;
1452 struct ath_common *common = ath9k_hw_common(ah);
1453
1454 if (freq < 4000)
1455 is2GHz = true;
1456
1457 targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
1458 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
1459 is2GHz);
1460 targetPowerValT2[ALL_TARGET_LEGACY_36] =
1461 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
1462 is2GHz);
1463 targetPowerValT2[ALL_TARGET_LEGACY_48] =
1464 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
1465 is2GHz);
1466 targetPowerValT2[ALL_TARGET_LEGACY_54] =
1467 ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
1468 is2GHz);
1469 targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
1470 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
1471 freq);
1472 targetPowerValT2[ALL_TARGET_LEGACY_5S] =
1473 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
1474 targetPowerValT2[ALL_TARGET_LEGACY_11L] =
1475 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
1476 targetPowerValT2[ALL_TARGET_LEGACY_11S] =
1477 ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
1478 targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
1479 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1480 is2GHz);
1481 targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
1482 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1483 freq, is2GHz);
1484 targetPowerValT2[ALL_TARGET_HT20_4] =
1485 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1486 is2GHz);
1487 targetPowerValT2[ALL_TARGET_HT20_5] =
1488 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1489 is2GHz);
1490 targetPowerValT2[ALL_TARGET_HT20_6] =
1491 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1492 is2GHz);
1493 targetPowerValT2[ALL_TARGET_HT20_7] =
1494 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1495 is2GHz);
1496 targetPowerValT2[ALL_TARGET_HT20_12] =
1497 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1498 is2GHz);
1499 targetPowerValT2[ALL_TARGET_HT20_13] =
1500 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1501 is2GHz);
1502 targetPowerValT2[ALL_TARGET_HT20_14] =
1503 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1504 is2GHz);
1505 targetPowerValT2[ALL_TARGET_HT20_15] =
1506 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1507 is2GHz);
1508 targetPowerValT2[ALL_TARGET_HT20_20] =
1509 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1510 is2GHz);
1511 targetPowerValT2[ALL_TARGET_HT20_21] =
1512 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1513 is2GHz);
1514 targetPowerValT2[ALL_TARGET_HT20_22] =
1515 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1516 is2GHz);
1517 targetPowerValT2[ALL_TARGET_HT20_23] =
1518 ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1519 is2GHz);
1520 targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
1521 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1522 is2GHz) + ht40PowerIncForPdadc;
1523 targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
1524 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1525 freq,
1526 is2GHz) + ht40PowerIncForPdadc;
1527 targetPowerValT2[ALL_TARGET_HT40_4] =
1528 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1529 is2GHz) + ht40PowerIncForPdadc;
1530 targetPowerValT2[ALL_TARGET_HT40_5] =
1531 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1532 is2GHz) + ht40PowerIncForPdadc;
1533 targetPowerValT2[ALL_TARGET_HT40_6] =
1534 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1535 is2GHz) + ht40PowerIncForPdadc;
1536 targetPowerValT2[ALL_TARGET_HT40_7] =
1537 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1538 is2GHz) + ht40PowerIncForPdadc;
1539 targetPowerValT2[ALL_TARGET_HT40_12] =
1540 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1541 is2GHz) + ht40PowerIncForPdadc;
1542 targetPowerValT2[ALL_TARGET_HT40_13] =
1543 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1544 is2GHz) + ht40PowerIncForPdadc;
1545 targetPowerValT2[ALL_TARGET_HT40_14] =
1546 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1547 is2GHz) + ht40PowerIncForPdadc;
1548 targetPowerValT2[ALL_TARGET_HT40_15] =
1549 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1550 is2GHz) + ht40PowerIncForPdadc;
1551 targetPowerValT2[ALL_TARGET_HT40_20] =
1552 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1553 is2GHz) + ht40PowerIncForPdadc;
1554 targetPowerValT2[ALL_TARGET_HT40_21] =
1555 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1556 is2GHz) + ht40PowerIncForPdadc;
1557 targetPowerValT2[ALL_TARGET_HT40_22] =
1558 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1559 is2GHz) + ht40PowerIncForPdadc;
1560 targetPowerValT2[ALL_TARGET_HT40_23] =
1561 ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1562 is2GHz) + ht40PowerIncForPdadc;
1563
1564 while (i < ar9300RateSize) {
1565 ath_print(common, ATH_DBG_EEPROM,
1566 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1567 i++;
1568
1569 ath_print(common, ATH_DBG_EEPROM,
1570 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1571 i++;
1572
1573 ath_print(common, ATH_DBG_EEPROM,
1574 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1575 i++;
1576
1577 ath_print(common, ATH_DBG_EEPROM,
1578 "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
1579 i++;
1580 }
1581 }
1582
1583 static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
1584 int mode,
1585 int ipier,
1586 int ichain,
1587 int *pfrequency,
1588 int *pcorrection,
1589 int *ptemperature, int *pvoltage)
1590 {
1591 u8 *pCalPier;
1592 struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
1593 int is2GHz;
1594 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1595 struct ath_common *common = ath9k_hw_common(ah);
1596
1597 if (ichain >= AR9300_MAX_CHAINS) {
1598 ath_print(common, ATH_DBG_EEPROM,
1599 "Invalid chain index, must be less than %d\n",
1600 AR9300_MAX_CHAINS);
1601 return -1;
1602 }
1603
1604 if (mode) { /* 5GHz */
1605 if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
1606 ath_print(common, ATH_DBG_EEPROM,
1607 "Invalid 5GHz cal pier index, must "
1608 "be less than %d\n",
1609 AR9300_NUM_5G_CAL_PIERS);
1610 return -1;
1611 }
1612 pCalPier = &(eep->calFreqPier5G[ipier]);
1613 pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
1614 is2GHz = 0;
1615 } else {
1616 if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
1617 ath_print(common, ATH_DBG_EEPROM,
1618 "Invalid 2GHz cal pier index, must "
1619 "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
1620 return -1;
1621 }
1622
1623 pCalPier = &(eep->calFreqPier2G[ipier]);
1624 pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
1625 is2GHz = 1;
1626 }
1627
1628 *pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
1629 *pcorrection = pCalPierStruct->refPower;
1630 *ptemperature = pCalPierStruct->tempMeas;
1631 *pvoltage = pCalPierStruct->voltMeas;
1632
1633 return 0;
1634 }
1635
1636 static int ar9003_hw_power_control_override(struct ath_hw *ah,
1637 int frequency,
1638 int *correction,
1639 int *voltage, int *temperature)
1640 {
1641 int tempSlope = 0;
1642 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1643
1644 REG_RMW(ah, AR_PHY_TPC_11_B0,
1645 (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1646 AR_PHY_TPC_OLPC_GAIN_DELTA);
1647 REG_RMW(ah, AR_PHY_TPC_11_B1,
1648 (correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1649 AR_PHY_TPC_OLPC_GAIN_DELTA);
1650 REG_RMW(ah, AR_PHY_TPC_11_B2,
1651 (correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1652 AR_PHY_TPC_OLPC_GAIN_DELTA);
1653
1654 /* enable open loop power control on chip */
1655 REG_RMW(ah, AR_PHY_TPC_6_B0,
1656 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1657 AR_PHY_TPC_6_ERROR_EST_MODE);
1658 REG_RMW(ah, AR_PHY_TPC_6_B1,
1659 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1660 AR_PHY_TPC_6_ERROR_EST_MODE);
1661 REG_RMW(ah, AR_PHY_TPC_6_B2,
1662 (3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1663 AR_PHY_TPC_6_ERROR_EST_MODE);
1664
1665 /*
1666 * enable temperature compensation
1667 * Need to use register names
1668 */
1669 if (frequency < 4000)
1670 tempSlope = eep->modalHeader2G.tempSlope;
1671 else
1672 tempSlope = eep->modalHeader5G.tempSlope;
1673
1674 REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
1675 REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
1676 temperature[0]);
1677
1678 return 0;
1679 }
1680
1681 /* Apply the recorded correction values. */
1682 static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
1683 {
1684 int ichain, ipier, npier;
1685 int mode;
1686 int lfrequency[AR9300_MAX_CHAINS],
1687 lcorrection[AR9300_MAX_CHAINS],
1688 ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
1689 int hfrequency[AR9300_MAX_CHAINS],
1690 hcorrection[AR9300_MAX_CHAINS],
1691 htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
1692 int fdiff;
1693 int correction[AR9300_MAX_CHAINS],
1694 voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
1695 int pfrequency, pcorrection, ptemperature, pvoltage;
1696 struct ath_common *common = ath9k_hw_common(ah);
1697
1698 mode = (frequency >= 4000);
1699 if (mode)
1700 npier = AR9300_NUM_5G_CAL_PIERS;
1701 else
1702 npier = AR9300_NUM_2G_CAL_PIERS;
1703
1704 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1705 lfrequency[ichain] = 0;
1706 hfrequency[ichain] = 100000;
1707 }
1708 /* identify best lower and higher frequency calibration measurement */
1709 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1710 for (ipier = 0; ipier < npier; ipier++) {
1711 if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
1712 &pfrequency, &pcorrection,
1713 &ptemperature, &pvoltage)) {
1714 fdiff = frequency - pfrequency;
1715
1716 /*
1717 * this measurement is higher than
1718 * our desired frequency
1719 */
1720 if (fdiff <= 0) {
1721 if (hfrequency[ichain] <= 0 ||
1722 hfrequency[ichain] >= 100000 ||
1723 fdiff >
1724 (frequency - hfrequency[ichain])) {
1725 /*
1726 * new best higher
1727 * frequency measurement
1728 */
1729 hfrequency[ichain] = pfrequency;
1730 hcorrection[ichain] =
1731 pcorrection;
1732 htemperature[ichain] =
1733 ptemperature;
1734 hvoltage[ichain] = pvoltage;
1735 }
1736 }
1737 if (fdiff >= 0) {
1738 if (lfrequency[ichain] <= 0
1739 || fdiff <
1740 (frequency - lfrequency[ichain])) {
1741 /*
1742 * new best lower
1743 * frequency measurement
1744 */
1745 lfrequency[ichain] = pfrequency;
1746 lcorrection[ichain] =
1747 pcorrection;
1748 ltemperature[ichain] =
1749 ptemperature;
1750 lvoltage[ichain] = pvoltage;
1751 }
1752 }
1753 }
1754 }
1755 }
1756
1757 /* interpolate */
1758 for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1759 ath_print(common, ATH_DBG_EEPROM,
1760 "ch=%d f=%d low=%d %d h=%d %d\n",
1761 ichain, frequency, lfrequency[ichain],
1762 lcorrection[ichain], hfrequency[ichain],
1763 hcorrection[ichain]);
1764 /* they're the same, so just pick one */
1765 if (hfrequency[ichain] == lfrequency[ichain]) {
1766 correction[ichain] = lcorrection[ichain];
1767 voltage[ichain] = lvoltage[ichain];
1768 temperature[ichain] = ltemperature[ichain];
1769 }
1770 /* the low frequency is good */
1771 else if (frequency - lfrequency[ichain] < 1000) {
1772 /* so is the high frequency, interpolate */
1773 if (hfrequency[ichain] - frequency < 1000) {
1774
1775 correction[ichain] = lcorrection[ichain] +
1776 (((frequency - lfrequency[ichain]) *
1777 (hcorrection[ichain] -
1778 lcorrection[ichain])) /
1779 (hfrequency[ichain] - lfrequency[ichain]));
1780
1781 temperature[ichain] = ltemperature[ichain] +
1782 (((frequency - lfrequency[ichain]) *
1783 (htemperature[ichain] -
1784 ltemperature[ichain])) /
1785 (hfrequency[ichain] - lfrequency[ichain]));
1786
1787 voltage[ichain] =
1788 lvoltage[ichain] +
1789 (((frequency -
1790 lfrequency[ichain]) * (hvoltage[ichain] -
1791 lvoltage[ichain]))
1792 / (hfrequency[ichain] -
1793 lfrequency[ichain]));
1794 }
1795 /* only low is good, use it */
1796 else {
1797 correction[ichain] = lcorrection[ichain];
1798 temperature[ichain] = ltemperature[ichain];
1799 voltage[ichain] = lvoltage[ichain];
1800 }
1801 }
1802 /* only high is good, use it */
1803 else if (hfrequency[ichain] - frequency < 1000) {
1804 correction[ichain] = hcorrection[ichain];
1805 temperature[ichain] = htemperature[ichain];
1806 voltage[ichain] = hvoltage[ichain];
1807 } else { /* nothing is good, presume 0???? */
1808 correction[ichain] = 0;
1809 temperature[ichain] = 0;
1810 voltage[ichain] = 0;
1811 }
1812 }
1813
1814 ar9003_hw_power_control_override(ah, frequency, correction, voltage,
1815 temperature);
1816
1817 ath_print(common, ATH_DBG_EEPROM,
1818 "for frequency=%d, calibration correction = %d %d %d\n",
1819 frequency, correction[0], correction[1], correction[2]);
1820
1821 return 0;
1822 }
1823
1824 static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
1825 int idx,
1826 int edge,
1827 bool is2GHz)
1828 {
1829 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
1830 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
1831
1832 if (is2GHz)
1833 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
1834 else
1835 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
1836 }
1837
1838 static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
1839 int idx,
1840 unsigned int edge,
1841 u16 freq,
1842 bool is2GHz)
1843 {
1844 struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
1845 struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
1846
1847 u8 *ctl_freqbin = is2GHz ?
1848 &eep->ctl_freqbin_2G[idx][0] :
1849 &eep->ctl_freqbin_5G[idx][0];
1850
1851 if (is2GHz) {
1852 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
1853 CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
1854 return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
1855 } else {
1856 if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
1857 CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
1858 return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
1859 }
1860
1861 return AR9300_MAX_RATE_POWER;
1862 }
1863
1864 /*
1865 * Find the maximum conformance test limit for the given channel and CTL info
1866 */
1867 static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
1868 u16 freq, int idx, bool is2GHz)
1869 {
1870 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
1871 u8 *ctl_freqbin = is2GHz ?
1872 &eep->ctl_freqbin_2G[idx][0] :
1873 &eep->ctl_freqbin_5G[idx][0];
1874 u16 num_edges = is2GHz ?
1875 AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
1876 unsigned int edge;
1877
1878 /* Get the edge power */
1879 for (edge = 0;
1880 (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
1881 edge++) {
1882 /*
1883 * If there's an exact channel match or an inband flag set
1884 * on the lower channel use the given rdEdgePower
1885 */
1886 if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
1887 twiceMaxEdgePower =
1888 ar9003_hw_get_direct_edge_power(eep, idx,
1889 edge, is2GHz);
1890 break;
1891 } else if ((edge > 0) &&
1892 (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
1893 is2GHz))) {
1894 twiceMaxEdgePower =
1895 ar9003_hw_get_indirect_edge_power(eep, idx,
1896 edge, freq,
1897 is2GHz);
1898 /*
1899 * Leave loop - no more affecting edges possible in
1900 * this monotonic increasing list
1901 */
1902 break;
1903 }
1904 }
1905 return twiceMaxEdgePower;
1906 }
1907
1908 static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
1909 struct ath9k_channel *chan,
1910 u8 *pPwrArray, u16 cfgCtl,
1911 u8 twiceAntennaReduction,
1912 u8 twiceMaxRegulatoryPower,
1913 u16 powerLimit)
1914 {
1915 struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1916 struct ath_common *common = ath9k_hw_common(ah);
1917 struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
1918 u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
1919 static const u16 tpScaleReductionTable[5] = {
1920 0, 3, 6, 9, AR9300_MAX_RATE_POWER
1921 };
1922 int i;
1923 int16_t twiceLargestAntenna;
1924 u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
1925 u16 ctlModesFor11a[] = {
1926 CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1927 };
1928 u16 ctlModesFor11g[] = {
1929 CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
1930 CTL_11G_EXT, CTL_2GHT40
1931 };
1932 u16 numCtlModes, *pCtlMode, ctlMode, freq;
1933 struct chan_centers centers;
1934 u8 *ctlIndex;
1935 u8 ctlNum;
1936 u16 twiceMinEdgePower;
1937 bool is2ghz = IS_CHAN_2GHZ(chan);
1938
1939 ath9k_hw_get_channel_centers(ah, chan, &centers);
1940
1941 /* Compute TxPower reduction due to Antenna Gain */
1942 if (is2ghz)
1943 twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
1944 else
1945 twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
1946
1947 twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
1948 twiceLargestAntenna, 0);
1949
1950 /*
1951 * scaledPower is the minimum of the user input power level
1952 * and the regulatory allowed power level
1953 */
1954 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1955
1956 if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
1957 maxRegAllowedPower -=
1958 (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
1959 }
1960
1961 scaledPower = min(powerLimit, maxRegAllowedPower);
1962
1963 /*
1964 * Reduce scaled Power by number of chains active to get
1965 * to per chain tx power level
1966 */
1967 switch (ar5416_get_ntxchains(ah->txchainmask)) {
1968 case 1:
1969 break;
1970 case 2:
1971 scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
1972 break;
1973 case 3:
1974 scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
1975 break;
1976 }
1977
1978 scaledPower = max((u16)0, scaledPower);
1979
1980 /*
1981 * Get target powers from EEPROM - our baseline for TX Power
1982 */
1983 if (is2ghz) {
1984 /* Setup for CTL modes */
1985 /* CTL_11B, CTL_11G, CTL_2GHT20 */
1986 numCtlModes =
1987 ARRAY_SIZE(ctlModesFor11g) -
1988 SUB_NUM_CTL_MODES_AT_2G_40;
1989 pCtlMode = ctlModesFor11g;
1990 if (IS_CHAN_HT40(chan))
1991 /* All 2G CTL's */
1992 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1993 } else {
1994 /* Setup for CTL modes */
1995 /* CTL_11A, CTL_5GHT20 */
1996 numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1997 SUB_NUM_CTL_MODES_AT_5G_40;
1998 pCtlMode = ctlModesFor11a;
1999 if (IS_CHAN_HT40(chan))
2000 /* All 5G CTL's */
2001 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
2002 }
2003
2004 /*
2005 * For MIMO, need to apply regulatory caps individually across
2006 * dynamically running modes: CCK, OFDM, HT20, HT40
2007 *
2008 * The outer loop walks through each possible applicable runtime mode.
2009 * The inner loop walks through each ctlIndex entry in EEPROM.
2010 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
2011 */
2012 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
2013 bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
2014 (pCtlMode[ctlMode] == CTL_2GHT40);
2015 if (isHt40CtlMode)
2016 freq = centers.synth_center;
2017 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
2018 freq = centers.ext_center;
2019 else
2020 freq = centers.ctl_center;
2021
2022 ath_print(common, ATH_DBG_REGULATORY,
2023 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
2024 "EXT_ADDITIVE %d\n",
2025 ctlMode, numCtlModes, isHt40CtlMode,
2026 (pCtlMode[ctlMode] & EXT_ADDITIVE));
2027
2028 /* walk through each CTL index stored in EEPROM */
2029 if (is2ghz) {
2030 ctlIndex = pEepData->ctlIndex_2G;
2031 ctlNum = AR9300_NUM_CTLS_2G;
2032 } else {
2033 ctlIndex = pEepData->ctlIndex_5G;
2034 ctlNum = AR9300_NUM_CTLS_5G;
2035 }
2036
2037 for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
2038 ath_print(common, ATH_DBG_REGULATORY,
2039 "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
2040 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
2041 "chan %dn",
2042 i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
2043 chan->channel);
2044
2045 /*
2046 * compare test group from regulatory
2047 * channel list with test mode from pCtlMode
2048 * list
2049 */
2050 if ((((cfgCtl & ~CTL_MODE_M) |
2051 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2052 ctlIndex[i]) ||
2053 (((cfgCtl & ~CTL_MODE_M) |
2054 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2055 ((ctlIndex[i] & CTL_MODE_M) |
2056 SD_NO_CTL))) {
2057 twiceMinEdgePower =
2058 ar9003_hw_get_max_edge_power(pEepData,
2059 freq, i,
2060 is2ghz);
2061
2062 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
2063 /*
2064 * Find the minimum of all CTL
2065 * edge powers that apply to
2066 * this channel
2067 */
2068 twiceMaxEdgePower =
2069 min(twiceMaxEdgePower,
2070 twiceMinEdgePower);
2071 else {
2072 /* specific */
2073 twiceMaxEdgePower =
2074 twiceMinEdgePower;
2075 break;
2076 }
2077 }
2078 }
2079
2080 minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
2081
2082 ath_print(common, ATH_DBG_REGULATORY,
2083 "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d "
2084 "sP %d minCtlPwr %d\n",
2085 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
2086 scaledPower, minCtlPower);
2087
2088 /* Apply ctl mode to correct target power set */
2089 switch (pCtlMode[ctlMode]) {
2090 case CTL_11B:
2091 for (i = ALL_TARGET_LEGACY_1L_5L;
2092 i <= ALL_TARGET_LEGACY_11S; i++)
2093 pPwrArray[i] =
2094 (u8)min((u16)pPwrArray[i],
2095 minCtlPower);
2096 break;
2097 case CTL_11A:
2098 case CTL_11G:
2099 for (i = ALL_TARGET_LEGACY_6_24;
2100 i <= ALL_TARGET_LEGACY_54; i++)
2101 pPwrArray[i] =
2102 (u8)min((u16)pPwrArray[i],
2103 minCtlPower);
2104 break;
2105 case CTL_5GHT20:
2106 case CTL_2GHT20:
2107 for (i = ALL_TARGET_HT20_0_8_16;
2108 i <= ALL_TARGET_HT20_21; i++)
2109 pPwrArray[i] =
2110 (u8)min((u16)pPwrArray[i],
2111 minCtlPower);
2112 pPwrArray[ALL_TARGET_HT20_22] =
2113 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
2114 minCtlPower);
2115 pPwrArray[ALL_TARGET_HT20_23] =
2116 (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
2117 minCtlPower);
2118 break;
2119 case CTL_5GHT40:
2120 case CTL_2GHT40:
2121 for (i = ALL_TARGET_HT40_0_8_16;
2122 i <= ALL_TARGET_HT40_23; i++)
2123 pPwrArray[i] =
2124 (u8)min((u16)pPwrArray[i],
2125 minCtlPower);
2126 break;
2127 default:
2128 break;
2129 }
2130 } /* end ctl mode checking */
2131 }
2132
2133 static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
2134 struct ath9k_channel *chan, u16 cfgCtl,
2135 u8 twiceAntennaReduction,
2136 u8 twiceMaxRegulatoryPower,
2137 u8 powerLimit)
2138 {
2139 struct ath_common *common = ath9k_hw_common(ah);
2140 u8 targetPowerValT2[ar9300RateSize];
2141 unsigned int i = 0;
2142
2143 ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
2144 ar9003_hw_set_power_per_rate_table(ah, chan,
2145 targetPowerValT2, cfgCtl,
2146 twiceAntennaReduction,
2147 twiceMaxRegulatoryPower,
2148 powerLimit);
2149
2150 while (i < ar9300RateSize) {
2151 ath_print(common, ATH_DBG_EEPROM,
2152 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2153 i++;
2154 ath_print(common, ATH_DBG_EEPROM,
2155 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2156 i++;
2157 ath_print(common, ATH_DBG_EEPROM,
2158 "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2159 i++;
2160 ath_print(common, ATH_DBG_EEPROM,
2161 "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]);
2162 i++;
2163 }
2164
2165 /* Write target power array to registers */
2166 ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
2167
2168 /*
2169 * This is the TX power we send back to driver core,
2170 * and it can use to pass to userspace to display our
2171 * currently configured TX power setting.
2172 *
2173 * Since power is rate dependent, use one of the indices
2174 * from the AR9300_Rates enum to select an entry from
2175 * targetPowerValT2[] to report. Currently returns the
2176 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
2177 * as CCK power is less interesting (?).
2178 */
2179 i = ALL_TARGET_LEGACY_6_24; /* legacy */
2180 if (IS_CHAN_HT40(chan))
2181 i = ALL_TARGET_HT40_0_8_16; /* ht40 */
2182 else if (IS_CHAN_HT20(chan))
2183 i = ALL_TARGET_HT20_0_8_16; /* ht20 */
2184
2185 ah->txpower_limit = targetPowerValT2[i];
2186
2187 ar9003_hw_calibration_apply(ah, chan->channel);
2188 }
2189
2190 static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
2191 u16 i, bool is2GHz)
2192 {
2193 return AR_NO_SPUR;
2194 }
2195
2196 s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
2197 {
2198 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2199
2200 return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
2201 }
2202
2203 s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
2204 {
2205 struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2206
2207 return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
2208 }
2209
2210 const struct eeprom_ops eep_ar9300_ops = {
2211 .check_eeprom = ath9k_hw_ar9300_check_eeprom,
2212 .get_eeprom = ath9k_hw_ar9300_get_eeprom,
2213 .fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
2214 .get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
2215 .get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
2216 .get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
2217 .get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
2218 .set_board_values = ath9k_hw_ar9300_set_board_values,
2219 .set_addac = ath9k_hw_ar9300_set_addac,
2220 .set_txpower = ath9k_hw_ar9300_set_txpower,
2221 .get_spur_channel = ath9k_hw_ar9300_get_spur_channel
2222 };