diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ath9k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/beacon.c | 21 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/init.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/xmit.c | 2 |
5 files changed, 43 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index df1c4957e3f0..8519e75a2e79 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -420,6 +420,7 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); | |||
420 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); | 420 | void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); |
421 | void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif); | 421 | void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif); |
422 | void ath9k_set_beacon(struct ath_softc *sc); | 422 | void ath9k_set_beacon(struct ath_softc *sc); |
423 | bool ath9k_csa_is_finished(struct ath_softc *sc); | ||
423 | 424 | ||
424 | /*******************/ | 425 | /*******************/ |
425 | /* Link Monitoring */ | 426 | /* Link Monitoring */ |
@@ -756,6 +757,7 @@ struct ath_softc { | |||
756 | #endif | 757 | #endif |
757 | 758 | ||
758 | struct ath_descdma txsdma; | 759 | struct ath_descdma txsdma; |
760 | struct ieee80211_vif *csa_vif; | ||
759 | 761 | ||
760 | struct ath_ant_comb ant_comb; | 762 | struct ath_ant_comb ant_comb; |
761 | u8 ant_tx, ant_rx; | 763 | u8 ant_tx, ant_rx; |
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c index 1a17732bb089..b5c16b3a37b9 100644 --- a/drivers/net/wireless/ath/ath9k/beacon.c +++ b/drivers/net/wireless/ath/ath9k/beacon.c | |||
@@ -291,6 +291,23 @@ void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif) | |||
291 | (unsigned long long)tsfadjust, avp->av_bslot); | 291 | (unsigned long long)tsfadjust, avp->av_bslot); |
292 | } | 292 | } |
293 | 293 | ||
294 | bool ath9k_csa_is_finished(struct ath_softc *sc) | ||
295 | { | ||
296 | struct ieee80211_vif *vif; | ||
297 | |||
298 | vif = sc->csa_vif; | ||
299 | if (!vif || !vif->csa_active) | ||
300 | return false; | ||
301 | |||
302 | if (!ieee80211_csa_is_complete(vif)) | ||
303 | return false; | ||
304 | |||
305 | ieee80211_csa_finish(vif); | ||
306 | |||
307 | sc->csa_vif = NULL; | ||
308 | return true; | ||
309 | } | ||
310 | |||
294 | void ath9k_beacon_tasklet(unsigned long data) | 311 | void ath9k_beacon_tasklet(unsigned long data) |
295 | { | 312 | { |
296 | struct ath_softc *sc = (struct ath_softc *)data; | 313 | struct ath_softc *sc = (struct ath_softc *)data; |
@@ -336,6 +353,10 @@ void ath9k_beacon_tasklet(unsigned long data) | |||
336 | return; | 353 | return; |
337 | } | 354 | } |
338 | 355 | ||
356 | /* EDMA devices check that in the tx completion function. */ | ||
357 | if (!edma && ath9k_csa_is_finished(sc)) | ||
358 | return; | ||
359 | |||
339 | slot = ath9k_beacon_choose_slot(sc); | 360 | slot = ath9k_beacon_choose_slot(sc); |
340 | vif = sc->beacon.bslot[slot]; | 361 | vif = sc->beacon.bslot[slot]; |
341 | 362 | ||
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 60bb4d6f1d82..abf1eb5d97ad 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -861,6 +861,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
861 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; | 861 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS; |
862 | hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; | 862 | hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; |
863 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; | 863 | hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; |
864 | hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; | ||
864 | 865 | ||
865 | #ifdef CONFIG_PM_SLEEP | 866 | #ifdef CONFIG_PM_SLEEP |
866 | if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && | 867 | if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index ba382a8c8b9a..ac9f18fa0729 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1032,6 +1032,9 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1032 | if (ath9k_uses_beacons(vif->type)) | 1032 | if (ath9k_uses_beacons(vif->type)) |
1033 | ath9k_beacon_remove_slot(sc, vif); | 1033 | ath9k_beacon_remove_slot(sc, vif); |
1034 | 1034 | ||
1035 | if (sc->csa_vif == vif) | ||
1036 | sc->csa_vif = NULL; | ||
1037 | |||
1035 | ath9k_ps_wakeup(sc); | 1038 | ath9k_ps_wakeup(sc); |
1036 | ath9k_calculate_summary_state(hw, NULL); | 1039 | ath9k_calculate_summary_state(hw, NULL); |
1037 | ath9k_ps_restore(sc); | 1040 | ath9k_ps_restore(sc); |
@@ -2318,6 +2321,19 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw) | |||
2318 | clear_bit(SC_OP_SCANNING, &sc->sc_flags); | 2321 | clear_bit(SC_OP_SCANNING, &sc->sc_flags); |
2319 | } | 2322 | } |
2320 | 2323 | ||
2324 | static void ath9k_channel_switch_beacon(struct ieee80211_hw *hw, | ||
2325 | struct ieee80211_vif *vif, | ||
2326 | struct cfg80211_chan_def *chandef) | ||
2327 | { | ||
2328 | struct ath_softc *sc = hw->priv; | ||
2329 | |||
2330 | /* mac80211 does not support CSA in multi-if cases (yet) */ | ||
2331 | if (WARN_ON(sc->csa_vif)) | ||
2332 | return; | ||
2333 | |||
2334 | sc->csa_vif = vif; | ||
2335 | } | ||
2336 | |||
2321 | struct ieee80211_ops ath9k_ops = { | 2337 | struct ieee80211_ops ath9k_ops = { |
2322 | .tx = ath9k_tx, | 2338 | .tx = ath9k_tx, |
2323 | .start = ath9k_start, | 2339 | .start = ath9k_start, |
@@ -2365,4 +2381,5 @@ struct ieee80211_ops ath9k_ops = { | |||
2365 | #endif | 2381 | #endif |
2366 | .sw_scan_start = ath9k_sw_scan_start, | 2382 | .sw_scan_start = ath9k_sw_scan_start, |
2367 | .sw_scan_complete = ath9k_sw_scan_complete, | 2383 | .sw_scan_complete = ath9k_sw_scan_complete, |
2384 | .channel_switch_beacon = ath9k_channel_switch_beacon, | ||
2368 | }; | 2385 | }; |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 7223e303f3a1..35b515fe3ffa 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -2559,6 +2559,8 @@ void ath_tx_edma_tasklet(struct ath_softc *sc) | |||
2559 | if (ts.qid == sc->beacon.beaconq) { | 2559 | if (ts.qid == sc->beacon.beaconq) { |
2560 | sc->beacon.tx_processed = true; | 2560 | sc->beacon.tx_processed = true; |
2561 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); | 2561 | sc->beacon.tx_last = !(ts.ts_status & ATH9K_TXERR_MASK); |
2562 | |||
2563 | ath9k_csa_is_finished(sc); | ||
2562 | continue; | 2564 | continue; |
2563 | } | 2565 | } |
2564 | 2566 | ||