---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -1048,6 +1048,8 @@ static int ath9k_start(struct ieee80211_
- "Starting driver with initial channel: %d MHz\n",
- curchan->center_freq);
+--- 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));
+ }
-+ ath9k_ps_wakeup(sc);
-+
- mutex_lock(&sc->mutex);
+--- 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;
+ }
- /* setup initial channel */
-@@ -1143,6 +1145,8 @@ static int ath9k_start(struct ieee80211_
- mutex_unlock:
- mutex_unlock(&sc->mutex);
+-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_ps_restore(sc);
+- 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);
+
- return r;
++ /* 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;
}
---- a/net/mac80211/ibss.c
-+++ b/net/mac80211/ibss.c
-@@ -661,7 +661,6 @@ static void ieee80211_sta_find_ibss(stru
- static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
- struct sk_buff *req)
+ static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
+ u8 num_chains,
+ struct coeff *coeff)
{
-- struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req);
- struct ieee80211_mgmt *mgmt = (void *)req->data;
- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
- struct ieee80211_local *local = sdata->local;
-@@ -685,7 +684,7 @@ static void ieee80211_rx_mgmt_probe_req(
- mgmt->bssid, tx_last_beacon);
- #endif /* CONFIG_MAC80211_IBSS_DEBUG */
-
-- if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH))
-+ if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da))
- return;
-
- if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 &&
---- a/net/mac80211/rc80211_minstrel_ht.c
-+++ b/net/mac80211/rc80211_minstrel_ht.c
-@@ -659,18 +659,14 @@ minstrel_ht_update_caps(void *priv, stru
- struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs;
- struct ieee80211_local *local = hw_to_local(mp->hw);
- u16 sta_cap = sta->ht_cap.cap;
-+ int n_supported = 0;
- int ack_dur;
- int stbc;
- int i;
+- 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);
++ }
+
+- /*
+- * 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++) {
- /* fall back to the old minstrel for legacy stations */
-- if (!sta->ht_cap.ht_supported) {
-- msp->is_ht = false;
-- memset(&msp->legacy, 0, sizeof(msp->legacy));
-- msp->legacy.r = msp->ratelist;
-- msp->legacy.sample_table = msp->sample_table;
-- return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
+- 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 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;
+-
+- }
+- }
- }
-+ if (!sta->ht_cap.ht_supported)
-+ goto use_legacy;
+-
+- 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;
- BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) !=
- MINSTREL_MAX_STREAMS * MINSTREL_STREAM_GROUPS);
-@@ -725,7 +721,22 @@ minstrel_ht_update_caps(void *priv, stru
+- 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);
- mi->groups[i].supported =
- mcs->rx_mask[minstrel_mcs_groups[i].streams - 1];
+- 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 (mi->groups[i].supported)
-+ n_supported++;
++ 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 +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++;
}
+
+- 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;
+
-+ if (!n_supported)
-+ goto use_legacy;
++ 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;
++ }
+
+- 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]);
++ }
+
+- 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;
+ }
+
-+ return;
++ coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
++ coeff.phs_coeff[i][im] =
++ (coeff.iqc_coeff[0] >> 7) & 0x7f;
+
-+use_legacy:
-+ msp->is_ht = false;
-+ memset(&msp->legacy, 0, sizeof(msp->legacy));
-+ msp->legacy.r = msp->ratelist;
-+ msp->legacy.sample_table = msp->sample_table;
-+ return mac80211_minstrel.rate_init(priv, sband, sta, &msp->legacy);
- }
-
- static void
---- a/net/mac80211/ieee80211_i.h
-+++ b/net/mac80211/ieee80211_i.h
-@@ -814,8 +814,8 @@ struct ieee80211_local {
-
- struct rate_control_ref *rate_ctrl;
-
-- struct crypto_blkcipher *wep_tx_tfm;
-- struct crypto_blkcipher *wep_rx_tfm;
-+ struct crypto_cipher *wep_tx_tfm;
-+ struct crypto_cipher *wep_rx_tfm;
- u32 wep_iv;
-
- /* see iface.c */
---- a/net/mac80211/tkip.c
-+++ b/net/mac80211/tkip.c
-@@ -202,7 +202,7 @@ EXPORT_SYMBOL(ieee80211_get_tkip_key);
- * @payload_len is the length of payload (_not_ including IV/ICV length).
- * @ta is the transmitter addresses.
- */
--int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *pos, size_t payload_len, u8 *ta)
++ 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
{
-@@ -223,7 +223,7 @@ int ieee80211_tkip_encrypt_data(struct c
- * beginning of the buffer containing IEEE 802.11 header payload, i.e.,
- * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the
- * length of payload, including IV, Ext. IV, MIC, ICV. */
--int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *payload, size_t payload_len, u8 *ta,
- u8 *ra, int only_iv, int queue,
---- a/net/mac80211/tkip.h
-+++ b/net/mac80211/tkip.h
-@@ -15,7 +15,7 @@
-
- u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16);
-
--int ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_encrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *pos, size_t payload_len, u8 *ta);
- enum {
-@@ -24,7 +24,7 @@ enum {
- TKIP_DECRYPT_INVALID_KEYIDX = -2,
- TKIP_DECRYPT_REPLAY = -3,
- };
--int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
-+int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm,
- struct ieee80211_key *key,
- u8 *payload, size_t payload_len, u8 *ta,
- u8 *ra, int only_iv, int queue,
---- a/net/mac80211/wep.c
-+++ b/net/mac80211/wep.c
-@@ -30,17 +30,15 @@ int ieee80211_wep_init(struct ieee80211_
- /* start WEP IV from a random value */
- get_random_bytes(&local->wep_iv, WEP_IV_LEN);
-
-- local->wep_tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
-- CRYPTO_ALG_ASYNC);
-+ local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(local->wep_tx_tfm)) {
- local->wep_rx_tfm = ERR_PTR(-EINVAL);
- return PTR_ERR(local->wep_tx_tfm);
+ 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);
++ }
+
+ /* Calibrate the AGC */
+ REG_WRITE(ah, AR_PHY_AGC_CONTROL,
+@@ -979,7 +885,7 @@ static bool ar9003_hw_init_cal(struct at
+ return false;
}
-- local->wep_rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0,
-- CRYPTO_ALG_ASYNC);
-+ local->wep_rx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(local->wep_rx_tfm)) {
-- crypto_free_blkcipher(local->wep_tx_tfm);
-+ crypto_free_cipher(local->wep_tx_tfm);
- local->wep_tx_tfm = ERR_PTR(-EINVAL);
- return PTR_ERR(local->wep_rx_tfm);
+- 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 */
+--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
++++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+@@ -548,15 +548,12 @@
+
+ #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))
+@@ -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;
}
-@@ -51,9 +49,9 @@ int ieee80211_wep_init(struct ieee80211_
- void ieee80211_wep_free(struct ieee80211_local *local)
- {
- if (!IS_ERR(local->wep_tx_tfm))
-- crypto_free_blkcipher(local->wep_tx_tfm);
-+ crypto_free_cipher(local->wep_tx_tfm);
- if (!IS_ERR(local->wep_rx_tfm))
-- crypto_free_blkcipher(local->wep_rx_tfm);
-+ crypto_free_cipher(local->wep_rx_tfm);
- }
+--- 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))
- static inline bool ieee80211_wep_weak_iv(u32 iv, int keylen)
-@@ -127,12 +125,11 @@ static void ieee80211_wep_remove_iv(stru
- /* Perform WEP encryption using given key. data buffer must have tailroom
- * for 4-byte ICV. data_len must not include this ICV. Note: this function
- * does _not_ add IV. data = RC4(data | CRC32(data)) */
--int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len)
- {
-- struct blkcipher_desc desc = { .tfm = tfm };
-- struct scatterlist sg;
- __le32 icv;
-+ int i;
-
- if (IS_ERR(tfm))
- return -1;
-@@ -140,9 +137,9 @@ int ieee80211_wep_encrypt_data(struct cr
- icv = cpu_to_le32(~crc32_le(~0, data, data_len));
- put_unaligned(icv, (__le32 *)(data + data_len));
-
-- crypto_blkcipher_setkey(tfm, rc4key, klen);
-- sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
-- crypto_blkcipher_encrypt(&desc, &sg, &sg, sg.length);
-+ crypto_cipher_setkey(tfm, rc4key, klen);
-+ for (i = 0; i < data_len + WEP_ICV_LEN; i++)
-+ crypto_cipher_encrypt_one(tfm, data + i, data + i);
-
- return 0;
- }
-@@ -186,19 +183,18 @@ int ieee80211_wep_encrypt(struct ieee802
- /* Perform WEP decryption using given key. data buffer includes encrypted
- * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV.
- * Return 0 on success and -1 on ICV mismatch. */
--int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len)
+ #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:
+
+ 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)
{
-- struct blkcipher_desc desc = { .tfm = tfm };
-- struct scatterlist sg;
- __le32 crc;
-+ int i;
-
- if (IS_ERR(tfm))
- return -1;
-
-- crypto_blkcipher_setkey(tfm, rc4key, klen);
-- sg_init_one(&sg, data, data_len + WEP_ICV_LEN);
-- crypto_blkcipher_decrypt(&desc, &sg, &sg, sg.length);
-+ crypto_cipher_setkey(tfm, rc4key, klen);
-+ for (i = 0; i < data_len + WEP_ICV_LEN; i++)
-+ crypto_cipher_decrypt_one(tfm, data + i, data + i);
-
- crc = cpu_to_le32(~crc32_le(~0, data, data_len));
- if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0)
---- a/net/mac80211/wep.h
-+++ b/net/mac80211/wep.h
-@@ -18,12 +18,12 @@
-
- int ieee80211_wep_init(struct ieee80211_local *local);
- void ieee80211_wep_free(struct ieee80211_local *local);
--int ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len);
- int ieee80211_wep_encrypt(struct ieee80211_local *local,
- struct sk_buff *skb,
- const u8 *key, int keylen, int keyidx);
--int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
-+int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key,
- size_t klen, u8 *data, size_t data_len);
- bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
+ struct ath_common *common = ath9k_hw_common(ah);
++ 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;
+ h = cal->nfCalHist;
+ limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
+
+ for (i = 0; i < NUM_NF_READINGS; i++) {
++ if (!(chainmask & (1 << i)) ||
++ ((i >= AR5416_MAX_CHAINS) && !conf_is_ht40(conf)))
++ continue;
++
+ 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;
++
+ 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;
++
+ val = REG_READ(ah, ah->nf_regs[i]);
+ val &= 0xFFFFFE00;
+ val |= (((u32) (-50) << 1) & 0x1ff);