Skip to content

Commit

Permalink
iwlwifi: changing EEPROM layout handling
Browse files Browse the repository at this point in the history
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: Tomas Winkler <tomas.winkler@intel.com>
Signed-off-by: Ron Rindjunsky <ron.rindjunsky@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Tomas Winkler authored and John W. Linville committed May 7, 2008
1 parent 5da4b55 commit 073d3f5
Show file tree
Hide file tree
Showing 7 changed files with 188 additions and 148 deletions.
3 changes: 3 additions & 0 deletions drivers/net/wireless/iwlwifi/iwl-4965-hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@
#ifndef __iwl_4965_hw_h__
#define __iwl_4965_hw_h__

/* EERPROM */
#define IWL4965_EEPROM_IMG_SIZE 1024

/*
* uCode queue management definitions ...
* Queue #4 is the command queue for 3945 and 4965; map it to Tx FIFO chnl 4.
Expand Down
62 changes: 40 additions & 22 deletions drivers/net/wireless/iwlwifi/iwl-4965.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,8 +699,9 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv)
unsigned long flags;
struct iwl4965_rx_queue *rxq = &priv->rxq;
u8 rev_id;
u32 val;
u8 val_link;
u16 sku_cap;
u32 val;

/* nic_init */
spin_lock_irqsave(&priv->lock, flags);
Expand Down Expand Up @@ -759,7 +760,8 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv)

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");
return -EINVAL;
}
Expand Down Expand Up @@ -816,17 +818,22 @@ int iwl4965_hw_nic_init(struct iwl_priv *priv)
rxq->need_update = 1;
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);

/* Allocate and init all Tx and Command queues */
rc = iwl4965_txq_ctx_reset(priv);
if (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");

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");

set_bit(STATUS_INIT, &priv->status);
Expand Down Expand Up @@ -1542,11 +1549,11 @@ static u32 iwl4965_get_sub_band(const struct iwl_priv *priv, u32 channel)
s32 b = -1;

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;

if ((channel >= priv->eeprom.calib_info.band_info[b].ch_from)
&& (channel <= priv->eeprom.calib_info.band_info[b].ch_to))
if ((channel >= priv->calib_info->band_info[b].ch_from)
&& (channel <= priv->calib_info->band_info[b].ch_to))
break;
}

Expand Down Expand Up @@ -1574,14 +1581,14 @@ static s32 iwl4965_interpolate_value(s32 x, s32 x1, s32 y1, s32 x2, s32 y2)
* in channel number.
*/
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;
u32 c;
u32 m;
const struct iwl4965_eeprom_calib_measure *m1;
const struct iwl4965_eeprom_calib_measure *m2;
struct iwl4965_eeprom_calib_measure *omeas;
const struct iwl_eeprom_calib_measure *m1;
const struct iwl_eeprom_calib_measure *m2;
struct iwl_eeprom_calib_measure *omeas;
u32 ch_i1;
u32 ch_i2;

Expand All @@ -1591,18 +1598,18 @@ static int iwl4965_interpolate_chan(struct iwl_priv *priv, u32 channel,
return -1;
}

ch_i1 = priv->eeprom.calib_info.band_info[s].ch1.ch_num;
ch_i2 = priv->eeprom.calib_info.band_info[s].ch2.ch_num;
ch_i1 = priv->calib_info->band_info[s].ch1.ch_num;
ch_i2 = priv->calib_info->band_info[s].ch2.ch_num;
chan_info->ch_num = (u8) channel;

IWL_DEBUG_TXPOWER("channel %d subband %d factory cal ch %d & %d\n",
channel, s, ch_i1, ch_i2);

for (c = 0; c < EEPROM_TX_POWER_TX_CHAINS; c++) {
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]);
m2 = &(priv->eeprom.calib_info.band_info[s].ch2.
m2 = &(priv->calib_info->band_info[s].ch2.
measurements[c][m]);
omeas = &(chan_info->measurements[c][m]);

Expand Down Expand Up @@ -1921,8 +1928,8 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
int i;
int c;
const struct iwl_channel_info *ch_info = NULL;
struct iwl4965_eeprom_calib_ch_info ch_eeprom_info;
const struct iwl4965_eeprom_calib_measure *measurement;
struct iwl_eeprom_calib_ch_info ch_eeprom_info;
const struct iwl_eeprom_calib_measure *measurement;
s16 voltage;
s32 init_voltage;
s32 voltage_compensation;
Expand Down Expand Up @@ -1979,9 +1986,9 @@ static int iwl4965_fill_txpower_tbl(struct iwl_priv *priv, u8 band, u16 channel,
/* hardware txpower limits ...
* saturation (clipping distortion) txpowers are in half-dBm */
if (band)
saturation_power = priv->eeprom.calib_info.saturation_power24;
saturation_power = priv->calib_info->saturation_power24;
else
saturation_power = priv->eeprom.calib_info.saturation_power52;
saturation_power = priv->calib_info->saturation_power52;

if (saturation_power < IWL_TX_POWER_SATURATION_MIN ||
saturation_power > IWL_TX_POWER_SATURATION_MAX) {
Expand Down Expand Up @@ -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);

/* 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);
voltage_compensation =
iwl4965_get_voltage_compensation(voltage, init_voltage);
Expand Down Expand Up @@ -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)
{
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",
((hw_version >> 8) & 0x0F),
((hw_version >> 8) >> 4), (hw_version & 0x00FF));

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
Expand Down Expand Up @@ -4340,9 +4347,19 @@ static struct iwl_lib_ops iwl4965_lib = {
.set_pwr_src = iwl4965_set_pwr_src,
},
.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,
.acquire_semaphore = iwlcore_eeprom_acquire_semaphore,
.release_semaphore = iwlcore_eeprom_release_semaphore,
.query_addr = iwlcore_eeprom_query_addr,
},
.radio_kill_sw = iwl4965_radio_kill_sw,
.set_power = iwl4965_set_power,
Expand All @@ -4359,6 +4376,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.name = "4965AGN",
.fw_name = "iwlwifi-4965" IWL4965_UCODE_API ".ucode",
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
.eeprom_size = IWL4965_EEPROM_IMG_SIZE,
.ops = &iwl4965_ops,
.mod_params = &iwl4965_mod_params,
};
Expand Down
9 changes: 5 additions & 4 deletions drivers/net/wireless/iwlwifi/iwl-4965.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ enum {
struct iwl_channel_info {
struct iwl4965_channel_tgd_info tgd;
struct iwl4965_channel_tgh_info tgh;
struct iwl4965_eeprom_channel eeprom; /* EEPROM regulatory limit */
struct iwl4965_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
* FAT channel */
struct iwl_eeprom_channel eeprom; /* EEPROM regulatory limit */
struct iwl_eeprom_channel fat_eeprom; /* EEPROM regulatory limit for
* FAT channel */

u8 channel; /* channel number */
u8 flags; /* flags copied from EEPROM */
Expand Down Expand Up @@ -1122,7 +1122,8 @@ struct iwl_priv {
struct list_head ibss_mac_hash[IWL_IBSS_MAC_HASH_SIZE];

/* eeprom */
struct iwl4965_eeprom eeprom;
u8 *eeprom;
struct iwl_eeprom_calib_info *calib_info;

enum ieee80211_if_types iw_mode;

Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/iwlwifi/iwl-core.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ struct iwl_cfg {
const char *name;
const char *fw_name;
unsigned int sku;
int eeprom_size;
const struct iwl_ops *ops;
const struct iwl_mod_params *mod_params;
};
Expand Down
Loading

0 comments on commit 073d3f5

Please sign in to comment.