aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/main.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c691
1 files changed, 515 insertions, 176 deletions
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 248e5b24acfa..6049d8b82855 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -19,6 +19,9 @@
19#include "ath9k.h" 19#include "ath9k.h"
20#include "btcoex.h" 20#include "btcoex.h"
21 21
22static void ath9k_set_assoc_state(struct ath_softc *sc,
23 struct ieee80211_vif *vif);
24
22u8 ath9k_parse_mpdudensity(u8 mpdudensity) 25u8 ath9k_parse_mpdudensity(u8 mpdudensity)
23{ 26{
24 /* 27 /*
@@ -167,8 +170,6 @@ static void ath_cancel_work(struct ath_softc *sc)
167 170
168static void ath_restart_work(struct ath_softc *sc) 171static void ath_restart_work(struct ath_softc *sc)
169{ 172{
170 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
171
172 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); 173 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
173 174
174 if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9485(sc->sc_ah) || 175 if (AR_SREV_9340(sc->sc_ah) || AR_SREV_9485(sc->sc_ah) ||
@@ -177,21 +178,18 @@ static void ath_restart_work(struct ath_softc *sc)
177 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL)); 178 msecs_to_jiffies(ATH_PLL_WORK_INTERVAL));
178 179
179 ath_start_rx_poll(sc, 3); 180 ath_start_rx_poll(sc, 3);
180 181 ath_start_ani(sc);
181 if (!common->disable_ani)
182 ath_start_ani(common);
183} 182}
184 183
185static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush) 184static bool ath_prepare_reset(struct ath_softc *sc, bool retry_tx, bool flush)
186{ 185{
187 struct ath_hw *ah = sc->sc_ah; 186 struct ath_hw *ah = sc->sc_ah;
188 struct ath_common *common = ath9k_hw_common(ah);
189 bool ret = true; 187 bool ret = true;
190 188
191 ieee80211_stop_queues(sc->hw); 189 ieee80211_stop_queues(sc->hw);
192 190
193 sc->hw_busy_count = 0; 191 sc->hw_busy_count = 0;
194 del_timer_sync(&common->ani.timer); 192 ath_stop_ani(sc);
195 del_timer_sync(&sc->rx_poll_timer); 193 del_timer_sync(&sc->rx_poll_timer);
196 194
197 ath9k_debug_samp_bb_mac(sc); 195 ath9k_debug_samp_bb_mac(sc);
@@ -236,7 +234,7 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
236 if (!test_bit(SC_OP_BEACONS, &sc->sc_flags)) 234 if (!test_bit(SC_OP_BEACONS, &sc->sc_flags))
237 goto work; 235 goto work;
238 236
239 ath_set_beacon(sc); 237 ath9k_set_beacon(sc);
240 238
241 if (ah->opmode == NL80211_IFTYPE_STATION && 239 if (ah->opmode == NL80211_IFTYPE_STATION &&
242 test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) { 240 test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
@@ -365,6 +363,7 @@ void ath9k_tasklet(unsigned long data)
365 struct ath_softc *sc = (struct ath_softc *)data; 363 struct ath_softc *sc = (struct ath_softc *)data;
366 struct ath_hw *ah = sc->sc_ah; 364 struct ath_hw *ah = sc->sc_ah;
367 struct ath_common *common = ath9k_hw_common(ah); 365 struct ath_common *common = ath9k_hw_common(ah);
366 enum ath_reset_type type;
368 unsigned long flags; 367 unsigned long flags;
369 u32 status = sc->intrstatus; 368 u32 status = sc->intrstatus;
370 u32 rxmask; 369 u32 rxmask;
@@ -374,18 +373,13 @@ void ath9k_tasklet(unsigned long data)
374 373
375 if ((status & ATH9K_INT_FATAL) || 374 if ((status & ATH9K_INT_FATAL) ||
376 (status & ATH9K_INT_BB_WATCHDOG)) { 375 (status & ATH9K_INT_BB_WATCHDOG)) {
377#ifdef CONFIG_ATH9K_DEBUGFS
378 enum ath_reset_type type;
379 376
380 if (status & ATH9K_INT_FATAL) 377 if (status & ATH9K_INT_FATAL)
381 type = RESET_TYPE_FATAL_INT; 378 type = RESET_TYPE_FATAL_INT;
382 else 379 else
383 type = RESET_TYPE_BB_WATCHDOG; 380 type = RESET_TYPE_BB_WATCHDOG;
384 381
385 RESET_STAT_INC(sc, type); 382 ath9k_queue_reset(sc, type);
386#endif
387 set_bit(SC_OP_HW_RESET, &sc->sc_flags);
388 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
389 goto out; 383 goto out;
390 } 384 }
391 385
@@ -493,6 +487,17 @@ irqreturn_t ath_isr(int irq, void *dev)
493 if (status & SCHED_INTR) 487 if (status & SCHED_INTR)
494 sched = true; 488 sched = true;
495 489
490#ifdef CONFIG_PM_SLEEP
491 if (status & ATH9K_INT_BMISS) {
492 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {
493 ath_dbg(common, ANY, "during WoW we got a BMISS\n");
494 atomic_inc(&sc->wow_got_bmiss_intr);
495 atomic_dec(&sc->wow_sleep_proc_intr);
496 }
497 ath_dbg(common, INTERRUPT, "beacon miss interrupt\n");
498 }
499#endif
500
496 /* 501 /*
497 * If a FATAL or RXORN interrupt is received, we have to reset the 502 * If a FATAL or RXORN interrupt is received, we have to reset the
498 * chip immediately. 503 * chip immediately.
@@ -575,6 +580,15 @@ static int ath_reset(struct ath_softc *sc, bool retry_tx)
575 return r; 580 return r;
576} 581}
577 582
583void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type)
584{
585#ifdef CONFIG_ATH9K_DEBUGFS
586 RESET_STAT_INC(sc, type);
587#endif
588 set_bit(SC_OP_HW_RESET, &sc->sc_flags);
589 ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
590}
591
578void ath_reset_work(struct work_struct *work) 592void ath_reset_work(struct work_struct *work)
579{ 593{
580 struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work); 594 struct ath_softc *sc = container_of(work, struct ath_softc, hw_reset_work);
@@ -841,16 +855,6 @@ bool ath9k_uses_beacons(int type)
841 } 855 }
842} 856}
843 857
844static void ath9k_reclaim_beacon(struct ath_softc *sc,
845 struct ieee80211_vif *vif)
846{
847 struct ath_vif *avp = (void *)vif->drv_priv;
848
849 ath9k_set_beaconing_status(sc, false);
850 ath_beacon_return(sc, avp);
851 ath9k_set_beaconing_status(sc, true);
852}
853
854static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) 858static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
855{ 859{
856 struct ath9k_vif_iter_data *iter_data = data; 860 struct ath9k_vif_iter_data *iter_data = data;
@@ -882,6 +886,18 @@ static void ath9k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
882 } 886 }
883} 887}
884 888
889static void ath9k_sta_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
890{
891 struct ath_softc *sc = data;
892 struct ath_vif *avp = (void *)vif->drv_priv;
893
894 if (vif->type != NL80211_IFTYPE_STATION)
895 return;
896
897 if (avp->primary_sta_vif)
898 ath9k_set_assoc_state(sc, vif);
899}
900
885/* Called with sc->mutex held. */ 901/* Called with sc->mutex held. */
886void ath9k_calculate_iter_data(struct ieee80211_hw *hw, 902void ath9k_calculate_iter_data(struct ieee80211_hw *hw,
887 struct ieee80211_vif *vif, 903 struct ieee80211_vif *vif,
@@ -915,21 +931,18 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
915 struct ath_hw *ah = sc->sc_ah; 931 struct ath_hw *ah = sc->sc_ah;
916 struct ath_common *common = ath9k_hw_common(ah); 932 struct ath_common *common = ath9k_hw_common(ah);
917 struct ath9k_vif_iter_data iter_data; 933 struct ath9k_vif_iter_data iter_data;
934 enum nl80211_iftype old_opmode = ah->opmode;
918 935
919 ath9k_calculate_iter_data(hw, vif, &iter_data); 936 ath9k_calculate_iter_data(hw, vif, &iter_data);
920 937
921 /* Set BSSID mask. */
922 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN); 938 memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
923 ath_hw_setbssidmask(common); 939 ath_hw_setbssidmask(common);
924 940
925 /* Set op-mode & TSF */
926 if (iter_data.naps > 0) { 941 if (iter_data.naps > 0) {
927 ath9k_hw_set_tsfadjust(ah, 1); 942 ath9k_hw_set_tsfadjust(ah, true);
928 set_bit(SC_OP_TSF_RESET, &sc->sc_flags);
929 ah->opmode = NL80211_IFTYPE_AP; 943 ah->opmode = NL80211_IFTYPE_AP;
930 } else { 944 } else {
931 ath9k_hw_set_tsfadjust(ah, 0); 945 ath9k_hw_set_tsfadjust(ah, false);
932 clear_bit(SC_OP_TSF_RESET, &sc->sc_flags);
933 946
934 if (iter_data.nmeshes) 947 if (iter_data.nmeshes)
935 ah->opmode = NL80211_IFTYPE_MESH_POINT; 948 ah->opmode = NL80211_IFTYPE_MESH_POINT;
@@ -941,9 +954,8 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
941 ah->opmode = NL80211_IFTYPE_STATION; 954 ah->opmode = NL80211_IFTYPE_STATION;
942 } 955 }
943 956
944 /* 957 ath9k_hw_setopmode(ah);
945 * Enable MIB interrupts when there are hardware phy counters. 958
946 */
947 if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0) 959 if ((iter_data.nstations + iter_data.nadhocs + iter_data.nmeshes) > 0)
948 ah->imask |= ATH9K_INT_TSFOOR; 960 ah->imask |= ATH9K_INT_TSFOOR;
949 else 961 else
@@ -951,34 +963,15 @@ static void ath9k_calculate_summary_state(struct ieee80211_hw *hw,
951 963
952 ath9k_hw_set_interrupts(ah); 964 ath9k_hw_set_interrupts(ah);
953 965
954 /* Set up ANI */ 966 /*
955 if (iter_data.naps > 0) { 967 * If we are changing the opmode to STATION,
956 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER; 968 * a beacon sync needs to be done.
957 969 */
958 if (!common->disable_ani) { 970 if (ah->opmode == NL80211_IFTYPE_STATION &&
959 set_bit(SC_OP_ANI_RUN, &sc->sc_flags); 971 old_opmode == NL80211_IFTYPE_AP &&
960 ath_start_ani(common); 972 test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
961 } 973 ieee80211_iterate_active_interfaces_atomic(sc->hw,
962 974 ath9k_sta_vif_iter, sc);
963 } else {
964 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
965 del_timer_sync(&common->ani.timer);
966 }
967}
968
969/* Called with sc->mutex held, vif counts set up properly. */
970static void ath9k_do_vif_add_setup(struct ieee80211_hw *hw,
971 struct ieee80211_vif *vif)
972{
973 struct ath_softc *sc = hw->priv;
974
975 ath9k_calculate_summary_state(hw, vif);
976
977 if (ath9k_uses_beacons(vif->type)) {
978 /* Reserve a beacon slot for the vif */
979 ath9k_set_beaconing_status(sc, false);
980 ath_beacon_alloc(sc, vif);
981 ath9k_set_beaconing_status(sc, true);
982 } 975 }
983} 976}
984 977
@@ -1021,7 +1014,10 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1021 1014
1022 sc->nvifs++; 1015 sc->nvifs++;
1023 1016
1024 ath9k_do_vif_add_setup(hw, vif); 1017 ath9k_calculate_summary_state(hw, vif);
1018 if (ath9k_uses_beacons(vif->type))
1019 ath9k_beacon_assign_slot(sc, vif);
1020
1025out: 1021out:
1026 mutex_unlock(&sc->mutex); 1022 mutex_unlock(&sc->mutex);
1027 ath9k_ps_restore(sc); 1023 ath9k_ps_restore(sc);
@@ -1038,6 +1034,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1038 int ret = 0; 1034 int ret = 0;
1039 1035
1040 ath_dbg(common, CONFIG, "Change Interface\n"); 1036 ath_dbg(common, CONFIG, "Change Interface\n");
1037
1041 mutex_lock(&sc->mutex); 1038 mutex_lock(&sc->mutex);
1042 ath9k_ps_wakeup(sc); 1039 ath9k_ps_wakeup(sc);
1043 1040
@@ -1050,15 +1047,16 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1050 } 1047 }
1051 } 1048 }
1052 1049
1053 /* Clean up old vif stuff */
1054 if (ath9k_uses_beacons(vif->type)) 1050 if (ath9k_uses_beacons(vif->type))
1055 ath9k_reclaim_beacon(sc, vif); 1051 ath9k_beacon_remove_slot(sc, vif);
1056 1052
1057 /* Add new settings */
1058 vif->type = new_type; 1053 vif->type = new_type;
1059 vif->p2p = p2p; 1054 vif->p2p = p2p;
1060 1055
1061 ath9k_do_vif_add_setup(hw, vif); 1056 ath9k_calculate_summary_state(hw, vif);
1057 if (ath9k_uses_beacons(vif->type))
1058 ath9k_beacon_assign_slot(sc, vif);
1059
1062out: 1060out:
1063 ath9k_ps_restore(sc); 1061 ath9k_ps_restore(sc);
1064 mutex_unlock(&sc->mutex); 1062 mutex_unlock(&sc->mutex);
@@ -1078,9 +1076,8 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1078 1076
1079 sc->nvifs--; 1077 sc->nvifs--;
1080 1078
1081 /* Reclaim beacon resources */
1082 if (ath9k_uses_beacons(vif->type)) 1079 if (ath9k_uses_beacons(vif->type))
1083 ath9k_reclaim_beacon(sc, vif); 1080 ath9k_beacon_remove_slot(sc, vif);
1084 1081
1085 ath9k_calculate_summary_state(hw, NULL); 1082 ath9k_calculate_summary_state(hw, NULL);
1086 1083
@@ -1377,21 +1374,18 @@ static int ath9k_conf_tx(struct ieee80211_hw *hw,
1377 qi.tqi_aifs = params->aifs; 1374 qi.tqi_aifs = params->aifs;
1378 qi.tqi_cwmin = params->cw_min; 1375 qi.tqi_cwmin = params->cw_min;
1379 qi.tqi_cwmax = params->cw_max; 1376 qi.tqi_cwmax = params->cw_max;
1380 qi.tqi_burstTime = params->txop; 1377 qi.tqi_burstTime = params->txop * 32;
1381 1378
1382 ath_dbg(common, CONFIG, 1379 ath_dbg(common, CONFIG,
1383 "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n", 1380 "Configure tx [queue/halq] [%d/%d], aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
1384 queue, txq->axq_qnum, params->aifs, params->cw_min, 1381 queue, txq->axq_qnum, params->aifs, params->cw_min,
1385 params->cw_max, params->txop); 1382 params->cw_max, params->txop);
1386 1383
1384 ath_update_max_aggr_framelen(sc, queue, qi.tqi_burstTime);
1387 ret = ath_txq_update(sc, txq->axq_qnum, &qi); 1385 ret = ath_txq_update(sc, txq->axq_qnum, &qi);
1388 if (ret) 1386 if (ret)
1389 ath_err(common, "TXQ Update failed\n"); 1387 ath_err(common, "TXQ Update failed\n");
1390 1388
1391 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1392 if (queue == WME_AC_BE && !ret)
1393 ath_beaconq_config(sc);
1394
1395 mutex_unlock(&sc->mutex); 1389 mutex_unlock(&sc->mutex);
1396 ath9k_ps_restore(sc); 1390 ath9k_ps_restore(sc);
1397 1391
@@ -1460,86 +1454,53 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
1460 1454
1461 return ret; 1455 return ret;
1462} 1456}
1463static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif) 1457
1458static void ath9k_set_assoc_state(struct ath_softc *sc,
1459 struct ieee80211_vif *vif)
1464{ 1460{
1465 struct ath_softc *sc = data;
1466 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1461 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1467 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1468 struct ath_vif *avp = (void *)vif->drv_priv; 1462 struct ath_vif *avp = (void *)vif->drv_priv;
1463 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1469 unsigned long flags; 1464 unsigned long flags;
1465
1466 set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags);
1467 avp->primary_sta_vif = true;
1468
1470 /* 1469 /*
1471 * Skip iteration if primary station vif's bss info 1470 * Set the AID, BSSID and do beacon-sync only when
1472 * was not changed 1471 * the HW opmode is STATION.
1472 *
1473 * But the primary bit is set above in any case.
1473 */ 1474 */
1474 if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) 1475 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
1475 return; 1476 return;
1476 1477
1477 if (bss_conf->assoc) { 1478 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1478 set_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags); 1479 common->curaid = bss_conf->aid;
1479 avp->primary_sta_vif = true; 1480 ath9k_hw_write_associd(sc->sc_ah);
1480 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1481 common->curaid = bss_conf->aid;
1482 ath9k_hw_write_associd(sc->sc_ah);
1483 ath_dbg(common, CONFIG, "Bss Info ASSOC %d, bssid: %pM\n",
1484 bss_conf->aid, common->curbssid);
1485 ath_beacon_config(sc, vif);
1486 /*
1487 * Request a re-configuration of Beacon related timers
1488 * on the receipt of the first Beacon frame (i.e.,
1489 * after time sync with the AP).
1490 */
1491 spin_lock_irqsave(&sc->sc_pm_lock, flags);
1492 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
1493 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1494
1495 /* Reset rssi stats */
1496 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
1497 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1498 1481
1499 ath_start_rx_poll(sc, 3); 1482 sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
1483 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1500 1484
1501 if (!common->disable_ani) { 1485 spin_lock_irqsave(&sc->sc_pm_lock, flags);
1502 set_bit(SC_OP_ANI_RUN, &sc->sc_flags); 1486 sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
1503 ath_start_ani(common); 1487 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
1504 }
1505 1488
1506 } 1489 ath_dbg(common, CONFIG,
1490 "Primary Station interface: %pM, BSSID: %pM\n",
1491 vif->addr, common->curbssid);
1507} 1492}
1508 1493
1509static void ath9k_config_bss(struct ath_softc *sc, struct ieee80211_vif *vif) 1494static void ath9k_bss_assoc_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
1510{ 1495{
1511 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1496 struct ath_softc *sc = data;
1512 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf; 1497 struct ieee80211_bss_conf *bss_conf = &vif->bss_conf;
1513 struct ath_vif *avp = (void *)vif->drv_priv;
1514 1498
1515 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION) 1499 if (test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags))
1516 return; 1500 return;
1517 1501
1518 /* Reconfigure bss info */ 1502 if (bss_conf->assoc)
1519 if (avp->primary_sta_vif && !bss_conf->assoc) { 1503 ath9k_set_assoc_state(sc, vif);
1520 ath_dbg(common, CONFIG, "Bss Info DISASSOC %d, bssid %pM\n",
1521 common->curaid, common->curbssid);
1522 clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags);
1523 clear_bit(SC_OP_BEACONS, &sc->sc_flags);
1524 avp->primary_sta_vif = false;
1525 memset(common->curbssid, 0, ETH_ALEN);
1526 common->curaid = 0;
1527 }
1528
1529 ieee80211_iterate_active_interfaces_atomic(
1530 sc->hw, ath9k_bss_iter, sc);
1531
1532 /*
1533 * None of station vifs are associated.
1534 * Clear bssid & aid
1535 */
1536 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
1537 ath9k_hw_write_associd(sc->sc_ah);
1538 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
1539 del_timer_sync(&common->ani.timer);
1540 del_timer_sync(&sc->rx_poll_timer);
1541 memset(&sc->caldata, 0, sizeof(sc->caldata));
1542 }
1543} 1504}
1544 1505
1545static void ath9k_bss_info_changed(struct ieee80211_hw *hw, 1506static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
@@ -1547,6 +1508,11 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1547 struct ieee80211_bss_conf *bss_conf, 1508 struct ieee80211_bss_conf *bss_conf,
1548 u32 changed) 1509 u32 changed)
1549{ 1510{
1511#define CHECK_ANI \
1512 (BSS_CHANGED_ASSOC | \
1513 BSS_CHANGED_IBSS | \
1514 BSS_CHANGED_BEACON_ENABLED)
1515
1550 struct ath_softc *sc = hw->priv; 1516 struct ath_softc *sc = hw->priv;
1551 struct ath_hw *ah = sc->sc_ah; 1517 struct ath_hw *ah = sc->sc_ah;
1552 struct ath_common *common = ath9k_hw_common(ah); 1518 struct ath_common *common = ath9k_hw_common(ah);
@@ -1557,53 +1523,41 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1557 mutex_lock(&sc->mutex); 1523 mutex_lock(&sc->mutex);
1558 1524
1559 if (changed & BSS_CHANGED_ASSOC) { 1525 if (changed & BSS_CHANGED_ASSOC) {
1560 ath9k_config_bss(sc, vif); 1526 ath_dbg(common, CONFIG, "BSSID %pM Changed ASSOC %d\n",
1527 bss_conf->bssid, bss_conf->assoc);
1561 1528
1562 ath_dbg(common, CONFIG, "BSSID: %pM aid: 0x%x\n", 1529 if (avp->primary_sta_vif && !bss_conf->assoc) {
1563 common->curbssid, common->curaid); 1530 clear_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags);
1531 avp->primary_sta_vif = false;
1532
1533 if (ah->opmode == NL80211_IFTYPE_STATION)
1534 clear_bit(SC_OP_BEACONS, &sc->sc_flags);
1535 }
1536
1537 ieee80211_iterate_active_interfaces_atomic(sc->hw,
1538 ath9k_bss_assoc_iter, sc);
1539
1540 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags) &&
1541 ah->opmode == NL80211_IFTYPE_STATION) {
1542 memset(common->curbssid, 0, ETH_ALEN);
1543 common->curaid = 0;
1544 ath9k_hw_write_associd(sc->sc_ah);
1545 }
1564 } 1546 }
1565 1547
1566 if (changed & BSS_CHANGED_IBSS) { 1548 if (changed & BSS_CHANGED_IBSS) {
1567 /* There can be only one vif available */
1568 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN); 1549 memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
1569 common->curaid = bss_conf->aid; 1550 common->curaid = bss_conf->aid;
1570 ath9k_hw_write_associd(sc->sc_ah); 1551 ath9k_hw_write_associd(sc->sc_ah);
1571
1572 if (bss_conf->ibss_joined) {
1573 sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
1574
1575 if (!common->disable_ani) {
1576 set_bit(SC_OP_ANI_RUN, &sc->sc_flags);
1577 ath_start_ani(common);
1578 }
1579
1580 } else {
1581 clear_bit(SC_OP_ANI_RUN, &sc->sc_flags);
1582 del_timer_sync(&common->ani.timer);
1583 del_timer_sync(&sc->rx_poll_timer);
1584 }
1585 } 1552 }
1586 1553
1587 /* 1554 if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
1588 * In case of AP mode, the HW TSF has to be reset 1555 (changed & BSS_CHANGED_BEACON_INT)) {
1589 * when the beacon interval changes. 1556 if (ah->opmode == NL80211_IFTYPE_AP &&
1590 */ 1557 bss_conf->enable_beacon)
1591 if ((changed & BSS_CHANGED_BEACON_INT) && 1558 ath9k_set_tsfadjust(sc, vif);
1592 (vif->type == NL80211_IFTYPE_AP)) 1559 if (ath9k_allow_beacon_config(sc, vif))
1593 set_bit(SC_OP_TSF_RESET, &sc->sc_flags); 1560 ath9k_beacon_config(sc, vif, changed);
1594
1595 /* Configure beaconing (AP, IBSS, MESH) */
1596 if (ath9k_uses_beacons(vif->type) &&
1597 ((changed & BSS_CHANGED_BEACON) ||
1598 (changed & BSS_CHANGED_BEACON_ENABLED) ||
1599 (changed & BSS_CHANGED_BEACON_INT))) {
1600 ath9k_set_beaconing_status(sc, false);
1601 if (bss_conf->enable_beacon)
1602 ath_beacon_alloc(sc, vif);
1603 else
1604 avp->is_bslot_active = false;
1605 ath_beacon_config(sc, vif);
1606 ath9k_set_beaconing_status(sc, true);
1607 } 1561 }
1608 1562
1609 if (changed & BSS_CHANGED_ERP_SLOT) { 1563 if (changed & BSS_CHANGED_ERP_SLOT) {
@@ -1625,8 +1579,13 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1625 } 1579 }
1626 } 1580 }
1627 1581
1582 if (changed & CHECK_ANI)
1583 ath_check_ani(sc);
1584
1628 mutex_unlock(&sc->mutex); 1585 mutex_unlock(&sc->mutex);
1629 ath9k_ps_restore(sc); 1586 ath9k_ps_restore(sc);
1587
1588#undef CHECK_ANI
1630} 1589}
1631 1590
1632static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 1591static u64 ath9k_get_tsf(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
@@ -1855,10 +1814,11 @@ static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
1855 if (!vif) 1814 if (!vif)
1856 return 0; 1815 return 0;
1857 1816
1858 avp = (void *)vif->drv_priv; 1817 if (!vif->bss_conf.enable_beacon)
1859 if (!avp->is_bslot_active)
1860 return 0; 1818 return 0;
1861 1819
1820 avp = (void *)vif->drv_priv;
1821
1862 if (!sc->beacon.tx_processed && !edma) { 1822 if (!sc->beacon.tx_processed && !edma) {
1863 tasklet_disable(&sc->bcon_tasklet); 1823 tasklet_disable(&sc->bcon_tasklet);
1864 1824
@@ -1912,12 +1872,29 @@ static u32 fill_chainmask(u32 cap, u32 new)
1912 return filled; 1872 return filled;
1913} 1873}
1914 1874
1875static bool validate_antenna_mask(struct ath_hw *ah, u32 val)
1876{
1877 switch (val & 0x7) {
1878 case 0x1:
1879 case 0x3:
1880 case 0x7:
1881 return true;
1882 case 0x2:
1883 return (ah->caps.rx_chainmask == 1);
1884 default:
1885 return false;
1886 }
1887}
1888
1915static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) 1889static int ath9k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
1916{ 1890{
1917 struct ath_softc *sc = hw->priv; 1891 struct ath_softc *sc = hw->priv;
1918 struct ath_hw *ah = sc->sc_ah; 1892 struct ath_hw *ah = sc->sc_ah;
1919 1893
1920 if (!rx_ant || !tx_ant) 1894 if (ah->caps.rx_chainmask != 1)
1895 rx_ant |= tx_ant;
1896
1897 if (!validate_antenna_mask(ah, rx_ant) || !tx_ant)
1921 return -EINVAL; 1898 return -EINVAL;
1922 1899
1923 sc->ant_rx = rx_ant; 1900 sc->ant_rx = rx_ant;
@@ -2075,6 +2052,362 @@ static void ath9k_get_et_stats(struct ieee80211_hw *hw,
2075#endif 2052#endif
2076 2053
2077 2054
2055#ifdef CONFIG_PM_SLEEP
2056
2057static void ath9k_wow_map_triggers(struct ath_softc *sc,
2058 struct cfg80211_wowlan *wowlan,
2059 u32 *wow_triggers)
2060{
2061 if (wowlan->disconnect)
2062 *wow_triggers |= AH_WOW_LINK_CHANGE |
2063 AH_WOW_BEACON_MISS;
2064 if (wowlan->magic_pkt)
2065 *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
2066
2067 if (wowlan->n_patterns)
2068 *wow_triggers |= AH_WOW_USER_PATTERN_EN;
2069
2070 sc->wow_enabled = *wow_triggers;
2071
2072}
2073
2074static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
2075{
2076 struct ath_hw *ah = sc->sc_ah;
2077 struct ath_common *common = ath9k_hw_common(ah);
2078 struct ath9k_hw_capabilities *pcaps = &ah->caps;
2079 int pattern_count = 0;
2080 int i, byte_cnt;
2081 u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
2082 u8 dis_deauth_mask[MAX_PATTERN_SIZE];
2083
2084 memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
2085 memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
2086
2087 /*
2088 * Create Dissassociate / Deauthenticate packet filter
2089 *
2090 * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
2091 * +--------------+----------+---------+--------+--------+----
2092 * + Frame Control+ Duration + DA + SA + BSSID +
2093 * +--------------+----------+---------+--------+--------+----
2094 *
2095 * The above is the management frame format for disassociate/
2096 * deauthenticate pattern, from this we need to match the first byte
2097 * of 'Frame Control' and DA, SA, and BSSID fields
2098 * (skipping 2nd byte of FC and Duration feild.
2099 *
2100 * Disassociate pattern
2101 * --------------------
2102 * Frame control = 00 00 1010
2103 * DA, SA, BSSID = x:x:x:x:x:x
2104 * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
2105 * | x:x:x:x:x:x -- 22 bytes
2106 *
2107 * Deauthenticate pattern
2108 * ----------------------
2109 * Frame control = 00 00 1100
2110 * DA, SA, BSSID = x:x:x:x:x:x
2111 * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
2112 * | x:x:x:x:x:x -- 22 bytes
2113 */
2114
2115 /* Create Disassociate Pattern first */
2116
2117 byte_cnt = 0;
2118
2119 /* Fill out the mask with all FF's */
2120
2121 for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
2122 dis_deauth_mask[i] = 0xff;
2123
2124 /* copy the first byte of frame control field */
2125 dis_deauth_pattern[byte_cnt] = 0xa0;
2126 byte_cnt++;
2127
2128 /* skip 2nd byte of frame control and Duration field */
2129 byte_cnt += 3;
2130
2131 /*
2132 * need not match the destination mac address, it can be a broadcast
2133 * mac address or an unicast to this station
2134 */
2135 byte_cnt += 6;
2136
2137 /* copy the source mac address */
2138 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
2139
2140 byte_cnt += 6;
2141
2142 /* copy the bssid, its same as the source mac address */
2143
2144 memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
2145
2146 /* Create Disassociate pattern mask */
2147
2148 if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_EXACT) {
2149
2150 if (pcaps->hw_caps & ATH9K_HW_WOW_PATTERN_MATCH_DWORD) {
2151 /*
2152 * for AR9280, because of hardware limitation, the
2153 * first 4 bytes have to be matched for all patterns.
2154 * the mask for disassociation and de-auth pattern
2155 * matching need to enable the first 4 bytes.
2156 * also the duration field needs to be filled.
2157 */
2158 dis_deauth_mask[0] = 0xf0;
2159
2160 /*
2161 * fill in duration field
2162 FIXME: what is the exact value ?
2163 */
2164 dis_deauth_pattern[2] = 0xff;
2165 dis_deauth_pattern[3] = 0xff;
2166 } else {
2167 dis_deauth_mask[0] = 0xfe;
2168 }
2169
2170 dis_deauth_mask[1] = 0x03;
2171 dis_deauth_mask[2] = 0xc0;
2172 } else {
2173 dis_deauth_mask[0] = 0xef;
2174 dis_deauth_mask[1] = 0x3f;
2175 dis_deauth_mask[2] = 0x00;
2176 dis_deauth_mask[3] = 0xfc;
2177 }
2178
2179 ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
2180
2181 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
2182 pattern_count, byte_cnt);
2183
2184 pattern_count++;
2185 /*
2186 * for de-authenticate pattern, only the first byte of the frame
2187 * control field gets changed from 0xA0 to 0xC0
2188 */
2189 dis_deauth_pattern[0] = 0xC0;
2190
2191 ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
2192 pattern_count, byte_cnt);
2193
2194}
2195
2196static void ath9k_wow_add_pattern(struct ath_softc *sc,
2197 struct cfg80211_wowlan *wowlan)
2198{
2199 struct ath_hw *ah = sc->sc_ah;
2200 struct ath9k_wow_pattern *wow_pattern = NULL;
2201 struct cfg80211_wowlan_trig_pkt_pattern *patterns = wowlan->patterns;
2202 int mask_len;
2203 s8 i = 0;
2204
2205 if (!wowlan->n_patterns)
2206 return;
2207
2208 /*
2209 * Add the new user configured patterns
2210 */
2211 for (i = 0; i < wowlan->n_patterns; i++) {
2212
2213 wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
2214
2215 if (!wow_pattern)
2216 return;
2217
2218 /*
2219 * TODO: convert the generic user space pattern to
2220 * appropriate chip specific/802.11 pattern.
2221 */
2222
2223 mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
2224 memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
2225 memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
2226 memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
2227 patterns[i].pattern_len);
2228 memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
2229 wow_pattern->pattern_len = patterns[i].pattern_len;
2230
2231 /*
2232 * just need to take care of deauth and disssoc pattern,
2233 * make sure we don't overwrite them.
2234 */
2235
2236 ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
2237 wow_pattern->mask_bytes,
2238 i + 2,
2239 wow_pattern->pattern_len);
2240 kfree(wow_pattern);
2241
2242 }
2243
2244}
2245
2246static int ath9k_suspend(struct ieee80211_hw *hw,
2247 struct cfg80211_wowlan *wowlan)
2248{
2249 struct ath_softc *sc = hw->priv;
2250 struct ath_hw *ah = sc->sc_ah;
2251 struct ath_common *common = ath9k_hw_common(ah);
2252 u32 wow_triggers_enabled = 0;
2253 int ret = 0;
2254
2255 mutex_lock(&sc->mutex);
2256
2257 ath_cancel_work(sc);
2258 del_timer_sync(&common->ani.timer);
2259 del_timer_sync(&sc->rx_poll_timer);
2260
2261 if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
2262 ath_dbg(common, ANY, "Device not present\n");
2263 ret = -EINVAL;
2264 goto fail_wow;
2265 }
2266
2267 if (WARN_ON(!wowlan)) {
2268 ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
2269 ret = -EINVAL;
2270 goto fail_wow;
2271 }
2272
2273 if (!device_can_wakeup(sc->dev)) {
2274 ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
2275 ret = 1;
2276 goto fail_wow;
2277 }
2278
2279 /*
2280 * none of the sta vifs are associated
2281 * and we are not currently handling multivif
2282 * cases, for instance we have to seperately
2283 * configure 'keep alive frame' for each
2284 * STA.
2285 */
2286
2287 if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
2288 ath_dbg(common, WOW, "None of the STA vifs are associated\n");
2289 ret = 1;
2290 goto fail_wow;
2291 }
2292
2293 if (sc->nvifs > 1) {
2294 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
2295 ret = 1;
2296 goto fail_wow;
2297 }
2298
2299 ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
2300
2301 ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
2302 wow_triggers_enabled);
2303
2304 ath9k_ps_wakeup(sc);
2305
2306 ath9k_stop_btcoex(sc);
2307
2308 /*
2309 * Enable wake up on recieving disassoc/deauth
2310 * frame by default.
2311 */
2312 ath9k_wow_add_disassoc_deauth_pattern(sc);
2313
2314 if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
2315 ath9k_wow_add_pattern(sc, wowlan);
2316
2317 spin_lock_bh(&sc->sc_pcu_lock);
2318 /*
2319 * To avoid false wake, we enable beacon miss interrupt only
2320 * when we go to sleep. We save the current interrupt mask
2321 * so we can restore it after the system wakes up
2322 */
2323 sc->wow_intr_before_sleep = ah->imask;
2324 ah->imask &= ~ATH9K_INT_GLOBAL;
2325 ath9k_hw_disable_interrupts(ah);
2326 ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
2327 ath9k_hw_set_interrupts(ah);
2328 ath9k_hw_enable_interrupts(ah);
2329
2330 spin_unlock_bh(&sc->sc_pcu_lock);
2331
2332 /*
2333 * we can now sync irq and kill any running tasklets, since we already
2334 * disabled interrupts and not holding a spin lock
2335 */
2336 synchronize_irq(sc->irq);
2337 tasklet_kill(&sc->intr_tq);
2338
2339 ath9k_hw_wow_enable(ah, wow_triggers_enabled);
2340
2341 ath9k_ps_restore(sc);
2342 ath_dbg(common, ANY, "WoW enabled in ath9k\n");
2343 atomic_inc(&sc->wow_sleep_proc_intr);
2344
2345fail_wow:
2346 mutex_unlock(&sc->mutex);
2347 return ret;
2348}
2349
2350static int ath9k_resume(struct ieee80211_hw *hw)
2351{
2352 struct ath_softc *sc = hw->priv;
2353 struct ath_hw *ah = sc->sc_ah;
2354 struct ath_common *common = ath9k_hw_common(ah);
2355 u32 wow_status;
2356
2357 mutex_lock(&sc->mutex);
2358
2359 ath9k_ps_wakeup(sc);
2360
2361 spin_lock_bh(&sc->sc_pcu_lock);
2362
2363 ath9k_hw_disable_interrupts(ah);
2364 ah->imask = sc->wow_intr_before_sleep;
2365 ath9k_hw_set_interrupts(ah);
2366 ath9k_hw_enable_interrupts(ah);
2367
2368 spin_unlock_bh(&sc->sc_pcu_lock);
2369
2370 wow_status = ath9k_hw_wow_wakeup(ah);
2371
2372 if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
2373 /*
2374 * some devices may not pick beacon miss
2375 * as the reason they woke up so we add
2376 * that here for that shortcoming.
2377 */
2378 wow_status |= AH_WOW_BEACON_MISS;
2379 atomic_dec(&sc->wow_got_bmiss_intr);
2380 ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
2381 }
2382
2383 atomic_dec(&sc->wow_sleep_proc_intr);
2384
2385 if (wow_status) {
2386 ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
2387 ath9k_hw_wow_event_to_string(wow_status), wow_status);
2388 }
2389
2390 ath_restart_work(sc);
2391 ath9k_start_btcoex(sc);
2392
2393 ath9k_ps_restore(sc);
2394 mutex_unlock(&sc->mutex);
2395
2396 return 0;
2397}
2398
2399static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
2400{
2401 struct ath_softc *sc = hw->priv;
2402
2403 mutex_lock(&sc->mutex);
2404 device_init_wakeup(sc->dev, 1);
2405 device_set_wakeup_enable(sc->dev, enabled);
2406 mutex_unlock(&sc->mutex);
2407}
2408
2409#endif
2410
2078struct ieee80211_ops ath9k_ops = { 2411struct ieee80211_ops ath9k_ops = {
2079 .tx = ath9k_tx, 2412 .tx = ath9k_tx,
2080 .start = ath9k_start, 2413 .start = ath9k_start,
@@ -2104,6 +2437,12 @@ struct ieee80211_ops ath9k_ops = {
2104 .set_antenna = ath9k_set_antenna, 2437 .set_antenna = ath9k_set_antenna,
2105 .get_antenna = ath9k_get_antenna, 2438 .get_antenna = ath9k_get_antenna,
2106 2439
2440#ifdef CONFIG_PM_SLEEP
2441 .suspend = ath9k_suspend,
2442 .resume = ath9k_resume,
2443 .set_wakeup = ath9k_set_wakeup,
2444#endif
2445
2107#ifdef CONFIG_ATH9K_DEBUGFS 2446#ifdef CONFIG_ATH9K_DEBUGFS
2108 .get_et_sset_count = ath9k_get_et_sset_count, 2447 .get_et_sset_count = ath9k_get_et_sset_count,
2109 .get_et_stats = ath9k_get_et_stats, 2448 .get_et_stats = ath9k_get_et_stats,