diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/gpio.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/gpio.c | 44 |
1 files changed, 29 insertions, 15 deletions
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index 281a9af0f1b6..26032cb59b8a 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c | |||
@@ -132,17 +132,18 @@ static void ath_detect_bt_priority(struct ath_softc *sc) | |||
132 | 132 | ||
133 | if (time_after(jiffies, btcoex->bt_priority_time + | 133 | if (time_after(jiffies, btcoex->bt_priority_time + |
134 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { | 134 | msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) { |
135 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | 135 | clear_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
136 | clear_bit(BT_OP_SCAN, &btcoex->op_flags); | ||
136 | /* Detect if colocated bt started scanning */ | 137 | /* Detect if colocated bt started scanning */ |
137 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { | 138 | if (btcoex->bt_priority_cnt >= ATH_BT_CNT_SCAN_THRESHOLD) { |
138 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, | 139 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
139 | "BT scan detected\n"); | 140 | "BT scan detected\n"); |
140 | sc->sc_flags |= (SC_OP_BT_SCAN | | 141 | set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
141 | SC_OP_BT_PRIORITY_DETECTED); | 142 | set_bit(BT_OP_SCAN, &btcoex->op_flags); |
142 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { | 143 | } else if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) { |
143 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, | 144 | ath_dbg(ath9k_hw_common(sc->sc_ah), BTCOEX, |
144 | "BT priority traffic detected\n"); | 145 | "BT priority traffic detected\n"); |
145 | sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED; | 146 | set_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags); |
146 | } | 147 | } |
147 | 148 | ||
148 | btcoex->bt_priority_cnt = 0; | 149 | btcoex->bt_priority_cnt = 0; |
@@ -190,13 +191,26 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
190 | struct ath_softc *sc = (struct ath_softc *) data; | 191 | struct ath_softc *sc = (struct ath_softc *) data; |
191 | struct ath_hw *ah = sc->sc_ah; | 192 | struct ath_hw *ah = sc->sc_ah; |
192 | struct ath_btcoex *btcoex = &sc->btcoex; | 193 | struct ath_btcoex *btcoex = &sc->btcoex; |
194 | struct ath_mci_profile *mci = &btcoex->mci; | ||
193 | u32 timer_period; | 195 | u32 timer_period; |
194 | bool is_btscan; | 196 | bool is_btscan; |
195 | 197 | ||
196 | ath9k_ps_wakeup(sc); | 198 | ath9k_ps_wakeup(sc); |
197 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) | 199 | if (!(ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) |
198 | ath_detect_bt_priority(sc); | 200 | ath_detect_bt_priority(sc); |
199 | is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | 201 | is_btscan = test_bit(BT_OP_SCAN, &btcoex->op_flags); |
202 | |||
203 | btcoex->bt_wait_time += btcoex->btcoex_period; | ||
204 | if (btcoex->bt_wait_time > ATH_BTCOEX_RX_WAIT_TIME) { | ||
205 | if (ar9003_mci_state(ah, MCI_STATE_NEED_FTP_STOMP) && | ||
206 | (mci->num_pan || mci->num_other_acl)) | ||
207 | ah->btcoex_hw.mci.stomp_ftp = | ||
208 | (sc->rx.num_pkts < ATH_BTCOEX_STOMP_FTP_THRESH); | ||
209 | else | ||
210 | ah->btcoex_hw.mci.stomp_ftp = false; | ||
211 | btcoex->bt_wait_time = 0; | ||
212 | sc->rx.num_pkts = 0; | ||
213 | } | ||
200 | 214 | ||
201 | spin_lock_bh(&btcoex->btcoex_lock); | 215 | spin_lock_bh(&btcoex->btcoex_lock); |
202 | 216 | ||
@@ -218,9 +232,8 @@ static void ath_btcoex_period_timer(unsigned long data) | |||
218 | } | 232 | } |
219 | 233 | ||
220 | ath9k_ps_restore(sc); | 234 | ath9k_ps_restore(sc); |
221 | timer_period = btcoex->btcoex_period / 1000; | 235 | timer_period = btcoex->btcoex_period; |
222 | mod_timer(&btcoex->period_timer, jiffies + | 236 | mod_timer(&btcoex->period_timer, jiffies + msecs_to_jiffies(timer_period)); |
223 | msecs_to_jiffies(timer_period)); | ||
224 | } | 237 | } |
225 | 238 | ||
226 | /* | 239 | /* |
@@ -233,14 +246,14 @@ static void ath_btcoex_no_stomp_timer(void *arg) | |||
233 | struct ath_hw *ah = sc->sc_ah; | 246 | struct ath_hw *ah = sc->sc_ah; |
234 | struct ath_btcoex *btcoex = &sc->btcoex; | 247 | struct ath_btcoex *btcoex = &sc->btcoex; |
235 | struct ath_common *common = ath9k_hw_common(ah); | 248 | struct ath_common *common = ath9k_hw_common(ah); |
236 | bool is_btscan = sc->sc_flags & SC_OP_BT_SCAN; | ||
237 | 249 | ||
238 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); | 250 | ath_dbg(common, BTCOEX, "no stomp timer running\n"); |
239 | 251 | ||
240 | ath9k_ps_wakeup(sc); | 252 | ath9k_ps_wakeup(sc); |
241 | spin_lock_bh(&btcoex->btcoex_lock); | 253 | spin_lock_bh(&btcoex->btcoex_lock); |
242 | 254 | ||
243 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan) | 255 | if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || |
256 | test_bit(BT_OP_SCAN, &btcoex->op_flags)) | ||
244 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); | 257 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); |
245 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) | 258 | else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL) |
246 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); | 259 | ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW); |
@@ -254,10 +267,10 @@ static int ath_init_btcoex_timer(struct ath_softc *sc) | |||
254 | { | 267 | { |
255 | struct ath_btcoex *btcoex = &sc->btcoex; | 268 | struct ath_btcoex *btcoex = &sc->btcoex; |
256 | 269 | ||
257 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000; | 270 | btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD; |
258 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * | 271 | btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) * 1000 * |
259 | btcoex->btcoex_period / 100; | 272 | btcoex->btcoex_period / 100; |
260 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * | 273 | btcoex->btscan_no_stomp = (100 - ATH_BTCOEX_BTSCAN_DUTY_CYCLE) * 1000 * |
261 | btcoex->btcoex_period / 100; | 274 | btcoex->btcoex_period / 100; |
262 | 275 | ||
263 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, | 276 | setup_timer(&btcoex->period_timer, ath_btcoex_period_timer, |
@@ -292,7 +305,7 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) | |||
292 | 305 | ||
293 | btcoex->bt_priority_cnt = 0; | 306 | btcoex->bt_priority_cnt = 0; |
294 | btcoex->bt_priority_time = jiffies; | 307 | btcoex->bt_priority_time = jiffies; |
295 | sc->sc_flags &= ~(SC_OP_BT_PRIORITY_DETECTED | SC_OP_BT_SCAN); | 308 | btcoex->op_flags &= ~(BT_OP_PRIORITY_DETECTED | BT_OP_SCAN); |
296 | 309 | ||
297 | mod_timer(&btcoex->period_timer, jiffies); | 310 | mod_timer(&btcoex->period_timer, jiffies); |
298 | } | 311 | } |
@@ -316,12 +329,13 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) | |||
316 | 329 | ||
317 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) | 330 | u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) |
318 | { | 331 | { |
332 | struct ath_btcoex *btcoex = &sc->btcoex; | ||
319 | struct ath_mci_profile *mci = &sc->btcoex.mci; | 333 | struct ath_mci_profile *mci = &sc->btcoex.mci; |
320 | u16 aggr_limit = 0; | 334 | u16 aggr_limit = 0; |
321 | 335 | ||
322 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) | 336 | if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI) && mci->aggr_limit) |
323 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; | 337 | aggr_limit = (max_4ms_framelen * mci->aggr_limit) >> 4; |
324 | else if (sc->sc_flags & SC_OP_BT_PRIORITY_DETECTED) | 338 | else if (test_bit(BT_OP_PRIORITY_DETECTED, &btcoex->op_flags)) |
325 | aggr_limit = min((max_4ms_framelen * 3) / 8, | 339 | aggr_limit = min((max_4ms_framelen * 3) / 8, |
326 | (u32)ATH_AMPDU_LIMIT_MAX); | 340 | (u32)ATH_AMPDU_LIMIT_MAX); |
327 | 341 | ||