All of lore.kernel.org
 help / color / mirror / Atom feed
* [ath9k-devel] [RFC/RFT] ath9k: support for multiple beacon intervals
@ 2011-06-28 22:12 Steve Brown
  2011-06-29  1:09 ` kang haiyang
                   ` (2 more replies)
  0 siblings, 3 replies; 21+ messages in thread
From: Steve Brown @ 2011-06-28 22:12 UTC (permalink / raw)
  To: ath9k-devel

This patch maintains a beacon interval for each beacon. The SWBA interrupts
are based on the shortest interval of the active beacons.

This has been tested as a mesh access point with both AP and MESH
on one interface.

Signed-off-by: Steve Brown <sbrown@cortland.com>

---

A patch to wireshark has been posted to lists.open80211s.org
that decodes the traffic.

I have left some printk's to aid in testing. I'll remove
them when I submit the patch.

Index: wireless-testing/drivers/net/wireless/ath/ath9k/ath9k.h
===================================================================
--- wireless-testing.orig/drivers/net/wireless/ath/ath9k/ath9k.h
+++ wireless-testing/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -351,6 +351,9 @@ struct ath_vif {
 	bool is_bslot_active, primary_sta_vif;
 	__le64 tsf_adjust; /* TSF adjustment for staggered beacons */
 	struct ath_buf *av_bcbuf;
+	u16 dtim_period;
+	u32 intval; /* beacon interval */
+	int intval_remaining; /* time to next beacon */
 };
 
 /*******************/
@@ -406,6 +409,9 @@ void ath_beacon_return(struct ath_softc 
 int ath_beaconq_config(struct ath_softc *sc);
 void ath_set_beacon(struct ath_softc *sc);
 void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
+struct ath_vif *ath_find_min_intval(struct ath_softc *sc);
+void ath9k_beacon_init(struct ath_softc *sc, u32 next_beacon,
+	u32 beacon_period);
 
 /*******/
 /* ANI */
Index: wireless-testing/drivers/net/wireless/ath/ath9k/beacon.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/ath/ath9k/beacon.c
+++ wireless-testing/drivers/net/wireless/ath/ath9k/beacon.c
@@ -286,7 +286,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;
 
@@ -349,9 +349,79 @@ void ath_beacon_return(struct ath_softc 
 		list_add_tail(&bf->list, &sc->beacon.bbuf);
 
 		avp->av_bcbuf = NULL;
+
+		/*
+		 * If number of beaconing vifs > 0, find the minimum
+		 * beacon_interval and reset the SWBA timer * and
+		 * cur_beacon_conf
+		 */
+		if (sc->nbcnvifs > 0) {
+			struct ath_vif *avp_local;
+			struct ath_beacon_config
+				*cur_conf = &sc->cur_beacon_conf;
+			struct ath_hw *ah = sc->sc_ah;
+			u32 nexttbtt, intval;
+
+			avp_local = ath_find_min_intval(sc);
+
+			/* If new intval needed, reset hw beacon timer */
+			if (cur_conf->beacon_interval != avp_local->intval) {
+				intval = TU_TO_USEC(avp_local->intval);
+				intval /= ATH_BCBUF;
+				nexttbtt = intval;
+
+				/* Set the computed AP beacon timers */
+				ath9k_hw_disable_interrupts(ah);
+				ath9k_beacon_init(sc, nexttbtt, intval);
+				sc->beacon.bmisscnt = 0;
+				ath9k_hw_set_interrupts(ah, ah->imask);
+
+				cur_conf->beacon_interval = avp_local->intval;
+				cur_conf->dtim_period = avp_local->dtim_period;
+			}
+		}
 	}
 }
 
+struct ath_vif *ath_find_min_intval(struct ath_softc *sc)
+{
+	struct ath_vif *avp, *min_avp = NULL;
+	struct ieee80211_vif *vif;
+	u32 min_intval = 0;
+	int i;
+
+	/* find min beacon interval */
+	for (i = 0; i < ATH_BCBUF; i++) {
+		vif = sc->beacon.bslot[i];
+
+		printk(KERN_DEBUG "%s:%d i:%d vif:%p", __func__, __LINE__,
+			i, vif);
+		if (vif != NULL) {
+			avp = (void *)vif->drv_priv;
+			printk(" avp:%p intval:%d dtim:%d\n",
+				avp, avp->intval, avp->dtim_period);
+			} else
+			printk("\n");
+
+		if (vif == NULL)
+			continue;
+		avp = (void *)vif->drv_priv;
+		if (min_intval == 0) {
+			min_intval = avp->intval;
+			min_avp = avp;
+		} else if (avp->intval < min_intval) {
+			min_intval = avp->intval;
+			min_avp = avp;
+		}
+
+	}
+
+	printk(KERN_DEBUG "%s:%d min_intval:%d min_avp:%p\n",
+		__func__, __LINE__, min_intval, min_avp);
+
+	return min_avp;
+}
+
 void ath_beacon_tasklet(unsigned long data)
 {
 	struct ath_softc *sc = (struct ath_softc *)data;
@@ -361,6 +431,7 @@ void ath_beacon_tasklet(unsigned long da
 	struct ath_buf *bf = NULL;
 	struct ieee80211_vif *vif;
 	struct ath_tx_status ts;
+	struct ath_vif *avp;
 	int slot;
 	u32 bfaddr, bc = 0;
 
@@ -423,10 +494,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 -= cur_conf->beacon_interval;
+		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;
 		}
 
 		if (sc->beacon.bmisscnt != 0) {
@@ -475,7 +554,7 @@ void ath_beacon_tasklet(unsigned long da
 	}
 }
 
-static void ath9k_beacon_init(struct ath_softc *sc,
+void ath9k_beacon_init(struct ath_softc *sc,
 			      u32 next_beacon,
 			      u32 beacon_period)
 {
@@ -697,30 +776,16 @@ static void ath_beacon_config_adhoc(stru
 static bool ath9k_allow_beacon_config(struct ath_softc *sc,
 				      struct ieee80211_vif *vif)
 {
-	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
 	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
-	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
 	struct ath_vif *avp = (void *)vif->drv_priv;
 
 	/*
-	 * Can not have different beacon interval on multiple
-	 * AP interface case
-	 */
-	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
-	    (sc->nbcnvifs > 1) &&
-	    (vif->type == NL80211_IFTYPE_AP) &&
-	    (cur_conf->beacon_interval != bss_conf->beacon_int)) {
-		ath_dbg(common, ATH_DBG_CONFIG,
-			"Changing beacon interval of multiple \
-			AP interfaces !\n");
-		return false;
-	}
-	/*
 	 * Can not configure station vif's beacon config
 	 * while on AP opmode
 	 */
 	if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
-	    (vif->type != NL80211_IFTYPE_AP)) {
+	    !(vif->type == NL80211_IFTYPE_AP ||
+	      vif->type == NL80211_IFTYPE_MESH_POINT)) {
 		ath_dbg(common, ATH_DBG_CONFIG,
 			"STA vif's beacon not allowed on AP mode\n");
 		return false;
@@ -744,17 +809,25 @@ void ath_beacon_config(struct ath_softc 
 {
 	struct ath_beacon_config *cur_conf = &sc->cur_beacon_conf;
 	struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
+	struct ath_vif *avp, *avp_min;
 
 	if (!ath9k_allow_beacon_config(sc, vif))
 		return;
 
+	/* 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;
+	avp->dtim_period = bss_conf->dtim_period;
+
 	/* Setup the beacon configuration parameters */
-	cur_conf->beacon_interval = bss_conf->beacon_int;
-	cur_conf->dtim_period = bss_conf->dtim_period;
 	cur_conf->listen_interval = 1;
 	cur_conf->dtim_count = 1;
 	cur_conf->bmiss_timeout =
 		ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
+	avp_min = ath_find_min_intval(sc);
+	cur_conf->beacon_interval = avp_min->intval;
+	cur_conf->dtim_period = avp_min->dtim_period;
 
 	/*
 	 * It looks like mac80211 may end up using beacon interval of zero in
@@ -802,11 +875,11 @@ void ath_set_beacon(struct ath_softc *sc
 
 	switch (sc->sc_ah->opmode) {
 	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
 		if (ath_has_valid_bslot(sc))
 			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:
Index: wireless-testing/drivers/net/wireless/ath/ath9k/hw.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/ath/ath9k/hw.c
+++ wireless-testing/drivers/net/wireless/ath/ath9k/hw.c
@@ -1082,11 +1082,11 @@ static void ath9k_hw_set_operating_mode(
 
 	switch (opmode) {
 	case NL80211_IFTYPE_ADHOC:
-	case NL80211_IFTYPE_MESH_POINT:
 		set |= AR_STA_ID1_ADHOC;
 		REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
 		break;
 	case NL80211_IFTYPE_AP:
+	case NL80211_IFTYPE_MESH_POINT:
 		set |= AR_STA_ID1_STA_AP;
 		/* fall through */
 	case NL80211_IFTYPE_STATION:
@@ -1822,7 +1822,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, next_beacon +
Index: wireless-testing/drivers/net/wireless/ath/ath9k/main.c
===================================================================
--- wireless-testing.orig/drivers/net/wireless/ath/ath9k/main.c
+++ wireless-testing/drivers/net/wireless/ath/ath9k/main.c
@@ -1396,9 +1396,7 @@ static void ath9k_calculate_summary_stat
 		ath9k_hw_set_tsfadjust(ah, 0);
 		sc->sc_flags &= ~SC_OP_TSF_RESET;
 
-		if (iter_data.nmeshes)
-			ah->opmode = NL80211_IFTYPE_MESH_POINT;
-		else if (iter_data.nwds)
+		if (iter_data.nmeshes + iter_data.nwds)
 			ah->opmode = NL80211_IFTYPE_AP;
 		else if (iter_data.nadhocs)
 			ah->opmode = NL80211_IFTYPE_ADHOC;

^ permalink raw reply	[flat|nested] 21+ messages in thread
* [ath9k-devel] AR9380 MSI
@ 2011-06-30  4:50 Alex Hacker
  2011-07-01  9:38 ` Sucheta ROY
  0 siblings, 1 reply; 21+ messages in thread
From: Alex Hacker @ 2011-06-30  4:50 UTC (permalink / raw)
  To: ath9k-devel

I'd not work with MSI and our Atheros based hardware do not require it. I only
have a AR9380 based card and done some tests on standard PC for Sucheta ROY.
I haavn't much knowlege how the MSI is processed in Linux kernel, but it seems
not working with AR9380 without some special setup in hardware.
Really don't understand how MSI can correlate with scan results...
Best regards,
Alex.

On Wed, Jun 29, 2011 at 08:56:06PM +0200, Matevz Langus wrote:
> Hello,
> 
> I have tried the same thing as you did on Freescale P1020 processor (Power architecture) using 2.6.39.1 and I am getting some results when performing scanning.
> Before enabling MSI in ath9k pci.c, I newer got any scan results. But now when enabled I am getting at least 1 network very often.
> 
> However it seems the operation is not very stable. I can not connect to the AP. 
> 
> Have you made any progress on this one?
> I got an answer from Atheros guys, they use INTA by default. And also looking at defines AR_PCIE_MSI and AR_PCIE_MSI_ENABLE I got a question: who is using that defines? It seems like nobody???
> 
> regards,
>   Matevz Langus

^ permalink raw reply	[flat|nested] 21+ messages in thread
* [ath9k-devel] setting AR_NAV register
@ 2011-05-17 11:16 Andrés García Saavedra
  2011-05-17 13:29 ` [ath9k-devel] AR9285 MSI Sucheta ROY
  0 siblings, 1 reply; 21+ messages in thread
From: Andrés García Saavedra @ 2011-05-17 11:16 UTC (permalink / raw)
  To: ath9k-devel

Dear all,

I would like to set the NAV value from software in mac80211/ath9k. Is it
possible to change this value, e.g., using the AR_NAV?

Thank you for your help,
Andr?s
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20110517/737957a1/attachment.htm 

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2011-07-03 22:28 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-06-28 22:12 [ath9k-devel] [RFC/RFT] ath9k: support for multiple beacon intervals Steve Brown
2011-06-29  1:09 ` kang haiyang
2011-06-29 13:28   ` Steve Brown
2011-06-29  1:31 ` Adrian Chadd
2011-06-29 13:22   ` Steve Brown
2011-06-29 17:15     ` Adrian Chadd
2011-06-29 18:56       ` [ath9k-devel] AR9380 MSI Matevz Langus
2011-07-03 15:30       ` [ath9k-devel] [RFC/RFT] ath9k: support for multiple beacon intervals Steve Brown
2011-07-03 22:28         ` Adrian Chadd
2011-07-01  8:49 ` Björn Smedman
2011-07-03 14:58   ` Steve Brown
  -- strict thread matches above, loose matches on Subject: below --
2011-06-30  4:50 [ath9k-devel] AR9380 MSI Alex Hacker
2011-07-01  9:38 ` Sucheta ROY
2011-07-01 10:18   ` Matevz Langus
2011-05-17 11:16 [ath9k-devel] setting AR_NAV register Andrés García Saavedra
2011-05-17 13:29 ` [ath9k-devel] AR9285 MSI Sucheta ROY
2011-05-17 14:41   ` Mohammed Shafi
2011-05-18  1:09     ` Peter Stuge
2011-05-18  2:15       ` Adrian Chadd
2011-05-18  9:29         ` Sucheta ROY
2011-05-18 10:54           ` Senthilkumar Balasubramanian
2011-05-19  0:32             ` Peter Stuge
2011-05-19  4:33               ` Sucheta ROY
2011-05-19  6:01                 ` Alex Hacker
2011-05-19  8:35                   ` [ath9k-devel] AR9380 MSI Sucheta ROY
2011-05-19 11:06                     ` Falk-Moritz Schaefer
2011-05-19 12:02                       ` Sucheta ROY
2011-05-19 12:32                         ` Falk-Moritz Schaefer
2011-05-19 12:16                     ` Alex Hacker
2011-05-20  9:30                       ` Sucheta ROY
2011-05-20 10:15                         ` Alex Hacker

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.