2010-05-10 22:28:21

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 00/47] iwlwifi updates for 2.6.35

First off, I apologize for the size of this submission. We do our best to
avoid large submissions such as this, unfortunately a few things worked
against us during this round. Actually, in addition to this, we had something
working for us too in the form of a very active developer.

As our previous submission I again merged wireless-2.6 into
wireless-next-2.6. This is because our single wireless-2.6 patch will cause
merge conflict when it is applied to wireless-next-2.6 and there is a
particular way we prefer this conflict be handled.

In this series we add support for plcp error checking to 3945. This
introduced the usage of RF reset to 3945 and thus requires the scan races
to be fixed for it also. The station management code keeps receiving
updates and fixes after it has been converted to use the mac80211
callbacks. We introduce support for a new firmware file format that
utilizes TLVs. More changes are made to driver where it was doing something
unnecessarily due to mac80211 already doing it or using information from
mac80211 more effectively. We continue to add recognition and support for a
new series of hardware "6000 series Gen2". A significant portion of this
series include code cleanup, which, for example, reduce the times decisions
are made based on hardcoded device type instead relying on a generic
configuration.

These patches are also available from wireless-next-2.6 branch on
git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git

Abhijeet Kolekar (2):
iwl3945: fix scan races
iwl3945: add plcp error checking

Johannes Berg (31):
iwlwifi: use vif iwl_bss_info_changed
iwl3945: use iwl3945_add_bcast_station
iwlwifi: pass address to iwl_remove_station
iwlwifi: manage IBSS station properly
iwlagn: show and store firmware build number
iwl3945: remove ucode access indirection
iwlwifi: remove ucode virtual functions
iwlwifi: move eeprom version printout to eeprom init
iwlagn: prepare for new firmware file format
iwlagn: implement loading a new firmware file type
iwlwifi: remove rts_threshold
iwlagn: move iwl_get_ra_sta_id to 4965
iwlagn: use vif->type to check station
iwlwifi: apply filter flags directly
iwlwifi: push virtual interface through
iwlagn: use virtual interface in TX aggregation handling
iwlwifi: remove useless priv->vif check
iwlwifi: use vif in iwl_ht_conf
iwlwifi: note that priv->bssid is used only by 3945
iwlwifi: fix iwl_sta_init_lq station ID
iwlwifi: split allocation/sending local station LQ
iwlwifi: rework broadcast station management
iwlwifi: track station IDs
iwlwifi: add iwl_sta_id()
iwlwifi: use iwl_find_station less
iwlagn: use iwl_sta_id() for aggregation
iwlwifi: use iwl_sta_id() for TKIP key update
iwlwifi: move iwl_find_station() to 4965
iwlwifi: rename iwl_add_local_station
iwlwifi: remove pointless HT check
iwlwifi: clear driver stations when going down

Reinette Chatre (2):
iwlwifi: make bcast LQ command available for later restore actions
iwlagn: work around rate scaling reset delay

Shanyu Zhao (2):
iwlwifi: rename 6000 series Gen2 devices to Gen2a
iwlwifi: dump firmware build info in error case

Wey-Yi Guy (10):
iwlwifi: remove powersave debugfs if it is not supported
iwlwifi: rename "tx_power" to "chain_tx_power"
iwlwifi: remove device type checking for tx power in debugfs
iwlwifi: use .cfg to enable/disable continuous ucode trace
iwlwifi: use cfg to configure calibration operation
iwlwifi: give correct return information for tx power debugfs
iwlwifi: wimax co-exist code clean up
iwlwifi: checking for all the possible failure cases
iwlwifi: "tx power per chain" are part of ucode_tx_stats
iwlwifi: provide more comments for cfg structure

drivers/net/wireless/iwlwifi/iwl-1000.c | 9 +-
drivers/net/wireless/iwlwifi/iwl-3945.c | 147 +++++--
drivers/net/wireless/iwlwifi/iwl-3945.h | 22 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 100 +++--
drivers/net/wireless/iwlwifi/iwl-5000.c | 27 +-
drivers/net/wireless/iwlwifi/iwl-6000.c | 51 ++-
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 16 +
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 31 +-
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 29 +-
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 109 +++---
drivers/net/wireless/iwlwifi/iwl-agn.c | 550 ++++++++++++++++--------
drivers/net/wireless/iwlwifi/iwl-agn.h | 14 +-
drivers/net/wireless/iwlwifi/iwl-commands.h | 6 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 199 +++------
drivers/net/wireless/iwlwifi/iwl-core.h | 60 ++--
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 66 +---
drivers/net/wireless/iwlwifi/iwl-dev.h | 87 ++++-
drivers/net/wireless/iwlwifi/iwl-eeprom.c | 7 +
drivers/net/wireless/iwlwifi/iwl-power.c | 5 +-
drivers/net/wireless/iwlwifi/iwl-rx.c | 9 +-
drivers/net/wireless/iwlwifi/iwl-scan.c | 16 +-
drivers/net/wireless/iwlwifi/iwl-sta.c | 456 +++++++++-----------
drivers/net/wireless/iwlwifi/iwl-sta.h | 60 ++-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 163 ++++---
24 files changed, 1300 insertions(+), 939 deletions(-)



2010-05-10 22:28:32

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 33/47] iwlwifi: fix iwl_sta_init_lq station ID

From: Johannes Berg <[email protected]>

The "is_ap" argument to iwl_sta_init_lq is never true,
so it and the corresponding code can be removed. However,
it needs to have the station ID because it is also used
for the IBSS BSSID station, and that doesn't have the
broadcast ID.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-sta.c | 11 ++++-------
1 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 0db742c..dd1c639 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -408,7 +408,7 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
EXPORT_SYMBOL(iwl_add_station_common);

static struct iwl_link_quality_cmd *iwl_sta_init_lq(struct iwl_priv *priv,
- const u8 *addr, bool is_ap)
+ u8 sta_id)
{
int i, r;
struct iwl_link_quality_cmd *link_cmd;
@@ -422,9 +422,7 @@ static struct iwl_link_quality_cmd *iwl_sta_init_lq(struct iwl_priv *priv,
}
/* Set up the rate scaling to start at selected rate, fall back
* all the way down to 1M in IEEE order, and then spin on 1M */
- if (is_ap)
- r = IWL_RATE_54M_INDEX;
- else if (priv->band == IEEE80211_BAND_5GHZ)
+ if (priv->band == IEEE80211_BAND_5GHZ)
r = IWL_RATE_6M_INDEX;
else
r = IWL_RATE_1M_INDEX;
@@ -459,8 +457,7 @@ static struct iwl_link_quality_cmd *iwl_sta_init_lq(struct iwl_priv *priv,
link_cmd->agg_params.agg_time_limit =
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);

- /* Update the rate scaling for control frame Tx to AP */
- link_cmd->sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
+ link_cmd->sta_id = sta_id;

ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true);
if (ret)
@@ -496,7 +493,7 @@ int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)

if (init_rs) {
/* Set up default rate scaling table in device's station table */
- link_cmd = iwl_sta_init_lq(priv, addr, false);
+ link_cmd = iwl_sta_init_lq(priv, sta_id);
if (!link_cmd) {
IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
addr);
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 34/47] iwlwifi: split allocation/sending local station LQ

From: Johannes Berg <[email protected]>

Rename iwl_sta_init_lq to iwl_sta_alloc_lq and
move sending it out into the caller.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-sta.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index dd1c639..5bf82b9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -407,13 +407,12 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
}
EXPORT_SYMBOL(iwl_add_station_common);

-static struct iwl_link_quality_cmd *iwl_sta_init_lq(struct iwl_priv *priv,
- u8 sta_id)
+static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
+ u8 sta_id)
{
int i, r;
struct iwl_link_quality_cmd *link_cmd;
u32 rate_flags;
- int ret = 0;

link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
if (!link_cmd) {
@@ -459,10 +458,6 @@ static struct iwl_link_quality_cmd *iwl_sta_init_lq(struct iwl_priv *priv,

link_cmd->sta_id = sta_id;

- ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true);
- if (ret)
- IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
-
return link_cmd;
}

@@ -493,12 +488,17 @@ int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)

if (init_rs) {
/* Set up default rate scaling table in device's station table */
- link_cmd = iwl_sta_init_lq(priv, sta_id);
+ link_cmd = iwl_sta_alloc_lq(priv, sta_id);
if (!link_cmd) {
IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
addr);
return -ENOMEM;
}
+
+ ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true);
+ if (ret)
+ IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
+
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].lq = link_cmd;
spin_unlock_irqrestore(&priv->sta_lock, flags);
--
1.6.3.3


2010-05-10 22:28:24

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 10/47] iwlwifi: wimax co-exist code clean up

From: Wey-Yi Guy <[email protected]>

wifi/wimax co-exist command is part of _agn device configuration
sequence; move it to iwl-agn-ucode.c which is more appropriate place for the
function.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 60 +++++++++++++++++++++++++-
drivers/net/wireless/iwlwifi/iwl-core.c | 59 -------------------------
drivers/net/wireless/iwlwifi/iwl-core.h | 1 -
3 files changed, 59 insertions(+), 61 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index ae476c2..c3e3283 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -52,6 +52,37 @@ static const s8 iwlagn_default_queue_to_tx_fifo[] = {
IWL_TX_FIFO_UNUSED,
};

+static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
+ {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
+ 0, COEX_UNASSOC_IDLE_FLAGS},
+ {COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
+ 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
+ {COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
+ 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
+ {COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
+ 0, COEX_CALIBRATION_FLAGS},
+ {COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
+ 0, COEX_PERIODIC_CALIBRATION_FLAGS},
+ {COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
+ 0, COEX_CONNECTION_ESTAB_FLAGS},
+ {COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
+ 0, COEX_ASSOCIATED_IDLE_FLAGS},
+ {COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
+ 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
+ {COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
+ 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
+ {COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
+ 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
+ {COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
+ {COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
+ {COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
+ 0, COEX_STAND_ALONE_DEBUG_FLAGS},
+ {COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
+ 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
+ {COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
+ {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
+};
+
/*
* ucode
*/
@@ -320,6 +351,33 @@ restart:
queue_work(priv->workqueue, &priv->restart);
}

+static int iwlagn_send_wimax_coex(struct iwl_priv *priv)
+{
+ struct iwl_wimax_coex_cmd coex_cmd;
+
+ if (priv->cfg->support_wimax_coexist) {
+ /* UnMask wake up src at associated sleep */
+ coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
+
+ /* UnMask wake up src at unassociated sleep */
+ coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
+ memcpy(coex_cmd.sta_prio, cu_priorities,
+ sizeof(struct iwl_wimax_coex_event_entry) *
+ COEX_NUM_OF_EVENTS);
+
+ /* enabling the coexistence feature */
+ coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
+
+ /* enabling the priorities tables */
+ coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
+ } else {
+ /* coexistence is disabled */
+ memset(&coex_cmd, 0, sizeof(coex_cmd));
+ }
+ return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
+ sizeof(coex_cmd), &coex_cmd);
+}
+
int iwlagn_alive_notify(struct iwl_priv *priv)
{
u32 a;
@@ -407,7 +465,7 @@ int iwlagn_alive_notify(struct iwl_priv *priv)

spin_unlock_irqrestore(&priv->lock, flags);

- iwl_send_wimax_coex(priv);
+ iwlagn_send_wimax_coex(priv);

iwlagn_set_Xtal_calib(priv);
iwl_send_calib_results(priv);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d8ee528..0c3b984 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -67,37 +67,6 @@ static bool bt_coex_active = true;
module_param(bt_coex_active, bool, S_IRUGO);
MODULE_PARM_DESC(bt_coex_active, "enable wifi/bluetooth co-exist");

-static struct iwl_wimax_coex_event_entry cu_priorities[COEX_NUM_OF_EVENTS] = {
- {COEX_CU_UNASSOC_IDLE_RP, COEX_CU_UNASSOC_IDLE_WP,
- 0, COEX_UNASSOC_IDLE_FLAGS},
- {COEX_CU_UNASSOC_MANUAL_SCAN_RP, COEX_CU_UNASSOC_MANUAL_SCAN_WP,
- 0, COEX_UNASSOC_MANUAL_SCAN_FLAGS},
- {COEX_CU_UNASSOC_AUTO_SCAN_RP, COEX_CU_UNASSOC_AUTO_SCAN_WP,
- 0, COEX_UNASSOC_AUTO_SCAN_FLAGS},
- {COEX_CU_CALIBRATION_RP, COEX_CU_CALIBRATION_WP,
- 0, COEX_CALIBRATION_FLAGS},
- {COEX_CU_PERIODIC_CALIBRATION_RP, COEX_CU_PERIODIC_CALIBRATION_WP,
- 0, COEX_PERIODIC_CALIBRATION_FLAGS},
- {COEX_CU_CONNECTION_ESTAB_RP, COEX_CU_CONNECTION_ESTAB_WP,
- 0, COEX_CONNECTION_ESTAB_FLAGS},
- {COEX_CU_ASSOCIATED_IDLE_RP, COEX_CU_ASSOCIATED_IDLE_WP,
- 0, COEX_ASSOCIATED_IDLE_FLAGS},
- {COEX_CU_ASSOC_MANUAL_SCAN_RP, COEX_CU_ASSOC_MANUAL_SCAN_WP,
- 0, COEX_ASSOC_MANUAL_SCAN_FLAGS},
- {COEX_CU_ASSOC_AUTO_SCAN_RP, COEX_CU_ASSOC_AUTO_SCAN_WP,
- 0, COEX_ASSOC_AUTO_SCAN_FLAGS},
- {COEX_CU_ASSOC_ACTIVE_LEVEL_RP, COEX_CU_ASSOC_ACTIVE_LEVEL_WP,
- 0, COEX_ASSOC_ACTIVE_LEVEL_FLAGS},
- {COEX_CU_RF_ON_RP, COEX_CU_RF_ON_WP, 0, COEX_CU_RF_ON_FLAGS},
- {COEX_CU_RF_OFF_RP, COEX_CU_RF_OFF_WP, 0, COEX_RF_OFF_FLAGS},
- {COEX_CU_STAND_ALONE_DEBUG_RP, COEX_CU_STAND_ALONE_DEBUG_WP,
- 0, COEX_STAND_ALONE_DEBUG_FLAGS},
- {COEX_CU_IPAN_ASSOC_LEVEL_RP, COEX_CU_IPAN_ASSOC_LEVEL_WP,
- 0, COEX_IPAN_ASSOC_LEVEL_FLAGS},
- {COEX_CU_RSRVD1_RP, COEX_CU_RSRVD1_WP, 0, COEX_RSRVD1_FLAGS},
- {COEX_CU_RSRVD2_RP, COEX_CU_RSRVD2_WP, 0, COEX_RSRVD2_FLAGS}
-};
-
#define IWL_DECLARE_RATE_INFO(r, s, ip, in, rp, rn, pp, np) \
[IWL_RATE_##r##M_INDEX] = { IWL_RATE_##r##M_PLCP, \
IWL_RATE_SISO_##s##M_PLCP, \
@@ -2340,34 +2309,6 @@ void iwl_free_txq_mem(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_free_txq_mem);

-int iwl_send_wimax_coex(struct iwl_priv *priv)
-{
- struct iwl_wimax_coex_cmd coex_cmd;
-
- if (priv->cfg->support_wimax_coexist) {
- /* UnMask wake up src at associated sleep */
- coex_cmd.flags = COEX_FLAGS_ASSOC_WA_UNMASK_MSK;
-
- /* UnMask wake up src at unassociated sleep */
- coex_cmd.flags |= COEX_FLAGS_UNASSOC_WA_UNMASK_MSK;
- memcpy(coex_cmd.sta_prio, cu_priorities,
- sizeof(struct iwl_wimax_coex_event_entry) *
- COEX_NUM_OF_EVENTS);
-
- /* enabling the coexistence feature */
- coex_cmd.flags |= COEX_FLAGS_COEX_ENABLE_MSK;
-
- /* enabling the priorities tables */
- coex_cmd.flags |= COEX_FLAGS_STA_TABLE_VALID_MSK;
- } else {
- /* coexistence is disabled */
- memset(&coex_cmd, 0, sizeof(coex_cmd));
- }
- return iwl_send_cmd_pdu(priv, COEX_PRIORITY_TABLE_CMD,
- sizeof(coex_cmd), &coex_cmd);
-}
-EXPORT_SYMBOL(iwl_send_wimax_coex);
-
#ifdef CONFIG_IWLWIFI_DEBUGFS

#define IWL_TRAFFIC_DUMP_SIZE (IWL_TRAFFIC_ENTRY_SIZE * IWL_TRAFFIC_ENTRIES)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 88c6412..f66c1c1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -373,7 +373,6 @@ int iwl_alloc_txq_mem(struct iwl_priv *priv);
void iwl_free_txq_mem(struct iwl_priv *priv);
void iwlcore_rts_tx_cmd_flag(struct ieee80211_tx_info *info,
__le32 *tx_flags);
-int iwl_send_wimax_coex(struct iwl_priv *priv);
#ifdef CONFIG_IWLWIFI_DEBUGFS
int iwl_alloc_traffic_mem(struct iwl_priv *priv);
void iwl_free_traffic_mem(struct iwl_priv *priv);
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 13/47] iwlwifi: make bcast LQ command available for later restore actions

From: Reinette Chatre <[email protected]>

When adding the broadcast station the link quality command is
generated on demand, sent to device, and disappears. It is thus not
available for later cases when we need to restore stations and need
to send the link quality command afterwards. Now, when first adding the
broadcast station, also generate its link quality command to always be
available for later restoring.

Also fix an issue when adding local stations where the "in progress" state
is never cleared.

Reported-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 4 +-
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-sta.c | 91 ++++++++++++++++++++++---------
drivers/net/wireless/iwlwifi/iwl-sta.h | 7 ++-
4 files changed, 75 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d609414..e8c9bca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2042,7 +2042,9 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
goto out_err;

/* Add the broadcast address so we can send broadcast frames */
- priv->cfg->ops->lib->add_bcast_station(priv);
+ err = priv->cfg->ops->lib->add_bcast_station(priv);
+ if (err)
+ goto out_err;

goto out;

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index f66c1c1..8d53fc9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -201,7 +201,7 @@ struct iwl_lib_ops {
/* temperature */
struct iwl_temp_ops temp_ops;
/* station management */
- void (*add_bcast_station)(struct iwl_priv *priv);
+ int (*add_bcast_station)(struct iwl_priv *priv);
/* recover from tx queue stall */
void (*recover_from_tx_stall)(unsigned long data);
/* check for plcp health */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index db93447..5c6b326 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -418,15 +418,19 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
}
EXPORT_SYMBOL(iwl_add_station_common);

-static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
+static struct iwl_link_quality_cmd *iwl_sta_init_lq(struct iwl_priv *priv,
+ const u8 *addr, bool is_ap)
{
int i, r;
- struct iwl_link_quality_cmd link_cmd = {
- .reserved1 = 0,
- };
+ struct iwl_link_quality_cmd *link_cmd;
u32 rate_flags;
int ret = 0;

+ link_cmd = kzalloc(sizeof(struct iwl_link_quality_cmd), GFP_KERNEL);
+ if (!link_cmd) {
+ IWL_ERR(priv, "Unable to allocate memory for LQ cmd.\n");
+ return NULL;
+ }
/* Set up the rate scaling to start at selected rate, fall back
* all the way down to 1M in IEEE order, and then spin on 1M */
if (is_ap)
@@ -444,35 +448,36 @@ static void iwl_sta_init_lq(struct iwl_priv *priv, const u8 *addr, bool is_ap)
rate_flags |= first_antenna(priv->hw_params.valid_tx_ant) <<
RATE_MCS_ANT_POS;

- link_cmd.rs_table[i].rate_n_flags =
+ link_cmd->rs_table[i].rate_n_flags =
iwl_hw_set_rate_n_flags(iwl_rates[r].plcp, rate_flags);
r = iwl_get_prev_ieee_rate(r);
}

- link_cmd.general_params.single_stream_ant_msk =
+ link_cmd->general_params.single_stream_ant_msk =
first_antenna(priv->hw_params.valid_tx_ant);

- link_cmd.general_params.dual_stream_ant_msk =
+ link_cmd->general_params.dual_stream_ant_msk =
priv->hw_params.valid_tx_ant &
~first_antenna(priv->hw_params.valid_tx_ant);
- if (!link_cmd.general_params.dual_stream_ant_msk) {
- link_cmd.general_params.dual_stream_ant_msk = ANT_AB;
+ if (!link_cmd->general_params.dual_stream_ant_msk) {
+ link_cmd->general_params.dual_stream_ant_msk = ANT_AB;
} else if (num_of_ant(priv->hw_params.valid_tx_ant) == 2) {
- link_cmd.general_params.dual_stream_ant_msk =
+ link_cmd->general_params.dual_stream_ant_msk =
priv->hw_params.valid_tx_ant;
}

- link_cmd.agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
- link_cmd.agg_params.agg_time_limit =
+ link_cmd->agg_params.agg_dis_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
+ link_cmd->agg_params.agg_time_limit =
cpu_to_le16(LINK_QUAL_AGG_TIME_LIMIT_DEF);

/* Update the rate scaling for control frame Tx to AP */
- link_cmd.sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;
+ link_cmd->sta_id = is_ap ? IWL_AP_ID : priv->hw_params.bcast_sta_id;

- ret = iwl_send_cmd_pdu(priv, REPLY_TX_LINK_QUALITY_CMD,
- sizeof(link_cmd), &link_cmd);
+ ret = iwl_send_lq_cmd(priv, link_cmd, CMD_SYNC, true);
if (ret)
- IWL_ERR(priv, "REPLY_TX_LINK_QUALITY_CMD failed (%d)\n", ret);
+ IWL_ERR(priv, "Link quality command failed (%d)\n", ret);
+
+ return link_cmd;
}

/*
@@ -487,6 +492,8 @@ int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)
{
int ret;
u8 sta_id;
+ struct iwl_link_quality_cmd *link_cmd;
+ unsigned long flags;

ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
if (ret) {
@@ -494,9 +501,23 @@ int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)
return ret;
}

- if (init_rs)
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].used |= IWL_STA_LOCAL;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ if (init_rs) {
/* Set up default rate scaling table in device's station table */
- iwl_sta_init_lq(priv, addr, false);
+ link_cmd = iwl_sta_init_lq(priv, addr, false);
+ if (!link_cmd) {
+ IWL_ERR(priv, "Unable to initialize rate scaling for station %pM.\n",
+ addr);
+ return -ENOMEM;
+ }
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].lq = link_cmd;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ }
+
return 0;
}
EXPORT_SYMBOL(iwl_add_local_station);
@@ -509,7 +530,8 @@ EXPORT_SYMBOL(iwl_add_local_station);
static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
{
/* Ucode must be active and driver must be non active */
- if (priv->stations[sta_id].used != IWL_STA_UCODE_ACTIVE)
+ if ((priv->stations[sta_id].used &
+ (IWL_STA_UCODE_ACTIVE | IWL_STA_DRIVER_ACTIVE)) != IWL_STA_UCODE_ACTIVE)
IWL_ERR(priv, "removed non active STA %u\n", sta_id);

priv->stations[sta_id].used &= ~IWL_STA_UCODE_ACTIVE;
@@ -676,8 +698,23 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force)
spin_lock_irqsave(&priv->sta_lock, flags_spin);
if (force) {
IWL_DEBUG_INFO(priv, "Clearing all station information in driver\n");
+ /*
+ * The station entry contains a link to the LQ command. For
+ * all stations managed by mac80211 this memory will be
+ * managed by it also. For local stations (broadcast and
+ * bssid station when in adhoc mode) we need to maintain
+ * this lq command separately. This memory is created when
+ * these stations are added.
+ */
+ for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (priv->stations[i].used & IWL_STA_LOCAL) {
+ kfree(priv->stations[i].lq);
+ priv->stations[i].lq = NULL;
+ }
+ }
priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
+ cleared = true;
} else {
for (i = 0; i < priv->hw_params.max_stations; i++) {
if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
@@ -1207,7 +1244,8 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
BUG_ON(init && (cmd.flags & CMD_ASYNC));

ret = iwl_send_cmd(priv, &cmd);
- if (ret || (cmd.flags & CMD_ASYNC))
+
+ if (cmd.flags & CMD_ASYNC)
return ret;

if (init) {
@@ -1217,33 +1255,36 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
priv->stations[lq->sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
}
- return 0;
+ return ret;
}
EXPORT_SYMBOL(iwl_send_lq_cmd);

/**
* iwl_add_bcast_station - add broadcast station into station table.
*/
-void iwl_add_bcast_station(struct iwl_priv *priv)
+int iwl_add_bcast_station(struct iwl_priv *priv)
{
IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
- iwl_add_local_station(priv, iwl_bcast_addr, true);
+ return iwl_add_local_station(priv, iwl_bcast_addr, true);
}
EXPORT_SYMBOL(iwl_add_bcast_station);

/**
* iwl3945_add_bcast_station - add broadcast station into station table.
*/
-void iwl3945_add_bcast_station(struct iwl_priv *priv)
+int iwl3945_add_bcast_station(struct iwl_priv *priv)
{
+ int ret;
+
IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
- iwl_add_local_station(priv, iwl_bcast_addr, false);
+ ret = iwl_add_local_station(priv, iwl_bcast_addr, false);
/*
* It is assumed that when station is added more initialization
* needs to be done, but for 3945 it is not the case and we can
* just release station table access right here.
*/
priv->stations[priv->hw_params.bcast_sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
+ return ret;

}
EXPORT_SYMBOL(iwl3945_add_bcast_station);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 42cd2f4..b0ed2eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -36,6 +36,9 @@
#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of
being activated */
+#define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211
+ this is for bcast and bssid (when adhoc)
+ stations */


/**
@@ -57,8 +60,8 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
const u8 *addr, u32 iv32, u16 *phase1key);

-void iwl_add_bcast_station(struct iwl_priv *priv);
-void iwl3945_add_bcast_station(struct iwl_priv *priv);
+int iwl_add_bcast_station(struct iwl_priv *priv);
+int iwl3945_add_bcast_station(struct iwl_priv *priv);
void iwl_restore_stations(struct iwl_priv *priv);
void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
--
1.6.3.3


2010-05-10 22:28:26

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 20/47] iwlwifi: move eeprom version printout to eeprom init

From: Johannes Berg <[email protected]>

It doesn't belong into firmware loading,
it should instead be printed after loading
the EEPROM.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 ------
drivers/net/wireless/iwlwifi/iwl-eeprom.c | 7 +++++++
2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 7bcc8a3..70094bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1551,7 +1551,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
u32 api_ver, build;
u32 inst_size, data_size, init_size, init_data_size, boot_size;
int err, hdr_size;
- u16 eeprom_ver;
char buildstr[25];

if (!ucode_raw) {
@@ -1654,11 +1653,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
IWL_UCODE_SERIAL(priv->ucode_ver),
buildstr);

- eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
- IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
- (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
- ? "OTP" : "EEPROM", eeprom_ver);
-
IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
priv->ucode_ver);
IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index fd37152..a8dd2fd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -589,9 +589,16 @@ int iwl_eeprom_init(struct iwl_priv *priv)
e[addr / 2] = cpu_to_le16(r >> 16);
}
}
+
+ IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
+ (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
+ ? "OTP" : "EEPROM",
+ iwl_eeprom_query16(priv, EEPROM_VERSION));
+
ret = 0;
done:
priv->cfg->ops->lib->eeprom_ops.release_semaphore(priv);
+
err:
if (ret)
iwl_eeprom_free(priv);
--
1.6.3.3


2010-05-10 22:28:25

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 15/47] iwlwifi: pass address to iwl_remove_station

From: Johannes Berg <[email protected]>

We'll need that function for IBSS station management,
so pass it the address, which is the only thing it
uses from the station struct.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-sta.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 5c6b326..354eb13 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -596,7 +596,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
/**
* iwl_remove_station - Remove driver's knowledge of station.
*/
-static int iwl_remove_station(struct iwl_priv *priv, struct ieee80211_sta *sta)
+static int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
{
int sta_id = IWL_INVALID_STATION;
int i, ret = -EINVAL;
@@ -607,7 +607,7 @@ static int iwl_remove_station(struct iwl_priv *priv, struct ieee80211_sta *sta)
if (!iwl_is_ready(priv)) {
IWL_DEBUG_INFO(priv,
"Unable to remove station %pM, device not ready.\n",
- sta->addr);
+ addr);
/*
* It is typical for stations to be removed when we are
* going down. Return success since device will be down
@@ -624,7 +624,7 @@ static int iwl_remove_station(struct iwl_priv *priv, struct ieee80211_sta *sta)
for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
if (priv->stations[i].used &&
!compare_ether_addr(priv->stations[i].sta.sta.addr,
- sta->addr)) {
+ addr)) {
sta_id = i;
break;
}
@@ -633,17 +633,17 @@ static int iwl_remove_station(struct iwl_priv *priv, struct ieee80211_sta *sta)
goto out;

IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
- sta_id, sta->addr);
+ sta_id, addr);

if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
- sta->addr);
+ addr);
goto out;
}

if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
- sta->addr);
+ addr);
goto out;
}

@@ -1450,7 +1450,7 @@ int iwl_mac_sta_remove(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
sta->addr);
- ret = iwl_remove_station(priv, sta);
+ ret = iwl_remove_station(priv, sta->addr);
if (ret)
IWL_ERR(priv, "Error removing station %pM\n",
sta->addr);
--
1.6.3.3


2010-05-10 22:28:24

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 08/47] iwlwifi: use cfg to configure calibration operation

From: Wey-Yi Guy <[email protected]>

sensitivity calibration and chain noise calibration are not available
for all the devices; use .cfg to configure the availability of those
calibration functions

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-1000.c | 4 ++++
drivers/net/wireless/iwlwifi/iwl-4965.c | 2 ++
drivers/net/wireless/iwlwifi/iwl-5000.c | 14 ++++++++++++++
drivers/net/wireless/iwlwifi/iwl-6000.c | 14 ++++++++++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 2 ++
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 13 ++++++++-----
6 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index f9f8a56..4d360d7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -261,6 +261,8 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl1000_bg_cfg = {
@@ -291,6 +293,8 @@ struct iwl_cfg iwl1000_bg_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a756fd4..6b0ae74 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2264,6 +2264,8 @@ struct iwl_cfg iwl4965_agn_cfg = {
.max_event_log_size = 512,
.tx_power_by_driver = true,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
/*
* Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A.
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index c32db49..8ed616e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -467,6 +467,8 @@ struct iwl_cfg iwl5300_agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl5100_bgn_cfg = {
@@ -496,6 +498,8 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl5100_abg_cfg = {
@@ -523,6 +527,8 @@ struct iwl_cfg iwl5100_abg_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl5100_agn_cfg = {
@@ -552,6 +558,8 @@ struct iwl_cfg iwl5100_agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl5350_agn_cfg = {
@@ -581,6 +589,8 @@ struct iwl_cfg iwl5350_agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl5150_agn_cfg = {
@@ -610,6 +620,8 @@ struct iwl_cfg iwl5150_agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl5150_abg_cfg = {
@@ -637,6 +649,8 @@ struct iwl_cfg iwl5150_abg_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 7cd45fe..b69fa36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -443,6 +443,8 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

/*
@@ -481,6 +483,8 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -514,6 +518,8 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -547,6 +553,8 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl6050_2agn_cfg = {
@@ -582,6 +590,8 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl6050_2abg_cfg = {
@@ -615,6 +625,8 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

struct iwl_cfg iwl6000_3agn_cfg = {
@@ -650,6 +662,8 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
.ucode_tracing = true,
+ .sensitivity_calib_by_driver = true,
+ .chain_noise_calib_by_driver = true,
};

MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 5034dc0..88c6412 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -321,6 +321,8 @@ struct iwl_cfg {
u32 max_event_log_size;
const bool tx_power_by_driver;
const bool ucode_tracing;
+ const bool sensitivity_calib_by_driver;
+ const bool chain_noise_calib_by_driver;
u8 scan_antennas[IEEE80211_NUM_BANDS];
};

diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 59355fa..df34c31 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1637,17 +1637,20 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(ucode_tx_stats, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(ucode_general_stats, dir_debug, S_IRUSR);

- if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
+ if (priv->cfg->sensitivity_calib_by_driver)
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
+ if (priv->cfg->chain_noise_calib_by_driver)
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
- }
if (priv->cfg->ucode_tracing)
DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
- DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
- DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
- &priv->disable_chain_noise_cal);
+ if (priv->cfg->sensitivity_calib_by_driver)
+ DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf,
+ &priv->disable_sens_cal);
+ if (priv->cfg->chain_noise_calib_by_driver)
+ DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
+ &priv->disable_chain_noise_cal);
if (priv->cfg->tx_power_by_driver)
DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
&priv->disable_tx_power_cal);
--
1.6.3.3


2010-05-10 22:28:24

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 09/47] iwlwifi: give correct return information for tx power debugfs

From: Wey-Yi Guy <[email protected]>

Return -EAGAIN when request tx power information and uCode is not ready;
so it will not confuse with tx power information not available.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index df34c31..06905bb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1225,7 +1225,7 @@ static ssize_t iwl_dbgfs_chain_tx_power_read(struct file *file,
struct statistics_tx *tx;

if (!iwl_is_alive(priv))
- pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
+ return -EAGAIN;
else {
tx = &priv->statistics.tx;
if (tx->tx_power.ant_a ||
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 32/47] iwlwifi: note that priv->bssid is used only by 3945

From: Johannes Berg <[email protected]>

The bssid member of struct iwl_priv is now
only used by 3945 code, so note that. It
shouldn't be used by any other code in the
future.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index bcdb663..46571f7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1210,7 +1210,7 @@ struct iwl_priv {
#endif

/* context information */
- u8 bssid[ETH_ALEN];
+ u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
u8 mac_addr[ETH_ALEN];

/*station table variables */
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 41/47] iwlwifi: use iwl_find_station less

From: Johannes Berg <[email protected]>

Since we now store the station ID in each station
struct, many places need not look at the station
table any more since they can just pull the station
ID out of the struct. Remove iwl_get_sta_id() and
use iwl_sta_id() instead as appropriate.

This reduces the amount of code needed to find the
right station significantly, and works since
mac80211 passes the station only after it has been
fully initialised, ie. even if TX races with
station addition it will only be passed to TX once
the addition is complete.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 6 +-
drivers/net/wireless/iwlwifi/iwl-agn.c | 19 +++++----
drivers/net/wireless/iwlwifi/iwl-sta.c | 56 ---------------------------
drivers/net/wireless/iwlwifi/iwl-sta.h | 3 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 23 ++++++-----
5 files changed, 29 insertions(+), 78 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 6a306e8..89c85d1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -566,11 +566,11 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)

hdr_len = ieee80211_hdrlen(fc);

- /* Find (or create) index into station table for destination station */
- if (info->flags & IEEE80211_TX_CTL_INJECTED)
+ /* Find index into station table for destination station */
+ if (!info->control.sta)
sta_id = priv->hw_params.bcast_sta_id;
else
- sta_id = iwl_get_sta_id(priv, hdr);
+ sta_id = iwl_sta_id(info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index b2c5665..8a4b830 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3070,7 +3070,6 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
- const u8 *addr;
int ret;
u8 sta_id;
bool is_default_wep_key = false;
@@ -3081,13 +3080,17 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
IWL_DEBUG_MAC80211(priv, "leave - hwcrypto disabled\n");
return -EOPNOTSUPP;
}
- addr = sta ? sta->addr : iwl_bcast_addr;
- sta_id = iwl_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
- addr);
- return -EINVAL;

+ if (sta) {
+ sta_id = iwl_sta_id(sta);
+
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
+ sta->addr);
+ return -EINVAL;
+ }
+ } else {
+ sta_id = priv->hw_params.bcast_sta_id;
}

mutex_lock(&priv->mutex);
@@ -3212,7 +3215,7 @@ static void iwl_mac_sta_notify(struct ieee80211_hw *hw,
if (!sta_priv->asleep)
break;
sta_priv->asleep = false;
- sta_id = iwl_find_station(priv, sta->addr);
+ sta_id = iwl_sta_id(sta);
if (sta_id != IWL_INVALID_STATION)
iwl_sta_modify_ps_wake(priv, sta_id);
break;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index d1986de..4be7940 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1307,62 +1307,6 @@ void iwl_dealloc_bcast_station(struct iwl_priv *priv)
EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station);

/**
- * iwl_get_sta_id - Find station's index within station table
- *
- * If new IBSS station, create new entry in station table
- */
-int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
-{
- int sta_id;
- __le16 fc = hdr->frame_control;
-
- /* If this frame is broadcast or management, use broadcast station id */
- if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
- return priv->hw_params.bcast_sta_id;
-
- switch (priv->iw_mode) {
-
- /* If we are a client station in a BSS network, use the special
- * AP station entry (that's the only station we communicate with) */
- case NL80211_IFTYPE_STATION:
- /*
- * If addition of station not complete yet, which means
- * that rate scaling has not been initialized, then return
- * the broadcast station.
- */
- if (!(priv->stations[IWL_AP_ID].used & IWL_STA_UCODE_ACTIVE))
- return priv->hw_params.bcast_sta_id;
- return IWL_AP_ID;
-
- /* If we are an AP, then find the station, or use BCAST */
- case NL80211_IFTYPE_AP:
- sta_id = iwl_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
- return priv->hw_params.bcast_sta_id;
-
- /* If this frame is going out to an IBSS network, find the station,
- * or create a new station table entry */
- case NL80211_IFTYPE_ADHOC:
- sta_id = iwl_find_station(priv, hdr->addr1);
- if (sta_id != IWL_INVALID_STATION)
- return sta_id;
-
- IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
- "Defaulting to broadcast...\n",
- hdr->addr1);
- iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
- return priv->hw_params.bcast_sta_id;
-
- default:
- IWL_WARN(priv, "Unknown mode of operation: %d\n",
- priv->iw_mode);
- return priv->hw_params.bcast_sta_id;
- }
-}
-EXPORT_SYMBOL(iwl_get_sta_id);
-
-/**
* iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
*/
void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 7229e2c..646f644 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -29,6 +29,8 @@
#ifndef __iwl_sta_h__
#define __iwl_sta_h__

+#include "iwl-dev.h"
+
#define HW_KEY_DYNAMIC 0
#define HW_KEY_DEFAULT 1

@@ -65,7 +67,6 @@ void iwl_clear_ucode_stations(struct iwl_priv *priv);
int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq);
void iwl_dealloc_bcast_station(struct iwl_priv *priv);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
-int iwl_get_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);
int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 48fb59b..4916f23 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -508,11 +508,11 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)

hdr_len = ieee80211_hdrlen(fc);

- /* Find (or create) index into station table for destination station */
- if (info->flags & IEEE80211_TX_CTL_INJECTED)
+ /* Find index into station table for destination station */
+ if (!info->control.sta)
sta_id = priv->hw_params.bcast_sta_id;
else
- sta_id = iwl_get_sta_id(priv, hdr);
+ sta_id = iwl_sta_id(info->control.sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
hdr->addr1);
@@ -3321,7 +3321,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
struct ieee80211_key_conf *key)
{
struct iwl_priv *priv = hw->priv;
- const u8 *addr;
int ret = 0;
u8 sta_id = IWL_INVALID_STATION;
u8 static_key;
@@ -3333,15 +3332,19 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
return -EOPNOTSUPP;
}

- addr = sta ? sta->addr : iwl_bcast_addr;
static_key = !iwl_is_associated(priv);

if (!static_key) {
- sta_id = iwl_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
- addr);
- return -EINVAL;
+ if (!sta) {
+ sta_id = priv->hw_params.bcast_sta_id;
+ } else {
+ sta_id = iwl_sta_id(sta);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_DEBUG_MAC80211(priv,
+ "leave - %pM not in station map.\n",
+ sta->addr);
+ return -EINVAL;
+ }
}
}

--
1.6.3.3


2010-05-10 22:28:22

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 03/47] iwlwifi: remove powersave debugfs if it is not supported

From: Wey-Yi Guy <[email protected]>

For the devices do not have power save support, remove the power save
control related debugfs files.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 0aedbec..f0d9b72 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1612,8 +1612,11 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(interrupt, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(qos, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(led, dir_data, S_IRUSR);
- DEBUGFS_ADD_FILE(sleep_level_override, dir_data, S_IWUSR | S_IRUSR);
- DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
+ if (!priv->cfg->broken_powersave) {
+ DEBUGFS_ADD_FILE(sleep_level_override, dir_data,
+ S_IWUSR | S_IRUSR);
+ DEBUGFS_ADD_FILE(current_sleep_command, dir_data, S_IRUSR);
+ }
DEBUGFS_ADD_FILE(thermal_throttling, dir_data, S_IRUSR);
DEBUGFS_ADD_FILE(disable_ht40, dir_data, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_statistics, dir_debug, S_IRUSR);
--
1.6.3.3


2010-05-10 22:28:25

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 22/47] iwlagn: implement loading a new firmware file type

From: Johannes Berg <[email protected]>

The old firmware file type does not allow indicating
any firmware capabilities, which we frequently want
to make things easier.

This implements a new firmware type that is based on
a TLV structure, and adds a TLV for the maximum length
of probe requests in scans.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 133 +++++++++++++++++++++++++-
drivers/net/wireless/iwlwifi/iwl-commands.h | 1 -
drivers/net/wireless/iwlwifi/iwl-dev.h | 58 ++++++++++++-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 4 +-
4 files changed, 187 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 65ae636..97184e1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1505,9 +1505,13 @@ static void iwl_nic_start(struct iwl_priv *priv)
iwl_write32(priv, CSR_RESET, 0);
}

+struct iwlagn_ucode_capabilities {
+ u32 max_probe_length;
+};

static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
-static int iwl_mac_setup_register(struct iwl_priv *priv);
+static int iwl_mac_setup_register(struct iwl_priv *priv,
+ struct iwlagn_ucode_capabilities *capa);

static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
{
@@ -1619,6 +1623,114 @@ static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
return 0;
}

+static int iwlagn_wanted_ucode_alternative = 1;
+
+static int iwlagn_load_firmware(struct iwl_priv *priv,
+ const struct firmware *ucode_raw,
+ struct iwlagn_firmware_pieces *pieces,
+ struct iwlagn_ucode_capabilities *capa)
+{
+ struct iwl_tlv_ucode_header *ucode = (void *)ucode_raw->data;
+ struct iwl_ucode_tlv *tlv;
+ size_t len = ucode_raw->size;
+ const u8 *data;
+ int wanted_alternative = iwlagn_wanted_ucode_alternative, tmp;
+ u64 alternatives;
+
+ if (len < sizeof(*ucode))
+ return -EINVAL;
+
+ if (ucode->magic != cpu_to_le32(IWL_TLV_UCODE_MAGIC))
+ return -EINVAL;
+
+ /*
+ * Check which alternatives are present, and "downgrade"
+ * when the chosen alternative is not present, warning
+ * the user when that happens. Some files may not have
+ * any alternatives, so don't warn in that case.
+ */
+ alternatives = le64_to_cpu(ucode->alternatives);
+ tmp = wanted_alternative;
+ if (wanted_alternative > 63)
+ wanted_alternative = 63;
+ while (wanted_alternative && !(alternatives & BIT(wanted_alternative)))
+ wanted_alternative--;
+ if (wanted_alternative && wanted_alternative != tmp)
+ IWL_WARN(priv,
+ "uCode alternative %d not available, choosing %d\n",
+ tmp, wanted_alternative);
+
+ priv->ucode_ver = le32_to_cpu(ucode->ver);
+ pieces->build = le32_to_cpu(ucode->build);
+ data = ucode->data;
+
+ len -= sizeof(*ucode);
+
+ while (len >= sizeof(*tlv)) {
+ u32 tlv_len;
+ enum iwl_ucode_tlv_type tlv_type;
+ u16 tlv_alt;
+ const u8 *tlv_data;
+
+ len -= sizeof(*tlv);
+ tlv = (void *)data;
+
+ tlv_len = le32_to_cpu(tlv->length);
+ tlv_type = le16_to_cpu(tlv->type);
+ tlv_alt = le16_to_cpu(tlv->alternative);
+ tlv_data = tlv->data;
+
+ if (len < tlv_len)
+ return -EINVAL;
+ len -= ALIGN(tlv_len, 4);
+ data += sizeof(*tlv) + ALIGN(tlv_len, 4);
+
+ /*
+ * Alternative 0 is always valid.
+ *
+ * Skip alternative TLVs that are not selected.
+ */
+ if (tlv_alt != 0 && tlv_alt != wanted_alternative)
+ continue;
+
+ switch (tlv_type) {
+ case IWL_UCODE_TLV_INST:
+ pieces->inst = tlv_data;
+ pieces->inst_size = tlv_len;
+ break;
+ case IWL_UCODE_TLV_DATA:
+ pieces->data = tlv_data;
+ pieces->data_size = tlv_len;
+ break;
+ case IWL_UCODE_TLV_INIT:
+ pieces->init = tlv_data;
+ pieces->init_size = tlv_len;
+ break;
+ case IWL_UCODE_TLV_INIT_DATA:
+ pieces->init_data = tlv_data;
+ pieces->init_data_size = tlv_len;
+ break;
+ case IWL_UCODE_TLV_BOOT:
+ pieces->boot = tlv_data;
+ pieces->boot_size = tlv_len;
+ break;
+ case IWL_UCODE_TLV_PROBE_MAX_LEN:
+ if (tlv_len != 4)
+ return -EINVAL;
+ capa->max_probe_length =
+ le32_to_cpup((__le32 *)tlv_data);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (len)
+ return -EINVAL;
+
+ return 0;
+}
+
/**
* iwl_ucode_callback - callback when firmware was loaded
*
@@ -1636,6 +1748,9 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
u32 api_ver;
char buildstr[25];
u32 build;
+ struct iwlagn_ucode_capabilities ucode_capa = {
+ .max_probe_length = 200,
+ };

memset(&pieces, 0, sizeof(pieces));

@@ -1660,7 +1775,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
if (ucode->ver)
err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
else
- err = -EINVAL;
+ err = iwlagn_load_firmware(priv, ucode_raw, &pieces,
+ &ucode_capa);

if (err)
goto try_again;
@@ -1757,7 +1873,6 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto try_again;
}

-
/* Allocate ucode buffers for card's bus-master loading ... */

/* Runtime instructions and 2 copies of data:
@@ -1841,7 +1956,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
*
* 9. Setup and register with mac80211 and debugfs
**************************************************/
- err = iwl_mac_setup_register(priv);
+ err = iwl_mac_setup_register(priv, &ucode_capa);
if (err)
goto out_unbind;

@@ -2716,7 +2831,8 @@ void iwl_post_associate(struct iwl_priv *priv)
* Not a mac80211 entry point function, but it fits in with all the
* other mac80211 functions grouped here.
*/
-static int iwl_mac_setup_register(struct iwl_priv *priv)
+static int iwl_mac_setup_register(struct iwl_priv *priv,
+ struct iwlagn_ucode_capabilities *capa)
{
int ret;
struct ieee80211_hw *hw = priv->hw;
@@ -2751,7 +2867,7 @@ static int iwl_mac_setup_register(struct iwl_priv *priv)

hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;
/* we create the 802.11 header and a zero-length SSID element */
- hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
+ hw->wiphy->max_scan_ie_len = capa->max_probe_length - 24 - 2;

/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
@@ -3974,3 +4090,8 @@ MODULE_PARM_DESC(fw_restart, "restart firmware in case of error");
module_param_named(
disable_hw_scan, iwlagn_mod_params.disable_hw_scan, int, S_IRUGO);
MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
+
+module_param_named(ucode_alternative, iwlagn_wanted_ucode_alternative, int,
+ S_IRUGO);
+MODULE_PARM_DESC(ucode_alternative,
+ "specify ucode alternative to use from ucode file");
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 0086019..449d41f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -2668,7 +2668,6 @@ struct iwl_ssid_ie {
#define IWL_GOOD_CRC_TH_NEVER cpu_to_le16(0xffff)
#define IWL_MAX_SCAN_SIZE 1024
#define IWL_MAX_CMD_SIZE 4096
-#define IWL_MAX_PROBE_REQUEST 200

/*
* REPLY_SCAN_CMD = 0x80 (command)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index fe938d9..19a5c89 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -518,7 +518,7 @@ struct fw_desc {
u32 len; /* bytes */
};

-/* uCode file layout */
+/* v1/v2 uCode file layout */
struct iwl_ucode_header {
__le32 ver; /* major/minor/API/serial */
union {
@@ -542,6 +542,62 @@ struct iwl_ucode_header {
} u;
};

+/*
+ * new TLV uCode file layout
+ *
+ * The new TLV file format contains TLVs, that each specify
+ * some piece of data. To facilitate "groups", for example
+ * different instruction image with different capabilities,
+ * bundled with the same init image, an alternative mechanism
+ * is provided:
+ * When the alternative field is 0, that means that the item
+ * is always valid. When it is non-zero, then it is only
+ * valid in conjunction with items of the same alternative,
+ * in which case the driver (user) selects one alternative
+ * to use.
+ */
+
+enum iwl_ucode_tlv_type {
+ IWL_UCODE_TLV_INVALID = 0, /* unused */
+ IWL_UCODE_TLV_INST = 1,
+ IWL_UCODE_TLV_DATA = 2,
+ IWL_UCODE_TLV_INIT = 3,
+ IWL_UCODE_TLV_INIT_DATA = 4,
+ IWL_UCODE_TLV_BOOT = 5,
+ IWL_UCODE_TLV_PROBE_MAX_LEN = 6, /* a u32 value */
+};
+
+struct iwl_ucode_tlv {
+ __le16 type; /* see above */
+ __le16 alternative; /* see comment */
+ __le32 length; /* not including type/length fields */
+ u8 data[0];
+} __attribute__ ((packed));
+
+#define IWL_TLV_UCODE_MAGIC 0x0a4c5749
+
+struct iwl_tlv_ucode_header {
+ /*
+ * The TLV style ucode header is distinguished from
+ * the v1/v2 style header by first four bytes being
+ * zero, as such is an invalid combination of
+ * major/minor/API/serial versions.
+ */
+ __le32 zero;
+ __le32 magic;
+ u8 human_readable[64];
+ __le32 ver; /* major/minor/API/serial */
+ __le32 build;
+ __le64 alternatives; /* bitmask of valid alternatives */
+ /*
+ * The data contained herein has a TLV layout,
+ * see above for the TLV header and types.
+ * Note that each TLV is padded to a length
+ * that is a multiple of 4 for alignment.
+ */
+ u8 data[0];
+};
+
struct iwl4965_ibss_seq {
u8 mac[ETH_ALEN];
u16 seq_num;
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 59c85f5..77ab00b 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3875,6 +3875,8 @@ err:
return ret;
}

+#define IWL3945_MAX_PROBE_REQUEST 200
+
static int iwl3945_setup_mac(struct iwl_priv *priv)
{
int ret;
@@ -3900,7 +3902,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)

hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
/* we create the 802.11 header and a zero-length SSID element */
- hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2;
+ hw->wiphy->max_scan_ie_len = IWL3945_MAX_PROBE_REQUEST - 24 - 2;

/* Default value; 4 EDCA QOS priorities */
hw->queues = 4;
--
1.6.3.3


2010-05-10 22:28:25

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 14/47] iwl3945: use iwl3945_add_bcast_station

From: Johannes Berg <[email protected]>

iwl3945 should not use iwl_add_local_station(..., false)
because that would leave the IWL_STA_UCODE_INPROGRESS flag
set for the station, which is not desirable. Instead it
can use iwl3945_add_bcast_station() here.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 04cedef..4f20cca 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3293,7 +3293,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv);
- iwl_add_local_station(priv, iwl_bcast_addr, false);
+ iwl3945_add_bcast_station(priv);
}
iwl3945_send_beacon_cmd(priv);

--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 44/47] iwlwifi: move iwl_find_station() to 4965

From: Johannes Berg <[email protected]>

4965 code is the only thing that now still
needs iwl_find_station(), so move it there
and make it static. Everything else can
rely on the station data passed by mac80211.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 44 ++++++++++++++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl-sta.c | 45 -------------------------------
drivers/net/wireless/iwlwifi/iwl-sta.h | 6 ----
3 files changed, 44 insertions(+), 51 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 93893ae..d3afdda 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1953,6 +1953,50 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
return 0;
}

+static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
+{
+ int i;
+ int start = 0;
+ int ret = IWL_INVALID_STATION;
+ unsigned long flags;
+
+ if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
+ (priv->iw_mode == NL80211_IFTYPE_AP))
+ start = IWL_STA_ID;
+
+ if (is_broadcast_ether_addr(addr))
+ return priv->hw_params.bcast_sta_id;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ for (i = start; i < priv->hw_params.max_stations; i++)
+ if (priv->stations[i].used &&
+ (!compare_ether_addr(priv->stations[i].sta.sta.addr,
+ addr))) {
+ ret = i;
+ goto out;
+ }
+
+ IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
+ addr, priv->num_stations);
+
+ out:
+ /*
+ * It may be possible that more commands interacting with stations
+ * arrive before we completed processing the adding of
+ * station
+ */
+ if (ret != IWL_INVALID_STATION &&
+ (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
+ ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
+ (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
+ IWL_ERR(priv, "Requested station info for sta %d before ready.\n",
+ ret);
+ ret = IWL_INVALID_STATION;
+ }
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ return ret;
+}
+
static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
{
if (priv->iw_mode == NL80211_IFTYPE_STATION) {
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index b8053e7..ba36df5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -35,51 +35,6 @@
#include "iwl-core.h"
#include "iwl-sta.h"

-u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
-{
- int i;
- int start = 0;
- int ret = IWL_INVALID_STATION;
- unsigned long flags;
-
- if ((priv->iw_mode == NL80211_IFTYPE_ADHOC) ||
- (priv->iw_mode == NL80211_IFTYPE_AP))
- start = IWL_STA_ID;
-
- if (is_broadcast_ether_addr(addr))
- return priv->hw_params.bcast_sta_id;
-
- spin_lock_irqsave(&priv->sta_lock, flags);
- for (i = start; i < priv->hw_params.max_stations; i++)
- if (priv->stations[i].used &&
- (!compare_ether_addr(priv->stations[i].sta.sta.addr,
- addr))) {
- ret = i;
- goto out;
- }
-
- IWL_DEBUG_ASSOC_LIMIT(priv, "can not find STA %pM total %d\n",
- addr, priv->num_stations);
-
- out:
- /*
- * It may be possible that more commands interacting with stations
- * arrive before we completed processing the adding of
- * station
- */
- if (ret != IWL_INVALID_STATION &&
- (!(priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) ||
- ((priv->stations[ret].used & IWL_STA_UCODE_ACTIVE) &&
- (priv->stations[ret].used & IWL_STA_UCODE_INPROGRESS)))) {
- IWL_ERR(priv, "Requested station info for sta %d before ready.\n",
- ret);
- ret = IWL_INVALID_STATION;
- }
- spin_unlock_irqrestore(&priv->sta_lock, flags);
- return ret;
-}
-EXPORT_SYMBOL(iwl_find_station);
-
/* priv->sta_lock must be held */
static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 08d4bc1..6872bcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -43,12 +43,6 @@
#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */


-/**
- * iwl_find_station - Find station id for a given BSSID
- * @bssid: MAC address of station ID to find
- */
-u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);
-
int iwl_remove_default_wep_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key);
int iwl_set_default_wep_key(struct iwl_priv *priv,
--
1.6.3.3


2010-05-10 22:28:27

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 27/47] iwlwifi: apply filter flags directly

From: Johannes Berg <[email protected]>

Since iwl_configure_filter can now sleep since
the mac80211 callback was changed, we can now
apply filter flags changes directly.

Also, while at it, make the code a bit more
generic with a local macro. There's no need
to check changed_flags since we apply all at
the same time anyway.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 52 +++++++++++++------------------
1 files changed, 22 insertions(+), 30 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 5c6f254..246538a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1257,41 +1257,33 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
u64 multicast)
{
struct iwl_priv *priv = hw->priv;
- __le32 *filter_flags = &priv->staging_rxon.filter_flags;
+ __le32 filter_or = 0, filter_nand = 0;
+
+#define CHK(test, flag) do { \
+ if (*total_flags & (test)) \
+ filter_or |= (flag); \
+ else \
+ filter_nand |= (flag); \
+ } while (0)

IWL_DEBUG_MAC80211(priv, "Enter: changed: 0x%x, total: 0x%x\n",
changed_flags, *total_flags);

- if (changed_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS)) {
- if (*total_flags & (FIF_OTHER_BSS | FIF_PROMISC_IN_BSS))
- *filter_flags |= RXON_FILTER_PROMISC_MSK;
- else
- *filter_flags &= ~RXON_FILTER_PROMISC_MSK;
- }
- if (changed_flags & FIF_ALLMULTI) {
- if (*total_flags & FIF_ALLMULTI)
- *filter_flags |= RXON_FILTER_ACCEPT_GRP_MSK;
- else
- *filter_flags &= ~RXON_FILTER_ACCEPT_GRP_MSK;
- }
- if (changed_flags & FIF_CONTROL) {
- if (*total_flags & FIF_CONTROL)
- *filter_flags |= RXON_FILTER_CTL2HOST_MSK;
- else
- *filter_flags &= ~RXON_FILTER_CTL2HOST_MSK;
- }
- if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
- if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
- *filter_flags |= RXON_FILTER_BCON_AWARE_MSK;
- else
- *filter_flags &= ~RXON_FILTER_BCON_AWARE_MSK;
- }
+ CHK(FIF_OTHER_BSS | FIF_PROMISC_IN_BSS, RXON_FILTER_PROMISC_MSK);
+ CHK(FIF_ALLMULTI, RXON_FILTER_ACCEPT_GRP_MSK);
+ CHK(FIF_CONTROL, RXON_FILTER_CTL2HOST_MSK);
+ CHK(FIF_BCN_PRBRESP_PROMISC, RXON_FILTER_BCON_AWARE_MSK);

- /* We avoid iwl_commit_rxon here to commit the new filter flags
- * since mac80211 will call ieee80211_hw_config immediately.
- * (mc_list is not supported at this time). Otherwise, we need to
- * queue a background iwl_commit_rxon work.
- */
+#undef CHK
+
+ mutex_lock(&priv->mutex);
+
+ priv->staging_rxon.filter_flags &= ~filter_nand;
+ priv->staging_rxon.filter_flags |= filter_or;
+
+ iwlcore_commit_rxon(priv);
+
+ mutex_unlock(&priv->mutex);

*total_flags &= FIF_OTHER_BSS | FIF_ALLMULTI | FIF_PROMISC_IN_BSS |
FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
--
1.6.3.3


2010-05-10 22:28:31

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 36/47] iwlagn: work around rate scaling reset delay

From: Reinette Chatre <[email protected]>

When station is using an HT channel to communicate to AP and communication
is lost then driver will first be notified that channel is not an HT
channel anymore before AP station is removed. A consequence of that is that
the driver will know that it is not communicating on HT anymore, but the
rate scaling table is still under the impression it is operating in HT. Any
time after driver has been notified channel is not HT anymore there will
thus be a firmware SYSASSERT when the current active LQ command is sent.

A workaround for this issue is to not send a LQ command in the short time between
being notified channel is not HT anymore and rate scaling table being
updated.

This fixes http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2173

Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-sta.c | 38 +++++++++++++++++++++++++++++++-
1 files changed, 37 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7e51647..e95282b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1170,6 +1170,39 @@ static inline void iwl_dump_lq_cmd(struct iwl_priv *priv,
#endif

/**
+ * is_lq_table_valid() - Test one aspect of LQ cmd for validity
+ *
+ * It sometimes happens when a HT rate has been in use and we
+ * loose connectivity with AP then mac80211 will first tell us that the
+ * current channel is not HT anymore before removing the station. In such a
+ * scenario the RXON flags will be updated to indicate we are not
+ * communicating HT anymore, but the LQ command may still contain HT rates.
+ * Test for this to prevent driver from sending LQ command between the time
+ * RXON flags are updated and when LQ command is updated.
+ */
+static bool is_lq_table_valid(struct iwl_priv *priv,
+ struct iwl_link_quality_cmd *lq)
+{
+ int i;
+ struct iwl_ht_config *ht_conf = &priv->current_ht_config;
+
+ if (ht_conf->is_ht)
+ return true;
+
+ IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
+ priv->active_rxon.channel);
+ for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
+ if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
+ IWL_DEBUG_INFO(priv,
+ "index %d of LQ expects HT channel\n",
+ i);
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
* iwl_send_lq_cmd() - Send link quality command
* @init: This command is sent as part of station initialization right
* after station has been added.
@@ -1198,7 +1231,10 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
iwl_dump_lq_cmd(priv, lq);
BUG_ON(init && (cmd.flags & CMD_ASYNC));

- ret = iwl_send_cmd(priv, &cmd);
+ if (is_lq_table_valid(priv, lq))
+ ret = iwl_send_cmd(priv, &cmd);
+ else
+ ret = -EINVAL;

if (cmd.flags & CMD_ASYNC)
return ret;
--
1.6.3.3


2010-05-10 22:28:31

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 35/47] iwlwifi: rework broadcast station management

From: Johannes Berg <[email protected]>

Currently, the broadcast station is managed along
with the interface type, rather than always being
present. That leads to a bug with injection -- it
is currently not possible to inject frames when
the only virtual interface is a monitor, because
in that the required broadcast station is missing.

Additionally, allocating and deallocating the
broadcast station's LQ all the time is wasteful,
and the code to support this is fairly complex.

So this changes completely the way we manage the
broadcast station. Rather than manage it along
with any interface, we now allocate it when we
bring the device up, and remove it again when we
bring the device down. When we bring the device
up, we don't immediately program the broadcast
station into it, instead we just mark it active
and rely on the next restore cycle to upload it
to the device. This works because an unassociated
RXON is always required at least once to set up
device parameters, which implies a reprogramming
of stations into the device.

As we now manage all stations properly, there no
longer is a need for forcing a clearing of them
via iwl_clear_ucode_stations(), which can become
a lot simpler.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-1000.c | 1 -
drivers/net/wireless/iwlwifi/iwl-3945.c | 5 +-
drivers/net/wireless/iwlwifi/iwl-4965.c | 1 -
drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-agn.c | 12 ++-
drivers/net/wireless/iwlwifi/iwl-core.c | 7 --
drivers/net/wireless/iwlwifi/iwl-core.h | 1 -
drivers/net/wireless/iwlwifi/iwl-sta.c | 137 +++++++++++++--------------
drivers/net/wireless/iwlwifi/iwl-sta.h | 12 +-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 8 +-
11 files changed, 89 insertions(+), 99 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index a2f7cbc..6be2992 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -212,7 +212,6 @@ static struct iwl_lib_ops iwl1000_lib = {
.temperature = iwlagn_temperature,
.set_ct_kill = iwl1000_set_ct_threshold,
},
- .add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 05d808b..7fb1595 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1992,7 +1992,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
"configuration (%d).\n", rc);
return rc;
}
- iwl_clear_ucode_stations(priv, false);
+ iwl_clear_ucode_stations(priv);
iwl_restore_stations(priv);
}

@@ -2025,7 +2025,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));

if (!new_assoc) {
- iwl_clear_ucode_stations(priv, false);
+ iwl_clear_ucode_stations(priv);
iwl_restore_stations(priv);
}

@@ -2853,7 +2853,6 @@ static struct iwl_lib_ops iwl3945_lib = {
.isr = iwl_isr_legacy,
.config_ap = iwl3945_config_ap,
.manage_ibss_station = iwl3945_manage_ibss_station,
- .add_bcast_station = iwl3945_add_bcast_station,
.check_plcp_health = iwl3945_good_plcp_health,

.debugfs_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index b8bf837..93893ae 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2190,7 +2190,6 @@ static struct iwl_lib_ops iwl4965_lib = {
.temperature = iwl4965_temperature_calib,
.set_ct_kill = iwl4965_set_ct_threshold,
},
- .add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index efda0e8..a28af7e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -351,7 +351,6 @@ static struct iwl_lib_ops iwl5000_lib = {
.temperature = iwlagn_temperature,
.set_ct_kill = iwl5000_set_ct_threshold,
},
- .add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
@@ -414,7 +413,6 @@ static struct iwl_lib_ops iwl5150_lib = {
.temperature = iwl5150_temperature,
.set_ct_kill = iwl5150_set_ct_threshold,
},
- .add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 03c7324..9fbf54c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -317,7 +317,6 @@ static struct iwl_lib_ops iwl6000_lib = {
.temperature = iwlagn_temperature,
.set_ct_kill = iwl6000_set_ct_threshold,
},
- .add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
@@ -390,7 +389,6 @@ static struct iwl_lib_ops iwl6050_lib = {
.set_ct_kill = iwl6000_set_ct_threshold,
.set_calib_version = iwl6050_set_calib_version,
},
- .add_bcast_station = iwl_add_bcast_station,
.manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 85e045b..0c913ea 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -156,7 +156,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret);
return ret;
}
- iwl_clear_ucode_stations(priv, false);
+ iwl_clear_ucode_stations(priv);
iwl_restore_stations(priv);
ret = iwl_restore_default_wep_keys(priv);
if (ret) {
@@ -188,7 +188,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
}
IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
- iwl_clear_ucode_stations(priv, false);
+ iwl_clear_ucode_stations(priv);
iwl_restore_stations(priv);
ret = iwl_restore_default_wep_keys(priv);
if (ret) {
@@ -2403,7 +2403,8 @@ static void __iwl_down(struct iwl_priv *priv)
if (!exit_pending)
set_bit(STATUS_EXIT_PENDING, &priv->status);

- iwl_clear_ucode_stations(priv, true);
+ iwl_clear_ucode_stations(priv);
+ iwl_dealloc_bcast_station(priv);

/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2550,6 +2551,10 @@ static int __iwl_up(struct iwl_priv *priv)
return -EIO;
}

+ ret = iwl_alloc_bcast_station(priv, true);
+ if (ret)
+ return ret;
+
iwl_prepare_card_hw(priv);

if (!priv->hw_ready) {
@@ -3032,7 +3037,6 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv);
- iwl_add_bcast_station(priv);
}
iwl_send_beacon_cmd(priv);

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d7a3620..f007b36 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2042,11 +2042,6 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
if (err)
goto out_err;

- /* Add the broadcast address so we can send broadcast frames */
- err = priv->cfg->ops->lib->add_bcast_station(priv);
- if (err)
- goto out_err;
-
goto out;

out_err:
@@ -2069,8 +2064,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,

mutex_lock(&priv->mutex);

- iwl_clear_ucode_stations(priv, true);
-
if (iwl_is_ready_rf(priv)) {
iwl_scan_cancel_timeout(priv, 100);
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 1774ce9..d80aa6c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -191,7 +191,6 @@ struct iwl_lib_ops {
/* temperature */
struct iwl_temp_ops temp_ops;
/* station management */
- int (*add_bcast_station)(struct iwl_priv *priv);
int (*manage_ibss_station)(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add);
/* recover from tx queue stall */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 5bf82b9..7e51647 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -656,63 +656,27 @@ out:
EXPORT_SYMBOL_GPL(iwl_remove_station);

/**
- * iwl_clear_ucode_stations() - clear entire station table driver and/or ucode
- * @priv:
- * @force: If set then the uCode station table needs to be cleared here. If
- * not set then the uCode station table has already been cleared,
- * for example after sending it a RXON command without ASSOC bit
- * set, and we just need to change driver state here.
+ * iwl_clear_ucode_stations - clear ucode station table bits
+ *
+ * This function clears all the bits in the driver indicating
+ * which stations are active in the ucode. Call when something
+ * other than explicit station management would cause this in
+ * the ucode, e.g. unassociated RXON.
*/
-void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force)
+void iwl_clear_ucode_stations(struct iwl_priv *priv)
{
int i;
unsigned long flags_spin;
bool cleared = false;

- IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver%s\n",
- force ? " and ucode" : "");
-
- if (force) {
- if (!iwl_is_ready(priv)) {
- /*
- * If device is not ready at this point the station
- * table is likely already empty (uCode not ready
- * to receive station requests) or will soon be
- * due to interface going down.
- */
- IWL_DEBUG_INFO(priv, "Unable to remove stations from device - device not ready\n");
- } else {
- iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL);
- }
- }
+ IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n");

spin_lock_irqsave(&priv->sta_lock, flags_spin);
- if (force) {
- IWL_DEBUG_INFO(priv, "Clearing all station information in driver\n");
- /*
- * The station entry contains a link to the LQ command. For
- * all stations managed by mac80211 this memory will be
- * managed by it also. For local stations (broadcast and
- * bssid station when in adhoc mode) we need to maintain
- * this lq command separately. This memory is created when
- * these stations are added.
- */
- for (i = 0; i < priv->hw_params.max_stations; i++) {
- if (priv->stations[i].used & IWL_STA_LOCAL) {
- kfree(priv->stations[i].lq);
- priv->stations[i].lq = NULL;
- }
- }
- priv->num_stations = 0;
- memset(priv->stations, 0, sizeof(priv->stations));
- cleared = true;
- } else {
- for (i = 0; i < priv->hw_params.max_stations; i++) {
- if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
- IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
- priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
- cleared = true;
- }
+ for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) {
+ IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i);
+ priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
+ cleared = true;
}
}
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
@@ -1251,34 +1215,67 @@ int iwl_send_lq_cmd(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_send_lq_cmd);

/**
- * iwl_add_bcast_station - add broadcast station into station table.
+ * iwl_alloc_bcast_station - add broadcast station into driver's station table.
+ *
+ * This adds the broadcast station into the driver's station table
+ * and marks it driver active, so that it will be restored to the
+ * device at the next best time.
*/
-int iwl_add_bcast_station(struct iwl_priv *priv)
+int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq)
{
- IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
- return iwl_add_local_station(priv, iwl_bcast_addr, true);
+ struct iwl_link_quality_cmd *link_cmd;
+ unsigned long flags;
+ u8 sta_id;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL);
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_ERR(priv, "Unable to prepare broadcast station\n");
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ return -EINVAL;
+ }
+
+ priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE;
+ priv->stations[sta_id].used |= IWL_STA_BCAST;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+
+ if (init_lq) {
+ link_cmd = iwl_sta_alloc_lq(priv, sta_id);
+ if (!link_cmd) {
+ IWL_ERR(priv,
+ "Unable to initialize rate scaling for bcast station.\n");
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ priv->stations[sta_id].lq = link_cmd;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+ }
+
+ return 0;
}
-EXPORT_SYMBOL(iwl_add_bcast_station);
+EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);

-/**
- * iwl3945_add_bcast_station - add broadcast station into station table.
- */
-int iwl3945_add_bcast_station(struct iwl_priv *priv)
+void iwl_dealloc_bcast_station(struct iwl_priv *priv)
{
- int ret;
-
- IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n");
- ret = iwl_add_local_station(priv, iwl_bcast_addr, false);
- /*
- * It is assumed that when station is added more initialization
- * needs to be done, but for 3945 it is not the case and we can
- * just release station table access right here.
- */
- priv->stations[priv->hw_params.bcast_sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
- return ret;
+ unsigned long flags;
+ int i;

+ spin_lock_irqsave(&priv->sta_lock, flags);
+ for (i = 0; i < priv->hw_params.max_stations; i++) {
+ if (!(priv->stations[i].used & IWL_STA_BCAST))
+ continue;
+
+ priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE;
+ priv->num_stations--;
+ BUG_ON(priv->num_stations < 0);
+ kfree(priv->stations[i].lq);
+ priv->stations[i].lq = NULL;
+ }
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
}
-EXPORT_SYMBOL(iwl3945_add_bcast_station);
+EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station);

/**
* iwl_get_sta_id - Find station's index within station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 1a0e590..50c9d51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -36,9 +36,9 @@
#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */
#define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of
being activated */
-#define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211
- this is for bcast and bssid (when adhoc)
- stations */
+#define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211;
+ (this is for the IBSS BSSID stations) */
+#define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */


/**
@@ -60,10 +60,10 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
const u8 *addr, u32 iv32, u16 *phase1key);

-int iwl_add_bcast_station(struct iwl_priv *priv);
-int iwl3945_add_bcast_station(struct iwl_priv *priv);
void iwl_restore_stations(struct iwl_priv *priv);
-void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force);
+void iwl_clear_ucode_stations(struct iwl_priv *priv);
+int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq);
+void iwl_dealloc_bcast_station(struct iwl_priv *priv);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr);
int iwl_send_add_sta(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 85a46ad..1a44571 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2583,7 +2583,8 @@ static void __iwl3945_down(struct iwl_priv *priv)
set_bit(STATUS_EXIT_PENDING, &priv->status);

/* Station information will now be cleared in device */
- iwl_clear_ucode_stations(priv, true);
+ iwl_clear_ucode_stations(priv);
+ iwl_dealloc_bcast_station(priv);

/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2664,6 +2665,10 @@ static int __iwl3945_up(struct iwl_priv *priv)
{
int rc, i;

+ rc = iwl_alloc_bcast_station(priv, false);
+ if (rc)
+ return rc;
+
if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
return -EIO;
@@ -3302,7 +3307,6 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
/* restore RXON assoc */
priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv);
- iwl3945_add_bcast_station(priv);
}
iwl3945_send_beacon_cmd(priv);

--
1.6.3.3


2010-05-10 22:28:24

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 06/47] iwlwifi: remove device type checking for tx power in debugfs

From: Wey-Yi Guy <[email protected]>

Instead of checking device type for enable/disable tx power control,
move it to .cfg for better control and more flexibilities.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 7 +++++++
drivers/net/wireless/iwlwifi/iwl-4965.c | 1 +
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 +--
4 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 3faa78c..3607813 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -1714,6 +1714,11 @@ static int iwl3945_hw_reg_comp_txpower_temp(struct iwl_priv *priv)
int ref_temp;
int temperature = priv->temperature;

+ if (priv->disable_tx_power_cal ||
+ test_bit(STATUS_SCANNING, &priv->status)) {
+ /* do not perform tx power calibration */
+ return 0;
+ }
/* set up new Tx power info for each and every channel, 2.4 and 5.x */
for (i = 0; i < priv->channel_count; i++) {
ch_info = &priv->channel_info[i];
@@ -2842,6 +2847,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .tx_power_by_driver = true,
};

static struct iwl_cfg iwl3945_abg_cfg = {
@@ -2862,6 +2868,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .tx_power_by_driver = true,
};

DEFINE_PCI_DEVICE_TABLE(iwl3945_hw_card_ids) = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 136c290..460aea3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2262,6 +2262,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.monitor_recover_period = IWL_MONITORING_PERIOD,
.temperature_kelvin = true,
.max_event_log_size = 512,
+ .tx_power_by_driver = true,

/*
* Force use of chains B and C for scan RX on 5 GHz band
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7deed86..60d26e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -319,6 +319,7 @@ struct iwl_cfg {
u32 monitor_recover_period;
bool temperature_kelvin;
u32 max_event_log_size;
+ const bool tx_power_by_driver;
u8 scan_antennas[IEEE80211_NUM_BANDS];
};

diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index b071e1b..0faadf3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1647,8 +1647,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
DEBUGFS_ADD_BOOL(disable_chain_noise, dir_rf,
&priv->disable_chain_noise_cal);
- if (((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_4965) ||
- ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_3945))
+ if (priv->cfg->tx_power_by_driver)
DEBUGFS_ADD_BOOL(disable_tx_power, dir_rf,
&priv->disable_tx_power_cal);
return 0;
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 30/47] iwlwifi: remove useless priv->vif check

From: Johannes Berg <[email protected]>

This check is not useful, since we now no
longer dereference priv->vif at this spot.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-power.c b/drivers/net/wireless/iwlwifi/iwl-power.c
index 2655dbd..1fe9d84 100644
--- a/drivers/net/wireless/iwlwifi/iwl-power.c
+++ b/drivers/net/wireless/iwlwifi/iwl-power.c
@@ -317,10 +317,7 @@ int iwl_power_update_mode(struct iwl_priv *priv, bool force)
update_chains = priv->chain_noise_data.state == IWL_CHAIN_NOISE_DONE ||
priv->chain_noise_data.state == IWL_CHAIN_NOISE_ALIVE;

- if (priv->vif)
- dtimper = priv->hw->conf.ps_dtim_period;
- else
- dtimper = 1;
+ dtimper = priv->hw->conf.ps_dtim_period ?: 1;

if (priv->cfg->broken_powersave)
iwl_power_sleep_cam_cmd(priv, &cmd);
--
1.6.3.3


2010-05-10 22:28:28

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 24/47] iwlwifi: remove rts_threshold

From: Johannes Berg <[email protected]>

We never use that member of struct iwl_priv.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 19a5c89..d09c8bc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1211,7 +1211,6 @@ struct iwl_priv {

/* context information */
u8 bssid[ETH_ALEN];
- u16 rts_threshold;
u8 mac_addr[ETH_ALEN];

/*station table variables */
--
1.6.3.3


2010-05-10 22:28:30

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 43/47] iwlwifi: use iwl_sta_id() for TKIP key update

From: Johannes Berg <[email protected]>

With the station ID being stored in the
station struct, which mac80211 gives us
for TKIP phase 1 key updates, we can also
remove the use of iwl_find_station() in
that code path.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 3 +--
drivers/net/wireless/iwlwifi/iwl-sta.c | 21 +++++++++++++--------
drivers/net/wireless/iwlwifi/iwl-sta.h | 2 +-
3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 3265b63..dd26965 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3057,8 +3057,7 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
struct iwl_priv *priv = hw->priv;
IWL_DEBUG_MAC80211(priv, "enter\n");

- iwl_update_tkip_key(priv, keyconf,
- sta ? sta->addr : iwl_bcast_addr,
+ iwl_update_tkip_key(priv, keyconf, sta,
iv32, phase1key);

IWL_DEBUG_MAC80211(priv, "leave\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 8fec026..b8053e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1012,18 +1012,23 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,

void iwl_update_tkip_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
- const u8 *addr, u32 iv32, u16 *phase1key)
+ struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
{
- u8 sta_id = IWL_INVALID_STATION;
+ u8 sta_id;
unsigned long flags;
int i;

- sta_id = iwl_find_station(priv, addr);
- if (sta_id == IWL_INVALID_STATION) {
- IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n",
- addr);
- return;
- }
+ if (sta) {
+ sta_id = iwl_sta_id(sta);
+
+ if (sta_id == IWL_INVALID_STATION) {
+ IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n",
+ sta->addr);
+ return;
+ }
+ } else
+ sta_id = priv->hw_params.bcast_sta_id;
+

if (iwl_scan_cancel(priv)) {
/* cancel scan failed, just live w/ bad key and rely
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index d0ab3f8..08d4bc1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -60,7 +60,7 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
struct ieee80211_key_conf *key, u8 sta_id);
void iwl_update_tkip_key(struct iwl_priv *priv,
struct ieee80211_key_conf *keyconf,
- const u8 *addr, u32 iv32, u16 *phase1key);
+ struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);

void iwl_restore_stations(struct iwl_priv *priv);
void iwl_clear_ucode_stations(struct iwl_priv *priv);
--
1.6.3.3


2010-05-10 22:28:32

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 47/47] iwlwifi: clear driver stations when going down

From: Johannes Berg <[email protected]>

During a hw restart, mac80211 will attempt to
reconfigure all stations. Currently, that fails
and leads to warnings because we still have the
stations marked active. Therefore, clear all
stations when doing down.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 1 +
drivers/net/wireless/iwlwifi/iwl-sta.h | 19 +++++++++++++++++++
drivers/net/wireless/iwlwifi/iwl3945-base.c | 1 +
3 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index dd26965..47563cf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2405,6 +2405,7 @@ static void __iwl_down(struct iwl_priv *priv)

iwl_clear_ucode_stations(priv);
iwl_dealloc_bcast_station(priv);
+ iwl_clear_driver_stations(priv);

/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 6427148..c2a453a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -81,6 +81,25 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);

+/**
+ * iwl_clear_driver_stations - clear knowledge of all stations from driver
+ * @priv: iwl priv struct
+ *
+ * This is called during iwl_down() to make sure that in the case
+ * we're coming there from a hardware restart mac80211 will be
+ * able to reconfigure stations -- if we're getting there in the
+ * normal down flow then the stations will already be cleared.
+ */
+static inline void iwl_clear_driver_stations(struct iwl_priv *priv)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->sta_lock, flags);
+ memset(priv->stations, 0, sizeof(priv->stations));
+ priv->num_stations = 0;
+ spin_unlock_irqrestore(&priv->sta_lock, flags);
+}
+
static inline int iwl_sta_id(struct ieee80211_sta *sta)
{
if (WARN_ON(!sta))
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4916f23..4c78783 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2585,6 +2585,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
/* Station information will now be cleared in device */
iwl_clear_ucode_stations(priv);
iwl_dealloc_bcast_station(priv);
+ iwl_clear_driver_stations(priv);

/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
--
1.6.3.3


2010-05-10 22:53:02

by Zhao, Shanyu

[permalink] [raw]
Subject: RE: [PATCH 01/47] iwlwifi: rename 6000 series Gen2 devices to Gen2a

Yes, there's another patch coming shortly to enable Gen2b devices.

Thanks,
Shanyu

>-----Original Message-----
>From: G?bor Stefanik [mailto:[email protected]]
>Sent: Monday, May 10, 2010 3:47 PM
>To: Chatre, Reinette
>Cc: [email protected]; [email protected]; ipw3945-
>[email protected]; Zhao, Shanyu; Sternberg, Jay E
>Subject: Re: [PATCH 01/47] iwlwifi: rename 6000 series Gen2 devices to Gen2a
>
>What is the reason behind this change? Is Gen2b planned?
>
>On Tue, May 11, 2010 at 12:27 AM, Reinette Chatre
><[email protected]> wrote:
>> From: Shanyu Zhao <[email protected]>
>>
>> Rename the current 6000 series Gen2 devices to Gen2a.
>> Rename the ucode name prefix to iwlwifi-6000g2a.
>> Also corrected the device IDs for Gen2a series devices.
>>
>> Signed-off-by: Jay Sternberg <[email protected]>
>> Signed-off-by: Shanyu Zhao <[email protected]>
>> Signed-off-by: Reinette Chatre <[email protected]>
>> ---
>> ?drivers/net/wireless/iwlwifi/iwl-6000.c | ? 24 +++++++++++++-----------
>> ?drivers/net/wireless/iwlwifi/iwl-agn.c ?| ? ?9 ++++-----
>> ?drivers/net/wireless/iwlwifi/iwl-dev.h ?| ? ?2 +-
>> ?3 files changed, 18 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c
>b/drivers/net/wireless/iwlwifi/iwl-6000.c
>> index 7acef70..f057087 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-6000.c
>> +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
>> @@ -67,9 +67,10 @@
>> ?#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
>> ?#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
>>
>> -#define IWL6000G2_FW_PRE "iwlwifi-6005-"
>> -#define _IWL6000G2_MODULE_FIRMWARE(api) IWL6000G2_FW_PRE #api ".ucode"
>> -#define IWL6000G2_MODULE_FIRMWARE(api) _IWL6000G2_MODULE_FIRMWARE(api)
>> +#define IWL6000G2A_FW_PRE "iwlwifi-6000g2a-"
>> +#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode"
>> +#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api)
>> +
>>
>> ?static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
>> ?{
>> @@ -408,12 +409,10 @@ static const struct iwl_ops iwl6050_ops = {
>> ? ? ? ?.led = &iwlagn_led_ops,
>> ?};
>>
>> -/*
>> - * "i": Internal configuration, use internal Power Amplifier
>> - */
>> -struct iwl_cfg iwl6000g2_2agn_cfg = {
>> - ? ? ? .name = "6000 Series 2x2 AGN Gen2",
>> - ? ? ? .fw_name_pre = IWL6000G2_FW_PRE,
>> +
>> +struct iwl_cfg iwl6000g2a_2agn_cfg = {
>> + ? ? ? .name = "6000 Series 2x2 AGN Gen2a",
>> + ? ? ? .fw_name_pre = IWL6000G2A_FW_PRE,
>> ? ? ? ?.ucode_api_max = IWL6000G2_UCODE_API_MAX,
>> ? ? ? ?.ucode_api_min = IWL6000G2_UCODE_API_MIN,
>> ? ? ? ?.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
>> @@ -442,9 +441,12 @@ struct iwl_cfg iwl6000g2_2agn_cfg = {
>> ? ? ? ?.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
>> ? ? ? ?.chain_noise_scale = 1000,
>> ? ? ? ?.monitor_recover_period = IWL_MONITORING_PERIOD,
>> - ? ? ? .max_event_log_size = 1024,
>> + ? ? ? .max_event_log_size = 512,
>> ?};
>>
>> +/*
>> + * "i": Internal configuration, use internal Power Amplifier
>> + */
>> ?struct iwl_cfg iwl6000i_2agn_cfg = {
>> ? ? ? ?.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
>> ? ? ? ?.fw_name_pre = IWL6000_FW_PRE,
>> @@ -645,4 +647,4 @@ struct iwl_cfg iwl6000_3agn_cfg = {
>>
>> ?MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
>> ?MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
>> -MODULE_FIRMWARE(IWL6000G2_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
>> +MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c
>b/drivers/net/wireless/iwlwifi/iwl-agn.c
>> index dc28376..5cf3822 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-agn.c
>> +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
>> @@ -3789,11 +3789,10 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
>> ? ? ? ?{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
>> ? ? ? ?{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
>>
>> -/* 6x00 Series Gen2 */
>> - ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2_2agn_cfg)},
>> - ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2_2agn_cfg)},
>> - ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2_2agn_cfg)},
>> - ? ? ? {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2_2agn_cfg)},
>> +/* 6x00 Series Gen2a */
>> + ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
>> + ? ? ? {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
>> + ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
>>
>> ?/* 6x50 WiFi/WiMax Series */
>> ? ? ? ?{IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
>> diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h
>b/drivers/net/wireless/iwlwifi/iwl-dev.h
>> index cd3b932..e485465 100644
>> --- a/drivers/net/wireless/iwlwifi/iwl-dev.h
>> +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
>> @@ -57,8 +57,8 @@ extern struct iwl_cfg iwl5100_bgn_cfg;
>> ?extern struct iwl_cfg iwl5100_abg_cfg;
>> ?extern struct iwl_cfg iwl5150_agn_cfg;
>> ?extern struct iwl_cfg iwl5150_abg_cfg;
>> +extern struct iwl_cfg iwl6000g2a_2agn_cfg;
>> ?extern struct iwl_cfg iwl6000i_2agn_cfg;
>> -extern struct iwl_cfg iwl6000g2_2agn_cfg;
>> ?extern struct iwl_cfg iwl6000i_2abg_cfg;
>> ?extern struct iwl_cfg iwl6000i_2bg_cfg;
>> ?extern struct iwl_cfg iwl6000_3agn_cfg;
>> --
>> 1.6.3.3
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-wireless"
>in
>> the body of a message to [email protected]
>> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>>
>
>
>
>--
>Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

2010-05-10 22:28:23

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 04/47] iwlwifi: rename "tx_power" to "chain_tx_power"

From: Wey-Yi Guy <[email protected]>

The "chain_tx_power" debugfs function is to display the tx power per
chain based. Name it "tx_power" is misleading.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index f0d9b72..b071e1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1214,7 +1214,7 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
return ret;
}

-static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
+static ssize_t iwl_dbgfs_chain_tx_power_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos) {

@@ -1565,7 +1565,7 @@ DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
DEBUGFS_READ_FILE_OPS(ucode_general_stats);
DEBUGFS_READ_FILE_OPS(sensitivity);
DEBUGFS_READ_FILE_OPS(chain_noise);
-DEBUGFS_READ_FILE_OPS(tx_power);
+DEBUGFS_READ_FILE_OPS(chain_tx_power);
DEBUGFS_READ_FILE_OPS(power_save_status);
DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
@@ -1624,7 +1624,7 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
- DEBUGFS_ADD_FILE(tx_power, dir_debug, S_IRUSR);
+ DEBUGFS_ADD_FILE(chain_tx_power, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
--
1.6.3.3


2010-05-10 22:28:33

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 46/47] iwlwifi: remove pointless HT check

From: Johannes Berg <[email protected]>

Remove the check before invoking iwl_set_ht_add_station(),
since neither of the conditions in this check makes sense,
as either we pass in a NULL ht_info (first branch) or in
the IBSS case an ht_info with ht_enabled=false.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-sta.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index c15098e..85ed235 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -284,10 +284,12 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
station->sta.sta.sta_id = sta_id;
station->sta.station_flags = 0;

- /* BCAST station and IBSS stations do not work in HT mode */
- if (sta_id != priv->hw_params.bcast_sta_id &&
- priv->iw_mode != NL80211_IFTYPE_ADHOC)
- iwl_set_ht_add_station(priv, sta_id, ht_info);
+ /*
+ * OK to call unconditionally, since local stations (IBSS BSSID
+ * STA and broadcast STA) pass in a NULL ht_info, and mac80211
+ * doesn't allow HT IBSS.
+ */
+ iwl_set_ht_add_station(priv, sta_id, ht_info);

/* 3945 only */
rate = (priv->band == IEEE80211_BAND_5GHZ) ?
--
1.6.3.3


2010-05-10 22:28:23

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 05/47] iwlwifi: use vif iwl_bss_info_changed

From: Johannes Berg <[email protected]>

The iw_mode will always follow the only vif we
have, but using the vif directly seems easier.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 1e11706..d8ee528 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1857,8 +1857,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,

mutex_lock(&priv->mutex);

- if (changes & BSS_CHANGED_BEACON &&
- priv->iw_mode == NL80211_IFTYPE_AP) {
+ if (changes & BSS_CHANGED_BEACON && vif->type == NL80211_IFTYPE_AP) {
dev_kfree_skb(priv->ibss_beacon);
priv->ibss_beacon = ieee80211_beacon_get(hw, vif);
}
@@ -1884,8 +1883,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
}

/* mac80211 only sets assoc when in STATION mode */
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC ||
- bss_conf->assoc) {
+ if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
memcpy(priv->staging_rxon.bssid_addr,
bss_conf->bssid, ETH_ALEN);

@@ -1903,7 +1901,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
* mac80211 decides to do both changes at once because
* it will invoke post_associate.
*/
- if (priv->iw_mode == NL80211_IFTYPE_ADHOC &&
+ if (vif->type == NL80211_IFTYPE_ADHOC &&
changes & BSS_CHANGED_BEACON) {
struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);

--
1.6.3.3


2010-05-10 22:28:27

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 23/47] iwl3945: add plcp error checking

From: Abhijeet Kolekar <[email protected]>

Add plcp error checking for 3945. After threshold of plcp
is reached , it resets the radio

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 67 ++++++++++++++++++++++++++++++-
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +
drivers/net/wireless/iwlwifi/iwl-rx.c | 3 +-
3 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index a4d842a..05d808b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -390,6 +390,67 @@ static void iwl3945_accumulative_statistics(struct iwl_priv *priv,
}
#endif

+/**
+ * iwl3945_good_plcp_health - checks for plcp error.
+ *
+ * When the plcp error is exceeding the thresholds, reset the radio
+ * to improve the throughput.
+ */
+static bool iwl3945_good_plcp_health(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt)
+{
+ bool rc = true;
+ struct iwl3945_notif_statistics current_stat;
+ int combined_plcp_delta;
+ unsigned int plcp_msec;
+ unsigned long plcp_received_jiffies;
+
+ memcpy(&current_stat, pkt->u.raw, sizeof(struct
+ iwl3945_notif_statistics));
+ /*
+ * check for plcp_err and trigger radio reset if it exceeds
+ * the plcp error threshold plcp_delta.
+ */
+ plcp_received_jiffies = jiffies;
+ plcp_msec = jiffies_to_msecs((long) plcp_received_jiffies -
+ (long) priv->plcp_jiffies);
+ priv->plcp_jiffies = plcp_received_jiffies;
+ /*
+ * check to make sure plcp_msec is not 0 to prevent division
+ * by zero.
+ */
+ if (plcp_msec) {
+ combined_plcp_delta =
+ (le32_to_cpu(current_stat.rx.ofdm.plcp_err) -
+ le32_to_cpu(priv->_3945.statistics.rx.ofdm.plcp_err));
+
+ if ((combined_plcp_delta > 0) &&
+ ((combined_plcp_delta * 100) / plcp_msec) >
+ priv->cfg->plcp_delta_threshold) {
+ /*
+ * if plcp_err exceed the threshold, the following
+ * data is printed in csv format:
+ * Text: plcp_err exceeded %d,
+ * Received ofdm.plcp_err,
+ * Current ofdm.plcp_err,
+ * combined_plcp_delta,
+ * plcp_msec
+ */
+ IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
+ "%u, %d, %u mSecs\n",
+ priv->cfg->plcp_delta_threshold,
+ le32_to_cpu(current_stat.rx.ofdm.plcp_err),
+ combined_plcp_delta, plcp_msec);
+ /*
+ * Reset the RF radio due to the high plcp
+ * error rate
+ */
+ rc = false;
+ }
+ }
+ return rc;
+}
+
void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
{
@@ -401,6 +462,7 @@ void iwl3945_hw_rx_statistics(struct iwl_priv *priv,
#ifdef CONFIG_IWLWIFI_DEBUG
iwl3945_accumulative_statistics(priv, (__le32 *)&pkt->u.raw);
#endif
+ iwl_recover_from_statistics(priv, pkt);

memcpy(&priv->_3945.statistics, pkt->u.raw, sizeof(priv->_3945.statistics));
}
@@ -2792,6 +2854,7 @@ static struct iwl_lib_ops iwl3945_lib = {
.config_ap = iwl3945_config_ap,
.manage_ibss_station = iwl3945_manage_ibss_station,
.add_bcast_station = iwl3945_add_bcast_station,
+ .check_plcp_health = iwl3945_good_plcp_health,

.debugfs_ops = {
.rx_stats_read = iwl3945_ucode_rx_stats_read,
@@ -2832,7 +2895,7 @@ static struct iwl_cfg iwl3945_bg_cfg = {
.ht_greenfield_support = false,
.led_compensation = 64,
.broken_powersave = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.tx_power_by_driver = true,
@@ -2853,7 +2916,7 @@ static struct iwl_cfg iwl3945_abg_cfg = {
.ht_greenfield_support = false,
.led_compensation = 64,
.broken_powersave = true,
- .plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
+ .plcp_delta_threshold = IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
.tx_power_by_driver = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 2f664a3..7a3f949 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -441,6 +441,8 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
struct iwl_rx_packet *pkt);
bool iwl_good_ack_health(struct iwl_priv *priv,
struct iwl_rx_packet *pkt);
+void iwl_recover_from_statistics(struct iwl_priv *priv,
+ struct iwl_rx_packet *pkt);
void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
void iwl_reply_statistics(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index d661fce..c7c8d8a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -397,7 +397,7 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
}
EXPORT_SYMBOL(iwl_good_plcp_health);

-static void iwl_recover_from_statistics(struct iwl_priv *priv,
+void iwl_recover_from_statistics(struct iwl_priv *priv,
struct iwl_rx_packet *pkt)
{
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
@@ -428,6 +428,7 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
}
}
}
+EXPORT_SYMBOL(iwl_recover_from_statistics);

void iwl_rx_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb)
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 28/47] iwlwifi: push virtual interface through

From: Johannes Berg <[email protected]>

Rather than keeping every bit of information
around in priv and the virtual interface, add
a virtual interface to many functions and use
the information directly from it.

This removes beacon_int, assoc_capability and
assoc_id from struct iwl_priv.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.h | 8 ++-
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 18 ++++---
drivers/net/wireless/iwlwifi/iwl-agn.c | 52 +++++++++++-----------
drivers/net/wireless/iwlwifi/iwl-agn.h | 2 +-
drivers/net/wireless/iwlwifi/iwl-core.c | 54 +++++++++++------------
drivers/net/wireless/iwlwifi/iwl-core.h | 25 ++++++-----
drivers/net/wireless/iwlwifi/iwl-dev.h | 5 --
drivers/net/wireless/iwlwifi/iwl-scan.c | 13 +++---
drivers/net/wireless/iwlwifi/iwl3945-base.c | 63 +++++++++++++--------------
9 files changed, 118 insertions(+), 122 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index cea824c..8fe24ee 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -261,8 +261,10 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
struct iwl_rx_mem_buffer *rxb);
extern void iwl3945_disable_events(struct iwl_priv *priv);
extern int iwl4965_get_temperature(const struct iwl_priv *priv);
-extern void iwl3945_post_associate(struct iwl_priv *priv);
-extern void iwl3945_config_ap(struct iwl_priv *priv);
+extern void iwl3945_post_associate(struct iwl_priv *priv,
+ struct ieee80211_vif *vif);
+extern void iwl3945_config_ap(struct iwl_priv *priv,
+ struct ieee80211_vif *vif);

/**
* iwl3945_hw_find_station - Find station id for a given BSSID
@@ -288,7 +290,7 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);

/* scanning */
-void iwl3945_request_scan(struct iwl_priv *priv);
+void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);

/* Requires full declaration of iwl_priv before including */
#include "iwl-io.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 50ff313..f05e600 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1114,8 +1114,9 @@ void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
}

static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
- enum ieee80211_band band,
- struct iwl_scan_channel *scan_ch)
+ struct ieee80211_vif *vif,
+ enum ieee80211_band band,
+ struct iwl_scan_channel *scan_ch)
{
const struct ieee80211_supported_band *sband;
const struct iwl_channel_info *ch_info;
@@ -1131,7 +1132,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
}

active_dwell = iwl_get_active_dwell_time(priv, band, 0);
- passive_dwell = iwl_get_passive_dwell_time(priv, band);
+ passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);

if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
@@ -1180,6 +1181,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
}

static int iwl_get_channels_for_scan(struct iwl_priv *priv,
+ struct ieee80211_vif *vif,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
struct iwl_scan_channel *scan_ch)
@@ -1197,7 +1199,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return 0;

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

if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
@@ -1257,7 +1259,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
return added;
}

-void iwlagn_request_scan(struct iwl_priv *priv)
+void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
@@ -1343,7 +1345,7 @@ void iwlagn_request_scan(struct iwl_priv *priv)

IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
spin_lock_irqsave(&priv->lock, flags);
- interval = priv->beacon_int;
+ interval = vif ? vif->bss_conf.beacon_int : 0;
spin_unlock_irqrestore(&priv->lock, flags);

scan->suspend_time = 0;
@@ -1474,12 +1476,12 @@ void iwlagn_request_scan(struct iwl_priv *priv)

if (priv->is_internal_short_scan) {
scan->channel_count =
- iwl_get_single_channel_for_scan(priv, band,
+ iwl_get_single_channel_for_scan(priv, vif, band,
(void *)&scan->data[le16_to_cpu(
scan->tx_cmd.len)]);
} else {
scan->channel_count =
- iwl_get_channels_for_scan(priv, band,
+ iwl_get_channels_for_scan(priv, vif, band,
is_active, n_probes,
(void *)&scan->data[le16_to_cpu(
scan->tx_cmd.len)]);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 7c3363a..270635e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2356,7 +2356,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- iwl_connection_init_rx_config(priv, priv->iw_mode);
+ iwl_connection_init_rx_config(priv, NULL);

if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);
@@ -2729,12 +2729,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data)

#define IWL_DELAY_NEXT_SCAN (HZ*2)

-void iwl_post_associate(struct iwl_priv *priv)
+void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct ieee80211_conf *conf = NULL;
int ret = 0;

- if (priv->iw_mode == NL80211_IFTYPE_AP) {
+ if (!vif || !priv->is_open)
+ return;
+
+ if (vif->type == NL80211_IFTYPE_AP) {
IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}
@@ -2742,10 +2745,6 @@ void iwl_post_associate(struct iwl_priv *priv)
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

-
- if (!priv->vif || !priv->is_open)
- return;
-
iwl_scan_cancel_timeout(priv, 200);

conf = ieee80211_get_hw_conf(priv->hw);
@@ -2753,7 +2752,7 @@ void iwl_post_associate(struct iwl_priv *priv)
priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
iwlcore_commit_rxon(priv);

- iwl_setup_rxon_timing(priv);
+ iwl_setup_rxon_timing(priv, vif);
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
@@ -2767,43 +2766,41 @@ void iwl_post_associate(struct iwl_priv *priv)
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);

- priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
+ priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);

IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
- priv->assoc_id, priv->beacon_int);
+ vif->bss_conf.aid, vif->bss_conf.beacon_int);

- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+ if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;

if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ if (vif->bss_conf.assoc_capability &
+ WLAN_CAPABILITY_SHORT_SLOT_TIME)
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;

- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+ if (vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
}

iwlcore_commit_rxon(priv);

IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- priv->assoc_id, priv->active_rxon.bssid_addr);
+ vif->bss_conf.aid, priv->active_rxon.bssid_addr);

- switch (priv->iw_mode) {
+ switch (vif->type) {
case NL80211_IFTYPE_STATION:
break;
case NL80211_IFTYPE_ADHOC:
- /* assume default assoc id */
- priv->assoc_id = 1;
iwl_send_beacon_cmd(priv);
break;
default:
IWL_ERR(priv, "%s Should not be called in %d mode\n",
- __func__, priv->iw_mode);
+ __func__, vif->type);
break;
}

@@ -2980,7 +2977,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}

-void iwl_config_ap(struct iwl_priv *priv)
+void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
int ret = 0;

@@ -2995,7 +2992,7 @@ void iwl_config_ap(struct iwl_priv *priv)
iwlcore_commit_rxon(priv);

/* RXON Timing */
- iwl_setup_rxon_timing(priv);
+ iwl_setup_rxon_timing(priv, vif);
ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (ret)
@@ -3009,9 +3006,10 @@ void iwl_config_ap(struct iwl_priv *priv)
if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);

- /* FIXME: what should be the assoc_id for AP? */
- priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+ priv->staging_rxon.assoc_id = 0;
+
+ if (vif->bss_conf.assoc_capability &
+ WLAN_CAPABILITY_SHORT_PREAMBLE)
priv->staging_rxon.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK;
else
@@ -3019,15 +3017,15 @@ void iwl_config_ap(struct iwl_priv *priv)
~RXON_FLG_SHORT_PREAMBLE_MSK;

if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
- if (priv->assoc_capability &
- WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ if (vif->bss_conf.assoc_capability &
+ WLAN_CAPABILITY_SHORT_SLOT_TIME)
priv->staging_rxon.flags |=
RXON_FLG_SHORT_SLOT_MSK;
else
priv->staging_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK;

- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+ if (vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 4a1e7b2..f52bedb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -171,7 +171,7 @@ static inline bool iwl_is_tx_success(u32 status)
}

/* scan */
-void iwlagn_request_scan(struct iwl_priv *priv);
+void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);

/* station mgmt */
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 246538a..68c3693 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -480,7 +480,7 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
return new_val;
}

-void iwl_setup_rxon_timing(struct iwl_priv *priv)
+void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
u64 tsf;
s32 interval_tm, rem;
@@ -494,15 +494,14 @@ void iwl_setup_rxon_timing(struct iwl_priv *priv)
priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);

- if (priv->iw_mode == NL80211_IFTYPE_STATION) {
- beacon_int = priv->beacon_int;
- priv->rxon_timing.atim_window = 0;
- } else {
- beacon_int = priv->vif->bss_conf.beacon_int;
+ beacon_int = vif->bss_conf.beacon_int;

+ if (vif->type == NL80211_IFTYPE_ADHOC) {
/* TODO: we need to get atim_window from upper stack
* for now we set to 0 */
priv->rxon_timing.atim_window = 0;
+ } else {
+ priv->rxon_timing.atim_window = 0;
}

beacon_int = iwl_adjust_beacon_interval(beacon_int,
@@ -894,8 +893,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
}
EXPORT_SYMBOL(iwl_set_rxon_channel);

-void iwl_set_flags_for_band(struct iwl_priv *priv,
- enum ieee80211_band band)
+static void iwl_set_flags_for_band(struct iwl_priv *priv,
+ enum ieee80211_band band,
+ struct ieee80211_vif *vif)
{
if (band == IEEE80211_BAND_5GHZ) {
priv->staging_rxon.flags &=
@@ -904,12 +904,12 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
} else {
/* Copied from iwl_post_associate() */
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;

- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+ if (vif && vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;

priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
@@ -921,13 +921,18 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
/*
* initialize rxon structure with default values from eeprom
*/
-void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
+void iwl_connection_init_rx_config(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
{
const struct iwl_channel_info *ch_info;
+ enum nl80211_iftype type = NL80211_IFTYPE_STATION;
+
+ if (vif)
+ type = vif->type;

memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));

- switch (mode) {
+ switch (type) {
case NL80211_IFTYPE_AP:
priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
break;
@@ -945,7 +950,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
break;

default:
- IWL_ERR(priv, "Unsupported interface type %d\n", mode);
+ IWL_ERR(priv, "Unsupported interface type %d\n", type);
break;
}

@@ -967,7 +972,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
priv->band = ch_info->band;

- iwl_set_flags_for_band(priv, priv->band);
+ iwl_set_flags_for_band(priv, priv->band, vif);

priv->staging_rxon.ofdm_basic_rates =
(IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -1793,7 +1798,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,

static inline void iwl_set_no_assoc(struct iwl_priv *priv)
{
- priv->assoc_id = 0;
iwl_led_disassociate(priv);
/*
* inform the ucode that there is no longer an
@@ -1827,7 +1831,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
}

if (changes & BSS_CHANGED_BEACON_INT) {
- priv->beacon_int = bss_conf->beacon_int;
/* TODO: in AP mode, do something to make this take effect */
}

@@ -1917,20 +1920,17 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
if (changes & BSS_CHANGED_ASSOC) {
IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
if (bss_conf->assoc) {
- priv->assoc_id = bss_conf->aid;
- priv->beacon_int = bss_conf->beacon_int;
priv->timestamp = bss_conf->timestamp;
- priv->assoc_capability = bss_conf->assoc_capability;

iwl_led_associate(priv);

if (!iwl_is_rfkill(priv))
- priv->cfg->ops->lib->post_associate(priv);
+ priv->cfg->ops->lib->post_associate(priv, vif);
} else
iwl_set_no_assoc(priv);
}

- if (changes && iwl_is_associated(priv) && priv->assoc_id) {
+ if (changes && iwl_is_associated(priv) && bss_conf->aid) {
IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
changes);
ret = iwl_send_rxon_assoc(priv);
@@ -1947,7 +1947,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
memcpy(priv->staging_rxon.bssid_addr,
bss_conf->bssid, ETH_ALEN);
memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
- iwlcore_config_ap(priv);
+ iwlcore_config_ap(priv, vif);
} else
iwl_set_no_assoc(priv);
}
@@ -1987,14 +1987,13 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)

priv->ibss_beacon = skb;

- priv->assoc_id = 0;
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
priv->timestamp = le64_to_cpu(timestamp);

IWL_DEBUG_MAC80211(priv, "leave\n");
spin_unlock_irqrestore(&priv->lock, flags);

- priv->cfg->ops->lib->post_associate(priv);
+ priv->cfg->ops->lib->post_associate(priv, priv->vif);

return 0;
}
@@ -2002,7 +2001,7 @@ EXPORT_SYMBOL(iwl_mac_beacon_update);

static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
- iwl_connection_init_rx_config(priv, vif->type);
+ iwl_connection_init_rx_config(priv, vif);

if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);
@@ -2176,7 +2175,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
iwl_set_rxon_channel(priv, conf->channel);
iwl_set_rxon_ht(priv, ht_conf);

- iwl_set_flags_for_band(priv, conf->channel->band);
+ iwl_set_flags_for_band(priv, conf->channel->band, priv->vif);
spin_unlock_irqrestore(&priv->lock, flags);
if (iwl_is_associated(priv) &&
(le16_to_cpu(priv->active_rxon.channel) != ch) &&
@@ -2259,8 +2258,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
spin_unlock_irqrestore(&priv->lock, flags);

spin_lock_irqsave(&priv->lock, flags);
- priv->assoc_id = 0;
- priv->assoc_capability = 0;

/* new association get rid of ibss beacon skb */
if (priv->ibss_beacon)
@@ -2268,7 +2265,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)

priv->ibss_beacon = NULL;

- priv->beacon_int = priv->vif->bss_conf.beacon_int;
priv->timestamp = 0;

spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7a3f949..1774ce9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -106,7 +106,7 @@ struct iwl_hcmd_utils_ops {
__le32 *tx_flags);
int (*calc_rssi)(struct iwl_priv *priv,
struct iwl_rx_phy_res *rx_resp);
- void (*request_scan)(struct iwl_priv *priv);
+ void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
};

struct iwl_apm_ops {
@@ -180,8 +180,9 @@ struct iwl_lib_ops {
/* power */
int (*send_tx_power) (struct iwl_priv *priv);
void (*update_chain_flags)(struct iwl_priv *priv);
- void (*post_associate) (struct iwl_priv *priv);
- void (*config_ap) (struct iwl_priv *priv);
+ void (*post_associate)(struct iwl_priv *priv,
+ struct ieee80211_vif *vif);
+ void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif);
irqreturn_t (*isr) (int irq, void *data);

/* eeprom operations (as defined in iwl-eeprom.h) */
@@ -334,8 +335,8 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
struct ieee80211_sta_ht_cap *sta_ht_inf);
-void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band);
-void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode);
+void iwl_connection_init_rx_config(struct iwl_priv *priv,
+ struct ieee80211_vif *vif);
int iwl_set_decrypted_flag(struct iwl_priv *priv,
struct ieee80211_hdr *hdr,
u32 decrypt_res,
@@ -345,7 +346,7 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
unsigned int changed_flags,
unsigned int *total_flags, u64 multicast);
int iwl_set_hw_params(struct iwl_priv *priv);
-void iwl_post_associate(struct iwl_priv *priv);
+void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwl_bss_info_changed(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_bss_conf *bss_conf,
@@ -357,7 +358,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
-void iwl_config_ap(struct iwl_priv *priv);
+void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
int iwl_alloc_txq_mem(struct iwl_priv *priv);
void iwl_free_txq_mem(struct iwl_priv *priv);
@@ -520,7 +521,8 @@ 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);
+ enum ieee80211_band band,
+ struct ieee80211_vif *vif);
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);
@@ -684,7 +686,7 @@ extern int iwl_send_lq_cmd(struct iwl_priv *priv,
void iwl_apm_stop(struct iwl_priv *priv);
int iwl_apm_init(struct iwl_priv *priv);

-void iwl_setup_rxon_timing(struct iwl_priv *priv);
+void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif);
static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
{
return priv->cfg->ops->hcmd->rxon_assoc(priv);
@@ -693,9 +695,10 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
{
return priv->cfg->ops->hcmd->commit_rxon(priv);
}
-static inline void iwlcore_config_ap(struct iwl_priv *priv)
+static inline void iwlcore_config_ap(struct iwl_priv *priv,
+ struct ieee80211_vif *vif)
{
- priv->cfg->ops->lib->config_ap(priv);
+ priv->cfg->ops->lib->config_ap(priv, vif);
}
static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
struct iwl_priv *priv, enum ieee80211_band band)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d09c8bc..bcdb663 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1243,7 +1243,6 @@ struct iwl_priv {

/* Last Rx'd beacon timestamp */
u64 timestamp;
- u16 beacon_int;
struct ieee80211_vif *vif;

union {
@@ -1305,10 +1304,6 @@ struct iwl_priv {
struct iwl_hw_params hw_params;

u32 inta_mask;
- /* Current association information needed to configure the
- * hardware */
- u16 assoc_id;
- u16 assoc_capability;

struct iwl_qos_info qos_data;

diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 28e2d86..32ca848 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -264,7 +264,8 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
EXPORT_SYMBOL(iwl_get_active_dwell_time);

u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
- enum ieee80211_band band)
+ enum ieee80211_band band,
+ struct ieee80211_vif *vif)
{
u16 passive = (band == IEEE80211_BAND_2GHZ) ?
IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -274,7 +275,7 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *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;
+ passive = vif ? vif->bss_conf.beacon_int : 0;
if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
passive = IWL_PASSIVE_DWELL_BASE;
passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
@@ -294,7 +295,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
}
EXPORT_SYMBOL(iwl_init_scan_params);

-static int iwl_scan_initiate(struct iwl_priv *priv)
+static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
WARN_ON(!mutex_is_locked(&priv->mutex));

@@ -306,7 +307,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
if (WARN_ON(!priv->cfg->ops->utils->request_scan))
return -EOPNOTSUPP;

- priv->cfg->ops->utils->request_scan(priv);
+ priv->cfg->ops->utils->request_scan(priv, vif);

return 0;
}
@@ -347,7 +348,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
priv->scan_band = req->channels[0]->band;
priv->scan_request = req;

- ret = iwl_scan_initiate(priv);
+ ret = iwl_scan_initiate(priv, vif);

IWL_DEBUG_MAC80211(priv, "leave\n");

@@ -398,7 +399,7 @@ void iwl_bg_start_internal_scan(struct work_struct *work)
if (WARN_ON(!priv->cfg->ops->utils->request_scan))
goto unlock;

- priv->cfg->ops->utils->request_scan(priv);
+ priv->cfg->ops->utils->request_scan(priv, NULL);
unlock:
mutex_unlock(&priv->mutex);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 77ab00b..85a46ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1847,7 +1847,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
enum ieee80211_band band,
u8 is_active, u8 n_probes,
- struct iwl3945_scan_channel *scan_ch)
+ struct iwl3945_scan_channel *scan_ch,
+ struct ieee80211_vif *vif)
{
struct ieee80211_channel *chan;
const struct ieee80211_supported_band *sband;
@@ -1861,7 +1862,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
return 0;

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

if (passive_dwell <= active_dwell)
passive_dwell = active_dwell + 1;
@@ -2543,7 +2544,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
} else {
/* Initialize our rx_config data */
- iwl_connection_init_rx_config(priv, priv->iw_mode);
+ iwl_connection_init_rx_config(priv, NULL);
}

/* Configure Bluetooth device coexistence support */
@@ -2811,7 +2812,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data)

}

-void iwl3945_request_scan(struct iwl_priv *priv)
+void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
struct iwl_host_cmd cmd = {
.id = REPLY_SCAN_CMD,
@@ -2892,7 +2893,7 @@ void iwl3945_request_scan(struct iwl_priv *priv)
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");

spin_lock_irqsave(&priv->lock, flags);
- interval = priv->beacon_int;
+ interval = vif ? vif->bss_conf.beacon_int : 0;
spin_unlock_irqrestore(&priv->lock, flags);

scan->suspend_time = 0;
@@ -2987,7 +2988,7 @@ void iwl3945_request_scan(struct iwl_priv *priv)

scan->channel_count =
iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
- (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]);
+ (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif);

if (scan->channel_count == 0) {
IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
@@ -3060,26 +3061,25 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
mutex_unlock(&priv->mutex);
}

-void iwl3945_post_associate(struct iwl_priv *priv)
+void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
int rc = 0;
struct ieee80211_conf *conf = NULL;

- if (priv->iw_mode == NL80211_IFTYPE_AP) {
+ if (!vif || !priv->is_open)
+ return;
+
+ if (vif->type == NL80211_IFTYPE_AP) {
IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
return;
}

-
IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
- priv->assoc_id, priv->active_rxon.bssid_addr);
+ vif->bss_conf.aid, priv->active_rxon.bssid_addr);

if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return;

- if (!priv->vif || !priv->is_open)
- return;
-
iwl_scan_cancel_timeout(priv, 200);

conf = ieee80211_get_hw_conf(priv->hw);
@@ -3088,7 +3088,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
iwlcore_commit_rxon(priv);

memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
- iwl_setup_rxon_timing(priv);
+ iwl_setup_rxon_timing(priv, vif);
rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing), &priv->rxon_timing);
if (rc)
@@ -3097,40 +3097,38 @@ void iwl3945_post_associate(struct iwl_priv *priv)

priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;

- priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
+ priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);

IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
- priv->assoc_id, priv->beacon_int);
+ vif->bss_conf.aid, vif->bss_conf.beacon_int);

- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+ if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;

if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
else
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;

- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+ if (vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
-
}

iwlcore_commit_rxon(priv);

- switch (priv->iw_mode) {
+ switch (vif->type) {
case NL80211_IFTYPE_STATION:
iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
break;
case NL80211_IFTYPE_ADHOC:
- priv->assoc_id = 1;
iwl3945_send_beacon_cmd(priv);
break;
default:
- IWL_ERR(priv, "%s Should not be called in %d mode\n",
- __func__, priv->iw_mode);
+ IWL_ERR(priv, "%s Should not be called in %d mode\n",
+ __func__, vif->type);
break;
}
}
@@ -3254,7 +3252,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
return NETDEV_TX_OK;
}

-void iwl3945_config_ap(struct iwl_priv *priv)
+void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
int rc = 0;

@@ -3270,7 +3268,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)

/* RXON Timing */
memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
- iwl_setup_rxon_timing(priv);
+ iwl_setup_rxon_timing(priv, vif);
rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
sizeof(priv->rxon_timing),
&priv->rxon_timing);
@@ -3278,9 +3276,10 @@ void iwl3945_config_ap(struct iwl_priv *priv)
IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
"Attempting to continue.\n");

- /* FIXME: what should be the assoc_id for AP? */
- priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id);
- if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
+ priv->staging_rxon.assoc_id = 0;
+
+ if (vif->bss_conf.assoc_capability &
+ WLAN_CAPABILITY_SHORT_PREAMBLE)
priv->staging_rxon.flags |=
RXON_FLG_SHORT_PREAMBLE_MSK;
else
@@ -3288,15 +3287,15 @@ void iwl3945_config_ap(struct iwl_priv *priv)
~RXON_FLG_SHORT_PREAMBLE_MSK;

if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
- if (priv->assoc_capability &
- WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ if (vif->bss_conf.assoc_capability &
+ WLAN_CAPABILITY_SHORT_SLOT_TIME)
priv->staging_rxon.flags |=
RXON_FLG_SHORT_SLOT_MSK;
else
priv->staging_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK;

- if (priv->iw_mode == NL80211_IFTYPE_ADHOC)
+ if (vif->type == NL80211_IFTYPE_ADHOC)
priv->staging_rxon.flags &=
~RXON_FLG_SHORT_SLOT_MSK;
}
--
1.6.3.3


2010-05-10 22:28:25

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 11/47] iwlwifi: checking for all the possible failure cases

From: Wey-Yi Guy <[email protected]>

Multiple error condition require fw/rf reset, driver should check all
the possible errors as long as the error checking functions for the
devices are available.

Reported-by: Reinette Chatre <[email protected]>
Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-rx.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 1dff14a..d661fce 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -412,9 +412,11 @@ static void iwl_recover_from_statistics(struct iwl_priv *priv,
*/
IWL_ERR(priv, "low ack count detected, "
"restart firmware\n");
- iwl_force_reset(priv, IWL_FW_RESET);
+ if (!iwl_force_reset(priv, IWL_FW_RESET))
+ return;
}
- } else if (priv->cfg->ops->lib->check_plcp_health) {
+ }
+ if (priv->cfg->ops->lib->check_plcp_health) {
if (!priv->cfg->ops->lib->check_plcp_health(
priv, pkt)) {
/*
--
1.6.3.3


2010-05-10 22:28:26

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 17/47] iwlagn: show and store firmware build number

From: Johannes Berg <[email protected]>

We currently display the build number only if debugging
is enabled, but it is really helpful so show it all the
time. Also store it so it can be retrieved later via
ethtool.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 25 +++++++++++++++----------
1 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index dd1324d..f9c9c08 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1552,6 +1552,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
u32 inst_size, data_size, init_size, init_data_size, boot_size;
int err;
u16 eeprom_ver;
+ char buildstr[25];

if (!ucode_raw) {
IWL_ERR(priv, "request for firmware file '%s' failed.\n",
@@ -1599,22 +1600,26 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
"from http://www.intellinuxwireless.org.\n",
api_max, api_ver);

- IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u\n",
- IWL_UCODE_MAJOR(priv->ucode_ver),
- IWL_UCODE_MINOR(priv->ucode_ver),
- IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
+ if (build)
+ sprintf(buildstr, " build %u", build);
+ else
+ buildstr[0] = '\0';
+
+ IWL_INFO(priv, "loaded firmware version %u.%u.%u.%u%s\n",
+ IWL_UCODE_MAJOR(priv->ucode_ver),
+ IWL_UCODE_MINOR(priv->ucode_ver),
+ IWL_UCODE_API(priv->ucode_ver),
+ IWL_UCODE_SERIAL(priv->ucode_ver),
+ buildstr);

snprintf(priv->hw->wiphy->fw_version,
sizeof(priv->hw->wiphy->fw_version),
- "%u.%u.%u.%u",
+ "%u.%u.%u.%u%s",
IWL_UCODE_MAJOR(priv->ucode_ver),
IWL_UCODE_MINOR(priv->ucode_ver),
IWL_UCODE_API(priv->ucode_ver),
- IWL_UCODE_SERIAL(priv->ucode_ver));
-
- if (build)
- IWL_DEBUG_INFO(priv, "Build %u\n", build);
+ IWL_UCODE_SERIAL(priv->ucode_ver),
+ buildstr);

eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
--
1.6.3.3


2010-05-10 22:28:25

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 12/47] iwlwifi: dump firmware build info in error case

From: Shanyu Zhao <[email protected]>

Dump the firmware version and build number in case of firmware SW
error. This would help firmware engineer analyze the error log.

Requested-by: Jay Sternberg <[email protected]>
Signed-off-by: Shanyu Zhao <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 0c3b984..d609414 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1068,6 +1068,9 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
/* Cancel currently queued command. */
clear_bit(STATUS_HCMD_ACTIVE, &priv->status);

+ IWL_ERR(priv, "Loaded firmware version: %s\n",
+ priv->hw->wiphy->fw_version);
+
priv->cfg->ops->lib->dump_nic_error_log(priv);
if (priv->cfg->ops->lib->dump_csr)
priv->cfg->ops->lib->dump_csr(priv);
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 31/47] iwlwifi: use vif in iwl_ht_conf

From: Johannes Berg <[email protected]>

Pass the virtual interface pointer to iwl_ht_conf()
so it doesn't need to rely on iw_mode and other
global variables.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 68c3693..d7a3620 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1740,10 +1740,11 @@ int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
EXPORT_SYMBOL(iwl_mac_conf_tx);

static void iwl_ht_conf(struct iwl_priv *priv,
- struct ieee80211_bss_conf *bss_conf)
+ struct ieee80211_vif *vif)
{
struct iwl_ht_config *ht_conf = &priv->current_ht_config;
struct ieee80211_sta *sta;
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;

IWL_DEBUG_MAC80211(priv, "enter:\n");

@@ -1757,10 +1758,10 @@ static void iwl_ht_conf(struct iwl_priv *priv,

ht_conf->single_chain_sufficient = false;

- switch (priv->iw_mode) {
+ switch (vif->type) {
case NL80211_IFTYPE_STATION:
rcu_read_lock();
- sta = ieee80211_find_sta(priv->vif, priv->bssid);
+ sta = ieee80211_find_sta(vif, bss_conf->bssid);
if (sta) {
struct ieee80211_sta_ht_cap *ht_cap = &sta->ht_cap;
int maxstreams;
@@ -1911,7 +1912,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
}

if (changes & BSS_CHANGED_HT) {
- iwl_ht_conf(priv, bss_conf);
+ iwl_ht_conf(priv, vif);

if (priv->cfg->ops->hcmd->set_rxon_chain)
priv->cfg->ops->hcmd->set_rxon_chain(priv);
--
1.6.3.3


2010-05-10 22:28:32

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 38/47] iwlwifi: provide more comments for cfg structure

From: Wey-Yi Guy <[email protected]>

Provide comments for newly added cfg parameters

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index d80aa6c..7e5a5ba 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -247,6 +247,18 @@ struct iwl_mod_params {
* @support_wimax_coexist: support wimax/wifi co-exist
* @plcp_delta_threshold: plcp error rate threshold used to trigger
* radio tuning when there is a high receiving plcp error rate
+ * @chain_noise_scale: default chain noise scale used for gain computation
+ * @monitor_recover_period: default timer used to check stuck queues
+ * @temperature_kelvin: temperature report by uCode in kelvin
+ * @max_event_log_size: size of event log buffer size for ucode event logging
+ * @tx_power_by_driver: tx power calibration performed by driver
+ * instead of uCode
+ * @ucode_tracing: support ucode continuous tracing
+ * @sensitivity_calib_by_driver: driver has the capability to perform
+ * sensitivity calibration operation
+ * @chain_noise_calib_by_driver: driver has the capability to perform
+ * chain noise calibration operation
+ * @scan_antennas: available antenna for scan operation
*
* We enable the driver to be backward compatible wrt API version. The
* driver specifies which APIs it supports (with @ucode_api_max being the
--
1.6.3.3


2010-05-10 22:28:24

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 07/47] iwlwifi: use .cfg to enable/disable continuous ucode trace

From: Wey-Yi Guy <[email protected]>

Instead of checking device type for enable/disable continuous ucode
trace function; put it in .cfg for better control and more
flexibilities.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-1000.c | 2 ++
drivers/net/wireless/iwlwifi/iwl-4965.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-5000.c | 7 +++++++
drivers/net/wireless/iwlwifi/iwl-6000.c | 7 +++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 3 ++-
6 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index fb59af2..f9f8a56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -260,6 +260,7 @@ struct iwl_cfg iwl1000_bgn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl1000_bg_cfg = {
@@ -289,6 +290,7 @@ struct iwl_cfg iwl1000_bg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 128,
+ .ucode_tracing = true,
};

MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 460aea3..a756fd4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2263,7 +2263,7 @@ struct iwl_cfg iwl4965_agn_cfg = {
.temperature_kelvin = true,
.max_event_log_size = 512,
.tx_power_by_driver = true,
-
+ .ucode_tracing = true,
/*
* Force use of chains B and C for scan RX on 5 GHz band
* because the device has off-channel reception on chain A.
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 115d3ea..c32db49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -466,6 +466,7 @@ struct iwl_cfg iwl5300_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl5100_bgn_cfg = {
@@ -494,6 +495,7 @@ struct iwl_cfg iwl5100_bgn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl5100_abg_cfg = {
@@ -520,6 +522,7 @@ struct iwl_cfg iwl5100_abg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl5100_agn_cfg = {
@@ -548,6 +551,7 @@ struct iwl_cfg iwl5100_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl5350_agn_cfg = {
@@ -576,6 +580,7 @@ struct iwl_cfg iwl5350_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl5150_agn_cfg = {
@@ -604,6 +609,7 @@ struct iwl_cfg iwl5150_agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl5150_abg_cfg = {
@@ -630,6 +636,7 @@ struct iwl_cfg iwl5150_abg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

MODULE_FIRMWARE(IWL5000_MODULE_FIRMWARE(IWL5000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index f057087..7cd45fe 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -442,6 +442,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 512,
+ .ucode_tracing = true,
};

/*
@@ -479,6 +480,7 @@ struct iwl_cfg iwl6000i_2agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl6000i_2abg_cfg = {
@@ -511,6 +513,7 @@ struct iwl_cfg iwl6000i_2abg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl6000i_2bg_cfg = {
@@ -543,6 +546,7 @@ struct iwl_cfg iwl6000i_2bg_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl6050_2agn_cfg = {
@@ -577,6 +581,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
.chain_noise_scale = 1500,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl6050_2abg_cfg = {
@@ -609,6 +614,7 @@ struct iwl_cfg iwl6050_2abg_cfg = {
.chain_noise_scale = 1500,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
+ .ucode_tracing = true,
};

struct iwl_cfg iwl6000_3agn_cfg = {
@@ -643,6 +649,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
.max_event_log_size = 1024,
+ .ucode_tracing = true,
};

MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 60d26e4..5034dc0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -320,6 +320,7 @@ struct iwl_cfg {
bool temperature_kelvin;
u32 max_event_log_size;
const bool tx_power_by_driver;
+ const bool ucode_tracing;
u8 scan_antennas[IEEE80211_NUM_BANDS];
};

diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 0faadf3..59355fa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1640,8 +1640,9 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) != CSR_HW_REV_TYPE_3945) {
DEBUGFS_ADD_FILE(sensitivity, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
- DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
}
+ if (priv->cfg->ucode_tracing)
+ DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
DEBUGFS_ADD_BOOL(disable_sensitivity, dir_rf, &priv->disable_sens_cal);
--
1.6.3.3


2010-05-10 22:28:31

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 42/47] iwlagn: use iwl_sta_id() for aggregation

From: Johannes Berg <[email protected]>

With the station ID being stored in the
station struct, which mac80211 gives us
for aggregation callbacks, we can also
remove the use of iwl_find_station() in
those code paths.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 21 ++++++++-------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++----
drivers/net/wireless/iwlwifi/iwl-agn.h | 4 ++--
drivers/net/wireless/iwlwifi/iwl-sta.c | 13 +++++++------
drivers/net/wireless/iwlwifi/iwl-sta.h | 7 ++++---
5 files changed, 25 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 89c85d1..c402bfc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -962,7 +962,7 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_priv *priv)
}

int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
- const u8 *ra, u16 tid, u16 *ssn)
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
int sta_id;
int tx_fifo;
@@ -976,9 +976,9 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
return tx_fifo;

IWL_WARN(priv, "%s on ra = %pM tid = %d\n",
- __func__, ra, tid);
+ __func__, sta->addr, tid);

- sta_id = iwl_find_station(priv, ra);
+ sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Start AGG on invalid station\n");
return -ENXIO;
@@ -1012,7 +1012,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(vif, ra, tid);
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
} else {
IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
tid_data->tfds_in_queue);
@@ -1022,23 +1022,18 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
}

int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
- const u8 *ra, u16 tid)
+ struct ieee80211_sta *sta, u16 tid)
{
int tx_fifo_id, txq_id, sta_id, ssn = -1;
struct iwl_tid_data *tid_data;
int write_ptr, read_ptr;
unsigned long flags;

- if (!ra) {
- IWL_ERR(priv, "ra = NULL\n");
- return -EINVAL;
- }
-
tx_fifo_id = get_fifo_from_tid(tid);
if (unlikely(tx_fifo_id < 0))
return tx_fifo_id;

- sta_id = iwl_find_station(priv, ra);
+ sta_id = iwl_sta_id(sta);

if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
@@ -1048,7 +1043,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
if (priv->stations[sta_id].tid[tid].agg.state ==
IWL_EMPTYING_HW_QUEUE_ADDBA) {
IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
- ieee80211_stop_tx_ba_cb_irqsafe(vif, ra, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
return 0;
}
@@ -1085,7 +1080,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
tx_fifo_id);
spin_unlock_irqrestore(&priv->lock, flags);

- ieee80211_stop_tx_ba_cb_irqsafe(vif, ra, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);

return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 8a4b830..3265b63 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3154,17 +3154,17 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
switch (action) {
case IEEE80211_AMPDU_RX_START:
IWL_DEBUG_HT(priv, "start Rx\n");
- return iwl_sta_rx_agg_start(priv, sta->addr, tid, *ssn);
+ return iwl_sta_rx_agg_start(priv, sta, tid, *ssn);
case IEEE80211_AMPDU_RX_STOP:
IWL_DEBUG_HT(priv, "stop Rx\n");
- ret = iwl_sta_rx_agg_stop(priv, sta->addr, tid);
+ ret = iwl_sta_rx_agg_stop(priv, sta, tid);
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return 0;
else
return ret;
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT(priv, "start Tx\n");
- ret = iwlagn_tx_agg_start(priv, vif, sta->addr, tid, ssn);
+ ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn);
if (ret == 0) {
priv->_agn.agg_tids_count++;
IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
@@ -3173,7 +3173,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT(priv, "stop Tx\n");
- ret = iwlagn_tx_agg_stop(priv, vif, sta->addr, tid);
+ ret = iwlagn_tx_agg_stop(priv, vif, sta, tid);
if ((ret == 0) && (priv->_agn.agg_tids_count > 0)) {
priv->_agn.agg_tids_count--;
IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index c441773..2d74805 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -136,9 +136,9 @@ void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *info);
int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
- const u8 *ra, u16 tid, u16 *ssn);
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn);
int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
- const u8 *ra, u16 tid);
+ struct ieee80211_sta *sta, u16 tid);
int iwlagn_txq_check_empty(struct iwl_priv *priv,
int sta_id, u8 tid, int txq_id);
void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 4be7940..8fec026 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1324,13 +1324,13 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
}
EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);

-int iwl_sta_rx_agg_start(struct iwl_priv *priv,
- const u8 *addr, int tid, u16 ssn)
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid, u16 ssn)
{
unsigned long flags;
int sta_id;

- sta_id = iwl_find_station(priv, addr);
+ sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION)
return -ENXIO;

@@ -1343,16 +1343,17 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv,
spin_unlock_irqrestore(&priv->sta_lock, flags);

return iwl_send_add_sta(priv, &priv->stations[sta_id].sta,
- CMD_ASYNC);
+ CMD_ASYNC);
}
EXPORT_SYMBOL(iwl_sta_rx_agg_start);

-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid)
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid)
{
unsigned long flags;
int sta_id;

- sta_id = iwl_find_station(priv, addr);
+ sta_id = iwl_sta_id(sta);
if (sta_id == IWL_INVALID_STATION) {
IWL_ERR(priv, "Invalid station for AGG tid %d\n", tid);
return -ENXIO;
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 646f644..d0ab3f8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -80,9 +80,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
-int iwl_sta_rx_agg_start(struct iwl_priv *priv,
- const u8 *addr, int tid, u16 ssn);
-int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid);
+int iwl_sta_rx_agg_start(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid, u16 ssn);
+int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
+ int tid);
void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);

--
1.6.3.3


2010-05-10 22:28:32

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 45/47] iwlwifi: rename iwl_add_local_station

From: Johannes Berg <[email protected]>

This function is now only used for the special
IBSS BSSID station, so rename it to indicate
this. The new name is iwl_add_bssid_station.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-sta.c | 9 +++------
drivers/net/wireless/iwlwifi/iwl-sta.h | 2 +-
4 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 306e23a..0eb0faa 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2465,7 +2465,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
int ret;

if (add) {
- ret = iwl_add_local_station(priv, vif->bss_conf.bssid, false,
+ ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false,
&vif_priv->ibss_bssid_sta_id);
if (ret)
return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 81de88e..637d7b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1523,7 +1523,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;

if (add)
- return iwl_add_local_station(priv, vif->bss_conf.bssid, true,
+ return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true,
&vif_priv->ibss_bssid_sta_id);
return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
vif->bss_conf.bssid);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index ba36df5..c15098e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -417,14 +417,11 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
}

/*
- * iwl_add_local_station - Add stations not requested by mac80211
- *
- * This will be either the broadcast station or the bssid station needed by
- * ad-hoc.
+ * iwl_add_bssid_station - Add the special IBSS BSSID station
*
* Function sleeps.
*/
-int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
+int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
u8 *sta_id_r)
{
int ret;
@@ -468,7 +465,7 @@ int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,

return 0;
}
-EXPORT_SYMBOL(iwl_add_local_station);
+EXPORT_SYMBOL(iwl_add_bssid_station);

/**
* iwl_sta_ucode_deactivate - deactivate ucode status for a station
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 6872bcf..6427148 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -63,7 +63,7 @@ void iwl_dealloc_bcast_station(struct iwl_priv *priv);
int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_send_add_sta(struct iwl_priv *priv,
struct iwl_addsta_cmd *sta, u8 flags);
-int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
+int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
u8 *sta_id_r);
int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
bool is_ap,
--
1.6.3.3


2010-05-10 22:28:28

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 21/47] iwlagn: prepare for new firmware file format

From: Johannes Berg <[email protected]>

Currently the first four bytes in a firmware file
indicate the major, minor and api versions as well
as the serial number. These combined can never be
zero, so we can use that special case for a new,
future, file format.

This patch simply shuffles the code and prepares
for that new format.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn.c | 291 ++++++++++++++++++--------------
1 files changed, 168 insertions(+), 123 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 70094bb..65ae636 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1534,6 +1534,91 @@ static int __must_check iwl_request_firmware(struct iwl_priv *priv, bool first)
iwl_ucode_callback);
}

+struct iwlagn_firmware_pieces {
+ const void *inst, *data, *init, *init_data, *boot;
+ size_t inst_size, data_size, init_size, init_data_size, boot_size;
+
+ u32 build;
+};
+
+static int iwlagn_load_legacy_firmware(struct iwl_priv *priv,
+ const struct firmware *ucode_raw,
+ struct iwlagn_firmware_pieces *pieces)
+{
+ struct iwl_ucode_header *ucode = (void *)ucode_raw->data;
+ u32 api_ver, hdr_size;
+ const u8 *src;
+
+ priv->ucode_ver = le32_to_cpu(ucode->ver);
+ api_ver = IWL_UCODE_API(priv->ucode_ver);
+
+ switch (api_ver) {
+ default:
+ /*
+ * 4965 doesn't revision the firmware file format
+ * along with the API version, it always uses v1
+ * file format.
+ */
+ if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) !=
+ CSR_HW_REV_TYPE_4965) {
+ hdr_size = 28;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ return -EINVAL;
+ }
+ pieces->build = le32_to_cpu(ucode->u.v2.build);
+ pieces->inst_size = le32_to_cpu(ucode->u.v2.inst_size);
+ pieces->data_size = le32_to_cpu(ucode->u.v2.data_size);
+ pieces->init_size = le32_to_cpu(ucode->u.v2.init_size);
+ pieces->init_data_size = le32_to_cpu(ucode->u.v2.init_data_size);
+ pieces->boot_size = le32_to_cpu(ucode->u.v2.boot_size);
+ src = ucode->u.v2.data;
+ break;
+ }
+ /* fall through for 4965 */
+ case 0:
+ case 1:
+ case 2:
+ hdr_size = 24;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ return -EINVAL;
+ }
+ pieces->build = 0;
+ pieces->inst_size = le32_to_cpu(ucode->u.v1.inst_size);
+ pieces->data_size = le32_to_cpu(ucode->u.v1.data_size);
+ pieces->init_size = le32_to_cpu(ucode->u.v1.init_size);
+ pieces->init_data_size = le32_to_cpu(ucode->u.v1.init_data_size);
+ pieces->boot_size = le32_to_cpu(ucode->u.v1.boot_size);
+ src = ucode->u.v1.data;
+ break;
+ }
+
+ /* Verify size of file vs. image size info in file's header */
+ if (ucode_raw->size != hdr_size + pieces->inst_size +
+ pieces->data_size + pieces->init_size +
+ pieces->init_data_size + pieces->boot_size) {
+
+ IWL_ERR(priv,
+ "uCode file size %d does not match expected size\n",
+ (int)ucode_raw->size);
+ return -EINVAL;
+ }
+
+ pieces->inst = src;
+ src += pieces->inst_size;
+ pieces->data = src;
+ src += pieces->data_size;
+ pieces->init = src;
+ src += pieces->init_size;
+ pieces->init_data = src;
+ src += pieces->init_data_size;
+ pieces->boot = src;
+ src += pieces->boot_size;
+
+ return 0;
+}
+
/**
* iwl_ucode_callback - callback when firmware was loaded
*
@@ -1544,14 +1629,15 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
{
struct iwl_priv *priv = context;
struct iwl_ucode_header *ucode;
+ int err;
+ struct iwlagn_firmware_pieces pieces;
const unsigned int api_max = priv->cfg->ucode_api_max;
const unsigned int api_min = priv->cfg->ucode_api_min;
- u8 *src;
- size_t len;
- u32 api_ver, build;
- u32 inst_size, data_size, init_size, init_data_size, boot_size;
- int err, hdr_size;
+ u32 api_ver;
char buildstr[25];
+ u32 build;
+
+ memset(&pieces, 0, sizeof(pieces));

if (!ucode_raw) {
IWL_ERR(priv, "request for firmware file '%s' failed.\n",
@@ -1571,54 +1657,22 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
/* Data from ucode file: header followed by uCode images */
ucode = (struct iwl_ucode_header *)ucode_raw->data;

- priv->ucode_ver = le32_to_cpu(ucode->ver);
- api_ver = IWL_UCODE_API(priv->ucode_ver);
+ if (ucode->ver)
+ err = iwlagn_load_legacy_firmware(priv, ucode_raw, &pieces);
+ else
+ err = -EINVAL;

- switch (api_ver) {
- default:
- /*
- * 4965 doesn't revision the firmware file format
- * along with the API version, it always uses v1
- * file format.
- */
- if (priv->cfg != &iwl4965_agn_cfg) {
- hdr_size = 28;
- if (ucode_raw->size < hdr_size) {
- IWL_ERR(priv, "File size too small!\n");
- goto try_again;
- }
- build = ucode->u.v2.build;
- inst_size = ucode->u.v2.inst_size;
- data_size = ucode->u.v2.data_size;
- init_size = ucode->u.v2.init_size;
- init_data_size = ucode->u.v2.init_data_size;
- boot_size = ucode->u.v2.boot_size;
- src = ucode->u.v2.data;
- break;
- }
- /* fall through for 4965 */
- case 0:
- case 1:
- case 2:
- hdr_size = 24;
- if (ucode_raw->size < hdr_size) {
- IWL_ERR(priv, "File size too small!\n");
- goto try_again;
- }
- build = 0;
- inst_size = ucode->u.v1.inst_size;
- data_size = ucode->u.v1.data_size;
- init_size = ucode->u.v1.init_size;
- init_data_size = ucode->u.v1.init_data_size;
- boot_size = ucode->u.v1.boot_size;
- src = ucode->u.v1.data;
- break;
- }
+ if (err)
+ goto try_again;

- /* api_ver should match the api version forming part of the
- * firmware filename ... but we don't check for that and only rely
- * on the API version read from firmware header from here on forward */
+ api_ver = IWL_UCODE_API(priv->ucode_ver);
+ build = pieces.build;

+ /*
+ * api_ver should match the api version forming part of the
+ * firmware filename ... but we don't check for that and only rely
+ * on the API version read from firmware header from here on forward
+ */
if (api_ver < api_min || api_ver > api_max) {
IWL_ERR(priv, "Driver unable to support your firmware API. "
"Driver supports v%u, firmware is v%u.\n",
@@ -1653,75 +1707,69 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
IWL_UCODE_SERIAL(priv->ucode_ver),
buildstr);

- IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
- priv->ucode_ver);
- IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
- inst_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %u\n",
- data_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %u\n",
- init_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %u\n",
- init_data_size);
- IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %u\n",
- boot_size);
-
/*
* For any of the failures below (before allocating pci memory)
* we will try to load a version with a smaller API -- maybe the
* user just got a corrupted version of the latest API.
*/

- /* Verify size of file vs. image size info in file's header */
- if (ucode_raw->size != hdr_size + inst_size + data_size + init_size +
- init_data_size + boot_size) {
-
- IWL_DEBUG_INFO(priv,
- "uCode file size %d does not match expected size\n",
- (int)ucode_raw->size);
- goto try_again;
- }
+ IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
+ priv->ucode_ver);
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %Zd\n",
+ pieces.inst_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr runtime data size = %Zd\n",
+ pieces.data_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr init inst size = %Zd\n",
+ pieces.init_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr init data size = %Zd\n",
+ pieces.init_data_size);
+ IWL_DEBUG_INFO(priv, "f/w package hdr boot inst size = %Zd\n",
+ pieces.boot_size);

/* Verify that uCode images will fit in card's SRAM */
- if (inst_size > priv->hw_params.max_inst_size) {
- IWL_DEBUG_INFO(priv, "uCode instr len %d too large to fit in\n",
- inst_size);
+ if (pieces.inst_size > priv->hw_params.max_inst_size) {
+ IWL_ERR(priv, "uCode instr len %Zd too large to fit in\n",
+ pieces.inst_size);
goto try_again;
}

- if (data_size > priv->hw_params.max_data_size) {
- IWL_DEBUG_INFO(priv, "uCode data len %d too large to fit in\n",
- data_size);
+ if (pieces.data_size > priv->hw_params.max_data_size) {
+ IWL_ERR(priv, "uCode data len %Zd too large to fit in\n",
+ pieces.data_size);
goto try_again;
}
- if (init_size > priv->hw_params.max_inst_size) {
- IWL_INFO(priv, "uCode init instr len %d too large to fit in\n",
- init_size);
+
+ if (pieces.init_size > priv->hw_params.max_inst_size) {
+ IWL_ERR(priv, "uCode init instr len %Zd too large to fit in\n",
+ pieces.init_size);
goto try_again;
}
- if (init_data_size > priv->hw_params.max_data_size) {
- IWL_INFO(priv, "uCode init data len %d too large to fit in\n",
- init_data_size);
+
+ if (pieces.init_data_size > priv->hw_params.max_data_size) {
+ IWL_ERR(priv, "uCode init data len %Zd too large to fit in\n",
+ pieces.init_data_size);
goto try_again;
}
- if (boot_size > priv->hw_params.max_bsm_size) {
- IWL_INFO(priv, "uCode boot instr len %d too large to fit in\n",
- boot_size);
+
+ if (pieces.boot_size > priv->hw_params.max_bsm_size) {
+ IWL_ERR(priv, "uCode boot instr len %Zd too large to fit in\n",
+ pieces.boot_size);
goto try_again;
}

+
/* Allocate ucode buffers for card's bus-master loading ... */

/* Runtime instructions and 2 copies of data:
* 1) unmodified from disk
* 2) backup cache for save/restore during power-downs */
- priv->ucode_code.len = inst_size;
+ priv->ucode_code.len = pieces.inst_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_code);

- priv->ucode_data.len = data_size;
+ priv->ucode_data.len = pieces.data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data);

- priv->ucode_data_backup.len = data_size;
+ priv->ucode_data_backup.len = pieces.data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_data_backup);

if (!priv->ucode_code.v_addr || !priv->ucode_data.v_addr ||
@@ -1729,11 +1777,11 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
goto err_pci_alloc;

/* Initialization instructions and data */
- if (init_size && init_data_size) {
- priv->ucode_init.len = init_size;
+ if (pieces.init_size && pieces.init_data_size) {
+ priv->ucode_init.len = pieces.init_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init);

- priv->ucode_init_data.len = init_data_size;
+ priv->ucode_init_data.len = pieces.init_data_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_init_data);

if (!priv->ucode_init.v_addr || !priv->ucode_init_data.v_addr)
@@ -1741,8 +1789,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
}

/* Bootstrap (instructions only, no data) */
- if (boot_size) {
- priv->ucode_boot.len = boot_size;
+ if (pieces.boot_size) {
+ priv->ucode_boot.len = pieces.boot_size;
iwl_alloc_fw_desc(priv->pci_dev, &priv->ucode_boot);

if (!priv->ucode_boot.v_addr)
@@ -1752,44 +1800,41 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
/* Copy images into buffers for card's bus-master reads ... */

/* Runtime instructions (first block of data in file) */
- len = inst_size;
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
- memcpy(priv->ucode_code.v_addr, src, len);
- src += len;
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n",
+ pieces.inst_size);
+ memcpy(priv->ucode_code.v_addr, pieces.inst, pieces.inst_size);

IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);

- /* Runtime data (2nd block)
- * NOTE: Copy into backup buffer will be done in iwl_up() */
- len = data_size;
- IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
- memcpy(priv->ucode_data.v_addr, src, len);
- memcpy(priv->ucode_data_backup.v_addr, src, len);
- src += len;
-
- /* Initialization instructions (3rd block) */
- if (init_size) {
- len = init_size;
+ /*
+ * Runtime data
+ * NOTE: Copy into backup buffer will be done in iwl_up()
+ */
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n",
+ pieces.data_size);
+ memcpy(priv->ucode_data.v_addr, pieces.data, pieces.data_size);
+ memcpy(priv->ucode_data_backup.v_addr, pieces.data, pieces.data_size);
+
+ /* Initialization instructions */
+ if (pieces.init_size) {
IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
- len);
- memcpy(priv->ucode_init.v_addr, src, len);
- src += len;
+ pieces.init_size);
+ memcpy(priv->ucode_init.v_addr, pieces.init, pieces.init_size);
}

- /* Initialization data (4th block) */
- if (init_data_size) {
- len = init_data_size;
+ /* Initialization data */
+ if (pieces.init_data_size) {
IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
- len);
- memcpy(priv->ucode_init_data.v_addr, src, len);
- src += len;
+ pieces.init_data_size);
+ memcpy(priv->ucode_init_data.v_addr, pieces.init_data,
+ pieces.init_data_size);
}

- /* Bootstrap instructions (5th block) */
- len = boot_size;
- IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
- memcpy(priv->ucode_boot.v_addr, src, len);
+ /* Bootstrap instructions */
+ IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n",
+ pieces.boot_size);
+ memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);

/**************************************************
* This is still part of probe() in a sense...
--
1.6.3.3


2010-05-10 22:28:28

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 29/47] iwlagn: use virtual interface in TX aggregation handling

From: Johannes Berg <[email protected]>

Most of the TX aggregation handling can be passed
the virtual interface directly instead of having
to rely on priv->vif.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-tx.c | 12 +++++++-----
drivers/net/wireless/iwlwifi/iwl-agn.c | 8 ++++----
drivers/net/wireless/iwlwifi/iwl-agn.h | 5 +++--
3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index c2a5c85..6a306e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -961,7 +961,8 @@ static int iwlagn_txq_ctx_activate_free(struct iwl_priv *priv)
return -1;
}

-int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
+int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
+ const u8 *ra, u16 tid, u16 *ssn)
{
int sta_id;
int tx_fifo;
@@ -1011,7 +1012,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
if (tid_data->tfds_in_queue == 0) {
IWL_DEBUG_HT(priv, "HW queue is empty\n");
tid_data->agg.state = IWL_AGG_ON;
- ieee80211_start_tx_ba_cb_irqsafe(priv->vif, ra, tid);
+ ieee80211_start_tx_ba_cb_irqsafe(vif, ra, tid);
} else {
IWL_DEBUG_HT(priv, "HW queue is NOT empty: %d packets in HW queue\n",
tid_data->tfds_in_queue);
@@ -1020,7 +1021,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, const u8 *ra, u16 tid, u16 *ssn)
return ret;
}

-int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
+int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
+ const u8 *ra, u16 tid)
{
int tx_fifo_id, txq_id, sta_id, ssn = -1;
struct iwl_tid_data *tid_data;
@@ -1046,7 +1048,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
if (priv->stations[sta_id].tid[tid].agg.state ==
IWL_EMPTYING_HW_QUEUE_ADDBA) {
IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
- ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, ra, tid);
priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
return 0;
}
@@ -1083,7 +1085,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid)
tx_fifo_id);
spin_unlock_irqrestore(&priv->lock, flags);

- ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, ra, tid);

return 0;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 270635e..85e045b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3130,8 +3130,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,

static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
- enum ieee80211_ampdu_mlme_action action,
- struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+ enum ieee80211_ampdu_mlme_action action,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
{
struct iwl_priv *priv = hw->priv;
int ret;
@@ -3155,7 +3155,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT(priv, "start Tx\n");
- ret = iwlagn_tx_agg_start(priv, sta->addr, tid, ssn);
+ ret = iwlagn_tx_agg_start(priv, vif, sta->addr, tid, ssn);
if (ret == 0) {
priv->_agn.agg_tids_count++;
IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
@@ -3164,7 +3164,7 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT(priv, "stop Tx\n");
- ret = iwlagn_tx_agg_stop(priv, sta->addr, tid);
+ ret = iwlagn_tx_agg_stop(priv, vif, sta->addr, tid);
if ((ret == 0) && (priv->_agn.agg_tids_count > 0)) {
priv->_agn.agg_tids_count--;
IWL_DEBUG_HT(priv, "priv->_agn.agg_tids_count = %u\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index f52bedb..c441773 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -135,9 +135,10 @@ void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
void iwlagn_hwrate_to_tx_control(struct iwl_priv *priv, u32 rate_n_flags,
struct ieee80211_tx_info *info);
int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb);
-int iwlagn_tx_agg_start(struct iwl_priv *priv,
+int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
const u8 *ra, u16 tid, u16 *ssn);
-int iwlagn_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid);
+int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
+ const u8 *ra, u16 tid);
int iwlagn_txq_check_empty(struct iwl_priv *priv,
int sta_id, u8 tid, int txq_id);
void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
--
1.6.3.3


2010-05-10 22:28:22

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 01/47] iwlwifi: rename 6000 series Gen2 devices to Gen2a

From: Shanyu Zhao <[email protected]>

Rename the current 6000 series Gen2 devices to Gen2a.
Rename the ucode name prefix to iwlwifi-6000g2a.
Also corrected the device IDs for Gen2a series devices.

Signed-off-by: Jay Sternberg <[email protected]>
Signed-off-by: Shanyu Zhao <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-6000.c | 24 +++++++++++++-----------
drivers/net/wireless/iwlwifi/iwl-agn.c | 9 ++++-----
drivers/net/wireless/iwlwifi/iwl-dev.h | 2 +-
3 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 7acef70..f057087 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -67,9 +67,10 @@
#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)

-#define IWL6000G2_FW_PRE "iwlwifi-6005-"
-#define _IWL6000G2_MODULE_FIRMWARE(api) IWL6000G2_FW_PRE #api ".ucode"
-#define IWL6000G2_MODULE_FIRMWARE(api) _IWL6000G2_MODULE_FIRMWARE(api)
+#define IWL6000G2A_FW_PRE "iwlwifi-6000g2a-"
+#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode"
+#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api)
+

static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
{
@@ -408,12 +409,10 @@ static const struct iwl_ops iwl6050_ops = {
.led = &iwlagn_led_ops,
};

-/*
- * "i": Internal configuration, use internal Power Amplifier
- */
-struct iwl_cfg iwl6000g2_2agn_cfg = {
- .name = "6000 Series 2x2 AGN Gen2",
- .fw_name_pre = IWL6000G2_FW_PRE,
+
+struct iwl_cfg iwl6000g2a_2agn_cfg = {
+ .name = "6000 Series 2x2 AGN Gen2a",
+ .fw_name_pre = IWL6000G2A_FW_PRE,
.ucode_api_max = IWL6000G2_UCODE_API_MAX,
.ucode_api_min = IWL6000G2_UCODE_API_MIN,
.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
@@ -442,9 +441,12 @@ struct iwl_cfg iwl6000g2_2agn_cfg = {
.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
.chain_noise_scale = 1000,
.monitor_recover_period = IWL_MONITORING_PERIOD,
- .max_event_log_size = 1024,
+ .max_event_log_size = 512,
};

+/*
+ * "i": Internal configuration, use internal Power Amplifier
+ */
struct iwl_cfg iwl6000i_2agn_cfg = {
.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
.fw_name_pre = IWL6000_FW_PRE,
@@ -645,4 +647,4 @@ struct iwl_cfg iwl6000_3agn_cfg = {

MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
-MODULE_FIRMWARE(IWL6000G2_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
+MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index dc28376..5cf3822 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3789,11 +3789,10 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},

-/* 6x00 Series Gen2 */
- {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2_2agn_cfg)},
- {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2_2agn_cfg)},
+/* 6x00 Series Gen2a */
+ {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
+ {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},

/* 6x50 WiFi/WiMax Series */
{IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index cd3b932..e485465 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -57,8 +57,8 @@ extern struct iwl_cfg iwl5100_bgn_cfg;
extern struct iwl_cfg iwl5100_abg_cfg;
extern struct iwl_cfg iwl5150_agn_cfg;
extern struct iwl_cfg iwl5150_abg_cfg;
+extern struct iwl_cfg iwl6000g2a_2agn_cfg;
extern struct iwl_cfg iwl6000i_2agn_cfg;
-extern struct iwl_cfg iwl6000g2_2agn_cfg;
extern struct iwl_cfg iwl6000i_2abg_cfg;
extern struct iwl_cfg iwl6000i_2bg_cfg;
extern struct iwl_cfg iwl6000_3agn_cfg;
--
1.6.3.3


2010-05-10 22:28:22

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 02/47] iwl3945: fix scan races

From: Abhijeet Kolekar <[email protected]>

Port following patch to 3945.

"commit 90c4162ff59a3281b6d2f7206740be6217bd6758
Author: Johannes Berg <[email protected]>
Date: Wed Apr 7 00:21:36 2010 -0700
iwlwifi: fix scan races"

Signed-off-by: Abhijeet Kolekar <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-core.h | 1 +
drivers/net/wireless/iwlwifi/iwl-scan.c | 3 ++-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 ++
3 files changed, 5 insertions(+), 1 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7273609..7deed86 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -515,6 +515,7 @@ int iwl_scan_cancel_timeout(struct iwl_priv *priv, unsigned long ms);
int iwl_mac_hw_scan(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
+void iwl_bg_start_internal_scan(struct work_struct *work);
void iwl_internal_short_hw_scan(struct iwl_priv *priv);
int iwl_force_reset(struct iwl_priv *priv, int mode);
u16 iwl_fill_probe_req(struct iwl_priv *priv, struct ieee80211_mgmt *frame,
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 447c301..28e2d86 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -367,7 +367,7 @@ void iwl_internal_short_hw_scan(struct iwl_priv *priv)
queue_work(priv->workqueue, &priv->start_internal_scan);
}

-static void iwl_bg_start_internal_scan(struct work_struct *work)
+void iwl_bg_start_internal_scan(struct work_struct *work)
{
struct iwl_priv *priv =
container_of(work, struct iwl_priv, start_internal_scan);
@@ -402,6 +402,7 @@ static void iwl_bg_start_internal_scan(struct work_struct *work)
unlock:
mutex_unlock(&priv->mutex);
}
+EXPORT_SYMBOL(iwl_bg_start_internal_scan);

void iwl_bg_scan_check(struct work_struct *data)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 867d105..04cedef 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3739,6 +3739,7 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
+ INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);

iwl3945_hw_setup_deferred_work(priv);
@@ -3761,6 +3762,7 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
cancel_delayed_work_sync(&priv->init_alive_start);
cancel_delayed_work(&priv->scan_check);
cancel_delayed_work(&priv->alive_start);
+ cancel_work_sync(&priv->start_internal_scan);
cancel_work_sync(&priv->beacon_update);
if (priv->cfg->ops->lib->recover_from_tx_stall)
del_timer_sync(&priv->monitor_recover);
--
1.6.3.3


2010-05-10 22:47:20

by Gábor Stefanik

[permalink] [raw]
Subject: Re: [PATCH 01/47] iwlwifi: rename 6000 series Gen2 devices to Gen2a

What is the reason behind this change? Is Gen2b planned?

On Tue, May 11, 2010 at 12:27 AM, Reinette Chatre
<[email protected]> wrote:
> From: Shanyu Zhao <[email protected]>
>
> Rename the current 6000 series Gen2 devices to Gen2a.
> Rename the ucode name prefix to iwlwifi-6000g2a.
> Also corrected the device IDs for Gen2a series devices.
>
> Signed-off-by: Jay Sternberg <[email protected]>
> Signed-off-by: Shanyu Zhao <[email protected]>
> Signed-off-by: Reinette Chatre <[email protected]>
> ---
> ?drivers/net/wireless/iwlwifi/iwl-6000.c | ? 24 +++++++++++++-----------
> ?drivers/net/wireless/iwlwifi/iwl-agn.c ?| ? ?9 ++++-----
> ?drivers/net/wireless/iwlwifi/iwl-dev.h ?| ? ?2 +-
> ?3 files changed, 18 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
> index 7acef70..f057087 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-6000.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
> @@ -67,9 +67,10 @@
> ?#define _IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode"
> ?#define IWL6050_MODULE_FIRMWARE(api) _IWL6050_MODULE_FIRMWARE(api)
>
> -#define IWL6000G2_FW_PRE "iwlwifi-6005-"
> -#define _IWL6000G2_MODULE_FIRMWARE(api) IWL6000G2_FW_PRE #api ".ucode"
> -#define IWL6000G2_MODULE_FIRMWARE(api) _IWL6000G2_MODULE_FIRMWARE(api)
> +#define IWL6000G2A_FW_PRE "iwlwifi-6000g2a-"
> +#define _IWL6000G2A_MODULE_FIRMWARE(api) IWL6000G2A_FW_PRE #api ".ucode"
> +#define IWL6000G2A_MODULE_FIRMWARE(api) _IWL6000G2A_MODULE_FIRMWARE(api)
> +
>
> ?static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
> ?{
> @@ -408,12 +409,10 @@ static const struct iwl_ops iwl6050_ops = {
> ? ? ? ?.led = &iwlagn_led_ops,
> ?};
>
> -/*
> - * "i": Internal configuration, use internal Power Amplifier
> - */
> -struct iwl_cfg iwl6000g2_2agn_cfg = {
> - ? ? ? .name = "6000 Series 2x2 AGN Gen2",
> - ? ? ? .fw_name_pre = IWL6000G2_FW_PRE,
> +
> +struct iwl_cfg iwl6000g2a_2agn_cfg = {
> + ? ? ? .name = "6000 Series 2x2 AGN Gen2a",
> + ? ? ? .fw_name_pre = IWL6000G2A_FW_PRE,
> ? ? ? ?.ucode_api_max = IWL6000G2_UCODE_API_MAX,
> ? ? ? ?.ucode_api_min = IWL6000G2_UCODE_API_MIN,
> ? ? ? ?.sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
> @@ -442,9 +441,12 @@ struct iwl_cfg iwl6000g2_2agn_cfg = {
> ? ? ? ?.plcp_delta_threshold = IWL_MAX_PLCP_ERR_THRESHOLD_DEF,
> ? ? ? ?.chain_noise_scale = 1000,
> ? ? ? ?.monitor_recover_period = IWL_MONITORING_PERIOD,
> - ? ? ? .max_event_log_size = 1024,
> + ? ? ? .max_event_log_size = 512,
> ?};
>
> +/*
> + * "i": Internal configuration, use internal Power Amplifier
> + */
> ?struct iwl_cfg iwl6000i_2agn_cfg = {
> ? ? ? ?.name = "Intel(R) Centrino(R) Advanced-N 6200 AGN",
> ? ? ? ?.fw_name_pre = IWL6000_FW_PRE,
> @@ -645,4 +647,4 @@ struct iwl_cfg iwl6000_3agn_cfg = {
>
> ?MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
> ?MODULE_FIRMWARE(IWL6050_MODULE_FIRMWARE(IWL6050_UCODE_API_MAX));
> -MODULE_FIRMWARE(IWL6000G2_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
> +MODULE_FIRMWARE(IWL6000G2A_MODULE_FIRMWARE(IWL6000G2_UCODE_API_MAX));
> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
> index dc28376..5cf3822 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-agn.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
> @@ -3789,11 +3789,10 @@ static DEFINE_PCI_DEVICE_TABLE(iwl_hw_card_ids) = {
> ? ? ? ?{IWL_PCI_DEVICE(0x4239, 0x1311, iwl6000i_2agn_cfg)},
> ? ? ? ?{IWL_PCI_DEVICE(0x4239, 0x1316, iwl6000i_2abg_cfg)},
>
> -/* 6x00 Series Gen2 */
> - ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2_2agn_cfg)},
> - ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1301, iwl6000g2_2agn_cfg)},
> - ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1321, iwl6000g2_2agn_cfg)},
> - ? ? ? {IWL_PCI_DEVICE(0x0085, 0x1311, iwl6000g2_2agn_cfg)},
> +/* 6x00 Series Gen2a */
> + ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1201, iwl6000g2a_2agn_cfg)},
> + ? ? ? {IWL_PCI_DEVICE(0x0085, 0x1211, iwl6000g2a_2agn_cfg)},
> + ? ? ? {IWL_PCI_DEVICE(0x0082, 0x1221, iwl6000g2a_2agn_cfg)},
>
> ?/* 6x50 WiFi/WiMax Series */
> ? ? ? ?{IWL_PCI_DEVICE(0x0087, 0x1301, iwl6050_2agn_cfg)},
> diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
> index cd3b932..e485465 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-dev.h
> +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
> @@ -57,8 +57,8 @@ extern struct iwl_cfg iwl5100_bgn_cfg;
> ?extern struct iwl_cfg iwl5100_abg_cfg;
> ?extern struct iwl_cfg iwl5150_agn_cfg;
> ?extern struct iwl_cfg iwl5150_abg_cfg;
> +extern struct iwl_cfg iwl6000g2a_2agn_cfg;
> ?extern struct iwl_cfg iwl6000i_2agn_cfg;
> -extern struct iwl_cfg iwl6000g2_2agn_cfg;
> ?extern struct iwl_cfg iwl6000i_2abg_cfg;
> ?extern struct iwl_cfg iwl6000i_2bg_cfg;
> ?extern struct iwl_cfg iwl6000_3agn_cfg;
> --
> 1.6.3.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
>



--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)

2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 39/47] iwlwifi: track station IDs

From: Johannes Berg <[email protected]>

mac80211 allows us to store private data per
station, so put the station ID there. This
allows us to avoid the station ID lookup when
removing regular stations. To also be able to
avoid the lookup to remove the special IBSS
BSSID station, track its ID in the per-vif
private data.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 16 +++----
drivers/net/wireless/iwlwifi/iwl-3945.h | 5 ++
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 8 +++-
drivers/net/wireless/iwlwifi/iwl-agn.c | 8 +++-
drivers/net/wireless/iwlwifi/iwl-dev.h | 18 ++++++++
drivers/net/wireless/iwlwifi/iwl-sta.c | 61 ++++++++++++--------------
drivers/net/wireless/iwlwifi/iwl-sta.h | 6 ++-
drivers/net/wireless/iwlwifi/iwl3945-base.c | 12 +++--
8 files changed, 82 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 7fb1595..306e23a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2461,28 +2461,26 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
int ret;

- /*
- * NB: this assumes that the station it gets will be
- * IWL_STA_ID, which will happen but isn't obvious.
- */
-
if (add) {
- ret = iwl_add_local_station(priv, vif->bss_conf.bssid, false);
+ ret = iwl_add_local_station(priv, vif->bss_conf.bssid, false,
+ &vif_priv->ibss_bssid_sta_id);
if (ret)
return ret;

- iwl3945_sync_sta(priv, IWL_STA_ID,
+ iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
(priv->band == IEEE80211_BAND_5GHZ) ?
IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
CMD_ASYNC);
- iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
+ iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);

return 0;
}

- return iwl_remove_station(priv, vif->bss_conf.bssid);
+ return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
+ vif->bss_conf.bssid);
}

/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 8fe24ee..bb2aeeb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -106,7 +106,12 @@ struct iwl3945_rs_sta {
};


+/*
+ * The common struct MUST be first because it is shared between
+ * 3945 and agn!
+ */
struct iwl3945_sta_priv {
+ struct iwl_station_priv_common common;
struct iwl3945_rs_sta rs_sta;
};

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index f05e600..81de88e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1520,7 +1520,11 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
int iwlagn_manage_ibss_station(struct iwl_priv *priv,
struct ieee80211_vif *vif, bool add)
{
+ struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
+
if (add)
- return iwl_add_local_station(priv, vif->bss_conf.bssid, true);
- return iwl_remove_station(priv, vif->bss_conf.bssid);
+ return iwl_add_local_station(priv, vif->bss_conf.bssid, true,
+ &vif_priv->ibss_bssid_sta_id);
+ return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
+ vif->bss_conf.bssid);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 0c913ea..b2c5665 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2854,6 +2854,8 @@ static int iwl_mac_setup_register(struct iwl_priv *priv,
IEEE80211_HW_SUPPORTS_STATIC_SMPS;

hw->sta_data_size = sizeof(struct iwl_station_priv);
+ hw->vif_data_size = sizeof(struct iwl_vif_priv);
+
hw->wiphy->interface_modes =
BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC);
@@ -3229,6 +3231,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
int ret;
u8 sta_id;

+ sta_priv->common.sta_id = IWL_INVALID_STATION;
+
IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
sta->addr);

@@ -3245,12 +3249,14 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
return ret;
}

+ sta_priv->common.sta_id = sta_id;
+
/* Initialize rate scaling */
IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
sta->addr);
iwl_rs_rate_init(priv, sta, sta_id);

- return ret;
+ return 0;
}

/*****************************************************************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 46571f7..f3f3473 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -497,20 +497,38 @@ struct iwl_station_entry {
struct iwl_link_quality_cmd *lq;
};

+struct iwl_station_priv_common {
+ u8 sta_id;
+};
+
/*
* iwl_station_priv: Driver's private station information
*
* When mac80211 creates a station it reserves some space (hw->sta_data_size)
* in the structure for use by driver. This structure is places in that
* space.
+ *
+ * The common struct MUST be first because it is shared between
+ * 3945 and agn!
*/
struct iwl_station_priv {
+ struct iwl_station_priv_common common;
struct iwl_lq_sta lq_sta;
atomic_t pending_frames;
bool client;
bool asleep;
};

+/**
+ * struct iwl_vif_priv - driver's private per-interface information
+ *
+ * When mac80211 allocates a virtual interface, it can allocate
+ * space for us to put data into.
+ */
+struct iwl_vif_priv {
+ u8 ibss_bssid_sta_id;
+};
+
/* one for each uCode image (inst/data, boot/init/runtime) */
struct fw_desc {
void *v_addr; /* access by driver */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index e95282b..d1986de 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -462,26 +462,33 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
}

/*
- * iwl_add_local_stations - Add stations not requested by mac80211
+ * iwl_add_local_station - Add stations not requested by mac80211
*
* This will be either the broadcast station or the bssid station needed by
* ad-hoc.
*
* Function sleeps.
*/
-int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs)
+int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
+ u8 *sta_id_r)
{
int ret;
u8 sta_id;
struct iwl_link_quality_cmd *link_cmd;
unsigned long flags;

+ if (*sta_id_r)
+ *sta_id_r = IWL_INVALID_STATION;
+
ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
if (ret) {
IWL_ERR(priv, "Unable to add station %pM\n", addr);
return ret;
}

+ if (sta_id_r)
+ *sta_id_r = sta_id;
+
spin_lock_irqsave(&priv->sta_lock, flags);
priv->stations[sta_id].used |= IWL_STA_LOCAL;
spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -582,13 +589,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
/**
* iwl_remove_station - Remove driver's knowledge of station.
*/
-int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
+int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
+ const u8 *addr)
{
- int sta_id = IWL_INVALID_STATION;
- int i, ret = -EINVAL;
- unsigned long flags;
- bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
struct iwl_station_entry *station;
+ unsigned long flags;

if (!iwl_is_ready(priv)) {
IWL_DEBUG_INFO(priv,
@@ -602,35 +607,24 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
return 0;
}

- spin_lock_irqsave(&priv->sta_lock, flags);
-
- if (is_ap)
- sta_id = IWL_AP_ID;
- else
- for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
- if (priv->stations[i].used &&
- !compare_ether_addr(priv->stations[i].sta.sta.addr,
- addr)) {
- sta_id = i;
- break;
- }
+ IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
+ sta_id, addr);

- if (unlikely(sta_id == IWL_INVALID_STATION))
- goto out;
+ if (WARN_ON(sta_id == IWL_INVALID_STATION))
+ return -EINVAL;

- IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
- sta_id, addr);
+ spin_lock_irqsave(&priv->sta_lock, flags);

if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
addr);
- goto out;
+ goto out_err;
}

if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
addr);
- goto out;
+ goto out_err;
}

if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
@@ -647,11 +641,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
station = &priv->stations[sta_id];
spin_unlock_irqrestore(&priv->sta_lock, flags);

- ret = iwl_send_remove_station(priv, station);
- return ret;
-out:
+ return iwl_send_remove_station(priv, station);
+out_err:
spin_unlock_irqrestore(&priv->sta_lock, flags);
- return ret;
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(iwl_remove_station);

@@ -1467,14 +1460,16 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);

int iwl_mac_sta_remove(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_sta *sta)
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta)
{
- int ret;
struct iwl_priv *priv = hw->priv;
+ struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv;
+ int ret;
+
IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
sta->addr);
- ret = iwl_remove_station(priv, sta->addr);
+ ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
if (ret)
IWL_ERR(priv, "Error removing station %pM\n",
sta->addr);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 50c9d51..8efb83d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -68,12 +68,14 @@ int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
int iwl_get_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);
-int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs);
+int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
+ u8 *sta_id_r);
int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
bool is_ap,
struct ieee80211_sta_ht_cap *ht_info,
u8 *sta_id_r);
-int iwl_remove_station(struct iwl_priv *priv, const u8 *addr);
+int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
+ const u8 *addr);
int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 1a44571..48fb59b 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3378,10 +3378,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
struct ieee80211_sta *sta)
{
struct iwl_priv *priv = hw->priv;
+ struct iwl3945_sta_priv *sta_priv = (void *)sta->drv_priv;
int ret;
- bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
+ bool is_ap = vif->type == NL80211_IFTYPE_STATION;
u8 sta_id;

+ sta_priv->common.sta_id = IWL_INVALID_STATION;
+
IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
sta->addr);

@@ -3394,16 +3397,14 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
return ret;
}

+ sta_priv->common.sta_id = sta_id;
+
/* Initialize rate scaling */
IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
sta->addr);
iwl3945_rs_rate_init(priv, sta, sta_id);

return 0;
-
-
-
- return ret;
}
/*****************************************************************************
*
@@ -3887,6 +3888,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)

hw->rate_control_algorithm = "iwl-3945-rs";
hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
+ hw->vif_data_size = sizeof(struct iwl_vif_priv);

/* Tell mac80211 our characteristics */
hw->flags = IEEE80211_HW_SIGNAL_DBM |
--
1.6.3.3


2010-05-10 22:28:29

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 26/47] iwlagn: use vif->type to check station

From: Johannes Berg <[email protected]>

We need not check iw_mode, since we have
the vif pointer available.

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

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 97184e1..7c3363a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -3223,7 +3223,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
{
struct iwl_priv *priv = hw->priv;
struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
- bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
+ bool is_ap = vif->type == NL80211_IFTYPE_STATION;
int ret;
u8 sta_id;

--
1.6.3.3


2010-05-10 22:28:31

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 40/47] iwlwifi: add iwl_sta_id()

From: Johannes Berg <[email protected]>

In places where the station struct is
guaranteed to exist (presumably), use
this helper to get the station ID out
of it (and warn if there's no station
struct after all).

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-sta.h | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 8efb83d..7229e2c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -84,4 +84,12 @@ int iwl_sta_rx_agg_start(struct iwl_priv *priv,
int iwl_sta_rx_agg_stop(struct iwl_priv *priv, const u8 *addr, int tid);
void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id);
void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt);
+
+static inline int iwl_sta_id(struct ieee80211_sta *sta)
+{
+ if (WARN_ON(!sta))
+ return IWL_INVALID_STATION;
+
+ return ((struct iwl_station_priv_common *)sta->drv_priv)->sta_id;
+}
#endif /* __iwl_sta_h__ */
--
1.6.3.3


2010-05-10 22:28:26

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 25/47] iwlagn: move iwl_get_ra_sta_id to 4965

From: Johannes Berg <[email protected]>

This function is only needed by 4965, so
it need not be in core code and can be
made static.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-4965.c | 10 ++++++++++
drivers/net/wireless/iwlwifi/iwl-sta.c | 11 -----------
drivers/net/wireless/iwlwifi/iwl-sta.h | 1 -
3 files changed, 10 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index a3562a1..b8bf837 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1953,6 +1953,16 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
return 0;
}

+static int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
+{
+ if (priv->iw_mode == NL80211_IFTYPE_STATION) {
+ return IWL_AP_ID;
+ } else {
+ u8 *da = ieee80211_get_DA(hdr);
+ return iwl_find_station(priv, da);
+ }
+}
+
/**
* iwl4965_rx_reply_tx - Handle standard (non-aggregation) Tx response
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7da8ede..0db742c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -80,17 +80,6 @@ u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
}
EXPORT_SYMBOL(iwl_find_station);

-int iwl_get_ra_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
-{
- if (priv->iw_mode == NL80211_IFTYPE_STATION) {
- return IWL_AP_ID;
- } else {
- u8 *da = ieee80211_get_DA(hdr);
- return iwl_find_station(priv, da);
- }
-}
-EXPORT_SYMBOL(iwl_get_ra_sta_id);
-
/* priv->sta_lock must be held */
static void iwl_sta_ucode_activate(struct iwl_priv *priv, u8 sta_id)
{
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index 9a869f1..1a0e590 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -66,7 +66,6 @@ void iwl_restore_stations(struct iwl_priv *priv);
void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force);
int iwl_get_free_ucode_key_index(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);
int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs);
--
1.6.3.3


2010-05-10 22:28:27

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 19/47] iwlwifi: remove ucode virtual functions

From: Johannes Berg <[email protected]>

AGN devices all use the same ucode operations,
except for 4965, because 4965 uses only v1 file
headers.

Therefore, we can remove all the indirection
we have here and just code the API distinction
in place, with a small special case for 4965.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-1000.c | 1 -
drivers/net/wireless/iwlwifi/iwl-4965.c | 39 ----------------
drivers/net/wireless/iwlwifi/iwl-5000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-6000.c | 2 -
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c | 49 ---------------------
drivers/net/wireless/iwlwifi/iwl-agn.c | 61 +++++++++++++++++++------
drivers/net/wireless/iwlwifi/iwl-agn.h | 1 -
drivers/net/wireless/iwlwifi/iwl-core.h | 12 -----
drivers/net/wireless/iwlwifi/iwl-dev.h | 1 -
drivers/net/wireless/iwlwifi/iwl3945-base.c | 2 +-
10 files changed, 47 insertions(+), 123 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index ebaf02d..a2f7cbc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -225,7 +225,6 @@ static struct iwl_lib_ops iwl1000_lib = {
};

static const struct iwl_ops iwl1000_ops = {
- .ucode = &iwlagn_ucode,
.lib = &iwl1000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 5904a1b..a3562a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2112,34 +2112,6 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
cancel_work_sync(&priv->txpower_work);
}

-#define IWL4965_UCODE_GET(item) \
-static u32 iwl4965_ucode_get_##item(const struct iwl_ucode_header *ucode,\
- u32 api_ver) \
-{ \
- return le32_to_cpu(ucode->u.v1.item); \
-}
-
-static u32 iwl4965_ucode_get_header_size(u32 api_ver)
-{
- return UCODE_HEADER_SIZE(1);
-}
-static u32 iwl4965_ucode_get_build(const struct iwl_ucode_header *ucode,
- u32 api_ver)
-{
- return 0;
-}
-static u8 *iwl4965_ucode_get_data(const struct iwl_ucode_header *ucode,
- u32 api_ver)
-{
- return (u8 *) ucode->u.v1.data;
-}
-
-IWL4965_UCODE_GET(inst_size);
-IWL4965_UCODE_GET(data_size);
-IWL4965_UCODE_GET(init_size);
-IWL4965_UCODE_GET(init_data_size);
-IWL4965_UCODE_GET(boot_size);
-
static struct iwl_hcmd_ops iwl4965_hcmd = {
.rxon_assoc = iwl4965_send_rxon_assoc,
.commit_rxon = iwl_commit_rxon,
@@ -2147,16 +2119,6 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {
.send_bt_config = iwl_send_bt_config,
};

-static struct iwl_ucode_ops iwl4965_ucode = {
- .get_header_size = iwl4965_ucode_get_header_size,
- .get_build = iwl4965_ucode_get_build,
- .get_inst_size = iwl4965_ucode_get_inst_size,
- .get_data_size = iwl4965_ucode_get_data_size,
- .get_init_size = iwl4965_ucode_get_init_size,
- .get_init_data_size = iwl4965_ucode_get_init_data_size,
- .get_boot_size = iwl4965_ucode_get_boot_size,
- .get_data = iwl4965_ucode_get_data,
-};
static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
.get_hcmd_size = iwl4965_get_hcmd_size,
.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2229,7 +2191,6 @@ static struct iwl_lib_ops iwl4965_lib = {
};

static const struct iwl_ops iwl4965_ops = {
- .ucode = &iwl4965_ucode,
.lib = &iwl4965_lib,
.hcmd = &iwl4965_hcmd,
.utils = &iwl4965_hcmd_utils,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index bde0f18..efda0e8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -427,7 +427,6 @@ static struct iwl_lib_ops iwl5150_lib = {
};

static const struct iwl_ops iwl5000_ops = {
- .ucode = &iwlagn_ucode,
.lib = &iwl5000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
@@ -435,7 +434,6 @@ static const struct iwl_ops iwl5000_ops = {
};

static const struct iwl_ops iwl5150_ops = {
- .ucode = &iwlagn_ucode,
.lib = &iwl5150_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 5f0f586..03c7324 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -330,7 +330,6 @@ static struct iwl_lib_ops iwl6000_lib = {
};

static const struct iwl_ops iwl6000_ops = {
- .ucode = &iwlagn_ucode,
.lib = &iwl6000_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
@@ -404,7 +403,6 @@ static struct iwl_lib_ops iwl6050_lib = {
};

static const struct iwl_ops iwl6050_ops = {
- .ucode = &iwlagn_ucode,
.lib = &iwl6050_lib,
.hcmd = &iwlagn_hcmd,
.utils = &iwlagn_hcmd_utils,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
index c3e3283..637286c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
@@ -182,55 +182,6 @@ int iwlagn_load_ucode(struct iwl_priv *priv)
return ret;
}

-#define IWL_UCODE_GET(item) \
-static u32 iwlagn_ucode_get_##item(const struct iwl_ucode_header *ucode,\
- u32 api_ver) \
-{ \
- if (api_ver <= 2) \
- return le32_to_cpu(ucode->u.v1.item); \
- return le32_to_cpu(ucode->u.v2.item); \
-}
-
-static u32 iwlagn_ucode_get_header_size(u32 api_ver)
-{
- if (api_ver <= 2)
- return UCODE_HEADER_SIZE(1);
- return UCODE_HEADER_SIZE(2);
-}
-
-static u32 iwlagn_ucode_get_build(const struct iwl_ucode_header *ucode,
- u32 api_ver)
-{
- if (api_ver <= 2)
- return 0;
- return le32_to_cpu(ucode->u.v2.build);
-}
-
-static u8 *iwlagn_ucode_get_data(const struct iwl_ucode_header *ucode,
- u32 api_ver)
-{
- if (api_ver <= 2)
- return (u8 *) ucode->u.v1.data;
- return (u8 *) ucode->u.v2.data;
-}
-
-IWL_UCODE_GET(inst_size);
-IWL_UCODE_GET(data_size);
-IWL_UCODE_GET(init_size);
-IWL_UCODE_GET(init_data_size);
-IWL_UCODE_GET(boot_size);
-
-struct iwl_ucode_ops iwlagn_ucode = {
- .get_header_size = iwlagn_ucode_get_header_size,
- .get_build = iwlagn_ucode_get_build,
- .get_inst_size = iwlagn_ucode_get_inst_size,
- .get_data_size = iwlagn_ucode_get_data_size,
- .get_init_size = iwlagn_ucode_get_init_size,
- .get_init_data_size = iwlagn_ucode_get_init_data_size,
- .get_boot_size = iwlagn_ucode_get_boot_size,
- .get_data = iwlagn_ucode_get_data,
-};
-
/*
* Calibration
*/
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index f9c9c08..7bcc8a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1550,7 +1550,7 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
size_t len;
u32 api_ver, build;
u32 inst_size, data_size, init_size, init_data_size, boot_size;
- int err;
+ int err, hdr_size;
u16 eeprom_ver;
char buildstr[25];

@@ -1563,8 +1563,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
IWL_DEBUG_INFO(priv, "Loaded firmware file '%s' (%zd bytes).\n",
priv->firmware_name, ucode_raw->size);

- /* Make sure that we got at least the v1 header! */
- if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
+ /* Make sure that we got at least the API version number */
+ if (ucode_raw->size < 4) {
IWL_ERR(priv, "File size way too small!\n");
goto try_again;
}
@@ -1574,14 +1574,47 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)

priv->ucode_ver = le32_to_cpu(ucode->ver);
api_ver = IWL_UCODE_API(priv->ucode_ver);
- build = priv->cfg->ops->ucode->get_build(ucode, api_ver);
- inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
- data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
- init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
- init_data_size =
- priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
- boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
- src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
+
+ switch (api_ver) {
+ default:
+ /*
+ * 4965 doesn't revision the firmware file format
+ * along with the API version, it always uses v1
+ * file format.
+ */
+ if (priv->cfg != &iwl4965_agn_cfg) {
+ hdr_size = 28;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ goto try_again;
+ }
+ build = ucode->u.v2.build;
+ inst_size = ucode->u.v2.inst_size;
+ data_size = ucode->u.v2.data_size;
+ init_size = ucode->u.v2.init_size;
+ init_data_size = ucode->u.v2.init_data_size;
+ boot_size = ucode->u.v2.boot_size;
+ src = ucode->u.v2.data;
+ break;
+ }
+ /* fall through for 4965 */
+ case 0:
+ case 1:
+ case 2:
+ hdr_size = 24;
+ if (ucode_raw->size < hdr_size) {
+ IWL_ERR(priv, "File size too small!\n");
+ goto try_again;
+ }
+ build = 0;
+ inst_size = ucode->u.v1.inst_size;
+ data_size = ucode->u.v1.data_size;
+ init_size = ucode->u.v1.init_size;
+ init_data_size = ucode->u.v1.init_data_size;
+ boot_size = ucode->u.v1.boot_size;
+ src = ucode->u.v1.data;
+ break;
+ }

/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
@@ -1646,10 +1679,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
*/

/* Verify size of file vs. image size info in file's header */
- if (ucode_raw->size !=
- priv->cfg->ops->ucode->get_header_size(api_ver) +
- inst_size + data_size + init_size +
- init_data_size + boot_size) {
+ if (ucode_raw->size != hdr_size + inst_size + data_size + init_size +
+ init_data_size + boot_size) {

IWL_DEBUG_INFO(priv,
"uCode file size %d does not match expected size\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index a9ba9fc..4a1e7b2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -66,7 +66,6 @@
#include "iwl-dev.h"

extern struct iwl_mod_params iwlagn_mod_params;
-extern struct iwl_ucode_ops iwlagn_ucode;
extern struct iwl_hcmd_ops iwlagn_hcmd;
extern struct iwl_hcmd_utils_ops iwlagn_hcmd_utils;

diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 0fa9965..2f664a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -131,17 +131,6 @@ struct iwl_temp_ops {
void (*set_calib_version)(struct iwl_priv *priv);
};

-struct iwl_ucode_ops {
- u32 (*get_header_size)(u32);
- u32 (*get_build)(const struct iwl_ucode_header *, u32);
- u32 (*get_inst_size)(const struct iwl_ucode_header *, u32);
- u32 (*get_data_size)(const struct iwl_ucode_header *, u32);
- u32 (*get_init_size)(const struct iwl_ucode_header *, u32);
- u32 (*get_init_data_size)(const struct iwl_ucode_header *, u32);
- u32 (*get_boot_size)(const struct iwl_ucode_header *, u32);
- u8 * (*get_data)(const struct iwl_ucode_header *, u32);
-};
-
struct iwl_lib_ops {
/* set hw dependent parameters */
int (*set_hw_params)(struct iwl_priv *priv);
@@ -222,7 +211,6 @@ struct iwl_led_ops {
};

struct iwl_ops {
- const struct iwl_ucode_ops *ucode;
const struct iwl_lib_ops *lib;
const struct iwl_hcmd_ops *hcmd;
const struct iwl_hcmd_utils_ops *utils;
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index e485465..fe938d9 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -541,7 +541,6 @@ struct iwl_ucode_header {
} v2;
} u;
};
-#define UCODE_HEADER_SIZE(ver) ((ver) == 1 ? 24 : 28)

struct iwl4965_ibss_seq {
u8 mac[ETH_ALEN];
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index e9de109..59c85f5 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2117,7 +2117,7 @@ static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\

static u32 iwl3945_ucode_get_header_size(u32 api_ver)
{
- return UCODE_HEADER_SIZE(1);
+ return 24;
}

static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode)
--
1.6.3.3


2010-05-10 22:28:30

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 37/47] iwlwifi: "tx power per chain" are part of ucode_tx_stats

From: Wey-Yi Guy <[email protected]>

Move "tx power per chain" into ucode_tx_stats, it is debugging
information provided by uCode as part of statistics notification.

The "tx power per chain" parameters are optional parameters which only
supported by 6000 series device today; those are reserved fields for all
the other devices.

Signed-off-by: Wey-Yi Guy <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c | 16 +++++++++
drivers/net/wireless/iwlwifi/iwl-commands.h | 5 +++
drivers/net/wireless/iwlwifi/iwl-debugfs.c | 42 ------------------------
3 files changed, 21 insertions(+), 42 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index f249b70..48c023b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -709,6 +709,22 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
delta_tx->agg.rx_ba_rsp_cnt,
max_tx->agg.rx_ba_rsp_cnt);

+ if (tx->tx_power.ant_a || tx->tx_power.ant_b || tx->tx_power.ant_c) {
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "tx power: (1/2 dB step)\n");
+ if ((priv->cfg->valid_tx_ant & ANT_A) && tx->tx_power.ant_a)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tantenna A: 0x%X\n",
+ tx->tx_power.ant_a);
+ if ((priv->cfg->valid_tx_ant & ANT_B) && tx->tx_power.ant_b)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tantenna B: 0x%X\n",
+ tx->tx_power.ant_b);
+ if ((priv->cfg->valid_tx_ant & ANT_C) && tx->tx_power.ant_c)
+ pos += scnprintf(buf + pos, bufsz - pos,
+ "\tantenna C: 0x%X\n",
+ tx->tx_power.ant_c);
+ }
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 449d41f..9aab020 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -3127,6 +3127,11 @@ struct statistics_tx {
__le32 cts_timeout_collision;
__le32 ack_or_ba_timeout_collision;
struct statistics_tx_non_phy_agg agg;
+ /*
+ * "tx_power" are optional parameters provided by uCode,
+ * 6000 series is the only device provide the information,
+ * Those are reserved fields for all the other devices
+ */
struct statistics_tx_power tx_power;
__le32 reserved1;
} __attribute__ ((packed));
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index 06905bb..4d6de2d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -1214,46 +1214,6 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
return ret;
}

-static ssize_t iwl_dbgfs_chain_tx_power_read(struct file *file,
- char __user *user_buf,
- size_t count, loff_t *ppos) {
-
- struct iwl_priv *priv = file->private_data;
- char buf[128];
- int pos = 0;
- const size_t bufsz = sizeof(buf);
- struct statistics_tx *tx;
-
- if (!iwl_is_alive(priv))
- return -EAGAIN;
- else {
- tx = &priv->statistics.tx;
- if (tx->tx_power.ant_a ||
- tx->tx_power.ant_b ||
- tx->tx_power.ant_c) {
- pos += scnprintf(buf + pos, bufsz - pos,
- "tx power: (1/2 dB step)\n");
- if ((priv->cfg->valid_tx_ant & ANT_A) &&
- tx->tx_power.ant_a)
- pos += scnprintf(buf + pos, bufsz - pos,
- "\tantenna A: 0x%X\n",
- tx->tx_power.ant_a);
- if ((priv->cfg->valid_tx_ant & ANT_B) &&
- tx->tx_power.ant_b)
- pos += scnprintf(buf + pos, bufsz - pos,
- "\tantenna B: 0x%X\n",
- tx->tx_power.ant_b);
- if ((priv->cfg->valid_tx_ant & ANT_C) &&
- tx->tx_power.ant_c)
- pos += scnprintf(buf + pos, bufsz - pos,
- "\tantenna C: 0x%X\n",
- tx->tx_power.ant_c);
- } else
- pos += scnprintf(buf + pos, bufsz - pos, "N/A\n");
- }
- return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
-}
-
static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
char __user *user_buf,
size_t count, loff_t *ppos)
@@ -1565,7 +1525,6 @@ DEBUGFS_READ_FILE_OPS(ucode_tx_stats);
DEBUGFS_READ_FILE_OPS(ucode_general_stats);
DEBUGFS_READ_FILE_OPS(sensitivity);
DEBUGFS_READ_FILE_OPS(chain_noise);
-DEBUGFS_READ_FILE_OPS(chain_tx_power);
DEBUGFS_READ_FILE_OPS(power_save_status);
DEBUGFS_WRITE_FILE_OPS(clear_ucode_statistics);
DEBUGFS_WRITE_FILE_OPS(clear_traffic_statistics);
@@ -1624,7 +1583,6 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
DEBUGFS_ADD_FILE(traffic_log, dir_debug, S_IWUSR | S_IRUSR);
DEBUGFS_ADD_FILE(rx_queue, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(tx_queue, dir_debug, S_IRUSR);
- DEBUGFS_ADD_FILE(chain_tx_power, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(power_save_status, dir_debug, S_IRUSR);
DEBUGFS_ADD_FILE(clear_ucode_statistics, dir_debug, S_IWUSR);
DEBUGFS_ADD_FILE(clear_traffic_statistics, dir_debug, S_IWUSR);
--
1.6.3.3


2010-05-10 22:28:25

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 16/47] iwlwifi: manage IBSS station properly

From: Johannes Berg <[email protected]>

Currently iwlwifi will eventually exhaust the station
table when adding the BSSID station for IBSS mode,
unless the interface is set down.

The new mac80211 ibss joined/left notification allows
us to fix that easily by moving the code to add the
IBSS station to the notification, and also adding
code to remove it again when we leave the IBSS.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-1000.c | 1 +
drivers/net/wireless/iwlwifi/iwl-3945.c | 30 ++++++++++++++++++++++++++-
drivers/net/wireless/iwlwifi/iwl-3945.h | 9 --------
drivers/net/wireless/iwlwifi/iwl-4965.c | 1 +
drivers/net/wireless/iwlwifi/iwl-5000.c | 2 +
drivers/net/wireless/iwlwifi/iwl-6000.c | 2 +
drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 9 ++++++++
drivers/net/wireless/iwlwifi/iwl-agn.c | 6 -----
drivers/net/wireless/iwlwifi/iwl-agn.h | 4 +++
drivers/net/wireless/iwlwifi/iwl-core.c | 9 ++++++++
drivers/net/wireless/iwlwifi/iwl-core.h | 2 +
drivers/net/wireless/iwlwifi/iwl-sta.c | 7 +++++-
drivers/net/wireless/iwlwifi/iwl-sta.h | 1 +
drivers/net/wireless/iwlwifi/iwl3945-base.c | 11 ---------
14 files changed, 66 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 4d360d7..ebaf02d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -213,6 +213,7 @@ static struct iwl_lib_ops iwl1000_lib = {
.set_ct_kill = iwl1000_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 3607813..1e95939 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -884,7 +884,8 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
}

-u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate, u8 flags)
+static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
+ u16 tx_rate, u8 flags)
{
unsigned long flags_spin;
struct iwl_station_entry *station;
@@ -2395,6 +2396,32 @@ static u16 iwl3945_build_addsta_hcmd(const struct iwl_addsta_cmd *cmd, u8 *data)
return (u16)sizeof(struct iwl3945_addsta_cmd);
}

+static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
+ struct ieee80211_vif *vif, bool add)
+{
+ int ret;
+
+ /*
+ * NB: this assumes that the station it gets will be
+ * IWL_STA_ID, which will happen but isn't obvious.
+ */
+
+ if (add) {
+ ret = iwl_add_local_station(priv, vif->bss_conf.bssid, false);
+ if (ret)
+ return ret;
+
+ iwl3945_sync_sta(priv, IWL_STA_ID,
+ (priv->band == IEEE80211_BAND_5GHZ) ?
+ IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
+ CMD_ASYNC);
+ iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
+
+ return 0;
+ }
+
+ return iwl_remove_station(priv, vif->bss_conf.bssid);
+}

/**
* iwl3945_init_hw_rate_table - Initialize the hardware rate fallback table
@@ -2802,6 +2829,7 @@ static struct iwl_lib_ops iwl3945_lib = {
.post_associate = iwl3945_post_associate,
.isr = iwl_isr_legacy,
.config_ap = iwl3945_config_ap,
+ .manage_ibss_station = iwl3945_manage_ibss_station,
.add_bcast_station = iwl3945_add_bcast_station,

.debugfs_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index 643adb6..cea824c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -211,13 +211,6 @@ extern int iwl3945_dump_nic_event_log(struct iwl_priv *priv, bool full_log,
char **buf, bool display);
extern void iwl3945_dump_nic_error_log(struct iwl_priv *priv);

-/*
- * Currently used by iwl-3945-rs... look at restructuring so that it doesn't
- * call this... todo... fix that.
-*/
-extern u8 iwl3945_sync_station(struct iwl_priv *priv, int sta_id,
- u16 tx_rate, u8 flags);
-
/******************************************************************************
*
* Functions implemented in iwl-[34]*.c which are forward declared here
@@ -288,8 +281,6 @@ extern __le32 iwl3945_get_antenna_flags(const struct iwl_priv *priv);
extern int iwl3945_init_hw_rate_table(struct iwl_priv *priv);
extern void iwl3945_reg_txpower_periodic(struct iwl_priv *priv);
extern int iwl3945_txpower_set_from_eeprom(struct iwl_priv *priv);
-extern u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
- u16 tx_rate, u8 flags);

extern const struct iwl_channel_info *iwl3945_get_channel_info(
const struct iwl_priv *priv, enum ieee80211_band band, u16 channel);
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 6b0ae74..5904a1b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2219,6 +2219,7 @@ static struct iwl_lib_ops iwl4965_lib = {
.set_ct_kill = iwl4965_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 8ed616e..bde0f18 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -352,6 +352,7 @@ static struct iwl_lib_ops iwl5000_lib = {
.set_ct_kill = iwl5000_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -414,6 +415,7 @@ static struct iwl_lib_ops iwl5150_lib = {
.set_ct_kill = iwl5150_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index b69fa36..5f0f586 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -318,6 +318,7 @@ static struct iwl_lib_ops iwl6000_lib = {
.set_ct_kill = iwl6000_set_ct_threshold,
},
.add_bcast_station = iwl_add_bcast_station,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
@@ -391,6 +392,7 @@ static struct iwl_lib_ops iwl6050_lib = {
.set_calib_version = iwl6050_set_calib_version,
},
.add_bcast_station = iwl_add_bcast_station,
+ .manage_ibss_station = iwlagn_manage_ibss_station,
.debugfs_ops = {
.rx_stats_read = iwl_ucode_rx_stats_read,
.tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index a273474..50ff313 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -38,6 +38,7 @@
#include "iwl-helpers.h"
#include "iwl-agn-hw.h"
#include "iwl-agn.h"
+#include "iwl-sta.h"

static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp)
{
@@ -1513,3 +1514,11 @@ void iwlagn_request_scan(struct iwl_priv *priv)
/* inform mac80211 scan aborted */
queue_work(priv->workqueue, &priv->scan_completed);
}
+
+int iwlagn_manage_ibss_station(struct iwl_priv *priv,
+ struct ieee80211_vif *vif, bool add)
+{
+ if (add)
+ return iwl_add_local_station(priv, vif->bss_conf.bssid, true);
+ return iwl_remove_station(priv, vif->bss_conf.bssid);
+}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5cf3822..dd1324d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2606,17 +2606,11 @@ void iwl_post_associate(struct iwl_priv *priv)
switch (priv->iw_mode) {
case NL80211_IFTYPE_STATION:
break;
-
case NL80211_IFTYPE_ADHOC:
-
/* assume default assoc id */
priv->assoc_id = 1;
-
- iwl_add_local_station(priv, priv->bssid, true);
iwl_send_beacon_cmd(priv);
-
break;
-
default:
IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index cfee999..a9ba9fc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -174,4 +174,8 @@ static inline bool iwl_is_tx_success(u32 status)
/* scan */
void iwlagn_request_scan(struct iwl_priv *priv);

+/* station mgmt */
+int iwlagn_manage_ibss_station(struct iwl_priv *priv,
+ struct ieee80211_vif *vif, bool add);
+
#endif /* __iwl_agn_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index e8c9bca..5c6f254 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1960,6 +1960,15 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
iwl_set_no_assoc(priv);
}

+ if (changes & BSS_CHANGED_IBSS) {
+ ret = priv->cfg->ops->lib->manage_ibss_station(priv, vif,
+ bss_conf->ibss_joined);
+ if (ret)
+ IWL_ERR(priv, "failed to %s IBSS station %pM\n",
+ bss_conf->ibss_joined ? "add" : "remove",
+ bss_conf->bssid);
+ }
+
mutex_unlock(&priv->mutex);

IWL_DEBUG_MAC80211(priv, "leave\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 8d53fc9..0fa9965 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -202,6 +202,8 @@ struct iwl_lib_ops {
struct iwl_temp_ops temp_ops;
/* station management */
int (*add_bcast_station)(struct iwl_priv *priv);
+ int (*manage_ibss_station)(struct iwl_priv *priv,
+ struct ieee80211_vif *vif, bool add);
/* recover from tx queue stall */
void (*recover_from_tx_stall)(unsigned long data);
/* check for plcp health */
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 354eb13..7da8ede 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -596,7 +596,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
/**
* iwl_remove_station - Remove driver's knowledge of station.
*/
-static int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
{
int sta_id = IWL_INVALID_STATION;
int i, ret = -EINVAL;
@@ -647,6 +647,10 @@ static int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
goto out;
}

+ if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
+ kfree(priv->stations[sta_id].lq);
+ priv->stations[sta_id].lq = NULL;
+ }

priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;

@@ -663,6 +667,7 @@ out:
spin_unlock_irqrestore(&priv->sta_lock, flags);
return ret;
}
+EXPORT_SYMBOL_GPL(iwl_remove_station);

/**
* iwl_clear_ucode_stations() - clear entire station table driver and/or ucode
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index b0ed2eb..9a869f1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -74,6 +74,7 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
bool is_ap,
struct ieee80211_sta_ht_cap *ht_info,
u8 *sta_id_r);
+int iwl_remove_station(struct iwl_priv *priv, const u8 *addr);
int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid);
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 4f20cca..9486b32 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -3103,21 +3103,10 @@ void iwl3945_post_associate(struct iwl_priv *priv)
case NL80211_IFTYPE_STATION:
iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
break;
-
case NL80211_IFTYPE_ADHOC:
-
priv->assoc_id = 1;
- iwl_add_local_station(priv, priv->bssid, false);
- iwl3945_sync_sta(priv, IWL_STA_ID,
- (priv->band == IEEE80211_BAND_5GHZ) ?
- IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
- CMD_ASYNC);
- iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
-
iwl3945_send_beacon_cmd(priv);
-
break;
-
default:
IWL_ERR(priv, "%s Should not be called in %d mode\n",
__func__, priv->iw_mode);
--
1.6.3.3


2010-05-10 22:28:28

by Reinette Chatre

[permalink] [raw]
Subject: [PATCH 18/47] iwl3945: remove ucode access indirection

From: Johannes Berg <[email protected]>

As these function pointers will always point to
the 3945 functions, we can just call them directly
and avoid the indirection.

Signed-off-by: Johannes Berg <[email protected]>
Signed-off-by: Reinette Chatre <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-3945.c | 40 ---------------------------
drivers/net/wireless/iwlwifi/iwl3945-base.c | 39 ++++++++++++++++++++------
2 files changed, 30 insertions(+), 49 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 1e95939..a4d842a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2751,51 +2751,12 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
return 0;
}

-#define IWL3945_UCODE_GET(item) \
-static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
- u32 api_ver) \
-{ \
- return le32_to_cpu(ucode->u.v1.item); \
-}
-
-static u32 iwl3945_ucode_get_header_size(u32 api_ver)
-{
- return UCODE_HEADER_SIZE(1);
-}
-static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
- u32 api_ver)
-{
- return 0;
-}
-static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
- u32 api_ver)
-{
- return (u8 *) ucode->u.v1.data;
-}
-
-IWL3945_UCODE_GET(inst_size);
-IWL3945_UCODE_GET(data_size);
-IWL3945_UCODE_GET(init_size);
-IWL3945_UCODE_GET(init_data_size);
-IWL3945_UCODE_GET(boot_size);
-
static struct iwl_hcmd_ops iwl3945_hcmd = {
.rxon_assoc = iwl3945_send_rxon_assoc,
.commit_rxon = iwl3945_commit_rxon,
.send_bt_config = iwl_send_bt_config,
};

-static struct iwl_ucode_ops iwl3945_ucode = {
- .get_header_size = iwl3945_ucode_get_header_size,
- .get_build = iwl3945_ucode_get_build,
- .get_inst_size = iwl3945_ucode_get_inst_size,
- .get_data_size = iwl3945_ucode_get_data_size,
- .get_init_size = iwl3945_ucode_get_init_size,
- .get_init_data_size = iwl3945_ucode_get_init_data_size,
- .get_boot_size = iwl3945_ucode_get_boot_size,
- .get_data = iwl3945_ucode_get_data,
-};
-
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,
@@ -2847,7 +2808,6 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
};

static const struct iwl_ops iwl3945_ops = {
- .ucode = &iwl3945_ucode,
.lib = &iwl3945_lib,
.hcmd = &iwl3945_hcmd,
.utils = &iwl3945_hcmd_utils,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 9486b32..e9de109 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -2109,6 +2109,28 @@ static void iwl3945_nic_start(struct iwl_priv *priv)
iwl_write32(priv, CSR_RESET, 0);
}

+#define IWL3945_UCODE_GET(item) \
+static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\
+{ \
+ return le32_to_cpu(ucode->u.v1.item); \
+}
+
+static u32 iwl3945_ucode_get_header_size(u32 api_ver)
+{
+ return UCODE_HEADER_SIZE(1);
+}
+
+static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode)
+{
+ return (u8 *) ucode->u.v1.data;
+}
+
+IWL3945_UCODE_GET(inst_size);
+IWL3945_UCODE_GET(data_size);
+IWL3945_UCODE_GET(init_size);
+IWL3945_UCODE_GET(init_data_size);
+IWL3945_UCODE_GET(boot_size);
+
/**
* iwl3945_read_ucode - Read uCode images from disk file.
*
@@ -2157,7 +2179,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
goto error;

/* Make sure that we got at least our header! */
- if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
+ if (ucode_raw->size < iwl3945_ucode_get_header_size(1)) {
IWL_ERR(priv, "File size way too small!\n");
ret = -EINVAL;
goto err_release;
@@ -2168,13 +2190,12 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)

priv->ucode_ver = le32_to_cpu(ucode->ver);
api_ver = IWL_UCODE_API(priv->ucode_ver);
- inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
- data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
- init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
- init_data_size =
- priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
- boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
- src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
+ inst_size = iwl3945_ucode_get_inst_size(ucode);
+ data_size = iwl3945_ucode_get_data_size(ucode);
+ init_size = iwl3945_ucode_get_init_size(ucode);
+ init_data_size = iwl3945_ucode_get_init_data_size(ucode);
+ boot_size = iwl3945_ucode_get_boot_size(ucode);
+ src = iwl3945_ucode_get_data(ucode);

/* api_ver should match the api version forming part of the
* firmware filename ... but we don't check for that and only rely
@@ -2223,7 +2244,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)


/* Verify size of file vs. image size info in file's header */
- if (ucode_raw->size != priv->cfg->ops->ucode->get_header_size(api_ver) +
+ if (ucode_raw->size != iwl3945_ucode_get_header_size(api_ver) +
inst_size + data_size + init_size +
init_data_size + boot_size) {

--
1.6.3.3