aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
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 7c7f7dcb1b1..0a67b2fa52a 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;