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>
This commit is contained in:
parent
67289941d8
commit
e7a2a4f5e6
|
@ -243,6 +243,7 @@ struct ath9k_htc_target_stats {
|
|||
struct ath9k_htc_vif {
|
||||
u8 index;
|
||||
u16 seq_no;
|
||||
bool beacon_configured;
|
||||
};
|
||||
|
||||
struct ath9k_vif_iter_data {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1601,30 +1601,44 @@ static void ath9k_htc_bss_info_changed(struct ieee80211_hw *hw,
|
|||
struct ath9k_htc_priv *priv = hw->priv;
|
||||
struct ath_hw *ah = priv->ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
bool set_assoc;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
ath9k_htc_ps_wakeup(priv);
|
||||
|
||||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
common->curaid = bss_conf->assoc ?
|
||||
bss_conf->aid : 0;
|
||||
ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
|
||||
bss_conf->assoc);
|
||||
/*
|
||||
* Set the HW AID/BSSID only for the first station interface
|
||||
* or in IBSS mode.
|
||||
*/
|
||||
set_assoc = !!((priv->ah->opmode == NL80211_IFTYPE_ADHOC) ||
|
||||
((priv->ah->opmode == NL80211_IFTYPE_STATION) &&
|
||||
(priv->num_sta_vif == 1)));
|
||||
|
||||
if (bss_conf->assoc)
|
||||
ath9k_htc_start_ani(priv);
|
||||
else
|
||||
ath9k_htc_stop_ani(priv);
|
||||
|
||||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
if (set_assoc) {
|
||||
ath_dbg(common, ATH_DBG_CONFIG, "BSS Changed ASSOC %d\n",
|
||||
bss_conf->assoc);
|
||||
|
||||
common->curaid = bss_conf->assoc ?
|
||||
bss_conf->aid : 0;
|
||||
|
||||
if (bss_conf->assoc)
|
||||
ath9k_htc_start_ani(priv);
|
||||
else
|
||||
ath9k_htc_stop_ani(priv);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BSSID) {
|
||||
/* Set BSSID */
|
||||
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
|
||||
ath9k_hw_write_associd(ah);
|
||||
if (set_assoc) {
|
||||
memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
|
||||
ath9k_hw_write_associd(ah);
|
||||
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"BSSID: %pM aid: 0x%x\n",
|
||||
common->curbssid, common->curaid);
|
||||
ath_dbg(common, ATH_DBG_CONFIG,
|
||||
"BSSID: %pM aid: 0x%x\n",
|
||||
common->curbssid, common->curaid);
|
||||
}
|
||||
}
|
||||
|
||||
if ((changed & BSS_CHANGED_BEACON_ENABLED) && bss_conf->enable_beacon) {
|
||||
|
|
Loading…
Reference in New Issue