ath9k: merge a few reset / calibration fixes
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 38854
This commit is contained in:
parent
9706d4e00e
commit
03fcc9bf43
10 changed files with 241 additions and 19 deletions
|
@ -482,7 +482,15 @@
|
|||
}
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -454,7 +454,6 @@ static void ath9k_hw_init_config(struct
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/time.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "hw.h"
|
||||
@@ -454,7 +455,6 @@ static void ath9k_hw_init_config(struct
|
||||
}
|
||||
|
||||
ah->config.rx_intr_mitigation = true;
|
||||
|
@ -490,6 +498,67 @@
|
|||
|
||||
/*
|
||||
* We need this for PCI devices only (Cardbus, PCI, miniPCI)
|
||||
@@ -1502,8 +1502,9 @@ static bool ath9k_hw_channel_change(stru
|
||||
int r;
|
||||
|
||||
if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
|
||||
- band_switch = IS_CHAN_5GHZ(ah->curchan) != IS_CHAN_5GHZ(chan);
|
||||
- mode_diff = (chan->channelFlags != ah->curchan->channelFlags);
|
||||
+ u32 flags_diff = chan->channelFlags ^ ah->curchan->channelFlags;
|
||||
+ band_switch = !!(flags_diff & CHANNEL_5GHZ);
|
||||
+ mode_diff = !!(flags_diff & ~CHANNEL_HT);
|
||||
}
|
||||
|
||||
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
|
||||
@@ -1815,7 +1816,7 @@ static int ath9k_hw_do_fastcc(struct ath
|
||||
* If cross-band fcc is not supoprted, bail out if channelFlags differ.
|
||||
*/
|
||||
if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) &&
|
||||
- chan->channelFlags != ah->curchan->channelFlags)
|
||||
+ ((chan->channelFlags ^ ah->curchan->channelFlags) & ~CHANNEL_HT))
|
||||
goto fail;
|
||||
|
||||
if (!ath9k_hw_check_alive(ah))
|
||||
@@ -1856,10 +1857,12 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
+ struct timespec ts;
|
||||
u32 saveLedState;
|
||||
u32 saveDefAntenna;
|
||||
u32 macStaId1;
|
||||
u64 tsf = 0;
|
||||
+ s64 usec = 0;
|
||||
int r;
|
||||
bool start_mci_reset = false;
|
||||
bool save_fullsleep = ah->chip_fullsleep;
|
||||
@@ -1902,10 +1905,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
|
||||
macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
|
||||
|
||||
- /* For chips on which RTC reset is done, save TSF before it gets cleared */
|
||||
- if (AR_SREV_9100(ah) ||
|
||||
- (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)))
|
||||
- tsf = ath9k_hw_gettsf64(ah);
|
||||
+ /* Save TSF before chip reset, a cold reset clears it */
|
||||
+ tsf = ath9k_hw_gettsf64(ah);
|
||||
+ getrawmonotonic(&ts);
|
||||
+ usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000;
|
||||
|
||||
saveLedState = REG_READ(ah, AR_CFG_LED) &
|
||||
(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
|
||||
@@ -1938,8 +1941,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
}
|
||||
|
||||
/* Restore TSF */
|
||||
- if (tsf)
|
||||
- ath9k_hw_settsf64(ah, tsf);
|
||||
+ getrawmonotonic(&ts);
|
||||
+ usec = ts.tv_sec * 1000 + ts.tv_nsec / 1000 - usec;
|
||||
+ ath9k_hw_settsf64(ah, tsf + usec);
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah))
|
||||
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.h
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.h
|
||||
@@ -283,7 +283,6 @@ struct ath9k_ops_config {
|
||||
|
@ -4417,7 +4486,24 @@
|
|||
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
@@ -701,6 +701,54 @@ static int ar9550_hw_get_modes_txgain_in
|
||||
@@ -641,11 +641,12 @@ static void ar9003_hw_override_ini(struc
|
||||
else
|
||||
ah->enabled_cals &= ~TX_IQ_CAL;
|
||||
|
||||
- if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
|
||||
- ah->enabled_cals |= TX_CL_CAL;
|
||||
- else
|
||||
- ah->enabled_cals &= ~TX_CL_CAL;
|
||||
}
|
||||
+
|
||||
+ if (REG_READ(ah, AR_PHY_CL_CAL_CTL) & AR_PHY_CL_CAL_ENABLE)
|
||||
+ ah->enabled_cals |= TX_CL_CAL;
|
||||
+ else
|
||||
+ ah->enabled_cals &= ~TX_CL_CAL;
|
||||
}
|
||||
|
||||
static void ar9003_hw_prog_ini(struct ath_hw *ah,
|
||||
@@ -701,6 +702,54 @@ static int ar9550_hw_get_modes_txgain_in
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -4472,7 +4558,7 @@
|
|||
static int ar9003_hw_process_ini(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
@@ -726,6 +774,8 @@ static int ar9003_hw_process_ini(struct
|
||||
@@ -726,6 +775,8 @@ static int ar9003_hw_process_ini(struct
|
||||
modesIndex);
|
||||
}
|
||||
|
||||
|
@ -4527,3 +4613,141 @@
|
|||
skb = ieee80211_get_buffered_bc(rt2x00dev->hw, vif);
|
||||
}
|
||||
}
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
|
||||
@@ -1040,8 +1040,8 @@ static void ar9003_hw_cl_cal_post_proc(s
|
||||
}
|
||||
}
|
||||
|
||||
-static bool ar9003_hw_init_cal(struct ath_hw *ah,
|
||||
- struct ath9k_channel *chan)
|
||||
+static bool ar9003_hw_init_cal_pcoem(struct ath_hw *ah,
|
||||
+ struct ath9k_channel *chan)
|
||||
{
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
@@ -1228,13 +1228,109 @@ skip_tx_iqcal:
|
||||
return true;
|
||||
}
|
||||
|
||||
+static bool ar9003_hw_init_cal_soc(struct ath_hw *ah,
|
||||
+ struct ath9k_channel *chan)
|
||||
+{
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
|
||||
+ bool txiqcal_done = false;
|
||||
+ bool is_reusable = true, status = true;
|
||||
+ bool run_agc_cal = false, sep_iq_cal = false;
|
||||
+
|
||||
+ /* Use chip chainmask only for calibration */
|
||||
+ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask);
|
||||
+
|
||||
+ if (ah->enabled_cals & TX_CL_CAL) {
|
||||
+ REG_SET_BIT(ah, AR_PHY_CL_CAL_CTL, AR_PHY_CL_CAL_ENABLE);
|
||||
+ run_agc_cal = true;
|
||||
+ }
|
||||
+
|
||||
+ if (IS_CHAN_HALF_RATE(chan) || IS_CHAN_QUARTER_RATE(chan))
|
||||
+ goto skip_tx_iqcal;
|
||||
+
|
||||
+ /* Do Tx IQ Calibration */
|
||||
+ REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
|
||||
+ AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
|
||||
+ DELPT);
|
||||
+
|
||||
+ /*
|
||||
+ * For AR9485 or later chips, TxIQ cal runs as part of
|
||||
+ * AGC calibration. Specifically, AR9550 in SoC chips.
|
||||
+ */
|
||||
+ if (ah->enabled_cals & TX_IQ_ON_AGC_CAL) {
|
||||
+ txiqcal_done = true;
|
||||
+ run_agc_cal = true;
|
||||
+ } else {
|
||||
+ sep_iq_cal = true;
|
||||
+ run_agc_cal = true;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * In the SoC family, this will run for AR9300, AR9331 and AR9340.
|
||||
+ */
|
||||
+ if (sep_iq_cal) {
|
||||
+ 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);
|
||||
+ }
|
||||
+
|
||||
+skip_tx_iqcal:
|
||||
+ if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
|
||||
+ /* Calibrate the AGC */
|
||||
+ REG_WRITE(ah, AR_PHY_AGC_CONTROL,
|
||||
+ REG_READ(ah, AR_PHY_AGC_CONTROL) |
|
||||
+ AR_PHY_AGC_CONTROL_CAL);
|
||||
+
|
||||
+ /* Poll for offset calibration complete */
|
||||
+ status = ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL,
|
||||
+ AR_PHY_AGC_CONTROL_CAL,
|
||||
+ 0, AH_WAIT_TIMEOUT);
|
||||
+ }
|
||||
+
|
||||
+ if (!status) {
|
||||
+ ath_dbg(common, CALIBRATE,
|
||||
+ "offset calibration failed to complete in %d ms; noisy environment?\n",
|
||||
+ AH_WAIT_TIMEOUT / 1000);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ if (txiqcal_done)
|
||||
+ ar9003_hw_tx_iq_cal_post_proc(ah, is_reusable);
|
||||
+
|
||||
+ /* Revert chainmask to runtime parameters */
|
||||
+ ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
|
||||
+
|
||||
+ /* Initialize list pointers */
|
||||
+ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
|
||||
+
|
||||
+ INIT_CAL(&ah->iq_caldata);
|
||||
+ INSERT_CAL(ah, &ah->iq_caldata);
|
||||
+ ath_dbg(common, CALIBRATE, "enabling IQ Calibration\n");
|
||||
+
|
||||
+ /* Initialize current pointer to first element in list */
|
||||
+ ah->cal_list_curr = ah->cal_list;
|
||||
+
|
||||
+ if (ah->cal_list_curr)
|
||||
+ ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
|
||||
+
|
||||
+ if (caldata)
|
||||
+ caldata->CalValid = 0;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
|
||||
+ if (AR_SREV_9485(ah) || AR_SREV_9462(ah) || AR_SREV_9565(ah))
|
||||
+ priv_ops->init_cal = ar9003_hw_init_cal_pcoem;
|
||||
+ else
|
||||
+ priv_ops->init_cal = ar9003_hw_init_cal_soc;
|
||||
+
|
||||
priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
|
||||
- priv_ops->init_cal = ar9003_hw_init_cal;
|
||||
priv_ops->setup_calibration = ar9003_hw_setup_calibration;
|
||||
|
||||
ops->calibrate = ar9003_hw_calibrate;
|
||||
--- a/drivers/net/wireless/ath/ath9k/common.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/common.c
|
||||
@@ -98,10 +98,8 @@ struct ath9k_channel *ath9k_cmn_get_chan
|
||||
{
|
||||
struct ieee80211_channel *curchan = chandef->chan;
|
||||
struct ath9k_channel *channel;
|
||||
- u8 chan_idx;
|
||||
|
||||
- chan_idx = curchan->hw_value;
|
||||
- channel = &ah->channels[chan_idx];
|
||||
+ channel = &ah->channels[curchan->hw_value];
|
||||
ath9k_cmn_update_ichannel(channel, chandef);
|
||||
|
||||
return channel;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <linux/io.h>
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
+#include <linux/etherdevice.h>
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#include "hw.h"
|
||||
@@ -512,8 +513,16 @@ static int ath9k_hw_init_macaddr(struct
|
||||
@@ -513,8 +514,16 @@ static int ath9k_hw_init_macaddr(struct
|
||||
common->macaddr[2 * i] = eeval >> 8;
|
||||
common->macaddr[2 * i + 1] = eeval & 0xff;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -2014,8 +2014,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
@@ -2019,8 +2019,8 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
REG_WRITE(ah, AR_OBS, 8);
|
||||
|
||||
if (ah->config.rx_intr_mitigation) {
|
||||
|
|
|
@ -110,16 +110,14 @@
|
|||
case NL80211_CHAN_WIDTH_5:
|
||||
flags |= CHANNEL_QUARTER;
|
||||
break;
|
||||
@@ -97,12 +111,13 @@ struct ath9k_channel *ath9k_cmn_get_chan
|
||||
@@ -97,10 +111,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
|
||||
struct cfg80211_chan_def *chandef)
|
||||
{
|
||||
struct ieee80211_channel *curchan = chandef->chan;
|
||||
+ struct ath_common *common = ath9k_hw_common(ah);
|
||||
struct ath9k_channel *channel;
|
||||
u8 chan_idx;
|
||||
|
||||
chan_idx = curchan->hw_value;
|
||||
channel = &ah->channels[chan_idx];
|
||||
channel = &ah->channels[curchan->hw_value];
|
||||
- ath9k_cmn_update_ichannel(channel, chandef);
|
||||
+ ath9k_cmn_update_ichannel(common, channel, chandef);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -732,6 +732,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
@@ -733,6 +733,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
case AR9300_DEVID_AR9462:
|
||||
case AR9485_DEVID_AR1111:
|
||||
case AR9300_DEVID_AR9565:
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
|
||||
--- a/net/mac80211/ieee80211_i.h
|
||||
+++ b/net/mac80211/ieee80211_i.h
|
||||
@@ -1179,6 +1179,7 @@ struct ieee80211_local {
|
||||
@@ -1182,6 +1182,7 @@ struct ieee80211_local {
|
||||
int dynamic_ps_forced_timeout;
|
||||
|
||||
int user_power_level; /* in dBm, for all interfaces */
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -2853,7 +2853,7 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
@@ -2858,7 +2858,7 @@ void ath9k_hw_apply_txpower(struct ath_h
|
||||
channel = chan->chan;
|
||||
chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
|
||||
new_pwr = min_t(int, chan_pwr, reg->power_limit);
|
||||
|
|
|
@ -94,7 +94,7 @@
|
|||
void ath9k_debug_sync_cause(struct ath_common *common, u32 sync_cause);
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -1861,6 +1861,20 @@ fail:
|
||||
@@ -1863,6 +1863,20 @@ fail:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
@ -115,7 +115,7 @@
|
|||
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_hw_cal_data *caldata, bool fastcc)
|
||||
{
|
||||
@@ -2060,6 +2074,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
@@ -2065,6 +2079,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
|
||||
}
|
||||
|
||||
ath9k_hw_apply_gpio_override(ah);
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
--- a/drivers/net/wireless/ath/ath9k/hw.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/hw.c
|
||||
@@ -2453,17 +2453,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
|
||||
@@ -2458,17 +2458,25 @@ int ath9k_hw_fill_cap_info(struct ath_hw
|
||||
}
|
||||
|
||||
eeval = ah->eep_ops->get_eeprom(ah, EEP_OP_MODE);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
void (*spectral_scan_trigger)(struct ath_hw *ah);
|
||||
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
|
||||
@@ -1759,6 +1759,26 @@ static void ar9003_hw_tx99_set_txpower(s
|
||||
@@ -1760,6 +1760,26 @@ static void ar9003_hw_tx99_set_txpower(s
|
||||
ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0));
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@
|
|||
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
|
||||
{
|
||||
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
|
||||
@@ -1789,6 +1809,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
||||
@@ -1790,6 +1810,7 @@ void ar9003_hw_attach_phy_ops(struct ath
|
||||
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
|
||||
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
|
||||
|
||||
|
|
Loading…
Reference in a new issue