• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/net/wireless/ath/ath9k/
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 (0x300)
26#define AR_CH0_TOP_XPABIASLVL_S (8)
27
28#define AR_CH0_THERM (0x00016290)
29#define AR_CH0_THERM_XPABIASLVL_MSB 0x3
30#define AR_CH0_THERM_XPABIASLVL_MSB_S 0
31#define AR_CH0_THERM_XPASHORT2GND 0x4
32#define AR_CH0_THERM_XPASHORT2GND_S 2
33
34#define AR_SWITCH_TABLE_COM_ALL (0xffff)
35#define AR_SWITCH_TABLE_COM_ALL_S (0)
36
37#define AR_SWITCH_TABLE_COM2_ALL (0xffffff)
38#define AR_SWITCH_TABLE_COM2_ALL_S (0)
39
40#define AR_SWITCH_TABLE_ALL (0xfff)
41#define AR_SWITCH_TABLE_ALL_S (0)
42
43#define LE16(x) __constant_cpu_to_le16(x)
44#define LE32(x) __constant_cpu_to_le32(x)
45
46/* Local defines to distinguish between extension and control CTL's */
47#define EXT_ADDITIVE (0x8000)
48#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
49#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
50#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
51#define REDUCE_SCALED_POWER_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
52#define REDUCE_SCALED_POWER_BY_THREE_CHAIN   9  /* 10*log10(3)*2 */
53#define PWRINCR_3_TO_1_CHAIN      9             /* 10*log(3)*2 */
54#define PWRINCR_3_TO_2_CHAIN      3             /* floor(10*log(3/2)*2) */
55#define PWRINCR_2_TO_1_CHAIN      6             /* 10*log(2)*2 */
56
57#define SUB_NUM_CTL_MODES_AT_5G_40 2    /* excluding HT40, EXT-OFDM */
58#define SUB_NUM_CTL_MODES_AT_2G_40 3    /* excluding HT40, EXT-OFDM, EXT-CCK */
59
60#define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6))
61
62static const struct ar9300_eeprom ar9300_default = {
63	.eepromVersion = 2,
64	.templateVersion = 2,
65	.macAddr = {1, 2, 3, 4, 5, 6},
66	.custData = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
67		     0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
68	.baseEepHeader = {
69		.regDmn = { LE16(0), LE16(0x1f) },
70		.txrxMask =  0x77, /* 4 bits tx and 4 bits rx */
71		.opCapFlags = {
72			.opFlags = AR9300_OPFLAGS_11G | AR9300_OPFLAGS_11A,
73			.eepMisc = 0,
74		},
75		.rfSilent = 0,
76		.blueToothOptions = 0,
77		.deviceCap = 0,
78		.deviceType = 5, /* takes lower byte in eeprom location */
79		.pwrTableOffset = AR9300_PWR_TABLE_OFFSET,
80		.params_for_tuning_caps = {0, 0},
81		.featureEnable = 0x0c,
82		 /*
83		  * bit0 - enable tx temp comp - disabled
84		  * bit1 - enable tx volt comp - disabled
85		  * bit2 - enable fastClock - enabled
86		  * bit3 - enable doubling - enabled
87		  * bit4 - enable internal regulator - disabled
88		  * bit5 - enable pa predistortion - disabled
89		  */
90		.miscConfiguration = 0, /* bit0 - turn down drivestrength */
91		.eepromWriteEnableGpio = 3,
92		.wlanDisableGpio = 0,
93		.wlanLedGpio = 8,
94		.rxBandSelectGpio = 0xff,
95		.txrxgain = 0,
96		.swreg = 0,
97	 },
98	.modalHeader2G = {
99	/* ar9300_modal_eep_header  2g */
100		/* 4 idle,t1,t2,b(4 bits per setting) */
101		.antCtrlCommon = LE32(0x110),
102		/* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
103		.antCtrlCommon2 = LE32(0x22222),
104
105		/*
106		 * antCtrlChain[AR9300_MAX_CHAINS]; 6 idle, t, r,
107		 * rx1, rx12, b (2 bits each)
108		 */
109		.antCtrlChain = { LE16(0x150), LE16(0x150), LE16(0x150) },
110
111		/*
112		 * xatten1DB[AR9300_MAX_CHAINS];  3 xatten1_db
113		 * for ar9280 (0xa20c/b20c 5:0)
114		 */
115		.xatten1DB = {0, 0, 0},
116
117		/*
118		 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
119		 * for ar9280 (0xa20c/b20c 16:12
120		 */
121		.xatten1Margin = {0, 0, 0},
122		.tempSlope = 36,
123		.voltSlope = 0,
124
125		/*
126		 * spurChans[OSPREY_EEPROM_MODAL_SPURS]; spur
127		 * channels in usual fbin coding format
128		 */
129		.spurChans = {0, 0, 0, 0, 0},
130
131		/*
132		 * noiseFloorThreshCh[AR9300_MAX_CHAINS]; 3 Check
133		 * if the register is per chain
134		 */
135		.noiseFloorThreshCh = {-1, 0, 0},
136		.ob = {1, 1, 1},/* 3 chain */
137		.db_stage2 = {1, 1, 1}, /* 3 chain  */
138		.db_stage3 = {0, 0, 0},
139		.db_stage4 = {0, 0, 0},
140		.xpaBiasLvl = 0,
141		.txFrameToDataStart = 0x0e,
142		.txFrameToPaOn = 0x0e,
143		.txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
144		.antennaGain = 0,
145		.switchSettling = 0x2c,
146		.adcDesiredSize = -30,
147		.txEndToXpaOff = 0,
148		.txEndToRxOn = 0x2,
149		.txFrameToXpaOn = 0xe,
150		.thresh62 = 28,
151		.papdRateMaskHt20 = LE32(0x80c080),
152		.papdRateMaskHt40 = LE32(0x80c080),
153		.futureModal = {
154			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
155			0, 0, 0, 0, 0, 0, 0, 0
156		},
157	 },
158	.calFreqPier2G = {
159		FREQ2FBIN(2412, 1),
160		FREQ2FBIN(2437, 1),
161		FREQ2FBIN(2472, 1),
162	 },
163	/* ar9300_cal_data_per_freq_op_loop 2g */
164	.calPierData2G = {
165		{ {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
166		{ {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
167		{ {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0} },
168	 },
169	.calTarget_freqbin_Cck = {
170		FREQ2FBIN(2412, 1),
171		FREQ2FBIN(2484, 1),
172	 },
173	.calTarget_freqbin_2G = {
174		FREQ2FBIN(2412, 1),
175		FREQ2FBIN(2437, 1),
176		FREQ2FBIN(2472, 1)
177	 },
178	.calTarget_freqbin_2GHT20 = {
179		FREQ2FBIN(2412, 1),
180		FREQ2FBIN(2437, 1),
181		FREQ2FBIN(2472, 1)
182	 },
183	.calTarget_freqbin_2GHT40 = {
184		FREQ2FBIN(2412, 1),
185		FREQ2FBIN(2437, 1),
186		FREQ2FBIN(2472, 1)
187	 },
188	.calTargetPowerCck = {
189		 /* 1L-5L,5S,11L,11S */
190		 { {36, 36, 36, 36} },
191		 { {36, 36, 36, 36} },
192	},
193	.calTargetPower2G = {
194		 /* 6-24,36,48,54 */
195		 { {32, 32, 28, 24} },
196		 { {32, 32, 28, 24} },
197		 { {32, 32, 28, 24} },
198	},
199	.calTargetPower2GHT20 = {
200		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
201		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
202		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
203	},
204	.calTargetPower2GHT40 = {
205		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
206		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
207		{ {32, 32, 32, 32, 28, 20, 32, 32, 28, 20, 32, 32, 28, 20} },
208	},
209	.ctlIndex_2G =  {
210		0x11, 0x12, 0x15, 0x17, 0x41, 0x42,
211		0x45, 0x47, 0x31, 0x32, 0x35, 0x37,
212	},
213	.ctl_freqbin_2G = {
214		{
215			FREQ2FBIN(2412, 1),
216			FREQ2FBIN(2417, 1),
217			FREQ2FBIN(2457, 1),
218			FREQ2FBIN(2462, 1)
219		},
220		{
221			FREQ2FBIN(2412, 1),
222			FREQ2FBIN(2417, 1),
223			FREQ2FBIN(2462, 1),
224			0xFF,
225		},
226
227		{
228			FREQ2FBIN(2412, 1),
229			FREQ2FBIN(2417, 1),
230			FREQ2FBIN(2462, 1),
231			0xFF,
232		},
233		{
234			FREQ2FBIN(2422, 1),
235			FREQ2FBIN(2427, 1),
236			FREQ2FBIN(2447, 1),
237			FREQ2FBIN(2452, 1)
238		},
239
240		{
241			/* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
242			/* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
243			/* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
244			/* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(2484, 1),
245		},
246
247		{
248			/* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
249			/* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
250			/* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
251			0,
252		},
253
254		{
255			/* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
256			/* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
257			FREQ2FBIN(2472, 1),
258			0,
259		},
260
261		{
262			/* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
263			/* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
264			/* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
265			/* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(2462, 1),
266		},
267
268		{
269			/* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
270			/* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
271			/* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
272		},
273
274		{
275			/* Data[9].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
276			/* Data[9].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
277			/* Data[9].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
278			0
279		},
280
281		{
282			/* Data[10].ctlEdges[0].bChannel */ FREQ2FBIN(2412, 1),
283			/* Data[10].ctlEdges[1].bChannel */ FREQ2FBIN(2417, 1),
284			/* Data[10].ctlEdges[2].bChannel */ FREQ2FBIN(2472, 1),
285			0
286		},
287
288		{
289			/* Data[11].ctlEdges[0].bChannel */ FREQ2FBIN(2422, 1),
290			/* Data[11].ctlEdges[1].bChannel */ FREQ2FBIN(2427, 1),
291			/* Data[11].ctlEdges[2].bChannel */ FREQ2FBIN(2447, 1),
292			/* Data[11].ctlEdges[3].bChannel */
293			FREQ2FBIN(2462, 1),
294		}
295	 },
296	.ctlPowerData_2G = {
297		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
298		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
299		 { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } },
300
301		 { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } },
302		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
303		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
304
305		 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } },
306		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
307		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
308
309		 { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } },
310		 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
311		 { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } },
312	 },
313	.modalHeader5G = {
314		/* 4 idle,t1,t2,b (4 bits per setting) */
315		.antCtrlCommon = LE32(0x110),
316		/* 4 ra1l1, ra2l1, ra1l2,ra2l2,ra12 */
317		.antCtrlCommon2 = LE32(0x22222),
318		 /* antCtrlChain 6 idle, t,r,rx1,rx12,b (2 bits each) */
319		.antCtrlChain = {
320			LE16(0x000), LE16(0x000), LE16(0x000),
321		},
322		 /* xatten1DB 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
323		.xatten1DB = {0, 0, 0},
324
325		/*
326		 * xatten1Margin[AR9300_MAX_CHAINS]; 3 xatten1_margin
327		 * for merlin (0xa20c/b20c 16:12
328		 */
329		.xatten1Margin = {0, 0, 0},
330		.tempSlope = 68,
331		.voltSlope = 0,
332		/* spurChans spur channels in usual fbin coding format */
333		.spurChans = {0, 0, 0, 0, 0},
334		/* noiseFloorThreshCh Check if the register is per chain */
335		.noiseFloorThreshCh = {-1, 0, 0},
336		.ob = {3, 3, 3}, /* 3 chain */
337		.db_stage2 = {3, 3, 3}, /* 3 chain */
338		.db_stage3 = {3, 3, 3}, /* doesn't exist for 2G */
339		.db_stage4 = {3, 3, 3},	 /* don't exist for 2G */
340		.xpaBiasLvl = 0,
341		.txFrameToDataStart = 0x0e,
342		.txFrameToPaOn = 0x0e,
343		.txClip = 3, /* 4 bits tx_clip, 4 bits dac_scale_cck */
344		.antennaGain = 0,
345		.switchSettling = 0x2d,
346		.adcDesiredSize = -30,
347		.txEndToXpaOff = 0,
348		.txEndToRxOn = 0x2,
349		.txFrameToXpaOn = 0xe,
350		.thresh62 = 28,
351		.papdRateMaskHt20 = LE32(0xf0e0e0),
352		.papdRateMaskHt40 = LE32(0xf0e0e0),
353		.futureModal = {
354			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
355			0, 0, 0, 0, 0, 0, 0, 0
356		},
357	 },
358	.calFreqPier5G = {
359		FREQ2FBIN(5180, 0),
360		FREQ2FBIN(5220, 0),
361		FREQ2FBIN(5320, 0),
362		FREQ2FBIN(5400, 0),
363		FREQ2FBIN(5500, 0),
364		FREQ2FBIN(5600, 0),
365		FREQ2FBIN(5725, 0),
366		FREQ2FBIN(5825, 0)
367	},
368	.calPierData5G = {
369			{
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				{0, 0, 0, 0, 0},
377				{0, 0, 0, 0, 0},
378			},
379			{
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				{0, 0, 0, 0, 0},
387				{0, 0, 0, 0, 0},
388			},
389			{
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				{0, 0, 0, 0, 0},
397				{0, 0, 0, 0, 0},
398			},
399
400	},
401	.calTarget_freqbin_5G = {
402		FREQ2FBIN(5180, 0),
403		FREQ2FBIN(5220, 0),
404		FREQ2FBIN(5320, 0),
405		FREQ2FBIN(5400, 0),
406		FREQ2FBIN(5500, 0),
407		FREQ2FBIN(5600, 0),
408		FREQ2FBIN(5725, 0),
409		FREQ2FBIN(5825, 0)
410	},
411	.calTarget_freqbin_5GHT20 = {
412		FREQ2FBIN(5180, 0),
413		FREQ2FBIN(5240, 0),
414		FREQ2FBIN(5320, 0),
415		FREQ2FBIN(5500, 0),
416		FREQ2FBIN(5700, 0),
417		FREQ2FBIN(5745, 0),
418		FREQ2FBIN(5725, 0),
419		FREQ2FBIN(5825, 0)
420	},
421	.calTarget_freqbin_5GHT40 = {
422		FREQ2FBIN(5180, 0),
423		FREQ2FBIN(5240, 0),
424		FREQ2FBIN(5320, 0),
425		FREQ2FBIN(5500, 0),
426		FREQ2FBIN(5700, 0),
427		FREQ2FBIN(5745, 0),
428		FREQ2FBIN(5725, 0),
429		FREQ2FBIN(5825, 0)
430	 },
431	.calTargetPower5G = {
432		/* 6-24,36,48,54 */
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		{ {20, 20, 20, 10} },
440		{ {20, 20, 20, 10} },
441	 },
442	.calTargetPower5GHT20 = {
443		/*
444		 * 0_8_16,1-3_9-11_17-19,
445		 * 4,5,6,7,12,13,14,15,20,21,22,23
446		 */
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		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
454		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
455	 },
456	.calTargetPower5GHT40 =  {
457		/*
458		 * 0_8_16,1-3_9-11_17-19,
459		 * 4,5,6,7,12,13,14,15,20,21,22,23
460		 */
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		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
468		{ {20, 20, 10, 10, 0, 0, 10, 10, 0, 0, 10, 10, 0, 0} },
469	 },
470	.ctlIndex_5G =  {
471		0x10, 0x16, 0x18, 0x40, 0x46,
472		0x48, 0x30, 0x36, 0x38
473	},
474	.ctl_freqbin_5G =  {
475		{
476			/* Data[0].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
477			/* Data[0].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
478			/* Data[0].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
479			/* Data[0].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
480			/* Data[0].ctlEdges[4].bChannel */ FREQ2FBIN(5600, 0),
481			/* Data[0].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
482			/* Data[0].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
483			/* Data[0].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
484		},
485		{
486			/* Data[1].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
487			/* Data[1].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
488			/* Data[1].ctlEdges[2].bChannel */ FREQ2FBIN(5280, 0),
489			/* Data[1].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
490			/* Data[1].ctlEdges[4].bChannel */ FREQ2FBIN(5520, 0),
491			/* Data[1].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
492			/* Data[1].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
493			/* Data[1].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
494		},
495
496		{
497			/* Data[2].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
498			/* Data[2].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
499			/* Data[2].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
500			/* Data[2].ctlEdges[3].bChannel */ FREQ2FBIN(5310, 0),
501			/* Data[2].ctlEdges[4].bChannel */ FREQ2FBIN(5510, 0),
502			/* Data[2].ctlEdges[5].bChannel */ FREQ2FBIN(5550, 0),
503			/* Data[2].ctlEdges[6].bChannel */ FREQ2FBIN(5670, 0),
504			/* Data[2].ctlEdges[7].bChannel */ FREQ2FBIN(5755, 0)
505		},
506
507		{
508			/* Data[3].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
509			/* Data[3].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
510			/* Data[3].ctlEdges[2].bChannel */ FREQ2FBIN(5260, 0),
511			/* Data[3].ctlEdges[3].bChannel */ FREQ2FBIN(5320, 0),
512			/* Data[3].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
513			/* Data[3].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
514			/* Data[3].ctlEdges[6].bChannel */ 0xFF,
515			/* Data[3].ctlEdges[7].bChannel */ 0xFF,
516		},
517
518		{
519			/* Data[4].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
520			/* Data[4].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
521			/* Data[4].ctlEdges[2].bChannel */ FREQ2FBIN(5500, 0),
522			/* Data[4].ctlEdges[3].bChannel */ FREQ2FBIN(5700, 0),
523			/* Data[4].ctlEdges[4].bChannel */ 0xFF,
524			/* Data[4].ctlEdges[5].bChannel */ 0xFF,
525			/* Data[4].ctlEdges[6].bChannel */ 0xFF,
526			/* Data[4].ctlEdges[7].bChannel */ 0xFF,
527		},
528
529		{
530			/* Data[5].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
531			/* Data[5].ctlEdges[1].bChannel */ FREQ2FBIN(5270, 0),
532			/* Data[5].ctlEdges[2].bChannel */ FREQ2FBIN(5310, 0),
533			/* Data[5].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
534			/* Data[5].ctlEdges[4].bChannel */ FREQ2FBIN(5590, 0),
535			/* Data[5].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
536			/* Data[5].ctlEdges[6].bChannel */ 0xFF,
537			/* Data[5].ctlEdges[7].bChannel */ 0xFF
538		},
539
540		{
541			/* Data[6].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
542			/* Data[6].ctlEdges[1].bChannel */ FREQ2FBIN(5200, 0),
543			/* Data[6].ctlEdges[2].bChannel */ FREQ2FBIN(5220, 0),
544			/* Data[6].ctlEdges[3].bChannel */ FREQ2FBIN(5260, 0),
545			/* Data[6].ctlEdges[4].bChannel */ FREQ2FBIN(5500, 0),
546			/* Data[6].ctlEdges[5].bChannel */ FREQ2FBIN(5600, 0),
547			/* Data[6].ctlEdges[6].bChannel */ FREQ2FBIN(5700, 0),
548			/* Data[6].ctlEdges[7].bChannel */ FREQ2FBIN(5745, 0)
549		},
550
551		{
552			/* Data[7].ctlEdges[0].bChannel */ FREQ2FBIN(5180, 0),
553			/* Data[7].ctlEdges[1].bChannel */ FREQ2FBIN(5260, 0),
554			/* Data[7].ctlEdges[2].bChannel */ FREQ2FBIN(5320, 0),
555			/* Data[7].ctlEdges[3].bChannel */ FREQ2FBIN(5500, 0),
556			/* Data[7].ctlEdges[4].bChannel */ FREQ2FBIN(5560, 0),
557			/* Data[7].ctlEdges[5].bChannel */ FREQ2FBIN(5700, 0),
558			/* Data[7].ctlEdges[6].bChannel */ FREQ2FBIN(5745, 0),
559			/* Data[7].ctlEdges[7].bChannel */ FREQ2FBIN(5825, 0)
560		},
561
562		{
563			/* Data[8].ctlEdges[0].bChannel */ FREQ2FBIN(5190, 0),
564			/* Data[8].ctlEdges[1].bChannel */ FREQ2FBIN(5230, 0),
565			/* Data[8].ctlEdges[2].bChannel */ FREQ2FBIN(5270, 0),
566			/* Data[8].ctlEdges[3].bChannel */ FREQ2FBIN(5510, 0),
567			/* Data[8].ctlEdges[4].bChannel */ FREQ2FBIN(5550, 0),
568			/* Data[8].ctlEdges[5].bChannel */ FREQ2FBIN(5670, 0),
569			/* Data[8].ctlEdges[6].bChannel */ FREQ2FBIN(5755, 0),
570			/* Data[8].ctlEdges[7].bChannel */ FREQ2FBIN(5795, 0)
571		}
572	 },
573	.ctlPowerData_5G = {
574		{
575			{
576				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
577				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
578			}
579		},
580		{
581			{
582				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
583				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
584			}
585		},
586		{
587			{
588				CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1),
589				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
590			}
591		},
592		{
593			{
594				CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0),
595				CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
596			}
597		},
598		{
599			{
600				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
601				CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0),
602			}
603		},
604		{
605			{
606				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
607				CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0),
608			}
609		},
610		{
611			{
612				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
613				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1),
614			}
615		},
616		{
617			{
618				CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
619				CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0),
620			}
621		},
622		{
623			{
624				CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1),
625				CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1),
626			}
627		},
628	 }
629};
630
631static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
632{
633	if (fbin == AR9300_BCHAN_UNUSED)
634		return fbin;
635
636	return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
637}
638
639static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
640{
641	return 0;
642}
643
644static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah,
645				      enum eeprom_param param)
646{
647	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
648	struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader;
649
650	switch (param) {
651	case EEP_MAC_LSW:
652		return eep->macAddr[0] << 8 | eep->macAddr[1];
653	case EEP_MAC_MID:
654		return eep->macAddr[2] << 8 | eep->macAddr[3];
655	case EEP_MAC_MSW:
656		return eep->macAddr[4] << 8 | eep->macAddr[5];
657	case EEP_REG_0:
658		return le16_to_cpu(pBase->regDmn[0]);
659	case EEP_REG_1:
660		return le16_to_cpu(pBase->regDmn[1]);
661	case EEP_OP_CAP:
662		return pBase->deviceCap;
663	case EEP_OP_MODE:
664		return pBase->opCapFlags.opFlags;
665	case EEP_RF_SILENT:
666		return pBase->rfSilent;
667	case EEP_TX_MASK:
668		return (pBase->txrxMask >> 4) & 0xf;
669	case EEP_RX_MASK:
670		return pBase->txrxMask & 0xf;
671	case EEP_DRIVE_STRENGTH:
672#define AR9300_EEP_BASE_DRIV_STRENGTH	0x1
673		return pBase->miscConfiguration & AR9300_EEP_BASE_DRIV_STRENGTH;
674	case EEP_INTERNAL_REGULATOR:
675		/* Bit 4 is internal regulator flag */
676		return (pBase->featureEnable & 0x10) >> 4;
677	case EEP_SWREG:
678		return le32_to_cpu(pBase->swreg);
679	case EEP_PAPRD:
680		return !!(pBase->featureEnable & BIT(5));
681	default:
682		return 0;
683	}
684}
685
686static bool ar9300_eeprom_read_byte(struct ath_common *common, int address,
687				    u8 *buffer)
688{
689	u16 val;
690
691	if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
692		return false;
693
694	*buffer = (val >> (8 * (address % 2))) & 0xff;
695	return true;
696}
697
698static bool ar9300_eeprom_read_word(struct ath_common *common, int address,
699				    u8 *buffer)
700{
701	u16 val;
702
703	if (unlikely(!ath9k_hw_nvram_read(common, address / 2, &val)))
704		return false;
705
706	buffer[0] = val >> 8;
707	buffer[1] = val & 0xff;
708
709	return true;
710}
711
712static bool ar9300_read_eeprom(struct ath_hw *ah, int address, u8 *buffer,
713			       int count)
714{
715	struct ath_common *common = ath9k_hw_common(ah);
716	int i;
717
718	if ((address < 0) || ((address + count) / 2 > AR9300_EEPROM_SIZE - 1)) {
719		ath_print(common, ATH_DBG_EEPROM,
720			  "eeprom address not in range\n");
721		return false;
722	}
723
724	/*
725	 * Since we're reading the bytes in reverse order from a little-endian
726	 * word stream, an even address means we only use the lower half of
727	 * the 16-bit word at that address
728	 */
729	if (address % 2 == 0) {
730		if (!ar9300_eeprom_read_byte(common, address--, buffer++))
731			goto error;
732
733		count--;
734	}
735
736	for (i = 0; i < count / 2; i++) {
737		if (!ar9300_eeprom_read_word(common, address, buffer))
738			goto error;
739
740		address -= 2;
741		buffer += 2;
742	}
743
744	if (count % 2)
745		if (!ar9300_eeprom_read_byte(common, address, buffer))
746			goto error;
747
748	return true;
749
750error:
751	ath_print(common, ATH_DBG_EEPROM,
752		  "unable to read eeprom region at offset %d\n", address);
753	return false;
754}
755
756static void ar9300_comp_hdr_unpack(u8 *best, int *code, int *reference,
757				   int *length, int *major, int *minor)
758{
759	unsigned long value[4];
760
761	value[0] = best[0];
762	value[1] = best[1];
763	value[2] = best[2];
764	value[3] = best[3];
765	*code = ((value[0] >> 5) & 0x0007);
766	*reference = (value[0] & 0x001f) | ((value[1] >> 2) & 0x0020);
767	*length = ((value[1] << 4) & 0x07f0) | ((value[2] >> 4) & 0x000f);
768	*major = (value[2] & 0x000f);
769	*minor = (value[3] & 0x00ff);
770}
771
772static u16 ar9300_comp_cksum(u8 *data, int dsize)
773{
774	int it, checksum = 0;
775
776	for (it = 0; it < dsize; it++) {
777		checksum += data[it];
778		checksum &= 0xffff;
779	}
780
781	return checksum;
782}
783
784static bool ar9300_uncompress_block(struct ath_hw *ah,
785				    u8 *mptr,
786				    int mdataSize,
787				    u8 *block,
788				    int size)
789{
790	int it;
791	int spot;
792	int offset;
793	int length;
794	struct ath_common *common = ath9k_hw_common(ah);
795
796	spot = 0;
797
798	for (it = 0; it < size; it += (length+2)) {
799		offset = block[it];
800		offset &= 0xff;
801		spot += offset;
802		length = block[it+1];
803		length &= 0xff;
804
805		if (length > 0 && spot >= 0 && spot+length <= mdataSize) {
806			ath_print(common, ATH_DBG_EEPROM,
807				  "Restore at %d: spot=%d "
808				  "offset=%d length=%d\n",
809				   it, spot, offset, length);
810			memcpy(&mptr[spot], &block[it+2], length);
811			spot += length;
812		} else if (length > 0) {
813			ath_print(common, ATH_DBG_EEPROM,
814				  "Bad restore at %d: spot=%d "
815				  "offset=%d length=%d\n",
816				  it, spot, offset, length);
817			return false;
818		}
819	}
820	return true;
821}
822
823static int ar9300_compress_decision(struct ath_hw *ah,
824				    int it,
825				    int code,
826				    int reference,
827				    u8 *mptr,
828				    u8 *word, int length, int mdata_size)
829{
830	struct ath_common *common = ath9k_hw_common(ah);
831	u8 *dptr;
832
833	switch (code) {
834	case _CompressNone:
835		if (length != mdata_size) {
836			ath_print(common, ATH_DBG_EEPROM,
837				  "EEPROM structure size mismatch"
838				  "memory=%d eeprom=%d\n", mdata_size, length);
839			return -1;
840		}
841		memcpy(mptr, (u8 *) (word + COMP_HDR_LEN), length);
842		ath_print(common, ATH_DBG_EEPROM, "restored eeprom %d:"
843			  " uncompressed, length %d\n", it, length);
844		break;
845	case _CompressBlock:
846		if (reference == 0) {
847			dptr = mptr;
848		} else {
849			if (reference != 2) {
850				ath_print(common, ATH_DBG_EEPROM,
851					  "cant find reference eeprom"
852					  "struct %d\n", reference);
853				return -1;
854			}
855			memcpy(mptr, &ar9300_default, mdata_size);
856		}
857		ath_print(common, ATH_DBG_EEPROM,
858			  "restore eeprom %d: block, reference %d,"
859			  " length %d\n", it, reference, length);
860		ar9300_uncompress_block(ah, mptr, mdata_size,
861					(u8 *) (word + COMP_HDR_LEN), length);
862		break;
863	default:
864		ath_print(common, ATH_DBG_EEPROM, "unknown compression"
865			  " code %d\n", code);
866		return -1;
867	}
868	return 0;
869}
870
871/*
872 * Read the configuration data from the eeprom.
873 * The data can be put in any specified memory buffer.
874 *
875 * Returns -1 on error.
876 * Returns address of next memory location on success.
877 */
878static int ar9300_eeprom_restore_internal(struct ath_hw *ah,
879					  u8 *mptr, int mdata_size)
880{
881#define MDEFAULT 15
882#define MSTATE 100
883	int cptr;
884	u8 *word;
885	int code;
886	int reference, length, major, minor;
887	int osize;
888	int it;
889	u16 checksum, mchecksum;
890	struct ath_common *common = ath9k_hw_common(ah);
891
892	word = kzalloc(2048, GFP_KERNEL);
893	if (!word)
894		return -1;
895
896	memcpy(mptr, &ar9300_default, mdata_size);
897
898	cptr = AR9300_BASE_ADDR;
899	for (it = 0; it < MSTATE; it++) {
900		if (!ar9300_read_eeprom(ah, cptr, word, COMP_HDR_LEN))
901			goto fail;
902
903		if ((word[0] == 0 && word[1] == 0 && word[2] == 0 &&
904		     word[3] == 0) || (word[0] == 0xff && word[1] == 0xff
905				       && word[2] == 0xff && word[3] == 0xff))
906			break;
907
908		ar9300_comp_hdr_unpack(word, &code, &reference,
909				       &length, &major, &minor);
910		ath_print(common, ATH_DBG_EEPROM,
911			  "Found block at %x: code=%d ref=%d"
912			  "length=%d major=%d minor=%d\n", cptr, code,
913			  reference, length, major, minor);
914		if (length >= 1024) {
915			ath_print(common, ATH_DBG_EEPROM,
916				  "Skipping bad header\n");
917			cptr -= COMP_HDR_LEN;
918			continue;
919		}
920
921		osize = length;
922		ar9300_read_eeprom(ah, cptr, word,
923				   COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
924		checksum = ar9300_comp_cksum(&word[COMP_HDR_LEN], length);
925		mchecksum = word[COMP_HDR_LEN + osize] |
926		    (word[COMP_HDR_LEN + osize + 1] << 8);
927		ath_print(common, ATH_DBG_EEPROM,
928			  "checksum %x %x\n", checksum, mchecksum);
929		if (checksum == mchecksum) {
930			ar9300_compress_decision(ah, it, code, reference, mptr,
931						 word, length, mdata_size);
932		} else {
933			ath_print(common, ATH_DBG_EEPROM,
934				  "skipping block with bad checksum\n");
935		}
936		cptr -= (COMP_HDR_LEN + osize + COMP_CKSUM_LEN);
937	}
938
939	kfree(word);
940	return cptr;
941
942fail:
943	kfree(word);
944	return -1;
945}
946
947/*
948 * Restore the configuration structure by reading the eeprom.
949 * This function destroys any existing in-memory structure
950 * content.
951 */
952static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah)
953{
954	u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep;
955
956	if (ar9300_eeprom_restore_internal(ah, mptr,
957			sizeof(struct ar9300_eeprom)) < 0)
958		return false;
959
960	return true;
961}
962
963static int ath9k_hw_ar9300_get_eeprom_ver(struct ath_hw *ah)
964{
965	return ah->eeprom.ar9300_eep.eepromVersion;
966}
967
968static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah)
969{
970	return 0;
971}
972
973static u8 ath9k_hw_ar9300_get_num_ant_config(struct ath_hw *ah,
974					     enum ieee80211_band freq_band)
975{
976	return 1;
977}
978
979static u32 ath9k_hw_ar9300_get_eeprom_antenna_cfg(struct ath_hw *ah,
980						  struct ath9k_channel *chan)
981{
982	return -EINVAL;
983}
984
985static 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
995static 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);
999	REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB, bias >> 2);
1000	REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
1001}
1002
1003static 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
1015static 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
1027static 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
1044static 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
1062static 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
1103static 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
1128static 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
1137static 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 */
1151static 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
1205static 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
1240static 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
1276static 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
1312static 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 */
1338static 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
1445static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
1446					      u8 *targetPowerValT2)
1447{
1448	u8 ht40PowerIncForPdadc = 0;
1449	bool is2GHz = false;
1450	unsigned int i = 0;
1451	struct ath_common *common = ath9k_hw_common(ah);
1452
1453	if (freq < 4000)
1454		is2GHz = true;
1455
1456	targetPowerValT2[ALL_TARGET_LEGACY_6_24] =
1457	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_6_24, freq,
1458					 is2GHz);
1459	targetPowerValT2[ALL_TARGET_LEGACY_36] =
1460	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_36, freq,
1461					 is2GHz);
1462	targetPowerValT2[ALL_TARGET_LEGACY_48] =
1463	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_48, freq,
1464					 is2GHz);
1465	targetPowerValT2[ALL_TARGET_LEGACY_54] =
1466	    ar9003_hw_eeprom_get_tgt_pwr(ah, LEGACY_TARGET_RATE_54, freq,
1467					 is2GHz);
1468	targetPowerValT2[ALL_TARGET_LEGACY_1L_5L] =
1469	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_1L_5L,
1470					     freq);
1471	targetPowerValT2[ALL_TARGET_LEGACY_5S] =
1472	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_5S, freq);
1473	targetPowerValT2[ALL_TARGET_LEGACY_11L] =
1474	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11L, freq);
1475	targetPowerValT2[ALL_TARGET_LEGACY_11S] =
1476	    ar9003_hw_eeprom_get_cck_tgt_pwr(ah, LEGACY_TARGET_RATE_11S, freq);
1477	targetPowerValT2[ALL_TARGET_HT20_0_8_16] =
1478	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1479					      is2GHz);
1480	targetPowerValT2[ALL_TARGET_HT20_1_3_9_11_17_19] =
1481	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1482					      freq, is2GHz);
1483	targetPowerValT2[ALL_TARGET_HT20_4] =
1484	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1485					      is2GHz);
1486	targetPowerValT2[ALL_TARGET_HT20_5] =
1487	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1488					      is2GHz);
1489	targetPowerValT2[ALL_TARGET_HT20_6] =
1490	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1491					      is2GHz);
1492	targetPowerValT2[ALL_TARGET_HT20_7] =
1493	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1494					      is2GHz);
1495	targetPowerValT2[ALL_TARGET_HT20_12] =
1496	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1497					      is2GHz);
1498	targetPowerValT2[ALL_TARGET_HT20_13] =
1499	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1500					      is2GHz);
1501	targetPowerValT2[ALL_TARGET_HT20_14] =
1502	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1503					      is2GHz);
1504	targetPowerValT2[ALL_TARGET_HT20_15] =
1505	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1506					      is2GHz);
1507	targetPowerValT2[ALL_TARGET_HT20_20] =
1508	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1509					      is2GHz);
1510	targetPowerValT2[ALL_TARGET_HT20_21] =
1511	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1512					      is2GHz);
1513	targetPowerValT2[ALL_TARGET_HT20_22] =
1514	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1515					      is2GHz);
1516	targetPowerValT2[ALL_TARGET_HT20_23] =
1517	    ar9003_hw_eeprom_get_ht20_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1518					      is2GHz);
1519	targetPowerValT2[ALL_TARGET_HT40_0_8_16] =
1520	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_0_8_16, freq,
1521					      is2GHz) + ht40PowerIncForPdadc;
1522	targetPowerValT2[ALL_TARGET_HT40_1_3_9_11_17_19] =
1523	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_1_3_9_11_17_19,
1524					      freq,
1525					      is2GHz) + ht40PowerIncForPdadc;
1526	targetPowerValT2[ALL_TARGET_HT40_4] =
1527	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_4, freq,
1528					      is2GHz) + ht40PowerIncForPdadc;
1529	targetPowerValT2[ALL_TARGET_HT40_5] =
1530	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_5, freq,
1531					      is2GHz) + ht40PowerIncForPdadc;
1532	targetPowerValT2[ALL_TARGET_HT40_6] =
1533	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_6, freq,
1534					      is2GHz) + ht40PowerIncForPdadc;
1535	targetPowerValT2[ALL_TARGET_HT40_7] =
1536	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_7, freq,
1537					      is2GHz) + ht40PowerIncForPdadc;
1538	targetPowerValT2[ALL_TARGET_HT40_12] =
1539	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_12, freq,
1540					      is2GHz) + ht40PowerIncForPdadc;
1541	targetPowerValT2[ALL_TARGET_HT40_13] =
1542	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_13, freq,
1543					      is2GHz) + ht40PowerIncForPdadc;
1544	targetPowerValT2[ALL_TARGET_HT40_14] =
1545	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_14, freq,
1546					      is2GHz) + ht40PowerIncForPdadc;
1547	targetPowerValT2[ALL_TARGET_HT40_15] =
1548	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_15, freq,
1549					      is2GHz) + ht40PowerIncForPdadc;
1550	targetPowerValT2[ALL_TARGET_HT40_20] =
1551	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_20, freq,
1552					      is2GHz) + ht40PowerIncForPdadc;
1553	targetPowerValT2[ALL_TARGET_HT40_21] =
1554	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_21, freq,
1555					      is2GHz) + ht40PowerIncForPdadc;
1556	targetPowerValT2[ALL_TARGET_HT40_22] =
1557	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_22, freq,
1558					      is2GHz) + ht40PowerIncForPdadc;
1559	targetPowerValT2[ALL_TARGET_HT40_23] =
1560	    ar9003_hw_eeprom_get_ht40_tgt_pwr(ah, HT_TARGET_RATE_23, freq,
1561					      is2GHz) + ht40PowerIncForPdadc;
1562
1563	while (i < ar9300RateSize) {
1564		ath_print(common, ATH_DBG_EEPROM,
1565			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1566		i++;
1567
1568		ath_print(common, ATH_DBG_EEPROM,
1569			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1570		i++;
1571
1572		ath_print(common, ATH_DBG_EEPROM,
1573			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
1574		i++;
1575
1576		ath_print(common, ATH_DBG_EEPROM,
1577			  "TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
1578		i++;
1579	}
1580}
1581
1582static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
1583				  int mode,
1584				  int ipier,
1585				  int ichain,
1586				  int *pfrequency,
1587				  int *pcorrection,
1588				  int *ptemperature, int *pvoltage)
1589{
1590	u8 *pCalPier;
1591	struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
1592	int is2GHz;
1593	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1594	struct ath_common *common = ath9k_hw_common(ah);
1595
1596	if (ichain >= AR9300_MAX_CHAINS) {
1597		ath_print(common, ATH_DBG_EEPROM,
1598			  "Invalid chain index, must be less than %d\n",
1599			  AR9300_MAX_CHAINS);
1600		return -1;
1601	}
1602
1603	if (mode) {		/* 5GHz */
1604		if (ipier >= AR9300_NUM_5G_CAL_PIERS) {
1605			ath_print(common, ATH_DBG_EEPROM,
1606				  "Invalid 5GHz cal pier index, must "
1607				  "be less than %d\n",
1608				  AR9300_NUM_5G_CAL_PIERS);
1609			return -1;
1610		}
1611		pCalPier = &(eep->calFreqPier5G[ipier]);
1612		pCalPierStruct = &(eep->calPierData5G[ichain][ipier]);
1613		is2GHz = 0;
1614	} else {
1615		if (ipier >= AR9300_NUM_2G_CAL_PIERS) {
1616			ath_print(common, ATH_DBG_EEPROM,
1617				  "Invalid 2GHz cal pier index, must "
1618				  "be less than %d\n", AR9300_NUM_2G_CAL_PIERS);
1619			return -1;
1620		}
1621
1622		pCalPier = &(eep->calFreqPier2G[ipier]);
1623		pCalPierStruct = &(eep->calPierData2G[ichain][ipier]);
1624		is2GHz = 1;
1625	}
1626
1627	*pfrequency = FBIN2FREQ(*pCalPier, is2GHz);
1628	*pcorrection = pCalPierStruct->refPower;
1629	*ptemperature = pCalPierStruct->tempMeas;
1630	*pvoltage = pCalPierStruct->voltMeas;
1631
1632	return 0;
1633}
1634
1635static int ar9003_hw_power_control_override(struct ath_hw *ah,
1636					    int frequency,
1637					    int *correction,
1638					    int *voltage, int *temperature)
1639{
1640	int tempSlope = 0;
1641	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
1642
1643	REG_RMW(ah, AR_PHY_TPC_11_B0,
1644		(correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1645		AR_PHY_TPC_OLPC_GAIN_DELTA);
1646	REG_RMW(ah, AR_PHY_TPC_11_B1,
1647		(correction[1] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1648		AR_PHY_TPC_OLPC_GAIN_DELTA);
1649	REG_RMW(ah, AR_PHY_TPC_11_B2,
1650		(correction[2] << AR_PHY_TPC_OLPC_GAIN_DELTA_S),
1651		AR_PHY_TPC_OLPC_GAIN_DELTA);
1652
1653	/* enable open loop power control on chip */
1654	REG_RMW(ah, AR_PHY_TPC_6_B0,
1655		(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1656		AR_PHY_TPC_6_ERROR_EST_MODE);
1657	REG_RMW(ah, AR_PHY_TPC_6_B1,
1658		(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1659		AR_PHY_TPC_6_ERROR_EST_MODE);
1660	REG_RMW(ah, AR_PHY_TPC_6_B2,
1661		(3 << AR_PHY_TPC_6_ERROR_EST_MODE_S),
1662		AR_PHY_TPC_6_ERROR_EST_MODE);
1663
1664	/*
1665	 * enable temperature compensation
1666	 * Need to use register names
1667	 */
1668	if (frequency < 4000)
1669		tempSlope = eep->modalHeader2G.tempSlope;
1670	else
1671		tempSlope = eep->modalHeader5G.tempSlope;
1672
1673	REG_RMW_FIELD(ah, AR_PHY_TPC_19, AR_PHY_TPC_19_ALPHA_THERM, tempSlope);
1674	REG_RMW_FIELD(ah, AR_PHY_TPC_18, AR_PHY_TPC_18_THERM_CAL_VALUE,
1675		      temperature[0]);
1676
1677	return 0;
1678}
1679
1680/* Apply the recorded correction values. */
1681static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
1682{
1683	int ichain, ipier, npier;
1684	int mode;
1685	int lfrequency[AR9300_MAX_CHAINS],
1686	    lcorrection[AR9300_MAX_CHAINS],
1687	    ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS];
1688	int hfrequency[AR9300_MAX_CHAINS],
1689	    hcorrection[AR9300_MAX_CHAINS],
1690	    htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS];
1691	int fdiff;
1692	int correction[AR9300_MAX_CHAINS],
1693	    voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS];
1694	int pfrequency, pcorrection, ptemperature, pvoltage;
1695	struct ath_common *common = ath9k_hw_common(ah);
1696
1697	mode = (frequency >= 4000);
1698	if (mode)
1699		npier = AR9300_NUM_5G_CAL_PIERS;
1700	else
1701		npier = AR9300_NUM_2G_CAL_PIERS;
1702
1703	for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1704		lfrequency[ichain] = 0;
1705		hfrequency[ichain] = 100000;
1706	}
1707	/* identify best lower and higher frequency calibration measurement */
1708	for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1709		for (ipier = 0; ipier < npier; ipier++) {
1710			if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
1711						    &pfrequency, &pcorrection,
1712						    &ptemperature, &pvoltage)) {
1713				fdiff = frequency - pfrequency;
1714
1715				/*
1716				 * this measurement is higher than
1717				 * our desired frequency
1718				 */
1719				if (fdiff <= 0) {
1720					if (hfrequency[ichain] <= 0 ||
1721					    hfrequency[ichain] >= 100000 ||
1722					    fdiff >
1723					    (frequency - hfrequency[ichain])) {
1724						/*
1725						 * new best higher
1726						 * frequency measurement
1727						 */
1728						hfrequency[ichain] = pfrequency;
1729						hcorrection[ichain] =
1730						    pcorrection;
1731						htemperature[ichain] =
1732						    ptemperature;
1733						hvoltage[ichain] = pvoltage;
1734					}
1735				}
1736				if (fdiff >= 0) {
1737					if (lfrequency[ichain] <= 0
1738					    || fdiff <
1739					    (frequency - lfrequency[ichain])) {
1740						/*
1741						 * new best lower
1742						 * frequency measurement
1743						 */
1744						lfrequency[ichain] = pfrequency;
1745						lcorrection[ichain] =
1746						    pcorrection;
1747						ltemperature[ichain] =
1748						    ptemperature;
1749						lvoltage[ichain] = pvoltage;
1750					}
1751				}
1752			}
1753		}
1754	}
1755
1756	/* interpolate  */
1757	for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
1758		ath_print(common, ATH_DBG_EEPROM,
1759			  "ch=%d f=%d low=%d %d h=%d %d\n",
1760			  ichain, frequency, lfrequency[ichain],
1761			  lcorrection[ichain], hfrequency[ichain],
1762			  hcorrection[ichain]);
1763		/* they're the same, so just pick one */
1764		if (hfrequency[ichain] == lfrequency[ichain]) {
1765			correction[ichain] = lcorrection[ichain];
1766			voltage[ichain] = lvoltage[ichain];
1767			temperature[ichain] = ltemperature[ichain];
1768		}
1769		/* the low frequency is good */
1770		else if (frequency - lfrequency[ichain] < 1000) {
1771			/* so is the high frequency, interpolate */
1772			if (hfrequency[ichain] - frequency < 1000) {
1773
1774				correction[ichain] = lcorrection[ichain] +
1775				    (((frequency - lfrequency[ichain]) *
1776				      (hcorrection[ichain] -
1777				       lcorrection[ichain])) /
1778				     (hfrequency[ichain] - lfrequency[ichain]));
1779
1780				temperature[ichain] = ltemperature[ichain] +
1781				    (((frequency - lfrequency[ichain]) *
1782				      (htemperature[ichain] -
1783				       ltemperature[ichain])) /
1784				     (hfrequency[ichain] - lfrequency[ichain]));
1785
1786				voltage[ichain] =
1787				    lvoltage[ichain] +
1788				    (((frequency -
1789				       lfrequency[ichain]) * (hvoltage[ichain] -
1790							      lvoltage[ichain]))
1791				     / (hfrequency[ichain] -
1792					lfrequency[ichain]));
1793			}
1794			/* only low is good, use it */
1795			else {
1796				correction[ichain] = lcorrection[ichain];
1797				temperature[ichain] = ltemperature[ichain];
1798				voltage[ichain] = lvoltage[ichain];
1799			}
1800		}
1801		/* only high is good, use it */
1802		else if (hfrequency[ichain] - frequency < 1000) {
1803			correction[ichain] = hcorrection[ichain];
1804			temperature[ichain] = htemperature[ichain];
1805			voltage[ichain] = hvoltage[ichain];
1806		} else {	/* nothing is good, presume 0???? */
1807			correction[ichain] = 0;
1808			temperature[ichain] = 0;
1809			voltage[ichain] = 0;
1810		}
1811	}
1812
1813	ar9003_hw_power_control_override(ah, frequency, correction, voltage,
1814					 temperature);
1815
1816	ath_print(common, ATH_DBG_EEPROM,
1817		  "for frequency=%d, calibration correction = %d %d %d\n",
1818		  frequency, correction[0], correction[1], correction[2]);
1819
1820	return 0;
1821}
1822
1823static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
1824					   int idx,
1825					   int edge,
1826					   bool is2GHz)
1827{
1828	struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
1829	struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
1830
1831	if (is2GHz)
1832		return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]);
1833	else
1834		return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]);
1835}
1836
1837static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
1838					     int idx,
1839					     unsigned int edge,
1840					     u16 freq,
1841					     bool is2GHz)
1842{
1843	struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
1844	struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
1845
1846	u8 *ctl_freqbin = is2GHz ?
1847		&eep->ctl_freqbin_2G[idx][0] :
1848		&eep->ctl_freqbin_5G[idx][0];
1849
1850	if (is2GHz) {
1851		if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
1852		    CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1]))
1853			return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]);
1854	} else {
1855		if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
1856		    CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1]))
1857			return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]);
1858	}
1859
1860	return AR9300_MAX_RATE_POWER;
1861}
1862
1863/*
1864 * Find the maximum conformance test limit for the given channel and CTL info
1865 */
1866static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
1867					u16 freq, int idx, bool is2GHz)
1868{
1869	u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
1870	u8 *ctl_freqbin = is2GHz ?
1871		&eep->ctl_freqbin_2G[idx][0] :
1872		&eep->ctl_freqbin_5G[idx][0];
1873	u16 num_edges = is2GHz ?
1874		AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
1875	unsigned int edge;
1876
1877	/* Get the edge power */
1878	for (edge = 0;
1879	     (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
1880	     edge++) {
1881		/*
1882		 * If there's an exact channel match or an inband flag set
1883		 * on the lower channel use the given rdEdgePower
1884		 */
1885		if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
1886			twiceMaxEdgePower =
1887				ar9003_hw_get_direct_edge_power(eep, idx,
1888								edge, is2GHz);
1889			break;
1890		} else if ((edge > 0) &&
1891			   (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
1892						      is2GHz))) {
1893			twiceMaxEdgePower =
1894				ar9003_hw_get_indirect_edge_power(eep, idx,
1895								  edge, freq,
1896								  is2GHz);
1897			/*
1898			 * Leave loop - no more affecting edges possible in
1899			 * this monotonic increasing list
1900			 */
1901			break;
1902		}
1903	}
1904	return twiceMaxEdgePower;
1905}
1906
1907static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
1908					       struct ath9k_channel *chan,
1909					       u8 *pPwrArray, u16 cfgCtl,
1910					       u8 twiceAntennaReduction,
1911					       u8 twiceMaxRegulatoryPower,
1912					       u16 powerLimit)
1913{
1914	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
1915	struct ath_common *common = ath9k_hw_common(ah);
1916	struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
1917	u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
1918	static const u16 tpScaleReductionTable[5] = {
1919		0, 3, 6, 9, AR9300_MAX_RATE_POWER
1920	};
1921	int i;
1922	int16_t  twiceLargestAntenna;
1923	u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
1924	u16 ctlModesFor11a[] = {
1925		CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
1926	};
1927	u16 ctlModesFor11g[] = {
1928		CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
1929		CTL_11G_EXT, CTL_2GHT40
1930	};
1931	u16 numCtlModes, *pCtlMode, ctlMode, freq;
1932	struct chan_centers centers;
1933	u8 *ctlIndex;
1934	u8 ctlNum;
1935	u16 twiceMinEdgePower;
1936	bool is2ghz = IS_CHAN_2GHZ(chan);
1937
1938	ath9k_hw_get_channel_centers(ah, chan, &centers);
1939
1940	/* Compute TxPower reduction due to Antenna Gain */
1941	if (is2ghz)
1942		twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
1943	else
1944		twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
1945
1946	twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
1947				twiceLargestAntenna, 0);
1948
1949	/*
1950	 * scaledPower is the minimum of the user input power level
1951	 * and the regulatory allowed power level
1952	 */
1953	maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
1954
1955	if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
1956		maxRegAllowedPower -=
1957			(tpScaleReductionTable[(regulatory->tp_scale)] * 2);
1958	}
1959
1960	scaledPower = min(powerLimit, maxRegAllowedPower);
1961
1962	/*
1963	 * Reduce scaled Power by number of chains active to get
1964	 * to per chain tx power level
1965	 */
1966	switch (ar5416_get_ntxchains(ah->txchainmask)) {
1967	case 1:
1968		break;
1969	case 2:
1970		scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
1971		break;
1972	case 3:
1973		scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
1974		break;
1975	}
1976
1977	scaledPower = max((u16)0, scaledPower);
1978
1979	/*
1980	 * Get target powers from EEPROM - our baseline for TX Power
1981	 */
1982	if (is2ghz) {
1983		/* Setup for CTL modes */
1984		/* CTL_11B, CTL_11G, CTL_2GHT20 */
1985		numCtlModes =
1986			ARRAY_SIZE(ctlModesFor11g) -
1987				   SUB_NUM_CTL_MODES_AT_2G_40;
1988		pCtlMode = ctlModesFor11g;
1989		if (IS_CHAN_HT40(chan))
1990			/* All 2G CTL's */
1991			numCtlModes = ARRAY_SIZE(ctlModesFor11g);
1992	} else {
1993		/* Setup for CTL modes */
1994		/* CTL_11A, CTL_5GHT20 */
1995		numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
1996					 SUB_NUM_CTL_MODES_AT_5G_40;
1997		pCtlMode = ctlModesFor11a;
1998		if (IS_CHAN_HT40(chan))
1999			/* All 5G CTL's */
2000			numCtlModes = ARRAY_SIZE(ctlModesFor11a);
2001	}
2002
2003	/*
2004	 * For MIMO, need to apply regulatory caps individually across
2005	 * dynamically running modes: CCK, OFDM, HT20, HT40
2006	 *
2007	 * The outer loop walks through each possible applicable runtime mode.
2008	 * The inner loop walks through each ctlIndex entry in EEPROM.
2009	 * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
2010	 */
2011	for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
2012		bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
2013			(pCtlMode[ctlMode] == CTL_2GHT40);
2014		if (isHt40CtlMode)
2015			freq = centers.synth_center;
2016		else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
2017			freq = centers.ext_center;
2018		else
2019			freq = centers.ctl_center;
2020
2021		ath_print(common, ATH_DBG_REGULATORY,
2022			  "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
2023			  "EXT_ADDITIVE %d\n",
2024			  ctlMode, numCtlModes, isHt40CtlMode,
2025			  (pCtlMode[ctlMode] & EXT_ADDITIVE));
2026
2027		/* walk through each CTL index stored in EEPROM */
2028		if (is2ghz) {
2029			ctlIndex = pEepData->ctlIndex_2G;
2030			ctlNum = AR9300_NUM_CTLS_2G;
2031		} else {
2032			ctlIndex = pEepData->ctlIndex_5G;
2033			ctlNum = AR9300_NUM_CTLS_5G;
2034		}
2035
2036		for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
2037			ath_print(common, ATH_DBG_REGULATORY,
2038				  "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
2039				  "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
2040				  "chan %dn",
2041				  i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
2042				  chan->channel);
2043
2044				/*
2045				 * compare test group from regulatory
2046				 * channel list with test mode from pCtlMode
2047				 * list
2048				 */
2049				if ((((cfgCtl & ~CTL_MODE_M) |
2050				       (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2051					ctlIndex[i]) ||
2052				    (((cfgCtl & ~CTL_MODE_M) |
2053				       (pCtlMode[ctlMode] & CTL_MODE_M)) ==
2054				     ((ctlIndex[i] & CTL_MODE_M) |
2055				       SD_NO_CTL))) {
2056					twiceMinEdgePower =
2057					  ar9003_hw_get_max_edge_power(pEepData,
2058								       freq, i,
2059								       is2ghz);
2060
2061					if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
2062						/*
2063						 * Find the minimum of all CTL
2064						 * edge powers that apply to
2065						 * this channel
2066						 */
2067						twiceMaxEdgePower =
2068							min(twiceMaxEdgePower,
2069							    twiceMinEdgePower);
2070						else {
2071							/* specific */
2072							twiceMaxEdgePower =
2073							  twiceMinEdgePower;
2074							break;
2075						}
2076				}
2077			}
2078
2079			minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
2080
2081			ath_print(common, ATH_DBG_REGULATORY,
2082				  "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d "
2083				  "sP %d minCtlPwr %d\n",
2084				  ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
2085				  scaledPower, minCtlPower);
2086
2087			/* Apply ctl mode to correct target power set */
2088			switch (pCtlMode[ctlMode]) {
2089			case CTL_11B:
2090				for (i = ALL_TARGET_LEGACY_1L_5L;
2091				     i <= ALL_TARGET_LEGACY_11S; i++)
2092					pPwrArray[i] =
2093					  (u8)min((u16)pPwrArray[i],
2094						  minCtlPower);
2095				break;
2096			case CTL_11A:
2097			case CTL_11G:
2098				for (i = ALL_TARGET_LEGACY_6_24;
2099				     i <= ALL_TARGET_LEGACY_54; i++)
2100					pPwrArray[i] =
2101					  (u8)min((u16)pPwrArray[i],
2102						  minCtlPower);
2103				break;
2104			case CTL_5GHT20:
2105			case CTL_2GHT20:
2106				for (i = ALL_TARGET_HT20_0_8_16;
2107				     i <= ALL_TARGET_HT20_21; i++)
2108					pPwrArray[i] =
2109					  (u8)min((u16)pPwrArray[i],
2110						  minCtlPower);
2111				pPwrArray[ALL_TARGET_HT20_22] =
2112				  (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
2113					  minCtlPower);
2114				pPwrArray[ALL_TARGET_HT20_23] =
2115				  (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
2116					   minCtlPower);
2117				break;
2118			case CTL_5GHT40:
2119			case CTL_2GHT40:
2120				for (i = ALL_TARGET_HT40_0_8_16;
2121				     i <= ALL_TARGET_HT40_23; i++)
2122					pPwrArray[i] =
2123					  (u8)min((u16)pPwrArray[i],
2124						  minCtlPower);
2125				break;
2126			default:
2127			    break;
2128			}
2129	} /* end ctl mode checking */
2130}
2131
2132static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
2133					struct ath9k_channel *chan, u16 cfgCtl,
2134					u8 twiceAntennaReduction,
2135					u8 twiceMaxRegulatoryPower,
2136					u8 powerLimit)
2137{
2138	struct ath_common *common = ath9k_hw_common(ah);
2139	u8 targetPowerValT2[ar9300RateSize];
2140	unsigned int i = 0;
2141
2142	ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
2143	ar9003_hw_set_power_per_rate_table(ah, chan,
2144					   targetPowerValT2, cfgCtl,
2145					   twiceAntennaReduction,
2146					   twiceMaxRegulatoryPower,
2147					   powerLimit);
2148
2149	while (i < ar9300RateSize) {
2150		ath_print(common, ATH_DBG_EEPROM,
2151			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2152		i++;
2153		ath_print(common, ATH_DBG_EEPROM,
2154			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2155		i++;
2156		ath_print(common, ATH_DBG_EEPROM,
2157			  "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
2158		i++;
2159		ath_print(common, ATH_DBG_EEPROM,
2160			  "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]);
2161		i++;
2162	}
2163
2164	/* Write target power array to registers */
2165	ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
2166
2167	/*
2168	 * This is the TX power we send back to driver core,
2169	 * and it can use to pass to userspace to display our
2170	 * currently configured TX power setting.
2171	 *
2172	 * Since power is rate dependent, use one of the indices
2173	 * from the AR9300_Rates enum to select an entry from
2174	 * targetPowerValT2[] to report. Currently returns the
2175	 * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
2176	 * as CCK power is less interesting (?).
2177	 */
2178	i = ALL_TARGET_LEGACY_6_24; /* legacy */
2179	if (IS_CHAN_HT40(chan))
2180		i = ALL_TARGET_HT40_0_8_16; /* ht40 */
2181	else if (IS_CHAN_HT20(chan))
2182		i = ALL_TARGET_HT20_0_8_16; /* ht20 */
2183
2184	ah->txpower_limit = targetPowerValT2[i];
2185
2186	ar9003_hw_calibration_apply(ah, chan->channel);
2187}
2188
2189static u16 ath9k_hw_ar9300_get_spur_channel(struct ath_hw *ah,
2190					    u16 i, bool is2GHz)
2191{
2192	return AR_NO_SPUR;
2193}
2194
2195s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah)
2196{
2197	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2198
2199	return (eep->baseEepHeader.txrxgain >> 4) & 0xf; /* bits 7:4 */
2200}
2201
2202s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah)
2203{
2204	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
2205
2206	return (eep->baseEepHeader.txrxgain) & 0xf; /* bits 3:0 */
2207}
2208
2209const struct eeprom_ops eep_ar9300_ops = {
2210	.check_eeprom = ath9k_hw_ar9300_check_eeprom,
2211	.get_eeprom = ath9k_hw_ar9300_get_eeprom,
2212	.fill_eeprom = ath9k_hw_ar9300_fill_eeprom,
2213	.get_eeprom_ver = ath9k_hw_ar9300_get_eeprom_ver,
2214	.get_eeprom_rev = ath9k_hw_ar9300_get_eeprom_rev,
2215	.get_num_ant_config = ath9k_hw_ar9300_get_num_ant_config,
2216	.get_eeprom_antenna_cfg = ath9k_hw_ar9300_get_eeprom_antenna_cfg,
2217	.set_board_values = ath9k_hw_ar9300_set_board_values,
2218	.set_addac = ath9k_hw_ar9300_set_addac,
2219	.set_txpower = ath9k_hw_ar9300_set_txpower,
2220	.get_spur_channel = ath9k_hw_ar9300_get_spur_channel
2221};
2222