aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c21
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c2
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);
420void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); 420void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif);
421void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif); 421void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif);
422void ath9k_set_beacon(struct ath_softc *sc); 422void ath9k_set_beacon(struct ath_softc *sc);
423bool 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
294bool 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
294void ath9k_beacon_tasklet(unsigned long data) 311void 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
2324static 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
2321struct ieee80211_ops ath9k_ops = { 2337struct 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