Commit 073d3f5f authored by Tomas Winkler's avatar Tomas Winkler Committed by John W. Linville

iwlwifi: changing EEPROM layout handling

This patch
1. changes the current EEPROM handling through a single HW struct
layout representation, to more general approach, treating the EEPROM
image as a flat bytes array, handling this image through ops functions
and offsets.
2. Eeprom is dynamically allocated accroding HW type
Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarRon Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5da4b55f
...@@ -69,6 +69,9 @@ ...@@ -69,6 +69,9 @@
#ifndef __iwl_4965_hw_h__ #ifndef __iwl_4965_hw_h__
#define __iwl_4965_hw_h__ #define __iwl_4965_hw_h__
/* EERPROM */
#define IWL4965_EEPROM_IMG_SIZE 1024
/* /*
* uCode queue management definitions ... * uCode queue management definitions ...
* Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4. * Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4.
......
...@@ -699,8 +699,9 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv) ...@@ -699,8 +699,9 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv)
unsigned long flags; unsigned long flags;
struct iwl4965_rx_queue *rxq = &priv->rxq; struct iwl4965_rx_queue *rxq = &priv->rxq;
u8 rev_id; u8 rev_id;
u32 val;
u8 val_link; u8 val_link;
u16 sku_cap;
u32 val;
/* nic_init */ /* nic_init */
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
...@@ -759,7 +760,8 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv) ...@@ -759,7 +760,8 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv)
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
if (priv->eeprom.calib_version < EEPROM_TX_POWER_VERSION_NEW) { if (iwl_eeprom_query16(priv, EEPROM_4965_CALIB_VERSION_OFFSET) <
EEPROM_4965_TX_POWER_VERSION) {
IWL_ERROR("Older EEPROM detected! Aborting.\n"); IWL_ERROR("Older EEPROM detected! Aborting.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -816,6 +818,10 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv) ...@@ -816,6 +818,10 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv)
rxq->need_update = 1; rxq->need_update = 1;
iwl4965_rx_queue_update_write_ptr(priv, rxq); iwl4965_rx_queue_update_write_ptr(priv, rxq);
/* init the txpower calibration pointer */
priv->calib_info = (struct iwl_eeprom_calib_info *)
iwl_eeprom_query_addr(priv, EEPROM_4965_CALIB_TXPOWER_OFFSET);
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
/* Allocate and init all Tx and Command queues */ /* Allocate and init all Tx and Command queues */
...@@ -823,10 +829,11 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv) ...@@ -823,10 +829,11 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv)
if (rc) if (rc)
return rc; return rc;
if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE) sku_cap = iwl_eeprom_query16(priv, EEPROM_SKU_CAP);
if (sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n"); IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");
if (priv->eeprom.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE) if (sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n"); IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
set_bit(STATUS_INIT, &priv->status); set_bit(STATUS_INIT, &priv->status);
...@@ -1542,11 +1549,11 @@ static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel) ...@@ -1542,11 +1549,11 @@ static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
s32 b = -1; s32 b = -1;
for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) { for (b = 0; b < EEPROM_TX_POWER_BANDS; b++) {
if (priv->eeprom.calib_info.band_info[b].ch_from == 0) if (priv->calib_info->band_info[b].ch_from == 0)
continue; continue;
if ((channel >= priv->eeprom.calib_info.band_info[b].ch_from) if ((channel >= priv->calib_info->band_info[b].ch_from)
&& (channel <= priv->eeprom.calib_info.band_info[b].ch_to)) && (channel <= priv->calib_info->band_info[b].ch_to))
break; break;
} }
...@@ -1574,14 +1581,14 @@ static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2) ...@@ -1574,14 +1581,14 @@ static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
* in channel number. * in channel number.
*/ */
static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
struct iwl4965_eeprom_calib_ch_info *chan_info) struct iwl_eeprom_calib_ch_info *chan_info)
{ {
s32 s = -1; s32 s = -1;
u32 c; u32 c;
u32 m; u32 m;
const struct iwl4965_eeprom_calib_measure *m1; const struct iwl_eeprom_calib_measure *m1;
const struct iwl4965_eeprom_calib_measure *m2; const struct iwl_eeprom_calib_measure *m2;
struct iwl4965_eeprom_calib_measure *omeas; struct iwl_eeprom_calib_measure *omeas;
u32 ch_i1; u32 ch_i1;
u32 ch_i2; u32 ch_i2;
...@@ -1591,8 +1598,8 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, ...@@ -1591,8 +1598,8 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
return -1; return -1;
} }
ch_i1 = priv->eeprom.calib_info.band_info[s].ch1.ch_num; ch_i1 = priv->calib_info->band_info[s].ch1.ch_num;
ch_i2 = priv->eeprom.calib_info.band_info[s].ch2.ch_num; ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
chan_info->ch_num = (u8) channel; chan_info->ch_num = (u8) channel;
IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n", IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",
...@@ -1600,9 +1607,9 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel, ...@@ -1600,9 +1607,9 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) { for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) { for (m = 0; m < EEPROM_TX_POWER_MEASUREMENTS; m++) {
m1 = &(priv->eeprom.calib_info.band_info[s].ch1. m1 = &(priv->calib_info->band_info[s].ch1.
measurements[c][m]); measurements[c][m]);
m2 = &(priv->eeprom.calib_info.band_info[s].ch2. m2 = &(priv->calib_info->band_info[s].ch2.
measurements[c][m]); measurements[c][m]);
omeas = &(chan_info->measurements[c][m]); omeas = &(chan_info->measurements[c][m]);
...@@ -1921,8 +1928,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -1921,8 +1928,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
int i; int i;
int c; int c;
const struct iwl_channel_info *ch_info = NULL; const struct iwl_channel_info *ch_info = NULL;
struct iwl4965_eeprom_calib_ch_info ch_eeprom_info; struct iwl_eeprom_calib_ch_info ch_eeprom_info;
const struct iwl4965_eeprom_calib_measure *measurement; const struct iwl_eeprom_calib_measure *measurement;
s16 voltage; s16 voltage;
s32 init_voltage; s32 init_voltage;
s32 voltage_compensation; s32 voltage_compensation;
...@@ -1979,9 +1986,9 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -1979,9 +1986,9 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* hardware txpower limits ... /* hardware txpower limits ...
* saturation (clipping distortion) txpowers are in half-dBm */ * saturation (clipping distortion) txpowers are in half-dBm */
if (band) if (band)
saturation_power = priv->eeprom.calib_info.saturation_power24; saturation_power = priv->calib_info->saturation_power24;
else else
saturation_power = priv->eeprom.calib_info.saturation_power52; saturation_power = priv->calib_info->saturation_power52;
if (saturation_power < IWL_TX_POWER_SATURATION_MIN || if (saturation_power < IWL_TX_POWER_SATURATION_MIN ||
saturation_power > IWL_TX_POWER_SATURATION_MAX) { saturation_power > IWL_TX_POWER_SATURATION_MAX) {
...@@ -2011,7 +2018,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel, ...@@ -2011,7 +2018,7 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info); iwl4965_interpolate_chan(priv, channel, &ch_eeprom_info);
/* calculate tx gain adjustment based on power supply voltage */ /* calculate tx gain adjustment based on power supply voltage */
voltage = priv->eeprom.calib_info.voltage; voltage = priv->calib_info->voltage;
init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage); init_voltage = (s32)le32_to_cpu(priv->card_alive_init.voltage);
voltage_compensation = voltage_compensation =
iwl4965_get_voltage_compensation(voltage, init_voltage); iwl4965_get_voltage_compensation(voltage, init_voltage);
...@@ -2467,14 +2474,14 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr, ...@@ -2467,14 +2474,14 @@ int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
static void iwl4965_hw_card_show_info(struct iwl_priv *priv) static void iwl4965_hw_card_show_info(struct iwl_priv *priv)
{ {
u16 hw_version = priv->eeprom.board_revision_4965; u16 hw_version = iwl_eeprom_query16(priv, EEPROM_4965_BOARD_REVISION);
IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n", IWL_DEBUG_INFO("4965ABGN HW Version %u.%u.%u\n",
((hw_version >> 8) & 0x0F), ((hw_version >> 8) & 0x0F),
((hw_version >> 8) >> 4), (hw_version & 0x00FF)); ((hw_version >> 8) >> 4), (hw_version & 0x00FF));
IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n", IWL_DEBUG_INFO("4965ABGN PBA Number %.16s\n",
priv->eeprom.board_pba_number_4965); &priv->eeprom[EEPROM_4965_BOARD_PBA]);
} }
#define IWL_TX_CRC_SIZE 4 #define IWL_TX_CRC_SIZE 4
...@@ -4340,9 +4347,19 @@ static struct iwl_lib_ops iwl4965_lib = { ...@@ -4340,9 +4347,19 @@ static struct iwl_lib_ops iwl4965_lib = {
.set_pwr_src = iwl4965_set_pwr_src, .set_pwr_src = iwl4965_set_pwr_src,
}, },
.eeprom_ops = { .eeprom_ops = {
.regulatory_bands = {
EEPROM_REGULATORY_BAND_1_CHANNELS,
EEPROM_REGULATORY_BAND_2_CHANNELS,
EEPROM_REGULATORY_BAND_3_CHANNELS,
EEPROM_REGULATORY_BAND_4_CHANNELS,
EEPROM_REGULATORY_BAND_5_CHANNELS,
EEPROM_4965_REGULATORY_BAND_24_FAT_CHANNELS,
EEPROM_4965_REGULATORY_BAND_52_FAT_CHANNELS
},
.verify_signature = iwlcore_eeprom_verify_signature, .verify_signature = iwlcore_eeprom_verify_signature,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore, .acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore, .release_semaphore = iwlcore_eeprom_release_semaphore,
.query_addr = iwlcore_eeprom_query_addr,
}, },
.radio_kill_sw = iwl4965_radio_kill_sw, .radio_kill_sw = iwl4965_radio_kill_sw,
.set_power = iwl4965_set_power, .set_power = iwl4965_set_power,
...@@ -4359,6 +4376,7 @@ struct iwl_cfg iwl4965_agn_cfg = { ...@@ -4359,6 +4376,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.name = "4965AGN", .name = "4965AGN",
.fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode", .fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode",
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N, .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.eeprom_size = IWL4965_EEPROM_IMG_SIZE,
.ops = &iwl4965_ops, .ops = &iwl4965_ops,
.mod_params = &iwl4965_mod_params, .mod_params = &iwl4965_mod_params,
}; };
......
...@@ -200,9 +200,9 @@ enum { ...@@ -200,9 +200,9 @@ enum {
struct iwl_channel_info { struct iwl_channel_info {
struct iwl4965_channel_tgd_info tgd; struct iwl4965_channel_tgd_info tgd;
struct iwl4965_channel_tgh_info tgh; struct iwl4965_channel_tgh_info tgh;
struct iwl4965_eeprom_channel eeprom; /* EEPROM regulatory limit */ struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */
struct iwl4965_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for struct iwl_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
* FAT channel */ * FAT channel */
u8 channel; /* channel number */ u8 channel; /* channel number */
u8 flags; /* flags copied from EEPROM */ u8 flags; /* flags copied from EEPROM */
...@@ -1122,7 +1122,8 @@ struct iwl_priv { ...@@ -1122,7 +1122,8 @@ struct iwl_priv {
struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE]; struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];
/* eeprom */ /* eeprom */
struct iwl4965_eeprom eeprom; u8 *eeprom;
struct iwl_eeprom_calib_info *calib_info;
enum ieee80211_if_types iw_mode; enum ieee80211_if_types iw_mode;
......
...@@ -146,6 +146,7 @@ struct iwl_cfg { ...@@ -146,6 +146,7 @@ struct iwl_cfg {
const char *name; const char *name;
const char *fw_name; const char *fw_name;
unsigned int sku; unsigned int sku;
int eeprom_size;
const struct iwl_ops *ops; const struct iwl_ops *ops;
const struct iwl_mod_params *mod_params; const struct iwl_mod_params *mod_params;
}; };
......
...@@ -193,6 +193,12 @@ void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv) ...@@ -193,6 +193,12 @@ void iwlcore_eeprom_release_semaphore(struct iwl_priv *priv)
} }
EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore); EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
const u8 *iwlcore_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
{
BUG_ON(offset >= priv->cfg->eeprom_size);
return &priv->eeprom[offset];
}
EXPORT_SYMBOL(iwlcore_eeprom_query_addr);
/** /**
* iwl_eeprom_init - read EEPROM contents * iwl_eeprom_init - read EEPROM contents
...@@ -203,30 +209,35 @@ EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore); ...@@ -203,30 +209,35 @@ EXPORT_SYMBOL(iwlcore_eeprom_release_semaphore);
*/ */
int iwl_eeprom_init(struct iwl_priv *priv) int iwl_eeprom_init(struct iwl_priv *priv)
{ {
u16 *e = (u16 *)&priv->eeprom; u16 *e;
u32 gp = iwl_read32(priv, CSR_EEPROM_GP); u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
u32 r; u32 r;
int sz = sizeof(priv->eeprom); int sz = priv->cfg->eeprom_size;
int ret; int ret;
int i; int i;
u16 addr; u16 addr;
/* The EEPROM structure has several padding buffers within it /* allocate eeprom */
* and when adding new EEPROM maps is subject to programmer errors priv->eeprom = kzalloc(sz, GFP_KERNEL);
* which may be very difficult to identify without explicitly if (!priv->eeprom) {
* checking the resulting size of the eeprom map. */ ret = -ENOMEM;
BUILD_BUG_ON(sizeof(priv->eeprom) != IWL_EEPROM_IMAGE_SIZE); goto alloc_err;
}
e = (u16 *)priv->eeprom;
if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) { ret = priv->cfg->ops->lib->eeprom_ops.verify_signature(priv);
if (ret < 0) {
IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp); IWL_ERROR("EEPROM not found, EEPROM_GP=0x%08x", gp);
return -ENOENT; ret = -ENOENT;
goto err;
} }
/* Make sure driver (instead of uCode) is allowed to read EEPROM */ /* Make sure driver (instead of uCode) is allowed to read EEPROM */
ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv); ret = priv->cfg->ops->lib->eeprom_ops.acquire_semaphore(priv);
if (ret < 0) { if (ret < 0) {
IWL_ERROR("Failed to acquire EEPROM semaphore.\n"); IWL_ERROR("Failed to acquire EEPROM semaphore.\n");
return -ENOENT; ret = -ENOENT;
goto err;
} }
/* eeprom is an array of 16bit values */ /* eeprom is an array of 16bit values */
...@@ -250,61 +261,93 @@ int iwl_eeprom_init(struct iwl_priv *priv) ...@@ -250,61 +261,93 @@ int iwl_eeprom_init(struct iwl_priv *priv)
e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16)); e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
} }
ret = 0; ret = 0;
done: done:
priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv); priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
err:
if (ret)
kfree(priv->eeprom);
alloc_err:
return ret; return ret;
} }
EXPORT_SYMBOL(iwl_eeprom_init); EXPORT_SYMBOL(iwl_eeprom_init);
void iwl_eeprom_free(struct iwl_priv *priv)
{
if(priv->eeprom)
kfree(priv->eeprom);
priv->eeprom = NULL;
}
EXPORT_SYMBOL(iwl_eeprom_free);
const u8 *iwl_eeprom_query_addr(const struct iwl_priv *priv, size_t offset)
{
return priv->cfg->ops->lib->eeprom_ops.query_addr(priv, offset);
}
EXPORT_SYMBOL(iwl_eeprom_query_addr);
u16 iwl_eeprom_query16(const struct iwl_priv *priv, size_t offset)
{
return (u16)priv->eeprom[offset] | ((u16)priv->eeprom[offset + 1] << 8);
}
EXPORT_SYMBOL(iwl_eeprom_query16);
void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac) void iwl_eeprom_get_mac(const struct iwl_priv *priv, u8 *mac)
{ {
memcpy(mac, priv->eeprom.mac_address, 6); const u8 *addr = priv->cfg->ops->lib->eeprom_ops.query_addr(priv,
EEPROM_MAC_ADDRESS);
memcpy(mac, addr, ETH_ALEN);
} }
EXPORT_SYMBOL(iwl_eeprom_get_mac); EXPORT_SYMBOL(iwl_eeprom_get_mac);
static void iwl_init_band_reference(const struct iwl_priv *priv, static void iwl_init_band_reference(const struct iwl_priv *priv,
int band, int eep_band, int *eeprom_ch_count,
int *eeprom_ch_count, const struct iwl_eeprom_channel **eeprom_ch_info,
const struct iwl4965_eeprom_channel const u8 **eeprom_ch_index)
**eeprom_ch_info,
const u8 **eeprom_ch_index)
{ {
switch (band) { u32 offset = priv->cfg->ops->lib->
eeprom_ops.regulatory_bands[eep_band - 1];
switch (eep_band) {
case 1: /* 2.4GHz band */ case 1: /* 2.4GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1); *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_1);
*eeprom_ch_info = priv->eeprom.band_1_channels; *eeprom_ch_info = (struct iwl_eeprom_channel *)
iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_1; *eeprom_ch_index = iwl_eeprom_band_1;
break; break;
case 2: /* 4.9GHz band */ case 2: /* 4.9GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2); *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_2);
*eeprom_ch_info = priv->eeprom.band_2_channels; *eeprom_ch_info = (struct iwl_eeprom_channel *)
iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_2; *eeprom_ch_index = iwl_eeprom_band_2;
break; break;
case 3: /* 5.2GHz band */ case 3: /* 5.2GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3); *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_3);
*eeprom_ch_info = priv->eeprom.band_3_channels; *eeprom_ch_info = (struct iwl_eeprom_channel *)
iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_3; *eeprom_ch_index = iwl_eeprom_band_3;
break; break;
case 4: /* 5.5GHz band */ case 4: /* 5.5GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4); *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_4);
*eeprom_ch_info = priv->eeprom.band_4_channels; *eeprom_ch_info = (struct iwl_eeprom_channel *)
iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_4; *eeprom_ch_index = iwl_eeprom_band_4;
break; break;
case 5: /* 5.7GHz band */ case 5: /* 5.7GHz band */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5); *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_5);
*eeprom_ch_info = priv->eeprom.band_5_channels; *eeprom_ch_info = (struct iwl_eeprom_channel *)
iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_5; *eeprom_ch_index = iwl_eeprom_band_5;
break; break;
case 6: /* 2.4GHz FAT channels */ case 6: /* 2.4GHz FAT channels */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6); *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_6);
*eeprom_ch_info = priv->eeprom.band_24_channels; *eeprom_ch_info = (struct iwl_eeprom_channel *)
iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_6; *eeprom_ch_index = iwl_eeprom_band_6;
break; break;
case 7: /* 5 GHz FAT channels */ case 7: /* 5 GHz FAT channels */
*eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7); *eeprom_ch_count = ARRAY_SIZE(iwl_eeprom_band_7);
*eeprom_ch_info = priv->eeprom.band_52_channels; *eeprom_ch_info = (struct iwl_eeprom_channel *)
iwl_eeprom_query_addr(priv, offset);
*eeprom_ch_index = iwl_eeprom_band_7; *eeprom_ch_index = iwl_eeprom_band_7;
break; break;
default: default:
...@@ -323,7 +366,7 @@ static void iwl_init_band_reference(const struct iwl_priv *priv, ...@@ -323,7 +366,7 @@ static void iwl_init_band_reference(const struct iwl_priv *priv,
*/ */
static int iwl4965_set_fat_chan_info(struct iwl_priv *priv, static int iwl4965_set_fat_chan_info(struct iwl_priv *priv,
enum ieee80211_band band, u16 channel, enum ieee80211_band band, u16 channel,
const struct iwl4965_eeprom_channel *eeprom_ch, const struct iwl_eeprom_channel *eeprom_ch,
u8 fat_extension_channel) u8 fat_extension_channel)
{ {
struct iwl_channel_info *ch_info; struct iwl_channel_info *ch_info;
...@@ -372,7 +415,7 @@ int iwl_init_channel_map(struct iwl_priv *priv) ...@@ -372,7 +415,7 @@ int iwl_init_channel_map(struct iwl_priv *priv)
{ {
int eeprom_ch_count = 0; int eeprom_ch_count = 0;
const u8 *eeprom_ch_index = NULL; const u8 *eeprom_ch_index = NULL;
const struct iwl4965_eeprom_channel *eeprom_ch_info = NULL; const struct iwl_eeprom_channel *eeprom_ch_info = NULL;
int band, ch; int band, ch;
struct iwl_channel_info *ch_info; struct iwl_channel_info *ch_info;
...@@ -381,9 +424,9 @@ int iwl_init_channel_map(struct iwl_priv *priv) ...@@ -381,9 +424,9 @@ int iwl_init_channel_map(struct iwl_priv *priv)
return 0; return 0;
} }
if (priv->eeprom.version < 0x2f) { if (iwl_eeprom_query16(priv, EEPROM_VERSION) < 0x2f) {
IWL_WARNING("Unsupported EEPROM version: 0x%04X\n", IWL_WARNING("Unsupported EEPROM version: 0x%04X\n",
priv->eeprom.version); iwl_eeprom_query16(priv, EEPROM_VERSION));
return -EINVAL; return -EINVAL;
} }
......
This diff is collapsed.
...@@ -7550,7 +7550,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e ...@@ -7550,7 +7550,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
/* Device-specific setup */ /* Device-specific setup */
if (priv->cfg->ops->lib->set_hw_params(priv)) { if (priv->cfg->ops->lib->set_hw_params(priv)) {
IWL_ERROR("failed to set hw parameters\n"); IWL_ERROR("failed to set hw parameters\n");
goto out_iounmap; goto out_free_eeprom;
} }
/******************* /*******************
...@@ -7611,6 +7611,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e ...@@ -7611,6 +7611,8 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group); sysfs_remove_group(&pdev->dev.kobj, &iwl4965_attribute_group);
out_unset_hw_params: out_unset_hw_params:
iwl4965_unset_hw_params(priv); iwl4965_unset_hw_params(priv);
out_free_eeprom:
iwl_eeprom_free(priv);
out_iounmap: out_iounmap:
pci_iounmap(pdev, priv->hw_base); pci_iounmap(pdev, priv->hw_base);
out_pci_release_regions: out_pci_release_regions:
...@@ -7674,6 +7676,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev) ...@@ -7674,6 +7676,7 @@ static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
iwl4965_unset_hw_params(priv); iwl4965_unset_hw_params(priv);
iwlcore_clear_stations_table(priv); iwlcore_clear_stations_table(priv);
iwl_eeprom_free(priv);
/*netif_stop_queue(dev); */ /*netif_stop_queue(dev); */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment