linux/drivers/net/wireless/ath/ath11k/core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: BSD-3-Clause-Clear
   2/*
   3 * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved.
   4 */
   5
   6#include <linux/module.h>
   7#include <linux/slab.h>
   8#include <linux/remoteproc.h>
   9#include <linux/firmware.h>
  10#include <linux/of.h>
  11#include "core.h"
  12#include "dp_tx.h"
  13#include "dp_rx.h"
  14#include "debug.h"
  15#include "hif.h"
  16#include "wow.h"
  17
  18unsigned int ath11k_debug_mask;
  19EXPORT_SYMBOL(ath11k_debug_mask);
  20module_param_named(debug_mask, ath11k_debug_mask, uint, 0644);
  21MODULE_PARM_DESC(debug_mask, "Debugging mask");
  22
  23static unsigned int ath11k_crypto_mode;
  24module_param_named(crypto_mode, ath11k_crypto_mode, uint, 0644);
  25MODULE_PARM_DESC(crypto_mode, "crypto mode: 0-hardware, 1-software");
  26
  27/* frame mode values are mapped as per enum ath11k_hw_txrx_mode */
  28unsigned int ath11k_frame_mode = ATH11K_HW_TXRX_NATIVE_WIFI;
  29module_param_named(frame_mode, ath11k_frame_mode, uint, 0644);
  30MODULE_PARM_DESC(frame_mode,
  31                 "Datapath frame mode (0: raw, 1: native wifi (default), 2: ethernet)");
  32
  33static const struct ath11k_hw_params ath11k_hw_params[] = {
  34        {
  35                .hw_rev = ATH11K_HW_IPQ8074,
  36                .name = "ipq8074 hw2.0",
  37                .fw = {
  38                        .dir = "IPQ8074/hw2.0",
  39                        .board_size = 256 * 1024,
  40                        .cal_size = 256 * 1024,
  41                },
  42                .max_radios = 3,
  43                .bdf_addr = 0x4B0C0000,
  44                .hw_ops = &ipq8074_ops,
  45                .ring_mask = &ath11k_hw_ring_mask_ipq8074,
  46                .internal_sleep_clock = false,
  47                .regs = &ipq8074_regs,
  48                .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
  49                .host_ce_config = ath11k_host_ce_config_ipq8074,
  50                .ce_count = 12,
  51                .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
  52                .target_ce_count = 11,
  53                .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq8074,
  54                .svc_to_ce_map_len = 21,
  55                .single_pdev_only = false,
  56                .rxdma1_enable = true,
  57                .num_rxmda_per_pdev = 1,
  58                .rx_mac_buf_ring = false,
  59                .vdev_start_delay = false,
  60                .htt_peer_map_v2 = true,
  61                .tcl_0_only = false,
  62                .spectral_fft_sz = 2,
  63
  64                .interface_modes = BIT(NL80211_IFTYPE_STATION) |
  65                                        BIT(NL80211_IFTYPE_AP) |
  66                                        BIT(NL80211_IFTYPE_MESH_POINT),
  67                .supports_monitor = true,
  68                .supports_shadow_regs = false,
  69                .idle_ps = false,
  70                .cold_boot_calib = true,
  71                .supports_suspend = false,
  72                .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
  73        },
  74        {
  75                .hw_rev = ATH11K_HW_IPQ6018_HW10,
  76                .name = "ipq6018 hw1.0",
  77                .fw = {
  78                        .dir = "IPQ6018/hw1.0",
  79                        .board_size = 256 * 1024,
  80                        .cal_size = 256 * 1024,
  81                },
  82                .max_radios = 2,
  83                .bdf_addr = 0x4ABC0000,
  84                .hw_ops = &ipq6018_ops,
  85                .ring_mask = &ath11k_hw_ring_mask_ipq8074,
  86                .internal_sleep_clock = false,
  87                .regs = &ipq8074_regs,
  88                .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_IPQ8074,
  89                .host_ce_config = ath11k_host_ce_config_ipq8074,
  90                .ce_count = 12,
  91                .target_ce_config = ath11k_target_ce_config_wlan_ipq8074,
  92                .target_ce_count = 11,
  93                .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_ipq6018,
  94                .svc_to_ce_map_len = 19,
  95                .single_pdev_only = false,
  96                .rxdma1_enable = true,
  97                .num_rxmda_per_pdev = 1,
  98                .rx_mac_buf_ring = false,
  99                .vdev_start_delay = false,
 100                .htt_peer_map_v2 = true,
 101                .tcl_0_only = false,
 102                .spectral_fft_sz = 4,
 103
 104                .interface_modes = BIT(NL80211_IFTYPE_STATION) |
 105                                        BIT(NL80211_IFTYPE_AP) |
 106                                        BIT(NL80211_IFTYPE_MESH_POINT),
 107                .supports_monitor = true,
 108                .supports_shadow_regs = false,
 109                .idle_ps = false,
 110                .cold_boot_calib = true,
 111                .supports_suspend = false,
 112                .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
 113        },
 114        {
 115                .name = "qca6390 hw2.0",
 116                .hw_rev = ATH11K_HW_QCA6390_HW20,
 117                .fw = {
 118                        .dir = "QCA6390/hw2.0",
 119                        .board_size = 256 * 1024,
 120                        .cal_size = 256 * 1024,
 121                },
 122                .max_radios = 3,
 123                .bdf_addr = 0x4B0C0000,
 124                .hw_ops = &qca6390_ops,
 125                .ring_mask = &ath11k_hw_ring_mask_qca6390,
 126                .internal_sleep_clock = true,
 127                .regs = &qca6390_regs,
 128                .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCA6390,
 129                .host_ce_config = ath11k_host_ce_config_qca6390,
 130                .ce_count = 9,
 131                .target_ce_config = ath11k_target_ce_config_wlan_qca6390,
 132                .target_ce_count = 9,
 133                .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qca6390,
 134                .svc_to_ce_map_len = 14,
 135                .single_pdev_only = true,
 136                .rxdma1_enable = false,
 137                .num_rxmda_per_pdev = 2,
 138                .rx_mac_buf_ring = true,
 139                .vdev_start_delay = true,
 140                .htt_peer_map_v2 = false,
 141                .tcl_0_only = true,
 142                .spectral_fft_sz = 0,
 143
 144                .interface_modes = BIT(NL80211_IFTYPE_STATION) |
 145                                        BIT(NL80211_IFTYPE_AP),
 146                .supports_monitor = false,
 147                .supports_shadow_regs = true,
 148                .idle_ps = true,
 149                .cold_boot_calib = false,
 150                .supports_suspend = true,
 151                .hal_desc_sz = sizeof(struct hal_rx_desc_ipq8074),
 152        },
 153        {
 154                .name = "qcn9074 hw1.0",
 155                .hw_rev = ATH11K_HW_QCN9074_HW10,
 156                .fw = {
 157                        .dir = "QCN9074/hw1.0",
 158                        .board_size = 256 * 1024,
 159                        .cal_size = 256 * 1024,
 160                },
 161                .max_radios = 1,
 162                .single_pdev_only = false,
 163                .qmi_service_ins_id = ATH11K_QMI_WLFW_SERVICE_INS_ID_V01_QCN9074,
 164                .hw_ops = &qcn9074_ops,
 165                .ring_mask = &ath11k_hw_ring_mask_qcn9074,
 166                .internal_sleep_clock = false,
 167                .regs = &qcn9074_regs,
 168                .host_ce_config = ath11k_host_ce_config_qcn9074,
 169                .ce_count = 6,
 170                .target_ce_config = ath11k_target_ce_config_wlan_qcn9074,
 171                .target_ce_count = 9,
 172                .svc_to_ce_map = ath11k_target_service_to_ce_map_wlan_qcn9074,
 173                .svc_to_ce_map_len = 18,
 174                .rxdma1_enable = true,
 175                .num_rxmda_per_pdev = 1,
 176                .rx_mac_buf_ring = false,
 177                .vdev_start_delay = false,
 178                .htt_peer_map_v2 = true,
 179                .tcl_0_only = false,
 180                .interface_modes = BIT(NL80211_IFTYPE_STATION) |
 181                                        BIT(NL80211_IFTYPE_AP) |
 182                                        BIT(NL80211_IFTYPE_MESH_POINT),
 183                .supports_monitor = true,
 184                .supports_shadow_regs = false,
 185                .idle_ps = false,
 186                .cold_boot_calib = false,
 187                .supports_suspend = false,
 188                .hal_desc_sz = sizeof(struct hal_rx_desc_qcn9074),
 189        },
 190};
 191
 192int ath11k_core_suspend(struct ath11k_base *ab)
 193{
 194        int ret;
 195
 196        if (!ab->hw_params.supports_suspend)
 197                return -EOPNOTSUPP;
 198
 199        /* TODO: there can frames in queues so for now add delay as a hack.
 200         * Need to implement to handle and remove this delay.
 201         */
 202        msleep(500);
 203
 204        ret = ath11k_dp_rx_pktlog_stop(ab, true);
 205        if (ret) {
 206                ath11k_warn(ab, "failed to stop dp rx (and timer) pktlog during suspend: %d\n",
 207                            ret);
 208                return ret;
 209        }
 210
 211        ret = ath11k_wow_enable(ab);
 212        if (ret) {
 213                ath11k_warn(ab, "failed to enable wow during suspend: %d\n", ret);
 214                return ret;
 215        }
 216
 217        ret = ath11k_dp_rx_pktlog_stop(ab, false);
 218        if (ret) {
 219                ath11k_warn(ab, "failed to stop dp rx pktlog during suspend: %d\n",
 220                            ret);
 221                return ret;
 222        }
 223
 224        ath11k_ce_stop_shadow_timers(ab);
 225        ath11k_dp_stop_shadow_timers(ab);
 226
 227        ath11k_hif_irq_disable(ab);
 228        ath11k_hif_ce_irq_disable(ab);
 229
 230        ret = ath11k_hif_suspend(ab);
 231        if (ret) {
 232                ath11k_warn(ab, "failed to suspend hif: %d\n", ret);
 233                return ret;
 234        }
 235
 236        return 0;
 237}
 238EXPORT_SYMBOL(ath11k_core_suspend);
 239
 240int ath11k_core_resume(struct ath11k_base *ab)
 241{
 242        int ret;
 243
 244        if (!ab->hw_params.supports_suspend)
 245                return -EOPNOTSUPP;
 246
 247        ret = ath11k_hif_resume(ab);
 248        if (ret) {
 249                ath11k_warn(ab, "failed to resume hif during resume: %d\n", ret);
 250                return ret;
 251        }
 252
 253        ath11k_hif_ce_irq_enable(ab);
 254        ath11k_hif_irq_enable(ab);
 255
 256        ret = ath11k_dp_rx_pktlog_start(ab);
 257        if (ret) {
 258                ath11k_warn(ab, "failed to start rx pktlog during resume: %d\n",
 259                            ret);
 260                return ret;
 261        }
 262
 263        ret = ath11k_wow_wakeup(ab);
 264        if (ret) {
 265                ath11k_warn(ab, "failed to wakeup wow during resume: %d\n", ret);
 266                return ret;
 267        }
 268
 269        return 0;
 270}
 271EXPORT_SYMBOL(ath11k_core_resume);
 272
 273int ath11k_core_check_dt(struct ath11k_base *ab)
 274{
 275        size_t max_len = sizeof(ab->qmi.target.bdf_ext);
 276        const char *variant = NULL;
 277        struct device_node *node;
 278
 279        node = ab->dev->of_node;
 280        if (!node)
 281                return -ENOENT;
 282
 283        of_property_read_string(node, "qcom,ath11k-calibration-variant",
 284                                &variant);
 285        if (!variant)
 286                return -ENODATA;
 287
 288        if (strscpy(ab->qmi.target.bdf_ext, variant, max_len) < 0)
 289                ath11k_dbg(ab, ATH11K_DBG_BOOT,
 290                           "bdf variant string is longer than the buffer can accommodate (variant: %s)\n",
 291                            variant);
 292
 293        return 0;
 294}
 295
 296static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name,
 297                                         size_t name_len)
 298{
 299        /* strlen(',variant=') + strlen(ab->qmi.target.bdf_ext) */
 300        char variant[9 + ATH11K_QMI_BDF_EXT_STR_LENGTH] = { 0 };
 301
 302        if (ab->qmi.target.bdf_ext[0] != '\0')
 303                scnprintf(variant, sizeof(variant), ",variant=%s",
 304                          ab->qmi.target.bdf_ext);
 305
 306        scnprintf(name, name_len,
 307                  "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s",
 308                  ath11k_bus_str(ab->hif.bus),
 309                  ab->qmi.target.chip_id,
 310                  ab->qmi.target.board_id, variant);
 311
 312        ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name);
 313
 314        return 0;
 315}
 316
 317const struct firmware *ath11k_core_firmware_request(struct ath11k_base *ab,
 318                                                    const char *file)
 319{
 320        const struct firmware *fw;
 321        char path[100];
 322        int ret;
 323
 324        if (file == NULL)
 325                return ERR_PTR(-ENOENT);
 326
 327        ath11k_core_create_firmware_path(ab, file, path, sizeof(path));
 328
 329        ret = firmware_request_nowarn(&fw, path, ab->dev);
 330        if (ret)
 331                return ERR_PTR(ret);
 332
 333        ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot firmware request %s size %zu\n",
 334                   path, fw->size);
 335
 336        return fw;
 337}
 338
 339void ath11k_core_free_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
 340{
 341        if (!IS_ERR(bd->fw))
 342                release_firmware(bd->fw);
 343
 344        memset(bd, 0, sizeof(*bd));
 345}
 346
 347static int ath11k_core_parse_bd_ie_board(struct ath11k_base *ab,
 348                                         struct ath11k_board_data *bd,
 349                                         const void *buf, size_t buf_len,
 350                                         const char *boardname,
 351                                         int bd_ie_type)
 352{
 353        const struct ath11k_fw_ie *hdr;
 354        bool name_match_found;
 355        int ret, board_ie_id;
 356        size_t board_ie_len;
 357        const void *board_ie_data;
 358
 359        name_match_found = false;
 360
 361        /* go through ATH11K_BD_IE_BOARD_ elements */
 362        while (buf_len > sizeof(struct ath11k_fw_ie)) {
 363                hdr = buf;
 364                board_ie_id = le32_to_cpu(hdr->id);
 365                board_ie_len = le32_to_cpu(hdr->len);
 366                board_ie_data = hdr->data;
 367
 368                buf_len -= sizeof(*hdr);
 369                buf += sizeof(*hdr);
 370
 371                if (buf_len < ALIGN(board_ie_len, 4)) {
 372                        ath11k_err(ab, "invalid ATH11K_BD_IE_BOARD length: %zu < %zu\n",
 373                                   buf_len, ALIGN(board_ie_len, 4));
 374                        ret = -EINVAL;
 375                        goto out;
 376                }
 377
 378                switch (board_ie_id) {
 379                case ATH11K_BD_IE_BOARD_NAME:
 380                        ath11k_dbg_dump(ab, ATH11K_DBG_BOOT, "board name", "",
 381                                        board_ie_data, board_ie_len);
 382
 383                        if (board_ie_len != strlen(boardname))
 384                                break;
 385
 386                        ret = memcmp(board_ie_data, boardname, strlen(boardname));
 387                        if (ret)
 388                                break;
 389
 390                        name_match_found = true;
 391                        ath11k_dbg(ab, ATH11K_DBG_BOOT,
 392                                   "boot found match for name '%s'",
 393                                   boardname);
 394                        break;
 395                case ATH11K_BD_IE_BOARD_DATA:
 396                        if (!name_match_found)
 397                                /* no match found */
 398                                break;
 399
 400                        ath11k_dbg(ab, ATH11K_DBG_BOOT,
 401                                   "boot found board data for '%s'", boardname);
 402
 403                        bd->data = board_ie_data;
 404                        bd->len = board_ie_len;
 405
 406                        ret = 0;
 407                        goto out;
 408                default:
 409                        ath11k_warn(ab, "unknown ATH11K_BD_IE_BOARD found: %d\n",
 410                                    board_ie_id);
 411                        break;
 412                }
 413
 414                /* jump over the padding */
 415                board_ie_len = ALIGN(board_ie_len, 4);
 416
 417                buf_len -= board_ie_len;
 418                buf += board_ie_len;
 419        }
 420
 421        /* no match found */
 422        ret = -ENOENT;
 423
 424out:
 425        return ret;
 426}
 427
 428static int ath11k_core_fetch_board_data_api_n(struct ath11k_base *ab,
 429                                              struct ath11k_board_data *bd,
 430                                              const char *boardname)
 431{
 432        size_t len, magic_len;
 433        const u8 *data;
 434        char *filename, filepath[100];
 435        size_t ie_len;
 436        struct ath11k_fw_ie *hdr;
 437        int ret, ie_id;
 438
 439        filename = ATH11K_BOARD_API2_FILE;
 440
 441        if (!bd->fw)
 442                bd->fw = ath11k_core_firmware_request(ab, filename);
 443
 444        if (IS_ERR(bd->fw))
 445                return PTR_ERR(bd->fw);
 446
 447        data = bd->fw->data;
 448        len = bd->fw->size;
 449
 450        ath11k_core_create_firmware_path(ab, filename,
 451                                         filepath, sizeof(filepath));
 452
 453        /* magic has extra null byte padded */
 454        magic_len = strlen(ATH11K_BOARD_MAGIC) + 1;
 455        if (len < magic_len) {
 456                ath11k_err(ab, "failed to find magic value in %s, file too short: %zu\n",
 457                           filepath, len);
 458                ret = -EINVAL;
 459                goto err;
 460        }
 461
 462        if (memcmp(data, ATH11K_BOARD_MAGIC, magic_len)) {
 463                ath11k_err(ab, "found invalid board magic\n");
 464                ret = -EINVAL;
 465                goto err;
 466        }
 467
 468        /* magic is padded to 4 bytes */
 469        magic_len = ALIGN(magic_len, 4);
 470        if (len < magic_len) {
 471                ath11k_err(ab, "failed: %s too small to contain board data, len: %zu\n",
 472                           filepath, len);
 473                ret = -EINVAL;
 474                goto err;
 475        }
 476
 477        data += magic_len;
 478        len -= magic_len;
 479
 480        while (len > sizeof(struct ath11k_fw_ie)) {
 481                hdr = (struct ath11k_fw_ie *)data;
 482                ie_id = le32_to_cpu(hdr->id);
 483                ie_len = le32_to_cpu(hdr->len);
 484
 485                len -= sizeof(*hdr);
 486                data = hdr->data;
 487
 488                if (len < ALIGN(ie_len, 4)) {
 489                        ath11k_err(ab, "invalid length for board ie_id %d ie_len %zu len %zu\n",
 490                                   ie_id, ie_len, len);
 491                        return -EINVAL;
 492                }
 493
 494                switch (ie_id) {
 495                case ATH11K_BD_IE_BOARD:
 496                        ret = ath11k_core_parse_bd_ie_board(ab, bd, data,
 497                                                            ie_len,
 498                                                            boardname,
 499                                                            ATH11K_BD_IE_BOARD);
 500                        if (ret == -ENOENT)
 501                                /* no match found, continue */
 502                                break;
 503                        else if (ret)
 504                                /* there was an error, bail out */
 505                                goto err;
 506                        /* either found or error, so stop searching */
 507                        goto out;
 508                }
 509
 510                /* jump over the padding */
 511                ie_len = ALIGN(ie_len, 4);
 512
 513                len -= ie_len;
 514                data += ie_len;
 515        }
 516
 517out:
 518        if (!bd->data || !bd->len) {
 519                ath11k_err(ab,
 520                           "failed to fetch board data for %s from %s\n",
 521                           boardname, filepath);
 522                ret = -ENODATA;
 523                goto err;
 524        }
 525
 526        return 0;
 527
 528err:
 529        ath11k_core_free_bdf(ab, bd);
 530        return ret;
 531}
 532
 533static int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab,
 534                                              struct ath11k_board_data *bd)
 535{
 536        bd->fw = ath11k_core_firmware_request(ab, ATH11K_DEFAULT_BOARD_FILE);
 537        if (IS_ERR(bd->fw))
 538                return PTR_ERR(bd->fw);
 539
 540        bd->data = bd->fw->data;
 541        bd->len = bd->fw->size;
 542
 543        return 0;
 544}
 545
 546#define BOARD_NAME_SIZE 100
 547int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd)
 548{
 549        char boardname[BOARD_NAME_SIZE];
 550        int ret;
 551
 552        ret = ath11k_core_create_board_name(ab, boardname, BOARD_NAME_SIZE);
 553        if (ret) {
 554                ath11k_err(ab, "failed to create board name: %d", ret);
 555                return ret;
 556        }
 557
 558        ab->bd_api = 2;
 559        ret = ath11k_core_fetch_board_data_api_n(ab, bd, boardname);
 560        if (!ret)
 561                goto success;
 562
 563        ab->bd_api = 1;
 564        ret = ath11k_core_fetch_board_data_api_1(ab, bd);
 565        if (ret) {
 566                ath11k_err(ab, "failed to fetch board-2.bin or board.bin from %s\n",
 567                           ab->hw_params.fw.dir);
 568                return ret;
 569        }
 570
 571success:
 572        ath11k_dbg(ab, ATH11K_DBG_BOOT, "using board api %d\n", ab->bd_api);
 573        return 0;
 574}
 575
 576static void ath11k_core_stop(struct ath11k_base *ab)
 577{
 578        if (!test_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags))
 579                ath11k_qmi_firmware_stop(ab);
 580
 581        ath11k_hif_stop(ab);
 582        ath11k_wmi_detach(ab);
 583        ath11k_dp_pdev_reo_cleanup(ab);
 584
 585        /* De-Init of components as needed */
 586}
 587
 588static int ath11k_core_soc_create(struct ath11k_base *ab)
 589{
 590        int ret;
 591
 592        ret = ath11k_qmi_init_service(ab);
 593        if (ret) {
 594                ath11k_err(ab, "failed to initialize qmi :%d\n", ret);
 595                return ret;
 596        }
 597
 598        ret = ath11k_debugfs_soc_create(ab);
 599        if (ret) {
 600                ath11k_err(ab, "failed to create ath11k debugfs\n");
 601                goto err_qmi_deinit;
 602        }
 603
 604        ret = ath11k_hif_power_up(ab);
 605        if (ret) {
 606                ath11k_err(ab, "failed to power up :%d\n", ret);
 607                goto err_debugfs_reg;
 608        }
 609
 610        return 0;
 611
 612err_debugfs_reg:
 613        ath11k_debugfs_soc_destroy(ab);
 614err_qmi_deinit:
 615        ath11k_qmi_deinit_service(ab);
 616        return ret;
 617}
 618
 619static void ath11k_core_soc_destroy(struct ath11k_base *ab)
 620{
 621        ath11k_debugfs_soc_destroy(ab);
 622        ath11k_dp_free(ab);
 623        ath11k_reg_free(ab);
 624        ath11k_qmi_deinit_service(ab);
 625}
 626
 627static int ath11k_core_pdev_create(struct ath11k_base *ab)
 628{
 629        int ret;
 630
 631        ret = ath11k_debugfs_pdev_create(ab);
 632        if (ret) {
 633                ath11k_err(ab, "failed to create core pdev debugfs: %d\n", ret);
 634                return ret;
 635        }
 636
 637        ret = ath11k_mac_register(ab);
 638        if (ret) {
 639                ath11k_err(ab, "failed register the radio with mac80211: %d\n", ret);
 640                goto err_pdev_debug;
 641        }
 642
 643        ret = ath11k_dp_pdev_alloc(ab);
 644        if (ret) {
 645                ath11k_err(ab, "failed to attach DP pdev: %d\n", ret);
 646                goto err_mac_unregister;
 647        }
 648
 649        ret = ath11k_thermal_register(ab);
 650        if (ret) {
 651                ath11k_err(ab, "could not register thermal device: %d\n",
 652                           ret);
 653                goto err_dp_pdev_free;
 654        }
 655
 656        ret = ath11k_spectral_init(ab);
 657        if (ret) {
 658                ath11k_err(ab, "failed to init spectral %d\n", ret);
 659                goto err_thermal_unregister;
 660        }
 661
 662        return 0;
 663
 664err_thermal_unregister:
 665        ath11k_thermal_unregister(ab);
 666err_dp_pdev_free:
 667        ath11k_dp_pdev_free(ab);
 668err_mac_unregister:
 669        ath11k_mac_unregister(ab);
 670err_pdev_debug:
 671        ath11k_debugfs_pdev_destroy(ab);
 672
 673        return ret;
 674}
 675
 676static void ath11k_core_pdev_destroy(struct ath11k_base *ab)
 677{
 678        ath11k_spectral_deinit(ab);
 679        ath11k_thermal_unregister(ab);
 680        ath11k_mac_unregister(ab);
 681        ath11k_hif_irq_disable(ab);
 682        ath11k_dp_pdev_free(ab);
 683        ath11k_debugfs_pdev_destroy(ab);
 684}
 685
 686static int ath11k_core_start(struct ath11k_base *ab,
 687                             enum ath11k_firmware_mode mode)
 688{
 689        int ret;
 690
 691        ret = ath11k_qmi_firmware_start(ab, mode);
 692        if (ret) {
 693                ath11k_err(ab, "failed to attach wmi: %d\n", ret);
 694                return ret;
 695        }
 696
 697        ret = ath11k_wmi_attach(ab);
 698        if (ret) {
 699                ath11k_err(ab, "failed to attach wmi: %d\n", ret);
 700                goto err_firmware_stop;
 701        }
 702
 703        ret = ath11k_htc_init(ab);
 704        if (ret) {
 705                ath11k_err(ab, "failed to init htc: %d\n", ret);
 706                goto err_wmi_detach;
 707        }
 708
 709        ret = ath11k_hif_start(ab);
 710        if (ret) {
 711                ath11k_err(ab, "failed to start HIF: %d\n", ret);
 712                goto err_wmi_detach;
 713        }
 714
 715        ret = ath11k_htc_wait_target(&ab->htc);
 716        if (ret) {
 717                ath11k_err(ab, "failed to connect to HTC: %d\n", ret);
 718                goto err_hif_stop;
 719        }
 720
 721        ret = ath11k_dp_htt_connect(&ab->dp);
 722        if (ret) {
 723                ath11k_err(ab, "failed to connect to HTT: %d\n", ret);
 724                goto err_hif_stop;
 725        }
 726
 727        ret = ath11k_wmi_connect(ab);
 728        if (ret) {
 729                ath11k_err(ab, "failed to connect wmi: %d\n", ret);
 730                goto err_hif_stop;
 731        }
 732
 733        ret = ath11k_htc_start(&ab->htc);
 734        if (ret) {
 735                ath11k_err(ab, "failed to start HTC: %d\n", ret);
 736                goto err_hif_stop;
 737        }
 738
 739        ret = ath11k_wmi_wait_for_service_ready(ab);
 740        if (ret) {
 741                ath11k_err(ab, "failed to receive wmi service ready event: %d\n",
 742                           ret);
 743                goto err_hif_stop;
 744        }
 745
 746        ret = ath11k_mac_allocate(ab);
 747        if (ret) {
 748                ath11k_err(ab, "failed to create new hw device with mac80211 :%d\n",
 749                           ret);
 750                goto err_hif_stop;
 751        }
 752
 753        ath11k_dp_pdev_pre_alloc(ab);
 754
 755        ret = ath11k_dp_pdev_reo_setup(ab);
 756        if (ret) {
 757                ath11k_err(ab, "failed to initialize reo destination rings: %d\n", ret);
 758                goto err_mac_destroy;
 759        }
 760
 761        ret = ath11k_wmi_cmd_init(ab);
 762        if (ret) {
 763                ath11k_err(ab, "failed to send wmi init cmd: %d\n", ret);
 764                goto err_reo_cleanup;
 765        }
 766
 767        ret = ath11k_wmi_wait_for_unified_ready(ab);
 768        if (ret) {
 769                ath11k_err(ab, "failed to receive wmi unified ready event: %d\n",
 770                           ret);
 771                goto err_reo_cleanup;
 772        }
 773
 774        /* put hardware to DBS mode */
 775        if (ab->hw_params.single_pdev_only) {
 776                ret = ath11k_wmi_set_hw_mode(ab, WMI_HOST_HW_MODE_DBS);
 777                if (ret) {
 778                        ath11k_err(ab, "failed to send dbs mode: %d\n", ret);
 779                        goto err_hif_stop;
 780                }
 781        }
 782
 783        ret = ath11k_dp_tx_htt_h2t_ver_req_msg(ab);
 784        if (ret) {
 785                ath11k_err(ab, "failed to send htt version request message: %d\n",
 786                           ret);
 787                goto err_reo_cleanup;
 788        }
 789
 790        return 0;
 791
 792err_reo_cleanup:
 793        ath11k_dp_pdev_reo_cleanup(ab);
 794err_mac_destroy:
 795        ath11k_mac_destroy(ab);
 796err_hif_stop:
 797        ath11k_hif_stop(ab);
 798err_wmi_detach:
 799        ath11k_wmi_detach(ab);
 800err_firmware_stop:
 801        ath11k_qmi_firmware_stop(ab);
 802
 803        return ret;
 804}
 805
 806int ath11k_core_qmi_firmware_ready(struct ath11k_base *ab)
 807{
 808        int ret;
 809
 810        ret = ath11k_ce_init_pipes(ab);
 811        if (ret) {
 812                ath11k_err(ab, "failed to initialize CE: %d\n", ret);
 813                return ret;
 814        }
 815
 816        ret = ath11k_dp_alloc(ab);
 817        if (ret) {
 818                ath11k_err(ab, "failed to init DP: %d\n", ret);
 819                return ret;
 820        }
 821
 822        switch (ath11k_crypto_mode) {
 823        case ATH11K_CRYPT_MODE_SW:
 824                set_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
 825                set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
 826                break;
 827        case ATH11K_CRYPT_MODE_HW:
 828                clear_bit(ATH11K_FLAG_HW_CRYPTO_DISABLED, &ab->dev_flags);
 829                clear_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
 830                break;
 831        default:
 832                ath11k_info(ab, "invalid crypto_mode: %d\n", ath11k_crypto_mode);
 833                return -EINVAL;
 834        }
 835
 836        if (ath11k_frame_mode == ATH11K_HW_TXRX_RAW)
 837                set_bit(ATH11K_FLAG_RAW_MODE, &ab->dev_flags);
 838
 839        mutex_lock(&ab->core_lock);
 840        ret = ath11k_core_start(ab, ATH11K_FIRMWARE_MODE_NORMAL);
 841        if (ret) {
 842                ath11k_err(ab, "failed to start core: %d\n", ret);
 843                goto err_dp_free;
 844        }
 845
 846        ret = ath11k_core_pdev_create(ab);
 847        if (ret) {
 848                ath11k_err(ab, "failed to create pdev core: %d\n", ret);
 849                goto err_core_stop;
 850        }
 851        ath11k_hif_irq_enable(ab);
 852        mutex_unlock(&ab->core_lock);
 853
 854        return 0;
 855
 856err_core_stop:
 857        ath11k_core_stop(ab);
 858        ath11k_mac_destroy(ab);
 859err_dp_free:
 860        ath11k_dp_free(ab);
 861        mutex_unlock(&ab->core_lock);
 862        return ret;
 863}
 864
 865static int ath11k_core_reconfigure_on_crash(struct ath11k_base *ab)
 866{
 867        int ret;
 868
 869        mutex_lock(&ab->core_lock);
 870        ath11k_thermal_unregister(ab);
 871        ath11k_hif_irq_disable(ab);
 872        ath11k_dp_pdev_free(ab);
 873        ath11k_spectral_deinit(ab);
 874        ath11k_hif_stop(ab);
 875        ath11k_wmi_detach(ab);
 876        ath11k_dp_pdev_reo_cleanup(ab);
 877        mutex_unlock(&ab->core_lock);
 878
 879        ath11k_dp_free(ab);
 880        ath11k_hal_srng_deinit(ab);
 881
 882        ab->free_vdev_map = (1LL << (ab->num_radios * TARGET_NUM_VDEVS)) - 1;
 883
 884        ret = ath11k_hal_srng_init(ab);
 885        if (ret)
 886                return ret;
 887
 888        clear_bit(ATH11K_FLAG_CRASH_FLUSH, &ab->dev_flags);
 889
 890        ret = ath11k_core_qmi_firmware_ready(ab);
 891        if (ret)
 892                goto err_hal_srng_deinit;
 893
 894        clear_bit(ATH11K_FLAG_RECOVERY, &ab->dev_flags);
 895
 896        return 0;
 897
 898err_hal_srng_deinit:
 899        ath11k_hal_srng_deinit(ab);
 900        return ret;
 901}
 902
 903void ath11k_core_halt(struct ath11k *ar)
 904{
 905        struct ath11k_base *ab = ar->ab;
 906
 907        lockdep_assert_held(&ar->conf_mutex);
 908
 909        ar->num_created_vdevs = 0;
 910        ar->allocated_vdev_map = 0;
 911
 912        ath11k_mac_scan_finish(ar);
 913        ath11k_mac_peer_cleanup_all(ar);
 914        cancel_delayed_work_sync(&ar->scan.timeout);
 915        cancel_work_sync(&ar->regd_update_work);
 916
 917        rcu_assign_pointer(ab->pdevs_active[ar->pdev_idx], NULL);
 918        synchronize_rcu();
 919        INIT_LIST_HEAD(&ar->arvifs);
 920        idr_init(&ar->txmgmt_idr);
 921}
 922
 923static void ath11k_core_restart(struct work_struct *work)
 924{
 925        struct ath11k_base *ab = container_of(work, struct ath11k_base, restart_work);
 926        struct ath11k *ar;
 927        struct ath11k_pdev *pdev;
 928        int i, ret = 0;
 929
 930        spin_lock_bh(&ab->base_lock);
 931        ab->stats.fw_crash_counter++;
 932        spin_unlock_bh(&ab->base_lock);
 933
 934        for (i = 0; i < ab->num_radios; i++) {
 935                pdev = &ab->pdevs[i];
 936                ar = pdev->ar;
 937                if (!ar || ar->state == ATH11K_STATE_OFF)
 938                        continue;
 939
 940                ieee80211_stop_queues(ar->hw);
 941                ath11k_mac_drain_tx(ar);
 942                complete(&ar->scan.started);
 943                complete(&ar->scan.completed);
 944                complete(&ar->peer_assoc_done);
 945                complete(&ar->peer_delete_done);
 946                complete(&ar->install_key_done);
 947                complete(&ar->vdev_setup_done);
 948                complete(&ar->vdev_delete_done);
 949                complete(&ar->bss_survey_done);
 950                complete(&ar->thermal.wmi_sync);
 951
 952                wake_up(&ar->dp.tx_empty_waitq);
 953                idr_for_each(&ar->txmgmt_idr,
 954                             ath11k_mac_tx_mgmt_pending_free, ar);
 955                idr_destroy(&ar->txmgmt_idr);
 956        }
 957
 958        wake_up(&ab->wmi_ab.tx_credits_wq);
 959        wake_up(&ab->peer_mapping_wq);
 960
 961        ret = ath11k_core_reconfigure_on_crash(ab);
 962        if (ret) {
 963                ath11k_err(ab, "failed to reconfigure driver on crash recovery\n");
 964                return;
 965        }
 966
 967        for (i = 0; i < ab->num_radios; i++) {
 968                pdev = &ab->pdevs[i];
 969                ar = pdev->ar;
 970                if (!ar || ar->state == ATH11K_STATE_OFF)
 971                        continue;
 972
 973                mutex_lock(&ar->conf_mutex);
 974
 975                switch (ar->state) {
 976                case ATH11K_STATE_ON:
 977                        ar->state = ATH11K_STATE_RESTARTING;
 978                        ath11k_core_halt(ar);
 979                        ieee80211_restart_hw(ar->hw);
 980                        break;
 981                case ATH11K_STATE_OFF:
 982                        ath11k_warn(ab,
 983                                    "cannot restart radio %d that hasn't been started\n",
 984                                    i);
 985                        break;
 986                case ATH11K_STATE_RESTARTING:
 987                        break;
 988                case ATH11K_STATE_RESTARTED:
 989                        ar->state = ATH11K_STATE_WEDGED;
 990                        fallthrough;
 991                case ATH11K_STATE_WEDGED:
 992                        ath11k_warn(ab,
 993                                    "device is wedged, will not restart radio %d\n", i);
 994                        break;
 995                }
 996                mutex_unlock(&ar->conf_mutex);
 997        }
 998        complete(&ab->driver_recovery);
 999}
1000
1001static int ath11k_init_hw_params(struct ath11k_base *ab)
1002{
1003        const struct ath11k_hw_params *hw_params = NULL;
1004        int i;
1005
1006        for (i = 0; i < ARRAY_SIZE(ath11k_hw_params); i++) {
1007                hw_params = &ath11k_hw_params[i];
1008
1009                if (hw_params->hw_rev == ab->hw_rev)
1010                        break;
1011        }
1012
1013        if (i == ARRAY_SIZE(ath11k_hw_params)) {
1014                ath11k_err(ab, "Unsupported hardware version: 0x%x\n", ab->hw_rev);
1015                return -EINVAL;
1016        }
1017
1018        ab->hw_params = *hw_params;
1019
1020        ath11k_info(ab, "%s\n", ab->hw_params.name);
1021
1022        return 0;
1023}
1024
1025int ath11k_core_pre_init(struct ath11k_base *ab)
1026{
1027        int ret;
1028
1029        ret = ath11k_init_hw_params(ab);
1030        if (ret) {
1031                ath11k_err(ab, "failed to get hw params: %d\n", ret);
1032                return ret;
1033        }
1034
1035        return 0;
1036}
1037EXPORT_SYMBOL(ath11k_core_pre_init);
1038
1039int ath11k_core_init(struct ath11k_base *ab)
1040{
1041        int ret;
1042
1043        ret = ath11k_core_soc_create(ab);
1044        if (ret) {
1045                ath11k_err(ab, "failed to create soc core: %d\n", ret);
1046                return ret;
1047        }
1048
1049        return 0;
1050}
1051EXPORT_SYMBOL(ath11k_core_init);
1052
1053void ath11k_core_deinit(struct ath11k_base *ab)
1054{
1055        mutex_lock(&ab->core_lock);
1056
1057        ath11k_core_pdev_destroy(ab);
1058        ath11k_core_stop(ab);
1059
1060        mutex_unlock(&ab->core_lock);
1061
1062        ath11k_hif_power_down(ab);
1063        ath11k_mac_destroy(ab);
1064        ath11k_core_soc_destroy(ab);
1065}
1066EXPORT_SYMBOL(ath11k_core_deinit);
1067
1068void ath11k_core_free(struct ath11k_base *ab)
1069{
1070        kfree(ab);
1071}
1072EXPORT_SYMBOL(ath11k_core_free);
1073
1074struct ath11k_base *ath11k_core_alloc(struct device *dev, size_t priv_size,
1075                                      enum ath11k_bus bus,
1076                                      const struct ath11k_bus_params *bus_params)
1077{
1078        struct ath11k_base *ab;
1079
1080        ab = kzalloc(sizeof(*ab) + priv_size, GFP_KERNEL);
1081        if (!ab)
1082                return NULL;
1083
1084        init_completion(&ab->driver_recovery);
1085
1086        ab->workqueue = create_singlethread_workqueue("ath11k_wq");
1087        if (!ab->workqueue)
1088                goto err_sc_free;
1089
1090        mutex_init(&ab->core_lock);
1091        spin_lock_init(&ab->base_lock);
1092
1093        INIT_LIST_HEAD(&ab->peers);
1094        init_waitqueue_head(&ab->peer_mapping_wq);
1095        init_waitqueue_head(&ab->wmi_ab.tx_credits_wq);
1096        init_waitqueue_head(&ab->qmi.cold_boot_waitq);
1097        INIT_WORK(&ab->restart_work, ath11k_core_restart);
1098        timer_setup(&ab->rx_replenish_retry, ath11k_ce_rx_replenish_retry, 0);
1099        init_completion(&ab->htc_suspend);
1100        init_completion(&ab->wow.wakeup_completed);
1101
1102        ab->dev = dev;
1103        ab->bus_params = *bus_params;
1104        ab->hif.bus = bus;
1105
1106        return ab;
1107
1108err_sc_free:
1109        kfree(ab);
1110        return NULL;
1111}
1112EXPORT_SYMBOL(ath11k_core_alloc);
1113
1114MODULE_DESCRIPTION("Core module for Qualcomm Atheros 802.11ax wireless LAN cards.");
1115MODULE_LICENSE("Dual BSD/GPL");
1116