1 /* 2 * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. 3 * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for 6 * any purpose with or without fee is hereby granted, provided that the 7 * above copyright notice and this permission notice appear in all 8 * copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL 11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED 12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE 13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 17 * PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <linux/firmware.h> 21 #include "ol_if_athvar.h" 22 #include "qdf_time.h" 23 #include "targaddrs.h" 24 #include "ol_cfg.h" 25 #include "cds_api.h" 26 #include "wma_api.h" 27 #include "wma.h" 28 #include "bin_sig.h" 29 #include "i_ar6320v2_regtable.h" 30 #include "epping_main.h" 31 #ifdef HIF_PCI 32 #include "ce_reg.h" 33 #endif 34 #if defined(HIF_SDIO) 35 #include "if_sdio.h" 36 #include "regtable_sdio.h" 37 #endif 38 #if defined(HIF_USB) 39 #include "if_usb.h" 40 #include "regtable_usb.h" 41 #endif 42 #include "pld_common.h" 43 #include "hif_main.h" 44 45 #include "i_bmi.h" 46 #include "qwlan_version.h" 47 #include "wlan_policy_mgr_api.h" 48 #include "dbglog_host.h" 49 50 #ifdef FEATURE_SECURE_FIRMWARE 51 static struct hash_fw fw_hash; 52 #endif 53 54 static uint32_t refclk_speed_to_hz[] = { 55 48000000, /* SOC_REFCLK_48_MHZ */ 56 19200000, /* SOC_REFCLK_19_2_MHZ */ 57 24000000, /* SOC_REFCLK_24_MHZ */ 58 26000000, /* SOC_REFCLK_26_MHZ */ 59 37400000, /* SOC_REFCLK_37_4_MHZ */ 60 38400000, /* SOC_REFCLK_38_4_MHZ */ 61 40000000, /* SOC_REFCLK_40_MHZ */ 62 52000000, /* SOC_REFCLK_52_MHZ */ 63 }; 64 65 static int ol_target_coredump(void *inst, void *memory_block, 66 uint32_t block_len); 67 68 #ifdef FEATURE_SECURE_FIRMWARE ol_check_fw_hash(struct device * dev,const u8 * data,u32 fw_size,enum ATH_BIN_FILE file)69 static int ol_check_fw_hash(struct device *dev, const u8 *data, 70 u32 fw_size, enum ATH_BIN_FILE file) 71 { 72 u8 *hash = NULL; 73 u8 *fw_mem = NULL; 74 u8 digest[SHA256_DIGEST_SIZE]; 75 u8 temp[SHA256_DIGEST_SIZE] = { }; 76 int ret = 0; 77 78 switch (file) { 79 case ATH_BOARD_DATA_FILE: 80 hash = fw_hash.bdwlan; 81 break; 82 case ATH_OTP_FILE: 83 hash = fw_hash.otp; 84 break; 85 case ATH_FIRMWARE_FILE: 86 #ifdef QCA_WIFI_FTM 87 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { 88 hash = fw_hash.utf; 89 break; 90 } 91 #endif 92 hash = fw_hash.qwlan; 93 default: 94 break; 95 } 96 97 if (!hash) { 98 BMI_INFO("No entry for file:%d Download FW in non-secure mode", 99 file); 100 goto end; 101 } 102 103 if (qdf_mem_cmp(hash, temp, SHA256_DIGEST_SIZE)) { 104 BMI_INFO("Download FW in non-secure mode:%d", file); 105 goto end; 106 } 107 108 fw_mem = pld_get_fw_ptr(dev); 109 if (!fw_mem || (fw_size > MAX_FIRMWARE_SIZE)) { 110 BMI_ERR("No Memory to copy FW data"); 111 ret = -1; 112 goto end; 113 } 114 qdf_mem_copy(fw_mem, data, fw_size); 115 116 ret = pld_get_sha_hash(dev, fw_mem, fw_size, "sha256", digest); 117 118 if (ret) { 119 BMI_ERR("Sha256 Hash computation failed err:%d", ret); 120 goto end; 121 } 122 123 if (qdf_mem_cmp(hash, digest, SHA256_DIGEST_SIZE)) { 124 BMI_ERR("Hash Mismatch"); 125 qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, 126 digest, SHA256_DIGEST_SIZE); 127 qdf_trace_hex_dump(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_FATAL, 128 hash, SHA256_DIGEST_SIZE); 129 ret = QDF_STATUS_E_FAILURE; 130 } 131 end: 132 return ret; 133 } 134 #endif 135 136 /** 137 * ol_board_id_to_filename() - Auto BDF board_id to filename conversion 138 * @old_name: name of the default board data file 139 * @board_id: board ID 140 * 141 * The API return board filename based on the board_id and chip_id. 142 * eg: input = "bdwlan30.bin", board_id = 0x01, board_file = "bdwlan30.b01" 143 * Return: The buffer with the formatted board filename. 144 */ ol_board_id_to_filename(const char * old_name,uint16_t board_id)145 static char *ol_board_id_to_filename(const char *old_name, 146 uint16_t board_id) 147 { 148 int name_len; 149 char *new_name; 150 151 name_len = strlen(old_name); 152 new_name = qdf_mem_malloc(name_len + 1); 153 154 if (!new_name) 155 goto out; 156 157 if (board_id > 0xFF) 158 board_id = 0x0; 159 160 qdf_mem_copy(new_name, old_name, name_len); 161 snprintf(&new_name[name_len - 2], 3, "%.2x", board_id); 162 out: 163 return new_name; 164 } 165 166 #ifdef QCA_SIGNED_SPLIT_BINARY_SUPPORT 167 #define SIGNED_SPLIT_BINARY_VALUE true 168 #else 169 #define SIGNED_SPLIT_BINARY_VALUE false 170 #endif 171 172 static int __ol_transfer_bin_file(struct ol_context * ol_ctx,enum ATH_BIN_FILE file,uint32_t address,bool compressed)173 __ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file, 174 uint32_t address, bool compressed) 175 { 176 struct hif_opaque_softc *scn = ol_ctx->scn; 177 int status = 0; 178 const char *filename; 179 const struct firmware *fw_entry; 180 uint32_t fw_entry_size; 181 uint8_t *temp_eeprom; 182 uint32_t board_data_size; 183 bool bin_sign = false; 184 int bin_off, bin_len; 185 SIGN_HEADER_T *sign_header; 186 struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); 187 uint32_t target_type = tgt_info->target_type; 188 struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx); 189 qdf_device_t qdf_dev = ol_ctx->qdf_dev; 190 int i; 191 192 /* 193 * If there is no board data file bases on board id, the default 194 * board data file should be used. 195 * For factory mode, the sequence for file selection should be 196 * utfbd.board_id -> utfbd.bin -> bd.board_id -> bd.bin. So we 197 * need to cache 4 file names. 198 */ 199 uint32_t bd_files = 1; 200 char *bd_id_filename[2] = {NULL, NULL}; 201 const char *bd_filename[2] = {NULL, NULL}; 202 203 switch (file) { 204 default: 205 BMI_ERR("%s: Unknown file type", __func__); 206 return -EINVAL; 207 case ATH_OTP_FILE: 208 filename = bmi_ctx->fw_files.otp_data; 209 if (SIGNED_SPLIT_BINARY_VALUE) 210 bin_sign = true; 211 212 break; 213 case ATH_FIRMWARE_FILE: 214 if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) { 215 filename = bmi_ctx->fw_files.epping_file; 216 BMI_INFO("%s: Loading epping firmware file %s", 217 __func__, filename); 218 break; 219 } 220 #ifdef QCA_WIFI_FTM 221 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { 222 filename = bmi_ctx->fw_files.utf_file; 223 if (SIGNED_SPLIT_BINARY_VALUE) 224 bin_sign = true; 225 BMI_INFO("%s: Loading firmware file %s", 226 __func__, filename); 227 break; 228 } 229 #endif 230 if (cds_get_conparam() == QDF_GLOBAL_IBSS_MODE && 231 (bmi_ctx->fw_files.ibss_image_file[0] != '\0')) { 232 filename = bmi_ctx->fw_files.ibss_image_file; 233 } else { 234 filename = bmi_ctx->fw_files.image_file; 235 } 236 237 if (SIGNED_SPLIT_BINARY_VALUE) 238 bin_sign = true; 239 break; 240 case ATH_PATCH_FILE: 241 BMI_INFO("%s: no Patch file defined", __func__); 242 return 0; 243 case ATH_BOARD_DATA_FILE: 244 filename = bmi_ctx->fw_files.board_data; 245 #ifdef QCA_WIFI_FTM 246 if (cds_get_conparam() == QDF_GLOBAL_FTM_MODE) { 247 filename = bmi_ctx->fw_files.utf_board_data; 248 if (SIGNED_SPLIT_BINARY_VALUE) 249 bin_sign = true; 250 251 BMI_INFO("%s: Loading board data file %s", 252 __func__, filename); 253 254 /* 255 * In FTM mode, if utf files do not exit. 256 * bdwlan should be used. 257 */ 258 bd_files = 2; 259 } 260 #endif /* QCA_WIFI_FTM */ 261 if (SIGNED_SPLIT_BINARY_VALUE) 262 bin_sign = false; 263 264 bd_filename[0] = filename; 265 266 /* 267 * For factory mode, we should cache 2 group of file names. 268 * For mission mode, bd_files==1, only one group of file names. 269 */ 270 bd_filename[bd_files - 1] = 271 bmi_ctx->fw_files.board_data; 272 for (i = 0; i < bd_files; i++) { 273 bd_id_filename[i] = 274 ol_board_id_to_filename(bd_filename[i], 275 bmi_ctx->board_id); 276 if (bd_id_filename[i]) { 277 BMI_INFO("%s: board data file is %s", 278 __func__, bd_id_filename[i]); 279 } else { 280 BMI_ERR("%s: Fail to allocate board filename", 281 __func__); 282 } 283 } 284 break; 285 case ATH_SETUP_FILE: 286 if (cds_get_conparam() != QDF_GLOBAL_FTM_MODE && 287 !QDF_IS_EPPING_ENABLED(cds_get_conparam())) { 288 filename = bmi_ctx->fw_files.setup_file; 289 if (filename[0] == 0) { 290 BMI_INFO("%s: no Setup file defined", __func__); 291 return -EPERM; 292 } 293 294 if (SIGNED_SPLIT_BINARY_VALUE) 295 bin_sign = true; 296 297 BMI_INFO("%s: Loading setup file %s", 298 __func__, filename); 299 } else { 300 BMI_INFO("%s: no Setup file needed", __func__); 301 return -EPERM; 302 } 303 break; 304 } 305 306 /* For FTM mode. bd.bin is used if there is no utf.bin */ 307 if (file == ATH_BOARD_DATA_FILE) { 308 for (i = 0; i < bd_files; i++) { 309 if (bd_id_filename[i]) { 310 BMI_DBG("%s: Trying to load %s", 311 __func__, bd_id_filename[i]); 312 status = request_firmware(&fw_entry, 313 bd_id_filename[i], 314 qdf_dev->dev); 315 if (!status) 316 break; 317 BMI_ERR("%s: Failed to get %s:%d", 318 __func__, bd_id_filename[i], 319 status); 320 } 321 322 /* bd.board_id not exits, using bd.bin */ 323 BMI_DBG("%s: Trying to load default %s", 324 __func__, bd_filename[i]); 325 status = request_firmware(&fw_entry, bd_filename[i], 326 qdf_dev->dev); 327 if (!status) 328 break; 329 BMI_ERR("%s: Failed to get default %s:%d", 330 __func__, bd_filename[i], status); 331 } 332 } else { 333 status = request_firmware(&fw_entry, filename, qdf_dev->dev); 334 } 335 336 if (status) { 337 BMI_ERR("%s: Failed to get %s", __func__, filename); 338 status = -ENOENT; 339 goto release_fw; 340 } 341 342 if (!fw_entry || !fw_entry->data) { 343 BMI_ERR("Invalid fw_entries"); 344 status = -ENOENT; 345 goto release_fw; 346 } 347 348 fw_entry_size = fw_entry->size; 349 temp_eeprom = NULL; 350 351 #ifdef FEATURE_SECURE_FIRMWARE 352 if (ol_check_fw_hash(qdf_dev->dev, fw_entry->data, 353 fw_entry_size, file)) { 354 BMI_ERR("Hash Check failed for file:%s", filename); 355 status = -EINVAL; 356 goto end; 357 } 358 #endif 359 360 if (file == ATH_BOARD_DATA_FILE) { 361 uint32_t board_ext_address = 0; 362 int32_t board_ext_data_size; 363 364 temp_eeprom = qdf_mem_malloc(fw_entry_size); 365 if (!temp_eeprom) { 366 status = -ENOMEM; 367 goto release_fw; 368 } 369 370 qdf_mem_copy(temp_eeprom, (uint8_t *) fw_entry->data, 371 fw_entry_size); 372 373 switch (target_type) { 374 case TARGET_TYPE_AR6004: 375 board_data_size = AR6004_BOARD_DATA_SZ; 376 board_ext_data_size = AR6004_BOARD_EXT_DATA_SZ; 377 break; 378 case TARGET_TYPE_AR9888: 379 board_data_size = AR9888_BOARD_DATA_SZ; 380 board_ext_data_size = AR9888_BOARD_EXT_DATA_SZ; 381 break; 382 default: 383 board_data_size = 0; 384 board_ext_data_size = 0; 385 break; 386 } 387 388 /* Determine where in Target RAM to write Board Data */ 389 bmi_read_memory(HOST_INTEREST_ITEM_ADDRESS(target_type, 390 hi_board_ext_data), 391 (uint8_t *) &board_ext_address, 4, ol_ctx); 392 BMI_INFO("Board extended Data download address: 0x%x", 393 board_ext_address); 394 395 /* Check whether the target has allocated memory for extended 396 * board data and file contains extended board data 397 */ 398 399 if ((board_ext_address) 400 && (fw_entry_size == 401 (board_data_size + board_ext_data_size))) { 402 uint32_t param; 403 404 status = bmi_write_memory(board_ext_address, 405 (uint8_t *)(temp_eeprom + 406 board_data_size), 407 board_ext_data_size, ol_ctx); 408 409 if (status) 410 goto end; 411 412 /* Record extended board Data initialized */ 413 param = (board_ext_data_size << 16) | 1; 414 bmi_write_memory( 415 HOST_INTEREST_ITEM_ADDRESS(target_type, 416 hi_board_ext_data_config), 417 (uint8_t *)¶m, 4, ol_ctx); 418 419 fw_entry_size = board_data_size; 420 } 421 } 422 423 if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) { 424 uint32_t chip_id; 425 426 if (fw_entry_size < sizeof(SIGN_HEADER_T)) { 427 BMI_ERR("Invalid binary size %d", fw_entry_size); 428 status = -EINVAL; 429 goto end; 430 } 431 432 sign_header = (SIGN_HEADER_T *) fw_entry->data; 433 chip_id = cpu_to_le32(sign_header->product_id); 434 if (sign_header->magic_num == SIGN_HEADER_MAGIC 435 && (chip_id == AR6320_REV1_1_VERSION 436 || chip_id == AR6320_REV1_3_VERSION 437 || chip_id == AR6320_REV2_1_VERSION)) { 438 439 bin_off = sizeof(SIGN_HEADER_T); 440 status = bmi_sign_stream_start(address, 441 (uint8_t *)fw_entry->data, 442 bin_off, ol_ctx); 443 if (status) { 444 BMI_ERR("unable to start sign stream"); 445 status = -EINVAL; 446 goto end; 447 } 448 449 bin_len = sign_header->rampatch_len - bin_off; 450 if (bin_len <= 0 || bin_len > fw_entry_size - bin_off) { 451 BMI_ERR("Invalid sign header"); 452 status = -EINVAL; 453 goto end; 454 } 455 } else { 456 bin_sign = false; 457 bin_off = 0; 458 bin_len = fw_entry_size; 459 } 460 } else { 461 bin_len = fw_entry_size; 462 bin_off = 0; 463 } 464 465 if (compressed) { 466 status = bmi_fast_download(address, 467 (uint8_t *) fw_entry->data + bin_off, 468 bin_len, ol_ctx); 469 } else { 470 if (file == ATH_BOARD_DATA_FILE && fw_entry->data) { 471 status = bmi_write_memory(address, 472 (uint8_t *) temp_eeprom, 473 fw_entry_size, ol_ctx); 474 } else { 475 status = bmi_write_memory(address, 476 (uint8_t *) fw_entry->data 477 + bin_off, bin_len, ol_ctx); 478 } 479 } 480 481 if (bin_sign && SIGNED_SPLIT_BINARY_VALUE) { 482 bin_off += bin_len; 483 bin_len = sign_header->total_len - sign_header->rampatch_len; 484 485 if (bin_len > 0 && bin_len <= fw_entry_size - bin_off) { 486 status = bmi_sign_stream_start(0, 487 (uint8_t *)fw_entry->data + 488 bin_off, bin_len, ol_ctx); 489 if (status) 490 BMI_ERR("sign stream error"); 491 } 492 } 493 494 end: 495 if (temp_eeprom) 496 qdf_mem_free(temp_eeprom); 497 498 release_fw: 499 if (fw_entry) 500 release_firmware(fw_entry); 501 502 for (i = 0; i < bd_files; i++) { 503 if (bd_id_filename[i]) { 504 qdf_mem_free(bd_id_filename[i]); 505 bd_id_filename[i] = NULL; 506 } 507 } 508 509 if (status) 510 BMI_ERR("%s, BMI operation failed: %d", __func__, __LINE__); 511 else 512 BMI_INFO("transferring file: %s size %d bytes done!", 513 (filename) ? filename : " ", fw_entry_size); 514 return status; 515 } 516 517 static int ol_transfer_bin_file(struct ol_context * ol_ctx,enum ATH_BIN_FILE file,uint32_t address,bool compressed)518 ol_transfer_bin_file(struct ol_context *ol_ctx, enum ATH_BIN_FILE file, 519 uint32_t address, bool compressed) 520 { 521 #define MAX_WAKELOCK_FOR_FW_DOWNLOAD 1000 //1s 522 int ret; 523 524 qdf_wake_lock_timeout_acquire(&ol_ctx->fw_dl_wakelock, 525 MAX_WAKELOCK_FOR_FW_DOWNLOAD); 526 527 ret = __ol_transfer_bin_file(ol_ctx, file, address, compressed); 528 529 qdf_wake_lock_release(&ol_ctx->fw_dl_wakelock, 0); 530 531 return ret; 532 } 533 534 /** 535 * struct ramdump_info: Structure to hold ramdump information 536 * @base: Base address for Ramdump collection 537 * @size: Size of the dump 538 * 539 * Ramdump information. 540 */ 541 struct ramdump_info { 542 void *base; 543 unsigned long size; 544 }; 545 546 /* 547 * if have platform driver support, reinit will be called by CNSS. 548 * recovery flag will be cleaned and CRASHED indication will be sent 549 * to user space by reinit function. If not support, clean recovery 550 * flag and send CRASHED indication in CLD driver. 551 */ ol_check_clean_recovery_flag(struct ol_context * ol_ctx)552 static inline void ol_check_clean_recovery_flag(struct ol_context *ol_ctx) 553 { 554 qdf_device_t qdf_dev = ol_ctx->qdf_dev; 555 556 if (!pld_have_platform_driver_support(qdf_dev->dev)) { 557 if (ol_ctx->fw_crashed_cb) 558 ol_ctx->fw_crashed_cb(); 559 } 560 } 561 562 #if !defined(QCA_WIFI_3_0) ol_get_ramdump_mem(struct device * dev,struct ramdump_info * info)563 static inline void ol_get_ramdump_mem(struct device *dev, 564 struct ramdump_info *info) 565 { 566 info->base = pld_get_virt_ramdump_mem(dev, &info->size); 567 } 568 ol_release_ramdump_mem(struct device * dev,struct ramdump_info * info)569 static inline void ol_release_ramdump_mem(struct device *dev, 570 struct ramdump_info *info) 571 { 572 pld_release_virt_ramdump_mem(dev, info->base); 573 } 574 #else ol_get_ramdump_mem(struct device * dev,struct ramdump_info * info)575 static inline void ol_get_ramdump_mem(struct device *dev, 576 struct ramdump_info *info) { } ol_release_ramdump_mem(struct device * dev,struct ramdump_info * info)577 static inline void ol_release_ramdump_mem(struct device *dev, 578 struct ramdump_info *info) { } 579 #endif 580 ol_copy_ramdump(struct hif_opaque_softc * scn)581 int ol_copy_ramdump(struct hif_opaque_softc *scn) 582 { 583 int ret = -1; 584 struct ramdump_info *info; 585 qdf_device_t qdf_dev = cds_get_context(QDF_MODULE_ID_QDF_DEVICE); 586 587 if (!qdf_dev) 588 return -EINVAL; 589 590 if (pld_is_fw_dump_skipped(qdf_dev->dev)) { 591 BMI_INFO("%s ssr enabled, skip ramdump", __func__); 592 return 0; 593 } 594 info = qdf_mem_malloc(sizeof(struct ramdump_info)); 595 if (!info) 596 return -ENOMEM; 597 598 ol_get_ramdump_mem(qdf_dev->dev, info); 599 600 if (!info->base || !info->size) { 601 BMI_ERR("%s:ramdump collection fail", __func__); 602 qdf_mem_free(info); 603 return -EACCES; 604 } 605 606 ret = ol_target_coredump(scn, info->base, info->size); 607 608 ol_release_ramdump_mem(qdf_dev->dev, info); 609 qdf_mem_free(info); 610 return ret; 611 } 612 __ramdump_work_handler(void * data)613 static void __ramdump_work_handler(void *data) 614 { 615 int ret; 616 uint32_t host_interest_address; 617 uint32_t dram_dump_values[4]; 618 uint32_t target_type; 619 struct hif_target_info *tgt_info; 620 struct ol_context *ol_ctx = data; 621 struct hif_opaque_softc *ramdump_scn = ol_ctx->scn; 622 qdf_device_t qdf_dev = ol_ctx->qdf_dev; 623 struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); 624 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 625 626 if (!ramdump_scn) { 627 BMI_ERR("%s:Ramdump_scn is null:", __func__); 628 goto out_fail; 629 } 630 tgt_info = hif_get_target_info_handle(ramdump_scn); 631 target_type = tgt_info->target_type; 632 #ifdef WLAN_DEBUG 633 ret = hif_check_soc_status(ramdump_scn); 634 if (ret) 635 goto out_fail; 636 637 ret = hif_dump_registers(ramdump_scn); 638 if (ret) 639 goto out_fail; 640 641 #endif 642 643 if (hif_diag_read_mem(ramdump_scn, 644 hif_hia_item_address(target_type, 645 offsetof(struct host_interest_s, hi_failure_state)), 646 (uint8_t *)&host_interest_address, 647 sizeof(uint32_t)) != QDF_STATUS_SUCCESS) { 648 BMI_ERR("HifDiagReadiMem FW Dump Area Pointer failed!"); 649 ol_copy_ramdump(ramdump_scn); 650 pld_device_crashed(qdf_dev->dev); 651 ol_check_clean_recovery_flag(ol_ctx); 652 653 return; 654 } 655 656 BMI_ERR("Host interest item address: 0x%08x", host_interest_address); 657 658 if (hif_diag_read_mem(ramdump_scn, host_interest_address, 659 (uint8_t *) &dram_dump_values[0], 660 4 * sizeof(uint32_t)) != QDF_STATUS_SUCCESS) { 661 BMI_ERR("HifDiagReadiMem FW Dump Area failed!"); 662 goto out_fail; 663 } 664 BMI_ERR("FW Assertion at PC: 0x%08x BadVA: 0x%08x TargetID: 0x%08x", 665 dram_dump_values[2], dram_dump_values[3], dram_dump_values[0]); 666 667 if (ol_copy_ramdump(ramdump_scn)) 668 goto out_fail; 669 670 BMI_ERR("%s: RAM dump collecting completed!", __func__); 671 qdf_event_set(&wma->recovery_event); 672 673 /* 674 * if unloading is in progress, then skip SSR, 675 * otherwise notify SSR framework the target has crashed. 676 */ 677 if (cds_is_load_or_unload_in_progress()) 678 cds_set_recovery_in_progress(false); 679 else { 680 pld_device_crashed(qdf_dev->dev); 681 ol_check_clean_recovery_flag(ol_ctx); 682 } 683 return; 684 685 out_fail: 686 qdf_event_set(&wma->recovery_event); 687 /* Silent SSR on dump failure */ 688 if (ini_cfg->enable_self_recovery) 689 pld_device_self_recovery(qdf_dev->dev, 690 PLD_REASON_DEFAULT); 691 else 692 pld_device_crashed(qdf_dev->dev); 693 694 ol_check_clean_recovery_flag(ol_ctx); 695 } 696 ramdump_work_handler(void * data)697 void ramdump_work_handler(void *data) 698 { 699 struct qdf_op_sync *op_sync; 700 701 if (qdf_op_protect(&op_sync)) 702 return; 703 704 __ramdump_work_handler(data); 705 706 qdf_op_unprotect(op_sync); 707 } 708 fw_indication_work_handler(void * data)709 void fw_indication_work_handler(void *data) 710 { 711 struct ol_context *ol_ctx = data; 712 qdf_device_t qdf_dev = ol_ctx->qdf_dev; 713 714 pld_device_self_recovery(qdf_dev->dev, 715 PLD_REASON_DEFAULT); 716 717 ol_check_clean_recovery_flag(ol_ctx); 718 } 719 ol_target_failure(void * instance,QDF_STATUS status)720 void ol_target_failure(void *instance, QDF_STATUS status) 721 { 722 struct ol_context *ol_ctx = instance; 723 struct hif_opaque_softc *scn = ol_ctx->scn; 724 tp_wma_handle wma = cds_get_context(QDF_MODULE_ID_WMA); 725 struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); 726 qdf_device_t qdf_dev = ol_ctx->qdf_dev; 727 int ret; 728 bool skip_recovering_check = false; 729 enum hif_target_status target_status = hif_get_target_status(scn); 730 731 if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SNOC) { 732 BMI_ERR("SNOC doesn't support this code path!"); 733 return; 734 } 735 736 /* If Host driver trigger target failure, skip recovering check */ 737 if (cds_is_target_asserting()) 738 skip_recovering_check = true; 739 740 if (TARGET_STATUS_RESET == target_status) { 741 BMI_ERR("Target is already asserted, ignore!"); 742 goto out; 743 } 744 745 hif_set_target_status(scn, TARGET_STATUS_RESET); 746 747 if (hif_get_bus_type(scn) == QDF_BUS_TYPE_USB) { 748 if (status == QDF_STATUS_E_USB_ERROR) 749 hif_ramdump_handler(scn); 750 goto out; 751 } 752 753 if (!skip_recovering_check && cds_is_driver_recovering()) { 754 BMI_ERR("%s: Recovery in progress, ignore!\n", __func__); 755 return; 756 } 757 758 if (cds_is_driver_in_bad_state()) { 759 BMI_ERR("%s: Driver in bad state, ignore!\n", __func__); 760 goto out; 761 } 762 763 if (cds_is_load_or_unload_in_progress()) { 764 BMI_ERR("%s: Loading/Unloading is in progress, ignore!", 765 __func__); 766 goto out; 767 } 768 cds_set_target_ready(false); 769 cds_set_recovery_in_progress(true); 770 771 ret = hif_check_fw_reg(scn); 772 if (0 == ret) { 773 if (ini_cfg->enable_self_recovery) { 774 qdf_sched_work(0, &ol_ctx->fw_indication_work); 775 goto out; 776 } 777 } else if (-1 == ret) { 778 goto out; 779 } 780 781 BMI_ERR("XXX TARGET ASSERTED XXX"); 782 783 cds_svc_fw_shutdown_ind(qdf_dev->dev); 784 /* Collect the RAM dump through a workqueue */ 785 if (ini_cfg->enable_ramdump_collection) { 786 qdf_sched_work(0, &ol_ctx->ramdump_work); 787 } else { 788 pr_debug("%s: athdiag read for target reg\n", __func__); 789 qdf_event_set(&wma->recovery_event); 790 } 791 792 return; 793 out: 794 qdf_event_set(&wma->recovery_event); 795 return; 796 } 797 798 #ifdef CONFIG_DISABLE_CDC_MAX_PERF_WAR ol_disable_cdc_max_perf(struct ol_context * ol_ctx)799 static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx) 800 { 801 uint32_t param; 802 struct hif_opaque_softc *scn = ol_ctx->scn; 803 struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); 804 uint32_t target_type = tgt_info->target_type; 805 806 /* set the firmware to disable CDC max perf WAR */ 807 if (bmi_read_memory(hif_hia_item_address(target_type, 808 offsetof(struct host_interest_s, hi_option_flag2)), 809 (uint8_t *) ¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 810 BMI_ERR("BMI READ for setting cdc max perf failed"); 811 return QDF_STATUS_E_FAILURE; 812 } 813 814 param |= HI_OPTION_DISABLE_CDC_MAX_PERF_WAR; 815 if (bmi_write_memory( 816 hif_hia_item_address(target_type, 817 offsetof(struct host_interest_s, hi_option_flag2)), 818 (uint8_t *)¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 819 BMI_ERR("setting cdc max perf failed"); 820 return QDF_STATUS_E_FAILURE; 821 } 822 823 return QDF_STATUS_SUCCESS; 824 } 825 826 #else ol_disable_cdc_max_perf(struct ol_context * ol_ctx)827 static QDF_STATUS ol_disable_cdc_max_perf(struct ol_context *ol_ctx) 828 { 829 return QDF_STATUS_SUCCESS; 830 } 831 832 #endif 833 834 #ifdef WLAN_FEATURE_LPSS ol_set_lpass_support(struct ol_context * ol_ctx)835 static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx) 836 { 837 uint32_t param; 838 struct hif_opaque_softc *scn = ol_ctx->scn; 839 struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); 840 struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); 841 uint32_t target_type = tgt_info->target_type; 842 843 if (ini_cfg->enable_lpass_support) { 844 if (bmi_read_memory(hif_hia_item_address(target_type, 845 offsetof(struct host_interest_s, hi_option_flag2)), 846 (uint8_t *) ¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 847 BMI_ERR("BMI READ:Setting LPASS Support failed"); 848 return QDF_STATUS_E_FAILURE; 849 } 850 851 param |= HI_OPTION_DBUART_SUPPORT; 852 if (bmi_write_memory( 853 hif_hia_item_address(target_type, 854 offsetof(struct host_interest_s, hi_option_flag2)), 855 (uint8_t *)¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 856 BMI_ERR("BMI_READ for setting LPASS Support fail"); 857 return QDF_STATUS_E_FAILURE; 858 } 859 } 860 861 return QDF_STATUS_SUCCESS; 862 } 863 864 #else ol_set_lpass_support(struct ol_context * ol_ctx)865 static QDF_STATUS ol_set_lpass_support(struct ol_context *ol_ctx) 866 { 867 return QDF_STATUS_SUCCESS; 868 } 869 870 #endif 871 872 ol_configure_target(struct ol_context * ol_ctx)873 QDF_STATUS ol_configure_target(struct ol_context *ol_ctx) 874 { 875 uint32_t param; 876 struct pld_platform_cap cap = {0}; 877 int ret; 878 struct hif_opaque_softc *scn = ol_ctx->scn; 879 struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); 880 uint32_t target_type = tgt_info->target_type; 881 qdf_device_t qdf_dev = ol_ctx->qdf_dev; 882 883 /* Tell target which HTC version it is used */ 884 param = HTC_PROTOCOL_VERSION; 885 if (bmi_write_memory( 886 hif_hia_item_address(target_type, 887 offsetof(struct host_interest_s, hi_app_host_interest)), 888 (uint8_t *) ¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 889 BMI_ERR("bmi_write_memory for htc version failed"); 890 return QDF_STATUS_E_FAILURE; 891 } 892 893 /* set the firmware mode to STA/IBSS/AP */ 894 { 895 if (bmi_read_memory(hif_hia_item_address(target_type, 896 offsetof(struct host_interest_s, hi_option_flag)), 897 (uint8_t *)¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 898 BMI_ERR("bmi_read_memory for setting fwmode failed"); 899 return QDF_STATUS_E_FAILURE; 900 } 901 902 /* TODO following parameters need to be re-visited. */ 903 param |= (1 << HI_OPTION_NUM_DEV_SHIFT); /* num_device */ 904 /* Firmware mode ?? */ 905 param |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT); 906 /* mac_addr_method */ 907 param |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT); 908 /* firmware_bridge */ 909 param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT); 910 /* fwsubmode */ 911 param |= (0 << HI_OPTION_FW_SUBMODE_SHIFT); 912 913 BMI_INFO("NUM_DEV=%d FWMODE=0x%x FWSUBMODE=0x%x FWBR_BUF %d", 914 1, HI_OPTION_FW_MODE_AP, 0, 0); 915 916 if (bmi_write_memory( 917 hif_hia_item_address(target_type, 918 offsetof(struct host_interest_s, hi_option_flag)), 919 (uint8_t *)¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 920 BMI_ERR("BMI WRITE for setting fwmode failed"); 921 return QDF_STATUS_E_FAILURE; 922 } 923 } 924 if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) { 925 if (ol_disable_cdc_max_perf(ol_ctx)) 926 return QDF_STATUS_E_FAILURE; 927 928 qdf_mem_zero(&cap, sizeof(cap)); 929 930 ret = pld_get_platform_cap(qdf_dev->dev, &cap); 931 if (ret) 932 BMI_ERR("platform capability info not available"); 933 934 if (!ret && cap.cap_flag & PLD_HAS_EXTERNAL_SWREG) { 935 if (bmi_read_memory(hif_hia_item_address(target_type, 936 offsetof(struct host_interest_s, 937 hi_option_flag2)), 938 (uint8_t *)¶m, 4, ol_ctx) != 939 QDF_STATUS_SUCCESS) { 940 BMI_ERR("BMI READ failed for external SWREG"); 941 return QDF_STATUS_E_FAILURE; 942 } 943 944 param |= HI_OPTION_USE_EXT_LDO; 945 if (bmi_write_memory( 946 hif_hia_item_address(target_type, 947 offsetof(struct host_interest_s, 948 hi_option_flag2)), 949 (uint8_t *)¶m, 4, ol_ctx) != 950 QDF_STATUS_SUCCESS) { 951 BMI_ERR("BMI WRITE failed for external SWREG"); 952 return QDF_STATUS_E_FAILURE; 953 } 954 } 955 956 if (ol_set_lpass_support(ol_ctx)) 957 return QDF_STATUS_E_FAILURE; 958 } 959 960 /* If host is running on a BE CPU, set the host interest area */ 961 { 962 #ifdef BIG_ENDIAN_HOST 963 param = 1; 964 #else 965 param = 0; 966 #endif 967 if (bmi_write_memory( 968 hif_hia_item_address(target_type, 969 offsetof(struct host_interest_s, hi_be)), 970 (uint8_t *) ¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 971 BMI_ERR("setting host CPU BE mode failed"); 972 return QDF_STATUS_E_FAILURE; 973 } 974 } 975 976 /* FW descriptor/Data swap flags */ 977 param = 0; 978 if (bmi_write_memory( 979 hif_hia_item_address(target_type, 980 offsetof(struct host_interest_s, hi_fw_swap)), 981 (uint8_t *) ¶m, 4, ol_ctx) != QDF_STATUS_SUCCESS) { 982 BMI_ERR("BMI WRITE failed setting FW data/desc swap flags"); 983 return QDF_STATUS_E_FAILURE; 984 } 985 986 return QDF_STATUS_SUCCESS; 987 } 988 989 static int ol_check_dataset_patch(struct hif_opaque_softc * scn,uint32_t * address)990 ol_check_dataset_patch(struct hif_opaque_softc *scn, uint32_t *address) 991 { 992 /* Check if patch file needed for this target type/version. */ 993 return 0; 994 } 995 ol_fw_populate_clk_settings(enum a_refclk_speed_t refclk,struct cmnos_clock_s * clock_s)996 static QDF_STATUS ol_fw_populate_clk_settings(enum a_refclk_speed_t refclk, 997 struct cmnos_clock_s *clock_s) 998 { 999 if (!clock_s) 1000 return QDF_STATUS_E_FAILURE; 1001 1002 switch (refclk) { 1003 case SOC_REFCLK_48_MHZ: 1004 clock_s->wlan_pll.div = 0xE; 1005 clock_s->wlan_pll.rnfrac = 0x2AAA8; 1006 clock_s->pll_settling_time = 2400; 1007 break; 1008 case SOC_REFCLK_19_2_MHZ: 1009 clock_s->wlan_pll.div = 0x24; 1010 clock_s->wlan_pll.rnfrac = 0x2AAA8; 1011 clock_s->pll_settling_time = 960; 1012 break; 1013 case SOC_REFCLK_24_MHZ: 1014 clock_s->wlan_pll.div = 0x1D; 1015 clock_s->wlan_pll.rnfrac = 0x15551; 1016 clock_s->pll_settling_time = 1200; 1017 break; 1018 case SOC_REFCLK_26_MHZ: 1019 clock_s->wlan_pll.div = 0x1B; 1020 clock_s->wlan_pll.rnfrac = 0x4EC4; 1021 clock_s->pll_settling_time = 1300; 1022 break; 1023 case SOC_REFCLK_37_4_MHZ: 1024 clock_s->wlan_pll.div = 0x12; 1025 clock_s->wlan_pll.rnfrac = 0x34B49; 1026 clock_s->pll_settling_time = 1870; 1027 break; 1028 case SOC_REFCLK_38_4_MHZ: 1029 clock_s->wlan_pll.div = 0x12; 1030 clock_s->wlan_pll.rnfrac = 0x15551; 1031 clock_s->pll_settling_time = 1920; 1032 break; 1033 case SOC_REFCLK_40_MHZ: 1034 clock_s->wlan_pll.div = 0x11; 1035 clock_s->wlan_pll.rnfrac = 0x26665; 1036 clock_s->pll_settling_time = 2000; 1037 break; 1038 case SOC_REFCLK_52_MHZ: 1039 clock_s->wlan_pll.div = 0x1B; 1040 clock_s->wlan_pll.rnfrac = 0x4EC4; 1041 clock_s->pll_settling_time = 2600; 1042 break; 1043 case SOC_REFCLK_UNKNOWN: 1044 clock_s->wlan_pll.refdiv = 0; 1045 clock_s->wlan_pll.div = 0; 1046 clock_s->wlan_pll.rnfrac = 0; 1047 clock_s->wlan_pll.outdiv = 0; 1048 clock_s->pll_settling_time = 1024; 1049 clock_s->refclk_hz = 0; 1050 fallthrough; 1051 default: 1052 return QDF_STATUS_E_FAILURE; 1053 } 1054 1055 clock_s->refclk_hz = refclk_speed_to_hz[refclk]; 1056 clock_s->wlan_pll.refdiv = 0; 1057 clock_s->wlan_pll.outdiv = 1; 1058 1059 return QDF_STATUS_SUCCESS; 1060 } 1061 ol_patch_pll_switch(struct ol_context * ol_ctx)1062 static QDF_STATUS ol_patch_pll_switch(struct ol_context *ol_ctx) 1063 { 1064 struct hif_opaque_softc *hif = ol_ctx->scn; 1065 QDF_STATUS status = QDF_STATUS_SUCCESS; 1066 uint32_t addr = 0; 1067 uint32_t reg_val = 0; 1068 uint32_t mem_val = 0; 1069 struct cmnos_clock_s clock_s; 1070 uint32_t cmnos_core_clk_div_addr = 0; 1071 uint32_t cmnos_cpu_pll_init_done_addr = 0; 1072 uint32_t cmnos_cpu_speed_addr = 0; 1073 struct hif_target_info *tgt_info = hif_get_target_info_handle(hif); 1074 uint32_t target_version = tgt_info->target_version; 1075 struct targetdef_t *scn = &ol_ctx->tgt_def; 1076 1077 switch (target_version) { 1078 case AR6320_REV1_1_VERSION: 1079 cmnos_core_clk_div_addr = AR6320_CORE_CLK_DIV_ADDR; 1080 cmnos_cpu_pll_init_done_addr = AR6320_CPU_PLL_INIT_DONE_ADDR; 1081 cmnos_cpu_speed_addr = AR6320_CPU_SPEED_ADDR; 1082 break; 1083 case AR6320_REV1_3_VERSION: 1084 case AR6320_REV2_1_VERSION: 1085 cmnos_core_clk_div_addr = AR6320V2_CORE_CLK_DIV_ADDR; 1086 cmnos_cpu_pll_init_done_addr = AR6320V2_CPU_PLL_INIT_DONE_ADDR; 1087 cmnos_cpu_speed_addr = AR6320V2_CPU_SPEED_ADDR; 1088 break; 1089 case AR6320_REV3_VERSION: 1090 case AR6320_REV3_2_VERSION: 1091 case QCA9379_REV1_VERSION: 1092 case QCA9377_REV1_1_VERSION: 1093 cmnos_core_clk_div_addr = AR6320V3_CORE_CLK_DIV_ADDR; 1094 cmnos_cpu_pll_init_done_addr = AR6320V3_CPU_PLL_INIT_DONE_ADDR; 1095 cmnos_cpu_speed_addr = AR6320V3_CPU_SPEED_ADDR; 1096 break; 1097 default: 1098 BMI_ERR("%s: Unsupported target version %x", __func__, 1099 target_version); 1100 goto end; 1101 } 1102 1103 addr = (RTC_SOC_BASE_ADDRESS | EFUSE_OFFSET); 1104 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1105 if (status != QDF_STATUS_SUCCESS) { 1106 BMI_ERR("Failed to read EFUSE Addr"); 1107 goto end; 1108 } 1109 1110 status = ol_fw_populate_clk_settings(EFUSE_XTAL_SEL_GET(reg_val), 1111 &clock_s); 1112 if (status != QDF_STATUS_SUCCESS) { 1113 BMI_ERR("Failed to set clock settings"); 1114 goto end; 1115 } 1116 BMI_DBG("crystal_freq: %dHz", clock_s.refclk_hz); 1117 1118 /* ------Step 1---- */ 1119 reg_val = 0; 1120 addr = (RTC_SOC_BASE_ADDRESS | BB_PLL_CONFIG_OFFSET); 1121 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1122 if (status != QDF_STATUS_SUCCESS) { 1123 BMI_ERR("Failed to read PLL_CONFIG Addr"); 1124 goto end; 1125 } 1126 BMI_DBG("Step 1a: %8X", reg_val); 1127 1128 reg_val &= ~(BB_PLL_CONFIG_FRAC_MASK | BB_PLL_CONFIG_OUTDIV_MASK); 1129 reg_val |= (BB_PLL_CONFIG_FRAC_SET(clock_s.wlan_pll.rnfrac) | 1130 BB_PLL_CONFIG_OUTDIV_SET(clock_s.wlan_pll.outdiv)); 1131 status = bmi_write_soc_register(addr, reg_val, ol_ctx); 1132 if (status != QDF_STATUS_SUCCESS) { 1133 BMI_ERR("Failed to write PLL_CONFIG Addr"); 1134 goto end; 1135 } 1136 1137 reg_val = 0; 1138 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1139 if (status != QDF_STATUS_SUCCESS) { 1140 BMI_ERR("Failed to read back PLL_CONFIG Addr"); 1141 goto end; 1142 } 1143 BMI_DBG("Step 1b: %8X", reg_val); 1144 1145 /* ------Step 2---- */ 1146 reg_val = 0; 1147 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_SETTLE_OFFSET); 1148 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1149 if (status != QDF_STATUS_SUCCESS) { 1150 BMI_ERR("Failed to read PLL_SETTLE Addr"); 1151 goto end; 1152 } 1153 BMI_DBG("Step 2a: %8X", reg_val); 1154 1155 reg_val &= ~WLAN_PLL_SETTLE_TIME_MASK; 1156 reg_val |= WLAN_PLL_SETTLE_TIME_SET(clock_s.pll_settling_time); 1157 status = bmi_write_soc_register(addr, reg_val, ol_ctx); 1158 if (status != QDF_STATUS_SUCCESS) { 1159 BMI_ERR("Failed to write PLL_SETTLE Addr"); 1160 goto end; 1161 } 1162 1163 reg_val = 0; 1164 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1165 if (status != QDF_STATUS_SUCCESS) { 1166 BMI_ERR("Failed to read back PLL_SETTLE Addr"); 1167 goto end; 1168 } 1169 BMI_DBG("Step 2b: %8X", reg_val); 1170 1171 /* ------Step 3---- */ 1172 reg_val = 0; 1173 addr = (RTC_SOC_BASE_ADDRESS | SOC_CORE_CLK_CTRL_OFFSET); 1174 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1175 if (status != QDF_STATUS_SUCCESS) { 1176 BMI_ERR("Failed to read CLK_CTRL Addr"); 1177 goto end; 1178 } 1179 BMI_DBG("Step 3a: %8X", reg_val); 1180 1181 reg_val &= ~SOC_CORE_CLK_CTRL_DIV_MASK; 1182 reg_val |= SOC_CORE_CLK_CTRL_DIV_SET(1); 1183 status = bmi_write_soc_register(addr, reg_val, ol_ctx); 1184 if (status != QDF_STATUS_SUCCESS) { 1185 BMI_ERR("Failed to write CLK_CTRL Addr"); 1186 goto end; 1187 } 1188 1189 reg_val = 0; 1190 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1191 if (status != QDF_STATUS_SUCCESS) { 1192 BMI_ERR("Failed to read back CLK_CTRL Addr"); 1193 goto end; 1194 } 1195 BMI_DBG("Step 3b: %8X", reg_val); 1196 1197 /* ------Step 4----- */ 1198 mem_val = 1; 1199 status = bmi_write_memory(cmnos_core_clk_div_addr, 1200 (uint8_t *) &mem_val, 4, ol_ctx); 1201 if (status != QDF_STATUS_SUCCESS) { 1202 BMI_ERR("Failed to write CLK_DIV Addr"); 1203 goto end; 1204 } 1205 1206 /* ------Step 5----- */ 1207 reg_val = 0; 1208 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET); 1209 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1210 if (status != QDF_STATUS_SUCCESS) { 1211 BMI_ERR("Failed to read PLL_CTRL Addr"); 1212 goto end; 1213 } 1214 BMI_DBG("Step 5a: %8X", reg_val); 1215 1216 reg_val &= ~(WLAN_PLL_CONTROL_REFDIV_MASK | WLAN_PLL_CONTROL_DIV_MASK | 1217 WLAN_PLL_CONTROL_NOPWD_MASK); 1218 reg_val |= (WLAN_PLL_CONTROL_REFDIV_SET(clock_s.wlan_pll.refdiv) | 1219 WLAN_PLL_CONTROL_DIV_SET(clock_s.wlan_pll.div) | 1220 WLAN_PLL_CONTROL_NOPWD_SET(1)); 1221 status = bmi_write_soc_register(addr, reg_val, ol_ctx); 1222 if (status != QDF_STATUS_SUCCESS) { 1223 BMI_ERR("Failed to write PLL_CTRL Addr"); 1224 goto end; 1225 } 1226 1227 reg_val = 0; 1228 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1229 if (status != QDF_STATUS_SUCCESS) { 1230 BMI_ERR("Failed to read back PLL_CTRL Addr"); 1231 goto end; 1232 } 1233 qdf_udelay(100); 1234 BMI_DBG("Step 5b: %8X", reg_val); 1235 1236 /* ------Step 6------- */ 1237 do { 1238 reg_val = 0; 1239 status = bmi_read_soc_register((RTC_WMAC_BASE_ADDRESS | 1240 RTC_SYNC_STATUS_OFFSET), ®_val, ol_ctx); 1241 if (status != QDF_STATUS_SUCCESS) { 1242 BMI_ERR("Failed to read RTC_SYNC_STATUS Addr"); 1243 goto end; 1244 } 1245 } while (RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val)); 1246 1247 /* ------Step 7------- */ 1248 reg_val = 0; 1249 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET); 1250 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1251 if (status != QDF_STATUS_SUCCESS) { 1252 BMI_ERR("Failed to read PLL_CTRL Addr for CTRL_BYPASS"); 1253 goto end; 1254 } 1255 BMI_DBG("Step 7a: %8X", reg_val); 1256 1257 reg_val &= ~WLAN_PLL_CONTROL_BYPASS_MASK; 1258 reg_val |= WLAN_PLL_CONTROL_BYPASS_SET(0); 1259 status = bmi_write_soc_register(addr, reg_val, ol_ctx); 1260 if (status != QDF_STATUS_SUCCESS) { 1261 BMI_ERR("Failed to write PLL_CTRL Addr for CTRL_BYPASS"); 1262 goto end; 1263 } 1264 1265 reg_val = 0; 1266 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1267 if (status != QDF_STATUS_SUCCESS) { 1268 BMI_ERR("Failed to read back PLL_CTRL Addr for CTRL_BYPASS"); 1269 goto end; 1270 } 1271 BMI_DBG("Step 7b: %8X", reg_val); 1272 1273 /* ------Step 8-------- */ 1274 do { 1275 reg_val = 0; 1276 status = bmi_read_soc_register((RTC_WMAC_BASE_ADDRESS | 1277 RTC_SYNC_STATUS_OFFSET), ®_val, ol_ctx); 1278 if (status != QDF_STATUS_SUCCESS) { 1279 BMI_ERR("Failed to read SYNC_STATUS Addr"); 1280 goto end; 1281 } 1282 } while (RTC_SYNC_STATUS_PLL_CHANGING_GET(reg_val)); 1283 1284 /* ------Step 9-------- */ 1285 reg_val = 0; 1286 addr = (RTC_SOC_BASE_ADDRESS | SOC_CPU_CLOCK_OFFSET); 1287 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1288 if (status != QDF_STATUS_SUCCESS) { 1289 BMI_ERR("Failed to read CPU_CLK Addr"); 1290 goto end; 1291 } 1292 BMI_DBG("Step 9a: %8X", reg_val); 1293 1294 reg_val &= ~SOC_CPU_CLOCK_STANDARD_MASK; 1295 reg_val |= SOC_CPU_CLOCK_STANDARD_SET(1); 1296 status = bmi_write_soc_register(addr, reg_val, ol_ctx); 1297 if (status != QDF_STATUS_SUCCESS) { 1298 BMI_ERR("Failed to write CPU_CLK Addr"); 1299 goto end; 1300 } 1301 1302 reg_val = 0; 1303 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1304 if (status != QDF_STATUS_SUCCESS) { 1305 BMI_ERR("Failed to read back CPU_CLK Addr"); 1306 goto end; 1307 } 1308 BMI_DBG("Step 9b: %8X", reg_val); 1309 1310 /* ------Step 10------- */ 1311 reg_val = 0; 1312 addr = (RTC_WMAC_BASE_ADDRESS | WLAN_PLL_CONTROL_OFFSET); 1313 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1314 if (status != QDF_STATUS_SUCCESS) { 1315 BMI_ERR("Failed to read PLL_CTRL Addr for NOPWD"); 1316 goto end; 1317 } 1318 BMI_DBG("Step 10a: %8X", reg_val); 1319 1320 reg_val &= ~WLAN_PLL_CONTROL_NOPWD_MASK; 1321 status = bmi_write_soc_register(addr, reg_val, ol_ctx); 1322 if (status != QDF_STATUS_SUCCESS) { 1323 BMI_ERR("Failed to write PLL_CTRL Addr for NOPWD"); 1324 goto end; 1325 } 1326 reg_val = 0; 1327 status = bmi_read_soc_register(addr, ®_val, ol_ctx); 1328 if (status != QDF_STATUS_SUCCESS) { 1329 BMI_ERR("Failed to read back PLL_CTRL Addr for NOPWD"); 1330 goto end; 1331 } 1332 BMI_DBG("Step 10b: %8X", reg_val); 1333 1334 /* ------Step 11------- */ 1335 mem_val = 1; 1336 status = bmi_write_memory(cmnos_cpu_pll_init_done_addr, 1337 (uint8_t *) &mem_val, 4, ol_ctx); 1338 if (status != QDF_STATUS_SUCCESS) { 1339 BMI_ERR("Failed to write PLL_INIT Addr"); 1340 goto end; 1341 } 1342 1343 mem_val = TARGET_CPU_FREQ; 1344 status = bmi_write_memory(cmnos_cpu_speed_addr, 1345 (uint8_t *) &mem_val, 4, ol_ctx); 1346 if (status != QDF_STATUS_SUCCESS) { 1347 BMI_ERR("Failed to write CPU_SPEED Addr"); 1348 goto end; 1349 } 1350 1351 end: 1352 return status; 1353 } 1354 ol_download_firmware(struct ol_context * ol_ctx)1355 QDF_STATUS ol_download_firmware(struct ol_context *ol_ctx) 1356 { 1357 struct hif_opaque_softc *scn = ol_ctx->scn; 1358 uint32_t param, address = 0; 1359 QDF_STATUS status = !QDF_STATUS_SUCCESS; 1360 QDF_STATUS ret; 1361 struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); 1362 struct ol_config_info *ini_cfg = ol_get_ini_handle(ol_ctx); 1363 uint32_t target_type = tgt_info->target_type; 1364 uint32_t target_version = tgt_info->target_version; 1365 struct bmi_info *bmi_ctx = GET_BMI_CONTEXT(ol_ctx); 1366 qdf_device_t qdf_dev = ol_ctx->qdf_dev; 1367 1368 if (0 != pld_get_fw_files_for_target(qdf_dev->dev, 1369 &bmi_ctx->fw_files, 1370 target_type, 1371 target_version)) { 1372 BMI_ERR("%s: No FW files from platform driver", __func__); 1373 return QDF_STATUS_E_FAILURE; 1374 } 1375 1376 /* Transfer Board Data from Target EEPROM to Target RAM */ 1377 /* Determine where in Target RAM to write Board Data */ 1378 bmi_read_memory(hif_hia_item_address(target_type, 1379 offsetof(struct host_interest_s, hi_board_data)), 1380 (uint8_t *)&address, 4, ol_ctx); 1381 1382 if (!address) { 1383 address = AR6004_REV5_BOARD_DATA_ADDRESS; 1384 BMI_DBG("%s: Target address not known! Using 0x%x", 1385 __func__, address); 1386 } 1387 1388 if (hif_get_bus_type(scn) != QDF_BUS_TYPE_USB) { 1389 ret = ol_patch_pll_switch(ol_ctx); 1390 if (ret != QDF_STATUS_SUCCESS) { 1391 BMI_ERR("pll switch failed. status %d", ret); 1392 return ret; 1393 } 1394 } 1395 1396 if (ol_ctx->cal_in_flash) { 1397 /* Write EEPROM or Flash data to Target RAM */ 1398 status = ol_transfer_bin_file(ol_ctx, ATH_FLASH_FILE, 1399 address, false); 1400 } 1401 1402 if (!status) { 1403 /* Record the fact that Board Data is initialized */ 1404 param = 1; 1405 bmi_write_memory( 1406 hif_hia_item_address(target_type, 1407 offsetof(struct host_interest_s, 1408 hi_board_data_initialized)), 1409 (uint8_t *) ¶m, 4, ol_ctx); 1410 } else { 1411 /* Transfer One Time Programmable data */ 1412 address = BMI_SEGMENTED_WRITE_ADDR; 1413 BMI_INFO("%s: Using 0x%x for the remainder of init", 1414 __func__, address); 1415 1416 status = ol_transfer_bin_file(ol_ctx, ATH_OTP_FILE, 1417 address, true); 1418 /* Execute the OTP code only if entry found and downloaded */ 1419 if (!status) { 1420 uint16_t board_id = 0xffff; 1421 /* get board id */ 1422 param = 0x10; 1423 bmi_execute(address, ¶m, ol_ctx); 1424 if (!(param & 0xff)) 1425 board_id = (param >> 8) & 0xffff; 1426 BMI_INFO("%s: board ID is 0x%0x", __func__, board_id); 1427 bmi_ctx->board_id = board_id; 1428 } else if (status < 0) { 1429 return status; 1430 } 1431 1432 bmi_read_memory(hif_hia_item_address(target_type, 1433 offsetof(struct host_interest_s, 1434 hi_board_data)), 1435 (uint8_t *)&address, 4, ol_ctx); 1436 1437 if (!address) { 1438 address = AR6004_REV5_BOARD_DATA_ADDRESS; 1439 pr_err("%s: Target address not known! Using 0x%x\n", 1440 __func__, address); 1441 } 1442 1443 /* Flash is either not available or invalid */ 1444 if (ol_transfer_bin_file(ol_ctx, ATH_BOARD_DATA_FILE, 1445 address, false)) { 1446 return QDF_STATUS_E_FAILURE; 1447 } 1448 1449 /* Record the fact that Board Data is initialized */ 1450 param = 1; 1451 bmi_write_memory(hif_hia_item_address(target_type, 1452 offsetof(struct host_interest_s, 1453 hi_board_data_initialized)), 1454 (uint8_t *) ¶m, 4, ol_ctx); 1455 address = BMI_SEGMENTED_WRITE_ADDR; 1456 param = 0; 1457 bmi_execute(address, ¶m, ol_ctx); 1458 } 1459 1460 if (!ol_transfer_bin_file(ol_ctx, ATH_SETUP_FILE, 1461 BMI_SEGMENTED_WRITE_ADDR, true)) { 1462 param = 0; 1463 bmi_execute(address, ¶m, ol_ctx); 1464 } 1465 1466 /* Download Target firmware 1467 * TODO point to target specific files in runtime 1468 */ 1469 address = BMI_SEGMENTED_WRITE_ADDR; 1470 if (ol_transfer_bin_file(ol_ctx, ATH_FIRMWARE_FILE, 1471 address, true)) { 1472 return QDF_STATUS_E_FAILURE; 1473 } 1474 1475 /* Apply the patches */ 1476 if (ol_check_dataset_patch(scn, &address)) { 1477 if (ol_transfer_bin_file(ol_ctx, ATH_PATCH_FILE, address, 1478 false)) { 1479 return QDF_STATUS_E_FAILURE; 1480 } 1481 bmi_write_memory(hif_hia_item_address(target_type, 1482 offsetof(struct host_interest_s, hi_dset_list_head)), 1483 (uint8_t *) &address, 4, ol_ctx); 1484 } 1485 1486 switch (target_version) { 1487 case AR6004_VERSION_REV1_3: 1488 param = 11; 1489 break; 1490 case AR6320_REV1_VERSION: 1491 case AR6320_REV2_VERSION: 1492 case AR6320_REV3_VERSION: 1493 case AR6320_REV3_2_VERSION: 1494 case QCA9377_REV1_1_VERSION: 1495 case QCA9379_REV1_VERSION: 1496 case AR6320_REV4_VERSION: 1497 case AR6320_DEV_VERSION: 1498 /* 1499 * In sdio interface chip, both sdio_data2 and uart_tx pin 1500 * will use GPIO6. It is set by fw rom code, which will cause 1501 * sdio CRC error when there is sdio transaction. 1502 * Override uart tx pin to avoid side effect to sdio pin. 1503 */ 1504 if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO) 1505 param = 19; 1506 else 1507 param = 6; 1508 break; 1509 default: 1510 /* Configure GPIO AR9888 UART */ 1511 param = 7; 1512 } 1513 1514 bmi_write_memory(hif_hia_item_address(target_type, 1515 offsetof(struct host_interest_s, hi_dbg_uart_txpin)), 1516 (uint8_t *)¶m, 4, ol_ctx); 1517 1518 if (ini_cfg->enable_uart_print) { 1519 param = 1; 1520 bmi_write_memory(hif_hia_item_address(target_type, 1521 offsetof(struct host_interest_s, hi_serial_enable)), 1522 (uint8_t *)¶m, 4, ol_ctx); 1523 } else { 1524 /* 1525 * Explicitly setting UART prints to zero as target turns it on 1526 * based on scratch registers. 1527 */ 1528 param = 0; 1529 bmi_write_memory(hif_hia_item_address(target_type, 1530 offsetof(struct host_interest_s, hi_serial_enable)), 1531 (uint8_t *)¶m, 4, ol_ctx); 1532 } 1533 1534 if (ini_cfg->enable_fw_log) { 1535 bmi_read_memory(hif_hia_item_address(target_type, 1536 offsetof(struct host_interest_s, hi_option_flag)), 1537 (uint8_t *)¶m, 4, ol_ctx); 1538 1539 param &= ~(HI_OPTION_DISABLE_DBGLOG); 1540 bmi_write_memory(hif_hia_item_address(target_type, 1541 offsetof(struct host_interest_s, hi_option_flag)), 1542 (uint8_t *)¶m, 4, ol_ctx); 1543 } else { 1544 /* 1545 * Explicitly setting fwlog prints to zero as target turns it on 1546 * based on scratch registers. 1547 */ 1548 bmi_read_memory(hif_hia_item_address(target_type, 1549 offsetof(struct host_interest_s, hi_option_flag)), 1550 (uint8_t *)¶m, 4, ol_ctx); 1551 1552 param |= HI_OPTION_DISABLE_DBGLOG; 1553 bmi_write_memory(hif_hia_item_address(target_type, 1554 offsetof(struct host_interest_s, hi_option_flag)), 1555 (uint8_t *) ¶m, 4, ol_ctx); 1556 } 1557 status = ol_extra_initialization(ol_ctx); 1558 1559 return status; 1560 } 1561 ol_diag_read(struct hif_opaque_softc * scn,uint8_t * buffer,uint32_t pos,size_t count)1562 static int ol_diag_read(struct hif_opaque_softc *scn, uint8_t *buffer, 1563 uint32_t pos, size_t count) 1564 { 1565 int result = 0; 1566 1567 if ((4 == count) && ((pos & 3) == 0)) { 1568 result = hif_diag_read_access(scn, pos, 1569 (uint32_t *) buffer); 1570 } else { 1571 size_t amount_read = 0; 1572 size_t readSize = PCIE_READ_LIMIT; 1573 size_t remainder = 0; 1574 1575 if (count > PCIE_READ_LIMIT) { 1576 while ((amount_read < count) && (0 == result)) { 1577 result = hif_diag_read_mem(scn, pos, 1578 buffer, readSize); 1579 if (0 == result) { 1580 buffer += readSize; 1581 pos += readSize; 1582 amount_read += readSize; 1583 remainder = count - amount_read; 1584 if (remainder < PCIE_READ_LIMIT) 1585 readSize = remainder; 1586 } 1587 } 1588 } else { 1589 result = hif_diag_read_mem(scn, pos, 1590 buffer, count); 1591 } 1592 } 1593 1594 if (!result) 1595 return count; 1596 else 1597 return -EIO; 1598 } 1599 ol_ath_get_reg_table(struct hif_opaque_softc * scn,uint32_t target_version,struct tgt_reg_table * reg_table)1600 static int ol_ath_get_reg_table(struct hif_opaque_softc *scn, 1601 uint32_t target_version, 1602 struct tgt_reg_table *reg_table) 1603 { 1604 int section_len = 0; 1605 1606 if (!reg_table) { 1607 qdf_assert(0); 1608 return section_len; 1609 } 1610 1611 if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI && 1612 hif_get_bus_type(scn) != QDF_BUS_TYPE_SDIO) 1613 return section_len; 1614 1615 switch (target_version) { 1616 case AR6320_REV2_1_VERSION: 1617 reg_table->section = ar6320v2_reg_table; 1618 reg_table->section_size = ARRAY_SIZE(ar6320v2_reg_table); 1619 section_len = AR6320_REV2_1_REG_SIZE; 1620 break; 1621 case AR6320_REV3_VERSION: 1622 case AR6320_REV3_2_VERSION: 1623 case QCA9379_REV1_VERSION: 1624 case QCA9377_REV1_1_VERSION: 1625 reg_table->section = ar6320v3_reg_table; 1626 reg_table->section_size = ARRAY_SIZE(ar6320v3_reg_table); 1627 section_len = AR6320_REV3_REG_SIZE; 1628 break; 1629 default: 1630 reg_table->section = NULL; 1631 reg_table->section_size = 0; 1632 section_len = 0; 1633 } 1634 1635 return section_len; 1636 } 1637 ol_diag_read_reg_loc(struct hif_opaque_softc * scn,uint8_t * buffer,uint32_t buffer_len)1638 static int ol_diag_read_reg_loc(struct hif_opaque_softc *scn, uint8_t *buffer, 1639 uint32_t buffer_len) 1640 { 1641 int i, len, section_len, fill_len; 1642 int dump_len, result = 0; 1643 struct tgt_reg_table reg_table; 1644 const struct tgt_reg_section *curr_sec, *next_sec; 1645 struct hif_target_info *tgt_info = hif_get_target_info_handle(scn); 1646 uint32_t target_version = tgt_info->target_version; 1647 1648 reg_table.section = NULL; 1649 reg_table.section_size = 0; 1650 1651 section_len = ol_ath_get_reg_table(scn, target_version, ®_table); 1652 1653 if (!reg_table.section || !reg_table.section_size || !section_len) { 1654 BMI_ERR("%s: failed to get reg table", __func__); 1655 result = -EIO; 1656 goto out; 1657 } 1658 1659 curr_sec = reg_table.section; 1660 for (i = 0; i < reg_table.section_size; i++) { 1661 1662 dump_len = curr_sec->end_addr - curr_sec->start_addr; 1663 1664 if ((buffer_len - result) < dump_len) { 1665 BMI_ERR("No buffer to dump regs:%d: 0x%08x-0x%08x", 1666 i, curr_sec->start_addr, curr_sec->end_addr); 1667 goto out; 1668 } 1669 1670 len = ol_diag_read(scn, buffer, curr_sec->start_addr, dump_len); 1671 1672 if (len != -EIO) { 1673 buffer += len; 1674 result += len; 1675 } else { 1676 BMI_ERR("%s: can't read reg 0x%08x len = %d", 1677 __func__, curr_sec->start_addr, dump_len); 1678 result = -EIO; 1679 goto out; 1680 } 1681 1682 if (result < section_len) { 1683 next_sec = (struct tgt_reg_section *) ((uint8_t *) 1684 curr_sec + sizeof(*curr_sec)); 1685 fill_len = next_sec->start_addr - curr_sec->end_addr; 1686 if ((buffer_len - result) < fill_len) { 1687 BMI_ERR("No buf to fill regs:%d: 0x%08x-0x%08x", 1688 i, curr_sec->end_addr, 1689 next_sec->start_addr); 1690 goto out; 1691 } 1692 1693 if (fill_len) { 1694 buffer += fill_len; 1695 result += fill_len; 1696 } 1697 } 1698 curr_sec++; 1699 } 1700 1701 out: 1702 return result; 1703 } 1704 1705 static ol_dump_target_memory(struct hif_opaque_softc * scn,void * memory_block)1706 void ol_dump_target_memory(struct hif_opaque_softc *scn, void *memory_block) 1707 { 1708 char *buffer_loc = memory_block; 1709 u_int32_t section_count = 0; 1710 u_int32_t address = 0; 1711 u_int32_t size = 0; 1712 1713 if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO || 1714 hif_get_bus_type(scn) == QDF_BUS_TYPE_USB) 1715 return; 1716 1717 for (; section_count < 2; section_count++) { 1718 switch (section_count) { 1719 case 0: 1720 address = DRAM_LOCAL_BASE_ADDR; 1721 size = DRAM_SIZE; 1722 break; 1723 case 1: 1724 address = AXI_LOCATION; 1725 size = AXI_SIZE; 1726 break; 1727 default: 1728 break; 1729 } 1730 hif_dump_target_memory(scn, buffer_loc, address, size); 1731 buffer_loc += size; 1732 } 1733 } 1734 1735 static int ol_dump_ce_register(struct hif_opaque_softc * scn,void * memory_block)1736 ol_dump_ce_register(struct hif_opaque_softc *scn, void *memory_block) 1737 { 1738 int ret; 1739 1740 BMI_ERR("Could not read dump section!"); 1741 1742 if (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO || 1743 hif_get_bus_type(scn) == QDF_BUS_TYPE_USB) 1744 return 0; 1745 1746 if (hif_dump_registers(scn)) 1747 BMI_ERR("Failed to dump bus registers"); 1748 1749 ol_dump_target_memory(scn, memory_block); 1750 ret = -EACCES; 1751 1752 return ret; 1753 } 1754 1755 static inline uint32_t ol_get_max_section_count(struct hif_opaque_softc * scn)1756 ol_get_max_section_count(struct hif_opaque_softc *scn) 1757 { 1758 if (hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) 1759 return 5; 1760 else 1761 return 4; 1762 } 1763 1764 /** 1765 * ol_set_ram_config_reg() - set target RAM configuration register 1766 * @scn: pointer of hif_softc context 1767 * @config: value to be written to the register 1768 * 1769 * This function will write the given value to target RAM configuration 1770 * register which is bit[23-20] of target CPU inbound address in order to 1771 * provide correct address mapping. 1772 * 1773 * Return: 0 for success or reasons for failure 1774 */ ol_set_ram_config_reg(struct hif_opaque_softc * scn,uint32_t config)1775 static int ol_set_ram_config_reg(struct hif_opaque_softc *scn, uint32_t config) 1776 { 1777 QDF_STATUS status; 1778 uint32_t val; 1779 struct targetdef_s *targetdef = 1780 (struct targetdef_s *)hif_get_targetdef(scn); 1781 uint32_t ram_config_addr = 1782 targetdef->d_SOC_CORE_BASE_ADDRESS + FW_RAM_CONFIG_ADDRESS; 1783 1784 if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI) 1785 return -EACCES; 1786 1787 status = hif_diag_write_access(scn, ram_config_addr, config); 1788 if (QDF_IS_STATUS_ERROR(status)) { 1789 return -EACCES; 1790 } 1791 status = hif_diag_read_access(scn, ram_config_addr, &val); 1792 if (QDF_IS_STATUS_ERROR(status)) { 1793 return -EACCES; 1794 } 1795 if (val != config) { 1796 BMI_ERR("%s: Failed to set RAM config reg from 0x%x to 0x%x", 1797 __func__, val, config); 1798 return -EACCES; 1799 } 1800 return 0; 1801 } 1802 1803 static int ol_get_iram_len_and_pos(struct hif_opaque_softc * scn,uint32_t * pos,uint32_t * len,uint32_t section)1804 ol_get_iram_len_and_pos(struct hif_opaque_softc *scn, uint32_t *pos, 1805 uint32_t *len, uint32_t section) 1806 { 1807 enum hif_target_status status; 1808 uint32_t iram_addr, iram_size; 1809 int ret; 1810 1811 if (hif_get_bus_type(scn) != QDF_BUS_TYPE_PCI) { 1812 *pos = IRAM_LOCATION; 1813 *len = IRAM_SIZE; 1814 BMI_ERR("%s: Dumping IRAM Section", __func__); 1815 return 0; 1816 } 1817 1818 status = hif_get_target_status(scn); 1819 if (status != TARGET_STATUS_RESET) { 1820 BMI_ERR("%s: Target status invalid: %d", __func__, status); 1821 return -EBUSY; 1822 } 1823 1824 switch (section) { 1825 case 3: 1826 BMI_ERR("%s: Dumping IRAM1 section", __func__); 1827 iram_addr = IRAM1_LOCATION; 1828 iram_size = IRAM1_SIZE; 1829 break; 1830 case 4: 1831 BMI_ERR("%s: Dumping IRAM2 section", __func__); 1832 iram_addr = IRAM2_LOCATION; 1833 iram_size = IRAM2_SIZE; 1834 break; 1835 default: 1836 BMI_ERR("%s: Invalid input iram section %d", 1837 __func__, section); 1838 return A_EINVAL; 1839 } 1840 1841 ret = ol_set_ram_config_reg(scn, iram_addr >> 20); 1842 if (ret) { 1843 BMI_ERR("%s: Skip IRAM1 ret:%d", __func__, ret); 1844 return -EBUSY; 1845 } 1846 1847 *pos = iram_addr; 1848 *len = iram_size; 1849 return 0; 1850 } 1851 1852 /** 1853 * ol_target_coredump() - API to collect target ramdump 1854 * @inst: private context 1855 * @memory_block: non-NULL reserved memory location 1856 * @block_len: size of the dump to collect 1857 * 1858 * Function to perform core dump for the target. 1859 * 1860 * Return: int 1861 */ ol_target_coredump(void * inst,void * memory_block,uint32_t block_len)1862 static int ol_target_coredump(void *inst, void *memory_block, 1863 uint32_t block_len) 1864 { 1865 struct hif_opaque_softc *scn = (struct hif_opaque_softc *)inst; 1866 int8_t *buffer_loc = memory_block; 1867 int result = 0; 1868 int ret = 0; 1869 uint32_t amount_read = 0; 1870 uint32_t section_count = 0; 1871 uint32_t pos = 0; 1872 uint32_t read_len = 0; 1873 uint32_t max_count = ol_get_max_section_count(scn); 1874 1875 while ((section_count < max_count) && (amount_read < block_len)) { 1876 switch (section_count) { 1877 case 0: 1878 pos = DRAM_LOCATION; 1879 read_len = DRAM_SIZE; 1880 BMI_ERR("%s: Dumping DRAM section...", __func__); 1881 break; 1882 case 1: 1883 pos = AXI_LOCATION; 1884 read_len = AXI_SIZE; 1885 BMI_ERR("%s: Dumping AXI section...", __func__); 1886 break; 1887 case 2: 1888 pos = REGISTER_LOCATION; 1889 /* ol_diag_read_reg_loc checks for buffer overrun */ 1890 read_len = 0; 1891 BMI_ERR("%s: Dumping Register section...", __func__); 1892 break; 1893 case 3: 1894 case 4: 1895 ret = ol_get_iram_len_and_pos(scn, &pos, &read_len, 1896 section_count); 1897 if (ret) { 1898 BMI_ERR("%s: Fail to Dump IRAM Section " 1899 "ret:%d", __func__, ret); 1900 return ret; 1901 } 1902 break; 1903 default: 1904 BMI_ERR("%s: INVALID SECTION_:%d", __func__, 1905 section_count); 1906 return 0; 1907 } 1908 1909 if (block_len - amount_read < read_len) { 1910 BMI_ERR("%s: No memory to dump section:%d buffer!", 1911 __func__, section_count); 1912 return -ENOMEM; 1913 } 1914 1915 if (((hif_get_bus_type(scn) == QDF_BUS_TYPE_PCI) || 1916 (hif_get_bus_type(scn) == QDF_BUS_TYPE_SDIO)) && 1917 pos == REGISTER_LOCATION) 1918 result = ol_diag_read_reg_loc(scn, buffer_loc, 1919 block_len - amount_read); 1920 else 1921 result = ol_diag_read(scn, buffer_loc, pos, read_len); 1922 1923 if (result == -EIO) 1924 return ol_dump_ce_register(scn, memory_block); 1925 1926 BMI_INFO("%s: Section:%d Bytes Read:%0x", __func__, 1927 section_count, result); 1928 1929 amount_read += result; 1930 buffer_loc += result; 1931 section_count++; 1932 } 1933 return ret; 1934 } 1935 1936 /** 1937 * ol_get_ini_handle() - API to get Ol INI configuration 1938 * @ol_ctx: OL Context 1939 * 1940 * Return: pointer to OL configuration 1941 */ ol_get_ini_handle(struct ol_context * ol_ctx)1942 struct ol_config_info *ol_get_ini_handle(struct ol_context *ol_ctx) 1943 { 1944 return &ol_ctx->cfg_info; 1945 } 1946 1947 /** 1948 * ol_init_ini_config() - API to initialize INI configuration 1949 * @ol_ctx: OL Context 1950 * @cfg: OL ini configuration 1951 * 1952 * Return: void 1953 */ ol_init_ini_config(struct ol_context * ol_ctx,struct ol_config_info * cfg)1954 void ol_init_ini_config(struct ol_context *ol_ctx, 1955 struct ol_config_info *cfg) 1956 { 1957 qdf_mem_copy(&ol_ctx->cfg_info, cfg, sizeof(struct ol_config_info)); 1958 } 1959 ol_set_fw_crashed_cb(struct ol_context * ol_ctx,void (* callback_fn)(void))1960 void ol_set_fw_crashed_cb(struct ol_context *ol_ctx, 1961 void (*callback_fn)(void)) 1962 { 1963 ol_ctx->fw_crashed_cb = callback_fn; 1964 } 1965