diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2012-10-09 15:03:21 +0100 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2012-10-09 15:04:25 +0100 |
commit | ffe315012510165ce82e4dd4767f0a5dba9edbf7 (patch) | |
tree | f601cd980af9d0ced5ca9aedecef4fa0d2ca0e15 /drivers/net/wireless/ath | |
parent | e2d3a35ee427aaba99b6c68a56609ce276c51270 (diff) | |
parent | 4a8e43feeac7996b8de2d5b2823e316917493df4 (diff) |
Merge tag 'disintegrate-mtd-20121009' of git://git.infradead.org/users/dhowells/linux-headers
UAPI Disintegration 2012-10-09
Conflicts:
MAINTAINERS
arch/arm/configs/bcmring_defconfig
arch/arm/mach-imx/clk-imx51-imx53.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/bcm_umi_nand.c
drivers/mtd/nand/nand_bcm_umi.h
drivers/mtd/nand/orion_nand.c
Diffstat (limited to 'drivers/net/wireless/ath')
52 files changed, 2322 insertions, 445 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h index 6169fbd23ed..4521342c62c 100644 --- a/drivers/net/wireless/ath/ath.h +++ b/drivers/net/wireless/ath/ath.h @@ -159,6 +159,7 @@ struct ath_common { bool btcoex_enabled; bool disable_ani; + bool antenna_diversity; }; struct sk_buff *ath_rxbuf_alloc(struct ath_common *common, diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9d48f9a461e..9fd6d9a9942 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -2057,9 +2057,7 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) void ath5k_beacon_config(struct ath5k_hw *ah) { - unsigned long flags; - - spin_lock_irqsave(&ah->block, flags); + spin_lock_bh(&ah->block); ah->bmisscount = 0; ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); @@ -2086,7 +2084,7 @@ ath5k_beacon_config(struct ath5k_hw *ah) ath5k_hw_set_imr(ah, ah->imask); mmiowb(); - spin_unlock_irqrestore(&ah->block, flags); + spin_unlock_bh(&ah->block); } static void ath5k_tasklet_beacon(unsigned long data) @@ -2448,6 +2446,7 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | + IEEE80211_HW_MFP_CAPABLE | IEEE80211_HW_REPORTS_TX_ACK_STATUS; hw->wiphy->interface_modes = diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 4026c906cc7..b7e0258887e 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c @@ -1482,7 +1482,7 @@ ath5k_eeprom_read_target_rate_pwr_info(struct ath5k_hw *ah, unsigned int mode) case AR5K_EEPROM_MODE_11A: offset += AR5K_EEPROM_TARGET_PWR_OFF_11A(ee->ee_version); rate_pcal_info = ee->ee_rate_tpwr_a; - ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_CHAN; + ee->ee_rate_target_pwr_num[mode] = AR5K_EEPROM_N_5GHZ_RATE_CHAN; break; case AR5K_EEPROM_MODE_11B: offset += AR5K_EEPROM_TARGET_PWR_OFF_11B(ee->ee_version); diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h index dc2bcfeadeb..94a9bbea687 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.h +++ b/drivers/net/wireless/ath/ath5k/eeprom.h @@ -182,6 +182,7 @@ #define AR5K_EEPROM_EEP_DELTA 10 #define AR5K_EEPROM_N_MODES 3 #define AR5K_EEPROM_N_5GHZ_CHAN 10 +#define AR5K_EEPROM_N_5GHZ_RATE_CHAN 8 #define AR5K_EEPROM_N_2GHZ_CHAN 3 #define AR5K_EEPROM_N_2GHZ_CHAN_2413 4 #define AR5K_EEPROM_N_2GHZ_CHAN_MAX 4 diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index c89fa6ead61..7a28538e6e0 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c @@ -255,7 +255,6 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ath5k_vif *avf = (void *)vif->drv_priv; struct ath5k_hw *ah = hw->priv; struct ath_common *common = ath5k_hw_common(ah); - unsigned long flags; mutex_lock(&ah->lock); @@ -301,9 +300,9 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, } if (changes & BSS_CHANGED_BEACON) { - spin_lock_irqsave(&ah->block, flags); + spin_lock_bh(&ah->block); ath5k_beacon_update(hw, vif); - spin_unlock_irqrestore(&ah->block, flags); + spin_unlock_bh(&ah->block); } if (changes & BSS_CHANGED_BEACON_ENABLED) @@ -490,6 +489,9 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (ath5k_modparam_nohwcrypt) return -EOPNOTSUPP; + if (key->flags & IEEE80211_KEY_FLAG_RX_MGMT) + return -EOPNOTSUPP; + if (vif->type == NL80211_IFTYPE_ADHOC && (key->cipher == WLAN_CIPHER_SUITE_TKIP || key->cipher == WLAN_CIPHER_SUITE_CCMP) && @@ -524,7 +526,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, if (key->cipher == WLAN_CIPHER_SUITE_TKIP) key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; if (key->cipher == WLAN_CIPHER_SUITE_CCMP) - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ret = 0; } break; diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index 01c90ed5845..ab363f34b4d 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c @@ -1975,11 +1975,13 @@ ath5k_hw_set_spur_mitigation_filter(struct ath5k_hw *ah, spur_delta_phase = (spur_offset << 18) / 25; spur_freq_sigma_delta = (spur_delta_phase >> 10); symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 2; + break; case AR5K_BWMODE_5MHZ: /* Both sample_freq and chip_freq are 10MHz (?) */ spur_delta_phase = (spur_offset << 19) / 25; spur_freq_sigma_delta = (spur_delta_phase >> 10); symbol_width = AR5K_SPUR_SYMBOL_WIDTH_BASE_100Hz / 4; + break; default: if (channel->band == IEEE80211_BAND_5GHZ) { /* Both sample_freq and chip_freq are 40MHz */ diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c index 86aeef4b9d7..7089f8160ad 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.c +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c @@ -1488,7 +1488,7 @@ static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy, } static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy, - char *name, + const char *name, enum nl80211_iftype type, u32 *flags, struct vif_params *params) @@ -3477,7 +3477,7 @@ void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif) ar->num_vif--; } -struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name, +struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type) { diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h index 56b1ebe7981..780f77775a9 100644 --- a/drivers/net/wireless/ath/ath6kl/cfg80211.h +++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h @@ -25,7 +25,7 @@ enum ath6kl_cfg_suspend_mode { ATH6KL_CFG_SUSPEND_SCHED_SCAN, }; -struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, char *name, +struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name, enum nl80211_iftype type, u8 fw_vif_idx, u8 nw_type); void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq, diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index ff007f500fe..e09ec40ce71 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -237,7 +237,7 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, entry_cck->fir_step_level); /* Skip MRC CCK for pre AR9003 families */ - if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah)) + if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) return; if (aniState->mrcCCK != entry_cck->mrc_cck_on) diff --git a/drivers/net/wireless/ath/ath9k/antenna.c b/drivers/net/wireless/ath/ath9k/antenna.c index bbcfeb3b2a6..664844c5d3d 100644 --- a/drivers/net/wireless/ath/ath9k/antenna.c +++ b/drivers/net/wireless/ath/ath9k/antenna.c @@ -311,6 +311,9 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, struct ath_ant_comb *antcomb, int alt_ratio) { + ant_conf->main_gaintb = 0; + ant_conf->alt_gaintb = 0; + if (ant_conf->div_group == 0) { /* Adjust the fast_div_bias based on main and alt lna conf */ switch ((ant_conf->main_lna_conf << 4) | @@ -360,18 +363,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->alt_lna_conf) { case 0x01: /* A-B LNA2 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x02: /* A-B LNA1 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x03: /* A-B A+B */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x10: /* LNA2 A-B */ if (!(antcomb->scan) && @@ -379,13 +376,9 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x3f; else ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x12: /* LNA2 LNA1 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x13: /* LNA2 A+B */ if (!(antcomb->scan) && @@ -393,8 +386,6 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x3f; else ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x20: /* LNA1 A-B */ if (!(antcomb->scan) && @@ -402,13 +393,9 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x3f; else ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x21: /* LNA1 LNA2 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x23: /* LNA1 A+B */ if (!(antcomb->scan) && @@ -416,23 +403,15 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x3f; else ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x30: /* A+B A-B */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x31: /* A+B LNA2 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x32: /* A+B LNA1 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; default: break; @@ -443,18 +422,12 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->alt_lna_conf) { case 0x01: /* A-B LNA2 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x02: /* A-B LNA1 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x03: /* A-B A+B */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x10: /* LNA2 A-B */ if (!(antcomb->scan) && @@ -462,13 +435,9 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x1; else ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x12: /* LNA2 LNA1 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x13: /* LNA2 A+B */ if (!(antcomb->scan) && @@ -476,8 +445,6 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x1; else ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x20: /* LNA1 A-B */ if (!(antcomb->scan) && @@ -485,13 +452,9 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x1; else ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x21: /* LNA1 LNA2 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x23: /* LNA1 A+B */ if (!(antcomb->scan) && @@ -499,23 +462,77 @@ static void ath_ant_div_conf_fast_divbias(struct ath_hw_antcomb_conf *ant_conf, ant_conf->fast_div_bias = 0x1; else ant_conf->fast_div_bias = 0x2; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x30: /* A+B A-B */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x31: /* A+B LNA2 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; break; case 0x32: /* A+B LNA1 */ ant_conf->fast_div_bias = 0x1; - ant_conf->main_gaintb = 0; - ant_conf->alt_gaintb = 0; + break; + default: + break; + } + } else if (ant_conf->div_group == 3) { + switch ((ant_conf->main_lna_conf << 4) | + ant_conf->alt_lna_conf) { + case 0x01: /* A-B LNA2 */ + ant_conf->fast_div_bias = 0x1; + break; + case 0x02: /* A-B LNA1 */ + ant_conf->fast_div_bias = 0x39; + break; + case 0x03: /* A-B A+B */ + ant_conf->fast_div_bias = 0x1; + break; + case 0x10: /* LNA2 A-B */ + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x1; + } + break; + case 0x12: /* LNA2 LNA1 */ + ant_conf->fast_div_bias = 0x39; + break; + case 0x13: /* LNA2 A+B */ + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x1; + } + break; + case 0x20: /* LNA1 A-B */ + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x4; + } + break; + case 0x21: /* LNA1 LNA2 */ + ant_conf->fast_div_bias = 0x6; + break; + case 0x23: /* LNA1 A+B */ + if ((antcomb->scan == 0) && + (alt_ratio > ATH_ANT_DIV_COMB_ALT_ANT_RATIO)) { + ant_conf->fast_div_bias = 0x3f; + } else { + ant_conf->fast_div_bias = 0x6; + } + break; + case 0x30: /* A+B A-B */ + ant_conf->fast_div_bias = 0x1; + break; + case 0x31: /* A+B LNA2 */ + ant_conf->fast_div_bias = 0x6; + break; + case 0x32: /* A+B LNA1 */ + ant_conf->fast_div_bias = 0x1; break; default: break; @@ -759,6 +776,7 @@ div_comb_done: void ath_ant_comb_update(struct ath_softc *sc) { struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); struct ath_hw_antcomb_conf div_ant_conf; u8 lna_conf; @@ -773,4 +791,7 @@ void ath_ant_comb_update(struct ath_softc *sc) div_ant_conf.alt_lna_conf = lna_conf; ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf); + + if (common->antenna_diversity) + ath9k_hw_antctrl_shared_chain_lnadiv(ah, true); } diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c37fe9620e4..5bbe5057ba1 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -138,7 +138,8 @@ static const struct ar9300_eeprom ar9300_default = { }, .base_ext1 = { .ant_div_control = 0, - .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + .future = {0, 0, 0}, + .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} }, .calFreqPier2G = { FREQ2FBIN(2412, 1), @@ -713,7 +714,8 @@ static const struct ar9300_eeprom ar9300_x113 = { }, .base_ext1 = { .ant_div_control = 0, - .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + .future = {0, 0, 0}, + .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} }, .calFreqPier2G = { FREQ2FBIN(2412, 1), @@ -1289,7 +1291,8 @@ static const struct ar9300_eeprom ar9300_h112 = { }, .base_ext1 = { .ant_div_control = 0, - .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + .future = {0, 0, 0}, + .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} }, .calFreqPier2G = { FREQ2FBIN(2412, 1), @@ -1865,7 +1868,8 @@ static const struct ar9300_eeprom ar9300_x112 = { }, .base_ext1 = { .ant_div_control = 0, - .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + .future = {0, 0, 0}, + .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} }, .calFreqPier2G = { FREQ2FBIN(2412, 1), @@ -2440,7 +2444,8 @@ static const struct ar9300_eeprom ar9300_h116 = { }, .base_ext1 = { .ant_div_control = 0, - .future = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + .future = {0, 0, 0}, + .tempslopextension = {0, 0, 0, 0, 0, 0, 0, 0} }, .calFreqPier2G = { FREQ2FBIN(2412, 1), @@ -2982,6 +2987,10 @@ static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, case EEP_RX_MASK: return pBase->txrxMask & 0xf; case EEP_PAPRD: + if (AR_SREV_9462(ah)) + return false; + if (!ah->config.enable_paprd); + return false; return !!(pBase->featureEnable & BIT(5)); case EEP_CHAIN_MASK_REDUCE: return (pBase->miscConfiguration >> 0x3) & 0x1; @@ -3520,7 +3529,7 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz) if (AR_SREV_9485(ah) || AR_SREV_9330(ah) || AR_SREV_9340(ah)) REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias); - else if (AR_SREV_9462(ah) || AR_SREV_9550(ah)) + else if (AR_SREV_9462(ah) || AR_SREV_9550(ah) || AR_SREV_9565(ah)) REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); else { REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias); @@ -3557,9 +3566,9 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain, static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) { + struct ath9k_hw_capabilities *pCap = &ah->caps; int chain; u32 regval; - u32 ant_div_ctl1; static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = { AR_PHY_SWITCH_CHAIN_0, AR_PHY_SWITCH_CHAIN_1, @@ -3568,7 +3577,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz); - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_AR9462_ALL, value); } else if (AR_SREV_9550(ah)) { @@ -3612,7 +3621,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) } } - if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { + if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) { value = ath9k_hw_ar9300_get_eeprom(ah, EEP_ANT_DIV_CTL1); /* * main_lnaconf, alt_lnaconf, main_tb, alt_tb @@ -3622,41 +3631,44 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz) regval &= (~AR_ANT_DIV_CTRL_ALL); regval |= (value & 0x3f) << AR_ANT_DIV_CTRL_ALL_S; /* enable_lnadiv */ - regval &= (~AR_PHY_9485_ANT_DIV_LNADIV); - regval |= ((value >> 6) & 0x1) << - AR_PHY_9485_ANT_DIV_LNADIV_S; + regval &= (~AR_PHY_ANT_DIV_LNADIV); + regval |= ((value >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S; + + if (AR_SREV_9565(ah)) { + if (ah->shared_chain_lnadiv) { + regval |= (1 << AR_PHY_ANT_SW_RX_PROT_S); + } else { + regval &= ~(1 << AR_PHY_ANT_DIV_LNADIV_S); + regval &= ~(1 << AR_PHY_ANT_SW_RX_PROT_S); + } + } + REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); /*enable fast_div */ regval = REG_READ(ah, AR_PHY_CCK_DETECT); regval &= (~AR_FAST_DIV_ENABLE); - regval |= ((value >> 7) & 0x1) << - AR_FAST_DIV_ENABLE_S; + regval |= ((value >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S; REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); - ant_div_ctl1 = - ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); - /* check whether antenna diversity is enabled */ - if ((ant_div_ctl1 >> 0x6) == 0x3) { + + if (pCap->hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB) { regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); /* * clear bits 25-30 main_lnaconf, alt_lnaconf, * main_tb, alt_tb */ - regval &= (~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF | - AR_PHY_9485_ANT_DIV_ALT_LNACONF | - AR_PHY_9485_ANT_DIV_ALT_GAINTB | - AR_PHY_9485_ANT_DIV_MAIN_GAINTB)); + regval &= (~(AR_PHY_ANT_DIV_MAIN_LNACONF | + AR_PHY_ANT_DIV_ALT_LNACONF | + AR_PHY_ANT_DIV_ALT_GAINTB | + AR_PHY_ANT_DIV_MAIN_GAINTB)); /* by default use LNA1 for the main antenna */ - regval |= (AR_PHY_9485_ANT_DIV_LNA1 << - AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S); - regval |= (AR_PHY_9485_ANT_DIV_LNA2 << - AR_PHY_9485_ANT_DIV_ALT_LNACONF_S); + regval |= (AR_PHY_ANT_DIV_LNA1 << + AR_PHY_ANT_DIV_MAIN_LNACONF_S); + regval |= (AR_PHY_ANT_DIV_LNA2 << + AR_PHY_ANT_DIV_ALT_LNACONF_S); REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); } - - } - } static void ar9003_hw_drive_strength_apply(struct ath_hw *ah) @@ -3843,7 +3855,7 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) REG_WRITE(ah, AR_PHY_PMU2, reg_pmu_set); if (!is_pmu_set(ah, AR_PHY_PMU2, reg_pmu_set)) return; - } else if (AR_SREV_9462(ah)) { + } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { reg_val = le32_to_cpu(pBase->swreg); REG_WRITE(ah, AR_PHY_PMU1, reg_val); } else { @@ -3874,7 +3886,7 @@ void ar9003_hw_internal_regulator_apply(struct ath_hw *ah) while (!REG_READ_FIELD(ah, AR_PHY_PMU2, AR_PHY_PMU2_PGM)) udelay(10); - } else if (AR_SREV_9462(ah)) + } else if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) REG_RMW_FIELD(ah, AR_PHY_PMU1, AR_PHY_PMU1_PWD, 0x1); else { reg_val = REG_READ(ah, AR_RTC_SLEEP_CLK) | @@ -3977,6 +3989,62 @@ static void ar9003_hw_xlna_bias_strength_apply(struct ath_hw *ah, bool is2ghz) bias & 0x3); } +static int ar9003_hw_get_thermometer(struct ath_hw *ah) +{ + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; + struct ar9300_base_eep_hdr *pBase = &eep->baseEepHeader; + int thermometer = (pBase->miscConfiguration >> 1) & 0x3; + + return --thermometer; +} + +static void ar9003_hw_thermometer_apply(struct ath_hw *ah) +{ + int thermometer = ar9003_hw_get_thermometer(ah); + u8 therm_on = (thermometer < 0) ? 0 : 1; + + REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, + AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on); + if (ah->caps.tx_chainmask & BIT(1)) + REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, + AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on); + if (ah->caps.tx_chainmask & BIT(2)) + REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, + AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR, therm_on); + + therm_on = (thermometer < 0) ? 0 : (thermometer == 0); + REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_RXTX4, + AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on); + if (ah->caps.tx_chainmask & BIT(1)) { + therm_on = (thermometer < 0) ? 0 : (thermometer == 1); + REG_RMW_FIELD(ah, AR_PHY_65NM_CH1_RXTX4, + AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on); + } + if (ah->caps.tx_chainmask & BIT(2)) { + therm_on = (thermometer < 0) ? 0 : (thermometer == 2); + REG_RMW_FIELD(ah, AR_PHY_65NM_CH2_RXTX4, + AR_PHY_65NM_CH0_RXTX4_THERM_ON, therm_on); + } +} + +static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah) +{ + u32 data, ko, kg; + + if (!AR_SREV_9462_20(ah)) + return; + ar9300_otp_read_word(ah, 1, &data); + ko = data & 0xff; + kg = (data >> 8) & 0xff; + if (ko || kg) { + REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3, + AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET, ko); + REG_RMW_FIELD(ah, AR_PHY_BB_THERM_ADC_3, + AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN, + kg + 256); + } +} + static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, struct ath9k_channel *chan) { @@ -3992,6 +4060,8 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah, ar9003_hw_internal_regulator_apply(ah); ar9003_hw_apply_tuning_caps(ah); ar9003_hw_txend_to_xpa_off_apply(ah, is2ghz); + ar9003_hw_thermometer_apply(ah); + ar9003_hw_thermo_cal_apply(ah); } static void ath9k_hw_ar9300_set_addac(struct ath_hw *ah, @@ -4528,7 +4598,7 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, { int tempSlope = 0; struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; - int f[3], t[3]; + int f[8], t[8], i; REG_RMW(ah, AR_PHY_TPC_11_B0, (correction[0] << AR_PHY_TPC_OLPC_GAIN_DELTA_S), @@ -4561,7 +4631,14 @@ static int ar9003_hw_power_control_override(struct ath_hw *ah, */ if (frequency < 4000) tempSlope = eep->modalHeader2G.tempSlope; - else if (eep->base_ext2.tempSlopeLow != 0) { + else if ((eep->baseEepHeader.miscConfiguration & 0x20) != 0) { + for (i = 0; i < 8; i++) { + t[i] = eep->base_ext1.tempslopextension[i]; + f[i] = FBIN2FREQ(eep->calFreqPier5G[i], 0); + } + tempSlope = ar9003_hw_power_interpolate((s32) frequency, + f, t, 8); + } else if (eep->base_ext2.tempSlopeLow != 0) { t[0] = eep->base_ext2.tempSlopeLow; f[0] = 5180; t[1] = eep->modalHeader5G.tempSlope; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 3a1ff55bceb..41b1a75e6be 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -267,7 +267,8 @@ struct cal_ctl_data_5g { struct ar9300_BaseExtension_1 { u8 ant_div_control; - u8 future[11]; + u8 future[3]; + u8 tempslopextension[8]; int8_t quick_drop_low; int8_t quick_drop_high; } __packed; diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c index 1e8a4da5952..1a36fa26263 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c @@ -24,6 +24,7 @@ #include "ar955x_1p0_initvals.h" #include "ar9580_1p0_initvals.h" #include "ar9462_2p0_initvals.h" +#include "ar9565_1p0_initvals.h" /* General hardware code for the AR9003 hadware family */ @@ -34,14 +35,12 @@ */ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) { -#define PCIE_PLL_ON_CREQ_DIS_L1_2P0 \ - ar9462_pciephy_pll_on_clkreq_disable_L1_2p0 - #define AR9462_BB_CTX_COEFJ(x) \ ar9462_##x##_baseband_core_txfir_coeff_japan_2484 #define AR9462_BBC_TXIFR_COEFFJ \ ar9462_2p0_baseband_core_txfir_coeff_japan_2484 + if (AR_SREV_9330_11(ah)) { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], @@ -220,10 +219,10 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) /* Awake -> Sleep Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdes, - PCIE_PLL_ON_CREQ_DIS_L1_2P0); + ar9462_pciephy_pll_on_clkreq_disable_L1_2p0); /* Sleep -> Awake Setting */ INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, - PCIE_PLL_ON_CREQ_DIS_L1_2P0); + ar9462_pciephy_pll_on_clkreq_disable_L1_2p0); /* Fast clock modal settings */ INIT_INI_ARRAY(&ah->iniModesFastClock, @@ -302,6 +301,39 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah) INIT_INI_ARRAY(&ah->iniModesFastClock, ar9580_1p0_modes_fast_clock); + } else if (AR_SREV_9565(ah)) { + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], + ar9565_1p0_mac_core); + INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST], + ar9565_1p0_mac_postamble); + + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE], + ar9565_1p0_baseband_core); + INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST], + ar9565_1p0_baseband_postamble); + + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE], + ar9565_1p0_radio_core); + INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST], + ar9565_1p0_radio_postamble); + + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE], + ar9565_1p0_soc_preamble); + INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], + ar9565_1p0_soc_postamble); + + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9565_1p0_Common_rx_gain_table); + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_Modes_lowest_ob_db_tx_gain_table); + + INIT_INI_ARRAY(&ah->iniPcieSerdes, + ar9565_1p0_pciephy_pll_on_clkreq_disable_L1); + INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, + ar9565_1p0_pciephy_pll_on_clkreq_disable_L1); + + INIT_INI_ARRAY(&ah->iniModesFastClock, + ar9565_1p0_modes_fast_clock); } else { /* mac */ INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], @@ -374,6 +406,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah) else if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9462_modes_low_ob_db_tx_gain_table_2p0); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_modes_low_ob_db_tx_gain_table); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_lowest_ob_db_tx_gain_table_2p2); @@ -402,6 +437,9 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah) else if (AR_SREV_9462_20(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9462_modes_high_ob_db_tx_gain_table_2p0); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_modes_high_ob_db_tx_gain_table); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_high_ob_db_tx_gain_table_2p2); @@ -424,6 +462,9 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah) else if (AR_SREV_9580(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9580_1p0_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); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_low_ob_db_tx_gain_table_2p2); @@ -446,6 +487,9 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah) else if (AR_SREV_9580(ah)) INIT_INI_ARRAY(&ah->iniModesTxGain, ar9580_1p0_high_power_tx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesTxGain, + ar9565_1p0_modes_high_power_tx_gain_table); else INIT_INI_ARRAY(&ah->iniModesTxGain, ar9300Modes_high_power_tx_gain_table_2p2); @@ -538,6 +582,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah) } else if (AR_SREV_9580(ah)) INIT_INI_ARRAY(&ah->iniModesRxGain, ar9580_1p0_wo_xlna_rx_gain_table); + else if (AR_SREV_9565(ah)) + INIT_INI_ARRAY(&ah->iniModesRxGain, + ar9565_1p0_common_wo_xlna_rx_gain_table); else INIT_INI_ARRAY(&ah->iniModesRxGain, ar9300Common_wo_xlna_rx_gain_table_2p2); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c index 78816b8b217..301bf72c53b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c @@ -31,7 +31,7 @@ ar9003_set_txdesc(struct ath_hw *ah, void *ds, struct ath_tx_info *i) u32 val, ctl12, ctl17; u8 desc_len; - desc_len = (AR_SREV_9462(ah) ? 0x18 : 0x17); + desc_len = ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x18 : 0x17); val = (ATHEROS_VENDOR_ID << AR_DescId_S) | (1 << AR_TxRxDesc_S) | @@ -182,6 +182,7 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) struct ath9k_hw_capabilities *pCap = &ah->caps; struct ath_common *common = ath9k_hw_common(ah); u32 sync_cause = 0, async_cause, async_mask = AR_INTR_MAC_IRQ; + bool fatal_int; if (ath9k_hw_mci_is_enabled(ah)) async_mask |= AR_INTR_ASYNC_MASK_MCI; @@ -310,6 +311,22 @@ static bool ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked) if (sync_cause) { ath9k_debug_sync_cause(common, sync_cause); + fatal_int = + (sync_cause & + (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR)) + ? true : false; + + if (fatal_int) { + if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) { + ath_dbg(common, ANY, + "received PCI FATAL interrupt\n"); + } + if (sync_cause & AR_INTR_SYNC_HOST1_PERR) { + ath_dbg(common, ANY, + "received PCI PERR interrupt\n"); + } + *masked |= ATH9K_INT_FATAL; + } if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) { REG_WRITE(ah, AR_RC, AR_RC_HOSTIF); @@ -531,7 +548,7 @@ int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah, struct ath_rx_status *rxs, rxs->rs_status |= ATH9K_RXERR_PHY; rxs->rs_phyerr = phyerr; } - }; + } } if (rxsp->status11 & AR_KeyMiss) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c index 9a34fcaae3f..44c202ce6c6 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c @@ -714,6 +714,7 @@ bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan) return true; } +EXPORT_SYMBOL(ar9003_mci_start_reset); int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata) @@ -812,8 +813,8 @@ static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable) AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); } -void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, - bool is_full_sleep) +int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, + bool is_full_sleep) { struct ath_common *common = ath9k_hw_common(ah); struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; @@ -823,14 +824,13 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, is_full_sleep, is_2g); if (!mci->gpm_addr && !mci->sched_addr) { - ath_dbg(common, MCI, - "MCI GPM and schedule buffers are not allocated\n"); - return; + ath_err(common, "MCI GPM and schedule buffers are not allocated\n"); + return -ENOMEM; } if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { - ath_dbg(common, MCI, "BTCOEX control register is dead\n"); - return; + ath_err(common, "BTCOEX control register is dead\n"); + return -EINVAL; } /* Program MCI DMA related registers */ @@ -912,6 +912,8 @@ void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, if (en_int) ar9003_mci_enable_interrupt(ah); + + return 0; } void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep) @@ -1026,6 +1028,7 @@ void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force) if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA)) ar9003_mci_osla_setup(ah, true); + REG_WRITE(ah, AR_SELFGEN_MASK, 0x02); } else { ar9003_mci_send_lna_take(ah, true); udelay(5); @@ -1142,8 +1145,8 @@ void ar9003_mci_init_cal_done(struct ath_hw *ah) ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false); } -void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, - u16 len, u32 sched_addr) +int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, + u16 len, u32 sched_addr) { struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci; @@ -1152,7 +1155,7 @@ void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, mci->gpm_len = len; mci->sched_addr = sched_addr; - ar9003_mci_reset(ah, true, true, true); + return ar9003_mci_reset(ah, true, true, true); } EXPORT_SYMBOL(ar9003_mci_setup); @@ -1201,12 +1204,6 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) ar9003_mci_2g5g_switch(ah, false); break; - case MCI_STATE_SET_BT_CAL_START: - mci->bt_state = MCI_BT_CAL_START; - break; - case MCI_STATE_SET_BT_CAL: - mci->bt_state = MCI_BT_CAL; - break; case MCI_STATE_RESET_REQ_WAKE: ar9003_mci_reset_req_wakeup(ah); mci->update_2g5g = true; @@ -1240,6 +1237,10 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type) case MCI_STATE_NEED_FTP_STOMP: value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP); break; + case MCI_STATE_NEED_FLUSH_BT_INFO: + value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0; + mci->need_flush_btinfo = false; + break; default: break; } @@ -1289,7 +1290,7 @@ void ar9003_mci_set_power_awake(struct ath_hw *ah) } REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18))); lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3; - bt_sleep = REG_READ(ah, AR_MCI_RX_STATUS) & AR_MCI_RX_REMOTE_SLEEP; + bt_sleep = MS(REG_READ(ah, AR_MCI_RX_STATUS), AR_MCI_RX_REMOTE_SLEEP); REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2); REG_WRITE(ah, AR_DIAG_SW, diag_sw); @@ -1327,6 +1328,10 @@ u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) if (first) { gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); + + if (gpm_ptr >= mci->gpm_len) + gpm_ptr = 0; + mci->gpm_idx = gpm_ptr; return gpm_ptr; } @@ -1371,6 +1376,10 @@ u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, bool first, u32 *more) more_gpm = MCI_GPM_NOMORE; temp_index = mci->gpm_idx; + + if (temp_index >= mci->gpm_len) + temp_index = 0; + mci->gpm_idx++; if (mci->gpm_idx >= mci->gpm_len) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h index d33b8e12885..2a2d0188961 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h @@ -190,8 +190,6 @@ enum mci_bt_state { enum mci_state_type { MCI_STATE_ENABLE, MCI_STATE_SET_BT_AWAKE, - MCI_STATE_SET_BT_CAL_START, - MCI_STATE_SET_BT_CAL, MCI_STATE_LAST_SCHD_MSG_OFFSET, MCI_STATE_REMOTE_SLEEP, MCI_STATE_RESET_REQ_WAKE, @@ -202,6 +200,7 @@ enum mci_state_type { MCI_STATE_RECOVER_RX, MCI_STATE_NEED_FTP_STOMP, MCI_STATE_DEBUG, + MCI_STATE_NEED_FLUSH_BT_INFO, MCI_STATE_MAX }; @@ -213,7 +212,8 @@ enum mci_gpm_coex_opcode { MCI_GPM_COEX_WLAN_CHANNELS, MCI_GPM_COEX_BT_PROFILE_INFO, MCI_GPM_COEX_BT_STATUS_UPDATE, - MCI_GPM_COEX_BT_UPDATE_FLAGS + MCI_GPM_COEX_BT_UPDATE_FLAGS, + MCI_GPM_COEX_NOOP, }; #define MCI_GPM_NOMORE 0 @@ -249,8 +249,8 @@ bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag, u32 *payload, u8 len, bool wait_done, bool check_bt); u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type); -void ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, - u16 len, u32 sched_addr); +int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf, + u16 len, u32 sched_addr); void ar9003_mci_cleanup(struct ath_hw *ah); void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr, u32 *rx_msg_intr); @@ -272,8 +272,8 @@ void ar9003_mci_check_bt(struct ath_hw *ah); bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan); int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata); -void ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, - bool is_full_sleep); +int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g, + bool is_full_sleep); void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked); void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah); void ar9003_mci_set_power_awake(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c index 2c9f7d7ed4c..0ed3846f9cb 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c @@ -142,6 +142,7 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) }; int training_power; int i, val; + u32 am2pm_mask = ah->paprd_ratemask; if (IS_CHAN_2GHZ(ah->curchan)) training_power = ar9003_get_training_power_2g(ah); @@ -158,10 +159,13 @@ static int ar9003_paprd_setup_single_table(struct ath_hw *ah) } ah->paprd_training_power = training_power; + if (AR_SREV_9330(ah)) + am2pm_mask = 0; + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, ah->paprd_ratemask); REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, - ah->paprd_ratemask); + am2pm_mask); REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ah->paprd_ratemask_ht40); @@ -782,6 +786,102 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) } EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); +static bool ar9003_paprd_retrain_pa_in(struct ath_hw *ah, + struct ath9k_hw_cal_data *caldata, + int chain) +{ + u32 *pa_in = caldata->pa_table[chain]; + int capdiv_offset, quick_drop_offset; + int capdiv2g, quick_drop; + int count = 0; + int i; + + if (!AR_SREV_9485(ah) && !AR_SREV_9330(ah)) + return false; + + capdiv2g = REG_READ_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, + AR_PHY_65NM_CH0_TXRF3_CAPDIV2G); + + quick_drop = REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP); + + if (quick_drop) + quick_drop -= 0x40; + + for (i = 0; i < NUM_BIN + 1; i++) { + if (pa_in[i] == 1400) + count++; + } + + if (AR_SREV_9485(ah)) { + if (pa_in[23] < 800) { + capdiv_offset = (int)((1000 - pa_in[23] + 75) / 150); + capdiv2g += capdiv_offset; + if (capdiv2g > 7) { + capdiv2g = 7; + if (pa_in[23] < 600) { + quick_drop++; + if (quick_drop > 0) + quick_drop = 0; + } + } + } else if (pa_in[23] == 1400) { + quick_drop_offset = min_t(int, count / 3, 2); + quick_drop += quick_drop_offset; + capdiv2g += quick_drop_offset / 2; + + if (capdiv2g > 7) + capdiv2g = 7; + + if (quick_drop > 0) { + quick_drop = 0; + capdiv2g -= quick_drop_offset; + if (capdiv2g < 0) + capdiv2g = 0; + } + } else { + return false; + } + } else if (AR_SREV_9330(ah)) { + if (pa_in[23] < 1000) { + capdiv_offset = (1000 - pa_in[23]) / 100; + capdiv2g += capdiv_offset; + if (capdiv_offset > 3) { + capdiv_offset = 1; + quick_drop--; + } + + capdiv2g += capdiv_offset; + if (capdiv2g > 6) + capdiv2g = 6; + if (quick_drop < -4) + quick_drop = -4; + } else if (pa_in[23] == 1400) { + if (count > 3) { + quick_drop++; + capdiv2g -= count / 4; + if (quick_drop > -2) + quick_drop = -2; + } else { + capdiv2g--; + } + + if (capdiv2g < 0) + capdiv2g = 0; + } else { + return false; + } + } + + REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_TXRF3, + AR_PHY_65NM_CH0_TXRF3_CAPDIV2G, capdiv2g); + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, + quick_drop); + + return true; +} + int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_hw_cal_data *caldata, int chain) { @@ -817,6 +917,9 @@ int ar9003_paprd_create_curve(struct ath_hw *ah, if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) status = -2; + if (ar9003_paprd_retrain_pa_in(ah, caldata, chain)) + status = -EINPROGRESS; + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index e476f9f92ce..759f5f5a715 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -88,7 +88,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) channelSel = (freq * 4) / div; chan_frac = (((freq * 4) % div) * 0x20000) / div; channelSel = (channelSel << 17) | chan_frac; - } else if (AR_SREV_9485(ah)) { + } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { u32 chan_frac; /* @@ -206,6 +206,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, for (i = 0; i < max_spur_cnts; i++) { if (AR_SREV_9462(ah) && (i == 0 || i == 3)) continue; + negative = 0; if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) || AR_SREV_9550(ah)) @@ -301,7 +302,9 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah, int freq_offset, int spur_freq_sd, int spur_delta_phase, - int spur_subchannel_sd) + int spur_subchannel_sd, + int range, + int synth_freq) { int mask_index = 0; @@ -316,8 +319,11 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd); REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1); - REG_RMW_FIELD(ah, AR_PHY_TIMING11, - AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1); + + if (!(AR_SREV_9565(ah) && range == 10 && synth_freq == 2437)) + REG_RMW_FIELD(ah, AR_PHY_TIMING11, + AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1); + REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1); REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, @@ -358,9 +364,44 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff); } +static void ar9003_hw_spur_ofdm_9565(struct ath_hw *ah, + int freq_offset) +{ + int mask_index = 0; + + mask_index = (freq_offset << 4) / 5; + if (mask_index < 0) + mask_index = mask_index - 1; + + mask_index = mask_index & 0x7f; + + REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, + AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B, + mask_index); + + /* A == B */ + REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_B, + AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, + mask_index); + + REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, + AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B, + mask_index); + REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, + AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_B, 0xe); + REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, + AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_B, 0xe); + + /* A == B */ + REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_B, + AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0); +} + static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, struct ath9k_channel *chan, - int freq_offset) + int freq_offset, + int range, + int synth_freq) { int spur_freq_sd = 0; int spur_subchannel_sd = 0; @@ -402,7 +443,8 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, freq_offset, spur_freq_sd, spur_delta_phase, - spur_subchannel_sd); + spur_subchannel_sd, + range, synth_freq); } /* Spur mitigation for OFDM */ @@ -447,7 +489,17 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i], mode); freq_offset -= synth_freq; if (abs(freq_offset) < range) { - ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); + ar9003_hw_spur_ofdm_work(ah, chan, freq_offset, + range, synth_freq); + + if (AR_SREV_9565(ah) && (i < 4)) { + freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i + 1], + mode); + freq_offset -= synth_freq; + if (abs(freq_offset) < range) + ar9003_hw_spur_ofdm_9565(ah, freq_offset); + } + break; } } @@ -456,7 +508,8 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, static void ar9003_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) { - ar9003_hw_spur_mitigate_mrc_cck(ah, chan); + if (!AR_SREV_9565(ah)) + ar9003_hw_spur_mitigate_mrc_cck(ah, chan); ar9003_hw_spur_mitigate_ofdm(ah, chan); } @@ -552,9 +605,6 @@ static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); - else if (AR_SREV_9462(ah)) - /* xxx only when MCI support is enabled */ - REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); else REG_WRITE(ah, AR_SELFGEN_MASK, tx); @@ -736,7 +786,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, if (chan->channel == 2484) ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); - if (AR_SREV_9462(ah)) + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, AR_GLB_SWREG_DISCONT_EN_BT_WLAN); @@ -746,9 +796,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ath9k_hw_apply_txpower(ah, chan, false); - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, - AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) + AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) ah->enabled_cals |= TX_IQ_CAL; else ah->enabled_cals &= ~TX_IQ_CAL; @@ -1111,7 +1161,7 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah) if (AR_SREV_9330(ah)) ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ; - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ; ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9462_2GHZ; ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ; @@ -1223,17 +1273,17 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah) } static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, - struct ath_hw_antcomb_conf *antconf) + struct ath_hw_antcomb_conf *antconf) { u32 regval; regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); - antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >> - AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S; - antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >> - AR_PHY_9485_ANT_DIV_ALT_LNACONF_S; - antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >> - AR_PHY_9485_ANT_FAST_DIV_BIAS_S; + antconf->main_lna_conf = (regval & AR_PHY_ANT_DIV_MAIN_LNACONF) >> + AR_PHY_ANT_DIV_MAIN_LNACONF_S; + antconf->alt_lna_conf = (regval & AR_PHY_ANT_DIV_ALT_LNACONF) >> + AR_PHY_ANT_DIV_ALT_LNACONF_S; + antconf->fast_div_bias = (regval & AR_PHY_ANT_FAST_DIV_BIAS) >> + AR_PHY_ANT_FAST_DIV_BIAS_S; if (AR_SREV_9330_11(ah)) { antconf->lna1_lna2_delta = -9; @@ -1241,6 +1291,9 @@ static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, } else if (AR_SREV_9485(ah)) { antconf->lna1_lna2_delta = -9; antconf->div_group = 2; + } else if (AR_SREV_9565(ah)) { + antconf->lna1_lna2_delta = -3; + antconf->div_group = 3; } else { antconf->lna1_lna2_delta = -3; antconf->div_group = 0; @@ -1253,26 +1306,84 @@ static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah, u32 regval; regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); - regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF | - AR_PHY_9485_ANT_DIV_ALT_LNACONF | - AR_PHY_9485_ANT_FAST_DIV_BIAS | - AR_PHY_9485_ANT_DIV_MAIN_GAINTB | - AR_PHY_9485_ANT_DIV_ALT_GAINTB); - regval |= ((antconf->main_lna_conf << - AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S) - & AR_PHY_9485_ANT_DIV_MAIN_LNACONF); - regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S) - & AR_PHY_9485_ANT_DIV_ALT_LNACONF); - regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S) - & AR_PHY_9485_ANT_FAST_DIV_BIAS); - regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S) - & AR_PHY_9485_ANT_DIV_MAIN_GAINTB); - regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S) - & AR_PHY_9485_ANT_DIV_ALT_GAINTB); + regval &= ~(AR_PHY_ANT_DIV_MAIN_LNACONF | + AR_PHY_ANT_DIV_ALT_LNACONF | + AR_PHY_ANT_FAST_DIV_BIAS | + AR_PHY_ANT_DIV_MAIN_GAINTB | + AR_PHY_ANT_DIV_ALT_GAINTB); + regval |= ((antconf->main_lna_conf << AR_PHY_ANT_DIV_MAIN_LNACONF_S) + & AR_PHY_ANT_DIV_MAIN_LNACONF); + regval |= ((antconf->alt_lna_conf << AR_PHY_ANT_DIV_ALT_LNACONF_S) + & AR_PHY_ANT_DIV_ALT_LNACONF); + regval |= ((antconf->fast_div_bias << AR_PHY_ANT_FAST_DIV_BIAS_S) + & AR_PHY_ANT_FAST_DIV_BIAS); + regval |= ((antconf->main_gaintb << AR_PHY_ANT_DIV_MAIN_GAINTB_S) + & AR_PHY_ANT_DIV_MAIN_GAINTB); + regval |= ((antconf->alt_gaintb << AR_PHY_ANT_DIV_ALT_GAINTB_S) + & AR_PHY_ANT_DIV_ALT_GAINTB); REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); } +static void ar9003_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah, + bool enable) +{ + u8 ant_div_ctl1; + u32 regval; + + if (!AR_SREV_9565(ah)) + return; + + ah->shared_chain_lnadiv = enable; + ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); + + regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); + regval &= (~AR_ANT_DIV_CTRL_ALL); + regval |= (ant_div_ctl1 & 0x3f) << AR_ANT_DIV_CTRL_ALL_S; + regval &= ~AR_PHY_ANT_DIV_LNADIV; + regval |= ((ant_div_ctl1 >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S; + + if (enable) + regval |= AR_ANT_DIV_ENABLE; + + REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); + + regval = REG_READ(ah, AR_PHY_CCK_DETECT); + regval &= ~AR_FAST_DIV_ENABLE; + regval |= ((ant_div_ctl1 >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S; + + if (enable) + regval |= AR_FAST_DIV_ENABLE; + + REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); + + if (enable) { + REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, + (1 << AR_PHY_ANT_SW_RX_PROT_S)); + if (ah->curchan && IS_CHAN_2GHZ(ah->curchan)) + REG_SET_BIT(ah, AR_PHY_RESTART, + AR_PHY_RESTART_ENABLE_DIV_M2FLAG); + REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, + AR_BTCOEX_WL_LNADIV_FORCE_ON); + } else { + REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE); + REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, + (1 << AR_PHY_ANT_SW_RX_PROT_S)); + REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE); + REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, + AR_BTCOEX_WL_LNADIV_FORCE_ON); + + regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); + regval &= ~(AR_PHY_ANT_DIV_MAIN_LNACONF | + AR_PHY_ANT_DIV_ALT_LNACONF | + AR_PHY_ANT_DIV_MAIN_GAINTB | + AR_PHY_ANT_DIV_ALT_GAINTB); + regval |= (AR_PHY_ANT_DIV_LNA1 << AR_PHY_ANT_DIV_MAIN_LNACONF_S); + regval |= (AR_PHY_ANT_DIV_LNA2 << AR_PHY_ANT_DIV_ALT_LNACONF_S); + REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); + } +} + static int ar9003_hw_fast_chan_change(struct ath_hw *ah, struct ath9k_channel *chan, u8 *ini_reloaded) @@ -1312,10 +1423,10 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, ar9003_hw_prog_ini(ah, &ah->iniMac[ATH_INI_POST], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex); + if (AR_SREV_9462_20(ah)) - ar9003_hw_prog_ini(ah, - &ah->ini_radio_post_sys2ant, - modesIndex); + ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant, + modesIndex); REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); @@ -1326,6 +1437,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, if (IS_CHAN_A_FAST_CLOCK(ah, chan)) REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); + if (AR_SREV_9565(ah)) + REG_WRITE_ARRAY(&ah->iniModesFastClock, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); ah->modes_index = modesIndex; @@ -1368,6 +1482,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; + ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv; ar9003_hw_set_nf_limits(ah); ar9003_hw_set_radar_conf(ah); diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h index 7bfbaf065a4..9a48e3d2f23 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h @@ -223,15 +223,24 @@ #define AR_PHY_ML_CNTL_2 (AR_MRC_BASE + 0x1c) #define AR_PHY_TST_ADC (AR_MRC_BASE + 0x20) -#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0 +#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A 0x00000FE0 #define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_A_S 5 -#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F -#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0 +#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A 0x1F +#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_A_S 0 +#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B 0x00FE0000 +#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B_S 17 +#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_B 0x0001F000 +#define AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_B_S 12 #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A 0x00000FE0 #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_A_S 5 #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A 0x1F #define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_A_S 0 +#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B 0x00FE0000 +#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B_S 17 +#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_B 0x0001F000 +#define AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_B_S 12 + /* * MRC Feild Definitions @@ -271,23 +280,25 @@ #define AR_ANT_DIV_ENABLE_S 24 -#define AR_PHY_9485_ANT_FAST_DIV_BIAS 0x00007e00 -#define AR_PHY_9485_ANT_FAST_DIV_BIAS_S 9 -#define AR_PHY_9485_ANT_DIV_LNADIV 0x01000000 -#define AR_PHY_9485_ANT_DIV_LNADIV_S 24 -#define AR_PHY_9485_ANT_DIV_ALT_LNACONF 0x06000000 -#define AR_PHY_9485_ANT_DIV_ALT_LNACONF_S 25 -#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF 0x18000000 -#define AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S 27 -#define AR_PHY_9485_ANT_DIV_ALT_GAINTB 0x20000000 -#define AR_PHY_9485_ANT_DIV_ALT_GAINTB_S 29 -#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB 0x40000000 -#define AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S 30 - -#define AR_PHY_9485_ANT_DIV_LNA1_MINUS_LNA2 0x0 -#define AR_PHY_9485_ANT_DIV_LNA2 0x1 -#define AR_PHY_9485_ANT_DIV_LNA1 0x2 -#define AR_PHY_9485_ANT_DIV_LNA1_PLUS_LNA2 0x3 +#define AR_PHY_ANT_FAST_DIV_BIAS 0x00007e00 +#define AR_PHY_ANT_FAST_DIV_BIAS_S 9 +#define AR_PHY_ANT_SW_RX_PROT 0x00800000 +#define AR_PHY_ANT_SW_RX_PROT_S 23 +#define AR_PHY_ANT_DIV_LNADIV 0x01000000 +#define AR_PHY_ANT_DIV_LNADIV_S 24 +#define AR_PHY_ANT_DIV_ALT_LNACONF 0x06000000 +#define AR_PHY_ANT_DIV_ALT_LNACONF_S 25 +#define AR_PHY_ANT_DIV_MAIN_LNACONF 0x18000000 +#define AR_PHY_ANT_DIV_MAIN_LNACONF_S 27 +#define AR_PHY_ANT_DIV_ALT_GAINTB 0x20000000 +#define AR_PHY_ANT_DIV_ALT_GAINTB_S 29 +#define AR_PHY_ANT_DIV_MAIN_GAINTB 0x40000000 +#define AR_PHY_ANT_DIV_MAIN_GAINTB_S 30 + +#define AR_PHY_ANT_DIV_LNA1_MINUS_LNA2 0x0 +#define AR_PHY_ANT_DIV_LNA2 0x1 +#define AR_PHY_ANT_DIV_LNA1 0x2 +#define AR_PHY_ANT_DIV_LNA1_PLUS_LNA2 0x3 #define AR_PHY_EXTCHN_PWRTHR1 (AR_AGC_BASE + 0x2c) #define AR_PHY_EXT_CHN_WIN (AR_AGC_BASE + 0x30) @@ -413,6 +424,8 @@ #define AR_PHY_FIND_SIG_RELSTEP 0x1f #define AR_PHY_FIND_SIG_RELSTEP_S 0 #define AR_PHY_FIND_SIG_RELSTEP_SIGN_BIT 5 +#define AR_PHY_RESTART_ENABLE_DIV_M2FLAG 0x00200000 +#define AR_PHY_RESTART_ENABLE_DIV_M2FLAG_S 21 #define AR_PHY_RESTART_DIV_GC 0x001C0000 #define AR_PHY_RESTART_DIV_GC_S 18 #define AR_PHY_RESTART_ENA 0x01 @@ -609,6 +622,12 @@ #define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff #define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0 +#define AR_PHY_BB_THERM_ADC_3 (AR_SM_BASE + 0x250) +#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN 0x0001ff00 +#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_SCALE_GAIN_S 8 +#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET 0x000000ff +#define AR_PHY_BB_THERM_ADC_3_THERM_ADC_OFFSET_S 0 + #define AR_PHY_BB_THERM_ADC_4 (AR_SM_BASE + 0x254) #define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE 0x000000ff #define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_S 0 @@ -625,9 +644,13 @@ #define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0) #define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc) +#define AR_PHY_65NM_CH0_TXRF3 0x16048 +#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e +#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1 + #define AR_PHY_65NM_CH0_SYNTH4 0x1608c -#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT (AR_SREV_9462(ah) ? 0x00000001 : 0x00000002) -#define AR_PHY_SYNTH4_LONG_SHIFT_SELECT_S (AR_SREV_9462(ah) ? 0 : 1) +#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_BIAS1 0x160c0 #define AR_PHY_65NM_CH0_BIAS2 0x160c4 @@ -637,7 +660,7 @@ #define AR_PHY_65NM_CH2_RXTX4 0x1690c #define AR_CH0_TOP (AR_SREV_9300(ah) ? 0x16288 : \ - ((AR_SREV_9462(ah) ? 0x1628c : 0x16280))) + (((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x1628c : 0x16280))) #define AR_CH0_TOP_XPABIASLVL (AR_SREV_9550(ah) ? 0x3c0 : 0x300) #define AR_CH0_TOP_XPABIASLVL_S (AR_SREV_9550(ah) ? 6 : 8) @@ -665,7 +688,7 @@ #define AR_SWITCH_TABLE_ALL_S (0) #define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\ - (AR_SREV_9462(ah) ? 0x16294 : 0x1628c)) + ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16294 : 0x1628c)) #define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31 @@ -687,17 +710,17 @@ #define AR_CH0_TOP2_XPABIASLVL_S 12 #define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \ - (AR_SREV_9462(ah) ? 0x16298 : 0x16290)) + ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16298 : 0x16290)) #define AR_CH0_XTAL_CAPINDAC 0x7f000000 #define AR_CH0_XTAL_CAPINDAC_S 24 #define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000 #define AR_CH0_XTAL_CAPOUTDAC_S 17 -#define AR_PHY_PMU1 (AR_SREV_9462(ah) ? 0x16340 : 0x16c40) +#define AR_PHY_PMU1 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16340 : 0x16c40) #define AR_PHY_PMU1_PWD 0x1 #define AR_PHY_PMU1_PWD_S 0 -#define AR_PHY_PMU2 (AR_SREV_9462(ah) ? 0x16344 : 0x16c44) +#define AR_PHY_PMU2 ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x16344 : 0x16c44) #define AR_PHY_PMU2_PGM 0x00200000 #define AR_PHY_PMU2_PGM_S 21 @@ -877,6 +900,8 @@ #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 +#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR 0x20000000 +#define AR_PHY_65NM_CH0_RXTX4_THERM_ON_OVR_S 29 #define AR_PHY_65NM_RXTX4_XLNA_BIAS 0xC0000000 #define AR_PHY_65NM_RXTX4_XLNA_BIAS_S 30 @@ -1240,4 +1265,24 @@ #define AR_PHY_CL_TAB_CL_GAIN_MOD 0x1f #define AR_PHY_CL_TAB_CL_GAIN_MOD_S 0 +#define AR_BTCOEX_WL_LNADIV 0x1a64 +#define AR_BTCOEX_WL_LNADIV_PREDICTED_PERIOD 0x00003FFF +#define AR_BTCOEX_WL_LNADIV_PREDICTED_PERIOD_S 0 +#define AR_BTCOEX_WL_LNADIV_DPDT_IGNORE_PRIORITY 0x00004000 +#define AR_BTCOEX_WL_LNADIV_DPDT_IGNORE_PRIORITY_S 14 +#define AR_BTCOEX_WL_LNADIV_FORCE_ON 0x00008000 +#define AR_BTCOEX_WL_LNADIV_FORCE_ON_S 15 +#define AR_BTCOEX_WL_LNADIV_MODE_OPTION 0x00030000 +#define AR_BTCOEX_WL_LNADIV_MODE_OPTION_S 16 +#define AR_BTCOEX_WL_LNADIV_MODE 0x007c0000 +#define AR_BTCOEX_WL_LNADIV_MODE_S 18 +#define AR_BTCOEX_WL_LNADIV_ALLOWED_TX_ANTDIV_WL_TX_REQ 0x00800000 +#define AR_BTCOEX_WL_LNADIV_ALLOWED_TX_ANTDIV_WL_TX_REQ_S 23 +#define AR_BTCOEX_WL_LNADIV_DISABLE_TX_ANTDIV_ENABLE 0x01000000 +#define AR_BTCOEX_WL_LNADIV_DISABLE_TX_ANTDIV_ENABLE_S 24 +#define AR_BTCOEX_WL_LNADIV_CONTINUOUS_BT_ACTIVE_PROTECT 0x02000000 +#define AR_BTCOEX_WL_LNADIV_CONTINUOUS_BT_ACTIVE_PROTECT_S 25 +#define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD 0xFC000000 +#define AR_BTCOEX_WL_LNADIV_BT_INACTIVE_THRESHOLD_S 26 + #endif /* AR9003_PHY_H */ diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h index 4ef7dcccaa2..58f30f65c6b 100644 --- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h +++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h @@ -58,7 +58,7 @@ static const u32 ar9462_2p0_baseband_postamble[][5] = { {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, - {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282}, + {0x00009e3c, 0xcf946222, 0xcf946222, 0xcfd5c782, 0xcfd5c282}, {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27}, {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, diff --git a/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h new file mode 100644 index 00000000000..843e79f67ff --- /dev/null +++ b/drivers/net/wireless/ath/ath9k/ar9565_1p0_initvals.h @@ -0,0 +1,1231 @@ +/* + * 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_1P0_H +#define INITVALS_9565_1P0_H + +/* AR9565 1.0 */ + +static const u32 ar9565_1p0_mac_core[][2] = { + /* Addr allmodes */ + {0x00000008, 0x00000000}, + {0x00000030, 0x000a0085}, + {0x00000034, 0x00000005}, + {0x00000040, 0x00000000}, + {0x00000044, 0x00000000}, + {0x00000048, 0x00000008}, + {0x0000004c, 0x00000010}, + {0x00000050, 0x00000000}, + {0x00001040, 0x002ffc0f}, + {0x00001044, 0x002ffc0f}, + {0x00001048, 0x002ffc0f}, + {0x0000104c, 0x002ffc0f}, + {0x00001050, 0x002ffc0f}, + {0x00001054, 0x002ffc0f}, + {0x00001058, 0x002ffc0f}, + {0x0000105c, 0x002ffc0f}, + {0x00001060, 0x002ffc0f}, + {0x00001064, 0x002ffc0f}, + {0x000010f0, 0x00000100}, + {0x00001270, 0x00000000}, + {0x000012b0, 0x00000000}, + {0x000012f0, 0x00000000}, + {0x0000143c, 0x00000000}, + {0x0000147c, 0x00000000}, + {0x00001810, 0x0f000003}, + {0x00008000, 0x00000000}, + {0x00008004, 0x00000000}, + {0x00008008, 0x00000000}, + {0x0000800c, 0x00000000}, + {0x00008018, 0x00000000}, + {0x00008020, 0x00000000}, + {0x00008038, 0x00000000}, + {0x0000803c, 0x00000000}, + {0x00008040, 0x00000000}, + {0x00008044, 0x00000000}, + {0x00008048, 0x00000000}, + {0x00008054, 0x00000000}, + {0x00008058, 0x00000000}, + {0x0000805c, 0x000fc78f}, + {0x00008060, 0x0000000f}, + {0x00008064, 0x00000000}, + {0x00008070, 0x00000310}, + {0x00008074, 0x00000020}, + {0x00008078, 0x00000000}, + {0x0000809c, 0x0000000f}, + {0x000080a0, 0x00000000}, + {0x000080a4, 0x02ff0000}, + {0x000080a8, 0x0e070605}, + {0x000080ac, 0x0000000d}, + {0x000080b0, 0x00000000}, + {0x000080b4, 0x00000000}, + {0x000080b8, 0x00000000}, + {0x000080bc, 0x00000000}, + {0x000080c0, 0x2a800000}, + {0x000080c4, 0x06900168}, + {0x000080c8, 0x13881c20}, + {0x000080cc, 0x01f40000}, + {0x000080d0, 0x00252500}, + {0x000080d4, 0x00b00005}, + {0x000080d8, 0x00400002}, + {0x000080dc, 0x00000000}, + {0x000080e0, 0xffffffff}, + {0x000080e4, 0x0000ffff}, + {0x000080e8, 0x3f3f3f3f}, + {0x000080ec, 0x00000000}, + {0x000080f0, 0x00000000}, + {0x000080f4, 0x00000000}, + {0x000080fc, 0x00020000}, + {0x00008100, 0x00000000}, + {0x00008108, 0x00000052}, + {0x0000810c, 0x00000000}, + {0x00008110, 0x00000000}, + {0x00008114, 0x000007ff}, + {0x00008118, 0x000000aa}, + {0x0000811c, 0x00003210}, + {0x00008124, 0x00000000}, + {0x00008128, 0x00000000}, + {0x0000812c, 0x00000000}, + {0x00008130, 0x00000000}, + {0x00008134, 0x00000000}, + {0x00008138, 0x00000000}, + {0x0000813c, 0x0000ffff}, + {0x00008144, 0xffffffff}, + {0x00008168, 0x00000000}, + {0x0000816c, 0x00000000}, + {0x00008170, 0x18486200}, + {0x00008174, 0x33332210}, + {0x00008178, 0x00000000}, + {0x0000817c, 0x00020000}, + {0x000081c4, 0x33332210}, + {0x000081c8, 0x00000000}, + {0x000081cc, 0x00000000}, + {0x000081d4, 0x00000000}, + {0x000081ec, 0x00000000}, + {0x000081f0, 0x00000000}, + {0x000081f4, 0x00000000}, + {0x000081f8, 0x00000000}, + {0x000081fc, 0x00000000}, + {0x00008240, 0x00100000}, + {0x00008244, 0x0010f424}, + {0x00008248, 0x00000800}, + {0x0000824c, 0x0001e848}, + {0x00008250, 0x00000000}, + {0x00008254, 0x00000000}, + {0x00008258, 0x00000000}, + {0x0000825c, 0x40000000}, + {0x00008260, 0x00080922}, + {0x00008264, 0x9d400010}, + {0x00008268, 0xffffffff}, + {0x0000826c, 0x0000ffff}, + {0x00008270, 0x00000000}, + {0x00008274, 0x40000000}, + {0x00008278, 0x003e4180}, + {0x0000827c, 0x00000004}, + {0x00008284, 0x0000002c}, + {0x00008288, 0x0000002c}, + {0x0000828c, 0x000000ff}, + {0x00008294, 0x00000000}, + {0x00008298, 0x00000000}, + {0x0000829c, 0x00000000}, + {0x00008300, 0x00000140}, + {0x00008314, 0x00000000}, + {0x0000831c, 0x0000010d}, + {0x00008328, 0x00000000}, + {0x0000832c, 0x0000001f}, + {0x00008330, 0x00000302}, + {0x00008334, 0x00000700}, + {0x00008338, 0xffff0000}, + {0x0000833c, 0x02400000}, + {0x00008340, 0x000107ff}, + {0x00008344, 0xaa48105b}, + {0x00008348, 0x008f0000}, + {0x0000835c, 0x00000000}, + {0x00008360, 0xffffffff}, + {0x00008364, 0xffffffff}, + {0x00008368, 0x00000000}, + {0x00008370, 0x00000000}, + {0x00008374, 0x000000ff}, + {0x00008378, 0x00000000}, + {0x0000837c, 0x00000000}, + {0x00008380, 0xffffffff}, + {0x00008384, 0xffffffff}, + {0x00008390, 0xffffffff}, + {0x00008394, 0xffffffff}, + {0x00008398, 0x00000000}, + {0x0000839c, 0x00000000}, + {0x000083a4, 0x0000fa14}, + {0x000083a8, 0x000f0c00}, + {0x000083ac, 0x33332210}, + {0x000083b0, 0x33332210}, + {0x000083b4, 0x33332210}, + {0x000083b8, 0x33332210}, + {0x000083bc, 0x00000000}, + {0x000083c0, 0x00000000}, + {0x000083c4, 0x00000000}, + {0x000083c8, 0x00000000}, + {0x000083cc, 0x00000200}, + {0x000083d0, 0x800301ff}, +}; + +static const u32 ar9565_1p0_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 ar9565_1p0_baseband_core[][2] = { + /* Addr allmodes */ + {0x00009800, 0xafe68e30}, + {0x00009804, 0xfd14e000}, + {0x00009808, 0x9c0a8f6b}, + {0x0000980c, 0x04800000}, + {0x00009814, 0x9280c00a}, + {0x00009818, 0x00000000}, + {0x0000981c, 0x00020028}, + {0x00009834, 0x6400a290}, + {0x00009838, 0x0108ecff}, + {0x0000983c, 0x0d000600}, + {0x00009880, 0x201fff00}, + {0x00009884, 0x00001042}, + {0x000098a4, 0x00200400}, + {0x000098b0, 0x32840bbe}, + {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, 0x1883800a}, + {0x00009d10, 0x01834061}, + {0x00009d14, 0x00c00400}, + {0x00009d18, 0x00000000}, + {0x00009e08, 0x0078230c}, + {0x00009e24, 0x990bb515}, + {0x00009e28, 0x126f0000}, + {0x00009e30, 0x06336f77}, + {0x00009e34, 0x6af6532f}, + {0x00009e38, 0x0cc80c00}, + {0x00009e40, 0x0d261820}, + {0x00009e4c, 0x00001004}, + {0x00009e50, 0x00ff03f1}, + {0x00009e54, 0xe4c355c7}, + {0x00009e5c, 0xe9198724}, + {0x00009fc0, 0x823e4fc8}, + {0x00009fc4, 0x0001efb5}, + {0x00009fcc, 0x40000014}, + {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}, + {0x0000a3a4, 0x00000000}, + {0x0000a3a8, 0xaaaaaaaa}, + {0x0000a3ac, 0x3c466478}, + {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}, + {0x0000a41c, 0x1ce739ce}, + {0x0000a420, 0x000001ce}, + {0x0000a424, 0x1ce739ce}, + {0x0000a428, 0x000001ce}, + {0x0000a42c, 0x1ce739ce}, + {0x0000a430, 0x1ce739ce}, + {0x0000a434, 0x00000000}, + {0x0000a438, 0x00001801}, + {0x0000a43c, 0x00000000}, + {0x0000a440, 0x00000000}, + {0x0000a444, 0x00000000}, + {0x0000a448, 0x05000096}, + {0x0000a44c, 0x00000001}, + {0x0000a450, 0x00010000}, + {0x0000a454, 0x03000000}, + {0x0000a458, 0x00000000}, + {0x0000a644, 0xbfad9d74}, + {0x0000a648, 0x0048060a}, + {0x0000a64c, 0x00003c37}, + {0x0000a670, 0x03020100}, + {0x0000a674, 0x09080504}, + {0x0000a678, 0x0d0c0b0a}, + {0x0000a67c, 0x13121110}, + {0x0000a680, 0x31301514}, + {0x0000a684, 0x35343332}, + {0x0000a688, 0x00000036}, + {0x0000a690, 0x00000838}, + {0x0000a6b4, 0x00512c01}, + {0x0000a7c0, 0x00000000}, + {0x0000a7c4, 0xfffffffc}, + {0x0000a7c8, 0x00000000}, + {0x0000a7cc, 0x00000000}, + {0x0000a7d0, 0x00000000}, + {0x0000a7d4, 0x00000004}, + {0x0000a7dc, 0x00000001}, + {0x0000a7f0, 0x80000000}, +}; + +static const u32 ar9565_1p0_baseband_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8005, 0xd00a800d}, + {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae}, + {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x63c640da}, + {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x09143c81}, + {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4}, + {0x00009830, 0x0000059c, 0x0000059c, 0x0000059c, 0x0000059c}, + {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4}, + {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a0}, + {0x00009e04, 0x00802020, 0x00802020, 0x00802020, 0x00802020}, + {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8}, + {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e}, + {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3379605e, 0x33795d5e}, + {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c}, + {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce}, + {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021}, + {0x00009e3c, 0xcf946222, 0xcf946222, 0xcf946222, 0xcf946222}, + {0x00009e44, 0xfe321e27, 0xfe321e27, 0xfe291e27, 0xfe291e27}, + {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012}, + {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000}, + {0x0000a204, 0x07318fc0, 0x07318fc4, 0x07318fc4, 0x07318fc0}, + {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004}, + {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f}, + {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b}, + {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff}, + {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018}, + {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108}, + {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898}, + {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002}, + {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e}, + {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501}, + {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e}, + {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b}, + {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150}, + {0x0000a288, 0x00100510, 0x00100510, 0x00100510, 0x00100510}, + {0x0000a28c, 0x00021551, 0x00021551, 0x00021551, 0x00021551}, + {0x0000a2c4, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18}, + {0x0000a2d0, 0x00071982, 0x00071982, 0x00071982, 0x00071982}, + {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b}, + {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000ae04, 0x00800000, 0x00800000, 0x00800000, 0x00800000}, + {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9565_1p0_radio_core[][2] = { + /* Addr allmodes */ + {0x00016000, 0x36db6db6}, + {0x00016004, 0x6db6db40}, + {0x00016008, 0x73f00000}, + {0x0001600c, 0x00000000}, + {0x00016010, 0x6d823601}, + {0x00016040, 0x7f80fff8}, + {0x0001604c, 0x1c99e04f}, + {0x00016050, 0x6db6db6c}, + {0x00016058, 0x6c200000}, + {0x00016080, 0x000c0000}, + {0x00016084, 0x9a68048c}, + {0x00016088, 0x54214514}, + {0x0001608c, 0x1203040b}, + {0x00016090, 0x24926490}, + {0x00016098, 0xd28b3330}, + {0x000160a0, 0x0a108ffe}, + {0x000160a4, 0x812fc491}, + {0x000160a8, 0x423c8000}, + {0x000160b4, 0x92000000}, + {0x000160b8, 0x0285dddc}, + {0x000160bc, 0x02908888}, + {0x000160c0, 0x006db6d0}, + {0x000160c4, 0x6dd6db60}, + {0x000160c8, 0x6db6db6c}, + {0x000160cc, 0x6de6c1b0}, + {0x00016100, 0x3fffbe04}, + {0x00016104, 0xfff80000}, + {0x00016108, 0x00200400}, + {0x00016110, 0x00000000}, + {0x00016144, 0x02084080}, + {0x00016148, 0x000080c0}, + {0x00016280, 0x050a0001}, + {0x00016284, 0x3d841440}, + {0x00016288, 0x00000000}, + {0x0001628c, 0xe3000000}, + {0x00016290, 0xa1004080}, + {0x00016294, 0x40000028}, + {0x00016298, 0x55aa2900}, + {0x00016340, 0x131c827a}, + {0x00016344, 0x00300000}, +}; + +static const u32 ar9565_1p0_radio_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524}, + {0x000160ac, 0xa4646c08, 0xa4646c08, 0xa4646c08, 0xa4646c08}, + {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70}, + {0x0001610c, 0x40000000, 0x40000000, 0x40000000, 0x40000000}, + {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008}, +}; + +static const u32 ar9565_1p0_soc_preamble[][2] = { + /* Addr allmodes */ + {0x00004078, 0x00000002}, + {0x000040a4, 0x00a0c9c9}, + {0x00007020, 0x00000000}, + {0x00007034, 0x00000002}, + {0x00007038, 0x000004c2}, +}; + +static const u32 ar9565_1p0_soc_postamble[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x00007010, 0x00002233, 0x00002233, 0x00002233, 0x00002233}, +}; + +static const u32 ar9565_1p0_Common_rx_gain_table[][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, 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 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0xfc0a9380, 0xfc0a9380, 0xfdab5b52, 0xfdab5b52}, + {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, + {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, + {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, + {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, 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, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a618, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a61c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a620, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a624, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a628, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a62c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a630, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a634, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a638, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a63c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, + {0x00016048, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9565_1p0_pciephy_pll_on_clkreq_disable_L1[][2] = { + /* Addr allmodes */ + {0x00018c00, 0x18212ede}, + {0x00018c04, 0x000801d8}, + {0x00018c08, 0x0003780c}, +}; + +static const u32 ar9565_1p0_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, 0x03721821, 0x03721821}, + {0x0000a230, 0x0000400b, 0x00004016}, + {0x0000a254, 0x00000898, 0x00001130}, +}; + +static const u32 ar9565_1p0_common_wo_xlna_rx_gain_table[][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, 0x00bf00a0}, + {0x0000a0c4, 0x11a011a1}, + {0x0000a0c8, 0x11be11bf}, + {0x0000a0cc, 0x11bc11bd}, + {0x0000a0d0, 0x22632264}, + {0x0000a0d4, 0x22612262}, + {0x0000a0d8, 0x227f2260}, + {0x0000a0dc, 0x4322227e}, + {0x0000a0e0, 0x43204321}, + {0x0000a0e4, 0x433e433f}, + {0x0000a0e8, 0x4462433d}, + {0x0000a0ec, 0x44604461}, + {0x0000a0f0, 0x447e447f}, + {0x0000a0f4, 0x5582447d}, + {0x0000a0f8, 0x55805581}, + {0x0000a0fc, 0x559e559f}, + {0x0000a100, 0x66816682}, + {0x0000a104, 0x669f6680}, + {0x0000a108, 0x669d669e}, + {0x0000a10c, 0x77627763}, + {0x0000a110, 0x77607761}, + {0x0000a114, 0x00000000}, + {0x0000a118, 0x00000000}, + {0x0000a11c, 0x00000000}, + {0x0000a120, 0x00000000}, + {0x0000a124, 0x00000000}, + {0x0000a128, 0x00000000}, + {0x0000a12c, 0x00000000}, + {0x0000a130, 0x00000000}, + {0x0000a134, 0x00000000}, + {0x0000a138, 0x00000000}, + {0x0000a13c, 0x00000000}, + {0x0000a140, 0x00bf00a0}, + {0x0000a144, 0x11a011a1}, + {0x0000a148, 0x11be11bf}, + {0x0000a14c, 0x11bc11bd}, + {0x0000a150, 0x22632264}, + {0x0000a154, 0x22612262}, + {0x0000a158, 0x227f2260}, + {0x0000a15c, 0x4322227e}, + {0x0000a160, 0x43204321}, + {0x0000a164, 0x433e433f}, + {0x0000a168, 0x4462433d}, + {0x0000a16c, 0x44604461}, + {0x0000a170, 0x447e447f}, + {0x0000a174, 0x5582447d}, + {0x0000a178, 0x55805581}, + {0x0000a17c, 0x559e559f}, + {0x0000a180, 0x66816682}, + {0x0000a184, 0x669f6680}, + {0x0000a188, 0x669d669e}, + {0x0000a18c, 0x77627763}, + {0x0000a190, 0x77607761}, + {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 ar9565_1p0_modes_low_ob_db_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0xfc0a9380, 0xfc0a9380, 0xfdab5b52, 0xfdab5b52}, + {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, + {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, + {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, + {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, 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, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a618, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a61c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a620, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a624, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a628, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a62c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a630, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a634, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a638, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a63c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4}, + {0x00016048, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +static const u32 ar9565_1p0_modes_high_ob_db_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0xfc0a9380, 0xfc0a9380, 0xfdab5b52, 0xfdab5b52}, + {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, + {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, + {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000}, + {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002}, + {0x0000a508, 0x0b022220, 0x0b022220, 0x08000004, 0x08000004}, + {0x0000a50c, 0x10022223, 0x10022223, 0x0c000200, 0x0c000200}, + {0x0000a510, 0x15022620, 0x15022620, 0x10000202, 0x10000202}, + {0x0000a514, 0x19022622, 0x19022622, 0x13000400, 0x13000400}, + {0x0000a518, 0x1c022822, 0x1c022822, 0x17000402, 0x17000402}, + {0x0000a51c, 0x21022842, 0x21022842, 0x1b000404, 0x1b000404}, + {0x0000a520, 0x24022c41, 0x24022c41, 0x1e000603, 0x1e000603}, + {0x0000a524, 0x29023042, 0x29023042, 0x23000a02, 0x23000a02}, + {0x0000a528, 0x2d023044, 0x2d023044, 0x27000a04, 0x27000a04}, + {0x0000a52c, 0x31023644, 0x31023644, 0x2a000a20, 0x2a000a20}, + {0x0000a530, 0x36025643, 0x36025643, 0x2e000e20, 0x2e000e20}, + {0x0000a534, 0x3a025a44, 0x3a025a44, 0x32000e22, 0x32000e22}, + {0x0000a538, 0x3d025e45, 0x3d025e45, 0x36000e24, 0x36000e24}, + {0x0000a53c, 0x43025e4a, 0x43025e4a, 0x3a001640, 0x3a001640}, + {0x0000a540, 0x4a025e6c, 0x4a025e6c, 0x3e001660, 0x3e001660}, + {0x0000a544, 0x50025e8e, 0x50025e8e, 0x41001861, 0x41001861}, + {0x0000a548, 0x56025eb2, 0x56025eb2, 0x45001a81, 0x45001a81}, + {0x0000a54c, 0x5c025eb5, 0x5c025eb5, 0x49001a83, 0x49001a83}, + {0x0000a550, 0x62025ef6, 0x62025ef6, 0x4c001c84, 0x4c001c84}, + {0x0000a554, 0x65025f56, 0x65025f56, 0x4f001ce3, 0x4f001ce3}, + {0x0000a558, 0x69027f56, 0x69027f56, 0x53001ce5, 0x53001ce5}, + {0x0000a55c, 0x6d029f56, 0x6d029f56, 0x57001ce9, 0x57001ce9}, + {0x0000a560, 0x73049f56, 0x73049f56, 0x5b001ceb, 0x5b001ceb}, + {0x0000a564, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a568, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a56c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a570, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a574, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a578, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a57c, 0x7804ff56, 0x7804ff56, 0x5d001eec, 0x5d001eec}, + {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a60c, 0x00804000, 0x00804000, 0x00000000, 0x00000000}, + {0x0000a610, 0x00804201, 0x00804201, 0x00000000, 0x00000000}, + {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000}, + {0x0000a618, 0x00804201, 0x00804201, 0x01404501, 0x01404501}, + {0x0000a61c, 0x02008201, 0x02008201, 0x02008501, 0x02008501}, + {0x0000a620, 0x02c10a03, 0x02c10a03, 0x0280ca03, 0x0280ca03}, + {0x0000a624, 0x04815205, 0x04815205, 0x02c10b04, 0x02c10b04}, + {0x0000a628, 0x0581d406, 0x0581d406, 0x03814b04, 0x03814b04}, + {0x0000a62c, 0x0581d607, 0x0581d607, 0x05018e05, 0x05018e05}, + {0x0000a630, 0x0581d607, 0x0581d607, 0x05019406, 0x05019406}, + {0x0000a634, 0x0581d607, 0x0581d607, 0x05019406, 0x05019406}, + {0x0000a638, 0x0581d607, 0x0581d607, 0x05019406, 0x05019406}, + {0x0000a63c, 0x0581d607, 0x0581d607, 0x05019406, 0x05019406}, + {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4}, + {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060}, + {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000}, +}; + +static const u32 ar9565_1p0_modes_high_power_tx_gain_table[][5] = { + /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ + {0x0000a2dc, 0xfc0a9380, 0xfc0a9380, 0xfdab5b52, 0xfdab5b52}, + {0x0000a2e0, 0xffecec00, 0xffecec00, 0xfd339c84, 0xfd339c84}, + {0x0000a2e4, 0xfc0f0000, 0xfc0f0000, 0xfec3e000, 0xfec3e000}, + {0x0000a2e8, 0xfc100000, 0xfc100000, 0xfffc0000, 0xfffc0000}, + {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9}, + {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, 0x53025eb2, 0x53025eb2, 0x3e001a81, 0x3e001a81}, + {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83}, + {0x0000a550, 0x5f025ef6, 0x5f025ef6, 0x44001c84, 0x44001c84}, + {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3}, + {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5}, + {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9}, + {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb}, + {0x0000a564, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a568, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a56c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a570, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a574, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a578, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {0x0000a57c, 0x7504ff56, 0x7504ff56, 0x56001eec, 0x56001eec}, + {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, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a618, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a61c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a620, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a624, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a628, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a62c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a630, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a634, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a638, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x0000a63c, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016044, 0x056d82e6, 0x056d82e6, 0x056d82e6, 0x056d82e6}, + {0x00016048, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, + {0x00016054, 0x00000000, 0x00000000, 0x00000000, 0x00000000}, +}; + +#endif /* INITVALS_9565_1P0_H */ diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 7373e4b92c9..dfe6a4707fd 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h @@ -173,6 +173,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd, #define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) +#define IS_CCK_RATE(rate) ((rate >= 0x18) && (rate <= 0x1e)) + #define ATH_TX_COMPLETE_POLL_INT 1000 enum ATH_AGGR_STATUS { @@ -423,7 +425,6 @@ void ath9k_beacon_assign_slot(struct ath_softc *sc, struct ieee80211_vif *vif); void ath9k_beacon_remove_slot(struct ath_softc *sc, struct ieee80211_vif *vif); void ath9k_set_tsfadjust(struct ath_softc *sc, struct ieee80211_vif *vif); void ath9k_set_beacon(struct ath_softc *sc); -void ath9k_set_beaconing_status(struct ath_softc *sc, bool status); /*******************/ /* Link Monitoring */ @@ -473,7 +474,7 @@ struct ath_btcoex { unsigned long op_flags; int bt_stomp_type; /* Types of BT stomping */ u32 btcoex_no_stomp; /* in usec */ - u32 btcoex_period; /* in usec */ + u32 btcoex_period; /* in msec */ u32 btscan_no_stomp; /* in usec */ u32 duty_cycle; u32 bt_wait_time; @@ -538,6 +539,7 @@ struct ath9k_wow_pattern { #ifdef CONFIG_MAC80211_LEDS void ath_init_leds(struct ath_softc *sc); void ath_deinit_leds(struct ath_softc *sc); +void ath_fill_led_pin(struct ath_softc *sc); #else static inline void ath_init_leds(struct ath_softc *sc) { @@ -546,6 +548,9 @@ static inline void ath_init_leds(struct ath_softc *sc) static inline void ath_deinit_leds(struct ath_softc *sc) { } +static inline void ath_fill_led_pin(struct ath_softc *sc) +{ +} #endif /*******************************/ @@ -597,8 +602,6 @@ struct ath_ant_comb { int main_conf; enum ath9k_ant_div_comb_lna_conf first_quick_scan_conf; enum ath9k_ant_div_comb_lna_conf second_quick_scan_conf; - int first_bias; - int second_bias; bool first_ratio; bool second_ratio; unsigned long scan_start_time; diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c index acd437384fe..419e9a3f2fe 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.c +++ b/drivers/net/wireless/ath/ath9k/btcoex.c @@ -43,8 +43,8 @@ static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX] { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */ }; -static const u32 ar9462_wlan_weights[ATH_BTCOEX_STOMP_MAX] - [AR9300_NUM_WLAN_WEIGHTS] = { +static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX] + [AR9300_NUM_WLAN_WEIGHTS] = { { 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */ { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ @@ -208,14 +208,37 @@ static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah) AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); } +/* + * For AR9002, bt_weight/wlan_weight are used. + * For AR9003 and above, stomp_type is used. + */ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, u32 bt_weight, - u32 wlan_weight) + u32 wlan_weight, + enum ath_stomp_type stomp_type) { struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; - btcoex_hw->bt_coex_weights = SM(bt_weight, AR_BTCOEX_BT_WGHT) | - SM(wlan_weight, AR_BTCOEX_WL_WGHT); + if (AR_SREV_9300_20_OR_LATER(ah)) { + const u32 *weight = ar9003_wlan_weights[stomp_type]; + int i; + + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { + if ((stomp_type == ATH_BTCOEX_STOMP_LOW) && + btcoex_hw->mci.stomp_ftp) + stomp_type = ATH_BTCOEX_STOMP_LOW_FTP; + weight = mci_wlan_weights[stomp_type]; + } + + for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { + btcoex_hw->bt_weight[i] = AR9300_BT_WGHT; + btcoex_hw->wlan_weight[i] = weight[i]; + } + } else { + btcoex_hw->bt_coex_weights = + SM(bt_weight, AR_BTCOEX_BT_WGHT) | + SM(wlan_weight, AR_BTCOEX_WL_WGHT); + } } EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); @@ -282,7 +305,7 @@ void ath9k_hw_btcoex_enable(struct ath_hw *ah) ath9k_hw_btcoex_enable_2wire(ah); break; case ATH_BTCOEX_CFG_3WIRE: - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { ath9k_hw_btcoex_enable_mci(ah); return; } @@ -304,7 +327,7 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) int i; btcoex_hw->enabled = false; - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), @@ -332,26 +355,6 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_btcoex_disable); -static void ar9003_btcoex_bt_stomp(struct ath_hw *ah, - enum ath_stomp_type stomp_type) -{ - struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; - const u32 *weight = ar9003_wlan_weights[stomp_type]; - int i; - - if (AR_SREV_9462(ah)) { - if ((stomp_type == ATH_BTCOEX_STOMP_LOW) && - btcoex->mci.stomp_ftp) - stomp_type = ATH_BTCOEX_STOMP_LOW_FTP; - weight = ar9462_wlan_weights[stomp_type]; - } - - for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { - btcoex->bt_weight[i] = AR9300_BT_WGHT; - btcoex->wlan_weight[i] = weight[i]; - } -} - /* * Configures appropriate weight based on stomp type. */ @@ -359,22 +362,22 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, enum ath_stomp_type stomp_type) { if (AR_SREV_9300_20_OR_LATER(ah)) { - ar9003_btcoex_bt_stomp(ah, stomp_type); + ath9k_hw_btcoex_set_weight(ah, 0, 0, stomp_type); return; } switch (stomp_type) { case ATH_BTCOEX_STOMP_ALL: ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_ALL_WLAN_WGHT); + AR_STOMP_ALL_WLAN_WGHT, 0); break; case ATH_BTCOEX_STOMP_LOW: ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); + AR_STOMP_LOW_WLAN_WGHT, 0); break; case ATH_BTCOEX_STOMP_NONE: ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_NONE_WLAN_WGHT); + AR_STOMP_NONE_WLAN_WGHT, 0); break; default: ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n"); diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h index 20092f98658..385197ad79b 100644 --- a/drivers/net/wireless/ath/ath9k/btcoex.h +++ b/drivers/net/wireless/ath/ath9k/btcoex.h @@ -107,7 +107,8 @@ void ath9k_hw_btcoex_init_mci(struct ath_hw *ah); void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum); void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, u32 bt_weight, - u32 wlan_weight); + u32 wlan_weight, + enum ath_stomp_type stomp_type); void ath9k_hw_btcoex_disable(struct ath_hw *ah); void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, enum ath_stomp_type stomp_type); diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c index 68b643c8943..6727b566d29 100644 --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c @@ -222,6 +222,57 @@ static const struct file_operations fops_disable_ani = { .llseek = default_llseek, }; +static ssize_t read_file_ant_diversity(struct file *file, 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]; + unsigned int len; + + len = sprintf(buf, "%d\n", common->antenna_diversity); + return simple_read_from_buffer(user_buf, count, ppos, buf, len); +} + +static ssize_t write_file_ant_diversity(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); + unsigned long antenna_diversity; + char buf[32]; + ssize_t len; + + len = min(count, sizeof(buf) - 1); + if (copy_from_user(buf, user_buf, len)) + return -EFAULT; + + if (!AR_SREV_9565(sc->sc_ah)) + goto exit; + + buf[len] = '\0'; + if (strict_strtoul(buf, 0, &antenna_diversity)) + return -EINVAL; + + common->antenna_diversity = !!antenna_diversity; + ath9k_ps_wakeup(sc); + ath_ant_comb_update(sc); + ath_dbg(common, CONFIG, "Antenna diversity: %d\n", + common->antenna_diversity); + ath9k_ps_restore(sc); +exit: + return count; +} + +static const struct file_operations fops_ant_diversity = { + .read = read_file_ant_diversity, + .write = write_file_ant_diversity, + .open = simple_open, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + static ssize_t read_file_dma(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { @@ -373,6 +424,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status) sc->debug.stats.istats.tsfoor++; if (status & ATH9K_INT_MCI) sc->debug.stats.istats.mci++; + if (status & ATH9K_INT_GENTIMER) + sc->debug.stats.istats.gen_timer++; } static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, @@ -418,6 +471,7 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf, PR_IS("DTIM", dtim); PR_IS("TSFOOR", tsfoor); PR_IS("MCI", mci); + PR_IS("GENTIMER", gen_timer); PR_IS("TOTAL", total); len += snprintf(buf + len, mxlen - len, @@ -1577,6 +1631,8 @@ int ath9k_init_debug(struct ath_hw *ah) sc->debug.debugfs_phy, sc, &fops_tx_chainmask); debugfs_create_file("disable_ani", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_disable_ani); + debugfs_create_bool("paprd", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, + &sc->sc_ah->config.enable_paprd); debugfs_create_file("regidx", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, sc, &fops_regidx); debugfs_create_file("regval", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, @@ -1596,12 +1652,12 @@ int ath9k_init_debug(struct ath_hw *ah) debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc, &fops_samps); #endif - debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); - debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, &sc->sc_ah->gpio_val); + debugfs_create_file("diversity", S_IRUSR | S_IWUSR, + sc->debug.debugfs_phy, sc, &fops_ant_diversity); return 0; } diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h index 8b9d080d89d..2ed9785a38f 100644 --- a/drivers/net/wireless/ath/ath9k/debug.h +++ b/drivers/net/wireless/ath/ath9k/debug.h @@ -41,7 +41,6 @@ enum ath_reset_type { RESET_TYPE_PLL_HANG, RESET_TYPE_MAC_HANG, RESET_TYPE_BEACON_STUCK, - RESET_TYPE_MCI, __RESET_TYPE_MAX }; @@ -74,6 +73,8 @@ enum ath_reset_type { * from a beacon differs from the PCU's internal TSF by more than a * (programmable) threshold * @local_timeout: Internal bus timeout. + * @mci: MCI interrupt, specific to MCI based BTCOEX chipsets + * @gen_timer: Generic hardware timer interrupt */ struct ath_interrupt_stats { u32 total; @@ -100,6 +101,7 @@ struct ath_interrupt_stats { u32 bb_watchdog; u32 tsfoor; u32 mci; + u32 gen_timer; /* Sync-cause stats */ u32 sync_cause_all; diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index 484b3130590..319c651fa6c 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h @@ -96,6 +96,7 @@ #define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s)) #define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5)) +#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x)) #define ath9k_hw_use_flash(_ah) (!(_ah->ah_flags & AH_USE_EEPROM)) #define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) @@ -108,7 +109,7 @@ #define EEP_RFSILENT_ENABLED_S 0 #define EEP_RFSILENT_POLARITY 0x0002 #define EEP_RFSILENT_POLARITY_S 1 -#define EEP_RFSILENT_GPIO_SEL (AR_SREV_9462(ah) ? 0x00fc : 0x001c) +#define EEP_RFSILENT_GPIO_SEL ((AR_SREV_9462(ah) || AR_SREV_9565(ah)) ? 0x00fc : 0x001c) #define EEP_RFSILENT_GPIO_SEL_S 2 #define AR5416_OPFLAGS_11A 0x01 diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c index bacdb8fb4ef..d9ed141a053 100644 --- a/drivers/net/wireless/ath/ath9k/gpio.c +++ b/drivers/net/wireless/ath/ath9k/gpio.c @@ -44,25 +44,6 @@ void ath_init_leds(struct ath_softc *sc) if (AR_SREV_9100(sc->sc_ah)) return; - if (sc->sc_ah->led_pin < 0) { - if (AR_SREV_9287(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9287; - else if (AR_SREV_9485(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9485; - else if (AR_SREV_9300(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9300; - else if (AR_SREV_9462(sc->sc_ah)) - sc->sc_ah->led_pin = ATH_LED_PIN_9462; - else - sc->sc_ah->led_pin = ATH_LED_PIN_DEF; - } - - /* Configure gpio 1 for output */ - ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin, - AR_GPIO_OUTPUT_MUX_AS_OUTPUT); - /* LED off, active low */ - ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); - if (!led_blink) sc->led_cdev.default_trigger = ieee80211_get_radio_led_name(sc->hw); @@ -78,6 +59,31 @@ void ath_init_leds(struct ath_softc *sc) sc->led_registered = true; } + +void ath_fill_led_pin(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + if (AR_SREV_9100(ah) || (ah->led_pin >= 0)) + return; + + if (AR_SREV_9287(ah)) + ah->led_pin = ATH_LED_PIN_9287; + else if (AR_SREV_9485(sc->sc_ah)) + ah->led_pin = ATH_LED_PIN_9485; + else if (AR_SREV_9300(sc->sc_ah)) + ah->led_pin = ATH_LED_PIN_9300; + else if (AR_SREV_9462(sc->sc_ah) || AR_SREV_9565(sc->sc_ah)) + ah->led_pin = ATH_LED_PIN_9462; + else + ah->led_pin = ATH_LED_PIN_DEF; + + /* Configure gpio 1 for output */ + ath9k_hw_cfg_output(ah, ah->led_pin, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); + + /* LED off, active low */ + ath9k_hw_set_gpio(ah, ah->led_pin, 1); +} #endif /*******************/ @@ -228,7 +234,12 @@ static void ath_btcoex_period_timer(unsigned long data) ath9k_hw_btcoex_enable(ah); spin_unlock_bh(&btcoex->btcoex_lock); - if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) { + /* + * btcoex_period is in msec while (btocex/btscan_)no_stomp are in usec, + * ensure that we properly convert btcoex_period to usec + * for any comparision with (btcoex/btscan_)no_stomp. + */ + if (btcoex->btcoex_period * 1000 != btcoex->btcoex_no_stomp) { if (btcoex->hw_timer_enabled) ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); @@ -309,8 +320,10 @@ void ath9k_btcoex_timer_resume(struct ath_softc *sc) ath_dbg(ath9k_hw_common(ah), BTCOEX, "Starting btcoex timers\n"); /* make sure duty cycle timer is also stopped when resuming */ - if (btcoex->hw_timer_enabled) + if (btcoex->hw_timer_enabled) { ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); + btcoex->hw_timer_enabled = false; + } btcoex->bt_priority_cnt = 0; btcoex->bt_priority_time = jiffies; @@ -331,17 +344,20 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc) del_timer_sync(&btcoex->period_timer); - if (btcoex->hw_timer_enabled) + if (btcoex->hw_timer_enabled) { ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer); - - btcoex->hw_timer_enabled = false; + btcoex->hw_timer_enabled = false; + } } void ath9k_btcoex_stop_gen_timer(struct ath_softc *sc) { struct ath_btcoex *btcoex = &sc->btcoex; - ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); + if (btcoex->hw_timer_enabled) { + ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer); + btcoex->hw_timer_enabled = false; + } } u16 ath9k_btcoex_aggr_limit(struct ath_softc *sc, u32 max_4ms_framelen) @@ -379,7 +395,10 @@ void ath9k_start_btcoex(struct ath_softc *sc) !ah->btcoex_hw.enabled) { if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_MCI)) ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); + AR_STOMP_LOW_WLAN_WGHT, 0); + else + ath9k_hw_btcoex_set_weight(ah, 0, 0, + ATH_BTCOEX_STOMP_NONE); ath9k_hw_btcoex_enable(ah); if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) @@ -396,7 +415,7 @@ void ath9k_stop_btcoex(struct ath_softc *sc) if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) ath9k_btcoex_timer_pause(sc); ath9k_hw_btcoex_disable(ah); - if (AR_SREV_9462(ah)) + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) ath_mci_flush_profile(&sc->btcoex.mci); } } diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index aa327adcc3d..924c4616c3d 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c @@ -973,8 +973,8 @@ static void ath9k_hif_usb_dealloc_urbs(struct hif_device_usb *hif_dev) static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) { int transfer, err; - const void *data = hif_dev->firmware->data; - size_t len = hif_dev->firmware->size; + const void *data = hif_dev->fw_data; + size_t len = hif_dev->fw_size; u32 addr = AR9271_FIRMWARE; u8 *buf = kzalloc(4096, GFP_KERNEL); u32 firm_offset; @@ -1017,7 +1017,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev) return -EIO; dev_info(&hif_dev->udev->dev, "ath9k_htc: Transferred FW: %s, size: %ld\n", - hif_dev->fw_name, (unsigned long) hif_dev->firmware->size); + hif_dev->fw_name, (unsigned long) hif_dev->fw_size); return 0; } @@ -1072,14 +1072,15 @@ static void ath9k_hif_usb_dev_deinit(struct hif_device_usb *hif_dev) */ static void ath9k_hif_usb_firmware_fail(struct hif_device_usb *hif_dev) { - struct device *parent = hif_dev->udev->dev.parent; + struct device *dev = &hif_dev->udev->dev; + struct device *parent = dev->parent; complete(&hif_dev->fw_done); if (parent) device_lock(parent); - device_release_driver(&hif_dev->udev->dev); + device_release_driver(dev); if (parent) device_unlock(parent); @@ -1099,11 +1100,11 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) hif_dev->htc_handle = ath9k_htc_hw_alloc(hif_dev, &hif_usb, &hif_dev->udev->dev); - if (hif_dev->htc_handle == NULL) { - goto err_fw; - } + if (hif_dev->htc_handle == NULL) + goto err_dev_alloc; - hif_dev->firmware = fw; + hif_dev->fw_data = fw->data; + hif_dev->fw_size = fw->size; /* Proceed with initialization */ @@ -1121,6 +1122,8 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context) goto err_htc_hw_init; } + release_firmware(fw); + hif_dev->flags |= HIF_USB_READY; complete(&hif_dev->fw_done); return; @@ -1129,8 +1132,8 @@ err_htc_hw_init: ath9k_hif_usb_dev_deinit(hif_dev); err_dev_init: ath9k_htc_hw_free(hif_dev->htc_handle); +err_dev_alloc: release_firmware(fw); - hif_dev->firmware = NULL; err_fw: ath9k_hif_usb_firmware_fail(hif_dev); } @@ -1277,11 +1280,10 @@ static void ath9k_hif_usb_disconnect(struct usb_interface *interface) wait_for_completion(&hif_dev->fw_done); - if (hif_dev->firmware) { + if (hif_dev->flags & HIF_USB_READY) { ath9k_htc_hw_deinit(hif_dev->htc_handle, unplugged); ath9k_htc_hw_free(hif_dev->htc_handle); ath9k_hif_usb_dev_deinit(hif_dev); - release_firmware(hif_dev->firmware); } usb_set_intfdata(interface, NULL); @@ -1317,13 +1319,23 @@ static int ath9k_hif_usb_resume(struct usb_interface *interface) struct hif_device_usb *hif_dev = usb_get_intfdata(interface); struct htc_target *htc_handle = hif_dev->htc_handle; int ret; + const struct firmware *fw; ret = ath9k_hif_usb_alloc_urbs(hif_dev); if (ret) return ret; - if (hif_dev->firmware) { + if (hif_dev->flags & HIF_USB_READY) { + /* request cached firmware during suspend/resume cycle */ + ret = request_firmware(&fw, hif_dev->fw_name, + &hif_dev->udev->dev); + if (ret) + goto fail_resume; + + hif_dev->fw_data = fw->data; + hif_dev->fw_size = fw->size; ret = ath9k_hif_usb_download_fw(hif_dev); + release_firmware(fw); if (ret) goto fail_resume; } else { diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h index 487ff658b4c..51496e74b83 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.h +++ b/drivers/net/wireless/ath/ath9k/hif_usb.h @@ -85,12 +85,14 @@ struct cmd_buf { }; #define HIF_USB_START BIT(0) +#define HIF_USB_READY BIT(1) struct hif_device_usb { struct usb_device *udev; struct usb_interface *interface; const struct usb_device_id *usb_device_id; - const struct firmware *firmware; + const void *fw_data; + size_t fw_size; struct completion fw_done; struct htc_target *htc_handle; struct hif_usb_tx tx; diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c index 07df279c8d4..0eacfc13c91 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_gpio.c @@ -161,7 +161,7 @@ void ath9k_htc_start_btcoex(struct ath9k_htc_priv *priv) if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_3WIRE) { ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, - AR_STOMP_LOW_WLAN_WGHT); + AR_STOMP_LOW_WLAN_WGHT, 0); ath9k_hw_btcoex_enable(ah); ath_htc_resume_btcoex_work(priv); } @@ -173,17 +173,26 @@ void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv) if (ah->btcoex_hw.enabled && ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { - ath9k_hw_btcoex_disable(ah); if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) ath_htc_cancel_btcoex_work(priv); + ath9k_hw_btcoex_disable(ah); } } void ath9k_htc_init_btcoex(struct ath9k_htc_priv *priv, char *product) { struct ath_hw *ah = priv->ah; + struct ath_common *common = ath9k_hw_common(ah); int qnum; + /* + * Check if BTCOEX is globally disabled. + */ + if (!common->btcoex_enabled) { + ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_NONE; + return; + } + if (product && strncmp(product, ATH_HTC_BTCOEX_PRODUCT_ID, 5) == 0) { ah->btcoex_hw.scheme = ATH_BTCOEX_CFG_3WIRE; } diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index a035a380d66..d98255eb1b9 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c @@ -30,6 +30,10 @@ int htc_modparam_nohwcrypt; module_param_named(nohwcrypt, htc_modparam_nohwcrypt, int, 0444); MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption"); +static int ath9k_htc_btcoex_enable; +module_param_named(btcoex_enable, ath9k_htc_btcoex_enable, int, 0444); +MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); + #define CHAN2G(_freq, _idx) { \ .center_freq = (_freq), \ .hw_value = (_idx), \ @@ -635,6 +639,7 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv, common->hw = priv->hw; common->priv = priv; common->debug_mask = ath9k_debug; + common->btcoex_enabled = ath9k_htc_btcoex_enable == 1; spin_lock_init(&priv->beacon_lock); spin_lock_init(&priv->tx.tx_lock); diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 8a0ccf70aa1..ca78e33ca23 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c @@ -489,24 +489,20 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv, ista = (struct ath9k_htc_sta *) sta->drv_priv; memcpy(&tsta.macaddr, sta->addr, ETH_ALEN); memcpy(&tsta.bssid, common->curbssid, ETH_ALEN); - tsta.is_vif_sta = 0; ista->index = sta_idx; + tsta.is_vif_sta = 0; + maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + + sta->ht_cap.ampdu_factor); + tsta.maxampdu = cpu_to_be16(maxampdu); } else { memcpy(&tsta.macaddr, vif->addr, ETH_ALEN); tsta.is_vif_sta = 1; + tsta.maxampdu = cpu_to_be16(0xffff); } tsta.sta_index = sta_idx; tsta.vif_index = avp->index; - if (!sta) { - tsta.maxampdu = cpu_to_be16(0xffff); - } else { - maxampdu = 1 << (IEEE80211_HT_MAX_AMPDU_FACTOR + - sta->ht_cap.ampdu_factor); - tsta.maxampdu = cpu_to_be16(maxampdu); - } - WMI_CMD_BUF(WMI_NODE_CREATE_CMDID, &tsta); if (ret) { if (sta) @@ -1333,6 +1329,34 @@ static int ath9k_htc_sta_remove(struct ieee80211_hw *hw, return ret; } +static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_sta *sta, u32 changed) +{ + struct ath9k_htc_priv *priv = hw->priv; + struct ath_common *common = ath9k_hw_common(priv->ah); + struct ath9k_htc_target_rate trate; + + mutex_lock(&priv->mutex); + ath9k_htc_ps_wakeup(priv); + + if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { + memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); + ath9k_htc_setup_rate(priv, sta, &trate); + if (!ath9k_htc_send_rate_cmd(priv, &trate)) + ath_dbg(common, CONFIG, + "Supported rates for sta: %pM updated, rate caps: 0x%X\n", + sta->addr, be32_to_cpu(trate.capflags)); + else + ath_dbg(common, CONFIG, + "Unable to update supported rates for sta: %pM\n", + sta->addr); + } + + ath9k_htc_ps_restore(priv); + mutex_unlock(&priv->mutex); +} + static int ath9k_htc_conf_tx(struct ieee80211_hw *hw, struct ieee80211_vif *vif, u16 queue, const struct ieee80211_tx_queue_params *params) @@ -1421,7 +1445,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw, key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; if (priv->ah->sw_mgmt_crypto && key->cipher == WLAN_CIPHER_SUITE_CCMP) - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ret = 0; } break; @@ -1760,6 +1784,7 @@ struct ieee80211_ops ath9k_htc_ops = { .sta_add = ath9k_htc_sta_add, .sta_remove = ath9k_htc_sta_remove, .conf_tx = ath9k_htc_conf_tx, + .sta_rc_update = ath9k_htc_sta_rc_update, .bss_info_changed = ath9k_htc_bss_info_changed, .set_key = ath9k_htc_set_key, .get_tsf = ath9k_htc_get_tsf, diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h index 265bf77598a..0f2b97f6b73 100644 --- a/drivers/net/wireless/ath/ath9k/hw-ops.h +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h @@ -78,6 +78,13 @@ static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah, ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf); } +static inline void ath9k_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah, + bool enable) +{ + if (ath9k_hw_ops(ah)->antctrl_shared_chain_lnadiv) + ath9k_hw_ops(ah)->antctrl_shared_chain_lnadiv(ah, enable); +} + /* Private hardware call ops */ /* PHY ops */ diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 60b6a9daff7..f9a6ec5cf47 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -24,6 +24,7 @@ #include "rc.h" #include "ar9003_mac.h" #include "ar9003_mci.h" +#include "ar9003_phy.h" #include "debug.h" #include "ath9k.h" @@ -355,7 +356,7 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah) (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S; ah->hw_version.macRev = MS(val, AR_SREV_REVISION2); - if (AR_SREV_9462(ah)) + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) ah->is_pciexpress = true; else ah->is_pciexpress = (val & @@ -463,9 +464,6 @@ static void ath9k_hw_init_config(struct ath_hw *ah) ah->config.spurchans[i][1] = AR_NO_SPUR; } - /* PAPRD needs some more work to be enabled */ - ah->config.paprd_disable = 1; - ah->config.rx_intr_mitigation = true; ah->config.pcieSerDesWrite = true; @@ -605,6 +603,11 @@ static int __ath9k_hw_init(struct ath_hw *ah) if (AR_SREV_9462(ah)) ah->WARegVal &= ~AR_WA_D3_L1_DISABLE; + if (AR_SREV_9565(ah)) { + ah->WARegVal |= AR_WA_BIT22; + REG_WRITE(ah, AR_WA, ah->WARegVal); + } + ath9k_hw_init_defaults(ah); ath9k_hw_init_config(ah); @@ -650,6 +653,7 @@ static int __ath9k_hw_init(struct ath_hw *ah) case AR_SREV_VERSION_9340: case AR_SREV_VERSION_9462: case AR_SREV_VERSION_9550: + case AR_SREV_VERSION_9565: break; default: ath_err(common, @@ -711,7 +715,7 @@ int ath9k_hw_init(struct ath_hw *ah) int ret; struct ath_common *common = ath9k_hw_common(ah); - /* These are all the AR5008/AR9001/AR9002 hardware family of chipsets */ + /* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */ switch (ah->hw_version.devid) { case AR5416_DEVID_PCI: case AR5416_DEVID_PCIE: @@ -731,6 +735,7 @@ int ath9k_hw_init(struct ath_hw *ah) case AR9300_DEVID_AR9580: case AR9300_DEVID_AR9462: case AR9485_DEVID_AR1111: + case AR9300_DEVID_AR9565: break; default: if (common->bus_ops->ath_bus_type == ATH_USB) @@ -803,8 +808,7 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, { u32 pll; - if (AR_SREV_9485(ah)) { - + if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { /* program BB PLL ki and kd value, ki=0x4, kd=0x40 */ REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2, AR_CH0_BB_DPLL2_PLL_PWD, 0x1); @@ -915,7 +919,8 @@ static void ath9k_hw_init_pll(struct ath_hw *ah, } pll = ath9k_hw_compute_pll_control(ah, chan); - + if (AR_SREV_9565(ah)) + pll |= 0x40000; REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll); if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) || @@ -978,9 +983,6 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah, else imr_reg |= AR_IMR_TXOK; - if (opmode == NL80211_IFTYPE_AP) - imr_reg |= AR_IMR_MIB; - ENABLE_REGWRITE_BUFFER(ah); REG_WRITE(ah, AR_IMR, imr_reg); @@ -1732,12 +1734,12 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) if (!ret) goto fail; - ath9k_hw_loadnf(ah, ah->curchan); - ath9k_hw_start_nfcal(ah, true); - if (ath9k_hw_mci_is_enabled(ah)) ar9003_mci_2g5g_switch(ah, false); + ath9k_hw_loadnf(ah, ah->curchan); + ath9k_hw_start_nfcal(ah, true); + if (AR_SREV_9271(ah)) ar9002_hw_load_ani_reg(ah, chan); @@ -1778,6 +1780,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, /* Operating channel changed, reset channel calibration data */ memset(caldata, 0, sizeof(*caldata)); ath9k_init_nfcal_hist_buffer(ah, chan); + } else if (caldata) { + caldata->paprd_packet_sent = false; } ah->noise = ath9k_hw_getchan_noise(ah, chan); @@ -2022,6 +2026,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, ath9k_hw_apply_gpio_override(ah); + if (AR_SREV_9565(ah) && ah->shared_chain_lnadiv) + REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); + return 0; } EXPORT_SYMBOL(ath9k_hw_reset); @@ -2038,7 +2045,7 @@ static void ath9k_set_power_sleep(struct ath_hw *ah) { REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV); - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { REG_CLR_BIT(ah, AR_TIMER_MODE, 0xff); REG_CLR_BIT(ah, AR_NDP2_TIMER_MODE, 0xff); REG_CLR_BIT(ah, AR_SLP32_INC, 0xfffff); @@ -2405,7 +2412,10 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (eeval & AR5416_OPFLAGS_11G) pCap->hw_caps |= ATH9K_HW_CAP_2GHZ; - if (AR_SREV_9485(ah) || AR_SREV_9285(ah) || AR_SREV_9330(ah)) + if (AR_SREV_9485(ah) || + AR_SREV_9285(ah) || + AR_SREV_9330(ah) || + AR_SREV_9565(ah)) chip_chainmask = 1; else if (AR_SREV_9462(ah)) chip_chainmask = 3; @@ -2493,7 +2503,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) if (AR_SREV_9300_20_OR_LATER(ah)) { pCap->hw_caps |= ATH9K_HW_CAP_EDMA | ATH9K_HW_CAP_FASTCLOCK; - if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah)) + if (!AR_SREV_9330(ah) && !AR_SREV_9485(ah) && !AR_SREV_9565(ah)) pCap->hw_caps |= ATH9K_HW_CAP_LDPC; pCap->rx_hp_qdepth = ATH9K_HW_RX_HP_QDEPTH; @@ -2501,9 +2511,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) pCap->rx_status_len = sizeof(struct ar9003_rxs); pCap->tx_desc_len = sizeof(struct ar9003_txc); pCap->txs_len = sizeof(struct ar9003_txs); - if (!ah->config.paprd_disable && - ah->eep_ops->get_eeprom(ah, EEP_PAPRD)) - pCap->hw_caps |= ATH9K_HW_CAP_PAPRD; } else { pCap->tx_desc_len = sizeof(struct ath_desc); if (AR_SREV_9280_20(ah)) @@ -2532,7 +2539,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) } - if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) { + if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) { ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); /* * enable the diversity-combining algorithm only when @@ -2575,14 +2582,12 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah) ah->enabled_cals |= TX_IQ_ON_AGC_CAL; } - if (AR_SREV_9462(ah)) { - + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) pCap->hw_caps |= ATH9K_HW_CAP_MCI; if (AR_SREV_9462_20(ah)) pCap->hw_caps |= ATH9K_HW_CAP_RTT; - } @@ -2748,7 +2753,7 @@ void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits) ENABLE_REGWRITE_BUFFER(ah); - if (AR_SREV_9462(ah)) + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) bits |= ATH9K_RX_FILTER_CONTROL_WRAPPER; REG_WRITE(ah, AR_RX_FILTER, bits); @@ -3045,7 +3050,7 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah, REG_SET_BIT(ah, gen_tmr_configuration[timer->index].mode_addr, gen_tmr_configuration[timer->index].mode_mask); - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { /* * Starting from AR9462, each generic timer can select which tsf * to use. But we still follow the old rule, 0 - 7 use tsf and @@ -3079,6 +3084,16 @@ void ath9k_hw_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer) REG_CLR_BIT(ah, gen_tmr_configuration[timer->index].mode_addr, gen_tmr_configuration[timer->index].mode_mask); + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { + /* + * Need to switch back to TSF if it was using TSF2. + */ + if ((timer->index >= AR_GEN_TIMER_BANK_1_LEN)) { + REG_CLR_BIT(ah, AR_MAC_PCU_GEN_TIMER_TSF_SEL, + (1 << timer->index)); + } + } + /* Disable both trigger and thresh interrupt masks */ REG_CLR_BIT(ah, AR_IMR_S5, (SM(AR_GENTMR_BIT(timer->index), AR_IMR_S5_GENTIMER_THRESH) | @@ -3160,6 +3175,7 @@ static struct { { AR_SREV_VERSION_9485, "9485" }, { AR_SREV_VERSION_9462, "9462" }, { AR_SREV_VERSION_9550, "9550" }, + { AR_SREV_VERSION_9565, "9565" }, }; /* For devices with external radios */ diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index ce7332c64ef..566a4ce4f15 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -50,6 +50,7 @@ #define AR9300_DEVID_AR9330 0x0035 #define AR9300_DEVID_QCA955X 0x0038 #define AR9485_DEVID_AR1111 0x0037 +#define AR9300_DEVID_AR9565 0x0036 #define AR5416_AR9100_DEVID 0x000b @@ -236,7 +237,6 @@ enum ath9k_hw_caps { ATH9K_HW_CAP_LDPC = BIT(6), ATH9K_HW_CAP_FASTCLOCK = BIT(7), ATH9K_HW_CAP_SGI_20 = BIT(8), - ATH9K_HW_CAP_PAPRD = BIT(9), ATH9K_HW_CAP_ANT_DIV_COMB = BIT(10), ATH9K_HW_CAP_2GHZ = BIT(11), ATH9K_HW_CAP_5GHZ = BIT(12), @@ -287,12 +287,12 @@ struct ath9k_ops_config { u8 pcie_clock_req; u32 pcie_waen; u8 analog_shiftreg; - u8 paprd_disable; u32 ofdm_trig_low; u32 ofdm_trig_high; u32 cck_trig_high; u32 cck_trig_low; u32 enable_ani; + u32 enable_paprd; int serialize_regmode; bool rx_intr_mitigation; bool tx_intr_mitigation; @@ -405,6 +405,7 @@ struct ath9k_hw_cal_data { int8_t iCoff; int8_t qCoff; bool rtt_done; + bool paprd_packet_sent; bool paprd_done; bool nfcal_pending; bool nfcal_interference; @@ -685,7 +686,7 @@ struct ath_hw_ops { struct ath_hw_antcomb_conf *antconf); void (*antdiv_comb_conf_set)(struct ath_hw *ah, struct ath_hw_antcomb_conf *antconf); - + void (*antctrl_shared_chain_lnadiv)(struct ath_hw *hw, bool enable); }; struct ath_nf_limits { @@ -729,6 +730,7 @@ struct ath_hw { bool aspm_enabled; bool is_monitoring; bool need_an_top2_fixup; + bool shared_chain_lnadiv; u16 tx_trig_level; u32 nf_regs[6]; diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index f33712140fa..fad3ccd5cd9 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c @@ -46,6 +46,10 @@ static int ath9k_btcoex_enable; module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444); MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence"); +static int ath9k_enable_diversity; +module_param_named(enable_diversity, ath9k_enable_diversity, int, 0444); +MODULE_PARM_DESC(enable_diversity, "Enable Antenna diversity for AR9565"); + bool is_ath9k_unloaded; /* We use the hw_value as an index into our private channel structure */ @@ -258,7 +262,7 @@ static void setup_ht_cap(struct ath_softc *sc, ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K; ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8; - if (AR_SREV_9330(ah) || AR_SREV_9485(ah)) + if (AR_SREV_9330(ah) || AR_SREV_9485(ah) || AR_SREV_9565(ah)) max_streams = 1; else if (AR_SREV_9462(ah)) max_streams = 2; @@ -546,6 +550,14 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, common->debug_mask = ath9k_debug; common->btcoex_enabled = ath9k_btcoex_enable == 1; common->disable_ani = false; + + /* + * Enable Antenna diversity only when BTCOEX is disabled + * and the user manually requests the feature. + */ + if (!common->btcoex_enabled && ath9k_enable_diversity) + common->antenna_diversity = 1; + spin_lock_init(&common->cc_lock); spin_lock_init(&sc->sc_serial_rw); @@ -597,6 +609,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, ath9k_cmn_init_crypto(sc->sc_ah); ath9k_init_misc(sc); + ath_fill_led_pin(sc); if (common->bus_ops->aspm_init) common->bus_ops->aspm_init(common); diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index d4549e9aac5..7b88b9c39cc 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -254,8 +254,9 @@ void ath_paprd_calibrate(struct work_struct *work) int chain_ok = 0; int chain; int len = 1800; + int ret; - if (!caldata) + if (!caldata || !caldata->paprd_packet_sent || caldata->paprd_done) return; ath9k_ps_wakeup(sc); @@ -282,13 +283,6 @@ void ath_paprd_calibrate(struct work_struct *work) continue; chain_ok = 0; - - ath_dbg(common, CALIBRATE, - "Sending PAPRD frame for thermal measurement on chain %d\n", - chain); - if (!ath_paprd_send_frame(sc, skb, chain)) - goto fail_paprd; - ar9003_paprd_setup_gain_table(ah, chain); ath_dbg(common, CALIBRATE, @@ -302,7 +296,13 @@ void ath_paprd_calibrate(struct work_struct *work) break; } - if (ar9003_paprd_create_curve(ah, caldata, chain)) { + ret = ar9003_paprd_create_curve(ah, caldata, chain); + if (ret == -EINPROGRESS) { + ath_dbg(common, CALIBRATE, + "PAPRD curve on chain %d needs to be re-trained\n", + chain); + break; + } else if (ret) { ath_dbg(common, CALIBRATE, "PAPRD create curve failed on chain %d\n", chain); @@ -423,7 +423,7 @@ set_timer: cal_interval = min(cal_interval, (u32)short_cal_interval); mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval)); - if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) { + if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD) && ah->caldata) { if (!ah->caldata->paprd_done) ieee80211_queue_work(sc->hw, &sc->paprd_work); else if (!ah->paprd_table_write_done) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 7990cd55599..b42be910a83 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -773,15 +773,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah) } EXPORT_SYMBOL(ath9k_hw_intrpend); -void ath9k_hw_disable_interrupts(struct ath_hw *ah) +void ath9k_hw_kill_interrupts(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); - if (!(ah->imask & ATH9K_INT_GLOBAL)) - atomic_set(&ah->intr_ref_cnt, -1); - else - atomic_dec(&ah->intr_ref_cnt); - ath_dbg(common, INTERRUPT, "disable IER\n"); REG_WRITE(ah, AR_IER, AR_IER_DISABLE); (void) REG_READ(ah, AR_IER); @@ -793,6 +788,17 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah) (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); } } +EXPORT_SYMBOL(ath9k_hw_kill_interrupts); + +void ath9k_hw_disable_interrupts(struct ath_hw *ah) +{ + if (!(ah->imask & ATH9K_INT_GLOBAL)) + atomic_set(&ah->intr_ref_cnt, -1); + else + atomic_dec(&ah->intr_ref_cnt); + + ath9k_hw_kill_interrupts(ah); +} EXPORT_SYMBOL(ath9k_hw_disable_interrupts); void ath9k_hw_enable_interrupts(struct ath_hw *ah) diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 0eba36dca6f..4a745e68dd9 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h @@ -738,6 +738,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah); void ath9k_hw_set_interrupts(struct ath_hw *ah); void ath9k_hw_enable_interrupts(struct ath_hw *ah); void ath9k_hw_disable_interrupts(struct ath_hw *ah); +void ath9k_hw_kill_interrupts(struct ath_hw *ah); void ar9002_hw_attach_mac_ops(struct ath_hw *ah); diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 4d8dc9ff5a7..31ab82e3ba8 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -462,8 +462,10 @@ irqreturn_t ath_isr(int irq, void *dev) if (!ath9k_hw_intrpend(ah)) return IRQ_NONE; - if(test_bit(SC_OP_HW_RESET, &sc->sc_flags)) + if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) { + ath9k_hw_kill_interrupts(ah); return IRQ_HANDLED; + } /* * Figure out the reason(s) for the interrupt. Note @@ -984,47 +986,21 @@ static int ath9k_add_interface(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); - int ret = 0; - ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); - switch (vif->type) { - case NL80211_IFTYPE_STATION: - case NL80211_IFTYPE_WDS: - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_MESH_POINT: - break; - default: - ath_err(common, "Interface type %d not yet supported\n", - vif->type); - ret = -EOPNOTSUPP; - goto out; - } - - if (ath9k_uses_beacons(vif->type)) { - if (sc->nbcnvifs >= ATH_BCBUF) { - ath_err(common, "Not enough beacon buffers when adding" - " new interface of type: %i\n", - vif->type); - ret = -ENOBUFS; - goto out; - } - } - ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); - sc->nvifs++; + ath9k_ps_wakeup(sc); ath9k_calculate_summary_state(hw, vif); + ath9k_ps_restore(sc); + if (ath9k_uses_beacons(vif->type)) ath9k_beacon_assign_slot(sc, vif); -out: mutex_unlock(&sc->mutex); - ath9k_ps_restore(sc); - return ret; + return 0; } static int ath9k_change_interface(struct ieee80211_hw *hw, @@ -1034,21 +1010,9 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, { struct ath_softc *sc = hw->priv; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - int ret = 0; ath_dbg(common, CONFIG, "Change Interface\n"); - mutex_lock(&sc->mutex); - ath9k_ps_wakeup(sc); - - if (ath9k_uses_beacons(new_type) && - !ath9k_uses_beacons(vif->type)) { - if (sc->nbcnvifs >= ATH_BCBUF) { - ath_err(common, "No beacon slot available\n"); - ret = -ENOBUFS; - goto out; - } - } if (ath9k_uses_beacons(vif->type)) ath9k_beacon_remove_slot(sc, vif); @@ -1056,14 +1020,15 @@ static int ath9k_change_interface(struct ieee80211_hw *hw, vif->type = new_type; vif->p2p = p2p; + ath9k_ps_wakeup(sc); ath9k_calculate_summary_state(hw, vif); + ath9k_ps_restore(sc); + if (ath9k_uses_beacons(vif->type)) ath9k_beacon_assign_slot(sc, vif); -out: - ath9k_ps_restore(sc); mutex_unlock(&sc->mutex); - return ret; + return 0; } static void ath9k_remove_interface(struct ieee80211_hw *hw, @@ -1074,7 +1039,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, ath_dbg(common, CONFIG, "Detach Interface\n"); - ath9k_ps_wakeup(sc); mutex_lock(&sc->mutex); sc->nvifs--; @@ -1082,10 +1046,11 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, if (ath9k_uses_beacons(vif->type)) ath9k_beacon_remove_slot(sc, vif); + ath9k_ps_wakeup(sc); ath9k_calculate_summary_state(hw, NULL); + ath9k_ps_restore(sc); mutex_unlock(&sc->mutex); - ath9k_ps_restore(sc); } static void ath9k_enable_ps(struct ath_softc *sc) @@ -1441,7 +1406,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw, key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC; if (sc->sc_ah->sw_mgmt_crypto && key->cipher == WLAN_CIPHER_SUITE_CCMP) - key->flags |= IEEE80211_KEY_FLAG_SW_MGMT; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; ret = 0; } break; @@ -2258,7 +2223,7 @@ static int ath9k_suspend(struct ieee80211_hw *hw, mutex_lock(&sc->mutex); ath_cancel_work(sc); - del_timer_sync(&common->ani.timer); + ath_stop_ani(sc); del_timer_sync(&sc->rx_poll_timer); if (test_bit(SC_OP_INVALID, &sc->sc_flags)) { diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c index fb536e7e661..ec2d7c80756 100644 --- a/drivers/net/wireless/ath/ath9k/mci.c +++ b/drivers/net/wireless/ath/ath9k/mci.c @@ -80,6 +80,7 @@ void ath_mci_flush_profile(struct ath_mci_profile *mci) struct ath_mci_profile_info *info, *tinfo; mci->aggr_limit = 0; + mci->num_mgmt = 0; if (list_empty(&mci->info)) return; @@ -120,7 +121,14 @@ static void ath_mci_update_scheme(struct ath_softc *sc) if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_TUNING) goto skip_tuning; + mci->aggr_limit = 0; btcoex->duty_cycle = ath_mci_duty_cycle[num_profile]; + btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; + if (NUM_PROF(mci)) + btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; + else + btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : + ATH_BTCOEX_STOMP_LOW; if (num_profile == 1) { info = list_first_entry(&mci->info, @@ -132,7 +140,8 @@ static void ath_mci_update_scheme(struct ath_softc *sc) else if (info->T == 6) { mci->aggr_limit = 6; btcoex->duty_cycle = 30; - } + } else + mci->aggr_limit = 6; ath_dbg(common, MCI, "Single SCO, aggregation limit %d 1/4 ms\n", mci->aggr_limit); @@ -191,6 +200,23 @@ skip_tuning: ath9k_btcoex_timer_resume(sc); } +static void ath_mci_wait_btcal_done(struct ath_softc *sc) +{ + struct ath_hw *ah = sc->sc_ah; + + /* Stop tx & rx */ + ieee80211_stop_queues(sc->hw); + ath_stoprecv(sc); + ath_drain_all_txq(sc, false); + + /* Wait for cal done */ + ar9003_mci_start_reset(ah, ah->curchan); + + /* Resume tx & rx */ + ath_startrecv(sc); + ieee80211_wake_queues(sc->hw); +} + static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) { struct ath_hw *ah = sc->sc_ah; @@ -201,8 +227,8 @@ static void ath_mci_cal_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) switch (opcode) { case MCI_GPM_BT_CAL_REQ: if (mci_hw->bt_state == MCI_BT_AWAKE) { - ar9003_mci_state(ah, MCI_STATE_SET_BT_CAL_START); - ath9k_queue_reset(sc, RESET_TYPE_MCI); + mci_hw->bt_state = MCI_BT_CAL_START; + ath_mci_wait_btcal_done(sc); } ath_dbg(common, MCI, "MCI State : %d\n", mci_hw->bt_state); break; @@ -224,8 +250,8 @@ static void ath9k_mci_work(struct work_struct *work) ath_mci_update_scheme(sc); } -static void ath_mci_process_profile(struct ath_softc *sc, - struct ath_mci_profile_info *info) +static u8 ath_mci_process_profile(struct ath_softc *sc, + struct ath_mci_profile_info *info) { struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_btcoex *btcoex = &sc->btcoex; @@ -251,25 +277,15 @@ static void ath_mci_process_profile(struct ath_softc *sc, if (info->start) { if (!entry && !ath_mci_add_profile(common, mci, info)) - return; + return 0; } else ath_mci_del_profile(common, mci, entry); - btcoex->btcoex_period = ATH_MCI_DEF_BT_PERIOD; - mci->aggr_limit = mci->num_sco ? 6 : 0; - - btcoex->duty_cycle = ath_mci_duty_cycle[NUM_PROF(mci)]; - if (NUM_PROF(mci)) - btcoex->bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - else - btcoex->bt_stomp_type = mci->num_mgmt ? ATH_BTCOEX_STOMP_ALL : - ATH_BTCOEX_STOMP_LOW; - - ieee80211_queue_work(sc->hw, &sc->mci_work); + return 1; } -static void ath_mci_process_status(struct ath_softc *sc, - struct ath_mci_profile_status *status) +static u8 ath_mci_process_status(struct ath_softc *sc, + struct ath_mci_profile_status *status) { struct ath_btcoex *btcoex = &sc->btcoex; struct ath_mci_profile *mci = &btcoex->mci; @@ -278,14 +294,14 @@ static void ath_mci_process_status(struct ath_softc *sc, /* Link status type are not handled */ if (status->is_link) - return; + return 0; info.conn_handle = status->conn_handle; if (ath_mci_find_profile(mci, &info)) - return; + return 0; if (status->conn_handle >= ATH_MCI_MAX_PROFILE) - return; + return 0; if (status->is_critical) __set_bit(status->conn_handle, mci->status); @@ -299,7 +315,9 @@ static void ath_mci_process_status(struct ath_softc *sc, } while (++i < ATH_MCI_MAX_PROFILE); if (old_num_mgmt != mci->num_mgmt) - ieee80211_queue_work(sc->hw, &sc->mci_work); + return 1; + + return 0; } static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) @@ -308,9 +326,16 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) struct ath_mci_profile_info profile_info; struct ath_mci_profile_status profile_status; struct ath_common *common = ath9k_hw_common(sc->sc_ah); - u8 major, minor; + u8 major, minor, update_scheme = 0; u32 seq_num; + if (ar9003_mci_state(ah, MCI_STATE_NEED_FLUSH_BT_INFO) && + ar9003_mci_state(ah, MCI_STATE_ENABLE)) { + ath_dbg(common, MCI, "(MCI) Need to flush BT profiles\n"); + ath_mci_flush_profile(&sc->btcoex.mci); + ar9003_mci_state(ah, MCI_STATE_SEND_STATUS_QUERY); + } + switch (opcode) { case MCI_GPM_COEX_VERSION_QUERY: ar9003_mci_state(ah, MCI_STATE_SEND_WLAN_COEX_VERSION); @@ -336,7 +361,7 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) break; } - ath_mci_process_profile(sc, &profile_info); + update_scheme += ath_mci_process_profile(sc, &profile_info); break; case MCI_GPM_COEX_BT_STATUS_UPDATE: profile_status.is_link = *(rx_payload + @@ -352,12 +377,14 @@ static void ath_mci_msg(struct ath_softc *sc, u8 opcode, u8 *rx_payload) profile_status.is_link, profile_status.conn_handle, profile_status.is_critical, seq_num); - ath_mci_process_status(sc, &profile_status); + update_scheme += ath_mci_process_status(sc, &profile_status); break; default: ath_dbg(common, MCI, "Unknown GPM COEX message = 0x%02x\n", opcode); break; } + if (update_scheme) + ieee80211_queue_work(sc->hw, &sc->mci_work); } int ath_mci_setup(struct ath_softc *sc) @@ -365,6 +392,7 @@ int ath_mci_setup(struct ath_softc *sc) struct ath_common *common = ath9k_hw_common(sc->sc_ah); struct ath_mci_coex *mci = &sc->mci_coex; struct ath_mci_buf *buf = &mci->sched_buf; + int ret; buf->bf_addr = dma_alloc_coherent(sc->dev, ATH_MCI_SCHED_BUF_SIZE + ATH_MCI_GPM_BUF_SIZE, @@ -384,9 +412,13 @@ int ath_mci_setup(struct ath_softc *sc) mci->gpm_buf.bf_addr = (u8 *)mci->sched_buf.bf_addr + mci->sched_buf.bf_len; mci->gpm_buf.bf_paddr = mci->sched_buf.bf_paddr + mci->sched_buf.bf_len; - ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, - mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), - mci->sched_buf.bf_paddr); + ret = ar9003_mci_setup(sc->sc_ah, mci->gpm_buf.bf_paddr, + mci->gpm_buf.bf_addr, (mci->gpm_buf.bf_len >> 4), + mci->sched_buf.bf_paddr); + if (ret) { + ath_err(common, "Failed to initialize MCI\n"); + return ret; + } INIT_WORK(&sc->mci_work, ath9k_mci_work); ath_dbg(common, MCI, "MCI Initialized\n"); @@ -551,9 +583,11 @@ void ath_mci_intr(struct ath_softc *sc) } if ((mci_int & AR_MCI_INTERRUPT_RX_INVALID_HDR) || - (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) + (mci_int & AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT)) { mci_int &= ~(AR_MCI_INTERRUPT_RX_INVALID_HDR | AR_MCI_INTERRUPT_CONT_INFO_TIMEOUT); + ath_mci_msg(sc, MCI_GPM_COEX_NOOP, NULL); + } } void ath_mci_enable(struct ath_softc *sc) diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index d455de9162e..0e630a99b68 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c @@ -38,6 +38,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { { PCI_VDEVICE(ATHEROS, 0x0033) }, /* PCI-E AR9580 */ { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ + { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */ { 0 } }; @@ -113,41 +114,33 @@ static void ath_pci_aspm_init(struct ath_common *common) struct ath_hw *ah = sc->sc_ah; struct pci_dev *pdev = to_pci_dev(sc->dev); struct pci_dev *parent; - int pos; - u8 aspm; + u16 aspm; if (!ah->is_pciexpress) return; - pos = pci_pcie_cap(pdev); - if (!pos) - return; - parent = pdev->bus->self; if (!parent) return; - if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) { + if ((ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_NONE) && + (AR_SREV_9285(ah))) { /* Bluetooth coexistance requires disabling ASPM. */ - pci_read_config_byte(pdev, pos + PCI_EXP_LNKCTL, &aspm); - aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); - pci_write_config_byte(pdev, pos + PCI_EXP_LNKCTL, aspm); + pcie_capability_clear_word(pdev, PCI_EXP_LNKCTL, + PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); /* * Both upstream and downstream PCIe components should * have the same ASPM settings. */ - pos = pci_pcie_cap(parent); - pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); - aspm &= ~(PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); - pci_write_config_byte(parent, pos + PCI_EXP_LNKCTL, aspm); + pcie_capability_clear_word(parent, PCI_EXP_LNKCTL, + PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); ath_info(common, "Disabling ASPM since BTCOEX is enabled\n"); return; } - pos = pci_pcie_cap(parent); - pci_read_config_byte(parent, pos + PCI_EXP_LNKCTL, &aspm); + pcie_capability_read_word(parent, PCI_EXP_LNKCTL, &aspm); if (aspm & (PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1)) { ah->aspm_enabled = true; /* Initialize PCIe PM and SERDES registers. */ @@ -321,6 +314,7 @@ static int ath_pci_suspend(struct device *device) * Otherwise the chip never moved to full sleep, * when no interface is up. */ + ath9k_stop_btcoex(sc); ath9k_hw_disable(sc->sc_ah); ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c index 4b12c347d18..27ed80b5488 100644 --- a/drivers/net/wireless/ath/ath9k/rc.c +++ b/drivers/net/wireless/ath/ath9k/rc.c @@ -1222,11 +1222,14 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta) caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG; else if (sta->ht_cap.mcs.rx_mask[1]) caps |= WLAN_RC_DS_FLAG; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) + if (sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) { caps |= WLAN_RC_40_FLAG; - if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40 || - sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) - caps |= WLAN_RC_SGI_FLAG; + if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) + caps |= WLAN_RC_SGI_FLAG; + } else { + if (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) + caps |= WLAN_RC_SGI_FLAG; + } } return caps; diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 12aca02228c..83d16e7ed27 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c @@ -424,8 +424,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc) rfilt |= ATH9K_RX_FILTER_COMP_BAR; if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { - /* The following may also be needed for other older chips */ - if (sc->sc_ah->hw_version.macVersion == AR_SREV_VERSION_9160) + /* This is needed for older chips */ + if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL; } @@ -1044,7 +1044,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) struct ieee80211_hw *hw = sc->hw; struct ieee80211_hdr *hdr; int retval; - bool decrypt_error = false; struct ath_rx_status rs; enum ath9k_rx_qtype qtype; bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); @@ -1066,6 +1065,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) tsf_lower = tsf & 0xffffffff; do { + bool decrypt_error = false; /* If handling rx interrupt and flush is in progress => exit */ if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) break; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 87cac8eb783..4e6760f8596 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -801,6 +801,8 @@ #define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ #define AR_SREV_VERSION_9462 0x280 #define AR_SREV_REVISION_9462_20 2 +#define AR_SREV_VERSION_9565 0x2C0 +#define AR_SREV_REVISION_9565_10 0 #define AR_SREV_VERSION_9550 0x400 #define AR_SREV_5416(_ah) \ @@ -909,6 +911,13 @@ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20)) +#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_9550(_ah) \ (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9550)) diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c index 44a08eb53c6..a483d518758 100644 --- a/drivers/net/wireless/ath/ath9k/wow.c +++ b/drivers/net/wireless/ath/ath9k/wow.c @@ -497,7 +497,7 @@ void ath9k_hw_wow_enable(struct ath_hw *ah, u32 pattern_enable) REG_RMW(ah, AR_PCIE_PM_CTRL, set, clr); - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { /* * this is needed to prevent the chip waking up * the host within 3-4 seconds with certain diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index ef91f6cc2d7..36618e3a5e6 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c @@ -568,7 +568,7 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq, if (!an->sleeping) { ath_tx_queue_tid(txq, tid); - if (ts->ts_status & ATH9K_TXERR_FILT) + if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY)) tid->ac->clear_ps_filter = true; } } @@ -1820,10 +1820,14 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate) { struct ath_hw *ah = sc->sc_ah; struct ath9k_channel *curchan = ah->curchan; + if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (curchan->channelFlags & CHANNEL_5GHZ) && (chainmask == 0x7) && (rate < 0x90)) return 0x3; + else if (AR_SREV_9462(ah) && ath9k_hw_btcoex_is_enabled(ah) && + IS_CCK_RATE(rate)) + return 0x2; else return chainmask; } @@ -2019,6 +2023,9 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb, ath_dbg(common, XMIT, "TX complete: skb: %p\n", skb); + if (sc->sc_ah->caldata) + sc->sc_ah->caldata->paprd_packet_sent = true; + if (!(tx_flags & ATH_TX_ERROR)) /* Frame was ACKed */ tx_info->flags |= IEEE80211_TX_STAT_ACK; diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h index 8f0cbc35816..2aa4a59c72c 100644 --- a/drivers/net/wireless/ath/carl9170/carl9170.h +++ b/drivers/net/wireless/ath/carl9170/carl9170.h @@ -425,6 +425,7 @@ struct ar9170 { bool rx_has_plcp; struct sk_buff *rx_failover; int rx_failover_missing; + u32 ampdu_ref; /* FIFO for collecting outstanding BlockAckRequest */ struct list_head bar_list[__AR9170_NUM_TXQ]; diff --git a/drivers/net/wireless/ath/carl9170/mac.c b/drivers/net/wireless/ath/carl9170/mac.c index f8676280dc3..e3b1b6e8776 100644 --- a/drivers/net/wireless/ath/carl9170/mac.c +++ b/drivers/net/wireless/ath/carl9170/mac.c @@ -304,7 +304,8 @@ int carl9170_set_operating_mode(struct ar9170 *ar) struct ath_common *common = &ar->common; u8 *mac_addr, *bssid; u32 cam_mode = AR9170_MAC_CAM_DEFAULTS; - u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS; + u32 enc_mode = AR9170_MAC_ENCRYPTION_DEFAULTS | + AR9170_MAC_ENCRYPTION_MGMT_RX_SOFTWARE; u32 rx_ctrl = AR9170_MAC_RX_CTRL_DEAGG | AR9170_MAC_RX_CTRL_SHORT_FILTER; u32 sniffer = AR9170_MAC_SNIFFER_DEFAULTS; diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index 18554ab7673..67997b39aba 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c @@ -1149,6 +1149,7 @@ static int carl9170_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, break; case WLAN_CIPHER_SUITE_CCMP: ktype = AR9170_ENC_ALG_AESCCMP; + key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; break; default: return -EOPNOTSUPP; @@ -1780,6 +1781,7 @@ void *carl9170_alloc(size_t priv_size) hw->wiphy->interface_modes = 0; hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | + IEEE80211_HW_MFP_CAPABLE | IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK | diff --git a/drivers/net/wireless/ath/carl9170/rx.c b/drivers/net/wireless/ath/carl9170/rx.c index b813f43061f..a0b72307854 100644 --- a/drivers/net/wireless/ath/carl9170/rx.c +++ b/drivers/net/wireless/ath/carl9170/rx.c @@ -624,7 +624,8 @@ static void carl9170_ba_check(struct ar9170 *ar, void *data, unsigned int len) #undef TID_CHECK } -static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms) +static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms, + struct ieee80211_rx_status *rx_status) { __le16 fc; @@ -637,6 +638,9 @@ static bool carl9170_ampdu_check(struct ar9170 *ar, u8 *buf, u8 ms) return true; } + rx_status->flag |= RX_FLAG_AMPDU_DETAILS | RX_FLAG_AMPDU_LAST_KNOWN; + rx_status->ampdu_reference = ar->ampdu_ref; + /* * "802.11n - 7.4a.3 A-MPDU contents" describes in which contexts * certain frame types can be part of an aMPDU. @@ -685,12 +689,15 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (unlikely(len < sizeof(*mac))) goto drop; + memset(&status, 0, sizeof(status)); + mpdu_len = len - sizeof(*mac); mac = (void *)(buf + mpdu_len); mac_status = mac->status; switch (mac_status & AR9170_RX_STATUS_MPDU) { case AR9170_RX_STATUS_MPDU_FIRST: + ar->ampdu_ref++; /* Aggregated MPDUs start with an PLCP header */ if (likely(mpdu_len >= sizeof(struct ar9170_rx_head))) { head = (void *) buf; @@ -721,12 +728,13 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) break; case AR9170_RX_STATUS_MPDU_LAST: + status.flag |= RX_FLAG_AMPDU_IS_LAST; + /* * The last frame of an A-MPDU has an extra tail * which does contain the phy status of the whole * aggregate. */ - if (likely(mpdu_len >= sizeof(struct ar9170_rx_phystatus))) { mpdu_len -= sizeof(struct ar9170_rx_phystatus); phy = (void *)(buf + mpdu_len); @@ -774,11 +782,10 @@ static void carl9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len) if (unlikely(mpdu_len < (2 + 2 + ETH_ALEN + FCS_LEN))) goto drop; - memset(&status, 0, sizeof(status)); if (unlikely(carl9170_rx_mac_status(ar, head, mac, &status))) goto drop; - if (!carl9170_ampdu_check(ar, buf, mac_status)) + if (!carl9170_ampdu_check(ar, buf, mac_status, &status)) goto drop; if (phy) |