1 // SPDX-License-Identifier: ISC 2 /* 3 * Copyright (c) 2005-2011 Atheros Communications Inc. 4 * Copyright (c) 2011-2014,2016-2017 Qualcomm Atheros, Inc. 5 */ 6 7 #include "bmi.h" 8 #include "hif.h" 9 #include "debug.h" 10 #include "htc.h" 11 #include "hw.h" 12 13 void ath10k_bmi_start(struct ath10k *ar) 14 { 15 int ret; 16 17 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi start\n"); 18 19 ar->bmi.done_sent = false; 20 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); 25 } 26 } 27 28 int ath10k_bmi_done(struct ath10k *ar) 29 { 30 struct bmi_cmd cmd; 31 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done); 32 int ret; 33 34 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi done\n"); 35 36 if (ar->bmi.done_sent) { 37 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi skipped\n"); 38 return 0; 39 } 40 41 ar->bmi.done_sent = true; 42 cmd.id = __cpu_to_le32(BMI_DONE); 43 44 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); 45 if (ret) { 46 ath10k_warn(ar, "unable to write to the device: %d\n", ret); 47 return ret; 48 } 49 50 return 0; 51 } 52 53 int ath10k_bmi_get_target_info(struct ath10k *ar, 54 struct bmi_target_info *target_info) 55 { 56 struct bmi_cmd cmd; 57 union bmi_resp resp; 58 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.get_target_info); 59 u32 resplen = sizeof(resp.get_target_info); 60 int ret; 61 62 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi get target info\n"); 63 64 if (ar->bmi.done_sent) { 65 ath10k_warn(ar, "BMI Get Target Info Command disallowed\n"); 66 return -EBUSY; 67 } 68 69 cmd.id = __cpu_to_le32(BMI_GET_TARGET_INFO); 70 71 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); 72 if (ret) { 73 ath10k_warn(ar, "unable to get target info from device\n"); 74 return ret; 75 } 76 77 if (resplen < sizeof(resp.get_target_info)) { 78 ath10k_warn(ar, "invalid get_target_info response length (%d)\n", 79 resplen); 80 return -EIO; 81 } 82 83 target_info->version = __le32_to_cpu(resp.get_target_info.version); 84 target_info->type = __le32_to_cpu(resp.get_target_info.type); 85 86 return 0; 87 } 88 89 #define TARGET_VERSION_SENTINAL 0xffffffffu 90 91 int ath10k_bmi_get_target_info_sdio(struct ath10k *ar, 92 struct bmi_target_info *target_info) 93 { 94 struct bmi_cmd cmd; 95 union bmi_resp resp; 96 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.get_target_info); 97 u32 resplen, ver_len; 98 __le32 tmp; 99 int ret; 100 101 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi get target info SDIO\n"); 102 103 if (ar->bmi.done_sent) { 104 ath10k_warn(ar, "BMI Get Target Info Command disallowed\n"); 105 return -EBUSY; 106 } 107 108 cmd.id = __cpu_to_le32(BMI_GET_TARGET_INFO); 109 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 112 * version response. 113 */ 114 resplen = sizeof(u32); 115 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &tmp, &resplen); 116 if (ret) { 117 ath10k_warn(ar, "unable to read from device\n"); 118 return ret; 119 } 120 121 /* Some SDIO boards have a special sentinal byte before the real 122 * version response. 123 */ 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, 128 &resplen); 129 if (ret) { 130 ath10k_warn(ar, "unable to read from device\n"); 131 return ret; 132 } 133 } 134 135 ver_len = __le32_to_cpu(tmp); 136 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)); 141 return -EINVAL; 142 } 143 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, 148 &resplen); 149 if (ret) { 150 ath10k_warn(ar, "unable to read from device\n"); 151 return ret; 152 } 153 154 target_info->version = __le32_to_cpu(resp.get_target_info.version); 155 target_info->type = __le32_to_cpu(resp.get_target_info.type); 156 157 return 0; 158 } 159 160 int ath10k_bmi_read_memory(struct ath10k *ar, 161 u32 address, void *buffer, u32 length) 162 { 163 struct bmi_cmd cmd; 164 union bmi_resp resp; 165 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.read_mem); 166 u32 rxlen; 167 int ret; 168 169 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", 170 address, length); 171 172 if (ar->bmi.done_sent) { 173 ath10k_warn(ar, "command disallowed\n"); 174 return -EBUSY; 175 } 176 177 while (length) { 178 rxlen = min_t(u32, length, BMI_MAX_DATA_SIZE); 179 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); 183 184 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, 185 &resp, &rxlen); 186 if (ret) { 187 ath10k_warn(ar, "unable to read from the device (%d)\n", 188 ret); 189 return ret; 190 } 191 192 memcpy(buffer, resp.read_mem.payload, rxlen); 193 address += rxlen; 194 buffer += rxlen; 195 length -= rxlen; 196 } 197 198 return 0; 199 } 200 201 int ath10k_bmi_write_soc_reg(struct ath10k *ar, u32 address, u32 reg_val) 202 { 203 struct bmi_cmd cmd; 204 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.write_soc_reg); 205 int ret; 206 207 ath10k_dbg(ar, ATH10K_DBG_BMI, 208 "bmi write soc register 0x%08x val 0x%08x\n", 209 address, reg_val); 210 211 if (ar->bmi.done_sent) { 212 ath10k_warn(ar, "bmi write soc register command in progress\n"); 213 return -EBUSY; 214 } 215 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); 219 220 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); 221 if (ret) { 222 ath10k_warn(ar, "Unable to write soc register to device: %d\n", 223 ret); 224 return ret; 225 } 226 227 return 0; 228 } 229 230 int ath10k_bmi_read_soc_reg(struct ath10k *ar, u32 address, u32 *reg_val) 231 { 232 struct bmi_cmd cmd; 233 union bmi_resp resp; 234 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.read_soc_reg); 235 u32 resplen = sizeof(resp.read_soc_reg); 236 int ret; 237 238 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read soc register 0x%08x\n", 239 address); 240 241 if (ar->bmi.done_sent) { 242 ath10k_warn(ar, "bmi read soc register command in progress\n"); 243 return -EBUSY; 244 } 245 246 cmd.id = __cpu_to_le32(BMI_READ_SOC_REGISTER); 247 cmd.read_soc_reg.addr = __cpu_to_le32(address); 248 249 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); 250 if (ret) { 251 ath10k_warn(ar, "Unable to read soc register from device: %d\n", 252 ret); 253 return ret; 254 } 255 256 *reg_val = __le32_to_cpu(resp.read_soc_reg.value); 257 258 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi read soc register value 0x%08x\n", 259 *reg_val); 260 261 return 0; 262 } 263 264 int ath10k_bmi_write_memory(struct ath10k *ar, 265 u32 address, const void *buffer, u32 length) 266 { 267 struct bmi_cmd cmd; 268 u32 hdrlen = sizeof(cmd.id) + sizeof(cmd.write_mem); 269 u32 txlen; 270 int ret; 271 272 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", 273 address, length); 274 275 if (ar->bmi.done_sent) { 276 ath10k_warn(ar, "command disallowed\n"); 277 return -EBUSY; 278 } 279 280 while (length) { 281 txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen); 282 283 /* copy before roundup to avoid reading beyond buffer*/ 284 memcpy(cmd.write_mem.payload, buffer, txlen); 285 txlen = roundup(txlen, 4); 286 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); 290 291 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, 292 NULL, NULL); 293 if (ret) { 294 ath10k_warn(ar, "unable to write to the device (%d)\n", 295 ret); 296 return ret; 297 } 298 299 /* fixup roundup() so `length` zeroes out for last chunk */ 300 txlen = min(txlen, length); 301 302 address += txlen; 303 buffer += txlen; 304 length -= txlen; 305 } 306 307 return 0; 308 } 309 310 int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 param, u32 *result) 311 { 312 struct bmi_cmd cmd; 313 union bmi_resp resp; 314 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.execute); 315 u32 resplen = sizeof(resp.execute); 316 int ret; 317 318 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", 319 address, param); 320 321 if (ar->bmi.done_sent) { 322 ath10k_warn(ar, "command disallowed\n"); 323 return -EBUSY; 324 } 325 326 cmd.id = __cpu_to_le32(BMI_EXECUTE); 327 cmd.execute.addr = __cpu_to_le32(address); 328 cmd.execute.param = __cpu_to_le32(param); 329 330 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, &resp, &resplen); 331 if (ret) { 332 ath10k_warn(ar, "unable to read from the device\n"); 333 return ret; 334 } 335 336 if (resplen < sizeof(resp.execute)) { 337 ath10k_warn(ar, "invalid execute response length (%d)\n", 338 resplen); 339 return -EIO; 340 } 341 342 *result = __le32_to_cpu(resp.execute.result); 343 344 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi execute result 0x%x\n", *result); 345 346 return 0; 347 } 348 349 static int ath10k_bmi_lz_data_large(struct ath10k *ar, const void *buffer, u32 length) 350 { 351 struct bmi_cmd *cmd; 352 u32 hdrlen = sizeof(cmd->id) + sizeof(cmd->lz_data); 353 u32 txlen; 354 int ret; 355 size_t buf_len; 356 357 ath10k_dbg(ar, ATH10K_DBG_BMI, "large bmi lz data buffer 0x%pK length %d\n", 358 buffer, length); 359 360 if (ar->bmi.done_sent) { 361 ath10k_warn(ar, "command disallowed\n"); 362 return -EBUSY; 363 } 364 365 buf_len = sizeof(*cmd) + BMI_MAX_LARGE_DATA_SIZE - BMI_MAX_DATA_SIZE; 366 cmd = kzalloc(buf_len, GFP_KERNEL); 367 if (!cmd) 368 return -ENOMEM; 369 370 while (length) { 371 txlen = min(length, BMI_MAX_LARGE_DATA_SIZE - hdrlen); 372 373 WARN_ON_ONCE(txlen & 3); 374 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); 378 379 ret = ath10k_hif_exchange_bmi_msg(ar, cmd, hdrlen + txlen, 380 NULL, NULL); 381 if (ret) { 382 ath10k_warn(ar, "unable to write to the device\n"); 383 return ret; 384 } 385 386 buffer += txlen; 387 length -= txlen; 388 } 389 390 kfree(cmd); 391 392 return 0; 393 } 394 395 int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length) 396 { 397 struct bmi_cmd cmd; 398 u32 hdrlen = sizeof(cmd.id) + sizeof(cmd.lz_data); 399 u32 txlen; 400 int ret; 401 402 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz data buffer 0x%pK length %d\n", 403 buffer, length); 404 405 if (ar->bmi.done_sent) { 406 ath10k_warn(ar, "command disallowed\n"); 407 return -EBUSY; 408 } 409 410 while (length) { 411 txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen); 412 413 WARN_ON_ONCE(txlen & 3); 414 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); 418 419 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, hdrlen + txlen, 420 NULL, NULL); 421 if (ret) { 422 ath10k_warn(ar, "unable to write to the device\n"); 423 return ret; 424 } 425 426 buffer += txlen; 427 length -= txlen; 428 } 429 430 return 0; 431 } 432 433 int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address) 434 { 435 struct bmi_cmd cmd; 436 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start); 437 int ret; 438 439 ath10k_dbg(ar, ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", 440 address); 441 442 if (ar->bmi.done_sent) { 443 ath10k_warn(ar, "command disallowed\n"); 444 return -EBUSY; 445 } 446 447 cmd.id = __cpu_to_le32(BMI_LZ_STREAM_START); 448 cmd.lz_start.addr = __cpu_to_le32(address); 449 450 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); 451 if (ret) { 452 ath10k_warn(ar, "unable to Start LZ Stream to the device\n"); 453 return ret; 454 } 455 456 return 0; 457 } 458 459 int ath10k_bmi_fast_download(struct ath10k *ar, 460 u32 address, const void *buffer, u32 length) 461 { 462 u8 trailer[4] = {}; 463 u32 head_len = rounddown(length, 4); 464 u32 trailer_len = length - head_len; 465 int ret; 466 467 ath10k_dbg(ar, ATH10K_DBG_BMI, 468 "bmi fast download address 0x%x buffer 0x%pK length %d\n", 469 address, buffer, length); 470 471 ret = ath10k_bmi_lz_stream_start(ar, address); 472 if (ret) 473 return ret; 474 475 /* copy the last word into a zero padded buffer */ 476 if (trailer_len > 0) 477 memcpy(trailer, buffer + head_len, trailer_len); 478 479 if (ar->hw_params.bmi_large_size_download) 480 ret = ath10k_bmi_lz_data_large(ar, buffer, head_len); 481 else 482 ret = ath10k_bmi_lz_data(ar, buffer, head_len); 483 484 if (ret) 485 return ret; 486 487 if (trailer_len > 0) 488 ret = ath10k_bmi_lz_data(ar, trailer, 4); 489 490 if (ret != 0) 491 return ret; 492 493 /* 494 * Close compressed stream and open a new (fake) one. 495 * This serves mainly to flush Target caches. 496 */ 497 ret = ath10k_bmi_lz_stream_start(ar, 0x00); 498 499 return ret; 500 } 501 502 int ath10k_bmi_set_start(struct ath10k *ar, u32 address) 503 { 504 struct bmi_cmd cmd; 505 u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.set_app_start); 506 int ret; 507 508 if (ar->bmi.done_sent) { 509 ath10k_warn(ar, "bmi set start command disallowed\n"); 510 return -EBUSY; 511 } 512 513 cmd.id = __cpu_to_le32(BMI_SET_APP_START); 514 cmd.set_app_start.addr = __cpu_to_le32(address); 515 516 ret = ath10k_hif_exchange_bmi_msg(ar, &cmd, cmdlen, NULL, NULL); 517 if (ret) { 518 ath10k_warn(ar, "unable to set start to the device:%d\n", ret); 519 return ret; 520 } 521 522 return 0; 523 } 524