mac80211: add a missing chunk of the short slot patch
[openwrt/svn-archive/archive.git] / package / mac80211 / patches / 550-ath9k_clean_up_timing_handling.patch
1 --- a/drivers/net/wireless/ath/ath9k/main.c
2 +++ b/drivers/net/wireless/ath/ath9k/main.c
3 @@ -1790,6 +1790,7 @@ static void ath9k_bss_info_changed(struc
4 struct ath_hw *ah = sc->sc_ah;
5 struct ath_common *common = ath9k_hw_common(ah);
6 struct ath_vif *avp = (void *)vif->drv_priv;
7 + int slottime;
8 int error;
9
10 mutex_lock(&sc->mutex);
11 @@ -1825,6 +1826,25 @@ static void ath9k_bss_info_changed(struc
12 ath_beacon_config(sc, vif);
13 }
14
15 + if (changed & BSS_CHANGED_ERP_SLOT) {
16 + if (bss_conf->use_short_slot)
17 + slottime = 9;
18 + else
19 + slottime = 20;
20 + if (vif->type == NL80211_IFTYPE_AP) {
21 + /*
22 + * Defer update, so that connected stations can adjust
23 + * their settings at the same time.
24 + * See beacon.c for more details
25 + */
26 + sc->beacon.slottime = slottime;
27 + sc->beacon.updateslot = UPDATE;
28 + } else {
29 + ah->slottime = slottime;
30 + ath9k_hw_init_global_settings(ah);
31 + }
32 + }
33 +
34 /* Disable transmission of beacons */
35 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
36 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
37 --- a/drivers/net/wireless/ath/ath9k/hw.c
38 +++ b/drivers/net/wireless/ath/ath9k/hw.c
39 @@ -55,28 +55,6 @@ module_exit(ath9k_exit);
40 /* Helper Functions */
41 /********************/
42
43 -static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
44 -{
45 - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
46 -
47 - if (!ah->curchan) /* should really check for CCK instead */
48 - return clks / ATH9K_CLOCK_RATE_CCK;
49 - if (conf->channel->band == IEEE80211_BAND_2GHZ)
50 - return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
51 -
52 - return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
53 -}
54 -
55 -static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
56 -{
57 - struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
58 -
59 - if (conf_is_ht40(conf))
60 - return ath9k_hw_mac_usec(ah, clks) / 2;
61 - else
62 - return ath9k_hw_mac_usec(ah, clks);
63 -}
64 -
65 static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
66 {
67 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
68 @@ -413,8 +391,6 @@ static void ath9k_hw_init_defaults(struc
69 ah->beacon_interval = 100;
70 ah->enable_32kHz_clock = DONT_USE_32KHZ;
71 ah->slottime = (u32) -1;
72 - ah->acktimeout = (u32) -1;
73 - ah->ctstimeout = (u32) -1;
74 ah->globaltxtimeout = (u32) -1;
75 ah->power_mode = ATH9K_PM_UNDEFINED;
76 }
77 @@ -1196,34 +1172,25 @@ static void ath9k_hw_init_interrupt_mask
78 }
79 }
80
81 -static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
82 +static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
83 {
84 - if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
85 - ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
86 - "bad ack timeout %u\n", us);
87 - ah->acktimeout = (u32) -1;
88 - return false;
89 - } else {
90 - REG_RMW_FIELD(ah, AR_TIME_OUT,
91 - AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
92 - ah->acktimeout = us;
93 - return true;
94 - }
95 + u32 val = ath9k_hw_mac_to_clks(ah, us);
96 + val = min(val, (u32) 0xFFFF);
97 + REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
98 }
99
100 -static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
101 +static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
102 {
103 - if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
104 - ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
105 - "bad cts timeout %u\n", us);
106 - ah->ctstimeout = (u32) -1;
107 - return false;
108 - } else {
109 - REG_RMW_FIELD(ah, AR_TIME_OUT,
110 - AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
111 - ah->ctstimeout = us;
112 - return true;
113 - }
114 + u32 val = ath9k_hw_mac_to_clks(ah, us);
115 + val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
116 + REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
117 +}
118 +
119 +static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
120 +{
121 + u32 val = ath9k_hw_mac_to_clks(ah, us);
122 + val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
123 + REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
124 }
125
126 static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
127 @@ -1240,23 +1207,32 @@ static bool ath9k_hw_set_global_txtimeou
128 }
129 }
130
131 -static void ath9k_hw_init_user_settings(struct ath_hw *ah)
132 +void ath9k_hw_init_global_settings(struct ath_hw *ah)
133 {
134 + struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
135 + int acktimeout;
136 + int sifstime;
137 +
138 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
139 ah->misc_mode);
140
141 if (ah->misc_mode != 0)
142 REG_WRITE(ah, AR_PCU_MISC,
143 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
144 - if (ah->slottime != (u32) -1)
145 - ath9k_hw_setslottime(ah, ah->slottime);
146 - if (ah->acktimeout != (u32) -1)
147 - ath9k_hw_set_ack_timeout(ah, ah->acktimeout);
148 - if (ah->ctstimeout != (u32) -1)
149 - ath9k_hw_set_cts_timeout(ah, ah->ctstimeout);
150 +
151 + if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
152 + sifstime = 16;
153 + else
154 + sifstime = 10;
155 +
156 + acktimeout = ah->slottime + sifstime;
157 + ath9k_hw_setslottime(ah, ah->slottime);
158 + ath9k_hw_set_ack_timeout(ah, acktimeout);
159 + ath9k_hw_set_cts_timeout(ah, acktimeout);
160 if (ah->globaltxtimeout != (u32) -1)
161 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
162 }
163 +EXPORT_SYMBOL(ath9k_hw_init_global_settings);
164
165 void ath9k_hw_deinit(struct ath_hw *ah)
166 {
167 @@ -2077,7 +2053,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
168 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
169 ath9k_enable_rfkill(ah);
170
171 - ath9k_hw_init_user_settings(ah);
172 + ath9k_hw_init_global_settings(ah);
173
174 if (AR_SREV_9287_12_OR_LATER(ah)) {
175 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
176 @@ -3674,21 +3650,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *a
177 }
178 EXPORT_SYMBOL(ath9k_hw_extend_tsf);
179
180 -bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
181 -{
182 - if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
183 - ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
184 - "bad slot time %u\n", us);
185 - ah->slottime = (u32) -1;
186 - return false;
187 - } else {
188 - REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
189 - ah->slottime = us;
190 - return true;
191 - }
192 -}
193 -EXPORT_SYMBOL(ath9k_hw_setslottime);
194 -
195 void ath9k_hw_set11nmac2040(struct ath_hw *ah)
196 {
197 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
198 --- a/drivers/net/wireless/ath/ath9k/hw.h
199 +++ b/drivers/net/wireless/ath/ath9k/hw.h
200 @@ -553,8 +553,6 @@ struct ath_hw {
201 int16_t txpower_indexoffset;
202 u32 beacon_interval;
203 u32 slottime;
204 - u32 acktimeout;
205 - u32 ctstimeout;
206 u32 globaltxtimeout;
207
208 /* ANI */
209 @@ -668,7 +666,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah
210 void ath9k_hw_reset_tsf(struct ath_hw *ah);
211 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
212 u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
213 -bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
214 +void ath9k_hw_init_global_settings(struct ath_hw *ah);
215 void ath9k_hw_set11nmac2040(struct ath_hw *ah);
216 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
217 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
218 --- a/drivers/net/wireless/ath/ath9k/beacon.c
219 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
220 @@ -480,7 +480,8 @@ void ath_beacon_tasklet(unsigned long da
221 sc->beacon.updateslot = COMMIT; /* commit next beacon */
222 sc->beacon.slotupdate = slot;
223 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
224 - ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime);
225 + ah->slottime = sc->beacon.slottime;
226 + ath9k_hw_init_global_settings(ah);
227 sc->beacon.updateslot = OK;
228 }
229 if (bfaddr != 0) {