Skip to content

Commit

Permalink
ath10k: add large size for BMI download data for SDIO
Browse files Browse the repository at this point in the history
Download firmware time cost of SDIO is too long, it is about 480ms,
add large size 2048 bytes for BMI download for SDIO chip, its time
cost will reduced to 240ms.

This will optimize the download firmware time cost.

Tested with QCA6174 SDIO with firmware
WLAN.RMH.4.4.1-00017-QCARMSWP-1.

Signed-off-by: Wen Gong <wgong@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
  • Loading branch information
Wen Gong authored and Kalle Valo committed Nov 25, 2019
1 parent e01cc82 commit d58f466
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 2 deletions.
52 changes: 51 additions & 1 deletion drivers/net/wireless/ath/ath10k/bmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,52 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result)
return 0;
}

static int ath10k_bmi_lz_data_large(struct ath10k *ar, const void *buffer, u32 length)
{
struct bmi_cmd *cmd;
u32 hdrlen = sizeof(cmd->id) + sizeof(cmd->lz_data);
u32 txlen;
int ret;
size_t buf_len;

ath10k_dbg(ar, ATH10K_DBG_BMI, "large bmi lz data buffer 0x%pK length %d\n",
buffer, length);

if (ar->bmi.done_sent) {
ath10k_warn(ar, "command disallowed\n");
return -EBUSY;
}

buf_len = sizeof(*cmd) + BMI_MAX_LARGE_DATA_SIZE - BMI_MAX_DATA_SIZE;
cmd = kzalloc(buf_len, GFP_KERNEL);
if (!cmd)
return -ENOMEM;

while (length) {
txlen = min(length, BMI_MAX_LARGE_DATA_SIZE - hdrlen);

WARN_ON_ONCE(txlen & 3);

cmd->id = __cpu_to_le32(BMI_LZ_DATA);
cmd->lz_data.len = __cpu_to_le32(txlen);
memcpy(cmd->lz_data.payload, buffer, txlen);

ret = ath10k_hif_exchange_bmi_msg(ar, cmd, hdrlen + txlen,
NULL, NULL);
if (ret) {
ath10k_warn(ar, "unable to write to the device\n");
return ret;
}

buffer += txlen;
length -= txlen;
}

kfree(cmd);

return 0;
}

int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length)
{
struct bmi_cmd cmd;
Expand Down Expand Up @@ -430,7 +476,11 @@ int ath10k_bmi_fast_download(struct ath10k *ar,
if (trailer_len > 0)
memcpy(trailer, buffer + head_len, trailer_len);

ret = ath10k_bmi_lz_data(ar, buffer, head_len);
if (ar->hw_params.bmi_large_size_download)
ret = ath10k_bmi_lz_data_large(ar, buffer, head_len);
else
ret = ath10k_bmi_lz_data(ar, buffer, head_len);

if (ret)
return ret;

Expand Down
10 changes: 10 additions & 0 deletions drivers/net/wireless/ath/ath10k/bmi.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@
sizeof(u32) + \
sizeof(u32))

/* Maximum data size used for large BMI transfers */
#define BMI_MAX_LARGE_DATA_SIZE 2048

/* len = cmd + addr + length */
#define BMI_MAX_LARGE_CMDBUF_SIZE (BMI_MAX_LARGE_DATA_SIZE + \
sizeof(u32) + \
sizeof(u32) + \
sizeof(u32))

/* BMI Commands */

enum bmi_cmd_id {
Expand Down Expand Up @@ -258,6 +267,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address,
int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result);
int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address);
int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length);

int ath10k_bmi_fast_download(struct ath10k *ar, u32 address,
const void *buffer, u32 length);
int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/wireless/ath/ath10k/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = {
.num_wds_entries = 0x20,
.uart_pin_workaround = true,
.tx_stats_over_pktlog = false,
.bmi_large_size_download = true,
},
{
.id = QCA6174_HW_2_1_VERSION,
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/wireless/ath/ath10k/hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,9 @@ struct ath10k_hw_params {
/* target supporting fw download via diag ce */
bool fw_diag_ce_download;

/* target supporting fw download via large size BMI */
bool bmi_large_size_download;

/* need to set uart pin if disable uart print, workaround for a
* firmware bug
*/
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ath10k/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -2082,7 +2082,7 @@ static int ath10k_sdio_probe(struct sdio_func *func,
goto err_core_destroy;
}

ar_sdio->bmi_buf = devm_kzalloc(ar->dev, BMI_MAX_CMDBUF_SIZE, GFP_KERNEL);
ar_sdio->bmi_buf = devm_kzalloc(ar->dev, BMI_MAX_LARGE_CMDBUF_SIZE, GFP_KERNEL);
if (!ar_sdio->bmi_buf) {
ret = -ENOMEM;
goto err_core_destroy;
Expand Down

0 comments on commit d58f466

Please sign in to comment.