-+static bool ath9k_has_tx_pending(struct ath_softc *sc)
-+{
-+ int i, npend;
-+
-+ for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-+ if (!ATH_TXQ_SETUP(sc, i))
-+ continue;
-+
-+ if (!sc->tx.txq[i].axq_depth)
-+ continue;
-+
-+ npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
-+ if (npend)
-+ break;
-+ }
-+
-+ return !!npend;
-+}
-+
- static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop)
- {
- struct ath_softc *sc = hw->priv;
- struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
-- int timeout = 200; /* ms */
-- int i, j;
-+ int timeout = HZ / 5; /* 200 ms */
- bool drain_txq;
-
- mutex_lock(&sc->mutex);
-@@ -1841,25 +1881,9 @@ static void ath9k_flush(struct ieee80211
- return;
- }
-
-- for (j = 0; j < timeout; j++) {
-- bool npend = false;
--
-- if (j)
-- usleep_range(1000, 2000);
--
-- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
-- if (!ATH_TXQ_SETUP(sc, i))
-- continue;
--
-- npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
--
-- if (npend)
-- break;
-- }
--
-- if (!npend)
-- break;
-- }
-+ if (wait_event_timeout(sc->tx_wait, !ath9k_has_tx_pending(sc),
-+ timeout) > 0)
-+ drop = false;
-
- if (drop) {
- ath9k_ps_wakeup(sc);
-@@ -2021,333 +2045,6 @@ static int ath9k_get_antenna(struct ieee
- return 0;
- }
-
--#ifdef CONFIG_PM_SLEEP
--
--static void ath9k_wow_map_triggers(struct ath_softc *sc,
-- struct cfg80211_wowlan *wowlan,
-- u32 *wow_triggers)
--{
-- if (wowlan->disconnect)
-- *wow_triggers |= AH_WOW_LINK_CHANGE |
-- AH_WOW_BEACON_MISS;
-- if (wowlan->magic_pkt)
-- *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
--
-- if (wowlan->n_patterns)
-- *wow_triggers |= AH_WOW_USER_PATTERN_EN;
--
-- sc->wow_enabled = *wow_triggers;
--
--}
--
--static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
--{
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
-- int pattern_count = 0;
-- int i, byte_cnt;
-- u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
-- u8 dis_deauth_mask[MAX_PATTERN_SIZE];
--
-- memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
-- memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
--
-- /*
-- * Create Dissassociate / Deauthenticate packet filter
-- *
-- * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
-- * +--------------+----------+---------+--------+--------+----
-- * + Frame Control+ Duration + DA + SA + BSSID +
-- * +--------------+----------+---------+--------+--------+----
-- *
-- * The above is the management frame format for disassociate/
-- * deauthenticate pattern, from this we need to match the first byte
-- * of 'Frame Control' and DA, SA, and BSSID fields
-- * (skipping 2nd byte of FC and Duration feild.
-- *
-- * Disassociate pattern
-- * --------------------
-- * Frame control = 00 00 1010
-- * DA, SA, BSSID = x:x:x:x:x:x
-- * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-- * | x:x:x:x:x:x -- 22 bytes
-- *
-- * Deauthenticate pattern
-- * ----------------------
-- * Frame control = 00 00 1100
-- * DA, SA, BSSID = x:x:x:x:x:x
-- * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-- * | x:x:x:x:x:x -- 22 bytes
-- */
--
-- /* Create Disassociate Pattern first */
--
-- byte_cnt = 0;
--
-- /* Fill out the mask with all FF's */
--
-- for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
-- dis_deauth_mask[i] = 0xff;
--
-- /* copy the first byte of frame control field */
-- dis_deauth_pattern[byte_cnt] = 0xa0;
-- byte_cnt++;
--
-- /* skip 2nd byte of frame control and Duration field */
-- byte_cnt += 3;
--
-- /*
-- * need not match the destination mac address, it can be a broadcast
-- * mac address or an unicast to this station
-- */
-- byte_cnt += 6;
--
-- /* copy the source mac address */
-- memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
--
-- byte_cnt += 6;
--
-- /* copy the bssid, its same as the source mac address */
--
-- memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
--
-- /* Create Disassociate pattern mask */
--
-- dis_deauth_mask[0] = 0xfe;
-- dis_deauth_mask[1] = 0x03;
-- dis_deauth_mask[2] = 0xc0;
--
-- ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
--
-- ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-- pattern_count, byte_cnt);
--
-- pattern_count++;
-- /*
-- * for de-authenticate pattern, only the first byte of the frame
-- * control field gets changed from 0xA0 to 0xC0
-- */
-- dis_deauth_pattern[0] = 0xC0;
--
-- ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-- pattern_count, byte_cnt);
--
--}
--
--static void ath9k_wow_add_pattern(struct ath_softc *sc,
-- struct cfg80211_wowlan *wowlan)
--{
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath9k_wow_pattern *wow_pattern = NULL;
-- struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
-- int mask_len;
-- s8 i = 0;
--
-- if (!wowlan->n_patterns)
-- return;
--
-- /*
-- * Add the new user configured patterns
-- */
-- for (i = 0; i < wowlan->n_patterns; i++) {
--
-- wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
--
-- if (!wow_pattern)
-- return;
--
-- /*
-- * TODO: convert the generic user space pattern to
-- * appropriate chip specific/802.11 pattern.
-- */
--
-- mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
-- memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
-- memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
-- memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
-- patterns[i].pattern_len);
-- memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
-- wow_pattern->pattern_len = patterns[i].pattern_len;
--
-- /*
-- * just need to take care of deauth and disssoc pattern,
-- * make sure we don't overwrite them.
-- */
--
-- ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
-- wow_pattern->mask_bytes,
-- i + 2,
-- wow_pattern->pattern_len);
-- kfree(wow_pattern);
--
-- }
--
--}
--
--static int ath9k_suspend(struct ieee80211_hw *hw,
-- struct cfg80211_wowlan *wowlan)
--{
-- struct ath_softc *sc = hw->priv;
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
-- u32 wow_triggers_enabled = 0;
-- int ret = 0;
--
-- mutex_lock(&sc->mutex);
--
-- ath_cancel_work(sc);
-- ath_stop_ani(sc);
-- del_timer_sync(&sc->rx_poll_timer);
--
-- if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
-- ath_dbg(common, ANY, "Device not present\n");
-- ret = -EINVAL;
-- goto fail_wow;
-- }
--
-- if (WARN_ON(!wowlan)) {
-- ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
-- ret = -EINVAL;
-- goto fail_wow;
-- }
--
-- if (!device_can_wakeup(sc->dev)) {
-- ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
-- ret = 1;
-- goto fail_wow;
-- }
--
-- /*
-- * none of the sta vifs are associated
-- * and we are not currently handling multivif
-- * cases, for instance we have to seperately
-- * configure 'keep alive frame' for each
-- * STA.
-- */
--
-- if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
-- ath_dbg(common, WOW, "None of the STA vifs are associated\n");
-- ret = 1;
-- goto fail_wow;
-- }
--
-- if (sc->nvifs > 1) {
-- ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
-- ret = 1;
-- goto fail_wow;
-- }
--
-- ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
--
-- ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
-- wow_triggers_enabled);
--
-- ath9k_ps_wakeup(sc);
--
-- ath9k_stop_btcoex(sc);
--
-- /*
-- * Enable wake up on recieving disassoc/deauth
-- * frame by default.
-- */
-- ath9k_wow_add_disassoc_deauth_pattern(sc);
--
-- if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
-- ath9k_wow_add_pattern(sc, wowlan);
--
-- spin_lock_bh(&sc->sc_pcu_lock);
-- /*
-- * To avoid false wake, we enable beacon miss interrupt only
-- * when we go to sleep. We save the current interrupt mask
-- * so we can restore it after the system wakes up
-- */
-- sc->wow_intr_before_sleep = ah->imask;
-- ah->imask &= ~ATH9K_INT_GLOBAL;
-- ath9k_hw_disable_interrupts(ah);
-- ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
-- ath9k_hw_set_interrupts(ah);
-- ath9k_hw_enable_interrupts(ah);
--
-- spin_unlock_bh(&sc->sc_pcu_lock);
--
-- /*
-- * we can now sync irq and kill any running tasklets, since we already
-- * disabled interrupts and not holding a spin lock
-- */
-- synchronize_irq(sc->irq);
-- tasklet_kill(&sc->intr_tq);
--
-- ath9k_hw_wow_enable(ah, wow_triggers_enabled);
--
-- ath9k_ps_restore(sc);
-- ath_dbg(common, ANY, "WoW enabled in ath9k\n");
-- atomic_inc(&sc->wow_sleep_proc_intr);
--
--fail_wow:
-- mutex_unlock(&sc->mutex);
-- return ret;
--}
--
--static int ath9k_resume(struct ieee80211_hw *hw)
--{
-- struct ath_softc *sc = hw->priv;
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
-- u32 wow_status;
--
-- mutex_lock(&sc->mutex);
--
-- ath9k_ps_wakeup(sc);
--
-- spin_lock_bh(&sc->sc_pcu_lock);
--
-- ath9k_hw_disable_interrupts(ah);
-- ah->imask = sc->wow_intr_before_sleep;
-- ath9k_hw_set_interrupts(ah);
-- ath9k_hw_enable_interrupts(ah);
--
-- spin_unlock_bh(&sc->sc_pcu_lock);
--
-- wow_status = ath9k_hw_wow_wakeup(ah);
--
-- if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
-- /*
-- * some devices may not pick beacon miss
-- * as the reason they woke up so we add
-- * that here for that shortcoming.
-- */
-- wow_status |= AH_WOW_BEACON_MISS;
-- atomic_dec(&sc->wow_got_bmiss_intr);
-- ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
-- }
--
-- atomic_dec(&sc->wow_sleep_proc_intr);
--
-- if (wow_status) {
-- ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
-- ath9k_hw_wow_event_to_string(wow_status), wow_status);
-- }
--
-- ath_restart_work(sc);
-- ath9k_start_btcoex(sc);
--
-- ath9k_ps_restore(sc);
-- mutex_unlock(&sc->mutex);
--
-- return 0;
--}
--
--static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
--{
-- struct ath_softc *sc = hw->priv;
--
-- mutex_lock(&sc->mutex);
-- device_init_wakeup(sc->dev, 1);
-- device_set_wakeup_enable(sc->dev, enabled);
-- mutex_unlock(&sc->mutex);
--}
--
--#endif
- static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
- {
- struct ath_softc *sc = hw->priv;
-@@ -2373,134 +2070,6 @@ static void ath9k_channel_switch_beacon(
- sc->csa_vif = vif;
- }
-
--static void ath9k_tx99_stop(struct ath_softc *sc)
--{
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
--
-- ath_drain_all_txq(sc);
-- ath_startrecv(sc);
--
-- ath9k_hw_set_interrupts(ah);
-- ath9k_hw_enable_interrupts(ah);
--
-- ieee80211_wake_queues(sc->hw);
--
-- kfree_skb(sc->tx99_skb);
-- sc->tx99_skb = NULL;
-- sc->tx99_state = false;
--
-- ath9k_hw_tx99_stop(sc->sc_ah);
-- ath_dbg(common, XMIT, "TX99 stopped\n");
--}
--
--static struct sk_buff *ath9k_build_tx99_skb(struct ath_softc *sc)
--{
-- static u8 PN9Data[] = {0xff, 0x87, 0xb8, 0x59, 0xb7, 0xa1, 0xcc, 0x24,
-- 0x57, 0x5e, 0x4b, 0x9c, 0x0e, 0xe9, 0xea, 0x50,
-- 0x2a, 0xbe, 0xb4, 0x1b, 0xb6, 0xb0, 0x5d, 0xf1,
-- 0xe6, 0x9a, 0xe3, 0x45, 0xfd, 0x2c, 0x53, 0x18,
-- 0x0c, 0xca, 0xc9, 0xfb, 0x49, 0x37, 0xe5, 0xa8,
-- 0x51, 0x3b, 0x2f, 0x61, 0xaa, 0x72, 0x18, 0x84,
-- 0x02, 0x23, 0x23, 0xab, 0x63, 0x89, 0x51, 0xb3,
-- 0xe7, 0x8b, 0x72, 0x90, 0x4c, 0xe8, 0xfb, 0xc0};
-- u32 len = 1200;
-- struct ieee80211_hw *hw = sc->hw;
-- struct ieee80211_hdr *hdr;
-- struct ieee80211_tx_info *tx_info;
-- struct sk_buff *skb;
--
-- skb = alloc_skb(len, GFP_KERNEL);
-- if (!skb)
-- return NULL;
--
-- skb_put(skb, len);
--
-- memset(skb->data, 0, len);
--
-- hdr = (struct ieee80211_hdr *)skb->data;
-- hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA);
-- hdr->duration_id = 0;
--
-- memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
-- memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
-- memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
--
-- hdr->seq_ctrl |= cpu_to_le16(sc->tx.seq_no);
--
-- tx_info = IEEE80211_SKB_CB(skb);
-- memset(tx_info, 0, sizeof(*tx_info));
-- tx_info->band = hw->conf.chandef.chan->band;
-- tx_info->flags = IEEE80211_TX_CTL_NO_ACK;
-- tx_info->control.vif = sc->tx99_vif;
--
-- memcpy(skb->data + sizeof(*hdr), PN9Data, sizeof(PN9Data));
--
-- return skb;
--}
--
--void ath9k_tx99_deinit(struct ath_softc *sc)
--{
-- ath_reset(sc);
--
-- ath9k_ps_wakeup(sc);
-- ath9k_tx99_stop(sc);
-- ath9k_ps_restore(sc);
--}
--
--int ath9k_tx99_init(struct ath_softc *sc)
--{
-- struct ieee80211_hw *hw = sc->hw;
-- struct ath_hw *ah = sc->sc_ah;
-- struct ath_common *common = ath9k_hw_common(ah);
-- struct ath_tx_control txctl;
-- int r;
--
-- if (sc->sc_flags & SC_OP_INVALID) {
-- ath_err(common,
-- "driver is in invalid state unable to use TX99");
-- return -EINVAL;
-- }
--
-- sc->tx99_skb = ath9k_build_tx99_skb(sc);
-- if (!sc->tx99_skb)
-- return -ENOMEM;
--
-- memset(&txctl, 0, sizeof(txctl));
-- txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
--
-- ath_reset(sc);
--
-- ath9k_ps_wakeup(sc);
--
-- ath9k_hw_disable_interrupts(ah);
-- atomic_set(&ah->intr_ref_cnt, -1);
-- ath_drain_all_txq(sc);
-- ath_stoprecv(sc);
--
-- sc->tx99_state = true;
--
-- ieee80211_stop_queues(hw);
--
-- if (sc->tx99_power == MAX_RATE_POWER + 1)
-- sc->tx99_power = MAX_RATE_POWER;
--
-- ath9k_hw_tx99_set_txpower(ah, sc->tx99_power);
-- r = ath9k_tx99_send(sc, sc->tx99_skb, &txctl);
-- if (r) {
-- ath_dbg(common, XMIT, "Failed to xmit TX99 skb\n");
-- return r;
-- }
--
-- ath_dbg(common, XMIT, "TX99 xmit started using %d ( %ddBm)\n",
-- sc->tx99_power,
-- sc->tx99_power / 2);
--
-- /* We leave the harware awake as it will be chugging on */
--
-- return 0;
--}
--
- struct ieee80211_ops ath9k_ops = {
- .tx = ath9k_tx,
- .start = ath9k_start,
-@@ -2531,7 +2100,7 @@ struct ieee80211_ops ath9k_ops = {
- .set_antenna = ath9k_set_antenna,
- .get_antenna = ath9k_get_antenna,
-
--#ifdef CONFIG_PM_SLEEP
-+#ifdef CONFIG_ATH9K_WOW
- .suspend = ath9k_suspend,
- .resume = ath9k_resume,
- .set_wakeup = ath9k_set_wakeup,
---- a/drivers/net/wireless/ath/ath9k/wow.c
-+++ b/drivers/net/wireless/ath/ath9k/wow.c
-@@ -1,5 +1,5 @@
- /*
-- * Copyright (c) 2012 Qualcomm Atheros, Inc.
-+ * Copyright (c) 2013 Qualcomm Atheros, Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
-@@ -14,409 +14,348 @@
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
--#include <linux/export.h>
- #include "ath9k.h"
--#include "reg.h"
--#include "hw-ops.h"
-
--const char *ath9k_hw_wow_event_to_string(u32 wow_event)
-+static const struct wiphy_wowlan_support ath9k_wowlan_support = {
-+ .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
-+ .n_patterns = MAX_NUM_USER_PATTERN,
-+ .pattern_min_len = 1,
-+ .pattern_max_len = MAX_PATTERN_SIZE,
-+};
-+
-+static void ath9k_wow_map_triggers(struct ath_softc *sc,
-+ struct cfg80211_wowlan *wowlan,
-+ u32 *wow_triggers)
- {
-- if (wow_event & AH_WOW_MAGIC_PATTERN_EN)
-- return "Magic pattern";
-- if (wow_event & AH_WOW_USER_PATTERN_EN)
-- return "User pattern";
-- if (wow_event & AH_WOW_LINK_CHANGE)
-- return "Link change";
-- if (wow_event & AH_WOW_BEACON_MISS)
-- return "Beacon miss";
-+ if (wowlan->disconnect)
-+ *wow_triggers |= AH_WOW_LINK_CHANGE |
-+ AH_WOW_BEACON_MISS;
-+ if (wowlan->magic_pkt)
-+ *wow_triggers |= AH_WOW_MAGIC_PATTERN_EN;
-+
-+ if (wowlan->n_patterns)
-+ *wow_triggers |= AH_WOW_USER_PATTERN_EN;
-+
-+ sc->wow_enabled = *wow_triggers;
-
-- return "unknown reason";
- }
--EXPORT_SYMBOL(ath9k_hw_wow_event_to_string);
-
--static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah)
-+static void ath9k_wow_add_disassoc_deauth_pattern(struct ath_softc *sc)
- {
-+ struct ath_hw *ah = sc->sc_ah;
- struct ath_common *common = ath9k_hw_common(ah);
-+ int pattern_count = 0;
-+ int i, byte_cnt;
-+ u8 dis_deauth_pattern[MAX_PATTERN_SIZE];
-+ u8 dis_deauth_mask[MAX_PATTERN_SIZE];
-
-- REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
-+ memset(dis_deauth_pattern, 0, MAX_PATTERN_SIZE);
-+ memset(dis_deauth_mask, 0, MAX_PATTERN_SIZE);
-
-- /* set rx disable bit */
-- REG_WRITE(ah, AR_CR, AR_CR_RXD);
-+ /*
-+ * Create Dissassociate / Deauthenticate packet filter
-+ *
-+ * 2 bytes 2 byte 6 bytes 6 bytes 6 bytes
-+ * +--------------+----------+---------+--------+--------+----
-+ * + Frame Control+ Duration + DA + SA + BSSID +
-+ * +--------------+----------+---------+--------+--------+----
-+ *
-+ * The above is the management frame format for disassociate/
-+ * deauthenticate pattern, from this we need to match the first byte
-+ * of 'Frame Control' and DA, SA, and BSSID fields
-+ * (skipping 2nd byte of FC and Duration feild.
-+ *
-+ * Disassociate pattern
-+ * --------------------
-+ * Frame control = 00 00 1010
-+ * DA, SA, BSSID = x:x:x:x:x:x
-+ * Pattern will be A0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-+ * | x:x:x:x:x:x -- 22 bytes
-+ *
-+ * Deauthenticate pattern
-+ * ----------------------
-+ * Frame control = 00 00 1100
-+ * DA, SA, BSSID = x:x:x:x:x:x
-+ * Pattern will be C0000000 | x:x:x:x:x:x | x:x:x:x:x:x
-+ * | x:x:x:x:x:x -- 22 bytes
-+ */
-
-- if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0, AH_WAIT_TIMEOUT)) {
-- ath_err(common, "Failed to stop Rx DMA in 10ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
-- REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
-- return;
-- }
-+ /* Create Disassociate Pattern first */
-
-- REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT);
--}
-+ byte_cnt = 0;
-
--static void ath9k_wow_create_keep_alive_pattern(struct ath_hw *ah)
--{
-- struct ath_common *common = ath9k_hw_common(ah);
-- u8 sta_mac_addr[ETH_ALEN], ap_mac_addr[ETH_ALEN];
-- u32 ctl[13] = {0};
-- u32 data_word[KAL_NUM_DATA_WORDS];
-- u8 i;
-- u32 wow_ka_data_word0;
--
-- memcpy(sta_mac_addr, common->macaddr, ETH_ALEN);
-- memcpy(ap_mac_addr, common->curbssid, ETH_ALEN);
--
-- /* set the transmit buffer */
-- ctl[0] = (KAL_FRAME_LEN | (MAX_RATE_POWER << 16));
-- ctl[1] = 0;
-- ctl[3] = 0xb; /* OFDM_6M hardware value for this rate */
-- ctl[4] = 0;
-- ctl[7] = (ah->txchainmask) << 2;
-- ctl[2] = 0xf << 16; /* tx_tries 0 */
--
-- for (i = 0; i < KAL_NUM_DESC_WORDS; i++)
-- REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
--
-- REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + i * 4), ctl[i]);
--
-- data_word[0] = (KAL_FRAME_TYPE << 2) | (KAL_FRAME_SUB_TYPE << 4) |
-- (KAL_TO_DS << 8) | (KAL_DURATION_ID << 16);
-- data_word[1] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
-- (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
-- data_word[2] = (sta_mac_addr[1] << 24) | (sta_mac_addr[0] << 16) |
-- (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
-- data_word[3] = (sta_mac_addr[5] << 24) | (sta_mac_addr[4] << 16) |
-- (sta_mac_addr[3] << 8) | (sta_mac_addr[2]);
-- data_word[4] = (ap_mac_addr[3] << 24) | (ap_mac_addr[2] << 16) |
-- (ap_mac_addr[1] << 8) | (ap_mac_addr[0]);
-- data_word[5] = (ap_mac_addr[5] << 8) | (ap_mac_addr[4]);
--
-- if (AR_SREV_9462_20(ah)) {
-- /* AR9462 2.0 has an extra descriptor word (time based
-- * discard) compared to other chips */
-- REG_WRITE(ah, (AR_WOW_KA_DESC_WORD2 + (12 * 4)), 0);
-- wow_ka_data_word0 = AR_WOW_TXBUF(13);
-- } else {
-- wow_ka_data_word0 = AR_WOW_TXBUF(12);
-- }
-+ /* Fill out the mask with all FF's */
-
-- for (i = 0; i < KAL_NUM_DATA_WORDS; i++)
-- REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]);
-+ for (i = 0; i < MAX_PATTERN_MASK_SIZE; i++)
-+ dis_deauth_mask[i] = 0xff;
-
--}
-+ /* copy the first byte of frame control field */
-+ dis_deauth_pattern[byte_cnt] = 0xa0;
-+ byte_cnt++;
-
--void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern,
-- u8 *user_mask, int pattern_count,
-- int pattern_len)
--{
-- int i;
-- u32 pattern_val, mask_val;
-- u32 set, clr;
-+ /* skip 2nd byte of frame control and Duration field */
-+ byte_cnt += 3;
-
-- /* FIXME: should check count by querying the hardware capability */
-- if (pattern_count >= MAX_NUM_PATTERN)
-- return;
-+ /*
-+ * need not match the destination mac address, it can be a broadcast
-+ * mac address or an unicast to this station
-+ */
-+ byte_cnt += 6;
-
-- REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count));
-+ /* copy the source mac address */
-+ memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
-
-- /* set the registers for pattern */
-- for (i = 0; i < MAX_PATTERN_SIZE; i += 4) {
-- memcpy(&pattern_val, user_pattern, 4);
-- REG_WRITE(ah, (AR_WOW_TB_PATTERN(pattern_count) + i),
-- pattern_val);
-- user_pattern += 4;
-- }
-+ byte_cnt += 6;
-
-- /* set the registers for mask */
-- for (i = 0; i < MAX_PATTERN_MASK_SIZE; i += 4) {
-- memcpy(&mask_val, user_mask, 4);
-- REG_WRITE(ah, (AR_WOW_TB_MASK(pattern_count) + i), mask_val);
-- user_mask += 4;
-- }
-+ /* copy the bssid, its same as the source mac address */
-
-- /* set the pattern length to be matched
-- *
-- * AR_WOW_LENGTH1_REG1
-- * bit 31:24 pattern 0 length
-- * bit 23:16 pattern 1 length
-- * bit 15:8 pattern 2 length
-- * bit 7:0 pattern 3 length
-- *
-- * AR_WOW_LENGTH1_REG2
-- * bit 31:24 pattern 4 length
-- * bit 23:16 pattern 5 length
-- * bit 15:8 pattern 6 length
-- * bit 7:0 pattern 7 length
-- *
-- * the below logic writes out the new
-- * pattern length for the corresponding
-- * pattern_count, while masking out the
-- * other fields
-- */
-+ memcpy((dis_deauth_pattern + byte_cnt), common->curbssid, ETH_ALEN);
-
-- ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT);
-+ /* Create Disassociate pattern mask */
-
-- if (pattern_count < 4) {
-- /* Pattern 0-3 uses AR_WOW_LENGTH1 register */
-- set = (pattern_len & AR_WOW_LENGTH_MAX) <<
-- AR_WOW_LEN1_SHIFT(pattern_count);
-- clr = AR_WOW_LENGTH1_MASK(pattern_count);
-- REG_RMW(ah, AR_WOW_LENGTH1, set, clr);
-- } else {
-- /* Pattern 4-7 uses AR_WOW_LENGTH2 register */
-- set = (pattern_len & AR_WOW_LENGTH_MAX) <<
-- AR_WOW_LEN2_SHIFT(pattern_count);
-- clr = AR_WOW_LENGTH2_MASK(pattern_count);
-- REG_RMW(ah, AR_WOW_LENGTH2, set, clr);
-- }
-+ dis_deauth_mask[0] = 0xfe;
-+ dis_deauth_mask[1] = 0x03;
-+ dis_deauth_mask[2] = 0xc0;
-
--}
--EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern);
-+ ath_dbg(common, WOW, "Adding disassoc/deauth patterns for WoW\n");
-
--u32 ath9k_hw_wow_wakeup(struct ath_hw *ah)
--{
-- u32 wow_status = 0;
-- u32 val = 0, rval;
-+ ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-+ pattern_count, byte_cnt);
-
-+ pattern_count++;
- /*
-- * read the WoW status register to know
-- * the wakeup reason
-+ * for de-authenticate pattern, only the first byte of the frame
-+ * control field gets changed from 0xA0 to 0xC0
- */
-- rval = REG_READ(ah, AR_WOW_PATTERN);
-- val = AR_WOW_STATUS(rval);
-+ dis_deauth_pattern[0] = 0xC0;
-
-- /*
-- * mask only the WoW events that we have enabled. Sometimes
-- * we have spurious WoW events from the AR_WOW_PATTERN
-- * register. This mask will clean it up.
-- */
-+ ath9k_hw_wow_apply_pattern(ah, dis_deauth_pattern, dis_deauth_mask,
-+ pattern_count, byte_cnt);
-
-- val &= ah->wow_event_mask;
-+}
-
-- if (val) {
-- if (val & AR_WOW_MAGIC_PAT_FOUND)
-- wow_status |= AH_WOW_MAGIC_PATTERN_EN;
-- if (AR_WOW_PATTERN_FOUND(val))
-- wow_status |= AH_WOW_USER_PATTERN_EN;
-- if (val & AR_WOW_KEEP_ALIVE_FAIL)
-- wow_status |= AH_WOW_LINK_CHANGE;
-- if (val & AR_WOW_BEACON_FAIL)
-- wow_status |= AH_WOW_BEACON_MISS;
-- }
-+static void ath9k_wow_add_pattern(struct ath_softc *sc,
-+ struct cfg80211_wowlan *wowlan)
-+{
-+ struct ath_hw *ah = sc->sc_ah;
-+ struct ath9k_wow_pattern *wow_pattern = NULL;
-+ struct cfg80211_pkt_pattern *patterns = wowlan->patterns;
-+ int mask_len;
-+ s8 i = 0;
-+
-+ if (!wowlan->n_patterns)
-+ return;
-
- /*
-- * set and clear WOW_PME_CLEAR registers for the chip to
-- * generate next wow signal.
-- * disable D3 before accessing other registers ?
-+ * Add the new user configured patterns
- */
-+ for (i = 0; i < wowlan->n_patterns; i++) {
-
-- /* do we need to check the bit value 0x01000000 (7-10) ?? */
-- REG_RMW(ah, AR_PCIE_PM_CTRL, AR_PMCTRL_WOW_PME_CLR,
-- AR_PMCTRL_PWR_STATE_D1D3);
-+ wow_pattern = kzalloc(sizeof(*wow_pattern), GFP_KERNEL);
-
-- /*
-- * clear all events
-- */
-- REG_WRITE(ah, AR_WOW_PATTERN,
-- AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN)));
-+ if (!wow_pattern)
-+ return;
-
-- /*
-- * restore the beacon threshold to init value
-- */
-- REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
-+ /*
-+ * TODO: convert the generic user space pattern to
-+ * appropriate chip specific/802.11 pattern.
-+ */
-
-- /*
-- * Restore the way the PCI-E reset, Power-On-Reset, external
-- * PCIE_POR_SHORT pins are tied to its original value.
-- * Previously just before WoW sleep, we untie the PCI-E
-- * reset to our Chip's Power On Reset so that any PCI-E
-- * reset from the bus will not reset our chip
-- */
-- if (ah->is_pciexpress)
-- ath9k_hw_configpcipowersave(ah, false);
-+ mask_len = DIV_ROUND_UP(wowlan->patterns[i].pattern_len, 8);
-+ memset(wow_pattern->pattern_bytes, 0, MAX_PATTERN_SIZE);
-+ memset(wow_pattern->mask_bytes, 0, MAX_PATTERN_SIZE);
-+ memcpy(wow_pattern->pattern_bytes, patterns[i].pattern,
-+ patterns[i].pattern_len);
-+ memcpy(wow_pattern->mask_bytes, patterns[i].mask, mask_len);
-+ wow_pattern->pattern_len = patterns[i].pattern_len;
-+
-+ /*
-+ * just need to take care of deauth and disssoc pattern,
-+ * make sure we don't overwrite them.
-+ */
-+
-+ ath9k_hw_wow_apply_pattern(ah, wow_pattern->pattern_bytes,
-+ wow_pattern->mask_bytes,
-+ i + 2,
-+ wow_pattern->pattern_len);
-+ kfree(wow_pattern);
-
-- ah->wow_event_mask = 0;
-+ }
-
-- return wow_status;
- }
--EXPORT_SYMBOL(ath9k_hw_wow_wakeup);
-
--void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable)
-+int ath9k_suspend(struct ieee80211_hw *hw,
-+ struct cfg80211_wowlan *wowlan)
- {
-- u32 wow_event_mask;
-- u32 set, clr;
-+ struct ath_softc *sc = hw->priv;
-+ struct ath_hw *ah = sc->sc_ah;
-+ struct ath_common *common = ath9k_hw_common(ah);
-+ u32 wow_triggers_enabled = 0;
-+ int ret = 0;
-
-- /*
-- * wow_event_mask is a mask to the AR_WOW_PATTERN register to
-- * indicate which WoW events we have enabled. The WoW events
-- * are from the 'pattern_enable' in this function and
-- * 'pattern_count' of ath9k_hw_wow_apply_pattern()
-- */
-- wow_event_mask = ah->wow_event_mask;
-+ mutex_lock(&sc->mutex);
-
-- /*
-- * Untie Power-on-Reset from the PCI-E-Reset. When we are in
-- * WOW sleep, we do want the Reset from the PCI-E to disturb
-- * our hw state
-- */
-- if (ah->is_pciexpress) {
-- /*
-- * we need to untie the internal POR (power-on-reset)
-- * to the external PCI-E reset. We also need to tie
-- * the PCI-E Phy reset to the PCI-E reset.
-- */
-- set = AR_WA_RESET_EN | AR_WA_POR_SHORT;
-- clr = AR_WA_UNTIE_RESET_EN | AR_WA_D3_L1_DISABLE;
-- REG_RMW(ah, AR_WA, set, clr);
-+ ath_cancel_work(sc);
-+ ath_stop_ani(sc);
-+ del_timer_sync(&sc->rx_poll_timer);
-+
-+ if (test_bit(SC_OP_INVALID, &sc->sc_flags)) {
-+ ath_dbg(common, ANY, "Device not present\n");
-+ ret = -EINVAL;
-+ goto fail_wow;
- }
-
-- /*
-- * set the power states appropriately and enable PME
-- */
-- set = AR_PMCTRL_HOST_PME_EN | AR_PMCTRL_PWR_PM_CTRL_ENA |
-- AR_PMCTRL_AUX_PWR_DET | AR_PMCTRL_WOW_PME_CLR;
-+ if (WARN_ON(!wowlan)) {
-+ ath_dbg(common, WOW, "None of the WoW triggers enabled\n");
-+ ret = -EINVAL;
-+ goto fail_wow;
-+ }
-
-- /*
-- * set and clear WOW_PME_CLEAR registers for the chip
-- * to generate next wow signal.
-- */
-- REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
-- clr = AR_PMCTRL_WOW_PME_CLR;
-- REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-+ if (!device_can_wakeup(sc->dev)) {
-+ ath_dbg(common, WOW, "device_can_wakeup failed, WoW is not enabled\n");
-+ ret = 1;
-+ goto fail_wow;
-+ }
-
- /*
-- * Setup for:
-- * - beacon misses
-- * - magic pattern
-- * - keep alive timeout
-- * - pattern matching
-+ * none of the sta vifs are associated
-+ * and we are not currently handling multivif
-+ * cases, for instance we have to seperately
-+ * configure 'keep alive frame' for each
-+ * STA.
- */
-
-- /*
-- * Program default values for pattern backoff, aifs/slot/KAL count,
-- * beacon miss timeout, KAL timeout, etc.
-- */
-- set = AR_WOW_BACK_OFF_SHIFT(AR_WOW_PAT_BACKOFF);
-- REG_SET_BIT(ah, AR_WOW_PATTERN, set);
-+ if (!test_bit(SC_OP_PRIM_STA_VIF, &sc->sc_flags)) {
-+ ath_dbg(common, WOW, "None of the STA vifs are associated\n");
-+ ret = 1;
-+ goto fail_wow;
-+ }
-+
-+ if (sc->nvifs > 1) {
-+ ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
-+ ret = 1;
-+ goto fail_wow;
-+ }
-
-- set = AR_WOW_AIFS_CNT(AR_WOW_CNT_AIFS_CNT) |
-- AR_WOW_SLOT_CNT(AR_WOW_CNT_SLOT_CNT) |
-- AR_WOW_KEEP_ALIVE_CNT(AR_WOW_CNT_KA_CNT);
-- REG_SET_BIT(ah, AR_WOW_COUNT, set);
--
-- if (pattern_enable & AH_WOW_BEACON_MISS)
-- set = AR_WOW_BEACON_TIMO;
-- /* We are not using beacon miss, program a large value */
-- else
-- set = AR_WOW_BEACON_TIMO_MAX;
-+ ath9k_wow_map_triggers(sc, wowlan, &wow_triggers_enabled);
-
-- REG_WRITE(ah, AR_WOW_BCN_TIMO, set);
-+ ath_dbg(common, WOW, "WoW triggers enabled 0x%x\n",
-+ wow_triggers_enabled);
-
-- /*
-- * Keep alive timo in ms except AR9280
-- */
-- if (!pattern_enable)
-- set = AR_WOW_KEEP_ALIVE_NEVER;
-- else
-- set = KAL_TIMEOUT * 32;
-+ ath9k_ps_wakeup(sc);
-
-- REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set);
-+ ath9k_stop_btcoex(sc);
-
- /*
-- * Keep alive delay in us. based on 'power on clock',
-- * therefore in usec
-+ * Enable wake up on recieving disassoc/deauth
-+ * frame by default.
- */
-- set = KAL_DELAY * 1000;
-- REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set);
-+ ath9k_wow_add_disassoc_deauth_pattern(sc);
-
-- /*
-- * Create keep alive pattern to respond to beacons
-- */
-- ath9k_wow_create_keep_alive_pattern(ah);
-+ if (wow_triggers_enabled & AH_WOW_USER_PATTERN_EN)
-+ ath9k_wow_add_pattern(sc, wowlan);
-
-+ spin_lock_bh(&sc->sc_pcu_lock);
- /*
-- * Configure MAC WoW Registers
-+ * To avoid false wake, we enable beacon miss interrupt only
-+ * when we go to sleep. We save the current interrupt mask
-+ * so we can restore it after the system wakes up
- */
-- set = 0;
-- /* Send keep alive timeouts anyway */
-- clr = AR_WOW_KEEP_ALIVE_AUTO_DIS;
--
-- if (pattern_enable & AH_WOW_LINK_CHANGE)
-- wow_event_mask |= AR_WOW_KEEP_ALIVE_FAIL;
-- else
-- set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-+ sc->wow_intr_before_sleep = ah->imask;
-+ ah->imask &= ~ATH9K_INT_GLOBAL;
-+ ath9k_hw_disable_interrupts(ah);
-+ ah->imask = ATH9K_INT_BMISS | ATH9K_INT_GLOBAL;
-+ ath9k_hw_set_interrupts(ah);
-+ ath9k_hw_enable_interrupts(ah);
-
-- set = AR_WOW_KEEP_ALIVE_FAIL_DIS;
-- REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr);
-+ spin_unlock_bh(&sc->sc_pcu_lock);
-
- /*
-- * we are relying on a bmiss failure. ensure we have
-- * enough threshold to prevent false positives
-+ * we can now sync irq and kill any running tasklets, since we already
-+ * disabled interrupts and not holding a spin lock
- */
-- REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR,
-- AR_WOW_BMISSTHRESHOLD);
-+ synchronize_irq(sc->irq);
-+ tasklet_kill(&sc->intr_tq);
-+
-+ ath9k_hw_wow_enable(ah, wow_triggers_enabled);
-
-- set = 0;
-- clr = 0;
-+ ath9k_ps_restore(sc);
-+ ath_dbg(common, ANY, "WoW enabled in ath9k\n");
-+ atomic_inc(&sc->wow_sleep_proc_intr);
-
-- if (pattern_enable & AH_WOW_BEACON_MISS) {
-- set = AR_WOW_BEACON_FAIL_EN;
-- wow_event_mask |= AR_WOW_BEACON_FAIL;
-- } else {
-- clr = AR_WOW_BEACON_FAIL_EN;
-+fail_wow:
-+ mutex_unlock(&sc->mutex);
-+ return ret;
-+}
-+
-+int ath9k_resume(struct ieee80211_hw *hw)
-+{
-+ struct ath_softc *sc = hw->priv;
-+ struct ath_hw *ah = sc->sc_ah;
-+ struct ath_common *common = ath9k_hw_common(ah);
-+ u32 wow_status;
-+
-+ mutex_lock(&sc->mutex);
-+
-+ ath9k_ps_wakeup(sc);
-+
-+ spin_lock_bh(&sc->sc_pcu_lock);
-+
-+ ath9k_hw_disable_interrupts(ah);
-+ ah->imask = sc->wow_intr_before_sleep;
-+ ath9k_hw_set_interrupts(ah);
-+ ath9k_hw_enable_interrupts(ah);
-+
-+ spin_unlock_bh(&sc->sc_pcu_lock);
-+
-+ wow_status = ath9k_hw_wow_wakeup(ah);
-+
-+ if (atomic_read(&sc->wow_got_bmiss_intr) == 0) {
-+ /*
-+ * some devices may not pick beacon miss
-+ * as the reason they woke up so we add
-+ * that here for that shortcoming.
-+ */
-+ wow_status |= AH_WOW_BEACON_MISS;
-+ atomic_dec(&sc->wow_got_bmiss_intr);
-+ ath_dbg(common, ANY, "Beacon miss interrupt picked up during WoW sleep\n");
- }
-
-- REG_RMW(ah, AR_WOW_BCN_EN, set, clr);
-+ atomic_dec(&sc->wow_sleep_proc_intr);
-
-- set = 0;
-- clr = 0;
-- /*
-- * Enable the magic packet registers
-- */
-- if (pattern_enable & AH_WOW_MAGIC_PATTERN_EN) {
-- set = AR_WOW_MAGIC_EN;
-- wow_event_mask |= AR_WOW_MAGIC_PAT_FOUND;
-- } else {
-- clr = AR_WOW_MAGIC_EN;
-+ if (wow_status) {
-+ ath_dbg(common, ANY, "Waking up due to WoW triggers %s with WoW status = %x\n",
-+ ath9k_hw_wow_event_to_string(wow_status), wow_status);
- }
-- set |= AR_WOW_MAC_INTR_EN;
-- REG_RMW(ah, AR_WOW_PATTERN, set, clr);
-
-- REG_WRITE(ah, AR_WOW_PATTERN_MATCH_LT_256B,
-- AR_WOW_PATTERN_SUPPORTED);
-+ ath_restart_work(sc);
-+ ath9k_start_btcoex(sc);
-
-- /*
-- * Set the power states appropriately and enable PME
-- */
-- clr = 0;
-- set = AR_PMCTRL_PWR_STATE_D1D3 | AR_PMCTRL_HOST_PME_EN |
-- AR_PMCTRL_PWR_PM_CTRL_ENA;
-+ ath9k_ps_restore(sc);
-+ mutex_unlock(&sc->mutex);
-
-- clr = AR_PCIE_PM_CTRL_ENA;
-- REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr);
-+ return 0;
-+}
-
-- /*
-- * this is needed to prevent the chip waking up
-- * the host within 3-4 seconds with certain
-- * platform/BIOS. The fix is to enable
-- * D1 & D3 to match original definition and
-- * also match the OTP value. Anyway this
-- * is more related to SW WOW.
-- */
-- clr = AR_PMCTRL_PWR_STATE_D1D3;
-- REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, clr);
-+void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)
-+{
-+ struct ath_softc *sc = hw->priv;
-
-- set = AR_PMCTRL_PWR_STATE_D1D3_REAL;
-- REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set);
-+ mutex_lock(&sc->mutex);
-+ device_init_wakeup(sc->dev, 1);
-+ device_set_wakeup_enable(sc->dev, enabled);
-+ mutex_unlock(&sc->mutex);
-+}
-
-- REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM);
-+void ath9k_init_wow(struct ieee80211_hw *hw)
-+{
-+ struct ath_softc *sc = hw->priv;
-
-- /* to bring down WOW power low margin */
-- set = BIT(13);
-- REG_SET_BIT(ah, AR_PCIE_PHY_REG3, set);
-- /* HW WoW */
-- clr = BIT(5);
-- REG_CLR_BIT(ah, AR_PCU_MISC_MODE3, clr);
-+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
-+ (sc->driver_data & ATH9K_PCI_WOW) &&
-+ device_can_wakeup(sc->dev))
-+ hw->wiphy->wowlan = &ath9k_wowlan_support;
-
-- ath9k_hw_set_powermode_wow_sleep(ah);
-- ah->wow_event_mask = wow_event_mask;
-+ atomic_set(&sc->wow_sleep_proc_intr, -1);
-+ atomic_set(&sc->wow_got_bmiss_intr, -1);
- }
--EXPORT_SYMBOL(ath9k_hw_wow_enable);
---- a/drivers/net/wireless/ath/ath9k/xmit.c
-+++ b/drivers/net/wireless/ath/ath9k/xmit.c
-@@ -1786,6 +1786,9 @@ bool ath_drain_all_txq(struct ath_softc
- if (!ATH_TXQ_SETUP(sc, i))
- continue;
-
-+ if (!sc->tx.txq[i].axq_depth)
-+ continue;
-+
- if (ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum))
- npend |= BIT(i);
- }
-@@ -2749,6 +2752,8 @@ void ath_tx_node_cleanup(struct ath_soft
- }
- }
-
-+#ifdef CONFIG_ATH9K_TX99
-+
- int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb,
- struct ath_tx_control *txctl)
- {
-@@ -2791,3 +2796,5 @@ int ath9k_tx99_send(struct ath_softc *sc
-
- return 0;
- }
-+
-+#endif /* CONFIG_ATH9K_TX99 */
---- a/drivers/net/wireless/ath/regd.c
-+++ b/drivers/net/wireless/ath/regd.c
-@@ -37,17 +37,17 @@ static int __ath_regd_init(struct ath_re
-
- /* We enable active scan on these a case by case basis by regulatory domain */
- #define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
-- NL80211_RRF_PASSIVE_SCAN)
-+ NL80211_RRF_NO_IR)
- #define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\
-- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
-+ NL80211_RRF_NO_IR | NL80211_RRF_NO_OFDM)
-
- /* We allow IBSS on these on a case by case basis by regulatory domain */
- #define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
-- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-+ NL80211_RRF_NO_IR)
- #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
-- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-+ NL80211_RRF_NO_IR)
- #define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 80, 0, 30,\
-- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
-+ NL80211_RRF_NO_IR)
-
- #define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \
- ATH9K_2GHZ_CH12_13, \
-@@ -224,17 +224,16 @@ ath_reg_apply_beaconing_flags(struct wip
- * regulatory_hint().
- */
- if (!(reg_rule->flags &
-- NL80211_RRF_NO_IBSS))
-+ NL80211_RRF_NO_IR))
- ch->flags &=
-- ~IEEE80211_CHAN_NO_IBSS;
-+ ~IEEE80211_CHAN_NO_IR;
- if (!(reg_rule->flags &
-- NL80211_RRF_PASSIVE_SCAN))
-+ NL80211_RRF_NO_IR))
- ch->flags &=
-- ~IEEE80211_CHAN_PASSIVE_SCAN;
-+ ~IEEE80211_CHAN_NO_IR;
- } else {
- if (ch->beacon_found)
-- ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
-- IEEE80211_CHAN_PASSIVE_SCAN);
-+ ch->flags &= ~IEEE80211_CHAN_NO_IR;
- }
- }
- }
-@@ -260,11 +259,11 @@ ath_reg_apply_active_scan_flags(struct w
- */
- if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
- ch = &sband->channels[11]; /* CH 12 */
-- if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-- ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-+ if (ch->flags & IEEE80211_CHAN_NO_IR)
-+ ch->flags &= ~IEEE80211_CHAN_NO_IR;
- ch = &sband->channels[12]; /* CH 13 */
-- if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-- ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-+ if (ch->flags & IEEE80211_CHAN_NO_IR)
-+ ch->flags &= ~IEEE80211_CHAN_NO_IR;
- return;
- }
-
-@@ -278,17 +277,17 @@ ath_reg_apply_active_scan_flags(struct w
- ch = &sband->channels[11]; /* CH 12 */
- reg_rule = freq_reg_info(wiphy, ch->center_freq);
- if (!IS_ERR(reg_rule)) {
-- if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-- if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-- ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-+ if (!(reg_rule->flags & NL80211_RRF_NO_IR))
-+ if (ch->flags & IEEE80211_CHAN_NO_IR)
-+ ch->flags &= ~IEEE80211_CHAN_NO_IR;
- }
-
- ch = &sband->channels[12]; /* CH 13 */
- reg_rule = freq_reg_info(wiphy, ch->center_freq);
- if (!IS_ERR(reg_rule)) {
-- if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
-- if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
-- ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
-+ if (!(reg_rule->flags & NL80211_RRF_NO_IR))
-+ if (ch->flags & IEEE80211_CHAN_NO_IR)
-+ ch->flags &= ~IEEE80211_CHAN_NO_IR;
- }
- }
-
-@@ -320,8 +319,8 @@ static void ath_reg_apply_radar_flags(st
- */
- if (!(ch->flags & IEEE80211_CHAN_DISABLED))
- ch->flags |= IEEE80211_CHAN_RADAR |
-- IEEE80211_CHAN_NO_IBSS |
-- IEEE80211_CHAN_PASSIVE_SCAN;
-+ IEEE80211_CHAN_NO_IR |
-+ IEEE80211_CHAN_NO_IR;
- }
- }