diff options
author | Sujith Manoharan <Sujith.Manoharan@atheros.com> | 2011-05-17 03:12:03 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-19 13:54:01 -0400 |
commit | 0cd075d74b319b88bbaad666c2b9b911859a5b0e (patch) | |
tree | 26ae2e903713fa8c2c3710dc98a690ec58b8dd42 | |
parent | 33a5315f97e5b3964183f0cf74768ac47eabe631 (diff) |
ath9k_htc: Fix BSSID calculation
The BSSID/AID has to be set for the first associated station interface.
Subsequent interfaces may move out of assoc/disassoc status, in which
case, the BSSID has to be re-calculated from the available interfaces.
Also, ANI should be enabled or disabled based on the current opmode.
Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/htc_drv_main.c | 66 |
2 files changed, 44 insertions, 23 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 29dfdf8ebee4..fa5bb39fd952 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -438,6 +438,7 @@ struct ath9k_htc_priv { | |||
438 | u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; | 438 | u8 vif_sta_pos[ATH9K_HTC_MAX_VIF]; |
439 | u8 num_ibss_vif; | 439 | u8 num_ibss_vif; |
440 | u8 num_sta_vif; | 440 | u8 num_sta_vif; |
441 | u8 num_sta_assoc_vif; | ||
441 | u8 num_ap_vif; | 442 | u8 num_ap_vif; |
442 | 443 | ||
443 | u16 op_flags; | 444 | u16 op_flags; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8a82e821665c..6eedabbf1892 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -1436,6 +1436,37 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, | |||
1436 | return ret; | 1436 | return ret; |
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | static void ath9k_htc_set_bssid(struct ath9k_htc_priv *priv) | ||
1440 | { | ||
1441 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1442 | |||
1443 | ath9k_hw_write_associd(priv->ah); | ||
1444 | ath_dbg(common, ATH_DBG_CONFIG, | ||
1445 | "BSSID: %pM aid: 0x%x\n", | ||
1446 | common->curbssid, common->curaid); | ||
1447 | } | ||
1448 | |||
1449 | static void ath9k_htc_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | ||
1450 | { | ||
1451 | struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *)data; | ||
1452 | struct ath_common *common = ath9k_hw_common(priv->ah); | ||
1453 | struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; | ||
1454 | |||
1455 | if ((vif->type == NL80211_IFTYPE_STATION) && bss_conf->assoc) { | ||
1456 | common->curaid = bss_conf->aid; | ||
1457 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | ||
1458 | } | ||
1459 | } | ||
1460 | |||
1461 | static void ath9k_htc_choose_set_bssid(struct ath9k_htc_priv *priv) | ||
1462 | { | ||
1463 | if (priv->num_sta_assoc_vif == 1) { | ||
1464 | ieee80211_iterate_active_interfaces_atomic(priv->hw, | ||
1465 | ath9k_htc_bss_iter, priv); | ||
1466 | ath9k_htc_set_bssid(priv); | ||
1467 | } | ||
1468 | } | ||
1469 | |||
1439 | static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | 1470 | static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, |
1440 | struct ieee80211_vif *vif, | 1471 | struct ieee80211_vif *vif, |
1441 | struct ieee80211_bss_conf *bss_conf, | 1472 | struct ieee80211_bss_conf *bss_conf, |
@@ -1444,43 +1475,32 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw, | |||
1444 | struct ath9k_htc_priv *priv = hw->priv; | 1475 | struct ath9k_htc_priv *priv = hw->priv; |
1445 | struct ath_hw *ah = priv->ah; | 1476 | struct ath_hw *ah = priv->ah; |
1446 | struct ath_common *common = ath9k_hw_common(ah); | 1477 | struct ath_common *common = ath9k_hw_common(ah); |
1447 | bool set_assoc; | ||
1448 | 1478 | ||
1449 | mutex_lock(&priv->mutex); | 1479 | mutex_lock(&priv->mutex); |
1450 | ath9k_htc_ps_wakeup(priv); | 1480 | ath9k_htc_ps_wakeup(priv); |
1451 | 1481 | ||
1452 | /* | ||
1453 | * Set the HW AID/BSSID only for the first station interface | ||
1454 | * or in IBSS mode. | ||
1455 | */ | ||
1456 | set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) || | ||
1457 | ((priv->ah->opmode == NL80211_IFTYPE_STATION) && | ||
1458 | (priv->num_sta_vif == 1))); | ||
1459 | |||
1460 | |||
1461 | if (changed & BSS_CHANGED_ASSOC) { | 1482 | if (changed & BSS_CHANGED_ASSOC) { |
1462 | if (set_assoc) { | 1483 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", |
1463 | ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", | 1484 | bss_conf->assoc); |
1464 | bss_conf->assoc); | ||
1465 | 1485 | ||
1466 | common->curaid = bss_conf->assoc ? | 1486 | bss_conf->assoc ? |
1467 | bss_conf->aid : 0; | 1487 | priv->num_sta_assoc_vif++ : priv->num_sta_assoc_vif--; |
1468 | 1488 | ||
1469 | if (bss_conf->assoc) | 1489 | if (priv->ah->opmode == NL80211_IFTYPE_STATION) { |
1490 | if (bss_conf->assoc && (priv->num_sta_assoc_vif == 1)) | ||
1470 | ath9k_htc_start_ani(priv); | 1491 | ath9k_htc_start_ani(priv); |
1471 | else | 1492 | else if (priv->num_sta_assoc_vif == 0) |
1472 | ath9k_htc_stop_ani(priv); | 1493 | ath9k_htc_stop_ani(priv); |
1473 | } | 1494 | } |
1474 | } | 1495 | } |
1475 | 1496 | ||
1476 | if (changed & BSS_CHANGED_BSSID) { | 1497 | if (changed & BSS_CHANGED_BSSID) { |
1477 | if (set_assoc) { | 1498 | if (priv->ah->opmode == NL80211_IFTYPE_ADHOC) { |
1499 | common->curaid = bss_conf->aid; | ||
1478 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); | 1500 | memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); |
1479 | ath9k_hw_write_associd(ah); | 1501 | ath9k_htc_set_bssid(priv); |
1480 | 1502 | } else if (priv->ah->opmode == NL80211_IFTYPE_STATION) { | |
1481 | ath_dbg(common, ATH_DBG_CONFIG, | 1503 | ath9k_htc_choose_set_bssid(priv); |
1482 | "BSSID: %pM aid: 0x%x\n", | ||
1483 | common->curbssid, common->curaid); | ||
1484 | } | 1504 | } |
1485 | } | 1505 | } |
1486 | 1506 | ||