ath9k: fix a beacon enable handling bug
Backport of r44696 Signed-off-by: Felix Fietkau <nbd@openwrt.org> git-svn-id: svn://svn.openwrt.org/openwrt/branches/barrier_breaker@44697 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
12c281e5eb
commit
8737792072
|
@ -1,3 +1,20 @@
|
|||
commit 182a72b61971fc7120d6163b2077c06618c422a4
|
||||
Author: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Thu Mar 12 17:10:50 2015 +0100
|
||||
|
||||
ath9k: fix tracking of enabled AP beacons
|
||||
|
||||
sc->nbcnvifs tracks assigned beacon slots, not enabled beacons.
|
||||
Therefore, it cannot be used to decide if cur_conf->enable_beacon (bool)
|
||||
should be updated, or if beacons have been enabled already.
|
||||
With the current code (depending on the order of calls), beacons often
|
||||
do not get enabled in an AP+STA setup.
|
||||
To fix tracking of enabled beacons, convert cur_conf->enable_beacon to a
|
||||
bitmask of enabled beacon slots.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
|
||||
|
||||
commit 228ee4473b89118993c17ead26381c490c44f9fb
|
||||
Author: Felix Fietkau <nbd@openwrt.org>
|
||||
Date: Sun Nov 30 20:34:16 2014 +0100
|
||||
|
@ -3552,3 +3569,71 @@ Date: Mon May 19 21:20:49 2014 +0200
|
|||
break;
|
||||
default:
|
||||
ath_err(common, "Invalid TX queue type: %u\n", type);
|
||||
--- a/drivers/net/wireless/ath/ath9k/beacon.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
|
||||
@@ -223,12 +223,15 @@ void ath9k_beacon_remove_slot(struct ath
|
||||
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||
struct ath_vif *avp = (void *)vif->drv_priv;
|
||||
struct ath_buf *bf = avp->av_bcbuf;
|
||||
+ struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
|
||||
|
||||
ath_dbg(common, CONFIG, "Removing interface at beacon slot: %d\n",
|
||||
avp->av_bslot);
|
||||
|
||||
tasklet_disable(&sc->bcon_tasklet);
|
||||
|
||||
+ cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
|
||||
+
|
||||
if (bf && bf->bf_mpdu) {
|
||||
struct sk_buff *skb = bf->bf_mpdu;
|
||||
dma_unmap_single(sc->dev, bf->bf_buf_addr,
|
||||
@@ -503,8 +506,7 @@ static bool ath9k_allow_beacon_config(st
|
||||
struct ath_vif *avp = (void *)vif->drv_priv;
|
||||
|
||||
if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
|
||||
- if ((vif->type != NL80211_IFTYPE_AP) ||
|
||||
- (sc->nbcnvifs > 1)) {
|
||||
+ if (vif->type != NL80211_IFTYPE_AP) {
|
||||
ath_dbg(common, CONFIG,
|
||||
"An AP interface is already present !\n");
|
||||
return false;
|
||||
@@ -567,6 +569,7 @@ void ath9k_beacon_config(struct ath_soft
|
||||
struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
|
||||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
+ struct ath_vif *avp = (void *)vif->drv_priv;
|
||||
unsigned long flags;
|
||||
bool skip_beacon = false;
|
||||
|
||||
@@ -588,12 +591,14 @@ void ath9k_beacon_config(struct ath_soft
|
||||
* enabling/disabling SWBA.
|
||||
*/
|
||||
if (changed & BSS_CHANGED_BEACON_ENABLED) {
|
||||
- if (!bss_conf->enable_beacon &&
|
||||
- (sc->nbcnvifs <= 1)) {
|
||||
- cur_conf->enable_beacon = false;
|
||||
- } else if (bss_conf->enable_beacon) {
|
||||
- cur_conf->enable_beacon = true;
|
||||
- ath9k_cache_beacon_config(sc, bss_conf);
|
||||
+ bool enabled = cur_conf->enable_beacon;
|
||||
+
|
||||
+ if (!bss_conf->enable_beacon) {
|
||||
+ cur_conf->enable_beacon &= ~BIT(avp->av_bslot);
|
||||
+ } else {
|
||||
+ cur_conf->enable_beacon |= BIT(avp->av_bslot);
|
||||
+ if (!enabled)
|
||||
+ ath9k_cache_beacon_config(sc, bss_conf);
|
||||
}
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/ath/ath9k/common.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/common.h
|
||||
@@ -53,7 +53,7 @@ struct ath_beacon_config {
|
||||
u16 dtim_period;
|
||||
u16 bmiss_timeout;
|
||||
u8 dtim_count;
|
||||
- bool enable_beacon;
|
||||
+ u8 enable_beacon;
|
||||
bool ibss_creator;
|
||||
u32 nexttbtt;
|
||||
u32 intval;
|
||||
|
|
Loading…
Reference in New Issue