cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

eeprom.c (49239B)


      1/*
      2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
      3 * Copyright (c) 2006-2009 Nick Kossifidis <mickflemm@gmail.com>
      4 * Copyright (c) 2008-2009 Felix Fietkau <nbd@openwrt.org>
      5 *
      6 * Permission to use, copy, modify, and distribute this software for any
      7 * purpose with or without fee is hereby granted, provided that the above
      8 * copyright notice and this permission notice appear in all copies.
      9 *
     10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     17 *
     18 */
     19
     20/*************************************\
     21* EEPROM access functions and helpers *
     22\*************************************/
     23
     24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     25
     26#include <linux/slab.h>
     27
     28#include "ath5k.h"
     29#include "reg.h"
     30#include "debug.h"
     31
     32
     33/******************\
     34* Helper functions *
     35\******************/
     36
     37/*
     38 * Translate binary channel representation in EEPROM to frequency
     39 */
     40static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,
     41							unsigned int mode)
     42{
     43	u16 val;
     44
     45	if (bin == AR5K_EEPROM_CHANNEL_DIS)
     46		return bin;
     47
     48	if (mode == AR5K_EEPROM_MODE_11A) {
     49		if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
     50			val = (5 * bin) + 4800;
     51		else
     52			val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
     53				(bin * 10) + 5100;
     54	} else {
     55		if (ee->ee_version > AR5K_EEPROM_VERSION_3_2)
     56			val = bin + 2300;
     57		else
     58			val = bin + 2400;
     59	}
     60
     61	return val;
     62}
     63
     64
     65/*********\
     66* Parsers *
     67\*********/
     68
     69/*
     70 * Initialize eeprom & capabilities structs
     71 */
     72static int
     73ath5k_eeprom_init_header(struct ath5k_hw *ah)
     74{
     75	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
     76	u16 val;
     77	u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
     78
     79	/*
     80	 * Read values from EEPROM and store them in the capability structure
     81	 */
     82	AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
     83	AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
     84	AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
     85	AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
     86	AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
     87
     88	/* Return if we have an old EEPROM */
     89	if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
     90		return 0;
     91
     92	/*
     93	 * Validate the checksum of the EEPROM date. There are some
     94	 * devices with invalid EEPROMs.
     95	 */
     96	AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
     97	if (val) {
     98		eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
     99			   AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
    100		AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
    101		eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
    102
    103		/*
    104		 * Fail safe check to prevent stupid loops due
    105		 * to busted EEPROMs. XXX: This value is likely too
    106		 * big still, waiting on a better value.
    107		 */
    108		if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
    109			ATH5K_ERR(ah, "Invalid max custom EEPROM size: "
    110				  "%d (0x%04x) max expected: %d (0x%04x)\n",
    111				  eep_max, eep_max,
    112				  3 * AR5K_EEPROM_INFO_MAX,
    113				  3 * AR5K_EEPROM_INFO_MAX);
    114			return -EIO;
    115		}
    116	}
    117
    118	for (cksum = 0, offset = 0; offset < eep_max; offset++) {
    119		AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
    120		cksum ^= val;
    121	}
    122	if (cksum != AR5K_EEPROM_INFO_CKSUM) {
    123		ATH5K_ERR(ah, "Invalid EEPROM "
    124			  "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
    125			  cksum, eep_max,
    126			  eep_max == AR5K_EEPROM_INFO_MAX ?
    127				"default size" : "custom size");
    128		return -EIO;
    129	}
    130
    131	AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
    132	    ee_ant_gain);
    133
    134	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
    135		AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
    136		AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
    137
    138		/* XXX: Don't know which versions include these two */
    139		AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC2, ee_misc2);
    140
    141		if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3)
    142			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC3, ee_misc3);
    143
    144		if (ee->ee_version >= AR5K_EEPROM_VERSION_5_0) {
    145			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC4, ee_misc4);
    146			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC5, ee_misc5);
    147			AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC6, ee_misc6);
    148		}
    149	}
    150
    151	if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
    152		AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
    153		ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
    154		ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
    155
    156		AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
    157		ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
    158		ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
    159	}
    160
    161	AR5K_EEPROM_READ(AR5K_EEPROM_IS_HB63, val);
    162
    163	if ((ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4)) && val)
    164		ee->ee_is_hb63 = true;
    165	else
    166		ee->ee_is_hb63 = false;
    167
    168	AR5K_EEPROM_READ(AR5K_EEPROM_RFKILL, val);
    169	ee->ee_rfkill_pin = (u8) AR5K_REG_MS(val, AR5K_EEPROM_RFKILL_GPIO_SEL);
    170	ee->ee_rfkill_pol = val & AR5K_EEPROM_RFKILL_POLARITY ? true : false;
    171
    172	/* Check if PCIE_OFFSET points to PCIE_SERDES_SECTION
    173	 * and enable serdes programming if needed.
    174	 *
    175	 * XXX: Serdes values seem to be fixed so
    176	 * no need to read them here, we write them
    177	 * during ath5k_hw_init */
    178	AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);
    179	ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?
    180							true : false;
    181
    182	return 0;
    183}
    184
    185
    186/*
    187 * Read antenna infos from eeprom
    188 */
    189static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
    190		unsigned int mode)
    191{
    192	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    193	u32 o = *offset;
    194	u16 val;
    195	int i = 0;
    196
    197	AR5K_EEPROM_READ(o++, val);
    198	ee->ee_switch_settling[mode]	= (val >> 8) & 0x7f;
    199	ee->ee_atn_tx_rx[mode]		= (val >> 2) & 0x3f;
    200	ee->ee_ant_control[mode][i]	= (val << 4) & 0x3f;
    201
    202	AR5K_EEPROM_READ(o++, val);
    203	ee->ee_ant_control[mode][i++]	|= (val >> 12) & 0xf;
    204	ee->ee_ant_control[mode][i++]	= (val >> 6) & 0x3f;
    205	ee->ee_ant_control[mode][i++]	= val & 0x3f;
    206
    207	AR5K_EEPROM_READ(o++, val);
    208	ee->ee_ant_control[mode][i++]	= (val >> 10) & 0x3f;
    209	ee->ee_ant_control[mode][i++]	= (val >> 4) & 0x3f;
    210	ee->ee_ant_control[mode][i]	= (val << 2) & 0x3f;
    211
    212	AR5K_EEPROM_READ(o++, val);
    213	ee->ee_ant_control[mode][i++]	|= (val >> 14) & 0x3;
    214	ee->ee_ant_control[mode][i++]	= (val >> 8) & 0x3f;
    215	ee->ee_ant_control[mode][i++]	= (val >> 2) & 0x3f;
    216	ee->ee_ant_control[mode][i]	= (val << 4) & 0x3f;
    217
    218	AR5K_EEPROM_READ(o++, val);
    219	ee->ee_ant_control[mode][i++]	|= (val >> 12) & 0xf;
    220	ee->ee_ant_control[mode][i++]	= (val >> 6) & 0x3f;
    221	ee->ee_ant_control[mode][i++]	= val & 0x3f;
    222
    223	/* Get antenna switch tables */
    224	ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =
    225	    (ee->ee_ant_control[mode][0] << 4);
    226	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] =
    227	     ee->ee_ant_control[mode][1]	|
    228	    (ee->ee_ant_control[mode][2] << 6)	|
    229	    (ee->ee_ant_control[mode][3] << 12) |
    230	    (ee->ee_ant_control[mode][4] << 18) |
    231	    (ee->ee_ant_control[mode][5] << 24);
    232	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] =
    233	     ee->ee_ant_control[mode][6]	|
    234	    (ee->ee_ant_control[mode][7] << 6)	|
    235	    (ee->ee_ant_control[mode][8] << 12) |
    236	    (ee->ee_ant_control[mode][9] << 18) |
    237	    (ee->ee_ant_control[mode][10] << 24);
    238
    239	/* return new offset */
    240	*offset = o;
    241
    242	return 0;
    243}
    244
    245/*
    246 * Read supported modes and some mode-specific calibration data
    247 * from eeprom
    248 */
    249static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
    250		unsigned int mode)
    251{
    252	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    253	u32 o = *offset;
    254	u16 val;
    255
    256	ee->ee_n_piers[mode] = 0;
    257	AR5K_EEPROM_READ(o++, val);
    258	ee->ee_adc_desired_size[mode]	= (s8)((val >> 8) & 0xff);
    259	switch (mode) {
    260	case AR5K_EEPROM_MODE_11A:
    261		ee->ee_ob[mode][3]	= (val >> 5) & 0x7;
    262		ee->ee_db[mode][3]	= (val >> 2) & 0x7;
    263		ee->ee_ob[mode][2]	= (val << 1) & 0x7;
    264
    265		AR5K_EEPROM_READ(o++, val);
    266		ee->ee_ob[mode][2]	|= (val >> 15) & 0x1;
    267		ee->ee_db[mode][2]	= (val >> 12) & 0x7;
    268		ee->ee_ob[mode][1]	= (val >> 9) & 0x7;
    269		ee->ee_db[mode][1]	= (val >> 6) & 0x7;
    270		ee->ee_ob[mode][0]	= (val >> 3) & 0x7;
    271		ee->ee_db[mode][0]	= val & 0x7;
    272		break;
    273	case AR5K_EEPROM_MODE_11G:
    274	case AR5K_EEPROM_MODE_11B:
    275		ee->ee_ob[mode][1]	= (val >> 4) & 0x7;
    276		ee->ee_db[mode][1]	= val & 0x7;
    277		break;
    278	}
    279
    280	AR5K_EEPROM_READ(o++, val);
    281	ee->ee_tx_end2xlna_enable[mode]	= (val >> 8) & 0xff;
    282	ee->ee_thr_62[mode]		= val & 0xff;
    283
    284	if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
    285		ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
    286
    287	AR5K_EEPROM_READ(o++, val);
    288	ee->ee_tx_end2xpa_disable[mode]	= (val >> 8) & 0xff;
    289	ee->ee_tx_frm2xpa_enable[mode]	= val & 0xff;
    290
    291	AR5K_EEPROM_READ(o++, val);
    292	ee->ee_pga_desired_size[mode]	= (val >> 8) & 0xff;
    293
    294	if ((val & 0xff) & 0x80)
    295		ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
    296	else
    297		ee->ee_noise_floor_thr[mode] = val & 0xff;
    298
    299	if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
    300		ee->ee_noise_floor_thr[mode] =
    301		    mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
    302
    303	AR5K_EEPROM_READ(o++, val);
    304	ee->ee_xlna_gain[mode]		= (val >> 5) & 0xff;
    305	ee->ee_x_gain[mode]		= (val >> 1) & 0xf;
    306	ee->ee_xpd[mode]		= val & 0x1;
    307
    308	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
    309	    mode != AR5K_EEPROM_MODE_11B)
    310		ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
    311
    312	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
    313		AR5K_EEPROM_READ(o++, val);
    314		ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
    315
    316		if (mode == AR5K_EEPROM_MODE_11A)
    317			ee->ee_xr_power[mode] = val & 0x3f;
    318		else {
    319			/* b_DB_11[bg] and b_OB_11[bg] */
    320			ee->ee_ob[mode][0] = val & 0x7;
    321			ee->ee_db[mode][0] = (val >> 3) & 0x7;
    322		}
    323	}
    324
    325	if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
    326		ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
    327		ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
    328	} else {
    329		ee->ee_i_gain[mode] = (val >> 13) & 0x7;
    330
    331		AR5K_EEPROM_READ(o++, val);
    332		ee->ee_i_gain[mode] |= (val << 3) & 0x38;
    333
    334		if (mode == AR5K_EEPROM_MODE_11G) {
    335			ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
    336			if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6)
    337				ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
    338		}
    339	}
    340
    341	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
    342			mode == AR5K_EEPROM_MODE_11A) {
    343		ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
    344		ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
    345	}
    346
    347	if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_0)
    348		goto done;
    349
    350	/* Note: >= v5 have bg freq piers on another location
    351	 * so these freq piers are ignored for >= v5 (should be 0xff
    352	 * anyway) */
    353	switch (mode) {
    354	case AR5K_EEPROM_MODE_11A:
    355		if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)
    356			break;
    357
    358		AR5K_EEPROM_READ(o++, val);
    359		ee->ee_margin_tx_rx[mode] = val & 0x3f;
    360		break;
    361	case AR5K_EEPROM_MODE_11B:
    362		AR5K_EEPROM_READ(o++, val);
    363
    364		ee->ee_pwr_cal_b[0].freq =
    365			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
    366		if (ee->ee_pwr_cal_b[0].freq != AR5K_EEPROM_CHANNEL_DIS)
    367			ee->ee_n_piers[mode]++;
    368
    369		ee->ee_pwr_cal_b[1].freq =
    370			ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
    371		if (ee->ee_pwr_cal_b[1].freq != AR5K_EEPROM_CHANNEL_DIS)
    372			ee->ee_n_piers[mode]++;
    373
    374		AR5K_EEPROM_READ(o++, val);
    375		ee->ee_pwr_cal_b[2].freq =
    376			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
    377		if (ee->ee_pwr_cal_b[2].freq != AR5K_EEPROM_CHANNEL_DIS)
    378			ee->ee_n_piers[mode]++;
    379
    380		if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
    381			ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
    382		break;
    383	case AR5K_EEPROM_MODE_11G:
    384		AR5K_EEPROM_READ(o++, val);
    385
    386		ee->ee_pwr_cal_g[0].freq =
    387			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
    388		if (ee->ee_pwr_cal_g[0].freq != AR5K_EEPROM_CHANNEL_DIS)
    389			ee->ee_n_piers[mode]++;
    390
    391		ee->ee_pwr_cal_g[1].freq =
    392			ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
    393		if (ee->ee_pwr_cal_g[1].freq != AR5K_EEPROM_CHANNEL_DIS)
    394			ee->ee_n_piers[mode]++;
    395
    396		AR5K_EEPROM_READ(o++, val);
    397		ee->ee_turbo_max_power[mode] = val & 0x7f;
    398		ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
    399
    400		AR5K_EEPROM_READ(o++, val);
    401		ee->ee_pwr_cal_g[2].freq =
    402			ath5k_eeprom_bin2freq(ee, val & 0xff, mode);
    403		if (ee->ee_pwr_cal_g[2].freq != AR5K_EEPROM_CHANNEL_DIS)
    404			ee->ee_n_piers[mode]++;
    405
    406		if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
    407			ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
    408
    409		AR5K_EEPROM_READ(o++, val);
    410		ee->ee_i_cal[mode] = (val >> 5) & 0x3f;
    411		ee->ee_q_cal[mode] = val & 0x1f;
    412
    413		if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
    414			AR5K_EEPROM_READ(o++, val);
    415			ee->ee_cck_ofdm_gain_delta = val & 0xff;
    416		}
    417		break;
    418	}
    419
    420	/*
    421	 * Read turbo mode information on newer EEPROM versions
    422	 */
    423	if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)
    424		goto done;
    425
    426	switch (mode) {
    427	case AR5K_EEPROM_MODE_11A:
    428		ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f;
    429
    430		ee->ee_atn_tx_rx_turbo[mode] = (val >> 13) & 0x7;
    431		AR5K_EEPROM_READ(o++, val);
    432		ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x7) << 3;
    433		ee->ee_margin_tx_rx_turbo[mode] = (val >> 3) & 0x3f;
    434
    435		ee->ee_adc_desired_size_turbo[mode] = (val >> 9) & 0x7f;
    436		AR5K_EEPROM_READ(o++, val);
    437		ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;
    438		ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff;
    439
    440		if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >= 2)
    441			ee->ee_pd_gain_overlap = (val >> 9) & 0xf;
    442		break;
    443	case AR5K_EEPROM_MODE_11G:
    444		ee->ee_switch_settling_turbo[mode] = (val >> 8) & 0x7f;
    445
    446		ee->ee_atn_tx_rx_turbo[mode] = (val >> 15) & 0x7;
    447		AR5K_EEPROM_READ(o++, val);
    448		ee->ee_atn_tx_rx_turbo[mode] |= (val & 0x1f) << 1;
    449		ee->ee_margin_tx_rx_turbo[mode] = (val >> 5) & 0x3f;
    450
    451		ee->ee_adc_desired_size_turbo[mode] = (val >> 11) & 0x7f;
    452		AR5K_EEPROM_READ(o++, val);
    453		ee->ee_adc_desired_size_turbo[mode] |= (val & 0x7) << 5;
    454		ee->ee_pga_desired_size_turbo[mode] = (val >> 3) & 0xff;
    455		break;
    456	}
    457
    458done:
    459	/* return new offset */
    460	*offset = o;
    461
    462	return 0;
    463}
    464
    465/* Read mode-specific data (except power calibration data) */
    466static int
    467ath5k_eeprom_init_modes(struct ath5k_hw *ah)
    468{
    469	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    470	u32 mode_offset[3];
    471	unsigned int mode;
    472	u32 offset;
    473	int ret;
    474
    475	/*
    476	 * Get values for all modes
    477	 */
    478	mode_offset[AR5K_EEPROM_MODE_11A] = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
    479	mode_offset[AR5K_EEPROM_MODE_11B] = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
    480	mode_offset[AR5K_EEPROM_MODE_11G] = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
    481
    482	ee->ee_turbo_max_power[AR5K_EEPROM_MODE_11A] =
    483		AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
    484
    485	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) {
    486		offset = mode_offset[mode];
    487
    488		ret = ath5k_eeprom_read_ants(ah, &offset, mode);
    489		if (ret)
    490			return ret;
    491
    492		ret = ath5k_eeprom_read_modes(ah, &offset, mode);
    493		if (ret)
    494			return ret;
    495	}
    496
    497	/* override for older eeprom versions for better performance */
    498	if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) {
    499		ee->ee_thr_62[AR5K_EEPROM_MODE_11A] = 15;
    500		ee->ee_thr_62[AR5K_EEPROM_MODE_11B] = 28;
    501		ee->ee_thr_62[AR5K_EEPROM_MODE_11G] = 28;
    502	}
    503
    504	return 0;
    505}
    506
    507/* Read the frequency piers for each mode (mostly used on newer eeproms with 0xff
    508 * frequency mask) */
    509static inline int
    510ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,
    511			struct ath5k_chan_pcal_info *pc, unsigned int mode)
    512{
    513	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    514	int o = *offset;
    515	int i = 0;
    516	u8 freq1, freq2;
    517	u16 val;
    518
    519	ee->ee_n_piers[mode] = 0;
    520	while (i < max) {
    521		AR5K_EEPROM_READ(o++, val);
    522
    523		freq1 = val & 0xff;
    524		if (!freq1)
    525			break;
    526
    527		pc[i++].freq = ath5k_eeprom_bin2freq(ee,
    528				freq1, mode);
    529		ee->ee_n_piers[mode]++;
    530
    531		freq2 = (val >> 8) & 0xff;
    532		if (!freq2)
    533			break;
    534
    535		pc[i++].freq = ath5k_eeprom_bin2freq(ee,
    536				freq2, mode);
    537		ee->ee_n_piers[mode]++;
    538	}
    539
    540	/* return new offset */
    541	*offset = o;
    542
    543	return 0;
    544}
    545
    546/* Read frequency piers for 802.11a */
    547static int
    548ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)
    549{
    550	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    551	struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a;
    552	int i;
    553	u16 val;
    554	u8 mask;
    555
    556	if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
    557		ath5k_eeprom_read_freq_list(ah, &offset,
    558			AR5K_EEPROM_N_5GHZ_CHAN, pcal,
    559			AR5K_EEPROM_MODE_11A);
    560	} else {
    561		mask = AR5K_EEPROM_FREQ_M(ah->ah_ee_version);
    562
    563		AR5K_EEPROM_READ(offset++, val);
    564		pcal[0].freq  = (val >> 9) & mask;
    565		pcal[1].freq  = (val >> 2) & mask;
    566		pcal[2].freq  = (val << 5) & mask;
    567
    568		AR5K_EEPROM_READ(offset++, val);
    569		pcal[2].freq |= (val >> 11) & 0x1f;
    570		pcal[3].freq  = (val >> 4) & mask;
    571		pcal[4].freq  = (val << 3) & mask;
    572
    573		AR5K_EEPROM_READ(offset++, val);
    574		pcal[4].freq |= (val >> 13) & 0x7;
    575		pcal[5].freq  = (val >> 6) & mask;
    576		pcal[6].freq  = (val << 1) & mask;
    577
    578		AR5K_EEPROM_READ(offset++, val);
    579		pcal[6].freq |= (val >> 15) & 0x1;
    580		pcal[7].freq  = (val >> 8) & mask;
    581		pcal[8].freq  = (val >> 1) & mask;
    582		pcal[9].freq  = (val << 6) & mask;
    583
    584		AR5K_EEPROM_READ(offset++, val);
    585		pcal[9].freq |= (val >> 10) & 0x3f;
    586
    587		/* Fixed number of piers */
    588		ee->ee_n_piers[AR5K_EEPROM_MODE_11A] = 10;
    589
    590		for (i = 0; i < AR5K_EEPROM_N_5GHZ_CHAN; i++) {
    591			pcal[i].freq = ath5k_eeprom_bin2freq(ee,
    592				pcal[i].freq, AR5K_EEPROM_MODE_11A);
    593		}
    594	}
    595
    596	return 0;
    597}
    598
    599/* Read frequency piers for 802.11bg on eeprom versions >= 5 and eemap >= 2 */
    600static inline int
    601ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)
    602{
    603	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    604	struct ath5k_chan_pcal_info *pcal;
    605
    606	switch (mode) {
    607	case AR5K_EEPROM_MODE_11B:
    608		pcal = ee->ee_pwr_cal_b;
    609		break;
    610	case AR5K_EEPROM_MODE_11G:
    611		pcal = ee->ee_pwr_cal_g;
    612		break;
    613	default:
    614		return -EINVAL;
    615	}
    616
    617	ath5k_eeprom_read_freq_list(ah, &offset,
    618		AR5K_EEPROM_N_2GHZ_CHAN_2413, pcal,
    619		mode);
    620
    621	return 0;
    622}
    623
    624
    625/*
    626 * Read power calibration for RF5111 chips
    627 *
    628 * For RF5111 we have an XPD -eXternal Power Detector- curve
    629 * for each calibrated channel. Each curve has 0,5dB Power steps
    630 * on x axis and PCDAC steps (offsets) on y axis and looks like an
    631 * exponential function. To recreate the curve we read 11 points
    632 * here and interpolate later.
    633 */
    634
    635/* Used to match PCDAC steps with power values on RF5111 chips
    636 * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC
    637 * steps that match with the power values we read from eeprom. On
    638 * older eeprom versions (< 3.2) these steps are equally spaced at
    639 * 10% of the pcdac curve -until the curve reaches its maximum-
    640 * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)
    641 * these 11 steps are spaced in a different way. This function returns
    642 * the pcdac steps based on eeprom version and curve min/max so that we
    643 * can have pcdac/pwr points.
    644 */
    645static inline void
    646ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)
    647{
    648	static const u16 intercepts3[] = {
    649		0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100
    650	};
    651	static const u16 intercepts3_2[] = {
    652		0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
    653	};
    654	const u16 *ip;
    655	int i;
    656
    657	if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_2)
    658		ip = intercepts3_2;
    659	else
    660		ip = intercepts3;
    661
    662	for (i = 0; i < ARRAY_SIZE(intercepts3); i++)
    663		vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;
    664}
    665
    666static int
    667ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode)
    668{
    669	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    670	struct ath5k_chan_pcal_info *chinfo;
    671	u8 pier, pdg;
    672
    673	switch (mode) {
    674	case AR5K_EEPROM_MODE_11A:
    675		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
    676			return 0;
    677		chinfo = ee->ee_pwr_cal_a;
    678		break;
    679	case AR5K_EEPROM_MODE_11B:
    680		if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
    681			return 0;
    682		chinfo = ee->ee_pwr_cal_b;
    683		break;
    684	case AR5K_EEPROM_MODE_11G:
    685		if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
    686			return 0;
    687		chinfo = ee->ee_pwr_cal_g;
    688		break;
    689	default:
    690		return -EINVAL;
    691	}
    692
    693	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
    694		if (!chinfo[pier].pd_curves)
    695			continue;
    696
    697		for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) {
    698			struct ath5k_pdgain_info *pd =
    699					&chinfo[pier].pd_curves[pdg];
    700
    701			kfree(pd->pd_step);
    702			kfree(pd->pd_pwr);
    703		}
    704
    705		kfree(chinfo[pier].pd_curves);
    706	}
    707
    708	return 0;
    709}
    710
    711/* Convert RF5111 specific data to generic raw data
    712 * used by interpolation code */
    713static int
    714ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,
    715				struct ath5k_chan_pcal_info *chinfo)
    716{
    717	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    718	struct ath5k_chan_pcal_info_rf5111 *pcinfo;
    719	struct ath5k_pdgain_info *pd;
    720	u8 pier, point, idx;
    721	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
    722
    723	/* Fill raw data for each calibration pier */
    724	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
    725
    726		pcinfo = &chinfo[pier].rf5111_info;
    727
    728		/* Allocate pd_curves for this cal pier */
    729		chinfo[pier].pd_curves =
    730			kcalloc(AR5K_EEPROM_N_PD_CURVES,
    731				sizeof(struct ath5k_pdgain_info),
    732				GFP_KERNEL);
    733
    734		if (!chinfo[pier].pd_curves)
    735			goto err_out;
    736
    737		/* Only one curve for RF5111
    738		 * find out which one and place
    739		 * in pd_curves.
    740		 * Note: ee_x_gain is reversed here */
    741		for (idx = 0; idx < AR5K_EEPROM_N_PD_CURVES; idx++) {
    742
    743			if (!((ee->ee_x_gain[mode] >> idx) & 0x1)) {
    744				pdgain_idx[0] = idx;
    745				break;
    746			}
    747		}
    748
    749		if (idx == AR5K_EEPROM_N_PD_CURVES)
    750			goto err_out;
    751
    752		ee->ee_pd_gains[mode] = 1;
    753
    754		pd = &chinfo[pier].pd_curves[idx];
    755
    756		pd->pd_points = AR5K_EEPROM_N_PWR_POINTS_5111;
    757
    758		/* Allocate pd points for this curve */
    759		pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
    760					sizeof(u8), GFP_KERNEL);
    761		if (!pd->pd_step)
    762			goto err_out;
    763
    764		pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,
    765					sizeof(s16), GFP_KERNEL);
    766		if (!pd->pd_pwr)
    767			goto err_out;
    768
    769		/* Fill raw dataset
    770		 * (convert power to 0.25dB units
    771		 * for RF5112 compatibility) */
    772		for (point = 0; point < pd->pd_points; point++) {
    773
    774			/* Absolute values */
    775			pd->pd_pwr[point] = 2 * pcinfo->pwr[point];
    776
    777			/* Already sorted */
    778			pd->pd_step[point] = pcinfo->pcdac[point];
    779		}
    780
    781		/* Set min/max pwr */
    782		chinfo[pier].min_pwr = pd->pd_pwr[0];
    783		chinfo[pier].max_pwr = pd->pd_pwr[10];
    784
    785	}
    786
    787	return 0;
    788
    789err_out:
    790	ath5k_eeprom_free_pcal_info(ah, mode);
    791	return -ENOMEM;
    792}
    793
    794/* Parse EEPROM data */
    795static int
    796ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)
    797{
    798	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    799	struct ath5k_chan_pcal_info *pcal;
    800	int offset, ret;
    801	int i;
    802	u16 val;
    803
    804	offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
    805	switch (mode) {
    806	case AR5K_EEPROM_MODE_11A:
    807		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
    808			return 0;
    809
    810		ret = ath5k_eeprom_init_11a_pcal_freq(ah,
    811			offset + AR5K_EEPROM_GROUP1_OFFSET);
    812		if (ret < 0)
    813			return ret;
    814
    815		offset += AR5K_EEPROM_GROUP2_OFFSET;
    816		pcal = ee->ee_pwr_cal_a;
    817		break;
    818	case AR5K_EEPROM_MODE_11B:
    819		if (!AR5K_EEPROM_HDR_11B(ee->ee_header) &&
    820		    !AR5K_EEPROM_HDR_11G(ee->ee_header))
    821			return 0;
    822
    823		pcal = ee->ee_pwr_cal_b;
    824		offset += AR5K_EEPROM_GROUP3_OFFSET;
    825
    826		/* fixed piers */
    827		pcal[0].freq = 2412;
    828		pcal[1].freq = 2447;
    829		pcal[2].freq = 2484;
    830		ee->ee_n_piers[mode] = 3;
    831		break;
    832	case AR5K_EEPROM_MODE_11G:
    833		if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
    834			return 0;
    835
    836		pcal = ee->ee_pwr_cal_g;
    837		offset += AR5K_EEPROM_GROUP4_OFFSET;
    838
    839		/* fixed piers */
    840		pcal[0].freq = 2312;
    841		pcal[1].freq = 2412;
    842		pcal[2].freq = 2484;
    843		ee->ee_n_piers[mode] = 3;
    844		break;
    845	default:
    846		return -EINVAL;
    847	}
    848
    849	for (i = 0; i < ee->ee_n_piers[mode]; i++) {
    850		struct ath5k_chan_pcal_info_rf5111 *cdata =
    851			&pcal[i].rf5111_info;
    852
    853		AR5K_EEPROM_READ(offset++, val);
    854		cdata->pcdac_max = ((val >> 10) & AR5K_EEPROM_PCDAC_M);
    855		cdata->pcdac_min = ((val >> 4) & AR5K_EEPROM_PCDAC_M);
    856		cdata->pwr[0] = ((val << 2) & AR5K_EEPROM_POWER_M);
    857
    858		AR5K_EEPROM_READ(offset++, val);
    859		cdata->pwr[0] |= ((val >> 14) & 0x3);
    860		cdata->pwr[1] = ((val >> 8) & AR5K_EEPROM_POWER_M);
    861		cdata->pwr[2] = ((val >> 2) & AR5K_EEPROM_POWER_M);
    862		cdata->pwr[3] = ((val << 4) & AR5K_EEPROM_POWER_M);
    863
    864		AR5K_EEPROM_READ(offset++, val);
    865		cdata->pwr[3] |= ((val >> 12) & 0xf);
    866		cdata->pwr[4] = ((val >> 6) & AR5K_EEPROM_POWER_M);
    867		cdata->pwr[5] = (val  & AR5K_EEPROM_POWER_M);
    868
    869		AR5K_EEPROM_READ(offset++, val);
    870		cdata->pwr[6] = ((val >> 10) & AR5K_EEPROM_POWER_M);
    871		cdata->pwr[7] = ((val >> 4) & AR5K_EEPROM_POWER_M);
    872		cdata->pwr[8] = ((val << 2) & AR5K_EEPROM_POWER_M);
    873
    874		AR5K_EEPROM_READ(offset++, val);
    875		cdata->pwr[8] |= ((val >> 14) & 0x3);
    876		cdata->pwr[9] = ((val >> 8) & AR5K_EEPROM_POWER_M);
    877		cdata->pwr[10] = ((val >> 2) & AR5K_EEPROM_POWER_M);
    878
    879		ath5k_get_pcdac_intercepts(ah, cdata->pcdac_min,
    880			cdata->pcdac_max, cdata->pcdac);
    881	}
    882
    883	return ath5k_eeprom_convert_pcal_info_5111(ah, mode, pcal);
    884}
    885
    886
    887/*
    888 * Read power calibration for RF5112 chips
    889 *
    890 * For RF5112 we have 4 XPD -eXternal Power Detector- curves
    891 * for each calibrated channel on 0, -6, -12 and -18dBm but we only
    892 * use the higher (3) and the lower (0) curves. Each curve has 0.5dB
    893 * power steps on x axis and PCDAC steps on y axis and looks like a
    894 * linear function. To recreate the curve and pass the power values
    895 * on hw, we read 4 points for xpd 0 (lower gain -> max power)
    896 * and 3 points for xpd 3 (higher gain -> lower power) here and
    897 * interpolate later.
    898 *
    899 * Note: Many vendors just use xpd 0 so xpd 3 is zeroed.
    900 */
    901
    902/* Convert RF5112 specific data to generic raw data
    903 * used by interpolation code */
    904static int
    905ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,
    906				struct ath5k_chan_pcal_info *chinfo)
    907{
    908	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
    909	struct ath5k_chan_pcal_info_rf5112 *pcinfo;
    910	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
    911	unsigned int pier, pdg, point;
    912
    913	/* Fill raw data for each calibration pier */
    914	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
    915
    916		pcinfo = &chinfo[pier].rf5112_info;
    917
    918		/* Allocate pd_curves for this cal pier */
    919		chinfo[pier].pd_curves =
    920				kcalloc(AR5K_EEPROM_N_PD_CURVES,
    921					sizeof(struct ath5k_pdgain_info),
    922					GFP_KERNEL);
    923
    924		if (!chinfo[pier].pd_curves)
    925			goto err_out;
    926
    927		/* Fill pd_curves */
    928		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
    929
    930			u8 idx = pdgain_idx[pdg];
    931			struct ath5k_pdgain_info *pd =
    932					&chinfo[pier].pd_curves[idx];
    933
    934			/* Lowest gain curve (max power) */
    935			if (pdg == 0) {
    936				/* One more point for better accuracy */
    937				pd->pd_points = AR5K_EEPROM_N_XPD0_POINTS;
    938
    939				/* Allocate pd points for this curve */
    940				pd->pd_step = kcalloc(pd->pd_points,
    941						sizeof(u8), GFP_KERNEL);
    942
    943				if (!pd->pd_step)
    944					goto err_out;
    945
    946				pd->pd_pwr = kcalloc(pd->pd_points,
    947						sizeof(s16), GFP_KERNEL);
    948
    949				if (!pd->pd_pwr)
    950					goto err_out;
    951
    952				/* Fill raw dataset
    953				 * (all power levels are in 0.25dB units) */
    954				pd->pd_step[0] = pcinfo->pcdac_x0[0];
    955				pd->pd_pwr[0] = pcinfo->pwr_x0[0];
    956
    957				for (point = 1; point < pd->pd_points;
    958				point++) {
    959					/* Absolute values */
    960					pd->pd_pwr[point] =
    961						pcinfo->pwr_x0[point];
    962
    963					/* Deltas */
    964					pd->pd_step[point] =
    965						pd->pd_step[point - 1] +
    966						pcinfo->pcdac_x0[point];
    967				}
    968
    969				/* Set min power for this frequency */
    970				chinfo[pier].min_pwr = pd->pd_pwr[0];
    971
    972			/* Highest gain curve (min power) */
    973			} else if (pdg == 1) {
    974
    975				pd->pd_points = AR5K_EEPROM_N_XPD3_POINTS;
    976
    977				/* Allocate pd points for this curve */
    978				pd->pd_step = kcalloc(pd->pd_points,
    979						sizeof(u8), GFP_KERNEL);
    980
    981				if (!pd->pd_step)
    982					goto err_out;
    983
    984				pd->pd_pwr = kcalloc(pd->pd_points,
    985						sizeof(s16), GFP_KERNEL);
    986
    987				if (!pd->pd_pwr)
    988					goto err_out;
    989
    990				/* Fill raw dataset
    991				 * (all power levels are in 0.25dB units) */
    992				for (point = 0; point < pd->pd_points;
    993				point++) {
    994					/* Absolute values */
    995					pd->pd_pwr[point] =
    996						pcinfo->pwr_x3[point];
    997
    998					/* Fixed points */
    999					pd->pd_step[point] =
   1000						pcinfo->pcdac_x3[point];
   1001				}
   1002
   1003				/* Since we have a higher gain curve
   1004				 * override min power */
   1005				chinfo[pier].min_pwr = pd->pd_pwr[0];
   1006			}
   1007		}
   1008	}
   1009
   1010	return 0;
   1011
   1012err_out:
   1013	ath5k_eeprom_free_pcal_info(ah, mode);
   1014	return -ENOMEM;
   1015}
   1016
   1017/* Parse EEPROM data */
   1018static int
   1019ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)
   1020{
   1021	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
   1022	struct ath5k_chan_pcal_info_rf5112 *chan_pcal_info;
   1023	struct ath5k_chan_pcal_info *gen_chan_info;
   1024	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
   1025	u32 offset;
   1026	u8 i, c;
   1027	u16 val;
   1028	u8 pd_gains = 0;
   1029
   1030	/* Count how many curves we have and
   1031	 * identify them (which one of the 4
   1032	 * available curves we have on each count).
   1033	 * Curves are stored from lower (x0) to
   1034	 * higher (x3) gain */
   1035	for (i = 0; i < AR5K_EEPROM_N_PD_CURVES; i++) {
   1036		/* ee_x_gain[mode] is x gain mask */
   1037		if ((ee->ee_x_gain[mode] >> i) & 0x1)
   1038			pdgain_idx[pd_gains++] = i;
   1039	}
   1040	ee->ee_pd_gains[mode] = pd_gains;
   1041
   1042	if (pd_gains == 0 || pd_gains > 2)
   1043		return -EINVAL;
   1044
   1045	switch (mode) {
   1046	case AR5K_EEPROM_MODE_11A:
   1047		/*
   1048		 * Read 5GHz EEPROM channels
   1049		 */
   1050		offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
   1051		ath5k_eeprom_init_11a_pcal_freq(ah, offset);
   1052
   1053		offset += AR5K_EEPROM_GROUP2_OFFSET;
   1054		gen_chan_info = ee->ee_pwr_cal_a;
   1055		break;
   1056	case AR5K_EEPROM_MODE_11B:
   1057		offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
   1058		if (AR5K_EEPROM_HDR_11A(ee->ee_header))
   1059			offset += AR5K_EEPROM_GROUP3_OFFSET;
   1060
   1061		/* NB: frequency piers parsed during mode init */
   1062		gen_chan_info = ee->ee_pwr_cal_b;
   1063		break;
   1064	case AR5K_EEPROM_MODE_11G:
   1065		offset = AR5K_EEPROM_GROUPS_START(ee->ee_version);
   1066		if (AR5K_EEPROM_HDR_11A(ee->ee_header))
   1067			offset += AR5K_EEPROM_GROUP4_OFFSET;
   1068		else if (AR5K_EEPROM_HDR_11B(ee->ee_header))
   1069			offset += AR5K_EEPROM_GROUP2_OFFSET;
   1070
   1071		/* NB: frequency piers parsed during mode init */
   1072		gen_chan_info = ee->ee_pwr_cal_g;
   1073		break;
   1074	default:
   1075		return -EINVAL;
   1076	}
   1077
   1078	for (i = 0; i < ee->ee_n_piers[mode]; i++) {
   1079		chan_pcal_info = &gen_chan_info[i].rf5112_info;
   1080
   1081		/* Power values in quarter dB
   1082		 * for the lower xpd gain curve
   1083		 * (0 dBm -> higher output power) */
   1084		for (c = 0; c < AR5K_EEPROM_N_XPD0_POINTS; c++) {
   1085			AR5K_EEPROM_READ(offset++, val);
   1086			chan_pcal_info->pwr_x0[c] = (s8) (val & 0xff);
   1087			chan_pcal_info->pwr_x0[++c] = (s8) ((val >> 8) & 0xff);
   1088		}
   1089
   1090		/* PCDAC steps
   1091		 * corresponding to the above power
   1092		 * measurements */
   1093		AR5K_EEPROM_READ(offset++, val);
   1094		chan_pcal_info->pcdac_x0[1] = (val & 0x1f);
   1095		chan_pcal_info->pcdac_x0[2] = ((val >> 5) & 0x1f);
   1096		chan_pcal_info->pcdac_x0[3] = ((val >> 10) & 0x1f);
   1097
   1098		/* Power values in quarter dB
   1099		 * for the higher xpd gain curve
   1100		 * (18 dBm -> lower output power) */
   1101		AR5K_EEPROM_READ(offset++, val);
   1102		chan_pcal_info->pwr_x3[0] = (s8) (val & 0xff);
   1103		chan_pcal_info->pwr_x3[1] = (s8) ((val >> 8) & 0xff);
   1104
   1105		AR5K_EEPROM_READ(offset++, val);
   1106		chan_pcal_info->pwr_x3[2] = (val & 0xff);
   1107
   1108		/* PCDAC steps
   1109		 * corresponding to the above power
   1110		 * measurements (fixed) */
   1111		chan_pcal_info->pcdac_x3[0] = 20;
   1112		chan_pcal_info->pcdac_x3[1] = 35;
   1113		chan_pcal_info->pcdac_x3[2] = 63;
   1114
   1115		if (ee->ee_version >= AR5K_EEPROM_VERSION_4_3) {
   1116			chan_pcal_info->pcdac_x0[0] = ((val >> 8) & 0x3f);
   1117
   1118			/* Last xpd0 power level is also channel maximum */
   1119			gen_chan_info[i].max_pwr = chan_pcal_info->pwr_x0[3];
   1120		} else {
   1121			chan_pcal_info->pcdac_x0[0] = 1;
   1122			gen_chan_info[i].max_pwr = (s8) ((val >> 8) & 0xff);
   1123		}
   1124
   1125	}
   1126
   1127	return ath5k_eeprom_convert_pcal_info_5112(ah, mode, gen_chan_info);
   1128}
   1129
   1130
   1131/*
   1132 * Read power calibration for RF2413 chips
   1133 *
   1134 * For RF2413 we have a Power to PDDAC table (Power Detector)
   1135 * instead of a PCDAC and 4 pd gain curves for each calibrated channel.
   1136 * Each curve has power on x axis in 0.5 db steps and PDDADC steps on y
   1137 * axis and looks like an exponential function like the RF5111 curve.
   1138 *
   1139 * To recreate the curves we read here the points and interpolate
   1140 * later. Note that in most cases only 2 (higher and lower) curves are
   1141 * used (like RF5112) but vendors have the opportunity to include all
   1142 * 4 curves on eeprom. The final curve (higher power) has an extra
   1143 * point for better accuracy like RF5112.
   1144 */
   1145
   1146/* For RF2413 power calibration data doesn't start on a fixed location and
   1147 * if a mode is not supported, its section is missing -not zeroed-.
   1148 * So we need to calculate the starting offset for each section by using
   1149 * these two functions */
   1150
   1151/* Return the size of each section based on the mode and the number of pd
   1152 * gains available (maximum 4). */
   1153static inline unsigned int
   1154ath5k_pdgains_size_2413(struct ath5k_eeprom_info *ee, unsigned int mode)
   1155{
   1156	static const unsigned int pdgains_size[] = { 4, 6, 9, 12 };
   1157	unsigned int sz;
   1158
   1159	sz = pdgains_size[ee->ee_pd_gains[mode] - 1];
   1160	sz *= ee->ee_n_piers[mode];
   1161
   1162	return sz;
   1163}
   1164
   1165/* Return the starting offset for a section based on the modes supported
   1166 * and each section's size. */
   1167static unsigned int
   1168ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)
   1169{
   1170	u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4);
   1171
   1172	switch (mode) {
   1173	case AR5K_EEPROM_MODE_11G:
   1174		if (AR5K_EEPROM_HDR_11B(ee->ee_header))
   1175			offset += ath5k_pdgains_size_2413(ee,
   1176					AR5K_EEPROM_MODE_11B) +
   1177					AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
   1178		fallthrough;
   1179	case AR5K_EEPROM_MODE_11B:
   1180		if (AR5K_EEPROM_HDR_11A(ee->ee_header))
   1181			offset += ath5k_pdgains_size_2413(ee,
   1182					AR5K_EEPROM_MODE_11A) +
   1183					AR5K_EEPROM_N_5GHZ_CHAN / 2;
   1184		fallthrough;
   1185	case AR5K_EEPROM_MODE_11A:
   1186		break;
   1187	default:
   1188		break;
   1189	}
   1190
   1191	return offset;
   1192}
   1193
   1194/* Convert RF2413 specific data to generic raw data
   1195 * used by interpolation code */
   1196static int
   1197ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,
   1198				struct ath5k_chan_pcal_info *chinfo)
   1199{
   1200	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
   1201	struct ath5k_chan_pcal_info_rf2413 *pcinfo;
   1202	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
   1203	unsigned int pier, pdg, point;
   1204
   1205	/* Fill raw data for each calibration pier */
   1206	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) {
   1207
   1208		pcinfo = &chinfo[pier].rf2413_info;
   1209
   1210		/* Allocate pd_curves for this cal pier */
   1211		chinfo[pier].pd_curves =
   1212				kcalloc(AR5K_EEPROM_N_PD_CURVES,
   1213					sizeof(struct ath5k_pdgain_info),
   1214					GFP_KERNEL);
   1215
   1216		if (!chinfo[pier].pd_curves)
   1217			goto err_out;
   1218
   1219		/* Fill pd_curves */
   1220		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) {
   1221
   1222			u8 idx = pdgain_idx[pdg];
   1223			struct ath5k_pdgain_info *pd =
   1224					&chinfo[pier].pd_curves[idx];
   1225
   1226			/* One more point for the highest power
   1227			 * curve (lowest gain) */
   1228			if (pdg == ee->ee_pd_gains[mode] - 1)
   1229				pd->pd_points = AR5K_EEPROM_N_PD_POINTS;
   1230			else
   1231				pd->pd_points = AR5K_EEPROM_N_PD_POINTS - 1;
   1232
   1233			/* Allocate pd points for this curve */
   1234			pd->pd_step = kcalloc(pd->pd_points,
   1235					sizeof(u8), GFP_KERNEL);
   1236
   1237			if (!pd->pd_step)
   1238				goto err_out;
   1239
   1240			pd->pd_pwr = kcalloc(pd->pd_points,
   1241					sizeof(s16), GFP_KERNEL);
   1242
   1243			if (!pd->pd_pwr)
   1244				goto err_out;
   1245
   1246			/* Fill raw dataset
   1247			 * convert all pwr levels to
   1248			 * quarter dB for RF5112 compatibility */
   1249			pd->pd_step[0] = pcinfo->pddac_i[pdg];
   1250			pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg];
   1251
   1252			for (point = 1; point < pd->pd_points; point++) {
   1253
   1254				pd->pd_pwr[point] = pd->pd_pwr[point - 1] +
   1255					2 * pcinfo->pwr[pdg][point - 1];
   1256
   1257				pd->pd_step[point] = pd->pd_step[point - 1] +
   1258						pcinfo->pddac[pdg][point - 1];
   1259
   1260			}
   1261
   1262			/* Highest gain curve -> min power */
   1263			if (pdg == 0)
   1264				chinfo[pier].min_pwr = pd->pd_pwr[0];
   1265
   1266			/* Lowest gain curve -> max power */
   1267			if (pdg == ee->ee_pd_gains[mode] - 1)
   1268				chinfo[pier].max_pwr =
   1269					pd->pd_pwr[pd->pd_points - 1];
   1270		}
   1271	}
   1272
   1273	return 0;
   1274
   1275err_out:
   1276	ath5k_eeprom_free_pcal_info(ah, mode);
   1277	return -ENOMEM;
   1278}
   1279
   1280/* Parse EEPROM data */
   1281static int
   1282ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)
   1283{
   1284	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
   1285	struct ath5k_chan_pcal_info_rf2413 *pcinfo;
   1286	struct ath5k_chan_pcal_info *chinfo;
   1287	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];
   1288	u32 offset;
   1289	int idx, i;
   1290	u16 val;
   1291	u8 pd_gains = 0;
   1292
   1293	/* Count how many curves we have and
   1294	 * identify them (which one of the 4
   1295	 * available curves we have on each count).
   1296	 * Curves are stored from higher to
   1297	 * lower gain so we go backwards */
   1298	for (idx = AR5K_EEPROM_N_PD_CURVES - 1; idx >= 0; idx--) {
   1299		/* ee_x_gain[mode] is x gain mask */
   1300		if ((ee->ee_x_gain[mode] >> idx) & 0x1)
   1301			pdgain_idx[pd_gains++] = idx;
   1302
   1303	}
   1304	ee->ee_pd_gains[mode] = pd_gains;
   1305
   1306	if (pd_gains == 0)
   1307		return -EINVAL;
   1308
   1309	offset = ath5k_cal_data_offset_2413(ee, mode);
   1310	switch (mode) {
   1311	case AR5K_EEPROM_MODE_11A:
   1312		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))
   1313			return 0;
   1314
   1315		ath5k_eeprom_init_11a_pcal_freq(ah, offset);
   1316		offset += AR5K_EEPROM_N_5GHZ_CHAN / 2;
   1317		chinfo = ee->ee_pwr_cal_a;
   1318		break;
   1319	case AR5K_EEPROM_MODE_11B:
   1320		if (!AR5K_EEPROM_HDR_11B(ee->ee_header))
   1321			return 0;
   1322
   1323		ath5k_eeprom_init_11bg_2413(ah, mode, offset);
   1324		offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
   1325		chinfo = ee->ee_pwr_cal_b;
   1326		break;
   1327	case AR5K_EEPROM_MODE_11G:
   1328		if (!AR5K_EEPROM_HDR_11G(ee->ee_header))
   1329			return 0;
   1330
   1331		ath5k_eeprom_init_11bg_2413(ah, mode, offset);
   1332		offset += AR5K_EEPROM_N_2GHZ_CHAN_2413 / 2;
   1333		chinfo = ee->ee_pwr_cal_g;
   1334		break;
   1335	default:
   1336		return -EINVAL;
   1337	}
   1338
   1339	for (i = 0; i < ee->ee_n_piers[mode]; i++) {
   1340		pcinfo = &chinfo[i].rf2413_info;
   1341
   1342		/*
   1343		 * Read pwr_i, pddac_i and the first
   1344		 * 2 pd points (pwr, pddac)
   1345		 */
   1346		AR5K_EEPROM_READ(offset++, val);
   1347		pcinfo->pwr_i[0] = val & 0x1f;
   1348		pcinfo->pddac_i[0] = (val >> 5) & 0x7f;
   1349		pcinfo->pwr[0][0] = (val >> 12) & 0xf;
   1350
   1351		AR5K_EEPROM_READ(offset++, val);
   1352		pcinfo->pddac[0][0] = val & 0x3f;
   1353		pcinfo->pwr[0][1] = (val >> 6) & 0xf;
   1354		pcinfo->pddac[0][1] = (val >> 10) & 0x3f;
   1355
   1356		AR5K_EEPROM_READ(offset++, val);
   1357		pcinfo->pwr[0][2] = val & 0xf;
   1358		pcinfo->pddac[0][2] = (val >> 4) & 0x3f;
   1359
   1360		pcinfo->pwr[0][3] = 0;
   1361		pcinfo->pddac[0][3] = 0;
   1362
   1363		if (pd_gains > 1) {
   1364			/*
   1365			 * Pd gain 0 is not the last pd gain
   1366			 * so it only has 2 pd points.
   1367			 * Continue with pd gain 1.
   1368			 */
   1369			pcinfo->pwr_i[1] = (val >> 10) & 0x1f;
   1370
   1371			pcinfo->pddac_i[1] = (val >> 15) & 0x1;
   1372			AR5K_EEPROM_READ(offset++, val);
   1373			pcinfo->pddac_i[1] |= (val & 0x3F) << 1;
   1374
   1375			pcinfo->pwr[1][0] = (val >> 6) & 0xf;
   1376			pcinfo->pddac[1][0] = (val >> 10) & 0x3f;
   1377
   1378			AR5K_EEPROM_READ(offset++, val);
   1379			pcinfo->pwr[1][1] = val & 0xf;
   1380			pcinfo->pddac[1][1] = (val >> 4) & 0x3f;
   1381			pcinfo->pwr[1][2] = (val >> 10) & 0xf;
   1382
   1383			pcinfo->pddac[1][2] = (val >> 14) & 0x3;
   1384			AR5K_EEPROM_READ(offset++, val);
   1385			pcinfo->pddac[1][2] |= (val & 0xF) << 2;
   1386
   1387			pcinfo->pwr[1][3] = 0;
   1388			pcinfo->pddac[1][3] = 0;
   1389		} else if (pd_gains == 1) {
   1390			/*
   1391			 * Pd gain 0 is the last one so
   1392			 * read the extra point.
   1393			 */
   1394			pcinfo->pwr[0][3] = (val >> 10) & 0xf;
   1395
   1396			pcinfo->pddac[0][3] = (val >> 14) & 0x3;
   1397			AR5K_EEPROM_READ(offset++, val);
   1398			pcinfo->pddac[0][3] |= (val & 0xF) << 2;
   1399		}
   1400
   1401		/*
   1402		 * Proceed with the other pd_gains
   1403		 * as above.
   1404		 */
   1405		if (pd_gains > 2) {
   1406			pcinfo->pwr_i[2] = (val >> 4) & 0x1f;
   1407			pcinfo->pddac_i[2] = (val >> 9) & 0x7f;
   1408
   1409			AR5K_EEPROM_READ(offset++, val);
   1410			pcinfo->pwr[2][0] = (val >> 0) & 0xf;
   1411			pcinfo->pddac[2][0] = (val >> 4) & 0x3f;
   1412			pcinfo->pwr[2][1] = (val >> 10) & 0xf;
   1413
   1414			pcinfo->pddac[2][1] = (val >> 14) & 0x3;
   1415			AR5K_EEPROM_READ(offset++, val);
   1416			pcinfo->pddac[2][1] |= (val & 0xF) << 2;
   1417
   1418			pcinfo->pwr[2][2] = (val >> 4) & 0xf;
   1419			pcinfo->pddac[2][2] = (val >> 8) & 0x3f;
   1420
   1421			pcinfo->pwr[2][3] = 0;
   1422			pcinfo->pddac[2][3] = 0;
   1423		} else if (pd_gains == 2) {
   1424			pcinfo->pwr[1][3] = (val >> 4) & 0xf;
   1425			pcinfo->pddac[1][3] = (val >> 8) & 0x3f;
   1426		}
   1427
   1428		if (pd_gains > 3) {
   1429			pcinfo->pwr_i[3] = (val >> 14) & 0x3;
   1430			AR5K_EEPROM_READ(offset++, val);
   1431			pcinfo->pwr_i[3] |= ((val >> 0) & 0x7) << 2;
   1432
   1433			pcinfo->pddac_i[3] = (val >> 3) & 0x7f;
   1434			pcinfo->pwr[3][0] = (val >> 10) & 0xf;
   1435			pcinfo->pddac[3][0] = (val >> 14) & 0x3;
   1436
   1437			AR5K_EEPROM_READ(offset++, val);
   1438			pcinfo->pddac[3][0] |= (val & 0xF) << 2;
   1439			pcinfo->pwr[3][1] = (val >> 4) & 0xf;
   1440			pcinfo->pddac[3][1] = (val >> 8) & 0x3f;
   1441
   1442			pcinfo->pwr[3][2] = (val >> 14) & 0x3;
   1443			AR5K_EEPROM_READ(offset++, val);
   1444			pcinfo->pwr[3][2] |= ((val >> 0) & 0x3) << 2;
   1445
   1446			pcinfo->pddac[3][2] = (val >> 2) & 0x3f;
   1447			pcinfo->pwr[3][3] = (val >> 8) & 0xf;
   1448
   1449			pcinfo->pddac[3][3] = (val >> 12) & 0xF;
   1450			AR5K_EEPROM_READ(offset++, val);
   1451			pcinfo->pddac[3][3] |= ((val >> 0) & 0x3) << 4;
   1452		} else if (pd_gains == 3) {
   1453			pcinfo->pwr[2][3] = (val >> 14) & 0x3;
   1454			AR5K_EEPROM_READ(offset++, val);
   1455			pcinfo->pwr[2][3] |= ((val >> 0) & 0x3) << 2;
   1456
   1457			pcinfo->pddac[2][3] = (val >> 2) & 0x3f;
   1458		}
   1459	}
   1460
   1461	return ath5k_eeprom_convert_pcal_info_2413(ah, mode, chinfo);
   1462}
   1463
   1464
   1465/*
   1466 * Read per rate target power (this is the maximum tx power
   1467 * supported by the card). This info is used when setting
   1468 * tx power, no matter the channel.
   1469 *
   1470 * This also works for v5 EEPROMs.
   1471 */
   1472static int
   1473ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)
   1474{
   1475	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
   1476	struct ath5k_rate_pcal_info *rate_pcal_info;
   1477	u8 *rate_target_pwr_num;
   1478	u32 offset;
   1479	u16 val;
   1480	int i;
   1481
   1482	offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);
   1483	rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode];
   1484	switch (mode) {
   1485	case AR5K_EEPROM_MODE_11A:
   1486		offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);
   1487		rate_pcal_info = ee->ee_rate_tpwr_a;
   1488		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN;
   1489		break;
   1490	case AR5K_EEPROM_MODE_11B:
   1491		offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version);
   1492		rate_pcal_info = ee->ee_rate_tpwr_b;
   1493		ee->ee_rate_target_pwr_num[mode] = 2; /* 3rd is g mode's 1st */
   1494		break;
   1495	case AR5K_EEPROM_MODE_11G:
   1496		offset += AR5K_EEPROM_TARGET_PWR_OFF_11G(ee->ee_version);
   1497		rate_pcal_info = ee->ee_rate_tpwr_g;
   1498		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_2GHZ_CHAN;
   1499		break;
   1500	default:
   1501		return -EINVAL;
   1502	}
   1503
   1504	/* Different freq mask for older eeproms (<= v3.2) */
   1505	if (ee->ee_version <= AR5K_EEPROM_VERSION_3_2) {
   1506		for (i = 0; i < (*rate_target_pwr_num); i++) {
   1507			AR5K_EEPROM_READ(offset++, val);
   1508			rate_pcal_info[i].freq =
   1509			    ath5k_eeprom_bin2freq(ee, (val >> 9) & 0x7f, mode);
   1510
   1511			rate_pcal_info[i].target_power_6to24 = ((val >> 3) & 0x3f);
   1512			rate_pcal_info[i].target_power_36 = (val << 3) & 0x3f;
   1513
   1514			AR5K_EEPROM_READ(offset++, val);
   1515
   1516			if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
   1517			    val == 0) {
   1518				(*rate_target_pwr_num) = i;
   1519				break;
   1520			}
   1521
   1522			rate_pcal_info[i].target_power_36 |= ((val >> 13) & 0x7);
   1523			rate_pcal_info[i].target_power_48 = ((val >> 7) & 0x3f);
   1524			rate_pcal_info[i].target_power_54 = ((val >> 1) & 0x3f);
   1525		}
   1526	} else {
   1527		for (i = 0; i < (*rate_target_pwr_num); i++) {
   1528			AR5K_EEPROM_READ(offset++, val);
   1529			rate_pcal_info[i].freq =
   1530			    ath5k_eeprom_bin2freq(ee, (val >> 8) & 0xff, mode);
   1531
   1532			rate_pcal_info[i].target_power_6to24 = ((val >> 2) & 0x3f);
   1533			rate_pcal_info[i].target_power_36 = (val << 4) & 0x3f;
   1534
   1535			AR5K_EEPROM_READ(offset++, val);
   1536
   1537			if (rate_pcal_info[i].freq == AR5K_EEPROM_CHANNEL_DIS ||
   1538			    val == 0) {
   1539				(*rate_target_pwr_num) = i;
   1540				break;
   1541			}
   1542
   1543			rate_pcal_info[i].target_power_36 |= (val >> 12) & 0xf;
   1544			rate_pcal_info[i].target_power_48 = ((val >> 6) & 0x3f);
   1545			rate_pcal_info[i].target_power_54 = (val & 0x3f);
   1546		}
   1547	}
   1548
   1549	return 0;
   1550}
   1551
   1552
   1553/*
   1554 * Read per channel calibration info from EEPROM
   1555 *
   1556 * This info is used to calibrate the baseband power table. Imagine
   1557 * that for each channel there is a power curve that's hw specific
   1558 * (depends on amplifier etc) and we try to "correct" this curve using
   1559 * offsets we pass on to phy chip (baseband -> before amplifier) so that
   1560 * it can use accurate power values when setting tx power (takes amplifier's
   1561 * performance on each channel into account).
   1562 *
   1563 * EEPROM provides us with the offsets for some pre-calibrated channels
   1564 * and we have to interpolate to create the full table for these channels and
   1565 * also the table for any channel.
   1566 */
   1567static int
   1568ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)
   1569{
   1570	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
   1571	int (*read_pcal)(struct ath5k_hw *hw, int mode);
   1572	int mode;
   1573	int err;
   1574
   1575	if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) &&
   1576			(AR5K_EEPROM_EEMAP(ee->ee_misc0) == 1))
   1577		read_pcal = ath5k_eeprom_read_pcal_info_5112;
   1578	else if ((ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0) &&
   1579			(AR5K_EEPROM_EEMAP(ee->ee_misc0) == 2))
   1580		read_pcal = ath5k_eeprom_read_pcal_info_2413;
   1581	else
   1582		read_pcal = ath5k_eeprom_read_pcal_info_5111;
   1583
   1584
   1585	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G;
   1586	mode++) {
   1587		err = read_pcal(ah, mode);
   1588		if (err)
   1589			return err;
   1590
   1591		err = ath5k_eeprom_read_target_rate_pwr_info(ah, mode);
   1592		if (err < 0)
   1593			return err;
   1594	}
   1595
   1596	return 0;
   1597}
   1598
   1599/* Read conformance test limits used for regulatory control */
   1600static int
   1601ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)
   1602{
   1603	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
   1604	struct ath5k_edge_power *rep;
   1605	unsigned int fmask, pmask;
   1606	unsigned int ctl_mode;
   1607	int i, j;
   1608	u32 offset;
   1609	u16 val;
   1610
   1611	pmask = AR5K_EEPROM_POWER_M;
   1612	fmask = AR5K_EEPROM_FREQ_M(ee->ee_version);
   1613	offset = AR5K_EEPROM_CTL(ee->ee_version);
   1614	ee->ee_ctls = AR5K_EEPROM_N_CTLS(ee->ee_version);
   1615	for (i = 0; i < ee->ee_ctls; i += 2) {
   1616		AR5K_EEPROM_READ(offset++, val);
   1617		ee->ee_ctl[i] = (val >> 8) & 0xff;
   1618		ee->ee_ctl[i + 1] = val & 0xff;
   1619	}
   1620
   1621	offset = AR5K_EEPROM_GROUP8_OFFSET;
   1622	if (ee->ee_version >= AR5K_EEPROM_VERSION_4_0)
   1623		offset += AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1) -
   1624			AR5K_EEPROM_GROUP5_OFFSET;
   1625	else
   1626		offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);
   1627
   1628	rep = ee->ee_ctl_pwr;
   1629	for (i = 0; i < ee->ee_ctls; i++) {
   1630		switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) {
   1631		case AR5K_CTL_11A:
   1632		case AR5K_CTL_TURBO:
   1633			ctl_mode = AR5K_EEPROM_MODE_11A;
   1634			break;
   1635		default:
   1636			ctl_mode = AR5K_EEPROM_MODE_11G;
   1637			break;
   1638		}
   1639		if (ee->ee_ctl[i] == 0) {
   1640			if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3)
   1641				offset += 8;
   1642			else
   1643				offset += 7;
   1644			rep += AR5K_EEPROM_N_EDGES;
   1645			continue;
   1646		}
   1647		if (ee->ee_version >= AR5K_EEPROM_VERSION_3_3) {
   1648			for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
   1649				AR5K_EEPROM_READ(offset++, val);
   1650				rep[j].freq = (val >> 8) & fmask;
   1651				rep[j + 1].freq = val & fmask;
   1652			}
   1653			for (j = 0; j < AR5K_EEPROM_N_EDGES; j += 2) {
   1654				AR5K_EEPROM_READ(offset++, val);
   1655				rep[j].edge = (val >> 8) & pmask;
   1656				rep[j].flag = (val >> 14) & 1;
   1657				rep[j + 1].edge = val & pmask;
   1658				rep[j + 1].flag = (val >> 6) & 1;
   1659			}
   1660		} else {
   1661			AR5K_EEPROM_READ(offset++, val);
   1662			rep[0].freq = (val >> 9) & fmask;
   1663			rep[1].freq = (val >> 2) & fmask;
   1664			rep[2].freq = (val << 5) & fmask;
   1665
   1666			AR5K_EEPROM_READ(offset++, val);
   1667			rep[2].freq |= (val >> 11) & 0x1f;
   1668			rep[3].freq = (val >> 4) & fmask;
   1669			rep[4].freq = (val << 3) & fmask;
   1670
   1671			AR5K_EEPROM_READ(offset++, val);
   1672			rep[4].freq |= (val >> 13) & 0x7;
   1673			rep[5].freq = (val >> 6) & fmask;
   1674			rep[6].freq = (val << 1) & fmask;
   1675
   1676			AR5K_EEPROM_READ(offset++, val);
   1677			rep[6].freq |= (val >> 15) & 0x1;
   1678			rep[7].freq = (val >> 8) & fmask;
   1679
   1680			rep[0].edge = (val >> 2) & pmask;
   1681			rep[1].edge = (val << 4) & pmask;
   1682
   1683			AR5K_EEPROM_READ(offset++, val);
   1684			rep[1].edge |= (val >> 12) & 0xf;
   1685			rep[2].edge = (val >> 6) & pmask;
   1686			rep[3].edge = val & pmask;
   1687
   1688			AR5K_EEPROM_READ(offset++, val);
   1689			rep[4].edge = (val >> 10) & pmask;
   1690			rep[5].edge = (val >> 4) & pmask;
   1691			rep[6].edge = (val << 2) & pmask;
   1692
   1693			AR5K_EEPROM_READ(offset++, val);
   1694			rep[6].edge |= (val >> 14) & 0x3;
   1695			rep[7].edge = (val >> 8) & pmask;
   1696		}
   1697		for (j = 0; j < AR5K_EEPROM_N_EDGES; j++) {
   1698			rep[j].freq = ath5k_eeprom_bin2freq(ee,
   1699				rep[j].freq, ctl_mode);
   1700		}
   1701		rep += AR5K_EEPROM_N_EDGES;
   1702	}
   1703
   1704	return 0;
   1705}
   1706
   1707static int
   1708ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)
   1709{
   1710	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
   1711	u32 offset;
   1712	u16 val;
   1713	int  i;
   1714
   1715	offset = AR5K_EEPROM_CTL(ee->ee_version) +
   1716				AR5K_EEPROM_N_CTLS(ee->ee_version);
   1717
   1718	if (ee->ee_version < AR5K_EEPROM_VERSION_5_3) {
   1719		/* No spur info for 5GHz */
   1720		ee->ee_spur_chans[0][0] = AR5K_EEPROM_NO_SPUR;
   1721		/* 2 channels for 2GHz (2464/2420) */
   1722		ee->ee_spur_chans[0][1] = AR5K_EEPROM_5413_SPUR_CHAN_1;
   1723		ee->ee_spur_chans[1][1] = AR5K_EEPROM_5413_SPUR_CHAN_2;
   1724		ee->ee_spur_chans[2][1] = AR5K_EEPROM_NO_SPUR;
   1725	} else if (ee->ee_version >= AR5K_EEPROM_VERSION_5_3) {
   1726		for (i = 0; i < AR5K_EEPROM_N_SPUR_CHANS; i++) {
   1727			AR5K_EEPROM_READ(offset, val);
   1728			ee->ee_spur_chans[i][0] = val;
   1729			AR5K_EEPROM_READ(offset + AR5K_EEPROM_N_SPUR_CHANS,
   1730									val);
   1731			ee->ee_spur_chans[i][1] = val;
   1732			offset++;
   1733		}
   1734	}
   1735
   1736	return 0;
   1737}
   1738
   1739
   1740/***********************\
   1741* Init/Detach functions *
   1742\***********************/
   1743
   1744/*
   1745 * Initialize eeprom data structure
   1746 */
   1747int
   1748ath5k_eeprom_init(struct ath5k_hw *ah)
   1749{
   1750	int err;
   1751
   1752	err = ath5k_eeprom_init_header(ah);
   1753	if (err < 0)
   1754		return err;
   1755
   1756	err = ath5k_eeprom_init_modes(ah);
   1757	if (err < 0)
   1758		return err;
   1759
   1760	err = ath5k_eeprom_read_pcal_info(ah);
   1761	if (err < 0)
   1762		return err;
   1763
   1764	err = ath5k_eeprom_read_ctl_info(ah);
   1765	if (err < 0)
   1766		return err;
   1767
   1768	err = ath5k_eeprom_read_spur_chans(ah);
   1769	if (err < 0)
   1770		return err;
   1771
   1772	return 0;
   1773}
   1774
   1775void
   1776ath5k_eeprom_detach(struct ath5k_hw *ah)
   1777{
   1778	u8 mode;
   1779
   1780	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
   1781		ath5k_eeprom_free_pcal_info(ah, mode);
   1782}
   1783
   1784int
   1785ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah,
   1786		struct ieee80211_channel *channel)
   1787{
   1788	switch (channel->hw_value) {
   1789	case AR5K_MODE_11A:
   1790		return AR5K_EEPROM_MODE_11A;
   1791	case AR5K_MODE_11G:
   1792		return AR5K_EEPROM_MODE_11G;
   1793	case AR5K_MODE_11B:
   1794		return AR5K_EEPROM_MODE_11B;
   1795	default:
   1796		ATH5K_WARN(ah, "channel is not A/B/G!");
   1797		return AR5K_EEPROM_MODE_11A;
   1798	}
   1799}