Commit 40194e3b authored by Wen Gong's avatar Wen Gong Committed by Kalle Valo

ath10k: change swap mail box check after htc ready

The swap box flag of firmware is not set before htc ready, then it
will not set swap box flag in ath10k driver, and it will let swap
box setting not same between firmware and ath10k driver, then it
will trigger firmware assert failure.

Check the flag and set swap box after htc ready will fix the firmware
assert failure.

Tested with QCA6174 SDIO with firmware
WLAN.RMH.4.4.1-00005-QCARMSWP-1.
Signed-off-by: default avatarWen Gong <wgong@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent cdb78e5a
...@@ -2556,6 +2556,12 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode, ...@@ -2556,6 +2556,12 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode,
goto err_hif_stop; goto err_hif_stop;
} }
status = ath10k_hif_swap_mailbox(ar);
if (status) {
ath10k_err(ar, "failed to swap mailbox: %d\n", status);
goto err_hif_stop;
}
if (mode == ATH10K_FIRMWARE_MODE_NORMAL) { if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
status = ath10k_htt_connect(&ar->htt); status = ath10k_htt_connect(&ar->htt);
if (status) { if (status) {
......
...@@ -59,6 +59,8 @@ struct ath10k_hif_ops { ...@@ -59,6 +59,8 @@ struct ath10k_hif_ops {
*/ */
void (*stop)(struct ath10k *ar); void (*stop)(struct ath10k *ar);
int (*swap_mailbox)(struct ath10k *ar);
int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id, int (*map_service_to_pipe)(struct ath10k *ar, u16 service_id,
u8 *ul_pipe, u8 *dl_pipe); u8 *ul_pipe, u8 *dl_pipe);
...@@ -139,6 +141,13 @@ static inline void ath10k_hif_stop(struct ath10k *ar) ...@@ -139,6 +141,13 @@ static inline void ath10k_hif_stop(struct ath10k *ar)
return ar->hif.ops->stop(ar); return ar->hif.ops->stop(ar);
} }
static inline int ath10k_hif_swap_mailbox(struct ath10k *ar)
{
if (ar->hif.ops->swap_mailbox)
return ar->hif.ops->swap_mailbox(ar);
return 0;
}
static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar, static inline int ath10k_hif_map_service_to_pipe(struct ath10k *ar,
u16 service_id, u16 service_id,
u8 *ul_pipe, u8 *dl_pipe) u8 *ul_pipe, u8 *dl_pipe)
......
...@@ -1615,12 +1615,33 @@ static int ath10k_sdio_hif_diag_write_mem(struct ath10k *ar, u32 address, ...@@ -1615,12 +1615,33 @@ static int ath10k_sdio_hif_diag_write_mem(struct ath10k *ar, u32 address,
return 0; return 0;
} }
static int ath10k_sdio_hif_swap_mailbox(struct ath10k *ar)
{
struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
u32 addr, val;
int ret = 0;
addr = host_interest_item_address(HI_ITEM(hi_acs_flags));
ret = ath10k_sdio_hif_diag_read32(ar, addr, &val);
if (ret) {
ath10k_warn(ar, "unable to read hi_acs_flags : %d\n", ret);
return ret;
}
if (val & HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK) {
ath10k_dbg(ar, ATH10K_DBG_SDIO,
"sdio mailbox swap service enabled\n");
ar_sdio->swap_mbox = true;
}
return 0;
}
/* HIF start/stop */ /* HIF start/stop */
static int ath10k_sdio_hif_start(struct ath10k *ar) static int ath10k_sdio_hif_start(struct ath10k *ar)
{ {
struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar); struct ath10k_sdio *ar_sdio = ath10k_sdio_priv(ar);
u32 addr, val;
int ret; int ret;
/* Sleep 20 ms before HIF interrupts are disabled. /* Sleep 20 ms before HIF interrupts are disabled.
...@@ -1654,20 +1675,6 @@ static int ath10k_sdio_hif_start(struct ath10k *ar) ...@@ -1654,20 +1675,6 @@ static int ath10k_sdio_hif_start(struct ath10k *ar)
if (ret) if (ret)
ath10k_warn(ar, "failed to enable sdio interrupts: %d\n", ret); ath10k_warn(ar, "failed to enable sdio interrupts: %d\n", ret);
addr = host_interest_item_address(HI_ITEM(hi_acs_flags));
ret = ath10k_sdio_hif_diag_read32(ar, addr, &val);
if (ret) {
ath10k_warn(ar, "unable to read hi_acs_flags address: %d\n", ret);
return ret;
}
if (val & HI_ACS_FLAGS_SDIO_SWAP_MAILBOX_FW_ACK) {
ath10k_dbg(ar, ATH10K_DBG_SDIO,
"sdio mailbox swap service enabled\n");
ar_sdio->swap_mbox = true;
}
/* Enable sleep and then disable it again */ /* Enable sleep and then disable it again */
ret = ath10k_sdio_hif_set_mbox_sleep(ar, true); ret = ath10k_sdio_hif_set_mbox_sleep(ar, true);
if (ret) if (ret)
...@@ -1898,6 +1905,7 @@ static const struct ath10k_hif_ops ath10k_sdio_hif_ops = { ...@@ -1898,6 +1905,7 @@ static const struct ath10k_hif_ops ath10k_sdio_hif_ops = {
.exchange_bmi_msg = ath10k_sdio_bmi_exchange_msg, .exchange_bmi_msg = ath10k_sdio_bmi_exchange_msg,
.start = ath10k_sdio_hif_start, .start = ath10k_sdio_hif_start,
.stop = ath10k_sdio_hif_stop, .stop = ath10k_sdio_hif_stop,
.swap_mailbox = ath10k_sdio_hif_swap_mailbox,
.map_service_to_pipe = ath10k_sdio_hif_map_service_to_pipe, .map_service_to_pipe = ath10k_sdio_hif_map_service_to_pipe,
.get_default_pipe = ath10k_sdio_hif_get_default_pipe, .get_default_pipe = ath10k_sdio_hif_get_default_pipe,
.send_complete_check = ath10k_sdio_hif_send_complete_check, .send_complete_check = ath10k_sdio_hif_send_complete_check,
......
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