---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -324,7 +324,6 @@ static void ath_paprd_activate(struct at
- if (!caldata || !caldata->paprd_done)
- return;
-
-- ath9k_ps_wakeup(sc);
- ar9003_paprd_enable(ah, false);
- for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
- if (!(common->tx_chainmask & BIT(chain)))
-@@ -334,7 +333,6 @@ static void ath_paprd_activate(struct at
- }
-
- ar9003_paprd_enable(ah, true);
-- ath9k_ps_restore(sc);
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -1456,7 +1456,8 @@ static void reg_process_hint(struct regu
+ * We only time out user hints, given that they should be the only
+ * source of bogus requests.
+ */
+- if (reg_request->initiator == NL80211_REGDOM_SET_BY_USER)
++ if (r != -EALREADY &&
++ reg_request->initiator == NL80211_REGDOM_SET_BY_USER)
+ schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));
}
- static bool ath_paprd_send_frame(struct ath_softc *sc, struct sk_buff *skb, int chain)
-@@ -554,8 +552,11 @@ set_timer:
- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
- if (!ah->caldata->paprd_done)
- ieee80211_queue_work(sc->hw, &sc->paprd_work);
-- else if (!ah->paprd_table_write_done)
-+ else if (!ah->paprd_table_write_done) {
-+ ath9k_ps_wakeup(sc);
- ath_paprd_activate(sc);
-+ ath9k_ps_restore(sc);
-+ }
- }
+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+@@ -18,13 +18,13 @@
+ #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];
+ };
+
+@@ -608,36 +608,48 @@ static bool ar9003_hw_calc_iq_corr(struc
+ return true;
}
-@@ -1376,7 +1377,6 @@ static void ath9k_calculate_summary_stat
-
- ath9k_calculate_iter_data(hw, vif, &iter_data);
-
-- ath9k_ps_wakeup(sc);
- /* Set BSSID mask. */
- memcpy(common->bssidmask, iter_data.mask, ETH_ALEN);
- ath_hw_setbssidmask(common);
-@@ -1411,7 +1411,6 @@ static void ath9k_calculate_summary_stat
- }
-
- ath9k_hw_set_interrupts(ah, ah->imask);
-- ath9k_ps_restore(sc);
-
- /* Set up ANI */
- if ((iter_data.naps + iter_data.nadhocs) > 0) {
-@@ -1457,6 +1456,7 @@ static int ath9k_add_interface(struct ie
- struct ath_vif *avp = (void *)vif->drv_priv;
- int ret = 0;
-
-+ ath9k_ps_wakeup(sc);
- mutex_lock(&sc->mutex);
-
- switch (vif->type) {
-@@ -1503,6 +1503,7 @@ static int ath9k_add_interface(struct ie
- ath9k_do_vif_add_setup(hw, vif);
- out:
- mutex_unlock(&sc->mutex);
-+ ath9k_ps_restore(sc);
- return ret;
- }
-
-@@ -1517,6 +1518,7 @@ static int ath9k_change_interface(struct
-
- ath_dbg(common, ATH_DBG_CONFIG, "Change Interface\n");
- mutex_lock(&sc->mutex);
-+ ath9k_ps_wakeup(sc);
-
- /* See if new interface type is valid. */
- if ((new_type == NL80211_IFTYPE_ADHOC) &&
-@@ -1546,6 +1548,7 @@ static int ath9k_change_interface(struct
+-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;
+-
+- 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;
++ 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;
++ }
++ }
- ath9k_do_vif_add_setup(hw, vif);
- out:
-+ ath9k_ps_restore(sc);
- mutex_unlock(&sc->mutex);
- return ret;
+- return true;
++ /* 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);
++
++ /* 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;
}
-@@ -1558,6 +1561,7 @@ static void ath9k_remove_interface(struc
-
- ath_dbg(common, ATH_DBG_CONFIG, "Detach Interface\n");
-+ ath9k_ps_wakeup(sc);
- mutex_lock(&sc->mutex);
-
- sc->nvifs--;
-@@ -1569,6 +1573,7 @@ static void ath9k_remove_interface(struc
- ath9k_calculate_summary_state(hw, NULL);
+ 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 +669,28 @@ static void ar9003_hw_tx_iqcal_load_avg_
+
+ /* 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);
++
++ /* Detect phase outlier */
++ ar9003_hw_detect_outlier(coeff->phs_coeff[i],
++ nmeasurement, MAX_PHS_DELTA);
++ }
- mutex_unlock(&sc->mutex);
-+ ath9k_ps_restore(sc);
+- /*
+- * 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;
++ 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 +710,37 @@ static void ar9003_hw_tx_iqcal_load_avg_
+
+ 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 ath9k_enable_ps(struct ath_softc *sc)
-@@ -1809,6 +1814,7 @@ static int ath9k_conf_tx(struct ieee8021
-
- txq = sc->tx.txq_map[queue];
-
-+ ath9k_ps_wakeup(sc);
- mutex_lock(&sc->mutex);
-
- memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
-@@ -1832,6 +1838,7 @@ static int ath9k_conf_tx(struct ieee8021
- ath_beaconq_config(sc);
-
- mutex_unlock(&sc->mutex);
-+ ath9k_ps_restore(sc);
-
- return ret;
+-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;
}
-@@ -1908,6 +1915,7 @@ static void ath9k_bss_info_changed(struc
- int slottime;
- int error;
-
-+ ath9k_ps_wakeup(sc);
- mutex_lock(&sc->mutex);
- if (changed & BSS_CHANGED_BSSID) {
-@@ -2008,6 +2016,7 @@ static void ath9k_bss_info_changed(struc
+ 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 +752,7 @@ static void ar9003_hw_tx_iq_cal_post_pro
+ 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 +760,69 @@ static void ar9003_hw_tx_iq_cal_post_pro
+ num_chains++;
}
- mutex_unlock(&sc->mutex);
-+ ath9k_ps_restore(sc);
- }
+- 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++) {
++ if (REG_READ(ah, txiqcal_status[i]) &
++ AR_PHY_TX_IQCAL_STATUS_FAILED) {
+ 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,
+ "Tx IQ Cal failed for chain %d.\n", i);
+- goto tx_iqcal_fail;
+- }
++ goto tx_iqcal_fail;
++ }
- static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
---- a/drivers/net/wireless/ath/ath9k/beacon.c
-+++ b/drivers/net/wireless/ath/ath9k/beacon.c
-@@ -392,14 +392,6 @@ void ath_beacon_tasklet(unsigned long da
- tsf += TU_TO_USEC(ah->config.sw_beacon_response_time);
- tsftu = TSF_TO_TU((tsf * ATH_BCBUF) >>32, tsf * ATH_BCBUF);
- slot = (tsftu % (intval * ATH_BCBUF)) / intval;
-- /*
-- * Reverse the slot order to get slot 0 on the TBTT offset that does
-- * not require TSF adjustment and other slots adding
-- * slot/ATH_BCBUF * beacon_int to timestamp. For example, with
-- * ATH_BCBUF = 4, we process beacon slots as follows: 3 2 1 0 3 2 1 ..
-- * and slot 0 is at correct offset to TBTT.
-- */
-- slot = ATH_BCBUF - slot - 1;
- vif = sc->beacon.bslot[slot];
-
- ath_dbg(common, ATH_DBG_BEACON,
-@@ -708,7 +700,7 @@ void ath_beacon_config(struct ath_softc
- if (cur_conf->dtim_period == 0)
- cur_conf->dtim_period = 1;
-
-- switch (iftype) {
-+ switch (sc->sc_ah->opmode) {
- case NL80211_IFTYPE_AP:
- ath_beacon_config_ap(sc, cur_conf);
- break;
---- a/net/mac80211/rx.c
-+++ b/net/mac80211/rx.c
-@@ -1585,7 +1585,7 @@ ieee80211_drop_unencrypted_mgmt(struct i
- }
+- 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);
+-
+- 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]);
+- }
++ /* 16 bits */
++ iq_res[idx + 1] = 0xffff & REG_READ(ah,
++ chan_info_tab[i] + offset);
+
+- 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;
+- }
++ 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]);
++ }
- static int
--__ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
-+__ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
+- 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;
++ 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] = coeff.iqc_coeff[0] & 0x7f;
++ coeff.phs_coeff[i][im] =
++ (coeff.iqc_coeff[0] >> 7) & 0x7f;
++
++ 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);
+@@ -941,6 +838,7 @@ static bool ar9003_hw_init_cal(struct at
{
- struct ieee80211_sub_if_data *sdata = rx->sdata;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
-@@ -1593,6 +1593,7 @@ __ieee80211_data_to_8023(struct ieee8021
- struct ethhdr *ehdr;
- int ret;
-
-+ *port_control = false;
- if (ieee80211_has_a4(hdr->frame_control) &&
- sdata->vif.type == NL80211_IFTYPE_AP_VLAN && !sdata->u.vlan.sta)
- return -1;
-@@ -1611,11 +1612,13 @@ __ieee80211_data_to_8023(struct ieee8021
- return -1;
-
- ret = ieee80211_data_to_8023(rx->skb, sdata->vif.addr, sdata->vif.type);
-- if (ret < 0 || !check_port_control)
-+ if (ret < 0)
- return ret;
-
- ehdr = (struct ethhdr *) rx->skb->data;
-- if (ehdr->h_proto != rx->sdata->control_port_protocol)
-+ if (ehdr->h_proto == rx->sdata->control_port_protocol)
-+ *port_control = true;
-+ else if (check_port_control)
- return -1;
-
- return 0;
-@@ -1916,6 +1919,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_
- struct net_device *dev = sdata->dev;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
- __le16 fc = hdr->frame_control;
-+ bool port_control;
- int err;
-
- if (unlikely(!ieee80211_is_data(hdr->frame_control)))
-@@ -1932,13 +1936,21 @@ ieee80211_rx_h_data(struct ieee80211_rx_
- sdata->vif.type == NL80211_IFTYPE_AP)
- return RX_DROP_MONITOR;
-
-- err = __ieee80211_data_to_8023(rx);
-+ err = __ieee80211_data_to_8023(rx, &port_control);
- if (unlikely(err))
- return RX_DROP_UNUSABLE;
-
- if (!ieee80211_frame_allowed(rx, fc))
- return RX_DROP_MONITOR;
-
-+ if (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
-+ unlikely(port_control) && sdata->bss) {
-+ sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
-+ u.ap);
-+ dev = sdata->dev;
-+ rx->sdata = sdata;
+ struct ath_common *common = ath9k_hw_common(ah);
+ 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);
+@@ -957,14 +855,22 @@ static bool ar9003_hw_init_cal(struct at
+ ar9003_hw_set_chain_masks(ah, 0x7, 0x7);
+
+ /* 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);
+ }
-+
- rx->skb->dev = dev;
-
- dev->stats.rx_packets++;
---- a/drivers/net/wireless/ath/ath9k/recv.c
-+++ b/drivers/net/wireless/ath/ath9k/recv.c
-@@ -75,7 +75,6 @@ static void ath_rx_buf_link(struct ath_s
- *sc->rx.rxlink = bf->bf_daddr;
- sc->rx.rxlink = &ds->ds_link;
-- ath9k_hw_rxena(ah);
- }
+ /* Calibrate the AGC */
+ REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+@@ -979,7 +885,7 @@ static bool ar9003_hw_init_cal(struct at
+ return false;
+ }
- static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
-@@ -426,9 +425,7 @@ u32 ath_calcrxfilter(struct ath_softc *s
- else
- rfilt |= ATH9K_RX_FILTER_BEACON;
+- if (AR_SREV_9485(ah))
++ if (txiqcal_done)
+ ar9003_hw_tx_iq_cal_post_proc(ah);
-- if ((AR_SREV_9280_20_OR_LATER(sc->sc_ah) ||
-- AR_SREV_9285_12_OR_LATER(sc->sc_ah)) &&
-- (sc->sc_ah->opmode == NL80211_IFTYPE_AP) &&
-+ if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
- (sc->rx.rxfilter & FIF_PSPOLL))
- rfilt |= ATH9K_RX_FILTER_PSPOLL;
+ /* Revert chainmasks to their original values before NF cal */
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+@@ -548,15 +548,12 @@
-@@ -486,12 +483,12 @@ start_recv:
- bool ath_stoprecv(struct ath_softc *sc)
- {
- struct ath_hw *ah = sc->sc_ah;
-- bool stopped;
-+ bool stopped, reset = false;
-
- spin_lock_bh(&sc->rx.rxbuflock);
- ath9k_hw_abortpcurecv(ah);
- ath9k_hw_setrxfilter(ah, 0);
-- stopped = ath9k_hw_stopdmarecv(ah);
-+ stopped = ath9k_hw_stopdmarecv(ah, &reset);
-
- if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)
- ath_edma_stop_recv(sc);
-@@ -506,7 +503,7 @@ bool ath_stoprecv(struct ath_softc *sc)
- "confusing the DMA engine when we start RX up\n");
- ATH_DBG_WARN_ON_ONCE(!stopped);
- }
-- return stopped;
-+ return stopped && !reset;
- }
+ #define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
- void ath_flushrecv(struct ath_softc *sc)
-@@ -1767,6 +1764,7 @@ requeue:
- } else {
- list_move_tail(&bf->list, &sc->rx.rxbuf);
- ath_rx_buf_link(sc, bf);
-+ ath9k_hw_rxena(ah);
- }
- } while (1);
-
---- a/drivers/net/wireless/ath/ath9k/hw.c
-+++ b/drivers/net/wireless/ath/ath9k/hw.c
-@@ -1249,15 +1249,6 @@ int ath9k_hw_reset(struct ath_hw *ah, st
- ah->txchainmask = common->tx_chainmask;
- ah->rxchainmask = common->rx_chainmask;
-
-- if ((common->bus_ops->ath_bus_type != ATH_USB) && !ah->chip_fullsleep) {
-- ath9k_hw_abortpcurecv(ah);
-- if (!ath9k_hw_stopdmarecv(ah)) {
-- ath_dbg(common, ATH_DBG_XMIT,
-- "Failed to stop receive dma\n");
-- bChannelChange = false;
-- }
-- }
+-#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)
-
- if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
- return -EIO;
-
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -710,27 +710,46 @@ void ath9k_hw_abortpcurecv(struct ath_hw
- }
- EXPORT_SYMBOL(ath9k_hw_abortpcurecv);
+-#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))
+@@ -758,10 +755,10 @@
+ #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
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -453,6 +453,7 @@ void ath9k_btcoex_timer_pause(struct ath
+
+ #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
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
+@@ -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;
+ }
+--- a/drivers/net/wireless/ath/ath9k/reg.h
++++ b/drivers/net/wireless/ath/ath9k/reg.h
+@@ -868,6 +868,8 @@
+ #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_9285E_20(_ah) \
+ (AR_SREV_9285_12_OR_LATER(_ah) && \
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -652,7 +652,7 @@ static void ieee80211_sta_reorder_releas
+ set_release_timer:
--bool ath9k_hw_stopdmarecv(struct ath_hw *ah)
-+bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset)
+ mod_timer(&tid_agg_rx->reorder_timer,
+- tid_agg_rx->reorder_time[j] +
++ tid_agg_rx->reorder_time[j] + 1 +
+ HT_RX_REORDER_BUF_TIMEOUT);
+ } else {
+ del_timer(&tid_agg_rx->reorder_timer);
+--- a/drivers/net/wireless/ath/ath9k/calib.c
++++ b/drivers/net/wireless/ath/ath9k/calib.c
+@@ -69,15 +69,21 @@ static void ath9k_hw_update_nfcal_hist_b
+ int16_t *nfarray)
{
- #define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
struct ath_common *common = ath9k_hw_common(ah);
-+ u32 mac_status, last_mac_status = 0;
++ struct ieee80211_conf *conf = &common->hw->conf;
+ struct ath_nf_limits *limit;
+ struct ath9k_nfcal_hist *h;
+ bool high_nf_mid = false;
++ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
int i;
-+ /* Enable access to the DMA observation bus */
-+ REG_WRITE(ah, AR_MACMISC,
-+ ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
-+ (AR_MACMISC_MISC_OBS_BUS_1 <<
-+ AR_MACMISC_MISC_OBS_BUS_MSB_S)));
-+
- REG_WRITE(ah, AR_CR, AR_CR_RXD);
+ h = cal->nfCalHist;
+ limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
- /* Wait for rx enable bit to go low */
- for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
- if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
- break;
+ for (i = 0; i < NUM_NF_READINGS; i++) {
++ if (!(chainmask & (1 << i)) ||
++ ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
++ continue;
+
-+ if (!AR_SREV_9300_20_OR_LATER(ah)) {
-+ mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0;
-+ if (mac_status == 0x1c0 && mac_status == last_mac_status) {
-+ *reset = true;
-+ break;
-+ }
+ h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
+
+ if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
+@@ -225,6 +231,7 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
+ int32_t val;
+ u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
+ struct ath_common *common = ath9k_hw_common(ah);
++ struct ieee80211_conf *conf = &common->hw->conf;
+ s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
+
+ if (ah->caldata)
+@@ -234,6 +241,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
+ if (chainmask & (1 << i)) {
+ s16 nfval;
+
++ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
++ continue;
+
-+ last_mac_status = mac_status;
-+ }
+ if (h)
+ nfval = h[i].privNF;
+ else
+@@ -293,6 +303,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah,
+ ENABLE_REGWRITE_BUFFER(ah);
+ for (i = 0; i < NUM_NF_READINGS; i++) {
+ if (chainmask & (1 << i)) {
++ if ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf))
++ continue;
+
- udelay(AH_TIME_QUANTUM);
- }
-
- if (i == 0) {
- ath_err(common,
-- "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x\n",
-+ "DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
- AH_RX_STOP_DMA_TIMEOUT / 1000,
- REG_READ(ah, AR_CR),
-- REG_READ(ah, AR_DIAG_SW));
-+ REG_READ(ah, AR_DIAG_SW),
-+ REG_READ(ah, AR_DMADBG_7));
- return false;
- } else {
- return true;
---- a/drivers/net/wireless/ath/ath9k/mac.h
-+++ b/drivers/net/wireless/ath/ath9k/mac.h
-@@ -695,7 +695,7 @@ bool ath9k_hw_setrxabort(struct ath_hw *
- void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
- void ath9k_hw_startpcureceive(struct ath_hw *ah, bool is_scanning);
- void ath9k_hw_abortpcurecv(struct ath_hw *ah);
--bool ath9k_hw_stopdmarecv(struct ath_hw *ah);
-+bool ath9k_hw_stopdmarecv(struct ath_hw *ah, bool *reset);
- int ath9k_hw_beaconq_setup(struct ath_hw *ah);
-
- /* Interrupt Handling */
+ val = REG_READ(ah, ah->nf_regs[i]);
+ val &= 0xFFFFFE00;
+ val |= (((u32) (-50) << 1) & 0x1ff);