X-Git-Url: https://git.archive.openwrt.org/?p=openwrt.git;a=blobdiff_plain;f=package%2Fkernel%2Fmac80211%2Fpatches%2F300-pending_work.patch;h=4532a03d570888ee912cd071bac793dc7d05cb3e;hp=bd21e534058318b641ca2bcf409b195b06b8f8cc;hb=aa9c777a930d139484e38588baa52c6737f6b9e3;hpb=4d953d3a481dd847524eae78c7aae00153bc7efd diff --git a/package/kernel/mac80211/patches/300-pending_work.patch b/package/kernel/mac80211/patches/300-pending_work.patch index bd21e53405..4532a03d57 100644 --- a/package/kernel/mac80211/patches/300-pending_work.patch +++ b/package/kernel/mac80211/patches/300-pending_work.patch @@ -1,313 +1,8326 @@ ---- a/net/mac80211/agg-rx.c -+++ b/net/mac80211/agg-rx.c -@@ -204,6 +204,8 @@ static void ieee80211_send_addba_resp(st - memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); - else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) - memcpy(mgmt->bssid, sdata->u.ibss.bssid, ETH_ALEN); -+ else if (sdata->vif.type == NL80211_IFTYPE_WDS) -+ memcpy(mgmt->bssid, da, ETH_ALEN); - - mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | - IEEE80211_STYPE_ACTION); ---- a/net/mac80211/agg-tx.c -+++ b/net/mac80211/agg-tx.c -@@ -81,7 +81,8 @@ static void ieee80211_send_addba_request - memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); - if (sdata->vif.type == NL80211_IFTYPE_AP || - sdata->vif.type == NL80211_IFTYPE_AP_VLAN || -- sdata->vif.type == NL80211_IFTYPE_MESH_POINT) -+ sdata->vif.type == NL80211_IFTYPE_MESH_POINT || -+ sdata->vif.type == NL80211_IFTYPE_WDS) - memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN); - else if (sdata->vif.type == NL80211_IFTYPE_STATION) - memcpy(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN); -@@ -527,6 +528,7 @@ int ieee80211_start_tx_ba_session(struct - sdata->vif.type != NL80211_IFTYPE_MESH_POINT && - sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_AP && -+ sdata->vif.type != NL80211_IFTYPE_WDS && - sdata->vif.type != NL80211_IFTYPE_ADHOC) - return -EINVAL; +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -1351,12 +1351,12 @@ static int ath10k_update_channel_list(st + ch->allow_vht = true; ---- a/net/mac80211/debugfs_sta.c -+++ b/net/mac80211/debugfs_sta.c -@@ -66,11 +66,11 @@ static ssize_t sta_flags_read(struct fil - test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : "" - - int res = scnprintf(buf, sizeof(buf), -- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", -+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - TEST(AUTH), TEST(ASSOC), TEST(PS_STA), - TEST(PS_DRIVER), TEST(AUTHORIZED), - TEST(SHORT_PREAMBLE), -- TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), -+ TEST(WME), TEST(CLEAR_PS_FILT), - TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), - TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), - TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), ---- a/net/mac80211/ht.c -+++ b/net/mac80211/ht.c -@@ -281,13 +281,14 @@ void ieee80211_ba_session_work(struct wo - sta, tid, WLAN_BACK_RECIPIENT, - WLAN_REASON_UNSPECIFIED, true); - -+ spin_lock_bh(&sta->lock); -+ - tid_tx = sta->ampdu_mlme.tid_start_tx[tid]; - if (tid_tx) { - /* - * Assign it over to the normal tid_tx array - * where it "goes live". - */ -- spin_lock_bh(&sta->lock); - - sta->ampdu_mlme.tid_start_tx[tid] = NULL; - /* could there be a race? */ -@@ -300,6 +301,7 @@ void ieee80211_ba_session_work(struct wo - ieee80211_tx_ba_session_handle_start(sta, tid); - continue; - } -+ spin_unlock_bh(&sta->lock); + ch->allow_ibss = +- !(channel->flags & IEEE80211_CHAN_NO_IBSS); ++ !(channel->flags & IEEE80211_CHAN_NO_IR); - tid_tx = rcu_dereference_protected_tid_tx(sta, tid); - if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -463,7 +463,6 @@ int ieee80211_do_open(struct wireless_de - struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); - struct net_device *dev = wdev->netdev; - struct ieee80211_local *local = sdata->local; -- struct sta_info *sta; - u32 changed = 0; - int res; - u32 hw_reconf_flags = 0; -@@ -629,30 +628,8 @@ int ieee80211_do_open(struct wireless_de + ch->ht40plus = + !(channel->flags & IEEE80211_CHAN_NO_HT40PLUS); - set_bit(SDATA_STATE_RUNNING, &sdata->state); +- passive = channel->flags & IEEE80211_CHAN_PASSIVE_SCAN; ++ passive = channel->flags & IEEE80211_CHAN_NO_IR; + ch->passive = passive; -- if (sdata->vif.type == NL80211_IFTYPE_WDS) { -- /* Create STA entry for the WDS peer */ -- sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, -- GFP_KERNEL); -- if (!sta) { -- res = -ENOMEM; -- goto err_del_interface; -- } + ch->freq = channel->center_freq; +--- a/drivers/net/wireless/ath/ath9k/Kconfig ++++ b/drivers/net/wireless/ath/ath9k/Kconfig +@@ -90,7 +90,7 @@ config ATH9K_DFS_CERTIFIED + + config ATH9K_TX99 + bool "Atheros ath9k TX99 testing support" +- depends on CFG80211_CERTIFICATION_ONUS ++ depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS + default n + ---help--- + Say N. This should only be enabled on systems undergoing +@@ -108,6 +108,14 @@ config ATH9K_TX99 + be evaluated to meet the RF exposure limits set forth in the + governmental SAR regulations. + ++config ATH9K_WOW ++ bool "Wake on Wireless LAN support (EXPERIMENTAL)" ++ depends on ATH9K && PM ++ default n ++ ---help--- ++ This option enables Wake on Wireless LAN support for certain cards. ++ Currently, AR9462 is supported. ++ + config ATH9K_LEGACY_RATE_CONTROL + bool "Atheros ath9k rate control" + depends on ATH9K +--- a/drivers/net/wireless/ath/ath9k/Makefile ++++ b/drivers/net/wireless/ath/ath9k/Makefile +@@ -13,9 +13,9 @@ ath9k-$(CPTCFG_ATH9K_PCI) += pci.o + ath9k-$(CPTCFG_ATH9K_AHB) += ahb.o + ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o + ath9k-$(CPTCFG_ATH9K_DFS_DEBUGFS) += dfs_debug.o +-ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += \ +- dfs.o +-ath9k-$(CONFIG_PM_SLEEP) += wow.o ++ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += dfs.o ++ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o ++ath9k-$(CPTCFG_ATH9K_WOW) += wow.o + + obj-$(CPTCFG_ATH9K) += ath9k.o + +@@ -41,6 +41,8 @@ ath9k_hw-y:= \ + ar9003_eeprom.o \ + ar9003_paprd.o + ++ath9k_hw-$(CPTCFG_ATH9K_WOW) += ar9003_wow.o ++ + ath9k_hw-$(CPTCFG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ + ar9003_mci.o + obj-$(CPTCFG_ATH9K_HW) += ath9k_hw.o +--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c +@@ -26,6 +26,7 @@ + #include "ar9462_2p0_initvals.h" + #include "ar9462_2p1_initvals.h" + #include "ar9565_1p0_initvals.h" ++#include "ar9565_1p1_initvals.h" + + /* General hardware code for the AR9003 hadware family */ + +@@ -187,17 +188,17 @@ static void ar9003_hw_init_mode_regs(str + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, + ar9485_1_1_baseband_core_txfir_coeff_japan_2484); + +- /* Load PCIE SERDES settings from INI */ - -- sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); -- sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); -- sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); +- /* Awake Setting */ - -- res = sta_info_insert(sta); -- if (res) { -- /* STA has been freed */ -- goto err_del_interface; -- } +- INIT_INI_ARRAY(&ah->iniPcieSerdes, +- ar9485_1_1_pcie_phy_clkreq_disable_L1); - -- rate_control_rate_init(sta); -- netif_carrier_on(dev); -- } else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { -+ if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) - rcu_assign_pointer(local->p2p_sdata, sdata); -- } +- /* Sleep Setting */ +- +- INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, +- ar9485_1_1_pcie_phy_clkreq_disable_L1); ++ if (ah->config.no_pll_pwrsave) { ++ INIT_INI_ARRAY(&ah->iniPcieSerdes, ++ ar9485_1_1_pcie_phy_clkreq_disable_L1); ++ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, ++ ar9485_1_1_pcie_phy_clkreq_disable_L1); ++ } else { ++ INIT_INI_ARRAY(&ah->iniPcieSerdes, ++ ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1); ++ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, ++ ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1); ++ } + } else if (AR_SREV_9462_21(ah)) { + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9462_2p1_mac_core); +@@ -223,6 +224,10 @@ static void ar9003_hw_init_mode_regs(str + ar9462_2p1_modes_fast_clock); + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, + ar9462_2p1_baseband_core_txfir_coeff_japan_2484); ++ INIT_INI_ARRAY(&ah->iniPcieSerdes, ++ ar9462_2p1_pciephy_clkreq_disable_L1); ++ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, ++ ar9462_2p1_pciephy_clkreq_disable_L1); + } else if (AR_SREV_9462_20(ah)) { - /* - * set_multicast_list will be invoked by the networking core -@@ -1116,6 +1093,74 @@ static void ieee80211_if_setup(struct ne - dev->destructor = free_netdev; - } - -+static void ieee80211_wds_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, -+ struct sk_buff *skb) -+{ -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_rx_status *rx_status; -+ struct ieee802_11_elems elems; -+ struct ieee80211_mgmt *mgmt; -+ struct sta_info *sta; -+ size_t baselen; -+ u32 rates = 0; -+ u16 stype; -+ bool new = false; -+ enum ieee80211_band band; -+ struct ieee80211_supported_band *sband; -+ -+ rx_status = IEEE80211_SKB_RXCB(skb); -+ band = rx_status->band; -+ sband = local->hw.wiphy->bands[band]; -+ mgmt = (struct ieee80211_mgmt *) skb->data; -+ stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; -+ -+ if (stype != IEEE80211_STYPE_BEACON) -+ return; + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); +@@ -247,18 +252,18 @@ static void ar9003_hw_init_mode_regs(str + ar9462_2p0_soc_postamble); + + INIT_INI_ARRAY(&ah->iniModesRxGain, +- ar9462_common_rx_gain_table_2p0); ++ ar9462_2p0_common_rx_gain); + + /* Awake -> Sleep Setting */ + INIT_INI_ARRAY(&ah->iniPcieSerdes, +- ar9462_pciephy_clkreq_disable_L1_2p0); ++ ar9462_2p0_pciephy_clkreq_disable_L1); + /* Sleep -> Awake Setting */ + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, +- ar9462_pciephy_clkreq_disable_L1_2p0); ++ ar9462_2p0_pciephy_clkreq_disable_L1); + + /* Fast clock modal settings */ + INIT_INI_ARRAY(&ah->iniModesFastClock, +- ar9462_modes_fast_clock_2p0); ++ ar9462_2p0_modes_fast_clock); + + INIT_INI_ARRAY(&ah->iniCckfirJapan2484, + ar9462_2p0_baseband_core_txfir_coeff_japan_2484); +@@ -331,6 +336,41 @@ static void ar9003_hw_init_mode_regs(str + + INIT_INI_ARRAY(&ah->iniModesFastClock, + ar9580_1p0_modes_fast_clock); ++ } else if (AR_SREV_9565_11_OR_LATER(ah)) { ++ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ++ ar9565_1p1_mac_core); ++ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], ++ ar9565_1p1_mac_postamble); + -+ baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; -+ if (baselen > skb->len) -+ return; ++ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], ++ ar9565_1p1_baseband_core); ++ INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], ++ ar9565_1p1_baseband_postamble); + -+ ieee802_11_parse_elems(mgmt->u.probe_resp.variable, -+ skb->len - baselen, false, &elems); ++ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], ++ ar9565_1p1_radio_core); ++ INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], ++ ar9565_1p1_radio_postamble); + -+ rates = ieee80211_sta_get_rates(local, &elems, band, NULL); ++ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], ++ ar9565_1p1_soc_preamble); ++ INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], ++ ar9565_1p1_soc_postamble); + -+ rcu_read_lock(); ++ INIT_INI_ARRAY(&ah->iniModesRxGain, ++ ar9565_1p1_Common_rx_gain_table); ++ INIT_INI_ARRAY(&ah->iniModesTxGain, ++ ar9565_1p1_Modes_lowest_ob_db_tx_gain_table); + -+ sta = sta_info_get(sdata, sdata->u.wds.remote_addr); ++ INIT_INI_ARRAY(&ah->iniPcieSerdes, ++ ar9565_1p1_pciephy_clkreq_disable_L1); ++ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, ++ ar9565_1p1_pciephy_clkreq_disable_L1); + -+ if (!sta) { -+ rcu_read_unlock(); -+ sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, -+ GFP_KERNEL); -+ if (!sta) -+ return; ++ INIT_INI_ARRAY(&ah->iniModesFastClock, ++ ar9565_1p1_modes_fast_clock); ++ INIT_INI_ARRAY(&ah->iniCckfirJapan2484, ++ ar9565_1p1_baseband_core_txfir_coeff_japan_2484); + } else if (AR_SREV_9565(ah)) { + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9565_1p0_mac_core); +@@ -440,7 +480,10 @@ static void ar9003_tx_gain_table_mode0(s + ar9462_2p1_modes_low_ob_db_tx_gain); + else if (AR_SREV_9462_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, +- ar9462_modes_low_ob_db_tx_gain_table_2p0); ++ ar9462_2p0_modes_low_ob_db_tx_gain); ++ else if (AR_SREV_9565_11(ah)) ++ INIT_INI_ARRAY(&ah->iniModesTxGain, ++ ar9565_1p1_modes_low_ob_db_tx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_modes_low_ob_db_tx_gain_table); +@@ -474,7 +517,10 @@ static void ar9003_tx_gain_table_mode1(s + ar9462_2p1_modes_high_ob_db_tx_gain); + else if (AR_SREV_9462_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, +- ar9462_modes_high_ob_db_tx_gain_table_2p0); ++ ar9462_2p0_modes_high_ob_db_tx_gain); ++ else if (AR_SREV_9565_11(ah)) ++ INIT_INI_ARRAY(&ah->iniModesTxGain, ++ ar9565_1p1_modes_high_ob_db_tx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_modes_high_ob_db_tx_gain_table); +@@ -500,6 +546,9 @@ static void ar9003_tx_gain_table_mode2(s + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9580_1p0_low_ob_db_tx_gain_table); ++ else if (AR_SREV_9565_11(ah)) ++ INIT_INI_ARRAY(&ah->iniModesTxGain, ++ ar9565_1p1_modes_low_ob_db_tx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_modes_low_ob_db_tx_gain_table); +@@ -525,6 +574,9 @@ static void ar9003_tx_gain_table_mode3(s + else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9580_1p0_high_power_tx_gain_table); ++ else if (AR_SREV_9565_11(ah)) ++ INIT_INI_ARRAY(&ah->iniModesTxGain, ++ ar9565_1p1_modes_high_power_tx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_modes_high_power_tx_gain_table); +@@ -546,7 +598,7 @@ static void ar9003_tx_gain_table_mode4(s + ar9462_2p1_modes_mix_ob_db_tx_gain); + else if (AR_SREV_9462_20(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, +- ar9462_modes_mix_ob_db_tx_gain_table_2p0); ++ ar9462_2p0_modes_mix_ob_db_tx_gain); + else + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9300Modes_mixed_ob_db_tx_gain_table_2p2); +@@ -581,6 +633,13 @@ static void ar9003_tx_gain_table_mode6(s + ar9580_1p0_type6_tx_gain_table); + } + ++static void ar9003_tx_gain_table_mode7(struct ath_hw *ah) ++{ ++ if (AR_SREV_9340(ah)) ++ INIT_INI_ARRAY(&ah->iniModesTxGain, ++ ar9340_cus227_tx_gain_table_1p0); ++} + -+ new = true; -+ } + typedef void (*ath_txgain_tab)(struct ath_hw *ah); + + static void ar9003_tx_gain_table_apply(struct ath_hw *ah) +@@ -593,6 +652,7 @@ static void ar9003_tx_gain_table_apply(s + ar9003_tx_gain_table_mode4, + ar9003_tx_gain_table_mode5, + ar9003_tx_gain_table_mode6, ++ ar9003_tx_gain_table_mode7, + }; + int idx = ar9003_hw_get_tx_gain_idx(ah); + +@@ -629,7 +689,10 @@ static void ar9003_rx_gain_table_mode0(s + ar9462_2p1_common_rx_gain); + else if (AR_SREV_9462_20(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, +- ar9462_common_rx_gain_table_2p0); ++ ar9462_2p0_common_rx_gain); ++ else if (AR_SREV_9565_11(ah)) ++ INIT_INI_ARRAY(&ah->iniModesRxGain, ++ ar9565_1p1_Common_rx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9565_1p0_Common_rx_gain_table); +@@ -657,7 +720,7 @@ static void ar9003_rx_gain_table_mode1(s + ar9462_2p1_common_wo_xlna_rx_gain); + else if (AR_SREV_9462_20(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, +- ar9462_common_wo_xlna_rx_gain_table_2p0); ++ ar9462_2p0_common_wo_xlna_rx_gain); + else if (AR_SREV_9550(ah)) { + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar955x_1p0_common_wo_xlna_rx_gain_table); +@@ -666,6 +729,9 @@ static void ar9003_rx_gain_table_mode1(s + } else if (AR_SREV_9580(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9580_1p0_wo_xlna_rx_gain_table); ++ else if (AR_SREV_9565_11(ah)) ++ INIT_INI_ARRAY(&ah->iniModesRxGain, ++ ar9565_1p1_common_wo_xlna_rx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9565_1p0_common_wo_xlna_rx_gain_table); +@@ -687,7 +753,7 @@ static void ar9003_rx_gain_table_mode2(s + ar9462_2p1_baseband_postamble_5g_xlna); + } else if (AR_SREV_9462_20(ah)) { + INIT_INI_ARRAY(&ah->iniModesRxGain, +- ar9462_common_mixed_rx_gain_table_2p0); ++ ar9462_2p0_common_mixed_rx_gain); + INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, + ar9462_2p0_baseband_core_mix_rxgain); + INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble, +@@ -701,12 +767,12 @@ static void ar9003_rx_gain_table_mode3(s + { + if (AR_SREV_9462_21(ah)) { + INIT_INI_ARRAY(&ah->iniModesRxGain, +- ar9462_2p1_common_5g_xlna_only_rx_gain); ++ ar9462_2p1_common_5g_xlna_only_rxgain); + INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, + ar9462_2p1_baseband_postamble_5g_xlna); + } else if (AR_SREV_9462_20(ah)) { + INIT_INI_ARRAY(&ah->iniModesRxGain, +- ar9462_2p0_5g_xlna_only_rxgain); ++ ar9462_2p0_common_5g_xlna_only_rxgain); + INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, + ar9462_2p0_baseband_postamble_5g_xlna); + } +@@ -750,6 +816,9 @@ static void ar9003_hw_init_mode_gain_reg + static void ar9003_hw_configpcipowersave(struct ath_hw *ah, + bool power_off) + { ++ unsigned int i; ++ struct ar5416IniArray *array; ++ + /* + * Increase L1 Entry Latency. Some WB222 boards don't have + * this change in eeprom/OTP. +@@ -775,18 +844,13 @@ static void ar9003_hw_configpcipowersave + * Configire PCIE after Ini init. SERDES values now come from ini file + * This enables PCIe low power mode. + */ +- if (ah->config.pcieSerDesWrite) { +- unsigned int i; +- struct ar5416IniArray *array; +- +- array = power_off ? &ah->iniPcieSerdes : +- &ah->iniPcieSerdesLowPower; +- +- for (i = 0; i < array->ia_rows; i++) { +- REG_WRITE(ah, +- INI_RA(array, i, 0), +- INI_RA(array, i, 1)); +- } ++ array = power_off ? &ah->iniPcieSerdes : ++ &ah->iniPcieSerdesLowPower; + -+ sta->last_rx = jiffies; -+ sta->sta.supp_rates[band] = rates; ++ for (i = 0; i < array->ia_rows; i++) { ++ REG_WRITE(ah, ++ INI_RA(array, i, 0), ++ INI_RA(array, i, 1)); + } + } + +--- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h +@@ -1447,4 +1447,106 @@ static const u32 ar9340_1p0_soc_preamble + {0x00007038, 0x000004c2}, + }; + ++static const u32 ar9340_cus227_tx_gain_table_1p0[][5] = { ++ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ++ {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, ++ {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, ++ {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, ++ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, ++ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, ++ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, ++ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, ++ {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, ++ {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400}, ++ {0x0000a518, 0x21002220, 0x21002220, 0x15000402, 0x15000402}, ++ {0x0000a51c, 0x27002223, 0x27002223, 0x19000404, 0x19000404}, ++ {0x0000a520, 0x2c022220, 0x2c022220, 0x1b000603, 0x1b000603}, ++ {0x0000a524, 0x30022222, 0x30022222, 0x1f000a02, 0x1f000a02}, ++ {0x0000a528, 0x35022225, 0x35022225, 0x23000a04, 0x23000a04}, ++ {0x0000a52c, 0x3b02222a, 0x3b02222a, 0x26000a20, 0x26000a20}, ++ {0x0000a530, 0x3f02222c, 0x3f02222c, 0x2a000e20, 0x2a000e20}, ++ {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22}, ++ {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24}, ++ {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640}, ++ {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660}, ++ {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861}, ++ {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81}, ++ {0x0000a54c, 0x5c02486b, 0x5c02486b, 0x42001a83, 0x42001a83}, ++ {0x0000a550, 0x61024a6c, 0x61024a6c, 0x44001c84, 0x44001c84}, ++ {0x0000a554, 0x66026a6c, 0x66026a6c, 0x48001ce3, 0x48001ce3}, ++ {0x0000a558, 0x6b026e6c, 0x6b026e6c, 0x4c001ce5, 0x4c001ce5}, ++ {0x0000a55c, 0x7002708c, 0x7002708c, 0x50001ce9, 0x50001ce9}, ++ {0x0000a560, 0x7302b08a, 0x7302b08a, 0x54001ceb, 0x54001ceb}, ++ {0x0000a564, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, ++ {0x0000a568, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, ++ {0x0000a56c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, ++ {0x0000a570, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, ++ {0x0000a574, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, ++ {0x0000a578, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, ++ {0x0000a57c, 0x7702b08c, 0x7702b08c, 0x56001eec, 0x56001eec}, ++ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, ++ {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, ++ {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, ++ {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, ++ {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202}, ++ {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400}, ++ {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402}, ++ {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404}, ++ {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603}, ++ {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02}, ++ {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04}, ++ {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20}, ++ {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20}, ++ {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22}, ++ {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24}, ++ {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640}, ++ {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660}, ++ {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861}, ++ {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81}, ++ {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83}, ++ {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84}, ++ {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3}, ++ {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5}, ++ {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9}, ++ {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb}, ++ {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, ++ {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, ++ {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, ++ {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, ++ {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, ++ {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, ++ {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec}, ++ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, ++ {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, ++ {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, ++ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, ++ {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, ++ {0x00016048, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, ++ {0x00016280, 0x01000015, 0x01000015, 0x01001015, 0x01001015}, ++ {0x00016288, 0x30318000, 0x30318000, 0x00318000, 0x00318000}, ++ {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4}, ++ {0x00016448, 0x24925666, 0x24925666, 0x8e481266, 0x8e481266}, ++ {0x0000a3a4, 0x00000011, 0x00000011, 0x00000011, 0x00000011}, ++ {0x0000a3a8, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c, 0x3c3c3c3c}, ++ {0x0000a3ac, 0x30303030, 0x30303030, 0x30303030, 0x30303030}, ++}; ++ + #endif /* INITVALS_9340_H */ +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -459,6 +459,7 @@ void ath_check_ani(struct ath_softc *sc) + int ath_update_survey_stats(struct ath_softc *sc); + void ath_update_survey_nf(struct ath_softc *sc, int channel); + void ath9k_queue_reset(struct ath_softc *sc, enum ath_reset_type type); ++void ath_ps_full_sleep(unsigned long data); + + /**********/ + /* BTCOEX */ +@@ -570,6 +571,34 @@ static inline void ath_fill_led_pin(stru + } + #endif + ++/************************/ ++/* Wake on Wireless LAN */ ++/************************/ ++ ++#ifdef CONFIG_ATH9K_WOW ++void ath9k_init_wow(struct ieee80211_hw *hw); ++int ath9k_suspend(struct ieee80211_hw *hw, ++ struct cfg80211_wowlan *wowlan); ++int ath9k_resume(struct ieee80211_hw *hw); ++void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled); ++#else ++static inline void ath9k_init_wow(struct ieee80211_hw *hw) ++{ ++} ++static inline int ath9k_suspend(struct ieee80211_hw *hw, ++ struct cfg80211_wowlan *wowlan) ++{ ++ return 0; ++} ++static inline int ath9k_resume(struct ieee80211_hw *hw) ++{ ++ return 0; ++} ++static inline void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled) ++{ ++} ++#endif /* CONFIG_ATH9K_WOW */ + -+ if (elems.ht_cap_elem) -+ ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband, -+ elems.ht_cap_elem, sta); + /*******************************/ + /* Antenna diversity/combining */ + /*******************************/ +@@ -632,15 +661,16 @@ void ath_ant_comb_scan(struct ath_softc + /* Main driver core */ + /********************/ + +-#define ATH9K_PCI_CUS198 0x0001 +-#define ATH9K_PCI_CUS230 0x0002 +-#define ATH9K_PCI_CUS217 0x0004 +-#define ATH9K_PCI_CUS252 0x0008 +-#define ATH9K_PCI_WOW 0x0010 +-#define ATH9K_PCI_BT_ANT_DIV 0x0020 +-#define ATH9K_PCI_D3_L1_WAR 0x0040 +-#define ATH9K_PCI_AR9565_1ANT 0x0080 +-#define ATH9K_PCI_AR9565_2ANT 0x0100 ++#define ATH9K_PCI_CUS198 0x0001 ++#define ATH9K_PCI_CUS230 0x0002 ++#define ATH9K_PCI_CUS217 0x0004 ++#define ATH9K_PCI_CUS252 0x0008 ++#define ATH9K_PCI_WOW 0x0010 ++#define ATH9K_PCI_BT_ANT_DIV 0x0020 ++#define ATH9K_PCI_D3_L1_WAR 0x0040 ++#define ATH9K_PCI_AR9565_1ANT 0x0080 ++#define ATH9K_PCI_AR9565_2ANT 0x0100 ++#define ATH9K_PCI_NO_PLL_PWRSAVE 0x0200 + + /* + * Default cache line size, in bytes. +@@ -723,6 +753,7 @@ struct ath_softc { + struct work_struct hw_check_work; + struct work_struct hw_reset_work; + struct completion paprd_complete; ++ wait_queue_head_t tx_wait; + + unsigned int hw_busy_count; + unsigned long sc_flags; +@@ -759,6 +790,7 @@ struct ath_softc { + struct delayed_work tx_complete_work; + struct delayed_work hw_pll_work; + struct timer_list rx_poll_timer; ++ struct timer_list sleep_timer; + + #ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT + struct ath_btcoex btcoex; +@@ -783,7 +815,7 @@ struct ath_softc { + bool tx99_state; + s16 tx99_power; + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ATH9K_WOW + atomic_t wow_got_bmiss_intr; + atomic_t wow_sleep_proc_intr; /* in the middle of WoW sleep ? */ + u32 wow_intr_before_sleep; +@@ -946,10 +978,25 @@ struct fft_sample_ht20_40 { + u8 data[SPECTRAL_HT20_40_NUM_BINS]; + } __packed; + +-int ath9k_tx99_init(struct ath_softc *sc); +-void ath9k_tx99_deinit(struct ath_softc *sc); ++/********/ ++/* TX99 */ ++/********/ + -+ if (elems.wmm_param) -+ set_sta_flag(sta, WLAN_STA_WME); ++#ifdef CONFIG_ATH9K_TX99 ++void ath9k_tx99_init_debug(struct ath_softc *sc); + int ath9k_tx99_send(struct ath_softc *sc, struct sk_buff *skb, + struct ath_tx_control *txctl); ++#else ++static inline void ath9k_tx99_init_debug(struct ath_softc *sc) ++{ ++} ++static inline int ath9k_tx99_send(struct ath_softc *sc, ++ struct sk_buff *skb, ++ struct ath_tx_control *txctl) ++{ ++ return 0; ++} ++#endif /* CONFIG_ATH9K_TX99 */ + + void ath9k_tasklet(unsigned long data); + int ath_cabq_update(struct ath_softc *); +@@ -966,6 +1013,9 @@ extern bool is_ath9k_unloaded; + + u8 ath9k_parse_mpdudensity(u8 mpdudensity); + irqreturn_t ath_isr(int irq, void *dev); ++int ath_reset(struct ath_softc *sc); ++void ath_cancel_work(struct ath_softc *sc); ++void ath_restart_work(struct ath_softc *sc); + int ath9k_init_device(u16 devid, struct ath_softc *sc, + const struct ath_bus_ops *bus_ops); + void ath9k_deinit_device(struct ath_softc *sc); +--- a/drivers/net/wireless/ath/ath9k/debug.c ++++ b/drivers/net/wireless/ath/ath9k/debug.c +@@ -1782,111 +1782,6 @@ void ath9k_deinit_debug(struct ath_softc + } + } + +-static ssize_t read_file_tx99(struct file *file, char __user *user_buf, +- size_t count, loff_t *ppos) +-{ +- struct ath_softc *sc = file->private_data; +- char buf[3]; +- unsigned int len; +- +- len = sprintf(buf, "%d\n", sc->tx99_state); +- return simple_read_from_buffer(user_buf, count, ppos, buf, len); +-} +- +-static ssize_t write_file_tx99(struct file *file, const char __user *user_buf, +- size_t count, loff_t *ppos) +-{ +- struct ath_softc *sc = file->private_data; +- struct ath_common *common = ath9k_hw_common(sc->sc_ah); +- char buf[32]; +- bool start; +- ssize_t len; +- int r; +- +- if (sc->nvifs > 1) +- return -EOPNOTSUPP; +- +- len = min(count, sizeof(buf) - 1); +- if (copy_from_user(buf, user_buf, len)) +- return -EFAULT; +- +- if (strtobool(buf, &start)) +- return -EINVAL; +- +- if (start == sc->tx99_state) { +- if (!start) +- return count; +- ath_dbg(common, XMIT, "Resetting TX99\n"); +- ath9k_tx99_deinit(sc); +- } +- +- if (!start) { +- ath9k_tx99_deinit(sc); +- return count; +- } +- +- r = ath9k_tx99_init(sc); +- if (r) +- return r; +- +- return count; +-} +- +-static const struct file_operations fops_tx99 = { +- .read = read_file_tx99, +- .write = write_file_tx99, +- .open = simple_open, +- .owner = THIS_MODULE, +- .llseek = default_llseek, +-}; +- +-static ssize_t read_file_tx99_power(struct file *file, +- char __user *user_buf, +- size_t count, loff_t *ppos) +-{ +- struct ath_softc *sc = file->private_data; +- char buf[32]; +- unsigned int len; +- +- len = sprintf(buf, "%d (%d dBm)\n", +- sc->tx99_power, +- sc->tx99_power / 2); +- +- return simple_read_from_buffer(user_buf, count, ppos, buf, len); +-} +- +-static ssize_t write_file_tx99_power(struct file *file, +- const char __user *user_buf, +- size_t count, loff_t *ppos) +-{ +- struct ath_softc *sc = file->private_data; +- int r; +- u8 tx_power; +- +- r = kstrtou8_from_user(user_buf, count, 0, &tx_power); +- if (r) +- return r; +- +- if (tx_power > MAX_RATE_POWER) +- return -EINVAL; +- +- sc->tx99_power = tx_power; +- +- ath9k_ps_wakeup(sc); +- ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power); +- ath9k_ps_restore(sc); +- +- return count; +-} +- +-static const struct file_operations fops_tx99_power = { +- .read = read_file_tx99_power, +- .write = write_file_tx99_power, +- .open = simple_open, +- .owner = THIS_MODULE, +- .llseek = default_llseek, +-}; +- + int ath9k_init_debug(struct ath_hw *ah) + { + struct ath_common *common = ath9k_hw_common(ah); +@@ -1903,6 +1798,7 @@ int ath9k_init_debug(struct ath_hw *ah) + #endif + + ath9k_dfs_init_debug(sc); ++ ath9k_tx99_init_debug(sc); + + debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_dma); +@@ -1978,15 +1874,6 @@ int ath9k_init_debug(struct ath_hw *ah) + debugfs_create_file("btcoex", S_IRUSR, sc->debug.debugfs_phy, sc, + &fops_btcoex); + #endif +- if (config_enabled(CPTCFG_ATH9K_TX99) && +- AR_SREV_9300_20_OR_LATER(ah)) { +- debugfs_create_file("tx99", S_IRUSR | S_IWUSR, +- sc->debug.debugfs_phy, sc, +- &fops_tx99); +- debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR, +- sc->debug.debugfs_phy, sc, +- &fops_tx99_power); +- } + + return 0; + } +--- a/drivers/net/wireless/ath/ath9k/hw.c ++++ b/drivers/net/wireless/ath/ath9k/hw.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + #include + + #include "hw.h" +@@ -454,7 +455,6 @@ static void ath9k_hw_init_config(struct + } + + ah->config.rx_intr_mitigation = true; +- ah->config.pcieSerDesWrite = true; + + /* + * We need this for PCI devices only (Cardbus, PCI, miniPCI) +@@ -1502,8 +1502,9 @@ static bool ath9k_hw_channel_change(stru + int r; + + if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) { +- band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan); +- mode_diff = (chan->channelFlags != ah->curchan->channelFlags); ++ u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags; ++ band_switch = !!(flags_diff & CHANNEL_5GHZ); ++ mode_diff = !!(flags_diff & ~CHANNEL_HT); + } + + for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { +@@ -1815,7 +1816,7 @@ static int ath9k_hw_do_fastcc(struct ath + * If cross-band fcc is not supoprted, bail out if channelFlags differ. + */ + if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) && +- chan->channelFlags != ah->curchan->channelFlags) ++ ((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT)) + goto fail; + + if (!ath9k_hw_check_alive(ah)) +@@ -1856,10 +1857,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st + struct ath9k_hw_cal_data *caldata, bool fastcc) + { + struct ath_common *common = ath9k_hw_common(ah); ++ struct timespec ts; + u32 saveLedState; + u32 saveDefAntenna; + u32 macStaId1; + u64 tsf = 0; ++ s64 usec = 0; + int r; + bool start_mci_reset = false; + bool save_fullsleep = ah->chip_fullsleep; +@@ -1902,10 +1905,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st + + macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B; + +- /* For chips on which RTC reset is done, save TSF before it gets cleared */ +- if (AR_SREV_9100(ah) || +- (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))) +- tsf = ath9k_hw_gettsf64(ah); ++ /* Save TSF before chip reset, a cold reset clears it */ ++ tsf = ath9k_hw_gettsf64(ah); ++ getrawmonotonic(&ts); ++ usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000; + + saveLedState = REG_READ(ah, AR_CFG_LED) & + (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL | +@@ -1938,8 +1941,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st + } + + /* Restore TSF */ +- if (tsf) +- ath9k_hw_settsf64(ah, tsf); ++ getrawmonotonic(&ts); ++ usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec; ++ ath9k_hw_settsf64(ah, tsf + usec); + + if (AR_SREV_9280_20_OR_LATER(ah)) + REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -283,7 +283,6 @@ struct ath9k_ops_config { + int additional_swba_backoff; + int ack_6mb; + u32 cwm_ignore_extcca; +- bool pcieSerDesWrite; + u8 pcie_clock_req; + u32 pcie_waen; + u8 analog_shiftreg; +@@ -316,6 +315,7 @@ struct ath9k_ops_config { + u32 ant_ctrl_comm2g_switch_enable; + bool xatten_margin_cfg; + bool alt_mingainidx; ++ bool no_pll_pwrsave; + }; + + enum ath9k_int { +@@ -920,7 +920,7 @@ struct ath_hw { + /* Enterprise mode cap */ + u32 ent_mode; + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ATH9K_WOW + u32 wow_event_mask; + #endif + bool is_clk_25mhz; +@@ -1126,7 +1126,7 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw + #endif /* CPTCFG_ATH9K_BTCOEX_SUPPORT */ + + +-#ifdef CONFIG_PM_SLEEP ++#ifdef CONFIG_ATH9K_WOW + const char *ath9k_hw_wow_event_to_string(u32 wow_event); + void ath9k_hw_wow_apply_pattern(struct ath_hw *ah, u8 *user_pattern, + u8 *user_mask, int pattern_count, +--- a/drivers/net/wireless/ath/ath9k/init.c ++++ b/drivers/net/wireless/ath/ath9k/init.c +@@ -609,6 +609,11 @@ static void ath9k_init_platform(struct a + ah->config.pcie_waen = 0x0040473b; + ath_info(common, "Enable WAR for ASPM D3/L1\n"); + } + -+ if (new) { -+ sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); -+ sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); -+ sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); -+ rate_control_rate_init(sta); -+ sta_info_insert_rcu(sta); ++ if (sc->driver_data & ATH9K_PCI_NO_PLL_PWRSAVE) { ++ ah->config.no_pll_pwrsave = true; ++ ath_info(common, "Disable PLL PowerSave\n"); + } + } + + static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob, +@@ -683,6 +688,7 @@ static int ath9k_init_softc(u16 devid, s + common = ath9k_hw_common(ah); + sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET); + sc->tx99_power = MAX_RATE_POWER + 1; ++ init_waitqueue_head(&sc->tx_wait); + + if (!pdata) { + ah->ah_flags |= AH_USE_EEPROM; +@@ -730,6 +736,7 @@ static int ath9k_init_softc(u16 devid, s + tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet, + (unsigned long)sc); + ++ setup_timer(&sc->sleep_timer, ath_ps_full_sleep, (unsigned long)sc); + INIT_WORK(&sc->hw_reset_work, ath_reset_work); + INIT_WORK(&sc->hw_check_work, ath_hw_check); + INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); +@@ -845,7 +852,8 @@ static const struct ieee80211_iface_limi + }; + + static const struct ieee80211_iface_limit if_dfs_limits[] = { +- { .max = 1, .types = BIT(NL80211_IFTYPE_AP) }, ++ { .max = 1, .types = BIT(NL80211_IFTYPE_AP) | ++ BIT(NL80211_IFTYPE_ADHOC) }, + }; + + static const struct ieee80211_iface_combination if_comb[] = { +@@ -862,20 +870,11 @@ static const struct ieee80211_iface_comb + .max_interfaces = 1, + .num_different_channels = 1, + .beacon_int_infra_match = true, +- .radar_detect_widths = BIT(NL80211_CHAN_NO_HT) | +- BIT(NL80211_CHAN_HT20), ++ .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | ++ BIT(NL80211_CHAN_WIDTH_20), + } + }; + +-#ifdef CONFIG_PM +-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, +-}; +-#endif +- + void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) + { + struct ath_hw *ah = sc->sc_ah; +@@ -925,16 +924,6 @@ void ath9k_set_hw_capab(struct ath_softc + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; + hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH; + +-#ifdef CONFIG_PM_SLEEP +- if ((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; +- +- atomic_set(&sc->wow_sleep_proc_intr, -1); +- atomic_set(&sc->wow_got_bmiss_intr, -1); +-#endif +- + hw->queues = 4; + hw->max_rates = 4; + hw->channel_change_time = 5000; +@@ -960,6 +949,7 @@ void ath9k_set_hw_capab(struct ath_softc + hw->wiphy->bands[IEEE80211_BAND_5GHZ] = + &sc->sbands[IEEE80211_BAND_5GHZ]; + ++ ath9k_init_wow(hw); + ath9k_reload_chainmask_settings(sc); + + SET_IEEE80211_PERM_ADDR(hw, common->macaddr); +@@ -1058,6 +1048,7 @@ static void ath9k_deinit_softc(struct at + if (ATH_TXQ_SETUP(sc, i)) + ath_tx_cleanupq(sc, &sc->tx.txq[i]); + ++ del_timer_sync(&sc->sleep_timer); + ath9k_hw_deinit(sc->sc_ah); + if (sc->dfs_detector != NULL) + sc->dfs_detector->exit(sc->dfs_detector); +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -82,6 +82,22 @@ static bool ath9k_setpower(struct ath_so + return ret; + } + ++void ath_ps_full_sleep(unsigned long data) ++{ ++ struct ath_softc *sc = (struct ath_softc *) data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ bool reset; ++ ++ spin_lock(&common->cc_lock); ++ ath_hw_cycle_counters_update(common); ++ spin_unlock(&common->cc_lock); ++ ++ ath9k_hw_setrxabort(sc->sc_ah, 1); ++ ath9k_hw_stopdmarecv(sc->sc_ah, &reset); + -+ rcu_read_unlock(); ++ ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); +} + - static void ieee80211_iface_work(struct work_struct *work) + void ath9k_ps_wakeup(struct ath_softc *sc) { - struct ieee80211_sub_if_data *sdata = -@@ -1220,6 +1265,9 @@ static void ieee80211_iface_work(struct - break; - ieee80211_mesh_rx_queued_mgmt(sdata, skb); - break; -+ case NL80211_IFTYPE_WDS: -+ ieee80211_wds_rx_queued_mgmt(sdata, skb); -+ break; - default: - WARN(1, "frame for unexpected interface type"); - break; ---- a/net/mac80211/rx.c -+++ b/net/mac80211/rx.c -@@ -2369,6 +2369,7 @@ ieee80211_rx_h_action(struct ieee80211_r - sdata->vif.type != NL80211_IFTYPE_MESH_POINT && - sdata->vif.type != NL80211_IFTYPE_AP_VLAN && - sdata->vif.type != NL80211_IFTYPE_AP && -+ sdata->vif.type != NL80211_IFTYPE_WDS && - sdata->vif.type != NL80211_IFTYPE_ADHOC) - break; - -@@ -2720,14 +2721,15 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_ - - if (!ieee80211_vif_is_mesh(&sdata->vif) && - sdata->vif.type != NL80211_IFTYPE_ADHOC && -- sdata->vif.type != NL80211_IFTYPE_STATION) -+ sdata->vif.type != NL80211_IFTYPE_STATION && -+ sdata->vif.type != NL80211_IFTYPE_WDS) - return RX_DROP_MONITOR; - - switch (stype) { - case cpu_to_le16(IEEE80211_STYPE_AUTH): - case cpu_to_le16(IEEE80211_STYPE_BEACON): - case cpu_to_le16(IEEE80211_STYPE_PROBE_RESP): -- /* process for all: mesh, mlme, ibss */ -+ /* process for all: mesh, mlme, ibss, wds */ - break; - case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP): - case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP): -@@ -3059,10 +3061,16 @@ static int prepare_for_handlers(struct i - } - break; - case NL80211_IFTYPE_WDS: -- if (bssid || !ieee80211_is_data(hdr->frame_control)) -- return 0; - if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2)) - return 0; -+ -+ if (ieee80211_is_data(hdr->frame_control) || -+ ieee80211_is_action(hdr->frame_control)) { -+ if (compare_ether_addr(sdata->vif.addr, hdr->addr1)) -+ return 0; -+ } else if (!ieee80211_is_beacon(hdr->frame_control)) -+ return 0; + struct ath_common *common = ath9k_hw_common(sc->sc_ah); +@@ -92,6 +108,7 @@ void ath9k_ps_wakeup(struct ath_softc *s + if (++sc->ps_usecount != 1) + goto unlock; + ++ del_timer_sync(&sc->sleep_timer); + power_mode = sc->sc_ah->power_mode; + ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE); + +@@ -117,17 +134,17 @@ void ath9k_ps_restore(struct ath_softc * + struct ath_common *common = ath9k_hw_common(sc->sc_ah); + enum ath9k_power_mode mode; + unsigned long flags; +- bool reset; + + spin_lock_irqsave(&sc->sc_pm_lock, flags); + if (--sc->ps_usecount != 0) + goto unlock; + + if (sc->ps_idle) { +- ath9k_hw_setrxabort(sc->sc_ah, 1); +- ath9k_hw_stopdmarecv(sc->sc_ah, &reset); +- mode = ATH9K_PM_FULL_SLEEP; +- } else if (sc->ps_enabled && ++ mod_timer(&sc->sleep_timer, jiffies + HZ / 10); ++ goto unlock; ++ } + - break; - case NL80211_IFTYPE_P2P_DEVICE: - if (!ieee80211_is_public_action(hdr, skb->len) && ---- a/net/mac80211/sta_info.c -+++ b/net/mac80211/sta_info.c -@@ -149,6 +149,7 @@ static void cleanup_single_sta(struct st - * directly by station destruction. - */ - for (i = 0; i < IEEE80211_NUM_TIDS; i++) { -+ kfree(sta->ampdu_mlme.tid_start_tx[i]); - tid_tx = rcu_dereference_raw(sta->ampdu_mlme.tid_tx[i]); - if (!tid_tx) - continue; ---- a/net/mac80211/sta_info.h -+++ b/net/mac80211/sta_info.h -@@ -32,7 +32,6 @@ - * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble - * frames. - * @WLAN_STA_WME: Station is a QoS-STA. -- * @WLAN_STA_WDS: Station is one of our WDS peers. - * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the - * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next - * frame to this station is transmitted. -@@ -66,7 +65,6 @@ enum ieee80211_sta_info_flags { - WLAN_STA_AUTHORIZED, - WLAN_STA_SHORT_PREAMBLE, - WLAN_STA_WME, -- WLAN_STA_WDS, - WLAN_STA_CLEAR_PS_FILT, - WLAN_STA_MFP, - WLAN_STA_BLOCK_BA, -@@ -203,6 +201,7 @@ struct tid_ampdu_rx { - * driver requested to close until the work for it runs - * @mtx: mutex to protect all TX data (except non-NULL assignments - * to tid_tx[idx], which are protected by the sta spinlock) -+ * tid_start_tx is also protected by sta->lock. - */ - struct sta_ampdu_mlme { - struct mutex mtx; ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -1778,9 +1778,13 @@ static void ath_tx_txqaddbuf(struct ath_ ++ if (sc->ps_enabled && + !(sc->ps_flags & (PS_WAIT_FOR_BEACON | + PS_WAIT_FOR_CAB | + PS_WAIT_FOR_PSPOLL_DATA | +@@ -163,13 +180,13 @@ static void __ath_cancel_work(struct ath + #endif + } + +-static void ath_cancel_work(struct ath_softc *sc) ++void ath_cancel_work(struct ath_softc *sc) + { + __ath_cancel_work(sc); + cancel_work_sync(&sc->hw_reset_work); + } + +-static void ath_restart_work(struct ath_softc *sc) ++void ath_restart_work(struct ath_softc *sc) + { + ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0); + +@@ -487,6 +504,8 @@ void ath9k_tasklet(unsigned long data) + ath_tx_edma_tasklet(sc); + else + ath_tx_tasklet(sc); ++ ++ wake_up(&sc->tx_wait); } - if (!internal) { -- txq->axq_depth++; -- if (bf_is_ampdu_not_probing(bf)) -- txq->axq_ampdu_depth++; -+ while (bf) { -+ txq->axq_depth++; -+ if (bf_is_ampdu_not_probing(bf)) -+ txq->axq_ampdu_depth++; + ath9k_btcoex_handle_interrupt(sc, status); +@@ -579,7 +598,8 @@ irqreturn_t ath_isr(int irq, void *dev) + + goto chip_reset; + } +-#ifdef CONFIG_PM_SLEEP + -+ bf = bf->bf_lastbf->bf_next; -+ } ++#ifdef CONFIG_ATH9K_WOW + if (status & ATH9K_INT_BMISS) { + if (atomic_read(&sc->wow_sleep_proc_intr) == 0) { + ath_dbg(common, ANY, "during WoW we got a BMISS\n"); +@@ -588,6 +608,8 @@ irqreturn_t ath_isr(int irq, void *dev) + } } + #endif ++ ++ + if (status & ATH9K_INT_SWBA) + tasklet_schedule(&sc->bcon_tasklet); + +@@ -627,7 +649,7 @@ chip_reset: + #undef SCHED_INTR + } + +-static int ath_reset(struct ath_softc *sc) ++int ath_reset(struct ath_softc *sc) + { + int r; + +@@ -1817,13 +1839,31 @@ static void ath9k_set_coverage_class(str + mutex_unlock(&sc->mutex); } ---- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c -@@ -1183,7 +1183,7 @@ static int ath9k_htc_config(struct ieee8 - mutex_lock(&priv->htc_pm_lock); ++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; + } - priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); -- if (priv->ps_idle) -+ if (!priv->ps_idle) - chip_reset = true; +-#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 + #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; + } + } + +--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c +@@ -812,7 +812,7 @@ static s32 brcmf_p2p_run_escan(struct br + struct ieee80211_channel *chan = request->channels[i]; + + if (chan->flags & (IEEE80211_CHAN_RADAR | +- IEEE80211_CHAN_PASSIVE_SCAN)) ++ IEEE80211_CHAN_NO_IR)) + continue; + + chanspecs[i] = channel_to_chanspec(&p2p->cfg->d11inf, +--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c ++++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +@@ -202,9 +202,9 @@ static struct ieee80211_supported_band _ + + /* This is to override regulatory domains defined in cfg80211 module (reg.c) + * By default world regulatory domain defined in reg.c puts the flags +- * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for +- * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't +- * start p2p operations on 5GHz channels. All the changes in world regulatory ++ * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165). ++ * With respect to these flags, wpa_supplicant doesn't * start p2p ++ * operations on 5GHz channels. All the changes in world regulatory + * domain are to be done here. + */ + static const struct ieee80211_regdomain brcmf_regdom = { +@@ -5197,10 +5197,10 @@ static s32 brcmf_construct_reginfo(struc + if (channel & WL_CHAN_RADAR) + band_chan_arr[index].flags |= + (IEEE80211_CHAN_RADAR | +- IEEE80211_CHAN_NO_IBSS); ++ IEEE80211_CHAN_NO_IR); + if (channel & WL_CHAN_PASSIVE) + band_chan_arr[index].flags |= +- IEEE80211_CHAN_PASSIVE_SCAN; ++ IEEE80211_CHAN_NO_IR; + } + } + if (!update) +--- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c +@@ -59,23 +59,20 @@ + + #define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) + #define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + + #define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + #define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ ++ NL80211_RRF_NO_IR | \ + NL80211_RRF_DFS | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + #define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ ++ NL80211_RRF_NO_IR | \ + NL80211_RRF_DFS | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + #define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + + static const struct ieee80211_regdomain brcms_regdom_x2 = { + .n_reg_rules = 6, +@@ -395,7 +392,7 @@ brcms_c_channel_set_chanspec(struct brcm + brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); + + brcms_b_set_chanspec(wlc->hw, chanspec, +- !!(ch->flags & IEEE80211_CHAN_PASSIVE_SCAN), ++ !!(ch->flags & IEEE80211_CHAN_NO_IR), + &txpwr); + } + +@@ -657,8 +654,8 @@ static void brcms_reg_apply_radar_flags( + */ + 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; + } + } + +@@ -688,14 +685,13 @@ brcms_reg_apply_beaconing_flags(struct w + if (IS_ERR(rule)) + continue; + +- if (!(rule->flags & NL80211_RRF_NO_IBSS)) +- ch->flags &= ~IEEE80211_CHAN_NO_IBSS; +- if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN)) ++ if (!(rule->flags & NL80211_RRF_NO_IR)) ++ ch->flags &= ~IEEE80211_CHAN_NO_IR; ++ if (!(rule->flags & 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; + } + } + } +--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c ++++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c +@@ -125,13 +125,13 @@ static struct ieee80211_channel brcms_2g + CHAN2GHZ(10, 2457, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(11, 2462, IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(12, 2467, +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | ++ IEEE80211_CHAN_NO_IR | + IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(13, 2472, +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | ++ IEEE80211_CHAN_NO_IR | + IEEE80211_CHAN_NO_HT40PLUS), + CHAN2GHZ(14, 2484, +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_IBSS | ++ IEEE80211_CHAN_NO_IR | + IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS | + IEEE80211_CHAN_NO_OFDM) + }; +@@ -144,51 +144,51 @@ static struct ieee80211_channel brcms_5g + CHAN5GHZ(48, IEEE80211_CHAN_NO_HT40PLUS), + /* UNII-2 */ + CHAN5GHZ(52, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(56, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(60, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(64, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), + /* MID */ + CHAN5GHZ(100, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(104, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(108, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(112, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(116, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(120, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(124, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(128, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(132, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40MINUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40MINUS), + CHAN5GHZ(136, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS), ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS), + CHAN5GHZ(140, +- IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | IEEE80211_CHAN_NO_HT40PLUS | ++ IEEE80211_CHAN_RADAR | IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_NO_HT40PLUS | + IEEE80211_CHAN_NO_HT40MINUS), + /* UNII-3 */ + CHAN5GHZ(149, IEEE80211_CHAN_NO_HT40MINUS), +--- a/drivers/net/wireless/cw1200/scan.c ++++ b/drivers/net/wireless/cw1200/scan.c +@@ -197,9 +197,9 @@ void cw1200_scan_work(struct work_struct + if ((*it)->band != first->band) + break; + if (((*it)->flags ^ first->flags) & +- IEEE80211_CHAN_PASSIVE_SCAN) ++ IEEE80211_CHAN_NO_IR) + break; +- if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && ++ if (!(first->flags & IEEE80211_CHAN_NO_IR) && + (*it)->max_power != first->max_power) + break; + } +@@ -210,7 +210,7 @@ void cw1200_scan_work(struct work_struct + else + scan.max_tx_rate = WSM_TRANSMIT_RATE_1; + scan.num_probes = +- (first->flags & IEEE80211_CHAN_PASSIVE_SCAN) ? 0 : 2; ++ (first->flags & IEEE80211_CHAN_NO_IR) ? 0 : 2; + scan.num_ssids = priv->scan.n_ssids; + scan.ssids = &priv->scan.ssids[0]; + scan.num_channels = it - priv->scan.curr; +@@ -233,7 +233,7 @@ void cw1200_scan_work(struct work_struct + } + for (i = 0; i < scan.num_channels; ++i) { + scan.ch[i].number = priv->scan.curr[i]->hw_value; +- if (priv->scan.curr[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) { ++ if (priv->scan.curr[i]->flags & IEEE80211_CHAN_NO_IR) { + scan.ch[i].min_chan_time = 50; + scan.ch[i].max_chan_time = 100; + } else { +@@ -241,7 +241,7 @@ void cw1200_scan_work(struct work_struct + scan.ch[i].max_chan_time = 25; + } + } +- if (!(first->flags & IEEE80211_CHAN_PASSIVE_SCAN) && ++ if (!(first->flags & IEEE80211_CHAN_NO_IR) && + priv->scan.output_power != first->max_power) { + priv->scan.output_power = first->max_power; + wsm_set_output_power(priv, +--- a/drivers/net/wireless/ipw2x00/ipw2100.c ++++ b/drivers/net/wireless/ipw2x00/ipw2100.c +@@ -1934,10 +1934,10 @@ static int ipw2100_wdev_init(struct net_ + bg_band->channels[i].max_power = geo->bg[i].max_power; + if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) + bg_band->channels[i].flags |= +- IEEE80211_CHAN_PASSIVE_SCAN; ++ IEEE80211_CHAN_NO_IR; + if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) + bg_band->channels[i].flags |= +- IEEE80211_CHAN_NO_IBSS; ++ IEEE80211_CHAN_NO_IR; + if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) + bg_band->channels[i].flags |= + IEEE80211_CHAN_RADAR; +--- a/drivers/net/wireless/ipw2x00/ipw2200.c ++++ b/drivers/net/wireless/ipw2x00/ipw2200.c +@@ -11472,10 +11472,10 @@ static int ipw_wdev_init(struct net_devi + bg_band->channels[i].max_power = geo->bg[i].max_power; + if (geo->bg[i].flags & LIBIPW_CH_PASSIVE_ONLY) + bg_band->channels[i].flags |= +- IEEE80211_CHAN_PASSIVE_SCAN; ++ IEEE80211_CHAN_NO_IR; + if (geo->bg[i].flags & LIBIPW_CH_NO_IBSS) + bg_band->channels[i].flags |= +- IEEE80211_CHAN_NO_IBSS; ++ IEEE80211_CHAN_NO_IR; + if (geo->bg[i].flags & LIBIPW_CH_RADAR_DETECT) + bg_band->channels[i].flags |= + IEEE80211_CHAN_RADAR; +@@ -11511,10 +11511,10 @@ static int ipw_wdev_init(struct net_devi + a_band->channels[i].max_power = geo->a[i].max_power; + if (geo->a[i].flags & LIBIPW_CH_PASSIVE_ONLY) + a_band->channels[i].flags |= +- IEEE80211_CHAN_PASSIVE_SCAN; ++ IEEE80211_CHAN_NO_IR; + if (geo->a[i].flags & LIBIPW_CH_NO_IBSS) + a_band->channels[i].flags |= +- IEEE80211_CHAN_NO_IBSS; ++ IEEE80211_CHAN_NO_IR; + if (geo->a[i].flags & LIBIPW_CH_RADAR_DETECT) + a_band->channels[i].flags |= + IEEE80211_CHAN_RADAR; +--- a/drivers/net/wireless/iwlegacy/3945-mac.c ++++ b/drivers/net/wireless/iwlegacy/3945-mac.c +@@ -1595,7 +1595,7 @@ il3945_get_channels_for_scan(struct il_p + * and use long active_dwell time. + */ + if (!is_active || il_is_channel_passive(ch_info) || +- (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) { ++ (chan->flags & IEEE80211_CHAN_NO_IR)) { + scan_ch->type = 0; /* passive */ + if (IL_UCODE_API(il->ucode_ver) == 1) + scan_ch->active_dwell = +--- a/drivers/net/wireless/iwlegacy/4965-mac.c ++++ b/drivers/net/wireless/iwlegacy/4965-mac.c +@@ -805,7 +805,7 @@ il4965_get_channels_for_scan(struct il_p + } + + if (!is_active || il_is_channel_passive(ch_info) || +- (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) ++ (chan->flags & IEEE80211_CHAN_NO_IR)) + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + else + scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; +--- a/drivers/net/wireless/iwlegacy/common.c ++++ b/drivers/net/wireless/iwlegacy/common.c +@@ -3447,10 +3447,10 @@ il_init_geos(struct il_priv *il) + + if (il_is_channel_valid(ch)) { + if (!(ch->flags & EEPROM_CHANNEL_IBSS)) +- geo_ch->flags |= IEEE80211_CHAN_NO_IBSS; ++ geo_ch->flags |= IEEE80211_CHAN_NO_IR; + + if (!(ch->flags & EEPROM_CHANNEL_ACTIVE)) +- geo_ch->flags |= IEEE80211_CHAN_PASSIVE_SCAN; ++ geo_ch->flags |= IEEE80211_CHAN_NO_IR; + + if (ch->flags & EEPROM_CHANNEL_RADAR) + geo_ch->flags |= IEEE80211_CHAN_RADAR; +--- a/drivers/net/wireless/iwlegacy/debug.c ++++ b/drivers/net/wireless/iwlegacy/debug.c +@@ -567,12 +567,12 @@ il_dbgfs_channels_read(struct file *file + flags & IEEE80211_CHAN_RADAR ? + " (IEEE 802.11h required)" : "", + ((channels[i]. +- flags & IEEE80211_CHAN_NO_IBSS) || ++ flags & IEEE80211_CHAN_NO_IR) || + (channels[i]. + flags & IEEE80211_CHAN_RADAR)) ? "" : + ", IBSS", + channels[i]. +- flags & IEEE80211_CHAN_PASSIVE_SCAN ? ++ flags & IEEE80211_CHAN_NO_IR ? + "passive only" : "active/passive"); + } + supp_band = il_get_hw_mode(il, IEEE80211_BAND_5GHZ); +@@ -594,12 +594,12 @@ il_dbgfs_channels_read(struct file *file + flags & IEEE80211_CHAN_RADAR ? + " (IEEE 802.11h required)" : "", + ((channels[i]. +- flags & IEEE80211_CHAN_NO_IBSS) || ++ flags & IEEE80211_CHAN_NO_IR) || + (channels[i]. + flags & IEEE80211_CHAN_RADAR)) ? "" : + ", IBSS", + channels[i]. +- flags & IEEE80211_CHAN_PASSIVE_SCAN ? ++ flags & IEEE80211_CHAN_NO_IR ? + "passive only" : "active/passive"); + } + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); +--- a/drivers/net/wireless/iwlwifi/dvm/debugfs.c ++++ b/drivers/net/wireless/iwlwifi/dvm/debugfs.c +@@ -352,12 +352,12 @@ static ssize_t iwl_dbgfs_channels_read(s + channels[i].max_power, + channels[i].flags & IEEE80211_CHAN_RADAR ? + " (IEEE 802.11h required)" : "", +- ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) ++ ((channels[i].flags & IEEE80211_CHAN_NO_IR) + || (channels[i].flags & + IEEE80211_CHAN_RADAR)) ? "" : + ", IBSS", + channels[i].flags & +- IEEE80211_CHAN_PASSIVE_SCAN ? ++ IEEE80211_CHAN_NO_IR ? + "passive only" : "active/passive"); + } + supp_band = iwl_get_hw_mode(priv, IEEE80211_BAND_5GHZ); +@@ -375,12 +375,12 @@ static ssize_t iwl_dbgfs_channels_read(s + channels[i].max_power, + channels[i].flags & IEEE80211_CHAN_RADAR ? + " (IEEE 802.11h required)" : "", +- ((channels[i].flags & IEEE80211_CHAN_NO_IBSS) ++ ((channels[i].flags & IEEE80211_CHAN_NO_IR) + || (channels[i].flags & + IEEE80211_CHAN_RADAR)) ? "" : + ", IBSS", + channels[i].flags & +- IEEE80211_CHAN_PASSIVE_SCAN ? ++ IEEE80211_CHAN_NO_IR ? + "passive only" : "active/passive"); + } + ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); +--- a/drivers/net/wireless/iwlwifi/dvm/scan.c ++++ b/drivers/net/wireless/iwlwifi/dvm/scan.c +@@ -544,7 +544,7 @@ static int iwl_get_channels_for_scan(str + channel = chan->hw_value; + scan_ch->channel = cpu_to_le16(channel); + +- if (!is_active || (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)) ++ if (!is_active || (chan->flags & IEEE80211_CHAN_NO_IR)) + scan_ch->type = SCAN_CHANNEL_TYPE_PASSIVE; + else + scan_ch->type = SCAN_CHANNEL_TYPE_ACTIVE; +--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c ++++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c +@@ -614,10 +614,10 @@ static int iwl_init_channel_map(struct d + channel->flags = IEEE80211_CHAN_NO_HT40; + + if (!(eeprom_ch->flags & EEPROM_CHANNEL_IBSS)) +- channel->flags |= IEEE80211_CHAN_NO_IBSS; ++ channel->flags |= IEEE80211_CHAN_NO_IR; + + if (!(eeprom_ch->flags & EEPROM_CHANNEL_ACTIVE)) +- channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; ++ channel->flags |= IEEE80211_CHAN_NO_IR; + + if (eeprom_ch->flags & EEPROM_CHANNEL_RADAR) + channel->flags |= IEEE80211_CHAN_RADAR; +--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c ++++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c +@@ -223,10 +223,10 @@ static int iwl_init_channel_map(struct d + channel->flags |= IEEE80211_CHAN_NO_160MHZ; + + if (!(ch_flags & NVM_CHANNEL_IBSS)) +- channel->flags |= IEEE80211_CHAN_NO_IBSS; ++ channel->flags |= IEEE80211_CHAN_NO_IR; + + if (!(ch_flags & NVM_CHANNEL_ACTIVE)) +- channel->flags |= IEEE80211_CHAN_PASSIVE_SCAN; ++ channel->flags |= IEEE80211_CHAN_NO_IR; + + if (ch_flags & NVM_CHANNEL_RADAR) + channel->flags |= IEEE80211_CHAN_RADAR; +--- a/drivers/net/wireless/iwlwifi/mvm/scan.c ++++ b/drivers/net/wireless/iwlwifi/mvm/scan.c +@@ -192,7 +192,7 @@ static void iwl_mvm_scan_fill_channels(s + for (i = 0; i < cmd->channel_count; i++) { + chan->channel = cpu_to_le16(req->channels[i]->hw_value); + chan->type = cpu_to_le32(type); +- if (req->channels[i]->flags & IEEE80211_CHAN_PASSIVE_SCAN) ++ if (req->channels[i]->flags & IEEE80211_CHAN_NO_IR) + chan->type &= cpu_to_le32(~SCAN_CHANNEL_TYPE_ACTIVE); + chan->active_dwell = cpu_to_le16(active_dwell); + chan->passive_dwell = cpu_to_le16(passive_dwell); +@@ -642,7 +642,7 @@ static void iwl_build_channel_cfg(struct + channels->iter_count[index] = cpu_to_le16(1); + channels->iter_interval[index] = 0; + +- if (!(s_band->channels[i].flags & IEEE80211_CHAN_PASSIVE_SCAN)) ++ if (!(s_band->channels[i].flags & IEEE80211_CHAN_NO_IR)) + channels->type[index] |= + cpu_to_le32(IWL_SCAN_OFFLOAD_CHANNEL_ACTIVE); + +--- a/drivers/net/wireless/mac80211_hwsim.c ++++ b/drivers/net/wireless/mac80211_hwsim.c +@@ -159,7 +159,7 @@ static const struct ieee80211_regdomain + .reg_rules = { + REG_RULE(2412-10, 2462+10, 40, 0, 20, 0), + REG_RULE(5725-10, 5850+10, 40, 0, 30, +- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), ++ NL80211_RRF_NO_IR), + } + }; + +@@ -1485,7 +1485,7 @@ static void hw_scan_work(struct work_str + req->channels[hwsim->scan_chan_idx]->center_freq); + + hwsim->tmp_chan = req->channels[hwsim->scan_chan_idx]; +- if (hwsim->tmp_chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || ++ if (hwsim->tmp_chan->flags & IEEE80211_CHAN_NO_IR || + !req->n_ssids) { + dwell = 120; + } else { +--- a/drivers/net/wireless/mwifiex/cfg80211.c ++++ b/drivers/net/wireless/mwifiex/cfg80211.c +@@ -50,24 +50,24 @@ static const struct ieee80211_regdomain + REG_RULE(2412-10, 2462+10, 40, 3, 20, 0), + /* Channel 12 - 13 */ + REG_RULE(2467-10, 2472+10, 20, 3, 20, +- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), ++ NL80211_RRF_NO_IR), + /* Channel 14 */ + REG_RULE(2484-10, 2484+10, 20, 3, 20, +- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | ++ NL80211_RRF_NO_IR | + NL80211_RRF_NO_OFDM), + /* Channel 36 - 48 */ + REG_RULE(5180-10, 5240+10, 40, 3, 20, +- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), ++ NL80211_RRF_NO_IR), + /* Channel 149 - 165 */ + REG_RULE(5745-10, 5825+10, 40, 3, 20, +- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS), ++ NL80211_RRF_NO_IR), + /* Channel 52 - 64 */ + REG_RULE(5260-10, 5320+10, 40, 3, 30, +- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | ++ NL80211_RRF_NO_IR | + NL80211_RRF_DFS), + /* Channel 100 - 140 */ + REG_RULE(5500-10, 5700+10, 40, 3, 30, +- NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS | ++ NL80211_RRF_NO_IR | + NL80211_RRF_DFS), + } + }; +@@ -1968,7 +1968,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiph + user_scan_cfg->chan_list[i].chan_number = chan->hw_value; + user_scan_cfg->chan_list[i].radio_type = chan->band; + +- if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) ++ if (chan->flags & IEEE80211_CHAN_NO_IR) + user_scan_cfg->chan_list[i].scan_type = + MWIFIEX_SCAN_TYPE_PASSIVE; + else +--- a/drivers/net/wireless/mwifiex/scan.c ++++ b/drivers/net/wireless/mwifiex/scan.c +@@ -515,14 +515,14 @@ mwifiex_scan_create_channel_list(struct + scan_chan_list[chan_idx].max_scan_time = + cpu_to_le16((u16) user_scan_in-> + chan_list[0].scan_time); +- else if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) ++ else if (ch->flags & IEEE80211_CHAN_NO_IR) + scan_chan_list[chan_idx].max_scan_time = + cpu_to_le16(adapter->passive_scan_time); + else + scan_chan_list[chan_idx].max_scan_time = + cpu_to_le16(adapter->active_scan_time); + +- if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) ++ if (ch->flags & IEEE80211_CHAN_NO_IR) + scan_chan_list[chan_idx].chan_scan_mode_bitmap + |= MWIFIEX_PASSIVE_SCAN; + else +--- a/drivers/net/wireless/rt2x00/rt2x00lib.h ++++ b/drivers/net/wireless/rt2x00/rt2x00lib.h +@@ -146,7 +146,7 @@ void rt2x00queue_remove_l2pad(struct sk_ + * @local: frame is not from mac80211 + */ + int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, +- bool local); ++ struct ieee80211_sta *sta, bool local); + + /** + * rt2x00queue_update_beacon - Send new beacon from mac80211 +--- a/drivers/net/wireless/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/rt2x00/rt2x00mac.c +@@ -90,7 +90,7 @@ static int rt2x00mac_tx_rts_cts(struct r + frag_skb->data, data_length, tx_info, + (struct ieee80211_rts *)(skb->data)); + +- retval = rt2x00queue_write_tx_frame(queue, skb, true); ++ retval = rt2x00queue_write_tx_frame(queue, skb, NULL, true); + if (retval) { + dev_kfree_skb_any(skb); + rt2x00_warn(rt2x00dev, "Failed to send RTS/CTS frame\n"); +@@ -151,7 +151,7 @@ void rt2x00mac_tx(struct ieee80211_hw *h + goto exit_fail; + } + +- if (unlikely(rt2x00queue_write_tx_frame(queue, skb, false))) ++ if (unlikely(rt2x00queue_write_tx_frame(queue, skb, control->sta, false))) + goto exit_fail; + + /* +--- a/drivers/net/wireless/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/rt2x00/rt2x00queue.c +@@ -635,7 +635,7 @@ static void rt2x00queue_bar_check(struct + } + + int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb, +- bool local) ++ struct ieee80211_sta *sta, bool local) + { + struct ieee80211_tx_info *tx_info; + struct queue_entry *entry; +@@ -649,7 +649,7 @@ int rt2x00queue_write_tx_frame(struct da + * after that we are free to use the skb->cb array + * for our information. + */ +- rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc, NULL); ++ rt2x00queue_create_tx_descriptor(queue->rt2x00dev, skb, &txdesc, sta); + + /* + * All information is retrieved from the skb->cb array, +--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c ++++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c +@@ -416,7 +416,7 @@ static int rtl8187_init_urbs(struct ieee + struct rtl8187_rx_info *info; + int ret = 0; + +- while (skb_queue_len(&priv->rx_queue) < 16) { ++ while (skb_queue_len(&priv->rx_queue) < 32) { + skb = __dev_alloc_skb(RTL8187_MAX_RX, GFP_KERNEL); + if (!skb) { + ret = -ENOMEM; +--- a/drivers/net/wireless/rtlwifi/base.c ++++ b/drivers/net/wireless/rtlwifi/base.c +@@ -1078,8 +1078,8 @@ u8 rtl_is_special_data(struct ieee80211_ + + ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + + SNAP_SIZE + PROTOC_TYPE_SIZE); +- ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); +- /* ether_type = ntohs(ether_type); */ ++ ether_type = be16_to_cpu(*(__be16 *)((u8 *)skb->data + mac_hdr_len + ++ SNAP_SIZE)); + + if (ETH_P_IP == ether_type) { + if (IPPROTO_UDP == ip->protocol) { +--- a/drivers/net/wireless/rtlwifi/regd.c ++++ b/drivers/net/wireless/rtlwifi/regd.c +@@ -59,30 +59,27 @@ static struct country_code_to_enum_rd al + */ + #define RTL819x_2GHZ_CH12_13 \ + REG_RULE(2467-10, 2472+10, 40, 0, 20,\ +- NL80211_RRF_PASSIVE_SCAN) ++ NL80211_RRF_NO_IR) + + #define RTL819x_2GHZ_CH14 \ + REG_RULE(2484-10, 2484+10, 40, 0, 20, \ +- NL80211_RRF_PASSIVE_SCAN | \ ++ NL80211_RRF_NO_IR | \ + NL80211_RRF_NO_OFDM) + + /* 5G chan 36 - chan 64*/ + #define RTL819x_5GHZ_5150_5350 \ + REG_RULE(5150-10, 5350+10, 40, 0, 30, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + + /* 5G chan 100 - chan 165*/ + #define RTL819x_5GHZ_5470_5850 \ + REG_RULE(5470-10, 5850+10, 40, 0, 30, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + + /* 5G chan 149 - chan 165*/ + #define RTL819x_5GHZ_5725_5850 \ + REG_RULE(5725-10, 5850+10, 40, 0, 30, \ +- NL80211_RRF_PASSIVE_SCAN | \ +- NL80211_RRF_NO_IBSS) ++ NL80211_RRF_NO_IR) + + #define RTL819x_5GHZ_ALL \ + (RTL819x_5GHZ_5150_5350, RTL819x_5GHZ_5470_5850) +@@ -185,16 +182,15 @@ static void _rtl_reg_apply_beaconing_fla + *regulatory_hint(). + */ + +- if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) +- ch->flags &= ~IEEE80211_CHAN_NO_IBSS; ++ if (!(reg_rule->flags & NL80211_RRF_NO_IR)) ++ ch->flags &= ~IEEE80211_CHAN_NO_IR; + if (!(reg_rule-> +- flags & NL80211_RRF_PASSIVE_SCAN)) ++ flags & 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; + } + } + } +@@ -219,11 +215,11 @@ static void _rtl_reg_apply_active_scan_f + */ + 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; + } + +@@ -237,17 +233,17 @@ static void _rtl_reg_apply_active_scan_f + 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; + } + } + +@@ -284,8 +280,8 @@ static void _rtl_reg_apply_radar_flags(s + */ + 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; + } + } + +--- a/drivers/net/wireless/ti/wl12xx/scan.c ++++ b/drivers/net/wireless/ti/wl12xx/scan.c +@@ -47,7 +47,7 @@ static int wl1271_get_scan_channels(stru + * In active scans, we only scan channels not + * marked as passive. + */ +- (passive || !(flags & IEEE80211_CHAN_PASSIVE_SCAN))) { ++ (passive || !(flags & IEEE80211_CHAN_NO_IR))) { + wl1271_debug(DEBUG_SCAN, "band %d, center_freq %d ", + req->channels[i]->band, + req->channels[i]->center_freq); +--- a/drivers/net/wireless/ti/wlcore/cmd.c ++++ b/drivers/net/wireless/ti/wlcore/cmd.c +@@ -1688,7 +1688,7 @@ int wlcore_cmd_regdomain_config_locked(s + + if (channel->flags & (IEEE80211_CHAN_DISABLED | + IEEE80211_CHAN_RADAR | +- IEEE80211_CHAN_PASSIVE_SCAN)) ++ IEEE80211_CHAN_NO_IR)) + continue; + + ch_bit_idx = wlcore_get_reg_conf_ch_idx(b, ch); +--- a/drivers/net/wireless/ti/wlcore/main.c ++++ b/drivers/net/wireless/ti/wlcore/main.c +@@ -91,8 +91,7 @@ static void wl1271_reg_notify(struct wip + continue; + + if (ch->flags & IEEE80211_CHAN_RADAR) +- ch->flags |= IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN; ++ ch->flags |= IEEE80211_CHAN_NO_IR; + + } + +--- a/drivers/net/wireless/ti/wlcore/scan.c ++++ b/drivers/net/wireless/ti/wlcore/scan.c +@@ -189,14 +189,14 @@ wlcore_scan_get_channels(struct wl1271 * + flags = req_channels[i]->flags; + + if (force_passive) +- flags |= IEEE80211_CHAN_PASSIVE_SCAN; ++ flags |= IEEE80211_CHAN_NO_IR; + + if ((req_channels[i]->band == band) && + !(flags & IEEE80211_CHAN_DISABLED) && + (!!(flags & IEEE80211_CHAN_RADAR) == radar) && + /* if radar is set, we ignore the passive flag */ + (radar || +- !!(flags & IEEE80211_CHAN_PASSIVE_SCAN) == passive)) { ++ !!(flags & IEEE80211_CHAN_NO_IR) == passive)) { + + + if (flags & IEEE80211_CHAN_RADAR) { +@@ -221,7 +221,7 @@ wlcore_scan_get_channels(struct wl1271 * + (band == IEEE80211_BAND_2GHZ) && + (channels[j].channel >= 12) && + (channels[j].channel <= 14) && +- (flags & IEEE80211_CHAN_PASSIVE_SCAN) && ++ (flags & IEEE80211_CHAN_NO_IR) && + !force_passive) { + /* pactive channels treated as DFS */ + channels[j].flags = SCAN_CHANNEL_FLAGS_DFS; +@@ -244,7 +244,7 @@ wlcore_scan_get_channels(struct wl1271 * + max_dwell_time_active, + flags & IEEE80211_CHAN_RADAR ? + ", DFS" : "", +- flags & IEEE80211_CHAN_PASSIVE_SCAN ? ++ flags & IEEE80211_CHAN_NO_IR ? + ", PASSIVE" : ""); + j++; + } +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -91,9 +91,8 @@ enum ieee80211_band { + * Channel flags set by the regulatory control code. + * + * @IEEE80211_CHAN_DISABLED: This channel is disabled. +- * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted +- * on this channel. +- * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. ++ * @IEEE80211_CHAN_NO_IR: do not initiate radiation, this includes ++ * sending probe requests or beaconing. + * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. + * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel + * is not permitted. +@@ -113,8 +112,8 @@ enum ieee80211_band { + */ + enum ieee80211_channel_flags { + IEEE80211_CHAN_DISABLED = 1<<0, +- IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, +- IEEE80211_CHAN_NO_IBSS = 1<<2, ++ IEEE80211_CHAN_NO_IR = 1<<1, ++ /* hole at 1<<2 */ + IEEE80211_CHAN_RADAR = 1<<3, + IEEE80211_CHAN_NO_HT40PLUS = 1<<4, + IEEE80211_CHAN_NO_HT40MINUS = 1<<5, +@@ -4149,6 +4148,7 @@ void cfg80211_radar_event(struct wiphy * + /** + * cfg80211_cac_event - Channel availability check (CAC) event + * @netdev: network device ++ * @chandef: chandef for the current channel + * @event: type of event + * @gfp: context flags + * +@@ -4157,6 +4157,7 @@ void cfg80211_radar_event(struct wiphy * + * also by full-MAC drivers. + */ + void cfg80211_cac_event(struct net_device *netdev, ++ const struct cfg80211_chan_def *chandef, + enum nl80211_radar_event event, gfp_t gfp); + + +@@ -4282,7 +4283,8 @@ bool cfg80211_reg_can_beacon(struct wiph + * @dev: the device which switched channels + * @chandef: the new channel definition + * +- * Acquires wdev_lock, so must only be called from sleepable driver context! ++ * Caller must acquire wdev_lock, therefore must only be called from sleepable ++ * driver context! + */ + void cfg80211_ch_switch_notify(struct net_device *dev, + struct cfg80211_chan_def *chandef); +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -1508,6 +1508,12 @@ enum nl80211_commands { + * to react to radar events, e.g. initiate a channel switch or leave the + * IBSS network. + * ++ * @NL80211_ATTR_SUPPORT_5_MHZ: A flag indicating that the device supports ++ * 5 MHz channel bandwidth. ++ * ++ * @NL80211_ATTR_SUPPORT_10_MHZ: A flag indicating that the device supports ++ * 10 MHz channel bandwidth. ++ * + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use + */ +@@ -1824,6 +1830,9 @@ enum nl80211_attrs { + + NL80211_ATTR_HANDLE_DFS, + ++ NL80211_ATTR_SUPPORT_5_MHZ, ++ NL80211_ATTR_SUPPORT_10_MHZ, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +@@ -2224,10 +2233,9 @@ enum nl80211_band_attr { + * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz + * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current + * regulatory domain. +- * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is +- * permitted on this channel in current regulatory domain. +- * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted +- * on this channel in current regulatory domain. ++ * @NL80211_FREQUENCY_ATTR_NO_IR: no mechanisms that initiate radiation ++ * are permitted on this channel, this includes sending probe ++ * requests, or modes of operation that require beaconing. + * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory + * on this channel in current regulatory domain. + * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm +@@ -2254,8 +2262,8 @@ enum nl80211_frequency_attr { + __NL80211_FREQUENCY_ATTR_INVALID, + NL80211_FREQUENCY_ATTR_FREQ, + NL80211_FREQUENCY_ATTR_DISABLED, +- NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, +- NL80211_FREQUENCY_ATTR_NO_IBSS, ++ NL80211_FREQUENCY_ATTR_NO_IR, ++ __NL80211_FREQUENCY_ATTR_NO_IBSS, + NL80211_FREQUENCY_ATTR_RADAR, + NL80211_FREQUENCY_ATTR_MAX_TX_POWER, + NL80211_FREQUENCY_ATTR_DFS_STATE, +@@ -2271,6 +2279,9 @@ enum nl80211_frequency_attr { + }; + + #define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER ++#define NL80211_FREQUENCY_ATTR_PASSIVE_SCAN NL80211_FREQUENCY_ATTR_NO_IR ++#define NL80211_FREQUENCY_ATTR_NO_IBSS NL80211_FREQUENCY_ATTR_NO_IR ++#define NL80211_FREQUENCY_ATTR_NO_IR NL80211_FREQUENCY_ATTR_NO_IR + + /** + * enum nl80211_bitrate_attr - bitrate attributes +@@ -2413,8 +2424,9 @@ enum nl80211_sched_scan_match_attr { + * @NL80211_RRF_DFS: DFS support is required to be used + * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links + * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links +- * @NL80211_RRF_PASSIVE_SCAN: passive scan is required +- * @NL80211_RRF_NO_IBSS: no IBSS is allowed ++ * @NL80211_RRF_NO_IR: no mechanisms that initiate radiation are allowed, ++ * this includes probe requests or modes of operation that require ++ * beaconing. + */ + enum nl80211_reg_rule_flags { + NL80211_RRF_NO_OFDM = 1<<0, +@@ -2424,10 +2436,17 @@ enum nl80211_reg_rule_flags { + NL80211_RRF_DFS = 1<<4, + NL80211_RRF_PTP_ONLY = 1<<5, + NL80211_RRF_PTMP_ONLY = 1<<6, +- NL80211_RRF_PASSIVE_SCAN = 1<<7, +- NL80211_RRF_NO_IBSS = 1<<8, ++ NL80211_RRF_NO_IR = 1<<7, ++ __NL80211_RRF_NO_IBSS = 1<<8, + }; + ++#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR ++#define NL80211_RRF_NO_IBSS NL80211_RRF_NO_IR ++#define NL80211_RRF_NO_IR NL80211_RRF_NO_IR ++ ++/* For backport compatibility with older userspace */ ++#define NL80211_RRF_NO_IR_ALL (NL80211_RRF_NO_IR | __NL80211_RRF_NO_IBSS) ++ + /** + * enum nl80211_dfs_regions - regulatory DFS regions + * +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -846,7 +846,7 @@ static int ieee80211_set_probe_resp(stru + if (!resp || !resp_len) + return 1; + +- old = rtnl_dereference(sdata->u.ap.probe_resp); ++ old = sdata_dereference(sdata->u.ap.probe_resp, sdata); + + new = kzalloc(sizeof(struct probe_resp) + resp_len, GFP_KERNEL); + if (!new) +@@ -870,7 +870,8 @@ int ieee80211_assign_beacon(struct ieee8 + int size, err; + u32 changed = BSS_CHANGED_BEACON; + +- old = rtnl_dereference(sdata->u.ap.beacon); ++ old = sdata_dereference(sdata->u.ap.beacon, sdata); ++ + + /* Need to have a beacon head if we don't have one yet */ + if (!params->head && !old) +@@ -947,7 +948,7 @@ static int ieee80211_start_ap(struct wip + BSS_CHANGED_P2P_PS; + int err; + +- old = rtnl_dereference(sdata->u.ap.beacon); ++ old = sdata_dereference(sdata->u.ap.beacon, sdata); + if (old) + return -EALREADY; + +@@ -1001,7 +1002,8 @@ static int ieee80211_start_ap(struct wip + + err = drv_start_ap(sdata->local, sdata); + if (err) { +- old = rtnl_dereference(sdata->u.ap.beacon); ++ old = sdata_dereference(sdata->u.ap.beacon, sdata); ++ + if (old) + kfree_rcu(old, rcu_head); + RCU_INIT_POINTER(sdata->u.ap.beacon, NULL); +@@ -1032,7 +1034,7 @@ static int ieee80211_change_beacon(struc + if (sdata->vif.csa_active) + return -EBUSY; + +- old = rtnl_dereference(sdata->u.ap.beacon); ++ old = sdata_dereference(sdata->u.ap.beacon, sdata); + if (!old) + return -ENOENT; + +@@ -1050,15 +1052,18 @@ static int ieee80211_stop_ap(struct wiph + struct ieee80211_local *local = sdata->local; + struct beacon_data *old_beacon; + struct probe_resp *old_probe_resp; ++ struct cfg80211_chan_def chandef; + +- old_beacon = rtnl_dereference(sdata->u.ap.beacon); ++ old_beacon = sdata_dereference(sdata->u.ap.beacon, sdata); + if (!old_beacon) + return -ENOENT; +- old_probe_resp = rtnl_dereference(sdata->u.ap.probe_resp); ++ old_probe_resp = sdata_dereference(sdata->u.ap.probe_resp, sdata); + + /* abort any running channel switch */ + sdata->vif.csa_active = false; +- cancel_work_sync(&sdata->csa_finalize_work); ++ kfree(sdata->u.ap.next_beacon); ++ sdata->u.ap.next_beacon = NULL; ++ + cancel_work_sync(&sdata->u.ap.request_smps_work); + + /* turn off carrier for this interface and dependent VLANs */ +@@ -1091,8 +1096,10 @@ static int ieee80211_stop_ap(struct wiph + ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); + + if (sdata->wdev.cac_started) { ++ chandef = sdata->vif.bss_conf.chandef; + cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); +- cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, ++ cfg80211_cac_event(sdata->dev, &chandef, ++ NL80211_RADAR_CAC_ABORTED, + GFP_KERNEL); + } + +@@ -1368,7 +1375,7 @@ static int sta_apply_parameters(struct i + changed |= + ieee80211_mps_set_sta_local_pm(sta, + params->local_pm); +- ieee80211_bss_info_change_notify(sdata, changed); ++ ieee80211_mbss_info_change_notify(sdata, changed); + #endif + } + +@@ -1953,7 +1960,7 @@ static int ieee80211_change_bss(struct w + enum ieee80211_band band; + u32 changed = 0; + +- if (!rtnl_dereference(sdata->u.ap.beacon)) ++ if (!sdata_dereference(sdata->u.ap.beacon, sdata)) + return -ENOENT; + + band = ieee80211_get_sdata_band(sdata); +@@ -2964,27 +2971,33 @@ void ieee80211_csa_finalize_work(struct + struct ieee80211_local *local = sdata->local; + int err, changed = 0; + ++ sdata_lock(sdata); ++ /* AP might have been stopped while waiting for the lock. */ ++ if (!sdata->vif.csa_active) ++ goto unlock; ++ + if (!ieee80211_sdata_running(sdata)) +- return; ++ goto unlock; + + sdata->radar_required = sdata->csa_radar_required; +- err = ieee80211_vif_change_channel(sdata, &local->csa_chandef, +- &changed); ++ err = ieee80211_vif_change_channel(sdata, &changed); + if (WARN_ON(err < 0)) +- return; ++ goto unlock; + + if (!local->use_chanctx) { +- local->_oper_chandef = local->csa_chandef; ++ local->_oper_chandef = sdata->csa_chandef; + ieee80211_hw_config(local, 0); + } + + ieee80211_bss_info_change_notify(sdata, changed); + ++ sdata->vif.csa_active = false; + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP: + err = ieee80211_assign_beacon(sdata, sdata->u.ap.next_beacon); + if (err < 0) +- return; ++ goto unlock; ++ + changed |= err; + kfree(sdata->u.ap.next_beacon); + sdata->u.ap.next_beacon = NULL; +@@ -2998,20 +3011,22 @@ void ieee80211_csa_finalize_work(struct + case NL80211_IFTYPE_MESH_POINT: + err = ieee80211_mesh_finish_csa(sdata); + if (err < 0) +- return; ++ goto unlock; + break; + #endif + default: + WARN_ON(1); +- return; ++ goto unlock; + } +- sdata->vif.csa_active = false; + + ieee80211_wake_queues_by_reason(&sdata->local->hw, + IEEE80211_MAX_QUEUE_MAP, + IEEE80211_QUEUE_STOP_REASON_CSA); + +- cfg80211_ch_switch_notify(sdata->dev, &local->csa_chandef); ++ cfg80211_ch_switch_notify(sdata->dev, &sdata->csa_chandef); ++ ++unlock: ++ sdata_unlock(sdata); + } + + static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev, +@@ -3024,6 +3039,8 @@ static int ieee80211_channel_switch(stru + struct ieee80211_if_mesh __maybe_unused *ifmsh; + int err, num_chanctx; + ++ lockdep_assert_held(&sdata->wdev.mtx); ++ + if (!list_empty(&local->roc_list) || local->scanning) + return -EBUSY; + +@@ -3120,9 +3137,17 @@ static int ieee80211_channel_switch(stru + params->chandef.chan->band) + return -EINVAL; + ++ ifmsh->chsw_init = true; ++ if (!ifmsh->pre_value) ++ ifmsh->pre_value = 1; ++ else ++ ifmsh->pre_value++; ++ + err = ieee80211_mesh_csa_beacon(sdata, params, true); +- if (err < 0) ++ if (err < 0) { ++ ifmsh->chsw_init = false; + return err; ++ } + break; + #endif + default: +@@ -3136,7 +3161,7 @@ static int ieee80211_channel_switch(stru + IEEE80211_MAX_QUEUE_MAP, + IEEE80211_QUEUE_STOP_REASON_CSA); + +- local->csa_chandef = params->chandef; ++ sdata->csa_chandef = params->chandef; + sdata->vif.csa_active = true; + + ieee80211_bss_info_change_notify(sdata, err); +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -749,6 +749,7 @@ static void ieee80211_do_stop(struct iee + u32 hw_reconf_flags = 0; + int i, flushed; + struct ps_data *ps; ++ struct cfg80211_chan_def chandef; + + clear_bit(SDATA_STATE_RUNNING, &sdata->state); + +@@ -828,11 +829,13 @@ static void ieee80211_do_stop(struct iee + cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); + + if (sdata->wdev.cac_started) { ++ chandef = sdata->vif.bss_conf.chandef; + WARN_ON(local->suspended); + mutex_lock(&local->iflist_mtx); + ieee80211_vif_release_channel(sdata); + mutex_unlock(&local->iflist_mtx); +- cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_ABORTED, ++ cfg80211_cac_event(sdata->dev, &chandef, ++ NL80211_RADAR_CAC_ABORTED, + GFP_KERNEL); + } + +@@ -1340,7 +1343,6 @@ static void ieee80211_setup_sdata(struct + sdata->vif.bss_conf.bssid = NULL; + break; + case NL80211_IFTYPE_AP_VLAN: +- break; + case NL80211_IFTYPE_P2P_DEVICE: + sdata->vif.bss_conf.bssid = sdata->vif.addr; + break; +--- a/net/mac80211/mlme.c ++++ b/net/mac80211/mlme.c +@@ -886,8 +886,7 @@ static void ieee80211_chswitch_work(stru + if (!ifmgd->associated) + goto out; + +- ret = ieee80211_vif_change_channel(sdata, &local->csa_chandef, +- &changed); ++ ret = ieee80211_vif_change_channel(sdata, &changed); + if (ret) { + sdata_info(sdata, + "vif channel switch failed, disconnecting\n"); +@@ -897,7 +896,7 @@ static void ieee80211_chswitch_work(stru + } + + if (!local->use_chanctx) { +- local->_oper_chandef = local->csa_chandef; ++ local->_oper_chandef = sdata->csa_chandef; + /* Call "hw_config" only if doing sw channel switch. + * Otherwise update the channel directly + */ +@@ -908,7 +907,7 @@ static void ieee80211_chswitch_work(stru + } + + /* XXX: shouldn't really modify cfg80211-owned data! */ +- ifmgd->associated->channel = local->csa_chandef.chan; ++ ifmgd->associated->channel = sdata->csa_chandef.chan; + + /* XXX: wait for a beacon first? */ + ieee80211_wake_queues_by_reason(&local->hw, +@@ -1035,7 +1034,7 @@ ieee80211_sta_process_chanswitch(struct + } + mutex_unlock(&local->chanctx_mtx); + +- local->csa_chandef = csa_ie.chandef; ++ sdata->csa_chandef = csa_ie.chandef; + + if (csa_ie.mode) + ieee80211_stop_queues_by_reason(&local->hw, +@@ -1398,10 +1397,12 @@ void ieee80211_dfs_cac_timer_work(struct + struct ieee80211_sub_if_data *sdata = + container_of(delayed_work, struct ieee80211_sub_if_data, + dfs_cac_timer_work); ++ struct cfg80211_chan_def chandef = sdata->vif.bss_conf.chandef; + + ieee80211_vif_release_channel(sdata); +- +- cfg80211_cac_event(sdata->dev, NL80211_RADAR_CAC_FINISHED, GFP_KERNEL); ++ cfg80211_cac_event(sdata->dev, &chandef, ++ NL80211_RADAR_CAC_FINISHED, ++ GFP_KERNEL); + } + + /* MLME */ +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -729,9 +729,7 @@ static void ieee80211_release_reorder_fr + lockdep_assert_held(&tid_agg_rx->reorder_lock); + + while (ieee80211_sn_less(tid_agg_rx->head_seq_num, head_seq_num)) { +- index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, +- tid_agg_rx->ssn) % +- tid_agg_rx->buf_size; ++ index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, + frames); + } +@@ -757,8 +755,7 @@ static void ieee80211_sta_reorder_releas + lockdep_assert_held(&tid_agg_rx->reorder_lock); + + /* release the buffer until next missing frame */ +- index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, +- tid_agg_rx->ssn) % tid_agg_rx->buf_size; ++ index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + if (!tid_agg_rx->reorder_buf[index] && + tid_agg_rx->stored_mpdu_num) { + /* +@@ -793,15 +790,11 @@ static void ieee80211_sta_reorder_releas + } else while (tid_agg_rx->reorder_buf[index]) { + ieee80211_release_reorder_frame(sdata, tid_agg_rx, index, + frames); +- index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, +- tid_agg_rx->ssn) % +- tid_agg_rx->buf_size; ++ index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + } + + if (tid_agg_rx->stored_mpdu_num) { +- j = index = ieee80211_sn_sub(tid_agg_rx->head_seq_num, +- tid_agg_rx->ssn) % +- tid_agg_rx->buf_size; ++ j = index = tid_agg_rx->head_seq_num % tid_agg_rx->buf_size; + + for (; j != (index - 1) % tid_agg_rx->buf_size; + j = (j + 1) % tid_agg_rx->buf_size) { +@@ -861,8 +854,7 @@ static bool ieee80211_sta_manage_reorder + + /* Now the new frame is always in the range of the reordering buffer */ + +- index = ieee80211_sn_sub(mpdu_seq_num, +- tid_agg_rx->ssn) % tid_agg_rx->buf_size; ++ index = mpdu_seq_num % tid_agg_rx->buf_size; + + /* check if we already stored this frame */ + if (tid_agg_rx->reorder_buf[index]) { +@@ -911,7 +903,8 @@ static void ieee80211_rx_reorder_ampdu(s + u16 sc; + u8 tid, ack_policy; + +- if (!ieee80211_is_data_qos(hdr->frame_control)) ++ if (!ieee80211_is_data_qos(hdr->frame_control) || ++ is_multicast_ether_addr(hdr->addr1)) + goto dont_reorder; + + /* +--- a/net/mac80211/scan.c ++++ b/net/mac80211/scan.c +@@ -526,7 +526,7 @@ static int __ieee80211_start_scan(struct + ieee80211_hw_config(local, 0); + + if ((req->channels[0]->flags & +- IEEE80211_CHAN_PASSIVE_SCAN) || ++ IEEE80211_CHAN_NO_IR) || + !local->scan_req->n_ssids) { + next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; + } else { +@@ -572,7 +572,7 @@ ieee80211_scan_get_channel_time(struct i + * TODO: channel switching also consumes quite some time, + * add that delay as well to get a better estimation + */ +- if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) ++ if (chan->flags & IEEE80211_CHAN_NO_IR) + return IEEE80211_PASSIVE_CHANNEL_TIME; + return IEEE80211_PROBE_DELAY + IEEE80211_CHANNEL_TIME; + } +@@ -696,7 +696,7 @@ static void ieee80211_scan_state_set_cha + * + * In any case, it is not necessary for a passive scan. + */ +- if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN || ++ if (chan->flags & IEEE80211_CHAN_NO_IR || + !local->scan_req->n_ssids) { + *next_delay = IEEE80211_PASSIVE_CHANNEL_TIME; + local->next_scan_state = SCAN_DECISION; +@@ -881,7 +881,7 @@ int ieee80211_request_ibss_scan(struct i + struct ieee80211_channel *tmp_ch = + &local->hw.wiphy->bands[band]->channels[i]; + +- if (tmp_ch->flags & (IEEE80211_CHAN_NO_IBSS | ++ if (tmp_ch->flags & (IEEE80211_CHAN_NO_IR | + IEEE80211_CHAN_DISABLED)) + continue; + +@@ -895,7 +895,7 @@ int ieee80211_request_ibss_scan(struct i + + local->int_scan_req->n_channels = n_ch; + } else { +- if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IBSS | ++ if (WARN_ON_ONCE(chan->flags & (IEEE80211_CHAN_NO_IR | + IEEE80211_CHAN_DISABLED))) + goto unlock; + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1728,8 +1728,7 @@ netdev_tx_t ieee80211_monitor_start_xmit + * radar detection by itself. We can do that later by adding a + * monitor flag interfaces used for AP support. + */ +- if ((chan->flags & (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_RADAR | +- IEEE80211_CHAN_PASSIVE_SCAN))) ++ if ((chan->flags & (IEEE80211_CHAN_NO_IR | IEEE80211_CHAN_RADAR))) + goto fail_rcu; + + ieee80211_xmit(sdata, skb, chan->band); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -2259,14 +2259,17 @@ u64 ieee80211_calculate_rx_timestamp(str + void ieee80211_dfs_cac_cancel(struct ieee80211_local *local) + { + struct ieee80211_sub_if_data *sdata; ++ struct cfg80211_chan_def chandef; + + mutex_lock(&local->iflist_mtx); + list_for_each_entry(sdata, &local->interfaces, list) { + cancel_delayed_work_sync(&sdata->dfs_cac_timer_work); + + if (sdata->wdev.cac_started) { ++ chandef = sdata->vif.bss_conf.chandef; + ieee80211_vif_release_channel(sdata); + cfg80211_cac_event(sdata->dev, ++ &chandef, + NL80211_RADAR_CAC_ABORTED, + GFP_KERNEL); + } +@@ -2459,14 +2462,9 @@ int ieee80211_send_action_csa(struct iee + WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00; + put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */ + pos += 2; +- if (!ifmsh->pre_value) +- ifmsh->pre_value = 1; +- else +- ifmsh->pre_value++; + pre_value = cpu_to_le16(ifmsh->pre_value); + memcpy(pos, &pre_value, 2); /* Precedence Value */ + pos += 2; +- ifmsh->chsw_init = true; + } + + ieee80211_tx_skb(sdata, skb); +--- a/net/wireless/chan.c ++++ b/net/wireless/chan.c +@@ -277,6 +277,32 @@ void cfg80211_set_dfs_state(struct wiphy + width, dfs_state); + } + ++static u32 cfg80211_get_start_freq(u32 center_freq, ++ u32 bandwidth) ++{ ++ u32 start_freq; ++ ++ if (bandwidth <= 20) ++ start_freq = center_freq; ++ else ++ start_freq = center_freq - bandwidth/2 + 10; ++ ++ return start_freq; ++} ++ ++static u32 cfg80211_get_end_freq(u32 center_freq, ++ u32 bandwidth) ++{ ++ u32 end_freq; ++ ++ if (bandwidth <= 20) ++ end_freq = center_freq; ++ else ++ end_freq = center_freq + bandwidth/2 - 10; ++ ++ return end_freq; ++} ++ + static int cfg80211_get_chans_dfs_required(struct wiphy *wiphy, + u32 center_freq, + u32 bandwidth) +@@ -284,13 +310,8 @@ static int cfg80211_get_chans_dfs_requir + struct ieee80211_channel *c; + u32 freq, start_freq, end_freq; + +- if (bandwidth <= 20) { +- start_freq = center_freq; +- end_freq = center_freq; +- } else { +- start_freq = center_freq - bandwidth/2 + 10; +- end_freq = center_freq + bandwidth/2 - 10; +- } ++ start_freq = cfg80211_get_start_freq(center_freq, bandwidth); ++ end_freq = cfg80211_get_end_freq(center_freq, bandwidth); + + for (freq = start_freq; freq <= end_freq; freq += 20) { + c = ieee80211_get_channel(wiphy, freq); +@@ -330,33 +351,159 @@ int cfg80211_chandef_dfs_required(struct + } + EXPORT_SYMBOL(cfg80211_chandef_dfs_required); + +-static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, +- u32 center_freq, u32 bandwidth, +- u32 prohibited_flags) ++static int cfg80211_get_chans_dfs_usable(struct wiphy *wiphy, ++ u32 center_freq, ++ u32 bandwidth) + { + struct ieee80211_channel *c; + u32 freq, start_freq, end_freq; ++ int count = 0; + +- if (bandwidth <= 20) { +- start_freq = center_freq; +- end_freq = center_freq; +- } else { +- start_freq = center_freq - bandwidth/2 + 10; +- end_freq = center_freq + bandwidth/2 - 10; ++ start_freq = cfg80211_get_start_freq(center_freq, bandwidth); ++ end_freq = cfg80211_get_end_freq(center_freq, bandwidth); ++ ++ /* ++ * Check entire range of channels for the bandwidth. ++ * Check all channels are DFS channels (DFS_USABLE or ++ * DFS_AVAILABLE). Return number of usable channels ++ * (require CAC). Allow DFS and non-DFS channel mix. ++ */ ++ for (freq = start_freq; freq <= end_freq; freq += 20) { ++ c = ieee80211_get_channel(wiphy, freq); ++ if (!c) ++ return -EINVAL; ++ ++ if (c->flags & IEEE80211_CHAN_DISABLED) ++ return -EINVAL; ++ ++ if (c->flags & IEEE80211_CHAN_RADAR) { ++ if (c->dfs_state == NL80211_DFS_UNAVAILABLE) ++ return -EINVAL; ++ ++ if (c->dfs_state == NL80211_DFS_USABLE) ++ count++; ++ } ++ } ++ ++ return count; ++} ++ ++bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, ++ const struct cfg80211_chan_def *chandef) ++{ ++ int width; ++ int r1, r2 = 0; ++ ++ if (WARN_ON(!cfg80211_chandef_valid(chandef))) ++ return false; ++ ++ width = cfg80211_chandef_get_width(chandef); ++ if (width < 0) ++ return false; ++ ++ r1 = cfg80211_get_chans_dfs_usable(wiphy, chandef->center_freq1, ++ width); ++ ++ if (r1 < 0) ++ return false; ++ ++ switch (chandef->width) { ++ case NL80211_CHAN_WIDTH_80P80: ++ WARN_ON(!chandef->center_freq2); ++ r2 = cfg80211_get_chans_dfs_usable(wiphy, ++ chandef->center_freq2, ++ width); ++ if (r2 < 0) ++ return false; ++ break; ++ default: ++ WARN_ON(chandef->center_freq2); ++ break; + } + ++ return (r1 + r2 > 0); ++} ++ ++ ++static bool cfg80211_get_chans_dfs_available(struct wiphy *wiphy, ++ u32 center_freq, ++ u32 bandwidth) ++{ ++ struct ieee80211_channel *c; ++ u32 freq, start_freq, end_freq; ++ ++ start_freq = cfg80211_get_start_freq(center_freq, bandwidth); ++ end_freq = cfg80211_get_end_freq(center_freq, bandwidth); ++ ++ /* ++ * Check entire range of channels for the bandwidth. ++ * If any channel in between is disabled or has not ++ * had gone through CAC return false ++ */ + for (freq = start_freq; freq <= end_freq; freq += 20) { + c = ieee80211_get_channel(wiphy, freq); + if (!c) + return false; + +- /* check for radar flags */ +- if ((prohibited_flags & c->flags & IEEE80211_CHAN_RADAR) && ++ if (c->flags & IEEE80211_CHAN_DISABLED) ++ return false; ++ ++ if ((c->flags & IEEE80211_CHAN_RADAR) && + (c->dfs_state != NL80211_DFS_AVAILABLE)) + return false; ++ } ++ ++ return true; ++} ++ ++static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy, ++ const struct cfg80211_chan_def *chandef) ++{ ++ int width; ++ int r; ++ ++ if (WARN_ON(!cfg80211_chandef_valid(chandef))) ++ return false; + +- /* check for the other flags */ +- if (c->flags & prohibited_flags & ~IEEE80211_CHAN_RADAR) ++ width = cfg80211_chandef_get_width(chandef); ++ if (width < 0) ++ return false; ++ ++ r = cfg80211_get_chans_dfs_available(wiphy, chandef->center_freq1, ++ width); ++ ++ /* If any of channels unavailable for cf1 just return */ ++ if (!r) ++ return r; ++ ++ switch (chandef->width) { ++ case NL80211_CHAN_WIDTH_80P80: ++ WARN_ON(!chandef->center_freq2); ++ r = cfg80211_get_chans_dfs_available(wiphy, ++ chandef->center_freq2, ++ width); ++ default: ++ WARN_ON(chandef->center_freq2); ++ break; ++ } ++ ++ return r; ++} ++ ++ ++static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy, ++ u32 center_freq, u32 bandwidth, ++ u32 prohibited_flags) ++{ ++ struct ieee80211_channel *c; ++ u32 freq, start_freq, end_freq; ++ ++ start_freq = cfg80211_get_start_freq(center_freq, bandwidth); ++ end_freq = cfg80211_get_end_freq(center_freq, bandwidth); ++ ++ for (freq = start_freq; freq <= end_freq; freq += 20) { ++ c = ieee80211_get_channel(wiphy, freq); ++ if (!c || c->flags & prohibited_flags) + return false; + } + +@@ -462,14 +609,19 @@ bool cfg80211_reg_can_beacon(struct wiph + struct cfg80211_chan_def *chandef) + { + bool res; ++ u32 prohibited_flags = IEEE80211_CHAN_DISABLED | ++ IEEE80211_CHAN_NO_IR | ++ IEEE80211_CHAN_RADAR; + + trace_cfg80211_reg_can_beacon(wiphy, chandef); + +- res = cfg80211_chandef_usable(wiphy, chandef, +- IEEE80211_CHAN_DISABLED | +- IEEE80211_CHAN_PASSIVE_SCAN | +- IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_RADAR); ++ if (cfg80211_chandef_dfs_required(wiphy, chandef) > 0 && ++ cfg80211_chandef_dfs_available(wiphy, chandef)) { ++ /* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */ ++ prohibited_flags = IEEE80211_CHAN_DISABLED; ++ } ++ ++ res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags); + + trace_cfg80211_return_bool(res); + return res; +--- a/net/wireless/core.h ++++ b/net/wireless/core.h +@@ -382,6 +382,19 @@ int cfg80211_can_use_iftype_chan(struct + enum cfg80211_chan_mode chanmode, + u8 radar_detect); + ++/** ++ * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable ++ * @wiphy: the wiphy to validate against ++ * @chandef: the channel definition to check ++ * ++ * Checks if chandef is usable and we can/need start CAC on such channel. ++ * ++ * Return: Return true if all channels available and at least ++ * one channel require CAC (NL80211_DFS_USABLE) ++ */ ++bool cfg80211_chandef_dfs_usable(struct wiphy *wiphy, ++ const struct cfg80211_chan_def *chandef); ++ + void cfg80211_set_dfs_state(struct wiphy *wiphy, + const struct cfg80211_chan_def *chandef, + enum nl80211_dfs_state dfs_state); +--- a/net/wireless/genregdb.awk ++++ b/net/wireless/genregdb.awk +@@ -107,10 +107,13 @@ active && /^[ \t]*\(/ { + } else if (flagarray[arg] == "PTMP-ONLY") { + flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | " + } else if (flagarray[arg] == "PASSIVE-SCAN") { +- flags = flags "\n\t\t\tNL80211_RRF_PASSIVE_SCAN | " ++ flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " + } else if (flagarray[arg] == "NO-IBSS") { +- flags = flags "\n\t\t\tNL80211_RRF_NO_IBSS | " ++ flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " ++ } else if (flagarray[arg] == "NO-IR") { ++ flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " + } ++ + } + flags = flags "0" + printf "\t\tREG_RULE(%d, %d, %d, %d, %d, %s),\n", start, end, bw, gain, power, flags +--- a/net/wireless/ibss.c ++++ b/net/wireless/ibss.c +@@ -274,7 +274,7 @@ int cfg80211_ibss_wext_join(struct cfg80 + + for (i = 0; i < sband->n_channels; i++) { + chan = &sband->channels[i]; +- if (chan->flags & IEEE80211_CHAN_NO_IBSS) ++ if (chan->flags & IEEE80211_CHAN_NO_IR) + continue; + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; +@@ -345,7 +345,7 @@ int cfg80211_ibss_wext_siwfreq(struct ne + chan = ieee80211_get_channel(wdev->wiphy, freq); + if (!chan) + return -EINVAL; +- if (chan->flags & IEEE80211_CHAN_NO_IBSS || ++ if (chan->flags & IEEE80211_CHAN_NO_IR || + chan->flags & IEEE80211_CHAN_DISABLED) + return -EINVAL; + } +--- a/net/wireless/mesh.c ++++ b/net/wireless/mesh.c +@@ -141,8 +141,7 @@ int __cfg80211_join_mesh(struct cfg80211 + + for (i = 0; i < sband->n_channels; i++) { + chan = &sband->channels[i]; +- if (chan->flags & (IEEE80211_CHAN_NO_IBSS | +- IEEE80211_CHAN_PASSIVE_SCAN | ++ if (chan->flags & (IEEE80211_CHAN_NO_IR | + IEEE80211_CHAN_DISABLED | + IEEE80211_CHAN_RADAR)) + continue; +--- a/net/wireless/mlme.c ++++ b/net/wireless/mlme.c +@@ -763,12 +763,12 @@ void cfg80211_radar_event(struct wiphy * + EXPORT_SYMBOL(cfg80211_radar_event); + + void cfg80211_cac_event(struct net_device *netdev, ++ const struct cfg80211_chan_def *chandef, + enum nl80211_radar_event event, gfp_t gfp) + { + struct wireless_dev *wdev = netdev->ieee80211_ptr; + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); +- struct cfg80211_chan_def chandef; + unsigned long timeout; + + trace_cfg80211_cac_event(netdev, event); +@@ -779,14 +779,12 @@ void cfg80211_cac_event(struct net_devic + if (WARN_ON(!wdev->channel)) + return; + +- cfg80211_chandef_create(&chandef, wdev->channel, NL80211_CHAN_NO_HT); +- + switch (event) { + case NL80211_RADAR_CAC_FINISHED: + timeout = wdev->cac_start_time + + msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS); + WARN_ON(!time_after_eq(jiffies, timeout)); +- cfg80211_set_dfs_state(wiphy, &chandef, NL80211_DFS_AVAILABLE); ++ cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE); + break; + case NL80211_RADAR_CAC_ABORTED: + break; +@@ -796,6 +794,6 @@ void cfg80211_cac_event(struct net_devic + } + wdev->cac_started = false; + +- nl80211_radar_notify(rdev, &chandef, event, netdev, gfp); ++ nl80211_radar_notify(rdev, chandef, event, netdev, gfp); + } + EXPORT_SYMBOL(cfg80211_cac_event); +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -545,12 +545,12 @@ static int nl80211_msg_put_channel(struc + if ((chan->flags & IEEE80211_CHAN_DISABLED) && + nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) + goto nla_put_failure; +- if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && +- nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN)) +- goto nla_put_failure; +- if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && +- nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) +- goto nla_put_failure; ++ if (chan->flags & IEEE80211_CHAN_NO_IR) { ++ if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IR)) ++ goto nla_put_failure; ++ if (nla_put_flag(msg, __NL80211_FREQUENCY_ATTR_NO_IBSS)) ++ goto nla_put_failure; ++ } + if (chan->flags & IEEE80211_CHAN_RADAR) { + if (nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) + goto nla_put_failure; +@@ -1229,7 +1229,8 @@ static int nl80211_send_wiphy(struct cfg + nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) + goto nla_put_failure; + if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_5_10_MHZ) && +- nla_put_flag(msg, WIPHY_FLAG_SUPPORTS_5_10_MHZ)) ++ (nla_put_flag(msg, NL80211_ATTR_SUPPORT_5_MHZ) || ++ nla_put_flag(msg, NL80211_ATTR_SUPPORT_10_MHZ))) + goto nla_put_failure; + + state->split_start++; +@@ -2170,7 +2171,7 @@ static inline u64 wdev_id(struct wireles + } + + static int nl80211_send_chandef(struct sk_buff *msg, +- struct cfg80211_chan_def *chandef) ++ const struct cfg80211_chan_def *chandef) + { + WARN_ON(!cfg80211_chandef_valid(chandef)); + +@@ -3219,6 +3220,7 @@ static int nl80211_start_ap(struct sk_bu + return PTR_ERR(params.acl); + } + ++ wdev_lock(wdev); + err = rdev_start_ap(rdev, dev, ¶ms); + if (!err) { + wdev->preset_chandef = params.chandef; +@@ -3227,6 +3229,7 @@ static int nl80211_start_ap(struct sk_bu + wdev->ssid_len = params.ssid_len; + memcpy(wdev->ssid, params.ssid, wdev->ssid_len); + } ++ wdev_unlock(wdev); + + kfree(params.acl); + +@@ -3255,7 +3258,11 @@ static int nl80211_set_beacon(struct sk_ + if (err) + return err; + +- return rdev_change_beacon(rdev, dev, ¶ms); ++ wdev_lock(wdev); ++ err = rdev_change_beacon(rdev, dev, ¶ms); ++ wdev_unlock(wdev); ++ ++ return err; + } + + static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) +@@ -4461,7 +4468,9 @@ static int nl80211_set_bss(struct sk_buf + { + struct cfg80211_registered_device *rdev = info->user_ptr[0]; + struct net_device *dev = info->user_ptr[1]; ++ struct wireless_dev *wdev = dev->ieee80211_ptr; + struct bss_parameters params; ++ int err; + + memset(¶ms, 0, sizeof(params)); + /* default to not changing parameters */ +@@ -4527,7 +4536,11 @@ static int nl80211_set_bss(struct sk_buf + dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) + return -EOPNOTSUPP; + +- return rdev_change_bss(rdev, dev, ¶ms); ++ wdev_lock(wdev); ++ err = rdev_change_bss(rdev, dev, ¶ms); ++ wdev_unlock(wdev); ++ ++ return err; + } + + static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { +@@ -5653,7 +5666,7 @@ static int nl80211_start_radar_detection + if (err == 0) + return -EINVAL; + +- if (chandef.chan->dfs_state != NL80211_DFS_USABLE) ++ if (!cfg80211_chandef_dfs_usable(wdev->wiphy, &chandef)) + return -EINVAL; + + if (!rdev->ops->start_radar_detection) +@@ -5793,7 +5806,11 @@ skip_beacons: + if (info->attrs[NL80211_ATTR_CH_SWITCH_BLOCK_TX]) + params.block_tx = true; + +- return rdev_channel_switch(rdev, dev, ¶ms); ++ wdev_lock(wdev); ++ err = rdev_channel_switch(rdev, dev, ¶ms); ++ wdev_unlock(wdev); ++ ++ return err; + } + + static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, +@@ -10809,21 +10826,18 @@ void cfg80211_ch_switch_notify(struct ne + struct wiphy *wiphy = wdev->wiphy; + struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); + +- trace_cfg80211_ch_switch_notify(dev, chandef); ++ ASSERT_WDEV_LOCK(wdev); + +- wdev_lock(wdev); ++ trace_cfg80211_ch_switch_notify(dev, chandef); + + if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP && + wdev->iftype != NL80211_IFTYPE_P2P_GO && + wdev->iftype != NL80211_IFTYPE_ADHOC && + wdev->iftype != NL80211_IFTYPE_MESH_POINT)) +- goto out; ++ return; + + wdev->channel = chandef->chan; + nl80211_ch_switch_notify(rdev, dev, chandef, GFP_KERNEL); +-out: +- wdev_unlock(wdev); +- return; + } + EXPORT_SYMBOL(cfg80211_ch_switch_notify); + +@@ -10882,7 +10896,7 @@ EXPORT_SYMBOL(cfg80211_cqm_txe_notify); + + void + nl80211_radar_notify(struct cfg80211_registered_device *rdev, +- struct cfg80211_chan_def *chandef, ++ const struct cfg80211_chan_def *chandef, + enum nl80211_radar_event event, + struct net_device *netdev, gfp_t gfp) + { +--- a/net/wireless/nl80211.h ++++ b/net/wireless/nl80211.h +@@ -70,7 +70,7 @@ int nl80211_send_mgmt(struct cfg80211_re + + void + nl80211_radar_notify(struct cfg80211_registered_device *rdev, +- struct cfg80211_chan_def *chandef, ++ const struct cfg80211_chan_def *chandef, + enum nl80211_radar_event event, + struct net_device *netdev, gfp_t gfp); + +--- a/net/wireless/reg.c ++++ b/net/wireless/reg.c +@@ -163,35 +163,29 @@ static const struct ieee80211_regdomain + REG_RULE(2412-10, 2462+10, 40, 6, 20, 0), + /* IEEE 802.11b/g, channels 12..13. */ + REG_RULE(2467-10, 2472+10, 40, 6, 20, +- NL80211_RRF_PASSIVE_SCAN | +- NL80211_RRF_NO_IBSS), ++ NL80211_RRF_NO_IR), + /* IEEE 802.11 channel 14 - Only JP enables + * this and for 802.11b only */ + REG_RULE(2484-10, 2484+10, 20, 6, 20, +- NL80211_RRF_PASSIVE_SCAN | +- NL80211_RRF_NO_IBSS | ++ NL80211_RRF_NO_IR | + NL80211_RRF_NO_OFDM), + /* IEEE 802.11a, channel 36..48 */ + REG_RULE(5180-10, 5240+10, 160, 6, 20, +- NL80211_RRF_PASSIVE_SCAN | +- NL80211_RRF_NO_IBSS), ++ NL80211_RRF_NO_IR), + + /* IEEE 802.11a, channel 52..64 - DFS required */ + REG_RULE(5260-10, 5320+10, 160, 6, 20, +- NL80211_RRF_PASSIVE_SCAN | +- NL80211_RRF_NO_IBSS | ++ NL80211_RRF_NO_IR | + NL80211_RRF_DFS), + + /* IEEE 802.11a, channel 100..144 - DFS required */ + REG_RULE(5500-10, 5720+10, 160, 6, 20, +- NL80211_RRF_PASSIVE_SCAN | +- NL80211_RRF_NO_IBSS | ++ NL80211_RRF_NO_IR | + NL80211_RRF_DFS), + + /* IEEE 802.11a, channel 149..165 */ + REG_RULE(5745-10, 5825+10, 80, 6, 20, +- NL80211_RRF_PASSIVE_SCAN | +- NL80211_RRF_NO_IBSS), ++ NL80211_RRF_NO_IR), + + /* IEEE 802.11ad (60gHz), channels 1..3 */ + REG_RULE(56160+2160*1-1080, 56160+2160*3+1080, 2160, 0, 0, 0), +@@ -698,10 +692,8 @@ regdom_intersect(const struct ieee80211_ + static u32 map_regdom_flags(u32 rd_flags) + { + u32 channel_flags = 0; +- if (rd_flags & NL80211_RRF_PASSIVE_SCAN) +- channel_flags |= IEEE80211_CHAN_PASSIVE_SCAN; +- if (rd_flags & NL80211_RRF_NO_IBSS) +- channel_flags |= IEEE80211_CHAN_NO_IBSS; ++ if (rd_flags & NL80211_RRF_NO_IR_ALL) ++ channel_flags |= IEEE80211_CHAN_NO_IR; + if (rd_flags & NL80211_RRF_DFS) + channel_flags |= IEEE80211_CHAN_RADAR; + if (rd_flags & NL80211_RRF_NO_OFDM) +@@ -1066,13 +1058,8 @@ static void handle_reg_beacon(struct wip + chan_before.center_freq = chan->center_freq; + chan_before.flags = chan->flags; + +- if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) { +- chan->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; +- channel_changed = true; +- } +- +- if (chan->flags & IEEE80211_CHAN_NO_IBSS) { +- chan->flags &= ~IEEE80211_CHAN_NO_IBSS; ++ if (chan->flags & IEEE80211_CHAN_NO_IR) { ++ chan->flags &= ~IEEE80211_CHAN_NO_IR; + channel_changed = true; + } + +--- /dev/null ++++ b/drivers/net/wireless/ath/ath9k/ar9003_wow.c +@@ -0,0 +1,422 @@ ++/* ++ * Copyright (c) 2012 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 ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include ++#include "ath9k.h" ++#include "reg.h" ++#include "hw-ops.h" ++ ++const char *ath9k_hw_wow_event_to_string(u32 wow_event) ++{ ++ 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"; ++ ++ return "unknown reason"; ++} ++EXPORT_SYMBOL(ath9k_hw_wow_event_to_string); ++ ++static void ath9k_hw_set_powermode_wow_sleep(struct ath_hw *ah) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ ++ REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); ++ ++ /* set rx disable bit */ ++ REG_WRITE(ah, AR_CR, AR_CR_RXD); ++ ++ 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; ++ } ++ ++ REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_ON_INT); ++} ++ ++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); ++ } ++ ++ for (i = 0; i < KAL_NUM_DATA_WORDS; i++) ++ REG_WRITE(ah, (wow_ka_data_word0 + i*4), data_word[i]); ++ ++} ++ ++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; ++ ++ /* FIXME: should check count by querying the hardware capability */ ++ if (pattern_count >= MAX_NUM_PATTERN) ++ return; ++ ++ REG_SET_BIT(ah, AR_WOW_PATTERN, BIT(pattern_count)); ++ ++ /* 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; ++ } ++ ++ /* 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; ++ } ++ ++ /* 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 ++ */ ++ ++ ah->wow_event_mask |= BIT(pattern_count + AR_WOW_PAT_FOUND_SHIFT); ++ ++ 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); ++ } ++ ++} ++EXPORT_SYMBOL(ath9k_hw_wow_apply_pattern); ++ ++u32 ath9k_hw_wow_wakeup(struct ath_hw *ah) ++{ ++ u32 wow_status = 0; ++ u32 val = 0, rval; ++ ++ /* ++ * read the WoW status register to know ++ * the wakeup reason ++ */ ++ rval = REG_READ(ah, AR_WOW_PATTERN); ++ val = AR_WOW_STATUS(rval); ++ ++ /* ++ * 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. ++ */ ++ ++ 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; ++ } ++ ++ /* ++ * set and clear WOW_PME_CLEAR registers for the chip to ++ * generate next wow signal. ++ * disable D3 before accessing other registers ? ++ */ ++ ++ /* 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); ++ ++ /* ++ * clear all events ++ */ ++ REG_WRITE(ah, AR_WOW_PATTERN, ++ AR_WOW_CLEAR_EVENTS(REG_READ(ah, AR_WOW_PATTERN))); ++ ++ /* ++ * restore the beacon threshold to init value ++ */ ++ REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR); ++ ++ /* ++ * 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); ++ ++ 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) ++{ ++ u32 wow_event_mask; ++ u32 set, clr; ++ ++ /* ++ * 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; ++ ++ /* ++ * 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); ++ } ++ ++ /* ++ * 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; ++ ++ /* ++ * 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); ++ ++ /* ++ * Setup for: ++ * - beacon misses ++ * - magic pattern ++ * - keep alive timeout ++ * - pattern matching ++ */ ++ ++ /* ++ * 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); ++ ++ 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; ++ ++ REG_WRITE(ah, AR_WOW_BCN_TIMO, set); ++ ++ /* ++ * Keep alive timo in ms except AR9280 ++ */ ++ if (!pattern_enable) ++ set = AR_WOW_KEEP_ALIVE_NEVER; ++ else ++ set = KAL_TIMEOUT * 32; ++ ++ REG_WRITE(ah, AR_WOW_KEEP_ALIVE_TIMO, set); ++ ++ /* ++ * Keep alive delay in us. based on 'power on clock', ++ * therefore in usec ++ */ ++ set = KAL_DELAY * 1000; ++ REG_WRITE(ah, AR_WOW_KEEP_ALIVE_DELAY, set); ++ ++ /* ++ * Create keep alive pattern to respond to beacons ++ */ ++ ath9k_wow_create_keep_alive_pattern(ah); ++ ++ /* ++ * Configure MAC WoW Registers ++ */ ++ 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; ++ ++ set = AR_WOW_KEEP_ALIVE_FAIL_DIS; ++ REG_RMW(ah, AR_WOW_KEEP_ALIVE, set, clr); ++ ++ /* ++ * we are relying on a bmiss failure. ensure we have ++ * enough threshold to prevent false positives ++ */ ++ REG_RMW_FIELD(ah, AR_RSSI_THR, AR_RSSI_THR_BM_THR, ++ AR_WOW_BMISSTHRESHOLD); ++ ++ set = 0; ++ clr = 0; ++ ++ 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; ++ } ++ ++ REG_RMW(ah, AR_WOW_BCN_EN, set, clr); ++ ++ 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; ++ } ++ 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); ++ ++ /* ++ * 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; ++ ++ clr = AR_PCIE_PM_CTRL_ENA; ++ REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); ++ ++ /* ++ * 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); ++ ++ set = AR_PMCTRL_PWR_STATE_D1D3_REAL; ++ REG_SET_BIT(ah, AR_PCIE_PM_CTRL, set); ++ ++ REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PRESERVE_SEQNUM); ++ ++ /* 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); ++ ++ ath9k_hw_set_powermode_wow_sleep(ah); ++ ah->wow_event_mask = wow_event_mask; ++} ++EXPORT_SYMBOL(ath9k_hw_wow_enable); +--- /dev/null ++++ b/drivers/net/wireless/ath/ath9k/tx99.c +@@ -0,0 +1,263 @@ ++/* ++ * 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 ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "ath9k.h" ++ ++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; ++} ++ ++static void ath9k_tx99_deinit(struct ath_softc *sc) ++{ ++ ath_reset(sc); ++ ++ ath9k_ps_wakeup(sc); ++ ath9k_tx99_stop(sc); ++ ath9k_ps_restore(sc); ++} ++ ++static 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 (test_bit(SC_OP_INVALID, &sc->sc_flags)) { ++ 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; ++} ++ ++static ssize_t read_file_tx99(struct file *file, char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[3]; ++ unsigned int len; ++ ++ len = sprintf(buf, "%d\n", sc->tx99_state); ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_tx99(struct file *file, const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ struct ath_common *common = ath9k_hw_common(sc->sc_ah); ++ char buf[32]; ++ bool start; ++ ssize_t len; ++ int r; ++ ++ if (sc->nvifs > 1) ++ return -EOPNOTSUPP; ++ ++ len = min(count, sizeof(buf) - 1); ++ if (copy_from_user(buf, user_buf, len)) ++ return -EFAULT; ++ ++ if (strtobool(buf, &start)) ++ return -EINVAL; ++ ++ if (start == sc->tx99_state) { ++ if (!start) ++ return count; ++ ath_dbg(common, XMIT, "Resetting TX99\n"); ++ ath9k_tx99_deinit(sc); ++ } ++ ++ if (!start) { ++ ath9k_tx99_deinit(sc); ++ return count; ++ } ++ ++ r = ath9k_tx99_init(sc); ++ if (r) ++ return r; ++ ++ return count; ++} ++ ++static const struct file_operations fops_tx99 = { ++ .read = read_file_tx99, ++ .write = write_file_tx99, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++static ssize_t read_file_tx99_power(struct file *file, ++ char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ char buf[32]; ++ unsigned int len; ++ ++ len = sprintf(buf, "%d (%d dBm)\n", ++ sc->tx99_power, ++ sc->tx99_power / 2); ++ ++ return simple_read_from_buffer(user_buf, count, ppos, buf, len); ++} ++ ++static ssize_t write_file_tx99_power(struct file *file, ++ const char __user *user_buf, ++ size_t count, loff_t *ppos) ++{ ++ struct ath_softc *sc = file->private_data; ++ int r; ++ u8 tx_power; ++ ++ r = kstrtou8_from_user(user_buf, count, 0, &tx_power); ++ if (r) ++ return r; ++ ++ if (tx_power > MAX_RATE_POWER) ++ return -EINVAL; ++ ++ sc->tx99_power = tx_power; ++ ++ ath9k_ps_wakeup(sc); ++ ath9k_hw_tx99_set_txpower(sc->sc_ah, sc->tx99_power); ++ ath9k_ps_restore(sc); ++ ++ return count; ++} ++ ++static const struct file_operations fops_tx99_power = { ++ .read = read_file_tx99_power, ++ .write = write_file_tx99_power, ++ .open = simple_open, ++ .owner = THIS_MODULE, ++ .llseek = default_llseek, ++}; ++ ++void ath9k_tx99_init_debug(struct ath_softc *sc) ++{ ++ if (!AR_SREV_9300_20_OR_LATER(sc->sc_ah)) ++ return; ++ ++ debugfs_create_file("tx99", S_IRUSR | S_IWUSR, ++ sc->debug.debugfs_phy, sc, ++ &fops_tx99); ++ debugfs_create_file("tx99_power", S_IRUSR | S_IWUSR, ++ sc->debug.debugfs_phy, sc, ++ &fops_tx99_power); ++} +--- a/drivers/net/wireless/ath/ath9k/dfs_debug.c ++++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c +@@ -44,14 +44,20 @@ static ssize_t read_file_dfs(struct file + if (buf == NULL) + return -ENOMEM; + +- if (sc->dfs_detector) +- dfs_pool_stats = sc->dfs_detector->get_stats(sc->dfs_detector); +- + len += scnprintf(buf + len, size - len, "DFS support for " + "macVersion = 0x%x, macRev = 0x%x: %s\n", + hw_ver->macVersion, hw_ver->macRev, + (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ? + "enabled" : "disabled"); ++ ++ if (!sc->dfs_detector) { ++ len += scnprintf(buf + len, size - len, ++ "DFS detector not enabled\n"); ++ goto exit; ++ } ++ ++ dfs_pool_stats = sc->dfs_detector->get_stats(sc->dfs_detector); ++ + len += scnprintf(buf + len, size - len, "Pulse detector statistics:\n"); + ATH9K_DFS_STAT("pulse events reported ", pulses_total); + ATH9K_DFS_STAT("invalid pulse events ", pulses_no_dfs); +@@ -76,6 +82,7 @@ static ssize_t read_file_dfs(struct file + ATH9K_DFS_POOL_STAT("Seqs. alloc error ", pseq_alloc_error); + ATH9K_DFS_POOL_STAT("Seqs. in use ", pseq_used); + ++exit: + if (len > size) + len = size; + +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c +@@ -641,11 +641,12 @@ static void ar9003_hw_override_ini(struc + else + ah->enabled_cals &= ~TX_IQ_CAL; + +- if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) +- ah->enabled_cals |= TX_CL_CAL; +- else +- ah->enabled_cals &= ~TX_CL_CAL; + } ++ ++ if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) ++ ah->enabled_cals |= TX_CL_CAL; ++ else ++ ah->enabled_cals &= ~TX_CL_CAL; + } + + static void ar9003_hw_prog_ini(struct ath_hw *ah, +@@ -701,6 +702,54 @@ static int ar9550_hw_get_modes_txgain_in + return ret; + } + ++static void ar9003_doubler_fix(struct ath_hw *ah) ++{ ++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) { ++ REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); ++ REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); ++ REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S, 0); ++ ++ udelay(200); ++ ++ REG_CLR_BIT(ah, AR_PHY_65NM_CH0_RXTX2, ++ AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); ++ REG_CLR_BIT(ah, AR_PHY_65NM_CH1_RXTX2, ++ AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); ++ REG_CLR_BIT(ah, AR_PHY_65NM_CH2_RXTX2, ++ AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK); ++ ++ udelay(1); ++ ++ REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX2, ++ AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); ++ REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX2, ++ AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); ++ REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX2, ++ AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK, 1); ++ ++ udelay(200); ++ ++ REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_SYNTH12, ++ AR_PHY_65NM_CH0_SYNTH12_VREFMUL3, 0xf); ++ ++ REG_RMW(ah, AR_PHY_65NM_CH0_RXTX2, 0, ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); ++ REG_RMW(ah, AR_PHY_65NM_CH1_RXTX2, 0, ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); ++ REG_RMW(ah, AR_PHY_65NM_CH2_RXTX2, 0, ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S | ++ 1 << AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S); ++ } ++} ++ + static int ar9003_hw_process_ini(struct ath_hw *ah, + struct ath9k_channel *chan) + { +@@ -726,6 +775,8 @@ static int ar9003_hw_process_ini(struct + modesIndex); + } + ++ ar9003_doubler_fix(ah); ++ + /* + * RXGAIN initvals. + */ +--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h +@@ -656,13 +656,24 @@ + #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x00000001 : 0x00000002) + #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0 : 1) + #define AR_PHY_65NM_CH0_SYNTH7 0x16098 ++#define AR_PHY_65NM_CH0_SYNTH12 0x160ac + #define AR_PHY_65NM_CH0_BIAS1 0x160c0 + #define AR_PHY_65NM_CH0_BIAS2 0x160c4 + #define AR_PHY_65NM_CH0_BIAS4 0x160cc ++#define AR_PHY_65NM_CH0_RXTX2 0x16104 ++#define AR_PHY_65NM_CH1_RXTX2 0x16504 ++#define AR_PHY_65NM_CH2_RXTX2 0x16904 + #define AR_PHY_65NM_CH0_RXTX4 0x1610c + #define AR_PHY_65NM_CH1_RXTX4 0x1650c + #define AR_PHY_65NM_CH2_RXTX4 0x1690c + ++#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3 0x00780000 ++#define AR_PHY_65NM_CH0_SYNTH12_VREFMUL3_S 19 ++#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK 0x00000004 ++#define AR_PHY_65NM_CH0_RXTX2_SYNTHON_MASK_S 2 ++#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK 0x00000008 ++#define AR_PHY_65NM_CH0_RXTX2_SYNTHOVR_MASK_S 3 ++ + #define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ + (((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x1628c : 0x16280))) + #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300) +--- a/drivers/net/wireless/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/rt2x00/rt2x00dev.c +@@ -181,6 +181,7 @@ static void rt2x00lib_autowakeup(struct + static void rt2x00lib_bc_buffer_iter(void *data, u8 *mac, + struct ieee80211_vif *vif) + { ++ struct ieee80211_tx_control control = {}; + struct rt2x00_dev *rt2x00dev = data; + struct sk_buff *skb; + +@@ -195,7 +196,7 @@ static void rt2x00lib_bc_buffer_iter(voi + */ + skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); + while (skb) { +- rt2x00mac_tx(rt2x00dev->hw, NULL, skb); ++ rt2x00mac_tx(rt2x00dev->hw, &control, skb); + skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif); + } + } +--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c +@@ -1040,14 +1040,14 @@ static void ar9003_hw_cl_cal_post_proc(s + } + } + +-static bool ar9003_hw_init_cal(struct ath_hw *ah, +- struct ath9k_channel *chan) ++static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah, ++ struct ath9k_channel *chan) + { + struct ath_common *common = ath9k_hw_common(ah); + struct ath9k_hw_cal_data *caldata = ah->caldata; + bool txiqcal_done = false; + bool is_reusable = true, status = true; +- bool run_rtt_cal = false, run_agc_cal, sep_iq_cal = false; ++ bool run_rtt_cal = false, run_agc_cal; + bool rtt = !!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT); + u32 rx_delay = 0; + u32 agc_ctrl = 0, agc_supp_cals = AR_PHY_AGC_CONTROL_OFFSET_CAL | +@@ -1119,22 +1119,12 @@ static bool ar9003_hw_init_cal(struct at + REG_CLR_BIT(ah, AR_PHY_TX_IQCAL_CONTROL_0, + AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL); + txiqcal_done = run_agc_cal = true; +- } else if (caldata && !test_bit(TXIQCAL_DONE, &caldata->cal_flags)) { +- run_agc_cal = true; +- sep_iq_cal = true; + } + + skip_tx_iqcal: + if (ath9k_hw_mci_is_enabled(ah) && IS_CHAN_2GHZ(chan) && run_agc_cal) + ar9003_mci_init_cal_req(ah, &is_reusable); + +- if (sep_iq_cal) { +- txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); +- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); +- udelay(5); +- REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); +- } +- + if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE) { + rx_delay = REG_READ(ah, AR_PHY_RX_DELAY); + /* Disable BB_active */ +@@ -1228,13 +1218,109 @@ skip_tx_iqcal: + return true; + } + ++static bool ar9003_hw_init_cal_soc(struct ath_hw *ah, ++ struct ath9k_channel *chan) ++{ ++ struct ath_common *common = ath9k_hw_common(ah); ++ struct ath9k_hw_cal_data *caldata = ah->caldata; ++ bool txiqcal_done = false; ++ bool is_reusable = true, status = true; ++ bool run_agc_cal = false, sep_iq_cal = false; ++ ++ /* Use chip chainmask only for calibration */ ++ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); ++ ++ if (ah->enabled_cals & TX_CL_CAL) { ++ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE); ++ run_agc_cal = true; ++ } ++ ++ if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan)) ++ goto skip_tx_iqcal; ++ ++ /* Do Tx IQ Calibration */ ++ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1, ++ AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, ++ DELPT); ++ ++ /* ++ * For AR9485 or later chips, TxIQ cal runs as part of ++ * AGC calibration. Specifically, AR9550 in SoC chips. ++ */ ++ if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) { ++ txiqcal_done = true; ++ run_agc_cal = true; ++ } else { ++ sep_iq_cal = true; ++ run_agc_cal = true; ++ } ++ ++ /* ++ * In the SoC family, this will run for AR9300, AR9331 and AR9340. ++ */ ++ if (sep_iq_cal) { ++ txiqcal_done = ar9003_hw_tx_iq_cal_run(ah); ++ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS); ++ udelay(5); ++ REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN); ++ } ++ ++skip_tx_iqcal: ++ if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) { ++ /* Calibrate the AGC */ ++ REG_WRITE(ah, AR_PHY_AGC_CONTROL, ++ REG_READ(ah, AR_PHY_AGC_CONTROL) | ++ AR_PHY_AGC_CONTROL_CAL); ++ ++ /* Poll for offset calibration complete */ ++ status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, ++ AR_PHY_AGC_CONTROL_CAL, ++ 0, AH_WAIT_TIMEOUT); ++ } ++ ++ if (!status) { ++ ath_dbg(common, CALIBRATE, ++ "offset calibration failed to complete in %d ms; noisy environment?\n", ++ AH_WAIT_TIMEOUT / 1000); ++ return false; ++ } ++ ++ if (txiqcal_done) ++ ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable); ++ ++ /* Revert chainmask to runtime parameters */ ++ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ++ ++ /* Initialize list pointers */ ++ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; ++ ++ INIT_CAL(&ah->iq_caldata); ++ INSERT_CAL(ah, &ah->iq_caldata); ++ ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n"); ++ ++ /* Initialize current pointer to first element in list */ ++ ah->cal_list_curr = ah->cal_list; ++ ++ if (ah->cal_list_curr) ++ ath9k_hw_reset_calibration(ah, ah->cal_list_curr); ++ ++ if (caldata) ++ caldata->CalValid = 0; ++ ++ return true; ++} ++ + void ar9003_hw_attach_calib_ops(struct ath_hw *ah) + { + struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); + struct ath_hw_ops *ops = ath9k_hw_ops(ah); + ++ if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah)) ++ priv_ops->init_cal = ar9003_hw_init_cal_pcoem; ++ else ++ priv_ops->init_cal = ar9003_hw_init_cal_soc; ++ + priv_ops->init_cal_settings = ar9003_hw_init_cal_settings; +- priv_ops->init_cal = ar9003_hw_init_cal; + priv_ops->setup_calibration = ar9003_hw_setup_calibration; + + ops->calibrate = ar9003_hw_calibrate; +--- a/drivers/net/wireless/ath/ath9k/common.c ++++ b/drivers/net/wireless/ath/ath9k/common.c +@@ -98,10 +98,8 @@ struct ath9k_channel *ath9k_cmn_get_chan + { + struct ieee80211_channel *curchan = chandef->chan; + struct ath9k_channel *channel; +- u8 chan_idx; + +- chan_idx = curchan->hw_value; +- channel = &ah->channels[chan_idx]; ++ channel = &ah->channels[curchan->hw_value]; + ath9k_cmn_update_ichannel(channel, chandef); + + return channel; +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -226,7 +226,7 @@ minstrel_ht_calc_tp(struct minstrel_ht_s + nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); + + nsecs += minstrel_mcs_groups[group].duration[rate]; +- tp = 1000000 * ((mr->probability * 1000) / nsecs); ++ tp = 1000000 * ((prob * 1000) / nsecs); + + mr->cur_tp = MINSTREL_TRUNC(tp); + } +--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c ++++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +@@ -3984,18 +3984,20 @@ static void ar9003_hw_quick_drop_apply(s + int quick_drop; + s32 t[3], f[3] = {5180, 5500, 5785}; + +- if (!(pBase->miscConfiguration & BIT(1))) ++ if (!(pBase->miscConfiguration & BIT(4))) + return; + +- if (freq < 4000) +- quick_drop = eep->modalHeader2G.quick_drop; +- else { +- t[0] = eep->base_ext1.quick_drop_low; +- t[1] = eep->modalHeader5G.quick_drop; +- t[2] = eep->base_ext1.quick_drop_high; +- quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3); ++ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9340(ah)) { ++ if (freq < 4000) { ++ quick_drop = eep->modalHeader2G.quick_drop; ++ } else { ++ t[0] = eep->base_ext1.quick_drop_low; ++ t[1] = eep->modalHeader5G.quick_drop; ++ t[2] = eep->base_ext1.quick_drop_high; ++ quick_drop = ar9003_hw_power_interpolate(freq, f, t, 3); ++ } ++ REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); + } +- REG_RMW_FIELD(ah, AR_PHY_AGC, AR_PHY_AGC_QUICK_DROP, quick_drop); + } + + static void ar9003_hw_txend_to_xpa_off_apply(struct ath_hw *ah, bool is2ghz) +@@ -4035,7 +4037,7 @@ static void ar9003_hw_xlna_bias_strength + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + u8 bias; + +- if (!(eep->baseEepHeader.featureEnable & 0x40)) ++ if (!(eep->baseEepHeader.miscConfiguration & 0x40)) + return; + + if (!AR_SREV_9300(ah)) +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -735,6 +735,7 @@ struct ieee80211_sub_if_data { + int csa_counter_offset_beacon; + int csa_counter_offset_presp; + bool csa_radar_required; ++ struct cfg80211_chan_def csa_chandef; + + /* used to reconfigure hardware SM PS */ + struct work_struct recalc_smps; +@@ -811,6 +812,9 @@ static inline void sdata_unlock(struct i + __release(&sdata->wdev.mtx); + } + ++#define sdata_dereference(p, sdata) \ ++ rcu_dereference_protected(p, lockdep_is_held(&sdata->wdev.mtx)) ++ + static inline void + sdata_assert_lock(struct ieee80211_sub_if_data *sdata) + { +@@ -1098,7 +1102,6 @@ struct ieee80211_local { + enum mac80211_scan_state next_scan_state; + struct delayed_work scan_work; + struct ieee80211_sub_if_data __rcu *scan_sdata; +- struct cfg80211_chan_def csa_chandef; + /* For backward compatibility only -- do not use */ + struct cfg80211_chan_def _oper_chandef; + +@@ -1236,6 +1239,7 @@ struct ieee80211_csa_ie { + u8 mode; + u8 count; + u8 ttl; ++ u16 pre_value; + }; + + /* Parsed Information Elements */ +@@ -1738,7 +1742,6 @@ ieee80211_vif_change_bandwidth(struct ie + /* NOTE: only use ieee80211_vif_change_channel() for channel switch */ + int __must_check + ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, +- const struct cfg80211_chan_def *chandef, + u32 *changed); + void ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata); + void ieee80211_vif_vlan_copy_chanctx(struct ieee80211_sub_if_data *sdata); +--- a/net/mac80211/chan.c ++++ b/net/mac80211/chan.c +@@ -411,12 +411,12 @@ int ieee80211_vif_use_channel(struct iee + } + + int ieee80211_vif_change_channel(struct ieee80211_sub_if_data *sdata, +- const struct cfg80211_chan_def *chandef, + u32 *changed) + { + struct ieee80211_local *local = sdata->local; + struct ieee80211_chanctx_conf *conf; + struct ieee80211_chanctx *ctx; ++ const struct cfg80211_chan_def *chandef = &sdata->csa_chandef; + int ret; + u32 chanctx_changed = 0; + +--- a/net/mac80211/ibss.c ++++ b/net/mac80211/ibss.c +@@ -550,12 +550,12 @@ int ieee80211_ibss_finish_csa(struct iee + capability); + /* XXX: should not really modify cfg80211 data */ + if (cbss) { +- cbss->channel = sdata->local->csa_chandef.chan; ++ cbss->channel = sdata->csa_chandef.chan; + cfg80211_put_bss(sdata->local->hw.wiphy, cbss); + } + } + +- ifibss->chandef = sdata->local->csa_chandef; ++ ifibss->chandef = sdata->csa_chandef; + + /* generate the beacon */ + err = ieee80211_ibss_csa_beacon(sdata, NULL); +@@ -922,7 +922,7 @@ ieee80211_ibss_process_chanswitch(struct + IEEE80211_MAX_QUEUE_MAP, + IEEE80211_QUEUE_STOP_REASON_CSA); + +- sdata->local->csa_chandef = params.chandef; ++ sdata->csa_chandef = params.chandef; + sdata->vif.csa_active = true; + + ieee80211_bss_info_change_notify(sdata, err); +--- a/net/mac80211/mesh.c ++++ b/net/mac80211/mesh.c +@@ -943,14 +943,19 @@ ieee80211_mesh_process_chnswitch(struct + params.chandef.chan->center_freq); + + params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT; +- if (beacon) ++ if (beacon) { + ifmsh->chsw_ttl = csa_ie.ttl - 1; +- else +- ifmsh->chsw_ttl = 0; ++ if (ifmsh->pre_value >= csa_ie.pre_value) ++ return false; ++ ifmsh->pre_value = csa_ie.pre_value; ++ } + +- if (ifmsh->chsw_ttl > 0) ++ if (ifmsh->chsw_ttl < ifmsh->mshcfg.dot11MeshTTL) { + if (ieee80211_mesh_csa_beacon(sdata, ¶ms, false) < 0) + return false; ++ } else { ++ return false; ++ } + + sdata->csa_radar_required = params.radar_required; + +@@ -959,7 +964,7 @@ ieee80211_mesh_process_chnswitch(struct + IEEE80211_MAX_QUEUE_MAP, + IEEE80211_QUEUE_STOP_REASON_CSA); + +- sdata->local->csa_chandef = params.chandef; ++ sdata->csa_chandef = params.chandef; + sdata->vif.csa_active = true; + + ieee80211_bss_info_change_notify(sdata, err); +@@ -1163,7 +1168,6 @@ static int mesh_fwd_csa_frame(struct iee + offset_ttl = (len < 42) ? 7 : 10; + *(pos + offset_ttl) -= 1; + *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR; +- sdata->u.mesh.chsw_ttl = *(pos + offset_ttl); + + memcpy(mgmt_fwd, mgmt, len); + eth_broadcast_addr(mgmt_fwd->da); +@@ -1182,7 +1186,7 @@ static void mesh_rx_csa_frame(struct iee + u16 pre_value; + bool fwd_csa = true; + size_t baselen; +- u8 *pos, ttl; ++ u8 *pos; + + if (mgmt->u.action.u.measurement.action_code != + WLAN_ACTION_SPCT_CHL_SWITCH) +@@ -1193,8 +1197,8 @@ static void mesh_rx_csa_frame(struct iee + u.action.u.chan_switch.variable); + ieee802_11_parse_elems(pos, len - baselen, false, &elems); + +- ttl = elems.mesh_chansw_params_ie->mesh_ttl; +- if (!--ttl) ++ ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl; ++ if (!--ifmsh->chsw_ttl) + fwd_csa = false; + + pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value); +--- a/net/mac80211/spectmgmt.c ++++ b/net/mac80211/spectmgmt.c +@@ -78,6 +78,8 @@ int ieee80211_parse_ch_switch_ie(struct + if (elems->mesh_chansw_params_ie) { + csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl; + csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags; ++ csa_ie->pre_value = le16_to_cpu( ++ elems->mesh_chansw_params_ie->mesh_pre_value); + } + + new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band); +--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c ++++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c +@@ -1109,7 +1109,9 @@ void ath6kl_cfg80211_ch_switch_notify(st + (mode == WMI_11G_HT20) ? + NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT); + ++ mutex_lock(vif->wdev->mtx); + cfg80211_ch_switch_notify(vif->ndev, &chandef); ++ mutex_unlock(vif->wdev->mtx); + } + + static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, +--- a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h +@@ -20,6 +20,44 @@ + + /* AR9462 2.1 */ + ++#define ar9462_2p1_mac_postamble ar9462_2p0_mac_postamble ++ ++#define ar9462_2p1_baseband_core ar9462_2p0_baseband_core ++ ++#define ar9462_2p1_radio_core ar9462_2p0_radio_core ++ ++#define ar9462_2p1_radio_postamble ar9462_2p0_radio_postamble ++ ++#define ar9462_2p1_soc_postamble ar9462_2p0_soc_postamble ++ ++#define ar9462_2p1_radio_postamble_sys2ant ar9462_2p0_radio_postamble_sys2ant ++ ++#define ar9462_2p1_common_rx_gain ar9462_2p0_common_rx_gain ++ ++#define ar9462_2p1_common_mixed_rx_gain ar9462_2p0_common_mixed_rx_gain ++ ++#define ar9462_2p1_common_5g_xlna_only_rxgain ar9462_2p0_common_5g_xlna_only_rxgain ++ ++#define ar9462_2p1_baseband_core_mix_rxgain ar9462_2p0_baseband_core_mix_rxgain ++ ++#define ar9462_2p1_baseband_postamble_mix_rxgain ar9462_2p0_baseband_postamble_mix_rxgain ++ ++#define ar9462_2p1_baseband_postamble_5g_xlna ar9462_2p0_baseband_postamble_5g_xlna ++ ++#define ar9462_2p1_common_wo_xlna_rx_gain ar9462_2p0_common_wo_xlna_rx_gain ++ ++#define ar9462_2p1_modes_low_ob_db_tx_gain ar9462_2p0_modes_low_ob_db_tx_gain ++ ++#define ar9462_2p1_modes_high_ob_db_tx_gain ar9462_2p0_modes_high_ob_db_tx_gain ++ ++#define ar9462_2p1_modes_mix_ob_db_tx_gain ar9462_2p0_modes_mix_ob_db_tx_gain ++ ++#define ar9462_2p1_modes_fast_clock ar9462_2p0_modes_fast_clock ++ ++#define ar9462_2p1_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 ++ ++#define ar9462_2p1_pciephy_clkreq_disable_L1 ar9462_2p0_pciephy_clkreq_disable_L1 ++ + static const u32 ar9462_2p1_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, +@@ -183,168 +221,6 @@ static const u32 ar9462_2p1_mac_core[][2 + {0x000083d0, 0x000301ff}, + }; + +-static const u32 ar9462_2p1_mac_postamble[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160}, +- {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c}, +- {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38}, +- {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00}, +- {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b}, +- {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810}, +- {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a}, +- {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, +-}; +- +-static const u32 ar9462_2p1_baseband_core[][2] = { +- /* Addr allmodes */ +- {0x00009800, 0xafe68e30}, +- {0x00009804, 0xfd14e000}, +- {0x00009808, 0x9c0a9f6b}, +- {0x0000980c, 0x04900000}, +- {0x00009814, 0x9280c00a}, +- {0x00009818, 0x00000000}, +- {0x0000981c, 0x00020028}, +- {0x00009834, 0x6400a290}, +- {0x00009838, 0x0108ecff}, +- {0x0000983c, 0x0d000600}, +- {0x00009880, 0x201fff00}, +- {0x00009884, 0x00001042}, +- {0x000098a4, 0x00200400}, +- {0x000098b0, 0x32440bbe}, +- {0x000098d0, 0x004b6a8e}, +- {0x000098d4, 0x00000820}, +- {0x000098dc, 0x00000000}, +- {0x000098e4, 0x01ffffff}, +- {0x000098e8, 0x01ffffff}, +- {0x000098ec, 0x01ffffff}, +- {0x000098f0, 0x00000000}, +- {0x000098f4, 0x00000000}, +- {0x00009bf0, 0x80000000}, +- {0x00009c04, 0xff55ff55}, +- {0x00009c08, 0x0320ff55}, +- {0x00009c0c, 0x00000000}, +- {0x00009c10, 0x00000000}, +- {0x00009c14, 0x00046384}, +- {0x00009c18, 0x05b6b440}, +- {0x00009c1c, 0x00b6b440}, +- {0x00009d00, 0xc080a333}, +- {0x00009d04, 0x40206c10}, +- {0x00009d08, 0x009c4060}, +- {0x00009d0c, 0x9883800a}, +- {0x00009d10, 0x01834061}, +- {0x00009d14, 0x00c0040b}, +- {0x00009d18, 0x00000000}, +- {0x00009e08, 0x0038230c}, +- {0x00009e24, 0x990bb515}, +- {0x00009e28, 0x0c6f0000}, +- {0x00009e30, 0x06336f77}, +- {0x00009e34, 0x6af6532f}, +- {0x00009e38, 0x0cc80c00}, +- {0x00009e40, 0x15262820}, +- {0x00009e4c, 0x00001004}, +- {0x00009e50, 0x00ff03f1}, +- {0x00009e54, 0xe4c555c2}, +- {0x00009e58, 0xfd857722}, +- {0x00009e5c, 0xe9198724}, +- {0x00009fc0, 0x803e4788}, +- {0x00009fc4, 0x0001efb5}, +- {0x00009fcc, 0x40000014}, +- {0x00009fd0, 0x0a193b93}, +- {0x0000a20c, 0x00000000}, +- {0x0000a220, 0x00000000}, +- {0x0000a224, 0x00000000}, +- {0x0000a228, 0x10002310}, +- {0x0000a23c, 0x00000000}, +- {0x0000a244, 0x0c000000}, +- {0x0000a2a0, 0x00000001}, +- {0x0000a2c0, 0x00000001}, +- {0x0000a2c8, 0x00000000}, +- {0x0000a2cc, 0x18c43433}, +- {0x0000a2d4, 0x00000000}, +- {0x0000a2ec, 0x00000000}, +- {0x0000a2f0, 0x00000000}, +- {0x0000a2f4, 0x00000000}, +- {0x0000a2f8, 0x00000000}, +- {0x0000a344, 0x00000000}, +- {0x0000a34c, 0x00000000}, +- {0x0000a350, 0x0000a000}, +- {0x0000a364, 0x00000000}, +- {0x0000a370, 0x00000000}, +- {0x0000a390, 0x00000001}, +- {0x0000a394, 0x00000444}, +- {0x0000a398, 0x001f0e0f}, +- {0x0000a39c, 0x0075393f}, +- {0x0000a3a0, 0xb79f6427}, +- {0x0000a3c0, 0x20202020}, +- {0x0000a3c4, 0x22222220}, +- {0x0000a3c8, 0x20200020}, +- {0x0000a3cc, 0x20202020}, +- {0x0000a3d0, 0x20202020}, +- {0x0000a3d4, 0x20202020}, +- {0x0000a3d8, 0x20202020}, +- {0x0000a3dc, 0x20202020}, +- {0x0000a3e0, 0x20202020}, +- {0x0000a3e4, 0x20202020}, +- {0x0000a3e8, 0x20202020}, +- {0x0000a3ec, 0x20202020}, +- {0x0000a3f0, 0x00000000}, +- {0x0000a3f4, 0x00000006}, +- {0x0000a3f8, 0x0c9bd380}, +- {0x0000a3fc, 0x000f0f01}, +- {0x0000a400, 0x8fa91f01}, +- {0x0000a404, 0x00000000}, +- {0x0000a408, 0x0e79e5c6}, +- {0x0000a40c, 0x00820820}, +- {0x0000a414, 0x1ce739ce}, +- {0x0000a418, 0x2d001dce}, +- {0x0000a434, 0x00000000}, +- {0x0000a438, 0x00001801}, +- {0x0000a43c, 0x00100000}, +- {0x0000a444, 0x00000000}, +- {0x0000a448, 0x05000080}, +- {0x0000a44c, 0x00000001}, +- {0x0000a450, 0x00010000}, +- {0x0000a454, 0x07000000}, +- {0x0000a644, 0xbfad9d74}, +- {0x0000a648, 0x0048060a}, +- {0x0000a64c, 0x00002037}, +- {0x0000a670, 0x03020100}, +- {0x0000a674, 0x09080504}, +- {0x0000a678, 0x0d0c0b0a}, +- {0x0000a67c, 0x13121110}, +- {0x0000a680, 0x31301514}, +- {0x0000a684, 0x35343332}, +- {0x0000a688, 0x00000036}, +- {0x0000a690, 0x00000838}, +- {0x0000a6b0, 0x0000000a}, +- {0x0000a6b4, 0x00512c01}, +- {0x0000a7c0, 0x00000000}, +- {0x0000a7c4, 0xfffffffc}, +- {0x0000a7c8, 0x00000000}, +- {0x0000a7cc, 0x00000000}, +- {0x0000a7d0, 0x00000000}, +- {0x0000a7d4, 0x00000004}, +- {0x0000a7dc, 0x00000000}, +- {0x0000a7f0, 0x80000000}, +- {0x0000a8d0, 0x004b6a8e}, +- {0x0000a8d4, 0x00000820}, +- {0x0000a8dc, 0x00000000}, +- {0x0000a8f0, 0x00000000}, +- {0x0000a8f4, 0x00000000}, +- {0x0000abf0, 0x80000000}, +- {0x0000b2d0, 0x00000080}, +- {0x0000b2d4, 0x00000000}, +- {0x0000b2ec, 0x00000000}, +- {0x0000b2f0, 0x00000000}, +- {0x0000b2f4, 0x00000000}, +- {0x0000b2f8, 0x00000000}, +- {0x0000b408, 0x0e79e5c0}, +- {0x0000b40c, 0x00820820}, +- {0x0000b420, 0x00000000}, +- {0x0000b6b0, 0x0000000a}, +- {0x0000b6b4, 0x00000001}, +-}; +- + static const u32 ar9462_2p1_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, +@@ -361,7 +237,7 @@ static const u32 ar9462_2p1_baseband_pos + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, +- {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, ++ {0x00009e20, 0x000003a5, 0x000003a5, 0x000003a5, 0x000003a5}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, + {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, +@@ -400,1375 +276,16 @@ static const u32 ar9462_2p1_baseband_pos + {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, +- {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce}, ++ {0x0000ae20, 0x000001a6, 0x000001a6, 0x000001aa, 0x000001aa}, + {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, + }; + +-static const u32 ar9462_2p1_radio_core[][2] = { +- /* Addr allmodes */ +- {0x00016000, 0x36db6db6}, +- {0x00016004, 0x6db6db40}, +- {0x00016008, 0x73f00000}, +- {0x0001600c, 0x00000000}, +- {0x00016010, 0x6d820001}, +- {0x00016040, 0x7f80fff8}, +- {0x0001604c, 0x2699e04f}, +- {0x00016050, 0x6db6db6c}, +- {0x00016058, 0x6c200000}, +- {0x00016080, 0x000c0000}, +- {0x00016084, 0x9a68048c}, +- {0x00016088, 0x54214514}, +- {0x0001608c, 0x1203040b}, +- {0x00016090, 0x24926490}, +- {0x00016098, 0xd2888888}, +- {0x000160a0, 0x0a108ffe}, +- {0x000160a4, 0x812fc491}, +- {0x000160a8, 0x423c8000}, +- {0x000160b4, 0x92000000}, +- {0x000160b8, 0x0285dddc}, +- {0x000160bc, 0x02908888}, +- {0x000160c0, 0x00adb6d0}, +- {0x000160c4, 0x6db6db60}, +- {0x000160c8, 0x6db6db6c}, +- {0x000160cc, 0x0de6c1b0}, +- {0x00016100, 0x3fffbe04}, +- {0x00016104, 0xfff80000}, +- {0x00016108, 0x00200400}, +- {0x00016110, 0x00000000}, +- {0x00016144, 0x02084080}, +- {0x00016148, 0x000080c0}, +- {0x00016280, 0x050a0001}, +- {0x00016284, 0x3d841418}, +- {0x00016288, 0x00000000}, +- {0x0001628c, 0xe3000000}, +- {0x00016290, 0xa1005080}, +- {0x00016294, 0x00000020}, +- {0x00016298, 0x54a82900}, +- {0x00016340, 0x121e4276}, +- {0x00016344, 0x00300000}, +- {0x00016400, 0x36db6db6}, +- {0x00016404, 0x6db6db40}, +- {0x00016408, 0x73f00000}, +- {0x0001640c, 0x00000000}, +- {0x00016410, 0x6c800001}, +- {0x00016440, 0x7f80fff8}, +- {0x0001644c, 0x4699e04f}, +- {0x00016450, 0x6db6db6c}, +- {0x00016500, 0x3fffbe04}, +- {0x00016504, 0xfff80000}, +- {0x00016508, 0x00200400}, +- {0x00016510, 0x00000000}, +- {0x00016544, 0x02084080}, +- {0x00016548, 0x000080c0}, +-}; +- +-static const u32 ar9462_2p1_radio_postamble[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, +- {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, +- {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, +- {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, +-}; +- + static const u32 ar9462_2p1_soc_preamble[][2] = { + /* Addr allmodes */ +- {0x000040a4, 0x00a0c1c9}, ++ {0x000040a4, 0x00a0c9c9}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, + }; + +-static const u32 ar9462_2p1_soc_postamble[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033}, +-}; +- +-static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, +- {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, +- {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, +-}; +- +-static const u32 ar9462_2p1_common_rx_gain[][2] = { +- /* Addr allmodes */ +- {0x0000a000, 0x00010000}, +- {0x0000a004, 0x00030002}, +- {0x0000a008, 0x00050004}, +- {0x0000a00c, 0x00810080}, +- {0x0000a010, 0x00830082}, +- {0x0000a014, 0x01810180}, +- {0x0000a018, 0x01830182}, +- {0x0000a01c, 0x01850184}, +- {0x0000a020, 0x01890188}, +- {0x0000a024, 0x018b018a}, +- {0x0000a028, 0x018d018c}, +- {0x0000a02c, 0x01910190}, +- {0x0000a030, 0x01930192}, +- {0x0000a034, 0x01950194}, +- {0x0000a038, 0x038a0196}, +- {0x0000a03c, 0x038c038b}, +- {0x0000a040, 0x0390038d}, +- {0x0000a044, 0x03920391}, +- {0x0000a048, 0x03940393}, +- {0x0000a04c, 0x03960395}, +- {0x0000a050, 0x00000000}, +- {0x0000a054, 0x00000000}, +- {0x0000a058, 0x00000000}, +- {0x0000a05c, 0x00000000}, +- {0x0000a060, 0x00000000}, +- {0x0000a064, 0x00000000}, +- {0x0000a068, 0x00000000}, +- {0x0000a06c, 0x00000000}, +- {0x0000a070, 0x00000000}, +- {0x0000a074, 0x00000000}, +- {0x0000a078, 0x00000000}, +- {0x0000a07c, 0x00000000}, +- {0x0000a080, 0x22222229}, +- {0x0000a084, 0x1d1d1d1d}, +- {0x0000a088, 0x1d1d1d1d}, +- {0x0000a08c, 0x1d1d1d1d}, +- {0x0000a090, 0x171d1d1d}, +- {0x0000a094, 0x11111717}, +- {0x0000a098, 0x00030311}, +- {0x0000a09c, 0x00000000}, +- {0x0000a0a0, 0x00000000}, +- {0x0000a0a4, 0x00000000}, +- {0x0000a0a8, 0x00000000}, +- {0x0000a0ac, 0x00000000}, +- {0x0000a0b0, 0x00000000}, +- {0x0000a0b4, 0x00000000}, +- {0x0000a0b8, 0x00000000}, +- {0x0000a0bc, 0x00000000}, +- {0x0000a0c0, 0x001f0000}, +- {0x0000a0c4, 0x01000101}, +- {0x0000a0c8, 0x011e011f}, +- {0x0000a0cc, 0x011c011d}, +- {0x0000a0d0, 0x02030204}, +- {0x0000a0d4, 0x02010202}, +- {0x0000a0d8, 0x021f0200}, +- {0x0000a0dc, 0x0302021e}, +- {0x0000a0e0, 0x03000301}, +- {0x0000a0e4, 0x031e031f}, +- {0x0000a0e8, 0x0402031d}, +- {0x0000a0ec, 0x04000401}, +- {0x0000a0f0, 0x041e041f}, +- {0x0000a0f4, 0x0502041d}, +- {0x0000a0f8, 0x05000501}, +- {0x0000a0fc, 0x051e051f}, +- {0x0000a100, 0x06010602}, +- {0x0000a104, 0x061f0600}, +- {0x0000a108, 0x061d061e}, +- {0x0000a10c, 0x07020703}, +- {0x0000a110, 0x07000701}, +- {0x0000a114, 0x00000000}, +- {0x0000a118, 0x00000000}, +- {0x0000a11c, 0x00000000}, +- {0x0000a120, 0x00000000}, +- {0x0000a124, 0x00000000}, +- {0x0000a128, 0x00000000}, +- {0x0000a12c, 0x00000000}, +- {0x0000a130, 0x00000000}, +- {0x0000a134, 0x00000000}, +- {0x0000a138, 0x00000000}, +- {0x0000a13c, 0x00000000}, +- {0x0000a140, 0x001f0000}, +- {0x0000a144, 0x01000101}, +- {0x0000a148, 0x011e011f}, +- {0x0000a14c, 0x011c011d}, +- {0x0000a150, 0x02030204}, +- {0x0000a154, 0x02010202}, +- {0x0000a158, 0x021f0200}, +- {0x0000a15c, 0x0302021e}, +- {0x0000a160, 0x03000301}, +- {0x0000a164, 0x031e031f}, +- {0x0000a168, 0x0402031d}, +- {0x0000a16c, 0x04000401}, +- {0x0000a170, 0x041e041f}, +- {0x0000a174, 0x0502041d}, +- {0x0000a178, 0x05000501}, +- {0x0000a17c, 0x051e051f}, +- {0x0000a180, 0x06010602}, +- {0x0000a184, 0x061f0600}, +- {0x0000a188, 0x061d061e}, +- {0x0000a18c, 0x07020703}, +- {0x0000a190, 0x07000701}, +- {0x0000a194, 0x00000000}, +- {0x0000a198, 0x00000000}, +- {0x0000a19c, 0x00000000}, +- {0x0000a1a0, 0x00000000}, +- {0x0000a1a4, 0x00000000}, +- {0x0000a1a8, 0x00000000}, +- {0x0000a1ac, 0x00000000}, +- {0x0000a1b0, 0x00000000}, +- {0x0000a1b4, 0x00000000}, +- {0x0000a1b8, 0x00000000}, +- {0x0000a1bc, 0x00000000}, +- {0x0000a1c0, 0x00000000}, +- {0x0000a1c4, 0x00000000}, +- {0x0000a1c8, 0x00000000}, +- {0x0000a1cc, 0x00000000}, +- {0x0000a1d0, 0x00000000}, +- {0x0000a1d4, 0x00000000}, +- {0x0000a1d8, 0x00000000}, +- {0x0000a1dc, 0x00000000}, +- {0x0000a1e0, 0x00000000}, +- {0x0000a1e4, 0x00000000}, +- {0x0000a1e8, 0x00000000}, +- {0x0000a1ec, 0x00000000}, +- {0x0000a1f0, 0x00000396}, +- {0x0000a1f4, 0x00000396}, +- {0x0000a1f8, 0x00000396}, +- {0x0000a1fc, 0x00000196}, +- {0x0000b000, 0x00010000}, +- {0x0000b004, 0x00030002}, +- {0x0000b008, 0x00050004}, +- {0x0000b00c, 0x00810080}, +- {0x0000b010, 0x00830082}, +- {0x0000b014, 0x01810180}, +- {0x0000b018, 0x01830182}, +- {0x0000b01c, 0x01850184}, +- {0x0000b020, 0x02810280}, +- {0x0000b024, 0x02830282}, +- {0x0000b028, 0x02850284}, +- {0x0000b02c, 0x02890288}, +- {0x0000b030, 0x028b028a}, +- {0x0000b034, 0x0388028c}, +- {0x0000b038, 0x038a0389}, +- {0x0000b03c, 0x038c038b}, +- {0x0000b040, 0x0390038d}, +- {0x0000b044, 0x03920391}, +- {0x0000b048, 0x03940393}, +- {0x0000b04c, 0x03960395}, +- {0x0000b050, 0x00000000}, +- {0x0000b054, 0x00000000}, +- {0x0000b058, 0x00000000}, +- {0x0000b05c, 0x00000000}, +- {0x0000b060, 0x00000000}, +- {0x0000b064, 0x00000000}, +- {0x0000b068, 0x00000000}, +- {0x0000b06c, 0x00000000}, +- {0x0000b070, 0x00000000}, +- {0x0000b074, 0x00000000}, +- {0x0000b078, 0x00000000}, +- {0x0000b07c, 0x00000000}, +- {0x0000b080, 0x2a2d2f32}, +- {0x0000b084, 0x21232328}, +- {0x0000b088, 0x19191c1e}, +- {0x0000b08c, 0x12141417}, +- {0x0000b090, 0x07070e0e}, +- {0x0000b094, 0x03030305}, +- {0x0000b098, 0x00000003}, +- {0x0000b09c, 0x00000000}, +- {0x0000b0a0, 0x00000000}, +- {0x0000b0a4, 0x00000000}, +- {0x0000b0a8, 0x00000000}, +- {0x0000b0ac, 0x00000000}, +- {0x0000b0b0, 0x00000000}, +- {0x0000b0b4, 0x00000000}, +- {0x0000b0b8, 0x00000000}, +- {0x0000b0bc, 0x00000000}, +- {0x0000b0c0, 0x003f0020}, +- {0x0000b0c4, 0x00400041}, +- {0x0000b0c8, 0x0140005f}, +- {0x0000b0cc, 0x0160015f}, +- {0x0000b0d0, 0x017e017f}, +- {0x0000b0d4, 0x02410242}, +- {0x0000b0d8, 0x025f0240}, +- {0x0000b0dc, 0x027f0260}, +- {0x0000b0e0, 0x0341027e}, +- {0x0000b0e4, 0x035f0340}, +- {0x0000b0e8, 0x037f0360}, +- {0x0000b0ec, 0x04400441}, +- {0x0000b0f0, 0x0460045f}, +- {0x0000b0f4, 0x0541047f}, +- {0x0000b0f8, 0x055f0540}, +- {0x0000b0fc, 0x057f0560}, +- {0x0000b100, 0x06400641}, +- {0x0000b104, 0x0660065f}, +- {0x0000b108, 0x067e067f}, +- {0x0000b10c, 0x07410742}, +- {0x0000b110, 0x075f0740}, +- {0x0000b114, 0x077f0760}, +- {0x0000b118, 0x07800781}, +- {0x0000b11c, 0x07a0079f}, +- {0x0000b120, 0x07c107bf}, +- {0x0000b124, 0x000007c0}, +- {0x0000b128, 0x00000000}, +- {0x0000b12c, 0x00000000}, +- {0x0000b130, 0x00000000}, +- {0x0000b134, 0x00000000}, +- {0x0000b138, 0x00000000}, +- {0x0000b13c, 0x00000000}, +- {0x0000b140, 0x003f0020}, +- {0x0000b144, 0x00400041}, +- {0x0000b148, 0x0140005f}, +- {0x0000b14c, 0x0160015f}, +- {0x0000b150, 0x017e017f}, +- {0x0000b154, 0x02410242}, +- {0x0000b158, 0x025f0240}, +- {0x0000b15c, 0x027f0260}, +- {0x0000b160, 0x0341027e}, +- {0x0000b164, 0x035f0340}, +- {0x0000b168, 0x037f0360}, +- {0x0000b16c, 0x04400441}, +- {0x0000b170, 0x0460045f}, +- {0x0000b174, 0x0541047f}, +- {0x0000b178, 0x055f0540}, +- {0x0000b17c, 0x057f0560}, +- {0x0000b180, 0x06400641}, +- {0x0000b184, 0x0660065f}, +- {0x0000b188, 0x067e067f}, +- {0x0000b18c, 0x07410742}, +- {0x0000b190, 0x075f0740}, +- {0x0000b194, 0x077f0760}, +- {0x0000b198, 0x07800781}, +- {0x0000b19c, 0x07a0079f}, +- {0x0000b1a0, 0x07c107bf}, +- {0x0000b1a4, 0x000007c0}, +- {0x0000b1a8, 0x00000000}, +- {0x0000b1ac, 0x00000000}, +- {0x0000b1b0, 0x00000000}, +- {0x0000b1b4, 0x00000000}, +- {0x0000b1b8, 0x00000000}, +- {0x0000b1bc, 0x00000000}, +- {0x0000b1c0, 0x00000000}, +- {0x0000b1c4, 0x00000000}, +- {0x0000b1c8, 0x00000000}, +- {0x0000b1cc, 0x00000000}, +- {0x0000b1d0, 0x00000000}, +- {0x0000b1d4, 0x00000000}, +- {0x0000b1d8, 0x00000000}, +- {0x0000b1dc, 0x00000000}, +- {0x0000b1e0, 0x00000000}, +- {0x0000b1e4, 0x00000000}, +- {0x0000b1e8, 0x00000000}, +- {0x0000b1ec, 0x00000000}, +- {0x0000b1f0, 0x00000396}, +- {0x0000b1f4, 0x00000396}, +- {0x0000b1f8, 0x00000396}, +- {0x0000b1fc, 0x00000196}, +-}; +- +-static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = { +- /* Addr allmodes */ +- {0x0000a000, 0x00010000}, +- {0x0000a004, 0x00030002}, +- {0x0000a008, 0x00050004}, +- {0x0000a00c, 0x00810080}, +- {0x0000a010, 0x00830082}, +- {0x0000a014, 0x01810180}, +- {0x0000a018, 0x01830182}, +- {0x0000a01c, 0x01850184}, +- {0x0000a020, 0x01890188}, +- {0x0000a024, 0x018b018a}, +- {0x0000a028, 0x018d018c}, +- {0x0000a02c, 0x03820190}, +- {0x0000a030, 0x03840383}, +- {0x0000a034, 0x03880385}, +- {0x0000a038, 0x038a0389}, +- {0x0000a03c, 0x038c038b}, +- {0x0000a040, 0x0390038d}, +- {0x0000a044, 0x03920391}, +- {0x0000a048, 0x03940393}, +- {0x0000a04c, 0x03960395}, +- {0x0000a050, 0x00000000}, +- {0x0000a054, 0x00000000}, +- {0x0000a058, 0x00000000}, +- {0x0000a05c, 0x00000000}, +- {0x0000a060, 0x00000000}, +- {0x0000a064, 0x00000000}, +- {0x0000a068, 0x00000000}, +- {0x0000a06c, 0x00000000}, +- {0x0000a070, 0x00000000}, +- {0x0000a074, 0x00000000}, +- {0x0000a078, 0x00000000}, +- {0x0000a07c, 0x00000000}, +- {0x0000a080, 0x29292929}, +- {0x0000a084, 0x29292929}, +- {0x0000a088, 0x29292929}, +- {0x0000a08c, 0x29292929}, +- {0x0000a090, 0x22292929}, +- {0x0000a094, 0x1d1d2222}, +- {0x0000a098, 0x0c111117}, +- {0x0000a09c, 0x00030303}, +- {0x0000a0a0, 0x00000000}, +- {0x0000a0a4, 0x00000000}, +- {0x0000a0a8, 0x00000000}, +- {0x0000a0ac, 0x00000000}, +- {0x0000a0b0, 0x00000000}, +- {0x0000a0b4, 0x00000000}, +- {0x0000a0b8, 0x00000000}, +- {0x0000a0bc, 0x00000000}, +- {0x0000a0c0, 0x001f0000}, +- {0x0000a0c4, 0x01000101}, +- {0x0000a0c8, 0x011e011f}, +- {0x0000a0cc, 0x011c011d}, +- {0x0000a0d0, 0x02030204}, +- {0x0000a0d4, 0x02010202}, +- {0x0000a0d8, 0x021f0200}, +- {0x0000a0dc, 0x0302021e}, +- {0x0000a0e0, 0x03000301}, +- {0x0000a0e4, 0x031e031f}, +- {0x0000a0e8, 0x0402031d}, +- {0x0000a0ec, 0x04000401}, +- {0x0000a0f0, 0x041e041f}, +- {0x0000a0f4, 0x0502041d}, +- {0x0000a0f8, 0x05000501}, +- {0x0000a0fc, 0x051e051f}, +- {0x0000a100, 0x06010602}, +- {0x0000a104, 0x061f0600}, +- {0x0000a108, 0x061d061e}, +- {0x0000a10c, 0x07020703}, +- {0x0000a110, 0x07000701}, +- {0x0000a114, 0x00000000}, +- {0x0000a118, 0x00000000}, +- {0x0000a11c, 0x00000000}, +- {0x0000a120, 0x00000000}, +- {0x0000a124, 0x00000000}, +- {0x0000a128, 0x00000000}, +- {0x0000a12c, 0x00000000}, +- {0x0000a130, 0x00000000}, +- {0x0000a134, 0x00000000}, +- {0x0000a138, 0x00000000}, +- {0x0000a13c, 0x00000000}, +- {0x0000a140, 0x001f0000}, +- {0x0000a144, 0x01000101}, +- {0x0000a148, 0x011e011f}, +- {0x0000a14c, 0x011c011d}, +- {0x0000a150, 0x02030204}, +- {0x0000a154, 0x02010202}, +- {0x0000a158, 0x021f0200}, +- {0x0000a15c, 0x0302021e}, +- {0x0000a160, 0x03000301}, +- {0x0000a164, 0x031e031f}, +- {0x0000a168, 0x0402031d}, +- {0x0000a16c, 0x04000401}, +- {0x0000a170, 0x041e041f}, +- {0x0000a174, 0x0502041d}, +- {0x0000a178, 0x05000501}, +- {0x0000a17c, 0x051e051f}, +- {0x0000a180, 0x06010602}, +- {0x0000a184, 0x061f0600}, +- {0x0000a188, 0x061d061e}, +- {0x0000a18c, 0x07020703}, +- {0x0000a190, 0x07000701}, +- {0x0000a194, 0x00000000}, +- {0x0000a198, 0x00000000}, +- {0x0000a19c, 0x00000000}, +- {0x0000a1a0, 0x00000000}, +- {0x0000a1a4, 0x00000000}, +- {0x0000a1a8, 0x00000000}, +- {0x0000a1ac, 0x00000000}, +- {0x0000a1b0, 0x00000000}, +- {0x0000a1b4, 0x00000000}, +- {0x0000a1b8, 0x00000000}, +- {0x0000a1bc, 0x00000000}, +- {0x0000a1c0, 0x00000000}, +- {0x0000a1c4, 0x00000000}, +- {0x0000a1c8, 0x00000000}, +- {0x0000a1cc, 0x00000000}, +- {0x0000a1d0, 0x00000000}, +- {0x0000a1d4, 0x00000000}, +- {0x0000a1d8, 0x00000000}, +- {0x0000a1dc, 0x00000000}, +- {0x0000a1e0, 0x00000000}, +- {0x0000a1e4, 0x00000000}, +- {0x0000a1e8, 0x00000000}, +- {0x0000a1ec, 0x00000000}, +- {0x0000a1f0, 0x00000396}, +- {0x0000a1f4, 0x00000396}, +- {0x0000a1f8, 0x00000396}, +- {0x0000a1fc, 0x00000196}, +- {0x0000b000, 0x00010000}, +- {0x0000b004, 0x00030002}, +- {0x0000b008, 0x00050004}, +- {0x0000b00c, 0x00810080}, +- {0x0000b010, 0x00830082}, +- {0x0000b014, 0x01810180}, +- {0x0000b018, 0x01830182}, +- {0x0000b01c, 0x01850184}, +- {0x0000b020, 0x02810280}, +- {0x0000b024, 0x02830282}, +- {0x0000b028, 0x02850284}, +- {0x0000b02c, 0x02890288}, +- {0x0000b030, 0x028b028a}, +- {0x0000b034, 0x0388028c}, +- {0x0000b038, 0x038a0389}, +- {0x0000b03c, 0x038c038b}, +- {0x0000b040, 0x0390038d}, +- {0x0000b044, 0x03920391}, +- {0x0000b048, 0x03940393}, +- {0x0000b04c, 0x03960395}, +- {0x0000b050, 0x00000000}, +- {0x0000b054, 0x00000000}, +- {0x0000b058, 0x00000000}, +- {0x0000b05c, 0x00000000}, +- {0x0000b060, 0x00000000}, +- {0x0000b064, 0x00000000}, +- {0x0000b068, 0x00000000}, +- {0x0000b06c, 0x00000000}, +- {0x0000b070, 0x00000000}, +- {0x0000b074, 0x00000000}, +- {0x0000b078, 0x00000000}, +- {0x0000b07c, 0x00000000}, +- {0x0000b080, 0x2a2d2f32}, +- {0x0000b084, 0x21232328}, +- {0x0000b088, 0x19191c1e}, +- {0x0000b08c, 0x12141417}, +- {0x0000b090, 0x07070e0e}, +- {0x0000b094, 0x03030305}, +- {0x0000b098, 0x00000003}, +- {0x0000b09c, 0x00000000}, +- {0x0000b0a0, 0x00000000}, +- {0x0000b0a4, 0x00000000}, +- {0x0000b0a8, 0x00000000}, +- {0x0000b0ac, 0x00000000}, +- {0x0000b0b0, 0x00000000}, +- {0x0000b0b4, 0x00000000}, +- {0x0000b0b8, 0x00000000}, +- {0x0000b0bc, 0x00000000}, +- {0x0000b0c0, 0x003f0020}, +- {0x0000b0c4, 0x00400041}, +- {0x0000b0c8, 0x0140005f}, +- {0x0000b0cc, 0x0160015f}, +- {0x0000b0d0, 0x017e017f}, +- {0x0000b0d4, 0x02410242}, +- {0x0000b0d8, 0x025f0240}, +- {0x0000b0dc, 0x027f0260}, +- {0x0000b0e0, 0x0341027e}, +- {0x0000b0e4, 0x035f0340}, +- {0x0000b0e8, 0x037f0360}, +- {0x0000b0ec, 0x04400441}, +- {0x0000b0f0, 0x0460045f}, +- {0x0000b0f4, 0x0541047f}, +- {0x0000b0f8, 0x055f0540}, +- {0x0000b0fc, 0x057f0560}, +- {0x0000b100, 0x06400641}, +- {0x0000b104, 0x0660065f}, +- {0x0000b108, 0x067e067f}, +- {0x0000b10c, 0x07410742}, +- {0x0000b110, 0x075f0740}, +- {0x0000b114, 0x077f0760}, +- {0x0000b118, 0x07800781}, +- {0x0000b11c, 0x07a0079f}, +- {0x0000b120, 0x07c107bf}, +- {0x0000b124, 0x000007c0}, +- {0x0000b128, 0x00000000}, +- {0x0000b12c, 0x00000000}, +- {0x0000b130, 0x00000000}, +- {0x0000b134, 0x00000000}, +- {0x0000b138, 0x00000000}, +- {0x0000b13c, 0x00000000}, +- {0x0000b140, 0x003f0020}, +- {0x0000b144, 0x00400041}, +- {0x0000b148, 0x0140005f}, +- {0x0000b14c, 0x0160015f}, +- {0x0000b150, 0x017e017f}, +- {0x0000b154, 0x02410242}, +- {0x0000b158, 0x025f0240}, +- {0x0000b15c, 0x027f0260}, +- {0x0000b160, 0x0341027e}, +- {0x0000b164, 0x035f0340}, +- {0x0000b168, 0x037f0360}, +- {0x0000b16c, 0x04400441}, +- {0x0000b170, 0x0460045f}, +- {0x0000b174, 0x0541047f}, +- {0x0000b178, 0x055f0540}, +- {0x0000b17c, 0x057f0560}, +- {0x0000b180, 0x06400641}, +- {0x0000b184, 0x0660065f}, +- {0x0000b188, 0x067e067f}, +- {0x0000b18c, 0x07410742}, +- {0x0000b190, 0x075f0740}, +- {0x0000b194, 0x077f0760}, +- {0x0000b198, 0x07800781}, +- {0x0000b19c, 0x07a0079f}, +- {0x0000b1a0, 0x07c107bf}, +- {0x0000b1a4, 0x000007c0}, +- {0x0000b1a8, 0x00000000}, +- {0x0000b1ac, 0x00000000}, +- {0x0000b1b0, 0x00000000}, +- {0x0000b1b4, 0x00000000}, +- {0x0000b1b8, 0x00000000}, +- {0x0000b1bc, 0x00000000}, +- {0x0000b1c0, 0x00000000}, +- {0x0000b1c4, 0x00000000}, +- {0x0000b1c8, 0x00000000}, +- {0x0000b1cc, 0x00000000}, +- {0x0000b1d0, 0x00000000}, +- {0x0000b1d4, 0x00000000}, +- {0x0000b1d8, 0x00000000}, +- {0x0000b1dc, 0x00000000}, +- {0x0000b1e0, 0x00000000}, +- {0x0000b1e4, 0x00000000}, +- {0x0000b1e8, 0x00000000}, +- {0x0000b1ec, 0x00000000}, +- {0x0000b1f0, 0x00000396}, +- {0x0000b1f4, 0x00000396}, +- {0x0000b1f8, 0x00000396}, +- {0x0000b1fc, 0x00000196}, +-}; +- +-static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = { +- /* Addr allmodes */ +- {0x00009fd0, 0x0a2d6b93}, +-}; +- +-static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae}, +- {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da}, +- {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81}, +- {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8}, +- {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e}, +- {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e}, +-}; +- +-static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, +-}; +- +-static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = { +- /* Addr allmodes */ +- {0x0000a000, 0x00010000}, +- {0x0000a004, 0x00030002}, +- {0x0000a008, 0x00050004}, +- {0x0000a00c, 0x00810080}, +- {0x0000a010, 0x00830082}, +- {0x0000a014, 0x01810180}, +- {0x0000a018, 0x01830182}, +- {0x0000a01c, 0x01850184}, +- {0x0000a020, 0x01890188}, +- {0x0000a024, 0x018b018a}, +- {0x0000a028, 0x018d018c}, +- {0x0000a02c, 0x03820190}, +- {0x0000a030, 0x03840383}, +- {0x0000a034, 0x03880385}, +- {0x0000a038, 0x038a0389}, +- {0x0000a03c, 0x038c038b}, +- {0x0000a040, 0x0390038d}, +- {0x0000a044, 0x03920391}, +- {0x0000a048, 0x03940393}, +- {0x0000a04c, 0x03960395}, +- {0x0000a050, 0x00000000}, +- {0x0000a054, 0x00000000}, +- {0x0000a058, 0x00000000}, +- {0x0000a05c, 0x00000000}, +- {0x0000a060, 0x00000000}, +- {0x0000a064, 0x00000000}, +- {0x0000a068, 0x00000000}, +- {0x0000a06c, 0x00000000}, +- {0x0000a070, 0x00000000}, +- {0x0000a074, 0x00000000}, +- {0x0000a078, 0x00000000}, +- {0x0000a07c, 0x00000000}, +- {0x0000a080, 0x29292929}, +- {0x0000a084, 0x29292929}, +- {0x0000a088, 0x29292929}, +- {0x0000a08c, 0x29292929}, +- {0x0000a090, 0x22292929}, +- {0x0000a094, 0x1d1d2222}, +- {0x0000a098, 0x0c111117}, +- {0x0000a09c, 0x00030303}, +- {0x0000a0a0, 0x00000000}, +- {0x0000a0a4, 0x00000000}, +- {0x0000a0a8, 0x00000000}, +- {0x0000a0ac, 0x00000000}, +- {0x0000a0b0, 0x00000000}, +- {0x0000a0b4, 0x00000000}, +- {0x0000a0b8, 0x00000000}, +- {0x0000a0bc, 0x00000000}, +- {0x0000a0c0, 0x001f0000}, +- {0x0000a0c4, 0x01000101}, +- {0x0000a0c8, 0x011e011f}, +- {0x0000a0cc, 0x011c011d}, +- {0x0000a0d0, 0x02030204}, +- {0x0000a0d4, 0x02010202}, +- {0x0000a0d8, 0x021f0200}, +- {0x0000a0dc, 0x0302021e}, +- {0x0000a0e0, 0x03000301}, +- {0x0000a0e4, 0x031e031f}, +- {0x0000a0e8, 0x0402031d}, +- {0x0000a0ec, 0x04000401}, +- {0x0000a0f0, 0x041e041f}, +- {0x0000a0f4, 0x0502041d}, +- {0x0000a0f8, 0x05000501}, +- {0x0000a0fc, 0x051e051f}, +- {0x0000a100, 0x06010602}, +- {0x0000a104, 0x061f0600}, +- {0x0000a108, 0x061d061e}, +- {0x0000a10c, 0x07020703}, +- {0x0000a110, 0x07000701}, +- {0x0000a114, 0x00000000}, +- {0x0000a118, 0x00000000}, +- {0x0000a11c, 0x00000000}, +- {0x0000a120, 0x00000000}, +- {0x0000a124, 0x00000000}, +- {0x0000a128, 0x00000000}, +- {0x0000a12c, 0x00000000}, +- {0x0000a130, 0x00000000}, +- {0x0000a134, 0x00000000}, +- {0x0000a138, 0x00000000}, +- {0x0000a13c, 0x00000000}, +- {0x0000a140, 0x001f0000}, +- {0x0000a144, 0x01000101}, +- {0x0000a148, 0x011e011f}, +- {0x0000a14c, 0x011c011d}, +- {0x0000a150, 0x02030204}, +- {0x0000a154, 0x02010202}, +- {0x0000a158, 0x021f0200}, +- {0x0000a15c, 0x0302021e}, +- {0x0000a160, 0x03000301}, +- {0x0000a164, 0x031e031f}, +- {0x0000a168, 0x0402031d}, +- {0x0000a16c, 0x04000401}, +- {0x0000a170, 0x041e041f}, +- {0x0000a174, 0x0502041d}, +- {0x0000a178, 0x05000501}, +- {0x0000a17c, 0x051e051f}, +- {0x0000a180, 0x06010602}, +- {0x0000a184, 0x061f0600}, +- {0x0000a188, 0x061d061e}, +- {0x0000a18c, 0x07020703}, +- {0x0000a190, 0x07000701}, +- {0x0000a194, 0x00000000}, +- {0x0000a198, 0x00000000}, +- {0x0000a19c, 0x00000000}, +- {0x0000a1a0, 0x00000000}, +- {0x0000a1a4, 0x00000000}, +- {0x0000a1a8, 0x00000000}, +- {0x0000a1ac, 0x00000000}, +- {0x0000a1b0, 0x00000000}, +- {0x0000a1b4, 0x00000000}, +- {0x0000a1b8, 0x00000000}, +- {0x0000a1bc, 0x00000000}, +- {0x0000a1c0, 0x00000000}, +- {0x0000a1c4, 0x00000000}, +- {0x0000a1c8, 0x00000000}, +- {0x0000a1cc, 0x00000000}, +- {0x0000a1d0, 0x00000000}, +- {0x0000a1d4, 0x00000000}, +- {0x0000a1d8, 0x00000000}, +- {0x0000a1dc, 0x00000000}, +- {0x0000a1e0, 0x00000000}, +- {0x0000a1e4, 0x00000000}, +- {0x0000a1e8, 0x00000000}, +- {0x0000a1ec, 0x00000000}, +- {0x0000a1f0, 0x00000396}, +- {0x0000a1f4, 0x00000396}, +- {0x0000a1f8, 0x00000396}, +- {0x0000a1fc, 0x00000196}, +- {0x0000b000, 0x00010000}, +- {0x0000b004, 0x00030002}, +- {0x0000b008, 0x00050004}, +- {0x0000b00c, 0x00810080}, +- {0x0000b010, 0x00830082}, +- {0x0000b014, 0x01810180}, +- {0x0000b018, 0x01830182}, +- {0x0000b01c, 0x01850184}, +- {0x0000b020, 0x02810280}, +- {0x0000b024, 0x02830282}, +- {0x0000b028, 0x02850284}, +- {0x0000b02c, 0x02890288}, +- {0x0000b030, 0x028b028a}, +- {0x0000b034, 0x0388028c}, +- {0x0000b038, 0x038a0389}, +- {0x0000b03c, 0x038c038b}, +- {0x0000b040, 0x0390038d}, +- {0x0000b044, 0x03920391}, +- {0x0000b048, 0x03940393}, +- {0x0000b04c, 0x03960395}, +- {0x0000b050, 0x00000000}, +- {0x0000b054, 0x00000000}, +- {0x0000b058, 0x00000000}, +- {0x0000b05c, 0x00000000}, +- {0x0000b060, 0x00000000}, +- {0x0000b064, 0x00000000}, +- {0x0000b068, 0x00000000}, +- {0x0000b06c, 0x00000000}, +- {0x0000b070, 0x00000000}, +- {0x0000b074, 0x00000000}, +- {0x0000b078, 0x00000000}, +- {0x0000b07c, 0x00000000}, +- {0x0000b080, 0x32323232}, +- {0x0000b084, 0x2f2f3232}, +- {0x0000b088, 0x23282a2d}, +- {0x0000b08c, 0x1c1e2123}, +- {0x0000b090, 0x14171919}, +- {0x0000b094, 0x0e0e1214}, +- {0x0000b098, 0x03050707}, +- {0x0000b09c, 0x00030303}, +- {0x0000b0a0, 0x00000000}, +- {0x0000b0a4, 0x00000000}, +- {0x0000b0a8, 0x00000000}, +- {0x0000b0ac, 0x00000000}, +- {0x0000b0b0, 0x00000000}, +- {0x0000b0b4, 0x00000000}, +- {0x0000b0b8, 0x00000000}, +- {0x0000b0bc, 0x00000000}, +- {0x0000b0c0, 0x003f0020}, +- {0x0000b0c4, 0x00400041}, +- {0x0000b0c8, 0x0140005f}, +- {0x0000b0cc, 0x0160015f}, +- {0x0000b0d0, 0x017e017f}, +- {0x0000b0d4, 0x02410242}, +- {0x0000b0d8, 0x025f0240}, +- {0x0000b0dc, 0x027f0260}, +- {0x0000b0e0, 0x0341027e}, +- {0x0000b0e4, 0x035f0340}, +- {0x0000b0e8, 0x037f0360}, +- {0x0000b0ec, 0x04400441}, +- {0x0000b0f0, 0x0460045f}, +- {0x0000b0f4, 0x0541047f}, +- {0x0000b0f8, 0x055f0540}, +- {0x0000b0fc, 0x057f0560}, +- {0x0000b100, 0x06400641}, +- {0x0000b104, 0x0660065f}, +- {0x0000b108, 0x067e067f}, +- {0x0000b10c, 0x07410742}, +- {0x0000b110, 0x075f0740}, +- {0x0000b114, 0x077f0760}, +- {0x0000b118, 0x07800781}, +- {0x0000b11c, 0x07a0079f}, +- {0x0000b120, 0x07c107bf}, +- {0x0000b124, 0x000007c0}, +- {0x0000b128, 0x00000000}, +- {0x0000b12c, 0x00000000}, +- {0x0000b130, 0x00000000}, +- {0x0000b134, 0x00000000}, +- {0x0000b138, 0x00000000}, +- {0x0000b13c, 0x00000000}, +- {0x0000b140, 0x003f0020}, +- {0x0000b144, 0x00400041}, +- {0x0000b148, 0x0140005f}, +- {0x0000b14c, 0x0160015f}, +- {0x0000b150, 0x017e017f}, +- {0x0000b154, 0x02410242}, +- {0x0000b158, 0x025f0240}, +- {0x0000b15c, 0x027f0260}, +- {0x0000b160, 0x0341027e}, +- {0x0000b164, 0x035f0340}, +- {0x0000b168, 0x037f0360}, +- {0x0000b16c, 0x04400441}, +- {0x0000b170, 0x0460045f}, +- {0x0000b174, 0x0541047f}, +- {0x0000b178, 0x055f0540}, +- {0x0000b17c, 0x057f0560}, +- {0x0000b180, 0x06400641}, +- {0x0000b184, 0x0660065f}, +- {0x0000b188, 0x067e067f}, +- {0x0000b18c, 0x07410742}, +- {0x0000b190, 0x075f0740}, +- {0x0000b194, 0x077f0760}, +- {0x0000b198, 0x07800781}, +- {0x0000b19c, 0x07a0079f}, +- {0x0000b1a0, 0x07c107bf}, +- {0x0000b1a4, 0x000007c0}, +- {0x0000b1a8, 0x00000000}, +- {0x0000b1ac, 0x00000000}, +- {0x0000b1b0, 0x00000000}, +- {0x0000b1b4, 0x00000000}, +- {0x0000b1b8, 0x00000000}, +- {0x0000b1bc, 0x00000000}, +- {0x0000b1c0, 0x00000000}, +- {0x0000b1c4, 0x00000000}, +- {0x0000b1c8, 0x00000000}, +- {0x0000b1cc, 0x00000000}, +- {0x0000b1d0, 0x00000000}, +- {0x0000b1d4, 0x00000000}, +- {0x0000b1d8, 0x00000000}, +- {0x0000b1dc, 0x00000000}, +- {0x0000b1e0, 0x00000000}, +- {0x0000b1e4, 0x00000000}, +- {0x0000b1e8, 0x00000000}, +- {0x0000b1ec, 0x00000000}, +- {0x0000b1f0, 0x00000396}, +- {0x0000b1f4, 0x00000396}, +- {0x0000b1f8, 0x00000396}, +- {0x0000b1fc, 0x00000196}, +-}; +- +-static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = { +- /* Addr allmodes */ +- {0x0000a000, 0x00010000}, +- {0x0000a004, 0x00030002}, +- {0x0000a008, 0x00050004}, +- {0x0000a00c, 0x00810080}, +- {0x0000a010, 0x00830082}, +- {0x0000a014, 0x01810180}, +- {0x0000a018, 0x01830182}, +- {0x0000a01c, 0x01850184}, +- {0x0000a020, 0x01890188}, +- {0x0000a024, 0x018b018a}, +- {0x0000a028, 0x018d018c}, +- {0x0000a02c, 0x03820190}, +- {0x0000a030, 0x03840383}, +- {0x0000a034, 0x03880385}, +- {0x0000a038, 0x038a0389}, +- {0x0000a03c, 0x038c038b}, +- {0x0000a040, 0x0390038d}, +- {0x0000a044, 0x03920391}, +- {0x0000a048, 0x03940393}, +- {0x0000a04c, 0x03960395}, +- {0x0000a050, 0x00000000}, +- {0x0000a054, 0x00000000}, +- {0x0000a058, 0x00000000}, +- {0x0000a05c, 0x00000000}, +- {0x0000a060, 0x00000000}, +- {0x0000a064, 0x00000000}, +- {0x0000a068, 0x00000000}, +- {0x0000a06c, 0x00000000}, +- {0x0000a070, 0x00000000}, +- {0x0000a074, 0x00000000}, +- {0x0000a078, 0x00000000}, +- {0x0000a07c, 0x00000000}, +- {0x0000a080, 0x29292929}, +- {0x0000a084, 0x29292929}, +- {0x0000a088, 0x29292929}, +- {0x0000a08c, 0x29292929}, +- {0x0000a090, 0x22292929}, +- {0x0000a094, 0x1d1d2222}, +- {0x0000a098, 0x0c111117}, +- {0x0000a09c, 0x00030303}, +- {0x0000a0a0, 0x00000000}, +- {0x0000a0a4, 0x00000000}, +- {0x0000a0a8, 0x00000000}, +- {0x0000a0ac, 0x00000000}, +- {0x0000a0b0, 0x00000000}, +- {0x0000a0b4, 0x00000000}, +- {0x0000a0b8, 0x00000000}, +- {0x0000a0bc, 0x00000000}, +- {0x0000a0c0, 0x001f0000}, +- {0x0000a0c4, 0x01000101}, +- {0x0000a0c8, 0x011e011f}, +- {0x0000a0cc, 0x011c011d}, +- {0x0000a0d0, 0x02030204}, +- {0x0000a0d4, 0x02010202}, +- {0x0000a0d8, 0x021f0200}, +- {0x0000a0dc, 0x0302021e}, +- {0x0000a0e0, 0x03000301}, +- {0x0000a0e4, 0x031e031f}, +- {0x0000a0e8, 0x0402031d}, +- {0x0000a0ec, 0x04000401}, +- {0x0000a0f0, 0x041e041f}, +- {0x0000a0f4, 0x0502041d}, +- {0x0000a0f8, 0x05000501}, +- {0x0000a0fc, 0x051e051f}, +- {0x0000a100, 0x06010602}, +- {0x0000a104, 0x061f0600}, +- {0x0000a108, 0x061d061e}, +- {0x0000a10c, 0x07020703}, +- {0x0000a110, 0x07000701}, +- {0x0000a114, 0x00000000}, +- {0x0000a118, 0x00000000}, +- {0x0000a11c, 0x00000000}, +- {0x0000a120, 0x00000000}, +- {0x0000a124, 0x00000000}, +- {0x0000a128, 0x00000000}, +- {0x0000a12c, 0x00000000}, +- {0x0000a130, 0x00000000}, +- {0x0000a134, 0x00000000}, +- {0x0000a138, 0x00000000}, +- {0x0000a13c, 0x00000000}, +- {0x0000a140, 0x001f0000}, +- {0x0000a144, 0x01000101}, +- {0x0000a148, 0x011e011f}, +- {0x0000a14c, 0x011c011d}, +- {0x0000a150, 0x02030204}, +- {0x0000a154, 0x02010202}, +- {0x0000a158, 0x021f0200}, +- {0x0000a15c, 0x0302021e}, +- {0x0000a160, 0x03000301}, +- {0x0000a164, 0x031e031f}, +- {0x0000a168, 0x0402031d}, +- {0x0000a16c, 0x04000401}, +- {0x0000a170, 0x041e041f}, +- {0x0000a174, 0x0502041d}, +- {0x0000a178, 0x05000501}, +- {0x0000a17c, 0x051e051f}, +- {0x0000a180, 0x06010602}, +- {0x0000a184, 0x061f0600}, +- {0x0000a188, 0x061d061e}, +- {0x0000a18c, 0x07020703}, +- {0x0000a190, 0x07000701}, +- {0x0000a194, 0x00000000}, +- {0x0000a198, 0x00000000}, +- {0x0000a19c, 0x00000000}, +- {0x0000a1a0, 0x00000000}, +- {0x0000a1a4, 0x00000000}, +- {0x0000a1a8, 0x00000000}, +- {0x0000a1ac, 0x00000000}, +- {0x0000a1b0, 0x00000000}, +- {0x0000a1b4, 0x00000000}, +- {0x0000a1b8, 0x00000000}, +- {0x0000a1bc, 0x00000000}, +- {0x0000a1c0, 0x00000000}, +- {0x0000a1c4, 0x00000000}, +- {0x0000a1c8, 0x00000000}, +- {0x0000a1cc, 0x00000000}, +- {0x0000a1d0, 0x00000000}, +- {0x0000a1d4, 0x00000000}, +- {0x0000a1d8, 0x00000000}, +- {0x0000a1dc, 0x00000000}, +- {0x0000a1e0, 0x00000000}, +- {0x0000a1e4, 0x00000000}, +- {0x0000a1e8, 0x00000000}, +- {0x0000a1ec, 0x00000000}, +- {0x0000a1f0, 0x00000396}, +- {0x0000a1f4, 0x00000396}, +- {0x0000a1f8, 0x00000396}, +- {0x0000a1fc, 0x00000196}, +- {0x0000b000, 0x00010000}, +- {0x0000b004, 0x00030002}, +- {0x0000b008, 0x00050004}, +- {0x0000b00c, 0x00810080}, +- {0x0000b010, 0x00830082}, +- {0x0000b014, 0x01810180}, +- {0x0000b018, 0x01830182}, +- {0x0000b01c, 0x01850184}, +- {0x0000b020, 0x02810280}, +- {0x0000b024, 0x02830282}, +- {0x0000b028, 0x02850284}, +- {0x0000b02c, 0x02890288}, +- {0x0000b030, 0x028b028a}, +- {0x0000b034, 0x0388028c}, +- {0x0000b038, 0x038a0389}, +- {0x0000b03c, 0x038c038b}, +- {0x0000b040, 0x0390038d}, +- {0x0000b044, 0x03920391}, +- {0x0000b048, 0x03940393}, +- {0x0000b04c, 0x03960395}, +- {0x0000b050, 0x00000000}, +- {0x0000b054, 0x00000000}, +- {0x0000b058, 0x00000000}, +- {0x0000b05c, 0x00000000}, +- {0x0000b060, 0x00000000}, +- {0x0000b064, 0x00000000}, +- {0x0000b068, 0x00000000}, +- {0x0000b06c, 0x00000000}, +- {0x0000b070, 0x00000000}, +- {0x0000b074, 0x00000000}, +- {0x0000b078, 0x00000000}, +- {0x0000b07c, 0x00000000}, +- {0x0000b080, 0x2a2d2f32}, +- {0x0000b084, 0x21232328}, +- {0x0000b088, 0x19191c1e}, +- {0x0000b08c, 0x12141417}, +- {0x0000b090, 0x07070e0e}, +- {0x0000b094, 0x03030305}, +- {0x0000b098, 0x00000003}, +- {0x0000b09c, 0x00000000}, +- {0x0000b0a0, 0x00000000}, +- {0x0000b0a4, 0x00000000}, +- {0x0000b0a8, 0x00000000}, +- {0x0000b0ac, 0x00000000}, +- {0x0000b0b0, 0x00000000}, +- {0x0000b0b4, 0x00000000}, +- {0x0000b0b8, 0x00000000}, +- {0x0000b0bc, 0x00000000}, +- {0x0000b0c0, 0x003f0020}, +- {0x0000b0c4, 0x00400041}, +- {0x0000b0c8, 0x0140005f}, +- {0x0000b0cc, 0x0160015f}, +- {0x0000b0d0, 0x017e017f}, +- {0x0000b0d4, 0x02410242}, +- {0x0000b0d8, 0x025f0240}, +- {0x0000b0dc, 0x027f0260}, +- {0x0000b0e0, 0x0341027e}, +- {0x0000b0e4, 0x035f0340}, +- {0x0000b0e8, 0x037f0360}, +- {0x0000b0ec, 0x04400441}, +- {0x0000b0f0, 0x0460045f}, +- {0x0000b0f4, 0x0541047f}, +- {0x0000b0f8, 0x055f0540}, +- {0x0000b0fc, 0x057f0560}, +- {0x0000b100, 0x06400641}, +- {0x0000b104, 0x0660065f}, +- {0x0000b108, 0x067e067f}, +- {0x0000b10c, 0x07410742}, +- {0x0000b110, 0x075f0740}, +- {0x0000b114, 0x077f0760}, +- {0x0000b118, 0x07800781}, +- {0x0000b11c, 0x07a0079f}, +- {0x0000b120, 0x07c107bf}, +- {0x0000b124, 0x000007c0}, +- {0x0000b128, 0x00000000}, +- {0x0000b12c, 0x00000000}, +- {0x0000b130, 0x00000000}, +- {0x0000b134, 0x00000000}, +- {0x0000b138, 0x00000000}, +- {0x0000b13c, 0x00000000}, +- {0x0000b140, 0x003f0020}, +- {0x0000b144, 0x00400041}, +- {0x0000b148, 0x0140005f}, +- {0x0000b14c, 0x0160015f}, +- {0x0000b150, 0x017e017f}, +- {0x0000b154, 0x02410242}, +- {0x0000b158, 0x025f0240}, +- {0x0000b15c, 0x027f0260}, +- {0x0000b160, 0x0341027e}, +- {0x0000b164, 0x035f0340}, +- {0x0000b168, 0x037f0360}, +- {0x0000b16c, 0x04400441}, +- {0x0000b170, 0x0460045f}, +- {0x0000b174, 0x0541047f}, +- {0x0000b178, 0x055f0540}, +- {0x0000b17c, 0x057f0560}, +- {0x0000b180, 0x06400641}, +- {0x0000b184, 0x0660065f}, +- {0x0000b188, 0x067e067f}, +- {0x0000b18c, 0x07410742}, +- {0x0000b190, 0x075f0740}, +- {0x0000b194, 0x077f0760}, +- {0x0000b198, 0x07800781}, +- {0x0000b19c, 0x07a0079f}, +- {0x0000b1a0, 0x07c107bf}, +- {0x0000b1a4, 0x000007c0}, +- {0x0000b1a8, 0x00000000}, +- {0x0000b1ac, 0x00000000}, +- {0x0000b1b0, 0x00000000}, +- {0x0000b1b4, 0x00000000}, +- {0x0000b1b8, 0x00000000}, +- {0x0000b1bc, 0x00000000}, +- {0x0000b1c0, 0x00000000}, +- {0x0000b1c4, 0x00000000}, +- {0x0000b1c8, 0x00000000}, +- {0x0000b1cc, 0x00000000}, +- {0x0000b1d0, 0x00000000}, +- {0x0000b1d4, 0x00000000}, +- {0x0000b1d8, 0x00000000}, +- {0x0000b1dc, 0x00000000}, +- {0x0000b1e0, 0x00000000}, +- {0x0000b1e4, 0x00000000}, +- {0x0000b1e8, 0x00000000}, +- {0x0000b1ec, 0x00000000}, +- {0x0000b1f0, 0x00000396}, +- {0x0000b1f4, 0x00000396}, +- {0x0000b1f8, 0x00000396}, +- {0x0000b1fc, 0x00000196}, +-}; +- +-static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, +- {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, +- {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, +- {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, +- {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, +- {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, +- {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, +- {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, +- {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202}, +- {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400}, +- {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402}, +- {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404}, +- {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603}, +- {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02}, +- {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04}, +- {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20}, +- {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20}, +- {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22}, +- {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24}, +- {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640}, +- {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660}, +- {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861}, +- {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81}, +- {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83}, +- {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84}, +- {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3}, +- {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5}, +- {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9}, +- {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb}, +- {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, +- {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, +- {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, +- {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, +- {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, +- {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, +- {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec}, +- {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000}, +- {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501}, +- {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501}, +- {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03}, +- {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, +- {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04}, +- {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005}, +- {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, +- {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, +- {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, +- {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005}, +- {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, +- {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584}, +- {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800}, +- {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, +- {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060}, +- {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, +- {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, +- {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000}, +- {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, +-}; +- +-static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, +- {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, +- {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, +- {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, +- {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de}, +- {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, +- {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, +- {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, +- {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, +- {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, +- {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400}, +- {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402}, +- {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, +- {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603}, +- {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02}, +- {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04}, +- {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20}, +- {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20}, +- {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22}, +- {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24}, +- {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640}, +- {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660}, +- {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861}, +- {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81}, +- {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83}, +- {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84}, +- {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, +- {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, +- {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, +- {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, +- {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec}, +- {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0}, +- {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4}, +- {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, +- {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, +- {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, +- {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6}, +- {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, +- {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, +- {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, +- {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, +- {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, +- {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, +- {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, +- {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, +- {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, +- {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, +- {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, +- {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, +- {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, +- {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, +- {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000}, +- {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, +-}; +- +-static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = { +- /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +- {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, +- {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, +- {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, +- {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, +- {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de}, +- {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, +- {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, +- {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004}, +- {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200}, +- {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202}, +- {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400}, +- {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402}, +- {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404}, +- {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603}, +- {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02}, +- {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04}, +- {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20}, +- {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20}, +- {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22}, +- {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24}, +- {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640}, +- {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660}, +- {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861}, +- {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81}, +- {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83}, +- {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84}, +- {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3}, +- {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5}, +- {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9}, +- {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb}, +- {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec}, +- {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0}, +- {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4}, +- {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, +- {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, +- {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, +- {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6}, +- {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +- {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, +- {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, +- {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501}, +- {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501}, +- {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03}, +- {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04}, +- {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04}, +- {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005}, +- {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, +- {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, +- {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, +- {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +-}; +- +-static const u32 ar9462_2p1_modes_fast_clock[][3] = { +- /* Addr 5G_HT20 5G_HT40 */ +- {0x00001030, 0x00000268, 0x000004d0}, +- {0x00001070, 0x0000018c, 0x00000318}, +- {0x000010b0, 0x00000fd0, 0x00001fa0}, +- {0x00008014, 0x044c044c, 0x08980898}, +- {0x0000801c, 0x148ec02b, 0x148ec057}, +- {0x00008318, 0x000044c0, 0x00008980}, +- {0x00009e00, 0x0372131c, 0x0372131c}, +- {0x0000a230, 0x0000400b, 0x00004016}, +- {0x0000a254, 0x00000898, 0x00001130}, +-}; +- +-static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = { +- /* Addr allmodes */ +- {0x0000a398, 0x00000000}, +- {0x0000a39c, 0x6f7f0301}, +- {0x0000a3a0, 0xca9228ee}, +-}; +- + #endif /* INITVALS_9462_2P1_H */ +--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h +@@ -32,13 +32,6 @@ static const u32 ar9485_1_1_mac_postambl + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, + }; + +-static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = { +- /* Addr allmodes */ +- {0x00018c00, 0x18012e5e}, +- {0x00018c04, 0x000801d8}, +- {0x00018c08, 0x0000080c}, +-}; +- + static const u32 ar9485Common_wo_xlna_rx_gain_1_1[][2] = { + /* Addr allmodes */ + {0x00009e00, 0x037216a0}, +@@ -1101,20 +1094,6 @@ static const u32 ar9485_common_rx_gain_1 + {0x0000a1fc, 0x00000296}, + }; + +-static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = { +- /* Addr allmodes */ +- {0x00018c00, 0x18052e5e}, +- {0x00018c04, 0x000801d8}, +- {0x00018c08, 0x0000080c}, +-}; +- +-static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = { +- /* Addr allmodes */ +- {0x00018c00, 0x18053e5e}, +- {0x00018c04, 0x000801d8}, +- {0x00018c08, 0x0000080c}, +-}; +- + static const u32 ar9485_1_1_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00004014, 0xba280400}, +@@ -1173,13 +1152,6 @@ static const u32 ar9485_1_1_baseband_pos + {0x0000be18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + }; + +-static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { +- /* Addr allmodes */ +- {0x00018c00, 0x18013e5e}, +- {0x00018c04, 0x000801d8}, +- {0x00018c08, 0x0000080c}, +-}; +- + static const u32 ar9485_1_1_radio_postamble[][2] = { + /* Addr allmodes */ + {0x0001609c, 0x0b283f31}, +@@ -1358,4 +1330,18 @@ static const u32 ar9485_1_1_baseband_cor + {0x0000a3a0, 0xca9228ee}, + }; + ++static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = { ++ /* Addr allmodes */ ++ {0x00018c00, 0x18013e5e}, ++ {0x00018c04, 0x000801d8}, ++ {0x00018c08, 0x0000080c}, ++}; ++ ++static const u32 ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1[][2] = { ++ /* Addr allmodes */ ++ {0x00018c00, 0x1801265e}, ++ {0x00018c04, 0x000801d8}, ++ {0x00018c08, 0x0000080c}, ++}; ++ + #endif /* INITVALS_9485_H */ +--- a/drivers/net/wireless/ath/ath9k/pci.c ++++ b/drivers/net/wireless/ath/ath9k/pci.c +@@ -195,6 +195,93 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i + 0x3219), + .driver_data = ATH9K_PCI_BT_ANT_DIV }, + ++ /* AR9485 cards with PLL power-save disabled by default. */ ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x2C97), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x2100), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x1C56, /* ASKEY */ ++ 0x4001), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x11AD, /* LITEON */ ++ 0x6627), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x11AD, /* LITEON */ ++ 0x6628), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_FOXCONN, ++ 0xE04E), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_FOXCONN, ++ 0xE04F), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x144F, /* ASKEY */ ++ 0x7197), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x1B9A, /* XAVI */ ++ 0x2000), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x1B9A, /* XAVI */ ++ 0x2001), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x1186), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x1F86), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x1195), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_AZWAVE, ++ 0x1F95), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x1B9A, /* XAVI */ ++ 0x1C00), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ 0x1B9A, /* XAVI */ ++ 0x1C01), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS, ++ 0x0032, ++ PCI_VENDOR_ID_ASUSTEK, ++ 0x850D), ++ .driver_data = ATH9K_PCI_NO_PLL_PWRSAVE }, ++ + { PCI_VDEVICE(ATHEROS, 0x0032) }, /* PCI-E AR9485 */ + { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ + +--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +@@ -20,7 +20,7 @@ + + /* AR9462 2.0 */ + +-static const u32 ar9462_modes_fast_clock_2p0[][3] = { ++static const u32 ar9462_2p0_modes_fast_clock[][3] = { + /* Addr 5G_HT20 5G_HT40 */ + {0x00001030, 0x00000268, 0x000004d0}, + {0x00001070, 0x0000018c, 0x00000318}, +@@ -33,13 +33,6 @@ static const u32 ar9462_modes_fast_clock + {0x0000a254, 0x00000898, 0x00001130}, + }; + +-static const u32 ar9462_pciephy_clkreq_enable_L1_2p0[][2] = { +- /* Addr allmodes */ +- {0x00018c00, 0x18253ede}, +- {0x00018c04, 0x000801d8}, +- {0x00018c08, 0x0003780c}, +-}; +- + static const u32 ar9462_2p0_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d}, +@@ -99,7 +92,7 @@ static const u32 ar9462_2p0_baseband_pos + {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550}, + }; + +-static const u32 ar9462_common_rx_gain_table_2p0[][2] = { ++static const u32 ar9462_2p0_common_rx_gain[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, +@@ -359,20 +352,13 @@ static const u32 ar9462_common_rx_gain_t + {0x0000b1fc, 0x00000196}, + }; + +-static const u32 ar9462_pciephy_clkreq_disable_L1_2p0[][2] = { ++static const u32 ar9462_2p0_pciephy_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18213ede}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0003780c}, + }; + +-static const u32 ar9462_pciephy_pll_on_clkreq_disable_L1_2p0[][2] = { +- /* Addr allmodes */ +- {0x00018c00, 0x18212ede}, +- {0x00018c04, 0x000801d8}, +- {0x00018c08, 0x0003780c}, +-}; +- + static const u32 ar9462_2p0_radio_postamble_sys2ant[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, +@@ -380,7 +366,7 @@ static const u32 ar9462_2p0_radio_postam + {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, + }; + +-static const u32 ar9462_common_wo_xlna_rx_gain_table_2p0[][2] = { ++static const u32 ar9462_2p0_common_wo_xlna_rx_gain[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, +@@ -647,7 +633,7 @@ static const u32 ar9462_2p0_baseband_cor + {0x0000a3a0, 0xca9228ee}, + }; + +-static const u32 ar9462_modes_low_ob_db_tx_gain_table_2p0[][5] = { ++static const u32 ar9462_2p0_modes_low_ob_db_tx_gain[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, +@@ -879,7 +865,7 @@ static const u32 ar9462_2p0_radio_postam + {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, + }; + +-static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = { ++static const u32 ar9462_2p0_modes_mix_ob_db_tx_gain[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, +@@ -942,7 +928,7 @@ static const u32 ar9462_modes_mix_ob_db_ + {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, + }; + +-static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { ++static const u32 ar9462_2p0_modes_high_ob_db_tx_gain[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, + {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352}, +@@ -1252,7 +1238,7 @@ static const u32 ar9462_2p0_mac_postambl + {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440}, + }; + +-static const u32 ar9462_common_mixed_rx_gain_table_2p0[][2] = { ++static const u32 ar9462_2p0_common_mixed_rx_gain[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, +@@ -1517,7 +1503,7 @@ static const u32 ar9462_2p0_baseband_pos + {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, + }; + +-static const u32 ar9462_2p0_5g_xlna_only_rxgain[][2] = { ++static const u32 ar9462_2p0_common_5g_xlna_only_rxgain[][2] = { + /* Addr allmodes */ + {0x0000a000, 0x00010000}, + {0x0000a004, 0x00030002}, +--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h +@@ -352,7 +352,7 @@ static const u32 ar9300_2p2_baseband_pos + {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, + {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, +- {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, ++ {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982}, + {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, +@@ -378,9 +378,9 @@ static const u32 ar9300_2p2_baseband_cor + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, +- {0x00009834, 0x6400a290}, ++ {0x00009834, 0x6400a190}, + {0x00009838, 0x0108ecff}, +- {0x0000983c, 0x0d000600}, ++ {0x0000983c, 0x14000600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, +@@ -401,7 +401,7 @@ static const u32 ar9300_2p2_baseband_cor + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x9883800a}, +- {0x00009d10, 0x01834061}, ++ {0x00009d10, 0x01884061}, + {0x00009d14, 0x00c0040b}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038230c}, +@@ -459,7 +459,7 @@ static const u32 ar9300_2p2_baseband_cor + {0x0000a3e8, 0x20202020}, + {0x0000a3ec, 0x20202020}, + {0x0000a3f0, 0x00000000}, +- {0x0000a3f4, 0x00000246}, ++ {0x0000a3f4, 0x00000000}, + {0x0000a3f8, 0x0c9bd380}, + {0x0000a3fc, 0x000f0f01}, + {0x0000a400, 0x8fa91f01}, +@@ -644,7 +644,7 @@ static const u32 ar9300Modes_high_ob_db_ + {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584}, + {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800}, + {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, +- {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9}, ++ {0x0000a410, 0x000050d4, 0x000050d4, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002}, + {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004}, +@@ -1086,8 +1086,8 @@ static const u32 ar9300Common_rx_gain_ta + {0x0000b074, 0x00000000}, + {0x0000b078, 0x00000000}, + {0x0000b07c, 0x00000000}, +- {0x0000b080, 0x2a2d2f32}, +- {0x0000b084, 0x21232328}, ++ {0x0000b080, 0x23232323}, ++ {0x0000b084, 0x21232323}, + {0x0000b088, 0x19191c1e}, + {0x0000b08c, 0x12141417}, + {0x0000b090, 0x07070e0e}, +@@ -1385,9 +1385,9 @@ static const u32 ar9300_2p2_mac_core[][2 + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, +- {0x00008244, 0x0010f424}, ++ {0x00008244, 0x0010f400}, + {0x00008248, 0x00000800}, +- {0x0000824c, 0x0001e848}, ++ {0x0000824c, 0x0001e800}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, +@@ -1726,14 +1726,14 @@ static const u32 ar9300PciePhy_pll_on_cl + + static const u32 ar9300PciePhy_clkreq_enable_L1_2p2[][2] = { + /* Addr allmodes */ +- {0x00004040, 0x08253e5e}, ++ {0x00004040, 0x0825365e}, + {0x00004040, 0x0008003b}, + {0x00004044, 0x00000000}, + }; + + static const u32 ar9300PciePhy_clkreq_disable_L1_2p2[][2] = { + /* Addr allmodes */ +- {0x00004040, 0x08213e5e}, ++ {0x00004040, 0x0821365e}, + {0x00004040, 0x0008003b}, + {0x00004044, 0x00000000}, + }; +--- /dev/null ++++ b/drivers/net/wireless/ath/ath9k/ar9565_1p1_initvals.h +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (c) 2010-2011 Atheros Communications Inc. ++ * Copyright (c) 2011-2012 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 ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ++ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ++ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF ++ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#ifndef INITVALS_9565_1P1_H ++#define INITVALS_9565_1P1_H ++ ++/* AR9565 1.1 */ ++ ++#define ar9565_1p1_mac_core ar9565_1p0_mac_core ++ ++#define ar9565_1p1_mac_postamble ar9565_1p0_mac_postamble ++ ++#define ar9565_1p1_baseband_core ar9565_1p0_baseband_core ++ ++#define ar9565_1p1_baseband_postamble ar9565_1p0_baseband_postamble ++ ++#define ar9565_1p1_radio_core ar9565_1p0_radio_core ++ ++#define ar9565_1p1_soc_preamble ar9565_1p0_soc_preamble ++ ++#define ar9565_1p1_soc_postamble ar9565_1p0_soc_postamble ++ ++#define ar9565_1p1_Common_rx_gain_table ar9565_1p0_Common_rx_gain_table ++ ++#define ar9565_1p1_Modes_lowest_ob_db_tx_gain_table ar9565_1p0_Modes_lowest_ob_db_tx_gain_table ++ ++#define ar9565_1p1_pciephy_clkreq_disable_L1 ar9565_1p0_pciephy_clkreq_disable_L1 ++ ++#define ar9565_1p1_modes_fast_clock ar9565_1p0_modes_fast_clock ++ ++#define ar9565_1p1_common_wo_xlna_rx_gain_table ar9565_1p0_common_wo_xlna_rx_gain_table ++ ++#define ar9565_1p1_modes_low_ob_db_tx_gain_table ar9565_1p0_modes_low_ob_db_tx_gain_table ++ ++#define ar9565_1p1_modes_high_ob_db_tx_gain_table ar9565_1p0_modes_high_ob_db_tx_gain_table ++ ++#define ar9565_1p1_modes_high_power_tx_gain_table ar9565_1p0_modes_high_power_tx_gain_table ++ ++#define ar9565_1p1_baseband_core_txfir_coeff_japan_2484 ar9565_1p0_baseband_core_txfir_coeff_japan_2484 ++ ++static const u32 ar9565_1p1_radio_postamble[][5] = { ++ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ++ {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, ++ {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808}, ++ {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, ++ {0x0001610c, 0x40000000, 0x40000000, 0x40000000, 0x40000000}, ++ {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, ++}; ++ ++#endif /* INITVALS_9565_1P1_H */ +--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h ++++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h +@@ -20,18 +20,34 @@ + + /* AR9580 1.0 */ + ++#define ar9580_1p0_soc_preamble ar9300_2p2_soc_preamble ++ ++#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble ++ ++#define ar9580_1p0_radio_core ar9300_2p2_radio_core ++ ++#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble ++ ++#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2 ++ ++#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2 ++ ++#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 ++ + #define ar9580_1p0_modes_fast_clock ar9300Modes_fast_clock_2p2 + ++#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 ++ + static const u32 ar9580_1p0_radio_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0001609c, 0x0dd08f29, 0x0dd08f29, 0x0b283f31, 0x0b283f31}, + {0x000160ac, 0xa4653c00, 0xa4653c00, 0x24652800, 0x24652800}, + {0x000160b0, 0x03284f3e, 0x03284f3e, 0x05d08f20, 0x05d08f20}, +- {0x0001610c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0001610c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000}, + {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, +- {0x0001650c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0001650c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000}, + {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, +- {0x0001690c, 0x08000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0001690c, 0xc8000000, 0xc0000000, 0xc0000000, 0xc0000000}, + {0x00016940, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, + }; + +@@ -44,9 +60,9 @@ static const u32 ar9580_1p0_baseband_cor + {0x00009814, 0x3280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, +- {0x00009834, 0x6400a290}, ++ {0x00009834, 0x6400a190}, + {0x00009838, 0x0108ecff}, +- {0x0000983c, 0x0d000600}, ++ {0x0000983c, 0x14000600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, +@@ -67,7 +83,7 @@ static const u32 ar9580_1p0_baseband_cor + {0x00009d04, 0x40206c10}, + {0x00009d08, 0x009c4060}, + {0x00009d0c, 0x9883800a}, +- {0x00009d10, 0x01834061}, ++ {0x00009d10, 0x01884061}, + {0x00009d14, 0x00c0040b}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0038230c}, +@@ -198,8 +214,6 @@ static const u32 ar9580_1p0_baseband_cor + {0x0000c420, 0x00000000}, + }; + +-#define ar9580_1p0_mac_postamble ar9300_2p2_mac_postamble +- + static const u32 ar9580_1p0_low_ob_db_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352}, +@@ -306,7 +320,112 @@ static const u32 ar9580_1p0_low_ob_db_tx + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + }; + +-#define ar9580_1p0_high_power_tx_gain_table ar9580_1p0_low_ob_db_tx_gain_table ++static const u32 ar9580_1p0_high_power_tx_gain_table[][5] = { ++ /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ ++ {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, ++ {0x0000a2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, ++ {0x0000a2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, ++ {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, ++ {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002}, ++ {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004}, ++ {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200}, ++ {0x0000a510, 0x15000028, 0x15000028, 0x0f000202, 0x0f000202}, ++ {0x0000a514, 0x1b00002b, 0x1b00002b, 0x12000400, 0x12000400}, ++ {0x0000a518, 0x1f020028, 0x1f020028, 0x16000402, 0x16000402}, ++ {0x0000a51c, 0x2502002b, 0x2502002b, 0x19000404, 0x19000404}, ++ {0x0000a520, 0x2a04002a, 0x2a04002a, 0x1c000603, 0x1c000603}, ++ {0x0000a524, 0x2e06002a, 0x2e06002a, 0x21000a02, 0x21000a02}, ++ {0x0000a528, 0x3302202d, 0x3302202d, 0x25000a04, 0x25000a04}, ++ {0x0000a52c, 0x3804202c, 0x3804202c, 0x28000a20, 0x28000a20}, ++ {0x0000a530, 0x3c06202c, 0x3c06202c, 0x2c000e20, 0x2c000e20}, ++ {0x0000a534, 0x4108202d, 0x4108202d, 0x30000e22, 0x30000e22}, ++ {0x0000a538, 0x4506402d, 0x4506402d, 0x34000e24, 0x34000e24}, ++ {0x0000a53c, 0x4906222d, 0x4906222d, 0x38001640, 0x38001640}, ++ {0x0000a540, 0x4d062231, 0x4d062231, 0x3c001660, 0x3c001660}, ++ {0x0000a544, 0x50082231, 0x50082231, 0x3f001861, 0x3f001861}, ++ {0x0000a548, 0x5608422e, 0x5608422e, 0x43001a81, 0x43001a81}, ++ {0x0000a54c, 0x5e08442e, 0x5e08442e, 0x47001a83, 0x47001a83}, ++ {0x0000a550, 0x620a4431, 0x620a4431, 0x4a001c84, 0x4a001c84}, ++ {0x0000a554, 0x640a4432, 0x640a4432, 0x4e001ce3, 0x4e001ce3}, ++ {0x0000a558, 0x680a4434, 0x680a4434, 0x52001ce5, 0x52001ce5}, ++ {0x0000a55c, 0x6c0a6434, 0x6c0a6434, 0x56001ce9, 0x56001ce9}, ++ {0x0000a560, 0x6f0a6633, 0x6f0a6633, 0x5a001ceb, 0x5a001ceb}, ++ {0x0000a564, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a568, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a56c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a570, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a574, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a578, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a57c, 0x730c6634, 0x730c6634, 0x5d001eec, 0x5d001eec}, ++ {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, ++ {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002}, ++ {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004}, ++ {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200}, ++ {0x0000a590, 0x15800028, 0x15800028, 0x0f800202, 0x0f800202}, ++ {0x0000a594, 0x1b80002b, 0x1b80002b, 0x12800400, 0x12800400}, ++ {0x0000a598, 0x1f820028, 0x1f820028, 0x16800402, 0x16800402}, ++ {0x0000a59c, 0x2582002b, 0x2582002b, 0x19800404, 0x19800404}, ++ {0x0000a5a0, 0x2a84002a, 0x2a84002a, 0x1c800603, 0x1c800603}, ++ {0x0000a5a4, 0x2e86002a, 0x2e86002a, 0x21800a02, 0x21800a02}, ++ {0x0000a5a8, 0x3382202d, 0x3382202d, 0x25800a04, 0x25800a04}, ++ {0x0000a5ac, 0x3884202c, 0x3884202c, 0x28800a20, 0x28800a20}, ++ {0x0000a5b0, 0x3c86202c, 0x3c86202c, 0x2c800e20, 0x2c800e20}, ++ {0x0000a5b4, 0x4188202d, 0x4188202d, 0x30800e22, 0x30800e22}, ++ {0x0000a5b8, 0x4586402d, 0x4586402d, 0x34800e24, 0x34800e24}, ++ {0x0000a5bc, 0x4986222d, 0x4986222d, 0x38801640, 0x38801640}, ++ {0x0000a5c0, 0x4d862231, 0x4d862231, 0x3c801660, 0x3c801660}, ++ {0x0000a5c4, 0x50882231, 0x50882231, 0x3f801861, 0x3f801861}, ++ {0x0000a5c8, 0x5688422e, 0x5688422e, 0x43801a81, 0x43801a81}, ++ {0x0000a5cc, 0x5a88442e, 0x5a88442e, 0x47801a83, 0x47801a83}, ++ {0x0000a5d0, 0x5e8a4431, 0x5e8a4431, 0x4a801c84, 0x4a801c84}, ++ {0x0000a5d4, 0x648a4432, 0x648a4432, 0x4e801ce3, 0x4e801ce3}, ++ {0x0000a5d8, 0x688a4434, 0x688a4434, 0x52801ce5, 0x52801ce5}, ++ {0x0000a5dc, 0x6c8a6434, 0x6c8a6434, 0x56801ce9, 0x56801ce9}, ++ {0x0000a5e0, 0x6f8a6633, 0x6f8a6633, 0x5a801ceb, 0x5a801ceb}, ++ {0x0000a5e4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5e8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5ec, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f0, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f4, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5f8, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a5fc, 0x738c6634, 0x738c6634, 0x5d801eec, 0x5d801eec}, ++ {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, ++ {0x0000a608, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, ++ {0x0000a60c, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, ++ {0x0000a610, 0x01804601, 0x01804601, 0x00000000, 0x00000000}, ++ {0x0000a614, 0x01804601, 0x01804601, 0x01404000, 0x01404000}, ++ {0x0000a618, 0x01804601, 0x01804601, 0x01404501, 0x01404501}, ++ {0x0000a61c, 0x01804601, 0x01804601, 0x02008501, 0x02008501}, ++ {0x0000a620, 0x03408d02, 0x03408d02, 0x0280ca03, 0x0280ca03}, ++ {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04}, ++ {0x0000a628, 0x03410d04, 0x03410d04, 0x04014c04, 0x04014c04}, ++ {0x0000a62c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, ++ {0x0000a630, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, ++ {0x0000a634, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, ++ {0x0000a638, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, ++ {0x0000a63c, 0x03410d04, 0x03410d04, 0x04015005, 0x04015005}, ++ {0x0000b2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, ++ {0x0000b2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, ++ {0x0000b2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, ++ {0x0000c2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, ++ {0x0000c2e0, 0x000f0000, 0x000f0000, 0x03ccc584, 0x03ccc584}, ++ {0x0000c2e4, 0x03f00000, 0x03f00000, 0x03f0f800, 0x03f0f800}, ++ {0x0000c2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000}, ++ {0x00016044, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, ++ {0x00016048, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, ++ {0x00016068, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, ++ {0x00016288, 0x05a2040a, 0x05a2040a, 0x05a20408, 0x05a20408}, ++ {0x00016444, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, ++ {0x00016448, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, ++ {0x00016468, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, ++ {0x00016844, 0x012492d4, 0x012492d4, 0x012492d4, 0x012492d4}, ++ {0x00016848, 0x65240001, 0x65240001, 0x66480001, 0x66480001}, ++ {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, ++}; + + static const u32 ar9580_1p0_lowest_ob_db_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ +@@ -414,8 +533,6 @@ static const u32 ar9580_1p0_lowest_ob_db + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + }; + +-#define ar9580_1p0_baseband_core_txfir_coeff_japan_2484 ar9462_2p0_baseband_core_txfir_coeff_japan_2484 +- + static const u32 ar9580_1p0_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, +@@ -679,14 +796,6 @@ static const u32 ar9580_1p0_mixed_ob_db_ + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + }; + +-#define ar9580_1p0_wo_xlna_rx_gain_table ar9300Common_wo_xlna_rx_gain_table_2p2 +- +-#define ar9580_1p0_soc_postamble ar9300_2p2_soc_postamble +- +-#define ar9580_1p0_high_ob_db_tx_gain_table ar9300Modes_high_ob_db_tx_gain_table_2p2 +- +-#define ar9580_1p0_type5_tx_gain_table ar9300Modes_type5_tx_gain_table_2p2 +- + static const u32 ar9580_1p0_type6_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0x000cfff0, 0x000cfff0, 0x03aaa352, 0x03aaa352}, +@@ -761,160 +870,264 @@ static const u32 ar9580_1p0_type6_tx_gai + {0x00016868, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c, 0x6db6db6c}, + }; + +-static const u32 ar9580_1p0_soc_preamble[][2] = { +- /* Addr allmodes */ +- {0x000040a4, 0x00a0c1c9}, +- {0x00007008, 0x00000000}, +- {0x00007020, 0x00000000}, +- {0x00007034, 0x00000002}, +- {0x00007038, 0x000004c2}, +- {0x00007048, 0x00000008}, +-}; +- +-#define ar9580_1p0_rx_gain_table ar9462_common_rx_gain_table_2p0 +- +-static const u32 ar9580_1p0_radio_core[][2] = { ++static const u32 ar9580_1p0_rx_gain_table[][2] = { + /* Addr allmodes */ +- {0x00016000, 0x36db6db6}, +- {0x00016004, 0x6db6db40}, +- {0x00016008, 0x73f00000}, +- {0x0001600c, 0x00000000}, +- {0x00016040, 0x7f80fff8}, +- {0x0001604c, 0x76d005b5}, +- {0x00016050, 0x556cf031}, +- {0x00016054, 0x13449440}, +- {0x00016058, 0x0c51c92c}, +- {0x0001605c, 0x3db7fffc}, +- {0x00016060, 0xfffffffc}, +- {0x00016064, 0x000f0278}, +- {0x0001606c, 0x6db60000}, +- {0x00016080, 0x00000000}, +- {0x00016084, 0x0e48048c}, +- {0x00016088, 0x54214514}, +- {0x0001608c, 0x119f481e}, +- {0x00016090, 0x24926490}, +- {0x00016098, 0xd2888888}, +- {0x000160a0, 0x0a108ffe}, +- {0x000160a4, 0x812fc370}, +- {0x000160a8, 0x423c8000}, +- {0x000160b4, 0x92480080}, +- {0x000160c0, 0x00adb6d0}, +- {0x000160c4, 0x6db6db60}, +- {0x000160c8, 0x6db6db6c}, +- {0x000160cc, 0x01e6c000}, +- {0x00016100, 0x3fffbe01}, +- {0x00016104, 0xfff80000}, +- {0x00016108, 0x00080010}, +- {0x00016144, 0x02084080}, +- {0x00016148, 0x00000000}, +- {0x00016280, 0x058a0001}, +- {0x00016284, 0x3d840208}, +- {0x00016288, 0x05a20408}, +- {0x0001628c, 0x00038c07}, +- {0x00016290, 0x00000004}, +- {0x00016294, 0x458aa14f}, +- {0x00016380, 0x00000000}, +- {0x00016384, 0x00000000}, +- {0x00016388, 0x00800700}, +- {0x0001638c, 0x00800700}, +- {0x00016390, 0x00800700}, +- {0x00016394, 0x00000000}, +- {0x00016398, 0x00000000}, +- {0x0001639c, 0x00000000}, +- {0x000163a0, 0x00000001}, +- {0x000163a4, 0x00000001}, +- {0x000163a8, 0x00000000}, +- {0x000163ac, 0x00000000}, +- {0x000163b0, 0x00000000}, +- {0x000163b4, 0x00000000}, +- {0x000163b8, 0x00000000}, +- {0x000163bc, 0x00000000}, +- {0x000163c0, 0x000000a0}, +- {0x000163c4, 0x000c0000}, +- {0x000163c8, 0x14021402}, +- {0x000163cc, 0x00001402}, +- {0x000163d0, 0x00000000}, +- {0x000163d4, 0x00000000}, +- {0x00016400, 0x36db6db6}, +- {0x00016404, 0x6db6db40}, +- {0x00016408, 0x73f00000}, +- {0x0001640c, 0x00000000}, +- {0x00016440, 0x7f80fff8}, +- {0x0001644c, 0x76d005b5}, +- {0x00016450, 0x556cf031}, +- {0x00016454, 0x13449440}, +- {0x00016458, 0x0c51c92c}, +- {0x0001645c, 0x3db7fffc}, +- {0x00016460, 0xfffffffc}, +- {0x00016464, 0x000f0278}, +- {0x0001646c, 0x6db60000}, +- {0x00016500, 0x3fffbe01}, +- {0x00016504, 0xfff80000}, +- {0x00016508, 0x00080010}, +- {0x00016544, 0x02084080}, +- {0x00016548, 0x00000000}, +- {0x00016780, 0x00000000}, +- {0x00016784, 0x00000000}, +- {0x00016788, 0x00800700}, +- {0x0001678c, 0x00800700}, +- {0x00016790, 0x00800700}, +- {0x00016794, 0x00000000}, +- {0x00016798, 0x00000000}, +- {0x0001679c, 0x00000000}, +- {0x000167a0, 0x00000001}, +- {0x000167a4, 0x00000001}, +- {0x000167a8, 0x00000000}, +- {0x000167ac, 0x00000000}, +- {0x000167b0, 0x00000000}, +- {0x000167b4, 0x00000000}, +- {0x000167b8, 0x00000000}, +- {0x000167bc, 0x00000000}, +- {0x000167c0, 0x000000a0}, +- {0x000167c4, 0x000c0000}, +- {0x000167c8, 0x14021402}, +- {0x000167cc, 0x00001402}, +- {0x000167d0, 0x00000000}, +- {0x000167d4, 0x00000000}, +- {0x00016800, 0x36db6db6}, +- {0x00016804, 0x6db6db40}, +- {0x00016808, 0x73f00000}, +- {0x0001680c, 0x00000000}, +- {0x00016840, 0x7f80fff8}, +- {0x0001684c, 0x76d005b5}, +- {0x00016850, 0x556cf031}, +- {0x00016854, 0x13449440}, +- {0x00016858, 0x0c51c92c}, +- {0x0001685c, 0x3db7fffc}, +- {0x00016860, 0xfffffffc}, +- {0x00016864, 0x000f0278}, +- {0x0001686c, 0x6db60000}, +- {0x00016900, 0x3fffbe01}, +- {0x00016904, 0xfff80000}, +- {0x00016908, 0x00080010}, +- {0x00016944, 0x02084080}, +- {0x00016948, 0x00000000}, +- {0x00016b80, 0x00000000}, +- {0x00016b84, 0x00000000}, +- {0x00016b88, 0x00800700}, +- {0x00016b8c, 0x00800700}, +- {0x00016b90, 0x00800700}, +- {0x00016b94, 0x00000000}, +- {0x00016b98, 0x00000000}, +- {0x00016b9c, 0x00000000}, +- {0x00016ba0, 0x00000001}, +- {0x00016ba4, 0x00000001}, +- {0x00016ba8, 0x00000000}, +- {0x00016bac, 0x00000000}, +- {0x00016bb0, 0x00000000}, +- {0x00016bb4, 0x00000000}, +- {0x00016bb8, 0x00000000}, +- {0x00016bbc, 0x00000000}, +- {0x00016bc0, 0x000000a0}, +- {0x00016bc4, 0x000c0000}, +- {0x00016bc8, 0x14021402}, +- {0x00016bcc, 0x00001402}, +- {0x00016bd0, 0x00000000}, +- {0x00016bd4, 0x00000000}, ++ {0x0000a000, 0x00010000}, ++ {0x0000a004, 0x00030002}, ++ {0x0000a008, 0x00050004}, ++ {0x0000a00c, 0x00810080}, ++ {0x0000a010, 0x00830082}, ++ {0x0000a014, 0x01810180}, ++ {0x0000a018, 0x01830182}, ++ {0x0000a01c, 0x01850184}, ++ {0x0000a020, 0x01890188}, ++ {0x0000a024, 0x018b018a}, ++ {0x0000a028, 0x018d018c}, ++ {0x0000a02c, 0x01910190}, ++ {0x0000a030, 0x01930192}, ++ {0x0000a034, 0x01950194}, ++ {0x0000a038, 0x038a0196}, ++ {0x0000a03c, 0x038c038b}, ++ {0x0000a040, 0x0390038d}, ++ {0x0000a044, 0x03920391}, ++ {0x0000a048, 0x03940393}, ++ {0x0000a04c, 0x03960395}, ++ {0x0000a050, 0x00000000}, ++ {0x0000a054, 0x00000000}, ++ {0x0000a058, 0x00000000}, ++ {0x0000a05c, 0x00000000}, ++ {0x0000a060, 0x00000000}, ++ {0x0000a064, 0x00000000}, ++ {0x0000a068, 0x00000000}, ++ {0x0000a06c, 0x00000000}, ++ {0x0000a070, 0x00000000}, ++ {0x0000a074, 0x00000000}, ++ {0x0000a078, 0x00000000}, ++ {0x0000a07c, 0x00000000}, ++ {0x0000a080, 0x22222229}, ++ {0x0000a084, 0x1d1d1d1d}, ++ {0x0000a088, 0x1d1d1d1d}, ++ {0x0000a08c, 0x1d1d1d1d}, ++ {0x0000a090, 0x171d1d1d}, ++ {0x0000a094, 0x11111717}, ++ {0x0000a098, 0x00030311}, ++ {0x0000a09c, 0x00000000}, ++ {0x0000a0a0, 0x00000000}, ++ {0x0000a0a4, 0x00000000}, ++ {0x0000a0a8, 0x00000000}, ++ {0x0000a0ac, 0x00000000}, ++ {0x0000a0b0, 0x00000000}, ++ {0x0000a0b4, 0x00000000}, ++ {0x0000a0b8, 0x00000000}, ++ {0x0000a0bc, 0x00000000}, ++ {0x0000a0c0, 0x001f0000}, ++ {0x0000a0c4, 0x01000101}, ++ {0x0000a0c8, 0x011e011f}, ++ {0x0000a0cc, 0x011c011d}, ++ {0x0000a0d0, 0x02030204}, ++ {0x0000a0d4, 0x02010202}, ++ {0x0000a0d8, 0x021f0200}, ++ {0x0000a0dc, 0x0302021e}, ++ {0x0000a0e0, 0x03000301}, ++ {0x0000a0e4, 0x031e031f}, ++ {0x0000a0e8, 0x0402031d}, ++ {0x0000a0ec, 0x04000401}, ++ {0x0000a0f0, 0x041e041f}, ++ {0x0000a0f4, 0x0502041d}, ++ {0x0000a0f8, 0x05000501}, ++ {0x0000a0fc, 0x051e051f}, ++ {0x0000a100, 0x06010602}, ++ {0x0000a104, 0x061f0600}, ++ {0x0000a108, 0x061d061e}, ++ {0x0000a10c, 0x07020703}, ++ {0x0000a110, 0x07000701}, ++ {0x0000a114, 0x00000000}, ++ {0x0000a118, 0x00000000}, ++ {0x0000a11c, 0x00000000}, ++ {0x0000a120, 0x00000000}, ++ {0x0000a124, 0x00000000}, ++ {0x0000a128, 0x00000000}, ++ {0x0000a12c, 0x00000000}, ++ {0x0000a130, 0x00000000}, ++ {0x0000a134, 0x00000000}, ++ {0x0000a138, 0x00000000}, ++ {0x0000a13c, 0x00000000}, ++ {0x0000a140, 0x001f0000}, ++ {0x0000a144, 0x01000101}, ++ {0x0000a148, 0x011e011f}, ++ {0x0000a14c, 0x011c011d}, ++ {0x0000a150, 0x02030204}, ++ {0x0000a154, 0x02010202}, ++ {0x0000a158, 0x021f0200}, ++ {0x0000a15c, 0x0302021e}, ++ {0x0000a160, 0x03000301}, ++ {0x0000a164, 0x031e031f}, ++ {0x0000a168, 0x0402031d}, ++ {0x0000a16c, 0x04000401}, ++ {0x0000a170, 0x041e041f}, ++ {0x0000a174, 0x0502041d}, ++ {0x0000a178, 0x05000501}, ++ {0x0000a17c, 0x051e051f}, ++ {0x0000a180, 0x06010602}, ++ {0x0000a184, 0x061f0600}, ++ {0x0000a188, 0x061d061e}, ++ {0x0000a18c, 0x07020703}, ++ {0x0000a190, 0x07000701}, ++ {0x0000a194, 0x00000000}, ++ {0x0000a198, 0x00000000}, ++ {0x0000a19c, 0x00000000}, ++ {0x0000a1a0, 0x00000000}, ++ {0x0000a1a4, 0x00000000}, ++ {0x0000a1a8, 0x00000000}, ++ {0x0000a1ac, 0x00000000}, ++ {0x0000a1b0, 0x00000000}, ++ {0x0000a1b4, 0x00000000}, ++ {0x0000a1b8, 0x00000000}, ++ {0x0000a1bc, 0x00000000}, ++ {0x0000a1c0, 0x00000000}, ++ {0x0000a1c4, 0x00000000}, ++ {0x0000a1c8, 0x00000000}, ++ {0x0000a1cc, 0x00000000}, ++ {0x0000a1d0, 0x00000000}, ++ {0x0000a1d4, 0x00000000}, ++ {0x0000a1d8, 0x00000000}, ++ {0x0000a1dc, 0x00000000}, ++ {0x0000a1e0, 0x00000000}, ++ {0x0000a1e4, 0x00000000}, ++ {0x0000a1e8, 0x00000000}, ++ {0x0000a1ec, 0x00000000}, ++ {0x0000a1f0, 0x00000396}, ++ {0x0000a1f4, 0x00000396}, ++ {0x0000a1f8, 0x00000396}, ++ {0x0000a1fc, 0x00000196}, ++ {0x0000b000, 0x00010000}, ++ {0x0000b004, 0x00030002}, ++ {0x0000b008, 0x00050004}, ++ {0x0000b00c, 0x00810080}, ++ {0x0000b010, 0x00830082}, ++ {0x0000b014, 0x01810180}, ++ {0x0000b018, 0x01830182}, ++ {0x0000b01c, 0x01850184}, ++ {0x0000b020, 0x02810280}, ++ {0x0000b024, 0x02830282}, ++ {0x0000b028, 0x02850284}, ++ {0x0000b02c, 0x02890288}, ++ {0x0000b030, 0x028b028a}, ++ {0x0000b034, 0x0388028c}, ++ {0x0000b038, 0x038a0389}, ++ {0x0000b03c, 0x038c038b}, ++ {0x0000b040, 0x0390038d}, ++ {0x0000b044, 0x03920391}, ++ {0x0000b048, 0x03940393}, ++ {0x0000b04c, 0x03960395}, ++ {0x0000b050, 0x00000000}, ++ {0x0000b054, 0x00000000}, ++ {0x0000b058, 0x00000000}, ++ {0x0000b05c, 0x00000000}, ++ {0x0000b060, 0x00000000}, ++ {0x0000b064, 0x00000000}, ++ {0x0000b068, 0x00000000}, ++ {0x0000b06c, 0x00000000}, ++ {0x0000b070, 0x00000000}, ++ {0x0000b074, 0x00000000}, ++ {0x0000b078, 0x00000000}, ++ {0x0000b07c, 0x00000000}, ++ {0x0000b080, 0x23232323}, ++ {0x0000b084, 0x21232323}, ++ {0x0000b088, 0x19191c1e}, ++ {0x0000b08c, 0x12141417}, ++ {0x0000b090, 0x07070e0e}, ++ {0x0000b094, 0x03030305}, ++ {0x0000b098, 0x00000003}, ++ {0x0000b09c, 0x00000000}, ++ {0x0000b0a0, 0x00000000}, ++ {0x0000b0a4, 0x00000000}, ++ {0x0000b0a8, 0x00000000}, ++ {0x0000b0ac, 0x00000000}, ++ {0x0000b0b0, 0x00000000}, ++ {0x0000b0b4, 0x00000000}, ++ {0x0000b0b8, 0x00000000}, ++ {0x0000b0bc, 0x00000000}, ++ {0x0000b0c0, 0x003f0020}, ++ {0x0000b0c4, 0x00400041}, ++ {0x0000b0c8, 0x0140005f}, ++ {0x0000b0cc, 0x0160015f}, ++ {0x0000b0d0, 0x017e017f}, ++ {0x0000b0d4, 0x02410242}, ++ {0x0000b0d8, 0x025f0240}, ++ {0x0000b0dc, 0x027f0260}, ++ {0x0000b0e0, 0x0341027e}, ++ {0x0000b0e4, 0x035f0340}, ++ {0x0000b0e8, 0x037f0360}, ++ {0x0000b0ec, 0x04400441}, ++ {0x0000b0f0, 0x0460045f}, ++ {0x0000b0f4, 0x0541047f}, ++ {0x0000b0f8, 0x055f0540}, ++ {0x0000b0fc, 0x057f0560}, ++ {0x0000b100, 0x06400641}, ++ {0x0000b104, 0x0660065f}, ++ {0x0000b108, 0x067e067f}, ++ {0x0000b10c, 0x07410742}, ++ {0x0000b110, 0x075f0740}, ++ {0x0000b114, 0x077f0760}, ++ {0x0000b118, 0x07800781}, ++ {0x0000b11c, 0x07a0079f}, ++ {0x0000b120, 0x07c107bf}, ++ {0x0000b124, 0x000007c0}, ++ {0x0000b128, 0x00000000}, ++ {0x0000b12c, 0x00000000}, ++ {0x0000b130, 0x00000000}, ++ {0x0000b134, 0x00000000}, ++ {0x0000b138, 0x00000000}, ++ {0x0000b13c, 0x00000000}, ++ {0x0000b140, 0x003f0020}, ++ {0x0000b144, 0x00400041}, ++ {0x0000b148, 0x0140005f}, ++ {0x0000b14c, 0x0160015f}, ++ {0x0000b150, 0x017e017f}, ++ {0x0000b154, 0x02410242}, ++ {0x0000b158, 0x025f0240}, ++ {0x0000b15c, 0x027f0260}, ++ {0x0000b160, 0x0341027e}, ++ {0x0000b164, 0x035f0340}, ++ {0x0000b168, 0x037f0360}, ++ {0x0000b16c, 0x04400441}, ++ {0x0000b170, 0x0460045f}, ++ {0x0000b174, 0x0541047f}, ++ {0x0000b178, 0x055f0540}, ++ {0x0000b17c, 0x057f0560}, ++ {0x0000b180, 0x06400641}, ++ {0x0000b184, 0x0660065f}, ++ {0x0000b188, 0x067e067f}, ++ {0x0000b18c, 0x07410742}, ++ {0x0000b190, 0x075f0740}, ++ {0x0000b194, 0x077f0760}, ++ {0x0000b198, 0x07800781}, ++ {0x0000b19c, 0x07a0079f}, ++ {0x0000b1a0, 0x07c107bf}, ++ {0x0000b1a4, 0x000007c0}, ++ {0x0000b1a8, 0x00000000}, ++ {0x0000b1ac, 0x00000000}, ++ {0x0000b1b0, 0x00000000}, ++ {0x0000b1b4, 0x00000000}, ++ {0x0000b1b8, 0x00000000}, ++ {0x0000b1bc, 0x00000000}, ++ {0x0000b1c0, 0x00000000}, ++ {0x0000b1c4, 0x00000000}, ++ {0x0000b1c8, 0x00000000}, ++ {0x0000b1cc, 0x00000000}, ++ {0x0000b1d0, 0x00000000}, ++ {0x0000b1d4, 0x00000000}, ++ {0x0000b1d8, 0x00000000}, ++ {0x0000b1dc, 0x00000000}, ++ {0x0000b1e0, 0x00000000}, ++ {0x0000b1e4, 0x00000000}, ++ {0x0000b1e8, 0x00000000}, ++ {0x0000b1ec, 0x00000000}, ++ {0x0000b1f0, 0x00000396}, ++ {0x0000b1f4, 0x00000396}, ++ {0x0000b1f8, 0x00000396}, ++ {0x0000b1fc, 0x00000196}, + }; + + static const u32 ar9580_1p0_baseband_postamble[][5] = { +@@ -956,7 +1169,7 @@ static const u32 ar9580_1p0_baseband_pos + {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110}, + {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222}, + {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18}, +- {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982}, ++ {0x0000a2d0, 0x00041983, 0x00041983, 0x00041981, 0x00041982}, + {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c}, +--- a/drivers/net/wireless/ath/ath9k/reg.h ++++ b/drivers/net/wireless/ath/ath9k/reg.h +@@ -809,6 +809,8 @@ + #define AR_SREV_REVISION_9462_21 3 + #define AR_SREV_VERSION_9565 0x2C0 + #define AR_SREV_REVISION_9565_10 0 ++#define AR_SREV_REVISION_9565_101 1 ++#define AR_SREV_REVISION_9565_11 2 + #define AR_SREV_VERSION_9550 0x400 + + #define AR_SREV_5416(_ah) \ +@@ -927,10 +929,18 @@ + + #define AR_SREV_9565(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) +- + #define AR_SREV_9565_10(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ + ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_10)) ++#define AR_SREV_9565_101(_ah) \ ++ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ ++ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_101)) ++#define AR_SREV_9565_11(_ah) \ ++ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ ++ ((_ah)->hw_version.macRev == AR_SREV_REVISION_9565_11)) ++#define AR_SREV_9565_11_OR_LATER(_ah) \ ++ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565) && \ ++ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9565_11)) - mutex_unlock(&priv->htc_pm_lock); + #define AR_SREV_9550(_ah) \ + (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550))