brintos

brintos / linux-shallow public Read only

0
0
Text · 38.9 KiB · 7a45f5f Raw
1389 lines · c
1/*2 * Copyright (c) 2008-2011 Atheros Communications Inc.3 *4 * Permission to use, copy, modify, and/or distribute this software for any5 * purpose with or without fee is hereby granted, provided that the above6 * copyright notice and this permission notice appear in all copies.7 *8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.15 */16 17#include "hw.h"18#include "hw-ops.h"19#include "../regd.h"20#include "ar9002_phy.h"21 22/* All code below is for AR5008, AR9001, AR9002 */23 24#define AR5008_OFDM_RATES		825#define AR5008_HT_SS_RATES		826#define AR5008_HT_DS_RATES		827 28#define AR5008_HT20_SHIFT		1629#define AR5008_HT40_SHIFT		2430 31#define AR5008_11NA_OFDM_SHIFT		032#define AR5008_11NA_HT_SS_SHIFT		833#define AR5008_11NA_HT_DS_SHIFT		1634 35#define AR5008_11NG_OFDM_SHIFT		436#define AR5008_11NG_HT_SS_SHIFT		1237#define AR5008_11NG_HT_DS_SHIFT		2038 39/*40 * register values to turn OFDM weak signal detection OFF41 */42static const int m1ThreshLow_off = 127;43static const int m2ThreshLow_off = 127;44static const int m1Thresh_off = 127;45static const int m2Thresh_off = 127;46static const int m2CountThr_off =  31;47static const int m2CountThrLow_off =  63;48static const int m1ThreshLowExt_off = 127;49static const int m2ThreshLowExt_off = 127;50static const int m1ThreshExt_off = 127;51static const int m2ThreshExt_off = 127;52 53static const u32 ar5416Bank0[][2] = {54	/* Addr      allmodes  */55	{0x000098b0, 0x1e5795e5},56	{0x000098e0, 0x02008020},57};58 59static const u32 ar5416Bank1[][2] = {60	/* Addr      allmodes  */61	{0x000098b0, 0x02108421},62	{0x000098ec, 0x00000008},63};64 65static const u32 ar5416Bank2[][2] = {66	/* Addr      allmodes  */67	{0x000098b0, 0x0e73ff17},68	{0x000098e0, 0x00000420},69};70 71static const u32 ar5416Bank3[][3] = {72	/* Addr      5G          2G        */73	{0x000098f0, 0x01400018, 0x01c00018},74};75 76static const u32 ar5416Bank7[][2] = {77	/* Addr      allmodes  */78	{0x0000989c, 0x00000500},79	{0x0000989c, 0x00000800},80	{0x000098cc, 0x0000000e},81};82 83static const struct ar5416IniArray bank0 = STATIC_INI_ARRAY(ar5416Bank0);84static const struct ar5416IniArray bank1 = STATIC_INI_ARRAY(ar5416Bank1);85static const struct ar5416IniArray bank2 = STATIC_INI_ARRAY(ar5416Bank2);86static const struct ar5416IniArray bank3 = STATIC_INI_ARRAY(ar5416Bank3);87static const struct ar5416IniArray bank7 = STATIC_INI_ARRAY(ar5416Bank7);88 89static void ar5008_write_bank6(struct ath_hw *ah, unsigned int *writecnt)90{91	struct ar5416IniArray *array = &ah->iniBank6;92	u32 *data = ah->analogBank6Data;93	int r;94 95	ENABLE_REGWRITE_BUFFER(ah);96 97	for (r = 0; r < array->ia_rows; r++) {98		REG_WRITE(ah, INI_RA(array, r, 0), data[r]);99		DO_DELAY(*writecnt);100	}101 102	REGWRITE_BUFFER_FLUSH(ah);103}104 105/*106 * ar5008_hw_phy_modify_rx_buffer() - perform analog swizzling of parameters107 *108 * Performs analog "swizzling" of parameters into their location.109 * Used on external AR2133/AR5133 radios.110 */111static void ar5008_hw_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,112					   u32 numBits, u32 firstBit,113					   u32 column)114{115	u32 tmp32, mask, arrayEntry, lastBit;116	int32_t bitPosition, bitsLeft;117 118	tmp32 = ath9k_hw_reverse_bits(reg32, numBits);119	arrayEntry = (firstBit - 1) / 8;120	bitPosition = (firstBit - 1) % 8;121	bitsLeft = numBits;122	while (bitsLeft > 0) {123		lastBit = (bitPosition + bitsLeft > 8) ?124		    8 : bitPosition + bitsLeft;125		mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<126		    (column * 8);127		rfBuf[arrayEntry] &= ~mask;128		rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<129				      (column * 8)) & mask;130		bitsLeft -= 8 - bitPosition;131		tmp32 = tmp32 >> (8 - bitPosition);132		bitPosition = 0;133		arrayEntry++;134	}135}136 137/*138 * Fix on 2.4 GHz band for orientation sensitivity issue by increasing139 * rf_pwd_icsyndiv.140 *141 * Theoretical Rules:142 *   if 2 GHz band143 *      if forceBiasAuto144 *         if synth_freq < 2412145 *            bias = 0146 *         else if 2412 <= synth_freq <= 2422147 *            bias = 1148 *         else // synth_freq > 2422149 *            bias = 2150 *      else if forceBias > 0151 *         bias = forceBias & 7152 *      else153 *         no change, use value from ini file154 *   else155 *      no change, invalid band156 *157 *  1st Mod:158 *    2422 also uses value of 2159 *    <approved>160 *161 *  2nd Mod:162 *    Less than 2412 uses value of 0, 2412 and above uses value of 2163 */164static void ar5008_hw_force_bias(struct ath_hw *ah, u16 synth_freq)165{166	struct ath_common *common = ath9k_hw_common(ah);167	u32 tmp_reg;168	int reg_writes = 0;169	u32 new_bias = 0;170 171	if (!AR_SREV_5416(ah) || synth_freq >= 3000)172		return;173 174	BUG_ON(AR_SREV_9280_20_OR_LATER(ah));175 176	if (synth_freq < 2412)177		new_bias = 0;178	else if (synth_freq < 2422)179		new_bias = 1;180	else181		new_bias = 2;182 183	/* pre-reverse this field */184	tmp_reg = ath9k_hw_reverse_bits(new_bias, 3);185 186	ath_dbg(common, CONFIG, "Force rf_pwd_icsyndiv to %1d on %4d\n",187		new_bias, synth_freq);188 189	/* swizzle rf_pwd_icsyndiv */190	ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data, tmp_reg, 3, 181, 3);191 192	/* write Bank 6 with new params */193	ar5008_write_bank6(ah, &reg_writes);194}195 196/*197 * ar5008_hw_set_channel - tune to a channel on the external AR2133/AR5133 radios198 *199 * For the external AR2133/AR5133 radios, takes the MHz channel value and set200 * the channel value. Assumes writes enabled to analog bus and bank6 register201 * cache in ah->analogBank6Data.202 */203static int ar5008_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)204{205	struct ath_common *common = ath9k_hw_common(ah);206	u32 channelSel = 0;207	u32 bModeSynth = 0;208	u32 aModeRefSel = 0;209	u32 reg32 = 0;210	u16 freq;211	struct chan_centers centers;212 213	ath9k_hw_get_channel_centers(ah, chan, &centers);214	freq = centers.synth_center;215 216	if (freq < 4800) {217		u32 txctl;218 219		if (((freq - 2192) % 5) == 0) {220			channelSel = ((freq - 672) * 2 - 3040) / 10;221			bModeSynth = 0;222		} else if (((freq - 2224) % 5) == 0) {223			channelSel = ((freq - 704) * 2 - 3040) / 10;224			bModeSynth = 1;225		} else {226			ath_err(common, "Invalid channel %u MHz\n", freq);227			return -EINVAL;228		}229 230		channelSel = (channelSel << 2) & 0xff;231		channelSel = ath9k_hw_reverse_bits(channelSel, 8);232 233		txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);234		if (freq == 2484) {235 236			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,237				  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);238		} else {239			REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,240				  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);241		}242 243	} else if ((freq % 20) == 0 && freq >= 5120) {244		channelSel =245		    ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);246		aModeRefSel = ath9k_hw_reverse_bits(1, 2);247	} else if ((freq % 10) == 0) {248		channelSel =249		    ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);250		if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))251			aModeRefSel = ath9k_hw_reverse_bits(2, 2);252		else253			aModeRefSel = ath9k_hw_reverse_bits(1, 2);254	} else if ((freq % 5) == 0) {255		channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);256		aModeRefSel = ath9k_hw_reverse_bits(1, 2);257	} else {258		ath_err(common, "Invalid channel %u MHz\n", freq);259		return -EINVAL;260	}261 262	ar5008_hw_force_bias(ah, freq);263 264	reg32 =265	    (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |266	    (1 << 5) | 0x1;267 268	REG_WRITE(ah, AR_PHY(0x37), reg32);269 270	ah->curchan = chan;271 272	return 0;273}274 275void ar5008_hw_cmn_spur_mitigate(struct ath_hw *ah,276			  struct ath9k_channel *chan, int bin)277{278	int cur_bin;279	int upper, lower, cur_vit_mask;280	int i;281	int8_t mask_m[123] = {0};282	int8_t mask_p[123] = {0};283	int8_t mask_amt;284	int tmp_mask;285	static const int pilot_mask_reg[4] = {286		AR_PHY_TIMING7, AR_PHY_TIMING8,287		AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60288	};289	static const int chan_mask_reg[4] = {290		AR_PHY_TIMING9, AR_PHY_TIMING10,291		AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60292	};293	static const int inc[4] = { 0, 100, 0, 0 };294 295	cur_bin = -6000;296	upper = bin + 100;297	lower = bin - 100;298 299	for (i = 0; i < 4; i++) {300		int pilot_mask = 0;301		int chan_mask = 0;302		int bp = 0;303 304		for (bp = 0; bp < 30; bp++) {305			if ((cur_bin > lower) && (cur_bin < upper)) {306				pilot_mask = pilot_mask | 0x1 << bp;307				chan_mask = chan_mask | 0x1 << bp;308			}309			cur_bin += 100;310		}311		cur_bin += inc[i];312		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);313		REG_WRITE(ah, chan_mask_reg[i], chan_mask);314	}315 316	cur_vit_mask = 6100;317	upper = bin + 120;318	lower = bin - 120;319 320	for (i = 0; i < ARRAY_SIZE(mask_m); i++) {321		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {322			/* workaround for gcc bug #37014 */323			volatile int tmp_v = abs(cur_vit_mask - bin);324 325			if (tmp_v < 75)326				mask_amt = 1;327			else328				mask_amt = 0;329			if (cur_vit_mask < 0)330				mask_m[abs(cur_vit_mask / 100)] = mask_amt;331			else332				mask_p[cur_vit_mask / 100] = mask_amt;333		}334		cur_vit_mask -= 100;335	}336 337	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)338		| (mask_m[48] << 26) | (mask_m[49] << 24)339		| (mask_m[50] << 22) | (mask_m[51] << 20)340		| (mask_m[52] << 18) | (mask_m[53] << 16)341		| (mask_m[54] << 14) | (mask_m[55] << 12)342		| (mask_m[56] << 10) | (mask_m[57] << 8)343		| (mask_m[58] << 6) | (mask_m[59] << 4)344		| (mask_m[60] << 2) | (mask_m[61] << 0);345	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);346	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);347 348	tmp_mask = (mask_m[31] << 28)349		| (mask_m[32] << 26) | (mask_m[33] << 24)350		| (mask_m[34] << 22) | (mask_m[35] << 20)351		| (mask_m[36] << 18) | (mask_m[37] << 16)352		| (mask_m[48] << 14) | (mask_m[39] << 12)353		| (mask_m[40] << 10) | (mask_m[41] << 8)354		| (mask_m[42] << 6) | (mask_m[43] << 4)355		| (mask_m[44] << 2) | (mask_m[45] << 0);356	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);357	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);358 359	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)360		| (mask_m[18] << 26) | (mask_m[18] << 24)361		| (mask_m[20] << 22) | (mask_m[20] << 20)362		| (mask_m[22] << 18) | (mask_m[22] << 16)363		| (mask_m[24] << 14) | (mask_m[24] << 12)364		| (mask_m[25] << 10) | (mask_m[26] << 8)365		| (mask_m[27] << 6) | (mask_m[28] << 4)366		| (mask_m[29] << 2) | (mask_m[30] << 0);367	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);368	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);369 370	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)371		| (mask_m[2] << 26) | (mask_m[3] << 24)372		| (mask_m[4] << 22) | (mask_m[5] << 20)373		| (mask_m[6] << 18) | (mask_m[7] << 16)374		| (mask_m[8] << 14) | (mask_m[9] << 12)375		| (mask_m[10] << 10) | (mask_m[11] << 8)376		| (mask_m[12] << 6) | (mask_m[13] << 4)377		| (mask_m[14] << 2) | (mask_m[15] << 0);378	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);379	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);380 381	tmp_mask = (mask_p[15] << 28)382		| (mask_p[14] << 26) | (mask_p[13] << 24)383		| (mask_p[12] << 22) | (mask_p[11] << 20)384		| (mask_p[10] << 18) | (mask_p[9] << 16)385		| (mask_p[8] << 14) | (mask_p[7] << 12)386		| (mask_p[6] << 10) | (mask_p[5] << 8)387		| (mask_p[4] << 6) | (mask_p[3] << 4)388		| (mask_p[2] << 2) | (mask_p[1] << 0);389	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);390	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);391 392	tmp_mask = (mask_p[30] << 28)393		| (mask_p[29] << 26) | (mask_p[28] << 24)394		| (mask_p[27] << 22) | (mask_p[26] << 20)395		| (mask_p[25] << 18) | (mask_p[24] << 16)396		| (mask_p[23] << 14) | (mask_p[22] << 12)397		| (mask_p[21] << 10) | (mask_p[20] << 8)398		| (mask_p[19] << 6) | (mask_p[18] << 4)399		| (mask_p[17] << 2) | (mask_p[16] << 0);400	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);401	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);402 403	tmp_mask = (mask_p[45] << 28)404		| (mask_p[44] << 26) | (mask_p[43] << 24)405		| (mask_p[42] << 22) | (mask_p[41] << 20)406		| (mask_p[40] << 18) | (mask_p[39] << 16)407		| (mask_p[38] << 14) | (mask_p[37] << 12)408		| (mask_p[36] << 10) | (mask_p[35] << 8)409		| (mask_p[34] << 6) | (mask_p[33] << 4)410		| (mask_p[32] << 2) | (mask_p[31] << 0);411	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);412	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);413 414	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)415		| (mask_p[59] << 26) | (mask_p[58] << 24)416		| (mask_p[57] << 22) | (mask_p[56] << 20)417		| (mask_p[55] << 18) | (mask_p[54] << 16)418		| (mask_p[53] << 14) | (mask_p[52] << 12)419		| (mask_p[51] << 10) | (mask_p[50] << 8)420		| (mask_p[49] << 6) | (mask_p[48] << 4)421		| (mask_p[47] << 2) | (mask_p[46] << 0);422	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);423	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);424}425 426/*427 * ar5008_hw_spur_mitigate - convert baseband spur frequency for external radios428 *429 * For non single-chip solutions. Converts to baseband spur frequency given the430 * input channel frequency and compute register settings below.431 */432static void ar5008_hw_spur_mitigate(struct ath_hw *ah,433				    struct ath9k_channel *chan)434{435	int bb_spur = AR_NO_SPUR;436	int bin;437	int spur_freq_sd;438	int spur_delta_phase;439	int denominator;440	int tmp, new;441	int i;442 443	int cur_bb_spur;444	bool is2GHz = IS_CHAN_2GHZ(chan);445 446	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {447		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);448		if (AR_NO_SPUR == cur_bb_spur)449			break;450		cur_bb_spur = cur_bb_spur - (chan->channel * 10);451		if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {452			bb_spur = cur_bb_spur;453			break;454		}455	}456 457	if (AR_NO_SPUR == bb_spur)458		return;459 460	bin = bb_spur * 32;461 462	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));463	new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |464		     AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |465		     AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |466		     AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);467 468	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);469 470	new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |471	       AR_PHY_SPUR_REG_ENABLE_MASK_PPM |472	       AR_PHY_SPUR_REG_MASK_RATE_SELECT |473	       AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |474	       SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));475	REG_WRITE(ah, AR_PHY_SPUR_REG, new);476 477	spur_delta_phase = ((bb_spur * 524288) / 100) &478		AR_PHY_TIMING11_SPUR_DELTA_PHASE;479 480	denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;481	spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;482 483	new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |484	       SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |485	       SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));486	REG_WRITE(ah, AR_PHY_TIMING11, new);487 488	ar5008_hw_cmn_spur_mitigate(ah, chan, bin);489}490 491/**492 * ar5008_hw_rf_alloc_ext_banks - allocates banks for external radio programming493 * @ah: atheros hardware structure494 *495 * Only required for older devices with external AR2133/AR5133 radios.496 */497static int ar5008_hw_rf_alloc_ext_banks(struct ath_hw *ah)498{499	int size = ah->iniBank6.ia_rows * sizeof(u32);500 501	if (AR_SREV_9280_20_OR_LATER(ah))502	    return 0;503 504	ah->analogBank6Data = devm_kzalloc(ah->dev, size, GFP_KERNEL);505	if (!ah->analogBank6Data)506		return -ENOMEM;507 508	return 0;509}510 511 512/* *513 * ar5008_hw_set_rf_regs - programs rf registers based on EEPROM514 * @ah: atheros hardware structure515 * @chan:516 * @modesIndex:517 *518 * Used for the external AR2133/AR5133 radios.519 *520 * Reads the EEPROM header info from the device structure and programs521 * all rf registers. This routine requires access to the analog522 * rf device. This is not required for single-chip devices.523 */524static bool ar5008_hw_set_rf_regs(struct ath_hw *ah,525				  struct ath9k_channel *chan,526				  u16 modesIndex)527{528	u32 eepMinorRev;529	u32 ob5GHz = 0, db5GHz = 0;530	u32 ob2GHz = 0, db2GHz = 0;531	int regWrites = 0;532	int i;533 534	/*535	 * Software does not need to program bank data536	 * for single chip devices, that is AR9280 or anything537	 * after that.538	 */539	if (AR_SREV_9280_20_OR_LATER(ah))540		return true;541 542	/* Setup rf parameters */543	eepMinorRev = ah->eep_ops->get_eeprom_rev(ah);544 545	for (i = 0; i < ah->iniBank6.ia_rows; i++)546		ah->analogBank6Data[i] = INI_RA(&ah->iniBank6, i, modesIndex);547 548	/* Only the 5 or 2 GHz OB/DB need to be set for a mode */549	if (eepMinorRev >= 2) {550		if (IS_CHAN_2GHZ(chan)) {551			ob2GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_2);552			db2GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_2);553			ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,554						       ob2GHz, 3, 197, 0);555			ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,556						       db2GHz, 3, 194, 0);557		} else {558			ob5GHz = ah->eep_ops->get_eeprom(ah, EEP_OB_5);559			db5GHz = ah->eep_ops->get_eeprom(ah, EEP_DB_5);560			ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,561						       ob5GHz, 3, 203, 0);562			ar5008_hw_phy_modify_rx_buffer(ah->analogBank6Data,563						       db5GHz, 3, 200, 0);564		}565	}566 567	/* Write Analog registers */568	REG_WRITE_ARRAY(&bank0, 1, regWrites);569	REG_WRITE_ARRAY(&bank1, 1, regWrites);570	REG_WRITE_ARRAY(&bank2, 1, regWrites);571	REG_WRITE_ARRAY(&bank3, modesIndex, regWrites);572	ar5008_write_bank6(ah, &regWrites);573	REG_WRITE_ARRAY(&bank7, 1, regWrites);574 575	return true;576}577 578static void ar5008_hw_init_bb(struct ath_hw *ah,579			      struct ath9k_channel *chan)580{581	u32 synthDelay;582 583	synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;584 585	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);586 587	ath9k_hw_synth_delay(ah, chan, synthDelay);588}589 590static void ar5008_hw_init_chain_masks(struct ath_hw *ah)591{592	int rx_chainmask, tx_chainmask;593 594	rx_chainmask = ah->rxchainmask;595	tx_chainmask = ah->txchainmask;596 597 598	switch (rx_chainmask) {599	case 0x5:600		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,601			    AR_PHY_SWAP_ALT_CHAIN);602		fallthrough;603	case 0x3:604		if (ah->hw_version.macVersion == AR_SREV_REVISION_5416_10) {605			REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);606			REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);607			break;608		}609		fallthrough;610	case 0x1:611	case 0x2:612	case 0x7:613		ENABLE_REGWRITE_BUFFER(ah);614		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);615		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);616		break;617	default:618		ENABLE_REGWRITE_BUFFER(ah);619		break;620	}621 622	REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);623 624	REGWRITE_BUFFER_FLUSH(ah);625 626	if (tx_chainmask == 0x5) {627		REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,628			    AR_PHY_SWAP_ALT_CHAIN);629	}630	if (AR_SREV_9100(ah))631		REG_WRITE(ah, AR_PHY_ANALOG_SWAP,632			  REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);633}634 635static void ar5008_hw_override_ini(struct ath_hw *ah,636				   struct ath9k_channel *chan)637{638	u32 val;639 640	/*641	 * Set the RX_ABORT and RX_DIS and clear if off only after642	 * RXE is set for MAC. This prevents frames with corrupted643	 * descriptor status.644	 */645	REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));646 647	if (AR_SREV_9280_20_OR_LATER(ah)) {648		/*649		 * For AR9280 and above, there is a new feature that allows650		 * Multicast search based on both MAC Address and Key ID.651		 * By default, this feature is enabled. But since the driver652		 * is not using this feature, we switch it off; otherwise653		 * multicast search based on MAC addr only will fail.654		 */655		val = REG_READ(ah, AR_PCU_MISC_MODE2) &656			(~AR_ADHOC_MCAST_KEYID_ENABLE);657 658		if (!AR_SREV_9271(ah))659			val &= ~AR_PCU_MISC_MODE2_HWWAR1;660 661		if (AR_SREV_9287_11_OR_LATER(ah))662			val = val & (~AR_PCU_MISC_MODE2_HWWAR2);663 664		val |= AR_PCU_MISC_MODE2_CFP_IGNORE;665 666		REG_WRITE(ah, AR_PCU_MISC_MODE2, val);667	}668 669	if (AR_SREV_9280_20_OR_LATER(ah))670		return;671	/*672	 * Disable BB clock gating673	 * Necessary to avoid issues on AR5416 2.0674	 */675	REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);676 677	/*678	 * Disable RIFS search on some chips to avoid baseband679	 * hang issues.680	 */681	if (AR_SREV_9100(ah) || AR_SREV_9160(ah)) {682		val = REG_READ(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS);683		val &= ~AR_PHY_RIFS_INIT_DELAY;684		REG_WRITE(ah, AR_PHY_HEAVY_CLIP_FACTOR_RIFS, val);685	}686}687 688static void ar5008_hw_set_channel_regs(struct ath_hw *ah,689				       struct ath9k_channel *chan)690{691	u32 phymode;692	u32 enableDacFifo = 0;693 694	if (AR_SREV_9285_12_OR_LATER(ah))695		enableDacFifo = (REG_READ(ah, AR_PHY_TURBO) &696					 AR_PHY_FC_ENABLE_DAC_FIFO);697 698	phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40699		| AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH | enableDacFifo;700 701	if (IS_CHAN_HT40(chan)) {702		phymode |= AR_PHY_FC_DYN2040_EN;703 704		if (IS_CHAN_HT40PLUS(chan))705			phymode |= AR_PHY_FC_DYN2040_PRI_CH;706 707	}708	ENABLE_REGWRITE_BUFFER(ah);709	REG_WRITE(ah, AR_PHY_TURBO, phymode);710 711	/* This function do only REG_WRITE, so712	 * we can include it to REGWRITE_BUFFER. */713	ath9k_hw_set11nmac2040(ah, chan);714 715	REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);716	REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);717 718	REGWRITE_BUFFER_FLUSH(ah);719}720 721 722static int ar5008_hw_process_ini(struct ath_hw *ah,723				 struct ath9k_channel *chan)724{725	struct ath_common *common = ath9k_hw_common(ah);726	int i, regWrites = 0;727	u32 modesIndex, freqIndex;728 729	if (IS_CHAN_5GHZ(chan)) {730		freqIndex = 1;731		modesIndex = IS_CHAN_HT40(chan) ? 2 : 1;732	} else {733		freqIndex = 2;734		modesIndex = IS_CHAN_HT40(chan) ? 3 : 4;735	}736 737	/*738	 * Set correct baseband to analog shift setting to739	 * access analog chips.740	 */741	REG_WRITE(ah, AR_PHY(0), 0x00000007);742 743	/* Write ADDAC shifts */744	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);745	if (ah->eep_ops->set_addac)746		ah->eep_ops->set_addac(ah, chan);747 748	REG_WRITE_ARRAY(&ah->iniAddac, 1, regWrites);749	REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);750 751	ENABLE_REGWRITE_BUFFER(ah);752 753	for (i = 0; i < ah->iniModes.ia_rows; i++) {754		u32 reg = INI_RA(&ah->iniModes, i, 0);755		u32 val = INI_RA(&ah->iniModes, i, modesIndex);756 757		if (reg == AR_AN_TOP2 && ah->need_an_top2_fixup)758			val &= ~AR_AN_TOP2_PWDCLKIND;759 760		REG_WRITE(ah, reg, val);761 762		if (reg >= 0x7800 && reg < 0x78a0763		    && ah->config.analog_shiftreg764		    && (common->bus_ops->ath_bus_type != ATH_USB)) {765			udelay(100);766		}767 768		DO_DELAY(regWrites);769	}770 771	REGWRITE_BUFFER_FLUSH(ah);772 773	if (AR_SREV_9280(ah) || AR_SREV_9287_11_OR_LATER(ah))774		REG_WRITE_ARRAY(&ah->iniModesRxGain, modesIndex, regWrites);775 776	if (AR_SREV_9280(ah) || AR_SREV_9285_12_OR_LATER(ah) ||777	    AR_SREV_9287_11_OR_LATER(ah))778		REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites);779 780	if (AR_SREV_9271_10(ah)) {781		REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENA);782		REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_ADC_ON, 0xa);783	}784 785	ENABLE_REGWRITE_BUFFER(ah);786 787	/* Write common array parameters */788	for (i = 0; i < ah->iniCommon.ia_rows; i++) {789		u32 reg = INI_RA(&ah->iniCommon, i, 0);790		u32 val = INI_RA(&ah->iniCommon, i, 1);791 792		REG_WRITE(ah, reg, val);793 794		if (reg >= 0x7800 && reg < 0x78a0795		    && ah->config.analog_shiftreg796		    && (common->bus_ops->ath_bus_type != ATH_USB)) {797			udelay(100);798		}799 800		DO_DELAY(regWrites);801	}802 803	REGWRITE_BUFFER_FLUSH(ah);804 805	REG_WRITE_ARRAY(&ah->iniBB_RfGain, freqIndex, regWrites);806 807	if (IS_CHAN_A_FAST_CLOCK(ah, chan))808		REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex,809				regWrites);810 811	ar5008_hw_override_ini(ah, chan);812	ar5008_hw_set_channel_regs(ah, chan);813	ar5008_hw_init_chain_masks(ah);814	ath9k_olc_init(ah);815	ath9k_hw_apply_txpower(ah, chan, false);816 817	/* Write analog registers */818	if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {819		ath_err(ath9k_hw_common(ah), "ar5416SetRfRegs failed\n");820		return -EIO;821	}822 823	return 0;824}825 826static void ar5008_hw_set_rfmode(struct ath_hw *ah, struct ath9k_channel *chan)827{828	u32 rfMode = 0;829 830	if (chan == NULL)831		return;832 833	if (IS_CHAN_2GHZ(chan))834		rfMode |= AR_PHY_MODE_DYNAMIC;835	else836		rfMode |= AR_PHY_MODE_OFDM;837 838	if (!AR_SREV_9280_20_OR_LATER(ah))839		rfMode |= (IS_CHAN_5GHZ(chan)) ?840			AR_PHY_MODE_RF5GHZ : AR_PHY_MODE_RF2GHZ;841 842	if (IS_CHAN_A_FAST_CLOCK(ah, chan))843		rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);844 845	REG_WRITE(ah, AR_PHY_MODE, rfMode);846}847 848static void ar5008_hw_mark_phy_inactive(struct ath_hw *ah)849{850	REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);851}852 853static void ar5008_hw_set_delta_slope(struct ath_hw *ah,854				      struct ath9k_channel *chan)855{856	u32 coef_scaled, ds_coef_exp, ds_coef_man;857	u32 clockMhzScaled = 0x64000000;858	struct chan_centers centers;859 860	if (IS_CHAN_HALF_RATE(chan))861		clockMhzScaled = clockMhzScaled >> 1;862	else if (IS_CHAN_QUARTER_RATE(chan))863		clockMhzScaled = clockMhzScaled >> 2;864 865	ath9k_hw_get_channel_centers(ah, chan, &centers);866	coef_scaled = clockMhzScaled / centers.synth_center;867 868	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,869				      &ds_coef_exp);870 871	REG_RMW_FIELD(ah, AR_PHY_TIMING3,872		      AR_PHY_TIMING3_DSC_MAN, ds_coef_man);873	REG_RMW_FIELD(ah, AR_PHY_TIMING3,874		      AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);875 876	coef_scaled = (9 * coef_scaled) / 10;877 878	ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,879				      &ds_coef_exp);880 881	REG_RMW_FIELD(ah, AR_PHY_HALFGI,882		      AR_PHY_HALFGI_DSC_MAN, ds_coef_man);883	REG_RMW_FIELD(ah, AR_PHY_HALFGI,884		      AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);885}886 887static bool ar5008_hw_rfbus_req(struct ath_hw *ah)888{889	REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);890	return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,891			   AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);892}893 894static void ar5008_hw_rfbus_done(struct ath_hw *ah)895{896	u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;897 898	ath9k_hw_synth_delay(ah, ah->curchan, synthDelay);899 900	REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);901}902 903static void ar5008_restore_chainmask(struct ath_hw *ah)904{905	int rx_chainmask = ah->rxchainmask;906 907	if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {908		REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);909		REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);910	}911}912 913static u32 ar9160_hw_compute_pll_control(struct ath_hw *ah,914					 struct ath9k_channel *chan)915{916	u32 pll;917 918	pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);919 920	if (chan && IS_CHAN_HALF_RATE(chan))921		pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);922	else if (chan && IS_CHAN_QUARTER_RATE(chan))923		pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);924 925	if (chan && IS_CHAN_5GHZ(chan))926		pll |= SM(0x50, AR_RTC_9160_PLL_DIV);927	else928		pll |= SM(0x58, AR_RTC_9160_PLL_DIV);929 930	return pll;931}932 933static u32 ar5008_hw_compute_pll_control(struct ath_hw *ah,934					 struct ath9k_channel *chan)935{936	u32 pll;937 938	pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;939 940	if (chan && IS_CHAN_HALF_RATE(chan))941		pll |= SM(0x1, AR_RTC_PLL_CLKSEL);942	else if (chan && IS_CHAN_QUARTER_RATE(chan))943		pll |= SM(0x2, AR_RTC_PLL_CLKSEL);944 945	if (chan && IS_CHAN_5GHZ(chan))946		pll |= SM(0xa, AR_RTC_PLL_DIV);947	else948		pll |= SM(0xb, AR_RTC_PLL_DIV);949 950	return pll;951}952 953static bool ar5008_hw_ani_control_new(struct ath_hw *ah,954				      enum ath9k_ani_cmd cmd,955				      int param)956{957	struct ath_common *common = ath9k_hw_common(ah);958	struct ath9k_channel *chan = ah->curchan;959	struct ar5416AniState *aniState = &ah->ani;960	s32 value;961 962	switch (cmd & ah->ani_function) {963	case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{964		/*965		 * on == 1 means ofdm weak signal detection is ON966		 * on == 1 is the default, for less noise immunity967		 *968		 * on == 0 means ofdm weak signal detection is OFF969		 * on == 0 means more noise imm970		 */971		u32 on = param ? 1 : 0;972		/*973		 * make register setting for default974		 * (weak sig detect ON) come from INI file975		 */976		int m1ThreshLow = on ?977			aniState->iniDef.m1ThreshLow : m1ThreshLow_off;978		int m2ThreshLow = on ?979			aniState->iniDef.m2ThreshLow : m2ThreshLow_off;980		int m1Thresh = on ?981			aniState->iniDef.m1Thresh : m1Thresh_off;982		int m2Thresh = on ?983			aniState->iniDef.m2Thresh : m2Thresh_off;984		int m2CountThr = on ?985			aniState->iniDef.m2CountThr : m2CountThr_off;986		int m2CountThrLow = on ?987			aniState->iniDef.m2CountThrLow : m2CountThrLow_off;988		int m1ThreshLowExt = on ?989			aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;990		int m2ThreshLowExt = on ?991			aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;992		int m1ThreshExt = on ?993			aniState->iniDef.m1ThreshExt : m1ThreshExt_off;994		int m2ThreshExt = on ?995			aniState->iniDef.m2ThreshExt : m2ThreshExt_off;996 997		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,998			      AR_PHY_SFCORR_LOW_M1_THRESH_LOW,999			      m1ThreshLow);1000		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,1001			      AR_PHY_SFCORR_LOW_M2_THRESH_LOW,1002			      m2ThreshLow);1003		REG_RMW_FIELD(ah, AR_PHY_SFCORR,1004			      AR_PHY_SFCORR_M1_THRESH, m1Thresh);1005		REG_RMW_FIELD(ah, AR_PHY_SFCORR,1006			      AR_PHY_SFCORR_M2_THRESH, m2Thresh);1007		REG_RMW_FIELD(ah, AR_PHY_SFCORR,1008			      AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);1009		REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,1010			      AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,1011			      m2CountThrLow);1012 1013		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,1014			      AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);1015		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,1016			      AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);1017		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,1018			      AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);1019		REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,1020			      AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);1021 1022		if (on)1023			REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,1024				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);1025		else1026			REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,1027				    AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);1028 1029		if (on != aniState->ofdmWeakSigDetect) {1030			ath_dbg(common, ANI,1031				"** ch %d: ofdm weak signal: %s=>%s\n",1032				chan->channel,1033				aniState->ofdmWeakSigDetect ?1034				"on" : "off",1035				on ? "on" : "off");1036			if (on)1037				ah->stats.ast_ani_ofdmon++;1038			else1039				ah->stats.ast_ani_ofdmoff++;1040			aniState->ofdmWeakSigDetect = on;1041		}1042		break;1043	}1044	case ATH9K_ANI_FIRSTEP_LEVEL:{1045		u32 level = param;1046 1047		value = level * 2;1048		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,1049			      AR_PHY_FIND_SIG_FIRSTEP, value);1050		REG_RMW_FIELD(ah, AR_PHY_FIND_SIG_LOW,1051			      AR_PHY_FIND_SIG_FIRSTEP_LOW, value);1052 1053		if (level != aniState->firstepLevel) {1054			ath_dbg(common, ANI,1055				"** ch %d: level %d=>%d[def:%d] firstep[level]=%d ini=%d\n",1056				chan->channel,1057				aniState->firstepLevel,1058				level,1059				ATH9K_ANI_FIRSTEP_LVL,1060				value,1061				aniState->iniDef.firstep);1062			ath_dbg(common, ANI,1063				"** ch %d: level %d=>%d[def:%d] firstep_low[level]=%d ini=%d\n",1064				chan->channel,1065				aniState->firstepLevel,1066				level,1067				ATH9K_ANI_FIRSTEP_LVL,1068				value,1069				aniState->iniDef.firstepLow);1070			if (level > aniState->firstepLevel)1071				ah->stats.ast_ani_stepup++;1072			else if (level < aniState->firstepLevel)1073				ah->stats.ast_ani_stepdown++;1074			aniState->firstepLevel = level;1075		}1076		break;1077	}1078	case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{1079		u32 level = param;1080 1081		value = (level + 1) * 2;1082		REG_RMW_FIELD(ah, AR_PHY_TIMING5,1083			      AR_PHY_TIMING5_CYCPWR_THR1, value);1084 1085		REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,1086				  AR_PHY_EXT_TIMING5_CYCPWR_THR1, value - 1);1087 1088		if (level != aniState->spurImmunityLevel) {1089			ath_dbg(common, ANI,1090				"** ch %d: level %d=>%d[def:%d] cycpwrThr1[level]=%d ini=%d\n",1091				chan->channel,1092				aniState->spurImmunityLevel,1093				level,1094				ATH9K_ANI_SPUR_IMMUNE_LVL,1095				value,1096				aniState->iniDef.cycpwrThr1);1097			ath_dbg(common, ANI,1098				"** ch %d: level %d=>%d[def:%d] cycpwrThr1Ext[level]=%d ini=%d\n",1099				chan->channel,1100				aniState->spurImmunityLevel,1101				level,1102				ATH9K_ANI_SPUR_IMMUNE_LVL,1103				value,1104				aniState->iniDef.cycpwrThr1Ext);1105			if (level > aniState->spurImmunityLevel)1106				ah->stats.ast_ani_spurup++;1107			else if (level < aniState->spurImmunityLevel)1108				ah->stats.ast_ani_spurdown++;1109			aniState->spurImmunityLevel = level;1110		}1111		break;1112	}1113	case ATH9K_ANI_MRC_CCK:1114		/*1115		 * You should not see this as AR5008, AR9001, AR90021116		 * does not have hardware support for MRC CCK.1117		 */1118		WARN_ON(1);1119		break;1120	default:1121		ath_dbg(common, ANI, "invalid cmd %u\n", cmd);1122		return false;1123	}1124 1125	ath_dbg(common, ANI,1126		"ANI parameters: SI=%d, ofdmWS=%s FS=%d MRCcck=%s listenTime=%d ofdmErrs=%d cckErrs=%d\n",1127		aniState->spurImmunityLevel,1128		aniState->ofdmWeakSigDetect ? "on" : "off",1129		aniState->firstepLevel,1130		aniState->mrcCCK ? "on" : "off",1131		aniState->listenTime,1132		aniState->ofdmPhyErrCount,1133		aniState->cckPhyErrCount);1134	return true;1135}1136 1137static void ar5008_hw_do_getnf(struct ath_hw *ah,1138			      int16_t nfarray[NUM_NF_READINGS])1139{1140	int16_t nf;1141 1142	nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);1143	nfarray[0] = sign_extend32(nf, 8);1144 1145	nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR_PHY_CH1_MINCCA_PWR);1146	nfarray[1] = sign_extend32(nf, 8);1147 1148	nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);1149	nfarray[2] = sign_extend32(nf, 8);1150 1151	if (!IS_CHAN_HT40(ah->curchan))1152		return;1153 1154	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);1155	nfarray[3] = sign_extend32(nf, 8);1156 1157	nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR_PHY_CH1_EXT_MINCCA_PWR);1158	nfarray[4] = sign_extend32(nf, 8);1159 1160	nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA), AR_PHY_CH2_EXT_MINCCA_PWR);1161	nfarray[5] = sign_extend32(nf, 8);1162}1163 1164/*1165 * Initialize the ANI register values with default (ini) values.1166 * This routine is called during a (full) hardware reset after1167 * all the registers are initialised from the INI.1168 */1169static void ar5008_hw_ani_cache_ini_regs(struct ath_hw *ah)1170{1171	struct ath_common *common = ath9k_hw_common(ah);1172	struct ath9k_channel *chan = ah->curchan;1173	struct ar5416AniState *aniState = &ah->ani;1174	struct ath9k_ani_default *iniDef;1175	u32 val;1176 1177	iniDef = &aniState->iniDef;1178 1179	ath_dbg(common, ANI, "ver %d.%d opmode %u chan %d Mhz\n",1180		ah->hw_version.macVersion,1181		ah->hw_version.macRev,1182		ah->opmode,1183		chan->channel);1184 1185	val = REG_READ(ah, AR_PHY_SFCORR);1186	iniDef->m1Thresh = MS(val, AR_PHY_SFCORR_M1_THRESH);1187	iniDef->m2Thresh = MS(val, AR_PHY_SFCORR_M2_THRESH);1188	iniDef->m2CountThr = MS(val, AR_PHY_SFCORR_M2COUNT_THR);1189 1190	val = REG_READ(ah, AR_PHY_SFCORR_LOW);1191	iniDef->m1ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M1_THRESH_LOW);1192	iniDef->m2ThreshLow = MS(val, AR_PHY_SFCORR_LOW_M2_THRESH_LOW);1193	iniDef->m2CountThrLow = MS(val, AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW);1194 1195	val = REG_READ(ah, AR_PHY_SFCORR_EXT);1196	iniDef->m1ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH);1197	iniDef->m2ThreshExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH);1198	iniDef->m1ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M1_THRESH_LOW);1199	iniDef->m2ThreshLowExt = MS(val, AR_PHY_SFCORR_EXT_M2_THRESH_LOW);1200	iniDef->firstep = REG_READ_FIELD(ah,1201					 AR_PHY_FIND_SIG,1202					 AR_PHY_FIND_SIG_FIRSTEP);1203	iniDef->firstepLow = REG_READ_FIELD(ah,1204					    AR_PHY_FIND_SIG_LOW,1205					    AR_PHY_FIND_SIG_FIRSTEP_LOW);1206	iniDef->cycpwrThr1 = REG_READ_FIELD(ah,1207					    AR_PHY_TIMING5,1208					    AR_PHY_TIMING5_CYCPWR_THR1);1209	iniDef->cycpwrThr1Ext = REG_READ_FIELD(ah,1210					       AR_PHY_EXT_CCA,1211					       AR_PHY_EXT_TIMING5_CYCPWR_THR1);1212 1213	/* these levels just got reset to defaults by the INI */1214	aniState->spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;1215	aniState->firstepLevel = ATH9K_ANI_FIRSTEP_LVL;1216	aniState->ofdmWeakSigDetect = true;1217	aniState->mrcCCK = false; /* not available on pre AR9003 */1218}1219 1220static void ar5008_hw_set_nf_limits(struct ath_hw *ah)1221{1222	ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;1223	ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;1224	ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;1225	ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;1226	ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;1227	ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;1228}1229 1230static void ar5008_hw_set_radar_params(struct ath_hw *ah,1231				       struct ath_hw_radar_conf *conf)1232{1233	u32 radar_0 = 0, radar_1;1234 1235	if (!conf) {1236		REG_CLR_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_ENA);1237		return;1238	}1239 1240	radar_0 |= AR_PHY_RADAR_0_ENA | AR_PHY_RADAR_0_FFT_ENA;1241	radar_0 |= SM(conf->fir_power, AR_PHY_RADAR_0_FIRPWR);1242	radar_0 |= SM(conf->radar_rssi, AR_PHY_RADAR_0_RRSSI);1243	radar_0 |= SM(conf->pulse_height, AR_PHY_RADAR_0_HEIGHT);1244	radar_0 |= SM(conf->pulse_rssi, AR_PHY_RADAR_0_PRSSI);1245	radar_0 |= SM(conf->pulse_inband, AR_PHY_RADAR_0_INBAND);1246 1247	radar_1 = REG_READ(ah, AR_PHY_RADAR_1);1248	radar_1 &= ~(AR_PHY_RADAR_1_MAXLEN | AR_PHY_RADAR_1_RELSTEP_THRESH |1249		     AR_PHY_RADAR_1_RELPWR_THRESH);1250	radar_1 |= AR_PHY_RADAR_1_MAX_RRSSI;1251	radar_1 |= AR_PHY_RADAR_1_BLOCK_CHECK;1252	radar_1 |= SM(conf->pulse_maxlen, AR_PHY_RADAR_1_MAXLEN);1253	radar_1 |= SM(conf->pulse_inband_step, AR_PHY_RADAR_1_RELSTEP_THRESH);1254	radar_1 |= SM(conf->radar_inband, AR_PHY_RADAR_1_RELPWR_THRESH);1255 1256	REG_WRITE(ah, AR_PHY_RADAR_0, radar_0);1257	REG_WRITE(ah, AR_PHY_RADAR_1, radar_1);1258	if (conf->ext_channel)1259		REG_SET_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);1260	else1261		REG_CLR_BIT(ah, AR_PHY_RADAR_EXT, AR_PHY_RADAR_EXT_ENA);1262}1263 1264static void ar5008_hw_set_radar_conf(struct ath_hw *ah)1265{1266	struct ath_hw_radar_conf *conf = &ah->radar_conf;1267 1268	conf->fir_power = -33;1269	conf->radar_rssi = 20;1270	conf->pulse_height = 10;1271	conf->pulse_rssi = 15;1272	conf->pulse_inband = 15;1273	conf->pulse_maxlen = 255;1274	conf->pulse_inband_step = 12;1275	conf->radar_inband = 8;1276}1277 1278static void ar5008_hw_init_txpower_cck(struct ath_hw *ah, int16_t *rate_array)1279{1280#define CCK_DELTA(_ah, x) ((OLC_FOR_AR9280_20_LATER(_ah)) ? max((x) - 2, 0) : (x))1281	ah->tx_power[0] = CCK_DELTA(ah, rate_array[rate1l]);1282	ah->tx_power[1] = CCK_DELTA(ah, min(rate_array[rate2l],1283					rate_array[rate2s]));1284	ah->tx_power[2] = CCK_DELTA(ah, min(rate_array[rate5_5l],1285					rate_array[rate5_5s]));1286	ah->tx_power[3] = CCK_DELTA(ah, min(rate_array[rate11l],1287					rate_array[rate11s]));1288#undef CCK_DELTA1289}1290 1291static void ar5008_hw_init_txpower_ofdm(struct ath_hw *ah, int16_t *rate_array,1292					int offset)1293{1294	int i, idx = 0;1295 1296	for (i = offset; i < offset + AR5008_OFDM_RATES; i++) {1297		ah->tx_power[i] = rate_array[idx];1298		idx++;1299	}1300}1301 1302static void ar5008_hw_init_txpower_ht(struct ath_hw *ah, int16_t *rate_array,1303				      int ss_offset, int ds_offset,1304				      bool is_40, int ht40_delta)1305{1306	int i, mcs_idx = (is_40) ? AR5008_HT40_SHIFT : AR5008_HT20_SHIFT;1307 1308	for (i = ss_offset; i < ss_offset + AR5008_HT_SS_RATES; i++) {1309		ah->tx_power[i] = rate_array[mcs_idx] + ht40_delta;1310		mcs_idx++;1311	}1312	memcpy(&ah->tx_power[ds_offset], &ah->tx_power[ss_offset],1313	       AR5008_HT_SS_RATES);1314}1315 1316void ar5008_hw_init_rate_txpower(struct ath_hw *ah, int16_t *rate_array,1317				 struct ath9k_channel *chan, int ht40_delta)1318{1319	if (IS_CHAN_5GHZ(chan)) {1320		ar5008_hw_init_txpower_ofdm(ah, rate_array,1321					    AR5008_11NA_OFDM_SHIFT);1322		if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {1323			ar5008_hw_init_txpower_ht(ah, rate_array,1324						  AR5008_11NA_HT_SS_SHIFT,1325						  AR5008_11NA_HT_DS_SHIFT,1326						  IS_CHAN_HT40(chan),1327						  ht40_delta);1328		}1329	} else {1330		ar5008_hw_init_txpower_cck(ah, rate_array);1331		ar5008_hw_init_txpower_ofdm(ah, rate_array,1332					    AR5008_11NG_OFDM_SHIFT);1333		if (IS_CHAN_HT20(chan) || IS_CHAN_HT40(chan)) {1334			ar5008_hw_init_txpower_ht(ah, rate_array,1335						  AR5008_11NG_HT_SS_SHIFT,1336						  AR5008_11NG_HT_DS_SHIFT,1337						  IS_CHAN_HT40(chan),1338						  ht40_delta);1339		}1340	}1341}1342 1343int ar5008_hw_attach_phy_ops(struct ath_hw *ah)1344{1345	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);1346	static const u32 ar5416_cca_regs[6] = {1347		AR_PHY_CCA,1348		AR_PHY_CH1_CCA,1349		AR_PHY_CH2_CCA,1350		AR_PHY_EXT_CCA,1351		AR_PHY_CH1_EXT_CCA,1352		AR_PHY_CH2_EXT_CCA1353	};1354	int ret;1355 1356	ret = ar5008_hw_rf_alloc_ext_banks(ah);1357	if (ret)1358	    return ret;1359 1360	priv_ops->rf_set_freq = ar5008_hw_set_channel;1361	priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;1362 1363	priv_ops->set_rf_regs = ar5008_hw_set_rf_regs;1364	priv_ops->set_channel_regs = ar5008_hw_set_channel_regs;1365	priv_ops->init_bb = ar5008_hw_init_bb;1366	priv_ops->process_ini = ar5008_hw_process_ini;1367	priv_ops->set_rfmode = ar5008_hw_set_rfmode;1368	priv_ops->mark_phy_inactive = ar5008_hw_mark_phy_inactive;1369	priv_ops->set_delta_slope = ar5008_hw_set_delta_slope;1370	priv_ops->rfbus_req = ar5008_hw_rfbus_req;1371	priv_ops->rfbus_done = ar5008_hw_rfbus_done;1372	priv_ops->restore_chainmask = ar5008_restore_chainmask;1373	priv_ops->do_getnf = ar5008_hw_do_getnf;1374	priv_ops->set_radar_params = ar5008_hw_set_radar_params;1375 1376	priv_ops->ani_control = ar5008_hw_ani_control_new;1377	priv_ops->ani_cache_ini_regs = ar5008_hw_ani_cache_ini_regs;1378 1379	if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))1380		priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;1381	else1382		priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;1383 1384	ar5008_hw_set_nf_limits(ah);1385	ar5008_hw_set_radar_conf(ah);1386	memcpy(ah->nf_regs, ar5416_cca_regs, sizeof(ah->nf_regs));1387	return 0;1388}1389