diff --git a/package/mac80211/patches/461-ath5k_fix_short_preamble_dur.patch b/package/mac80211/patches/461-ath5k_fix_short_preamble_dur.patch new file mode 100644 index 0000000000..8d0a3e800f --- /dev/null +++ b/package/mac80211/patches/461-ath5k_fix_short_preamble_dur.patch @@ -0,0 +1,82 @@ +--- a/drivers/net/wireless/ath/ath5k/ath5k.h ++++ b/drivers/net/wireless/ath/ath5k/ath5k.h +@@ -1233,7 +1233,7 @@ int ath5k_eeprom_read_mac(struct ath5k_h + /* Protocol Control Unit Functions */ + /* Helpers */ + int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, +- int len, struct ieee80211_rate *rate); ++ int len, struct ieee80211_rate *rate, bool shortpre); + unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah); + unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah); + extern int ath5k_hw_set_opmode(struct ath5k_hw *ah, enum nl80211_iftype opmode); +--- a/drivers/net/wireless/ath/ath5k/pcu.c ++++ b/drivers/net/wireless/ath/ath5k/pcu.c +@@ -75,7 +75,7 @@ static const unsigned int ack_rates_high + * bwmodes. + */ + int ath5k_hw_get_frame_duration(struct ath5k_hw *ah, +- int len, struct ieee80211_rate *rate) ++ int len, struct ieee80211_rate *rate, bool shortpre) + { + struct ath5k_softc *sc = ah->ah_sc; + int sifs, preamble, plcp_bits, sym_time; +@@ -84,9 +84,15 @@ int ath5k_hw_get_frame_duration(struct a + + /* Fallback */ + if (!ah->ah_bwmode) { +- dur = ieee80211_generic_frame_duration(sc->hw, +- NULL, len, rate); +- return le16_to_cpu(dur); ++ __le16 raw_dur = ieee80211_generic_frame_duration(sc->hw, ++ NULL, len, rate); ++ ++ /* subtract difference between long and short preamble */ ++ dur = le16_to_cpu(raw_dur); ++ if (shortpre) ++ dur -= 96; ++ ++ return dur; + } + + bitrate = rate->bitrate; +@@ -263,27 +269,14 @@ static inline void ath5k_hw_write_rate_d + * actual rate for this rate. See mac80211 tx.c + * ieee80211_duration() for a brief description of + * what rate we should choose to TX ACKs. */ +- tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); ++ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); + + ath5k_hw_reg_write(ah, tx_time, reg); + + if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) + continue; + +- /* +- * We're not distinguishing short preamble here, +- * This is true, all we'll get is a longer value here +- * which is not necessarilly bad. We could use +- * export ieee80211_frame_duration() but that needs to be +- * fixed first to be properly used by mac802111 drivers: +- * +- * - remove erp stuff and let the routine figure ofdm +- * erp rates +- * - remove passing argument ieee80211_local as +- * drivers don't have access to it +- * - move drivers using ieee80211_generic_frame_duration() +- * to this +- */ ++ tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, true); + ath5k_hw_reg_write(ah, tx_time, + reg + (AR5K_SET_SHORT_PREAMBLE << 2)); + } +--- a/drivers/net/wireless/ath/ath5k/qcu.c ++++ b/drivers/net/wireless/ath/ath5k/qcu.c +@@ -550,7 +550,7 @@ int ath5k_hw_set_ifs_intervals(struct at + else + rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[0]; + +- ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate); ++ ack_tx_time = ath5k_hw_get_frame_duration(ah, 10, rate, false); + + /* ack_tx_time includes an SIFS already */ + eifs = ack_tx_time + sifs + 2 * slot_time; diff --git a/package/mac80211/patches/462-ath5k_fix_sifs.patch b/package/mac80211/patches/462-ath5k_fix_sifs.patch new file mode 100644 index 0000000000..7d3efcae5f --- /dev/null +++ b/package/mac80211/patches/462-ath5k_fix_sifs.patch @@ -0,0 +1,23 @@ +--- a/drivers/net/wireless/ath/ath5k/ath5k.h ++++ b/drivers/net/wireless/ath/ath5k/ath5k.h +@@ -224,8 +224,7 @@ + + /* SIFS */ + #define AR5K_INIT_SIFS_TURBO 6 +-/* XXX: 8 from initvals 10 from standard */ +-#define AR5K_INIT_SIFS_DEFAULT_BG 8 ++#define AR5K_INIT_SIFS_DEFAULT_BG 10 + #define AR5K_INIT_SIFS_DEFAULT_A 16 + #define AR5K_INIT_SIFS_HALF_RATE 32 + #define AR5K_INIT_SIFS_QUARTER_RATE 64 +--- a/drivers/net/wireless/ath/ath5k/qcu.c ++++ b/drivers/net/wireless/ath/ath5k/qcu.c +@@ -519,7 +519,7 @@ int ath5k_hw_set_ifs_intervals(struct at + return -EINVAL; + + sifs = ath5k_hw_get_default_sifs(ah); +- sifs_clock = ath5k_hw_htoclock(ah, sifs); ++ sifs_clock = ath5k_hw_htoclock(ah, sifs - 2); + + /* EIFS + * Txtime of ack at lowest rate + SIFS + DIFS diff --git a/package/mac80211/patches/463-ath9k_fix_slottime.patch b/package/mac80211/patches/463-ath9k_fix_slottime.patch new file mode 100644 index 0000000000..01e55d35d4 --- /dev/null +++ b/package/mac80211/patches/463-ath9k_fix_slottime.patch @@ -0,0 +1,42 @@ +--- a/drivers/net/wireless/ath/ath5k/ath5k.h ++++ b/drivers/net/wireless/ath/ath5k/ath5k.h +@@ -1057,6 +1057,7 @@ struct ath5k_hw { + u8 ah_coverage_class; + bool ah_ack_bitrate_high; + u8 ah_bwmode; ++ bool ah_short_slot; + + /* Antenna Control */ + u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; +--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c ++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c +@@ -282,6 +282,15 @@ ath5k_bss_info_changed(struct ieee80211_ + if (changes & BSS_CHANGED_BEACON_INT) + sc->bintval = bss_conf->beacon_int; + ++ if (changes & BSS_CHANGED_ERP_SLOT) { ++ int slot_time; ++ ++ ah->ah_short_slot = bss_conf->use_short_slot; ++ slot_time = ath5k_hw_get_default_slottime(ah) + ++ 3 * ah->ah_coverage_class; ++ ath5k_hw_set_ifs_intervals(ah, slot_time); ++ } ++ + if (changes & BSS_CHANGED_ASSOC) { + avf->assoc = bss_conf->assoc; + if (bss_conf->assoc) +--- a/drivers/net/wireless/ath/ath5k/pcu.c ++++ b/drivers/net/wireless/ath/ath5k/pcu.c +@@ -151,9 +151,9 @@ unsigned int ath5k_hw_get_default_slotti + slot_time = AR5K_INIT_SLOT_TIME_QUARTER_RATE; + break; + case AR5K_BWMODE_DEFAULT: +- slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; + default: +- if (channel->hw_value & CHANNEL_CCK) ++ slot_time = AR5K_INIT_SLOT_TIME_DEFAULT; ++ if ((channel->hw_value & CHANNEL_CCK) && !ah->ah_short_slot) + slot_time = AR5K_INIT_SLOT_TIME_B; + break; + }