Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 193805
b: refs/heads/master
c: 7e24619
h: refs/heads/master
i:
  193803: 3663781
v: v3
  • Loading branch information
Reinette Chatre committed Mar 19, 2010
1 parent e7be4d8 commit 9d3984d
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 58 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 647291f5c1596839eb69d6c1f231b2249a703c27
refs/heads/master: 7e2461910e9115c9964975f77584baf8c2f76bfe
10 changes: 6 additions & 4 deletions trunk/drivers/net/wireless/iwlwifi/iwl-3945.c
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,8 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
"configuration (%d).\n", rc);
return rc;
}
iwl_clear_ucode_stations(priv, false);
iwl_restore_stations(priv);
}

IWL_DEBUG_INFO(priv, "Sending RXON\n"
Expand Down Expand Up @@ -1941,7 +1943,10 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)

memcpy(active_rxon, staging_rxon, sizeof(*active_rxon));

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

/* If we issue a new RXON command which required a tune then we must
* send a new TXPOWER command or we won't be able to Tx any frames */
Expand All @@ -1951,9 +1956,6 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
return rc;
}

/* Add the broadcast address so we can send broadcast frames */
priv->cfg->ops->lib->add_bcast_station(priv);

/* If we have set the ASSOC_MSK and we are in BSS mode then
* add the IWL_AP_ID to the station rate table */
if (iwl_is_associated(priv) &&
Expand Down
1 change: 0 additions & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-5000.c
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,6 @@ void iwl5000_init_alive_start(struct iwl_priv *priv)
goto restart;
}

iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
IWL_WARN(priv,
Expand Down
27 changes: 10 additions & 17 deletions trunk/drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ 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_restore_stations(priv);
}

IWL_DEBUG_INFO(priv, "Sending RXON\n"
Expand All @@ -179,9 +181,8 @@ int iwl_commit_rxon(struct iwl_priv *priv)
iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);

/* Apply the new configuration
* RXON unassoc clears the station table in uCode, send it before
* we add the bcast station. If assoc bit is set, we will send RXON
* after having added the bcast and bssid station.
* RXON unassoc clears the station table in uCode so restoration of
* stations is needed after it (the RXON command) completes
*/
if (!new_assoc) {
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
Expand All @@ -190,17 +191,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
return ret;
}
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_restore_stations(priv);
}

iwl_clear_stations_table(priv);

priv->start_calib = 0;

/* Add the broadcast address so we can send broadcast frames */
priv->cfg->ops->lib->add_bcast_station(priv);


/* If we have set the ASSOC_MSK and we are in BSS mode then
* add the IWL_AP_ID to the station rate table */
if (new_assoc) {
Expand Down Expand Up @@ -2087,7 +2085,6 @@ static void iwl_alive_start(struct iwl_priv *priv)
goto restart;
}

iwl_clear_stations_table(priv);
ret = priv->cfg->ops->lib->alive_notify(priv);
if (ret) {
IWL_WARN(priv,
Expand Down Expand Up @@ -2143,6 +2140,8 @@ static void iwl_alive_start(struct iwl_priv *priv)
wake_up_interruptible(&priv->wait_command_queue);

iwl_power_update_mode(priv, true);
IWL_DEBUG_INFO(priv, "Updated power mode\n");


return;

Expand All @@ -2162,7 +2161,7 @@ static void __iwl_down(struct iwl_priv *priv)
if (!exit_pending)
set_bit(STATUS_EXIT_PENDING, &priv->status);

iwl_clear_stations_table(priv);
iwl_clear_ucode_stations(priv, true);

/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
Expand Down Expand Up @@ -2359,8 +2358,6 @@ static int __iwl_up(struct iwl_priv *priv)

for (i = 0; i < MAX_HW_RESTARTS; i++) {

iwl_clear_stations_table(priv);

/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
Expand Down Expand Up @@ -3270,9 +3267,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
mutex_init(&priv->mutex);
mutex_init(&priv->sync_cmd_mutex);

/* Clear the driver's (not device's) station table */
iwl_clear_stations_table(priv);

priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
priv->band = IEEE80211_BAND_2GHZ;
Expand Down Expand Up @@ -3649,7 +3643,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev)
iwl_rx_queue_free(priv, &priv->rxq);
iwl_hw_txq_ctx_free(priv);

iwl_clear_stations_table(priv);
iwl_eeprom_free(priv);


Expand Down
8 changes: 6 additions & 2 deletions trunk/drivers/net/wireless/iwlwifi/iwl-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2283,8 +2283,6 @@ static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)

memcpy(priv->staging_rxon.node_addr, priv->mac_addr, ETH_ALEN);

iwl_clear_stations_table(priv);

return iwlcore_commit_rxon(priv);
}

Expand Down Expand Up @@ -2317,6 +2315,10 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
err = iwl_set_mode(priv, vif);
if (err)
goto out_err;

/* Add the broadcast address so we can send broadcast frames */
priv->cfg->ops->lib->add_bcast_station(priv);

goto out;

out_err:
Expand All @@ -2339,6 +2341,8 @@ 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;
Expand Down
108 changes: 85 additions & 23 deletions trunk/drivers/net/wireless/iwlwifi/iwl-sta.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,6 @@
#include "iwl-core.h"
#include "iwl-sta.h"

#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
#define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */

u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
{
int i;
Expand Down Expand Up @@ -495,37 +492,102 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap)
}

/**
* iwl_clear_stations_table - Clear the driver's station table
*
* NOTE: This does not clear or otherwise alter the device's station table.
* 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.
*/
void iwl_clear_stations_table(struct iwl_priv *priv)
void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force)
{
unsigned long flags;
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);
}
}

spin_lock_irqsave(&priv->sta_lock, flags);
spin_lock_irqsave(&priv->sta_lock, flags_spin);
if (force) {
IWL_DEBUG_INFO(priv, "Clearing all station information in driver\n");
priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
} 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;
}
}
}
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);

if (!cleared)
IWL_DEBUG_INFO(priv, "No active stations found to be cleared\n");
}
EXPORT_SYMBOL(iwl_clear_ucode_stations);

if (iwl_is_alive(priv) &&
!test_bit(STATUS_EXIT_PENDING, &priv->status) &&
iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL))
IWL_ERR(priv, "Couldn't clear the station table\n");
/**
* iwl_restore_stations() - Restore driver known stations to device
*
* All stations considered active by driver, but not present in ucode, is
* restored.
*/
void iwl_restore_stations(struct iwl_priv *priv)
{
unsigned long flags_spin;
int i;
bool found = false;

priv->num_stations = 0;
memset(priv->stations, 0, sizeof(priv->stations));
if (!iwl_is_ready(priv)) {
IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
return;
}

/* clean ucode key table bit map */
priv->ucode_key_table = 0;
IWL_DEBUG_ASSOC(priv, "Restoring all known stations ... start.\n");
spin_lock_irqsave(&priv->sta_lock, flags_spin);
for (i = 0; i < priv->hw_params.max_stations; i++) {
if ((priv->stations[i].used & IWL_STA_DRIVER_ACTIVE) &&
!(priv->stations[i].used & IWL_STA_UCODE_ACTIVE)) {
IWL_DEBUG_ASSOC(priv, "Restoring sta %pM\n",
priv->stations[i].sta.sta.addr);
priv->stations[i].sta.mode = 0;
priv->stations[i].used |= IWL_STA_UCODE_INPROGRESS;
found = true;
}
}

/* keep track of static keys */
for (i = 0; i < WEP_KEYS_MAX ; i++) {
if (priv->wep_keys[i].key_size)
set_bit(i, &priv->ucode_key_table);
for (i = 0; i < priv->hw_params.max_stations; i++) {
if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
iwl_send_add_sta(priv, &priv->stations[i].sta,
CMD_ASYNC);
priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
}
}

spin_unlock_irqrestore(&priv->sta_lock, flags);
spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
if (!found)
IWL_DEBUG_INFO(priv, "Restoring all known stations .... no stations to be restored.\n");
else
IWL_DEBUG_INFO(priv, "Restoring all known stations .... in progress.\n");
}
EXPORT_SYMBOL(iwl_clear_stations_table);
EXPORT_SYMBOL(iwl_restore_stations);

int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
{
Expand Down
9 changes: 8 additions & 1 deletion trunk/drivers/net/wireless/iwlwifi/iwl-sta.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@
#define HW_KEY_DYNAMIC 0
#define HW_KEY_DEFAULT 1

#define IWL_STA_DRIVER_ACTIVE BIT(0) /* driver entry is active */
#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 */


/**
* iwl_find_station - Find station id for a given BSSID
* @bssid: MAC address of station ID to find
Expand All @@ -55,7 +61,8 @@ int iwl_rxon_add_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
void iwl_add_bcast_station(struct iwl_priv *priv);
void iwl3945_add_bcast_station(struct iwl_priv *priv);
int iwl_remove_station(struct iwl_priv *priv, const u8 *addr, bool is_ap);
void iwl_clear_stations_table(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);
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);
Expand Down
11 changes: 2 additions & 9 deletions trunk/drivers/net/wireless/iwlwifi/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2480,8 +2480,6 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
goto restart;
}

iwl_clear_stations_table(priv);

rfkill = iwl_read_prph(priv, APMG_RFKILL_REG);
IWL_DEBUG_INFO(priv, "RFKILL status: 0x%x\n", rfkill);

Expand Down Expand Up @@ -2558,7 +2556,8 @@ static void __iwl3945_down(struct iwl_priv *priv)
if (!exit_pending)
set_bit(STATUS_EXIT_PENDING, &priv->status);

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

/* Unblock any waiting calls */
wake_up_interruptible_all(&priv->wait_command_queue);
Expand Down Expand Up @@ -2692,8 +2691,6 @@ static int __iwl3945_up(struct iwl_priv *priv)

for (i = 0; i < MAX_HW_RESTARTS; i++) {

iwl_clear_stations_table(priv);

/* load bootstrap state machine,
* load bootstrap program into processor's memory,
* prepare to load the "initialize" uCode */
Expand Down Expand Up @@ -3834,9 +3831,6 @@ static int iwl3945_init_drv(struct iwl_priv *priv)
mutex_init(&priv->mutex);
mutex_init(&priv->sync_cmd_mutex);

/* Clear the driver's (not device's) station table */
iwl_clear_stations_table(priv);

priv->ieee_channels = NULL;
priv->ieee_rates = NULL;
priv->band = IEEE80211_BAND_2GHZ;
Expand Down Expand Up @@ -4196,7 +4190,6 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
iwl3945_hw_txq_ctx_free(priv);

iwl3945_unset_hw_params(priv);
iwl_clear_stations_table(priv);

/*netif_stop_queue(dev); */
flush_workqueue(priv->workqueue);
Expand Down

0 comments on commit 9d3984d

Please sign in to comment.