diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-04-30 14:30:43 -0400 |
---|---|---|
committer | Reinette Chatre <reinette.chatre@intel.com> | 2010-05-10 18:09:04 -0400 |
commit | fd1af15d0a82ae681ecf34192150e27455c9c494 (patch) | |
tree | 828b4532c5aa2df1859f461e828fd8b4606ec43c /drivers/net/wireless/iwlwifi/iwl-sta.c | |
parent | 4ff739747de20506e478269221f22f3d8d24c706 (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.c | 61 |
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 | */ |
472 | int iwl_add_local_station(struct iwl_priv *priv, const u8 *addr, bool init_rs) | 472 | int 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 | */ |
585 | int iwl_remove_station(struct iwl_priv *priv, const u8 *addr) | 592 | int 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; | 645 | out_err: |
652 | out: | ||
653 | spin_unlock_irqrestore(&priv->sta_lock, flags); | 646 | spin_unlock_irqrestore(&priv->sta_lock, flags); |
654 | return ret; | 647 | return -EINVAL; |
655 | } | 648 | } |
656 | EXPORT_SYMBOL_GPL(iwl_remove_station); | 649 | EXPORT_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) | |||
1467 | EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); | 1460 | EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); |
1468 | 1461 | ||
1469 | int iwl_mac_sta_remove(struct ieee80211_hw *hw, | 1462 | int 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); |