diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/eeprom.c')
| -rw-r--r-- | drivers/net/wireless/ath/ath5k/eeprom.c | 226 |
1 files changed, 105 insertions, 121 deletions
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index efb672cb31e..94d34ee0226 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -21,12 +21,13 @@ * 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" /******************\ @@ -105,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, @@ -119,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 ? @@ -223,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); @@ -255,7 +256,7 @@ static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, 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; @@ -349,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; @@ -422,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; @@ -436,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: @@ -516,7 +517,7 @@ ath5k_eeprom_read_freq_list(struct ath5k_hw *ah, int *offset, int max, u16 val; ee->ee_n_piers[mode] = 0; - while(i < max) { + while (i < max) { AR5K_EEPROM_READ(o++, val); freq1 = val & 0xff; @@ -602,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; @@ -634,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 @@ -644,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; @@ -660,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 @@ -684,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 @@ -708,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 */ @@ -734,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 */ @@ -747,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; @@ -833,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 @@ -867,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++) { @@ -886,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) */ @@ -925,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) */ @@ -954,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 */ @@ -1111,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, @@ -1156,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++) { @@ -1177,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]; @@ -1213,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 */ @@ -1423,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); @@ -1534,53 +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; -} - /* Read conformance test limits used for regulatory control */ static int ath5k_eeprom_read_ctl_info(struct ath5k_hw *ah) @@ -1611,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; @@ -1721,35 +1733,6 @@ ath5k_eeprom_read_spur_chans(struct ath5k_hw *ah) return ret; } -/* - * Read the MAC address from eeprom - */ -int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) -{ - u8 mac_d[ETH_ALEN] = {}; - u32 total, offset; - u16 data; - int octet; - - AR5K_EEPROM_READ(0x20, data); - - for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { - AR5K_EEPROM_READ(offset, data); - - total += data; - mac_d[octet + 1] = data & 0xff; - mac_d[octet] = data >> 8; - octet += 2; - } - - if (!total || total == 3 * 0xffff) - return -EINVAL; - - memcpy(mac, mac_d, ETH_ALEN); - - return 0; -} - /***********************\ * Init/Detach functions * @@ -1796,17 +1779,18 @@ ath5k_eeprom_detach(struct ath5k_hw *ah) } int -ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel) +ath5k_eeprom_mode_from_channel(struct ath5k_hw *ah, + struct ieee80211_channel *channel) { - switch (channel->hw_value & CHANNEL_MODES) { - case CHANNEL_A: - case CHANNEL_XR: + switch (channel->hw_value) { + case AR5K_MODE_11A: return AR5K_EEPROM_MODE_11A; - case CHANNEL_G: + case AR5K_MODE_11G: return AR5K_EEPROM_MODE_11G; - case CHANNEL_B: + case AR5K_MODE_11B: return AR5K_EEPROM_MODE_11B; default: - return -1; + ATH5K_WARN(ah, "channel is not A/B/G!"); + return AR5K_EEPROM_MODE_11A; } } |
