aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-04-30 14:30:43 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-05-10 18:09:04 -0400
commitfd1af15d0a82ae681ecf34192150e27455c9c494 (patch)
tree828b4532c5aa2df1859f461e828fd8b4606ec43c /drivers/net/wireless/iwlwifi/iwl-sta.c
parent4ff739747de20506e478269221f22f3d8d24c706 (diff)
iwlwifi: track station IDs
mac80211 allows us to store private data per station, so put the station ID there. This allows us to avoid the station ID lookup when removing regular stations. To also be able to avoid the lookup to remove the special IBSS BSSID station, track its ID in the per-vif private data. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
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);