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.c61
1 files changed, 28 insertions, 33 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index e95282b93c3a..d1986dedc863 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -462,26 +462,33 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
462} 462}
463 463
464/* 464/*
465 * iwl_add_local_stations - Add stations not requested by mac80211 465 * iwl_add_local_station - Add stations not requested by mac80211
466 * 466 *
467 * This will be either the broadcast station or the bssid station needed by 467 * This will be either the broadcast station or the bssid station needed by
468 * ad-hoc. 468 * ad-hoc.
469 * 469 *
470 * Function sleeps. 470 * Function sleeps.
471 */ 471 */
472int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs) 472int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
473 u8 *sta_id_r)
473{ 474{
474 int ret; 475 int ret;
475 u8 sta_id; 476 u8 sta_id;
476 struct iwl_link_quality_cmd *link_cmd; 477 struct iwl_link_quality_cmd *link_cmd;
477 unsigned long flags; 478 unsigned long flags;
478 479
480 if (*sta_id_r)
481 *sta_id_r = IWL_INVALID_STATION;
482
479 ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id); 483 ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id);
480 if (ret) { 484 if (ret) {
481 IWL_ERR(priv, "Unable to add station %pM\n", addr); 485 IWL_ERR(priv, "Unable to add station %pM\n", addr);
482 return ret; 486 return ret;
483 } 487 }
484 488
489 if (sta_id_r)
490 *sta_id_r = sta_id;
491
485 spin_lock_irqsave(&priv->sta_lock, flags); 492 spin_lock_irqsave(&priv->sta_lock, flags);
486 priv->stations[sta_id].used |= IWL_STA_LOCAL; 493 priv->stations[sta_id].used |= IWL_STA_LOCAL;
487 spin_unlock_irqrestore(&priv->sta_lock, flags); 494 spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -582,13 +589,11 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
582/** 589/**
583 * iwl_remove_station - Remove driver's knowledge of station. 590 * iwl_remove_station - Remove driver's knowledge of station.
584 */ 591 */
585int iwl_remove_station(struct iwl_priv *priv, const u8 *addr) 592int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
593 const u8 *addr)
586{ 594{
587 int sta_id = IWL_INVALID_STATION;
588 int i, ret = -EINVAL;
589 unsigned long flags;
590 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION;
591 struct iwl_station_entry *station; 595 struct iwl_station_entry *station;
596 unsigned long flags;
592 597
593 if (!iwl_is_ready(priv)) { 598 if (!iwl_is_ready(priv)) {
594 IWL_DEBUG_INFO(priv, 599 IWL_DEBUG_INFO(priv,
@@ -602,35 +607,24 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
602 return 0; 607 return 0;
603 } 608 }
604 609
605 spin_lock_irqsave(&priv->sta_lock, flags); 610 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n",
606 611 sta_id, addr);
607 if (is_ap)
608 sta_id = IWL_AP_ID;
609 else
610 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++)
611 if (priv->stations[i].used &&
612 !compare_ether_addr(priv->stations[i].sta.sta.addr,
613 addr)) {
614 sta_id = i;
615 break;
616 }
617 612
618 if (unlikely(sta_id == IWL_INVALID_STATION)) 613 if (WARN_ON(sta_id == IWL_INVALID_STATION))
619 goto out; 614 return -EINVAL;
620 615
621 IWL_DEBUG_ASSOC(priv, "Removing STA from driver:%d %pM\n", 616 spin_lock_irqsave(&priv->sta_lock, flags);
622 sta_id, addr);
623 617
624 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) { 618 if (!(priv->stations[sta_id].used & IWL_STA_DRIVER_ACTIVE)) {
625 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n", 619 IWL_DEBUG_INFO(priv, "Removing %pM but non DRIVER active\n",
626 addr); 620 addr);
627 goto out; 621 goto out_err;
628 } 622 }
629 623
630 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) { 624 if (!(priv->stations[sta_id].used & IWL_STA_UCODE_ACTIVE)) {
631 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n", 625 IWL_DEBUG_INFO(priv, "Removing %pM but non UCODE active\n",
632 addr); 626 addr);
633 goto out; 627 goto out_err;
634 } 628 }
635 629
636 if (priv->stations[sta_id].used & IWL_STA_LOCAL) { 630 if (priv->stations[sta_id].used & IWL_STA_LOCAL) {
@@ -647,11 +641,10 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 *addr)
647 station = &priv->stations[sta_id]; 641 station = &priv->stations[sta_id];
648 spin_unlock_irqrestore(&priv->sta_lock, flags); 642 spin_unlock_irqrestore(&priv->sta_lock, flags);
649 643
650 ret = iwl_send_remove_station(priv, station); 644 return iwl_send_remove_station(priv, station);
651 return ret; 645out_err:
652out:
653 spin_unlock_irqrestore(&priv->sta_lock, flags); 646 spin_unlock_irqrestore(&priv->sta_lock, flags);
654 return ret; 647 return -EINVAL;
655} 648}
656EXPORT_SYMBOL_GPL(iwl_remove_station); 649EXPORT_SYMBOL_GPL(iwl_remove_station);
657 650
@@ -1467,14 +1460,16 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1467EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); 1460EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1468 1461
1469int iwl_mac_sta_remove(struct ieee80211_hw *hw, 1462int iwl_mac_sta_remove(struct ieee80211_hw *hw,
1470 struct ieee80211_vif *vif, 1463 struct ieee80211_vif *vif,
1471 struct ieee80211_sta *sta) 1464 struct ieee80211_sta *sta)
1472{ 1465{
1473 int ret;
1474 struct iwl_priv *priv = hw->priv; 1466 struct iwl_priv *priv = hw->priv;
1467 struct iwl_station_priv_common *sta_common = (void *)sta->drv_priv;
1468 int ret;
1469
1475 IWL_DEBUG_INFO(priv, "received request to remove station %pM\n", 1470 IWL_DEBUG_INFO(priv, "received request to remove station %pM\n",
1476 sta->addr); 1471 sta->addr);
1477 ret = iwl_remove_station(priv, sta->addr); 1472 ret = iwl_remove_station(priv, sta_common->sta_id, sta->addr);
1478 if (ret) 1473 if (ret)
1479 IWL_ERR(priv, "Error removing station %pM\n", 1474 IWL_ERR(priv, "Error removing station %pM\n",
1480 sta->addr); 1475 sta->addr);