diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-sta.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 51 |
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 | ||
402 | static int iwl_send_remove_station(struct iwl_priv *priv, | 402 | static 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); |
509 | out_err: | 512 | out_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 | } |
625 | EXPORT_SYMBOL(iwl_restore_stations); | 628 | EXPORT_SYMBOL(iwl_restore_stations); |
626 | 629 | ||
630 | void 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 | } | ||
666 | EXPORT_SYMBOL(iwl_reprogram_ap_sta); | ||
667 | |||
627 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) | 668 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv) |
628 | { | 669 | { |
629 | int i; | 670 | int i; |