linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] mac80211: force use_short_slot=true for 5GHz
@ 2010-01-15  1:27 Felix Fietkau
  2010-01-15  1:33 ` [PATCH 2/3] ath9k: cleanup slot time and ack/cts timeout handling Felix Fietkau
  2010-01-15  2:00 ` [PATCH v2 1/3] mac80211: force use_short_slot=true for 5GHz Felix Fietkau
  0 siblings, 2 replies; 4+ messages in thread
From: Felix Fietkau @ 2010-01-15  1:27 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, John W. Linville

Normally 5GHz does not have a concept of long vs short slot time,
however the slot time that it ends up using is the same as for 2.4 GHZ
and use_short_slot == true
Because of that, it makes more sense to force use_short_slot = true
whenever 5 GHz is being used, so that this particular check does not
have to be in every single driver that uses this flag.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -670,6 +670,8 @@ static u32 ieee80211_handle_bss_capabili
 	}

 	use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
+	if (sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
+		use_short_slot = true;

 	if (use_protection != bss_conf->use_cts_prot) {
 		bss_conf->use_cts_prot = use_protection;

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

* [PATCH 2/3] ath9k: cleanup slot time and ack/cts timeout handling
  2010-01-15  1:27 [PATCH 1/3] mac80211: force use_short_slot=true for 5GHz Felix Fietkau
@ 2010-01-15  1:33 ` Felix Fietkau
  2010-01-15  1:34   ` [PATCH 3/3] ath9k: implement coverage class support Felix Fietkau
  2010-01-15  2:00 ` [PATCH v2 1/3] mac80211: force use_short_slot=true for 5GHz Felix Fietkau
  1 sibling, 1 reply; 4+ messages in thread
From: Felix Fietkau @ 2010-01-15  1:33 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luis R. Rodriguez, John W. Linville

Previously ath9k left the initialization of slot timing and ACK/CTS
timeout to the mode specific initvals. This does not handle short vs
long slot in 2.4 GHz and uses a rather strange value for the 2.4 GHz
ACK timeout (64 usec).
This patch uses the proper ath9k_hw functions for setting slot time and
timeouts and also implements the switch between short and long slot
time in 2.4 GHz

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1790,6 +1790,7 @@ static void ath9k_bss_info_changed(struc
 	struct ath_hw *ah = sc->sc_ah;
 	struct ath_common *common = ath9k_hw_common(ah);
 	struct ath_vif *avp = (void *)vif->drv_priv;
+	int slottime;
 	int error;
 
 	mutex_lock(&sc->mutex);
@@ -1825,6 +1826,25 @@ static void ath9k_bss_info_changed(struc
 			ath_beacon_config(sc, vif);
 	}
 
+	if (changed & BSS_CHANGED_ERP_SLOT) {
+		if (bss_conf->use_short_slot)
+			slottime = 9;
+		else
+			slottime = 20;
+		if (vif->type == NL80211_IFTYPE_AP) {
+			/*
+			 * Defer update, so that connected stations can adjust
+			 * their settings at the same time.
+			 * See beacon.c for more details
+			 */
+			sc->beacon.slottime = slottime;
+			sc->beacon.updateslot = UPDATE;
+		} else {
+			ah->slottime = slottime;
+			ath9k_hw_init_global_settings(ah);
+		}
+	}
+
 	/* Disable transmission of beacons */
 	if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
 		ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -55,28 +55,6 @@ module_exit(ath9k_exit);
 /* Helper Functions */
 /********************/
 
-static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
-{
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-	if (!ah->curchan) /* should really check for CCK instead */
-		return clks / ATH9K_CLOCK_RATE_CCK;
-	if (conf->channel->band == IEEE80211_BAND_2GHZ)
-		return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
-
-	return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
-}
-
-static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
-{
-	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
-
-	if (conf_is_ht40(conf))
-		return ath9k_hw_mac_usec(ah, clks) / 2;
-	else
-		return ath9k_hw_mac_usec(ah, clks);
-}
-
 static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
 {
 	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
@@ -413,8 +391,6 @@ static void ath9k_hw_init_defaults(struc
 	ah->beacon_interval = 100;
 	ah->enable_32kHz_clock = DONT_USE_32KHZ;
 	ah->slottime = (u32) -1;
-	ah->acktimeout = (u32) -1;
-	ah->ctstimeout = (u32) -1;
 	ah->globaltxtimeout = (u32) -1;
 	ah->power_mode = ATH9K_PM_UNDEFINED;
 }
@@ -1196,34 +1172,25 @@ static void ath9k_hw_init_interrupt_mask
 	}
 }
 
-static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
+static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
 {
-	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-			  "bad ack timeout %u\n", us);
-		ah->acktimeout = (u32) -1;
-		return false;
-	} else {
-		REG_RMW_FIELD(ah, AR_TIME_OUT,
-			      AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
-		ah->acktimeout = us;
-		return true;
-	}
+	u32 val = ath9k_hw_mac_to_clks(ah, us);
+	val = min(val, (u32) 0xFFFF);
+	REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
 }
 
-static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
 {
-	if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-			  "bad cts timeout %u\n", us);
-		ah->ctstimeout = (u32) -1;
-		return false;
-	} else {
-		REG_RMW_FIELD(ah, AR_TIME_OUT,
-			      AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
-		ah->ctstimeout = us;
-		return true;
-	}
+	u32 val = ath9k_hw_mac_to_clks(ah, us);
+	val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
+	REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
+}
+
+static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
+{
+	u32 val = ath9k_hw_mac_to_clks(ah, us);
+	val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
+	REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
 }
 
 static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
@@ -1240,23 +1207,32 @@ static bool ath9k_hw_set_global_txtimeou
 	}
 }
 
-static void ath9k_hw_init_user_settings(struct ath_hw *ah)
+void ath9k_hw_init_global_settings(struct ath_hw *ah)
 {
+	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
+	int acktimeout;
+	int sifstime;
+
 	ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
 		  ah->misc_mode);
 
 	if (ah->misc_mode != 0)
 		REG_WRITE(ah, AR_PCU_MISC,
 			  REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
-	if (ah->slottime != (u32) -1)
-		ath9k_hw_setslottime(ah, ah->slottime);
-	if (ah->acktimeout != (u32) -1)
-		ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
-	if (ah->ctstimeout != (u32) -1)
-		ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
+
+	if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
+		sifstime = 16;
+	else
+		sifstime = 10;
+
+	acktimeout = ah->slottime + sifstime;
+	ath9k_hw_setslottime(ah, ah->slottime);
+	ath9k_hw_set_ack_timeout(ah, acktimeout);
+	ath9k_hw_set_cts_timeout(ah, acktimeout);
 	if (ah->globaltxtimeout != (u32) -1)
 		ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
 }
+EXPORT_SYMBOL(ath9k_hw_init_global_settings);
 
 void ath9k_hw_deinit(struct ath_hw *ah)
 {
@@ -2077,7 +2053,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
 	if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
 		ath9k_enable_rfkill(ah);
 
-	ath9k_hw_init_user_settings(ah);
+	ath9k_hw_init_global_settings(ah);
 
 	if (AR_SREV_9287_12_OR_LATER(ah)) {
 		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
@@ -3674,21 +3650,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *a
 }
 EXPORT_SYMBOL(ath9k_hw_extend_tsf);
 
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
-{
-	if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
-		ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
-			  "bad slot time %u\n", us);
-		ah->slottime = (u32) -1;
-		return false;
-	} else {
-		REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
-		ah->slottime = us;
-		return true;
-	}
-}
-EXPORT_SYMBOL(ath9k_hw_setslottime);
-
 void ath9k_hw_set11nmac2040(struct ath_hw *ah)
 {
 	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -553,8 +553,6 @@ struct ath_hw {
 	int16_t txpower_indexoffset;
 	u32 beacon_interval;
 	u32 slottime;
-	u32 acktimeout;
-	u32 ctstimeout;
 	u32 globaltxtimeout;
 
 	/* ANI */
@@ -668,7 +666,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah
 void ath9k_hw_reset_tsf(struct ath_hw *ah);
 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
 u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
-bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
+void ath9k_hw_init_global_settings(struct ath_hw *ah);
 void ath9k_hw_set11nmac2040(struct ath_hw *ah);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -480,7 +480,8 @@ void ath_beacon_tasklet(unsigned long da
 		sc->beacon.updateslot = COMMIT; /* commit next beacon */
 		sc->beacon.slotupdate = slot;
 	} else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
-		ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
+		ah->slottime = sc->beacon.slottime;
+		ath9k_hw_init_global_settings(ah);
 		sc->beacon.updateslot = OK;
 	}
 	if (bfaddr != 0) {

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

* [PATCH 3/3] ath9k: implement coverage class support
  2010-01-15  1:33 ` [PATCH 2/3] ath9k: cleanup slot time and ack/cts timeout handling Felix Fietkau
@ 2010-01-15  1:34   ` Felix Fietkau
  0 siblings, 0 replies; 4+ messages in thread
From: Felix Fietkau @ 2010-01-15  1:34 UTC (permalink / raw)
  To: linux-wireless; +Cc: Luis R. Rodriguez, John W. Linville

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1211,6 +1211,7 @@ void ath9k_hw_init_global_settings(struc
 {
 	struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
 	int acktimeout;
+	int slottime;
 	int sifstime;

 	ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
@@ -1225,8 +1226,10 @@ void ath9k_hw_init_global_settings(struc
 	else
 		sifstime = 10;

-	acktimeout = ah->slottime + sifstime;
-	ath9k_hw_setslottime(ah, ah->slottime);
+	/* As defined by IEEE 802.11-2007 17.3.8.6 */
+	slottime = ah->slottime + 3 * ah->coverage_class;
+	acktimeout = slottime + sifstime;
+	ath9k_hw_setslottime(ah, slottime);
 	ath9k_hw_set_ack_timeout(ah, acktimeout);
 	ath9k_hw_set_cts_timeout(ah, acktimeout);
 	if (ah->globaltxtimeout != (u32) -1)
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -551,6 +551,7 @@ struct ath_hw {
 	u32 *bank6Temp;

 	int16_t txpower_indexoffset;
+	int coverage_class;
 	u32 beacon_interval;
 	u32 slottime;
 	u32 globaltxtimeout;
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2015,6 +2015,18 @@ static void ath9k_sw_scan_complete(struc
 	mutex_unlock(&sc->mutex);
 }

+static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8
coverage_class)
+{
+	struct ath_wiphy *aphy = hw->priv;
+	struct ath_softc *sc = aphy->sc;
+	struct ath_hw *ah = sc->sc_ah;
+
+	mutex_lock(&sc->mutex);
+	ah->coverage_class = coverage_class;
+	ath9k_hw_init_global_settings(ah);
+	mutex_unlock(&sc->mutex);
+}
+
 struct ieee80211_ops ath9k_ops = {
 	.tx 		    = ath9k_tx,
 	.start 		    = ath9k_start,
@@ -2034,4 +2046,5 @@ struct ieee80211_ops ath9k_ops = {
 	.sw_scan_start      = ath9k_sw_scan_start,
 	.sw_scan_complete   = ath9k_sw_scan_complete,
 	.rfkill_poll        = ath9k_rfkill_poll_state,
+	.set_coverage_class = ath9k_set_coverage_class,
 };


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

* [PATCH v2 1/3] mac80211: force use_short_slot=true for 5GHz
  2010-01-15  1:27 [PATCH 1/3] mac80211: force use_short_slot=true for 5GHz Felix Fietkau
  2010-01-15  1:33 ` [PATCH 2/3] ath9k: cleanup slot time and ack/cts timeout handling Felix Fietkau
@ 2010-01-15  2:00 ` Felix Fietkau
  1 sibling, 0 replies; 4+ messages in thread
From: Felix Fietkau @ 2010-01-15  2:00 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, John W. Linville

Normally 5GHz does not have a concept of long vs short slot time,
however the slot time that it ends up using is the same as for 2.4 GHZ
and use_short_slot == true
Because of that, it makes more sense to force use_short_slot = true
whenever 5 GHz is being used, so that this particular check does not
have to be in every single driver that uses this flag.

Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
v2: sorry, forgot one chunk of the patch
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -670,6 +670,8 @@ static u32 ieee80211_handle_bss_capabili
 	}
 
 	use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
+	if (sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
+		use_short_slot = true;
 
 	if (use_protection != bss_conf->use_cts_prot) {
 		bss_conf->use_cts_prot = use_protection;
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1087,6 +1087,13 @@ static int ieee80211_change_bss(struct w
 			params->use_short_preamble;
 		changed |= BSS_CHANGED_ERP_PREAMBLE;
 	}
+
+	if (!sdata->vif.bss_conf.use_short_slot &&
+	    sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
+		sdata->vif.bss_conf.use_short_slot = true;
+		changed |= BSS_CHANGED_ERP_SLOT;
+	}
+
 	if (params->use_short_slot_time >= 0) {
 		sdata->vif.bss_conf.use_short_slot =
 			params->use_short_slot_time;

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

end of thread, other threads:[~2010-01-15  2:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-15  1:27 [PATCH 1/3] mac80211: force use_short_slot=true for 5GHz Felix Fietkau
2010-01-15  1:33 ` [PATCH 2/3] ath9k: cleanup slot time and ack/cts timeout handling Felix Fietkau
2010-01-15  1:34   ` [PATCH 3/3] ath9k: implement coverage class support Felix Fietkau
2010-01-15  2:00 ` [PATCH v2 1/3] mac80211: force use_short_slot=true for 5GHz Felix Fietkau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).