• 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
20static const int firstep_table[] =
21/* level:  0   1   2   3   4   5   6   7   8  */
22	{ -4, -2,  0,  2,  4,  6,  8, 10, 12 }; /* lvl 0-8, default 2 */
23
24static const int cycpwrThr1_table[] =
25/* level:  0   1   2   3   4   5   6   7   8  */
26	{ -6, -4, -2,  0,  2,  4,  6,  8 };     /* lvl 0-7, default 3 */
27
28/*
29 * register values to turn OFDM weak signal detection OFF
30 */
31static const int m1ThreshLow_off = 127;
32static const int m2ThreshLow_off = 127;
33static const int m1Thresh_off = 127;
34static const int m2Thresh_off = 127;
35static const int m2CountThr_off =  31;
36static const int m2CountThrLow_off =  63;
37static const int m1ThreshLowExt_off = 127;
38static const int m2ThreshLowExt_off = 127;
39static const int m1ThreshExt_off = 127;
40static const int m2ThreshExt_off = 127;
41
42/**
43 * ar9003_hw_set_channel - set channel on single-chip device
44 * @ah: atheros hardware structure
45 * @chan:
46 *
47 * This is the function to change channel on single-chip devices, that is
48 * all devices after ar9280.
49 *
50 * This function takes the channel value in MHz and sets
51 * hardware channel value. Assumes writes have been enabled to analog bus.
52 *
53 * Actual Expression,
54 *
55 * For 2GHz channel,
56 * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
57 * (freq_ref = 40MHz)
58 *
59 * For 5GHz channel,
60 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
61 * (freq_ref = 40MHz/(24>>amodeRefSel))
62 *
63 * For 5GHz channels which are 5MHz spaced,
64 * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
65 * (freq_ref = 40MHz)
66 */
67static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
68{
69	u16 bMode, fracMode = 0, aModeRefSel = 0;
70	u32 freq, channelSel = 0, reg32 = 0;
71	struct chan_centers centers;
72	int loadSynthChannel;
73
74	ath9k_hw_get_channel_centers(ah, chan, &centers);
75	freq = centers.synth_center;
76
77	if (freq < 4800) {     /* 2 GHz, fractional mode */
78		channelSel = CHANSEL_2G(freq);
79		/* Set to 2G mode */
80		bMode = 1;
81	} else {
82		channelSel = CHANSEL_5G(freq);
83		/* Doubler is ON, so, divide channelSel by 2. */
84		channelSel >>= 1;
85		/* Set to 5G mode */
86		bMode = 0;
87	}
88
89	/* Enable fractional mode for all channels */
90	fracMode = 1;
91	aModeRefSel = 0;
92	loadSynthChannel = 0;
93
94	reg32 = (bMode << 29);
95	REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
96
97	/* Enable Long shift Select for Synthesizer */
98	REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH4,
99		      AR_PHY_SYNTH4_LONG_SHIFT_SELECT, 1);
100
101	/* Program Synth. setting */
102	reg32 = (channelSel << 2) | (fracMode << 30) |
103		(aModeRefSel << 28) | (loadSynthChannel << 31);
104	REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
105
106	/* Toggle Load Synth channel bit */
107	loadSynthChannel = 1;
108	reg32 = (channelSel << 2) | (fracMode << 30) |
109		(aModeRefSel << 28) | (loadSynthChannel << 31);
110	REG_WRITE(ah, AR_PHY_65NM_CH0_SYNTH7, reg32);
111
112	ah->curchan = chan;
113	ah->curchan_rad_index = -1;
114
115	return 0;
116}
117
118/**
119 * ar9003_hw_spur_mitigate_mrc_cck - convert baseband spur frequency
120 * @ah: atheros hardware structure
121 * @chan:
122 *
123 * For single-chip solutions. Converts to baseband spur frequency given the
124 * input channel frequency and compute register settings below.
125 *
126 * Spur mitigation for MRC CCK
127 */
128static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
129					    struct ath9k_channel *chan)
130{
131	u32 spur_freq[4] = { 2420, 2440, 2464, 2480 };
132	int cur_bb_spur, negative = 0, cck_spur_freq;
133	int i;
134
135	/*
136	 * Need to verify range +/- 10 MHz in control channel, otherwise spur
137	 * is out-of-band and can be ignored.
138	 */
139
140	for (i = 0; i < 4; i++) {
141		negative = 0;
142		cur_bb_spur = spur_freq[i] - chan->channel;
143
144		if (cur_bb_spur < 0) {
145			negative = 1;
146			cur_bb_spur = -cur_bb_spur;
147		}
148		if (cur_bb_spur < 10) {
149			cck_spur_freq = (int)((cur_bb_spur << 19) / 11);
150
151			if (negative == 1)
152				cck_spur_freq = -cck_spur_freq;
153
154			cck_spur_freq = cck_spur_freq & 0xfffff;
155
156			REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
157				      AR_PHY_AGC_CONTROL_YCOK_MAX, 0x7);
158			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
159				      AR_PHY_CCK_SPUR_MIT_SPUR_RSSI_THR, 0x7f);
160			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
161				      AR_PHY_CCK_SPUR_MIT_SPUR_FILTER_TYPE,
162				      0x2);
163			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
164				      AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT,
165				      0x1);
166			REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
167				      AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ,
168				      cck_spur_freq);
169
170			return;
171		}
172	}
173
174	REG_RMW_FIELD(ah, AR_PHY_AGC_CONTROL,
175		      AR_PHY_AGC_CONTROL_YCOK_MAX, 0x5);
176	REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
177		      AR_PHY_CCK_SPUR_MIT_USE_CCK_SPUR_MIT, 0x0);
178	REG_RMW_FIELD(ah, AR_PHY_CCK_SPUR_MIT,
179		      AR_PHY_CCK_SPUR_MIT_CCK_SPUR_FREQ, 0x0);
180}
181
182/* Clean all spur register fields */
183static void ar9003_hw_spur_ofdm_clear(struct ath_hw *ah)
184{
185	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
186		      AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0);
187	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
188		      AR_PHY_TIMING11_SPUR_FREQ_SD, 0);
189	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
190		      AR_PHY_TIMING11_SPUR_DELTA_PHASE, 0);
191	REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
192		      AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, 0);
193	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
194		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0);
195	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
196		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0);
197	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
198		      AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0);
199	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
200		      AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 0);
201	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
202		      AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 0);
203
204	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
205		      AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0);
206	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
207		      AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0);
208	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
209		      AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0);
210	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
211		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, 0);
212	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
213		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, 0);
214	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
215		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, 0);
216	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
217		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0);
218	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
219		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0);
220	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
221		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0);
222	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
223		      AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0);
224}
225
226static void ar9003_hw_spur_ofdm(struct ath_hw *ah,
227				int freq_offset,
228				int spur_freq_sd,
229				int spur_delta_phase,
230				int spur_subchannel_sd)
231{
232	int mask_index = 0;
233
234	/* OFDM Spur mitigation */
235	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
236		 AR_PHY_TIMING4_ENABLE_SPUR_FILTER, 0x1);
237	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
238		      AR_PHY_TIMING11_SPUR_FREQ_SD, spur_freq_sd);
239	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
240		      AR_PHY_TIMING11_SPUR_DELTA_PHASE, spur_delta_phase);
241	REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
242		      AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd);
243	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
244		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1);
245	REG_RMW_FIELD(ah, AR_PHY_TIMING11,
246		      AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1);
247	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
248		      AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1);
249	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
250		      AR_PHY_SPUR_REG_SPUR_RSSI_THRESH, 34);
251	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
252		      AR_PHY_SPUR_REG_EN_VIT_SPUR_RSSI, 1);
253
254	if (REG_READ_FIELD(ah, AR_PHY_MODE,
255			   AR_PHY_MODE_DYNAMIC) == 0x1)
256		REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
257			      AR_PHY_SPUR_REG_ENABLE_NF_RSSI_SPUR_MIT, 1);
258
259	mask_index = (freq_offset << 4) / 5;
260	if (mask_index < 0)
261		mask_index = mask_index - 1;
262
263	mask_index = mask_index & 0x7f;
264
265	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
266		      AR_PHY_SPUR_REG_ENABLE_MASK_PPM, 0x1);
267	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
268		      AR_PHY_TIMING4_ENABLE_PILOT_MASK, 0x1);
269	REG_RMW_FIELD(ah, AR_PHY_TIMING4,
270		      AR_PHY_TIMING4_ENABLE_CHAN_MASK, 0x1);
271	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
272		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A, mask_index);
273	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
274		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, mask_index);
275	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
276		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A, mask_index);
277	REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK,
278		      AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A, 0xc);
279	REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK,
280		      AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A, 0xc);
281	REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_A,
282		      AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0);
283	REG_RMW_FIELD(ah, AR_PHY_SPUR_REG,
284		      AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff);
285}
286
287static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah,
288				     struct ath9k_channel *chan,
289				     int freq_offset)
290{
291	int spur_freq_sd = 0;
292	int spur_subchannel_sd = 0;
293	int spur_delta_phase = 0;
294
295	if (IS_CHAN_HT40(chan)) {
296		if (freq_offset < 0) {
297			if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
298					   AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
299				spur_subchannel_sd = 1;
300			else
301				spur_subchannel_sd = 0;
302
303			spur_freq_sd = ((freq_offset + 10) << 9) / 11;
304
305		} else {
306			if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
307			    AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
308				spur_subchannel_sd = 0;
309			else
310				spur_subchannel_sd = 1;
311
312			spur_freq_sd = ((freq_offset - 10) << 9) / 11;
313
314		}
315
316		spur_delta_phase = (freq_offset << 17) / 5;
317
318	} else {
319		spur_subchannel_sd = 0;
320		spur_freq_sd = (freq_offset << 9) /11;
321		spur_delta_phase = (freq_offset << 18) / 5;
322	}
323
324	spur_freq_sd = spur_freq_sd & 0x3ff;
325	spur_delta_phase = spur_delta_phase & 0xfffff;
326
327	ar9003_hw_spur_ofdm(ah,
328			    freq_offset,
329			    spur_freq_sd,
330			    spur_delta_phase,
331			    spur_subchannel_sd);
332}
333
334/* Spur mitigation for OFDM */
335static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah,
336					 struct ath9k_channel *chan)
337{
338	int synth_freq;
339	int range = 10;
340	int freq_offset = 0;
341	int mode;
342	u8* spurChansPtr;
343	unsigned int i;
344	struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
345
346	if (IS_CHAN_5GHZ(chan)) {
347		spurChansPtr = &(eep->modalHeader5G.spurChans[0]);
348		mode = 0;
349	}
350	else {
351		spurChansPtr = &(eep->modalHeader2G.spurChans[0]);
352		mode = 1;
353	}
354
355	if (spurChansPtr[0] == 0)
356		return; /* No spur in the mode */
357
358	if (IS_CHAN_HT40(chan)) {
359		range = 19;
360		if (REG_READ_FIELD(ah, AR_PHY_GEN_CTRL,
361				   AR_PHY_GC_DYN2040_PRI_CH) == 0x0)
362			synth_freq = chan->channel - 10;
363		else
364			synth_freq = chan->channel + 10;
365	} else {
366		range = 10;
367		synth_freq = chan->channel;
368	}
369
370	ar9003_hw_spur_ofdm_clear(ah);
371
372	for (i = 0; spurChansPtr[i] && i < 5; i++) {
373		freq_offset = FBIN2FREQ(spurChansPtr[i], mode) - synth_freq;
374		if (abs(freq_offset) < range) {
375			ar9003_hw_spur_ofdm_work(ah, chan, freq_offset);
376			break;
377		}
378	}
379}
380
381static void ar9003_hw_spur_mitigate(struct ath_hw *ah,
382				    struct ath9k_channel *chan)
383{
384	ar9003_hw_spur_mitigate_mrc_cck(ah, chan);
385	ar9003_hw_spur_mitigate_ofdm(ah, chan);
386}
387
388static u32 ar9003_hw_compute_pll_control(struct ath_hw *ah,
389					 struct ath9k_channel *chan)
390{
391	u32 pll;
392
393	pll = SM(0x5, AR_RTC_9300_PLL_REFDIV);
394
395	if (chan && IS_CHAN_HALF_RATE(chan))
396		pll |= SM(0x1, AR_RTC_9300_PLL_CLKSEL);
397	else if (chan && IS_CHAN_QUARTER_RATE(chan))
398		pll |= SM(0x2, AR_RTC_9300_PLL_CLKSEL);
399
400	pll |= SM(0x2c, AR_RTC_9300_PLL_DIV);
401
402	return pll;
403}
404
405static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
406				       struct ath9k_channel *chan)
407{
408	u32 phymode;
409	u32 enableDacFifo = 0;
410
411	enableDacFifo =
412		(REG_READ(ah, AR_PHY_GEN_CTRL) & AR_PHY_GC_ENABLE_DAC_FIFO);
413
414	/* Enable 11n HT, 20 MHz */
415	phymode = AR_PHY_GC_HT_EN | AR_PHY_GC_SINGLE_HT_LTF1 | AR_PHY_GC_WALSH |
416		  AR_PHY_GC_SHORT_GI_40 | enableDacFifo;
417
418	/* Configure baseband for dynamic 20/40 operation */
419	if (IS_CHAN_HT40(chan)) {
420		phymode |= AR_PHY_GC_DYN2040_EN;
421		/* Configure control (primary) channel at +-10MHz */
422		if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
423		    (chan->chanmode == CHANNEL_G_HT40PLUS))
424			phymode |= AR_PHY_GC_DYN2040_PRI_CH;
425
426	}
427
428	/* make sure we preserve INI settings */
429	phymode |= REG_READ(ah, AR_PHY_GEN_CTRL);
430	/* turn off Green Field detection for STA for now */
431	phymode &= ~AR_PHY_GC_GF_DETECT_EN;
432
433	REG_WRITE(ah, AR_PHY_GEN_CTRL, phymode);
434
435	/* Configure MAC for 20/40 operation */
436	ath9k_hw_set11nmac2040(ah);
437
438	/* global transmit timeout (25 TUs default)*/
439	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
440	/* carrier sense timeout */
441	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
442}
443
444static void ar9003_hw_init_bb(struct ath_hw *ah,
445			      struct ath9k_channel *chan)
446{
447	u32 synthDelay;
448
449	/*
450	 * Wait for the frequency synth to settle (synth goes on
451	 * via AR_PHY_ACTIVE_EN).  Read the phy active delay register.
452	 * Value is in 100ns increments.
453	 */
454	synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
455	if (IS_CHAN_B(chan))
456		synthDelay = (4 * synthDelay) / 22;
457	else
458		synthDelay /= 10;
459
460	/* Activate the PHY (includes baseband activate + synthesizer on) */
461	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
462
463	udelay(synthDelay + BASE_ACTIVATE_DELAY);
464}
465
466void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
467{
468	switch (rx) {
469	case 0x5:
470		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
471			    AR_PHY_SWAP_ALT_CHAIN);
472	case 0x3:
473	case 0x1:
474	case 0x2:
475	case 0x7:
476		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx);
477		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx);
478		break;
479	default:
480		break;
481	}
482
483	REG_WRITE(ah, AR_SELFGEN_MASK, tx);
484	if (tx == 0x5) {
485		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
486			    AR_PHY_SWAP_ALT_CHAIN);
487	}
488}
489
490/*
491 * Override INI values with chip specific configuration.
492 */
493static void ar9003_hw_override_ini(struct ath_hw *ah)
494{
495	u32 val;
496
497	/*
498	 * Set the RX_ABORT and RX_DIS and clear it only after
499	 * RXE is set for MAC. This prevents frames with
500	 * corrupted descriptor status.
501	 */
502	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
503
504	/*
505	 * For AR9280 and above, there is a new feature that allows
506	 * Multicast search based on both MAC Address and Key ID. By default,
507	 * this feature is enabled. But since the driver is not using this
508	 * feature, we switch it off; otherwise multicast search based on
509	 * MAC addr only will fail.
510	 */
511	val = REG_READ(ah, AR_PCU_MISC_MODE2) & (~AR_ADHOC_MCAST_KEYID_ENABLE);
512	REG_WRITE(ah, AR_PCU_MISC_MODE2,
513		  val | AR_AGG_WEP_ENABLE_FIX | AR_AGG_WEP_ENABLE);
514}
515
516static void ar9003_hw_prog_ini(struct ath_hw *ah,
517			       struct ar5416IniArray *iniArr,
518			       int column)
519{
520	unsigned int i, regWrites = 0;
521
522	/* New INI format: Array may be undefined (pre, core, post arrays) */
523	if (!iniArr->ia_array)
524		return;
525
526	/*
527	 * New INI format: Pre, core, and post arrays for a given subsystem
528	 * may be modal (> 2 columns) or non-modal (2 columns). Determine if
529	 * the array is non-modal and force the column to 1.
530	 */
531	if (column >= iniArr->ia_columns)
532		column = 1;
533
534	for (i = 0; i < iniArr->ia_rows; i++) {
535		u32 reg = INI_RA(iniArr, i, 0);
536		u32 val = INI_RA(iniArr, i, column);
537
538		if (reg >= 0x16000 && reg < 0x17000)
539			ath9k_hw_analog_shift_regwrite(ah, reg, val);
540		else
541			REG_WRITE(ah, reg, val);
542
543		DO_DELAY(regWrites);
544	}
545}
546
547static int ar9003_hw_process_ini(struct ath_hw *ah,
548				 struct ath9k_channel *chan)
549{
550	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
551	unsigned int regWrites = 0, i;
552	struct ieee80211_channel *channel = chan->chan;
553	u32 modesIndex, freqIndex;
554
555	switch (chan->chanmode) {
556	case CHANNEL_A:
557	case CHANNEL_A_HT20:
558		modesIndex = 1;
559		freqIndex = 1;
560		break;
561	case CHANNEL_A_HT40PLUS:
562	case CHANNEL_A_HT40MINUS:
563		modesIndex = 2;
564		freqIndex = 1;
565		break;
566	case CHANNEL_G:
567	case CHANNEL_G_HT20:
568	case CHANNEL_B:
569		modesIndex = 4;
570		freqIndex = 2;
571		break;
572	case CHANNEL_G_HT40PLUS:
573	case CHANNEL_G_HT40MINUS:
574		modesIndex = 3;
575		freqIndex = 2;
576		break;
577
578	default:
579		return -EINVAL;
580	}
581
582	for (i = 0; i < ATH_INI_NUM_SPLIT; i++) {
583		ar9003_hw_prog_ini(ah, &ah->iniSOC[i], modesIndex);
584		ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
585		ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
586		ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
587	}
588
589	REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
590	REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);
591
592	/*
593	 * For 5GHz channels requiring Fast Clock, apply
594	 * different modal values.
595	 */
596	if (IS_CHAN_A_FAST_CLOCK(ah, chan))
597		REG_WRITE_ARRAY(&ah->iniModesAdditional,
598				modesIndex, regWrites);
599
600	ar9003_hw_override_ini(ah);
601	ar9003_hw_set_channel_regs(ah, chan);
602	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
603
604	/* Set TX power */
605	ah->eep_ops->set_txpower(ah, chan,
606				 ath9k_regd_get_ctl(regulatory, chan),
607				 channel->max_antenna_gain * 2,
608				 channel->max_power * 2,
609				 min((u32) MAX_RATE_POWER,
610				 (u32) regulatory->power_limit));
611
612	return 0;
613}
614
615static void ar9003_hw_set_rfmode(struct ath_hw *ah,
616				 struct ath9k_channel *chan)
617{
618	u32 rfMode = 0;
619
620	if (chan == NULL)
621		return;
622
623	rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
624		? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
625
626	if (IS_CHAN_A_FAST_CLOCK(ah, chan))
627		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
628
629	REG_WRITE(ah, AR_PHY_MODE, rfMode);
630}
631
632static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah)
633{
634	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
635}
636
637static void ar9003_hw_set_delta_slope(struct ath_hw *ah,
638				      struct ath9k_channel *chan)
639{
640	u32 coef_scaled, ds_coef_exp, ds_coef_man;
641	u32 clockMhzScaled = 0x64000000;
642	struct chan_centers centers;
643
644	/*
645	 * half and quarter rate can divide the scaled clock by 2 or 4
646	 * scale for selected channel bandwidth
647	 */
648	if (IS_CHAN_HALF_RATE(chan))
649		clockMhzScaled = clockMhzScaled >> 1;
650	else if (IS_CHAN_QUARTER_RATE(chan))
651		clockMhzScaled = clockMhzScaled >> 2;
652
653	/*
654	 * ALGO -> coef = 1e8/fcarrier*fclock/40;
655	 * scaled coef to provide precision for this floating calculation
656	 */
657	ath9k_hw_get_channel_centers(ah, chan, &centers);
658	coef_scaled = clockMhzScaled / centers.synth_center;
659
660	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
661				      &ds_coef_exp);
662
663	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
664		      AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
665	REG_RMW_FIELD(ah, AR_PHY_TIMING3,
666		      AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
667
668	/*
669	 * For Short GI,
670	 * scaled coeff is 9/10 that of normal coeff
671	 */
672	coef_scaled = (9 * coef_scaled) / 10;
673
674	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
675				      &ds_coef_exp);
676
677	/* for short gi */
678	REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
679		      AR_PHY_SGI_DSC_MAN, ds_coef_man);
680	REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
681		      AR_PHY_SGI_DSC_EXP, ds_coef_exp);
682}
683
684static bool ar9003_hw_rfbus_req(struct ath_hw *ah)
685{
686	REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
687	return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
688			     AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
689}
690
691/*
692 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
693 * Read the phy active delay register. Value is in 100ns increments.
694 */
695static void ar9003_hw_rfbus_done(struct ath_hw *ah)
696{
697	u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
698	if (IS_CHAN_B(ah->curchan))
699		synthDelay = (4 * synthDelay) / 22;
700	else
701		synthDelay /= 10;
702
703	udelay(synthDelay + BASE_ACTIVATE_DELAY);
704
705	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
706}
707
708/*
709 * Set the interrupt and GPIO values so the ISR can disable RF
710 * on a switch signal.  Assumes GPIO port and interrupt polarity
711 * are set prior to call.
712 */
713static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
714{
715	/* Connect rfsilent_bb_l to baseband */
716	REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
717		    AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
718	/* Set input mux for rfsilent_bb_l to GPIO #0 */
719	REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
720		    AR_GPIO_INPUT_MUX2_RFSILENT);
721
722	/*
723	 * Configure the desired GPIO port for input and
724	 * enable baseband rf silence.
725	 */
726	ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
727	REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
728}
729
730static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
731{
732	u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
733	if (value)
734		v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
735	else
736		v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
737	REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
738}
739
740static bool ar9003_hw_ani_control(struct ath_hw *ah,
741				  enum ath9k_ani_cmd cmd, int param)
742{
743	struct ar5416AniState *aniState = ah->curani;
744	struct ath_common *common = ath9k_hw_common(ah);
745	struct ath9k_channel *chan = ah->curchan;
746	s32 value, value2;
747
748	switch (cmd & ah->ani_function) {
749	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
750		/*
751		 * on == 1 means ofdm weak signal detection is ON
752		 * on == 1 is the default, for less noise immunity
753		 *
754		 * on == 0 means ofdm weak signal detection is OFF
755		 * on == 0 means more noise imm
756		 */
757		u32 on = param ? 1 : 0;
758		/*
759		 * make register setting for default
760		 * (weak sig detect ON) come from INI file
761		 */
762		int m1ThreshLow = on ?
763			aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
764		int m2ThreshLow = on ?
765			aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
766		int m1Thresh = on ?
767			aniState->iniDef.m1Thresh : m1Thresh_off;
768		int m2Thresh = on ?
769			aniState->iniDef.m2Thresh : m2Thresh_off;
770		int m2CountThr = on ?
771			aniState->iniDef.m2CountThr : m2CountThr_off;
772		int m2CountThrLow = on ?
773			aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
774		int m1ThreshLowExt = on ?
775			aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
776		int m2ThreshLowExt = on ?
777			aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
778		int m1ThreshExt = on ?
779			aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
780		int m2ThreshExt = on ?
781			aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
782
783		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
784			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
785			      m1ThreshLow);
786		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
787			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
788			      m2ThreshLow);
789		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
790			      AR_PHY_SFCORR_M1_THRESH, m1Thresh);
791		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
792			      AR_PHY_SFCORR_M2_THRESH, m2Thresh);
793		REG_RMW_FIELD(ah, AR_PHY_SFCORR,
794			      AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
795		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
796			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
797			      m2CountThrLow);
798
799		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
800			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
801		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
802			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
803		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
804			      AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
805		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
806			      AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
807
808		if (on)
809			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
810				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
811		else
812			REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
813				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
814
815		if (!on != aniState->ofdmWeakSigDetectOff) {
816			ath_print(common, ATH_DBG_ANI,
817				  "** ch %d: ofdm weak signal: %s=>%s\n",
818				  chan->channel,
819				  !aniState->ofdmWeakSigDetectOff ?
820					"on" : "off",
821				  on ? "on" : "off");
822			if (on)
823				ah->stats.ast_ani_ofdmon++;
824			else
825				ah->stats.ast_ani_ofdmoff++;
826			aniState->ofdmWeakSigDetectOff = !on;
827		}
828		break;
829	}
830	case ATH9K_ANI_FIRSTEP_LEVEL:{
831		u32 level = param;
832
833		if (level >= ARRAY_SIZE(firstep_table)) {
834			ath_print(common, ATH_DBG_ANI,
835				  "ATH9K_ANI_FIRSTEP_LEVEL: level "
836				  "out of range (%u > %u)\n",
837				  level,
838				  (unsigned) ARRAY_SIZE(firstep_table));
839			return false;
840		}
841
842		/*
843		 * make register setting relative to default
844		 * from INI file & cap value
845		 */
846		value = firstep_table[level] -
847			firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
848			aniState->iniDef.firstep;
849		if (value < ATH9K_SIG_FIRSTEP_SETTING_MIN)
850			value = ATH9K_SIG_FIRSTEP_SETTING_MIN;
851		if (value > ATH9K_SIG_FIRSTEP_SETTING_MAX)
852			value = ATH9K_SIG_FIRSTEP_SETTING_MAX;
853		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
854			      AR_PHY_FIND_SIG_FIRSTEP,
855			      value);
856		/*
857		 * we need to set first step low register too
858		 * make register setting relative to default
859		 * from INI file & cap value
860		 */
861		value2 = firstep_table[level] -
862			 firstep_table[ATH9K_ANI_FIRSTEP_LVL_NEW] +
863			 aniState->iniDef.firstepLow;
864		if (value2 < ATH9K_SIG_FIRSTEP_SETTING_MIN)
865			value2 = ATH9K_SIG_FIRSTEP_SETTING_MIN;
866		if (value2 > ATH9K_SIG_FIRSTEP_SETTING_MAX)
867			value2 = ATH9K_SIG_FIRSTEP_SETTING_MAX;
868
869		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,
870			      AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW, value2);
871
872		if (level != aniState->firstepLevel) {
873			ath_print(common, ATH_DBG_ANI,
874				  "** ch %d: level %d=>%d[def:%d] "
875				  "firstep[level]=%d ini=%d\n",
876				  chan->channel,
877				  aniState->firstepLevel,
878				  level,
879				  ATH9K_ANI_FIRSTEP_LVL_NEW,
880				  value,
881				  aniState->iniDef.firstep);
882			ath_print(common, ATH_DBG_ANI,
883				  "** ch %d: level %d=>%d[def:%d] "
884				  "firstep_low[level]=%d ini=%d\n",
885				  chan->channel,
886				  aniState->firstepLevel,
887				  level,
888				  ATH9K_ANI_FIRSTEP_LVL_NEW,
889				  value2,
890				  aniState->iniDef.firstepLow);
891			if (level > aniState->firstepLevel)
892				ah->stats.ast_ani_stepup++;
893			else if (level < aniState->firstepLevel)
894				ah->stats.ast_ani_stepdown++;
895			aniState->firstepLevel = level;
896		}
897		break;
898	}
899	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
900		u32 level = param;
901
902		if (level >= ARRAY_SIZE(cycpwrThr1_table)) {
903			ath_print(common, ATH_DBG_ANI,
904				  "ATH9K_ANI_SPUR_IMMUNITY_LEVEL: level "
905				  "out of range (%u > %u)\n",
906				  level,
907				  (unsigned) ARRAY_SIZE(cycpwrThr1_table));
908			return false;
909		}
910		/*
911		 * make register setting relative to default
912		 * from INI file & cap value
913		 */
914		value = cycpwrThr1_table[level] -
915			cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
916			aniState->iniDef.cycpwrThr1;
917		if (value < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
918			value = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
919		if (value > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
920			value = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
921		REG_RMW_FIELD(ah, AR_PHY_TIMING5,
922			      AR_PHY_TIMING5_CYCPWR_THR1,
923			      value);
924
925		/*
926		 * set AR_PHY_EXT_CCA for extension channel
927		 * make register setting relative to default
928		 * from INI file & cap value
929		 */
930		value2 = cycpwrThr1_table[level] -
931			 cycpwrThr1_table[ATH9K_ANI_SPUR_IMMUNE_LVL_NEW] +
932			 aniState->iniDef.cycpwrThr1Ext;
933		if (value2 < ATH9K_SIG_SPUR_IMM_SETTING_MIN)
934			value2 = ATH9K_SIG_SPUR_IMM_SETTING_MIN;
935		if (value2 > ATH9K_SIG_SPUR_IMM_SETTING_MAX)
936			value2 = ATH9K_SIG_SPUR_IMM_SETTING_MAX;
937		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
938			      AR_PHY_EXT_CYCPWR_THR1, value2);
939
940		if (level != aniState->spurImmunityLevel) {
941			ath_print(common, ATH_DBG_ANI,
942				  "** ch %d: level %d=>%d[def:%d] "
943				  "cycpwrThr1[level]=%d ini=%d\n",
944				  chan->channel,
945				  aniState->spurImmunityLevel,
946				  level,
947				  ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
948				  value,
949				  aniState->iniDef.cycpwrThr1);
950			ath_print(common, ATH_DBG_ANI,
951				  "** ch %d: level %d=>%d[def:%d] "
952				  "cycpwrThr1Ext[level]=%d ini=%d\n",
953				  chan->channel,
954				  aniState->spurImmunityLevel,
955				  level,
956				  ATH9K_ANI_SPUR_IMMUNE_LVL_NEW,
957				  value2,
958				  aniState->iniDef.cycpwrThr1Ext);
959			if (level > aniState->spurImmunityLevel)
960				ah->stats.ast_ani_spurup++;
961			else if (level < aniState->spurImmunityLevel)
962				ah->stats.ast_ani_spurdown++;
963			aniState->spurImmunityLevel = level;
964		}
965		break;
966	}
967	case ATH9K_ANI_MRC_CCK:{
968		/*
969		 * is_on == 1 means MRC CCK ON (default, less noise imm)
970		 * is_on == 0 means MRC CCK is OFF (more noise imm)
971		 */
972		bool is_on = param ? 1 : 0;
973		REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
974			      AR_PHY_MRC_CCK_ENABLE, is_on);
975		REG_RMW_FIELD(ah, AR_PHY_MRC_CCK_CTRL,
976			      AR_PHY_MRC_CCK_MUX_REG, is_on);
977		if (!is_on != aniState->mrcCCKOff) {
978			ath_print(common, ATH_DBG_ANI,
979				  "** ch %d: MRC CCK: %s=>%s\n",
980				  chan->channel,
981				  !aniState->mrcCCKOff ? "on" : "off",
982				  is_on ? "on" : "off");
983		if (is_on)
984			ah->stats.ast_ani_ccklow++;
985		else
986			ah->stats.ast_ani_cckhigh++;
987		aniState->mrcCCKOff = !is_on;
988		}
989	break;
990	}
991	case ATH9K_ANI_PRESENT:
992		break;
993	default:
994		ath_print(common, ATH_DBG_ANI,
995			  "invalid cmd %u\n", cmd);
996		return false;
997	}
998
999	ath_print(common, ATH_DBG_ANI,
1000		  "ANI parameters: SI=%d, ofdmWS=%s FS=%d "
1001		  "MRCcck=%s listenTime=%d CC=%d listen=%d "
1002		  "ofdmErrs=%d cckErrs=%d\n",
1003		  aniState->spurImmunityLevel,
1004		  !aniState->ofdmWeakSigDetectOff ? "on" : "off",
1005		  aniState->firstepLevel,
1006		  !aniState->mrcCCKOff ? "on" : "off",
1007		  aniState->listenTime,
1008		  aniState->cycleCount,
1009		  aniState->listenTime,
1010		  aniState->ofdmPhyErrCount,
1011		  aniState->cckPhyErrCount);
1012	return true;
1013}
1014
1015static void ar9003_hw_do_getnf(struct ath_hw *ah,
1016			      int16_t nfarray[NUM_NF_READINGS])
1017{
1018	int16_t nf;
1019
1020	nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
1021	nfarray[0] = sign_extend(nf, 9);
1022
1023	nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
1024	nfarray[1] = sign_extend(nf, 9);
1025
1026	nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
1027	nfarray[2] = sign_extend(nf, 9);
1028
1029	if (!IS_CHAN_HT40(ah->curchan))
1030		return;
1031
1032	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
1033	nfarray[3] = sign_extend(nf, 9);
1034
1035	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
1036	nfarray[4] = sign_extend(nf, 9);
1037
1038	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
1039	nfarray[5] = sign_extend(nf, 9);
1040}
1041
1042static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
1043{
1044	ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
1045	ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
1046	ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
1047	ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
1048	ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
1049	ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
1050}
1051
1052/*
1053 * Initialize the ANI register values with default (ini) values.
1054 * This routine is called during a (full) hardware reset after
1055 * all the registers are initialised from the INI.
1056 */
1057static void ar9003_hw_ani_cache_ini_regs(struct ath_hw *ah)
1058{
1059	struct ar5416AniState *aniState;
1060	struct ath_common *common = ath9k_hw_common(ah);
1061	struct ath9k_channel *chan = ah->curchan;
1062	struct ath9k_ani_default *iniDef;
1063	int index;
1064	u32 val;
1065
1066	index = ath9k_hw_get_ani_channel_idx(ah, chan);
1067	aniState = &ah->ani[index];
1068	ah->curani = aniState;
1069	iniDef = &aniState->iniDef;
1070
1071	ath_print(common, ATH_DBG_ANI,
1072		  "ver %d.%d opmode %u chan %d Mhz/0x%x\n",
1073		  ah->hw_version.macVersion,
1074		  ah->hw_version.macRev,
1075		  ah->opmode,
1076		  chan->channel,
1077		  chan->channelFlags);
1078
1079	val = REG_READ(ah, AR_PHY_SFCORR);
1080	iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);
1081	iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);
1082	iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);
1083
1084	val = REG_READ(ah, AR_PHY_SFCORR_LOW);
1085	iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);
1086	iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);
1087	iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);
1088
1089	val = REG_READ(ah, AR_PHY_SFCORR_EXT);
1090	iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);
1091	iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);
1092	iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);
1093	iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);
1094	iniDef->firstep = REG_READ_FIELD(ah,
1095					 AR_PHY_FIND_SIG,
1096					 AR_PHY_FIND_SIG_FIRSTEP);
1097	iniDef->firstepLow = REG_READ_FIELD(ah,
1098					    AR_PHY_FIND_SIG_LOW,
1099					    AR_PHY_FIND_SIG_LOW_FIRSTEP_LOW);
1100	iniDef->cycpwrThr1 = REG_READ_FIELD(ah,
1101					    AR_PHY_TIMING5,
1102					    AR_PHY_TIMING5_CYCPWR_THR1);
1103	iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,
1104					       AR_PHY_EXT_CCA,
1105					       AR_PHY_EXT_CYCPWR_THR1);
1106
1107	/* these levels just got reset to defaults by the INI */
1108	aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
1109	aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
1110	aniState->ofdmWeakSigDetectOff = !ATH9K_ANI_USE_OFDM_WEAK_SIG;
1111	aniState->mrcCCKOff = !ATH9K_ANI_ENABLE_MRC_CCK;
1112
1113	aniState->cycleCount = 0;
1114}
1115
1116void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
1117{
1118	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
1119	const u32 ar9300_cca_regs[6] = {
1120		AR_PHY_CCA_0,
1121		AR_PHY_CCA_1,
1122		AR_PHY_CCA_2,
1123		AR_PHY_EXT_CCA,
1124		AR_PHY_EXT_CCA_1,
1125		AR_PHY_EXT_CCA_2,
1126	};
1127
1128	priv_ops->rf_set_freq = ar9003_hw_set_channel;
1129	priv_ops->spur_mitigate_freq = ar9003_hw_spur_mitigate;
1130	priv_ops->compute_pll_control = ar9003_hw_compute_pll_control;
1131	priv_ops->set_channel_regs = ar9003_hw_set_channel_regs;
1132	priv_ops->init_bb = ar9003_hw_init_bb;
1133	priv_ops->process_ini = ar9003_hw_process_ini;
1134	priv_ops->set_rfmode = ar9003_hw_set_rfmode;
1135	priv_ops->mark_phy_inactive = ar9003_hw_mark_phy_inactive;
1136	priv_ops->set_delta_slope = ar9003_hw_set_delta_slope;
1137	priv_ops->rfbus_req = ar9003_hw_rfbus_req;
1138	priv_ops->rfbus_done = ar9003_hw_rfbus_done;
1139	priv_ops->enable_rfkill = ar9003_hw_enable_rfkill;
1140	priv_ops->set_diversity = ar9003_hw_set_diversity;
1141	priv_ops->ani_control = ar9003_hw_ani_control;
1142	priv_ops->do_getnf = ar9003_hw_do_getnf;
1143	priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
1144
1145	ar9003_hw_set_nf_limits(ah);
1146	memcpy(ah->nf_regs, ar9300_cca_regs, sizeof(ah->nf_regs));
1147}
1148
1149void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
1150{
1151	struct ath_common *common = ath9k_hw_common(ah);
1152	u32 idle_tmo_ms = ah->bb_watchdog_timeout_ms;
1153	u32 val, idle_count;
1154
1155	if (!idle_tmo_ms) {
1156		/* disable IRQ, disable chip-reset for BB panic */
1157		REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2,
1158			  REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) &
1159			  ~(AR_PHY_WATCHDOG_RST_ENABLE |
1160			    AR_PHY_WATCHDOG_IRQ_ENABLE));
1161
1162		/* disable watchdog in non-IDLE mode, disable in IDLE mode */
1163		REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1,
1164			  REG_READ(ah, AR_PHY_WATCHDOG_CTL_1) &
1165			  ~(AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
1166			    AR_PHY_WATCHDOG_IDLE_ENABLE));
1167
1168		ath_print(common, ATH_DBG_RESET, "Disabled BB Watchdog\n");
1169		return;
1170	}
1171
1172	/* enable IRQ, disable chip-reset for BB watchdog */
1173	val = REG_READ(ah, AR_PHY_WATCHDOG_CTL_2) & AR_PHY_WATCHDOG_CNTL2_MASK;
1174	REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_2,
1175		  (val | AR_PHY_WATCHDOG_IRQ_ENABLE) &
1176		  ~AR_PHY_WATCHDOG_RST_ENABLE);
1177
1178	/* bound limit to 10 secs */
1179	if (idle_tmo_ms > 10000)
1180		idle_tmo_ms = 10000;
1181
1182	/*
1183	 * The time unit for watchdog event is 2^15 44/88MHz cycles.
1184	 *
1185	 * For HT20 we have a time unit of 2^15/44 MHz = .74 ms per tick
1186	 * For HT40 we have a time unit of 2^15/88 MHz = .37 ms per tick
1187	 *
1188	 * Given we use fast clock now in 5 GHz, these time units should
1189	 * be common for both 2 GHz and 5 GHz.
1190	 */
1191	idle_count = (100 * idle_tmo_ms) / 74;
1192	if (ah->curchan && IS_CHAN_HT40(ah->curchan))
1193		idle_count = (100 * idle_tmo_ms) / 37;
1194
1195	/*
1196	 * enable watchdog in non-IDLE mode, disable in IDLE mode,
1197	 * set idle time-out.
1198	 */
1199	REG_WRITE(ah, AR_PHY_WATCHDOG_CTL_1,
1200		  AR_PHY_WATCHDOG_NON_IDLE_ENABLE |
1201		  AR_PHY_WATCHDOG_IDLE_MASK |
1202		  (AR_PHY_WATCHDOG_NON_IDLE_MASK & (idle_count << 2)));
1203
1204	ath_print(common, ATH_DBG_RESET,
1205		  "Enabled BB Watchdog timeout (%u ms)\n",
1206		  idle_tmo_ms);
1207}
1208
1209void ar9003_hw_bb_watchdog_read(struct ath_hw *ah)
1210{
1211	/*
1212	 * we want to avoid printing in ISR context so we save the
1213	 * watchdog status to be printed later in bottom half context.
1214	 */
1215	ah->bb_watchdog_last_status = REG_READ(ah, AR_PHY_WATCHDOG_STATUS);
1216
1217	/*
1218	 * the watchdog timer should reset on status read but to be sure
1219	 * sure we write 0 to the watchdog status bit.
1220	 */
1221	REG_WRITE(ah, AR_PHY_WATCHDOG_STATUS,
1222		  ah->bb_watchdog_last_status & ~AR_PHY_WATCHDOG_STATUS_CLR);
1223}
1224
1225void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah)
1226{
1227	struct ath_common *common = ath9k_hw_common(ah);
1228	u32 rxc_pcnt = 0, rxf_pcnt = 0, txf_pcnt = 0, status;
1229
1230	if (likely(!(common->debug_mask & ATH_DBG_RESET)))
1231		return;
1232
1233	status = ah->bb_watchdog_last_status;
1234	ath_print(common, ATH_DBG_RESET,
1235		  "\n==== BB update: BB status=0x%08x ====\n", status);
1236	ath_print(common, ATH_DBG_RESET,
1237		  "** BB state: wd=%u det=%u rdar=%u rOFDM=%d "
1238		  "rCCK=%u tOFDM=%u tCCK=%u agc=%u src=%u **\n",
1239		  MS(status, AR_PHY_WATCHDOG_INFO),
1240		  MS(status, AR_PHY_WATCHDOG_DET_HANG),
1241		  MS(status, AR_PHY_WATCHDOG_RADAR_SM),
1242		  MS(status, AR_PHY_WATCHDOG_RX_OFDM_SM),
1243		  MS(status, AR_PHY_WATCHDOG_RX_CCK_SM),
1244		  MS(status, AR_PHY_WATCHDOG_TX_OFDM_SM),
1245		  MS(status, AR_PHY_WATCHDOG_TX_CCK_SM),
1246		  MS(status, AR_PHY_WATCHDOG_AGC_SM),
1247		  MS(status,AR_PHY_WATCHDOG_SRCH_SM));
1248
1249	ath_print(common, ATH_DBG_RESET,
1250		  "** BB WD cntl: cntl1=0x%08x cntl2=0x%08x **\n",
1251		  REG_READ(ah, AR_PHY_WATCHDOG_CTL_1),
1252		  REG_READ(ah, AR_PHY_WATCHDOG_CTL_2));
1253	ath_print(common, ATH_DBG_RESET,
1254		  "** BB mode: BB_gen_controls=0x%08x **\n",
1255		  REG_READ(ah, AR_PHY_GEN_CTRL));
1256
1257	if (ath9k_hw_GetMibCycleCountsPct(ah, &rxc_pcnt, &rxf_pcnt, &txf_pcnt))
1258		ath_print(common, ATH_DBG_RESET,
1259			  "** BB busy times: rx_clear=%d%%, "
1260			  "rx_frame=%d%%, tx_frame=%d%% **\n",
1261			  rxc_pcnt, rxf_pcnt, txf_pcnt);
1262
1263	ath_print(common, ATH_DBG_RESET,
1264		  "==== BB update: done ====\n\n");
1265}
1266EXPORT_SYMBOL(ar9003_hw_bb_watchdog_dbg_info);
1267