diff options
author | Reinette Chatre <reinette.chatre@intel.com> | 2010-02-19 01:58:32 -0500 |
---|---|---|
committer | Reinette Chatre <reinette.chatre@intel.com> | 2010-03-19 16:40:49 -0400 |
commit | 7e2461910e9115c9964975f77584baf8c2f76bfe (patch) | |
tree | edb0c98a855116e54555f162db166d4fd8ffaafc /drivers/net/wireless/iwlwifi/iwl-agn.c | |
parent | 647291f5c1596839eb69d6c1f231b2249a703c27 (diff) |
iwlwifi: only add broadcast station once
Currently the broadcast station is added after every RXON command. Change
this to only add the broadcast station when interface is added by mac80211.
With this we need some extra work to ensure broadcast station is always
present since station table is cleared when RXON without ASSOC bit set is
sent. To deal with this we re-add all driver known stations to uCode after
such an RXON command is sent.
We also do some cleanup and remove the various calls to clear the station
table. We now only clear the station table in two scenarios:
- only clear uCode portion of station table when RXON command without ASSOC
bit is sent
- clear uCode and driver portion when interface goes down or is removed.
We need to do this clearing when interface goes down to deal with the
device restart/reconfigure routines which do not remove the interface, but
do add the interface during reconfiguration.
Previously the keys were also cleared when station table in driver is
cleared, this is not done anymore since mac80211 will take care that keys
are set and cleared correctly.
There is a known issue with this change. Associating with different AP
without bringing interface down fails with a firmware error. This is
because of the lack of full station notification support and the later
patches in this series that complete the station notification support will
fix this.
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 27 |
1 files changed, 10 insertions, 17 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index d6e1a059b9b0..85ff1552481f 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -166,6 +166,8 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
166 | IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); | 166 | IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); |
167 | return ret; | 167 | return ret; |
168 | } | 168 | } |
169 | iwl_clear_ucode_stations(priv, false); | ||
170 | iwl_restore_stations(priv); | ||
169 | } | 171 | } |
170 | 172 | ||
171 | IWL_DEBUG_INFO(priv, "Sending RXON\n" | 173 | IWL_DEBUG_INFO(priv, "Sending RXON\n" |
@@ -179,9 +181,8 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
179 | iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); | 181 | iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); |
180 | 182 | ||
181 | /* Apply the new configuration | 183 | /* Apply the new configuration |
182 | * RXON unassoc clears the station table in uCode, send it before | 184 | * RXON unassoc clears the station table in uCode so restoration of |
183 | * we add the bcast station. If assoc bit is set, we will send RXON | 185 | * stations is needed after it (the RXON command) completes |
184 | * after having added the bcast and bssid station. | ||
185 | */ | 186 | */ |
186 | if (!new_assoc) { | 187 | if (!new_assoc) { |
187 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, | 188 | ret = iwl_send_cmd_pdu(priv, REPLY_RXON, |
@@ -190,17 +191,14 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
190 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); | 191 | IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); |
191 | return ret; | 192 | return ret; |
192 | } | 193 | } |
194 | IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON. \n"); | ||
193 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 195 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
196 | iwl_clear_ucode_stations(priv, false); | ||
197 | iwl_restore_stations(priv); | ||
194 | } | 198 | } |
195 | 199 | ||
196 | iwl_clear_stations_table(priv); | ||
197 | |||
198 | priv->start_calib = 0; | 200 | priv->start_calib = 0; |
199 | 201 | ||
200 | /* Add the broadcast address so we can send broadcast frames */ | ||
201 | priv->cfg->ops->lib->add_bcast_station(priv); | ||
202 | |||
203 | |||
204 | /* If we have set the ASSOC_MSK and we are in BSS mode then | 202 | /* If we have set the ASSOC_MSK and we are in BSS mode then |
205 | * add the IWL_AP_ID to the station rate table */ | 203 | * add the IWL_AP_ID to the station rate table */ |
206 | if (new_assoc) { | 204 | if (new_assoc) { |
@@ -2087,7 +2085,6 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2087 | goto restart; | 2085 | goto restart; |
2088 | } | 2086 | } |
2089 | 2087 | ||
2090 | iwl_clear_stations_table(priv); | ||
2091 | ret = priv->cfg->ops->lib->alive_notify(priv); | 2088 | ret = priv->cfg->ops->lib->alive_notify(priv); |
2092 | if (ret) { | 2089 | if (ret) { |
2093 | IWL_WARN(priv, | 2090 | IWL_WARN(priv, |
@@ -2143,6 +2140,8 @@ static void iwl_alive_start(struct iwl_priv *priv) | |||
2143 | wake_up_interruptible(&priv->wait_command_queue); | 2140 | wake_up_interruptible(&priv->wait_command_queue); |
2144 | 2141 | ||
2145 | iwl_power_update_mode(priv, true); | 2142 | iwl_power_update_mode(priv, true); |
2143 | IWL_DEBUG_INFO(priv, "Updated power mode\n"); | ||
2144 | |||
2146 | 2145 | ||
2147 | return; | 2146 | return; |
2148 | 2147 | ||
@@ -2162,7 +2161,7 @@ static void __iwl_down(struct iwl_priv *priv) | |||
2162 | if (!exit_pending) | 2161 | if (!exit_pending) |
2163 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2162 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
2164 | 2163 | ||
2165 | iwl_clear_stations_table(priv); | 2164 | iwl_clear_ucode_stations(priv, true); |
2166 | 2165 | ||
2167 | /* Unblock any waiting calls */ | 2166 | /* Unblock any waiting calls */ |
2168 | wake_up_interruptible_all(&priv->wait_command_queue); | 2167 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -2359,8 +2358,6 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2359 | 2358 | ||
2360 | for (i = 0; i < MAX_HW_RESTARTS; i++) { | 2359 | for (i = 0; i < MAX_HW_RESTARTS; i++) { |
2361 | 2360 | ||
2362 | iwl_clear_stations_table(priv); | ||
2363 | |||
2364 | /* load bootstrap state machine, | 2361 | /* load bootstrap state machine, |
2365 | * load bootstrap program into processor's memory, | 2362 | * load bootstrap program into processor's memory, |
2366 | * prepare to load the "initialize" uCode */ | 2363 | * prepare to load the "initialize" uCode */ |
@@ -3270,9 +3267,6 @@ static int iwl_init_drv(struct iwl_priv *priv) | |||
3270 | mutex_init(&priv->mutex); | 3267 | mutex_init(&priv->mutex); |
3271 | mutex_init(&priv->sync_cmd_mutex); | 3268 | mutex_init(&priv->sync_cmd_mutex); |
3272 | 3269 | ||
3273 | /* Clear the driver's (not device's) station table */ | ||
3274 | iwl_clear_stations_table(priv); | ||
3275 | |||
3276 | priv->ieee_channels = NULL; | 3270 | priv->ieee_channels = NULL; |
3277 | priv->ieee_rates = NULL; | 3271 | priv->ieee_rates = NULL; |
3278 | priv->band = IEEE80211_BAND_2GHZ; | 3272 | priv->band = IEEE80211_BAND_2GHZ; |
@@ -3649,7 +3643,6 @@ static void __devexit iwl_pci_remove(struct pci_dev *pdev) | |||
3649 | iwl_rx_queue_free(priv, &priv->rxq); | 3643 | iwl_rx_queue_free(priv, &priv->rxq); |
3650 | iwl_hw_txq_ctx_free(priv); | 3644 | iwl_hw_txq_ctx_free(priv); |
3651 | 3645 | ||
3652 | iwl_clear_stations_table(priv); | ||
3653 | iwl_eeprom_free(priv); | 3646 | iwl_eeprom_free(priv); |
3654 | 3647 | ||
3655 | 3648 | ||