diff --git a/package/mac80211/Makefile b/package/mac80211/Makefile index d5e5ef8ddf..c7078bc451 100644 --- a/package/mac80211/Makefile +++ b/package/mac80211/Makefile @@ -10,12 +10,12 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=2010-06-10 +PKG_VERSION:=2010-06-15 PKG_RELEASE:=1 PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources # http://www.orbit-lab.org/kernel/compat-wireless-2.6/2010/11 \ # http://wireless.kernel.org/download/compat-wireless-2.6 -PKG_MD5SUM:=4074469689f7a5a0d2e038f2b5dad0bb +PKG_MD5SUM:=7d18106ca78213bf9ce27406cd79458c PKG_SOURCE:=compat-wireless-$(PKG_VERSION).tar.bz2 PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION) diff --git a/package/mac80211/patches/170-dma_set_coherent_mask.patch b/package/mac80211/patches/170-dma_set_coherent_mask.patch deleted file mode 100644 index 9bafbeb87e..0000000000 --- a/package/mac80211/patches/170-dma_set_coherent_mask.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 3c02b107ec11e14ef21e7a444ad83f0ef1e68f79 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sun, 13 Jun 2010 20:41:55 +0200 -Subject: [PATCH 1/2] compat: backport dma_set_coherent_mask - - -Signed-off-by: Hauke Mehrtens ---- - include/linux/compat-2.6.34.h | 8 ++++++++ - 1 files changed, 8 insertions(+), 0 deletions(-) - ---- a/include/linux/compat-2.6.34.h -+++ b/include/linux/compat-2.6.34.h -@@ -216,6 +216,14 @@ do { \ - #define dma_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) - #endif - -+static inline int dma_set_coherent_mask(struct device *dev, u64 mask) -+{ -+ if (!dma_supported(dev, mask)) -+ return -EIO; -+ dev->coherent_dma_mask = mask; -+ return 0; -+} -+ - #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,34)) */ - - #endif /* LINUX_26_34_COMPAT_H */ diff --git a/package/mac80211/patches/405-ath9k-read-eeprom-data-from-platform-data-on-pci-bus.patch b/package/mac80211/patches/405-ath9k-read-eeprom-data-from-platform-data-on-pci-bus.patch index 560f8d42de..bbf46a0d22 100644 --- a/package/mac80211/patches/405-ath9k-read-eeprom-data-from-platform-data-on-pci-bus.patch +++ b/package/mac80211/patches/405-ath9k-read-eeprom-data-from-platform-data-on-pci-bus.patch @@ -8,7 +8,7 @@ #include "ath9k.h" static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = { -@@ -52,21 +53,36 @@ static void ath_pci_read_cachesize(struc +@@ -53,21 +54,36 @@ static void ath_pci_read_cachesize(struc static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) { diff --git a/package/mac80211/patches/406-ath9k-set-AH_USE_EEPROM-only-if-no-platform-data-present.patch b/package/mac80211/patches/406-ath9k-set-AH_USE_EEPROM-only-if-no-platform-data-present.patch index 72d3701dc5..0a0c2efb9f 100644 --- a/package/mac80211/patches/406-ath9k-set-AH_USE_EEPROM-only-if-no-platform-data-present.patch +++ b/package/mac80211/patches/406-ath9k-set-AH_USE_EEPROM-only-if-no-platform-data-present.patch @@ -10,7 +10,7 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -556,6 +556,7 @@ static int ath9k_init_softc(u16 devid, s +@@ -534,6 +534,7 @@ static int ath9k_init_softc(u16 devid, s { struct ath_hw *ah = NULL; struct ath_common *common; @@ -18,7 +18,7 @@ int ret = 0, i; int csz = 0; -@@ -567,6 +568,10 @@ static int ath9k_init_softc(u16 devid, s +@@ -545,6 +546,10 @@ static int ath9k_init_softc(u16 devid, s ah->hw_version.subsysid = subsysid; sc->sc_ah = ah; @@ -31,7 +31,7 @@ common->bus_ops = bus_ops; --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -423,10 +423,6 @@ static void ath9k_hw_init_defaults(struc +@@ -421,10 +421,6 @@ static void ath9k_hw_init_defaults(struc ah->hw_version.magic = AR5416_MAGIC; ah->hw_version.subvendorid = 0; @@ -40,5 +40,5 @@ - ah->ah_flags = AH_USE_EEPROM; - ah->atim_window = 0; - ah->sta_id1_defaults = AR_STA_ID1_CRPT_MIC_ENABLE; - ah->beacon_interval = 100; + ah->sta_id1_defaults = + AR_STA_ID1_CRPT_MIC_ENABLE | diff --git a/package/mac80211/patches/408-ath9k_tweak_rx_intr_mitigation.patch b/package/mac80211/patches/408-ath9k_tweak_rx_intr_mitigation.patch index 180368a1f4..7b40230c0a 100644 --- a/package/mac80211/patches/408-ath9k_tweak_rx_intr_mitigation.patch +++ b/package/mac80211/patches/408-ath9k_tweak_rx_intr_mitigation.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1398,7 +1398,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st +@@ -1401,7 +1401,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st if (ah->config.rx_intr_mitigation) { REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500); diff --git a/package/mac80211/patches/409-ath9k-add-wndr3700-antenna-initialization.patch b/package/mac80211/patches/409-ath9k-add-wndr3700-antenna-initialization.patch index 1cdd45e4ef..bef3b2dae3 100644 --- a/package/mac80211/patches/409-ath9k-add-wndr3700-antenna-initialization.patch +++ b/package/mac80211/patches/409-ath9k-add-wndr3700-antenna-initialization.patch @@ -8,7 +8,7 @@ #include "ath9k.h" static char *dev_info = "ath9k"; -@@ -571,6 +572,8 @@ static int ath9k_init_softc(u16 devid, s +@@ -549,6 +550,8 @@ static int ath9k_init_softc(u16 devid, s pdata = (struct ath9k_platform_data *) sc->dev->platform_data; if (!pdata) ah->ah_flags |= AH_USE_EEPROM; @@ -17,7 +17,7 @@ common = ath9k_hw_common(ah); common->ops = &ath9k_common_ops; -@@ -693,6 +696,24 @@ void ath9k_set_hw_capab(struct ath_softc +@@ -671,6 +674,24 @@ void ath9k_set_hw_capab(struct ath_softc SET_IEEE80211_PERM_ADDR(hw, common->macaddr); } @@ -42,7 +42,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { -@@ -711,6 +732,9 @@ int ath9k_init_device(u16 devid, struct +@@ -689,6 +710,9 @@ int ath9k_init_device(u16 devid, struct common = ath9k_hw_common(ah); ath9k_set_hw_capab(sc, hw); @@ -54,7 +54,7 @@ ath9k_reg_notifier); --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -583,6 +583,8 @@ struct ath_softc { +@@ -591,6 +591,8 @@ struct ath_softc { int beacon_interval; diff --git a/package/mac80211/patches/410-ath9k-wndr3700-led-pin-fix.patch b/package/mac80211/patches/410-ath9k-wndr3700-led-pin-fix.patch index eb1d316b58..7d6bd4f74c 100644 --- a/package/mac80211/patches/410-ath9k-wndr3700-led-pin-fix.patch +++ b/package/mac80211/patches/410-ath9k-wndr3700-led-pin-fix.patch @@ -13,7 +13,7 @@ sc->sc_ah->led_pin = ATH_LED_PIN_DEF; --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -458,6 +458,7 @@ void ath9k_btcoex_timer_pause(struct ath +@@ -463,6 +463,7 @@ void ath9k_btcoex_timer_pause(struct ath #define ATH_LED_PIN_DEF 1 #define ATH_LED_PIN_9287 8 diff --git a/package/mac80211/patches/500-ath9k_use_minstrel.patch b/package/mac80211/patches/500-ath9k_use_minstrel.patch index 8669c8c048..0983abf335 100644 --- a/package/mac80211/patches/500-ath9k_use_minstrel.patch +++ b/package/mac80211/patches/500-ath9k_use_minstrel.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -677,7 +677,11 @@ void ath9k_set_hw_capab(struct ath_softc +@@ -655,7 +655,11 @@ void ath9k_set_hw_capab(struct ath_softc hw->sta_data_size = sizeof(struct ath_node); hw->vif_data_size = sizeof(struct ath_vif); diff --git a/package/mac80211/patches/510-ath9k_fix_ampdu_retry_count.patch b/package/mac80211/patches/510-ath9k_fix_ampdu_retry_count.patch new file mode 100644 index 0000000000..8e6e6d0ad3 --- /dev/null +++ b/package/mac80211/patches/510-ath9k_fix_ampdu_retry_count.patch @@ -0,0 +1,62 @@ +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -328,6 +328,7 @@ static void ath_tx_complete_aggr(struct + u32 ba[WME_BA_BMP_SIZE >> 5]; + int isaggr, txfail, txpending, sendbar = 0, needreset = 0, nbad = 0; + bool rc_update = true; ++ struct ieee80211_tx_rate rates[4]; + + skb = bf->bf_mpdu; + hdr = (struct ieee80211_hdr *)skb->data; +@@ -335,6 +336,8 @@ static void ath_tx_complete_aggr(struct + tx_info = IEEE80211_SKB_CB(skb); + hw = bf->aphy->hw; + ++ memcpy(rates, tx_info->control.rates, sizeof(rates)); ++ + rcu_read_lock(); + + /* XXX: use ieee80211_find_sta! */ +@@ -375,6 +378,9 @@ static void ath_tx_complete_aggr(struct + txfail = txpending = 0; + bf_next = bf->bf_next; + ++ skb = bf->bf_mpdu; ++ tx_info = IEEE80211_SKB_CB(skb); ++ + if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) { + /* transmit completion, subframe is + * acked by block ack */ +@@ -428,6 +434,7 @@ static void ath_tx_complete_aggr(struct + spin_unlock_bh(&txq->axq_lock); + + if (rc_update && (acked_cnt == 1 || txfail_cnt == 1)) { ++ memcpy(tx_info->control.rates, rates, sizeof(rates)); + ath_tx_rc_status(bf, ts, nbad, txok, true); + rc_update = false; + } else { +@@ -2014,7 +2021,7 @@ static void ath_tx_rc_status(struct ath_ + tx_info->status.rates[i].idx = -1; + } + +- tx_info->status.rates[tx_rateindex].count = bf->bf_retries + 1; ++ tx_info->status.rates[tx_rateindex].count = ts->ts_longretry + 1; + } + + static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq) +@@ -2125,7 +2132,6 @@ static void ath_tx_processq(struct ath_s + * This frame is sent out as a single frame. + * Use hardware retry status for this frame. + */ +- bf->bf_retries = ts.ts_longretry; + if (ts.ts_status & ATH9K_TXERR_XRETRY) + bf->bf_state.bf_type |= BUF_XRETRY; + ath_tx_rc_status(bf, &ts, 0, txok, true); +@@ -2255,7 +2261,6 @@ void ath_tx_edma_tasklet(struct ath_soft + } + + if (!bf_isampdu(bf)) { +- bf->bf_retries = txs.ts_longretry; + if (txs.ts_status & ATH9K_TXERR_XRETRY) + bf->bf_state.bf_type |= BUF_XRETRY; + ath_tx_rc_status(bf, &txs, 0, txok, true); diff --git a/package/mac80211/patches/510-pending_work.patch b/package/mac80211/patches/510-pending_work.patch deleted file mode 100644 index d52eaa4446..0000000000 --- a/package/mac80211/patches/510-pending_work.patch +++ /dev/null @@ -1,1893 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/Makefile -+++ b/drivers/net/wireless/ath/ath9k/Makefile -@@ -32,7 +32,8 @@ ath9k_hw-y:= \ - mac.o \ - ar9002_mac.o \ - ar9003_mac.o \ -- ar9003_eeprom.o -+ ar9003_eeprom.o \ -+ ar9003_paprd.o - - obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o - ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c -@@ -67,6 +67,7 @@ static const struct ar9300_eeprom ar9300 - * bit2 - enable fastClock - enabled - * bit3 - enable doubling - enabled - * bit4 - enable internal regulator - disabled -+ * bit5 - enable pa predistortion - disabled - */ - .miscConfiguration = 0, /* bit0 - turn down drivestrength */ - .eepromWriteEnableGpio = 3, -@@ -129,9 +130,11 @@ static const struct ar9300_eeprom ar9300 - .txEndToRxOn = 0x2, - .txFrameToXpaOn = 0xe, - .thresh62 = 28, -- .futureModal = { /* [32] */ -+ .papdRateMaskHt20 = LE32(0x80c080), -+ .papdRateMaskHt40 = LE32(0x80c080), -+ .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0 - }, - }, - .calFreqPier2G = { -@@ -326,9 +329,11 @@ static const struct ar9300_eeprom ar9300 - .txEndToRxOn = 0x2, - .txFrameToXpaOn = 0xe, - .thresh62 = 28, -+ .papdRateMaskHt20 = LE32(0xf0e0e0), -+ .papdRateMaskHt40 = LE32(0xf0e0e0), - .futureModal = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -+ 0, 0, 0, 0, 0, 0, 0, 0 - }, - }, - .calFreqPier5G = { -@@ -644,6 +649,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(st - return (pBase->featureEnable & 0x10) >> 4; - case EEP_SWREG: - return le32_to_cpu(pBase->swreg); -+ case EEP_PAPRD: -+ return !!(pBase->featureEnable & BIT(5)); - default: - return 0; - } ---- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h -@@ -234,7 +234,9 @@ struct ar9300_modal_eep_header { - u8 txEndToRxOn; - u8 txFrameToXpaOn; - u8 thresh62; -- u8 futureModal[32]; -+ __le32 papdRateMaskHt20; -+ __le32 papdRateMaskHt40; -+ u8 futureModal[24]; - } __packed; - - struct ar9300_cal_data_per_freq_op_loop { ---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c -+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c -@@ -470,6 +470,14 @@ static void ar9003_hw_set11n_virtualmore - ads->ctl11 &= ~AR_VirtMoreFrag; - } - -+void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains) -+{ -+ struct ar9003_txc *ads = ds; -+ -+ ads->ctl12 |= SM(chains, AR_PAPRDChainMask); -+} -+EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc); -+ - void ar9003_hw_attach_mac_ops(struct ath_hw *hw) - { - struct ath_hw_ops *ops = ath9k_hw_ops(hw); ---- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h -@@ -40,6 +40,10 @@ - - #define AR_Not_Sounding 0x20000000 - -+/* ctl 12 */ -+#define AR_PAPRDChainMask 0x00000e00 -+#define AR_PAPRDChainMask_S 9 -+ - #define MAP_ISR_S2_CST 6 - #define MAP_ISR_S2_GTT 6 - #define MAP_ISR_S2_TIM 3 ---- /dev/null -+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c -@@ -0,0 +1,713 @@ -+/* -+ * Copyright (c) 2010 Atheros Communications Inc. -+ * -+ * Permission to use, copy, modify, and/or distribute this software for any -+ * purpose with or without fee is hereby granted, provided that the above -+ * copyright notice and this permission notice appear in all copies. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -+ */ -+ -+#include "hw.h" -+#include "ar9003_phy.h" -+ -+void ar9003_paprd_enable(struct ath_hw *ah, bool val) -+{ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0, -+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1, -+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2, -+ AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val); -+} -+EXPORT_SYMBOL(ar9003_paprd_enable); -+ -+static void ar9003_paprd_setup_single_table(struct ath_hw *ah) -+{ -+ struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep; -+ struct ar9300_modal_eep_header *hdr; -+ const u32 ctrl0[3] = { -+ AR_PHY_PAPRD_CTRL0_B0, -+ AR_PHY_PAPRD_CTRL0_B1, -+ AR_PHY_PAPRD_CTRL0_B2 -+ }; -+ const u32 ctrl1[3] = { -+ AR_PHY_PAPRD_CTRL1_B0, -+ AR_PHY_PAPRD_CTRL1_B1, -+ AR_PHY_PAPRD_CTRL1_B2 -+ }; -+ u32 am_mask, ht40_mask; -+ int i; -+ -+ if (ah->curchan && IS_CHAN_5GHZ(ah->curchan)) -+ hdr = &eep->modalHeader5G; -+ else -+ hdr = &eep->modalHeader2G; -+ -+ am_mask = le32_to_cpu(hdr->papdRateMaskHt20); -+ ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask); -+ -+ for (i = 0; i < 3; i++) { -+ REG_RMW_FIELD(ah, ctrl0[i], -+ AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE, 1); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE, 1); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK, 181); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT, 361); -+ REG_RMW_FIELD(ah, ctrl1[i], -+ AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0); -+ REG_RMW_FIELD(ah, ctrl0[i], -+ AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH, 3); -+ } -+ -+ ar9003_paprd_enable(ah, false); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1, -+ AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2, -+ AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE, -+ -15); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3, -+ AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, -+ AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, -+ AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4, -+ AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES, -+ 100); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 261376); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 248079); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 233759); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 220464); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 208194); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 196949); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 185706); -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0, -+ AR_PHY_PAPRD_PRE_POST_SCALING, 175487); -+} -+ -+static void ar9003_paprd_get_gain_table(struct ath_hw *ah) -+{ -+ u32 *entry = ah->paprd_gain_table_entries; -+ u8 *index = ah->paprd_gain_table_index; -+ u32 reg = AR_PHY_TXGAIN_TABLE; -+ int i; -+ -+ memset(entry, 0, sizeof(ah->paprd_gain_table_entries)); -+ memset(index, 0, sizeof(ah->paprd_gain_table_index)); -+ -+ for (i = 0; i < 32; i++) { -+ entry[i] = REG_READ(ah, reg); -+ index[i] = (entry[i] >> 24) & 0xff; -+ reg += 4; -+ } -+} -+ -+static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain, -+ int target_power) -+{ -+ int olpc_gain_delta = 0; -+ int alpha_therm, alpha_volt; -+ int therm_cal_value, volt_cal_value; -+ int therm_value, volt_value; -+ int thermal_gain_corr, voltage_gain_corr; -+ int desired_scale, desired_gain = 0; -+ u32 reg; -+ -+ REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+ desired_scale = REG_READ_FIELD(ah, AR_PHY_TPC_12, -+ AR_PHY_TPC_12_DESIRED_SCALE_HT40_5); -+ alpha_therm = REG_READ_FIELD(ah, AR_PHY_TPC_19, -+ AR_PHY_TPC_19_ALPHA_THERM); -+ alpha_volt = REG_READ_FIELD(ah, AR_PHY_TPC_19, -+ AR_PHY_TPC_19_ALPHA_VOLT); -+ therm_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18, -+ AR_PHY_TPC_18_THERM_CAL_VALUE); -+ volt_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18, -+ AR_PHY_TPC_18_VOLT_CAL_VALUE); -+ therm_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, -+ AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE); -+ volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4, -+ AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE); -+ -+ if (chain == 0) -+ reg = AR_PHY_TPC_11_B0; -+ else if (chain == 1) -+ reg = AR_PHY_TPC_11_B1; -+ else -+ reg = AR_PHY_TPC_11_B2; -+ -+ olpc_gain_delta = REG_READ_FIELD(ah, reg, -+ AR_PHY_TPC_11_OLPC_GAIN_DELTA); -+ -+ if (olpc_gain_delta >= 128) -+ olpc_gain_delta = olpc_gain_delta - 256; -+ -+ thermal_gain_corr = (alpha_therm * (therm_value - therm_cal_value) + -+ (256 / 2)) / 256; -+ voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) + -+ (128 / 2)) / 128; -+ desired_gain = target_power - olpc_gain_delta - thermal_gain_corr - -+ voltage_gain_corr + desired_scale; -+ -+ return desired_gain; -+} -+ -+static void ar9003_tx_force_gain(struct ath_hw *ah, unsigned int gain_index) -+{ -+ int selected_gain_entry, txbb1dbgain, txbb6dbgain, txmxrgain; -+ int padrvgnA, padrvgnB, padrvgnC, padrvgnD; -+ u32 *gain_table_entries = ah->paprd_gain_table_entries; -+ -+ selected_gain_entry = gain_table_entries[gain_index]; -+ txbb1dbgain = selected_gain_entry & 0x7; -+ txbb6dbgain = (selected_gain_entry >> 3) & 0x3; -+ txmxrgain = (selected_gain_entry >> 5) & 0xf; -+ padrvgnA = (selected_gain_entry >> 9) & 0xf; -+ padrvgnB = (selected_gain_entry >> 13) & 0xf; -+ padrvgnC = (selected_gain_entry >> 17) & 0xf; -+ padrvgnD = (selected_gain_entry >> 21) & 0x3; -+ -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN, txbb1dbgain); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN, txbb6dbgain); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN, txmxrgain); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA, padrvgnA); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB, padrvgnB); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC, padrvgnC); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND, padrvgnD); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL, 0); -+ REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN, -+ AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN, 0); -+ REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0); -+ REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN, 0); -+} -+ -+static inline int find_expn(int num) -+{ -+ return fls(num) - 1; -+} -+ -+static inline int find_proper_scale(int expn, int N) -+{ -+ return (expn > N) ? expn - 10 : 0; -+} -+ -+#define NUM_BIN 23 -+ -+static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain) -+{ -+ unsigned int thresh_accum_cnt; -+ int x_est[NUM_BIN + 1], Y[NUM_BIN + 1], theta[NUM_BIN + 1]; -+ int PA_in[NUM_BIN + 1]; -+ int B1_tmp[NUM_BIN + 1], B2_tmp[NUM_BIN + 1]; -+ unsigned int B1_abs_max, B2_abs_max; -+ int max_index, scale_factor; -+ int y_est[NUM_BIN + 1]; -+ int x_est_fxp1_nonlin, x_tilde[NUM_BIN + 1]; -+ unsigned int x_tilde_abs; -+ int G_fxp, Y_intercept, order_x_by_y, M, I, L, sum_y_sqr, sum_y_quad; -+ int Q_x, Q_B1, Q_B2, beta_raw, alpha_raw, scale_B; -+ int Q_scale_B, Q_beta, Q_alpha, alpha, beta, order_1, order_2; -+ int order1_5x, order2_3x, order1_5x_rem, order2_3x_rem; -+ int y5, y3, tmp; -+ int theta_low_bin = 0; -+ int i; -+ -+ /* disregard any bin that contains <= 16 samples */ -+ thresh_accum_cnt = 16; -+ scale_factor = 5; -+ max_index = 0; -+ memset(theta, 0, sizeof(theta)); -+ memset(x_est, 0, sizeof(x_est)); -+ memset(Y, 0, sizeof(Y)); -+ memset(y_est, 0, sizeof(y_est)); -+ memset(x_tilde, 0, sizeof(x_tilde)); -+ -+ for (i = 0; i < NUM_BIN; i++) { -+ s32 accum_cnt, accum_tx, accum_rx, accum_ang; -+ -+ /* number of samples */ -+ accum_cnt = data_L[i] & 0xffff; -+ -+ if (accum_cnt <= thresh_accum_cnt) -+ continue; -+ -+ /* sum(tx amplitude) */ -+ accum_tx = ((data_L[i] >> 16) & 0xffff) | -+ ((data_U[i] & 0x7ff) << 16); -+ -+ /* sum(rx amplitude distance to lower bin edge) */ -+ accum_rx = ((data_U[i] >> 11) & 0x1f) | -+ ((data_L[i + 23] & 0xffff) << 5); -+ -+ /* sum(angles) */ -+ accum_ang = ((data_L[i + 23] >> 16) & 0xffff) | -+ ((data_U[i + 23] & 0x7ff) << 16); -+ -+ accum_tx <<= scale_factor; -+ accum_rx <<= scale_factor; -+ x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >> -+ scale_factor; -+ -+ Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >> -+ scale_factor) + (1 << scale_factor) * max_index + 16; -+ -+ if (accum_ang >= (1 << 26)) -+ accum_ang -= 1 << 27; -+ -+ theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) / -+ accum_cnt; -+ -+ max_index++; -+ } -+ -+ /* -+ * Find average theta of first 5 bin and all of those to same value. -+ * Curve is linear at that range. -+ */ -+ for (i = 1; i < 6; i++) -+ theta_low_bin += theta[i]; -+ -+ theta_low_bin = theta_low_bin / 5; -+ for (i = 1; i < 6; i++) -+ theta[i] = theta_low_bin; -+ -+ /* Set values at origin */ -+ theta[0] = theta_low_bin; -+ for (i = 0; i <= max_index; i++) -+ theta[i] -= theta_low_bin; -+ -+ x_est[0] = 0; -+ Y[0] = 0; -+ scale_factor = 8; -+ -+ /* low signal gain */ -+ if (x_est[6] == x_est[3]) -+ return false; -+ -+ G_fxp = -+ (((Y[6] - Y[3]) * 1 << scale_factor) + -+ (x_est[6] - x_est[3])) / (x_est[6] - x_est[3]); -+ -+ Y_intercept = -+ (G_fxp * (x_est[0] - x_est[3]) + -+ (1 << scale_factor)) / (1 << scale_factor) + Y[3]; -+ -+ for (i = 0; i <= max_index; i++) -+ y_est[i] = Y[i] - Y_intercept; -+ -+ for (i = 0; i <= 3; i++) { -+ y_est[i] = i * 32; -+ -+ /* prevent division by zero */ -+ if (G_fxp == 0) -+ return false; -+ -+ x_est[i] = ((y_est[i] * 1 << scale_factor) + G_fxp) / G_fxp; -+ } -+ -+ x_est_fxp1_nonlin = -+ x_est[max_index] - ((1 << scale_factor) * y_est[max_index] + -+ G_fxp) / G_fxp; -+ -+ order_x_by_y = -+ (x_est_fxp1_nonlin + y_est[max_index]) / y_est[max_index]; -+ -+ if (order_x_by_y == 0) -+ M = 10; -+ else if (order_x_by_y == 1) -+ M = 9; -+ else -+ M = 8; -+ -+ I = (max_index > 15) ? 7 : max_index >> 1; -+ L = max_index - I; -+ scale_factor = 8; -+ sum_y_sqr = 0; -+ sum_y_quad = 0; -+ x_tilde_abs = 0; -+ -+ for (i = 0; i <= L; i++) { -+ unsigned int y_sqr; -+ unsigned int y_quad; -+ unsigned int tmp_abs; -+ -+ /* prevent division by zero */ -+ if (y_est[i + I] == 0) -+ return false; -+ -+ x_est_fxp1_nonlin = -+ x_est[i + I] - ((1 << scale_factor) * y_est[i + I] + -+ G_fxp) / G_fxp; -+ -+ x_tilde[i] = -+ (x_est_fxp1_nonlin * (1 << M) + y_est[i + I]) / y_est[i + -+ I]; -+ x_tilde[i] = -+ (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I]; -+ x_tilde[i] = -+ (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I]; -+ y_sqr = -+ (y_est[i + I] * y_est[i + I] + -+ (scale_factor * scale_factor)) / (scale_factor * -+ scale_factor); -+ tmp_abs = abs(x_tilde[i]); -+ if (tmp_abs > x_tilde_abs) -+ x_tilde_abs = tmp_abs; -+ -+ y_quad = y_sqr * y_sqr; -+ sum_y_sqr = sum_y_sqr + y_sqr; -+ sum_y_quad = sum_y_quad + y_quad; -+ B1_tmp[i] = y_sqr * (L + 1); -+ B2_tmp[i] = y_sqr; -+ } -+ -+ B1_abs_max = 0; -+ B2_abs_max = 0; -+ for (i = 0; i <= L; i++) { -+ int abs_val; -+ -+ B1_tmp[i] -= sum_y_sqr; -+ B2_tmp[i] = sum_y_quad - sum_y_sqr * B2_tmp[i]; -+ -+ abs_val = abs(B1_tmp[i]); -+ if (abs_val > B1_abs_max) -+ B1_abs_max = abs_val; -+ -+ abs_val = abs(B2_tmp[i]); -+ if (abs_val > B2_abs_max) -+ B2_abs_max = abs_val; -+ } -+ -+ Q_x = find_proper_scale(find_expn(x_tilde_abs), 10); -+ Q_B1 = find_proper_scale(find_expn(B1_abs_max), 10); -+ Q_B2 = find_proper_scale(find_expn(B2_abs_max), 10); -+ -+ beta_raw = 0; -+ alpha_raw = 0; -+ for (i = 0; i <= L; i++) { -+ x_tilde[i] = x_tilde[i] / (1 << Q_x); -+ B1_tmp[i] = B1_tmp[i] / (1 << Q_B1); -+ B2_tmp[i] = B2_tmp[i] / (1 << Q_B2); -+ beta_raw = beta_raw + B1_tmp[i] * x_tilde[i]; -+ alpha_raw = alpha_raw + B2_tmp[i] * x_tilde[i]; -+ } -+ -+ scale_B = -+ ((sum_y_quad / scale_factor) * (L + 1) - -+ (sum_y_sqr / scale_factor) * sum_y_sqr) * scale_factor; -+ -+ Q_scale_B = find_proper_scale(find_expn(abs(scale_B)), 10); -+ scale_B = scale_B / (1 << Q_scale_B); -+ Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10); -+ Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10); -+ beta_raw = beta_raw / (1 << Q_beta); -+ alpha_raw = alpha_raw / (1 << Q_alpha); -+ alpha = (alpha_raw << 10) / scale_B; -+ beta = (beta_raw << 10) / scale_B; -+ order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B; -+ order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B; -+ order1_5x = order_1 / 5; -+ order2_3x = order_2 / 3; -+ order1_5x_rem = order_1 - 5 * order1_5x; -+ order2_3x_rem = order_2 - 3 * order2_3x; -+ -+ for (i = 0; i < PAPRD_TABLE_SZ; i++) { -+ tmp = i * 32; -+ y5 = ((beta * tmp) >> 6) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = (y5 * tmp) >> order1_5x; -+ y5 = y5 >> order1_5x_rem; -+ y3 = (alpha * tmp) >> order2_3x; -+ y3 = (y3 * tmp) >> order2_3x; -+ y3 = (y3 * tmp) >> order2_3x; -+ y3 = y3 >> order2_3x_rem; -+ PA_in[i] = y5 + y3 + (256 * tmp) / G_fxp; -+ -+ if (i >= 2) { -+ tmp = PA_in[i] - PA_in[i - 1]; -+ if (tmp < 0) -+ PA_in[i] = -+ PA_in[i - 1] + (PA_in[i - 1] - -+ PA_in[i - 2]); -+ } -+ -+ PA_in[i] = (PA_in[i] < 1400) ? PA_in[i] : 1400; -+ } -+ -+ beta_raw = 0; -+ alpha_raw = 0; -+ -+ for (i = 0; i <= L; i++) { -+ int theta_tilde = -+ ((theta[i + I] << M) + y_est[i + I]) / y_est[i + I]; -+ theta_tilde = -+ ((theta_tilde << M) + y_est[i + I]) / y_est[i + I]; -+ theta_tilde = -+ ((theta_tilde << M) + y_est[i + I]) / y_est[i + I]; -+ beta_raw = beta_raw + B1_tmp[i] * theta_tilde; -+ alpha_raw = alpha_raw + B2_tmp[i] * theta_tilde; -+ } -+ -+ Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10); -+ Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10); -+ beta_raw = beta_raw / (1 << Q_beta); -+ alpha_raw = alpha_raw / (1 << Q_alpha); -+ -+ alpha = (alpha_raw << 10) / scale_B; -+ beta = (beta_raw << 10) / scale_B; -+ order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B + 5; -+ order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B + 5; -+ order1_5x = order_1 / 5; -+ order2_3x = order_2 / 3; -+ order1_5x_rem = order_1 - 5 * order1_5x; -+ order2_3x_rem = order_2 - 3 * order2_3x; -+ -+ for (i = 0; i < PAPRD_TABLE_SZ; i++) { -+ int PA_angle; -+ -+ /* pa_table[4] is calculated from PA_angle for i=5 */ -+ if (i == 4) -+ continue; -+ -+ tmp = i * 32; -+ if (beta > 0) -+ y5 = (((beta * tmp - 64) >> 6) - -+ (1 << order1_5x)) / (1 << order1_5x); -+ else -+ y5 = ((((beta * tmp - 64) >> 6) + -+ (1 << order1_5x)) / (1 << order1_5x)); -+ -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = (y5 * tmp) / (1 << order1_5x); -+ y5 = y5 / (1 << order1_5x_rem); -+ -+ if (beta > 0) -+ y3 = (alpha * tmp - -+ (1 << order2_3x)) / (1 << order2_3x); -+ else -+ y3 = (alpha * tmp + -+ (1 << order2_3x)) / (1 << order2_3x); -+ y3 = (y3 * tmp) / (1 << order2_3x); -+ y3 = (y3 * tmp) / (1 << order2_3x); -+ y3 = y3 / (1 << order2_3x_rem); -+ -+ if (i < 4) { -+ PA_angle = 0; -+ } else { -+ PA_angle = y5 + y3; -+ if (PA_angle < -150) -+ PA_angle = -150; -+ else if (PA_angle > 150) -+ PA_angle = 150; -+ } -+ -+ pa_table[i] = ((PA_in[i] & 0x7ff) << 11) + (PA_angle & 0x7ff); -+ if (i == 5) { -+ PA_angle = (PA_angle + 2) >> 1; -+ pa_table[i - 1] = ((PA_in[i - 1] & 0x7ff) << 11) + -+ (PA_angle & 0x7ff); -+ } -+ } -+ -+ *gain = G_fxp; -+ return true; -+} -+ -+void ar9003_paprd_populate_single_table(struct ath_hw *ah, -+ struct ath9k_channel *chan, int chain) -+{ -+ u32 *paprd_table_val = chan->pa_table[chain]; -+ u32 small_signal_gain = chan->small_signal_gain[chain]; -+ u32 training_power; -+ u32 reg = 0; -+ int i; -+ -+ training_power = -+ REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, -+ AR_PHY_POWERTX_RATE5_POWERTXHT20_0); -+ training_power -= 4; -+ -+ if (chain == 0) -+ reg = AR_PHY_PAPRD_MEM_TAB_B0; -+ else if (chain == 1) -+ reg = AR_PHY_PAPRD_MEM_TAB_B1; -+ else if (chain == 2) -+ reg = AR_PHY_PAPRD_MEM_TAB_B2; -+ -+ for (i = 0; i < PAPRD_TABLE_SZ; i++) { -+ REG_WRITE(ah, reg, paprd_table_val[i]); -+ reg = reg + 4; -+ } -+ -+ if (chain == 0) -+ reg = AR_PHY_PA_GAIN123_B0; -+ else if (chain == 1) -+ reg = AR_PHY_PA_GAIN123_B1; -+ else -+ reg = AR_PHY_PA_GAIN123_B2; -+ -+ REG_RMW_FIELD(ah, reg, AR_PHY_PA_GAIN123_PA_GAIN1, small_signal_gain); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B0, -+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, -+ training_power); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1, -+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, -+ training_power); -+ -+ REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2, -+ AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL, -+ training_power); -+} -+EXPORT_SYMBOL(ar9003_paprd_populate_single_table); -+ -+int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain) -+{ -+ -+ unsigned int i, desired_gain, gain_index; -+ unsigned int train_power; -+ -+ train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5, -+ AR_PHY_POWERTX_RATE5_POWERTXHT20_0); -+ -+ train_power = train_power - 4; -+ -+ desired_gain = ar9003_get_desired_gain(ah, chain, train_power); -+ -+ gain_index = 0; -+ for (i = 0; i < 32; i++) { -+ if (ah->paprd_gain_table_index[i] >= desired_gain) -+ break; -+ gain_index++; -+ } -+ -+ ar9003_tx_force_gain(ah, gain_index); -+ -+ REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+ -+ return 0; -+} -+EXPORT_SYMBOL(ar9003_paprd_setup_gain_table); -+ -+int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, -+ int chain) -+{ -+ u16 *small_signal_gain = &chan->small_signal_gain[chain]; -+ u32 *pa_table = chan->pa_table[chain]; -+ u32 *data_L, *data_U; -+ int i, status = 0; -+ u32 *buf; -+ u32 reg; -+ -+ memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain])); -+ -+ buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC); -+ if (!buf) -+ return -ENOMEM; -+ -+ data_L = &buf[0]; -+ data_U = &buf[48]; -+ -+ REG_CLR_BIT(ah, AR_PHY_CHAN_INFO_MEMORY, -+ AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ); -+ -+ reg = AR_PHY_CHAN_INFO_TAB_0; -+ for (i = 0; i < 48; i++) -+ data_L[i] = REG_READ(ah, reg + (i << 2)); -+ -+ REG_SET_BIT(ah, AR_PHY_CHAN_INFO_MEMORY, -+ AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ); -+ -+ for (i = 0; i < 48; i++) -+ data_U[i] = REG_READ(ah, reg + (i << 2)); -+ -+ if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain)) -+ status = -2; -+ -+ REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+ -+ kfree(buf); -+ -+ return status; -+} -+EXPORT_SYMBOL(ar9003_paprd_create_curve); -+ -+int ar9003_paprd_init_table(struct ath_hw *ah) -+{ -+ ar9003_paprd_setup_single_table(ah); -+ ar9003_paprd_get_gain_table(ah); -+ return 0; -+} -+EXPORT_SYMBOL(ar9003_paprd_init_table); -+ -+bool ar9003_paprd_is_done(struct ath_hw *ah) -+{ -+ return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1, -+ AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE); -+} -+EXPORT_SYMBOL(ar9003_paprd_is_done); ---- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h -+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h -@@ -451,7 +451,11 @@ - #define AR_PHY_TSTDAC (AR_SM_BASE + 0x168) - - #define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c) --#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) -+ -+#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170) -+#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ 0x00000008 -+#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S 3 -+ - #define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174) - #define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178) - #define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c) -@@ -467,17 +471,63 @@ - #define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0) - #define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4) - --#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) --#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) --#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) --#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) --#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) --#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) -+#define AR_PHY_TPC_1 (AR_SM_BASE + 0x1f8) -+#define AR_PHY_TPC_1_FORCED_DAC_GAIN 0x0000003e -+#define AR_PHY_TPC_1_FORCED_DAC_GAIN_S 1 -+#define AR_PHY_TPC_1_FORCE_DAC_GAIN 0x00000001 -+#define AR_PHY_TPC_1_FORCE_DAC_GAIN_S 0 -+ -+#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204) -+#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208) -+#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c) -+ -+#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220) -+#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) -+#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220) -+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA 0x00ff0000 -+#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_S 16 -+ -+#define AR_PHY_TPC_12 (AR_SM_BASE + 0x224) -+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5 0x3e000000 -+#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_S 25 -+ -+#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c) -+#define AR_PHY_TPC_18_THERM_CAL_VALUE 0x000000ff -+#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0 -+#define AR_PHY_TPC_18_VOLT_CAL_VALUE 0x0000ff00 -+#define AR_PHY_TPC_18_VOLT_CAL_VALUE_S 8 -+ -+#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240) -+#define AR_PHY_TPC_19_ALPHA_VOLT 0x001f0000 -+#define AR_PHY_TPC_19_ALPHA_VOLT_S 16 -+#define AR_PHY_TPC_19_ALPHA_THERM 0xff -+#define AR_PHY_TPC_19_ALPHA_THERM_S 0 -+ -+#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258) -+#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN 0x00000001 -+#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN_S 0 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN 0x0000000e -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_S 1 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN 0x00000030 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_S 4 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN 0x000003c0 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN_S 6 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA 0x00003c00 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA_S 10 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB 0x0003c000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB_S 14 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC 0x003c0000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC_S 18 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND 0x00c00000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND_S 22 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL 0x01000000 -+#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL_S 24 - --#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258) - - #define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280) - -+#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300) -+ - #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448) - #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440) - #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c) -@@ -490,7 +540,17 @@ - #define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0) - #define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4) - #define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc) --#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) -+ -+#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248) -+#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_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 -+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00 -+#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8 -+ - - #define AR_PHY_65NM_CH0_SYNTH4 0x1608c - #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002 -@@ -660,17 +720,9 @@ - #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff - #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0 - --#define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff --#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0 --#define AR_PHY_TPC_19_ALPHA_THERM 0xff --#define AR_PHY_TPC_19_ALPHA_THERM_S 0 -- - #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000 - #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28 - --#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff --#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0 -- - /* - * Channel 1 Register Map - */ -@@ -842,6 +894,144 @@ - - #define AR_PHY_WATCHDOG_STATUS_CLR 0x00000008 - -+/* -+ * PAPRD registers -+ */ -+#define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64) -+ -+#define AR_PHY_PAPRD_AM2AM (AR_CHAN_BASE + 0xe4) -+#define AR_PHY_PAPRD_AM2AM_MASK 0x01ffffff -+#define AR_PHY_PAPRD_AM2AM_MASK_S 0 -+ -+#define AR_PHY_PAPRD_AM2PM (AR_CHAN_BASE + 0xe8) -+#define AR_PHY_PAPRD_AM2PM_MASK 0x01ffffff -+#define AR_PHY_PAPRD_AM2PM_MASK_S 0 -+ -+#define AR_PHY_PAPRD_HT40 (AR_CHAN_BASE + 0xec) -+#define AR_PHY_PAPRD_HT40_MASK 0x01ffffff -+#define AR_PHY_PAPRD_HT40_MASK_S 0 -+ -+#define AR_PHY_PAPRD_CTRL0_B0 (AR_CHAN_BASE + 0xf0) -+#define AR_PHY_PAPRD_CTRL0_B1 (AR_CHAN1_BASE + 0xf0) -+#define AR_PHY_PAPRD_CTRL0_B2 (AR_CHAN2_BASE + 0xf0) -+#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE 0x00000001 -+#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE_S 0 -+#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK 0x00000002 -+#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK_S 1 -+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH 0xf8000000 -+#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_S 27 -+ -+#define AR_PHY_PAPRD_CTRL1_B0 (AR_CHAN_BASE + 0xf4) -+#define AR_PHY_PAPRD_CTRL1_B1 (AR_CHAN1_BASE + 0xf4) -+#define AR_PHY_PAPRD_CTRL1_B2 (AR_CHAN2_BASE + 0xf4) -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA 0x00000001 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA_S 0 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE 0x00000002 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE_S 1 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE 0x00000004 -+#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE_S 2 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL 0x000001f8 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_S 3 -+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK 0x0001fe00 -+#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK_S 9 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000 -+#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490) -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_S 1 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE 0x00000100 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_S 8 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE 0x00000200 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_S 9 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE 0x00000400 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_S 10 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE 0x00000800 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_S 11 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000 -+#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494) -+#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF -+#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498) -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_S 6 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL 0x0001f000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_S 12 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES 0x000e0000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_S 17 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN 0x00f00000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_S 20 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN 0x0f000000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_S 24 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000 -+#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29 -+ -+#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c) -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_S 12 -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR 0x00000fff -+#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_S 0 -+ -+#define AR_PHY_PAPRD_PRE_POST_SCALE_0_B0 (AR_CHAN_BASE + 0x100) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_1_B0 (AR_CHAN_BASE + 0x104) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_2_B0 (AR_CHAN_BASE + 0x108) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_3_B0 (AR_CHAN_BASE + 0x10c) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_4_B0 (AR_CHAN_BASE + 0x110) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_5_B0 (AR_CHAN_BASE + 0x114) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_6_B0 (AR_CHAN_BASE + 0x118) -+#define AR_PHY_PAPRD_PRE_POST_SCALE_7_B0 (AR_CHAN_BASE + 0x11c) -+#define AR_PHY_PAPRD_PRE_POST_SCALING 0x3FFFF -+#define AR_PHY_PAPRD_PRE_POST_SCALING_S 0 -+ -+#define AR_PHY_PAPRD_TRAINER_STAT1 (AR_SM_BASE + 0x4a0) -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE 0x00000001 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_S 0 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE 0x00000002 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_S 1 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR 0x00000004 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_S 2 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE 0x00000008 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_S 3 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX 0x000001f0 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_S 4 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR 0x0001fe00 -+#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_S 9 -+ -+#define AR_PHY_PAPRD_TRAINER_STAT2 (AR_SM_BASE + 0x4a4) -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL 0x0000ffff -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_S 0 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX 0x001f0000 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_S 16 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX 0x00600000 -+#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_S 21 -+ -+#define AR_PHY_PAPRD_TRAINER_STAT3 (AR_SM_BASE + 0x4a8) -+#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT 0x000fffff -+#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_S 0 -+ -+#define AR_PHY_PAPRD_MEM_TAB_B0 (AR_CHAN_BASE + 0x120) -+#define AR_PHY_PAPRD_MEM_TAB_B1 (AR_CHAN1_BASE + 0x120) -+#define AR_PHY_PAPRD_MEM_TAB_B2 (AR_CHAN2_BASE + 0x120) -+ -+#define AR_PHY_PA_GAIN123_B0 (AR_CHAN_BASE + 0xf8) -+#define AR_PHY_PA_GAIN123_B1 (AR_CHAN1_BASE + 0xf8) -+#define AR_PHY_PA_GAIN123_B2 (AR_CHAN2_BASE + 0xf8) -+#define AR_PHY_PA_GAIN123_PA_GAIN1 0x3FF -+#define AR_PHY_PA_GAIN123_PA_GAIN1_S 0 -+ -+#define AR_PHY_POWERTX_RATE5 (AR_SM_BASE + 0x1d0) -+#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F -+#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0 -+ - void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx); - - #endif /* AR9003_PHY_H */ ---- a/drivers/net/wireless/ath/ath9k/ath9k.h -+++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - #include "debug.h" - #include "common.h" -@@ -194,6 +195,7 @@ enum ATH_AGGR_STATUS { - - #define ATH_TXFIFO_DEPTH 8 - struct ath_txq { -+ int axq_class; - u32 axq_qnum; - u32 *axq_link; - struct list_head axq_q; -@@ -206,7 +208,6 @@ struct ath_txq { - struct list_head txq_fifo_pending; - u8 txq_headidx; - u8 txq_tailidx; -- int pending_frames; - }; - - struct ath_atx_ac { -@@ -224,6 +225,7 @@ struct ath_buf_state { - int bfs_tidno; - int bfs_retries; - u8 bf_type; -+ u8 bfs_paprd; - u32 bfs_keyix; - enum ath9k_key_type bfs_keytype; - }; -@@ -244,7 +246,6 @@ struct ath_buf { - struct ath_buf_state bf_state; - dma_addr_t bf_dmacontext; - struct ath_wiphy *aphy; -- struct ath_txq *txq; - }; - - struct ath_atx_tid { -@@ -281,6 +282,7 @@ struct ath_tx_control { - struct ath_txq *txq; - int if_id; - enum ath9k_internal_frame_type frame_type; -+ u8 paprd; - }; - - #define ATH_TX_ERROR 0x01 -@@ -290,11 +292,12 @@ struct ath_tx_control { - struct ath_tx { - u16 seq_no; - u32 txqsetup; -- int hwq_map[ATH9K_WME_AC_VO+1]; -+ int hwq_map[WME_NUM_AC]; - spinlock_t txbuflock; - struct list_head txbuf; - struct ath_txq txq[ATH9K_NUM_TX_QUEUES]; - struct ath_descdma txdma; -+ int pending_frames[WME_NUM_AC]; - }; - - struct ath_rx_edma { -@@ -421,6 +424,7 @@ int ath_beaconq_config(struct ath_softc - #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ - #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ - -+void ath_paprd_calibrate(struct work_struct *work); - void ath_ani_calibrate(unsigned long data); - - /**********/ -@@ -553,6 +557,9 @@ struct ath_softc { - spinlock_t sc_serial_rw; - spinlock_t sc_pm_lock; - struct mutex mutex; -+ struct work_struct paprd_work; -+ struct completion paprd_complete; -+ int paprd_txok; - - u32 intrstatus; - u32 sc_flags; /* SC_OP_* */ -@@ -613,7 +620,6 @@ struct ath_wiphy { - - void ath9k_tasklet(unsigned long data); - int ath_reset(struct ath_softc *sc, bool retry_tx); --int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); - int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); - int ath_cabq_update(struct ath_softc *); - -@@ -629,8 +635,6 @@ irqreturn_t ath_isr(int irq, void *dev); - int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, - const struct ath_bus_ops *bus_ops); - void ath9k_deinit_device(struct ath_softc *sc); --const char *ath_mac_bb_name(u32 mac_bb_version); --const char *ath_rf_name(u16 rf_version); - void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); - void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, - struct ath9k_channel *ichan); -@@ -681,8 +685,6 @@ void ath9k_set_wiphy_idle(struct ath_wip - void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue); - void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); - --int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); -- - void ath_start_rfkill_poll(struct ath_softc *sc); - extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw); - ---- a/drivers/net/wireless/ath/ath9k/eeprom.h -+++ b/drivers/net/wireless/ath/ath9k/eeprom.h -@@ -263,7 +263,8 @@ enum eeprom_param { - EEP_PWR_TABLE_OFFSET, - EEP_DRIVE_STRENGTH, - EEP_INTERNAL_REGULATOR, -- EEP_SWREG -+ EEP_SWREG, -+ EEP_PAPRD, - }; - - enum ar5416_rates { ---- a/drivers/net/wireless/ath/ath9k/hw.c -+++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2246,6 +2246,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw - 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->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) && ---- a/drivers/net/wireless/ath/ath9k/hw.h -+++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -158,6 +158,9 @@ - #define ATH9K_HW_RX_HP_QDEPTH 16 - #define ATH9K_HW_RX_LP_QDEPTH 128 - -+#define PAPRD_GAIN_TABLE_ENTRIES 32 -+#define PAPRD_TABLE_SZ 24 -+ - enum ath_ini_subsys { - ATH_INI_PRE = 0, - ATH_INI_CORE, -@@ -200,6 +203,7 @@ enum ath9k_hw_caps { - ATH9K_HW_CAP_LDPC = BIT(19), - ATH9K_HW_CAP_FASTCLOCK = BIT(20), - ATH9K_HW_CAP_SGI_20 = BIT(21), -+ ATH9K_HW_CAP_PAPRD = BIT(22), - }; - - enum ath9k_capability_type { -@@ -359,6 +363,9 @@ struct ath9k_channel { - int8_t iCoff; - int8_t qCoff; - int16_t rawNoiseFloor; -+ bool paprd_done; -+ u16 small_signal_gain[AR9300_MAX_CHAINS]; -+ u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ]; - }; - - #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \ -@@ -793,6 +800,9 @@ struct ath_hw { - - u32 bb_watchdog_last_status; - u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */ -+ -+ u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES]; -+ u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES]; - }; - - static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah) -@@ -922,6 +932,15 @@ void ar9003_hw_set_nf_limits(struct ath_ - void ar9003_hw_bb_watchdog_config(struct ath_hw *ah); - void ar9003_hw_bb_watchdog_read(struct ath_hw *ah); - void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah); -+void ar9003_paprd_enable(struct ath_hw *ah, bool val); -+void ar9003_paprd_populate_single_table(struct ath_hw *ah, -+ struct ath9k_channel *chan, int chain); -+int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan, -+ int chain); -+int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain); -+int ar9003_paprd_init_table(struct ath_hw *ah); -+bool ar9003_paprd_is_done(struct ath_hw *ah); -+void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains); - - /* Hardware family op attach helpers */ - void ar5008_hw_attach_phy_ops(struct ath_hw *ah); ---- a/drivers/net/wireless/ath/ath9k/init.c -+++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -427,7 +427,7 @@ static int ath9k_init_btcoex(struct ath_ - r = ath_init_btcoex_timer(sc); - if (r) - return -1; -- qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum); - sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW; - break; -@@ -464,23 +464,23 @@ static int ath9k_init_queues(struct ath_ - sc->config.cabqReadytime = ATH_CABQ_READY_TIME; - ath_cabq_update(sc); - -- if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { -+ if (!ath_tx_setup(sc, WME_AC_BK)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BK traffic\n"); - goto err; - } - -- if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { -+ if (!ath_tx_setup(sc, WME_AC_BE)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BE traffic\n"); - goto err; - } -- if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { -+ if (!ath_tx_setup(sc, WME_AC_VI)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VI traffic\n"); - goto err; - } -- if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { -+ if (!ath_tx_setup(sc, WME_AC_VO)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VO traffic\n"); - goto err; -@@ -769,6 +769,7 @@ int ath9k_init_device(u16 devid, struct - goto error_world; - } - -+ INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); - INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); - INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); - sc->wiphy_scheduler_int = msecs_to_jiffies(500); ---- a/drivers/net/wireless/ath/ath9k/main.c -+++ b/drivers/net/wireless/ath/ath9k/main.c -@@ -233,6 +233,104 @@ int ath_set_channel(struct ath_softc *sc - return r; - } - -+static void ath_paprd_activate(struct ath_softc *sc) -+{ -+ struct ath_hw *ah = sc->sc_ah; -+ int chain; -+ -+ if (!ah->curchan->paprd_done) -+ return; -+ -+ ath9k_ps_wakeup(sc); -+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { -+ if (!(ah->caps.tx_chainmask & BIT(chain))) -+ continue; -+ -+ ar9003_paprd_populate_single_table(ah, ah->curchan, chain); -+ } -+ -+ ar9003_paprd_enable(ah, true); -+ ath9k_ps_restore(sc); -+} -+ -+void ath_paprd_calibrate(struct work_struct *work) -+{ -+ struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work); -+ struct ieee80211_hw *hw = sc->hw; -+ struct ath_hw *ah = sc->sc_ah; -+ struct ieee80211_hdr *hdr; -+ struct sk_buff *skb = NULL; -+ struct ieee80211_tx_info *tx_info; -+ int band = hw->conf.channel->band; -+ struct ieee80211_supported_band *sband = &sc->sbands[band]; -+ struct ath_tx_control txctl; -+ int qnum, ftype; -+ int chain_ok = 0; -+ int chain; -+ int len = 1800; -+ int i; -+ -+ ath9k_ps_wakeup(sc); -+ skb = alloc_skb(len, GFP_KERNEL); -+ if (!skb) -+ return; -+ -+ tx_info = IEEE80211_SKB_CB(skb); -+ -+ skb_put(skb, len); -+ memset(skb->data, 0, len); -+ hdr = (struct ieee80211_hdr *)skb->data; -+ ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC; -+ hdr->frame_control = cpu_to_le16(ftype); -+ hdr->duration_id = 10; -+ memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN); -+ memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); -+ memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); -+ -+ memset(&txctl, 0, sizeof(txctl)); -+ qnum = sc->tx.hwq_map[WME_AC_BE]; -+ txctl.txq = &sc->tx.txq[qnum]; -+ -+ ar9003_paprd_init_table(ah); -+ for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { -+ if (!(ah->caps.tx_chainmask & BIT(chain))) -+ continue; -+ -+ chain_ok = 0; -+ memset(tx_info, 0, sizeof(*tx_info)); -+ tx_info->band = band; -+ -+ for (i = 0; i < 4; i++) { -+ tx_info->control.rates[i].idx = sband->n_bitrates - 1; -+ tx_info->control.rates[i].count = 6; -+ } -+ -+ init_completion(&sc->paprd_complete); -+ ar9003_paprd_setup_gain_table(ah, chain); -+ txctl.paprd = BIT(chain); -+ if (ath_tx_start(hw, skb, &txctl) != 0) -+ break; -+ -+ wait_for_completion(&sc->paprd_complete); -+ -+ if (!ar9003_paprd_is_done(ah)) -+ break; -+ -+ if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0) -+ break; -+ -+ chain_ok = 1; -+ } -+ kfree_skb(skb); -+ -+ if (chain_ok) { -+ ah->curchan->paprd_done = true; -+ ath_paprd_activate(sc); -+ } -+ -+ ath9k_ps_restore(sc); -+} -+ - /* - * This routine performs the periodic noise floor calibration function - * that is used to adjust and optimize the chip performance. This -@@ -332,6 +430,13 @@ 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) && -+ !(sc->sc_flags & SC_OP_SCANNING)) { -+ if (!sc->sc_ah->curchan->paprd_done) -+ ieee80211_queue_work(sc->hw, &sc->paprd_work); -+ else -+ ath_paprd_activate(sc); -+ } - } - - static void ath_start_ani(struct ath_common *common) -@@ -805,25 +910,25 @@ int ath_reset(struct ath_softc *sc, bool - return r; - } - --int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) -+static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) - { - int qnum; - - switch (queue) { - case 0: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO]; -+ qnum = sc->tx.hwq_map[WME_AC_VO]; - break; - case 1: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI]; -+ qnum = sc->tx.hwq_map[WME_AC_VI]; - break; - case 2: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - break; - case 3: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK]; -+ qnum = sc->tx.hwq_map[WME_AC_BK]; - break; - default: -- qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE]; -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - break; - } - -@@ -835,16 +940,16 @@ int ath_get_mac80211_qnum(u32 queue, str - int qnum; - - switch (queue) { -- case ATH9K_WME_AC_VO: -+ case WME_AC_VO: - qnum = 0; - break; -- case ATH9K_WME_AC_VI: -+ case WME_AC_VI: - qnum = 1; - break; -- case ATH9K_WME_AC_BE: -+ case WME_AC_BE: - qnum = 2; - break; -- case ATH9K_WME_AC_BK: -+ case WME_AC_BK: - qnum = 3; - break; - default: -@@ -1128,6 +1233,7 @@ static void ath9k_stop(struct ieee80211_ - - cancel_delayed_work_sync(&sc->ath_led_blink_work); - cancel_delayed_work_sync(&sc->tx_complete_work); -+ cancel_work_sync(&sc->paprd_work); - - if (!sc->num_sec_wiphy) { - cancel_delayed_work_sync(&sc->wiphy_work); -@@ -1556,7 +1662,7 @@ static int ath9k_conf_tx(struct ieee8021 - ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n"); - - if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) -- if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret) -+ if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret) - ath_beaconq_config(sc); - - mutex_unlock(&sc->mutex); -@@ -1843,6 +1949,7 @@ static void ath9k_sw_scan_start(struct i - ath9k_wiphy_pause_all_forced(sc, aphy); - sc->sc_flags |= SC_OP_SCANNING; - del_timer_sync(&common->ani.timer); -+ cancel_work_sync(&sc->paprd_work); - cancel_delayed_work_sync(&sc->tx_complete_work); - mutex_unlock(&sc->mutex); - } ---- a/drivers/net/wireless/ath/ath9k/xmit.c -+++ b/drivers/net/wireless/ath/ath9k/xmit.c -@@ -941,6 +941,7 @@ struct ath_txq *ath_txq_setup(struct ath - if (!ATH_TXQ_SETUP(sc, qnum)) { - struct ath_txq *txq = &sc->tx.txq[qnum]; - -+ txq->axq_class = subtype; - txq->axq_qnum = qnum; - txq->axq_link = NULL; - INIT_LIST_HEAD(&txq->axq_q); -@@ -958,32 +959,6 @@ struct ath_txq *ath_txq_setup(struct ath - return &sc->tx.txq[qnum]; - } - --int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype) --{ -- int qnum; -- -- switch (qtype) { -- case ATH9K_TX_QUEUE_DATA: -- if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) { -- ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL, -- "HAL AC %u out of range, max %zu!\n", -- haltype, ARRAY_SIZE(sc->tx.hwq_map)); -- return -1; -- } -- qnum = sc->tx.hwq_map[haltype]; -- break; -- case ATH9K_TX_QUEUE_BEACON: -- qnum = sc->beacon.beaconq; -- break; -- case ATH9K_TX_QUEUE_CAB: -- qnum = sc->beacon.cabq->axq_qnum; -- break; -- default: -- qnum = -1; -- } -- return qnum; --} -- - int ath_txq_update(struct ath_softc *sc, int qnum, - struct ath9k_tx_queue_info *qinfo) - { -@@ -1662,12 +1637,13 @@ static int ath_tx_setup_buffer(struct ie - bf->bf_frmlen -= padsize; - } - -- if (conf_is_ht(&hw->conf)) { -+ if (!txctl->paprd && conf_is_ht(&hw->conf)) { - bf->bf_state.bf_type |= BUF_HT; - if (tx_info->flags & IEEE80211_TX_CTL_LDPC) - use_ldpc = true; - } - -+ bf->bf_state.bfs_paprd = txctl->paprd; - bf->bf_flags = setup_tx_flags(skb, use_ldpc); - - bf->bf_keytype = get_hw_crypto_keytype(skb); -@@ -1742,6 +1718,9 @@ static void ath_tx_start_dma(struct ath_ - bf->bf_buf_addr, - txctl->txq->axq_qnum); - -+ if (bf->bf_state.bfs_paprd) -+ ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd); -+ - spin_lock_bh(&txctl->txq->axq_lock); - - if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) && -@@ -1785,7 +1764,7 @@ int ath_tx_start(struct ieee80211_hw *hw - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ath_txq *txq = txctl->txq; - struct ath_buf *bf; -- int r; -+ int q, r; - - bf = ath_tx_get_buffer(sc); - if (!bf) { -@@ -1793,14 +1772,6 @@ int ath_tx_start(struct ieee80211_hw *hw - return -1; - } - -- bf->txq = txctl->txq; -- spin_lock_bh(&bf->txq->axq_lock); -- if (++bf->txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) { -- ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); -- txq->stopped = 1; -- } -- spin_unlock_bh(&bf->txq->axq_lock); -- - r = ath_tx_setup_buffer(hw, bf, skb, txctl); - if (unlikely(r)) { - ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n"); -@@ -1821,6 +1792,17 @@ int ath_tx_start(struct ieee80211_hw *hw - return r; - } - -+ q = skb_get_queue_mapping(skb); -+ if (q >= 4) -+ q = 0; -+ -+ spin_lock_bh(&txq->axq_lock); -+ if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) { -+ ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb)); -+ txq->stopped = 1; -+ } -+ spin_unlock_bh(&txq->axq_lock); -+ - ath_tx_start_dma(sc, bf, txctl); - - return 0; -@@ -1890,7 +1872,7 @@ static void ath_tx_complete(struct ath_s - struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); - struct ath_common *common = ath9k_hw_common(sc->sc_ah); - struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data; -- int padpos, padsize; -+ int q, padpos, padsize; - - ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb); - -@@ -1929,8 +1911,16 @@ static void ath_tx_complete(struct ath_s - - if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) - ath9k_tx_status(hw, skb); -- else -+ else { -+ q = skb_get_queue_mapping(skb); -+ if (q >= 4) -+ q = 0; -+ -+ if (--sc->tx.pending_frames[q] < 0) -+ sc->tx.pending_frames[q] = 0; -+ - ieee80211_tx_status(hw, skb); -+ } - } - - static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf, -@@ -1951,16 +1941,15 @@ static void ath_tx_complete_buf(struct a - tx_flags |= ATH_TX_XRETRY; - } - -- if (bf->txq) { -- spin_lock_bh(&bf->txq->axq_lock); -- bf->txq->pending_frames--; -- spin_unlock_bh(&bf->txq->axq_lock); -- bf->txq = NULL; -- } -- - dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE); -- ath_tx_complete(sc, skb, bf->aphy, tx_flags); -- ath_debug_stat_tx(sc, txq, bf, ts); -+ -+ if (bf->bf_state.bfs_paprd) { -+ sc->paprd_txok = txok; -+ complete(&sc->paprd_complete); -+ } else { -+ ath_tx_complete(sc, skb, bf->aphy, tx_flags); -+ ath_debug_stat_tx(sc, txq, bf, ts); -+ } - - /* - * Return the list of ath_buf of this mpdu to free queue -@@ -2045,13 +2034,14 @@ static void ath_wake_mac80211_queue(stru - { - int qnum; - -+ qnum = ath_get_mac80211_qnum(txq->axq_class, sc); -+ if (qnum == -1) -+ return; -+ - spin_lock_bh(&txq->axq_lock); -- if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) { -- qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); -- if (qnum != -1) { -- ath_mac80211_start_queue(sc, qnum); -- txq->stopped = 0; -- } -+ if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) { -+ ath_mac80211_start_queue(sc, qnum); -+ txq->stopped = 0; - } - spin_unlock_bh(&txq->axq_lock); - } -@@ -2422,26 +2412,8 @@ void ath_tx_node_init(struct ath_softc * - for (acno = 0, ac = &an->ac[acno]; - acno < WME_NUM_AC; acno++, ac++) { - ac->sched = false; -+ ac->qnum = sc->tx.hwq_map[acno]; - INIT_LIST_HEAD(&ac->tid_q); -- -- switch (acno) { -- case WME_AC_BE: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE); -- break; -- case WME_AC_BK: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK); -- break; -- case WME_AC_VI: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI); -- break; -- case WME_AC_VO: -- ac->qnum = ath_tx_get_qnum(sc, -- ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO); -- break; -- } - } - } - ---- a/drivers/net/wireless/ath/ath9k/beacon.c -+++ b/drivers/net/wireless/ath/ath9k/beacon.c -@@ -38,8 +38,7 @@ int ath_beaconq_config(struct ath_softc - qi.tqi_cwmax = 0; - } else { - /* Adhoc mode; important thing is to use 2x cwmin. */ -- qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, -- ATH9K_WME_AC_BE); -+ qnum = sc->tx.hwq_map[WME_AC_BE]; - ath9k_hw_get_txq_props(ah, qnum, &qi_be); - qi.tqi_aifs = qi_be.tqi_aifs; - qi.tqi_cwmin = 4*qi_be.tqi_cwmin; ---- a/drivers/net/wireless/ath/ath9k/debug.c -+++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -630,10 +630,10 @@ static const struct file_operations fops - do { \ - len += snprintf(buf + len, size - len, \ - "%s%13u%11u%10u%10u\n", str, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \ -- sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \ -+ sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \ - } while(0) - - static ssize_t read_file_xmit(struct file *file, char __user *user_buf, -@@ -956,6 +956,10 @@ int ath9k_init_debug(struct ath_hw *ah) - sc->debug.debugfs_phy, sc, &fops_regval)) - goto err; - -+ if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR, -+ sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca)) -+ goto err; -+ - sc->debug.regidx = 0; - return 0; - err: ---- a/drivers/net/wireless/ath/ath9k/htc.h -+++ b/drivers/net/wireless/ath/ath9k/htc.h -@@ -398,7 +398,7 @@ struct ath9k_htc_priv { - - int beaconq; - int cabq; -- int hwq_map[ATH9K_WME_AC_VO+1]; -+ int hwq_map[WME_NUM_AC]; - - #ifdef CONFIG_ATH9K_HTC_DEBUGFS - struct ath9k_debug debug; ---- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c -@@ -227,7 +227,7 @@ void ath9k_htc_beaconq_config(struct ath - { - struct ath_hw *ah = priv->ah; - struct ath9k_tx_queue_info qi, qi_be; -- int qnum = priv->hwq_map[ATH9K_WME_AC_BE]; -+ int qnum = priv->hwq_map[WME_AC_BE]; - - memset(&qi, 0, sizeof(struct ath9k_tx_queue_info)); - memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info)); ---- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c -@@ -521,23 +521,23 @@ static int ath9k_init_queues(struct ath9 - goto err; - } - -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BE traffic\n"); - goto err; - } - -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for BK traffic\n"); - goto err; - } -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VI traffic\n"); - goto err; - } -- if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) { -+ if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) { - ath_print(common, ATH_DBG_FATAL, - "Unable to setup xmit queue for VO traffic\n"); - goto err; ---- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c -@@ -1590,7 +1590,7 @@ static int ath9k_htc_conf_tx(struct ieee - } - - if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) && -- (qnum == priv->hwq_map[ATH9K_WME_AC_BE])) -+ (qnum == priv->hwq_map[WME_AC_BE])) - ath9k_htc_beaconq_config(priv); - out: - ath9k_htc_ps_restore(priv); ---- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c -+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c -@@ -34,15 +34,15 @@ int get_hw_qnum(u16 queue, int *hwq_map) - { - switch (queue) { - case 0: -- return hwq_map[ATH9K_WME_AC_VO]; -+ return hwq_map[WME_AC_VO]; - case 1: -- return hwq_map[ATH9K_WME_AC_VI]; -+ return hwq_map[WME_AC_VI]; - case 2: -- return hwq_map[ATH9K_WME_AC_BE]; -+ return hwq_map[WME_AC_BE]; - case 3: -- return hwq_map[ATH9K_WME_AC_BK]; -+ return hwq_map[WME_AC_BK]; - default: -- return hwq_map[ATH9K_WME_AC_BE]; -+ return hwq_map[WME_AC_BE]; - } - } - ---- a/drivers/net/wireless/ath/ath9k/mac.h -+++ b/drivers/net/wireless/ath/ath9k/mac.h -@@ -577,13 +577,8 @@ enum ath9k_tx_queue { - - #define ATH9K_NUM_TX_QUEUES 10 - --enum ath9k_tx_queue_subtype { -- ATH9K_WME_AC_BK = 0, -- ATH9K_WME_AC_BE, -- ATH9K_WME_AC_VI, -- ATH9K_WME_AC_VO, -- ATH9K_WME_UPSD --}; -+/* Used as a queue subtype instead of a WMM AC */ -+#define ATH9K_WME_UPSD 4 - - enum ath9k_tx_queue_flags { - TXQ_FLAG_TXOKINT_ENABLE = 0x0001, -@@ -617,7 +612,7 @@ enum ath9k_pkt_type { - struct ath9k_tx_queue_info { - u32 tqi_ver; - enum ath9k_tx_queue tqi_type; -- enum ath9k_tx_queue_subtype tqi_subtype; -+ int tqi_subtype; - enum ath9k_tx_queue_flags tqi_qflags; - u32 tqi_priority; - u32 tqi_aifs; ---- a/drivers/net/wireless/ath/ath9k/virtual.c -+++ b/drivers/net/wireless/ath/ath9k/virtual.c -@@ -219,7 +219,7 @@ static int ath9k_send_nullfunc(struct at - info->control.rates[1].idx = -1; - - memset(&txctl, 0, sizeof(struct ath_tx_control)); -- txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]]; -+ txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]]; - txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE; - - if (ath_tx_start(aphy->hw, skb, &txctl) != 0) diff --git a/package/mac80211/patches/520-ath9k_enable_ar9300.patch b/package/mac80211/patches/520-ath9k_enable_ar9300.patch deleted file mode 100644 index f8fbe860f9..0000000000 --- a/package/mac80211/patches/520-ath9k_enable_ar9300.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/drivers/net/wireless/ath/ath9k/pci.c -+++ b/drivers/net/wireless/ath/ath9k/pci.c -@@ -29,6 +29,7 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_i - { PCI_VDEVICE(ATHEROS, 0x002C) }, /* PCI-E 802.11n bonded out */ - { PCI_VDEVICE(ATHEROS, 0x002D) }, /* PCI */ - { PCI_VDEVICE(ATHEROS, 0x002E) }, /* PCI-E */ -+ { PCI_VDEVICE(ATHEROS, 0x0030) }, /* PCI-E AR9300 */ - { 0 } - }; -