ath9k_hw: Speedup register ops for HTC driver
Fine-tuning register write operation and avoid unnecessay delays for ath9k_htc driver, saves hw reset time which improves scanning time and also solves one of the following scenario. Sometimes the ACK is sent by STA for assoc response is not seen at AP side. So the AP continues to send retry assoc responses. At the STA side, since the assoc response was already forwarded to mac80211, it proceeded to channel change which in turns does chip reset. In most of the cases the chip reset was completed before max retries are reached at AP side. Hence STA can able to ACK the retried frames again. But in clear environment these retries are completed within shortspan of time. Since ath9k_htc consumes more time for hw reset, this latency is causing dissociation by AP due to max reties are reached. This issue was originally reported with Cisco Aironet 1250 AP in HT40 mode in noise free environment. Signed-off-by: Rajkumar Manoharan <rmanoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
b0a9ede228
Коммит
e7fc63388d
|
@ -729,6 +729,7 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||||
struct ath9k_channel *chan)
|
struct ath9k_channel *chan)
|
||||||
{
|
{
|
||||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||||
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
int i, regWrites = 0;
|
int i, regWrites = 0;
|
||||||
struct ieee80211_channel *channel = chan->chan;
|
struct ieee80211_channel *channel = chan->chan;
|
||||||
u32 modesIndex, freqIndex;
|
u32 modesIndex, freqIndex;
|
||||||
|
@ -805,7 +806,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||||
REG_WRITE(ah, reg, val);
|
REG_WRITE(ah, reg, val);
|
||||||
|
|
||||||
if (reg >= 0x7800 && reg < 0x78a0
|
if (reg >= 0x7800 && reg < 0x78a0
|
||||||
&& ah->config.analog_shiftreg) {
|
&& ah->config.analog_shiftreg
|
||||||
|
&& (common->bus_ops->ath_bus_type != ATH_USB)) {
|
||||||
udelay(100);
|
udelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,7 +837,8 @@ static int ar5008_hw_process_ini(struct ath_hw *ah,
|
||||||
REG_WRITE(ah, reg, val);
|
REG_WRITE(ah, reg, val);
|
||||||
|
|
||||||
if (reg >= 0x7800 && reg < 0x78a0
|
if (reg >= 0x7800 && reg < 0x78a0
|
||||||
&& ah->config.analog_shiftreg) {
|
&& ah->config.analog_shiftreg
|
||||||
|
&& (common->bus_ops->ath_bus_type != ATH_USB)) {
|
||||||
udelay(100);
|
udelay(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -392,6 +392,8 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
|
||||||
numXpdGain);
|
numXpdGain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENABLE_REGWRITE_BUFFER(ah);
|
||||||
|
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
if (!ath9k_hw_ar9287_get_eeprom(ah,
|
if (!ath9k_hw_ar9287_get_eeprom(ah,
|
||||||
EEP_OL_PWRCTRL)) {
|
EEP_OL_PWRCTRL)) {
|
||||||
|
@ -442,6 +444,7 @@ static void ath9k_hw_set_ar9287_power_cal_table(struct ath_hw *ah,
|
||||||
regOffset += 4;
|
regOffset += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
REGWRITE_BUFFER_FLUSH(ah);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,6 +760,8 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
||||||
ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
|
ratesArray[i] -= AR9287_PWR_TABLE_OFFSET_DB * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENABLE_REGWRITE_BUFFER(ah);
|
||||||
|
|
||||||
/* OFDM power per rate */
|
/* OFDM power per rate */
|
||||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
|
REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
|
||||||
ATH9K_POW_SM(ratesArray[rate18mb], 24)
|
ATH9K_POW_SM(ratesArray[rate18mb], 24)
|
||||||
|
@ -840,6 +845,7 @@ static void ath9k_hw_ar9287_set_txpower(struct ath_hw *ah,
|
||||||
| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
|
| ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
|
||||||
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
|
| ATH9K_POW_SM(ratesArray[rateDupCck], 0));
|
||||||
}
|
}
|
||||||
|
REGWRITE_BUFFER_FLUSH(ah);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
|
static void ath9k_hw_ar9287_set_addac(struct ath_hw *ah,
|
||||||
|
|
|
@ -799,6 +799,8 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
|
||||||
pwr_table_offset,
|
pwr_table_offset,
|
||||||
&diff);
|
&diff);
|
||||||
|
|
||||||
|
ENABLE_REGWRITE_BUFFER(ah);
|
||||||
|
|
||||||
if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
|
if ((i == 0) || AR_SREV_5416_20_OR_LATER(ah)) {
|
||||||
if (OLC_FOR_AR9280_20_LATER) {
|
if (OLC_FOR_AR9280_20_LATER) {
|
||||||
REG_WRITE(ah,
|
REG_WRITE(ah,
|
||||||
|
@ -847,6 +849,7 @@ static void ath9k_hw_set_def_power_cal_table(struct ath_hw *ah,
|
||||||
|
|
||||||
regOffset += 4;
|
regOffset += 4;
|
||||||
}
|
}
|
||||||
|
REGWRITE_BUFFER_FLUSH(ah);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1205,6 +1208,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ENABLE_REGWRITE_BUFFER(ah);
|
||||||
|
|
||||||
REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
|
REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
|
||||||
ATH9K_POW_SM(ratesArray[rate18mb], 24)
|
ATH9K_POW_SM(ratesArray[rate18mb], 24)
|
||||||
| ATH9K_POW_SM(ratesArray[rate12mb], 16)
|
| ATH9K_POW_SM(ratesArray[rate12mb], 16)
|
||||||
|
@ -1291,6 +1296,8 @@ static void ath9k_hw_def_set_txpower(struct ath_hw *ah,
|
||||||
REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
|
REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
|
||||||
ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
|
ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
|
||||||
| ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
|
| ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0));
|
||||||
|
|
||||||
|
REGWRITE_BUFFER_FLUSH(ah);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
|
static u16 ath9k_hw_def_get_spur_channel(struct ath_hw *ah, u16 i, bool is2GHz)
|
||||||
|
|
|
@ -99,18 +99,22 @@
|
||||||
#define REG_CLR_BIT(_a, _r, _f) \
|
#define REG_CLR_BIT(_a, _r, _f) \
|
||||||
REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f))
|
REG_WRITE(_a, _r, REG_READ(_a, _r) & ~(_f))
|
||||||
|
|
||||||
#define DO_DELAY(x) do { \
|
#define DO_DELAY(x) do { \
|
||||||
if ((++(x) % 64) == 0) \
|
if (((++(x) % 64) == 0) && \
|
||||||
udelay(1); \
|
(ath9k_hw_common(ah)->bus_ops->ath_bus_type \
|
||||||
|
!= ATH_USB)) \
|
||||||
|
udelay(1); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
|
#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
|
||||||
int r; \
|
int r; \
|
||||||
|
ENABLE_REGWRITE_BUFFER(ah); \
|
||||||
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
|
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
|
||||||
REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
|
REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
|
||||||
INI_RA((iniarray), r, (column))); \
|
INI_RA((iniarray), r, (column))); \
|
||||||
DO_DELAY(regWr); \
|
DO_DELAY(regWr); \
|
||||||
} \
|
} \
|
||||||
|
REGWRITE_BUFFER_FLUSH(ah); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
|
#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
|
||||||
|
|
|
@ -40,10 +40,12 @@
|
||||||
|
|
||||||
#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
|
#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
|
||||||
int r; \
|
int r; \
|
||||||
|
ENABLE_REGWRITE_BUFFER(ah); \
|
||||||
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
|
for (r = 0; r < ((iniarray)->ia_rows); r++) { \
|
||||||
REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
|
REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
|
||||||
DO_DELAY(regWr); \
|
DO_DELAY(regWr); \
|
||||||
} \
|
} \
|
||||||
|
REGWRITE_BUFFER_FLUSH(ah); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define ANTSWAP_AB 0x0001
|
#define ANTSWAP_AB 0x0001
|
||||||
|
|
Загрузка…
Ссылка в новой задаче