ath9k_hw: fix RF bank initialization
ar900*_init_mode_regs needs to be called before RF banks are allocated, otherwise the storage size of RF banks isn't known. This patch fixes a memory overrun that can show up as a crash on unloading the module. Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Родитель
066433a6fa
Коммит
6aaacd8615
|
@ -23,13 +23,13 @@
|
|||
|
||||
/* General hardware code for the A5008/AR9001/AR9002 hadware families */
|
||||
|
||||
static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
static int ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9271(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271);
|
||||
INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271);
|
||||
INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ah->config.pcie_clock_req)
|
||||
|
@ -104,7 +104,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
|||
|
||||
data = devm_kzalloc(ah->dev, size, GFP_KERNEL);
|
||||
if (!data)
|
||||
return;
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(data, addac->ia_array, size);
|
||||
addac->ia_array = data;
|
||||
|
@ -120,6 +120,7 @@ static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
|
|||
INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
|
||||
ar9287Common_japan_2484_cck_fir_coeff_9287_1_1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
|
||||
|
@ -415,7 +416,10 @@ int ar9002_hw_attach_ops(struct ath_hw *ah)
|
|||
struct ath_hw_ops *ops = ath9k_hw_ops(ah);
|
||||
int ret;
|
||||
|
||||
priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
|
||||
ret = ar9002_hw_init_mode_regs(ah);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
|
||||
|
||||
ops->config_pci_powersave = ar9002_hw_configpcipowersave;
|
||||
|
|
|
@ -704,7 +704,7 @@ void ar9003_hw_attach_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);
|
||||
|
||||
priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
|
||||
ar9003_hw_init_mode_regs(ah);
|
||||
priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
|
||||
|
||||
ops->config_pci_powersave = ar9003_hw_configpcipowersave;
|
||||
|
|
|
@ -54,11 +54,6 @@ static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
|
|||
ath9k_hw_private_ops(ah)->init_cal_settings(ah);
|
||||
}
|
||||
|
||||
static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
|
||||
{
|
||||
ath9k_hw_private_ops(ah)->init_mode_regs(ah);
|
||||
}
|
||||
|
||||
static u32 ath9k_hw_compute_pll_control(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
|
@ -670,8 +665,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
|||
if (!AR_SREV_9300_20_OR_LATER(ah))
|
||||
ah->ani_function &= ~ATH9K_ANI_MRC_CCK;
|
||||
|
||||
ath9k_hw_init_mode_regs(ah);
|
||||
|
||||
if (!ah->is_pciexpress)
|
||||
ath9k_hw_disablepcie(ah);
|
||||
|
||||
|
|
|
@ -600,7 +600,6 @@ struct ath_hw_radar_conf {
|
|||
* @init_cal_settings: setup types of calibrations supported
|
||||
* @init_cal: starts actual calibration
|
||||
*
|
||||
* @init_mode_regs: Initializes mode registers
|
||||
* @init_mode_gain_regs: Initialize TX/RX gain registers
|
||||
*
|
||||
* @rf_set_freq: change frequency
|
||||
|
@ -619,7 +618,6 @@ struct ath_hw_private_ops {
|
|||
void (*init_cal_settings)(struct ath_hw *ah);
|
||||
bool (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
|
||||
|
||||
void (*init_mode_regs)(struct ath_hw *ah);
|
||||
void (*init_mode_gain_regs)(struct ath_hw *ah);
|
||||
void (*setup_calibration)(struct ath_hw *ah,
|
||||
struct ath9k_cal_list *currCal);
|
||||
|
|
Загрузка…
Ссылка в новой задаче