Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
John W. Linville [Thu, 5 May 2011 17:32:35 +0000 (13:32 -0400)]
Conflicts:
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/rtlwifi/pci.c
net/bluetooth/l2cap_sock.c

244 files changed:
drivers/net/wireless/ath/ath5k/reset.c
drivers/net/wireless/ath/ath9k/ahb.c
drivers/net/wireless/ath/ath9k/ani.c
drivers/net/wireless/ath/ath9k/ar9003_calib.c
drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
drivers/net/wireless/ath/ath9k/ar9003_hw.c
drivers/net/wireless/ath/ath9k/ar9003_phy.c
drivers/net/wireless/ath/ath9k/ar9003_phy.h
drivers/net/wireless/ath/ath9k/ar9340_initvals.h [new file with mode: 0644]
drivers/net/wireless/ath/ath9k/ath9k.h
drivers/net/wireless/ath/ath9k/beacon.c
drivers/net/wireless/ath/ath9k/btcoex.c
drivers/net/wireless/ath/ath9k/btcoex.h
drivers/net/wireless/ath/ath9k/common.c
drivers/net/wireless/ath/ath9k/common.h
drivers/net/wireless/ath/ath9k/debug.c
drivers/net/wireless/ath/ath9k/debug.h
drivers/net/wireless/ath/ath9k/eeprom_9287.c
drivers/net/wireless/ath/ath9k/eeprom_def.c
drivers/net/wireless/ath/ath9k/gpio.c
drivers/net/wireless/ath/ath9k/hif_usb.h
drivers/net/wireless/ath/ath9k/htc.h
drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
drivers/net/wireless/ath/ath9k/htc_drv_debug.c
drivers/net/wireless/ath/ath9k/htc_drv_gpio.c
drivers/net/wireless/ath/ath9k/htc_drv_init.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
drivers/net/wireless/ath/ath9k/htc_hst.h
drivers/net/wireless/ath/ath9k/hw.c
drivers/net/wireless/ath/ath9k/hw.h
drivers/net/wireless/ath/ath9k/init.c
drivers/net/wireless/ath/ath9k/mac.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/ath9k/phy.h
drivers/net/wireless/ath/ath9k/rc.c
drivers/net/wireless/ath/ath9k/recv.c
drivers/net/wireless/ath/ath9k/reg.h
drivers/net/wireless/ath/ath9k/wmi.c
drivers/net/wireless/ath/ath9k/wmi.h
drivers/net/wireless/ath/ath9k/xmit.c
drivers/net/wireless/ath/carl9170/carl9170.h
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/tx.c
drivers/net/wireless/b43/phy_n.c
drivers/net/wireless/iwlegacy/iwl-4965-lib.c
drivers/net/wireless/iwlegacy/iwl-core.c
drivers/net/wireless/iwlegacy/iwl-core.h
drivers/net/wireless/iwlegacy/iwl-dev.h
drivers/net/wireless/iwlegacy/iwl-hcmd.c
drivers/net/wireless/iwlegacy/iwl-helpers.h
drivers/net/wireless/iwlegacy/iwl-tx.c
drivers/net/wireless/iwlegacy/iwl3945-base.c
drivers/net/wireless/iwlegacy/iwl4965-base.c
drivers/net/wireless/iwlwifi/Makefile
drivers/net/wireless/iwlwifi/iwl-1000.c
drivers/net/wireless/iwlwifi/iwl-2000.c
drivers/net/wireless/iwlwifi/iwl-5000.c
drivers/net/wireless/iwlwifi/iwl-6000.c
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c [deleted file]
drivers/net/wireless/iwlwifi/iwl-agn-debugfs.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c
drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
drivers/net/wireless/iwlwifi/iwl-agn-lib.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-agn-ucode.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-agn.h
drivers/net/wireless/iwlwifi/iwl-commands.h
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-core.h
drivers/net/wireless/iwlwifi/iwl-debugfs.c
drivers/net/wireless/iwlwifi/iwl-dev.h
drivers/net/wireless/iwlwifi/iwl-eeprom.c
drivers/net/wireless/iwlwifi/iwl-eeprom.h
drivers/net/wireless/iwlwifi/iwl-helpers.h
drivers/net/wireless/iwlwifi/iwl-io.c
drivers/net/wireless/iwlwifi/iwl-io.h
drivers/net/wireless/iwlwifi/iwl-rx.c
drivers/net/wireless/iwlwifi/iwl-spectrum.h [deleted file]
drivers/net/wireless/iwlwifi/iwl-tx.c
drivers/net/wireless/libertas/cfg.c
drivers/net/wireless/libertas/cmd.c
drivers/net/wireless/libertas/cmdresp.c
drivers/net/wireless/libertas/debugfs.c
drivers/net/wireless/libertas/decl.h
drivers/net/wireless/libertas/defs.h
drivers/net/wireless/libertas/dev.h
drivers/net/wireless/libertas/ethtool.c
drivers/net/wireless/libertas/host.h
drivers/net/wireless/libertas/if_cs.c
drivers/net/wireless/libertas/if_spi.c
drivers/net/wireless/libertas/if_spi.h
drivers/net/wireless/libertas/if_usb.c
drivers/net/wireless/libertas/if_usb.h
drivers/net/wireless/libertas/main.c
drivers/net/wireless/libertas/mesh.c
drivers/net/wireless/libertas/mesh.h
drivers/net/wireless/libertas/rx.c
drivers/net/wireless/libertas/tx.c
drivers/net/wireless/libertas/types.h
drivers/net/wireless/mwifiex/11n.c
drivers/net/wireless/mwifiex/11n.h
drivers/net/wireless/mwifiex/cfg80211.c
drivers/net/wireless/mwifiex/join.c
drivers/net/wireless/mwifiex/main.h
drivers/net/wireless/mwifiex/scan.c
drivers/net/wireless/mwl8k.c
drivers/net/wireless/p54/eeprom.c
drivers/net/wireless/p54/fwio.c
drivers/net/wireless/p54/lmac.h
drivers/net/wireless/p54/main.c
drivers/net/wireless/p54/p54.h
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt2800lib.c
drivers/net/wireless/rt2x00/rt2800pci.c
drivers/net/wireless/rt2x00/rt2800usb.c
drivers/net/wireless/rt2x00/rt2x00.h
drivers/net/wireless/rt2x00/rt2x00config.c
drivers/net/wireless/rt2x00/rt2x00dev.c
drivers/net/wireless/rt2x00/rt2x00usb.c
drivers/net/wireless/rt2x00/rt2x00usb.h
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/rtlwifi/base.c
drivers/net/wireless/rtlwifi/base.h
drivers/net/wireless/rtlwifi/cam.c
drivers/net/wireless/rtlwifi/cam.h
drivers/net/wireless/rtlwifi/core.c
drivers/net/wireless/rtlwifi/core.h
drivers/net/wireless/rtlwifi/efuse.c
drivers/net/wireless/rtlwifi/efuse.h
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/pci.h
drivers/net/wireless/rtlwifi/ps.c
drivers/net/wireless/rtlwifi/ps.h
drivers/net/wireless/rtlwifi/rc.c
drivers/net/wireless/rtlwifi/rc.h
drivers/net/wireless/rtlwifi/regd.c
drivers/net/wireless/rtlwifi/regd.h
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.c
drivers/net/wireless/rtlwifi/rtl8192c/dm_common.h
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.h
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c
drivers/net/wireless/rtlwifi/rtl8192c/phy_common.h
drivers/net/wireless/rtlwifi/rtl8192ce/def.h
drivers/net/wireless/rtlwifi/rtl8192ce/dm.c
drivers/net/wireless/rtlwifi/rtl8192ce/dm.h
drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
drivers/net/wireless/rtlwifi/rtl8192ce/hw.h
drivers/net/wireless/rtlwifi/rtl8192ce/led.c
drivers/net/wireless/rtlwifi/rtl8192ce/led.h
drivers/net/wireless/rtlwifi/rtl8192ce/phy.c
drivers/net/wireless/rtlwifi/rtl8192ce/phy.h
drivers/net/wireless/rtlwifi/rtl8192ce/reg.h
drivers/net/wireless/rtlwifi/rtl8192ce/rf.c
drivers/net/wireless/rtlwifi/rtl8192ce/rf.h
drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
drivers/net/wireless/rtlwifi/rtl8192ce/sw.h
drivers/net/wireless/rtlwifi/rtl8192ce/trx.c
drivers/net/wireless/rtlwifi/rtl8192ce/trx.h
drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
drivers/net/wireless/rtlwifi/rtl8192cu/hw.h
drivers/net/wireless/rtlwifi/rtl8192cu/phy.c
drivers/net/wireless/rtlwifi/rtl8192cu/phy.h
drivers/net/wireless/rtlwifi/rtl8192cu/rf.c
drivers/net/wireless/rtlwifi/rtl8192cu/rf.h
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.c
drivers/net/wireless/rtlwifi/rtl8192cu/trx.h
drivers/net/wireless/rtlwifi/usb.c
drivers/net/wireless/rtlwifi/usb.h
drivers/net/wireless/rtlwifi/wifi.h
drivers/net/wireless/wl12xx/Kconfig
drivers/net/wireless/wl12xx/acx.c
drivers/net/wireless/wl12xx/acx.h
drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/boot.h
drivers/net/wireless/wl12xx/cmd.c
drivers/net/wireless/wl12xx/cmd.h
drivers/net/wireless/wl12xx/conf.h
drivers/net/wireless/wl12xx/debugfs.c
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/ini.h
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/init.h
drivers/net/wireless/wl12xx/io.c
drivers/net/wireless/wl12xx/io.h
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/ps.c
drivers/net/wireless/wl12xx/reg.h
drivers/net/wireless/wl12xx/rx.c
drivers/net/wireless/wl12xx/scan.c
drivers/net/wireless/wl12xx/sdio.c
drivers/net/wireless/wl12xx/sdio_test.c
drivers/net/wireless/wl12xx/spi.c
drivers/net/wireless/wl12xx/testmode.c
drivers/net/wireless/wl12xx/tx.c
drivers/net/wireless/wl12xx/tx.h
drivers/net/wireless/wl12xx/wl12xx.h
drivers/ssb/driver_chipcommon.c
drivers/ssb/driver_chipcommon_pmu.c
drivers/ssb/driver_pcicore.c
drivers/ssb/main.c
include/linux/ath9k_platform.h
include/linux/ssb/ssb_driver_chipcommon.h
include/linux/ssb/ssb_regs.h
include/linux/wl12xx.h
include/net/bluetooth/hci.h
include/net/bluetooth/hci_core.h
include/net/bluetooth/l2cap.h
include/net/bluetooth/mgmt.h
include/net/mac80211.h
net/bluetooth/cmtp/core.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/bluetooth/hci_sysfs.c
net/bluetooth/hidp/core.c
net/bluetooth/l2cap_core.c
net/bluetooth/l2cap_sock.c
net/bluetooth/mgmt.c
net/bluetooth/rfcomm/core.c
net/bluetooth/rfcomm/sock.c
net/mac80211/aes_ccm.c
net/mac80211/cfg.c
net/mac80211/driver-ops.h
net/mac80211/driver-trace.h
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/key.c
net/mac80211/main.c
net/mac80211/mesh.c
net/mac80211/mesh_hwmp.c
net/mac80211/pm.c
net/mac80211/rx.c
net/mac80211/sta_info.c
net/mac80211/status.c
net/mac80211/tx.c
net/mac80211/work.c
net/mac80211/wpa.c
net/wireless/core.c
net/wireless/reg.c

index 8420689..3510de2 100644 (file)
@@ -159,6 +159,11 @@ static void ath5k_hw_init_core_clock(struct ath5k_hw *ah)
        rxlat = AR5K_REG_MS(usec_reg, AR5K_USEC_RX_LATENCY_5211);
 
        /*
+        * Set default Tx frame to Tx data start delay
+        */
+       txf2txs = AR5K_INIT_TXF2TXD_START_DEFAULT;
+
+       /*
         * 5210 initvals don't include usec settings
         * so we need to use magic values here for
         * tx/rx latencies
index 5193ed5..6195639 100644 (file)
 #include <linux/ath9k_platform.h>
 #include "ath9k.h"
 
-const struct platform_device_id ath9k_platform_id_table[] = {
+static const struct platform_device_id ath9k_platform_id_table[] = {
        {
                .name = "ath9k",
                .driver_data = AR5416_AR9100_DEVID,
        },
+       {
+               .name = "ar934x_wmac",
+               .driver_data = AR9300_DEVID_AR9340,
+       },
        {},
 };
 
index 2e31c77..5a1f4f5 100644 (file)
@@ -899,12 +899,6 @@ void ath9k_hw_ani_init(struct ath_hw *ah)
         * check here default level should not modify INI setting.
         */
        if (use_new_ani(ah)) {
-               const struct ani_ofdm_level_entry *entry_ofdm;
-               const struct ani_cck_level_entry *entry_cck;
-
-               entry_ofdm = &ofdm_level_table[ATH9K_ANI_OFDM_DEF_LEVEL];
-               entry_cck = &cck_level_table[ATH9K_ANI_CCK_DEF_LEVEL];
-
                ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
                ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
        } else {
index 4a4cd88..f276cb9 100644 (file)
 #include "hw-ops.h"
 #include "ar9003_phy.h"
 
-#define MPASS  3
 #define MAX_MEASUREMENT        8
-#define MAX_DIFFERENCE 10
+#define MAX_MAG_DELTA  11
+#define MAX_PHS_DELTA  10
 
 struct coeff {
-       int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
-       int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT][MPASS];
+       int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
+       int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
        int iqc_coeff[2];
 };
 
@@ -185,17 +185,19 @@ static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
 
        /* Accumulate IQ cal measures for active chains */
        for (i = 0; i < AR5416_MAX_CHAINS; i++) {
-               ah->totalPowerMeasI[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
-               ah->totalPowerMeasQ[i] +=
-                       REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
-               ah->totalIqCorrMeas[i] +=
-                       (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
-               ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
-                       "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
-                       ah->cal_samples, i, ah->totalPowerMeasI[i],
-                       ah->totalPowerMeasQ[i],
-                       ah->totalIqCorrMeas[i]);
+               if (ah->txchainmask & BIT(i)) {
+                       ah->totalPowerMeasI[i] +=
+                               REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
+                       ah->totalPowerMeasQ[i] +=
+                               REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
+                       ah->totalIqCorrMeas[i] +=
+                               (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
+                       ath_dbg(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
+                               "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
+                               ah->cal_samples, i, ah->totalPowerMeasI[i],
+                               ah->totalPowerMeasQ[i],
+                               ah->totalIqCorrMeas[i]);
+               }
        }
 }
 
@@ -608,36 +610,48 @@ static bool ar9003_hw_calc_iq_corr(struct ath_hw *ah,
        return true;
 }
 
-static bool ar9003_hw_compute_closest_pass_and_avg(int *mp_coeff, int *mp_avg)
+static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
+                                    int max_delta)
 {
-       int diff[MPASS];
-
-       diff[0] = abs(mp_coeff[0] - mp_coeff[1]);
-       diff[1] = abs(mp_coeff[1] - mp_coeff[2]);
-       diff[2] = abs(mp_coeff[2] - mp_coeff[0]);
-
-       if (diff[0] > MAX_DIFFERENCE &&
-           diff[1] > MAX_DIFFERENCE &&
-           diff[2] > MAX_DIFFERENCE)
-               return false;
+       int mp_max = -64, max_idx = 0;
+       int mp_min = 63, min_idx = 0;
+       int mp_avg = 0, i, outlier_idx = 0;
+
+       /* find min/max mismatch across all calibrated gains */
+       for (i = 0; i < nmeasurement; i++) {
+               mp_avg += mp_coeff[i];
+               if (mp_coeff[i] > mp_max) {
+                       mp_max = mp_coeff[i];
+                       max_idx = i;
+               } else if (mp_coeff[i] < mp_min) {
+                       mp_min = mp_coeff[i];
+                       min_idx = i;
+               }
+       }
 
-       if (diff[0] <= diff[1] && diff[0] <= diff[2])
-               *mp_avg = (mp_coeff[0] + mp_coeff[1]) / 2;
-       else if (diff[1] <= diff[2])
-               *mp_avg = (mp_coeff[1] + mp_coeff[2]) / 2;
-       else
-               *mp_avg = (mp_coeff[2] + mp_coeff[0]) / 2;
+       /* find average (exclude max abs value) */
+       for (i = 0; i < nmeasurement; i++) {
+               if ((abs(mp_coeff[i]) < abs(mp_max)) ||
+                   (abs(mp_coeff[i]) < abs(mp_min)))
+                       mp_avg += mp_coeff[i];
+       }
+       mp_avg /= (nmeasurement - 1);
 
-       return true;
+       /* detect outlier */
+       if (abs(mp_max - mp_min) > max_delta) {
+               if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
+                       outlier_idx = max_idx;
+               else
+                       outlier_idx = min_idx;
+       }
+       mp_coeff[outlier_idx] = mp_avg;
 }
 
 static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
                                                 u8 num_chains,
                                                 struct coeff *coeff)
 {
-       struct ath_common *common = ath9k_hw_common(ah);
        int i, im, nmeasurement;
-       int magnitude, phase;
        u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
 
        memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
@@ -657,37 +671,28 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
 
        /* Load the average of 2 passes */
        for (i = 0; i < num_chains; i++) {
-               if (AR_SREV_9485(ah))
-                       nmeasurement = REG_READ_FIELD(ah,
-                                       AR_PHY_TX_IQCAL_STATUS_B0_9485,
-                                       AR_PHY_CALIBRATED_GAINS_0);
-               else
-                       nmeasurement = REG_READ_FIELD(ah,
-                                       AR_PHY_TX_IQCAL_STATUS_B0,
-                                       AR_PHY_CALIBRATED_GAINS_0);
+               nmeasurement = REG_READ_FIELD(ah,
+                               AR_PHY_TX_IQCAL_STATUS_B0,
+                               AR_PHY_CALIBRATED_GAINS_0);
 
                if (nmeasurement > MAX_MEASUREMENT)
                        nmeasurement = MAX_MEASUREMENT;
 
-               for (im = 0; im < nmeasurement; im++) {
-                       /*
-                        * Determine which 2 passes are closest and compute avg
-                        * magnitude
-                        */
-                       if (!ar9003_hw_compute_closest_pass_and_avg(coeff->mag_coeff[i][im],
-                                                                   &magnitude))
-                               goto disable_txiqcal;
+               /* detect outlier only if nmeasurement > 1 */
+               if (nmeasurement > 1) {
+                       /* Detect magnitude outlier */
+                       ar9003_hw_detect_outlier(coeff->mag_coeff[i],
+                                       nmeasurement, MAX_MAG_DELTA);
 
-                       /*
-                        * Determine which 2 passes are closest and compute avg
-                        * phase
-                        */
-                       if (!ar9003_hw_compute_closest_pass_and_avg(coeff->phs_coeff[i][im],
-                                                                   &phase))
-                               goto disable_txiqcal;
+                       /* Detect phase outlier */
+                       ar9003_hw_detect_outlier(coeff->phs_coeff[i],
+                                       nmeasurement, MAX_PHS_DELTA);
+               }
+
+               for (im = 0; im < nmeasurement; im++) {
 
-                       coeff->iqc_coeff[0] = (magnitude & 0x7f) |
-                                             ((phase & 0x7f) << 7);
+                       coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
+                               ((coeff->phs_coeff[i][im] & 0x7f) << 7);
 
                        if ((im % 2) == 0)
                                REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
@@ -707,141 +712,37 @@ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
 
        return;
 
-disable_txiqcal:
-       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
-                     AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x0);
-       REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
-                     AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x0);
-
-       ath_dbg(common, ATH_DBG_CALIBRATE, "TX IQ Cal disabled\n");
 }
 
-static void ar9003_hw_tx_iq_cal(struct ath_hw *ah)
+static bool ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       static const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
-               AR_PHY_TX_IQCAL_STATUS_B0,
-               AR_PHY_TX_IQCAL_STATUS_B1,
-               AR_PHY_TX_IQCAL_STATUS_B2,
-       };
-       static const u32 chan_info_tab[] = {
-               AR_PHY_CHAN_INFO_TAB_0,
-               AR_PHY_CHAN_INFO_TAB_1,
-               AR_PHY_CHAN_INFO_TAB_2,
-       };
-       struct coeff coeff;
-       s32 iq_res[6];
-       s32 i, j, ip, im, nmeasurement;
-       u8 nchains = get_streams(common->tx_chainmask);
-
-       for (ip = 0; ip < MPASS; ip++) {
-               REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
-                             AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
-                             DELPT);
-               REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
-                             AR_PHY_TX_IQCAL_START_DO_CAL,
-                             AR_PHY_TX_IQCAL_START_DO_CAL);
-
-               if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
-                                  AR_PHY_TX_IQCAL_START_DO_CAL,
-                                  0, AH_WAIT_TIMEOUT)) {
-                       ath_dbg(common, ATH_DBG_CALIBRATE,
-                               "Tx IQ Cal not complete.\n");
-                       goto TX_IQ_CAL_FAILED;
-               }
-
-               nmeasurement = REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_STATUS_B0,
-                                             AR_PHY_CALIBRATED_GAINS_0);
-                       if (nmeasurement > MAX_MEASUREMENT)
-                               nmeasurement = MAX_MEASUREMENT;
-
-               for (i = 0; i < nchains; i++) {
-                       ath_dbg(common, ATH_DBG_CALIBRATE,
-                               "Doing Tx IQ Cal for chain %d.\n", i);
-                       for (im = 0; im < nmeasurement; im++) {
-                               if (REG_READ(ah, txiqcal_status[i]) &
-                                            AR_PHY_TX_IQCAL_STATUS_FAILED) {
-                                       ath_dbg(common, ATH_DBG_CALIBRATE,
-                                               "Tx IQ Cal failed for chain %d.\n", i);
-                                       goto TX_IQ_CAL_FAILED;
-                               }
-
-                               for (j = 0; j < 3; j++) {
-                                       u8 idx = 2 * j,
-                                          offset = 4 * (3 * im + j);
-
-                                       REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
-                                                     AR_PHY_CHAN_INFO_TAB_S2_READ,
-                                                     0);
-
-                                       /* 32 bits */
-                                       iq_res[idx] = REG_READ(ah,
-                                                       chan_info_tab[i] +
-                                                       offset);
-
-                                       REG_RMW_FIELD(ah, AR_PHY_CHAN_INFO_MEMORY,
-                                                     AR_PHY_CHAN_INFO_TAB_S2_READ,
-                                                     1);
-
-                                       /* 16 bits */
-                                       iq_res[idx+1] = 0xffff & REG_READ(ah,
-                                                               chan_info_tab[i] +
-                                                               offset);
-
-                                       ath_dbg(common, ATH_DBG_CALIBRATE,
-                                               "IQ RES[%d]=0x%x IQ_RES[%d]=0x%x\n",
-                                               idx, iq_res[idx], idx+1, iq_res[idx+1]);
-                               }
-
-                               if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
-                                                           coeff.iqc_coeff)) {
-                                       ath_dbg(common, ATH_DBG_CALIBRATE,
-                                               "Failed in calculation of IQ correction.\n");
-                                       goto TX_IQ_CAL_FAILED;
-                               }
-                               coeff.mag_coeff[i][im][ip] =
-                                               coeff.iqc_coeff[0] & 0x7f;
-                               coeff.phs_coeff[i][im][ip] =
-                                               (coeff.iqc_coeff[0] >> 7) & 0x7f;
-
-                               if (coeff.mag_coeff[i][im][ip] > 63)
-                                       coeff.mag_coeff[i][im][ip] -= 128;
-                               if (coeff.phs_coeff[i][im][ip] > 63)
-                                       coeff.phs_coeff[i][im][ip] -= 128;
-
-                       }
-               }
-       }
-
-       ar9003_hw_tx_iqcal_load_avg_2_passes(ah, nchains, &coeff);
-
-       return;
-
-TX_IQ_CAL_FAILED:
-       ath_dbg(common, ATH_DBG_CALIBRATE, "Tx IQ Cal failed\n");
-}
-
-static void ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
-{
        u8 tx_gain_forced;
 
-       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1_9485,
-                     AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT, DELPT);
        tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
                                        AR_PHY_TXGAIN_FORCE);
        if (tx_gain_forced)
                REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
                              AR_PHY_TXGAIN_FORCE, 0);
 
-       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START_9485,
-                     AR_PHY_TX_IQCAL_START_DO_CAL_9485, 1);
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
+                     AR_PHY_TX_IQCAL_START_DO_CAL, 1);
+
+       if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
+                       AR_PHY_TX_IQCAL_START_DO_CAL, 0,
+                       AH_WAIT_TIMEOUT)) {
+               ath_dbg(common, ATH_DBG_CALIBRATE,
+                       "Tx IQ Cal is not completed.\n");
+               return false;
+       }
+       return true;
 }
 
 static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
        const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
-               AR_PHY_TX_IQCAL_STATUS_B0_9485,
+               AR_PHY_TX_IQCAL_STATUS_B0,
                AR_PHY_TX_IQCAL_STATUS_B1,
                AR_PHY_TX_IQCAL_STATUS_B2,
        };
@@ -853,7 +754,7 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
        struct coeff coeff;
        s32 iq_res[6];
        u8 num_chains = 0;
-       int i, ip, im, j;
+       int i, im, j;
        int nmeasurement;
 
        for (i = 0; i < AR9300_MAX_CHAINS; i++) {
@@ -861,71 +762,69 @@ static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
                        num_chains++;
        }
 
-       for (ip = 0; ip < MPASS; ip++) {
-               for (i = 0; i < num_chains; i++) {
-                       nmeasurement = REG_READ_FIELD(ah,
-                                       AR_PHY_TX_IQCAL_STATUS_B0_9485,
-                                       AR_PHY_CALIBRATED_GAINS_0);
-                       if (nmeasurement > MAX_MEASUREMENT)
-                               nmeasurement = MAX_MEASUREMENT;
+       for (i = 0; i < num_chains; i++) {
+               nmeasurement = REG_READ_FIELD(ah,
+                               AR_PHY_TX_IQCAL_STATUS_B0,
+                               AR_PHY_CALIBRATED_GAINS_0);
+               if (nmeasurement > MAX_MEASUREMENT)
+                       nmeasurement = MAX_MEASUREMENT;
 
-                       for (im = 0; im < nmeasurement; im++) {
-                               ath_dbg(common, ATH_DBG_CALIBRATE,
-                                       "Doing Tx IQ Cal for chain %d.\n", i);
+               for (im = 0; im < nmeasurement; im++) {
+                       ath_dbg(common, ATH_DBG_CALIBRATE,
+                               "Doing Tx IQ Cal for chain %d.\n", i);
 
-                               if (REG_READ(ah, txiqcal_status[i]) &
-                                   AR_PHY_TX_IQCAL_STATUS_FAILED) {
-                                       ath_dbg(common, ATH_DBG_CALIBRATE,
+                       if (REG_READ(ah, txiqcal_status[i]) &
+                                       AR_PHY_TX_IQCAL_STATUS_FAILED) {
+                               ath_dbg(common, ATH_DBG_CALIBRATE,
                                        "Tx IQ Cal failed for chain %d.\n", i);
-                                       goto tx_iqcal_fail;
-                               }
+                               goto tx_iqcal_fail;
+                       }
 
-                               for (j = 0; j < 3; j++) {
-                                       u32 idx = 2 * j, offset = 4 * (3 * im + j);
+                       for (j = 0; j < 3; j++) {
+                               u32 idx = 2 * j, offset = 4 * (3 * im + j);
 
-                                       REG_RMW_FIELD(ah,
+                               REG_RMW_FIELD(ah,
                                                AR_PHY_CHAN_INFO_MEMORY,
                                                AR_PHY_CHAN_INFO_TAB_S2_READ,
                                                0);
 
-                                       /* 32 bits */
-                                       iq_res[idx] = REG_READ(ah,
-                                                       chan_info_tab[i] +
-                                                       offset);
+                               /* 32 bits */
+                               iq_res[idx] = REG_READ(ah,
+                                               chan_info_tab[i] +
+                                               offset);
 
-                                       REG_RMW_FIELD(ah,
+                               REG_RMW_FIELD(ah,
                                                AR_PHY_CHAN_INFO_MEMORY,
                                                AR_PHY_CHAN_INFO_TAB_S2_READ,
                                                1);
 
-                                       /* 16 bits */
-                                       iq_res[idx + 1] = 0xffff & REG_READ(ah,
-                                                         chan_info_tab[i] + offset);
+                               /* 16 bits */
+                               iq_res[idx + 1] = 0xffff & REG_READ(ah,
+                                               chan_info_tab[i] + offset);
 
-                                       ath_dbg(common, ATH_DBG_CALIBRATE,
-                                               "IQ RES[%d]=0x%x"
-                                               "IQ_RES[%d]=0x%x\n",
-                                               idx, iq_res[idx], idx + 1,
-                                               iq_res[idx + 1]);
-                               }
+                               ath_dbg(common, ATH_DBG_CALIBRATE,
+                                       "IQ RES[%d]=0x%x"
+                                       "IQ_RES[%d]=0x%x\n",
+                                       idx, iq_res[idx], idx + 1,
+                                       iq_res[idx + 1]);
+                       }
 
-                               if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
-                                                           coeff.iqc_coeff)) {
-                                       ath_dbg(common, ATH_DBG_CALIBRATE,
-                                        "Failed in calculation of IQ correction.\n");
-                                       goto tx_iqcal_fail;
-                               }
+                       if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
+                                               coeff.iqc_coeff)) {
+                               ath_dbg(common, ATH_DBG_CALIBRATE,
+                                       "Failed in calculation of \
+                                       IQ correction.\n");
+                               goto tx_iqcal_fail;
+                       }
 
-                               coeff.mag_coeff[i][im][ip] =
-                                               coeff.iqc_coeff[0] & 0x7f;
-                               coeff.phs_coeff[i][im][ip] =
-                                               (coeff.iqc_coeff[0] >> 7) & 0x7f;
+                       coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
+                       coeff.phs_coeff[i][im] =
+                               (coeff.iqc_coeff[0] >> 7) & 0x7f;
 
-                               if (coeff.mag_coeff[i][im][ip] > 63)
-                                       coeff.mag_coeff[i][im][ip] -= 128;
-                               if (coeff.phs_coeff[i][im][ip] > 63)
-                                       coeff.phs_coeff[i][im][ip] -= 128;
-                       }
+                       if (coeff.mag_coeff[i][im] > 63)
+                               coeff.mag_coeff[i][im] -= 128;
+                       if (coeff.phs_coeff[i][im] > 63)
+                               coeff.phs_coeff[i][im] -= 128;
                }
        }
        ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
@@ -940,31 +839,37 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                               struct ath9k_channel *chan)
 {
        struct ath_common *common = ath9k_hw_common(ah);
+       struct ath9k_hw_capabilities *pCap = &ah->caps;
        int val;
+       bool txiqcal_done = false;
 
        val = REG_READ(ah, AR_ENT_OTP);
        ath_dbg(common, ATH_DBG_CALIBRATE, "ath9k: AR_ENT_OTP 0x%x\n", val);
 
-       if (AR_SREV_9485(ah))
-               ar9003_hw_set_chain_masks(ah, 0x1, 0x1);
-       else if (val & AR_ENT_OTP_CHAIN2_DISABLE)
+       /* Configure rx/tx chains before running AGC/TxiQ cals */
+       if (val & AR_ENT_OTP_CHAIN2_DISABLE)
                ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
        else
-               /*
-                * 0x7 = 0b111 , AR9003 needs to be configured for 3-chain
-                * mode before running AGC/TxIQ cals
-                */
-               ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+               ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
+                                         pCap->tx_chainmask);
 
        /* Do Tx IQ Calibration */
-       if (AR_SREV_9485(ah))
-               ar9003_hw_tx_iq_cal_run(ah);
-       else
-               ar9003_hw_tx_iq_cal(ah);
+       REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
+                     AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
+                     DELPT);
 
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
-       udelay(5);
-       REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+       /*
+        * For AR9485 or later chips, TxIQ cal runs as part of
+        * AGC calibration
+        */
+       if (AR_SREV_9485_OR_LATER(ah))
+               txiqcal_done = true;
+       else {
+               txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
+               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
+               udelay(5);
+               REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
+       }
 
        /* Calibrate the AGC */
        REG_WRITE(ah, AR_PHY_AGC_CONTROL,
@@ -979,7 +884,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
                return false;
        }
 
-       if (AR_SREV_9485(ah))
+       if (txiqcal_done)
                ar9003_hw_tx_iq_cal_post_proc(ah);
 
        /* Revert chainmasks to their original values before NF cal */
index 6eadf97..fb892e5 100644 (file)
@@ -3217,7 +3217,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
                                    u8 *word, int length, int mdata_size)
 {
        struct ath_common *common = ath9k_hw_common(ah);
-       u8 *dptr;
        const struct ar9300_eeprom *eep = NULL;
 
        switch (code) {
@@ -3235,7 +3234,6 @@ static int ar9300_compress_decision(struct ath_hw *ah,
                break;
        case _CompressBlock:
                if (reference == 0) {
-                       dptr = mptr;
                } else {
                        eep = ar9003_eeprom_struct_find_by_id(reference);
                        if (eep == NULL) {
@@ -3448,9 +3446,13 @@ static void ar9003_hw_xpa_bias_level_apply(struct ath_hw *ah, bool is2ghz)
                REG_RMW_FIELD(ah, AR_CH0_TOP2, AR_CH0_TOP2_XPABIASLVL, bias);
        else {
                REG_RMW_FIELD(ah, AR_CH0_TOP, AR_CH0_TOP_XPABIASLVL, bias);
-               REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPABIASLVL_MSB,
-                             bias >> 2);
-               REG_RMW_FIELD(ah, AR_CH0_THERM, AR_CH0_THERM_XPASHORT2GND, 1);
+               if (!AR_SREV_9340(ah)) {
+                       REG_RMW_FIELD(ah, AR_CH0_THERM,
+                                     AR_CH0_THERM_XPABIASLVL_MSB,
+                                     bias >> 2);
+                       REG_RMW_FIELD(ah, AR_CH0_THERM,
+                                     AR_CH0_THERM_XPASHORT2GND, 1);
+               }
        }
 }
 
@@ -3497,23 +3499,28 @@ static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah,
 
 static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
 {
+       int chain;
+       static const u32 switch_chain_reg[AR9300_MAX_CHAINS] = {
+                       AR_PHY_SWITCH_CHAIN_0,
+                       AR_PHY_SWITCH_CHAIN_1,
+                       AR_PHY_SWITCH_CHAIN_2,
+       };
+
        u32 value = ar9003_hw_ant_ctrl_common_get(ah, is2ghz);
+
        REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM, AR_SWITCH_TABLE_COM_ALL, value);
 
        value = ar9003_hw_ant_ctrl_common_2_get(ah, is2ghz);
        REG_RMW_FIELD(ah, AR_PHY_SWITCH_COM_2, AR_SWITCH_TABLE_COM2_ALL, value);
 
-       value = ar9003_hw_ant_ctrl_chain_get(ah, 0, is2ghz);
-       REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_0, AR_SWITCH_TABLE_ALL, value);
-
-       if (!AR_SREV_9485(ah)) {
-               value = ar9003_hw_ant_ctrl_chain_get(ah, 1, is2ghz);
-               REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_1, AR_SWITCH_TABLE_ALL,
-                             value);
-
-               value = ar9003_hw_ant_ctrl_chain_get(ah, 2, is2ghz);
-               REG_RMW_FIELD(ah, AR_PHY_SWITCH_CHAIN_2, AR_SWITCH_TABLE_ALL,
-                             value);
+       for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
+               if ((ah->rxchainmask & BIT(chain)) ||
+                   (ah->txchainmask & BIT(chain))) {
+                       value = ar9003_hw_ant_ctrl_chain_get(ah, chain,
+                                                            is2ghz);
+                       REG_RMW_FIELD(ah, switch_chain_reg[chain],
+                                     AR_SWITCH_TABLE_ALL, value);
+               }
        }
 
        if (AR_SREV_9485(ah)) {
@@ -3634,13 +3641,16 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
 
        /* Test value. if 0 then attenuation is unused. Don't load anything. */
        for (i = 0; i < 3; i++) {
-               value = ar9003_hw_atten_chain_get(ah, i, chan);
-               REG_RMW_FIELD(ah, ext_atten_reg[i],
-                             AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
-
-               value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
-               REG_RMW_FIELD(ah, ext_atten_reg[i],
-                             AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN, value);
+               if (ah->txchainmask & BIT(i)) {
+                       value = ar9003_hw_atten_chain_get(ah, i, chan);
+                       REG_RMW_FIELD(ah, ext_atten_reg[i],
+                                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_DB, value);
+
+                       value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
+                       REG_RMW_FIELD(ah, ext_atten_reg[i],
+                                     AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
+                                     value);
+               }
        }
 }
 
@@ -3749,8 +3759,9 @@ static void ath9k_hw_ar9300_set_board_values(struct ath_hw *ah,
        ar9003_hw_ant_ctrl_apply(ah, IS_CHAN_2GHZ(chan));
        ar9003_hw_drive_strength_apply(ah);
        ar9003_hw_atten_apply(ah, chan);
-       ar9003_hw_internal_regulator_apply(ah);
-       if (AR_SREV_9485(ah))
+       if (!AR_SREV_9340(ah))
+               ar9003_hw_internal_regulator_apply(ah);
+       if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
                ar9003_hw_apply_tuning_caps(ah);
 }
 
index aebaad9..a55eddb 100644 (file)
@@ -18,6 +18,7 @@
 #include "ar9003_mac.h"
 #include "ar9003_2p2_initvals.h"
 #include "ar9485_initvals.h"
+#include "ar9340_initvals.h"
 
 /* General hardware code for the AR9003 hadware family */
 
  */
 static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 {
-       if (AR_SREV_9485_11(ah)) {
+       if (AR_SREV_9340(ah)) {
+               /* mac */
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
+                               ar9340_1p0_mac_core,
+                               ARRAY_SIZE(ar9340_1p0_mac_core), 2);
+               INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
+                               ar9340_1p0_mac_postamble,
+                               ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
+
+               /* bb */
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
+                               ar9340_1p0_baseband_core,
+                               ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
+               INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
+                               ar9340_1p0_baseband_postamble,
+                               ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
+
+               /* radio */
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
+                               ar9340_1p0_radio_core,
+                               ARRAY_SIZE(ar9340_1p0_radio_core), 2);
+               INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
+                               ar9340_1p0_radio_postamble,
+                               ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
+
+               /* soc */
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
+                               ar9340_1p0_soc_preamble,
+                               ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
+               INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
+                               ar9340_1p0_soc_postamble,
+                               ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
+
+               /* rx/tx gain */
+               INIT_INI_ARRAY(&ah->iniModesRxGain,
+                               ar9340Common_wo_xlna_rx_gain_table_1p0,
+                               ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
+                               5);
+               INIT_INI_ARRAY(&ah->iniModesTxGain,
+                               ar9340Modes_high_ob_db_tx_gain_table_1p0,
+                               ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
+                               5);
+
+               INIT_INI_ARRAY(&ah->iniModesAdditional,
+                               ar9340Modes_fast_clock_1p0,
+                               ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
+                               3);
+
+               INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
+                               ar9340_1p0_radio_core_40M,
+                               ARRAY_SIZE(ar9340_1p0_radio_core_40M),
+                               2);
+       } else if (AR_SREV_9485_11(ah)) {
                /* mac */
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
                INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@@ -163,7 +220,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
        switch (ar9003_hw_get_tx_gain_idx(ah)) {
        case 0:
        default:
-               if (AR_SREV_9485_11(ah))
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485_modes_lowest_ob_db_tx_gain_1_1,
                                       ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
@@ -175,7 +237,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
                                       5);
                break;
        case 1:
-               if (AR_SREV_9485_11(ah))
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485Modes_high_ob_db_tx_gain_1_1,
                                       ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
@@ -187,7 +254,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
                                       5);
                break;
        case 2:
-               if (AR_SREV_9485_11(ah))
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485Modes_low_ob_db_tx_gain_1_1,
                                       ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
@@ -199,7 +271,12 @@ static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
                                       5);
                break;
        case 3:
-               if (AR_SREV_9485_11(ah))
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesTxGain,
+                                       ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
+                                      5);
+               else if (AR_SREV_9485_11(ah))
                        INIT_INI_ARRAY(&ah->iniModesTxGain,
                                       ar9485Modes_high_power_tx_gain_1_1,
                                       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
@@ -218,7 +295,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
        switch (ar9003_hw_get_rx_gain_idx(ah)) {
        case 0:
        default:
-               if (AR_SREV_9485_11(ah))
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9340Common_rx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
+                                      2);
+               else if (AR_SREV_9485_11(ah))
                        INIT_INI_ARRAY(&ah->iniModesRxGain,
                                       ar9485Common_wo_xlna_rx_gain_1_1,
                                       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
@@ -230,7 +312,12 @@ static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
                                       2);
                break;
        case 1:
-               if (AR_SREV_9485_11(ah))
+               if (AR_SREV_9340(ah))
+                       INIT_INI_ARRAY(&ah->iniModesRxGain,
+                                      ar9340Common_wo_xlna_rx_gain_table_1p0,
+                                      ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
+                                      2);
+               else if (AR_SREV_9485_11(ah))
                        INIT_INI_ARRAY(&ah->iniModesRxGain,
                                       ar9485Common_wo_xlna_rx_gain_1_1,
                                       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
index 1bc33f5..c83be2d 100644 (file)
@@ -86,14 +86,31 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
                        channelSel = (freq * 4) / 120;
                        chan_frac = (((freq * 4) % 120) * 0x20000) / 120;
                        channelSel = (channelSel << 17) | chan_frac;
+               } else if (AR_SREV_9340(ah)) {
+                       if (ah->is_clk_25mhz) {
+                               u32 chan_frac;
+
+                               channelSel = (freq * 2) / 75;
+                               chan_frac = (((freq * 2) % 75) * 0x20000) / 75;
+                               channelSel = (channelSel << 17) | chan_frac;
+                       } else
+                               channelSel = CHANSEL_2G(freq) >> 1;
                } else
                        channelSel = CHANSEL_2G(freq);
                /* Set to 2G mode */
                bMode = 1;
        } else {
-               channelSel = CHANSEL_5G(freq);
-               /* Doubler is ON, so, divide channelSel by 2. */
-               channelSel >>= 1;
+               if (AR_SREV_9340(ah) && ah->is_clk_25mhz) {
+                       u32 chan_frac;
+
+                       channelSel = (freq * 2) / 75;
+                       chan_frac = ((freq % 75) * 0x20000) / 75;
+                       channelSel = (channelSel << 17) | chan_frac;
+               } else {
+                       channelSel = CHANSEL_5G(freq);
+                       /* Doubler is ON, so, divide channelSel by 2. */
+                       channelSel >>= 1;
+               }
                /* Set to 5G mode */
                bMode = 0;
        }
@@ -151,7 +168,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
         * is out-of-band and can be ignored.
         */
 
-       if (AR_SREV_9485(ah)) {
+       if (AR_SREV_9485(ah) || AR_SREV_9340(ah)) {
                spur_fbin_ptr = ar9003_get_spur_chan_ptr(ah,
                                                         IS_CHAN_2GHZ(chan));
                if (spur_fbin_ptr[0] == 0) /* No spur */
@@ -176,7 +193,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah,
 
        for (i = 0; i < max_spur_cnts; i++) {
                negative = 0;
-               if (AR_SREV_9485(ah))
+               if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
                        cur_bb_spur = FBIN2FREQ(spur_fbin_ptr[i],
                                        IS_CHAN_2GHZ(chan)) - synth_freq;
                else
@@ -599,29 +616,25 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
        struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
        unsigned int regWrites = 0, i;
        struct ieee80211_channel *channel = chan->chan;
-       u32 modesIndex, freqIndex;
+       u32 modesIndex;
 
        switch (chan->chanmode) {
        case CHANNEL_A:
        case CHANNEL_A_HT20:
                modesIndex = 1;
-               freqIndex = 1;
                break;
        case CHANNEL_A_HT40PLUS:
        case CHANNEL_A_HT40MINUS:
                modesIndex = 2;
-               freqIndex = 1;
                break;
        case CHANNEL_G:
        case CHANNEL_G_HT20:
        case CHANNEL_B:
                modesIndex = 4;
-               freqIndex = 2;
                break;
        case CHANNEL_G_HT40PLUS:
        case CHANNEL_G_HT40MINUS:
                modesIndex = 3;
-               freqIndex = 2;
                break;
 
        default:
@@ -646,6 +659,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
                REG_WRITE_ARRAY(&ah->iniModesAdditional,
                                modesIndex, regWrites);
 
+       if (AR_SREV_9340(ah) && !ah->is_clk_25mhz)
+               REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites);
+
        ar9003_hw_override_ini(ah);
        ar9003_hw_set_channel_regs(ah, chan);
        ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
index 8bdda2c..2a0d5cb 100644 (file)
 
 #define AR_PHY_TXGAIN_TABLE      (AR_SM_BASE + 0x300)
 
-#define AR_PHY_TX_IQCAL_START_9485             (AR_SM_BASE + 0x3c4)
-#define AR_PHY_TX_IQCAL_START_DO_CAL_9485      0x80000000
-#define AR_PHY_TX_IQCAL_START_DO_CAL_9485_S    31
-#define AR_PHY_TX_IQCAL_CONTROL_1_9485         (AR_SM_BASE + 0x3c8)
-#define AR_PHY_TX_IQCAL_STATUS_B0_9485         (AR_SM_BASE + 0x3f0)
-
-#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)
+#define AR_PHY_TX_IQCAL_CONTROL_1   (AR_SM_BASE + AR_SREV_9485(ah) ? \
+                                                0x3c8 : 0x448)
+#define AR_PHY_TX_IQCAL_START       (AR_SM_BASE + AR_SREV_9485(ah) ? \
+                                                0x3c4 : 0x440)
+#define AR_PHY_TX_IQCAL_STATUS_B0   (AR_SM_BASE + AR_SREV_9485(ah) ? \
+                                                0x3f0 : 0x48c)
 #define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i)    (AR_SM_BASE + \
                                             (AR_SREV_9485(ah) ? \
                                              0x3d0 : 0x450) + ((_i) << 2))
 #define AR_PHY_65NM_CH0_BIAS2       0x160c4
 #define AR_PHY_65NM_CH0_BIAS4       0x160cc
 #define AR_PHY_65NM_CH0_RXTX4       0x1610c
-#define AR_PHY_65NM_CH0_THERM       (AR_SREV_9485(ah) ? 0x1628c : 0x16290)
+#define AR_PHY_65NM_CH0_THERM       (AR_SREV_9300(ah) ? 0x16290 : 0x1628c)
 
 #define AR_PHY_65NM_CH0_THERM_LOCAL   0x80000000
 #define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
 #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT   0x01000000
 #define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S 24
 #define AR_PHY_CHANNEL_STATUS_RX_CLEAR      0x00000004
-#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000
-#define AR_PHY_TX_IQCAQL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18
-#define AR_PHY_TX_IQCAL_START_DO_CAL        0x00000001
-#define AR_PHY_TX_IQCAL_START_DO_CAL_S      0
+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT             0x01fc0000
+#define AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT_S                   18
+#define AR_PHY_TX_IQCAL_START_DO_CAL       0x00000001
+#define AR_PHY_TX_IQCAL_START_DO_CAL_S     0
 
 #define AR_PHY_TX_IQCAL_STATUS_FAILED    0x00000001
 #define AR_PHY_CALIBRATED_GAINS_0       0x3e
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
new file mode 100644 (file)
index 0000000..815a8af
--- /dev/null
@@ -0,0 +1,1525 @@
+/*
+ * Copyright (c) 2011 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.
+ */
+
+#ifndef INITVALS_9340_H
+#define INITVALS_9340_H
+
+static const u32 ar9340_1p0_radio_postamble[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x000160ac, 0xa4646800, 0xa4646800, 0xa4646800, 0xa4646800},
+       {0x0001610c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+       {0x00016140, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+       {0x0001650c, 0x08000000, 0x08000000, 0x00000000, 0x00000000},
+       {0x00016540, 0x10804000, 0x10804000, 0x50804000, 0x50804000},
+};
+
+static const u32 ar9340Modes_lowest_ob_db_tx_gain_table_1p0[][5] = {
+       /*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {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},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+       {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_fast_clock_1p0[][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, 0x0000000b, 0x00000016},
+       {0x0000a254, 0x00000898, 0x00001130},
+};
+
+static const u32 ar9340_1p0_radio_core[][2] = {
+       /*  Addr     allmodes  */
+       {0x00016000, 0x36db6db6},
+       {0x00016004, 0x6db6db40},
+       {0x00016008, 0x73f00000},
+       {0x0001600c, 0x00000000},
+       {0x00016040, 0x7f80fff8},
+       {0x00016044, 0x03b6d2db},
+       {0x00016048, 0x24925266},
+       {0x0001604c, 0x000f0278},
+       {0x00016050, 0x6db6db6c},
+       {0x00016054, 0x6db60000},
+       {0x00016080, 0x00080000},
+       {0x00016084, 0x0e48048c},
+       {0x00016088, 0x14214514},
+       {0x0001608c, 0x119f081c},
+       {0x00016090, 0x24926490},
+       {0x00016094, 0x00000000},
+       {0x00016098, 0xd411eb84},
+       {0x0001609c, 0x03e47f32},
+       {0x000160a0, 0xc2108ffe},
+       {0x000160a4, 0x812fc370},
+       {0x000160a8, 0x423c8000},
+       {0x000160ac, 0xa4646800},
+       {0x000160b0, 0x00fe7f46},
+       {0x000160b4, 0x92480000},
+       {0x000160c0, 0x006db6db},
+       {0x000160c4, 0x6db6db60},
+       {0x000160c8, 0x6db6db6c},
+       {0x000160cc, 0x6de6db6c},
+       {0x000160d0, 0xb6da4924},
+       {0x00016100, 0x04cb0001},
+       {0x00016104, 0xfff80000},
+       {0x00016108, 0x00080010},
+       {0x0001610c, 0x00000000},
+       {0x00016140, 0x50804008},
+       {0x00016144, 0x01884080},
+       {0x00016148, 0x000080c0},
+       {0x00016280, 0x01000015},
+       {0x00016284, 0x05530000},
+       {0x00016288, 0x00318000},
+       {0x0001628c, 0x50000000},
+       {0x00016290, 0x4080294f},
+       {0x00016380, 0x00000000},
+       {0x00016384, 0x00000000},
+       {0x00016388, 0x00800700},
+       {0x0001638c, 0x00800700},
+       {0x00016390, 0x00800700},
+       {0x00016394, 0x00000000},
+       {0x00016398, 0x00000000},
+       {0x0001639c, 0x00000000},
+       {0x000163a0, 0x00000001},
+       {0x000163a4, 0x00000001},
+       {0x000163a8, 0x00000000},
+       {0x000163ac, 0x00000000},
+       {0x000163b0, 0x00000000},
+       {0x000163b4, 0x00000000},
+       {0x000163b8, 0x00000000},
+       {0x000163bc, 0x00000000},
+       {0x000163c0, 0x000000a0},
+       {0x000163c4, 0x000c0000},
+       {0x000163c8, 0x14021402},
+       {0x000163cc, 0x00001402},
+       {0x000163d0, 0x00000000},
+       {0x000163d4, 0x00000000},
+       {0x00016400, 0x36db6db6},
+       {0x00016404, 0x6db6db40},
+       {0x00016408, 0x73f00000},
+       {0x0001640c, 0x00000000},
+       {0x00016440, 0x7f80fff8},
+       {0x00016444, 0x03b6d2db},
+       {0x00016448, 0x24927266},
+       {0x0001644c, 0x000f0278},
+       {0x00016450, 0x6db6db6c},
+       {0x00016454, 0x6db60000},
+       {0x00016500, 0x04cb0001},
+       {0x00016504, 0xfff80000},
+       {0x00016508, 0x00080010},
+       {0x0001650c, 0x00000000},
+       {0x00016540, 0x50804008},
+       {0x00016544, 0x01884080},
+       {0x00016548, 0x000080c0},
+       {0x00016780, 0x00000000},
+       {0x00016784, 0x00000000},
+       {0x00016788, 0x00800700},
+       {0x0001678c, 0x00800700},
+       {0x00016790, 0x00800700},
+       {0x00016794, 0x00000000},
+       {0x00016798, 0x00000000},
+       {0x0001679c, 0x00000000},
+       {0x000167a0, 0x00000001},
+       {0x000167a4, 0x00000001},
+       {0x000167a8, 0x00000000},
+       {0x000167ac, 0x00000000},
+       {0x000167b0, 0x00000000},
+       {0x000167b4, 0x00000000},
+       {0x000167b8, 0x00000000},
+       {0x000167bc, 0x00000000},
+       {0x000167c0, 0x000000a0},
+       {0x000167c4, 0x000c0000},
+       {0x000167c8, 0x14021402},
+       {0x000167cc, 0x00001402},
+       {0x000167d0, 0x00000000},
+       {0x000167d4, 0x00000000},
+};
+
+static const u32 ar9340_1p0_radio_core_40M[][2] = {
+       {0x0001609c, 0x02566f3a},
+       {0x000160ac, 0xa4647c00},
+       {0x000160b0, 0x01885f5a},
+};
+
+static const u32 ar9340_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 ar9340_1p0_soc_postamble[][5] = {
+       /*   Addr     5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x00007010, 0x00000023, 0x00000023, 0x00000023, 0x00000023},
+};
+
+static const u32 ar9340_1p0_baseband_postamble[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a8011},
+       {0x00009820, 0x206a022e, 0x206a022e, 0x206a022e, 0x206a022e},
+       {0x00009824, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0},
+       {0x00009828, 0x06903081, 0x06903081, 0x06903881, 0x06903881},
+       {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
+       {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
+       {0x00009c00, 0x00000044, 0x000000c4, 0x000000c4, 0x00000044},
+       {0x00009e00, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0},
+       {0x00009e04, 0x00182020, 0x00182020, 0x00182020, 0x00182020},
+       {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000e2},
+       {0x00009e10, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e},
+       {0x00009e14, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e},
+       {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
+       {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
+       {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
+       {0x00009e44, 0x02321e27, 0x02321e27, 0x02291e27, 0x02291e27},
+       {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
+       {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
+       {0x0000a204, 0x00003fc0, 0x00003fc4, 0x00003fc4, 0x00003fc0},
+       {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
+       {0x0000a230, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b},
+       {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, 0x00000220, 0x00000220, 0x00000110, 0x00000110},
+       {0x0000a28c, 0x00011111, 0x00011111, 0x00022222, 0x00022222},
+       {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
+       {0x0000a2d0, 0x00071981, 0x00071981, 0x00071981, 0x00071982},
+       {0x0000a2d8, 0xf999a83a, 0xf999a83a, 0xf999a83a, 0xf999a83a},
+       {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000ae04, 0x00180000, 0x00180000, 0x00180000, 0x00180000},
+       {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
+       {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
+       {0x0000b284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
+};
+
+static const u32 ar9340_1p0_baseband_core[][2] = {
+       /*  Addr     allmodes  */
+       {0x00009800, 0xafe68e30},
+       {0x00009804, 0xfd14e000},
+       {0x00009808, 0x9c0a9f6b},
+       {0x0000980c, 0x04900000},
+       {0x00009814, 0xb280c00a},
+       {0x00009818, 0x00000000},
+       {0x0000981c, 0x00020028},
+       {0x00009834, 0x5f3ca3de},
+       {0x00009838, 0x0108ecff},
+       {0x0000983c, 0x14750600},
+       {0x00009880, 0x201fff00},
+       {0x00009884, 0x00001042},
+       {0x000098a4, 0x00200400},
+       {0x000098b0, 0x52440bbe},
+       {0x000098d0, 0x004b6a8e},
+       {0x000098d4, 0x00000820},
+       {0x000098dc, 0x00000000},
+       {0x000098f0, 0x00000000},
+       {0x000098f4, 0x00000000},
+       {0x00009c04, 0xff55ff55},
+       {0x00009c08, 0x0320ff55},
+       {0x00009c0c, 0x00000000},
+       {0x00009c10, 0x00000000},
+       {0x00009c14, 0x00046384},
+       {0x00009c18, 0x05b6b440},
+       {0x00009c1c, 0x00b6b440},
+       {0x00009d00, 0xc080a333},
+       {0x00009d04, 0x40206c10},
+       {0x00009d08, 0x009c4060},
+       {0x00009d0c, 0x9883800a},
+       {0x00009d10, 0x01834061},
+       {0x00009d14, 0x00c0040b},
+       {0x00009d18, 0x00000000},
+       {0x00009e08, 0x0038230c},
+       {0x00009e24, 0x990bb515},
+       {0x00009e28, 0x0c6f0000},
+       {0x00009e30, 0x06336f77},
+       {0x00009e34, 0x6af6532f},
+       {0x00009e38, 0x0cc80c00},
+       {0x00009e3c, 0xcf946222},
+       {0x00009e40, 0x0d261820},
+       {0x00009e4c, 0x00001004},
+       {0x00009e50, 0x00ff03f1},
+       {0x00009e54, 0x00000000},
+       {0x00009fc0, 0x803e4788},
+       {0x00009fc4, 0x0001efb5},
+       {0x00009fcc, 0x40000014},
+       {0x00009fd0, 0x01193b93},
+       {0x0000a20c, 0x00000000},
+       {0x0000a220, 0x00000000},
+       {0x0000a224, 0x00000000},
+       {0x0000a228, 0x10002310},
+       {0x0000a22c, 0x01036a1e},
+       {0x0000a234, 0x10000fff},
+       {0x0000a23c, 0x00000000},
+       {0x0000a244, 0x0c000000},
+       {0x0000a2a0, 0x00000001},
+       {0x0000a2c0, 0x00000001},
+       {0x0000a2c8, 0x00000000},
+       {0x0000a2cc, 0x18c43433},
+       {0x0000a2d4, 0x00000000},
+       {0x0000a2dc, 0x00000000},
+       {0x0000a2e0, 0x00000000},
+       {0x0000a2e4, 0x00000000},
+       {0x0000a2e8, 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, 0x00000246},
+       {0x0000a3f8, 0x0cdbd380},
+       {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, 0x04000080},
+       {0x0000a44c, 0x00000001},
+       {0x0000a450, 0x00010000},
+       {0x0000a458, 0x00000000},
+       {0x0000a600, 0x00000000},
+       {0x0000a604, 0x00000000},
+       {0x0000a608, 0x00000000},
+       {0x0000a60c, 0x00000000},
+       {0x0000a610, 0x00000000},
+       {0x0000a614, 0x00000000},
+       {0x0000a618, 0x00000000},
+       {0x0000a61c, 0x00000000},
+       {0x0000a620, 0x00000000},
+       {0x0000a624, 0x00000000},
+       {0x0000a628, 0x00000000},
+       {0x0000a62c, 0x00000000},
+       {0x0000a630, 0x00000000},
+       {0x0000a634, 0x00000000},
+       {0x0000a638, 0x00000000},
+       {0x0000a63c, 0x00000000},
+       {0x0000a640, 0x00000000},
+       {0x0000a644, 0x3fad9d74},
+       {0x0000a648, 0x0048060a},
+       {0x0000a64c, 0x00000637},
+       {0x0000a670, 0x03020100},
+       {0x0000a674, 0x09080504},
+       {0x0000a678, 0x0d0c0b0a},
+       {0x0000a67c, 0x13121110},
+       {0x0000a680, 0x31301514},
+       {0x0000a684, 0x35343332},
+       {0x0000a688, 0x00000036},
+       {0x0000a690, 0x00000838},
+       {0x0000a7c0, 0x00000000},
+       {0x0000a7c4, 0xfffffffc},
+       {0x0000a7c8, 0x00000000},
+       {0x0000a7cc, 0x00000000},
+       {0x0000a7d0, 0x00000000},
+       {0x0000a7d4, 0x00000004},
+       {0x0000a7dc, 0x00000000},
+       {0x0000a8d0, 0x004b6a8e},
+       {0x0000a8d4, 0x00000820},
+       {0x0000a8dc, 0x00000000},
+       {0x0000a8f0, 0x00000000},
+       {0x0000a8f4, 0x00000000},
+       {0x0000b2d0, 0x00000080},
+       {0x0000b2d4, 0x00000000},
+       {0x0000b2dc, 0x00000000},
+       {0x0000b2e0, 0x00000000},
+       {0x0000b2e4, 0x00000000},
+       {0x0000b2e8, 0x00000000},
+       {0x0000b2ec, 0x00000000},
+       {0x0000b2f0, 0x00000000},
+       {0x0000b2f4, 0x00000000},
+       {0x0000b2f8, 0x00000000},
+       {0x0000b408, 0x0e79e5c0},
+       {0x0000b40c, 0x00820820},
+       {0x0000b420, 0x00000000},
+};
+
+static const u32 ar9340Modes_high_power_tx_gain_table_1p0[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_high_ob_db_tx_gain_table_1p0[][5] = {
+       /*  Addr       5G_HT20    5G_HT40     2G_HT40     2G_HT20  */
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016048, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+       {0x00016444, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016448, 0x8e481266, 0x8e481266, 0x8e481266, 0x8e481266},
+};
+static const u32 ar9340Modes_ub124_tx_gain_table_1p0[][5] = {
+       /*  Addr      5G_HT20      5G_HT40     2G_HT40    2G_HT20  */
+       {0x0000a410, 0x000050d8, 0x000050d8, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
+       {0x0000a504, 0x04002222, 0x04002222, 0x04000002, 0x04000002},
+       {0x0000a508, 0x09002421, 0x09002421, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x0d002621, 0x0d002621, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x13004620, 0x13004620, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x19004a20, 0x19004a20, 0x11000400, 0x11000400},
+       {0x0000a518, 0x1d004e20, 0x1d004e20, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x21005420, 0x21005420, 0x19000404, 0x19000404},
+       {0x0000a520, 0x26005e20, 0x26005e20, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2b005e40, 0x2b005e40, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x2f005e42, 0x2f005e42, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x33005e44, 0x33005e44, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x38005e65, 0x38005e65, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x3c005e69, 0x3c005e69, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x40005e6b, 0x40005e6b, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x44005e6d, 0x44005e6d, 0x34001640, 0x34001640},
+       {0x0000a540, 0x49005e72, 0x49005e72, 0x38001660, 0x38001660},
+       {0x0000a544, 0x4e005eb2, 0x4e005eb2, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x53005f12, 0x53005f12, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x59025eb5, 0x59025eb5, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x5e025f12, 0x5e025f12, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x61027f12, 0x61027f12, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6702bf12, 0x6702bf12, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x6b02bf14, 0x6b02bf14, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x6f02bf16, 0x6f02bf16, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x6f02bf16, 0x6f02bf16, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00802220, 0x00802220, 0x00800000, 0x00800000},
+       {0x0000a584, 0x04802222, 0x04802222, 0x04800002, 0x04800002},
+       {0x0000a588, 0x09802421, 0x09802421, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x0d802621, 0x0d802621, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x13804620, 0x13804620, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x19804a20, 0x19804a20, 0x11800400, 0x11800400},
+       {0x0000a598, 0x1d804e20, 0x1d804e20, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x21805420, 0x21805420, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x26805e20, 0x26805e20, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2b805e40, 0x2b805e40, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x2f805e42, 0x2f805e42, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x33805e44, 0x33805e44, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x38805e65, 0x38805e65, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x3c805e69, 0x3c805e69, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x40805e6b, 0x40805e6b, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x44805e6d, 0x44805e6d, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x49805e72, 0x49805e72, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x4e805eb2, 0x4e805eb2, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x53805f12, 0x53805f12, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x59825eb2, 0x59825eb2, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x5e825f12, 0x5e825f12, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x61827f12, 0x61827f12, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6782bf12, 0x6782bf12, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x6b82bf14, 0x6b82bf14, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x6f82bf16, 0x6f82bf16, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x6f82bf16, 0x6f82bf16, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+       {0x00016048, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+       {0x00016444, 0x036db2db, 0x036db2db, 0x036db2db, 0x036db2db},
+       {0x00016448, 0x69b65266, 0x69b65266, 0x69b65266, 0x69b65266},
+};
+
+
+static const u32 ar9340Common_rx_gain_table_1p0[][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 ar9340Modes_low_ob_db_tx_gain_table_1p0[][5] = {
+       /*  Addr      5G_HT20     5G_HT40     2G_HT40     2G_HT20  */
+       {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},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x12800400, 0x12800400},
+       {0x0000a598, 0x21820220, 0x21820220, 0x16800402, 0x16800402},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1c800603, 0x1c800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x21800a02, 0x21800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x25800a04, 0x25800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x28800a20, 0x28800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2c800e20, 0x2c800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x30800e22, 0x30800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x34800e24, 0x34800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x38801640, 0x38801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x3c801660, 0x3c801660},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3f801861, 0x3f801861},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x43801a81, 0x43801a81},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x47801a83, 0x47801a83},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x4a801c84, 0x4a801c84},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x4e801ce3, 0x4e801ce3},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x52801ce5, 0x52801ce5},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x56801ce9, 0x56801ce9},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x5a801ceb, 0x5a801ceb},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x5d801eec, 0x5d801eec},
+       {0x00016044, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016048, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x056db2db, 0x056db2db},
+       {0x00016448, 0x24925266, 0x24925266, 0x24925266, 0x24925266},
+};
+
+static const u32 ar9340Modes_mixed_ob_db_tx_gain_table_1p0[][5] = {
+       /*  Addr       5G_HT20     5G_HT40     2G_HT40    2G_HT20  */
+       {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
+       {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
+       {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
+       {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
+       {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
+       {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
+       {0x0000a514, 0x1c000223, 0x1c000223, 0x11000400, 0x11000400},
+       {0x0000a518, 0x21020220, 0x21020220, 0x15000402, 0x15000402},
+       {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
+       {0x0000a520, 0x2b022220, 0x2b022220, 0x1b000603, 0x1b000603},
+       {0x0000a524, 0x2f022222, 0x2f022222, 0x1f000a02, 0x1f000a02},
+       {0x0000a528, 0x34022225, 0x34022225, 0x23000a04, 0x23000a04},
+       {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x26000a20, 0x26000a20},
+       {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2a000e20, 0x2a000e20},
+       {0x0000a534, 0x4202242a, 0x4202242a, 0x2e000e22, 0x2e000e22},
+       {0x0000a538, 0x4702244a, 0x4702244a, 0x31000e24, 0x31000e24},
+       {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x34001640, 0x34001640},
+       {0x0000a540, 0x4e02246c, 0x4e02246c, 0x38001660, 0x38001660},
+       {0x0000a544, 0x5302266c, 0x5302266c, 0x3b001861, 0x3b001861},
+       {0x0000a548, 0x5702286c, 0x5702286c, 0x3e001a81, 0x3e001a81},
+       {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x42001a83, 0x42001a83},
+       {0x0000a550, 0x61042a6c, 0x61042a6c, 0x44001c84, 0x44001c84},
+       {0x0000a554, 0x66062a6c, 0x66062a6c, 0x48001ce3, 0x48001ce3},
+       {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x4c001ce5, 0x4c001ce5},
+       {0x0000a55c, 0x7006308c, 0x7006308c, 0x50001ce9, 0x50001ce9},
+       {0x0000a560, 0x730a308a, 0x730a308a, 0x54001ceb, 0x54001ceb},
+       {0x0000a564, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a568, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a56c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a570, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a574, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a578, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a57c, 0x770a308c, 0x770a308c, 0x56001eec, 0x56001eec},
+       {0x0000a580, 0x00800000, 0x00800000, 0x00800000, 0x00800000},
+       {0x0000a584, 0x06800003, 0x06800003, 0x04800002, 0x04800002},
+       {0x0000a588, 0x0a800020, 0x0a800020, 0x08800004, 0x08800004},
+       {0x0000a58c, 0x10800023, 0x10800023, 0x0b800200, 0x0b800200},
+       {0x0000a590, 0x16800220, 0x16800220, 0x0f800202, 0x0f800202},
+       {0x0000a594, 0x1c800223, 0x1c800223, 0x11800400, 0x11800400},
+       {0x0000a598, 0x21820220, 0x21820220, 0x15800402, 0x15800402},
+       {0x0000a59c, 0x27820223, 0x27820223, 0x19800404, 0x19800404},
+       {0x0000a5a0, 0x2b822220, 0x2b822220, 0x1b800603, 0x1b800603},
+       {0x0000a5a4, 0x2f822222, 0x2f822222, 0x1f800a02, 0x1f800a02},
+       {0x0000a5a8, 0x34822225, 0x34822225, 0x23800a04, 0x23800a04},
+       {0x0000a5ac, 0x3a82222a, 0x3a82222a, 0x26800a20, 0x26800a20},
+       {0x0000a5b0, 0x3e82222c, 0x3e82222c, 0x2a800e20, 0x2a800e20},
+       {0x0000a5b4, 0x4282242a, 0x4282242a, 0x2e800e22, 0x2e800e22},
+       {0x0000a5b8, 0x4782244a, 0x4782244a, 0x31800e24, 0x31800e24},
+       {0x0000a5bc, 0x4b82244c, 0x4b82244c, 0x34801640, 0x34801640},
+       {0x0000a5c0, 0x4e82246c, 0x4e82246c, 0x38801660, 0x38801660},
+       {0x0000a5c4, 0x5382266c, 0x5382266c, 0x3b801861, 0x3b801861},
+       {0x0000a5c8, 0x5782286c, 0x5782286c, 0x3e801a81, 0x3e801a81},
+       {0x0000a5cc, 0x5c84286b, 0x5c84286b, 0x42801a83, 0x42801a83},
+       {0x0000a5d0, 0x61842a6c, 0x61842a6c, 0x44801c84, 0x44801c84},
+       {0x0000a5d4, 0x66862a6c, 0x66862a6c, 0x48801ce3, 0x48801ce3},
+       {0x0000a5d8, 0x6b862e6c, 0x6b862e6c, 0x4c801ce5, 0x4c801ce5},
+       {0x0000a5dc, 0x7086308c, 0x7086308c, 0x50801ce9, 0x50801ce9},
+       {0x0000a5e0, 0x738a308a, 0x738a308a, 0x54801ceb, 0x54801ceb},
+       {0x0000a5e4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5e8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5ec, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f0, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f4, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5f8, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x0000a5fc, 0x778a308c, 0x778a308c, 0x56801eec, 0x56801eec},
+       {0x00016044, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016048, 0x24927266, 0x24927266, 0x8e483266, 0x8e483266},
+       {0x00016444, 0x056db2db, 0x056db2db, 0x03b6d2e4, 0x03b6d2e4},
+       {0x00016448, 0x24927266, 0x24927266, 0x8e482266, 0x8e482266},
+};
+
+static const u32 ar9340_1p0_mac_core[][2] = {
+       /*    Addr        allmodes        */
+       {0x00000008, 0x00000000},
+       {0x00000030, 0x00020085},
+       {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},
+       {0x00008000, 0x00000000},
+       {0x00008004, 0x00000000},
+       {0x00008008, 0x00000000},
+       {0x0000800c, 0x00000000},
+       {0x00008018, 0x00000000},
+       {0x00008020, 0x00000000},
+       {0x00008038, 0x00000000},
+       {0x0000803c, 0x00000000},
+       {0x00008040, 0x00000000},
+       {0x00008044, 0x00000000},
+       {0x00008048, 0x00000000},
+       {0x0000804c, 0xffffffff},
+       {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, 0x00a00000},
+       {0x000080d8, 0x00400000},
+       {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},
+       {0x000081c0, 0x00000000},
+       {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, 0x00000007},
+       {0x00008330, 0x00000302},
+       {0x00008334, 0x00000700},
+       {0x00008338, 0x00ff0000},
+       {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},
+       {0x000083a0, 0x00000000},
+       {0x000083a4, 0x0000fa14},
+       {0x000083a8, 0x000f0c00},
+       {0x000083ac, 0x33332210},
+       {0x000083b0, 0x33332210},
+       {0x000083b4, 0x33332210},
+       {0x000083b8, 0x33332210},
+       {0x000083bc, 0x00000000},
+       {0x000083c0, 0x00000000},
+       {0x000083c4, 0x00000000},
+       {0x000083c8, 0x00000000},
+       {0x000083cc, 0x00000200},
+       {0x000083d0, 0x000301ff},
+};
+
+static const u32 ar9340Common_wo_xlna_rx_gain_table_1p0[][2] = {
+       /*    Addr        allmodes        */
+       {0x0000a000, 0x00010000},
+       {0x0000a004, 0x00030002},
+       {0x0000a008, 0x00050004},
+       {0x0000a00c, 0x00810080},
+       {0x0000a010, 0x00830082},
+       {0x0000a014, 0x01810180},
+       {0x0000a018, 0x01830182},
+       {0x0000a01c, 0x01850184},
+       {0x0000a020, 0x01890188},
+       {0x0000a024, 0x018b018a},
+       {0x0000a028, 0x018d018c},
+       {0x0000a02c, 0x03820190},
+       {0x0000a030, 0x03840383},
+       {0x0000a034, 0x03880385},
+       {0x0000a038, 0x038a0389},
+       {0x0000a03c, 0x038c038b},
+       {0x0000a040, 0x0390038d},
+       {0x0000a044, 0x03920391},
+       {0x0000a048, 0x03940393},
+       {0x0000a04c, 0x03960395},
+       {0x0000a050, 0x00000000},
+       {0x0000a054, 0x00000000},
+       {0x0000a058, 0x00000000},
+       {0x0000a05c, 0x00000000},
+       {0x0000a060, 0x00000000},
+       {0x0000a064, 0x00000000},
+       {0x0000a068, 0x00000000},
+       {0x0000a06c, 0x00000000},
+       {0x0000a070, 0x00000000},
+       {0x0000a074, 0x00000000},
+       {0x0000a078, 0x00000000},
+       {0x0000a07c, 0x00000000},
+       {0x0000a080, 0x29292929},
+       {0x0000a084, 0x29292929},
+       {0x0000a088, 0x29292929},
+       {0x0000a08c, 0x29292929},
+       {0x0000a090, 0x22292929},
+       {0x0000a094, 0x1d1d2222},
+       {0x0000a098, 0x0c111117},
+       {0x0000a09c, 0x00030303},
+       {0x0000a0a0, 0x00000000},
+       {0x0000a0a4, 0x00000000},
+       {0x0000a0a8, 0x00000000},
+       {0x0000a0ac, 0x00000000},
+       {0x0000a0b0, 0x00000000},
+       {0x0000a0b4, 0x00000000},
+       {0x0000a0b8, 0x00000000},
+       {0x0000a0bc, 0x00000000},
+       {0x0000a0c0, 0x001f0000},
+       {0x0000a0c4, 0x01000101},
+       {0x0000a0c8, 0x011e011f},
+       {0x0000a0cc, 0x011c011d},
+       {0x0000a0d0, 0x02030204},
+       {0x0000a0d4, 0x02010202},
+       {0x0000a0d8, 0x021f0200},
+       {0x0000a0dc, 0x0302021e},
+       {0x0000a0e0, 0x03000301},
+       {0x0000a0e4, 0x031e031f},
+       {0x0000a0e8, 0x0402031d},
+       {0x0000a0ec, 0x04000401},
+       {0x0000a0f0, 0x041e041f},
+       {0x0000a0f4, 0x0502041d},
+       {0x0000a0f8, 0x05000501},
+       {0x0000a0fc, 0x051e051f},
+       {0x0000a100, 0x06010602},
+       {0x0000a104, 0x061f0600},
+       {0x0000a108, 0x061d061e},
+       {0x0000a10c, 0x07020703},
+       {0x0000a110, 0x07000701},
+       {0x0000a114, 0x00000000},
+       {0x0000a118, 0x00000000},
+       {0x0000a11c, 0x00000000},
+       {0x0000a120, 0x00000000},
+       {0x0000a124, 0x00000000},
+       {0x0000a128, 0x00000000},
+       {0x0000a12c, 0x00000000},
+       {0x0000a130, 0x00000000},
+       {0x0000a134, 0x00000000},
+       {0x0000a138, 0x00000000},
+       {0x0000a13c, 0x00000000},
+       {0x0000a140, 0x001f0000},
+       {0x0000a144, 0x01000101},
+       {0x0000a148, 0x011e011f},
+       {0x0000a14c, 0x011c011d},
+       {0x0000a150, 0x02030204},
+       {0x0000a154, 0x02010202},
+       {0x0000a158, 0x021f0200},
+       {0x0000a15c, 0x0302021e},
+       {0x0000a160, 0x03000301},
+       {0x0000a164, 0x031e031f},
+       {0x0000a168, 0x0402031d},
+       {0x0000a16c, 0x04000401},
+       {0x0000a170, 0x041e041f},
+       {0x0000a174, 0x0502041d},
+       {0x0000a178, 0x05000501},
+       {0x0000a17c, 0x051e051f},
+       {0x0000a180, 0x06010602},
+       {0x0000a184, 0x061f0600},
+       {0x0000a188, 0x061d061e},
+       {0x0000a18c, 0x07020703},
+       {0x0000a190, 0x07000701},
+       {0x0000a194, 0x00000000},
+       {0x0000a198, 0x00000000},
+       {0x0000a19c, 0x00000000},
+       {0x0000a1a0, 0x00000000},
+       {0x0000a1a4, 0x00000000},
+       {0x0000a1a8, 0x00000000},
+       {0x0000a1ac, 0x00000000},
+       {0x0000a1b0, 0x00000000},
+       {0x0000a1b4, 0x00000000},
+       {0x0000a1b8, 0x00000000},
+       {0x0000a1bc, 0x00000000},
+       {0x0000a1c0, 0x00000000},
+       {0x0000a1c4, 0x00000000},
+       {0x0000a1c8, 0x00000000},
+       {0x0000a1cc, 0x00000000},
+       {0x0000a1d0, 0x00000000},
+       {0x0000a1d4, 0x00000000},
+       {0x0000a1d8, 0x00000000},
+       {0x0000a1dc, 0x00000000},
+       {0x0000a1e0, 0x00000000},
+       {0x0000a1e4, 0x00000000},
+       {0x0000a1e8, 0x00000000},
+       {0x0000a1ec, 0x00000000},
+       {0x0000a1f0, 0x00000396},
+       {0x0000a1f4, 0x00000396},
+       {0x0000a1f8, 0x00000396},
+       {0x0000a1fc, 0x00000196},
+       {0x0000b000, 0x00010000},
+       {0x0000b004, 0x00030002},
+       {0x0000b008, 0x00050004},
+       {0x0000b00c, 0x00810080},
+       {0x0000b010, 0x00830082},
+       {0x0000b014, 0x01810180},
+       {0x0000b018, 0x01830182},
+       {0x0000b01c, 0x01850184},
+       {0x0000b020, 0x02810280},
+       {0x0000b024, 0x02830282},
+       {0x0000b028, 0x02850284},
+       {0x0000b02c, 0x02890288},
+       {0x0000b030, 0x028b028a},
+       {0x0000b034, 0x0388028c},
+       {0x0000b038, 0x038a0389},
+       {0x0000b03c, 0x038c038b},
+       {0x0000b040, 0x0390038d},
+       {0x0000b044, 0x03920391},
+       {0x0000b048, 0x03940393},
+       {0x0000b04c, 0x03960395},
+       {0x0000b050, 0x00000000},
+       {0x0000b054, 0x00000000},
+       {0x0000b058, 0x00000000},
+       {0x0000b05c, 0x00000000},
+       {0x0000b060, 0x00000000},
+       {0x0000b064, 0x00000000},
+       {0x0000b068, 0x00000000},
+       {0x0000b06c, 0x00000000},
+       {0x0000b070, 0x00000000},
+       {0x0000b074, 0x00000000},
+       {0x0000b078, 0x00000000},
+       {0x0000b07c, 0x00000000},
+       {0x0000b080, 0x32323232},
+       {0x0000b084, 0x2f2f3232},
+       {0x0000b088, 0x23282a2d},
+       {0x0000b08c, 0x1c1e2123},
+       {0x0000b090, 0x14171919},
+       {0x0000b094, 0x0e0e1214},
+       {0x0000b098, 0x03050707},
+       {0x0000b09c, 0x00030303},
+       {0x0000b0a0, 0x00000000},
+       {0x0000b0a4, 0x00000000},
+       {0x0000b0a8, 0x00000000},
+       {0x0000b0ac, 0x00000000},
+       {0x0000b0b0, 0x00000000},
+       {0x0000b0b4, 0x00000000},
+       {0x0000b0b8, 0x00000000},
+       {0x0000b0bc, 0x00000000},
+       {0x0000b0c0, 0x003f0020},
+       {0x0000b0c4, 0x00400041},
+       {0x0000b0c8, 0x0140005f},
+       {0x0000b0cc, 0x0160015f},
+       {0x0000b0d0, 0x017e017f},
+       {0x0000b0d4, 0x02410242},
+       {0x0000b0d8, 0x025f0240},
+       {0x0000b0dc, 0x027f0260},
+       {0x0000b0e0, 0x0341027e},
+       {0x0000b0e4, 0x035f0340},
+       {0x0000b0e8, 0x037f0360},
+       {0x0000b0ec, 0x04400441},
+       {0x0000b0f0, 0x0460045f},
+       {0x0000b0f4, 0x0541047f},
+       {0x0000b0f8, 0x055f0540},
+       {0x0000b0fc, 0x057f0560},
+       {0x0000b100, 0x06400641},
+       {0x0000b104, 0x0660065f},
+       {0x0000b108, 0x067e067f},
+       {0x0000b10c, 0x07410742},
+       {0x0000b110, 0x075f0740},
+       {0x0000b114, 0x077f0760},
+       {0x0000b118, 0x07800781},
+       {0x0000b11c, 0x07a0079f},
+       {0x0000b120, 0x07c107bf},
+       {0x0000b124, 0x000007c0},
+       {0x0000b128, 0x00000000},
+       {0x0000b12c, 0x00000000},
+       {0x0000b130, 0x00000000},
+       {0x0000b134, 0x00000000},
+       {0x0000b138, 0x00000000},
+       {0x0000b13c, 0x00000000},
+       {0x0000b140, 0x003f0020},
+       {0x0000b144, 0x00400041},
+       {0x0000b148, 0x0140005f},
+       {0x0000b14c, 0x0160015f},
+       {0x0000b150, 0x017e017f},
+       {0x0000b154, 0x02410242},
+       {0x0000b158, 0x025f0240},
+       {0x0000b15c, 0x027f0260},
+       {0x0000b160, 0x0341027e},
+       {0x0000b164, 0x035f0340},
+       {0x0000b168, 0x037f0360},
+       {0x0000b16c, 0x04400441},
+       {0x0000b170, 0x0460045f},
+       {0x0000b174, 0x0541047f},
+       {0x0000b178, 0x055f0540},
+       {0x0000b17c, 0x057f0560},
+       {0x0000b180, 0x06400641},
+       {0x0000b184, 0x0660065f},
+       {0x0000b188, 0x067e067f},
+       {0x0000b18c, 0x07410742},
+       {0x0000b190, 0x075f0740},
+       {0x0000b194, 0x077f0760},
+       {0x0000b198, 0x07800781},
+       {0x0000b19c, 0x07a0079f},
+       {0x0000b1a0, 0x07c107bf},
+       {0x0000b1a4, 0x000007c0},
+       {0x0000b1a8, 0x00000000},
+       {0x0000b1ac, 0x00000000},
+       {0x0000b1b0, 0x00000000},
+       {0x0000b1b4, 0x00000000},
+       {0x0000b1b8, 0x00000000},
+       {0x0000b1bc, 0x00000000},
+       {0x0000b1c0, 0x00000000},
+       {0x0000b1c4, 0x00000000},
+       {0x0000b1c8, 0x00000000},
+       {0x0000b1cc, 0x00000000},
+       {0x0000b1d0, 0x00000000},
+       {0x0000b1d4, 0x00000000},
+       {0x0000b1d8, 0x00000000},
+       {0x0000b1dc, 0x00000000},
+       {0x0000b1e0, 0x00000000},
+       {0x0000b1e4, 0x00000000},
+       {0x0000b1e8, 0x00000000},
+       {0x0000b1ec, 0x00000000},
+       {0x0000b1f0, 0x00000396},
+       {0x0000b1f4, 0x00000396},
+       {0x0000b1f8, 0x00000396},
+       {0x0000b1fc, 0x00000196},
+};
+
+static const u32 ar9340_1p0_soc_preamble[][2] = {
+       /*    Addr        allmodes        */
+       {0x000040a4, 0x00a0c1c9},
+       {0x00007008, 0x00000000},
+       {0x00007020, 0x00000000},
+       {0x00007034, 0x00000002},
+       {0x00007038, 0x000004c2},
+};
+
+#endif
index a6b5388..0312aa0 100644 (file)
@@ -423,6 +423,7 @@ void ath9k_set_beaconing_status(struct ath_softc *sc, bool status);
 #define ATH_PAPRD_TIMEOUT      100 /* msecs */
 
 void ath_hw_check(struct work_struct *work);
+void ath_hw_pll_work(struct work_struct *work);
 void ath_paprd_calibrate(struct work_struct *work);
 void ath_ani_calibrate(unsigned long data);
 
@@ -453,6 +454,7 @@ void ath9k_btcoex_timer_pause(struct ath_softc *sc);
 
 #define ATH_LED_PIN_DEF                1
 #define ATH_LED_PIN_9287               8
+#define ATH_LED_PIN_9300               10
 #define ATH_LED_PIN_9485               6
 
 #ifdef CONFIG_MAC80211_LEDS
index 24f565b..22cd241 100644 (file)
@@ -781,12 +781,6 @@ void ath_set_beacon(struct ath_softc *sc)
                break;
        case NL80211_IFTYPE_STATION:
                ath_beacon_config_sta(sc, cur_conf);
-               /*
-                * Request a re-configuration of Beacon related timers
-                * on the receipt of the first Beacon frame (i.e.,
-                * after time sync with the AP).
-                */
-               sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
                break;
        default:
                ath_dbg(common, ATH_DBG_CONFIG,
index d33bf20..23f15a7 100644 (file)
@@ -51,6 +51,10 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
                .bt_hold_rx_clear = true,
        };
        u32 i;
+       bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity;
+
+       if (AR_SREV_9300_20_OR_LATER(ah))
+               rxclear_polarity = !ath_bt_config.bt_rxclear_polarity;
 
        btcoex_hw->bt_coex_mode =
                (btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) |
@@ -59,7 +63,7 @@ void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum)
                SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) |
                SM(ath_bt_config.bt_mode, AR_BT_MODE) |
                SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) |
-               SM(ath_bt_config.bt_rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
+               SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) |
                SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) |
                SM(ath_bt_config.bt_first_slot_time, AR_BT_FIRST_SLOT_TIME) |
                SM(qnum, AR_BT_QCU_THRESH);
@@ -142,6 +146,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
 }
 EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
 
+
 static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
 {
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
@@ -152,9 +157,22 @@ static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah)
         * enable coex 3-wire
         */
        REG_WRITE(ah, AR_BT_COEX_MODE, btcoex_hw->bt_coex_mode);
-       REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
        REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex_hw->bt_coex_mode2);
 
+
+       if (AR_SREV_9300_20_OR_LATER(ah)) {
+               REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, ah->bt_coex_wlan_weight[0]);
+               REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, ah->bt_coex_wlan_weight[1]);
+               REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, ah->bt_coex_bt_weight[0]);
+               REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, ah->bt_coex_bt_weight[1]);
+               REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, ah->bt_coex_bt_weight[2]);
+               REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, ah->bt_coex_bt_weight[3]);
+
+       } else
+               REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex_hw->bt_coex_weights);
+
+
+
        if (AR_SREV_9271(ah)) {
                val = REG_READ(ah, 0x50040);
                val &= 0xFFFFFEFF;
@@ -202,10 +220,86 @@ void ath9k_hw_btcoex_disable(struct ath_hw *ah)
 
        if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) {
                REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE);
-               REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
                REG_WRITE(ah, AR_BT_COEX_MODE2, 0);
+
+               if (AR_SREV_9300_20_OR_LATER(ah)) {
+                       REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0);
+                       REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0);
+                       REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS0, 0);
+                       REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS1, 0);
+                       REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS2, 0);
+                       REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS3, 0);
+               } else
+                       REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0);
+
        }
 
        ah->btcoex_hw.enabled = false;
 }
 EXPORT_SYMBOL(ath9k_hw_btcoex_disable);
+
+static void ar9003_btcoex_bt_stomp(struct ath_hw *ah,
+                        enum ath_stomp_type stomp_type)
+{
+       ah->bt_coex_bt_weight[0] = AR9300_BT_WGHT;
+       ah->bt_coex_bt_weight[1] = AR9300_BT_WGHT;
+       ah->bt_coex_bt_weight[2] = AR9300_BT_WGHT;
+       ah->bt_coex_bt_weight[3] = AR9300_BT_WGHT;
+
+
+       switch (stomp_type) {
+       case ATH_BTCOEX_STOMP_ALL:
+               ah->bt_coex_wlan_weight[0] = AR9300_STOMP_ALL_WLAN_WGHT0;
+               ah->bt_coex_wlan_weight[1] = AR9300_STOMP_ALL_WLAN_WGHT1;
+               break;
+       case ATH_BTCOEX_STOMP_LOW:
+               ah->bt_coex_wlan_weight[0] = AR9300_STOMP_LOW_WLAN_WGHT0;
+               ah->bt_coex_wlan_weight[1] = AR9300_STOMP_LOW_WLAN_WGHT1;
+               break;
+       case ATH_BTCOEX_STOMP_NONE:
+               ah->bt_coex_wlan_weight[0] = AR9300_STOMP_NONE_WLAN_WGHT0;
+               ah->bt_coex_wlan_weight[1] = AR9300_STOMP_NONE_WLAN_WGHT1;
+               break;
+
+       default:
+               ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+                               "Invalid Stomptype\n");
+               break;
+       }
+
+       ath9k_hw_btcoex_enable(ah);
+}
+
+/*
+ * Configures appropriate weight based on stomp type.
+ */
+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);
+               return;
+       }
+
+       switch (stomp_type) {
+       case ATH_BTCOEX_STOMP_ALL:
+               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+                               AR_STOMP_ALL_WLAN_WGHT);
+               break;
+       case ATH_BTCOEX_STOMP_LOW:
+               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+                               AR_STOMP_LOW_WLAN_WGHT);
+               break;
+       case ATH_BTCOEX_STOMP_NONE:
+               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
+                               AR_STOMP_NONE_WLAN_WGHT);
+               break;
+       default:
+               ath_dbg(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
+                               "Invalid Stomptype\n");
+               break;
+       }
+
+       ath9k_hw_btcoex_enable(ah);
+}
+EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp);
index 588dfd4..a9efca8 100644 (file)
 
 #include "hw.h"
 
-#define ATH_WLANACTIVE_GPIO    5
-#define ATH_BTACTIVE_GPIO      6
-#define ATH_BTPRIORITY_GPIO    7
+#define ATH_WLANACTIVE_GPIO_9280     5
+#define ATH_BTACTIVE_GPIO_9280       6
+#define ATH_BTPRIORITY_GPIO_9285     7
+
+#define ATH_WLANACTIVE_GPIO_9300     5
+#define ATH_BTACTIVE_GPIO_9300       4
+#define ATH_BTPRIORITY_GPIO_9300     8
 
 #define ATH_BTCOEX_DEF_BT_PERIOD  45
 #define ATH_BTCOEX_DEF_DUTY_CYCLE 55
 #define ATH_BT_CNT_THRESHOLD          3
 #define ATH_BT_CNT_SCAN_THRESHOLD      15
 
+/* Defines the BT AR_BT_COEX_WGHT used */
+enum ath_stomp_type {
+       ATH_BTCOEX_NO_STOMP,
+       ATH_BTCOEX_STOMP_ALL,
+       ATH_BTCOEX_STOMP_LOW,
+       ATH_BTCOEX_STOMP_NONE
+};
+
 enum ath_btcoex_scheme {
        ATH_BTCOEX_CFG_NONE,
        ATH_BTCOEX_CFG_2WIRE,
@@ -57,5 +69,7 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
                                u32 wlan_weight);
 void ath9k_hw_btcoex_enable(struct ath_hw *ah);
 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);
 
 #endif
index 16ba8c6..74535e6 100644 (file)
@@ -158,37 +158,6 @@ int ath9k_cmn_count_streams(unsigned int chainmask, int max)
 }
 EXPORT_SYMBOL(ath9k_cmn_count_streams);
 
-/*
- * Configures appropriate weight based on stomp type.
- */
-void ath9k_cmn_btcoex_bt_stomp(struct ath_common *common,
-                                 enum ath_stomp_type stomp_type)
-{
-       struct ath_hw *ah = common->ah;
-
-       switch (stomp_type) {
-       case ATH_BTCOEX_STOMP_ALL:
-               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-                                          AR_STOMP_ALL_WLAN_WGHT);
-               break;
-       case ATH_BTCOEX_STOMP_LOW:
-               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-                                          AR_STOMP_LOW_WLAN_WGHT);
-               break;
-       case ATH_BTCOEX_STOMP_NONE:
-               ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
-                                          AR_STOMP_NONE_WLAN_WGHT);
-               break;
-       default:
-               ath_dbg(common, ATH_DBG_BTCOEX,
-                       "Invalid Stomptype\n");
-               break;
-       }
-
-       ath9k_hw_btcoex_enable(ah);
-}
-EXPORT_SYMBOL(ath9k_cmn_btcoex_bt_stomp);
-
 void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
                            u16 new_txpow, u16 *txpower)
 {
index b2f7b5f..5124f14 100644 (file)
 #define ATH_EP_RND(x, mul)                                             \
        ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
 
-/* Defines the BT AR_BT_COEX_WGHT used */
-enum ath_stomp_type {
-       ATH_BTCOEX_NO_STOMP,
-       ATH_BTCOEX_STOMP_ALL,
-       ATH_BTCOEX_STOMP_LOW,
-       ATH_BTCOEX_STOMP_NONE
-};
-
 int ath9k_cmn_padpos(__le16 frame_control);
 int ath9k_cmn_get_hw_crypto_keytype(struct sk_buff *skb);
 void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
index 34f191e..bad1a87 100644 (file)
@@ -326,6 +326,8 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status)
                sc->debug.stats.istats.dtimsync++;
        if (status & ATH9K_INT_DTIM)
                sc->debug.stats.istats.dtim++;
+       if (status & ATH9K_INT_TSFOOR)
+               sc->debug.stats.istats.tsfoor++;
 }
 
 static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
@@ -380,8 +382,11 @@ static ssize_t read_file_interrupt(struct file *file, char __user *user_buf,
        len += snprintf(buf + len, sizeof(buf) - len,
                "%8s: %10u\n", "DTIM", sc->debug.stats.istats.dtim);
        len += snprintf(buf + len, sizeof(buf) - len,
+               "%8s: %10u\n", "TSFOOR", sc->debug.stats.istats.tsfoor);
+       len += snprintf(buf + len, sizeof(buf) - len,
                "%8s: %10u\n", "TOTAL", sc->debug.stats.istats.total);
 
+
        if (len > sizeof(buf))
                len = sizeof(buf);
 
index 1f9f8ea..5488a32 100644 (file)
@@ -54,6 +54,9 @@ struct ath_buf;
  * @dtimsync: DTIM sync lossage
  * @dtim: RX Beacon with DTIM
  * @bb_watchdog: Baseband watchdog
+ * @tsfoor: TSF out of range, indicates that the corrected TSF received
+ * from a beacon differs from the PCU's internal TSF by more than a
+ * (programmable) threshold
  */
 struct ath_interrupt_stats {
        u32 total;
@@ -78,6 +81,7 @@ struct ath_interrupt_stats {
        u32 dtimsync;
        u32 dtim;
        u32 bb_watchdog;
+       u32 tsfoor;
 };
 
 /**
index 1357975..b87db47 100644 (file)
@@ -319,10 +319,9 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
        u16 numXpdGain, xpdMask;
        u16 xpdGainValues[AR5416_NUM_PD_GAINS] = {0, 0, 0, 0};
        u32 reg32, regOffset, regChainOffset, regval;
-       int16_t modalIdx, diff = 0;
+       int16_t diff = 0;
        struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
 
-       modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
        xpdMask = pEepData->modalHeader.xpdGain;
 
        if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
index 995949d..c031854 100644 (file)
@@ -231,6 +231,10 @@ static int ath9k_hw_def_check_eeprom(struct ath_hw *ah)
                                integer = swab32(pModal->antCtrlChain[i]);
                                pModal->antCtrlChain[i] = integer;
                        }
+                       for (i = 0; i < 3; i++) {
+                               word = swab16(pModal->xpaBiasLvlFreq[i]);
+                               pModal->xpaBiasLvlFreq[i] = word;
+                       }
 
                        for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
                                word = swab16(pModal->spurChans[i].spurChan);
index 44a0a88..0349b3a 100644 (file)
@@ -46,6 +46,8 @@ void ath_init_leds(struct ath_softc *sc)
                        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
                        sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
        }
@@ -138,10 +140,10 @@ static void ath_detect_bt_priority(struct ath_softc *sc)
 
 static void ath9k_gen_timer_start(struct ath_hw *ah,
                                  struct ath_gen_timer *timer,
-                                 u32 timer_next,
+                                 u32 trig_timeout,
                                  u32 timer_period)
 {
-       ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
+       ath9k_hw_gen_timer_start(ah, timer, trig_timeout, timer_period);
 
        if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
                ath9k_hw_disable_interrupts(ah);
@@ -174,17 +176,17 @@ static void ath_btcoex_period_timer(unsigned long data)
        struct ath_softc *sc = (struct ath_softc *) data;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_btcoex *btcoex = &sc->btcoex;
-       struct ath_common *common = ath9k_hw_common(ah);
        u32 timer_period;
        bool is_btscan;
 
+       ath9k_ps_wakeup(sc);
        ath_detect_bt_priority(sc);
 
        is_btscan = sc->sc_flags & SC_OP_BT_SCAN;
 
        spin_lock_bh(&btcoex->btcoex_lock);
 
-       ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+       ath9k_hw_btcoex_bt_stomp(ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
                              btcoex->bt_stomp_type);
 
        spin_unlock_bh(&btcoex->btcoex_lock);
@@ -195,11 +197,12 @@ static void ath_btcoex_period_timer(unsigned long data)
 
                timer_period = is_btscan ? btcoex->btscan_no_stomp :
                                           btcoex->btcoex_no_stomp;
-               ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, 0,
+               ath9k_gen_timer_start(ah, btcoex->no_stomp_timer, timer_period,
                                      timer_period * 10);
                btcoex->hw_timer_enabled = true;
        }
 
+       ath9k_ps_restore(sc);
        mod_timer(&btcoex->period_timer, jiffies +
                                  msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
 }
@@ -219,14 +222,16 @@ static void ath_btcoex_no_stomp_timer(void *arg)
        ath_dbg(common, ATH_DBG_BTCOEX,
                "no stomp timer running\n");
 
+       ath9k_ps_wakeup(sc);
        spin_lock_bh(&btcoex->btcoex_lock);
 
        if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
-               ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
+               ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
         else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-               ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+               ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
 
        spin_unlock_bh(&btcoex->btcoex_lock);
+       ath9k_ps_restore(sc);
 }
 
 int ath_init_btcoex_timer(struct ath_softc *sc)
index f59df48..2bdcdbc 100644 (file)
@@ -17,6 +17,9 @@
 #ifndef HTC_USB_H
 #define HTC_USB_H
 
+#define MAJOR_VERSION_REQ 1
+#define MINOR_VERSION_REQ 2
+
 #define IS_AR7010_DEVICE(_v) (((_v) == AR9280_USB) || ((_v) == AR9287_USB))
 
 #define AR9271_FIRMWARE       0x501000
index 48a8855..dfc7a98 100644 (file)
@@ -66,8 +66,6 @@ enum htc_opmode {
        HTC_M_WDS       = 2
 };
 
-#define ATH9K_HTC_HDRSPACE sizeof(struct htc_frame_hdr)
-
 #define ATH9K_HTC_AMPDU  1
 #define ATH9K_HTC_NORMAL 2
 #define ATH9K_HTC_BEACON 3
@@ -75,7 +73,6 @@ enum htc_opmode {
 
 #define ATH9K_HTC_TX_CTSONLY      0x1
 #define ATH9K_HTC_TX_RTSCTS       0x2
-#define ATH9K_HTC_TX_USE_MIN_RATE 0x100
 
 struct tx_frame_hdr {
        u8 data_type;
@@ -106,15 +103,14 @@ struct tx_beacon_header {
        u16 rev;
 } __packed;
 
+#define MAX_TX_AMPDU_SUBFRAMES_9271 17
+#define MAX_TX_AMPDU_SUBFRAMES_7010 22
+
 struct ath9k_htc_cap_target {
-       u32 flags;
-       u32 flags_ext;
-       u32 ampdu_limit;
+       __be32 ampdu_limit;
        u8 ampdu_subframes;
+       u8 enable_coex;
        u8 tx_chainmask;
-       u8 tx_chainmask_legacy;
-       u8 rtscts_ratecode;
-       u8 protmode;
        u8 pad;
 } __packed;
 
@@ -175,6 +171,13 @@ struct ath9k_htc_target_rate {
        struct ath9k_htc_rate rates;
 };
 
+struct ath9k_htc_target_rate_mask {
+       u8 vif_index;
+       u8 band;
+       __be32 mask;
+       u16 pad;
+} __packed;
+
 struct ath9k_htc_target_int_stats {
        __be32 rx;
        __be32 rxorn;
@@ -382,25 +385,6 @@ static inline void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
 #define ATH_LED_PIN_9287            10
 #define ATH_LED_PIN_9271            15
 #define ATH_LED_PIN_7010            12
-#define ATH_LED_ON_DURATION_IDLE    350        /* in msecs */
-#define ATH_LED_OFF_DURATION_IDLE   250        /* in msecs */
-
-enum ath_led_type {
-       ATH_LED_RADIO,
-       ATH_LED_ASSOC,
-       ATH_LED_TX,
-       ATH_LED_RX
-};
-
-struct ath_led {
-       struct ath9k_htc_priv *priv;
-       struct led_classdev led_cdev;
-       enum ath_led_type led_type;
-       struct delayed_work brightness_work;
-       char name[32];
-       bool registered;
-       int brightness;
-};
 
 #define BSTUCK_THRESHOLD 10
 
@@ -434,14 +418,11 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv);
 
 #define OP_INVALID                BIT(0)
 #define OP_SCANNING               BIT(1)
-#define OP_LED_ASSOCIATED         BIT(2)
-#define OP_LED_ON                 BIT(3)
-#define OP_ENABLE_BEACON          BIT(4)
-#define OP_LED_DEINIT             BIT(5)
-#define OP_BT_PRIORITY_DETECTED    BIT(6)
-#define OP_BT_SCAN                 BIT(7)
-#define OP_ANI_RUNNING             BIT(8)
-#define OP_TSF_RESET               BIT(9)
+#define OP_ENABLE_BEACON           BIT(2)
+#define OP_BT_PRIORITY_DETECTED    BIT(3)
+#define OP_BT_SCAN                 BIT(4)
+#define OP_ANI_RUNNING             BIT(5)
+#define OP_TSF_RESET               BIT(6)
 
 struct ath9k_htc_priv {
        struct device *dev;
@@ -501,15 +482,13 @@ struct ath9k_htc_priv {
        bool ps_enabled;
        bool ps_idle;
 
-       struct ath_led radio_led;
-       struct ath_led assoc_led;
-       struct ath_led tx_led;
-       struct ath_led rx_led;
-       struct delayed_work ath9k_led_blink_work;
-       int led_on_duration;
-       int led_off_duration;
-       int led_on_cnt;
-       int led_off_cnt;
+#ifdef CONFIG_MAC80211_LEDS
+       enum led_brightness brightness;
+       bool led_registered;
+       char led_name[32];
+       struct led_classdev led_cdev;
+       struct work_struct led_work;
+#endif
 
        int beaconq;
        int cabq;
@@ -551,7 +530,8 @@ void ath9k_htc_txep(void *priv, struct sk_buff *skb, enum htc_endpoint_id ep_id,
 void ath9k_htc_beaconep(void *drv_priv, struct sk_buff *skb,
                        enum htc_endpoint_id ep_id, bool txok);
 
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv);
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+                               u8 enable_coex);
 void ath9k_htc_station_work(struct work_struct *work);
 void ath9k_htc_aggr_work(struct work_struct *work);
 void ath9k_htc_ani_work(struct work_struct *work);
@@ -593,9 +573,24 @@ void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
 void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
 void ath9k_htc_radio_enable(struct ieee80211_hw *hw);
 void ath9k_htc_radio_disable(struct ieee80211_hw *hw);
-void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv);
+
+#ifdef CONFIG_MAC80211_LEDS
 void ath9k_init_leds(struct ath9k_htc_priv *priv);
 void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
+void ath9k_led_work(struct work_struct *work);
+#else
+static inline void ath9k_init_leds(struct ath9k_htc_priv *priv)
+{
+}
+
+static inline void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
+{
+}
+
+static inline void ath9k_led_work(struct work_struct *work)
+{
+}
+#endif
 
 int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev,
                           u16 devid, char *product, u32 drv_info);
index a157107..0ded2c6 100644 (file)
@@ -74,7 +74,7 @@ static void ath9k_htc_beacon_config_sta(struct ath9k_htc_priv *priv,
        __be32 htc_imask = 0;
        u64 tsf;
        int num_beacons, offset, dtim_dec_count, cfp_dec_count;
-       int ret;
+       int ret __attribute__ ((unused));
        u8 cmd_rsp;
 
        memset(&bs, 0, sizeof(bs));
@@ -190,7 +190,7 @@ static void ath9k_htc_beacon_config_ap(struct ath9k_htc_priv *priv,
        enum ath9k_int imask = 0;
        u32 nexttbtt, intval, tsftu;
        __be32 htc_imask = 0;
-       int ret;
+       int ret __attribute__ ((unused));
        u8 cmd_rsp;
        u64 tsf;
 
@@ -246,7 +246,7 @@ static void ath9k_htc_beacon_config_adhoc(struct ath9k_htc_priv *priv,
        enum ath9k_int imask = 0;
        u32 nexttbtt, intval, tsftu;
        __be32 htc_imask = 0;
-       int ret;
+       int ret __attribute__ ((unused));
        u8 cmd_rsp;
        u64 tsf;
 
index eca7774..aa48b3a 100644 (file)
@@ -33,9 +33,15 @@ static ssize_t read_file_tgt_int_stats(struct file *file, char __user *user_buf,
 
        memset(&cmd_rsp, 0, sizeof(cmd_rsp));
 
+       ath9k_htc_ps_wakeup(priv);
+
        WMI_CMD(WMI_INT_STATS_CMDID);
-       if (ret)
+       if (ret) {
+               ath9k_htc_ps_restore(priv);
                return -EINVAL;
+       }
+
+       ath9k_htc_ps_restore(priv);
 
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "RX",
@@ -85,9 +91,15 @@ static ssize_t read_file_tgt_tx_stats(struct file *file, char __user *user_buf,
 
        memset(&cmd_rsp, 0, sizeof(cmd_rsp));
 
+       ath9k_htc_ps_wakeup(priv);
+
        WMI_CMD(WMI_TX_STATS_CMDID);
-       if (ret)
+       if (ret) {
+               ath9k_htc_ps_restore(priv);
                return -EINVAL;
+       }
+
+       ath9k_htc_ps_restore(priv);
 
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "Xretries",
@@ -149,9 +161,15 @@ static ssize_t read_file_tgt_rx_stats(struct file *file, char __user *user_buf,
 
        memset(&cmd_rsp, 0, sizeof(cmd_rsp));
 
+       ath9k_htc_ps_wakeup(priv);
+
        WMI_CMD(WMI_RX_STATS_CMDID);
-       if (ret)
+       if (ret) {
+               ath9k_htc_ps_restore(priv);
                return -EINVAL;
+       }
+
+       ath9k_htc_ps_restore(priv);
 
        len += snprintf(buf + len, sizeof(buf) - len,
                        "%20s : %10u\n", "NoBuf",
@@ -474,6 +492,439 @@ static const struct file_operations fops_debug = {
        .llseek = default_llseek,
 };
 
+static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
+                                    size_t count, loff_t *ppos)
+{
+       struct ath9k_htc_priv *priv = file->private_data;
+       struct ath_common *common = ath9k_hw_common(priv->ah);
+       struct base_eep_header *pBase = NULL;
+       unsigned int len = 0, size = 1500;
+       ssize_t retval = 0;
+       char *buf;
+
+       /*
+        * This can be done since all the 3 EEPROM families have the
+        * same base header upto a certain point, and we are interested in
+        * the data only upto that point.
+        */
+
+       if (AR_SREV_9271(priv->ah))
+               pBase = (struct base_eep_header *)
+                       &priv->ah->eeprom.map4k.baseEepHeader;
+       else if (priv->ah->hw_version.usbdev == AR9280_USB)
+               pBase = (struct base_eep_header *)
+                       &priv->ah->eeprom.def.baseEepHeader;
+       else if (priv->ah->hw_version.usbdev == AR9287_USB)
+               pBase = (struct base_eep_header *)
+                       &priv->ah->eeprom.map9287.baseEepHeader;
+
+       if (pBase == NULL) {
+               ath_err(common, "Unknown EEPROM type\n");
+               return 0;
+       }
+
+       buf = kzalloc(size, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n", "Major Version",
+                       pBase->version >> 12);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n", "Minor Version",
+                       pBase->version & 0xFFF);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n", "Checksum",
+                       pBase->checksum);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n", "Length",
+                       pBase->length);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n", "RegDomain1",
+                       pBase->regDmn[0]);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n", "RegDomain2",
+                       pBase->regDmn[1]);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "TX Mask", pBase->txMask);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "RX Mask", pBase->rxMask);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Allow 5GHz",
+                       !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Allow 2GHz",
+                       !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Disable 2GHz HT20",
+                       !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20));
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Disable 2GHz HT40",
+                       !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40));
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Disable 5Ghz HT20",
+                       !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20));
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Disable 5Ghz HT40",
+                       !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40));
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Big Endian",
+                       !!(pBase->eepMisc & 0x01));
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Cal Bin Major Ver",
+                       (pBase->binBuildNumber >> 24) & 0xFF);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Cal Bin Minor Ver",
+                       (pBase->binBuildNumber >> 16) & 0xFF);
+       len += snprintf(buf + len, size - len,
+                       "%20s : %10d\n",
+                       "Cal Bin Build",
+                       (pBase->binBuildNumber >> 8) & 0xFF);
+
+       /*
+        * UB91 specific data.
+        */
+       if (AR_SREV_9271(priv->ah)) {
+               struct base_eep_header_4k *pBase4k =
+                       &priv->ah->eeprom.map4k.baseEepHeader;
+
+               len += snprintf(buf + len, size - len,
+                               "%20s : %10d\n",
+                               "TX Gain type",
+                               pBase4k->txGainType);
+       }
+
+       /*
+        * UB95 specific data.
+        */
+       if (priv->ah->hw_version.usbdev == AR9287_USB) {
+               struct base_eep_ar9287_header *pBase9287 =
+                       &priv->ah->eeprom.map9287.baseEepHeader;
+
+               len += snprintf(buf + len, size - len,
+                               "%20s : %10ddB\n",
+                               "Power Table Offset",
+                               pBase9287->pwrTableOffset);
+
+               len += snprintf(buf + len, size - len,
+                               "%20s : %10d\n",
+                               "OpenLoop Power Ctrl",
+                               pBase9287->openLoopPwrCntl);
+       }
+
+       len += snprintf(buf + len, size - len,
+                       "%20s : %02X:%02X:%02X:%02X:%02X:%02X\n",
+                       "MacAddress",
+                       pBase->macAddr[0], pBase->macAddr[1], pBase->macAddr[2],
+                       pBase->macAddr[3], pBase->macAddr[4], pBase->macAddr[5]);
+       if (len > size)
+               len = size;
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+
+       return retval;
+}
+
+static const struct file_operations fops_base_eeprom = {
+       .read = read_file_base_eeprom,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
+static ssize_t read_4k_modal_eeprom(struct file *file,
+                                   char __user *user_buf,
+                                   size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val)                                               \
+       do {                                                            \
+               len += snprintf(buf + len, size - len, "%20s : %10d\n", \
+                               _s, (_val));                            \
+       } while (0)
+
+       struct ath9k_htc_priv *priv = file->private_data;
+       struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader;
+       unsigned int len = 0, size = 2048;
+       ssize_t retval = 0;
+       char *buf;
+
+       buf = kzalloc(size, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+       PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+       PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+       PR_EEP("Switch Settle", pModal->switchSettling);
+       PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+       PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+       PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+       PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
+       PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
+       PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+       PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+       PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+       PR_EEP("CCA Threshold)", pModal->thresh62);
+       PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+       PR_EEP("xpdGain", pModal->xpdGain);
+       PR_EEP("External PD", pModal->xpd);
+       PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+       PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+       PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+       PR_EEP("O/D Bias Version", pModal->version);
+       PR_EEP("CCK OutputBias", pModal->ob_0);
+       PR_EEP("BPSK OutputBias", pModal->ob_1);
+       PR_EEP("QPSK OutputBias", pModal->ob_2);
+       PR_EEP("16QAM OutputBias", pModal->ob_3);
+       PR_EEP("64QAM OutputBias", pModal->ob_4);
+       PR_EEP("CCK Driver1_Bias", pModal->db1_0);
+       PR_EEP("BPSK Driver1_Bias", pModal->db1_1);
+       PR_EEP("QPSK Driver1_Bias", pModal->db1_2);
+       PR_EEP("16QAM Driver1_Bias", pModal->db1_3);
+       PR_EEP("64QAM Driver1_Bias", pModal->db1_4);
+       PR_EEP("CCK Driver2_Bias", pModal->db2_0);
+       PR_EEP("BPSK Driver2_Bias", pModal->db2_1);
+       PR_EEP("QPSK Driver2_Bias", pModal->db2_2);
+       PR_EEP("16QAM Driver2_Bias", pModal->db2_3);
+       PR_EEP("64QAM Driver2_Bias", pModal->db2_4);
+       PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+       PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+       PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+       PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+       PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+       PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+       PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+       PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
+       PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
+       PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1);
+       PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2);
+       PR_EEP("TX Diversity", pModal->tx_diversity);
+
+       if (len > size)
+               len = size;
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+
+       return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_def_modal_eeprom(struct file *file,
+                                    char __user *user_buf,
+                                    size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val)                                               \
+       do {                                                            \
+               if (pBase->opCapFlags & AR5416_OPFLAGS_11G) {           \
+                       pModal = &priv->ah->eeprom.def.modalHeader[1];  \
+                       len += snprintf(buf + len, size - len, "%20s : %8d%7s", \
+                                       _s, (_val), "|");               \
+               }                                                       \
+               if (pBase->opCapFlags & AR5416_OPFLAGS_11A) {           \
+                       pModal = &priv->ah->eeprom.def.modalHeader[0];  \
+                       len += snprintf(buf + len, size - len, "%9d\n", \
+                                       (_val));                        \
+               }                                                       \
+       } while (0)
+
+       struct ath9k_htc_priv *priv = file->private_data;
+       struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader;
+       struct modal_eep_header *pModal = NULL;
+       unsigned int len = 0, size = 3500;
+       ssize_t retval = 0;
+       char *buf;
+
+       buf = kzalloc(size, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       len += snprintf(buf + len, size - len,
+                       "%31s %15s\n", "2G", "5G");
+       len += snprintf(buf + len, size - len,
+                       "%32s %16s\n", "====", "====\n");
+
+       PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+       PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
+       PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]);
+       PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+       PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+       PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
+       PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]);
+       PR_EEP("Switch Settle", pModal->switchSettling);
+       PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+       PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
+       PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]);
+       PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+       PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
+       PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]);
+       PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+       PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
+       PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
+       PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]);
+       PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]);
+       PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+       PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+       PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+       PR_EEP("CCA Threshold)", pModal->thresh62);
+       PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+       PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
+       PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]);
+       PR_EEP("xpdGain", pModal->xpdGain);
+       PR_EEP("External PD", pModal->xpd);
+       PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+       PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
+       PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]);
+       PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+       PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
+       PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]);
+       PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+       PR_EEP("Chain0 OutputBias", pModal->ob);
+       PR_EEP("Chain0 DriverBias", pModal->db);
+       PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+       PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain);
+       PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain);
+       PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+       PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+       PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+       PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+       PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
+       PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]);
+       PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+       PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
+       PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]);
+       PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+       PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
+       PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]);
+       PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]);
+       PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
+       PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]);
+       PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]);
+       PR_EEP("Chain1 OutputBias", pModal->ob_ch1);
+       PR_EEP("Chain1 DriverBias", pModal->db_ch1);
+       PR_EEP("LNA Control", pModal->lna_ctl);
+       PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]);
+       PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]);
+       PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]);
+
+       if (len > size)
+               len = size;
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+
+       return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_9287_modal_eeprom(struct file *file,
+                                     char __user *user_buf,
+                                     size_t count, loff_t *ppos)
+{
+#define PR_EEP(_s, _val)                                               \
+       do {                                                            \
+               len += snprintf(buf + len, size - len, "%20s : %10d\n", \
+                               _s, (_val));                            \
+       } while (0)
+
+       struct ath9k_htc_priv *priv = file->private_data;
+       struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader;
+       unsigned int len = 0, size = 3000;
+       ssize_t retval = 0;
+       char *buf;
+
+       buf = kzalloc(size, GFP_KERNEL);
+       if (buf == NULL)
+               return -ENOMEM;
+
+       PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
+       PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
+       PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
+       PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
+       PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
+       PR_EEP("Switch Settle", pModal->switchSettling);
+       PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
+       PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
+       PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
+       PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
+       PR_EEP("ADC Desired size", pModal->adcDesiredSize);
+       PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
+       PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
+       PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
+       PR_EEP("CCA Threshold)", pModal->thresh62);
+       PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
+       PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
+       PR_EEP("xpdGain", pModal->xpdGain);
+       PR_EEP("External PD", pModal->xpd);
+       PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
+       PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
+       PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
+       PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
+       PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
+       PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
+       PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
+       PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
+       PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
+       PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
+       PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
+       PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
+       PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
+       PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
+       PR_EEP("AR92x7 Version", pModal->version);
+       PR_EEP("DriverBias1", pModal->db1);
+       PR_EEP("DriverBias2", pModal->db1);
+       PR_EEP("CCK OutputBias", pModal->ob_cck);
+       PR_EEP("PSK OutputBias", pModal->ob_psk);
+       PR_EEP("QAM OutputBias", pModal->ob_qam);
+       PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off);
+
+       if (len > size)
+               len = size;
+
+       retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+       kfree(buf);
+
+       return retval;
+
+#undef PR_EEP
+}
+
+static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
+                                     size_t count, loff_t *ppos)
+{
+       struct ath9k_htc_priv *priv = file->private_data;
+
+       if (AR_SREV_9271(priv->ah))
+               return read_4k_modal_eeprom(file, user_buf, count, ppos);
+       else if (priv->ah->hw_version.usbdev == AR9280_USB)
+               return read_def_modal_eeprom(file, user_buf, count, ppos);
+       else if (priv->ah->hw_version.usbdev == AR9287_USB)
+               return read_9287_modal_eeprom(file, user_buf, count, ppos);
+
+       return 0;
+}
+
+static const struct file_operations fops_modal_eeprom = {
+       .read = read_file_modal_eeprom,
+       .open = ath9k_debugfs_open,
+       .owner = THIS_MODULE,
+       .llseek = default_llseek,
+};
+
 int ath9k_htc_init_debug(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
@@ -485,21 +936,25 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
                return -ENOMEM;
 
        debugfs_create_file("tgt_int_stats", S_IRUSR, priv->debug.debugfs_phy,
-                               priv, &fops_tgt_int_stats);
+                           priv, &fops_tgt_int_stats);
        debugfs_create_file("tgt_tx_stats", S_IRUSR, priv->debug.debugfs_phy,
-                               priv, &fops_tgt_tx_stats);
+                           priv, &fops_tgt_tx_stats);
        debugfs_create_file("tgt_rx_stats", S_IRUSR, priv->debug.debugfs_phy,
-                               priv, &fops_tgt_rx_stats);
+                           priv, &fops_tgt_rx_stats);
        debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy,
-                               priv, &fops_xmit);
+                           priv, &fops_xmit);
        debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy,
-                               priv, &fops_recv);
+                           priv, &fops_recv);
        debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
-                               priv, &fops_slot);
+                           priv, &fops_slot);
        debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy,
-                               priv, &fops_queue);
+                           priv, &fops_queue);
        debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
-                               priv, &fops_debug);
+                           priv, &fops_debug);
+       debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy,
+                           priv, &fops_base_eeprom);
+       debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy,
+                           priv, &fops_modal_eeprom);
 
        return 0;
 }
index dc0b33d..af57fe5 100644 (file)
@@ -65,17 +65,19 @@ static void ath_btcoex_period_work(struct work_struct *work)
        u32 timer_period;
        bool is_btscan;
        int ret;
-       u8 cmd_rsp, aggr;
 
        ath_detect_bt_priority(priv);
 
        is_btscan = !!(priv->op_flags & OP_BT_SCAN);
 
-       aggr = priv->op_flags & OP_BT_PRIORITY_DETECTED;
-
-       WMI_CMD_BUF(WMI_AGGR_LIMIT_CMD, &aggr);
+       ret = ath9k_htc_update_cap_target(priv,
+                                 !!(priv->op_flags & OP_BT_PRIORITY_DETECTED));
+       if (ret) {
+               ath_err(common, "Unable to set BTCOEX parameters\n");
+               return;
+       }
 
-       ath9k_cmn_btcoex_bt_stomp(common, is_btscan ? ATH_BTCOEX_STOMP_ALL :
+       ath9k_hw_btcoex_bt_stomp(priv->ah, is_btscan ? ATH_BTCOEX_STOMP_ALL :
                        btcoex->bt_stomp_type);
 
        timer_period = is_btscan ? btcoex->btscan_no_stomp :
@@ -103,9 +105,9 @@ static void ath_btcoex_duty_cycle_work(struct work_struct *work)
                "time slice work for bt and wlan\n");
 
        if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW || is_btscan)
-               ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_NONE);
+               ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE);
        else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
-               ath9k_cmn_btcoex_bt_stomp(common, ATH_BTCOEX_STOMP_LOW);
+               ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_LOW);
 }
 
 void ath_htc_init_btcoex_work(struct ath9k_htc_priv *priv)
@@ -152,140 +154,41 @@ void ath_htc_cancel_btcoex_work(struct ath9k_htc_priv *priv)
 /* LED */
 /*******/
 
-static void ath9k_led_blink_work(struct work_struct *work)
+#ifdef CONFIG_MAC80211_LEDS
+void ath9k_led_work(struct work_struct *work)
 {
-       struct ath9k_htc_priv *priv = container_of(work, struct ath9k_htc_priv,
-                                                  ath9k_led_blink_work.work);
+       struct ath9k_htc_priv *priv = container_of(work,
+                                                  struct ath9k_htc_priv,
+                                                  led_work);
 
-       if (!(priv->op_flags & OP_LED_ASSOCIATED))
-               return;
-
-       if ((priv->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
-           (priv->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
-               ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
-       else
-               ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
-                                 (priv->op_flags & OP_LED_ON) ? 1 : 0);
-
-       ieee80211_queue_delayed_work(priv->hw,
-                                    &priv->ath9k_led_blink_work,
-                                    (priv->op_flags & OP_LED_ON) ?
-                                    msecs_to_jiffies(priv->led_off_duration) :
-                                    msecs_to_jiffies(priv->led_on_duration));
-
-       priv->led_on_duration = priv->led_on_cnt ?
-               max((ATH_LED_ON_DURATION_IDLE - priv->led_on_cnt), 25) :
-               ATH_LED_ON_DURATION_IDLE;
-       priv->led_off_duration = priv->led_off_cnt ?
-               max((ATH_LED_OFF_DURATION_IDLE - priv->led_off_cnt), 10) :
-               ATH_LED_OFF_DURATION_IDLE;
-       priv->led_on_cnt = priv->led_off_cnt = 0;
-
-       if (priv->op_flags & OP_LED_ON)
-               priv->op_flags &= ~OP_LED_ON;
-       else
-               priv->op_flags |= OP_LED_ON;
-}
-
-static void ath9k_led_brightness_work(struct work_struct *work)
-{
-       struct ath_led *led = container_of(work, struct ath_led,
-                                          brightness_work.work);
-       struct ath9k_htc_priv *priv = led->priv;
-
-       switch (led->brightness) {
-       case LED_OFF:
-               if (led->led_type == ATH_LED_ASSOC ||
-                   led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
-                                         (led->led_type == ATH_LED_RADIO));
-                       priv->op_flags &= ~OP_LED_ASSOCIATED;
-                       if (led->led_type == ATH_LED_RADIO)
-                               priv->op_flags &= ~OP_LED_ON;
-               } else {
-                       priv->led_off_cnt++;
-               }
-               break;
-       case LED_FULL:
-               if (led->led_type == ATH_LED_ASSOC) {
-                       priv->op_flags |= OP_LED_ASSOCIATED;
-                       ieee80211_queue_delayed_work(priv->hw,
-                                            &priv->ath9k_led_blink_work, 0);
-               } else if (led->led_type == ATH_LED_RADIO) {
-                       ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 0);
-                       priv->op_flags |= OP_LED_ON;
-               } else {
-                       priv->led_on_cnt++;
-               }
-               break;
-       default:
-               break;
-       }
+       ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin,
+                         (priv->brightness == LED_OFF));
 }
 
 static void ath9k_led_brightness(struct led_classdev *led_cdev,
                                 enum led_brightness brightness)
 {
-       struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
-       struct ath9k_htc_priv *priv = led->priv;
+       struct ath9k_htc_priv *priv = container_of(led_cdev,
+                                                  struct ath9k_htc_priv,
+                                                  led_cdev);
 
-       led->brightness = brightness;
-       if (!(priv->op_flags & OP_LED_DEINIT))
-               ieee80211_queue_delayed_work(priv->hw,
-                                            &led->brightness_work, 0);
-}
-
-void ath9k_led_stop_brightness(struct ath9k_htc_priv *priv)
-{
-       cancel_delayed_work_sync(&priv->radio_led.brightness_work);
-       cancel_delayed_work_sync(&priv->assoc_led.brightness_work);
-       cancel_delayed_work_sync(&priv->tx_led.brightness_work);
-       cancel_delayed_work_sync(&priv->rx_led.brightness_work);
-}
-
-static int ath9k_register_led(struct ath9k_htc_priv *priv, struct ath_led *led,
-                             char *trigger)
-{
-       int ret;
-
-       led->priv = priv;
-       led->led_cdev.name = led->name;
-       led->led_cdev.default_trigger = trigger;
-       led->led_cdev.brightness_set = ath9k_led_brightness;
-
-       ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_cdev);
-       if (ret)
-               ath_err(ath9k_hw_common(priv->ah),
-                       "Failed to register led:%s", led->name);
-       else
-               led->registered = 1;
-
-       INIT_DELAYED_WORK(&led->brightness_work, ath9k_led_brightness_work);
-
-       return ret;
-}
-
-static void ath9k_unregister_led(struct ath_led *led)
-{
-       if (led->registered) {
-               led_classdev_unregister(&led->led_cdev);
-               led->registered = 0;
-       }
+       /* Not locked, but it's just a tiny green light..*/
+       priv->brightness = brightness;
+       ieee80211_queue_work(priv->hw, &priv->led_work);
 }
 
 void ath9k_deinit_leds(struct ath9k_htc_priv *priv)
 {
-       priv->op_flags |= OP_LED_DEINIT;
-       ath9k_unregister_led(&priv->assoc_led);
-       priv->op_flags &= ~OP_LED_ASSOCIATED;
-       ath9k_unregister_led(&priv->tx_led);
-       ath9k_unregister_led(&priv->rx_led);
-       ath9k_unregister_led(&priv->radio_led);
+       if (!priv->led_registered)
+               return;
+
+       ath9k_led_brightness(&priv->led_cdev, LED_OFF);
+       led_classdev_unregister(&priv->led_cdev);
+       cancel_work_sync(&priv->led_work);
 }
 
 void ath9k_init_leds(struct ath9k_htc_priv *priv)
 {
-       char *trigger;
        int ret;
 
        if (AR_SREV_9287(priv->ah))
@@ -303,48 +206,21 @@ void ath9k_init_leds(struct ath9k_htc_priv *priv)
        /* LED off, active low */
        ath9k_hw_set_gpio(priv->ah, priv->ah->led_pin, 1);
 
-       INIT_DELAYED_WORK(&priv->ath9k_led_blink_work, ath9k_led_blink_work);
-
-       trigger = ieee80211_get_radio_led_name(priv->hw);
-       snprintf(priv->radio_led.name, sizeof(priv->radio_led.name),
-               "ath9k-%s::radio", wiphy_name(priv->hw->wiphy));
-       ret = ath9k_register_led(priv, &priv->radio_led, trigger);
-       priv->radio_led.led_type = ATH_LED_RADIO;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_assoc_led_name(priv->hw);
-       snprintf(priv->assoc_led.name, sizeof(priv->assoc_led.name),
-               "ath9k-%s::assoc", wiphy_name(priv->hw->wiphy));
-       ret = ath9k_register_led(priv, &priv->assoc_led, trigger);
-       priv->assoc_led.led_type = ATH_LED_ASSOC;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_tx_led_name(priv->hw);
-       snprintf(priv->tx_led.name, sizeof(priv->tx_led.name),
-               "ath9k-%s::tx", wiphy_name(priv->hw->wiphy));
-       ret = ath9k_register_led(priv, &priv->tx_led, trigger);
-       priv->tx_led.led_type = ATH_LED_TX;
-       if (ret)
-               goto fail;
-
-       trigger = ieee80211_get_rx_led_name(priv->hw);
-       snprintf(priv->rx_led.name, sizeof(priv->rx_led.name),
-               "ath9k-%s::rx", wiphy_name(priv->hw->wiphy));
-       ret = ath9k_register_led(priv, &priv->rx_led, trigger);
-       priv->rx_led.led_type = ATH_LED_RX;
-       if (ret)
-               goto fail;
-
-       priv->op_flags &= ~OP_LED_DEINIT;
+       snprintf(priv->led_name, sizeof(priv->led_name),
+               "ath9k_htc-%s", wiphy_name(priv->hw->wiphy));
+       priv->led_cdev.name = priv->led_name;
+       priv->led_cdev.brightness_set = ath9k_led_brightness;
 
-       return;
+       ret = led_classdev_register(wiphy_dev(priv->hw->wiphy), &priv->led_cdev);
+       if (ret < 0)
+               return;
 
-fail:
-       cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
-       ath9k_deinit_leds(priv);
+       INIT_WORK(&priv->led_work, ath9k_led_work);
+       priv->led_registered = true;
+
+       return;
 }
+#endif
 
 /*******************/
 /*     Rfkill     */
index 06e043b..bfdc8a8 100644 (file)
@@ -117,6 +117,21 @@ static struct ieee80211_rate ath9k_legacy_rates[] = {
        RATE(540, 0x0c, 0),
 };
 
+#ifdef CONFIG_MAC80211_LEDS
+static const struct ieee80211_tpt_blink ath9k_htc_tpt_blink[] = {
+       { .throughput = 0 * 1024, .blink_time = 334 },
+       { .throughput = 1 * 1024, .blink_time = 260 },
+       { .throughput = 5 * 1024, .blink_time = 220 },
+       { .throughput = 10 * 1024, .blink_time = 190 },
+       { .throughput = 20 * 1024, .blink_time = 170 },
+       { .throughput = 50 * 1024, .blink_time = 150 },
+       { .throughput = 70 * 1024, .blink_time = 130 },
+       { .throughput = 100 * 1024, .blink_time = 110 },
+       { .throughput = 200 * 1024, .blink_time = 80 },
+       { .throughput = 300 * 1024, .blink_time = 50 },
+};
+#endif
+
 static int ath9k_htc_wait_for_target(struct ath9k_htc_priv *priv)
 {
        int time_left;
@@ -243,7 +258,7 @@ static int ath9k_init_htc_services(struct ath9k_htc_priv *priv, u16 devid,
         */
 
        if (IS_AR7010_DEVICE(drv_info))
-               priv->htc->credits = 45;
+               priv->htc->credits = 48;
        else
                priv->htc->credits = 33;
 
@@ -753,6 +768,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
        hw->queues = 4;
        hw->channel_change_time = 5000;
        hw->max_listen_interval = 10;
+
+       if (AR_SREV_9271(priv->ah))
+               hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_9271;
+       else
+               hw->max_tx_aggregation_subframes = MAX_TX_AMPDU_SUBFRAMES_7010;
+
        hw->vif_data_size = sizeof(struct ath9k_htc_vif);
        hw->sta_data_size = sizeof(struct ath9k_htc_sta);
 
@@ -802,6 +823,17 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
                 priv->fw_version_major,
                 priv->fw_version_minor);
 
+       /*
+        * Check if the available FW matches the driver's
+        * required version.
+        */
+       if (priv->fw_version_major != MAJOR_VERSION_REQ ||
+           priv->fw_version_minor != MINOR_VERSION_REQ) {
+               dev_err(priv->dev, "ath9k_htc: Please upgrade to FW version %d.%d\n",
+                       MAJOR_VERSION_REQ, MINOR_VERSION_REQ);
+               return -EINVAL;
+       }
+
        return 0;
 }
 
@@ -846,6 +878,13 @@ static int ath9k_init_device(struct ath9k_htc_priv *priv,
        if (error != 0)
                goto err_rx;
 
+#ifdef CONFIG_MAC80211_LEDS
+       /* must be initialized before ieee80211_register_hw */
+       priv->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(priv->hw,
+               IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_htc_tpt_blink,
+               ARRAY_SIZE(ath9k_htc_tpt_blink));
+#endif
+
        /* Register with mac80211 */
        error = ieee80211_register_hw(hw);
        if (error)
index 4de3864..5aa104f 100644 (file)
@@ -332,6 +332,11 @@ static void __ath9k_htc_remove_monitor_interface(struct ath9k_htc_priv *priv)
        memcpy(&hvif.myaddr, common->macaddr, ETH_ALEN);
        hvif.index = priv->mon_vif_idx;
        WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+       if (ret) {
+               ath_err(common, "Unable to remove monitor interface at idx: %d\n",
+                       priv->mon_vif_idx);
+       }
+
        priv->nvifs--;
        priv->vif_slot &= ~(1 << priv->mon_vif_idx);
 }
@@ -462,6 +467,7 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
        struct ath9k_htc_sta *ista;
        int ret, sta_idx;
        u8 cmd_rsp;
+       u16 maxampdu;
 
        if (priv->nstations >= ATH9K_HTC_MAX_STA)
                return -ENOBUFS;
@@ -485,7 +491,15 @@ static int ath9k_htc_add_station(struct ath9k_htc_priv *priv,
 
        tsta.sta_index = sta_idx;
        tsta.vif_index = avp->index;
-       tsta.maxampdu = cpu_to_be16(0xffff);
+
+       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);
+       }
+
        if (sta && sta->ht_cap.ht_supported)
                tsta.flags = cpu_to_be16(ATH_HTC_STA_HT);
 
@@ -558,7 +572,8 @@ static int ath9k_htc_remove_station(struct ath9k_htc_priv *priv,
        return 0;
 }
 
-int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
+int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv,
+                               u8 enable_coex)
 {
        struct ath9k_htc_cap_target tcap;
        int ret;
@@ -566,13 +581,9 @@ int ath9k_htc_update_cap_target(struct ath9k_htc_priv *priv)
 
        memset(&tcap, 0, sizeof(struct ath9k_htc_cap_target));
 
-       /* FIXME: Values are hardcoded */
-       tcap.flags = 0x240c40;
-       tcap.flags_ext = 0x80601000;
-       tcap.ampdu_limit = 0xffff0000;
-       tcap.ampdu_subframes = 20;
-       tcap.tx_chainmask_legacy = priv->ah->caps.tx_chainmask;
-       tcap.protmode = 1;
+       tcap.ampdu_limit = cpu_to_be32(0xffff);
+       tcap.ampdu_subframes = priv->hw->max_tx_aggregation_subframes;
+       tcap.enable_coex = enable_coex;
        tcap.tx_chainmask = priv->ah->caps.tx_chainmask;
 
        WMI_CMD_BUF(WMI_TARGET_IC_UPDATE_CMDID, &tcap);
@@ -931,7 +942,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
 
        ath9k_host_rx_init(priv);
 
-       ret = ath9k_htc_update_cap_target(priv);
+       ret = ath9k_htc_update_cap_target(priv, 0);
        if (ret)
                ath_dbg(common, ATH_DBG_CONFIG,
                        "Failed to update capability in target\n");
@@ -964,7 +975,7 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
        struct ath9k_htc_priv *priv = hw->priv;
        struct ath_hw *ah = priv->ah;
        struct ath_common *common = ath9k_hw_common(ah);
-       int ret = 0;
+       int ret __attribute__ ((unused));
        u8 cmd_rsp;
 
        mutex_lock(&priv->mutex);
@@ -992,9 +1003,11 @@ static void ath9k_htc_stop(struct ieee80211_hw *hw)
        /* Cancel all the running timers/work .. */
        cancel_work_sync(&priv->fatal_work);
        cancel_work_sync(&priv->ps_work);
-       cancel_delayed_work_sync(&priv->ath9k_led_blink_work);
+
+#ifdef CONFIG_MAC80211_LEDS
+       cancel_work_sync(&priv->led_work);
+#endif
        ath9k_htc_stop_ani(priv);
-       ath9k_led_stop_brightness(priv);
 
        mutex_lock(&priv->mutex);
 
@@ -1135,6 +1148,10 @@ static void ath9k_htc_remove_interface(struct ieee80211_hw *hw,
        memcpy(&hvif.myaddr, vif->addr, ETH_ALEN);
        hvif.index = avp->index;
        WMI_CMD_BUF(WMI_VAP_REMOVE_CMDID, &hvif);
+       if (ret) {
+               ath_err(common, "Unable to remove interface at idx: %d\n",
+                       avp->index);
+       }
        priv->nvifs--;
        priv->vif_slot &= ~(1 << avp->index);
 
@@ -1567,6 +1584,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
        int ret = 0;
 
        mutex_lock(&priv->mutex);
+       ath9k_htc_ps_wakeup(priv);
 
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
@@ -1592,6 +1610,7 @@ static int ath9k_htc_ampdu_action(struct ieee80211_hw *hw,
                ath_err(ath9k_hw_common(priv->ah), "Unknown AMPDU action\n");
        }
 
+       ath9k_htc_ps_restore(priv);
        mutex_unlock(&priv->mutex);
 
        return ret;
@@ -1642,6 +1661,55 @@ static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
        mutex_unlock(&priv->mutex);
 }
 
+/*
+ * Currently, this is used only for selecting the minimum rate
+ * for management frames, rate selection for data frames remain
+ * unaffected.
+ */
+static int ath9k_htc_set_bitrate_mask(struct ieee80211_hw *hw,
+                                     struct ieee80211_vif *vif,
+                                     const struct cfg80211_bitrate_mask *mask)
+{
+       struct ath9k_htc_priv *priv = hw->priv;
+       struct ath_common *common = ath9k_hw_common(priv->ah);
+       struct ath9k_htc_target_rate_mask tmask;
+       struct ath9k_htc_vif *avp = (void *)vif->drv_priv;
+       int ret = 0;
+       u8 cmd_rsp;
+
+       memset(&tmask, 0, sizeof(struct ath9k_htc_target_rate_mask));
+
+       tmask.vif_index = avp->index;
+       tmask.band = IEEE80211_BAND_2GHZ;
+       tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_2GHZ].legacy);
+
+       WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
+       if (ret) {
+               ath_err(common,
+                       "Unable to set 2G rate mask for "
+                       "interface at idx: %d\n", avp->index);
+               goto out;
+       }
+
+       tmask.band = IEEE80211_BAND_5GHZ;
+       tmask.mask = cpu_to_be32(mask->control[IEEE80211_BAND_5GHZ].legacy);
+
+       WMI_CMD_BUF(WMI_BITRATE_MASK_CMDID, &tmask);
+       if (ret) {
+               ath_err(common,
+                       "Unable to set 5G rate mask for "
+                       "interface at idx: %d\n", avp->index);
+               goto out;
+       }
+
+       ath_dbg(common, ATH_DBG_CONFIG,
+               "Set bitrate masks: 0x%x, 0x%x\n",
+               mask->control[IEEE80211_BAND_2GHZ].legacy,
+               mask->control[IEEE80211_BAND_5GHZ].legacy);
+out:
+       return ret;
+}
+
 struct ieee80211_ops ath9k_htc_ops = {
        .tx                 = ath9k_htc_tx,
        .start              = ath9k_htc_start,
@@ -1664,4 +1732,5 @@ struct ieee80211_ops ath9k_htc_ops = {
        .set_rts_threshold  = ath9k_htc_set_rts_threshold,
        .rfkill_poll        = ath9k_htc_rfkill_poll_state,
        .set_coverage_class = ath9k_htc_set_coverage_class,
+       .set_bitrate_mask   = ath9k_htc_set_bitrate_mask,
 };
index 723a3a9..a898dac 100644 (file)
@@ -446,7 +446,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
        struct ieee80211_tx_info *tx_info;
        struct ieee80211_tx_rate *rate;
        struct ieee80211_conf *cur_conf = &priv->hw->conf;
-       struct ieee80211_supported_band *sband;
        bool txok;
        int slot;
 
@@ -461,7 +460,6 @@ static void ath9k_htc_tx_process(struct ath9k_htc_priv *priv,
        tx_info = IEEE80211_SKB_CB(skb);
        vif = tx_info->control.vif;
        rate = &tx_info->status.rates[0];
-       sband = priv->hw->wiphy->bands[cur_conf->channel->band];
 
        memset(&tx_info->status, 0, sizeof(tx_info->status));
 
index cb9174a..91a5305 100644 (file)
@@ -83,21 +83,10 @@ struct htc_ep_callbacks {
        void (*rx) (void *, struct sk_buff *, enum htc_endpoint_id);
 };
 
-#define HTC_TX_QUEUE_SIZE 256
-
-struct htc_txq {
-       struct sk_buff *buf[HTC_TX_QUEUE_SIZE];
-       u32 txqdepth;
-       u16 txbuf_cnt;
-       u16 txq_head;
-       u16 txq_tail;
-};
-
 struct htc_endpoint {
        u16 service_id;
 
        struct htc_ep_callbacks ep_callbacks;
-       struct htc_txq htc_txq;
        u32 max_txqdepth;
        int max_msglen;
 
index 045abd5..58f3d42 100644 (file)
@@ -247,6 +247,17 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
 {
        u32 val;
 
+       switch (ah->hw_version.devid) {
+       case AR5416_AR9100_DEVID:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
+               break;
+       case AR9300_DEVID_AR9340:
+               ah->hw_version.macVersion = AR_SREV_VERSION_9340;
+               val = REG_READ(ah, AR_SREV);
+               ah->hw_version.macRev = MS(val, AR_SREV_REVISION2);
+               return;
+       }
+
        val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
 
        if (val == 0xFF) {
@@ -462,7 +473,7 @@ static int ath9k_hw_post_init(struct ath_hw *ah)
                return ecode;
        }
 
-       if (!AR_SREV_9100(ah)) {
+       if (!AR_SREV_9100(ah) && !AR_SREV_9340(ah)) {
                ath9k_hw_ani_setup(ah);
                ath9k_hw_ani_init(ah);
        }
@@ -484,9 +495,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
        struct ath_common *common = ath9k_hw_common(ah);
        int r = 0;
 
-       if (ah->hw_version.devid == AR5416_AR9100_DEVID)
-               ah->hw_version.macVersion = AR_SREV_VERSION_9100;
-
        ath9k_hw_read_revisions(ah);
 
        /*
@@ -544,6 +552,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
        case AR_SREV_VERSION_9271:
        case AR_SREV_VERSION_9300:
        case AR_SREV_VERSION_9485:
+       case AR_SREV_VERSION_9340:
                break;
        default:
                ath_err(common,
@@ -552,7 +561,7 @@ static int __ath9k_hw_init(struct ath_hw *ah)
                return -EOPNOTSUPP;
        }
 
-       if (AR_SREV_9271(ah) || AR_SREV_9100(ah))
+       if (AR_SREV_9271(ah) || AR_SREV_9100(ah) || AR_SREV_9340(ah))
                ah->is_pciexpress = false;
 
        ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
@@ -621,6 +630,7 @@ int ath9k_hw_init(struct ath_hw *ah)
        case AR2427_DEVID_PCIE:
        case AR9300_DEVID_PCIE:
        case AR9300_DEVID_AR9485_PCIE:
+       case AR9300_DEVID_AR9340:
                break;
        default:
                if (common->bus_ops->ath_bus_type == ATH_USB)
@@ -663,7 +673,7 @@ static void ath9k_hw_init_qos(struct ath_hw *ah)
        REGWRITE_BUFFER_FLUSH(ah);
 }
 
-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
 {
        REG_CLR_BIT(ah, PLL3, PLL3_DO_MEAS_MASK);
        udelay(100);
@@ -676,7 +686,6 @@ unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah)
 }
 EXPORT_SYMBOL(ar9003_get_pll_sqsum_dvc);
 
-#define DPLL3_PHASE_SHIFT_VAL 0x1
 static void ath9k_hw_init_pll(struct ath_hw *ah,
                              struct ath9k_channel *chan)
 {
@@ -713,16 +722,48 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
                REG_RMW_FIELD(ah, AR_CH0_BB_DPLL2,
                              AR_CH0_BB_DPLL2_PLL_PWD, 0x0);
                udelay(1000);
+       } else if (AR_SREV_9340(ah)) {
+               u32 regval, pll2_divint, pll2_divfrac, refdiv;
 
-               REG_RMW_FIELD(ah, AR_CH0_BB_DPLL3,
-                             AR_CH0_DPLL3_PHASE_SHIFT, DPLL3_PHASE_SHIFT_VAL);
+               REG_WRITE(ah, AR_RTC_PLL_CONTROL, 0x1142c);
+               udelay(1000);
+
+               REG_SET_BIT(ah, AR_PHY_PLL_MODE, 0x1 << 16);
+               udelay(100);
+
+               if (ah->is_clk_25mhz) {
+                       pll2_divint = 0x54;
+                       pll2_divfrac = 0x1eb85;
+                       refdiv = 3;
+               } else {
+                       pll2_divint = 88;
+                       pll2_divfrac = 0;
+                       refdiv = 5;
+               }
+
+               regval = REG_READ(ah, AR_PHY_PLL_MODE);
+               regval |= (0x1 << 16);
+               REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+               udelay(100);
+
+               REG_WRITE(ah, AR_PHY_PLL_CONTROL, (refdiv << 27) |
+                         (pll2_divint << 18) | pll2_divfrac);
+               udelay(100);
+
+               regval = REG_READ(ah, AR_PHY_PLL_MODE);
+               regval = (regval & 0x80071fff) | (0x1 << 30) | (0x1 << 13) |
+                        (0x4 << 26) | (0x18 << 19);
+               REG_WRITE(ah, AR_PHY_PLL_MODE, regval);
+               REG_WRITE(ah, AR_PHY_PLL_MODE,
+                         REG_READ(ah, AR_PHY_PLL_MODE) & 0xfffeffff);
+               udelay(1000);
        }
 
        pll = ath9k_hw_compute_pll_control(ah, chan);
 
        REG_WRITE(ah, AR_RTC_PLL_CONTROL, pll);
 
-       if (AR_SREV_9485(ah))
+       if (AR_SREV_9485(ah) || AR_SREV_9340(ah))
                udelay(1000);
 
        /* Switch the core clock for ar9271 to 117Mhz */
@@ -734,17 +775,34 @@ static void ath9k_hw_init_pll(struct ath_hw *ah,
        udelay(RTC_PLL_SETTLE_DELAY);
 
        REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
+
+       if (AR_SREV_9340(ah)) {
+               if (ah->is_clk_25mhz) {
+                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+                       REG_WRITE(ah,  AR_SLP32_INC, 0x0001e7ae);
+               } else {
+                       REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+                       REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+                       REG_WRITE(ah,  AR_SLP32_INC, 0x0001e800);
+               }
+               udelay(100);
+       }
 }
 
 static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
                                          enum nl80211_iftype opmode)
 {
+       u32 sync_default = AR_INTR_SYNC_DEFAULT;
        u32 imr_reg = AR_IMR_TXERR |
                AR_IMR_TXURN |
                AR_IMR_RXERR |
                AR_IMR_RXORN |
                AR_IMR_BCNMISC;
 
+       if (AR_SREV_9340(ah))
+               sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
        if (AR_SREV_9300_20_OR_LATER(ah)) {
                imr_reg |= AR_IMR_RXOK_HP;
                if (ah->config.rx_intr_mitigation)
@@ -775,7 +833,7 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
 
        if (!AR_SREV_9100(ah)) {
                REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
-               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
+               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
                REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
        }
 
@@ -1487,7 +1545,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
                                REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
                }
 #ifdef __BIG_ENDIAN
-                else
+               else if (AR_SREV_9340(ah))
+                       REG_RMW(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB, 0);
+               else
                        REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
 #endif
        }
@@ -1793,7 +1853,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
        struct ath_common *common = ath9k_hw_common(ah);
        struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
 
-       u16 capField = 0, eeval;
+       u16 eeval;
        u8 ant_div_ctl1, tx_chainmask, rx_chainmask;
 
        eeval = ah->eep_ops->get_eeprom(ah, EEP_REG_0);
@@ -1804,8 +1864,6 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
                eeval |= AR9285_RDEXT_DEFAULT;
        regulatory->current_rd_ext = eeval;
 
-       capField = ah->eep_ops->get_eeprom(ah, EEP_OP_CAP);
-
        if (ah->opmode != NL80211_IFTYPE_AP &&
            ah->hw_version.subvendorid == AR_SUBVENDOR_ID_NEW_A) {
                if (regulatory->current_rd == 0x64 ||
@@ -1898,15 +1956,23 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
        else
                pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
 
-       if (AR_SREV_9280_20_OR_LATER(ah) && common->btcoex_enabled) {
-               btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO;
-               btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO;
-
-               if (AR_SREV_9285(ah)) {
+       if (common->btcoex_enabled) {
+               if (AR_SREV_9300_20_OR_LATER(ah)) {
                        btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
-                       btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO;
-               } else {
-                       btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
+                       btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9300;
+                       btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9300;
+                       btcoex_hw->btpriority_gpio = ATH_BTPRIORITY_GPIO_9300;
+               } else if (AR_SREV_9280_20_OR_LATER(ah)) {
+                       btcoex_hw->btactive_gpio = ATH_BTACTIVE_GPIO_9280;
+                       btcoex_hw->wlanactive_gpio = ATH_WLANACTIVE_GPIO_9280;
+
+                       if (AR_SREV_9285(ah)) {
+                               btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE;
+                               btcoex_hw->btpriority_gpio =
+                                               ATH_BTPRIORITY_GPIO_9285;
+                       } else {
+                               btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE;
+                       }
                }
        } else {
                btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE;
@@ -2359,11 +2425,11 @@ EXPORT_SYMBOL(ath_gen_timer_alloc);
 
 void ath9k_hw_gen_timer_start(struct ath_hw *ah,
                              struct ath_gen_timer *timer,
-                             u32 timer_next,
+                             u32 trig_timeout,
                              u32 timer_period)
 {
        struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
-       u32 tsf;
+       u32 tsf, timer_next;
 
        BUG_ON(!timer_period);
 
@@ -2371,18 +2437,13 @@ void ath9k_hw_gen_timer_start(struct ath_hw *ah,
 
        tsf = ath9k_hw_gettsf32(ah);
 
+       timer_next = tsf + trig_timeout;
+
        ath_dbg(ath9k_hw_common(ah), ATH_DBG_HWTIMER,
                "current tsf %x period %x timer_next %x\n",
                tsf, timer_period, timer_next);
 
        /*
-        * Pull timer_next forward if the current TSF already passed it
-        * because of software latency
-        */
-       if (timer_next < tsf)
-               timer_next = tsf + timer_period;
-
-       /*
         * Program generic timer registers
         */
        REG_WRITE(ah, gen_tmr_configuration[timer->index].next_addr,
index 1018d6c..34ed1bd 100644 (file)
@@ -43,6 +43,7 @@
 #define AR9287_DEVID_PCI       0x002d
 #define AR9287_DEVID_PCIE      0x002e
 #define AR9300_DEVID_PCIE      0x0030
+#define AR9300_DEVID_AR9340    0x0031
 #define AR9300_DEVID_AR9485_PCIE 0x0032
 
 #define AR5416_AR9100_DEVID    0x000b
@@ -55,6 +56,9 @@
 #define AT9285_COEX3WIRE_SA_SUBSYSID   0x30aa
 #define AT9285_COEX3WIRE_DA_SUBSYSID   0x30ab
 
+#define AR9300_NUM_BT_WEIGHTS   4
+#define AR9300_NUM_WLAN_WEIGHTS 4
+
 #define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
 
 #define        ATH_DEFAULT_NOISE_FLOOR -95
 #define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
 
 #define BASE_ACTIVATE_DELAY         100
-#define RTC_PLL_SETTLE_DELAY        100
+#define RTC_PLL_SETTLE_DELAY        (AR_SREV_9340(ah) ? 1000 : 100)
 #define COEF_SCALE_S                24
 #define HT40_CHANNEL_CENTER_SHIFT   10
 
@@ -771,6 +775,8 @@ struct ath_hw {
 
        /* Bluetooth coexistance */
        struct ath_btcoex_hw btcoex_hw;
+       u32 bt_coex_bt_weight[AR9300_NUM_BT_WEIGHTS];
+       u32 bt_coex_wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
 
        u32 intr_txqs;
        u8 txchainmask;
@@ -799,6 +805,7 @@ struct ath_hw {
        struct ar5416IniArray iniPcieSerdes;
        struct ar5416IniArray iniPcieSerdesLowPower;
        struct ar5416IniArray iniModesAdditional;
+       struct ar5416IniArray iniModesAdditional_40M;
        struct ar5416IniArray iniModesRxGain;
        struct ar5416IniArray iniModesTxGain;
        struct ar5416IniArray iniModes_9271_1_0_only;
@@ -845,6 +852,8 @@ struct ath_hw {
 
        /* Enterprise mode cap */
        u32 ent_mode;
+
+       bool is_clk_25mhz;
 };
 
 struct ath_bus_ops {
@@ -928,7 +937,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
 void ath9k_hw_reset_tsf(struct ath_hw *ah);
 void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
 void ath9k_hw_init_global_settings(struct ath_hw *ah);
-unsigned long ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
 void ath9k_hw_set11nmac2040(struct ath_hw *ah);
 void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
 void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
index 1ac8318..b172d15 100644 (file)
@@ -574,6 +574,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
                sc->sc_ah->gpio_mask = pdata->gpio_mask;
                sc->sc_ah->gpio_val = pdata->gpio_val;
                sc->sc_ah->led_pin = pdata->led_pin;
+               ah->is_clk_25mhz = pdata->is_clk_25mhz;
        }
 
        common = ath9k_hw_common(ah);
@@ -800,6 +801,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
 
        INIT_WORK(&sc->hw_check_work, ath_hw_check);
        INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
+       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
        sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
 
        ath_init_leds(sc);
index 1968c67..9cf7a7d 100644 (file)
@@ -812,10 +812,14 @@ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
 void ath9k_hw_enable_interrupts(struct ath_hw *ah)
 {
        struct ath_common *common = ath9k_hw_common(ah);
+       u32 sync_default = AR_INTR_SYNC_DEFAULT;
 
        if (!(ah->imask & ATH9K_INT_GLOBAL))
                return;
 
+       if (AR_SREV_9340(ah))
+               sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+
        ath_dbg(common, ATH_DBG_INTERRUPT, "enable IER\n");
        REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
        if (!AR_SREV_9100(ah)) {
@@ -824,10 +828,8 @@ void ath9k_hw_enable_interrupts(struct ath_hw *ah)
                REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
 
 
-               REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
-                         AR_INTR_SYNC_DEFAULT);
-               REG_WRITE(ah, AR_INTR_SYNC_MASK,
-                         AR_INTR_SYNC_DEFAULT);
+               REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
+               REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
        }
        ath_dbg(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
                REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
@@ -883,6 +885,9 @@ void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
                        mask |= AR_IMR_GENTMR;
        }
 
+       if (ints & ATH9K_INT_GENTIMER)
+               mask |= AR_IMR_GENTMR;
+
        if (ints & (ATH9K_INT_BMISC)) {
                mask |= AR_IMR_BCNMISC;
                if (ints & ATH9K_INT_TIM)
index a8d9009..c3dbf26 100644 (file)
@@ -624,6 +624,43 @@ out:
        ath9k_ps_restore(sc);
 }
 
+static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
+{
+       static int count;
+       struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+
+       if (pll_sqsum >= 0x40000) {
+               count++;
+               if (count == 3) {
+                       /* Rx is hung for more than 500ms. Reset it */
+                       ath_dbg(common, ATH_DBG_RESET,
+                               "Possible RX hang, resetting");
+                       ath_reset(sc, true);
+                       count = 0;
+               }
+       } else
+               count = 0;
+}
+
+void ath_hw_pll_work(struct work_struct *work)
+{
+       struct ath_softc *sc = container_of(work, struct ath_softc,
+                                           hw_pll_work.work);
+       u32 pll_sqsum;
+
+       if (AR_SREV_9485(sc->sc_ah)) {
+
+               ath9k_ps_wakeup(sc);
+               pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
+               ath9k_ps_restore(sc);
+
+               ath_hw_pll_rx_hang_check(sc, pll_sqsum);
+
+               ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
+       }
+}
+
+
 void ath9k_tasklet(unsigned long data)
 {
        struct ath_softc *sc = (struct ath_softc *)data;
@@ -1932,6 +1969,12 @@ static void ath9k_bss_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
                                "Bss Info ASSOC %d, bssid: %pM\n",
                                bss_conf->aid, common->curbssid);
                        ath_beacon_config(sc, vif);
+                       /*
+                        * Request a re-configuration of Beacon related timers
+                        * on the receipt of the first Beacon frame (i.e.,
+                        * after time sync with the AP).
+                        */
+                       sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
                        /* Reset rssi stats */
                        sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
                        sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
@@ -2219,9 +2262,7 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
        int timeout = 200; /* ms */
        int i, j;
 
-       ath9k_ps_wakeup(sc);
        mutex_lock(&sc->mutex);
-
        cancel_delayed_work_sync(&sc->tx_complete_work);
 
        if (drop)
@@ -2244,15 +2285,15 @@ static void ath9k_flush(struct ieee80211_hw *hw, bool drop)
                    goto out;
        }
 
+       ath9k_ps_wakeup(sc);
        if (!ath_drain_all_txq(sc, false))
                ath_reset(sc, false);
-
+       ath9k_ps_restore(sc);
        ieee80211_wake_queues(hw);
 
 out:
        ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
        mutex_unlock(&sc->mutex);
-       ath9k_ps_restore(sc);
 }
 
 static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
index 8e5fe9d..9441bf8 100644 (file)
@@ -45,4 +45,7 @@
 #define        AR_PHY_TIMING11_SPUR_FREQ_SD            0x3FF00000
 #define        AR_PHY_TIMING11_SPUR_FREQ_SD_S          20
 
+#define AR_PHY_PLL_CONTROL 0x16180
+#define AR_PHY_PLL_MODE 0x16184
+
 #endif
index 1809409..4ccbf2d 100644 (file)
@@ -854,14 +854,13 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
        ath_rc_rate_set_rtscts(sc, rate_table, tx_info);
 }
 
-static bool ath_rc_update_per(struct ath_softc *sc,
+static void ath_rc_update_per(struct ath_softc *sc,
                              const struct ath_rate_table *rate_table,
                              struct ath_rate_priv *ath_rc_priv,
                                  struct ieee80211_tx_info *tx_info,
                              int tx_rate, int xretries, int retries,
                              u32 now_msec)
 {
-       bool state_change = false;
        int count, n_bad_frames;
        u8 last_per;
        static const u32 nretry_to_per_lookup[10] = {
@@ -992,8 +991,6 @@ static bool ath_rc_update_per(struct ath_softc *sc,
 
                }
        }
-
-       return state_change;
 }
 
 static void ath_debug_stat_retries(struct ath_rate_priv *rc, int rix,
@@ -1017,7 +1014,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
        u32 now_msec = jiffies_to_msecs(jiffies);
        int rate;
        u8 last_per;
-       bool state_change = false;
        const struct ath_rate_table *rate_table = ath_rc_priv->rate_table;
        int size = ath_rc_priv->rate_table_size;
 
@@ -1027,9 +1023,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
        last_per = ath_rc_priv->per[tx_rate];
 
        /* Update PER first */
-       state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
-                                        tx_info, tx_rate, xretries,
-                                        retries, now_msec);
+       ath_rc_update_per(sc, rate_table, ath_rc_priv,
+                         tx_info, tx_rate, xretries,
+                         retries, now_msec);
 
        /*
         * If this rate looks bad (high PER) then stop using it for
index f69dcdf..c5b7cbe 100644 (file)
@@ -1339,7 +1339,7 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
        struct ath_hw_antcomb_conf div_ant_conf;
        struct ath_ant_comb *antcomb = &sc->ant_comb;
        int alt_ratio = 0, alt_rssi_avg = 0, main_rssi_avg = 0, curr_alt_set;
-       int curr_main_set, curr_bias;
+       int curr_main_set;
        int main_rssi = rs->rs_rssi_ctl0;
        int alt_rssi = rs->rs_rssi_ctl1;
        int rx_ant_conf,  main_ant_conf;
@@ -1393,7 +1393,6 @@ static void ath_ant_comb_scan(struct ath_softc *sc, struct ath_rx_status *rs)
        ath9k_hw_antdiv_comb_conf_get(sc->sc_ah, &div_ant_conf);
        curr_alt_set = div_ant_conf.alt_lna_conf;
        curr_main_set = div_ant_conf.main_lna_conf;
-       curr_bias = div_ant_conf.fast_div_bias;
 
        antcomb->count++;
 
@@ -1743,7 +1742,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
                if ((sc->ps_flags & (PS_WAIT_FOR_BEACON |
                                              PS_WAIT_FOR_CAB |
                                              PS_WAIT_FOR_PSPOLL_DATA)) ||
-                                       unlikely(ath9k_check_auto_sleep(sc)))
+                                               ath9k_check_auto_sleep(sc))
                        ath_rx_ps(sc, skb);
                spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
 
index 6acbf0e..456f3ec 100644 (file)
 #define AR_RC_APB            0x00000002
 #define AR_RC_HOSTIF         0x00000100
 
-#define AR_WA                          0x4004
+#define AR_WA                  (AR_SREV_9340(ah) ? 0x40c4 : 0x4004)
 #define AR_WA_BIT6                     (1 << 6)
 #define AR_WA_BIT7                     (1 << 7)
 #define AR_WA_BIT23                    (1 << 23)
 #define AR_PM_STATE                 0x4008
 #define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
 
-#define AR_HOST_TIMEOUT             0x4018
+#define AR_HOST_TIMEOUT             (AR_SREV_9340(ah) ? 0x4008 : 0x4018)
 #define AR_HOST_TIMEOUT_APB_CNTR    0x0000FFFF
 #define AR_HOST_TIMEOUT_APB_CNTR_S  0
 #define AR_HOST_TIMEOUT_LCL_CNTR    0xFFFF0000
 #define EEPROM_PROTECT_WP_1024_2047   0x8000
 
 #define AR_SREV \
-       ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
+       ((AR_SREV_9100(ah)) ? 0x0600 : (AR_SREV_9340(ah) \
+                                       ? 0x400c : 0x4020))
 
 #define AR_SREV_ID \
        ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
 #define AR_SREV_VERSION_9485           0x240
 #define AR_SREV_REVISION_9485_10       0
 #define AR_SREV_REVISION_9485_11        1
+#define AR_SREV_VERSION_9340           0x300
 
 #define AR_SREV_5416(_ah) \
        (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
 #define AR_SREV_9485_11(_ah) \
        (AR_SREV_9485(_ah) && \
         ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
+#define AR_SREV_9485_OR_LATER(_ah) \
+       (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
+
+#define AR_SREV_9340(_ah) \
+       (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9340))
 
 #define AR_SREV_9285E_20(_ah) \
     (AR_SREV_9285_12_OR_LATER(_ah) && \
@@ -910,11 +917,11 @@ enum ath_usb_dev {
 #define AR_INTR_SPURIOUS                      0xFFFFFFFF
 
 
-#define AR_INTR_SYNC_CAUSE_CLR                0x4028
+#define AR_INTR_SYNC_CAUSE                    (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
+#define AR_INTR_SYNC_CAUSE_CLR                (AR_SREV_9340(ah) ? 0x4010 : 0x4028)
 
-#define AR_INTR_SYNC_CAUSE                    0x4028
 
-#define AR_INTR_SYNC_ENABLE                   0x402c
+#define AR_INTR_SYNC_ENABLE                   (AR_SREV_9340(ah) ? 0x4014 : 0x402c)
 #define AR_INTR_SYNC_ENABLE_GPIO              0xFFFC0000
 #define AR_INTR_SYNC_ENABLE_GPIO_S            18
 
@@ -954,24 +961,24 @@ enum {
 
 };
 
-#define AR_INTR_ASYNC_MASK                       0x4030
+#define AR_INTR_ASYNC_MASK                       (AR_SREV_9340(ah) ? 0x4018 : 0x4030)
 #define AR_INTR_ASYNC_MASK_GPIO                  0xFFFC0000
 #define AR_INTR_ASYNC_MASK_GPIO_S                18
 
-#define AR_INTR_SYNC_MASK                        0x4034
+#define AR_INTR_SYNC_MASK                        (AR_SREV_9340(ah) ? 0x401c : 0x4034)
 #define AR_INTR_SYNC_MASK_GPIO                   0xFFFC0000
 #define AR_INTR_SYNC_MASK_GPIO_S                 18
 
-#define AR_INTR_ASYNC_CAUSE_CLR                  0x4038
-#define AR_INTR_ASYNC_CAUSE                      0x4038
+#define AR_INTR_ASYNC_CAUSE_CLR                  (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
+#define AR_INTR_ASYNC_CAUSE                      (AR_SREV_9340(ah) ? 0x4020 : 0x4038)
 
-#define AR_INTR_ASYNC_ENABLE                     0x403c
+#define AR_INTR_ASYNC_ENABLE                     (AR_SREV_9340(ah) ? 0x4024 : 0x403c)
 #define AR_INTR_ASYNC_ENABLE_GPIO                0xFFFC0000
 #define AR_INTR_ASYNC_ENABLE_GPIO_S              18
 
 #define AR_PCIE_SERDES                           0x4040
 #define AR_PCIE_SERDES2                          0x4044
-#define AR_PCIE_PM_CTRL                          0x4014
+#define AR_PCIE_PM_CTRL                          (AR_SREV_9340(ah) ? 0x4004 : 0x4014)
 #define AR_PCIE_PM_CTRL_ENA                      0x00080000
 
 #define AR_NUM_GPIO                              14
@@ -982,7 +989,7 @@ enum {
 #define AR9300_NUM_GPIO                          17
 #define AR7010_NUM_GPIO                          16
 
-#define AR_GPIO_IN_OUT                           0x4048
+#define AR_GPIO_IN_OUT                           (AR_SREV_9340(ah) ? 0x4028 : 0x4048)
 #define AR_GPIO_IN_VAL                           0x0FFFC000
 #define AR_GPIO_IN_VAL_S                         14
 #define AR928X_GPIO_IN_VAL                       0x000FFC00
@@ -996,11 +1003,12 @@ enum {
 #define AR7010_GPIO_IN_VAL                       0x0000FFFF
 #define AR7010_GPIO_IN_VAL_S                     0
 
-#define AR_GPIO_IN                              0x404c
+#define AR_GPIO_IN                              (AR_SREV_9340(ah) ? 0x402c : 0x404c)
 #define AR9300_GPIO_IN_VAL                       0x0001FFFF
 #define AR9300_GPIO_IN_VAL_S                     0
 
-#define AR_GPIO_OE_OUT                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c)
+#define AR_GPIO_OE_OUT                           (AR_SREV_9340(ah) ? 0x4030 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c))
 #define AR_GPIO_OE_OUT_DRV                       0x3
 #define AR_GPIO_OE_OUT_DRV_NO                    0x0
 #define AR_GPIO_OE_OUT_DRV_LOW                   0x1
@@ -1022,11 +1030,13 @@ enum {
 #define AR7010_GPIO_INT_MASK                     0x52024
 #define AR7010_GPIO_FUNCTION                     0x52028
 
-#define AR_GPIO_INTR_POL                         (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050)
+#define AR_GPIO_INTR_POL                         (AR_SREV_9340(ah) ? 0x4038 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4058 : 0x4050))
 #define AR_GPIO_INTR_POL_VAL                     0x0001FFFF
 #define AR_GPIO_INTR_POL_VAL_S                   0
 
-#define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054)
+#define AR_GPIO_INPUT_EN_VAL                     (AR_SREV_9340(ah) ? 0x403c : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x405c : 0x4054))
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF     0x00000004
 #define AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_S       2
 #define AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF    0x00000008
@@ -1044,13 +1054,15 @@ enum {
 #define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE        0x00010000
 #define AR_GPIO_JTAG_DISABLE                     0x00020000
 
-#define AR_GPIO_INPUT_MUX1                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058)
+#define AR_GPIO_INPUT_MUX1                       (AR_SREV_9340(ah) ? 0x4040 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4060 : 0x4058))
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE             0x000f0000
 #define AR_GPIO_INPUT_MUX1_BT_ACTIVE_S           16
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY           0x00000f00
 #define AR_GPIO_INPUT_MUX1_BT_PRIORITY_S         8
 
-#define AR_GPIO_INPUT_MUX2                       (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c)
+#define AR_GPIO_INPUT_MUX2                       (AR_SREV_9340(ah) ? 0x4044 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4064 : 0x405c))
 #define AR_GPIO_INPUT_MUX2_CLK25                 0x0000000f
 #define AR_GPIO_INPUT_MUX2_CLK25_S               0
 #define AR_GPIO_INPUT_MUX2_RFSILENT              0x000000f0
@@ -1058,13 +1070,18 @@ enum {
 #define AR_GPIO_INPUT_MUX2_RTC_RESET             0x00000f00
 #define AR_GPIO_INPUT_MUX2_RTC_RESET_S           8
 
-#define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060)
-#define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064)
-#define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068)
+#define AR_GPIO_OUTPUT_MUX1                      (AR_SREV_9340(ah) ? 0x4048 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4068 : 0x4060))
+#define AR_GPIO_OUTPUT_MUX2                      (AR_SREV_9340(ah) ? 0x404c : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x406c : 0x4064))
+#define AR_GPIO_OUTPUT_MUX3                      (AR_SREV_9340(ah) ? 0x4050 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4070 : 0x4068))
 
-#define AR_INPUT_STATE                           (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c)
+#define AR_INPUT_STATE                           (AR_SREV_9340(ah) ? 0x4054 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4074 : 0x406c))
 
-#define AR_EEPROM_STATUS_DATA                    (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c)
+#define AR_EEPROM_STATUS_DATA                    (AR_SREV_9340(ah) ? 0x40c8 : \
+                                                 (AR_SREV_9300_20_OR_LATER(ah) ? 0x4084 : 0x407c))
 #define AR_EEPROM_STATUS_DATA_VAL                0x0000ffff
 #define AR_EEPROM_STATUS_DATA_VAL_S              0
 #define AR_EEPROM_STATUS_DATA_BUSY               0x00010000
@@ -1072,17 +1089,19 @@ enum {
 #define AR_EEPROM_STATUS_DATA_PROT_ACCESS        0x00040000
 #define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS      0x00080000
 
-#define AR_OBS                  (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080)
+#define AR_OBS                  (AR_SREV_9340(ah) ? 0x405c : \
+                                (AR_SREV_9300_20_OR_LATER(ah) ? 0x4088 : 0x4080))
 
 #define AR_GPIO_PDPU                             (AR_SREV_9300_20_OR_LATER(ah) ? 0x4090 : 0x4088)
 
-#define AR_PCIE_MSI                              (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094)
+#define AR_PCIE_MSI                             (AR_SREV_9340(ah) ? 0x40d8 : \
+                                                (AR_SREV_9300_20_OR_LATER(ah) ? 0x40a4 : 0x4094))
 #define AR_PCIE_MSI_ENABLE                       0x00000001
 
-#define AR_INTR_PRIO_SYNC_ENABLE  0x40c4
-#define AR_INTR_PRIO_ASYNC_MASK   0x40c8
-#define AR_INTR_PRIO_SYNC_MASK    0x40cc
-#define AR_INTR_PRIO_ASYNC_ENABLE 0x40d4
+#define AR_INTR_PRIO_SYNC_ENABLE  (AR_SREV_9340(ah) ? 0x4088 : 0x40c4)
+#define AR_INTR_PRIO_ASYNC_MASK   (AR_SREV_9340(ah) ? 0x408c : 0x40c8)
+#define AR_INTR_PRIO_SYNC_MASK    (AR_SREV_9340(ah) ? 0x4090 : 0x40cc)
+#define AR_INTR_PRIO_ASYNC_ENABLE (AR_SREV_9340(ah) ? 0x4094 : 0x40d4)
 #define AR_ENT_OTP               0x40d8
 #define AR_ENT_OTP_CHAIN2_DISABLE               0x00020000
 #define AR_ENT_OTP_MPSD                0x00800000
@@ -1163,6 +1182,7 @@ enum {
 #define AR_RTC_PLL_REFDIV_5     0x000000c0
 #define AR_RTC_PLL_CLKSEL       0x00000300
 #define AR_RTC_PLL_CLKSEL_S     8
+#define AR_RTC_PLL_BYPASS      0x00010000
 
 #define PLL3 0x16188
 #define PLL3_DO_MEAS_MASK 0x40000000
@@ -1209,7 +1229,8 @@ enum {
 
 /* RTC_DERIVED_* - only for AR9100 */
 
-#define AR_RTC_DERIVED_CLK           (AR_RTC_BASE + 0x0038)
+#define AR_RTC_DERIVED_CLK \
+       (AR_SREV_9100(ah) ? (AR_RTC_BASE + 0x0038) : 0x7038)
 #define AR_RTC_DERIVED_CLK_PERIOD    0x0000fffe
 #define AR_RTC_DERIVED_CLK_PERIOD_S  1
 
@@ -1688,6 +1709,22 @@ enum {
 #define AR_BTCOEX_WL_WGHT          0xffff0000
 #define AR_BTCOEX_WL_WGHT_S        16
 
+#define AR_BT_COEX_WL_WEIGHTS0     0x8174
+#define AR_BT_COEX_WL_WEIGHTS1     0x81c4
+
+#define AR_BT_COEX_BT_WEIGHTS0     0x83ac
+#define AR_BT_COEX_BT_WEIGHTS1     0x83b0
+#define AR_BT_COEX_BT_WEIGHTS2     0x83b4
+#define AR_BT_COEX_BT_WEIGHTS3     0x83b8
+
+#define AR9300_BT_WGHT                     0xcccc4444
+#define AR9300_STOMP_ALL_WLAN_WGHT0        0xfffffff0
+#define AR9300_STOMP_ALL_WLAN_WGHT1        0xfffffff0
+#define AR9300_STOMP_LOW_WLAN_WGHT0        0x88888880
+#define AR9300_STOMP_LOW_WLAN_WGHT1        0x88888880
+#define AR9300_STOMP_NONE_WLAN_WGHT0       0x00000000
+#define AR9300_STOMP_NONE_WLAN_WGHT1       0x00000000
+
 #define AR_BT_COEX_MODE2           0x817c
 #define AR_BT_BCN_MISS_THRESH      0x000000ff
 #define AR_BT_BCN_MISS_THRESH_S    0
index 8f095ad..f9b1eb4 100644 (file)
@@ -79,8 +79,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
                return "WMI_TX_STATS_CMDID";
        case WMI_RX_STATS_CMDID:
                return "WMI_RX_STATS_CMDID";
-       case WMI_AGGR_LIMIT_CMD:
-               return "WMI_AGGR_LIMIT_CMD";
+       case WMI_BITRATE_MASK_CMDID:
+               return "WMI_BITRATE_MASK_CMDID";
        }
 
        return "Bogus";
index 02ecb9f..6095eeb 100644 (file)
@@ -111,7 +111,7 @@ enum wmi_cmd_id {
        WMI_INT_STATS_CMDID,
        WMI_TX_STATS_CMDID,
        WMI_RX_STATS_CMDID,
-       WMI_AGGR_LIMIT_CMD = 0x0026,
+       WMI_BITRATE_MASK_CMDID,
 };
 
 enum wmi_event_id {
index e9e99f7..7b91b2a 100644 (file)
@@ -2180,28 +2180,6 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
        }
 }
 
-static void ath_hw_pll_work(struct work_struct *work)
-{
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           hw_pll_work.work);
-       static int count;
-
-       if (AR_SREV_9485(sc->sc_ah)) {
-               if (ar9003_get_pll_sqsum_dvc(sc->sc_ah) >= 0x40000) {
-                       count++;
-
-                       if (count == 3) {
-                               /* Rx is hung for more than 500ms. Reset it */
-                               ath_reset(sc, true);
-                               count = 0;
-                       }
-               } else
-                       count = 0;
-
-               ieee80211_queue_delayed_work(sc->hw, &sc->hw_pll_work, HZ/5);
-       }
-}
-
 static void ath_tx_complete_poll_work(struct work_struct *work)
 {
        struct ath_softc *sc = container_of(work, struct ath_softc,
@@ -2396,7 +2374,6 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
        }
 
        INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
-       INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
 
        if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
                error = ath_tx_edma_init(sc);
index 3d4ed58..bb57869 100644 (file)
@@ -448,6 +448,8 @@ struct carl9170_ba_stats {
 
 struct carl9170_sta_info {
        bool ht_sta;
+       bool sleeping;
+       atomic_t pending_frames;
        unsigned int ampdu_max_len;
        struct carl9170_sta_tid *agg[CARL9170_NUM_TID];
        struct carl9170_ba_stats stats[CARL9170_NUM_TID];
index 89fe60a..1638468 100644 (file)
@@ -1193,6 +1193,8 @@ static int carl9170_op_sta_add(struct ieee80211_hw *hw,
        struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
        unsigned int i;
 
+       atomic_set(&sta_info->pending_frames, 0);
+
        if (sta->ht_cap.ht_supported) {
                if (sta->ht_cap.ampdu_density > 6) {
                        /*
@@ -1467,99 +1469,17 @@ static void carl9170_op_sta_notify(struct ieee80211_hw *hw,
                                   enum sta_notify_cmd cmd,
                                   struct ieee80211_sta *sta)
 {
-       struct ar9170 *ar = hw->priv;
        struct carl9170_sta_info *sta_info = (void *) sta->drv_priv;
-       struct sk_buff *skb, *tmp;
-       struct sk_buff_head free;
-       int i;
 
        switch (cmd) {
        case STA_NOTIFY_SLEEP:
-               /*
-                * Since the peer is no longer listening, we have to return
-                * as many SKBs as possible back to the mac80211 stack.
-                * It will deal with the retry procedure, once the peer
-                * has become available again.
-                *
-                * NB: Ideally, the driver should return the all frames in
-                * the correct, ascending order. However, I think that this
-                * functionality should be implemented in the stack and not
-                * here...
-                */
-
-               __skb_queue_head_init(&free);
-
-               if (sta->ht_cap.ht_supported) {
-                       rcu_read_lock();
-                       for (i = 0; i < CARL9170_NUM_TID; i++) {
-                               struct carl9170_sta_tid *tid_info;
-
-                               tid_info = rcu_dereference(sta_info->agg[i]);
-
-                               if (!tid_info)
-                                       continue;
-
-                               spin_lock_bh(&ar->tx_ampdu_list_lock);
-                               if (tid_info->state >
-                                   CARL9170_TID_STATE_SUSPEND)
-                                       tid_info->state =
-                                               CARL9170_TID_STATE_SUSPEND;
-                               spin_unlock_bh(&ar->tx_ampdu_list_lock);
-
-                               spin_lock_bh(&tid_info->lock);
-                               while ((skb = __skb_dequeue(&tid_info->queue)))
-                                       __skb_queue_tail(&free, skb);
-                               spin_unlock_bh(&tid_info->lock);
-                       }
-                       rcu_read_unlock();
-               }
-
-               for (i = 0; i < ar->hw->queues; i++) {
-                       spin_lock_bh(&ar->tx_pending[i].lock);
-                       skb_queue_walk_safe(&ar->tx_pending[i], skb, tmp) {
-                               struct _carl9170_tx_superframe *super;
-                               struct ieee80211_hdr *hdr;
-                               struct ieee80211_tx_info *info;
-
-                               super = (void *) skb->data;
-                               hdr = (void *) super->frame_data;
-
-                               if (compare_ether_addr(hdr->addr1, sta->addr))
-                                       continue;
-
-                               __skb_unlink(skb, &ar->tx_pending[i]);
-
-                               info = IEEE80211_SKB_CB(skb);
-                               if (info->flags & IEEE80211_TX_CTL_AMPDU)
-                                       atomic_dec(&ar->tx_ampdu_upload);
-
-                               carl9170_tx_status(ar, skb, false);
-                       }
-                       spin_unlock_bh(&ar->tx_pending[i].lock);
-               }
-
-               while ((skb = __skb_dequeue(&free)))
-                       carl9170_tx_status(ar, skb, false);
-
+               sta_info->sleeping = true;
+               if (atomic_read(&sta_info->pending_frames))
+                       ieee80211_sta_block_awake(hw, sta, true);
                break;
 
        case STA_NOTIFY_AWAKE:
-               if (!sta->ht_cap.ht_supported)
-                       return;
-
-               rcu_read_lock();
-               for (i = 0; i < CARL9170_NUM_TID; i++) {
-                       struct carl9170_sta_tid *tid_info;
-
-                       tid_info = rcu_dereference(sta_info->agg[i]);
-
-                       if (!tid_info)
-                               continue;
-
-                       if ((tid_info->state == CARL9170_TID_STATE_SUSPEND))
-                               tid_info->state = CARL9170_TID_STATE_IDLE;
-               }
-               rcu_read_unlock();
+               sta_info->sleeping = false;
                break;
        }
 }
index cb70ed7..bf2eff9 100644 (file)
@@ -104,6 +104,56 @@ static void carl9170_tx_accounting(struct ar9170 *ar, struct sk_buff *skb)
        spin_unlock_bh(&ar->tx_stats_lock);
 }
 
+/* needs rcu_read_lock */
+static struct ieee80211_sta *__carl9170_get_tx_sta(struct ar9170 *ar,
+                                                  struct sk_buff *skb)
+{
+       struct _carl9170_tx_superframe *super = (void *) skb->data;
+       struct ieee80211_hdr *hdr = (void *) super->frame_data;
+       struct ieee80211_vif *vif;
+       unsigned int vif_id;
+
+       vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
+                CARL9170_TX_SUPER_MISC_VIF_ID_S;
+
+       if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
+               return NULL;
+
+       vif = rcu_dereference(ar->vif_priv[vif_id].vif);
+       if (unlikely(!vif))
+               return NULL;
+
+       /*
+        * Normally we should use wrappers like ieee80211_get_DA to get
+        * the correct peer ieee80211_sta.
+        *
+        * But there is a problem with indirect traffic (broadcasts, or
+        * data which is designated for other stations) in station mode.
+        * The frame will be directed to the AP for distribution and not
+        * to the actual destination.
+        */
+
+       return ieee80211_find_sta(vif, hdr->addr1);
+}
+
+static void carl9170_tx_ps_unblock(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ieee80211_sta *sta;
+       struct carl9170_sta_info *sta_info;
+
+       rcu_read_lock();
+       sta = __carl9170_get_tx_sta(ar, skb);
+       if (unlikely(!sta))
+               goto out_rcu;
+
+       sta_info = (struct carl9170_sta_info *) sta->drv_priv;
+       if (atomic_dec_return(&sta_info->pending_frames) == 0)
+               ieee80211_sta_block_awake(ar->hw, sta, false);
+
+out_rcu:
+       rcu_read_unlock();
+}
+
 static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
 {
        struct ieee80211_tx_info *txinfo;
@@ -135,6 +185,7 @@ static void carl9170_tx_accounting_free(struct ar9170 *ar, struct sk_buff *skb)
        }
 
        spin_unlock_bh(&ar->tx_stats_lock);
+
        if (atomic_dec_and_test(&ar->tx_total_queued))
                complete(&ar->tx_flush);
 }
@@ -329,13 +380,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
 {
        struct _carl9170_tx_superframe *super = (void *) skb->data;
        struct ieee80211_hdr *hdr = (void *) super->frame_data;
-       struct ieee80211_tx_info *tx_info;
        struct carl9170_tx_info *ar_info;
-       struct carl9170_sta_info *sta_info;
        struct ieee80211_sta *sta;
+       struct carl9170_sta_info *sta_info;
        struct carl9170_sta_tid *tid_info;
-       struct ieee80211_vif *vif;
-       unsigned int vif_id;
        u8 tid;
 
        if (!(txinfo->flags & IEEE80211_TX_CTL_AMPDU) ||
@@ -343,30 +391,10 @@ static void carl9170_tx_status_process_ampdu(struct ar9170 *ar,
           (!(super->f.mac_control & cpu_to_le16(AR9170_TX_MAC_AGGR))))
                return;
 
-       tx_info = IEEE80211_SKB_CB(skb);
-       ar_info = (void *) tx_info->rate_driver_data;
-
-       vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
-                CARL9170_TX_SUPER_MISC_VIF_ID_S;
-
-       if (WARN_ON_ONCE(vif_id >= AR9170_MAX_VIRTUAL_MAC))
-               return;
+       ar_info = (void *) txinfo->rate_driver_data;
 
        rcu_read_lock();
-       vif = rcu_dereference(ar->vif_priv[vif_id].vif);
-       if (unlikely(!vif))
-               goto out_rcu;
-
-       /*
-        * Normally we should use wrappers like ieee80211_get_DA to get
-        * the correct peer ieee80211_sta.
-        *
-        * But there is a problem with indirect traffic (broadcasts, or
-        * data which is designated for other stations) in station mode.
-        * The frame will be directed to the AP for distribution and not
-        * to the actual destination.
-        */
-       sta = ieee80211_find_sta(vif, hdr->addr1);
+       sta = __carl9170_get_tx_sta(ar, skb);
        if (unlikely(!sta))
                goto out_rcu;
 
@@ -427,6 +455,7 @@ void carl9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
        if (txinfo->flags & IEEE80211_TX_CTL_AMPDU)
                carl9170_tx_status_process_ampdu(ar, skb, txinfo);
 
+       carl9170_tx_ps_unblock(ar, skb);
        carl9170_tx_put_skb(skb);
 }
 
@@ -540,11 +569,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
        struct sk_buff *skb;
        struct ieee80211_tx_info *txinfo;
        struct carl9170_tx_info *arinfo;
-       struct _carl9170_tx_superframe *super;
        struct ieee80211_sta *sta;
-       struct ieee80211_vif *vif;
-       struct ieee80211_hdr *hdr;
-       unsigned int vif_id;
 
        rcu_read_lock();
        list_for_each_entry_rcu(iter, &ar->tx_ampdu_list, list) {
@@ -562,20 +587,7 @@ static void carl9170_tx_ampdu_timeout(struct ar9170 *ar)
                    msecs_to_jiffies(CARL9170_QUEUE_TIMEOUT)))
                        goto unlock;
 
-               super = (void *) skb->data;
-               hdr = (void *) super->frame_data;
-
-               vif_id = (super->s.misc & CARL9170_TX_SUPER_MISC_VIF_ID) >>
-                        CARL9170_TX_SUPER_MISC_VIF_ID_S;
-
-               if (WARN_ON(vif_id >= AR9170_MAX_VIRTUAL_MAC))
-                       goto unlock;
-
-               vif = rcu_dereference(ar->vif_priv[vif_id].vif);
-               if (WARN_ON(!vif))
-                       goto unlock;
-
-               sta = ieee80211_find_sta(vif, hdr->addr1);
+               sta = __carl9170_get_tx_sta(ar, skb);
                if (WARN_ON(!sta))
                        goto unlock;
 
@@ -1199,15 +1211,6 @@ static struct sk_buff *carl9170_tx_pick_skb(struct ar9170 *ar,
        arinfo = (void *) info->rate_driver_data;
 
        arinfo->timeout = jiffies;
-
-       /*
-        * increase ref count to "2".
-        * Ref counting is the easiest way to solve the race between
-        * the the urb's completion routine: carl9170_tx_callback and
-        * wlan tx status functions: carl9170_tx_status/janitor.
-        */
-       carl9170_tx_get_skb(skb);
-
        return skb;
 
 err_unlock:
@@ -1228,6 +1231,36 @@ void carl9170_tx_drop(struct ar9170 *ar, struct sk_buff *skb)
        __carl9170_tx_process_status(ar, super->s.cookie, q);
 }
 
+static bool carl9170_tx_ps_drop(struct ar9170 *ar, struct sk_buff *skb)
+{
+       struct ieee80211_sta *sta;
+       struct carl9170_sta_info *sta_info;
+
+       rcu_read_lock();
+       sta = __carl9170_get_tx_sta(ar, skb);
+       if (!sta)
+               goto out_rcu;
+
+       sta_info = (void *) sta->drv_priv;
+       if (unlikely(sta_info->sleeping)) {
+               struct ieee80211_tx_info *tx_info;
+
+               rcu_read_unlock();
+
+               tx_info = IEEE80211_SKB_CB(skb);
+               if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
+                       atomic_dec(&ar->tx_ampdu_upload);
+
+               tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
+               carl9170_tx_status(ar, skb, false);
+               return true;
+       }
+
+out_rcu:
+       rcu_read_unlock();
+       return false;
+}
+
 static void carl9170_tx(struct ar9170 *ar)
 {
        struct sk_buff *skb;
@@ -1247,6 +1280,9 @@ static void carl9170_tx(struct ar9170 *ar)
                        if (unlikely(!skb))
                                break;
 
+                       if (unlikely(carl9170_tx_ps_drop(ar, skb)))
+                               continue;
+
                        atomic_inc(&ar->tx_total_pending);
 
                        q = __carl9170_get_queue(ar, i);
@@ -1256,6 +1292,16 @@ static void carl9170_tx(struct ar9170 *ar)
                         */
                        skb_queue_tail(&ar->tx_status[q], skb);
 
+                       /*
+                        * increase ref count to "2".
+                        * Ref counting is the easiest way to solve the
+                        * race between the urb's completion routine:
+                        *      carl9170_tx_callback
+                        * and wlan tx status functions:
+                        *      carl9170_tx_status/janitor.
+                        */
+                       carl9170_tx_get_skb(skb);
+
                        carl9170_usb_tx(ar, skb);
                        schedule_garbagecollector = true;
                }
@@ -1368,6 +1414,11 @@ void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
         * all ressouces which are associated with the frame.
         */
 
+       if (sta) {
+               struct carl9170_sta_info *stai = (void *) sta->drv_priv;
+               atomic_inc(&stai->pending_frames);
+       }
+
        if (info->flags & IEEE80211_TX_CTL_AMPDU) {
                run = carl9170_tx_ampdu_queue(ar, sta, skb);
                if (run)
index 8a00f9a..6755063 100644 (file)
@@ -2281,6 +2281,7 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
                save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
                save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
                save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
+               save_regs_phy[8] = 0;
        } else {
                save_regs_phy[0] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
                save_regs_phy[1] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
@@ -2289,6 +2290,8 @@ static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
                save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_RFCTL_OVER);
                save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO1);
                save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_RFCTL_RSSIO2);
+               save_regs_phy[7] = 0;
+               save_regs_phy[8] = 0;
        }
 
        b43_nphy_rssi_select(dev, 5, type);
@@ -3845,8 +3848,8 @@ static int b43_nphy_set_channel(struct b43_wldev *dev,
 {
        struct b43_phy *phy = &dev->phy;
 
-       const struct b43_nphy_channeltab_entry_rev2 *tabent_r2;
-       const struct b43_nphy_channeltab_entry_rev3 *tabent_r3;
+       const struct b43_nphy_channeltab_entry_rev2 *tabent_r2 = NULL;
+       const struct b43_nphy_channeltab_entry_rev3 *tabent_r3 = NULL;
 
        u8 tmp;
 
index 5a8a3cc..7e5e85a 100644 (file)
@@ -955,9 +955,6 @@ int iwl4965_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
        if (priv->cfg->scan_rx_antennas[band])
                rx_ant = priv->cfg->scan_rx_antennas[band];
 
-       if (priv->cfg->scan_tx_antennas[band])
-               scan_tx_antennas = priv->cfg->scan_tx_antennas[band];
-
        priv->scan_tx_ant[band] = iwl4965_toggle_tx_ant(priv,
                                                priv->scan_tx_ant[band],
                                                    scan_tx_antennas);
index c1511b1..d743373 100644 (file)
@@ -211,10 +211,7 @@ int iwl_legacy_init_geos(struct iwl_priv *priv)
                if (!iwl_legacy_is_channel_valid(ch))
                        continue;
 
-               if (iwl_legacy_is_channel_a_band(ch))
-                       sband =  &priv->bands[IEEE80211_BAND_5GHZ];
-               else
-                       sband =  &priv->bands[IEEE80211_BAND_2GHZ];
+               sband = &priv->bands[ch->band];
 
                geo_ch = &sband->channels[sband->n_channels++];
 
@@ -2117,10 +2114,9 @@ int iwl_legacy_mac_config(struct ieee80211_hw *hw, u32 changed)
        IWL_DEBUG_MAC80211(priv, "enter to channel %d changed 0x%X\n",
                                        channel->hw_value, changed);
 
-       if (unlikely(!priv->cfg->mod_params->disable_hw_scan &&
-                       test_bit(STATUS_SCANNING, &priv->status))) {
+       if (unlikely(test_bit(STATUS_SCANNING, &priv->status))) {
                scan_active = 1;
-               IWL_DEBUG_MAC80211(priv, "leave - scanning\n");
+               IWL_DEBUG_MAC80211(priv, "scan active\n");
        }
 
        if (changed & (IEEE80211_CONF_CHANGE_SMPS |
@@ -2433,11 +2429,13 @@ void iwl_legacy_mac_bss_info_changed(struct ieee80211_hw *hw,
 
        IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
 
-       if (!iwl_legacy_is_alive(priv))
-               return;
-
        mutex_lock(&priv->mutex);
 
+       if (!iwl_legacy_is_alive(priv)) {
+               mutex_unlock(&priv->mutex);
+               return;
+       }
+
        if (changes & BSS_CHANGED_QOS) {
                unsigned long flags;
 
@@ -2646,7 +2644,7 @@ unplugged:
 
 none:
        /* re-enable interrupts here since we don't have anything to service. */
-       /* only Re-enable if diabled by irq */
+       /* only Re-enable if disabled by irq */
        if (test_bit(STATUS_INT_ENABLED, &priv->status))
                iwl_legacy_enable_interrupts(priv);
        spin_unlock_irqrestore(&priv->lock, flags);
index f03b463..bc66c60 100644 (file)
@@ -287,7 +287,6 @@ struct iwl_cfg {
        struct iwl_base_params *base_params;
        /* params likely to change within a device family */
        u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
-       u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
        enum iwl_led_mode led_mode;
 };
 
index 9ee849d..2d87dba 100644 (file)
@@ -134,7 +134,7 @@ struct iwl_queue {
                                * space more than this */
        int high_mark;         /* high watermark, stop queue if free
                                * space less than this */
-} __packed;
+};
 
 /* One for each TFD */
 struct iwl_tx_info {
@@ -290,6 +290,7 @@ enum {
        CMD_SIZE_HUGE = (1 << 0),
        CMD_ASYNC = (1 << 1),
        CMD_WANT_SKB = (1 << 2),
+       CMD_MAPPED = (1 << 3),
 };
 
 #define DEF_CMD_PAYLOAD_SIZE 320
@@ -1076,7 +1077,6 @@ struct iwl_priv {
        spinlock_t hcmd_lock;   /* protect hcmd */
        spinlock_t reg_lock;    /* protect hw register access */
        struct mutex mutex;
-       struct mutex sync_cmd_mutex; /* enable serialization of sync commands */
 
        /* basic pci-network driver stuff */
        struct pci_dev *pci_dev;
index 9d721cb..62b4b09 100644 (file)
@@ -145,6 +145,8 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
        int cmd_idx;
        int ret;
 
+       lockdep_assert_held(&priv->mutex);
+
        BUG_ON(cmd->flags & CMD_ASYNC);
 
         /* A synchronous command can not have a callback set. */
@@ -152,7 +154,6 @@ int iwl_legacy_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
 
        IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",
                        iwl_legacy_get_cmd_string(cmd->id));
-       mutex_lock(&priv->sync_cmd_mutex);
 
        set_bit(STATUS_HCMD_ACTIVE, &priv->status);
        IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s\n",
@@ -224,7 +225,6 @@ fail:
                cmd->reply_page = 0;
        }
 out:
-       mutex_unlock(&priv->sync_cmd_mutex);
        return ret;
 }
 EXPORT_SYMBOL(iwl_legacy_send_cmd_sync);
diff --git