All of lore.kernel.org
 help / color / mirror / Atom feed
* [ath9k-devel] [RFC 2/2] ath9k: support multiple beacon intervals
@ 2011-01-27 22:18 Steve Brown
  0 siblings, 0 replies; only message in thread
From: Steve Brown @ 2011-01-27 22:18 UTC (permalink / raw)
  To: ath9k-devel

This patch maintains a beacon interval for each beacon. The SWBA interrupts
are based on the shortest interval. If an interface with a relatively short
beacon is deleted, there is no attempt to change the SWBA rate. It's
probably an uncommon operation and doesn't seem to carry much overhead.

---

--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -56,6 +56,7 @@ struct ath_node;
 	} while (0)
 
 #define A_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define A_MIN(a, b) ((a) < (b) ? (a) : (b))
 
 #define ATH9K_PM_QOS_DEFAULT_VALUE	55
 
@@ -350,6 +351,8 @@ struct ath_vif {
 	__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
 	enum nl80211_iftype av_opmode;
 	struct ath_buf *av_bcbuf;
+	u32 intval; /* beacon interval */
+	int intval_remaining; /* time to next beacon */
 	u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
 };
 
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -281,7 +281,7 @@ int ath_beacon_alloc(struct ath_softc *s
 	/* Calculate a TSF adjustment factor required for staggered beacons. */
 	if (avp->av_bslot > 0) {
 		u64 tsfadjust;
-		int intval;
+		u32 intval;
 
 		intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
 
@@ -352,10 +352,11 @@ void ath_beacon_tasklet(unsigned long da
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_buf *bf = NULL;
 	struct ieee80211_vif *vif;
+	struct ath_vif *avp;
 	int slot;
 	u32 bfaddr, bc = 0, tsftu;
 	u64 tsf;
-	u16 intval;
+	u32 intval;
 
 	/*
 	 * Check if the previous beacon has gone out.  If
@@ -396,6 +397,8 @@ void ath_beacon_tasklet(unsigned long da
 	 */
 
 	intval = cur_conf->beacon_interval ? : ATH_DEFAULT_BINTVAL;
+//printk("%s:%d:%s sc:%p beacon_interval:%d intval:%d\n",
+//       __FILE__, __LINE__, __FUNCTION__, sc, cur_conf->beacon_interval, intval);
 
 	tsf = ath9k_hw_gettsf64(ah);
 	tsftu = TSF_TO_TU(tsf>>32, tsf);
@@ -416,10 +419,18 @@ void ath_beacon_tasklet(unsigned long da
 
 	bfaddr = 0;
 	if (vif) {
-		bf = ath_beacon_generate(sc->hw, vif);
-		if (bf != NULL) {
-			bfaddr = bf->bf_daddr;
-			bc = 1;
+		avp = (void *)vif->drv_priv;
+		ath_dbg(common, ATH_DBG_BEACON,
+			"vif:%p intval:%d remaining:%d\n",
+			vif, avp->intval, avp->intval_remaining);
+		avp->intval_remaining -= intval;
+		if (avp->intval_remaining <= 0) {
+			bf = ath_beacon_generate(sc->hw, vif);
+			if (bf != NULL) {
+				bfaddr = bf->bf_daddr;
+				bc = 1;
+			}
+			avp->intval_remaining = avp->intval;
 		}
 	}
 
@@ -470,6 +481,8 @@ static void ath9k_beacon_init(struct ath
 			      u32 next_beacon,
 			      u32 beacon_period)
 {
+printk("%s:%d:%s sc:%p next_beacon:%d beacon_period:%d flag:0x%0x\n",
+	__FILE__, __LINE__, __FUNCTION__, sc, next_beacon, beacon_period & ATH9K_BEACON_PERIOD, beacon_period >> 16);
 	if (beacon_period & ATH9K_BEACON_RESET_TSF)
 		ath9k_ps_wakeup(sc);
 
@@ -697,13 +710,30 @@ void ath_beacon_config(struct ath_softc 
 	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
 	enum nl80211_iftype iftype;
+	struct ath_vif *avp;
 
 	/* Setup the beacon configuration parameters */
 	if (vif) {
 		struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 		iftype = vif->type;
+printk("%s:%d:%s sc:%p nbcnvifs:%d beacon_interval:%d beacon_int:%d\n",
+	__FILE__, __LINE__, __FUNCTION__, sc, sc->nbcnvifs, cur_conf->beacon_interval, bss_conf->beacon_int);
+		if ((sc->nbcnvifs > 1) && (cur_conf->beacon_interval !=0)) {
+			cur_conf->beacon_interval =
+				A_MIN(cur_conf->beacon_interval,bss_conf->beacon_int);
+			cur_conf->dtim_period =
+				A_MIN(cur_conf->dtim_period, bss_conf->dtim_period);
+		} else {
 		cur_conf->beacon_interval = bss_conf->beacon_int;
 		cur_conf->dtim_period = bss_conf->dtim_period;
+		}
+printk("%s:%d:%s sc:%p nbcnvifs:%d beacon_interval:%d beacon_int:%d\n",
+	__FILE__, __LINE__, __FUNCTION__, sc, sc->nbcnvifs, cur_conf->beacon_interval, bss_conf->beacon_int);
+
+	 /* Retain mac80211 beacon interval for each vif. */
+		avp = (void *)vif->drv_priv;
+		avp->intval = bss_conf->beacon_int;
+		avp->intval_remaining = bss_conf->beacon_int;
 	} else {
 		iftype = sc->sc_ah->opmode;
 	}
@@ -731,10 +761,10 @@ void ath_beacon_config(struct ath_softc 
 
 	switch (iftype) {
 	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
 		ath_beacon_config_ap(sc, cur_conf);
 		break;
 	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_MESH_POINT:
 		ath_beacon_config_adhoc(sc, cur_conf);
 		break;
 	case NL80211_IFTYPE_STATION:
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -586,6 +586,7 @@ static int ath9k_init_softc(u16 devid, s
 	tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
 	tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
 		     (unsigned long)sc);
+printk("%s:%d:%s sc:%p\n",  __FILE__, __LINE__, __FUNCTION__, sc);
 
 	/*
 	 * Cache line size is used to size and align various
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1922,7 +1922,6 @@ static void ath9k_bss_info_changed(struc
 				   u32 changed)
 {
 	struct ath_softc *sc = hw->priv;
-	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;
@@ -1981,7 +1980,6 @@ static void ath9k_bss_info_changed(struc
 		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
 
 	if (changed & BSS_CHANGED_BEACON_INT) {
-		cur_conf->beacon_interval = bss_conf->beacon_int;
 		/*
 		 * In case of AP mode, the HW TSF has to be reset
 		 * when the beacon interval changes.
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1664,7 +1664,6 @@ void ath9k_hw_beaconinit(struct ath_hw *
 
 	switch (ah->opmode) {
 	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_MESH_POINT:
 		REG_SET_BIT(ah, AR_TXCFG,
 			    AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
 		REG_WRITE(ah, AR_NEXT_NDP_TIMER,
@@ -1673,6 +1672,7 @@ void ath9k_hw_beaconinit(struct ath_hw *
 				      atim_window : 1)));
 		flags |= AR_NDP_TIMER_EN;
 	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
 		REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
 		REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
 			  TU_TO_USEC(next_beacon -

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-01-27 22:18 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-27 22:18 [ath9k-devel] [RFC 2/2] ath9k: support multiple beacon intervals Steve Brown

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.