diff options
Diffstat (limited to 'package/mac80211')
3 files changed, 300 insertions, 0 deletions
| diff --git a/package/mac80211/patches/540-short_slot_handling.patch b/package/mac80211/patches/540-short_slot_handling.patch new file mode 100644 index 000000000..ed6831fbe --- /dev/null +++ b/package/mac80211/patches/540-short_slot_handling.patch @@ -0,0 +1,11 @@ +--- 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; diff --git a/package/mac80211/patches/550-ath9k_clean_up_timing_handling.patch b/package/mac80211/patches/550-ath9k_clean_up_timing_handling.patch new file mode 100644 index 000000000..dc6502274 --- /dev/null +++ b/package/mac80211/patches/550-ath9k_clean_up_timing_handling.patch @@ -0,0 +1,229 @@ +--- 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) { diff --git a/package/mac80211/patches/560-ath9k_coverage_class.patch b/package/mac80211/patches/560-ath9k_coverage_class.patch new file mode 100644 index 000000000..035eabb1f --- /dev/null +++ b/package/mac80211/patches/560-ath9k_coverage_class.patch @@ -0,0 +1,60 @@ +--- 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, + }; | 
