linux/drivers/net/wireless/ath/ath10k/core.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2005-2011 Atheros Communications Inc.
   3 * Copyright (c) 2011-2013 Qualcomm Atheros, Inc.
   4 *
   5 * Permission to use, copy, modify, and/or distribute this software for any
   6 * purpose with or without fee is hereby granted, provided that the above
   7 * copyright notice and this permission notice appear in all copies.
   8 *
   9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16 */
  17
  18#include <linux/module.h>
  19#include <linux/firmware.h>
  20
  21#include "core.h"
  22#include "mac.h"
  23#include "htc.h"
  24#include "hif.h"
  25#include "wmi.h"
  26#include "bmi.h"
  27#include "debug.h"
  28#include "htt.h"
  29
  30unsigned int ath10k_debug_mask;
  31static bool uart_print;
  32static unsigned int ath10k_p2p;
  33module_param_named(debug_mask, ath10k_debug_mask, uint, 0644);
  34module_param(uart_print, bool, 0644);
  35module_param_named(p2p, ath10k_p2p, uint, 0644);
  36MODULE_PARM_DESC(debug_mask, "Debugging mask");
  37MODULE_PARM_DESC(uart_print, "Uart target debugging");
  38MODULE_PARM_DESC(p2p, "Enable ath10k P2P support");
  39
  40static const struct ath10k_hw_params ath10k_hw_params_list[] = {
  41        {
  42                .id = QCA988X_HW_1_0_VERSION,
  43                .name = "qca988x hw1.0",
  44                .patch_load_addr = QCA988X_HW_1_0_PATCH_LOAD_ADDR,
  45                .fw = {
  46                        .dir = QCA988X_HW_1_0_FW_DIR,
  47                        .fw = QCA988X_HW_1_0_FW_FILE,
  48                        .otp = QCA988X_HW_1_0_OTP_FILE,
  49                        .board = QCA988X_HW_1_0_BOARD_DATA_FILE,
  50                },
  51        },
  52        {
  53                .id = QCA988X_HW_2_0_VERSION,
  54                .name = "qca988x hw2.0",
  55                .patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
  56                .fw = {
  57                        .dir = QCA988X_HW_2_0_FW_DIR,
  58                        .fw = QCA988X_HW_2_0_FW_FILE,
  59                        .otp = QCA988X_HW_2_0_OTP_FILE,
  60                        .board = QCA988X_HW_2_0_BOARD_DATA_FILE,
  61                },
  62        },
  63};
  64
  65static void ath10k_send_suspend_complete(struct ath10k *ar)
  66{
  67        ath10k_dbg(ATH10K_DBG_CORE, "%s\n", __func__);
  68
  69        ar->is_target_paused = true;
  70        wake_up(&ar->event_queue);
  71}
  72
  73static int ath10k_check_fw_version(struct ath10k *ar)
  74{
  75        char version[32];
  76
  77        if (ar->fw_version_major >= SUPPORTED_FW_MAJOR &&
  78            ar->fw_version_minor >= SUPPORTED_FW_MINOR &&
  79            ar->fw_version_release >= SUPPORTED_FW_RELEASE &&
  80            ar->fw_version_build >= SUPPORTED_FW_BUILD)
  81                return 0;
  82
  83        snprintf(version, sizeof(version), "%u.%u.%u.%u",
  84                 SUPPORTED_FW_MAJOR, SUPPORTED_FW_MINOR,
  85                 SUPPORTED_FW_RELEASE, SUPPORTED_FW_BUILD);
  86
  87        ath10k_warn("WARNING: Firmware version %s is not officially supported.\n",
  88                    ar->hw->wiphy->fw_version);
  89        ath10k_warn("Please upgrade to version %s (or newer)\n", version);
  90
  91        return 0;
  92}
  93
  94static int ath10k_init_connect_htc(struct ath10k *ar)
  95{
  96        int status;
  97
  98        status = ath10k_wmi_connect_htc_service(ar);
  99        if (status)
 100                goto conn_fail;
 101
 102        /* Start HTC */
 103        status = ath10k_htc_start(&ar->htc);
 104        if (status)
 105                goto conn_fail;
 106
 107        /* Wait for WMI event to be ready */
 108        status = ath10k_wmi_wait_for_service_ready(ar);
 109        if (status <= 0) {
 110                ath10k_warn("wmi service ready event not received");
 111                status = -ETIMEDOUT;
 112                goto timeout;
 113        }
 114
 115        ath10k_dbg(ATH10K_DBG_CORE, "core wmi ready\n");
 116        return 0;
 117
 118timeout:
 119        ath10k_htc_stop(&ar->htc);
 120conn_fail:
 121        return status;
 122}
 123
 124static int ath10k_init_configure_target(struct ath10k *ar)
 125{
 126        u32 param_host;
 127        int ret;
 128
 129        /* tell target which HTC version it is used*/
 130        ret = ath10k_bmi_write32(ar, hi_app_host_interest,
 131                                 HTC_PROTOCOL_VERSION);
 132        if (ret) {
 133                ath10k_err("settings HTC version failed\n");
 134                return ret;
 135        }
 136
 137        /* set the firmware mode to STA/IBSS/AP */
 138        ret = ath10k_bmi_read32(ar, hi_option_flag, &param_host);
 139        if (ret) {
 140                ath10k_err("setting firmware mode (1/2) failed\n");
 141                return ret;
 142        }
 143
 144        /* TODO following parameters need to be re-visited. */
 145        /* num_device */
 146        param_host |= (1 << HI_OPTION_NUM_DEV_SHIFT);
 147        /* Firmware mode */
 148        /* FIXME: Why FW_MODE_AP ??.*/
 149        param_host |= (HI_OPTION_FW_MODE_AP << HI_OPTION_FW_MODE_SHIFT);
 150        /* mac_addr_method */
 151        param_host |= (1 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
 152        /* firmware_bridge */
 153        param_host |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
 154        /* fwsubmode */
 155        param_host |= (0 << HI_OPTION_FW_SUBMODE_SHIFT);
 156
 157        ret = ath10k_bmi_write32(ar, hi_option_flag, param_host);
 158        if (ret) {
 159                ath10k_err("setting firmware mode (2/2) failed\n");
 160                return ret;
 161        }
 162
 163        /* We do all byte-swapping on the host */
 164        ret = ath10k_bmi_write32(ar, hi_be, 0);
 165        if (ret) {
 166                ath10k_err("setting host CPU BE mode failed\n");
 167                return ret;
 168        }
 169
 170        /* FW descriptor/Data swap flags */
 171        ret = ath10k_bmi_write32(ar, hi_fw_swap, 0);
 172
 173        if (ret) {
 174                ath10k_err("setting FW data/desc swap flags failed\n");
 175                return ret;
 176        }
 177
 178        return 0;
 179}
 180
 181static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
 182                                                   const char *dir,
 183                                                   const char *file)
 184{
 185        char filename[100];
 186        const struct firmware *fw;
 187        int ret;
 188
 189        if (file == NULL)
 190                return ERR_PTR(-ENOENT);
 191
 192        if (dir == NULL)
 193                dir = ".";
 194
 195        snprintf(filename, sizeof(filename), "%s/%s", dir, file);
 196        ret = request_firmware(&fw, filename, ar->dev);
 197        if (ret)
 198                return ERR_PTR(ret);
 199
 200        return fw;
 201}
 202
 203static int ath10k_push_board_ext_data(struct ath10k *ar,
 204                                      const struct firmware *fw)
 205{
 206        u32 board_data_size = QCA988X_BOARD_DATA_SZ;
 207        u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ;
 208        u32 board_ext_data_addr;
 209        int ret;
 210
 211        ret = ath10k_bmi_read32(ar, hi_board_ext_data, &board_ext_data_addr);
 212        if (ret) {
 213                ath10k_err("could not read board ext data addr (%d)\n", ret);
 214                return ret;
 215        }
 216
 217        ath10k_dbg(ATH10K_DBG_CORE,
 218                   "ath10k: Board extended Data download addr: 0x%x\n",
 219                   board_ext_data_addr);
 220
 221        if (board_ext_data_addr == 0)
 222                return 0;
 223
 224        if (fw->size != (board_data_size + board_ext_data_size)) {
 225                ath10k_err("invalid board (ext) data sizes %zu != %d+%d\n",
 226                           fw->size, board_data_size, board_ext_data_size);
 227                return -EINVAL;
 228        }
 229
 230        ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
 231                                      fw->data + board_data_size,
 232                                      board_ext_data_size);
 233        if (ret) {
 234                ath10k_err("could not write board ext data (%d)\n", ret);
 235                return ret;
 236        }
 237
 238        ret = ath10k_bmi_write32(ar, hi_board_ext_data_config,
 239                                 (board_ext_data_size << 16) | 1);
 240        if (ret) {
 241                ath10k_err("could not write board ext data bit (%d)\n", ret);
 242                return ret;
 243        }
 244
 245        return 0;
 246}
 247
 248static int ath10k_download_board_data(struct ath10k *ar)
 249{
 250        const struct firmware *fw = ar->board_data;
 251        u32 board_data_size = QCA988X_BOARD_DATA_SZ;
 252        u32 address;
 253        int ret;
 254
 255        ret = ath10k_push_board_ext_data(ar, fw);
 256        if (ret) {
 257                ath10k_err("could not push board ext data (%d)\n", ret);
 258                goto exit;
 259        }
 260
 261        ret = ath10k_bmi_read32(ar, hi_board_data, &address);
 262        if (ret) {
 263                ath10k_err("could not read board data addr (%d)\n", ret);
 264                goto exit;
 265        }
 266
 267        ret = ath10k_bmi_write_memory(ar, address, fw->data,
 268                                      min_t(u32, board_data_size, fw->size));
 269        if (ret) {
 270                ath10k_err("could not write board data (%d)\n", ret);
 271                goto exit;
 272        }
 273
 274        ret = ath10k_bmi_write32(ar, hi_board_data_initialized, 1);
 275        if (ret) {
 276                ath10k_err("could not write board data bit (%d)\n", ret);
 277                goto exit;
 278        }
 279
 280exit:
 281        return ret;
 282}
 283
 284static int ath10k_download_and_run_otp(struct ath10k *ar)
 285{
 286        const struct firmware *fw = ar->otp;
 287        u32 address = ar->hw_params.patch_load_addr;
 288        u32 exec_param;
 289        int ret;
 290
 291        /* OTP is optional */
 292
 293        if (!ar->otp)
 294                return 0;
 295
 296        ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size);
 297        if (ret) {
 298                ath10k_err("could not write otp (%d)\n", ret);
 299                goto exit;
 300        }
 301
 302        exec_param = 0;
 303        ret = ath10k_bmi_execute(ar, address, &exec_param);
 304        if (ret) {
 305                ath10k_err("could not execute otp (%d)\n", ret);
 306                goto exit;
 307        }
 308
 309exit:
 310        return ret;
 311}
 312
 313static int ath10k_download_fw(struct ath10k *ar)
 314{
 315        const struct firmware *fw = ar->firmware;
 316        u32 address;
 317        int ret;
 318
 319        address = ar->hw_params.patch_load_addr;
 320
 321        ret = ath10k_bmi_fast_download(ar, address, fw->data, fw->size);
 322        if (ret) {
 323                ath10k_err("could not write fw (%d)\n", ret);
 324                goto exit;
 325        }
 326
 327exit:
 328        return ret;
 329}
 330
 331static void ath10k_core_free_firmware_files(struct ath10k *ar)
 332{
 333        if (ar->board_data && !IS_ERR(ar->board_data))
 334                release_firmware(ar->board_data);
 335
 336        if (ar->otp && !IS_ERR(ar->otp))
 337                release_firmware(ar->otp);
 338
 339        if (ar->firmware && !IS_ERR(ar->firmware))
 340                release_firmware(ar->firmware);
 341
 342        ar->board_data = NULL;
 343        ar->otp = NULL;
 344        ar->firmware = NULL;
 345}
 346
 347static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
 348{
 349        int ret = 0;
 350
 351        if (ar->hw_params.fw.fw == NULL) {
 352                ath10k_err("firmware file not defined\n");
 353                return -EINVAL;
 354        }
 355
 356        if (ar->hw_params.fw.board == NULL) {
 357                ath10k_err("board data file not defined");
 358                return -EINVAL;
 359        }
 360
 361        ar->board_data = ath10k_fetch_fw_file(ar,
 362                                              ar->hw_params.fw.dir,
 363                                              ar->hw_params.fw.board);
 364        if (IS_ERR(ar->board_data)) {
 365                ret = PTR_ERR(ar->board_data);
 366                ath10k_err("could not fetch board data (%d)\n", ret);
 367                goto err;
 368        }
 369
 370        ar->firmware = ath10k_fetch_fw_file(ar,
 371                                            ar->hw_params.fw.dir,
 372                                            ar->hw_params.fw.fw);
 373        if (IS_ERR(ar->firmware)) {
 374                ret = PTR_ERR(ar->firmware);
 375                ath10k_err("could not fetch firmware (%d)\n", ret);
 376                goto err;
 377        }
 378
 379        /* OTP may be undefined. If so, don't fetch it at all */
 380        if (ar->hw_params.fw.otp == NULL)
 381                return 0;
 382
 383        ar->otp = ath10k_fetch_fw_file(ar,
 384                                       ar->hw_params.fw.dir,
 385                                       ar->hw_params.fw.otp);
 386        if (IS_ERR(ar->otp)) {
 387                ret = PTR_ERR(ar->otp);
 388                ath10k_err("could not fetch otp (%d)\n", ret);
 389                goto err;
 390        }
 391
 392        return 0;
 393
 394err:
 395        ath10k_core_free_firmware_files(ar);
 396        return ret;
 397}
 398
 399static int ath10k_init_download_firmware(struct ath10k *ar)
 400{
 401        int ret;
 402
 403        ret = ath10k_download_board_data(ar);
 404        if (ret)
 405                return ret;
 406
 407        ret = ath10k_download_and_run_otp(ar);
 408        if (ret)
 409                return ret;
 410
 411        ret = ath10k_download_fw(ar);
 412        if (ret)
 413                return ret;
 414
 415        return ret;
 416}
 417
 418static int ath10k_init_uart(struct ath10k *ar)
 419{
 420        int ret;
 421
 422        /*
 423         * Explicitly setting UART prints to zero as target turns it on
 424         * based on scratch registers.
 425         */
 426        ret = ath10k_bmi_write32(ar, hi_serial_enable, 0);
 427        if (ret) {
 428                ath10k_warn("could not disable UART prints (%d)\n", ret);
 429                return ret;
 430        }
 431
 432        if (!uart_print) {
 433                ath10k_info("UART prints disabled\n");
 434                return 0;
 435        }
 436
 437        ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, 7);
 438        if (ret) {
 439                ath10k_warn("could not enable UART prints (%d)\n", ret);
 440                return ret;
 441        }
 442
 443        ret = ath10k_bmi_write32(ar, hi_serial_enable, 1);
 444        if (ret) {
 445                ath10k_warn("could not enable UART prints (%d)\n", ret);
 446                return ret;
 447        }
 448
 449        ath10k_info("UART prints enabled\n");
 450        return 0;
 451}
 452
 453static int ath10k_init_hw_params(struct ath10k *ar)
 454{
 455        const struct ath10k_hw_params *uninitialized_var(hw_params);
 456        int i;
 457
 458        for (i = 0; i < ARRAY_SIZE(ath10k_hw_params_list); i++) {
 459                hw_params = &ath10k_hw_params_list[i];
 460
 461                if (hw_params->id == ar->target_version)
 462                        break;
 463        }
 464
 465        if (i == ARRAY_SIZE(ath10k_hw_params_list)) {
 466                ath10k_err("Unsupported hardware version: 0x%x\n",
 467                           ar->target_version);
 468                return -EINVAL;
 469        }
 470
 471        ar->hw_params = *hw_params;
 472
 473        ath10k_info("Hardware name %s version 0x%x\n",
 474                    ar->hw_params.name, ar->target_version);
 475
 476        return 0;
 477}
 478
 479static void ath10k_core_restart(struct work_struct *work)
 480{
 481        struct ath10k *ar = container_of(work, struct ath10k, restart_work);
 482
 483        mutex_lock(&ar->conf_mutex);
 484
 485        switch (ar->state) {
 486        case ATH10K_STATE_ON:
 487                ath10k_halt(ar);
 488                ar->state = ATH10K_STATE_RESTARTING;
 489                ieee80211_restart_hw(ar->hw);
 490                break;
 491        case ATH10K_STATE_OFF:
 492                /* this can happen if driver is being unloaded */
 493                ath10k_warn("cannot restart a device that hasn't been started\n");
 494                break;
 495        case ATH10K_STATE_RESTARTING:
 496        case ATH10K_STATE_RESTARTED:
 497                ar->state = ATH10K_STATE_WEDGED;
 498                /* fall through */
 499        case ATH10K_STATE_WEDGED:
 500                ath10k_warn("device is wedged, will not restart\n");
 501                break;
 502        }
 503
 504        mutex_unlock(&ar->conf_mutex);
 505}
 506
 507struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,
 508                                  const struct ath10k_hif_ops *hif_ops)
 509{
 510        struct ath10k *ar;
 511
 512        ar = ath10k_mac_create();
 513        if (!ar)
 514                return NULL;
 515
 516        ar->ath_common.priv = ar;
 517        ar->ath_common.hw = ar->hw;
 518
 519        ar->p2p = !!ath10k_p2p;
 520        ar->dev = dev;
 521
 522        ar->hif.priv = hif_priv;
 523        ar->hif.ops = hif_ops;
 524
 525        init_completion(&ar->scan.started);
 526        init_completion(&ar->scan.completed);
 527        init_completion(&ar->scan.on_channel);
 528
 529        init_completion(&ar->install_key_done);
 530        init_completion(&ar->vdev_setup_done);
 531
 532        setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar);
 533
 534        ar->workqueue = create_singlethread_workqueue("ath10k_wq");
 535        if (!ar->workqueue)
 536                goto err_wq;
 537
 538        mutex_init(&ar->conf_mutex);
 539        spin_lock_init(&ar->data_lock);
 540
 541        INIT_LIST_HEAD(&ar->peers);
 542        init_waitqueue_head(&ar->peer_mapping_wq);
 543
 544        init_completion(&ar->offchan_tx_completed);
 545        INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);
 546        skb_queue_head_init(&ar->offchan_tx_queue);
 547
 548        init_waitqueue_head(&ar->event_queue);
 549
 550        INIT_WORK(&ar->restart_work, ath10k_core_restart);
 551
 552        return ar;
 553
 554err_wq:
 555        ath10k_mac_destroy(ar);
 556        return NULL;
 557}
 558EXPORT_SYMBOL(ath10k_core_create);
 559
 560void ath10k_core_destroy(struct ath10k *ar)
 561{
 562        flush_workqueue(ar->workqueue);
 563        destroy_workqueue(ar->workqueue);
 564
 565        ath10k_mac_destroy(ar);
 566}
 567EXPORT_SYMBOL(ath10k_core_destroy);
 568
 569int ath10k_core_start(struct ath10k *ar)
 570{
 571        int status;
 572
 573        ath10k_bmi_start(ar);
 574
 575        if (ath10k_init_configure_target(ar)) {
 576                status = -EINVAL;
 577                goto err;
 578        }
 579
 580        status = ath10k_init_download_firmware(ar);
 581        if (status)
 582                goto err;
 583
 584        status = ath10k_init_uart(ar);
 585        if (status)
 586                goto err;
 587
 588        ar->htc.htc_ops.target_send_suspend_complete =
 589                ath10k_send_suspend_complete;
 590
 591        status = ath10k_htc_init(ar);
 592        if (status) {
 593                ath10k_err("could not init HTC (%d)\n", status);
 594                goto err;
 595        }
 596
 597        status = ath10k_bmi_done(ar);
 598        if (status)
 599                goto err;
 600
 601        status = ath10k_wmi_attach(ar);
 602        if (status) {
 603                ath10k_err("WMI attach failed: %d\n", status);
 604                goto err;
 605        }
 606
 607        status = ath10k_htc_wait_target(&ar->htc);
 608        if (status)
 609                goto err_wmi_detach;
 610
 611        status = ath10k_htt_attach(ar);
 612        if (status) {
 613                ath10k_err("could not attach htt (%d)\n", status);
 614                goto err_wmi_detach;
 615        }
 616
 617        status = ath10k_init_connect_htc(ar);
 618        if (status)
 619                goto err_htt_detach;
 620
 621        ath10k_info("firmware %s booted\n", ar->hw->wiphy->fw_version);
 622
 623        status = ath10k_check_fw_version(ar);
 624        if (status)
 625                goto err_disconnect_htc;
 626
 627        status = ath10k_wmi_cmd_init(ar);
 628        if (status) {
 629                ath10k_err("could not send WMI init command (%d)\n", status);
 630                goto err_disconnect_htc;
 631        }
 632
 633        status = ath10k_wmi_wait_for_unified_ready(ar);
 634        if (status <= 0) {
 635                ath10k_err("wmi unified ready event not received\n");
 636                status = -ETIMEDOUT;
 637                goto err_disconnect_htc;
 638        }
 639
 640        status = ath10k_htt_attach_target(&ar->htt);
 641        if (status)
 642                goto err_disconnect_htc;
 643
 644        ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;
 645
 646        return 0;
 647
 648err_disconnect_htc:
 649        ath10k_htc_stop(&ar->htc);
 650err_htt_detach:
 651        ath10k_htt_detach(&ar->htt);
 652err_wmi_detach:
 653        ath10k_wmi_detach(ar);
 654err:
 655        return status;
 656}
 657EXPORT_SYMBOL(ath10k_core_start);
 658
 659void ath10k_core_stop(struct ath10k *ar)
 660{
 661        ath10k_htc_stop(&ar->htc);
 662        ath10k_htt_detach(&ar->htt);
 663        ath10k_wmi_detach(ar);
 664}
 665EXPORT_SYMBOL(ath10k_core_stop);
 666
 667/* mac80211 manages fw/hw initialization through start/stop hooks. However in
 668 * order to know what hw capabilities should be advertised to mac80211 it is
 669 * necessary to load the firmware (and tear it down immediately since start
 670 * hook will try to init it again) before registering */
 671static int ath10k_core_probe_fw(struct ath10k *ar)
 672{
 673        struct bmi_target_info target_info;
 674        int ret = 0;
 675
 676        ret = ath10k_hif_power_up(ar);
 677        if (ret) {
 678                ath10k_err("could not start pci hif (%d)\n", ret);
 679                return ret;
 680        }
 681
 682        memset(&target_info, 0, sizeof(target_info));
 683        ret = ath10k_bmi_get_target_info(ar, &target_info);
 684        if (ret) {
 685                ath10k_err("could not get target info (%d)\n", ret);
 686                ath10k_hif_power_down(ar);
 687                return ret;
 688        }
 689
 690        ar->target_version = target_info.version;
 691        ar->hw->wiphy->hw_version = target_info.version;
 692
 693        ret = ath10k_init_hw_params(ar);
 694        if (ret) {
 695                ath10k_err("could not get hw params (%d)\n", ret);
 696                ath10k_hif_power_down(ar);
 697                return ret;
 698        }
 699
 700        ret = ath10k_core_fetch_firmware_files(ar);
 701        if (ret) {
 702                ath10k_err("could not fetch firmware files (%d)\n", ret);
 703                ath10k_hif_power_down(ar);
 704                return ret;
 705        }
 706
 707        ret = ath10k_core_start(ar);
 708        if (ret) {
 709                ath10k_err("could not init core (%d)\n", ret);
 710                ath10k_core_free_firmware_files(ar);
 711                ath10k_hif_power_down(ar);
 712                return ret;
 713        }
 714
 715        ath10k_core_stop(ar);
 716        ath10k_hif_power_down(ar);
 717        return 0;
 718}
 719
 720int ath10k_core_register(struct ath10k *ar)
 721{
 722        int status;
 723
 724        status = ath10k_core_probe_fw(ar);
 725        if (status) {
 726                ath10k_err("could not probe fw (%d)\n", status);
 727                return status;
 728        }
 729
 730        status = ath10k_mac_register(ar);
 731        if (status) {
 732                ath10k_err("could not register to mac80211 (%d)\n", status);
 733                goto err_release_fw;
 734        }
 735
 736        status = ath10k_debug_create(ar);
 737        if (status) {
 738                ath10k_err("unable to initialize debugfs\n");
 739                goto err_unregister_mac;
 740        }
 741
 742        return 0;
 743
 744err_unregister_mac:
 745        ath10k_mac_unregister(ar);
 746err_release_fw:
 747        ath10k_core_free_firmware_files(ar);
 748        return status;
 749}
 750EXPORT_SYMBOL(ath10k_core_register);
 751
 752void ath10k_core_unregister(struct ath10k *ar)
 753{
 754        /* We must unregister from mac80211 before we stop HTC and HIF.
 755         * Otherwise we will fail to submit commands to FW and mac80211 will be
 756         * unhappy about callback failures. */
 757        ath10k_mac_unregister(ar);
 758        ath10k_core_free_firmware_files(ar);
 759}
 760EXPORT_SYMBOL(ath10k_core_unregister);
 761
 762MODULE_AUTHOR("Qualcomm Atheros");
 763MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
 764MODULE_LICENSE("Dual BSD/GPL");
 765