1 // SPDX-License-Identifier: BSD-3-Clause-Clear 2 /* 3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. 4 * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. 5 */ 6 7 #if defined(__FreeBSD__) 8 #define LINUXKPI_PARAM_PREFIX ath11k_core_ 9 #endif 10 11 #include <linux/module.h> 12 #include <linux/slab.h> 13 #include <linux/remoteproc.h> 14 #include <linux/firmware.h> 15 #if defined(CONFIG_OF) 16 #include <linux/of.h> 17 #endif 18 #if defined(__FreeBSD__) 19 #include <linux/delay.h> 20 #endif 21 #include "core.h" 22 #include "dp_tx.h" 23 #include "dp_rx.h" 24 #include "debug.h" 25 #include "hif.h" 26 #include "wow.h" 27 28 unsigned int ath11k_debug_mask; 29 EXPORT_SYMBOL(ath11k_debug_mask); 30 module_param_named(debug_mask, ath11k_debug_mask, uint, 0644); 31 MODULE_PARM_DESC(debug_mask, "Debugging mask"); 32 33 static unsigned int ath11k_crypto_mode; 34 module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644); 35 MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software"); 36 37 /* frame mode values are mapped as per enum ath11k_hw_txrx_mode */ 38 unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI; 39 module_param_named(frame_mode, ath11k_frame_mode, uint, 0644); 40 MODULE_PARM_DESC(frame_mode, 41 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)"); 42 43 static const struct ath11k_hw_params ath11k_hw_params[] = { 44 { 45 .hw_rev = ATH11K_HW_IPQ8074, 46 .name = "ipq8074 hw2.0", 47 .fw = { 48 .dir = "IPQ8074/hw2.0", 49 .board_size = 256 * 1024, 50 .cal_offset = 128 * 1024, 51 }, 52 .max_radios = 3, 53 .bdf_addr = 0x4B0C0000, 54 .hw_ops = &ipq8074_ops, 55 .ring_mask = &ath11k_hw_ring_mask_ipq8074, 56 .internal_sleep_clock = false, 57 .regs = &ipq8074_regs, 58 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074, 59 .host_ce_config = ath11k_host_ce_config_ipq8074, 60 .ce_count = 12, 61 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074, 62 .target_ce_count = 11, 63 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074, 64 .svc_to_ce_map_len = 21, 65 .rfkill_pin = 0, 66 .rfkill_cfg = 0, 67 .rfkill_on_level = 0, 68 .single_pdev_only = false, 69 .rxdma1_enable = true, 70 .num_rxmda_per_pdev = 1, 71 .rx_mac_buf_ring = false, 72 .vdev_start_delay = false, 73 .htt_peer_map_v2 = true, 74 75 .spectral = { 76 .fft_sz = 2, 77 /* HW bug, expected BIN size is 2 bytes but HW report as 4 bytes. 78 * so added pad size as 2 bytes to compensate the BIN size 79 */ 80 .fft_pad_sz = 2, 81 .summary_pad_sz = 0, 82 .fft_hdr_len = 16, 83 .max_fft_bins = 512, 84 }, 85 86 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 87 BIT(NL80211_IFTYPE_AP) | 88 BIT(NL80211_IFTYPE_MESH_POINT), 89 .supports_monitor = true, 90 .full_monitor_mode = false, 91 .supports_shadow_regs = false, 92 .idle_ps = false, 93 .supports_sta_ps = false, 94 .cold_boot_calib = true, 95 .fw_mem_mode = 0, 96 .num_vdevs = 16 + 1, 97 .num_peers = 512, 98 .supports_suspend = false, 99 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), 100 .supports_regdb = false, 101 .fix_l1ss = true, 102 .credit_flow = false, 103 .max_tx_ring = DP_TCL_NUM_RING_MAX, 104 .hal_params = &ath11k_hw_hal_params_ipq8074, 105 .supports_dynamic_smps_6ghz = false, 106 .alloc_cacheable_memory = true, 107 .wakeup_mhi = false, 108 .supports_rssi_stats = false, 109 .fw_wmi_diag_event = false, 110 }, 111 { 112 .hw_rev = ATH11K_HW_IPQ6018_HW10, 113 .name = "ipq6018 hw1.0", 114 .fw = { 115 .dir = "IPQ6018/hw1.0", 116 .board_size = 256 * 1024, 117 .cal_offset = 128 * 1024, 118 }, 119 .max_radios = 2, 120 .bdf_addr = 0x4ABC0000, 121 .hw_ops = &ipq6018_ops, 122 .ring_mask = &ath11k_hw_ring_mask_ipq8074, 123 .internal_sleep_clock = false, 124 .regs = &ipq8074_regs, 125 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074, 126 .host_ce_config = ath11k_host_ce_config_ipq8074, 127 .ce_count = 12, 128 .target_ce_config = ath11k_target_ce_config_wlan_ipq8074, 129 .target_ce_count = 11, 130 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018, 131 .svc_to_ce_map_len = 19, 132 .rfkill_pin = 0, 133 .rfkill_cfg = 0, 134 .rfkill_on_level = 0, 135 .single_pdev_only = false, 136 .rxdma1_enable = true, 137 .num_rxmda_per_pdev = 1, 138 .rx_mac_buf_ring = false, 139 .vdev_start_delay = false, 140 .htt_peer_map_v2 = true, 141 142 .spectral = { 143 .fft_sz = 4, 144 .fft_pad_sz = 0, 145 .summary_pad_sz = 0, 146 .fft_hdr_len = 16, 147 .max_fft_bins = 512, 148 }, 149 150 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 151 BIT(NL80211_IFTYPE_AP) | 152 BIT(NL80211_IFTYPE_MESH_POINT), 153 .supports_monitor = true, 154 .full_monitor_mode = false, 155 .supports_shadow_regs = false, 156 .idle_ps = false, 157 .supports_sta_ps = false, 158 .cold_boot_calib = true, 159 .fw_mem_mode = 0, 160 .num_vdevs = 16 + 1, 161 .num_peers = 512, 162 .supports_suspend = false, 163 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), 164 .supports_regdb = false, 165 .fix_l1ss = true, 166 .credit_flow = false, 167 .max_tx_ring = DP_TCL_NUM_RING_MAX, 168 .hal_params = &ath11k_hw_hal_params_ipq8074, 169 .supports_dynamic_smps_6ghz = false, 170 .alloc_cacheable_memory = true, 171 .wakeup_mhi = false, 172 .supports_rssi_stats = false, 173 .fw_wmi_diag_event = false, 174 }, 175 { 176 .name = "qca6390 hw2.0", 177 .hw_rev = ATH11K_HW_QCA6390_HW20, 178 .fw = { 179 .dir = "QCA6390/hw2.0", 180 .board_size = 256 * 1024, 181 .cal_offset = 128 * 1024, 182 }, 183 .max_radios = 3, 184 .bdf_addr = 0x4B0C0000, 185 .hw_ops = &qca6390_ops, 186 .ring_mask = &ath11k_hw_ring_mask_qca6390, 187 .internal_sleep_clock = true, 188 .regs = &qca6390_regs, 189 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, 190 .host_ce_config = ath11k_host_ce_config_qca6390, 191 .ce_count = 9, 192 .target_ce_config = ath11k_target_ce_config_wlan_qca6390, 193 .target_ce_count = 9, 194 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, 195 .svc_to_ce_map_len = 14, 196 .rfkill_pin = 48, 197 .rfkill_cfg = 0, 198 .rfkill_on_level = 1, 199 .single_pdev_only = true, 200 .rxdma1_enable = false, 201 .num_rxmda_per_pdev = 2, 202 .rx_mac_buf_ring = true, 203 .vdev_start_delay = true, 204 .htt_peer_map_v2 = false, 205 206 .spectral = { 207 .fft_sz = 0, 208 .fft_pad_sz = 0, 209 .summary_pad_sz = 0, 210 .fft_hdr_len = 0, 211 .max_fft_bins = 0, 212 }, 213 214 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 215 BIT(NL80211_IFTYPE_AP), 216 .supports_monitor = false, 217 .full_monitor_mode = false, 218 .supports_shadow_regs = true, 219 .idle_ps = true, 220 .supports_sta_ps = true, 221 .cold_boot_calib = false, 222 .fw_mem_mode = 0, 223 .num_vdevs = 16 + 1, 224 .num_peers = 512, 225 .supports_suspend = true, 226 .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074), 227 .supports_regdb = true, 228 .fix_l1ss = true, 229 .credit_flow = true, 230 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, 231 .hal_params = &ath11k_hw_hal_params_qca6390, 232 .supports_dynamic_smps_6ghz = false, 233 .alloc_cacheable_memory = false, 234 .wakeup_mhi = true, 235 .supports_rssi_stats = true, 236 .fw_wmi_diag_event = true, 237 }, 238 { 239 .name = "qcn9074 hw1.0", 240 .hw_rev = ATH11K_HW_QCN9074_HW10, 241 .fw = { 242 .dir = "QCN9074/hw1.0", 243 .board_size = 256 * 1024, 244 .cal_offset = 128 * 1024, 245 }, 246 .max_radios = 1, 247 .single_pdev_only = false, 248 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074, 249 .hw_ops = &qcn9074_ops, 250 .ring_mask = &ath11k_hw_ring_mask_qcn9074, 251 .internal_sleep_clock = false, 252 .regs = &qcn9074_regs, 253 .host_ce_config = ath11k_host_ce_config_qcn9074, 254 .ce_count = 6, 255 .target_ce_config = ath11k_target_ce_config_wlan_qcn9074, 256 .target_ce_count = 9, 257 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074, 258 .svc_to_ce_map_len = 18, 259 .rfkill_pin = 0, 260 .rfkill_cfg = 0, 261 .rfkill_on_level = 0, 262 .rxdma1_enable = true, 263 .num_rxmda_per_pdev = 1, 264 .rx_mac_buf_ring = false, 265 .vdev_start_delay = false, 266 .htt_peer_map_v2 = true, 267 268 .spectral = { 269 .fft_sz = 2, 270 .fft_pad_sz = 0, 271 .summary_pad_sz = 16, 272 .fft_hdr_len = 24, 273 .max_fft_bins = 1024, 274 }, 275 276 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 277 BIT(NL80211_IFTYPE_AP) | 278 BIT(NL80211_IFTYPE_MESH_POINT), 279 .supports_monitor = true, 280 .full_monitor_mode = true, 281 .supports_shadow_regs = false, 282 .idle_ps = false, 283 .supports_sta_ps = false, 284 .cold_boot_calib = false, 285 .fw_mem_mode = 2, 286 .num_vdevs = 8, 287 .num_peers = 128, 288 .supports_suspend = false, 289 .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074), 290 .supports_regdb = false, 291 .fix_l1ss = true, 292 .credit_flow = false, 293 .max_tx_ring = DP_TCL_NUM_RING_MAX, 294 .hal_params = &ath11k_hw_hal_params_ipq8074, 295 .supports_dynamic_smps_6ghz = true, 296 .alloc_cacheable_memory = true, 297 .wakeup_mhi = false, 298 .supports_rssi_stats = false, 299 .fw_wmi_diag_event = false, 300 }, 301 { 302 .name = "wcn6855 hw2.0", 303 .hw_rev = ATH11K_HW_WCN6855_HW20, 304 .fw = { 305 .dir = "WCN6855/hw2.0", 306 .board_size = 256 * 1024, 307 .cal_offset = 128 * 1024, 308 }, 309 .max_radios = 3, 310 .bdf_addr = 0x4B0C0000, 311 .hw_ops = &wcn6855_ops, 312 .ring_mask = &ath11k_hw_ring_mask_qca6390, 313 .internal_sleep_clock = true, 314 .regs = &wcn6855_regs, 315 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, 316 .host_ce_config = ath11k_host_ce_config_qca6390, 317 .ce_count = 9, 318 .target_ce_config = ath11k_target_ce_config_wlan_qca6390, 319 .target_ce_count = 9, 320 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, 321 .svc_to_ce_map_len = 14, 322 .rfkill_pin = 0, 323 .rfkill_cfg = 0, 324 .rfkill_on_level = 0, 325 .single_pdev_only = true, 326 .rxdma1_enable = false, 327 .num_rxmda_per_pdev = 2, 328 .rx_mac_buf_ring = true, 329 .vdev_start_delay = true, 330 .htt_peer_map_v2 = false, 331 332 .spectral = { 333 .fft_sz = 0, 334 .fft_pad_sz = 0, 335 .summary_pad_sz = 0, 336 .fft_hdr_len = 0, 337 .max_fft_bins = 0, 338 }, 339 340 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 341 BIT(NL80211_IFTYPE_AP), 342 .supports_monitor = false, 343 .full_monitor_mode = false, 344 .supports_shadow_regs = true, 345 .idle_ps = true, 346 .supports_sta_ps = true, 347 .cold_boot_calib = false, 348 .fw_mem_mode = 0, 349 .num_vdevs = 16 + 1, 350 .num_peers = 512, 351 .supports_suspend = true, 352 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), 353 .supports_regdb = true, 354 .fix_l1ss = false, 355 .credit_flow = true, 356 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, 357 .hal_params = &ath11k_hw_hal_params_qca6390, 358 .supports_dynamic_smps_6ghz = false, 359 .alloc_cacheable_memory = false, 360 .wakeup_mhi = true, 361 .supports_rssi_stats = true, 362 .fw_wmi_diag_event = true, 363 }, 364 { 365 .name = "wcn6855 hw2.1", 366 .hw_rev = ATH11K_HW_WCN6855_HW21, 367 .fw = { 368 .dir = "WCN6855/hw2.1", 369 .board_size = 256 * 1024, 370 .cal_offset = 128 * 1024, 371 }, 372 .max_radios = 3, 373 .bdf_addr = 0x4B0C0000, 374 .hw_ops = &wcn6855_ops, 375 .ring_mask = &ath11k_hw_ring_mask_qca6390, 376 .internal_sleep_clock = true, 377 .regs = &wcn6855_regs, 378 .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390, 379 .host_ce_config = ath11k_host_ce_config_qca6390, 380 .ce_count = 9, 381 .target_ce_config = ath11k_target_ce_config_wlan_qca6390, 382 .target_ce_count = 9, 383 .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390, 384 .svc_to_ce_map_len = 14, 385 .rfkill_pin = 0, 386 .rfkill_cfg = 0, 387 .rfkill_on_level = 0, 388 .single_pdev_only = true, 389 .rxdma1_enable = false, 390 .num_rxmda_per_pdev = 2, 391 .rx_mac_buf_ring = true, 392 .vdev_start_delay = true, 393 .htt_peer_map_v2 = false, 394 395 .spectral = { 396 .fft_sz = 0, 397 .fft_pad_sz = 0, 398 .summary_pad_sz = 0, 399 .fft_hdr_len = 0, 400 .max_fft_bins = 0, 401 }, 402 403 .interface_modes = BIT(NL80211_IFTYPE_STATION) | 404 BIT(NL80211_IFTYPE_AP), 405 .supports_monitor = false, 406 .supports_shadow_regs = true, 407 .idle_ps = true, 408 .supports_sta_ps = true, 409 .cold_boot_calib = false, 410 .fw_mem_mode = 0, 411 .num_vdevs = 16 + 1, 412 .num_peers = 512, 413 .supports_suspend = true, 414 .hal_desc_sz = sizeof(struct hal_rx_desc_wcn6855), 415 .supports_regdb = true, 416 .fix_l1ss = false, 417 .credit_flow = true, 418 .max_tx_ring = DP_TCL_NUM_RING_MAX_QCA6390, 419 .hal_params = &ath11k_hw_hal_params_qca6390, 420 .supports_dynamic_smps_6ghz = false, 421 .alloc_cacheable_memory = false, 422 .wakeup_mhi = true, 423 .supports_rssi_stats = true, 424 .fw_wmi_diag_event = true, 425 }, 426 }; 427 428 int ath11k_core_suspend(struct ath11k_base *ab) 429 { 430 int ret; 431 432 if (!ab->hw_params.supports_suspend) 433 return -EOPNOTSUPP; 434 435 /* TODO: there can frames in queues so for now add delay as a hack. 436 * Need to implement to handle and remove this delay. 437 */ 438 msleep(500); 439 440 ret = ath11k_dp_rx_pktlog_stop(ab, true); 441 if (ret) { 442 ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n", 443 ret); 444 return ret; 445 } 446 447 ret = ath11k_wow_enable(ab); 448 if (ret) { 449 ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret); 450 return ret; 451 } 452 453 ret = ath11k_dp_rx_pktlog_stop(ab, false); 454 if (ret) { 455 ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n", 456 ret); 457 return ret; 458 } 459 460 ath11k_ce_stop_shadow_timers(ab); 461 ath11k_dp_stop_shadow_timers(ab); 462 463 ath11k_hif_irq_disable(ab); 464 ath11k_hif_ce_irq_disable(ab); 465 466 ret = ath11k_hif_suspend(ab); 467 if (ret) { 468 ath11k_warn(ab, "failed to suspend hif: %d\n", ret); 469 return ret; 470 } 471 472 return 0; 473 } 474 EXPORT_SYMBOL(ath11k_core_suspend); 475 476 int ath11k_core_resume(struct ath11k_base *ab) 477 { 478 int ret; 479 480 if (!ab->hw_params.supports_suspend) 481 return -EOPNOTSUPP; 482 483 ret = ath11k_hif_resume(ab); 484 if (ret) { 485 ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret); 486 return ret; 487 } 488 489 ath11k_hif_ce_irq_enable(ab); 490 ath11k_hif_irq_enable(ab); 491 492 ret = ath11k_dp_rx_pktlog_start(ab); 493 if (ret) { 494 ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n", 495 ret); 496 return ret; 497 } 498 499 ret = ath11k_wow_wakeup(ab); 500 if (ret) { 501 ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret); 502 return ret; 503 } 504 505 return 0; 506 } 507 EXPORT_SYMBOL(ath11k_core_resume); 508 509 int ath11k_core_check_dt(struct ath11k_base *ab) 510 { 511 #if defined(__linux__) 512 size_t max_len = sizeof(ab->qmi.target.bdf_ext); 513 const char *variant = NULL; 514 struct device_node *node; 515 516 node = ab->dev->of_node; 517 if (!node) 518 return -ENOENT; 519 520 of_property_read_string(node, "qcom,ath11k-calibration-variant", 521 &variant); 522 if (!variant) 523 return -ENODATA; 524 525 if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0) 526 ath11k_dbg(ab, ATH11K_DBG_BOOT, 527 "bdf variant string is longer than the buffer can accommodate (variant: %s)\n", 528 variant); 529 530 return 0; 531 #elif defined(__FreeBSD__) 532 return -ENOENT; 533 #endif 534 } 535 536 static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, 537 size_t name_len) 538 { 539 /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */ 540 char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 }; 541 542 if (ab->qmi.target.bdf_ext[0] != '\0') 543 scnprintf(variant, sizeof(variant), ",variant=%s", 544 ab->qmi.target.bdf_ext); 545 546 switch (ab->id.bdf_search) { 547 case ATH11K_BDF_SEARCH_BUS_AND_BOARD: 548 scnprintf(name, name_len, 549 "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", 550 ath11k_bus_str(ab->hif.bus), 551 ab->id.vendor, ab->id.device, 552 ab->id.subsystem_vendor, 553 ab->id.subsystem_device, 554 ab->qmi.target.chip_id, 555 ab->qmi.target.board_id, 556 variant); 557 break; 558 default: 559 scnprintf(name, name_len, 560 "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", 561 ath11k_bus_str(ab->hif.bus), 562 ab->qmi.target.chip_id, 563 ab->qmi.target.board_id, variant); 564 break; 565 } 566 567 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name); 568 569 return 0; 570 } 571 572 const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab, 573 const char *file) 574 { 575 const struct firmware *fw; 576 char path[100]; 577 int ret; 578 579 if (file == NULL) 580 return ERR_PTR(-ENOENT); 581 582 ath11k_core_create_firmware_path(ab, file, path, sizeof(path)); 583 584 ret = firmware_request_nowarn(&fw, path, ab->dev); 585 if (ret) 586 return ERR_PTR(ret); 587 588 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n", 589 path, fw->size); 590 591 return fw; 592 } 593 594 void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) 595 { 596 if (!IS_ERR(bd->fw)) 597 release_firmware(bd->fw); 598 599 memset(bd, 0, sizeof(*bd)); 600 } 601 602 static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab, 603 struct ath11k_board_data *bd, 604 #if defined(__linux__) 605 const void *buf, size_t buf_len, 606 #elif defined(__FreeBSD__) 607 const u8 *buf, size_t buf_len, 608 #endif 609 const char *boardname, 610 int bd_ie_type) 611 { 612 const struct ath11k_fw_ie *hdr; 613 bool name_match_found; 614 int ret, board_ie_id; 615 size_t board_ie_len; 616 const void *board_ie_data; 617 618 name_match_found = false; 619 620 /* go through ATH11K_BD_IE_BOARD_ elements */ 621 while (buf_len > sizeof(struct ath11k_fw_ie)) { 622 #if defined(__linux__) 623 hdr = buf; 624 #elif defined(__FreeBSD__) 625 hdr = (const struct ath11k_fw_ie *)buf; 626 #endif 627 board_ie_id = le32_to_cpu(hdr->id); 628 board_ie_len = le32_to_cpu(hdr->len); 629 board_ie_data = hdr->data; 630 631 buf_len -= sizeof(*hdr); 632 buf += sizeof(*hdr); 633 634 if (buf_len < ALIGN(board_ie_len, 4)) { 635 ath11k_err(ab, "invalid ATH11K_BD_IE_BOARD length: %zu < %zu\n", 636 buf_len, ALIGN(board_ie_len, 4)); 637 ret = -EINVAL; 638 goto out; 639 } 640 641 switch (board_ie_id) { 642 case ATH11K_BD_IE_BOARD_NAME: 643 ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "", 644 board_ie_data, board_ie_len); 645 646 if (board_ie_len != strlen(boardname)) 647 break; 648 649 ret = memcmp(board_ie_data, boardname, strlen(boardname)); 650 if (ret) 651 break; 652 653 name_match_found = true; 654 ath11k_dbg(ab, ATH11K_DBG_BOOT, 655 "boot found match for name '%s'", 656 boardname); 657 break; 658 case ATH11K_BD_IE_BOARD_DATA: 659 if (!name_match_found) 660 /* no match found */ 661 break; 662 663 ath11k_dbg(ab, ATH11K_DBG_BOOT, 664 "boot found board data for '%s'", boardname); 665 666 bd->data = board_ie_data; 667 bd->len = board_ie_len; 668 669 ret = 0; 670 goto out; 671 default: 672 ath11k_warn(ab, "unknown ATH11K_BD_IE_BOARD found: %d\n", 673 board_ie_id); 674 break; 675 } 676 677 /* jump over the padding */ 678 board_ie_len = ALIGN(board_ie_len, 4); 679 680 buf_len -= board_ie_len; 681 buf += board_ie_len; 682 } 683 684 /* no match found */ 685 ret = -ENOENT; 686 687 out: 688 return ret; 689 } 690 691 static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab, 692 struct ath11k_board_data *bd, 693 const char *boardname) 694 { 695 size_t len, magic_len; 696 const u8 *data; 697 char *filename, filepath[100]; 698 size_t ie_len; 699 #if defined(__linux__) 700 struct ath11k_fw_ie *hdr; 701 #elif defined(__FreeBSD__) 702 const struct ath11k_fw_ie *hdr; 703 #endif 704 int ret, ie_id; 705 706 filename = ATH11K_BOARD_API2_FILE; 707 708 if (!bd->fw) 709 bd->fw = ath11k_core_firmware_request(ab, filename); 710 711 if (IS_ERR(bd->fw)) 712 return PTR_ERR(bd->fw); 713 714 data = bd->fw->data; 715 len = bd->fw->size; 716 717 ath11k_core_create_firmware_path(ab, filename, 718 filepath, sizeof(filepath)); 719 720 /* magic has extra null byte padded */ 721 magic_len = strlen(ATH11K_BOARD_MAGIC) + 1; 722 if (len < magic_len) { 723 ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n", 724 filepath, len); 725 ret = -EINVAL; 726 goto err; 727 } 728 729 if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) { 730 ath11k_err(ab, "found invalid board magic\n"); 731 ret = -EINVAL; 732 goto err; 733 } 734 735 /* magic is padded to 4 bytes */ 736 magic_len = ALIGN(magic_len, 4); 737 if (len < magic_len) { 738 ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n", 739 filepath, len); 740 ret = -EINVAL; 741 goto err; 742 } 743 744 data += magic_len; 745 len -= magic_len; 746 747 while (len > sizeof(struct ath11k_fw_ie)) { 748 #if defined(__linux__) 749 hdr = (struct ath11k_fw_ie *)data; 750 #elif defined(__FreeBSD__) 751 hdr = (const struct ath11k_fw_ie *)data; 752 #endif 753 ie_id = le32_to_cpu(hdr->id); 754 ie_len = le32_to_cpu(hdr->len); 755 756 len -= sizeof(*hdr); 757 data = hdr->data; 758 759 if (len < ALIGN(ie_len, 4)) { 760 ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n", 761 ie_id, ie_len, len); 762 ret = -EINVAL; 763 goto err; 764 } 765 766 switch (ie_id) { 767 case ATH11K_BD_IE_BOARD: 768 ret = ath11k_core_parse_bd_ie_board(ab, bd, data, 769 ie_len, 770 boardname, 771 ATH11K_BD_IE_BOARD); 772 if (ret == -ENOENT) 773 /* no match found, continue */ 774 break; 775 else if (ret) 776 /* there was an error, bail out */ 777 goto err; 778 /* either found or error, so stop searching */ 779 goto out; 780 } 781 782 /* jump over the padding */ 783 ie_len = ALIGN(ie_len, 4); 784 785 len -= ie_len; 786 data += ie_len; 787 } 788 789 out: 790 if (!bd->data || !bd->len) { 791 ath11k_err(ab, 792 "failed to fetch board data for %s from %s\n", 793 boardname, filepath); 794 ret = -ENODATA; 795 goto err; 796 } 797 798 return 0; 799 800 err: 801 ath11k_core_free_bdf(ab, bd); 802 return ret; 803 } 804 805 int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab, 806 struct ath11k_board_data *bd, 807 const char *name) 808 { 809 bd->fw = ath11k_core_firmware_request(ab, name); 810 811 if (IS_ERR(bd->fw)) 812 return PTR_ERR(bd->fw); 813 814 bd->data = bd->fw->data; 815 bd->len = bd->fw->size; 816 817 return 0; 818 } 819 820 #define BOARD_NAME_SIZE 200 821 int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) 822 { 823 char boardname[BOARD_NAME_SIZE]; 824 int ret; 825 826 ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE); 827 if (ret) { 828 ath11k_err(ab, "failed to create board name: %d", ret); 829 return ret; 830 } 831 832 ab->bd_api = 2; 833 ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname); 834 if (!ret) 835 goto success; 836 837 ab->bd_api = 1; 838 ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_DEFAULT_BOARD_FILE); 839 if (ret) { 840 ath11k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n", 841 ab->hw_params.fw.dir); 842 return ret; 843 } 844 845 success: 846 ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api); 847 return 0; 848 } 849 850 int ath11k_core_fetch_regdb(struct ath11k_base *ab, struct ath11k_board_data *bd) 851 { 852 int ret; 853 854 ret = ath11k_core_fetch_board_data_api_1(ab, bd, ATH11K_REGDB_FILE_NAME); 855 if (ret) 856 ath11k_dbg(ab, ATH11K_DBG_BOOT, "failed to fetch %s from %s\n", 857 ATH11K_REGDB_FILE_NAME, ab->hw_params.fw.dir); 858 859 return ret; 860 } 861 862 static void ath11k_core_stop(struct ath11k_base *ab) 863 { 864 if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags)) 865 ath11k_qmi_firmware_stop(ab); 866 867 ath11k_hif_stop(ab); 868 ath11k_wmi_detach(ab); 869 ath11k_dp_pdev_reo_cleanup(ab); 870 871 /* De-Init of components as needed */ 872 } 873 874 static int ath11k_core_soc_create(struct ath11k_base *ab) 875 { 876 int ret; 877 878 ret = ath11k_qmi_init_service(ab); 879 if (ret) { 880 ath11k_err(ab, "failed to initialize qmi :%d\n", ret); 881 return ret; 882 } 883 884 ret = ath11k_debugfs_soc_create(ab); 885 if (ret) { 886 ath11k_err(ab, "failed to create ath11k debugfs\n"); 887 goto err_qmi_deinit; 888 } 889 890 ret = ath11k_hif_power_up(ab); 891 if (ret) { 892 ath11k_err(ab, "failed to power up :%d\n", ret); 893 goto err_debugfs_reg; 894 } 895 896 return 0; 897 898 err_debugfs_reg: 899 ath11k_debugfs_soc_destroy(ab); 900 err_qmi_deinit: 901 ath11k_qmi_deinit_service(ab); 902 return ret; 903 } 904 905 static void ath11k_core_soc_destroy(struct ath11k_base *ab) 906 { 907 ath11k_debugfs_soc_destroy(ab); 908 ath11k_dp_free(ab); 909 ath11k_reg_free(ab); 910 ath11k_qmi_deinit_service(ab); 911 } 912 913 static int ath11k_core_pdev_create(struct ath11k_base *ab) 914 { 915 int ret; 916 917 ret = ath11k_debugfs_pdev_create(ab); 918 if (ret) { 919 ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret); 920 return ret; 921 } 922 923 ret = ath11k_mac_register(ab); 924 if (ret) { 925 ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret); 926 goto err_pdev_debug; 927 } 928 929 ret = ath11k_dp_pdev_alloc(ab); 930 if (ret) { 931 ath11k_err(ab, "failed to attach DP pdev: %d\n", ret); 932 goto err_mac_unregister; 933 } 934 935 ret = ath11k_thermal_register(ab); 936 if (ret) { 937 ath11k_err(ab, "could not register thermal device: %d\n", 938 ret); 939 goto err_dp_pdev_free; 940 } 941 942 ret = ath11k_spectral_init(ab); 943 if (ret) { 944 ath11k_err(ab, "failed to init spectral %d\n", ret); 945 goto err_thermal_unregister; 946 } 947 948 return 0; 949 950 err_thermal_unregister: 951 ath11k_thermal_unregister(ab); 952 err_dp_pdev_free: 953 ath11k_dp_pdev_free(ab); 954 err_mac_unregister: 955 ath11k_mac_unregister(ab); 956 err_pdev_debug: 957 ath11k_debugfs_pdev_destroy(ab); 958 959 return ret; 960 } 961 962 static void ath11k_core_pdev_destroy(struct ath11k_base *ab) 963 { 964 ath11k_spectral_deinit(ab); 965 ath11k_thermal_unregister(ab); 966 ath11k_mac_unregister(ab); 967 ath11k_hif_irq_disable(ab); 968 ath11k_dp_pdev_free(ab); 969 ath11k_debugfs_pdev_destroy(ab); 970 } 971 972 static int ath11k_core_start(struct ath11k_base *ab, 973 enum ath11k_firmware_mode mode) 974 { 975 int ret; 976 977 ret = ath11k_qmi_firmware_start(ab, mode); 978 if (ret) { 979 ath11k_err(ab, "failed to attach wmi: %d\n", ret); 980 return ret; 981 } 982 983 ret = ath11k_wmi_attach(ab); 984 if (ret) { 985 ath11k_err(ab, "failed to attach wmi: %d\n", ret); 986 goto err_firmware_stop; 987 } 988 989 ret = ath11k_htc_init(ab); 990 if (ret) { 991 ath11k_err(ab, "failed to init htc: %d\n", ret); 992 goto err_wmi_detach; 993 } 994 995 ret = ath11k_hif_start(ab); 996 if (ret) { 997 ath11k_err(ab, "failed to start HIF: %d\n", ret); 998 goto err_wmi_detach; 999 } 1000 1001 ret = ath11k_htc_wait_target(&ab->htc); 1002 if (ret) { 1003 ath11k_err(ab, "failed to connect to HTC: %d\n", ret); 1004 goto err_hif_stop; 1005 } 1006 1007 ret = ath11k_dp_htt_connect(&ab->dp); 1008 if (ret) { 1009 ath11k_err(ab, "failed to connect to HTT: %d\n", ret); 1010 goto err_hif_stop; 1011 } 1012 1013 ret = ath11k_wmi_connect(ab); 1014 if (ret) { 1015 ath11k_err(ab, "failed to connect wmi: %d\n", ret); 1016 goto err_hif_stop; 1017 } 1018 1019 ret = ath11k_htc_start(&ab->htc); 1020 if (ret) { 1021 ath11k_err(ab, "failed to start HTC: %d\n", ret); 1022 goto err_hif_stop; 1023 } 1024 1025 ret = ath11k_wmi_wait_for_service_ready(ab); 1026 if (ret) { 1027 ath11k_err(ab, "failed to receive wmi service ready event: %d\n", 1028 ret); 1029 goto err_hif_stop; 1030 } 1031 1032 ret = ath11k_mac_allocate(ab); 1033 if (ret) { 1034 ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n", 1035 ret); 1036 goto err_hif_stop; 1037 } 1038 1039 ath11k_dp_pdev_pre_alloc(ab); 1040 1041 ret = ath11k_dp_pdev_reo_setup(ab); 1042 if (ret) { 1043 ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret); 1044 goto err_mac_destroy; 1045 } 1046 1047 ret = ath11k_wmi_cmd_init(ab); 1048 if (ret) { 1049 ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret); 1050 goto err_reo_cleanup; 1051 } 1052 1053 ret = ath11k_wmi_wait_for_unified_ready(ab); 1054 if (ret) { 1055 ath11k_err(ab, "failed to receive wmi unified ready event: %d\n", 1056 ret); 1057 goto err_reo_cleanup; 1058 } 1059 1060 /* put hardware to DBS mode */ 1061 if (ab->hw_params.single_pdev_only) { 1062 ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS); 1063 if (ret) { 1064 ath11k_err(ab, "failed to send dbs mode: %d\n", ret); 1065 goto err_hif_stop; 1066 } 1067 } 1068 1069 ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab); 1070 if (ret) { 1071 ath11k_err(ab, "failed to send htt version request message: %d\n", 1072 ret); 1073 goto err_reo_cleanup; 1074 } 1075 1076 return 0; 1077 1078 err_reo_cleanup: 1079 ath11k_dp_pdev_reo_cleanup(ab); 1080 err_mac_destroy: 1081 ath11k_mac_destroy(ab); 1082 err_hif_stop: 1083 ath11k_hif_stop(ab); 1084 err_wmi_detach: 1085 ath11k_wmi_detach(ab); 1086 err_firmware_stop: 1087 ath11k_qmi_firmware_stop(ab); 1088 1089 return ret; 1090 } 1091 1092 static int ath11k_core_rfkill_config(struct ath11k_base *ab) 1093 { 1094 struct ath11k *ar; 1095 int ret = 0, i; 1096 1097 if (!(ab->target_caps.sys_cap_info & WMI_SYS_CAP_INFO_RFKILL)) 1098 return 0; 1099 1100 for (i = 0; i < ab->num_radios; i++) { 1101 ar = ab->pdevs[i].ar; 1102 1103 ret = ath11k_mac_rfkill_config(ar); 1104 if (ret && ret != -EOPNOTSUPP) { 1105 ath11k_warn(ab, "failed to configure rfkill: %d", ret); 1106 return ret; 1107 } 1108 } 1109 1110 return ret; 1111 } 1112 1113 int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab) 1114 { 1115 int ret; 1116 1117 ret = ath11k_ce_init_pipes(ab); 1118 if (ret) { 1119 ath11k_err(ab, "failed to initialize CE: %d\n", ret); 1120 return ret; 1121 } 1122 1123 ret = ath11k_dp_alloc(ab); 1124 if (ret) { 1125 ath11k_err(ab, "failed to init DP: %d\n", ret); 1126 return ret; 1127 } 1128 1129 switch (ath11k_crypto_mode) { 1130 case ATH11K_CRYPT_MODE_SW: 1131 set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags); 1132 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); 1133 break; 1134 case ATH11K_CRYPT_MODE_HW: 1135 clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags); 1136 clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); 1137 break; 1138 default: 1139 ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode); 1140 return -EINVAL; 1141 } 1142 1143 if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW) 1144 set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags); 1145 1146 mutex_lock(&ab->core_lock); 1147 ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL); 1148 if (ret) { 1149 ath11k_err(ab, "failed to start core: %d\n", ret); 1150 goto err_dp_free; 1151 } 1152 1153 ret = ath11k_core_pdev_create(ab); 1154 if (ret) { 1155 ath11k_err(ab, "failed to create pdev core: %d\n", ret); 1156 goto err_core_stop; 1157 } 1158 ath11k_hif_irq_enable(ab); 1159 1160 ret = ath11k_core_rfkill_config(ab); 1161 if (ret && ret != -EOPNOTSUPP) { 1162 ath11k_err(ab, "failed to config rfkill: %d\n", ret); 1163 goto err_core_stop; 1164 } 1165 1166 mutex_unlock(&ab->core_lock); 1167 1168 return 0; 1169 1170 err_core_stop: 1171 ath11k_core_stop(ab); 1172 ath11k_mac_destroy(ab); 1173 err_dp_free: 1174 ath11k_dp_free(ab); 1175 mutex_unlock(&ab->core_lock); 1176 return ret; 1177 } 1178 1179 static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab) 1180 { 1181 int ret; 1182 1183 mutex_lock(&ab->core_lock); 1184 ath11k_thermal_unregister(ab); 1185 ath11k_hif_irq_disable(ab); 1186 ath11k_dp_pdev_free(ab); 1187 ath11k_spectral_deinit(ab); 1188 ath11k_hif_stop(ab); 1189 ath11k_wmi_detach(ab); 1190 ath11k_dp_pdev_reo_cleanup(ab); 1191 mutex_unlock(&ab->core_lock); 1192 1193 ath11k_dp_free(ab); 1194 ath11k_hal_srng_deinit(ab); 1195 1196 ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS(ab))) - 1; 1197 1198 ret = ath11k_hal_srng_init(ab); 1199 if (ret) 1200 return ret; 1201 1202 clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags); 1203 1204 ret = ath11k_core_qmi_firmware_ready(ab); 1205 if (ret) 1206 goto err_hal_srng_deinit; 1207 1208 clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags); 1209 1210 return 0; 1211 1212 err_hal_srng_deinit: 1213 ath11k_hal_srng_deinit(ab); 1214 return ret; 1215 } 1216 1217 void ath11k_core_halt(struct ath11k *ar) 1218 { 1219 struct ath11k_base *ab = ar->ab; 1220 1221 lockdep_assert_held(&ar->conf_mutex); 1222 1223 ar->num_created_vdevs = 0; 1224 ar->allocated_vdev_map = 0; 1225 1226 ath11k_mac_scan_finish(ar); 1227 ath11k_mac_peer_cleanup_all(ar); 1228 cancel_delayed_work_sync(&ar->scan.timeout); 1229 cancel_work_sync(&ar->regd_update_work); 1230 cancel_work_sync(&ab->update_11d_work); 1231 cancel_work_sync(&ab->rfkill_work); 1232 1233 rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL); 1234 synchronize_rcu(); 1235 INIT_LIST_HEAD(&ar->arvifs); 1236 idr_init(&ar->txmgmt_idr); 1237 } 1238 1239 static void ath11k_rfkill_work(struct work_struct *work) 1240 { 1241 struct ath11k_base *ab = container_of(work, struct ath11k_base, rfkill_work); 1242 struct ath11k *ar; 1243 bool rfkill_radio_on; 1244 int i; 1245 1246 spin_lock_bh(&ab->base_lock); 1247 rfkill_radio_on = ab->rfkill_radio_on; 1248 spin_unlock_bh(&ab->base_lock); 1249 1250 for (i = 0; i < ab->num_radios; i++) { 1251 ar = ab->pdevs[i].ar; 1252 if (!ar) 1253 continue; 1254 1255 /* notify cfg80211 radio state change */ 1256 ath11k_mac_rfkill_enable_radio(ar, rfkill_radio_on); 1257 wiphy_rfkill_set_hw_state(ar->hw->wiphy, !rfkill_radio_on); 1258 } 1259 } 1260 1261 static void ath11k_update_11d(struct work_struct *work) 1262 { 1263 struct ath11k_base *ab = container_of(work, struct ath11k_base, update_11d_work); 1264 struct ath11k *ar; 1265 struct ath11k_pdev *pdev; 1266 struct wmi_set_current_country_params set_current_param = {}; 1267 int ret, i; 1268 1269 spin_lock_bh(&ab->base_lock); 1270 memcpy(&set_current_param.alpha2, &ab->new_alpha2, 2); 1271 spin_unlock_bh(&ab->base_lock); 1272 1273 ath11k_dbg(ab, ATH11K_DBG_WMI, "update 11d new cc %c%c\n", 1274 set_current_param.alpha2[0], 1275 set_current_param.alpha2[1]); 1276 1277 for (i = 0; i < ab->num_radios; i++) { 1278 pdev = &ab->pdevs[i]; 1279 ar = pdev->ar; 1280 1281 ret = ath11k_wmi_send_set_current_country_cmd(ar, &set_current_param); 1282 if (ret) 1283 ath11k_warn(ar->ab, 1284 "pdev id %d failed set current country code: %d\n", 1285 i, ret); 1286 } 1287 } 1288 1289 static void ath11k_core_restart(struct work_struct *work) 1290 { 1291 struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work); 1292 struct ath11k *ar; 1293 struct ath11k_pdev *pdev; 1294 int i, ret = 0; 1295 1296 spin_lock_bh(&ab->base_lock); 1297 ab->stats.fw_crash_counter++; 1298 spin_unlock_bh(&ab->base_lock); 1299 1300 for (i = 0; i < ab->num_radios; i++) { 1301 pdev = &ab->pdevs[i]; 1302 ar = pdev->ar; 1303 if (!ar || ar->state == ATH11K_STATE_OFF) 1304 continue; 1305 1306 ieee80211_stop_queues(ar->hw); 1307 ath11k_mac_drain_tx(ar); 1308 complete(&ar->scan.started); 1309 complete(&ar->scan.completed); 1310 complete(&ar->peer_assoc_done); 1311 complete(&ar->peer_delete_done); 1312 complete(&ar->install_key_done); 1313 complete(&ar->vdev_setup_done); 1314 complete(&ar->vdev_delete_done); 1315 complete(&ar->bss_survey_done); 1316 complete(&ar->thermal.wmi_sync); 1317 1318 wake_up(&ar->dp.tx_empty_waitq); 1319 idr_for_each(&ar->txmgmt_idr, 1320 ath11k_mac_tx_mgmt_pending_free, ar); 1321 idr_destroy(&ar->txmgmt_idr); 1322 wake_up(&ar->txmgmt_empty_waitq); 1323 } 1324 1325 wake_up(&ab->wmi_ab.tx_credits_wq); 1326 wake_up(&ab->peer_mapping_wq); 1327 1328 ret = ath11k_core_reconfigure_on_crash(ab); 1329 if (ret) { 1330 ath11k_err(ab, "failed to reconfigure driver on crash recovery\n"); 1331 return; 1332 } 1333 1334 for (i = 0; i < ab->num_radios; i++) { 1335 pdev = &ab->pdevs[i]; 1336 ar = pdev->ar; 1337 if (!ar || ar->state == ATH11K_STATE_OFF) 1338 continue; 1339 1340 mutex_lock(&ar->conf_mutex); 1341 1342 switch (ar->state) { 1343 case ATH11K_STATE_ON: 1344 ar->state = ATH11K_STATE_RESTARTING; 1345 ath11k_core_halt(ar); 1346 ieee80211_restart_hw(ar->hw); 1347 break; 1348 case ATH11K_STATE_OFF: 1349 ath11k_warn(ab, 1350 "cannot restart radio %d that hasn't been started\n", 1351 i); 1352 break; 1353 case ATH11K_STATE_RESTARTING: 1354 break; 1355 case ATH11K_STATE_RESTARTED: 1356 ar->state = ATH11K_STATE_WEDGED; 1357 fallthrough; 1358 case ATH11K_STATE_WEDGED: 1359 ath11k_warn(ab, 1360 "device is wedged, will not restart radio %d\n", i); 1361 break; 1362 } 1363 mutex_unlock(&ar->conf_mutex); 1364 } 1365 complete(&ab->driver_recovery); 1366 } 1367 1368 static int ath11k_init_hw_params(struct ath11k_base *ab) 1369 { 1370 const struct ath11k_hw_params *hw_params = NULL; 1371 int i; 1372 1373 for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) { 1374 hw_params = &ath11k_hw_params[i]; 1375 1376 if (hw_params->hw_rev == ab->hw_rev) 1377 break; 1378 } 1379 1380 if (i == ARRAY_SIZE(ath11k_hw_params)) { 1381 ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev); 1382 return -EINVAL; 1383 } 1384 1385 ab->hw_params = *hw_params; 1386 1387 ath11k_info(ab, "%s\n", ab->hw_params.name); 1388 1389 return 0; 1390 } 1391 1392 int ath11k_core_pre_init(struct ath11k_base *ab) 1393 { 1394 int ret; 1395 1396 ret = ath11k_init_hw_params(ab); 1397 if (ret) { 1398 ath11k_err(ab, "failed to get hw params: %d\n", ret); 1399 return ret; 1400 } 1401 1402 return 0; 1403 } 1404 EXPORT_SYMBOL(ath11k_core_pre_init); 1405 1406 int ath11k_core_init(struct ath11k_base *ab) 1407 { 1408 int ret; 1409 1410 ret = ath11k_core_soc_create(ab); 1411 if (ret) { 1412 ath11k_err(ab, "failed to create soc core: %d\n", ret); 1413 return ret; 1414 } 1415 1416 return 0; 1417 } 1418 EXPORT_SYMBOL(ath11k_core_init); 1419 1420 void ath11k_core_deinit(struct ath11k_base *ab) 1421 { 1422 mutex_lock(&ab->core_lock); 1423 1424 ath11k_core_pdev_destroy(ab); 1425 ath11k_core_stop(ab); 1426 1427 mutex_unlock(&ab->core_lock); 1428 1429 ath11k_hif_power_down(ab); 1430 ath11k_mac_destroy(ab); 1431 ath11k_core_soc_destroy(ab); 1432 } 1433 EXPORT_SYMBOL(ath11k_core_deinit); 1434 1435 void ath11k_core_free(struct ath11k_base *ab) 1436 { 1437 flush_workqueue(ab->workqueue); 1438 destroy_workqueue(ab->workqueue); 1439 1440 kfree(ab); 1441 } 1442 EXPORT_SYMBOL(ath11k_core_free); 1443 1444 struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size, 1445 enum ath11k_bus bus, 1446 const struct ath11k_bus_params *bus_params) 1447 { 1448 struct ath11k_base *ab; 1449 1450 ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL); 1451 if (!ab) 1452 return NULL; 1453 1454 init_completion(&ab->driver_recovery); 1455 1456 ab->workqueue = create_singlethread_workqueue("ath11k_wq"); 1457 if (!ab->workqueue) 1458 goto err_sc_free; 1459 1460 mutex_init(&ab->core_lock); 1461 spin_lock_init(&ab->base_lock); 1462 mutex_init(&ab->vdev_id_11d_lock); 1463 1464 INIT_LIST_HEAD(&ab->peers); 1465 init_waitqueue_head(&ab->peer_mapping_wq); 1466 init_waitqueue_head(&ab->wmi_ab.tx_credits_wq); 1467 init_waitqueue_head(&ab->qmi.cold_boot_waitq); 1468 INIT_WORK(&ab->restart_work, ath11k_core_restart); 1469 INIT_WORK(&ab->update_11d_work, ath11k_update_11d); 1470 INIT_WORK(&ab->rfkill_work, ath11k_rfkill_work); 1471 timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0); 1472 init_completion(&ab->htc_suspend); 1473 init_completion(&ab->wow.wakeup_completed); 1474 1475 ab->dev = dev; 1476 ab->bus_params = *bus_params; 1477 ab->hif.bus = bus; 1478 1479 return ab; 1480 1481 err_sc_free: 1482 kfree(ab); 1483 return NULL; 1484 } 1485 EXPORT_SYMBOL(ath11k_core_alloc); 1486 1487 MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards."); 1488 MODULE_LICENSE("Dual BSD/GPL"); 1489