aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-11-10 21:25:48 -0500
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-11-16 10:46:35 -0500
commit2b5f7a679c2ae34407f6cc9387e77b563578bfdc (patch)
treebbd9eee3ec9925d132b4dbf044871b23997c8279 /drivers/net/wireless/iwlwifi/iwl-sta.c
parent893654de3ff41a4f5037397d06a3f853bbbb3484 (diff)
iwlagn: reprogram AP STA after assoc
Instead of unconditionally sending unassoc RXON, before any assoc RXON, re-send only the AP STA entry which is required after the BSSID has been programmed into the device to set up internal filters in the microcode properly. This fixes some issues that we correlated with sending a lot of RXON commands to the device. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-sta.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c51
1 files changed, 46 insertions, 5 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 7c7f7dcb1b1e..0a67b2fa52a1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -400,7 +400,8 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
400} 400}
401 401
402static int iwl_send_remove_station(struct iwl_priv *priv, 402static int iwl_send_remove_station(struct iwl_priv *priv,
403 const u8 *addr, int sta_id) 403 const u8 *addr, int sta_id,
404 bool temporary)
404{ 405{
405 struct iwl_rx_packet *pkt; 406 struct iwl_rx_packet *pkt;
406 int ret; 407 int ret;
@@ -436,9 +437,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
436 if (!ret) { 437 if (!ret) {
437 switch (pkt->u.rem_sta.status) { 438 switch (pkt->u.rem_sta.status) {
438 case REM_STA_SUCCESS_MSK: 439 case REM_STA_SUCCESS_MSK:
439 spin_lock_irqsave(&priv->sta_lock, flags_spin); 440 if (!temporary) {
440 iwl_sta_ucode_deactivate(priv, sta_id); 441 spin_lock_irqsave(&priv->sta_lock, flags_spin);
441 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 442 iwl_sta_ucode_deactivate(priv, sta_id);
443 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
444 }
442 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 445 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
443 break; 446 break;
444 default: 447 default:
@@ -505,7 +508,7 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
505 508
506 spin_unlock_irqrestore(&priv->sta_lock, flags); 509 spin_unlock_irqrestore(&priv->sta_lock, flags);
507 510
508 return iwl_send_remove_station(priv, addr, sta_id); 511 return iwl_send_remove_station(priv, addr, sta_id, false);
509out_err: 512out_err:
510 spin_unlock_irqrestore(&priv->sta_lock, flags); 513 spin_unlock_irqrestore(&priv->sta_lock, flags);
511 return -EINVAL; 514 return -EINVAL;
@@ -624,6 +627,44 @@ void iwl_restore_stations(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
624} 627}
625EXPORT_SYMBOL(iwl_restore_stations); 628EXPORT_SYMBOL(iwl_restore_stations);
626 629
630void iwl_reprogram_ap_sta(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
631{
632 unsigned long flags;
633 int sta_id = ctx->ap_sta_id;
634 int ret;
635 struct iwl_addsta_cmd sta_cmd;
636 struct iwl_link_quality_cmd lq;
637 bool active;
638
639 spin_lock_irqsave(&priv->sta_lock, flags);
640 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
641 spin_unlock_irqrestore(&priv->sta_lock, flags);
642 return;
643 }
644
645 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(sta_cmd));
646 sta_cmd.mode = 0;
647 memcpy(&lq, priv->stations[sta_id].lq, sizeof(lq));
648
649 active = priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE;
650 spin_unlock_irqrestore(&priv->sta_lock, flags);
651
652 if (active) {
653 ret = iwl_send_remove_station(
654 priv, priv->stations[sta_id].sta.sta.addr,
655 sta_id, true);
656 if (ret)
657 IWL_ERR(priv, "failed to remove STA %pM (%d)\n",
658 priv->stations[sta_id].sta.sta.addr, ret);
659 }
660 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
661 if (ret)
662 IWL_ERR(priv, "failed to re-add STA %pM (%d)\n",
663 priv->stations[sta_id].sta.sta.addr, ret);
664 iwl_send_lq_cmd(priv, ctx, &lq, CMD_SYNC, true);
665}
666EXPORT_SYMBOL(iwl_reprogram_ap_sta);
667
627int iwl_get_free_ucode_key_index(struct iwl_priv *priv) 668int iwl_get_free_ucode_key_index(struct iwl_priv *priv)
628{ 669{
629 int i; 670 int i;