aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-02-26 22:50:40 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-03-01 13:48:21 -0500
commite7a2a4f5e61ccfae03185384e06b852dbb1e3630 (patch)
treef798c3576f9eaf7ecaf3e7ee7c2cb85435b6d84c
parent67289941d80f18fd8239e350e015a4b84878412b (diff)
ath9k_htc: Handle BSSID/AID for multiple interfaces
The AID and BSSID should be set in the HW only for the first station interface or adhoc interface. Also, cancel the ANI timer in stop() for multi-STA scenario. And finally configure the HW beacon timers only for the first station interface. 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.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c58
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c42
3 files changed, 81 insertions, 20 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index e9c51cae88ab..753a245c5ad1 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -243,6 +243,7 @@ struct ath9k_htc_target_stats {
243struct ath9k_htc_vif { 243struct ath9k_htc_vif {
244 u8 index; 244 u8 index;
245 u16 seq_no; 245 u16 seq_no;
246 bool beacon_configured;
246}; 247};
247 248
248struct ath9k_vif_iter_data { 249struct ath9k_vif_iter_data {
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 007b99fc50c8..8d1d8792436d 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
@@ -123,8 +123,9 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
123 /* TSF out of range threshold fixed at 1 second */ 123 /* TSF out of range threshold fixed at 1 second */
124 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD; 124 bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
125 125
126 ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu); 126 ath_dbg(common, ATH_DBG_CONFIG, "intval: %u tsf: %llu tsftu: %u\n",
127 ath_dbg(common, ATH_DBG_BEACON, 127 intval, tsf, tsftu);
128 ath_dbg(common, ATH_DBG_CONFIG,
128 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n", 129 "bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
129 bs.bs_bmissthreshold, bs.bs_sleepduration, 130 bs.bs_bmissthreshold, bs.bs_sleepduration,
130 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext); 131 bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
@@ -309,12 +310,23 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
309 } 310 }
310} 311}
311 312
312void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv, 313static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
313 struct ieee80211_vif *vif) 314{
315 bool *beacon_configured = (bool *)data;
316 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
317
318 if (vif->type == NL80211_IFTYPE_STATION &&
319 avp->beacon_configured)
320 *beacon_configured = true;
321}
322
323static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
324 struct ieee80211_vif *vif)
314{ 325{
315 struct ath_common *common = ath9k_hw_common(priv->ah); 326 struct ath_common *common = ath9k_hw_common(priv->ah);
316 struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf; 327 struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
317 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 328 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
329 bool beacon_configured;
318 330
319 /* 331 /*
320 * Changing the beacon interval when multiple AP interfaces 332 * Changing the beacon interval when multiple AP interfaces
@@ -327,7 +339,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
327 (cur_conf->beacon_interval != bss_conf->beacon_int)) { 339 (cur_conf->beacon_interval != bss_conf->beacon_int)) {
328 ath_dbg(common, ATH_DBG_CONFIG, 340 ath_dbg(common, ATH_DBG_CONFIG,
329 "Changing beacon interval of multiple AP interfaces !\n"); 341 "Changing beacon interval of multiple AP interfaces !\n");
330 return; 342 return false;
331 } 343 }
332 344
333 /* 345 /*
@@ -338,9 +350,42 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
338 (vif->type != NL80211_IFTYPE_AP)) { 350 (vif->type != NL80211_IFTYPE_AP)) {
339 ath_dbg(common, ATH_DBG_CONFIG, 351 ath_dbg(common, ATH_DBG_CONFIG,
340 "HW in AP mode, cannot set STA beacon parameters\n"); 352 "HW in AP mode, cannot set STA beacon parameters\n");
341 return; 353 return false;
354 }
355
356 /*
357 * The beacon parameters are configured only for the first
358 * station interface.
359 */
360 if ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
361 (priv->num_sta_vif > 1) &&
362 (vif->type == NL80211_IFTYPE_STATION)) {
363 beacon_configured = false;
364 ieee80211_iterate_active_interfaces_atomic(priv->hw,
365 ath9k_htc_beacon_iter,
366 &beacon_configured);
367
368 if (beacon_configured) {
369 ath_dbg(common, ATH_DBG_CONFIG,
370 "Beacon already configured for a station interface\n");
371 return false;
372 }
342 } 373 }
343 374
375 return true;
376}
377
378void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
379 struct ieee80211_vif *vif)
380{
381 struct ath_common *common = ath9k_hw_common(priv->ah);
382 struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
383 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
384 struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
385
386 if (!ath9k_htc_check_beacon_config(priv, vif))
387 return;
388
344 cur_conf->beacon_interval = bss_conf->beacon_int; 389 cur_conf->beacon_interval = bss_conf->beacon_int;
345 if (cur_conf->beacon_interval == 0) 390 if (cur_conf->beacon_interval == 0)
346 cur_conf->beacon_interval = 100; 391 cur_conf->beacon_interval = 100;
@@ -352,6 +397,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
352 switch (vif->type) { 397 switch (vif->type) {
353 case NL80211_IFTYPE_STATION: 398 case NL80211_IFTYPE_STATION:
354 ath9k_htc_beacon_config_sta(priv, cur_conf); 399 ath9k_htc_beacon_config_sta(priv, cur_conf);
400 avp->beacon_configured = true;
355 break; 401 break;
356 case NL80211_IFTYPE_ADHOC: 402 case NL80211_IFTYPE_ADHOC:
357 ath9k_htc_beacon_config_adhoc(priv, cur_conf); 403 ath9k_htc_beacon_config_adhoc(priv, cur_conf);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 71adab34006c..db8c0c044e9e 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1601,30 +1601,44 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
1601 struct ath9k_htc_priv *priv = hw->priv; 1601 struct ath9k_htc_priv *priv = hw->priv;
1602 struct ath_hw *ah = priv->ah; 1602 struct ath_hw *ah = priv->ah;
1603 struct ath_common *common = ath9k_hw_common(ah); 1603 struct ath_common *common = ath9k_hw_common(ah);
1604 bool set_assoc;
1604 1605
1605 mutex_lock(&priv->mutex); 1606 mutex_lock(&priv->mutex);
1606 ath9k_htc_ps_wakeup(priv); 1607 ath9k_htc_ps_wakeup(priv);
1607 1608
1609 /*
1610 * Set the HW AID/BSSID only for the first station interface
1611 * or in IBSS mode.
1612 */
1613 set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) ||
1614 ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
1615 (priv->num_sta_vif == 1)));
1616
1617
1608 if (changed & BSS_CHANGED_ASSOC) { 1618 if (changed & BSS_CHANGED_ASSOC) {
1609 common->curaid = bss_conf->assoc ? 1619 if (set_assoc) {
1610 bss_conf->aid : 0; 1620 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
1611 ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n", 1621 bss_conf->assoc);
1612 bss_conf->assoc);
1613 1622
1614 if (bss_conf->assoc) 1623 common->curaid = bss_conf->assoc ?
1615 ath9k_htc_start_ani(priv); 1624 bss_conf->aid : 0;
1616 else 1625
1617 ath9k_htc_stop_ani(priv); 1626 if (bss_conf->assoc)
1627 ath9k_htc_start_ani(priv);
1628 else
1629 ath9k_htc_stop_ani(priv);
1630 }
1618 } 1631 }
1619 1632
1620 if (changed & BSS_CHANGED_BSSID) { 1633 if (changed & BSS_CHANGED_BSSID) {
1621 /* Set BSSID */ 1634 if (set_assoc) {
1622 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 1635 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1623 ath9k_hw_write_associd(ah); 1636 ath9k_hw_write_associd(ah);
1624 1637
1625 ath_dbg(common, ATH_DBG_CONFIG, 1638 ath_dbg(common, ATH_DBG_CONFIG,
1626 "BSSID: %pM aid: 0x%x\n", 1639 "BSSID: %pM aid: 0x%x\n",
1627 common->curbssid, common->curaid); 1640 common->curbssid, common->curaid);
1641 }
1628 } 1642 }
1629 1643
1630 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) { 1644 if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {