diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/eeprom.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.c | 307 | 
1 files changed, 141 insertions, 166 deletions
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 39722dd73e4..94d34ee0226 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -21,52 +21,24 @@  * EEPROM access functions and helpers *  \*************************************/ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +  #include <linux/slab.h>  #include "ath5k.h"  #include "reg.h"  #include "debug.h" -#include "base.h" -/* - * Read from eeprom - */ -static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) -{ -	u32 status, timeout; -	/* -	 * Initialize EEPROM access -	 */ -	if (ah->ah_version == AR5K_AR5210) { -		AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); -		(void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); -	} else { -		ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); -		AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, -				AR5K_EEPROM_CMD_READ); -	} - -	for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { -		status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); -		if (status & AR5K_EEPROM_STAT_RDDONE) { -			if (status & AR5K_EEPROM_STAT_RDERR) -				return -EIO; -			*data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & -					0xffff); -			return 0; -		} -		udelay(15); -	} - -	return -ETIMEDOUT; -} +/******************\ +* Helper functions * +\******************/  /*   * Translate binary channel representation in EEPROM to frequency   */  static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin, -                                 unsigned int mode) +							unsigned int mode)  {  	u16 val; @@ -89,6 +61,11 @@ static u16 ath5k_eeprom_bin2freq(struct ath5k_eeprom_info *ee, u16 bin,  	return val;  } + +/*********\ +* Parsers * +\*********/ +  /*   * Initialize eeprom & capabilities structs   */ @@ -96,7 +73,6 @@ static int  ath5k_eeprom_init_header(struct ath5k_hw *ah)  {  	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; -	int ret;  	u16 val;  	u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX; @@ -130,7 +106,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)  		 * big still, waiting on a better value.  		 */  		if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) { -			ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: " +			ATH5K_ERR(ah, "Invalid max custom EEPROM size: "  				  "%d (0x%04x) max expected: %d (0x%04x)\n",  				  eep_max, eep_max,  				  3 * AR5K_EEPROM_INFO_MAX, @@ -144,7 +120,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)  		cksum ^= val;  	}  	if (cksum != AR5K_EEPROM_INFO_CKSUM) { -		ATH5K_ERR(ah->ah_sc, "Invalid EEPROM " +		ATH5K_ERR(ah, "Invalid EEPROM "  			  "checksum: 0x%04x eep_max: 0x%04x (%s)\n",  			  cksum, eep_max,  			  eep_max == AR5K_EEPROM_INFO_MAX ? @@ -198,7 +174,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)  	 *  	 * XXX: Serdes values seem to be fixed so  	 * no need to read them here, we write them -	 * during ath5k_hw_attach */ +	 * during ath5k_hw_init */  	AR5K_EEPROM_READ(AR5K_EEPROM_PCIE_OFFSET, val);  	ee->ee_serdes = (val == AR5K_EEPROM_PCIE_SERDES_SECTION) ?  							true : false; @@ -216,7 +192,7 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,  	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;  	u32 o = *offset;  	u16 val; -	int ret, i = 0; +	int i = 0;  	AR5K_EEPROM_READ(o++, val);  	ee->ee_switch_settling[mode]	= (val >> 8) & 0x7f; @@ -248,14 +224,14 @@ static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,  	ah->ah_ant_ctl[mode][AR5K_ANT_CTL] =  	    (ee->ee_ant_control[mode][0] << 4);  	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_A] = -	     ee->ee_ant_control[mode][1] 	| -	    (ee->ee_ant_control[mode][2] << 6) 	| +	     ee->ee_ant_control[mode][1]	| +	    (ee->ee_ant_control[mode][2] << 6)	|  	    (ee->ee_ant_control[mode][3] << 12) |  	    (ee->ee_ant_control[mode][4] << 18) |  	    (ee->ee_ant_control[mode][5] << 24);  	ah->ah_ant_ctl[mode][AR5K_ANT_SWTABLE_B] = -	     ee->ee_ant_control[mode][6] 	| -	    (ee->ee_ant_control[mode][7] << 6) 	| +	     ee->ee_ant_control[mode][6]	| +	    (ee->ee_ant_control[mode][7] << 6)	|  	    (ee->ee_ant_control[mode][8] << 12) |  	    (ee->ee_ant_control[mode][9] << 18) |  	    (ee->ee_ant_control[mode][10] << 24); @@ -276,12 +252,11 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,  	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;  	u32 o = *offset;  	u16 val; -	int ret;  	ee->ee_n_piers[mode] = 0;  	AR5K_EEPROM_READ(o++, val);  	ee->ee_adc_desired_size[mode]	= (s8)((val >> 8) & 0xff); -	switch(mode) { +	switch (mode) {  	case AR5K_EEPROM_MODE_11A:  		ee->ee_ob[mode][3]	= (val >> 5) & 0x7;  		ee->ee_db[mode][3]	= (val >> 2) & 0x7; @@ -375,7 +350,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,  	/* Note: >= v5 have bg freq piers on another location  	 * so these freq piers are ignored for >= v5 (should be 0xff  	 * anyway) */ -	switch(mode) { +	switch (mode) {  	case AR5K_EEPROM_MODE_11A:  		if (ah->ah_ee_version < AR5K_EEPROM_VERSION_4_1)  			break; @@ -448,7 +423,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,  	if (ee->ee_version < AR5K_EEPROM_VERSION_5_0)  		goto done; -	switch (mode){ +	switch (mode) {  	case AR5K_EEPROM_MODE_11A:  		ee->ee_switch_settling_turbo[mode] = (val >> 6) & 0x7f; @@ -462,7 +437,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,  		ee->ee_adc_desired_size_turbo[mode] |= (val & 0x1) << 7;  		ee->ee_pga_desired_size_turbo[mode] = (val >> 1) & 0xff; -		if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >=2) +		if (AR5K_EEPROM_EEMAP(ee->ee_misc0) >= 2)  			ee->ee_pd_gain_overlap = (val >> 9) & 0xf;  		break;  	case AR5K_EEPROM_MODE_11G: @@ -539,11 +514,10 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max,  	int o = *offset;  	int i = 0;  	u8 freq1, freq2; -	int ret;  	u16 val;  	ee->ee_n_piers[mode] = 0; -	while(i < max) { +	while (i < max) {  		AR5K_EEPROM_READ(o++, val);  		freq1 = val & 0xff; @@ -575,7 +549,7 @@ ath5k_eeprom_init_11a_pcal_freq(struct ath5k_hw *ah, int offset)  {  	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;  	struct ath5k_chan_pcal_info *pcal = ee->ee_pwr_cal_a; -	int i, ret; +	int i;  	u16 val;  	u8 mask; @@ -629,7 +603,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)  	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;  	struct ath5k_chan_pcal_info *pcal; -	switch(mode) { +	switch (mode) {  	case AR5K_EEPROM_MODE_11B:  		pcal = ee->ee_pwr_cal_b;  		break; @@ -647,6 +621,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)  	return 0;  } +  /*   * Read power calibration for RF5111 chips   * @@ -660,7 +635,7 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)  /* Used to match PCDAC steps with power values on RF5111 chips   * (eeprom versions < 4). For RF5111 we have 11 pre-defined PCDAC   * steps that match with the power values we read from eeprom. On - * older eeprom versions (< 3.2) these steps are equaly spaced at + * older eeprom versions (< 3.2) these steps are equally spaced at   * 10% of the pcdac curve -until the curve reaches its maximum-   * (11 steps from 0 to 100%) but on newer eeprom versions (>= 3.2)   * these 11 steps are spaced in a different way. This function returns @@ -670,10 +645,12 @@ ath5k_eeprom_init_11bg_2413(struct ath5k_hw *ah, unsigned int mode, int offset)  static inline void  ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)  { -	static const u16 intercepts3[] = -		{ 0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 }; -	static const u16 intercepts3_2[] = -		{ 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }; +	static const u16 intercepts3[] = { +		0, 5, 10, 20, 30, 50, 70, 85, 90, 95, 100 +	}; +	static const u16 intercepts3_2[] = { +		0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 +	};  	const u16 *ip;  	int i; @@ -686,6 +663,51 @@ ath5k_get_pcdac_intercepts(struct ath5k_hw *ah, u8 min, u8 max, u8 *vp)  		vp[i] = (ip[i] * max + (100 - ip[i]) * min) / 100;  } +static int +ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) +{ +	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; +	struct ath5k_chan_pcal_info *chinfo; +	u8 pier, pdg; + +	switch (mode) { +	case AR5K_EEPROM_MODE_11A: +		if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) +			return 0; +		chinfo = ee->ee_pwr_cal_a; +		break; +	case AR5K_EEPROM_MODE_11B: +		if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) +			return 0; +		chinfo = ee->ee_pwr_cal_b; +		break; +	case AR5K_EEPROM_MODE_11G: +		if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) +			return 0; +		chinfo = ee->ee_pwr_cal_g; +		break; +	default: +		return -EINVAL; +	} + +	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { +		if (!chinfo[pier].pd_curves) +			continue; + +		for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) { +			struct ath5k_pdgain_info *pd = +					&chinfo[pier].pd_curves[pdg]; + +			kfree(pd->pd_step); +			kfree(pd->pd_pwr); +		} + +		kfree(chinfo[pier].pd_curves); +	} + +	return 0; +} +  /* Convert RF5111 specific data to generic raw data   * used by interpolation code */  static int @@ -710,7 +732,7 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,  				GFP_KERNEL);  		if (!chinfo[pier].pd_curves) -			return -ENOMEM; +			goto err_out;  		/* Only one curve for RF5111  		 * find out which one and place @@ -734,16 +756,16 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,  		pd->pd_step = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,  					sizeof(u8), GFP_KERNEL);  		if (!pd->pd_step) -			return -ENOMEM; +			goto err_out;  		pd->pd_pwr = kcalloc(AR5K_EEPROM_N_PWR_POINTS_5111,  					sizeof(s16), GFP_KERNEL);  		if (!pd->pd_pwr) -			return -ENOMEM; +			goto err_out;  		/* Fill raw dataset  		 * (convert power to 0.25dB units -		 * for RF5112 combatibility) */ +		 * for RF5112 compatibility) */  		for (point = 0; point < pd->pd_points; point++) {  			/* Absolute values */ @@ -760,6 +782,10 @@ ath5k_eeprom_convert_pcal_info_5111(struct ath5k_hw *ah, int mode,  	}  	return 0; + +err_out: +	ath5k_eeprom_free_pcal_info(ah, mode); +	return -ENOMEM;  }  /* Parse EEPROM data */ @@ -773,7 +799,7 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)  	u16 val;  	offset = AR5K_EEPROM_GROUPS_START(ee->ee_version); -	switch(mode) { +	switch (mode) {  	case AR5K_EEPROM_MODE_11A:  		if (!AR5K_EEPROM_HDR_11A(ee->ee_header))  			return 0; @@ -859,7 +885,7 @@ ath5k_eeprom_read_pcal_info_5111(struct ath5k_hw *ah, int mode)   * Read power calibration for RF5112 chips   *   * For RF5112 we have 4 XPD -eXternal Power Detector- curves - * for each calibrated channel on 0, -6, -12 and -18dbm but we only + * for each calibrated channel on 0, -6, -12 and -18dBm but we only   * use the higher (3) and the lower (0) curves. Each curve has 0.5dB   * power steps on x axis and PCDAC steps on y axis and looks like a   * linear function. To recreate the curve and pass the power values @@ -893,7 +919,7 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,  					GFP_KERNEL);  		if (!chinfo[pier].pd_curves) -			return -ENOMEM; +			goto err_out;  		/* Fill pd_curves */  		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { @@ -912,14 +938,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,  						sizeof(u8), GFP_KERNEL);  				if (!pd->pd_step) -					return -ENOMEM; +					goto err_out;  				pd->pd_pwr = kcalloc(pd->pd_points,  						sizeof(s16), GFP_KERNEL);  				if (!pd->pd_pwr) -					return -ENOMEM; - +					goto err_out;  				/* Fill raw dataset  				 * (all power levels are in 0.25dB units) */ @@ -951,13 +976,13 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,  						sizeof(u8), GFP_KERNEL);  				if (!pd->pd_step) -					return -ENOMEM; +					goto err_out;  				pd->pd_pwr = kcalloc(pd->pd_points,  						sizeof(s16), GFP_KERNEL);  				if (!pd->pd_pwr) -					return -ENOMEM; +					goto err_out;  				/* Fill raw dataset  				 * (all power levels are in 0.25dB units) */ @@ -980,6 +1005,10 @@ ath5k_eeprom_convert_pcal_info_5112(struct ath5k_hw *ah, int mode,  	}  	return 0; + +err_out: +	ath5k_eeprom_free_pcal_info(ah, mode); +	return -ENOMEM;  }  /* Parse EEPROM data */ @@ -993,7 +1022,6 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)  	u32 offset;  	u8 i, c;  	u16 val; -	int ret;  	u8 pd_gains = 0;  	/* Count how many curves we have and @@ -1107,7 +1135,7 @@ ath5k_eeprom_read_pcal_info_5112(struct ath5k_hw *ah, int mode)   *   * To recreate the curves we read here the points and interpolate   * later. Note that in most cases only 2 (higher and lower) curves are - * used (like RF5112) but vendors have the oportunity to include all + * used (like RF5112) but vendors have the opportunity to include all   * 4 curves on eeprom. The final curve (higher power) has an extra   * point for better accuracy like RF5112.   */ @@ -1138,7 +1166,7 @@ ath5k_cal_data_offset_2413(struct ath5k_eeprom_info *ee, int mode)  {  	u32 offset = AR5K_EEPROM_CAL_DATA_START(ee->ee_misc4); -	switch(mode) { +	switch (mode) {  	case AR5K_EEPROM_MODE_11G:  		if (AR5K_EEPROM_HDR_11B(ee->ee_header))  			offset += ath5k_pdgains_size_2413(ee, @@ -1183,7 +1211,7 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,  					GFP_KERNEL);  		if (!chinfo[pier].pd_curves) -			return -ENOMEM; +			goto err_out;  		/* Fill pd_curves */  		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { @@ -1204,17 +1232,17 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,  					sizeof(u8), GFP_KERNEL);  			if (!pd->pd_step) -				return -ENOMEM; +				goto err_out;  			pd->pd_pwr = kcalloc(pd->pd_points,  					sizeof(s16), GFP_KERNEL);  			if (!pd->pd_pwr) -				return -ENOMEM; +				goto err_out;  			/* Fill raw dataset  			 * convert all pwr levels to -			 * quarter dB for RF5112 combatibility */ +			 * quarter dB for RF5112 compatibility */  			pd->pd_step[0] = pcinfo->pddac_i[pdg];  			pd->pd_pwr[0] = 4 * pcinfo->pwr_i[pdg]; @@ -1240,6 +1268,10 @@ ath5k_eeprom_convert_pcal_info_2413(struct ath5k_hw *ah, int mode,  	}  	return 0; + +err_out: +	ath5k_eeprom_free_pcal_info(ah, mode); +	return -ENOMEM;  }  /* Parse EEPROM data */ @@ -1251,7 +1283,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)  	struct ath5k_chan_pcal_info *chinfo;  	u8 *pdgain_idx = ee->ee_pdc_to_idx[mode];  	u32 offset; -	int idx, i, ret; +	int idx, i;  	u16 val;  	u8 pd_gains = 0; @@ -1329,7 +1361,7 @@ ath5k_eeprom_read_pcal_info_2413(struct ath5k_hw *ah, int mode)  			/*  			 * Pd gain 0 is not the last pd gain  			 * so it only has 2 pd points. -			 * Continue wih pd gain 1. +			 * Continue with pd gain 1.  			 */  			pcinfo->pwr_i[1] = (val >> 10) & 0x1f; @@ -1442,7 +1474,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)  	u8 *rate_target_pwr_num;  	u32 offset;  	u16 val; -	int ret, i; +	int i;  	offset = AR5K_EEPROM_TARGET_PWRSTART(ee->ee_misc1);  	rate_target_pwr_num = &ee->ee_rate_target_pwr_num[mode]; @@ -1450,7 +1482,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)  	case AR5K_EEPROM_MODE_11A:  		offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version);  		rate_pcal_info = ee->ee_rate_tpwr_a; -		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; +		ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN;  		break;  	case AR5K_EEPROM_MODE_11B:  		offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); @@ -1514,6 +1546,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode)  	return 0;  } +  /*   * Read per channel calibration info from EEPROM   * @@ -1560,62 +1593,6 @@ ath5k_eeprom_read_pcal_info(struct ath5k_hw *ah)  	return 0;  } -static int -ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) -{ -	struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; -	struct ath5k_chan_pcal_info *chinfo; -	u8 pier, pdg; - -	switch (mode) { -	case AR5K_EEPROM_MODE_11A: -		if (!AR5K_EEPROM_HDR_11A(ee->ee_header)) -			return 0; -		chinfo = ee->ee_pwr_cal_a; -		break; -	case AR5K_EEPROM_MODE_11B: -		if (!AR5K_EEPROM_HDR_11B(ee->ee_header)) -			return 0; -		chinfo = ee->ee_pwr_cal_b; -		break; -	case AR5K_EEPROM_MODE_11G: -		if (!AR5K_EEPROM_HDR_11G(ee->ee_header)) -			return 0; -		chinfo = ee->ee_pwr_cal_g; -		break; -	default: -		return -EINVAL; -	} - -	for (pier = 0; pier < ee->ee_n_piers[mode]; pier++) { -		if (!chinfo[pier].pd_curves) -			continue; - -		for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { -			struct ath5k_pdgain_info *pd = -					&chinfo[pier].pd_curves[pdg]; - -			if (pd != NULL) { -				kfree(pd->pd_step); -				kfree(pd->pd_pwr); -			} -		} - -		kfree(chinfo[pier].pd_curves); -	} - -	return 0; -} - -void -ath5k_eeprom_detach(struct ath5k_hw *ah) -{ -	u8 mode; - -	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) -		ath5k_eeprom_free_pcal_info(ah, mode); -} -  /* Read conformance test limits used for regulatory control */  static int  ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) @@ -1624,7 +1601,7 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)  	struct ath5k_edge_power *rep;  	unsigned int fmask, pmask;  	unsigned int ctl_mode; -	int ret, i, j; +	int i, j;  	u32 offset;  	u16 val; @@ -1646,8 +1623,8 @@ ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah)  		offset += AR5K_EEPROM_GROUPS_START(ee->ee_version);  	rep = ee->ee_ctl_pwr; -	for(i = 0; i < ee->ee_ctls; i++) { -		switch(ee->ee_ctl[i] & AR5K_CTL_MODE_M) { +	for (i = 0; i < ee->ee_ctls; i++) { +		switch (ee->ee_ctl[i] & AR5K_CTL_MODE_M) {  		case AR5K_CTL_11A:  		case AR5K_CTL_TURBO:  			ctl_mode = AR5K_EEPROM_MODE_11A; @@ -1756,6 +1733,11 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah)  	return ret;  } + +/***********************\ +* Init/Detach functions * +\***********************/ +  /*   * Initialize eeprom data structure   */ @@ -1787,35 +1769,28 @@ ath5k_eeprom_init(struct ath5k_hw *ah)  	return 0;  } -/* - * Read the MAC address from eeprom - */ -int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) +void +ath5k_eeprom_detach(struct ath5k_hw *ah)  { -	u8 mac_d[ETH_ALEN] = {}; -	u32 total, offset; -	u16 data; -	int octet, ret; - -	ret = ath5k_hw_eeprom_read(ah, 0x20, &data); -	if (ret) -		return ret; +	u8 mode; -	for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { -		ret = ath5k_hw_eeprom_read(ah, offset, &data); -		if (ret) -			return ret; +	for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++) +		ath5k_eeprom_free_pcal_info(ah, mode); +} -		total += data; -		mac_d[octet + 1] = data & 0xff; -		mac_d[octet] = data >> 8; -		octet += 2; +int +ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah, +		struct ieee80211_channel *channel) +{ +	switch (channel->hw_value) { +	case AR5K_MODE_11A: +		return AR5K_EEPROM_MODE_11A; +	case AR5K_MODE_11G: +		return AR5K_EEPROM_MODE_11G; +	case AR5K_MODE_11B: +		return AR5K_EEPROM_MODE_11B; +	default: +		ATH5K_WARN(ah, "channel is not A/B/G!"); +		return AR5K_EEPROM_MODE_11A;  	} - -	if (!total || total == 3 * 0xffff) -		return -EINVAL; - -	memcpy(mac, mac_d, ETH_ALEN); - -	return 0;  }  | 
