2009-01-23 21:42:47

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 0/15] iwlwifi driver updates 01/23/2009

This series contains mostly patches for the 3945 porting effort.
In addition this series contains the following:
- a workaround to reduce off channel reception for 4965 when in monitor
mode (patches 1 and 2)
- a kernel oops fix (patch 14) tracked in
http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1861
- a printk formatting fix (patch 15)

[PATCH 01/15] iwlwifi: add test to determine if interface in monitor mode
[PATCH 02/15] iwlagn: reduce off channel reception for 4965
[PATCH 03/15] iwl3945: Define send_tx_power
[PATCH 04/15] iwl3945: Use iwlcore scan code
[PATCH 05/15] iwlwifi: make iwl_tx_queue->tfds void*
[PATCH 06/15] iwl3945: Use iwlcore TX queue management routines
[PATCH 07/15] iwl3945: Use iwl-eeprom.c routines
[PATCH 08/15] iwl3945: Use the iwlcore geos routines
[PATCH 09/15] iwlwifi: Remove IWL3945_DEBUG
[PATCH 10/15] iwl3945: Getting rid of priv->antenna
[PATCH 11/15] iwl3945: Add restart_fw module parameter
[PATCH 12/15] iwl3945: Remaining host command cleanups
[PATCH 13/15] iwlwifi: fix probe mask for 39 scan API
[PATCH 14/15] iwlwifi: fix kernel oops when ucode DMA memory allocation failure
[PATCH 15/15] iwlwifi: iwl_tx_queue_alloc : fix warning in printk formatting


Thank you

Reinette


2009-01-23 21:42:53

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 10/15] iwl3945: Getting rid of priv->antenna

From: Samuel Ortiz <[email protected]>

The iwl_priv antenna field is useless as we can simply use the corresponding
mod_params antenna field.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 35 ---------------------
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 -
drivers/net/wireless/iwlwifi/iwl3945-base.c | 44 +++++++++++++++++++++++---
3 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index b9c5cf9..7f1e042 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -197,41 +197,6 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
return -1;
}

-/**
- * iwl3945_get_antenna_flags - Get antenna flags for RXON command
- * @priv: eeprom and antenna fields are used to determine antenna flags
- *
- * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed
- * priv->antenna specifies the antenna diversity mode:
- *
- * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
- * IWL_ANTENNA_MAIN - Force MAIN antenna
- * IWL_ANTENNA_AUX - Force AUX antenna
- */
-__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
-{
- struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
-
- switch (priv->antenna) {
- case IWL_ANTENNA_DIVERSITY:
- return 0;
-
- case IWL_ANTENNA_MAIN:
- if (eeprom->antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
-
- case IWL_ANTENNA_AUX:
- if (eeprom->antenna_switch_type)
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
- return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
- }
-
- /* bad antenna selector value */
- IWL_ERR(priv, "Bad antenna selector value (0x%x)\n", priv->antenna);
- return 0; /* "diversity" is default if error */
-}
-
#ifdef CONFIG_IWLWIFI_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 5dbab76..437c05b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -978,7 +978,6 @@ struct iwl_priv {
u16 rates_mask;

u32 power_mode;
- u32 antenna;
u8 bssid[ETH_ALEN];
u16 rts_threshold;
u8 mac_addr[ETH_ALEN];
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d832cb9..8aaa6bf 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -448,6 +448,43 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
}

/**
+ * iwl3945_get_antenna_flags - Get antenna flags for RXON command
+ * @priv: eeprom and antenna fields are used to determine antenna flags
+ *
+ * priv->eeprom39 is used to determine if antenna AUX/MAIN are reversed
+ * iwl3945_mod_params.antenna specifies the antenna diversity mode:
+ *
+ * IWL_ANTENNA_DIVERSITY - NIC selects best antenna by itself
+ * IWL_ANTENNA_MAIN - Force MAIN antenna
+ * IWL_ANTENNA_AUX - Force AUX antenna
+ */
+__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
+{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+
+ switch (iwl3945_mod_params.antenna) {
+ case IWL_ANTENNA_DIVERSITY:
+ return 0;
+
+ case IWL_ANTENNA_MAIN:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+
+ case IWL_ANTENNA_AUX:
+ if (eeprom->antenna_switch_type)
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
+ return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
+ }
+
+ /* bad antenna selector value */
+ IWL_ERR(priv, "Bad antenna selector value (0x%x)\n",
+ iwl3945_mod_params.antenna);
+
+ return 0; /* "diversity" is default if error */
+}
+
+/**
* iwl3945_commit_rxon - commit staging_rxon to hardware
*
* The RXON command in staging_rxon is committed to the hardware and
@@ -5804,7 +5841,7 @@ static ssize_t show_antenna(struct device *d,
if (!iwl_is_alive(priv))
return -EAGAIN;

- return sprintf(buf, "%d\n", priv->antenna);
+ return sprintf(buf, "%d\n", iwl3945_mod_params.antenna);
}

static ssize_t store_antenna(struct device *d,
@@ -5824,7 +5861,7 @@ static ssize_t store_antenna(struct device *d,

if ((ant >= 0) && (ant <= 2)) {
IWL_DEBUG_INFO("Setting antenna select to %d.\n", ant);
- priv->antenna = (enum iwl3945_antenna)ant;
+ iwl3945_mod_params.antenna = (enum iwl3945_antenna)ant;
} else
IWL_DEBUG_INFO("Bad antenna select value %d.\n", ant);

@@ -6089,9 +6126,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
hw->rate_control_algorithm = "iwl-3945-rs";
hw->sta_data_size = sizeof(struct iwl3945_sta_priv);

- /* Select antenna (may be helpful if only one antenna is connected) */
- priv->antenna = (enum iwl3945_antenna)iwl3945_mod_params.antenna;
-
/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
IEEE80211_HW_NOISE_DBM;
--
1.5.4.3


2009-01-23 21:42:47

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 01/15] iwlwifi: add test to determine if interface in monitor mode

From: Chatre, Reinette <[email protected]>

mac80211 sets driver in monitor mode through configuring the
RX filters. We cannot trust priv->iw_mode to be accurate
regarding monitor mode as iw_mode is only set in add_interface,
which is not called by mac80211 when in monitor mode.

Signed-off-by: Reinette Chatre <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 9f284eb..ef4a7c5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -699,6 +699,18 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
}

/**
+ * iwl_is_monitor_mode - Determine if interface in monitor mode
+ *
+ * priv->iw_mode is set in add_interface, but add_interface is
+ * never called for monitor mode. The only way mac80211 informs us about
+ * monitor mode is through configuring filters (call to configure_filter).
+ */
+static bool iwl_is_monitor_mode(struct iwl_priv *priv)
+{
+ return !!(priv->staging_rxon.filter_flags & RXON_FILTER_PROMISC_MSK);
+}
+
+/**
* iwl_set_rxon_chain - Set up Rx chain usage in "staging" RXON image
*
* Selects how many and which Rx receivers/antennas/chains to use.
--
1.5.4.3


2009-01-23 21:42:53

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 07/15] iwl3945: Use iwl-eeprom.c routines

From: Samuel Ortiz <[email protected]>

By adding the eeprom ops to the 3945 code, we can now use the iwlcore eeprom
routines (defined in iwl-eeprom.c).
We also removed the heavy eeprom39 reference from iwl_priv and use the eeprom
pointer instead.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945-hw.h | 4 +-
drivers/net/wireless/iwlwifi/iwl-3945.c | 92 ++++++--
drivers/net/wireless/iwlwifi/iwl-dev.h | 3 -
drivers/net/wireless/iwlwifi/iwl-eeprom.c | 8 +
drivers/net/wireless/iwlwifi/iwl-eeprom.h | 3 +
drivers/net/wireless/iwlwifi/iwl3945-base.c | 372 ++-------------------------
6 files changed, 115 insertions(+), 367 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 013e24e..1327b2a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -182,7 +182,7 @@ struct iwl3945_eeprom {
* 2.4 GHz channels 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
*/
u16 band_1_count; /* abs.ofs: 196 */
- struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 196 */
+ struct iwl_eeprom_channel band_1_channels[14]; /* abs.ofs: 198 */

/*
* 4.9 GHz channels 183, 184, 185, 187, 188, 189, 192, 196,
@@ -225,7 +225,7 @@ struct iwl3945_eeprom {
u8 reserved16[172]; /* fill out to full 1024 byte block */
} __attribute__ ((packed));

-#define IWL_EEPROM_IMAGE_SIZE 1024
+#define IWL3945_EEPROM_IMG_SIZE 1024

/* End of EEPROM */

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 2689113..75e9553 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -42,6 +42,7 @@
#include "iwl-3945-fh.h"
#include "iwl-commands.h"
#include "iwl-3945.h"
+#include "iwl-eeprom.h"
#include "iwl-helpers.h"
#include "iwl-core.h"
#include "iwl-agn-rs.h"
@@ -209,17 +210,19 @@ static int iwl3945_hwrate_to_plcp_idx(u8 plcp)
*/
__le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+
switch (priv->antenna) {
case IWL_ANTENNA_DIVERSITY:
return 0;

case IWL_ANTENNA_MAIN:
- if (priv->eeprom39.antenna_switch_type)
+ if (eeprom->antenna_switch_type)
return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;

case IWL_ANTENNA_AUX:
- if (priv->eeprom39.antenna_switch_type)
+ if (eeprom->antenna_switch_type)
return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_A_MSK;
return RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_B_MSK;
}
@@ -1128,6 +1131,7 @@ out:

static void iwl3945_nic_config(struct iwl_priv *priv)
{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
unsigned long flags;
u8 rev_id = 0;

@@ -1145,42 +1149,42 @@ static void iwl3945_nic_config(struct iwl_priv *priv)
CSR39_HW_IF_CONFIG_REG_BIT_3945_MM);
}

- if (EEPROM_SKU_CAP_OP_MODE_MRC == priv->eeprom39.sku_cap) {
+ if (EEPROM_SKU_CAP_OP_MODE_MRC == eeprom->sku_cap) {
IWL_DEBUG_INFO("SKU OP mode is mrc\n");
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_SKU_MRC);
} else
IWL_DEBUG_INFO("SKU OP mode is basic\n");

- if ((priv->eeprom39.board_revision & 0xF0) == 0xD0) {
+ if ((eeprom->board_revision & 0xF0) == 0xD0) {
IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom39.board_revision);
+ eeprom->board_revision);
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
} else {
IWL_DEBUG_INFO("3945ABG revision is 0x%X\n",
- priv->eeprom39.board_revision);
+ eeprom->board_revision);
iwl_clear_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BIT_BOARD_TYPE);
}

- if (priv->eeprom39.almgor_m_version <= 1) {
+ if (eeprom->almgor_m_version <= 1) {
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_A);
IWL_DEBUG_INFO("Card M type A version is 0x%X\n",
- priv->eeprom39.almgor_m_version);
+ eeprom->almgor_m_version);
} else {
IWL_DEBUG_INFO("Card M type B version is 0x%X\n",
- priv->eeprom39.almgor_m_version);
+ eeprom->almgor_m_version);
iwl_set_bit(priv, CSR_HW_IF_CONFIG_REG,
CSR39_HW_IF_CONFIG_REG_BITS_SILICON_TYPE_B);
}
spin_unlock_irqrestore(&priv->lock, flags);

- if (priv->eeprom39.sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_SW_RF_KILL_ENABLE)
IWL_DEBUG_RF_KILL("SW RF KILL supported in EEPROM.\n");

- if (priv->eeprom39.sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
+ if (eeprom->sku_cap & EEPROM_SKU_CAP_HW_RF_KILL_ENABLE)
IWL_DEBUG_RF_KILL("HW RF KILL supported in EEPROM.\n");
}

@@ -1406,6 +1410,7 @@ int iwl3945_hw_get_temperature(struct iwl_priv *priv)
*/
static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
{
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int temperature;

temperature = iwl3945_hw_get_temperature(priv);
@@ -1421,7 +1426,7 @@ static int iwl3945_hw_reg_txpower_get_temperature(struct iwl_priv *priv)
/* if really really hot(?),
* substitute the 3rd band/group's temp measured at factory */
if (priv->last_temperature > 100)
- temperature = priv->eeprom39.groups[2].temperature;
+ temperature = eeprom->groups[2].temperature;
else /* else use most recent "sane" value from driver */
temperature = priv->last_temperature;
}
@@ -1720,7 +1725,7 @@ int iwl3945_send_tx_power(struct iwl_priv *priv)
};

txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
- ch_info = iwl3945_get_channel_info(priv,
+ ch_info = iwl_get_channel_info(priv,
priv->band,
le16_to_cpu(priv->active39_rxon.channel));
if (!ch_info) {
@@ -1881,6 +1886,7 @@ static int iwl3945_hw_reg_get_ch_txpower_limit(struct iwl_channel_info *ch_info)
static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
{
struct iwl_channel_info *ch_info = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
const s8 *clip_pwrs; /* array of h/w max power levels for each rate */
u8 a_band;
@@ -1896,7 +1902,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
a_band = is_channel_a_band(ch_info);

/* Get this chnlgrp's factory calibration temperature */
- ref_temp = (s16)priv->eeprom39.groups[ch_info->group_index].
+ ref_temp = (s16)eeprom->groups[ch_info->group_index].
temperature;

/* get power index adjustment based on current and factory
@@ -2041,7 +2047,8 @@ static void iwl3945_bg_reg_txpower_periodic(struct work_struct *work)
static u16 iwl3945_hw_reg_get_ch_grp_index(struct iwl_priv *priv,
const struct iwl_channel_info *ch_info)
{
- struct iwl3945_eeprom_txpower_group *ch_grp = &priv->eeprom39.groups[0];
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ struct iwl3945_eeprom_txpower_group *ch_grp = &eeprom->groups[0];
u8 group;
u16 group_index = 0; /* based on factory calib frequencies */
u8 grp_channel;
@@ -2077,6 +2084,7 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv,
s32 setting_index, s32 *new_index)
{
const struct iwl3945_eeprom_txpower_group *chnl_grp = NULL;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
s32 index0, index1;
s32 power = 2 * requested_power;
s32 i;
@@ -2085,7 +2093,7 @@ static int iwl3945_hw_reg_get_matched_power_index(struct iwl_priv *priv,
s32 res;
s32 denominator;

- chnl_grp = &priv->eeprom39.groups[setting_index];
+ chnl_grp = &eeprom->groups[setting_index];
samples = chnl_grp->samples;
for (i = 0; i < 5; i++) {
if (power == samples[i].power) {
@@ -2124,6 +2132,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
{
u32 i;
s32 rate_index;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
const struct iwl3945_eeprom_txpower_group *group;

IWL_DEBUG_POWER("Initializing factory calib info from EEPROM\n");
@@ -2131,7 +2140,7 @@ static void iwl3945_hw_reg_init_channel_groups(struct iwl_priv *priv)
for (i = 0; i < IWL_NUM_TX_CALIB_GROUPS; i++) {
s8 *clip_pwrs; /* table of power levels for each rate */
s8 satur_pwr; /* saturation power for each chnl group */
- group = &priv->eeprom39.groups[i];
+ group = &eeprom->groups[i];

/* sanity check on factory saturation power value */
if (group->saturation_power < 40) {
@@ -2204,6 +2213,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
{
struct iwl_channel_info *ch_info = NULL;
struct iwl3945_channel_power_info *pwr_info;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;
int delta_index;
u8 rate_index;
u8 scan_tbl_index;
@@ -2238,7 +2248,7 @@ int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv)
/* calculate power index *adjustment* value according to
* diff between current temperature and factory temperature */
delta_index = iwl3945_hw_reg_adjust_power_by_temp(temperature,
- priv->eeprom39.groups[ch_info->group_index].
+ eeprom->groups[ch_info->group_index].
temperature);

IWL_DEBUG_POWER("Delta index for channel %d: %d [%d]\n",
@@ -2585,6 +2595,33 @@ static int iwl3945_verify_bsm(struct iwl_priv *priv)
return 0;
}

+
+/******************************************************************************
+ *
+ * EEPROM related functions
+ *
+ ******************************************************************************/
+
+/*
+ * Clear the OWNER_MSK, to establish driver (instead of uCode running on
+ * embedded controller) as EEPROM reader; each read is a series of pulses
+ * to/from the EEPROM chip, not a single event, so even reads could conflict
+ * if they weren't arbitrated by some ownership mechanism. Here, the driver
+ * simply claims ownership, which should be safe when this function is called
+ * (i.e. before loading uCode!).
+ */
+static int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
+{
+ _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
+ return 0;
+}
+
+
+static void iwl3945_eeprom_release_semaphore(struct iwl_priv *priv)
+{
+ return;
+}
+
/**
* iwl3945_load_bsm - Load bootstrap instructions
*
@@ -2715,6 +2752,21 @@ static struct iwl_lib_ops iwl3945_lib = {
.config = iwl3945_nic_config,
.set_pwr_src = iwl3945_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,
+ IWL3945_EEPROM_IMG_SIZE,
+ IWL3945_EEPROM_IMG_SIZE,
+ },
+ .verify_signature = iwlcore_eeprom_verify_signature,
+ .acquire_semaphore = iwl3945_eeprom_acquire_semaphore,
+ .release_semaphore = iwl3945_eeprom_release_semaphore,
+ .query_addr = iwlcore_eeprom_query_addr,
+ },
.send_tx_power = iwl3945_send_tx_power,
};

@@ -2733,6 +2785,8 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
.ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params
};
@@ -2743,6 +2797,8 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.ucode_api_max = IWL3945_UCODE_API_MAX,
.ucode_api_min = IWL3945_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G,
+ .eeprom_size = IWL3945_EEPROM_IMG_SIZE,
+ .eeprom_ver = EEPROM_3945_EEPROM_VERSION,
.ops = &iwl3945_ops,
.mod_params = &iwl3945_mod_params
};
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 5aa22d6..d4e0778 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1091,9 +1091,6 @@ struct iwl_priv {

struct iwl3945_station_entry stations_39[IWL_STATION_COUNT];

- /* eeprom */
- struct iwl3945_eeprom eeprom39;
-
u32 sta_supp_rates;
}; /*iwl_priv */

diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index cebfb8f..eaa658f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -531,6 +531,13 @@ int iwl_init_channel_map(struct iwl_priv *priv)
}
}

+ /* Check if we do have FAT channels */
+ if (priv->cfg->ops->lib->eeprom_ops.regulatory_bands[5] >=
+ priv->cfg->eeprom_size &&
+ priv->cfg->ops->lib->eeprom_ops.regulatory_bands[6] >=
+ priv->cfg->eeprom_size)
+ return 0;
+
/* Two additional EEPROM bands for 2.4 and 5 GHz FAT channels */
for (band = 6; band <= 7; band++) {
enum ieee80211_band ieeeband;
@@ -582,6 +589,7 @@ void iwl_free_channel_map(struct iwl_priv *priv)
kfree(priv->channel_info);
priv->channel_count = 0;
}
+EXPORT_SYMBOL(iwl_free_channel_map);

/**
* iwl_get_channel_info - Find driver's private channel info
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
index dd2e7d2..17fed49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h
@@ -118,6 +118,9 @@ struct iwl_eeprom_channel {
s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */
} __attribute__ ((packed));

+/* 3945 Specific */
+#define EEPROM_3945_EEPROM_VERSION (0x2f)
+
/* 4965 has two radio transmitters (and 3 radio receivers) */
#define EEPROM_TX_POWER_TX_CHAINS (2)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 14f9523..b57c2b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -257,7 +257,7 @@ static int iwl3945_set_rxon_channel(struct iwl_priv *priv,
enum ieee80211_band band,
u16 channel)
{
- if (!iwl3945_get_channel_info(priv, band, channel)) {
+ if (!iwl_get_channel_info(priv, band, channel)) {
IWL_DEBUG_INFO("Could not set channel to %d [%d]\n",
channel, band);
return -EINVAL;
@@ -834,86 +834,6 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
return rc;
}

-/******************************************************************************
- *
- * EEPROM related functions
- *
- ******************************************************************************/
-
-static void get_eeprom_mac(struct iwl_priv *priv, u8 *mac)
-{
- memcpy(mac, priv->eeprom39.mac_address, 6);
-}
-
-/*
- * Clear the OWNER_MSK, to establish driver (instead of uCode running on
- * embedded controller) as EEPROM reader; each read is a series of pulses
- * to/from the EEPROM chip, not a single event, so even reads could conflict
- * if they weren't arbitrated by some ownership mechanism. Here, the driver
- * simply claims ownership, which should be safe when this function is called
- * (i.e. before loading uCode!).
- */
-static inline int iwl3945_eeprom_acquire_semaphore(struct iwl_priv *priv)
-{
- _iwl_clear_bit(priv, CSR_EEPROM_GP, CSR_EEPROM_GP_IF_OWNER_MSK);
- return 0;
-}
-
-/**
- * iwl3945_eeprom_init - read EEPROM contents
- *
- * Load the EEPROM contents from adapter into priv->eeprom39
- *
- * NOTE: This routine uses the non-debug IO access functions.
- */
-int iwl3945_eeprom_init(struct iwl_priv *priv)
-{
- u16 *e = (u16 *)&priv->eeprom39;
- u32 gp = iwl_read32(priv, CSR_EEPROM_GP);
- int sz = sizeof(priv->eeprom39);
- int ret;
- u16 addr;
-
- /* The EEPROM structure has several padding buffers within it
- * and when adding new EEPROM maps is subject to programmer errors
- * which may be very difficult to identify without explicitly
- * checking the resulting size of the eeprom map. */
- BUILD_BUG_ON(sizeof(priv->eeprom39) != IWL_EEPROM_IMAGE_SIZE);
-
- if ((gp & CSR_EEPROM_GP_VALID_MSK) == CSR_EEPROM_GP_BAD_SIGNATURE) {
- IWL_ERR(priv, "EEPROM not found, EEPROM_GP=0x%08x\n", gp);
- return -ENOENT;
- }
-
- /* Make sure driver (instead of uCode) is allowed to read EEPROM */
- ret = iwl3945_eeprom_acquire_semaphore(priv);
- if (ret < 0) {
- IWL_ERR(priv, "Failed to acquire EEPROM semaphore.\n");
- return -ENOENT;
- }
-
- /* eeprom is an array of 16bit values */
- for (addr = 0; addr < sz; addr += sizeof(u16)) {
- u32 r;
-
- _iwl_write32(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_MSK_ADDR & (addr << 1));
- _iwl_clear_bit(priv, CSR_EEPROM_REG, CSR_EEPROM_REG_BIT_CMD);
- ret = iwl_poll_direct_bit(priv, CSR_EEPROM_REG,
- CSR_EEPROM_REG_READ_VALID_MSK,
- IWL_EEPROM_ACCESS_TIMEOUT);
- if (ret < 0) {
- IWL_ERR(priv, "Time out reading EEPROM[%d]\n", addr);
- return ret;
- }
-
- r = _iwl_read_direct32(priv, CSR_EEPROM_REG);
- e[addr / 2] = le16_to_cpu((__force __le16)(r >> 16));
- }
-
- return 0;
-}
-
static void iwl3945_unset_hw_params(struct iwl_priv *priv)
{
if (priv->shared_virt)
@@ -1304,7 +1224,7 @@ static void iwl3945_connection_init_rx_config(struct iwl_priv *priv,
priv->staging39_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
#endif

- ch_info = iwl3945_get_channel_info(priv, priv->band,
+ ch_info = iwl_get_channel_info(priv, priv->band,
le16_to_cpu(priv->active39_rxon.channel));

if (!ch_info)
@@ -1336,7 +1256,7 @@ static int iwl3945_set_mode(struct iwl_priv *priv, int mode)
if (mode == NL80211_IFTYPE_ADHOC) {
const struct iwl_channel_info *ch_info;

- ch_info = iwl3945_get_channel_info(priv,
+ ch_info = iwl_get_channel_info(priv,
priv->band,
le16_to_cpu(priv->staging39_rxon.channel));

@@ -3349,258 +3269,6 @@ unplugged:
return IRQ_NONE;
}

-/************************** EEPROM BANDS ****************************
- *
- * The iwl3945_eeprom_band definitions below provide the mapping from the
- * EEPROM contents to the specific channel number supported for each
- * band.
- *
- * For example, iwl3945_priv->eeprom39.band_3_channels[4] from the band_3
- * definition below maps to physical channel 42 in the 5.2GHz spectrum.
- * The specific geography and calibration information for that channel
- * is contained in the eeprom map itself.
- *
- * During init, we copy the eeprom information and channel map
- * information into priv->channel_info_24/52 and priv->channel_map_24/52
- *
- * channel_map_24/52 provides the index in the channel_info array for a
- * given channel. We have to have two separate maps as there is channel
- * overlap with the 2.4GHz and 5.2GHz spectrum as seen in band_1 and
- * band_2
- *
- * A value of 0xff stored in the channel_map indicates that the channel
- * is not supported by the hardware at all.
- *
- * A value of 0xfe in the channel_map indicates that the channel is not
- * valid for Tx with the current hardware. This means that
- * while the system can tune and receive on a given channel, it may not
- * be able to associate or transmit any frames on that
- * channel. There is no corresponding channel information for that
- * entry.
- *
- *********************************************************************/
-
-/* 2.4 GHz */
-static const u8 iwl3945_eeprom_band_1[14] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14
-};
-
-/* 5.2 GHz bands */
-static const u8 iwl3945_eeprom_band_2[] = { /* 4915-5080MHz */
- 183, 184, 185, 187, 188, 189, 192, 196, 7, 8, 11, 12, 16
-};
-
-static const u8 iwl3945_eeprom_band_3[] = { /* 5170-5320MHz */
- 34, 36, 38, 40, 42, 44, 46, 48, 52, 56, 60, 64
-};
-
-static const u8 iwl3945_eeprom_band_4[] = { /* 5500-5700MHz */
- 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140
-};
-
-static const u8 iwl3945_eeprom_band_5[] = { /* 5725-5825MHz */
- 145, 149, 153, 157, 161, 165
-};
-
-static void iwl3945_init_band_reference(const struct iwl_priv *priv, int band,
- int *eeprom_ch_count,
- const struct iwl_eeprom_channel
- **eeprom_ch_info,
- const u8 **eeprom_ch_index)
-{
- switch (band) {
- case 1: /* 2.4GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_1);
- *eeprom_ch_info = priv->eeprom39.band_1_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_1;
- break;
- case 2: /* 4.9GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_2);
- *eeprom_ch_info = priv->eeprom39.band_2_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_2;
- break;
- case 3: /* 5.2GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_3);
- *eeprom_ch_info = priv->eeprom39.band_3_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_3;
- break;
- case 4: /* 5.5GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_4);
- *eeprom_ch_info = priv->eeprom39.band_4_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_4;
- break;
- case 5: /* 5.7GHz band */
- *eeprom_ch_count = ARRAY_SIZE(iwl3945_eeprom_band_5);
- *eeprom_ch_info = priv->eeprom39.band_5_channels;
- *eeprom_ch_index = iwl3945_eeprom_band_5;
- break;
- default:
- BUG();
- return;
- }
-}
-
-/**
- * iwl3945_get_channel_info - Find driver's private channel info
- *
- * Based on band and channel number.
- */
-const struct iwl_channel_info *
-iwl3945_get_channel_info(const struct iwl_priv *priv,
- enum ieee80211_band band, u16 channel)
-{
- int i;
-
- switch (band) {
- case IEEE80211_BAND_5GHZ:
- for (i = 14; i < priv->channel_count; i++) {
- if (priv->channel_info[i].channel == channel)
- return &priv->channel_info[i];
- }
- break;
-
- case IEEE80211_BAND_2GHZ:
- if (channel >= 1 && channel <= 14)
- return &priv->channel_info[channel - 1];
- break;
- case IEEE80211_NUM_BANDS:
- WARN_ON(1);
- }
-
- return NULL;
-}
-
-#define CHECK_AND_PRINT(x) ((eeprom_ch_info[ch].flags & EEPROM_CHANNEL_##x) \
- ? # x " " : "")
-
-/**
- * iwl3945_init_channel_map - Set up driver's info for all possible channels
- */
-static int iwl3945_init_channel_map(struct iwl_priv *priv)
-{
- int eeprom_ch_count = 0;
- const u8 *eeprom_ch_index = NULL;
- const struct iwl_eeprom_channel *eeprom_ch_info = NULL;
- int band, ch;
- struct iwl_channel_info *ch_info;
-
- if (priv->channel_count) {
- IWL_DEBUG_INFO("Channel map already initialized.\n");
- return 0;
- }
-
- if (priv->eeprom39.version < 0x2f) {
- IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
- priv->eeprom39.version);
- return -EINVAL;
- }
-
- IWL_DEBUG_INFO("Initializing regulatory info from EEPROM\n");
-
- priv->channel_count =
- ARRAY_SIZE(iwl3945_eeprom_band_1) +
- ARRAY_SIZE(iwl3945_eeprom_band_2) +
- ARRAY_SIZE(iwl3945_eeprom_band_3) +
- ARRAY_SIZE(iwl3945_eeprom_band_4) +
- ARRAY_SIZE(iwl3945_eeprom_band_5);
-
- IWL_DEBUG_INFO("Parsing data for %d channels.\n", priv->channel_count);
-
- priv->channel_info = kzalloc(sizeof(struct iwl_channel_info) *
- priv->channel_count, GFP_KERNEL);
- if (!priv->channel_info) {
- IWL_ERR(priv, "Could not allocate channel_info\n");
- priv->channel_count = 0;
- return -ENOMEM;
- }
-
- ch_info = priv->channel_info;
-
- /* Loop through the 5 EEPROM bands adding them in order to the
- * channel map we maintain (that contains additional information than
- * what just in the EEPROM) */
- for (band = 1; band <= 5; band++) {
-
- iwl3945_init_band_reference(priv, band, &eeprom_ch_count,
- &eeprom_ch_info, &eeprom_ch_index);
-
- /* Loop through each band adding each of the channels */
- for (ch = 0; ch < eeprom_ch_count; ch++) {
- ch_info->channel = eeprom_ch_index[ch];
- ch_info->band = (band == 1) ? IEEE80211_BAND_2GHZ :
- IEEE80211_BAND_5GHZ;
-
- /* permanently store EEPROM's channel regulatory flags
- * and max power in channel info database. */
- ch_info->eeprom = eeprom_ch_info[ch];
-
- /* Copy the run-time flags so they are there even on
- * invalid channels */
- ch_info->flags = eeprom_ch_info[ch].flags;
-
- if (!(is_channel_valid(ch_info))) {
- IWL_DEBUG_INFO("Ch. %d Flags %x [%sGHz] - "
- "No traffic\n",
- ch_info->channel,
- ch_info->flags,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4");
- ch_info++;
- continue;
- }
-
- /* Initialize regulatory-based run-time data */
- ch_info->max_power_avg = ch_info->curr_txpow =
- eeprom_ch_info[ch].max_power_avg;
- ch_info->scan_power = eeprom_ch_info[ch].max_power_avg;
- ch_info->min_power = 0;
-
- IWL_DEBUG_INFO("Ch. %d [%sGHz] %s%s%s%s%s%s(0x%02x"
- " %ddBm): Ad-Hoc %ssupported\n",
- ch_info->channel,
- is_channel_a_band(ch_info) ?
- "5.2" : "2.4",
- CHECK_AND_PRINT(VALID),
- CHECK_AND_PRINT(IBSS),
- CHECK_AND_PRINT(ACTIVE),
- CHECK_AND_PRINT(RADAR),
- CHECK_AND_PRINT(WIDE),
- CHECK_AND_PRINT(DFS),
- eeprom_ch_info[ch].flags,
- eeprom_ch_info[ch].max_power_avg,
- ((eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_IBSS)
- && !(eeprom_ch_info[ch].
- flags & EEPROM_CHANNEL_RADAR))
- ? "" : "not ");
-
- /* Set the tx_power_user_lmt to the highest power
- * supported by any channel */
- if (eeprom_ch_info[ch].max_power_avg >
- priv->tx_power_user_lmt)
- priv->tx_power_user_lmt =
- eeprom_ch_info[ch].max_power_avg;
-
- ch_info++;
- }
- }
-
- /* Set up txpower settings in driver for all channels */
- if (iwl3945_txpower_set_from_eeprom(priv))
- return -EIO;
-
- return 0;
-}
-
-/*
- * iwl3945_free_channel_map - undo allocations in iwl3945_init_channel_map
- */
-static void iwl3945_free_channel_map(struct iwl_priv *priv)
-{
- kfree(priv->channel_info);
- priv->channel_count = 0;
-}
-
static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
@@ -3631,7 +3299,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,

scan_ch->channel = channels[i].hw_value;

- ch_info = iwl3945_get_channel_info(priv, band, scan_ch->channel);
+ ch_info = iwl_get_channel_info(priv, band, scan_ch->channel);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_SCAN("Channel %d is INVALID for this band.\n",
scan_ch->channel);
@@ -3718,6 +3386,7 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
/**
* iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
*/
+#define IEEE80211_24GHZ_MAX_CHANNEL 14
static int iwl3945_init_geos(struct iwl_priv *priv)
{
struct iwl_channel_info *ch;
@@ -3748,7 +3417,7 @@ static int iwl3945_init_geos(struct iwl_priv *priv)

/* 5.2GHz channels start after the 2.4GHz channels */
sband = &priv->bands[IEEE80211_BAND_5GHZ];
- sband->channels = &channels[ARRAY_SIZE(iwl3945_eeprom_band_1)];
+ sband->channels = &channels[IEEE80211_24GHZ_MAX_CHANNEL];
/* just OFDM */
sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
@@ -5242,8 +4911,8 @@ static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed)

spin_lock_irqsave(&priv->lock, flags);

- ch_info = iwl3945_get_channel_info(priv, conf->channel->band,
- conf->channel->hw_value);
+ ch_info = iwl_get_channel_info(priv, conf->channel->band,
+ conf->channel->hw_value);
if (!is_channel_valid(ch_info)) {
IWL_DEBUG_SCAN("Channel %d [%d] is INVALID for this band.\n",
conf->channel->hw_value, conf->channel->band);
@@ -6423,6 +6092,7 @@ static struct ieee80211_ops iwl3945_hw_ops = {
static int iwl3945_init_drv(struct iwl_priv *priv)
{
int ret;
+ struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom;

priv->retry_rate = 1;
priv->ibss_beacon = NULL;
@@ -6456,12 +6126,24 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
priv->power_mode = IWL39_POWER_AC;
priv->tx_power_user_lmt = IWL_DEFAULT_TX_POWER;

- ret = iwl3945_init_channel_map(priv);
+ if (eeprom->version < EEPROM_3945_EEPROM_VERSION) {
+ IWL_WARN(priv, "Unsupported EEPROM version: 0x%04X\n",
+ eeprom->version);
+ ret = -EINVAL;
+ goto err;
+ }
+ ret = iwl_init_channel_map(priv);
if (ret) {
IWL_ERR(priv, "initializing regulatory failed: %d\n", ret);
goto err;
}

+ /* Set up txpower settings in driver for all channels */
+ if (iwl3945_txpower_set_from_eeprom(priv)) {
+ ret = -EIO;
+ goto err_free_channel_map;
+ }
+
ret = iwl3945_init_geos(priv);
if (ret) {
IWL_ERR(priv, "initializing geos failed: %d\n", ret);
@@ -6471,7 +6153,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
return 0;

err_free_channel_map:
- iwl3945_free_channel_map(priv);
+ iwl_free_channel_map(priv);
err:
return ret;
}
@@ -6482,6 +6164,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
struct iwl_priv *priv;
struct ieee80211_hw *hw;
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
+ struct iwl3945_eeprom *eeprom;
unsigned long flags;

/***********************
@@ -6597,13 +6280,14 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
* ********************/

/* Read the EEPROM */
- err = iwl3945_eeprom_init(priv);
+ err = iwl_eeprom_init(priv);
if (err) {
IWL_ERR(priv, "Unable to init EEPROM\n");
goto out_remove_sysfs;
}
/* MAC Address location in EEPROM same for 3945/4965 */
- get_eeprom_mac(priv, priv->mac_addr);
+ eeprom = (struct iwl3945_eeprom *)priv->eeprom;
+ memcpy(priv->mac_addr, eeprom->mac_address, ETH_ALEN);
IWL_DEBUG_INFO("MAC address: %pM\n", priv->mac_addr);
SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);

@@ -6776,7 +6460,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);

- iwl3945_free_channel_map(priv);
+ iwl_free_channel_map(priv);
iwl3945_free_geos(priv);
kfree(priv->scan);
if (priv->ibss_beacon)
--
1.5.4.3


2009-01-23 21:42:56

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 14/15] iwlwifi: fix kernel oops when ucode DMA memory allocation failure

From: Zhu, Yi <[email protected]>

The patch fixes memcpy to NULL address when the ucode DMA allocation failure.

This is a fix to bug
http://www.intellinuxwireless.org/bugzilla/show_bug.cgi?id=1861

Signed-off-by: Zhu Yi <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 757a9bd..6b7120a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1866,6 +1866,10 @@ static int iwl_read_ucode(struct iwl_priv *priv)
priv->ucode_data_backup.len = data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);

+ if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
+ !priv->ucode_data_backup.v_addr)
+ goto err_pci_alloc;
+
/* Initialization instructions and data */
if (init_size && init_data_size) {
priv->ucode_init.len = init_size;
--
1.5.4.3


2009-01-23 21:42:51

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 08/15] iwl3945: Use the iwlcore geos routines

From: Samuel Ortiz <[email protected]>

By removing the init_rates() routine outside of the init_geos() one, we can
share the geos routines between 3945 and agn.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 9 +-
drivers/net/wireless/iwlwifi/iwl-core.h | 5 +
drivers/net/wireless/iwlwifi/iwl3945-base.c | 145 ++-------------------------
3 files changed, 21 insertions(+), 138 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index b64377e..902b75f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -406,7 +406,7 @@ static void iwlcore_init_hw_rates(struct iwl_priv *priv,
/**
* iwlcore_init_geos - Initialize mac80211's geo/channel info based from eeprom
*/
-static int iwlcore_init_geos(struct iwl_priv *priv)
+int iwlcore_init_geos(struct iwl_priv *priv)
{
struct iwl_channel_info *ch;
struct ieee80211_supported_band *sband;
@@ -458,8 +458,6 @@ static int iwlcore_init_geos(struct iwl_priv *priv)
priv->ieee_channels = channels;
priv->ieee_rates = rates;

- iwlcore_init_hw_rates(priv, rates);
-
for (i = 0; i < priv->channel_count; i++) {
ch = &priv->channel_info[i];

@@ -526,16 +524,18 @@ static int iwlcore_init_geos(struct iwl_priv *priv)

return 0;
}
+EXPORT_SYMBOL(iwlcore_init_geos);

/*
* iwlcore_free_geos - undo allocations in iwlcore_init_geos
*/
-static void iwlcore_free_geos(struct iwl_priv *priv)
+void iwlcore_free_geos(struct iwl_priv *priv)
{
kfree(priv->ieee_channels);
kfree(priv->ieee_rates);
clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
}
+EXPORT_SYMBOL(iwlcore_free_geos);

static bool is_single_rx_stream(struct iwl_priv *priv)
{
@@ -936,6 +936,7 @@ int iwl_init_drv(struct iwl_priv *priv)
IWL_ERR(priv, "initializing geos failed: %d\n", ret);
goto err_free_channel_map;
}
+ iwlcore_init_hw_rates(priv, priv->ieee_rates);

return 0;

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 9a35080..0c6250c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -395,6 +395,11 @@ void iwl_enable_interrupts(struct iwl_priv *priv);
void iwl_dump_nic_error_log(struct iwl_priv *priv);
void iwl_dump_nic_event_log(struct iwl_priv *priv);

+/*****************************************************
+* GEOS
+******************************************************/
+int iwlcore_init_geos(struct iwl_priv *priv);
+void iwlcore_free_geos(struct iwl_priv *priv);

/*************** DRIVER STATUS FUNCTIONS *****/

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index b57c2b8..5fa5cb2 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3383,137 +3383,6 @@ static void iwl3945_init_hw_rates(struct iwl_priv *priv,
}
}

-/**
- * iwl3945_init_geos - Initialize mac80211's geo/channel info based from eeprom
- */
-#define IEEE80211_24GHZ_MAX_CHANNEL 14
-static int iwl3945_init_geos(struct iwl_priv *priv)
-{
- struct iwl_channel_info *ch;
- struct ieee80211_supported_band *sband;
- struct ieee80211_channel *channels;
- struct ieee80211_channel *geo_ch;
- struct ieee80211_rate *rates;
- int i = 0;
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_bitrates ||
- priv->bands[IEEE80211_BAND_5GHZ].n_bitrates) {
- IWL_DEBUG_INFO("Geography modes already initialized.\n");
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
- return 0;
- }
-
- channels = kzalloc(sizeof(struct ieee80211_channel) *
- priv->channel_count, GFP_KERNEL);
- if (!channels)
- return -ENOMEM;
-
- rates = kzalloc((sizeof(struct ieee80211_rate) * (IWL_RATE_COUNT + 1)),
- GFP_KERNEL);
- if (!rates) {
- kfree(channels);
- return -ENOMEM;
- }
-
- /* 5.2GHz channels start after the 2.4GHz channels */
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- sband->channels = &channels[IEEE80211_24GHZ_MAX_CHANNEL];
- /* just OFDM */
- sband->bitrates = &rates[IWL_FIRST_OFDM_RATE];
- sband->n_bitrates = IWL_RATE_COUNT - IWL_FIRST_OFDM_RATE;
-
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
- sband->channels = channels;
- /* OFDM & CCK */
- sband->bitrates = rates;
- sband->n_bitrates = IWL_RATE_COUNT;
-
- priv->ieee_channels = channels;
- priv->ieee_rates = rates;
-
- iwl3945_init_hw_rates(priv, rates);
-
- for (i = 0; i < priv->channel_count; i++) {
- ch = &priv->channel_info[i];
-
- /* FIXME: might be removed if scan is OK*/
- if (!is_channel_valid(ch))
- continue;
-
- if (is_channel_a_band(ch))
- sband = &priv->bands[IEEE80211_BAND_5GHZ];
- else
- sband = &priv->bands[IEEE80211_BAND_2GHZ];
-
- geo_ch = &sband->channels[sband->n_channels++];
-
- geo_ch->center_freq = ieee80211_channel_to_frequency(ch->channel);
- geo_ch->max_power = ch->max_power_avg;
- geo_ch->max_antenna_gain = 0xff;
- geo_ch->hw_value = ch->channel;
-
- if (is_channel_valid(ch)) {
- if (!(ch->flags & EEPROM_CHANNEL_IBSS))
- geo_ch->flags |= IEEE80211_CHAN_NO_IBSS;
-
- if (!(ch->flags & EEPROM_CHANNEL_ACTIVE))
- geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN;
-
- if (ch->flags & EEPROM_CHANNEL_RADAR)
- geo_ch->flags |= IEEE80211_CHAN_RADAR;
-
- if (ch->max_power_avg > priv->tx_power_channel_lmt)
- priv->tx_power_channel_lmt =
- ch->max_power_avg;
- } else {
- geo_ch->flags |= IEEE80211_CHAN_DISABLED;
- }
-
- /* Save flags for reg domain usage */
- geo_ch->orig_flags = geo_ch->flags;
-
- IWL_DEBUG_INFO("Channel %d Freq=%d[%sGHz] %s flag=0%X\n",
- ch->channel, geo_ch->center_freq,
- is_channel_a_band(ch) ? "5.2" : "2.4",
- geo_ch->flags & IEEE80211_CHAN_DISABLED ?
- "restricted" : "valid",
- geo_ch->flags);
- }
-
- if ((priv->bands[IEEE80211_BAND_5GHZ].n_channels == 0) &&
- priv->cfg->sku & IWL_SKU_A) {
- IWL_INFO(priv, "Incorrectly detected BG card as ABG. "
- "Please send your PCI ID 0x%04X:0x%04X to maintainer.\n",
- priv->pci_dev->device, priv->pci_dev->subsystem_device);
- priv->cfg->sku &= ~IWL_SKU_A;
- }
-
- IWL_INFO(priv, "Tunable channels: %d 802.11bg, %d 802.11a channels\n",
- priv->bands[IEEE80211_BAND_2GHZ].n_channels,
- priv->bands[IEEE80211_BAND_5GHZ].n_channels);
-
- if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
- &priv->bands[IEEE80211_BAND_2GHZ];
- if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
- priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
- &priv->bands[IEEE80211_BAND_5GHZ];
-
- set_bit(STATUS_GEO_CONFIGURED, &priv->status);
-
- return 0;
-}
-
-/*
- * iwl3945_free_geos - undo allocations in iwl3945_init_geos
- */
-static void iwl3945_free_geos(struct iwl_priv *priv)
-{
- kfree(priv->ieee_channels);
- kfree(priv->ieee_rates);
- clear_bit(STATUS_GEO_CONFIGURED, &priv->status);
-}
-
/******************************************************************************
*
* uCode download functions
@@ -6144,11 +6013,19 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
goto err_free_channel_map;
}

- ret = iwl3945_init_geos(priv);
+ ret = iwlcore_init_geos(priv);
if (ret) {
IWL_ERR(priv, "initializing geos failed: %d\n", ret);
goto err_free_channel_map;
}
+ iwl3945_init_hw_rates(priv, priv->ieee_rates);
+
+ if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
+ &priv->bands[IEEE80211_BAND_2GHZ];
+ if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
+ priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
+ &priv->bands[IEEE80211_BAND_5GHZ];

return 0;

@@ -6379,7 +6256,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
out_remove_sysfs:
sysfs_remove_group(&pdev->dev.kobj, &iwl3945_attribute_group);
out_free_geos:
- iwl3945_free_geos(priv);
+ iwlcore_free_geos(priv);

out_release_irq:
free_irq(priv->pci_dev->irq, priv);
@@ -6461,7 +6338,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);

iwl_free_channel_map(priv);
- iwl3945_free_geos(priv);
+ iwlcore_free_geos(priv);
kfree(priv->scan);
if (priv->ibss_beacon)
dev_kfree_skb(priv->ibss_beacon);
--
1.5.4.3


2009-01-23 21:42:57

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 15/15] iwlwifi: iwl_tx_queue_alloc : fix warning in printk formatting

From: Winkler, Tomas <[email protected]>

This patch fix compilation warning in printk formatting
iwl_tx_queue_alloc function.
Cleanup the code a bit on the way.

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-tx.c | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 58118c8..7d2b6e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -278,6 +278,7 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
struct iwl_tx_queue *txq, u32 id)
{
struct pci_dev *dev = priv->pci_dev;
+ size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;

/* Driver private data, only for Tx (not command) queues,
* not shared with device. */
@@ -289,18 +290,16 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
"structures failed\n");
goto error;
}
- } else
+ } else {
txq->txb = NULL;
+ }

/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
- txq->tfds = pci_alloc_consistent(dev,
- priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
+ txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);

if (!txq->tfds) {
- IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
- priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX);
+ IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);
goto error;
}
txq->q.id = id;
--
1.5.4.3


2009-01-23 21:42:47

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 03/15] iwl3945: Define send_tx_power

From: Samuel Ortiz <[email protected]>

We can define this iwl_lib ops for 3945, as this would help us cleaning the
scanning code.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 7 ++++---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++--
2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 4aeb101..602a3a9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1705,12 +1705,12 @@ static void iwl3945_hw_reg_set_scan_power(struct iwl_priv *priv, u32 scan_tbl_in
}

/**
- * iwl3945_hw_reg_send_txpower - fill in Tx Power command with gain settings
+ * iwl3945_send_tx_power - fill in Tx Power command with gain settings
*
* Configures power settings for all rates for the current channel,
* using values from channel info struct, and send to NIC
*/
-int iwl3945_hw_reg_send_txpower(struct iwl_priv *priv)
+int iwl3945_send_tx_power(struct iwl_priv *priv)
{
int rate_idx, i;
const struct iwl_channel_info *ch_info = NULL;
@@ -1935,7 +1935,7 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
}

/* send Txpower command for current channel to ucode */
- return iwl3945_hw_reg_send_txpower(priv);
+ return priv->cfg->ops->lib->send_tx_power(priv);
}

int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
@@ -2712,6 +2712,7 @@ static struct iwl_lib_ops iwl3945_lib = {
.config = iwl3945_nic_config,
.set_pwr_src = iwl3945_set_pwr_src,
},
+ .send_tx_power = iwl3945_send_tx_power,
};

static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index de8c8d7..997ac33 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -744,7 +744,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)

/* If we issue a new RXON command which required a tune then we must
* send a new TXPOWER command or we won't be able to Tx any frames */
- rc = iwl3945_hw_reg_send_txpower(priv);
+ rc = priv->cfg->ops->lib->send_tx_power(priv);
if (rc) {
IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
return rc;
@@ -5517,7 +5517,7 @@ static void iwl3945_bg_scan_completed(struct work_struct *work)
/* Since setting the TXPOWER may have been deferred while
* performing the scan, fire one off */
mutex_lock(&priv->mutex);
- iwl3945_hw_reg_send_txpower(priv);
+ priv->cfg->ops->lib->send_tx_power(priv);
mutex_unlock(&priv->mutex);
}

--
1.5.4.3


2009-01-23 21:42:46

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 02/15] iwlagn: reduce off channel reception for 4965

From: Rick Farrington <[email protected]>

Force use of chains B and C (0x6) for Rx for 4965
Avoid A (0x1) because of its off-channel reception on A-band.

Signed-off-by: Rick Farrington <[email protected]>
Signed-off-by: Ben Cahill <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
Signed-off-by: Tomas Winkler <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +++
drivers/net/wireless/iwlwifi/iwl-commands.h | 1 +
drivers/net/wireless/iwlwifi/iwl-core.c | 13 +++++++++++++
3 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c72a99a..61788a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2698,6 +2698,9 @@ static int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)

iwl_set_rate(priv);

+ /* call to ensure that 4965 rx_chain is set properly in monitor mode */
+ iwl_set_rxon_chain(priv);
+
if (memcmp(&priv->active_rxon,
&priv->staging_rxon, sizeof(priv->staging_rxon)))
iwl_commit_rxon(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 3ced5e5..7571110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -563,6 +563,7 @@ enum {


#define RXON_RX_CHAIN_DRIVER_FORCE_MSK cpu_to_le16(0x1 << 0)
+#define RXON_RX_CHAIN_DRIVER_FORCE_POS (0)
#define RXON_RX_CHAIN_VALID_MSK cpu_to_le16(0x7 << 1)
#define RXON_RX_CHAIN_VALID_POS (1)
#define RXON_RX_CHAIN_FORCE_SEL_MSK cpu_to_le16(0x7 << 4)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index ef4a7c5..b64377e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -753,6 +753,19 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;

+ /* copied from 'iwl_bg_request_scan()' */
+ /* Force use of chains B and C (0x6) for Rx for 4965
+ * Avoid A (0x1) because of its off-channel reception on A-band.
+ * MIMO is not used here, but value is required */
+ if (iwl_is_monitor_mode(priv) &&
+ !(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) &&
+ ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965)) {
+ rx_chain = 0x07 << RXON_RX_CHAIN_VALID_POS;
+ rx_chain |= 0x06 << RXON_RX_CHAIN_FORCE_SEL_POS;
+ rx_chain |= 0x07 << RXON_RX_CHAIN_FORCE_MIMO_SEL_POS;
+ rx_chain |= 0x01 << RXON_RX_CHAIN_DRIVER_FORCE_POS;
+ }
+
priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain);

if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
--
1.5.4.3


2009-01-23 21:42:49

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 05/15] iwlwifi: make iwl_tx_queue->tfds void*

From: Samuel Ortiz <[email protected]>

Instead of having both tfds and tfds39, we can just have a void *tfds.
It makes the tx_queue structure nicer, and the code cleaner. It also helps
with further TX queues management code merging.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 7 ++++---
drivers/net/wireless/iwlwifi/iwl-agn.c | 7 ++++---
drivers/net/wireless/iwlwifi/iwl-dev.h | 3 +--
drivers/net/wireless/iwlwifi/iwl-tx.c | 4 ++--
drivers/net/wireless/iwlwifi/iwl3945-base.c | 12 ++++++------
5 files changed, 17 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 602a3a9..22770f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -730,10 +730,11 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
{
int count;
struct iwl_queue *q;
- struct iwl3945_tfd *tfd;
+ struct iwl3945_tfd *tfd, *tfd_tmp;

q = &txq->q;
- tfd = &txq->tfds39[q->write_ptr];
+ tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];

if (reset)
memset(tfd, 0, sizeof(*tfd));
@@ -764,7 +765,7 @@ int iwl3945_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
*/
void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
- struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)&txq->tfds39[0];
+ struct iwl3945_tfd *tfd_tmp = (struct iwl3945_tfd *)txq->tfds;
struct iwl3945_tfd *tfd = &tfd_tmp[txq->q.read_ptr];
struct pci_dev *dev = priv->pci_dev;
int i;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 61788a5..4ce3d6a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -520,7 +520,7 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd)
*/
void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
{
- struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)&txq->tfds[0];
+ struct iwl_tfd *tfd_tmp = (struct iwl_tfd *)txq->tfds;
struct iwl_tfd *tfd;
struct pci_dev *dev = priv->pci_dev;
int index = txq->q.read_ptr;
@@ -563,11 +563,12 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
u8 reset, u8 pad)
{
struct iwl_queue *q;
- struct iwl_tfd *tfd;
+ struct iwl_tfd *tfd, *tfd_tmp;
u32 num_tbs;

q = &txq->q;
- tfd = &txq->tfds[q->write_ptr];
+ tfd_tmp = (struct iwl_tfd *)txq->tfds;
+ tfd = &tfd_tmp[q->write_ptr];

if (reset)
memset(tfd, 0, sizeof(*tfd));
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 79f2d45..78ce4f4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -149,8 +149,7 @@ struct iwl_tx_info {

struct iwl_tx_queue {
struct iwl_queue q;
- struct iwl_tfd *tfds;
- struct iwl3945_tfd *tfds39;
+ void *tfds;
struct iwl_cmd *cmd[TFD_TX_CMD_SLOTS];
struct iwl_tx_info *txb;
u8 need_update;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 1a2cfbe..83e9f32 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -295,12 +295,12 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
txq->tfds = pci_alloc_consistent(dev,
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX,
+ sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX,
&txq->q.dma_addr);

if (!txq->tfds) {
IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->tfds[0]) * TFD_QUEUE_SIZE_MAX);
+ sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX);
goto error;
}
txq->q.id = id;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index c7bb9c1..bc10e2a 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -172,13 +172,13 @@ static int iwl3945_tx_queue_alloc(struct iwl_priv *priv,

/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
- txq->tfds39 = pci_alloc_consistent(dev,
- sizeof(txq->tfds39[0]) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
+ txq->tfds = pci_alloc_consistent(dev,
+ sizeof(struct iwl3945_tfd) * TFD_QUEUE_SIZE_MAX,
+ &txq->q.dma_addr);

- if (!txq->tfds39) {
+ if (!txq->tfds) {
IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
- sizeof(txq->tfds39[0]) * TFD_QUEUE_SIZE_MAX);
+ sizeof(struct iwl3945_tfd) * TFD_QUEUE_SIZE_MAX);
goto error;
}
txq->q.id = id;
@@ -287,7 +287,7 @@ void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
/* De-alloc circular buffer of TFDs */
if (txq->q.n_bd)
pci_free_consistent(dev, sizeof(struct iwl3945_tfd) *
- txq->q.n_bd, txq->tfds39, txq->q.dma_addr);
+ txq->q.n_bd, txq->tfds, txq->q.dma_addr);

/* De-alloc array of per-TFD driver data */
kfree(txq->txb);
--
1.5.4.3


2009-01-23 21:42:49

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 06/15] iwl3945: Use iwlcore TX queue management routines

From: Samuel Ortiz <[email protected]>

By adding an additional hw_params (tfd_size) and a new iwl_lib ops (txq_init),
we can now use the iwlcore TX queue management routines.
We had to add a new hw_params because we need to allocate the right DMA buffer
for TFDs, and those have a different sizes depending if you're on 3945 or agn.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 8 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +
drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +
drivers/net/wireless/iwlwifi/iwl-agn.c | 32 ++++
drivers/net/wireless/iwlwifi/iwl-core.h | 7 +
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +
drivers/net/wireless/iwlwifi/iwl-tx.c | 49 ++-----
drivers/net/wireless/iwlwifi/iwl3945-base.c | 204 ---------------------------
8 files changed, 60 insertions(+), 246 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 22770f4..2689113 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1068,8 +1068,8 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++) {
slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
- rc = iwl3945_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
- txq_id);
+ rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
+ txq_id);
if (rc) {
IWL_ERR(priv, "Tx %d queue init failed\n", txq_id);
goto error;
@@ -1258,7 +1258,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)

/* Tx queues */
for (txq_id = 0; txq_id < TFD_QUEUE_MAX; txq_id++)
- iwl3945_tx_queue_free(priv, &priv->txq[txq_id]);
+ iwl_tx_queue_free(priv, txq_id);
}

void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
@@ -2491,6 +2491,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
return -ENOMEM;
}

+ priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
priv->hw_params.max_pkt_size = 2342;
priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
@@ -2705,6 +2706,7 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
static struct iwl_lib_ops iwl3945_lib = {
.txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl3945_hw_txq_free_tfd,
+ .txq_init = iwl3945_hw_tx_queue_init,
.load_ucode = iwl3945_load_bsm,
.apm_ops = {
.init = iwl3945_apm_init,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b2985e2..d7d956d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -815,6 +815,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH49_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL49_NUM_QUEUES * sizeof(struct iwl4965_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL4965_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID;
priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
@@ -2297,6 +2298,7 @@ static struct iwl_lib_ops iwl4965_lib = {
.txq_agg_disable = iwl4965_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwl4965_rx_handler_setup,
.setup_deferred_work = iwl4965_setup_deferred_work,
.cancel_deferred_work = iwl4965_cancel_deferred_work,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 04c2585..89d92a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -837,6 +837,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
priv->hw_params.dma_chnl_num = FH50_TCSR_CHNL_NUM;
priv->hw_params.scd_bc_tbls_size =
IWL50_NUM_QUEUES * sizeof(struct iwl5000_scd_bc_tbl);
+ priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
priv->hw_params.max_stations = IWL5000_STATION_COUNT;
priv->hw_params.bcast_sta_id = IWL5000_BROADCAST_ID;
priv->hw_params.max_data_size = IWL50_RTC_DATA_SIZE;
@@ -1494,6 +1495,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.txq_agg_disable = iwl5000_txq_agg_disable,
.txq_attach_buf_to_tfd = iwl_hw_txq_attach_buf_to_tfd,
.txq_free_tfd = iwl_hw_txq_free_tfd,
+ .txq_init = iwl_hw_tx_queue_init,
.rx_handler_setup = iwl5000_rx_handler_setup,
.setup_deferred_work = iwl5000_setup_deferred_work,
.is_valid_rtc_data_addr = iwl5000_hw_valid_rtc_data_addr,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4ce3d6a..5c6b3fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -592,6 +592,38 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
return 0;
}

+/*
+ * Tell nic where to find circular buffer of Tx Frame Descriptors for
+ * given Tx queue, and enable the DMA channel used for that queue.
+ *
+ * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
+ * channels supported in hardware.
+ */
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq)
+{
+ int ret;
+ unsigned long flags;
+ int txq_id = txq->q.id;
+
+ spin_lock_irqsave(&priv->lock, flags);
+ ret = iwl_grab_nic_access(priv);
+ if (ret) {
+ spin_unlock_irqrestore(&priv->lock, flags);
+ return ret;
+ }
+
+ /* Circular buffer (TFD queue in DRAM) physical base address */
+ iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
+ txq->q.dma_addr >> 8);
+
+ iwl_release_nic_access(priv);
+ spin_unlock_irqrestore(&priv->lock, flags);
+
+ return 0;
+}
+
+
/******************************************************************************
*
* Misc. internal state and helper functions
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 409caaa..9a35080 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -116,6 +116,8 @@ struct iwl_lib_ops {
u16 len, u8 reset, u8 pad);
void (*txq_free_tfd)(struct iwl_priv *priv,
struct iwl_tx_queue *txq);
+ int (*txq_init)(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
/* aggregations */
int (*txq_agg_enable)(struct iwl_priv *priv, int txq_id, int tx_fifo,
int sta_id, int tid, u16 ssn_idx);
@@ -264,7 +266,12 @@ int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv,
dma_addr_t addr, u16 len, u8 reset, u8 pad);
int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);
+int iwl_hw_tx_queue_init(struct iwl_priv *priv,
+ struct iwl_tx_queue *txq);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id);
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id);
int iwl_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn);
int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
int iwl_txq_check_empty(struct iwl_priv *priv, int sta_id, u8 tid, int txq_id);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 78ce4f4..5aa22d6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -567,6 +567,7 @@ struct iwl_sensitivity_ranges {
* @max_txq_num: Max # Tx queues supported
* @dma_chnl_num: Number of Tx DMA/FIFO channels
* @scd_bc_tbls_size: size of scheduler byte count tables
+ * @tfd_size: TFD size
* @tx/rx_chains_num: Number of TX/RX chains
* @valid_tx/rx_ant: usable antennas
* @max_rxq_size: Max # Rx frames in Rx queue (must be power-of-2)
@@ -587,6 +588,7 @@ struct iwl_hw_params {
u8 max_txq_num;
u8 dma_chnl_num;
u16 scd_bc_tbls_size;
+ u32 tfd_size;
u8 tx_chains_num;
u8 rx_chains_num;
u8 valid_tx_ant;
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 83e9f32..58118c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -131,7 +131,7 @@ EXPORT_SYMBOL(iwl_txq_update_write_ptr);
* Free all buffers.
* 0-fill, but do not free "txq" descriptor structure.
*/
-static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
+void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
{
struct iwl_tx_queue *txq = &priv->txq[txq_id];
struct iwl_queue *q = &txq->q;
@@ -154,7 +154,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)

/* De-alloc circular buffer of TFDs */
if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl_tfd) *
+ pci_free_consistent(dev, priv->hw_params.tfd_size *
txq->q.n_bd, txq->tfds, txq->q.dma_addr);

/* De-alloc array of per-TFD driver data */
@@ -164,7 +164,7 @@ static void iwl_tx_queue_free(struct iwl_priv *priv, int txq_id)
/* 0-fill queue descriptor structure */
memset(txq, 0, sizeof(*txq));
}
-
+EXPORT_SYMBOL(iwl_tx_queue_free);

/**
* iwl_cmd_queue_free - Deallocate DMA queue.
@@ -295,12 +295,12 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
/* Circular buffer of transmit frame descriptors (TFDs),
* shared with device */
txq->tfds = pci_alloc_consistent(dev,
- sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX,
+ priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX,
&txq->q.dma_addr);

if (!txq->tfds) {
IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
- sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX);
+ priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX);
goto error;
}
txq->q.id = id;
@@ -314,42 +314,11 @@ static int iwl_tx_queue_alloc(struct iwl_priv *priv,
return -ENOMEM;
}

-/*
- * Tell nic where to find circular buffer of Tx Frame Descriptors for
- * given Tx queue, and enable the DMA channel used for that queue.
- *
- * 4965 supports up to 16 Tx queues in DRAM, mapped to up to 8 Tx DMA
- * channels supported in hardware.
- */
-static int iwl_hw_tx_queue_init(struct iwl_priv *priv,
- struct iwl_tx_queue *txq)
-{
- int ret;
- unsigned long flags;
- int txq_id = txq->q.id;
-
- spin_lock_irqsave(&priv->lock, flags);
- ret = iwl_grab_nic_access(priv);
- if (ret) {
- spin_unlock_irqrestore(&priv->lock, flags);
- return ret;
- }
-
- /* Circular buffer (TFD queue in DRAM) physical base address */
- iwl_write_direct32(priv, FH_MEM_CBBC_QUEUE(txq_id),
- txq->q.dma_addr >> 8);
-
- iwl_release_nic_access(priv);
- spin_unlock_irqrestore(&priv->lock, flags);
-
- return 0;
-}
-
/**
* iwl_tx_queue_init - Allocate and initialize one tx/cmd queue
*/
-static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
- int slots_num, u32 txq_id)
+int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
+ int slots_num, u32 txq_id)
{
int i, len;
int ret;
@@ -391,7 +360,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv, struct iwl_tx_queue *txq,
iwl_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);

/* Tell device where to find queue */
- iwl_hw_tx_queue_init(priv, txq);
+ priv->cfg->ops->lib->txq_init(priv, txq);

return 0;
err:
@@ -406,6 +375,8 @@ err:
}
return -ENOMEM;
}
+EXPORT_SYMBOL(iwl_tx_queue_init);
+
/**
* iwl_hw_txq_ctx_free - Free TXQ Context
*
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index bc10e2a..14f9523 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -93,210 +93,6 @@ struct iwl_mod_params iwl3945_mod_params = {
/* the rest are 0 by default */
};

-/*************** DMA-QUEUE-GENERAL-FUNCTIONS *****
- * DMA services
- *
- * Theory of operation
- *
- * A Tx or Rx queue resides in host DRAM, and is comprised of a circular buffer
- * of buffer descriptors, each of which points to one or more data buffers for
- * the device to read from or fill. Driver and device exchange status of each
- * queue via "read" and "write" pointers. Driver keeps minimum of 2 empty
- * entries in each circular buffer, to protect against confusing empty and full
- * queue states.
- *
- * The device reads or writes the data in the queues via the device's several
- * DMA/FIFO channels. Each queue is mapped to a single DMA channel.
- *
- * For Tx queue, there are low mark and high mark limits. If, after queuing
- * the packet for Tx, free space become < low mark, Tx queue stopped. When
- * reclaiming packets (on 'tx done IRQ), if free space become > high mark,
- * Tx queue resumed.
- *
- * The 3945 operates with six queues: One receive queue, one transmit queue
- * (#4) for sending commands to the device firmware, and four transmit queues
- * (#0-3) for data tx via EDCA. An additional 2 HCCA queues are unused.
- ***************************************************/
-
-/**
- * iwl3945_queue_init - Initialize queue's high/low-water and read/write indexes
- */
-static int iwl3945_queue_init(struct iwl_priv *priv, struct iwl_queue *q,
- int count, int slots_num, u32 id)
-{
- q->n_bd = count;
- q->n_window = slots_num;
- q->id = id;
-
- /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
- * and iwl_queue_dec_wrap are broken. */
- BUG_ON(!is_power_of_2(count));
-
- /* slots_num must be power-of-two size, otherwise
- * get_cmd_index is broken. */
- BUG_ON(!is_power_of_2(slots_num));
-
- q->low_mark = q->n_window / 4;
- if (q->low_mark < 4)
- q->low_mark = 4;
-
- q->high_mark = q->n_window / 8;
- if (q->high_mark < 2)
- q->high_mark = 2;
-
- q->write_ptr = q->read_ptr = 0;
-
- return 0;
-}
-
-/**
- * iwl3945_tx_queue_alloc - Alloc driver data and TFD CB for one Tx/cmd queue
- */
-static int iwl3945_tx_queue_alloc(struct iwl_priv *priv,
- struct iwl_tx_queue *txq, u32 id)
-{
- struct pci_dev *dev = priv->pci_dev;
-
- /* Driver private data, only for Tx (not command) queues,
- * not shared with device. */
- if (id != IWL_CMD_QUEUE_NUM) {
- txq->txb = kmalloc(sizeof(txq->txb[0]) *
- TFD_QUEUE_SIZE_MAX, GFP_KERNEL);
- if (!txq->txb) {
- IWL_ERR(priv, "kmalloc for auxiliary BD "
- "structures failed\n");
- goto error;
- }
- } else
- txq->txb = NULL;
-
- /* Circular buffer of transmit frame descriptors (TFDs),
- * shared with device */
- txq->tfds = pci_alloc_consistent(dev,
- sizeof(struct iwl3945_tfd) * TFD_QUEUE_SIZE_MAX,
- &txq->q.dma_addr);
-
- if (!txq->tfds) {
- IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n",
- sizeof(struct iwl3945_tfd) * TFD_QUEUE_SIZE_MAX);
- goto error;
- }
- txq->q.id = id;
-
- return 0;
-
- error:
- kfree(txq->txb);
- txq->txb = NULL;
-
- return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_init - Allocate and initialize one tx/cmd queue
- */
-int iwl3945_tx_queue_init(struct iwl_priv *priv,
- struct iwl_tx_queue *txq, int slots_num, u32 txq_id)
-{
- int len, i;
- int rc = 0;
-
- /*
- * Alloc buffer array for commands (Tx or other types of commands).
- * For the command queue (#4), allocate command space + one big
- * command for scan, since scan command is very huge; the system will
- * not have two scans at the same time, so only one is needed.
- * For data Tx queues (all other queues), no super-size command
- * space is needed.
- */
- len = sizeof(struct iwl_cmd);
- for (i = 0; i <= slots_num; i++) {
- if (i == slots_num) {
- if (txq_id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
- else
- continue;
- }
-
- txq->cmd[i] = kmalloc(len, GFP_KERNEL);
- if (!txq->cmd[i])
- goto err;
- }
-
- /* Alloc driver data array and TFD circular buffer */
- rc = iwl3945_tx_queue_alloc(priv, txq, txq_id);
- if (rc)
- goto err;
-
- txq->need_update = 0;
-
- /* TFD_QUEUE_SIZE_MAX must be power-of-two size, otherwise
- * iwl_queue_inc_wrap and iwl_queue_dec_wrap are broken. */
- BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
-
- /* Initialize queue high/low-water, head/tail indexes */
- iwl3945_queue_init(priv, &txq->q, TFD_QUEUE_SIZE_MAX, slots_num, txq_id);
-
- /* Tell device where to find queue, enable DMA channel. */
- iwl3945_hw_tx_queue_init(priv, txq);
-
- return 0;
-err:
- for (i = 0; i < slots_num; i++) {
- kfree(txq->cmd[i]);
- txq->cmd[i] = NULL;
- }
-
- if (txq_id == IWL_CMD_QUEUE_NUM) {
- kfree(txq->cmd[slots_num]);
- txq->cmd[slots_num] = NULL;
- }
- return -ENOMEM;
-}
-
-/**
- * iwl3945_tx_queue_free - Deallocate DMA queue.
- * @txq: Transmit queue to deallocate.
- *
- * Empty queue by removing and destroying all BD's.
- * Free all buffers.
- * 0-fill, but do not free "txq" descriptor structure.
- */
-void iwl3945_tx_queue_free(struct iwl_priv *priv, struct iwl_tx_queue *txq)
-{
- struct iwl_queue *q = &txq->q;
- struct pci_dev *dev = priv->pci_dev;
- int len, i;
-
- if (q->n_bd == 0)
- return;
-
- /* first, empty all BD's */
- for (; q->write_ptr != q->read_ptr;
- q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd))
- priv->cfg->ops->lib->txq_free_tfd(priv, txq);
-
- len = sizeof(struct iwl_cmd) * q->n_window;
- if (q->id == IWL_CMD_QUEUE_NUM)
- len += IWL_MAX_SCAN_SIZE;
-
- /* De-alloc array of command/tx buffers */
- for (i = 0; i < TFD_TX_CMD_SLOTS; i++)
- kfree(txq->cmd[i]);
-
- /* De-alloc circular buffer of TFDs */
- if (txq->q.n_bd)
- pci_free_consistent(dev, sizeof(struct iwl3945_tfd) *
- txq->q.n_bd, txq->tfds, txq->q.dma_addr);
-
- /* De-alloc array of per-TFD driver data */
- kfree(txq->txb);
- txq->txb = NULL;
-
- /* 0-fill queue descriptor structure */
- memset(txq, 0, sizeof(*txq));
-}
-
/*************** STATION TABLE MANAGEMENT ****
* mac80211 should be examined to determine if sta_info is duplicating
* the functionality provided here
--
1.5.4.3


2009-01-23 21:42:56

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 12/15] iwl3945: Remaining host command cleanups

From: Samuel Ortiz <[email protected]>

With the recent host command routines merge, we can now look at the various
host command helpers and get rid of the duplicated ones.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 12 +++-
drivers/net/wireless/iwlwifi/iwl-3945.h | 1 -
drivers/net/wireless/iwlwifi/iwl-agn.c | 14 ---
drivers/net/wireless/iwlwifi/iwl-core.c | 15 ++++
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +
drivers/net/wireless/iwlwifi/iwl-scan.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-sta.c | 6 +-
drivers/net/wireless/iwlwifi/iwl-sta.h | 2 +
drivers/net/wireless/iwlwifi/iwl3945-base.c | 116 ++------------------------
9 files changed, 45 insertions(+), 127 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 7f1e042..12f93b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -41,6 +41,7 @@
#include "iwl-fh.h"
#include "iwl-3945-fh.h"
#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
#include "iwl-eeprom.h"
#include "iwl-helpers.h"
@@ -895,7 +896,8 @@ u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)

spin_unlock_irqrestore(&priv->sta_lock, flags_spin);

- iwl3945_send_add_station(priv, &station->sta, flags);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
IWL_DEBUG_RATE("SCALE sync station %d to rate %d\n",
sta_id, tx_rate);
return sta_id;
@@ -2376,6 +2378,13 @@ static u16 iwl3945_get_hcmd_size(u8 cmd_id, u16 len)
}
}

+static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
+{
+ u16 size = (u16)sizeof(struct iwl3945_addsta_cmd);
+ memcpy(data, cmd, size);
+ return size;
+}
+
/**
* iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
*/
@@ -2743,6 +2752,7 @@ static struct iwl_lib_ops iwl3945_lib = {

static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
.get_hcmd_size = iwl3945_get_hcmd_size,
+ .build_addsta_hcmd = iwl3945_build_addsta_hcmd,
};

static struct iwl_ops iwl3945_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 77e97ea..fef54e9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -222,7 +222,6 @@ extern int __must_check iwl3945_send_cmd(struct iwl_priv *priv,
struct iwl_host_cmd *cmd);
extern unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,int left);
-extern int iwl3945_send_statistics_request(struct iwl_priv *priv);
extern void iwl3945_set_decrypted_flag(struct iwl_priv *priv, struct sk_buff *skb,
u32 decrypt_res,
struct ieee80211_rx_status *stats);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5c6b3fe..757a9bd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -310,20 +310,6 @@ void iwl_update_chain_flags(struct iwl_priv *priv)
iwl_commit_rxon(priv);
}

-static int iwl_send_bt_config(struct iwl_priv *priv)
-{
- struct iwl_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
-
- return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(struct iwl_bt_cmd), &bt_cmd);
-}
-
static void iwl_clear_free_frames(struct iwl_priv *priv)
{
struct list_head *element;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 902b75f..21f3865 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1007,6 +1007,21 @@ void iwl_enable_interrupts(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_enable_interrupts);

+int iwl_send_bt_config(struct iwl_priv *priv)
+{
+ struct iwl_bt_cmd bt_cmd = {
+ .flags = 3,
+ .lead_time = 0xAA,
+ .max_kill = 1,
+ .kill_ack_mask = 0,
+ .kill_cts_mask = 0,
+ };
+
+ return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
+ sizeof(struct iwl_bt_cmd), &bt_cmd);
+}
+EXPORT_SYMBOL(iwl_send_bt_config);
+
int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags)
{
u32 stat_flags = 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 0c6250c..c8e1dad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -335,6 +335,7 @@ void iwl_bg_scan_check(struct work_struct *data);
void iwl_bg_abort_scan(struct work_struct *work);
void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);
+int iwl_send_scan_abort(struct iwl_priv *priv);

/* For faster active scanning, scan will move to the next channel if fewer than
* PLCP_QUIET_THRESH packets are heard on this channel within
@@ -468,6 +469,7 @@ static inline int iwl_is_ready_rf(struct iwl_priv *priv)
}

extern void iwl_rf_kill_ct_config(struct iwl_priv *priv);
+extern int iwl_send_bt_config(struct iwl_priv *priv);
extern int iwl_send_statistics_request(struct iwl_priv *priv, u8 flags);
extern int iwl_verify_ucode(struct iwl_priv *priv);
extern int iwl_send_lq_cmd(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 0ce122a..c282d1d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -109,7 +109,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms)
}
EXPORT_SYMBOL(iwl_scan_cancel_timeout);

-static int iwl_send_scan_abort(struct iwl_priv *priv)
+int iwl_send_scan_abort(struct iwl_priv *priv)
{
int ret = 0;
struct iwl_rx_packet *res;
@@ -150,7 +150,7 @@ static int iwl_send_scan_abort(struct iwl_priv *priv)

return ret;
}
-
+EXPORT_SYMBOL(iwl_send_scan_abort);

/* Service response to REPLY_SCAN_CMD (0x80) */
static void iwl_rx_reply_scan(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 0cbb449..9bba98e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -86,7 +86,8 @@ static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)

spin_lock_irqsave(&priv->sta_lock, flags);

- if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE))
+ if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE) &&
+ !(priv->stations_39[sta_id].used & IWL_STA_DRIVER_ACTIVE))
IWL_ERR(priv, "ACTIVATE a non DRIVER active station %d\n",
sta_id);

@@ -131,7 +132,7 @@ static int iwl_add_sta_callback(struct iwl_priv *priv,
return 1;
}

-static int iwl_send_add_sta(struct iwl_priv *priv,
+int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags)
{
struct iwl_rx_packet *res = NULL;
@@ -179,6 +180,7 @@ static int iwl_send_add_sta(struct iwl_priv *priv,

return ret;
}
+EXPORT_SYMBOL(iwl_send_add_sta);

static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
struct ieee80211_sta_ht_cap *sta_ht_inf)
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 3fe7cc5..97f6169 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -56,6 +56,8 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, int is_ap);
void iwl_clear_stations_table(struct iwl_priv *priv);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
+int iwl_send_add_sta(struct iwl_priv *priv,
+ struct iwl_addsta_cmd *sta, u8 flags);
u8 iwl_add_station_flags(struct iwl_priv *priv, const u8 *addr,
int is_ap, u8 flags,
struct ieee80211_sta_ht_cap *ht_info);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 13fb618..d093255 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -51,6 +51,7 @@
#include "iwl-fh.h"
#include "iwl-3945-fh.h"
#include "iwl-commands.h"
+#include "iwl-sta.h"
#include "iwl-3945.h"
#include "iwl-helpers.h"
#include "iwl-core.h"
@@ -226,24 +227,12 @@ u8 iwl3945_add_station(struct iwl_priv *priv, const u8 *addr, int is_ap, u8 flag
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);

/* Add station to device's station table */
- iwl3945_send_add_station(priv, &station->sta, flags);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&station->sta, flags);
return index;

}

-int iwl3945_send_statistics_request(struct iwl_priv *priv)
-{
- u32 val = 0;
-
- struct iwl_host_cmd cmd = {
- .id = REPLY_STATISTICS_CMD,
- .len = sizeof(val),
- .data = &val,
- };
-
- return iwl_send_cmd_sync(priv, &cmd);
-}
-
/**
* iwl3945_set_rxon_channel - Set the phymode and channel values in staging RXON
* @band: 2.4 or 5 GHz band
@@ -611,95 +600,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
return 0;
}

-static int iwl3945_send_bt_config(struct iwl_priv *priv)
-{
- struct iwl_bt_cmd bt_cmd = {
- .flags = 3,
- .lead_time = 0xAA,
- .max_kill = 1,
- .kill_ack_mask = 0,
- .kill_cts_mask = 0,
- };
-
- return iwl_send_cmd_pdu(priv, REPLY_BT_CONFIG,
- sizeof(bt_cmd), &bt_cmd);
-}
-
-static int iwl3945_add_sta_sync_callback(struct iwl_priv *priv,
- struct iwl_cmd *cmd, struct sk_buff *skb)
-{
- struct iwl_rx_packet *res = NULL;
-
- if (!skb) {
- IWL_ERR(priv, "Error: Response NULL in REPLY_ADD_STA.\n");
- return 1;
- }
-
- res = (struct iwl_rx_packet *)skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- return 1;
- }
-
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- break;
- default:
- break;
- }
-
- /* We didn't cache the SKB; let the caller free it */
- return 1;
-}
-
-int iwl3945_send_add_station(struct iwl_priv *priv,
- struct iwl3945_addsta_cmd *sta, u8 flags)
-{
- struct iwl_rx_packet *res = NULL;
- int rc = 0;
- struct iwl_host_cmd cmd = {
- .id = REPLY_ADD_STA,
- .len = sizeof(struct iwl3945_addsta_cmd),
- .meta.flags = flags,
- .data = sta,
- };
-
- if (flags & CMD_ASYNC)
- cmd.meta.u.callback = iwl3945_add_sta_sync_callback;
- else
- cmd.meta.flags |= CMD_WANT_SKB;
-
- rc = iwl_send_cmd(priv, &cmd);
-
- if (rc || (flags & CMD_ASYNC))
- return rc;
-
- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
- if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
- IWL_ERR(priv, "Bad return from REPLY_ADD_STA (0x%08X)\n",
- res->hdr.flags);
- rc = -EIO;
- }
-
- if (rc == 0) {
- switch (res->u.add_sta.status) {
- case ADD_STA_SUCCESS_MSK:
- IWL_DEBUG_INFO("REPLY_ADD_STA PASSED\n");
- break;
- default:
- rc = -EIO;
- IWL_WARN(priv, "REPLY_ADD_STA failed\n");
- break;
- }
- }
-
- priv->alloc_rxb_skb--;
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
static int iwl3945_update_sta_key_info(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
u8 sta_id)
@@ -734,7 +634,8 @@ static int iwl3945_update_sta_key_info(struct iwl_priv *priv,
spin_unlock_irqrestore(&priv->sta_lock, flags);

IWL_DEBUG_INFO("hwcrypto: modify ucode station key info\n");
- iwl3945_send_add_station(priv, &priv->stations_39[sta_id].sta, 0);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
return 0;
}

@@ -752,7 +653,8 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
spin_unlock_irqrestore(&priv->sta_lock, flags);

IWL_DEBUG_INFO("hwcrypto: clear ucode station key info\n");
- iwl3945_send_add_station(priv, &priv->stations_39[sta_id].sta, 0);
+ iwl_send_add_sta(priv,
+ (struct iwl_addsta_cmd *)&priv->stations_39[sta_id].sta, 0);
return 0;
}

@@ -4005,7 +3907,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
}

/* Configure Bluetooth device coexistence support */
- iwl3945_send_bt_config(priv);
+ iwl_send_bt_config(priv);

/* Configure the adapter for unassociated operation */
iwl3945_commit_rxon(priv);
@@ -5810,7 +5712,7 @@ static ssize_t show_statistics(struct device *d,
return -EAGAIN;

mutex_lock(&priv->mutex);
- rc = iwl3945_send_statistics_request(priv);
+ rc = iwl_send_statistics_request(priv, 0);
mutex_unlock(&priv->mutex);

if (rc) {
--
1.5.4.3


2009-01-23 21:42:54

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 11/15] iwl3945: Add restart_fw module parameter

From: Samuel Ortiz <[email protected]>

In order to be in sync with the agn code, we're ading a fw_restart3945 module
parameter to iwl3945.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 8aaa6bf..13fb618 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -90,6 +90,7 @@ MODULE_LICENSE("GPL");
struct iwl_mod_params iwl3945_mod_params = {
.num_of_queues = IWL39_MAX_NUM_QUEUES,
.sw_crypto = 1,
+ .restart_fw = 1,
/* the rest are 0 by default */
};

@@ -3088,7 +3089,8 @@ static void iwl3945_irq_handle_error(struct iwl_priv *priv)
sizeof(priv->recovery39_rxon));
priv->error_recovering = 1;
}
- queue_work(priv->workqueue, &priv->restart);
+ if (priv->cfg->mod_params->restart_fw)
+ queue_work(priv->workqueue, &priv->restart);
}
}

@@ -6482,5 +6484,8 @@ MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444);
MODULE_PARM_DESC(queues_num, "number of hw queues.");

+module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
+MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
+
module_exit(iwl3945_exit);
module_init(iwl3945_init);
--
1.5.4.3


2009-01-23 21:42:54

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 13/15] iwlwifi: fix probe mask for 39 scan API

From: Winkler, Tomas <[email protected]>

This pach make use of 39 own scan probe mask
the variables or of different types

Signed-off-by: Tomas Winkler <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-commands.h | 6 ++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 1 -
drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 ++--
3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 7571110..e49415c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2432,6 +2432,9 @@ struct iwl3945_scan_channel {
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));

+/* set number of direct probes u8 type */
+#define IWL39_SCAN_PROBE_MASK(n) ((BIT(n) | (BIT(n) - BIT(1))))
+
struct iwl_scan_channel {
/*
* type is defined as:
@@ -2448,6 +2451,9 @@ struct iwl_scan_channel {
__le16 passive_dwell; /* in 1024-uSec TU (time units), typ 20-500 */
} __attribute__ ((packed));

+/* set number of direct probes __le32 type */
+#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
/**
* struct iwl_ssid_ie - directed scan network information element
*
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index c8e1dad..3c6a4b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -346,7 +346,6 @@ int iwl_send_scan_abort(struct iwl_priv *priv);
#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */

-#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))

/*******************************************************************************
* Calibrations - implemented in iwl-calib.c
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index d093255..25a3508 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3267,12 +3267,12 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
* hearing clear Rx packet).*/
if (IWL_UCODE_API(priv->ucode_ver) >= 2) {
if (n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
} else {
/* uCode v1 does not allow setting direct probe bits on
* passive channel. */
if ((scan_ch->type & 1) && n_probes)
- scan_ch->type |= IWL_SCAN_PROBE_MASK(n_probes);
+ scan_ch->type |= IWL39_SCAN_PROBE_MASK(n_probes);
}

/* Set txpower levels to defaults */
--
1.5.4.3


2009-01-23 21:42:48

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 04/15] iwl3945: Use iwlcore scan code

From: Samuel Ortiz <[email protected]>

A lot of the scanning related code is duplicated between 3945 and agn. Let's
use the iwlcore one and get rid of the 3945.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.h | 21 ++
drivers/net/wireless/iwlwifi/iwl-scan.c | 42 ++--
drivers/net/wireless/iwlwifi/iwl3945-base.c | 289 +--------------------------
3 files changed, 51 insertions(+), 301 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 2f23f78..409caaa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -316,9 +316,30 @@ void iwl_init_scan_params(struct iwl_priv *priv);
int iwl_scan_cancel(struct iwl_priv *priv);
int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_scan_initiate(struct iwl_priv *priv);
+u16 iwl_fill_probe_req(struct iwl_priv *priv, enum ieee80211_band band,
+ struct ieee80211_mgmt *frame, int left);
void iwl_setup_rx_scan_handlers(struct iwl_priv *priv);
+u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes);
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band);
+void iwl_bg_scan_check(struct work_struct *data);
+void iwl_bg_abort_scan(struct work_struct *work);
+void iwl_bg_scan_completed(struct work_struct *work);
void iwl_setup_scan_deferred_work(struct iwl_priv *priv);

+/* For faster active scanning, scan will move to the next channel if fewer than
+ * PLCP_QUIET_THRESH packets are heard on this channel within
+ * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
+ * time if it's a quiet channel (nothing responded to our probe, and there's
+ * no other traffic).
+ * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
+#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
+#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
+
+#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))
+
/*******************************************************************************
* Calibrations - implemented in iwl-calib.c
******************************************************************************/
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index e510f51..0ce122a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -46,15 +46,6 @@
#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)

-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
* Must be set longer than active dwell time.
* For the most reliable scan, set > AP beacon interval (typically 100msec). */
@@ -63,7 +54,6 @@
#define IWL_PASSIVE_DWELL_BASE (100)
#define IWL_CHANNEL_TUNE_TIME 5

-#define IWL_SCAN_PROBE_MASK(n) cpu_to_le32((BIT(n) | (BIT(n) - BIT(1))))


/**
@@ -296,9 +286,9 @@ void iwl_setup_rx_scan_handlers(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_setup_rx_scan_handlers);

-static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
+inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ u8 n_probes)
{
if (band == IEEE80211_BAND_5GHZ)
return IWL_ACTIVE_DWELL_TIME_52 +
@@ -307,9 +297,10 @@ static inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
return IWL_ACTIVE_DWELL_TIME_24 +
IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
}
+EXPORT_SYMBOL(iwl_get_active_dwell_time);

-static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
+u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
+ enum ieee80211_band band)
{
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -327,6 +318,7 @@ static u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,

return passive;
}
+EXPORT_SYMBOL(iwl_get_passive_dwell_time);

static int iwl_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
@@ -450,7 +442,7 @@ EXPORT_SYMBOL(iwl_scan_initiate);

#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)

-static void iwl_bg_scan_check(struct work_struct *data)
+void iwl_bg_scan_check(struct work_struct *data)
{
struct iwl_priv *priv =
container_of(data, struct iwl_priv, scan_check.work);
@@ -470,6 +462,8 @@ static void iwl_bg_scan_check(struct work_struct *data)
}
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_scan_check);
+
/**
* iwl_supported_rate_to_ie - fill in the supported rate in IE field
*
@@ -527,10 +521,10 @@ static void iwl_ht_cap_to_ie(const struct ieee80211_supported_band *sband,
* iwl_fill_probe_req - fill in all required fields and IE for probe request
*/

-static u16 iwl_fill_probe_req(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct ieee80211_mgmt *frame,
- int left)
+u16 iwl_fill_probe_req(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_mgmt *frame,
+ int left)
{
int len = 0;
u8 *pos = NULL;
@@ -624,6 +618,7 @@ static u16 iwl_fill_probe_req(struct iwl_priv *priv,

return (u16)len;
}
+EXPORT_SYMBOL(iwl_fill_probe_req);

static void iwl_bg_request_scan(struct work_struct *data)
{
@@ -839,7 +834,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
mutex_unlock(&priv->mutex);
}

-static void iwl_bg_abort_scan(struct work_struct *work)
+void iwl_bg_abort_scan(struct work_struct *work)
{
struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);

@@ -853,8 +848,9 @@ static void iwl_bg_abort_scan(struct work_struct *work)

mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_abort_scan);

-static void iwl_bg_scan_completed(struct work_struct *work)
+void iwl_bg_scan_completed(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, scan_completed);
@@ -872,7 +868,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
mutex_unlock(&priv->mutex);
}
-
+EXPORT_SYMBOL(iwl_bg_scan_completed);

void iwl_setup_scan_deferred_work(struct iwl_priv *priv)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 997ac33..c7bb9c1 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -791,47 +791,6 @@ static int iwl3945_send_bt_config(struct iwl_priv *priv)
sizeof(bt_cmd), &bt_cmd);
}

-static int iwl3945_send_scan_abort(struct iwl_priv *priv)
-{
- int rc = 0;
- struct iwl_rx_packet *res;
- struct iwl_host_cmd cmd = {
- .id = REPLY_SCAN_ABORT_CMD,
- .meta.flags = CMD_WANT_SKB,
- };
-
- /* If there isn't a scan actively going on in the hardware
- * then we are in between scan bands and not actually
- * actively scanning, so don't send the abort command */
- if (!test_bit(STATUS_SCAN_HW, &priv->status)) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return 0;
- }
-
- rc = iwl_send_cmd_sync(priv, &cmd);
- if (rc) {
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- return rc;
- }
-
- res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
- if (res->u.status != CAN_ABORT_STATUS) {
- /* The scan abort will return 1 for success or
- * 2 for "failure". A failure condition can be
- * due to simply not being in an active scan which
- * can occur if we send the scan abort before we
- * the microcode has notified us that a scan is
- * completed. */
- IWL_DEBUG_INFO("SCAN_ABORT returned %d.\n", res->u.status);
- clear_bit(STATUS_SCAN_ABORTING, &priv->status);
- clear_bit(STATUS_SCAN_HW, &priv->status);
- }
-
- dev_kfree_skb_any(cmd.meta.u.skb);
-
- return rc;
-}
-
static int iwl3945_add_sta_sync_callback(struct iwl_priv *priv,
struct iwl_cmd *cmd, struct sk_buff *skb)
{
@@ -1168,115 +1127,6 @@ static void iwl3945_unset_hw_params(struct iwl_priv *priv)
priv->shared_phys);
}

-/**
- * iwl3945_supported_rate_to_ie - fill in the supported rate in IE field
- *
- * return : set the bit for each supported rate insert in ie
- */
-static u16 iwl3945_supported_rate_to_ie(u8 *ie, u16 supported_rate,
- u16 basic_rate, int *left)
-{
- u16 ret_rates = 0, bit;
- int i;
- u8 *cnt = ie;
- u8 *rates = ie + 1;
-
- for (bit = 1, i = 0; i < IWL_RATE_COUNT; i++, bit <<= 1) {
- if (bit & supported_rate) {
- ret_rates |= bit;
- rates[*cnt] = iwl3945_rates[i].ieee |
- ((bit & basic_rate) ? 0x80 : 0x00);
- (*cnt)++;
- (*left)--;
- if ((*left <= 0) ||
- (*cnt >= IWL_SUPPORTED_RATES_IE_LEN))
- break;
- }
- }
-
- return ret_rates;
-}
-
-/**
- * iwl3945_fill_probe_req - fill in all required fields and IE for probe request
- */
-static u16 iwl3945_fill_probe_req(struct iwl_priv *priv,
- struct ieee80211_mgmt *frame,
- int left)
-{
- int len = 0;
- u8 *pos = NULL;
- u16 active_rates, ret_rates, cck_rates;
-
- /* Make sure there is enough space for the probe request,
- * two mandatory IEs and the data */
- left -= 24;
- if (left < 0)
- return 0;
- len += 24;
-
- frame->frame_control = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- memcpy(frame->da, iwl_bcast_addr, ETH_ALEN);
- memcpy(frame->sa, priv->mac_addr, ETH_ALEN);
- memcpy(frame->bssid, iwl_bcast_addr, ETH_ALEN);
- frame->seq_ctrl = 0;
-
- /* fill in our indirect SSID IE */
- /* ...next IE... */
-
- left -= 2;
- if (left < 0)
- return 0;
- len += 2;
- pos = &(frame->u.probe_req.variable[0]);
- *pos++ = WLAN_EID_SSID;
- *pos++ = 0;
-
- /* fill in supported rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
-
- /* ... fill it in... */
- *pos++ = WLAN_EID_SUPP_RATES;
- *pos = 0;
-
- priv->active_rate = priv->rates_mask;
- active_rates = priv->active_rate;
- priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
-
- cck_rates = IWL_CCK_RATES_MASK & active_rates;
- ret_rates = iwl3945_supported_rate_to_ie(pos, cck_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- ret_rates = iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- active_rates &= ~ret_rates;
-
- len += 2 + *pos;
- pos += (*pos) + 1;
- if (active_rates == 0)
- goto fill_end;
-
- /* fill in supported extended rate */
- /* ...next IE... */
- left -= 2;
- if (left < 0)
- return 0;
- /* ... fill it in... */
- *pos++ = WLAN_EID_EXT_SUPP_RATES;
- *pos = 0;
- iwl3945_supported_rate_to_ie(pos, active_rates,
- priv->active_rate_basic, &left);
- if (*pos > 0)
- len += 2 + *pos;
-
- fill_end:
- return (u16)len;
-}
-
/*
* QoS support
*/
@@ -3955,66 +3805,6 @@ static void iwl3945_free_channel_map(struct iwl_priv *priv)
priv->channel_count = 0;
}

-/* For active scan, listen ACTIVE_DWELL_TIME (msec) on each channel after
- * sending probe req. This should be set long enough to hear probe responses
- * from more than one AP. */
-#define IWL_ACTIVE_DWELL_TIME_24 (30) /* all times in msec */
-#define IWL_ACTIVE_DWELL_TIME_52 (20)
-
-#define IWL_ACTIVE_DWELL_FACTOR_24GHZ (3)
-#define IWL_ACTIVE_DWELL_FACTOR_52GHZ (2)
-
-/* For faster active scanning, scan will move to the next channel if fewer than
- * PLCP_QUIET_THRESH packets are heard on this channel within
- * ACTIVE_QUIET_TIME after sending probe request. This shortens the dwell
- * time if it's a quiet channel (nothing responded to our probe, and there's
- * no other traffic).
- * Disable "quiet" feature by setting PLCP_QUIET_THRESH to 0. */
-#define IWL_PLCP_QUIET_THRESH __constant_cpu_to_le16(1) /* packets */
-#define IWL_ACTIVE_QUIET_TIME __constant_cpu_to_le16(10) /* msec */
-
-/* For passive scan, listen PASSIVE_DWELL_TIME (msec) on each channel.
- * Must be set longer than active dwell time.
- * For the most reliable scan, set > AP beacon interval (typically 100msec). */
-#define IWL_PASSIVE_DWELL_TIME_24 (20) /* all times in msec */
-#define IWL_PASSIVE_DWELL_TIME_52 (10)
-#define IWL_PASSIVE_DWELL_BASE (100)
-#define IWL_CHANNEL_TUNE_TIME 5
-
-#define IWL_SCAN_PROBE_MASK(n) (BIT(n) | (BIT(n) - BIT(1)))
-
-static inline u16 iwl3945_get_active_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band,
- u8 n_probes)
-{
- if (band == IEEE80211_BAND_5GHZ)
- return IWL_ACTIVE_DWELL_TIME_52 +
- IWL_ACTIVE_DWELL_FACTOR_52GHZ * (n_probes + 1);
- else
- return IWL_ACTIVE_DWELL_TIME_24 +
- IWL_ACTIVE_DWELL_FACTOR_24GHZ * (n_probes + 1);
-}
-
-static u16 iwl3945_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
-{
- u16 passive = (band == IEEE80211_BAND_2GHZ) ?
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
- IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
-
- if (iwl3945_is_associated(priv)) {
- /* If we're associated, we clamp the maximum passive
- * dwell time to be 98% of the beacon interval (minus
- * 2 * channel tune time) */
- passive = priv->beacon_int;
- if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
- passive = IWL_PASSIVE_DWELL_BASE;
- passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
- }
-
- return passive;
-}
-
static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
@@ -4033,8 +3823,8 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,

channels = sband->channels;

- active_dwell = iwl3945_get_active_dwell_time(priv, band, n_probes);
- passive_dwell = iwl3945_get_passive_dwell_time(priv, band);
+ active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band);

if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
@@ -5135,28 +4925,6 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
}

#define IWL_SCAN_CHECK_WATCHDOG (7 * HZ)
-
-static void iwl3945_bg_scan_check(struct work_struct *data)
-{
- struct iwl_priv *priv =
- container_of(data, struct iwl_priv, scan_check.work);
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- mutex_lock(&priv->mutex);
- if (test_bit(STATUS_SCANNING, &priv->status) ||
- test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
- "Scan completion watchdog resetting adapter (%dms)\n",
- jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
-
- if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
- iwl3945_send_scan_abort(priv);
- }
- mutex_unlock(&priv->mutex);
-}
-
static void iwl3945_bg_request_scan(struct work_struct *data)
{
struct iwl_priv *priv =
@@ -5284,9 +5052,6 @@ static void iwl3945_bg_request_scan(struct work_struct *data)

/* We don't build a direct scan probe request; the uCode will do
* that based on the direct_mask added to each channel entry */
- scan->tx_cmd.len = cpu_to_le16(
- iwl3945_fill_probe_req(priv, (struct ieee80211_mgmt *)scan->data,
- IWL_MAX_SCAN_SIZE - sizeof(*scan)));
scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id;
scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
@@ -5307,6 +5072,11 @@ static void iwl3945_bg_request_scan(struct work_struct *data)
goto done;
}

+ scan->tx_cmd.len = cpu_to_le16(
+ iwl_fill_probe_req(priv, band,
+ (struct ieee80211_mgmt *)scan->data,
+ IWL_MAX_SCAN_SIZE - sizeof(*scan)));
+
/* select Rx antennas */
scan->flags |= iwl3945_get_antenna_flags(priv);

@@ -5482,45 +5252,8 @@ static void iwl3945_post_associate(struct iwl_priv *priv)
priv->next_scan_jiffies = jiffies + IWL_DELAY_NEXT_SCAN;
}

-static void iwl3945_bg_abort_scan(struct work_struct *work)
-{
- struct iwl_priv *priv = container_of(work, struct iwl_priv, abort_scan);
-
- if (!iwl_is_ready(priv))
- return;
-
- mutex_lock(&priv->mutex);
-
- set_bit(STATUS_SCAN_ABORTING, &priv->status);
- iwl3945_send_scan_abort(priv);
-
- mutex_unlock(&priv->mutex);
-}
-
static int iwl3945_mac_config(struct ieee80211_hw *hw, u32 changed);

-static void iwl3945_bg_scan_completed(struct work_struct *work)
-{
- struct iwl_priv *priv =
- container_of(work, struct iwl_priv, scan_completed);
-
- IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN, "SCAN complete scan\n");
-
- if (test_bit(STATUS_EXIT_PENDING, &priv->status))
- return;
-
- if (test_bit(STATUS_CONF_PENDING, &priv->status))
- iwl3945_mac_config(priv->hw, 0);
-
- ieee80211_scan_completed(priv->hw);
-
- /* Since setting the TXPOWER may have been deferred while
- * performing the scan, fire one off */
- mutex_lock(&priv->mutex);
- priv->cfg->ops->lib->send_tx_power(priv);
- mutex_unlock(&priv->mutex);
-}
-
/*****************************************************************************
*
* mac80211 entry point functions
@@ -6821,15 +6554,15 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
INIT_WORK(&priv->up, iwl3945_bg_up);
INIT_WORK(&priv->restart, iwl3945_bg_restart);
INIT_WORK(&priv->rx_replenish, iwl3945_bg_rx_replenish);
- INIT_WORK(&priv->scan_completed, iwl3945_bg_scan_completed);
- INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
- INIT_WORK(&priv->abort_scan, iwl3945_bg_abort_scan);
INIT_WORK(&priv->rf_kill, iwl_bg_rf_kill);
INIT_WORK(&priv->beacon_update, iwl3945_bg_beacon_update);
INIT_DELAYED_WORK(&priv->init_alive_start, iwl3945_bg_init_alive_start);
INIT_DELAYED_WORK(&priv->alive_start, iwl3945_bg_alive_start);
- INIT_DELAYED_WORK(&priv->scan_check, iwl3945_bg_scan_check);
INIT_DELAYED_WORK(&priv->rfkill_poll, iwl3945_rfkill_poll);
+ INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
+ INIT_WORK(&priv->request_scan, iwl3945_bg_request_scan);
+ INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);

iwl3945_hw_setup_deferred_work(priv);

--
1.5.4.3


2009-01-23 21:42:53

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 09/15] iwlwifi: Remove IWL3945_DEBUG

From: Samuel Ortiz <[email protected]>

IWL3945_DEBUG is pointless and obsolete. We already have an IWLWIFI_DEBUG
symbol, that needs to be set if we actually want to get 3945 debug (see
iwl-debug.h).
Thus, we can simply get rid of this symbol.

Signed-off-by: Samuel Ortiz <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/Kconfig | 29 +-------------------------
drivers/net/wireless/iwlwifi/iwl-3945.c | 22 ++++++++++++-------
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 30 +++++++++++++-------------
4 files changed, 31 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index f38130a..7b3bad1 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -20,7 +20,7 @@ config IWLWIFI_RFKILL
depends on IWLCORE

config IWLWIFI_DEBUG
- bool "Enable full debugging output in iwlagn driver"
+ bool "Enable full debugging output in iwlagn and iwl3945 drivers"
depends on IWLCORE
---help---
This option will enable debug tracing output for the iwlwifi drivers
@@ -144,30 +144,3 @@ config IWL3945_LEDS
depends on IWL3945
---help---
This option enables LEDS for the iwl3945 driver.
-
-config IWL3945_DEBUG
- bool "Enable full debugging output in iwl3945 driver"
- depends on IWL3945
- ---help---
- This option will enable debug tracing output for the iwl3945
- driver.
-
- This will result in the kernel module being ~100k larger. You can
- control which debug output is sent to the kernel log by setting the
- value in
-
- /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- This entry will only exist if this option is enabled.
-
- To set a value, simply echo an 8-byte hex value to the same file:
-
- % echo 0x43fff > /sys/bus/pci/drivers/${DRIVER}/debug_level
-
- You can find the list of debug mask values in:
- drivers/net/wireless/iwlwifi/iwl-3945-debug.h
-
- If this is your first time using this driver, you should say Y here
- as the debug information can assist others in helping you resolve
- any problems you may encounter.
-
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 75e9553..b9c5cf9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -232,7 +232,7 @@ __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv)
return 0; /* "diversity" is default if error */
}

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define TX_STATUS_ENTRY(x) case TX_STATUS_FAIL_ ## x: return #x

static const char *iwl3945_get_tx_fail_reason(u32 status)
@@ -412,7 +412,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *r
* Misc. internal state and helper functions
*
******************************************************************************/
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG

/**
* iwl3945_report_frame - dump frame to syslog during debug sessions
@@ -421,7 +421,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv, struct iwl_rx_mem_buffer *r
* including selective frame dumps.
* group100 parameter selects whether to show 1 out of 100 good frames.
*/
-static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
struct iwl_rx_packet *pkt,
struct ieee80211_hdr *header, int group100)
{
@@ -548,6 +548,15 @@ static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
if (print_dump)
iwl_print_hex_dump(priv, IWL_DL_RX, data, length);
}
+
+static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt,
+ struct ieee80211_hdr *header, int group100)
+{
+ if (priv->debug_level & IWL_DL_RX)
+ _iwl3945_dbg_report_frame(priv, pkt, header, group100);
+}
+
#else
static inline void iwl3945_dbg_report_frame(struct iwl_priv *priv,
struct iwl_rx_packet *pkt,
@@ -711,11 +720,8 @@ static void iwl3945_rx_reply_rx(struct iwl_priv *priv,
rx_status.signal, rx_status.signal,
rx_status.noise, rx_status.rate_idx);

-#ifdef CONFIG_IWL3945_DEBUG
- if (priv->debug_level & (IWL_DL_RX))
- /* Set "1" to report good data frames in groups of 100 */
- iwl3945_dbg_report_frame(priv, pkt, header, 1);
-#endif
+ /* Set "1" to report good data frames in groups of 100 */
+ iwl3945_dbg_report_frame(priv, pkt, header, 1);

if (network_packet) {
priv->last_beacon_time = le32_to_cpu(rx_end->beacon_timestamp);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d4e0778..5dbab76 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1059,7 +1059,7 @@ struct iwl_priv {
s8 tx_power_channel_lmt;


-#if defined(CONFIG_IWLWIFI_DEBUG) || defined(CONFIG_IWL3945_DEBUG)
+#ifdef CONFIG_IWLWIFI_DEBUG
/* debugging info */
u32 debug_level;
u32 framecnt_to_us;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 5fa5cb2..d832cb9 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -63,7 +63,7 @@
#define DRV_DESCRIPTION \
"Intel(R) PRO/Wireless 3945ABG/BG Network Connection driver for Linux"

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
#define VD "d"
#else
#define VD
@@ -1503,7 +1503,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)

fc = hdr->frame_control;

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (ieee80211_is_auth(fc))
IWL_DEBUG_TX("Sending AUTH frame\n");
else if (ieee80211_is_assoc_req(fc))
@@ -2045,7 +2045,7 @@ static void iwl3945_rx_spectrum_measure_notif(struct iwl_priv *priv,
static void iwl3945_rx_pm_sleep_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl_sleep_notification *sleep = &(pkt->u.sleep_notif);
IWL_DEBUG_RX("sleep mode: %d, src: %d\n",
@@ -2092,7 +2092,7 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl3945_beacon_notif *beacon = &(pkt->u.beacon_status);
u8 rate = beacon->beacon_notify_hdr.rate;
@@ -2115,7 +2115,7 @@ static void iwl3945_rx_beacon_notif(struct iwl_priv *priv,
static void iwl3945_rx_reply_scan(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
struct iwl_rx_packet *pkt = (void *)rxb->skb->data;
struct iwl_scanreq_notification *notif =
(struct iwl_scanreq_notification *)pkt->u.raw;
@@ -2788,7 +2788,7 @@ static void iwl3945_rx_handle(struct iwl_priv *priv)
iwl3945_rx_queue_restock(priv);
}

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
static void iwl3945_print_rx_config_cmd(struct iwl_priv *priv,
struct iwl3945_rxon_cmd *rxon)
{
@@ -3028,7 +3028,7 @@ static void iwl3945_irq_handle_error(struct iwl_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & IWL_DL_FW_ERRORS) {
iwl3945_dump_nic_error_log(priv);
iwl3945_dump_nic_event_log(priv);
@@ -3077,7 +3077,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
u32 inta, handled = 0;
u32 inta_fh;
unsigned long flags;
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
u32 inta_mask;
#endif

@@ -3095,7 +3095,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & IWL_DL_ISR) {
/* just for debug */
inta_mask = iwl_read32(priv, CSR_INT_MASK);
@@ -3129,7 +3129,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
return;
}

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
/* NIC fires this, but we don't use it, redundant with WAKEUP */
if (inta & CSR_INT_BIT_SCD)
@@ -3200,7 +3200,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
if (test_bit(STATUS_INT_ENABLED, &priv->status))
iwl3945_enable_interrupts(priv);

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
if (priv->debug_level & (IWL_DL_ISR)) {
inta = iwl_read32(priv, CSR_INT);
inta_mask = iwl_read32(priv, CSR_INT_MASK);
@@ -5414,7 +5414,7 @@ static int iwl3945_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *sk
*
*****************************************************************************/

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG

/*
* The following adds a new attribute to the sysfs representation
@@ -5450,7 +5450,7 @@ static ssize_t store_debug_level(struct device *d,
static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
show_debug_level, store_debug_level);

-#endif /* CONFIG_IWL3945_DEBUG */
+#endif /* CONFIG_IWLWIFI_DEBUG */

static ssize_t show_temperature(struct device *d,
struct device_attribute *attr, char *buf)
@@ -5930,7 +5930,7 @@ static struct attribute *iwl3945_sysfs_entries[] = {
&dev_attr_status.attr,
&dev_attr_temperature.attr,
&dev_attr_tx_power.attr,
-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
&dev_attr_debug_level.attr,
#endif
NULL
@@ -6082,7 +6082,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
priv->cfg = cfg;
priv->pci_dev = pdev;

-#ifdef CONFIG_IWL3945_DEBUG
+#ifdef CONFIG_IWLWIFI_DEBUG
priv->debug_level = iwl3945_mod_params.debug;
atomic_set(&priv->restrict_refcnt, 0);
#endif
--
1.5.4.3