aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
diff options
context:
space:
mode:
authorSujith Manoharan <Sujith.Manoharan@atheros.com>2011-02-27 09:20:40 +0530
committerJohn W. Linville <linville@tuxdriver.com>2011-03-01 13:48:21 -0500
commite7a2a4f5e61ccfae03185384e06b852dbb1e3630 (patch)
treef798c3576f9eaf7ecaf3e7ee7c2cb85435b6d84c /drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
parent67289941d80f18fd8239e350e015a4b84878412b (diff)
downloadkernel_samsung_smdk4412-e7a2a4f5e61ccfae03185384e06b852dbb1e3630.zip
kernel_samsung_smdk4412-e7a2a4f5e61ccfae03185384e06b852dbb1e3630.tar.gz
kernel_samsung_smdk4412-e7a2a4f5e61ccfae03185384e06b852dbb1e3630.tar.bz2
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>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/htc_drv_beacon.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_beacon.c58
1 files changed, 52 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
index 007b99f..8d1d879 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,
/* TSF out of range threshold fixed at 1 second */
bs.bs_tsfoor_threshold = ATH9K_TSFOOR_THRESHOLD;
- ath_dbg(common, ATH_DBG_BEACON, "tsf: %llu tsftu: %u\n", tsf, tsftu);
- ath_dbg(common, ATH_DBG_BEACON,
+ ath_dbg(common, ATH_DBG_CONFIG, "intval: %u tsf: %llu tsftu: %u\n",
+ intval, tsf, tsftu);
+ ath_dbg(common, ATH_DBG_CONFIG,
"bmiss: %u sleep: %u cfp-period: %u maxdur: %u next: %u\n",
bs.bs_bmissthreshold, bs.bs_sleepduration,
bs.bs_cfpperiod, bs.bs_cfpmaxduration, bs.bs_cfpnext);
@@ -309,12 +310,23 @@ void ath9k_htc_beaconq_config(struct ath9k_htc_priv *priv)
}
}
-void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
- struct ieee80211_vif *vif)
+static void ath9k_htc_beacon_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
+{
+ bool *beacon_configured = (bool *)data;
+ struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
+
+ if (vif->type == NL80211_IFTYPE_STATION &&
+ avp->beacon_configured)
+ *beacon_configured = true;
+}
+
+static bool ath9k_htc_check_beacon_config(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif)
{
struct ath_common *common = ath9k_hw_common(priv->ah);
struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ bool beacon_configured;
/*
* Changing the beacon interval when multiple AP interfaces
@@ -327,7 +339,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
(cur_conf->beacon_interval != bss_conf->beacon_int)) {
ath_dbg(common, ATH_DBG_CONFIG,
"Changing beacon interval of multiple AP interfaces !\n");
- return;
+ return false;
}
/*
@@ -338,9 +350,42 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
(vif->type != NL80211_IFTYPE_AP)) {
ath_dbg(common, ATH_DBG_CONFIG,
"HW in AP mode, cannot set STA beacon parameters\n");
- return;
+ return false;
+ }
+
+ /*
+ * The beacon parameters are configured only for the first
+ * station interface.
+ */
+ if ((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
+ (priv->num_sta_vif > 1) &&
+ (vif->type == NL80211_IFTYPE_STATION)) {
+ beacon_configured = false;
+ ieee80211_iterate_active_interfaces_atomic(priv->hw,
+ ath9k_htc_beacon_iter,
+ &beacon_configured);
+
+ if (beacon_configured) {
+ ath_dbg(common, ATH_DBG_CONFIG,
+ "Beacon already configured for a station interface\n");
+ return false;
+ }
}
+ return true;
+}
+
+void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
+ struct ieee80211_vif *vif)
+{
+ struct ath_common *common = ath9k_hw_common(priv->ah);
+ struct htc_beacon_config *cur_conf = &priv->cur_beacon_conf;
+ struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+ struct ath9k_htc_vif *avp = (struct ath9k_htc_vif *) vif->drv_priv;
+
+ if (!ath9k_htc_check_beacon_config(priv, vif))
+ return;
+
cur_conf->beacon_interval = bss_conf->beacon_int;
if (cur_conf->beacon_interval == 0)
cur_conf->beacon_interval = 100;
@@ -352,6 +397,7 @@ void ath9k_htc_beacon_config(struct ath9k_htc_priv *priv,
switch (vif->type) {
case NL80211_IFTYPE_STATION:
ath9k_htc_beacon_config_sta(priv, cur_conf);
+ avp->beacon_configured = true;
break;
case NL80211_IFTYPE_ADHOC:
ath9k_htc_beacon_config_adhoc(priv, cur_conf);