/*
 * Copyright (c) 2008-2011 Atheros Communications Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "hw.h"
#include <linux/ath9k_platform.h>

void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
{
        REG_WRITE(ah, reg, val);

        if (ah->config.analog_shiftreg)
		udelay(100);
}

void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
			       u32 shift, u32 val)
{
	REG_RMW(ah, reg, ((val << shift) & mask), mask);

	if (ah->config.analog_shiftreg)
		udelay(100);
}

int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
			     int16_t targetLeft, int16_t targetRight)
{
	int16_t rv;

	if (srcRight == srcLeft) {
		rv = targetLeft;
	} else {
		rv = (int16_t) (((target - srcLeft) * targetRight +
				 (srcRight - target) * targetLeft) /
				(srcRight - srcLeft));
	}
	return rv;
}

bool ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
				    u16 *indexL, u16 *indexR)
{
	u16 i;

	if (target <= pList[0]) {
		*indexL = *indexR = 0;
		return true;
	}
	if (target >= pList[listSize - 1]) {
		*indexL = *indexR = (u16) (listSize - 1);
		return true;
	}

	for (i = 0; i < listSize - 1; i++) {
		if (pList[i] == target) {
			*indexL = *indexR = i;
			return true;
		}
		if (target < pList[i + 1]) {
			*indexL = i;
			*indexR = (u16) (i + 1);
			return false;
		}
	}
	return false;
}

void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
				  int eep_start_loc, int size)
{
	int i = 0, j, addr;
	u32 addrdata[8];
	u32 data[8];

	for (addr = 0; addr < size; addr++) {
		addrdata[i] = AR5416_EEPROM_OFFSET +
			((addr + eep_start_loc) << AR5416_EEPROM_S);
		i++;
		if (i == 8) {
			REG_READ_MULTI(ah, addrdata, data, i);

			for (j = 0; j < i; j++) {
				*eep_data = data[j];
				eep_data++;
			}
			i = 0;
		}
	}

	if (i != 0) {
		REG_READ_MULTI(ah, addrdata, data, i);

		for (j = 0; j < i; j++) {
			*eep_data = data[j];
			eep_data++;
		}
	}
}

static bool ath9k_hw_nvram_read_array(u16 *blob, size_t blob_size,
				      off_t offset, u16 *data)
{
	if (offset >= blob_size)
		return false;

	*data =  blob[offset];
	return true;
}

static bool ath9k_hw_nvram_read_pdata(struct ath9k_platform_data *pdata,
				      off_t offset, u16 *data)
{
	return ath9k_hw_nvram_read_array(pdata->eeprom_data,
					 ARRAY_SIZE(pdata->eeprom_data),
					 offset, data);
}

static bool ath9k_hw_nvram_read_firmware(const struct firmware *eeprom_blob,
					 off_t offset, u16 *data)
{
	return ath9k_hw_nvram_read_array((u16 *) eeprom_blob->data,
					 eeprom_blob->size / sizeof(u16),
					 offset, data);
}

static bool ath9k_hw_nvram_read_nvmem(struct ath_hw *ah, off_t offset,
				      u16 *data)
{
	return ath9k_hw_nvram_read_array(ah->nvmem_blob,
					 ah->nvmem_blob_len / sizeof(u16),
					 offset, data);
}

bool ath9k_hw_nvram_read(struct ath_hw *ah, u32 off, u16 *data)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath9k_platform_data *pdata = ah->dev->platform_data;
	bool ret;

	if (ah->nvmem_blob)
		ret = ath9k_hw_nvram_read_nvmem(ah, off, data);
	else if (ah->eeprom_blob)
		ret = ath9k_hw_nvram_read_firmware(ah->eeprom_blob, off, data);
	else if (pdata && !pdata->use_eeprom)
		ret = ath9k_hw_nvram_read_pdata(pdata, off, data);
	else
		ret = common->bus_ops->eeprom_read(common, off, data);

	if (!ret)
		ath_dbg(common, EEPROM,
			"unable to read eeprom region at offset %u\n", off);

	return ret;
}

int ath9k_hw_nvram_swap_data(struct ath_hw *ah, bool *swap_needed, int size)
{
	u16 magic;
	u16 *eepdata;
	int i;
	bool needs_byteswap = false;
	struct ath_common *common = ath9k_hw_common(ah);

	if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET, &magic)) {
		ath_err(common, "Reading Magic # failed\n");
		return -EIO;
	}

	if (swab16(magic) == AR5416_EEPROM_MAGIC) {
		needs_byteswap = true;
		ath_dbg(common, EEPROM,
			"EEPROM needs byte-swapping to correct endianness.\n");
	} else if (magic != AR5416_EEPROM_MAGIC) {
		if (ath9k_hw_use_flash(ah)) {
			ath_dbg(common, EEPROM,
				"Ignoring invalid EEPROM magic (0x%04x).\n",
				magic);
		} else {
			ath_err(common,
				"Invalid EEPROM magic (0x%04x).\n", magic);
			return -EINVAL;
		}
	}

	if (needs_byteswap) {
		if (ah->ah_flags & AH_NO_EEP_SWAP) {
			ath_info(common,
				 "Ignoring endianness difference in EEPROM magic bytes.\n");
		} else {
			eepdata = (u16 *)(&ah->eeprom);

			for (i = 0; i < size; i++)
				eepdata[i] = swab16(eepdata[i]);
		}
	}

	if (ah->eep_ops->get_eepmisc(ah) & AR5416_EEPMISC_BIG_ENDIAN) {
		*swap_needed = true;
		ath_dbg(common, EEPROM,
			"Big Endian EEPROM detected according to EEPMISC register.\n");
	} else {
		*swap_needed = false;
	}

	return 0;
}

bool ath9k_hw_nvram_validate_checksum(struct ath_hw *ah, int size)
{
	u32 i, sum = 0;
	u16 *eepdata = (u16 *)(&ah->eeprom);
	struct ath_common *common = ath9k_hw_common(ah);

	for (i = 0; i < size; i++)
		sum ^= eepdata[i];

	if (sum != 0xffff) {
		ath_err(common, "Bad EEPROM checksum 0x%x\n", sum);
		return false;
	}

	return true;
}

bool ath9k_hw_nvram_check_version(struct ath_hw *ah, int version, int minrev)
{
	struct ath_common *common = ath9k_hw_common(ah);

	if (ah->eep_ops->get_eeprom_ver(ah) != version ||
	    ah->eep_ops->get_eeprom_rev(ah) < minrev) {
		ath_err(common, "Bad EEPROM VER 0x%04x or REV 0x%04x\n",
			ah->eep_ops->get_eeprom_ver(ah),
			ah->eep_ops->get_eeprom_rev(ah));
		return false;
	}

	return true;
}

void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
			     u8 *pVpdList, u16 numIntercepts,
			     u8 *pRetVpdList)
{
	u16 i, k;
	u8 currPwr = pwrMin;
	u16 idxL = 0, idxR = 0;

	for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
		ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
					       numIntercepts, &(idxL),
					       &(idxR));
		if (idxR < 1)
			idxR = 1;
		if (idxL == numIntercepts - 1)
			idxL = (u16) (numIntercepts - 2);
		if (pPwrList[idxL] == pPwrList[idxR])
			k = pVpdList[idxL];
		else
			k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
				   (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
				  (pPwrList[idxR] - pPwrList[idxL]));
		pRetVpdList[i] = (u8) k;
		currPwr += 2;
	}
}

void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
				       struct ath9k_channel *chan,
				       struct cal_target_power_leg *powInfo,
				       u16 numChannels,
				       struct cal_target_power_leg *pNewPower,
				       u16 numRates, bool isExtTarget)
{
	struct chan_centers centers;
	u16 clo, chi;
	int i;
	int matchIndex = -1, lowIndex = -1;
	u16 freq;

	ath9k_hw_get_channel_centers(ah, chan, &centers);
	freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;

	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
				       IS_CHAN_2GHZ(chan))) {
		matchIndex = 0;
	} else {
		for (i = 0; (i < numChannels) &&
			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
						       IS_CHAN_2GHZ(chan))) {
				matchIndex = i;
				break;
			} else if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
						IS_CHAN_2GHZ(chan)) && i > 0 &&
				   freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
						IS_CHAN_2GHZ(chan))) {
				lowIndex = i - 1;
				break;
			}
		}
		if ((matchIndex == -1) && (lowIndex == -1))
			matchIndex = i - 1;
	}

	if (matchIndex != -1) {
		*pNewPower = powInfo[matchIndex];
	} else {
		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
					 IS_CHAN_2GHZ(chan));
		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
					 IS_CHAN_2GHZ(chan));

		for (i = 0; i < numRates; i++) {
			pNewPower->tPow2x[i] =
				(u8)ath9k_hw_interpolate(freq, clo, chi,
						powInfo[lowIndex].tPow2x[i],
						powInfo[lowIndex + 1].tPow2x[i]);
		}
	}
}

void ath9k_hw_get_target_powers(struct ath_hw *ah,
				struct ath9k_channel *chan,
				struct cal_target_power_ht *powInfo,
				u16 numChannels,
				struct cal_target_power_ht *pNewPower,
				u16 numRates, bool isHt40Target)
{
	struct chan_centers centers;
	u16 clo, chi;
	int i;
	int matchIndex = -1, lowIndex = -1;
	u16 freq;

	ath9k_hw_get_channel_centers(ah, chan, &centers);
	freq = isHt40Target ? centers.synth_center : centers.ctl_center;

	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
		matchIndex = 0;
	} else {
		for (i = 0; (i < numChannels) &&
			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
						       IS_CHAN_2GHZ(chan))) {
				matchIndex = i;
				break;
			} else
				if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
						IS_CHAN_2GHZ(chan)) && i > 0 &&
				    freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
						IS_CHAN_2GHZ(chan))) {
					lowIndex = i - 1;
					break;
				}
		}
		if ((matchIndex == -1) && (lowIndex == -1))
			matchIndex = i - 1;
	}

	if (matchIndex != -1) {
		*pNewPower = powInfo[matchIndex];
	} else {
		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
					 IS_CHAN_2GHZ(chan));
		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
					 IS_CHAN_2GHZ(chan));

		for (i = 0; i < numRates; i++) {
			pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
						clo, chi,
						powInfo[lowIndex].tPow2x[i],
						powInfo[lowIndex + 1].tPow2x[i]);
		}
	}
}

u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
				bool is2GHz, int num_band_edges)
{
	u16 twiceMaxEdgePower = MAX_RATE_POWER;
	int i;

	for (i = 0; (i < num_band_edges) &&
		     (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
		if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
			twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
			break;
		} else if ((i > 0) &&
			   (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
						      is2GHz))) {
			if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
					       is2GHz) < freq &&
			    CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
				twiceMaxEdgePower =
					CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
			}
			break;
		}
	}

	return twiceMaxEdgePower;
}

u16 ath9k_hw_get_scaled_power(struct ath_hw *ah, u16 power_limit,
			      u8 antenna_reduction)
{
	u16 reduction = antenna_reduction;

	/*
	 * Reduce scaled Power by number of chains active
	 * to get the per chain tx power level.
	 */
	switch (ar5416_get_ntxchains(ah->txchainmask)) {
	case 1:
		break;
	case 2:
		reduction += POWER_CORRECTION_FOR_TWO_CHAIN;
		break;
	case 3:
		reduction += POWER_CORRECTION_FOR_THREE_CHAIN;
		break;
	}

	if (power_limit > reduction)
		power_limit -= reduction;
	else
		power_limit = 0;

	return min_t(u16, power_limit, MAX_RATE_POWER);
}

void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
{
	struct ath_common *common = ath9k_hw_common(ah);
	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);

	switch (ar5416_get_ntxchains(ah->txchainmask)) {
	case 1:
		break;
	case 2:
		regulatory->max_power_level += POWER_CORRECTION_FOR_TWO_CHAIN;
		break;
	case 3:
		regulatory->max_power_level += POWER_CORRECTION_FOR_THREE_CHAIN;
		break;
	default:
		ath_dbg(common, EEPROM, "Invalid chainmask configuration\n");
		break;
	}
}

void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
				struct ath9k_channel *chan,
				void *pRawDataSet,
				u8 *bChans, u16 availPiers,
				u16 tPdGainOverlap,
				u16 *pPdGainBoundaries, u8 *pPDADCValues,
				u16 numXpdGains)
{
	int i, j, k;
	int16_t ss;
	u16 idxL = 0, idxR = 0, numPiers;
	static u8 vpdTableL[AR5416_NUM_PD_GAINS]
		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
	static u8 vpdTableR[AR5416_NUM_PD_GAINS]
		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
	static u8 vpdTableI[AR5416_NUM_PD_GAINS]
		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];

	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
	u8 minPwrT4[AR5416_NUM_PD_GAINS];
	u8 maxPwrT4[AR5416_NUM_PD_GAINS];
	int16_t vpdStep;
	int16_t tmpVal;
	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
	bool match;
	int16_t minDelta = 0;
	struct chan_centers centers;
	int pdgain_boundary_default;
	struct cal_data_per_freq *data_def = pRawDataSet;
	struct cal_data_per_freq_4k *data_4k = pRawDataSet;
	struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
	bool eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
	int intercepts;

	if (AR_SREV_9287(ah))
		intercepts = AR9287_PD_GAIN_ICEPTS;
	else
		intercepts = AR5416_PD_GAIN_ICEPTS;

	memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
	ath9k_hw_get_channel_centers(ah, chan, &centers);

	for (numPiers = 0; numPiers < availPiers; numPiers++) {
		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
			break;
	}

	match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
							     IS_CHAN_2GHZ(chan)),
					       bChans, numPiers, &idxL, &idxR);

	if (match) {
		if (AR_SREV_9287(ah)) {
			for (i = 0; i < numXpdGains; i++) {
				minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
				maxPwrT4[i] = data_9287[idxL].pwrPdg[i][intercepts - 1];
				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
						data_9287[idxL].pwrPdg[i],
						data_9287[idxL].vpdPdg[i],
						intercepts,
						vpdTableI[i]);
			}
		} else if (eeprom_4k) {
			for (i = 0; i < numXpdGains; i++) {
				minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
				maxPwrT4[i] = data_4k[idxL].pwrPdg[i][intercepts - 1];
				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
						data_4k[idxL].pwrPdg[i],
						data_4k[idxL].vpdPdg[i],
						intercepts,
						vpdTableI[i]);
			}
		} else {
			for (i = 0; i < numXpdGains; i++) {
				minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
				maxPwrT4[i] = data_def[idxL].pwrPdg[i][intercepts - 1];
				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
						data_def[idxL].pwrPdg[i],
						data_def[idxL].vpdPdg[i],
						intercepts,
						vpdTableI[i]);
			}
		}
	} else {
		for (i = 0; i < numXpdGains; i++) {
			if (AR_SREV_9287(ah)) {
				pVpdL = data_9287[idxL].vpdPdg[i];
				pPwrL = data_9287[idxL].pwrPdg[i];
				pVpdR = data_9287[idxR].vpdPdg[i];
				pPwrR = data_9287[idxR].pwrPdg[i];
			} else if (eeprom_4k) {
				pVpdL = data_4k[idxL].vpdPdg[i];
				pPwrL = data_4k[idxL].pwrPdg[i];
				pVpdR = data_4k[idxR].vpdPdg[i];
				pPwrR = data_4k[idxR].pwrPdg[i];
			} else {
				pVpdL = data_def[idxL].vpdPdg[i];
				pPwrL = data_def[idxL].pwrPdg[i];
				pVpdR = data_def[idxR].vpdPdg[i];
				pPwrR = data_def[idxR].pwrPdg[i];
			}

			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);

			maxPwrT4[i] =
				min(pPwrL[intercepts - 1],
				    pPwrR[intercepts - 1]);


			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
						pPwrL, pVpdL,
						intercepts,
						vpdTableL[i]);
			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
						pPwrR, pVpdR,
						intercepts,
						vpdTableR[i]);

			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
				vpdTableI[i][j] =
					(u8)(ath9k_hw_interpolate((u16)
					     FREQ2FBIN(centers.
						       synth_center,
						       IS_CHAN_2GHZ
						       (chan)),
					     bChans[idxL], bChans[idxR],
					     vpdTableL[i][j], vpdTableR[i][j]));
			}
		}
	}

	k = 0;

	for (i = 0; i < numXpdGains; i++) {
		if (i == (numXpdGains - 1))
			pPdGainBoundaries[i] =
				(u16)(maxPwrT4[i] / 2);
		else
			pPdGainBoundaries[i] =
				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);

		pPdGainBoundaries[i] =
			min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);

		minDelta = 0;

		if (i == 0) {
			if (AR_SREV_9280_20_OR_LATER(ah))
				ss = (int16_t)(0 - (minPwrT4[i] / 2));
			else
				ss = 0;
		} else {
			ss = (int16_t)((pPdGainBoundaries[i - 1] -
					(minPwrT4[i] / 2)) -
				       tPdGainOverlap + 1 + minDelta);
		}
		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);

		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
			ss++;
		}

		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
				(minPwrT4[i] / 2));
		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
			tgtIndex : sizeCurrVpdTable;

		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
			pPDADCValues[k++] = vpdTableI[i][ss++];
		}

		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
				    vpdTableI[i][sizeCurrVpdTable - 2]);
		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);

		if (tgtIndex >= maxIndex) {
			while ((ss <= tgtIndex) &&
			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
				tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
						    (ss - maxIndex + 1) * vpdStep));
				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
							 255 : tmpVal);
				ss++;
			}
		}
	}

	if (eeprom_4k)
		pdgain_boundary_default = 58;
	else
		pdgain_boundary_default = pPdGainBoundaries[i - 1];

	while (i < AR5416_PD_GAINS_IN_MASK) {
		pPdGainBoundaries[i] = pdgain_boundary_default;
		i++;
	}

	while (k < AR5416_NUM_PDADC_VALUES) {
		pPDADCValues[k] = pPDADCValues[k - 1];
		k++;
	}
}

int ath9k_hw_eeprom_init(struct ath_hw *ah)
{
	int status;

	if (AR_SREV_9300_20_OR_LATER(ah))
		ah->eep_ops = &eep_ar9300_ops;
	else if (AR_SREV_9287(ah)) {
		ah->eep_ops = &eep_ar9287_ops;
	} else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
		ah->eep_ops = &eep_4k_ops;
	} else {
		ah->eep_ops = &eep_def_ops;
	}

	if (!ah->eep_ops->fill_eeprom(ah))
		return -EIO;

	status = ah->eep_ops->check_eeprom(ah);

	return status;
}
