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