Commit c7e3c93a authored by David S. Miller's avatar David S. Miller

Merge tag 'wireless-drivers-for-davem-2019-06-07' of...

Merge tag 'wireless-drivers-for-davem-2019-06-07' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers

Kalle Valo says:

====================
wireless-drivers fixes for 5.2

First set of fixes for 5.2. Most important here are buffer overflow
fixes for mwifiex.

rtw88

* fix out of bounds compiler warning

* fix rssi handling to get 4x more throughput

* avoid circular locking

rsi

* fix unitilised data warning, these are hopefully the last ones so
  that the warning can be enabled by default

mwifiex

* fix buffer overflows

iwlwifi

* remove not used debugfs file

* various fixes
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1e1d9263 69ae4f6a
...@@ -2747,3 +2747,42 @@ void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t) ...@@ -2747,3 +2747,42 @@ void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t)
jiffies + msecs_to_jiffies(collect_interval)); jiffies + msecs_to_jiffies(collect_interval));
} }
} }
#define FSEQ_REG(x) { .addr = (x), .str = #x, }
void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt)
{
struct iwl_trans *trans = fwrt->trans;
unsigned long flags;
int i;
struct {
u32 addr;
const char *str;
} fseq_regs[] = {
FSEQ_REG(FSEQ_ERROR_CODE),
FSEQ_REG(FSEQ_TOP_INIT_VERSION),
FSEQ_REG(FSEQ_CNVIO_INIT_VERSION),
FSEQ_REG(FSEQ_OTP_VERSION),
FSEQ_REG(FSEQ_TOP_CONTENT_VERSION),
FSEQ_REG(FSEQ_ALIVE_TOKEN),
FSEQ_REG(FSEQ_CNVI_ID),
FSEQ_REG(FSEQ_CNVR_ID),
FSEQ_REG(CNVI_AUX_MISC_CHIP),
FSEQ_REG(CNVR_AUX_MISC_CHIP),
FSEQ_REG(CNVR_SCU_SD_REGS_SD_REG_DIG_DCDC_VTRIM),
FSEQ_REG(CNVR_SCU_SD_REGS_SD_REG_ACTIVE_VDIG_MIRROR),
};
if (!iwl_trans_grab_nic_access(trans, &flags))
return;
IWL_ERR(fwrt, "Fseq Registers:\n");
for (i = 0; i < ARRAY_SIZE(fseq_regs); i++)
IWL_ERR(fwrt, "0x%08X | %s\n",
iwl_read_prph_no_grab(trans, fseq_regs[i].addr),
fseq_regs[i].str);
iwl_trans_release_nic_access(trans, &flags);
}
IWL_EXPORT_SYMBOL(iwl_fw_error_print_fseq_regs);
...@@ -471,4 +471,6 @@ static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt) ...@@ -471,4 +471,6 @@ static inline void iwl_fw_error_collect(struct iwl_fw_runtime *fwrt)
} }
void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t); void iwl_fw_dbg_periodic_trig_handler(struct timer_list *t);
void iwl_fw_error_print_fseq_regs(struct iwl_fw_runtime *fwrt);
#endif /* __iwl_fw_dbg_h__ */ #endif /* __iwl_fw_dbg_h__ */
...@@ -1597,7 +1597,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) ...@@ -1597,7 +1597,6 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
goto free; goto free;
out_free_fw: out_free_fw:
iwl_dealloc_ucode(drv);
release_firmware(ucode_raw); release_firmware(ucode_raw);
out_unbind: out_unbind:
complete(&drv->request_firmware_complete); complete(&drv->request_firmware_complete);
......
...@@ -395,7 +395,11 @@ enum { ...@@ -395,7 +395,11 @@ enum {
WFPM_AUX_CTL_AUX_IF_MAC_OWNER_MSK = 0x80000000, WFPM_AUX_CTL_AUX_IF_MAC_OWNER_MSK = 0x80000000,
}; };
#define AUX_MISC_REG 0xA200B0 #define CNVI_AUX_MISC_CHIP 0xA200B0
#define CNVR_AUX_MISC_CHIP 0xA2B800
#define CNVR_SCU_SD_REGS_SD_REG_DIG_DCDC_VTRIM 0xA29890
#define CNVR_SCU_SD_REGS_SD_REG_ACTIVE_VDIG_MIRROR 0xA29938
enum { enum {
HW_STEP_LOCATION_BITS = 24, HW_STEP_LOCATION_BITS = 24,
}; };
...@@ -408,7 +412,12 @@ enum aux_misc_master1_en { ...@@ -408,7 +412,12 @@ enum aux_misc_master1_en {
#define AUX_MISC_MASTER1_SMPHR_STATUS 0xA20800 #define AUX_MISC_MASTER1_SMPHR_STATUS 0xA20800
#define RSA_ENABLE 0xA24B08 #define RSA_ENABLE 0xA24B08
#define PREG_AUX_BUS_WPROT_0 0xA04CC0 #define PREG_AUX_BUS_WPROT_0 0xA04CC0
#define PREG_PRPH_WPROT_0 0xA04CE0
/* device family 9000 WPROT register */
#define PREG_PRPH_WPROT_9000 0xA04CE0
/* device family 22000 WPROT register */
#define PREG_PRPH_WPROT_22000 0xA04D00
#define SB_CPU_1_STATUS 0xA01E30 #define SB_CPU_1_STATUS 0xA01E30
#define SB_CPU_2_STATUS 0xA01E34 #define SB_CPU_2_STATUS 0xA01E34
#define UMAG_SB_CPU_1_STATUS 0xA038C0 #define UMAG_SB_CPU_1_STATUS 0xA038C0
...@@ -442,4 +451,13 @@ enum { ...@@ -442,4 +451,13 @@ enum {
#define UREG_DOORBELL_TO_ISR6 0xA05C04 #define UREG_DOORBELL_TO_ISR6 0xA05C04
#define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0) #define UREG_DOORBELL_TO_ISR6_NMI_BIT BIT(0)
#define FSEQ_ERROR_CODE 0xA340C8
#define FSEQ_TOP_INIT_VERSION 0xA34038
#define FSEQ_CNVIO_INIT_VERSION 0xA3403C
#define FSEQ_OTP_VERSION 0xA340FC
#define FSEQ_TOP_CONTENT_VERSION 0xA340F4
#define FSEQ_ALIVE_TOKEN 0xA340F0
#define FSEQ_CNVI_ID 0xA3408C
#define FSEQ_CNVR_ID 0xA34090
#endif /* __iwl_prph_h__ */ #endif /* __iwl_prph_h__ */
...@@ -1972,26 +1972,6 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, ...@@ -1972,26 +1972,6 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,
} }
} }
static void iwl_mvm_read_d3_sram(struct iwl_mvm *mvm)
{
#ifdef CONFIG_IWLWIFI_DEBUGFS
const struct fw_img *img = &mvm->fw->img[IWL_UCODE_WOWLAN];
u32 len = img->sec[IWL_UCODE_SECTION_DATA].len;
u32 offs = img->sec[IWL_UCODE_SECTION_DATA].offset;
if (!mvm->store_d3_resume_sram)
return;
if (!mvm->d3_resume_sram) {
mvm->d3_resume_sram = kzalloc(len, GFP_KERNEL);
if (!mvm->d3_resume_sram)
return;
}
iwl_trans_read_mem_bytes(mvm->trans, offs, mvm->d3_resume_sram, len);
#endif
}
static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac, static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
struct ieee80211_vif *vif) struct ieee80211_vif *vif)
{ {
...@@ -2054,8 +2034,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test) ...@@ -2054,8 +2034,6 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
} }
iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt); iwl_fw_dbg_read_d3_debug_data(&mvm->fwrt);
/* query SRAM first in case we want event logging */
iwl_mvm_read_d3_sram(mvm);
if (iwl_mvm_check_rt_status(mvm, vif)) { if (iwl_mvm_check_rt_status(mvm, vif)) {
set_bit(STATUS_FW_ERROR, &mvm->trans->status); set_bit(STATUS_FW_ERROR, &mvm->trans->status);
......
...@@ -1557,59 +1557,6 @@ static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm, ...@@ -1557,59 +1557,6 @@ static ssize_t iwl_dbgfs_bcast_filters_macs_write(struct iwl_mvm *mvm,
} }
#endif #endif
#ifdef CONFIG_PM_SLEEP
static ssize_t iwl_dbgfs_d3_sram_write(struct iwl_mvm *mvm, char *buf,
size_t count, loff_t *ppos)
{
int store;
if (sscanf(buf, "%d", &store) != 1)
return -EINVAL;
mvm->store_d3_resume_sram = store;
return count;
}
static ssize_t iwl_dbgfs_d3_sram_read(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
struct iwl_mvm *mvm = file->private_data;
const struct fw_img *img;
int ofs, len, pos = 0;
size_t bufsz, ret;
char *buf;
u8 *ptr = mvm->d3_resume_sram;
img = &mvm->fw->img[IWL_UCODE_WOWLAN];
len = img->sec[IWL_UCODE_SECTION_DATA].len;
bufsz = len * 4 + 256;
buf = kzalloc(bufsz, GFP_KERNEL);
if (!buf)
return -ENOMEM;
pos += scnprintf(buf, bufsz, "D3 SRAM capture: %sabled\n",
mvm->store_d3_resume_sram ? "en" : "dis");
if (ptr) {
for (ofs = 0; ofs < len; ofs += 16) {
pos += scnprintf(buf + pos, bufsz - pos,
"0x%.4x %16ph\n", ofs, ptr + ofs);
}
} else {
pos += scnprintf(buf + pos, bufsz - pos,
"(no data captured)\n");
}
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
kfree(buf);
return ret;
}
#endif
#define PRINT_MVM_REF(ref) do { \ #define PRINT_MVM_REF(ref) do { \
if (mvm->refs[ref]) \ if (mvm->refs[ref]) \
pos += scnprintf(buf + pos, bufsz - pos, \ pos += scnprintf(buf + pos, bufsz - pos, \
...@@ -1940,9 +1887,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256); ...@@ -1940,9 +1887,6 @@ MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters, 256);
MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256); MVM_DEBUGFS_READ_WRITE_FILE_OPS(bcast_filters_macs, 256);
#endif #endif
#ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_READ_WRITE_FILE_OPS(d3_sram, 8);
#endif
#ifdef CONFIG_ACPI #ifdef CONFIG_ACPI
MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile); MVM_DEBUGFS_READ_FILE_OPS(sar_geo_profile);
#endif #endif
...@@ -2159,7 +2103,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir) ...@@ -2159,7 +2103,6 @@ void iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
#endif #endif
#ifdef CONFIG_PM_SLEEP #ifdef CONFIG_PM_SLEEP
MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, 0600);
MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400); MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, 0400);
debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir, debugfs_create_bool("d3_wake_sysassert", 0600, mvm->debugfs_dir,
&mvm->d3_wake_sysassert); &mvm->d3_wake_sysassert);
......
...@@ -311,6 +311,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, ...@@ -311,6 +311,8 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
int ret; int ret;
enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img; enum iwl_ucode_type old_type = mvm->fwrt.cur_fw_img;
static const u16 alive_cmd[] = { MVM_ALIVE }; static const u16 alive_cmd[] = { MVM_ALIVE };
bool run_in_rfkill =
ucode_type == IWL_UCODE_INIT || iwl_mvm_has_unified_ucode(mvm);
if (ucode_type == IWL_UCODE_REGULAR && if (ucode_type == IWL_UCODE_REGULAR &&
iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) && iwl_fw_dbg_conf_usniffer(mvm->fw, FW_DBG_START_FROM_ALIVE) &&
...@@ -328,7 +330,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, ...@@ -328,7 +330,12 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm,
alive_cmd, ARRAY_SIZE(alive_cmd), alive_cmd, ARRAY_SIZE(alive_cmd),
iwl_alive_fn, &alive_data); iwl_alive_fn, &alive_data);
ret = iwl_trans_start_fw(mvm->trans, fw, ucode_type == IWL_UCODE_INIT); /*
* We want to load the INIT firmware even in RFKILL
* For the unified firmware case, the ucode_type is not
* INIT, but we still need to run it.
*/
ret = iwl_trans_start_fw(mvm->trans, fw, run_in_rfkill);
if (ret) { if (ret) {
iwl_fw_set_current_image(&mvm->fwrt, old_type); iwl_fw_set_current_image(&mvm->fwrt, old_type);
iwl_remove_notification(&mvm->notif_wait, &alive_wait); iwl_remove_notification(&mvm->notif_wait, &alive_wait);
...@@ -433,7 +440,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -433,7 +440,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
* commands * commands
*/ */
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(SYSTEM_GROUP, ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(SYSTEM_GROUP,
INIT_EXTENDED_CFG_CMD), 0, INIT_EXTENDED_CFG_CMD),
CMD_SEND_IN_RFKILL,
sizeof(init_cfg), &init_cfg); sizeof(init_cfg), &init_cfg);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to run init config command: %d\n", IWL_ERR(mvm, "Failed to run init config command: %d\n",
...@@ -457,7 +465,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -457,7 +465,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
} }
ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP, ret = iwl_mvm_send_cmd_pdu(mvm, WIDE_ID(REGULATORY_AND_NVM_GROUP,
NVM_ACCESS_COMPLETE), 0, NVM_ACCESS_COMPLETE),
CMD_SEND_IN_RFKILL,
sizeof(nvm_complete), &nvm_complete); sizeof(nvm_complete), &nvm_complete);
if (ret) { if (ret) {
IWL_ERR(mvm, "Failed to run complete NVM access: %d\n", IWL_ERR(mvm, "Failed to run complete NVM access: %d\n",
...@@ -482,6 +491,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -482,6 +491,8 @@ static int iwl_run_unified_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
} }
} }
mvm->rfkill_safe_init_done = true;
return 0; return 0;
error: error:
...@@ -526,7 +537,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -526,7 +537,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
lockdep_assert_held(&mvm->mutex); lockdep_assert_held(&mvm->mutex);
if (WARN_ON_ONCE(mvm->calibrating)) if (WARN_ON_ONCE(mvm->rfkill_safe_init_done))
return 0; return 0;
iwl_init_notification_wait(&mvm->notif_wait, iwl_init_notification_wait(&mvm->notif_wait,
...@@ -576,7 +587,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -576,7 +587,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
goto remove_notif; goto remove_notif;
} }
mvm->calibrating = true; mvm->rfkill_safe_init_done = true;
/* Send TX valid antennas before triggering calibrations */ /* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm)); ret = iwl_send_tx_ant_cfg(mvm, iwl_mvm_get_valid_tx_ant(mvm));
...@@ -612,7 +623,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ...@@ -612,7 +623,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
remove_notif: remove_notif:
iwl_remove_notification(&mvm->notif_wait, &calib_wait); iwl_remove_notification(&mvm->notif_wait, &calib_wait);
out: out:
mvm->calibrating = false; mvm->rfkill_safe_init_done = false;
if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) { if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
/* we want to debug INIT and we have no NVM - fake */ /* we want to debug INIT and we have no NVM - fake */
mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) + mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
......
...@@ -1209,7 +1209,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) ...@@ -1209,7 +1209,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
mvm->scan_status = 0; mvm->scan_status = 0;
mvm->ps_disabled = false; mvm->ps_disabled = false;
mvm->calibrating = false; mvm->rfkill_safe_init_done = false;
/* just in case one was running */ /* just in case one was running */
iwl_mvm_cleanup_roc_te(mvm); iwl_mvm_cleanup_roc_te(mvm);
......
...@@ -880,7 +880,7 @@ struct iwl_mvm { ...@@ -880,7 +880,7 @@ struct iwl_mvm {
struct iwl_mvm_vif *bf_allowed_vif; struct iwl_mvm_vif *bf_allowed_vif;
bool hw_registered; bool hw_registered;
bool calibrating; bool rfkill_safe_init_done;
bool support_umac_log; bool support_umac_log;
u32 ampdu_ref; u32 ampdu_ref;
...@@ -1039,8 +1039,6 @@ struct iwl_mvm { ...@@ -1039,8 +1039,6 @@ struct iwl_mvm {
#ifdef CONFIG_IWLWIFI_DEBUGFS #ifdef CONFIG_IWLWIFI_DEBUGFS
bool d3_wake_sysassert; bool d3_wake_sysassert;
bool d3_test_active; bool d3_test_active;
bool store_d3_resume_sram;
void *d3_resume_sram;
u32 d3_test_pme_ptr; u32 d3_test_pme_ptr;
struct ieee80211_vif *keep_vif; struct ieee80211_vif *keep_vif;
u32 last_netdetect_scans; /* no. of scans in the last net-detect wake */ u32 last_netdetect_scans; /* no. of scans in the last net-detect wake */
......
...@@ -918,9 +918,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode) ...@@ -918,9 +918,6 @@ static void iwl_op_mode_mvm_stop(struct iwl_op_mode *op_mode)
kfree(mvm->error_recovery_buf); kfree(mvm->error_recovery_buf);
mvm->error_recovery_buf = NULL; mvm->error_recovery_buf = NULL;
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_IWLWIFI_DEBUGFS)
kfree(mvm->d3_resume_sram);
#endif
iwl_trans_op_mode_leave(mvm->trans); iwl_trans_op_mode_leave(mvm->trans);
iwl_phy_db_free(mvm->phy_db); iwl_phy_db_free(mvm->phy_db);
...@@ -1212,7 +1209,8 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state) ...@@ -1212,7 +1209,8 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
{ {
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
bool calibrating = READ_ONCE(mvm->calibrating); bool rfkill_safe_init_done = READ_ONCE(mvm->rfkill_safe_init_done);
bool unified = iwl_mvm_has_unified_ucode(mvm);
if (state) if (state)
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status); set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
...@@ -1221,15 +1219,23 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state) ...@@ -1221,15 +1219,23 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
iwl_mvm_set_rfkill_state(mvm); iwl_mvm_set_rfkill_state(mvm);
/* iwl_run_init_mvm_ucode is waiting for results, abort it */ /* iwl_run_init_mvm_ucode is waiting for results, abort it. */
if (calibrating) if (rfkill_safe_init_done)
iwl_abort_notification_waits(&mvm->notif_wait); iwl_abort_notification_waits(&mvm->notif_wait);
/*
* Don't ask the transport to stop the firmware. We'll do it
* after cfg80211 takes us down.
*/
if (unified)
return false;
/* /*
* Stop the device if we run OPERATIONAL firmware or if we are in the * Stop the device if we run OPERATIONAL firmware or if we are in the
* middle of the calibrations. * middle of the calibrations.
*/ */
return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT || calibrating); return state && (mvm->fwrt.cur_fw_img != IWL_UCODE_INIT ||
rfkill_safe_init_done);
} }
static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
......
...@@ -441,7 +441,8 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta, ...@@ -441,7 +441,8 @@ void rs_fw_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
*/ */
sta->max_amsdu_len = max_amsdu_len; sta->max_amsdu_len = max_amsdu_len;
ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, 0, sizeof(cfg_cmd), &cfg_cmd); ret = iwl_mvm_send_cmd_pdu(mvm, cmd_id, CMD_ASYNC, sizeof(cfg_cmd),
&cfg_cmd);
if (ret) if (ret)
IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret); IWL_ERR(mvm, "Failed to send rate scale config (%d)\n", ret);
} }
......
...@@ -596,6 +596,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm) ...@@ -596,6 +596,8 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
iwl_mvm_dump_lmac_error_log(mvm, 1); iwl_mvm_dump_lmac_error_log(mvm, 1);
iwl_mvm_dump_umac_error_log(mvm); iwl_mvm_dump_umac_error_log(mvm);
iwl_fw_error_print_fseq_regs(&mvm->fwrt);
} }
int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id, int iwl_mvm_reconfig_scd(struct iwl_mvm *mvm, int queue, int fifo, int sta_id,
......
...@@ -928,7 +928,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans) ...@@ -928,7 +928,7 @@ static inline void iwl_enable_rfkill_int(struct iwl_trans *trans)
MSIX_HW_INT_CAUSES_REG_RF_KILL); MSIX_HW_INT_CAUSES_REG_RF_KILL);
} }
if (trans->cfg->device_family == IWL_DEVICE_FAMILY_9000) { if (trans->cfg->device_family >= IWL_DEVICE_FAMILY_9000) {
/* /*
* On 9000-series devices this bit isn't enabled by default, so * On 9000-series devices this bit isn't enabled by default, so
* when we power down the device we need set the bit to allow it * when we power down the device we need set the bit to allow it
......
...@@ -1698,26 +1698,26 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev, ...@@ -1698,26 +1698,26 @@ static int iwl_pcie_init_msix_handler(struct pci_dev *pdev,
return 0; return 0;
} }
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) static int iwl_trans_pcie_clear_persistence_bit(struct iwl_trans *trans)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); u32 hpm, wprot;
u32 hpm;
int err;
lockdep_assert_held(&trans_pcie->mutex);
err = iwl_pcie_prepare_card_hw(trans); switch (trans->cfg->device_family) {
if (err) { case IWL_DEVICE_FAMILY_9000:
IWL_ERR(trans, "Error while preparing HW: %d\n", err); wprot = PREG_PRPH_WPROT_9000;
return err; break;
case IWL_DEVICE_FAMILY_22000:
wprot = PREG_PRPH_WPROT_22000;
break;
default:
return 0;
} }
hpm = iwl_read_umac_prph_no_grab(trans, HPM_DEBUG); hpm = iwl_read_umac_prph_no_grab(trans, HPM_DEBUG);
if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) { if (hpm != 0xa5a5a5a0 && (hpm & PERSISTENCE_BIT)) {
int wfpm_val = iwl_read_umac_prph_no_grab(trans, u32 wprot_val = iwl_read_umac_prph_no_grab(trans, wprot);
PREG_PRPH_WPROT_0);
if (wfpm_val & PREG_WFPM_ACCESS) { if (wprot_val & PREG_WFPM_ACCESS) {
IWL_ERR(trans, IWL_ERR(trans,
"Error, can not clear persistence bit\n"); "Error, can not clear persistence bit\n");
return -EPERM; return -EPERM;
...@@ -1726,6 +1726,26 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power) ...@@ -1726,6 +1726,26 @@ static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
hpm & ~PERSISTENCE_BIT); hpm & ~PERSISTENCE_BIT);
} }
return 0;
}
static int _iwl_trans_pcie_start_hw(struct iwl_trans *trans, bool low_power)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
int err;
lockdep_assert_held(&trans_pcie->mutex);
err = iwl_pcie_prepare_card_hw(trans);
if (err) {
IWL_ERR(trans, "Error while preparing HW: %d\n", err);
return err;
}
err = iwl_trans_pcie_clear_persistence_bit(trans);
if (err)
return err;
iwl_trans_pcie_sw_reset(trans); iwl_trans_pcie_sw_reset(trans);
err = iwl_pcie_apm_init(trans); err = iwl_pcie_apm_init(trans);
...@@ -3526,7 +3546,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -3526,7 +3546,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
hw_step |= ENABLE_WFPM; hw_step |= ENABLE_WFPM;
iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG, iwl_write_umac_prph_no_grab(trans, WFPM_CTRL_REG,
hw_step); hw_step);
hw_step = iwl_read_prph_no_grab(trans, AUX_MISC_REG); hw_step = iwl_read_prph_no_grab(trans,
CNVI_AUX_MISC_CHIP);
hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF; hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
if (hw_step == 0x3) if (hw_step == 0x3)
trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) | trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) |
...@@ -3577,7 +3598,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, ...@@ -3577,7 +3598,9 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
} }
} else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) == } else if (CSR_HW_RF_ID_TYPE_CHIP_ID(trans->hw_rf_id) ==
CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) && CSR_HW_RF_ID_TYPE_CHIP_ID(CSR_HW_RF_ID_TYPE_HR) &&
(trans->cfg != &iwl_ax200_cfg_cc || ((trans->cfg != &iwl_ax200_cfg_cc &&
trans->cfg != &killer1650x_2ax_cfg &&
trans->cfg != &killer1650w_2ax_cfg) ||
trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) { trans->hw_rev == CSR_HW_REV_TYPE_QNJ_B0)) {
u32 hw_status; u32 hw_status;
......
...@@ -329,6 +329,8 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, ...@@ -329,6 +329,8 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
struct ieee80211_vendor_ie *vendorhdr; struct ieee80211_vendor_ie *vendorhdr;
u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
int left_len, parsed_len = 0; int left_len, parsed_len = 0;
unsigned int token_len;
int err = 0;
if (!info->tail || !info->tail_len) if (!info->tail || !info->tail_len)
return 0; return 0;
...@@ -344,6 +346,12 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, ...@@ -344,6 +346,12 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
*/ */
while (left_len > sizeof(struct ieee_types_header)) { while (left_len > sizeof(struct ieee_types_header)) {
hdr = (void *)(info->tail + parsed_len); hdr = (void *)(info->tail + parsed_len);
token_len = hdr->len + sizeof(struct ieee_types_header);
if (token_len > left_len) {
err = -EINVAL;
goto out;
}
switch (hdr->element_id) { switch (hdr->element_id) {
case WLAN_EID_SSID: case WLAN_EID_SSID:
case WLAN_EID_SUPP_RATES: case WLAN_EID_SUPP_RATES:
...@@ -361,17 +369,20 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, ...@@ -361,17 +369,20 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
WLAN_OUI_TYPE_MICROSOFT_WMM, WLAN_OUI_TYPE_MICROSOFT_WMM,
(const u8 *)hdr, (const u8 *)hdr,
hdr->len + sizeof(struct ieee_types_header))) token_len))
break; break;
/* fall through */ /* fall through */
default: default:
memcpy(gen_ie->ie_buffer + ie_len, hdr, if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
hdr->len + sizeof(struct ieee_types_header)); err = -EINVAL;
ie_len += hdr->len + sizeof(struct ieee_types_header); goto out;
}
memcpy(gen_ie->ie_buffer + ie_len, hdr, token_len);
ie_len += token_len;
break; break;
} }
left_len -= hdr->len + sizeof(struct ieee_types_header); left_len -= token_len;
parsed_len += hdr->len + sizeof(struct ieee_types_header); parsed_len += token_len;
} }
/* parse only WPA vendor IE from tail, WMM IE is configured by /* parse only WPA vendor IE from tail, WMM IE is configured by
...@@ -381,15 +392,17 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, ...@@ -381,15 +392,17 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
WLAN_OUI_TYPE_MICROSOFT_WPA, WLAN_OUI_TYPE_MICROSOFT_WPA,
info->tail, info->tail_len); info->tail, info->tail_len);
if (vendorhdr) { if (vendorhdr) {
memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len = vendorhdr->len + sizeof(struct ieee_types_header);
vendorhdr->len + sizeof(struct ieee_types_header)); if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
ie_len += vendorhdr->len + sizeof(struct ieee_types_header); err = -EINVAL;
goto out;
}
memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len);
ie_len += token_len;
} }
if (!ie_len) { if (!ie_len)
kfree(gen_ie); goto out;
return 0;
}
gen_ie->ie_index = cpu_to_le16(gen_idx); gen_ie->ie_index = cpu_to_le16(gen_idx);
gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON | gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
...@@ -399,13 +412,15 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv, ...@@ -399,13 +412,15 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL, if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL,
NULL, NULL)) { NULL, NULL)) {
kfree(gen_ie); err = -EINVAL;
return -1; goto out;
} }
priv->gen_idx = gen_idx; priv->gen_idx = gen_idx;
out:
kfree(gen_ie); kfree(gen_ie);
return 0; return err;
} }
/* This function parses different IEs-head & tail IEs, beacon IEs, /* This function parses different IEs-head & tail IEs, beacon IEs,
......
...@@ -1247,6 +1247,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1247,6 +1247,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
} }
switch (element_id) { switch (element_id) {
case WLAN_EID_SSID: case WLAN_EID_SSID:
if (element_len > IEEE80211_MAX_SSID_LEN)
return -EINVAL;
bss_entry->ssid.ssid_len = element_len; bss_entry->ssid.ssid_len = element_len;
memcpy(bss_entry->ssid.ssid, (current_ptr + 2), memcpy(bss_entry->ssid.ssid, (current_ptr + 2),
element_len); element_len);
...@@ -1256,6 +1258,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1256,6 +1258,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break; break;
case WLAN_EID_SUPP_RATES: case WLAN_EID_SUPP_RATES:
if (element_len > MWIFIEX_SUPPORTED_RATES)
return -EINVAL;
memcpy(bss_entry->data_rates, current_ptr + 2, memcpy(bss_entry->data_rates, current_ptr + 2,
element_len); element_len);
memcpy(bss_entry->supported_rates, current_ptr + 2, memcpy(bss_entry->supported_rates, current_ptr + 2,
...@@ -1265,6 +1269,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1265,6 +1269,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break; break;
case WLAN_EID_FH_PARAMS: case WLAN_EID_FH_PARAMS:
if (element_len + 2 < sizeof(*fh_param_set))
return -EINVAL;
fh_param_set = fh_param_set =
(struct ieee_types_fh_param_set *) current_ptr; (struct ieee_types_fh_param_set *) current_ptr;
memcpy(&bss_entry->phy_param_set.fh_param_set, memcpy(&bss_entry->phy_param_set.fh_param_set,
...@@ -1273,6 +1279,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1273,6 +1279,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break; break;
case WLAN_EID_DS_PARAMS: case WLAN_EID_DS_PARAMS:
if (element_len + 2 < sizeof(*ds_param_set))
return -EINVAL;
ds_param_set = ds_param_set =
(struct ieee_types_ds_param_set *) current_ptr; (struct ieee_types_ds_param_set *) current_ptr;
...@@ -1284,6 +1292,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1284,6 +1292,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break; break;
case WLAN_EID_CF_PARAMS: case WLAN_EID_CF_PARAMS:
if (element_len + 2 < sizeof(*cf_param_set))
return -EINVAL;
cf_param_set = cf_param_set =
(struct ieee_types_cf_param_set *) current_ptr; (struct ieee_types_cf_param_set *) current_ptr;
memcpy(&bss_entry->ss_param_set.cf_param_set, memcpy(&bss_entry->ss_param_set.cf_param_set,
...@@ -1292,6 +1302,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1292,6 +1302,8 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break; break;
case WLAN_EID_IBSS_PARAMS: case WLAN_EID_IBSS_PARAMS:
if (element_len + 2 < sizeof(*ibss_param_set))
return -EINVAL;
ibss_param_set = ibss_param_set =
(struct ieee_types_ibss_param_set *) (struct ieee_types_ibss_param_set *)
current_ptr; current_ptr;
...@@ -1301,10 +1313,14 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1301,10 +1313,14 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break; break;
case WLAN_EID_ERP_INFO: case WLAN_EID_ERP_INFO:
if (!element_len)
return -EINVAL;
bss_entry->erp_flags = *(current_ptr + 2); bss_entry->erp_flags = *(current_ptr + 2);
break; break;
case WLAN_EID_PWR_CONSTRAINT: case WLAN_EID_PWR_CONSTRAINT:
if (!element_len)
return -EINVAL;
bss_entry->local_constraint = *(current_ptr + 2); bss_entry->local_constraint = *(current_ptr + 2);
bss_entry->sensed_11h = true; bss_entry->sensed_11h = true;
break; break;
...@@ -1345,6 +1361,9 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter, ...@@ -1345,6 +1361,9 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
break; break;
case WLAN_EID_VENDOR_SPECIFIC: case WLAN_EID_VENDOR_SPECIFIC:
if (element_len + 2 < sizeof(vendor_ie->vend_hdr))
return -EINVAL;
vendor_ie = (struct ieee_types_vendor_specific *) vendor_ie = (struct ieee_types_vendor_specific *)
current_ptr; current_ptr;
......
...@@ -8,7 +8,8 @@ ...@@ -8,7 +8,8 @@
#include "reg.h" #include "reg.h"
#include "debug.h" #include "debug.h"
void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev, struct sk_buff *skb) static void rtw_fw_c2h_cmd_handle_ext(struct rtw_dev *rtwdev,
struct sk_buff *skb)
{ {
struct rtw_c2h_cmd *c2h; struct rtw_c2h_cmd *c2h;
u8 sub_cmd_id; u8 sub_cmd_id;
...@@ -47,7 +48,8 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb) ...@@ -47,7 +48,8 @@ void rtw_fw_c2h_cmd_handle(struct rtw_dev *rtwdev, struct sk_buff *skb)
} }
} }
void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev, u8 *h2c) static void rtw_fw_send_h2c_command(struct rtw_dev *rtwdev,
u8 *h2c)
{ {
u8 box; u8 box;
u8 box_state; u8 box_state;
......
...@@ -162,7 +162,8 @@ static void rtw_watch_dog_work(struct work_struct *work) ...@@ -162,7 +162,8 @@ static void rtw_watch_dog_work(struct work_struct *work)
rtwdev->stats.tx_cnt = 0; rtwdev->stats.tx_cnt = 0;
rtwdev->stats.rx_cnt = 0; rtwdev->stats.rx_cnt = 0;
rtw_iterate_vifs(rtwdev, rtw_vif_watch_dog_iter, &data); /* use atomic version to avoid taking local->iflist_mtx mutex */
rtw_iterate_vifs_atomic(rtwdev, rtw_vif_watch_dog_iter, &data);
/* fw supports only one station associated to enter lps, if there are /* fw supports only one station associated to enter lps, if there are
* more than two stations associated to the AP, then we can not enter * more than two stations associated to the AP, then we can not enter
......
...@@ -144,10 +144,10 @@ static void rtw_phy_stat_rssi_iter(void *data, struct ieee80211_sta *sta) ...@@ -144,10 +144,10 @@ static void rtw_phy_stat_rssi_iter(void *data, struct ieee80211_sta *sta)
struct rtw_phy_stat_iter_data *iter_data = data; struct rtw_phy_stat_iter_data *iter_data = data;
struct rtw_dev *rtwdev = iter_data->rtwdev; struct rtw_dev *rtwdev = iter_data->rtwdev;
struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv; struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
u8 rssi, rssi_level; u8 rssi;
rssi = ewma_rssi_read(&si->avg_rssi); rssi = ewma_rssi_read(&si->avg_rssi);
rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi); si->rssi_level = rtw_phy_get_rssi_level(si->rssi_level, rssi);
rtw_fw_send_rssi_info(rtwdev, si); rtw_fw_send_rssi_info(rtwdev, si);
...@@ -423,6 +423,11 @@ static u64 rtw_phy_db_2_linear(u8 power_db) ...@@ -423,6 +423,11 @@ static u64 rtw_phy_db_2_linear(u8 power_db)
u8 i, j; u8 i, j;
u64 linear; u64 linear;
if (power_db > 96)
power_db = 96;
else if (power_db < 1)
return 1;
/* 1dB ~ 96dB */ /* 1dB ~ 96dB */
i = (power_db - 1) >> 3; i = (power_db - 1) >> 3;
j = (power_db - 1) - (i << 3); j = (power_db - 1) - (i << 3);
...@@ -848,12 +853,13 @@ u8 rtw_vht_2s_rates[] = { ...@@ -848,12 +853,13 @@ u8 rtw_vht_2s_rates[] = {
DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9
}; };
u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates);
u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates); static u8 rtw_cck_size = ARRAY_SIZE(rtw_cck_rates);
u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates); static u8 rtw_ofdm_size = ARRAY_SIZE(rtw_ofdm_rates);
u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates); static u8 rtw_ht_1s_size = ARRAY_SIZE(rtw_ht_1s_rates);
u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates); static u8 rtw_ht_2s_size = ARRAY_SIZE(rtw_ht_2s_rates);
u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates); static u8 rtw_vht_1s_size = ARRAY_SIZE(rtw_vht_1s_rates);
static u8 rtw_vht_2s_size = ARRAY_SIZE(rtw_vht_2s_rates);
u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = { u8 *rtw_rate_section[RTW_RATE_SECTION_MAX] = {
rtw_cck_rates, rtw_ofdm_rates, rtw_cck_rates, rtw_ofdm_rates,
rtw_ht_1s_rates, rtw_ht_2s_rates, rtw_ht_1s_rates, rtw_ht_2s_rates,
......
...@@ -929,11 +929,15 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter) ...@@ -929,11 +929,15 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
u32 addr; u32 addr;
u8 *data; u8 *data;
data = kzalloc(RSI_9116_REG_SIZE, GFP_KERNEL);
if (!data)
return -ENOMEM;
status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR); status = rsi_sdio_master_access_msword(adapter, TA_BASE_ADDR);
if (status < 0) { if (status < 0) {
rsi_dbg(ERR_ZONE, rsi_dbg(ERR_ZONE,
"Unable to set ms word to common reg\n"); "Unable to set ms word to common reg\n");
return status; goto err;
} }
rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__); rsi_dbg(INIT_ZONE, "%s: Bring TA out of reset\n", __func__);
...@@ -944,7 +948,7 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter) ...@@ -944,7 +948,7 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
RSI_9116_REG_SIZE); RSI_9116_REG_SIZE);
if (status < 0) { if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n"); rsi_dbg(ERR_ZONE, "Unable to hold TA threads\n");
return status; goto err;
} }
put_unaligned_le32(TA_SOFT_RST_CLR, data); put_unaligned_le32(TA_SOFT_RST_CLR, data);
...@@ -954,7 +958,7 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter) ...@@ -954,7 +958,7 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
RSI_9116_REG_SIZE); RSI_9116_REG_SIZE);
if (status < 0) { if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n"); rsi_dbg(ERR_ZONE, "Unable to get TA out of reset\n");
return status; goto err;
} }
put_unaligned_le32(TA_PC_ZERO, data); put_unaligned_le32(TA_PC_ZERO, data);
...@@ -964,7 +968,8 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter) ...@@ -964,7 +968,8 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
RSI_9116_REG_SIZE); RSI_9116_REG_SIZE);
if (status < 0) { if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n"); rsi_dbg(ERR_ZONE, "Unable to Reset TA PC value\n");
return -EINVAL; status = -EINVAL;
goto err;
} }
put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data); put_unaligned_le32(TA_RELEASE_THREAD_VALUE, data);
...@@ -974,17 +979,19 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter) ...@@ -974,17 +979,19 @@ static int rsi_sdio_ta_reset(struct rsi_hw *adapter)
RSI_9116_REG_SIZE); RSI_9116_REG_SIZE);
if (status < 0) { if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to release TA threads\n"); rsi_dbg(ERR_ZONE, "Unable to release TA threads\n");
return status; goto err;
} }
status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR); status = rsi_sdio_master_access_msword(adapter, MISC_CFG_BASE_ADDR);
if (status < 0) { if (status < 0) {
rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n"); rsi_dbg(ERR_ZONE, "Unable to set ms word to common reg\n");
return status; goto err;
} }
rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n"); rsi_dbg(INIT_ZONE, "***** TA Reset done *****\n");
return 0; err:
kfree(data);
return status;
} }
static struct rsi_host_intf_ops sdio_host_intf_ops = { static struct rsi_host_intf_ops sdio_host_intf_ops = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment