1 // SPDX-License-Identifier: ISC
3 * Copyright (c) 2005-2011 Atheros Communications Inc.
4 * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc.
13 void ath10k_bmi_start(struct ath10k
*ar
)
17 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi start\n");
19 ar
->bmi
.done_sent
= false;
21 /* Enable hardware clock to speed up firmware download */
22 if (ar
->hw_params
.hw_ops
->enable_pll_clk
) {
23 ret
= ar
->hw_params
.hw_ops
->enable_pll_clk(ar
);
24 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi enable pll ret %d\n", ret
);
28 int ath10k_bmi_done(struct ath10k
*ar
)
31 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.done
);
34 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi done\n");
36 if (ar
->bmi
.done_sent
) {
37 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi skipped\n");
41 ar
->bmi
.done_sent
= true;
42 cmd
.id
= __cpu_to_le32(BMI_DONE
);
44 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, NULL
, NULL
);
46 ath10k_warn(ar
, "unable to write to the device: %d\n", ret
);
53 int ath10k_bmi_get_target_info(struct ath10k
*ar
,
54 struct bmi_target_info
*target_info
)
58 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.get_target_info
);
59 u32 resplen
= sizeof(resp
.get_target_info
);
62 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi get target info\n");
64 if (ar
->bmi
.done_sent
) {
65 ath10k_warn(ar
, "BMI Get Target Info Command disallowed\n");
69 cmd
.id
= __cpu_to_le32(BMI_GET_TARGET_INFO
);
71 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, &resp
, &resplen
);
73 ath10k_warn(ar
, "unable to get target info from device\n");
77 if (resplen
< sizeof(resp
.get_target_info
)) {
78 ath10k_warn(ar
, "invalid get_target_info response length (%d)\n",
83 target_info
->version
= __le32_to_cpu(resp
.get_target_info
.version
);
84 target_info
->type
= __le32_to_cpu(resp
.get_target_info
.type
);
89 #define TARGET_VERSION_SENTINAL 0xffffffffu
91 int ath10k_bmi_get_target_info_sdio(struct ath10k
*ar
,
92 struct bmi_target_info
*target_info
)
96 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.get_target_info
);
101 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi get target info SDIO\n");
103 if (ar
->bmi
.done_sent
) {
104 ath10k_warn(ar
, "BMI Get Target Info Command disallowed\n");
108 cmd
.id
= __cpu_to_le32(BMI_GET_TARGET_INFO
);
110 /* Step 1: Read 4 bytes of the target info and check if it is
111 * the special sentinal version word or the first word in the
114 resplen
= sizeof(u32
);
115 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, &tmp
, &resplen
);
117 ath10k_warn(ar
, "unable to read from device\n");
121 /* Some SDIO boards have a special sentinal byte before the real
124 if (__le32_to_cpu(tmp
) == TARGET_VERSION_SENTINAL
) {
125 /* Step 1b: Read the version length */
126 resplen
= sizeof(u32
);
127 ret
= ath10k_hif_exchange_bmi_msg(ar
, NULL
, 0, &tmp
,
130 ath10k_warn(ar
, "unable to read from device\n");
135 ver_len
= __le32_to_cpu(tmp
);
137 /* Step 2: Check the target info length */
138 if (ver_len
!= sizeof(resp
.get_target_info
)) {
139 ath10k_warn(ar
, "Unexpected target info len: %u. Expected: %zu\n",
140 ver_len
, sizeof(resp
.get_target_info
));
144 /* Step 3: Read the rest of the version response */
145 resplen
= sizeof(resp
.get_target_info
) - sizeof(u32
);
146 ret
= ath10k_hif_exchange_bmi_msg(ar
, NULL
, 0,
147 &resp
.get_target_info
.version
,
150 ath10k_warn(ar
, "unable to read from device\n");
154 target_info
->version
= __le32_to_cpu(resp
.get_target_info
.version
);
155 target_info
->type
= __le32_to_cpu(resp
.get_target_info
.type
);
160 int ath10k_bmi_read_memory(struct ath10k
*ar
,
161 u32 address
, void *buffer
, u32 length
)
165 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.read_mem
);
169 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi read address 0x%x length %d\n",
172 if (ar
->bmi
.done_sent
) {
173 ath10k_warn(ar
, "command disallowed\n");
178 rxlen
= min_t(u32
, length
, BMI_MAX_DATA_SIZE
);
180 cmd
.id
= __cpu_to_le32(BMI_READ_MEMORY
);
181 cmd
.read_mem
.addr
= __cpu_to_le32(address
);
182 cmd
.read_mem
.len
= __cpu_to_le32(rxlen
);
184 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
,
187 ath10k_warn(ar
, "unable to read from the device (%d)\n",
192 memcpy(buffer
, resp
.read_mem
.payload
, rxlen
);
201 int ath10k_bmi_write_soc_reg(struct ath10k
*ar
, u32 address
, u32 reg_val
)
204 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.write_soc_reg
);
207 ath10k_dbg(ar
, ATH10K_DBG_BMI
,
208 "bmi write soc register 0x%08x val 0x%08x\n",
211 if (ar
->bmi
.done_sent
) {
212 ath10k_warn(ar
, "bmi write soc register command in progress\n");
216 cmd
.id
= __cpu_to_le32(BMI_WRITE_SOC_REGISTER
);
217 cmd
.write_soc_reg
.addr
= __cpu_to_le32(address
);
218 cmd
.write_soc_reg
.value
= __cpu_to_le32(reg_val
);
220 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, NULL
, NULL
);
222 ath10k_warn(ar
, "Unable to write soc register to device: %d\n",
230 int ath10k_bmi_read_soc_reg(struct ath10k
*ar
, u32 address
, u32
*reg_val
)
234 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.read_soc_reg
);
235 u32 resplen
= sizeof(resp
.read_soc_reg
);
238 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi read soc register 0x%08x\n",
241 if (ar
->bmi
.done_sent
) {
242 ath10k_warn(ar
, "bmi read soc register command in progress\n");
246 cmd
.id
= __cpu_to_le32(BMI_READ_SOC_REGISTER
);
247 cmd
.read_soc_reg
.addr
= __cpu_to_le32(address
);
249 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, &resp
, &resplen
);
251 ath10k_warn(ar
, "Unable to read soc register from device: %d\n",
256 *reg_val
= __le32_to_cpu(resp
.read_soc_reg
.value
);
258 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi read soc register value 0x%08x\n",
264 int ath10k_bmi_write_memory(struct ath10k
*ar
,
265 u32 address
, const void *buffer
, u32 length
)
268 u32 hdrlen
= sizeof(cmd
.id
) + sizeof(cmd
.write_mem
);
272 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi write address 0x%x length %d\n",
275 if (ar
->bmi
.done_sent
) {
276 ath10k_warn(ar
, "command disallowed\n");
281 txlen
= min(length
, BMI_MAX_DATA_SIZE
- hdrlen
);
283 /* copy before roundup to avoid reading beyond buffer*/
284 memcpy(cmd
.write_mem
.payload
, buffer
, txlen
);
285 txlen
= roundup(txlen
, 4);
287 cmd
.id
= __cpu_to_le32(BMI_WRITE_MEMORY
);
288 cmd
.write_mem
.addr
= __cpu_to_le32(address
);
289 cmd
.write_mem
.len
= __cpu_to_le32(txlen
);
291 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, hdrlen
+ txlen
,
294 ath10k_warn(ar
, "unable to write to the device (%d)\n",
299 /* fixup roundup() so `length` zeroes out for last chunk */
300 txlen
= min(txlen
, length
);
310 int ath10k_bmi_execute(struct ath10k
*ar
, u32 address
, u32 param
, u32
*result
)
314 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.execute
);
315 u32 resplen
= sizeof(resp
.execute
);
318 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi execute address 0x%x param 0x%x\n",
321 if (ar
->bmi
.done_sent
) {
322 ath10k_warn(ar
, "command disallowed\n");
326 cmd
.id
= __cpu_to_le32(BMI_EXECUTE
);
327 cmd
.execute
.addr
= __cpu_to_le32(address
);
328 cmd
.execute
.param
= __cpu_to_le32(param
);
330 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, &resp
, &resplen
);
332 ath10k_warn(ar
, "unable to read from the device\n");
336 if (resplen
< sizeof(resp
.execute
)) {
337 ath10k_warn(ar
, "invalid execute response length (%d)\n",
342 *result
= __le32_to_cpu(resp
.execute
.result
);
344 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi execute result 0x%x\n", *result
);
349 static int ath10k_bmi_lz_data_large(struct ath10k
*ar
, const void *buffer
, u32 length
)
352 u32 hdrlen
= sizeof(cmd
->id
) + sizeof(cmd
->lz_data
);
357 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "large bmi lz data buffer 0x%pK length %d\n",
360 if (ar
->bmi
.done_sent
) {
361 ath10k_warn(ar
, "command disallowed\n");
365 buf_len
= sizeof(*cmd
) + BMI_MAX_LARGE_DATA_SIZE
- BMI_MAX_DATA_SIZE
;
366 cmd
= kzalloc(buf_len
, GFP_KERNEL
);
371 txlen
= min(length
, BMI_MAX_LARGE_DATA_SIZE
- hdrlen
);
373 WARN_ON_ONCE(txlen
& 3);
375 cmd
->id
= __cpu_to_le32(BMI_LZ_DATA
);
376 cmd
->lz_data
.len
= __cpu_to_le32(txlen
);
377 memcpy(cmd
->lz_data
.payload
, buffer
, txlen
);
379 ret
= ath10k_hif_exchange_bmi_msg(ar
, cmd
, hdrlen
+ txlen
,
382 ath10k_warn(ar
, "unable to write to the device\n");
395 int ath10k_bmi_lz_data(struct ath10k
*ar
, const void *buffer
, u32 length
)
398 u32 hdrlen
= sizeof(cmd
.id
) + sizeof(cmd
.lz_data
);
402 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi lz data buffer 0x%pK length %d\n",
405 if (ar
->bmi
.done_sent
) {
406 ath10k_warn(ar
, "command disallowed\n");
411 txlen
= min(length
, BMI_MAX_DATA_SIZE
- hdrlen
);
413 WARN_ON_ONCE(txlen
& 3);
415 cmd
.id
= __cpu_to_le32(BMI_LZ_DATA
);
416 cmd
.lz_data
.len
= __cpu_to_le32(txlen
);
417 memcpy(cmd
.lz_data
.payload
, buffer
, txlen
);
419 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, hdrlen
+ txlen
,
422 ath10k_warn(ar
, "unable to write to the device\n");
433 int ath10k_bmi_lz_stream_start(struct ath10k
*ar
, u32 address
)
436 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.lz_start
);
439 ath10k_dbg(ar
, ATH10K_DBG_BMI
, "bmi lz stream start address 0x%x\n",
442 if (ar
->bmi
.done_sent
) {
443 ath10k_warn(ar
, "command disallowed\n");
447 cmd
.id
= __cpu_to_le32(BMI_LZ_STREAM_START
);
448 cmd
.lz_start
.addr
= __cpu_to_le32(address
);
450 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, NULL
, NULL
);
452 ath10k_warn(ar
, "unable to Start LZ Stream to the device\n");
459 int ath10k_bmi_fast_download(struct ath10k
*ar
,
460 u32 address
, const void *buffer
, u32 length
)
463 u32 head_len
= rounddown(length
, 4);
464 u32 trailer_len
= length
- head_len
;
467 ath10k_dbg(ar
, ATH10K_DBG_BMI
,
468 "bmi fast download address 0x%x buffer 0x%pK length %d\n",
469 address
, buffer
, length
);
471 ret
= ath10k_bmi_lz_stream_start(ar
, address
);
475 /* copy the last word into a zero padded buffer */
477 memcpy(trailer
, buffer
+ head_len
, trailer_len
);
479 if (ar
->hw_params
.bmi_large_size_download
)
480 ret
= ath10k_bmi_lz_data_large(ar
, buffer
, head_len
);
482 ret
= ath10k_bmi_lz_data(ar
, buffer
, head_len
);
488 ret
= ath10k_bmi_lz_data(ar
, trailer
, 4);
494 * Close compressed stream and open a new (fake) one.
495 * This serves mainly to flush Target caches.
497 ret
= ath10k_bmi_lz_stream_start(ar
, 0x00);
502 int ath10k_bmi_set_start(struct ath10k
*ar
, u32 address
)
505 u32 cmdlen
= sizeof(cmd
.id
) + sizeof(cmd
.set_app_start
);
508 if (ar
->bmi
.done_sent
) {
509 ath10k_warn(ar
, "bmi set start command disallowed\n");
513 cmd
.id
= __cpu_to_le32(BMI_SET_APP_START
);
514 cmd
.set_app_start
.addr
= __cpu_to_le32(address
);
516 ret
= ath10k_hif_exchange_bmi_msg(ar
, &cmd
, cmdlen
, NULL
, NULL
);
518 ath10k_warn(ar
, "unable to set start to the device:%d\n", ret
);