linux/drivers/net/wireless/iwmc3200wifi/main.c
<<
>>
Prefs
   1/*
   2 * Intel Wireless Multicomm 3200 WiFi driver
   3 *
   4 * Copyright (C) 2009 Intel Corporation. All rights reserved.
   5 *
   6 * Redistribution and use in source and binary forms, with or without
   7 * modification, are permitted provided that the following conditions
   8 * are met:
   9 *
  10 *   * Redistributions of source code must retain the above copyright
  11 *     notice, this list of conditions and the following disclaimer.
  12 *   * Redistributions in binary form must reproduce the above copyright
  13 *     notice, this list of conditions and the following disclaimer in
  14 *     the documentation and/or other materials provided with the
  15 *     distribution.
  16 *   * Neither the name of Intel Corporation nor the names of its
  17 *     contributors may be used to endorse or promote products derived
  18 *     from this software without specific prior written permission.
  19 *
  20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31 *
  32 *
  33 * Intel Corporation <ilw@linux.intel.com>
  34 * Samuel Ortiz <samuel.ortiz@intel.com>
  35 * Zhu Yi <yi.zhu@intel.com>
  36 *
  37 */
  38
  39#include <linux/kernel.h>
  40#include <linux/netdevice.h>
  41#include <linux/sched.h>
  42#include <linux/ieee80211.h>
  43#include <linux/wireless.h>
  44
  45#include "iwm.h"
  46#include "debug.h"
  47#include "bus.h"
  48#include "umac.h"
  49#include "commands.h"
  50#include "hal.h"
  51#include "fw.h"
  52#include "rx.h"
  53
  54static struct iwm_conf def_iwm_conf = {
  55
  56        .sdio_ior_timeout       = 5000,
  57        .calib_map              = BIT(CALIB_CFG_DC_IDX) |
  58                                  BIT(CALIB_CFG_LO_IDX) |
  59                                  BIT(CALIB_CFG_TX_IQ_IDX)      |
  60                                  BIT(CALIB_CFG_RX_IQ_IDX)      |
  61                                  BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
  62        .expected_calib_map     = BIT(PHY_CALIBRATE_DC_CMD)     |
  63                                  BIT(PHY_CALIBRATE_LO_CMD)     |
  64                                  BIT(PHY_CALIBRATE_TX_IQ_CMD)  |
  65                                  BIT(PHY_CALIBRATE_RX_IQ_CMD)  |
  66                                  BIT(SHILOH_PHY_CALIBRATE_BASE_BAND_CMD),
  67        .reset_on_fatal_err     = 1,
  68        .auto_connect           = 1,
  69        .wimax_not_present      = 0,
  70        .enable_qos             = 1,
  71        .mode                   = UMAC_MODE_BSS,
  72
  73        /* UMAC configuration */
  74        .power_index            = 0,
  75        .frag_threshold         = IEEE80211_MAX_FRAG_THRESHOLD,
  76        .rts_threshold          = IEEE80211_MAX_RTS_THRESHOLD,
  77        .cts_to_self            = 0,
  78
  79        .assoc_timeout          = 2,
  80        .roam_timeout           = 10,
  81        .wireless_mode          = WIRELESS_MODE_11A | WIRELESS_MODE_11G,
  82        .coexist_mode           = COEX_MODE_CM,
  83
  84        /* IBSS */
  85        .ibss_band              = UMAC_BAND_2GHZ,
  86        .ibss_channel           = 1,
  87
  88        .mac_addr               = {0x00, 0x02, 0xb3, 0x01, 0x02, 0x03},
  89};
  90
  91static int modparam_reset;
  92module_param_named(reset, modparam_reset, bool, 0644);
  93MODULE_PARM_DESC(reset, "reset on firmware errors (default 0 [not reset])");
  94
  95int iwm_mode_to_nl80211_iftype(int mode)
  96{
  97        switch (mode) {
  98        case UMAC_MODE_BSS:
  99                return NL80211_IFTYPE_STATION;
 100        case UMAC_MODE_IBSS:
 101                return NL80211_IFTYPE_ADHOC;
 102        default:
 103                return NL80211_IFTYPE_UNSPECIFIED;
 104        }
 105
 106        return 0;
 107}
 108
 109static void iwm_statistics_request(struct work_struct *work)
 110{
 111        struct iwm_priv *iwm =
 112                container_of(work, struct iwm_priv, stats_request.work);
 113
 114        iwm_send_umac_stats_req(iwm, 0);
 115}
 116
 117static void iwm_disconnect_work(struct work_struct *work)
 118{
 119        struct iwm_priv *iwm =
 120                container_of(work, struct iwm_priv, disconnect.work);
 121
 122        if (iwm->umac_profile_active)
 123                iwm_invalidate_mlme_profile(iwm);
 124
 125        clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
 126        iwm->umac_profile_active = 0;
 127        memset(iwm->bssid, 0, ETH_ALEN);
 128        iwm->channel = 0;
 129
 130        iwm_link_off(iwm);
 131
 132        wake_up_interruptible(&iwm->mlme_queue);
 133
 134        cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
 135}
 136
 137static int __iwm_up(struct iwm_priv *iwm);
 138static int __iwm_down(struct iwm_priv *iwm);
 139
 140static void iwm_reset_worker(struct work_struct *work)
 141{
 142        struct iwm_priv *iwm;
 143        struct iwm_umac_profile *profile = NULL;
 144        int uninitialized_var(ret), retry = 0;
 145
 146        iwm = container_of(work, struct iwm_priv, reset_worker);
 147
 148        /*
 149         * XXX: The iwm->mutex is introduced purely for this reset work,
 150         * because the other users for iwm_up and iwm_down are only netdev
 151         * ndo_open and ndo_stop which are already protected by rtnl.
 152         * Please remove iwm->mutex together if iwm_reset_worker() is not
 153         * required in the future.
 154         */
 155        if (!mutex_trylock(&iwm->mutex)) {
 156                IWM_WARN(iwm, "We are in the middle of interface bringing "
 157                         "UP/DOWN. Skip driver resetting.\n");
 158                return;
 159        }
 160
 161        if (iwm->umac_profile_active) {
 162                profile = kmalloc(sizeof(struct iwm_umac_profile), GFP_KERNEL);
 163                if (profile)
 164                        memcpy(profile, iwm->umac_profile, sizeof(*profile));
 165                else
 166                        IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
 167        }
 168
 169        __iwm_down(iwm);
 170
 171        while (retry++ < 3) {
 172                ret = __iwm_up(iwm);
 173                if (!ret)
 174                        break;
 175
 176                schedule_timeout_uninterruptible(10 * HZ);
 177        }
 178
 179        if (ret) {
 180                IWM_WARN(iwm, "iwm_up() failed: %d\n", ret);
 181
 182                kfree(profile);
 183                goto out;
 184        }
 185
 186        if (profile) {
 187                IWM_DBG_MLME(iwm, DBG, "Resend UMAC profile\n");
 188                memcpy(iwm->umac_profile, profile, sizeof(*profile));
 189                iwm_send_mlme_profile(iwm);
 190                kfree(profile);
 191        } else
 192                clear_bit(IWM_STATUS_RESETTING, &iwm->status);
 193
 194 out:
 195        mutex_unlock(&iwm->mutex);
 196}
 197
 198static void iwm_watchdog(unsigned long data)
 199{
 200        struct iwm_priv *iwm = (struct iwm_priv *)data;
 201
 202        IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
 203
 204        if (modparam_reset)
 205                iwm_resetting(iwm);
 206}
 207
 208int iwm_priv_init(struct iwm_priv *iwm)
 209{
 210        int i;
 211        char name[32];
 212
 213        iwm->status = 0;
 214        INIT_LIST_HEAD(&iwm->pending_notif);
 215        init_waitqueue_head(&iwm->notif_queue);
 216        init_waitqueue_head(&iwm->nonwifi_queue);
 217        init_waitqueue_head(&iwm->wifi_ntfy_queue);
 218        init_waitqueue_head(&iwm->mlme_queue);
 219        memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf));
 220        spin_lock_init(&iwm->tx_credit.lock);
 221        INIT_LIST_HEAD(&iwm->wifi_pending_cmd);
 222        INIT_LIST_HEAD(&iwm->nonwifi_pending_cmd);
 223        iwm->wifi_seq_num = UMAC_WIFI_SEQ_NUM_BASE;
 224        iwm->nonwifi_seq_num = UMAC_NONWIFI_SEQ_NUM_BASE;
 225        spin_lock_init(&iwm->cmd_lock);
 226        iwm->scan_id = 1;
 227        INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
 228        INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
 229        INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
 230        INIT_LIST_HEAD(&iwm->bss_list);
 231
 232        skb_queue_head_init(&iwm->rx_list);
 233        INIT_LIST_HEAD(&iwm->rx_tickets);
 234        for (i = 0; i < IWM_RX_ID_HASH; i++)
 235                INIT_LIST_HEAD(&iwm->rx_packets[i]);
 236
 237        INIT_WORK(&iwm->rx_worker, iwm_rx_worker);
 238
 239        iwm->rx_wq = create_singlethread_workqueue(KBUILD_MODNAME "_rx");
 240        if (!iwm->rx_wq)
 241                return -EAGAIN;
 242
 243        for (i = 0; i < IWM_TX_QUEUES; i++) {
 244                INIT_WORK(&iwm->txq[i].worker, iwm_tx_worker);
 245                snprintf(name, 32, KBUILD_MODNAME "_tx_%d", i);
 246                iwm->txq[i].id = i;
 247                iwm->txq[i].wq = create_singlethread_workqueue(name);
 248                if (!iwm->txq[i].wq)
 249                        return -EAGAIN;
 250
 251                skb_queue_head_init(&iwm->txq[i].queue);
 252        }
 253
 254        for (i = 0; i < IWM_NUM_KEYS; i++)
 255                memset(&iwm->keys[i], 0, sizeof(struct iwm_key));
 256
 257        iwm->default_key = -1;
 258
 259        init_timer(&iwm->watchdog);
 260        iwm->watchdog.function = iwm_watchdog;
 261        iwm->watchdog.data = (unsigned long)iwm;
 262        mutex_init(&iwm->mutex);
 263
 264        iwm->last_fw_err = kzalloc(sizeof(struct iwm_fw_error_hdr),
 265                                   GFP_KERNEL);
 266        if (iwm->last_fw_err == NULL)
 267                return -ENOMEM;
 268
 269        return 0;
 270}
 271
 272void iwm_priv_deinit(struct iwm_priv *iwm)
 273{
 274        int i;
 275
 276        for (i = 0; i < IWM_TX_QUEUES; i++)
 277                destroy_workqueue(iwm->txq[i].wq);
 278
 279        destroy_workqueue(iwm->rx_wq);
 280        kfree(iwm->last_fw_err);
 281}
 282
 283/*
 284 * We reset all the structures, and we reset the UMAC.
 285 * After calling this routine, you're expected to reload
 286 * the firmware.
 287 */
 288void iwm_reset(struct iwm_priv *iwm)
 289{
 290        struct iwm_notif *notif, *next;
 291
 292        if (test_bit(IWM_STATUS_READY, &iwm->status))
 293                iwm_target_reset(iwm);
 294
 295        if (test_bit(IWM_STATUS_RESETTING, &iwm->status)) {
 296                iwm->status = 0;
 297                set_bit(IWM_STATUS_RESETTING, &iwm->status);
 298        } else
 299                iwm->status = 0;
 300        iwm->scan_id = 1;
 301
 302        list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
 303                list_del(&notif->pending);
 304                kfree(notif->buf);
 305                kfree(notif);
 306        }
 307
 308        iwm_cmd_flush(iwm);
 309
 310        flush_workqueue(iwm->rx_wq);
 311
 312        iwm_link_off(iwm);
 313}
 314
 315void iwm_resetting(struct iwm_priv *iwm)
 316{
 317        set_bit(IWM_STATUS_RESETTING, &iwm->status);
 318
 319        schedule_work(&iwm->reset_worker);
 320}
 321
 322/*
 323 * Notification code:
 324 *
 325 * We're faced with the following issue: Any host command can
 326 * have an answer or not, and if there's an answer to expect,
 327 * it can be treated synchronously or asynchronously.
 328 * To work around the synchronous answer case, we implemented
 329 * our notification mechanism.
 330 * When a code path needs to wait for a command response
 331 * synchronously, it calls notif_handle(), which waits for the
 332 * right notification to show up, and then process it. Before
 333 * starting to wait, it registered as a waiter for this specific
 334 * answer (by toggling a bit in on of the handler_map), so that
 335 * the rx code knows that it needs to send a notification to the
 336 * waiting processes. It does so by calling iwm_notif_send(),
 337 * which adds the notification to the pending notifications list,
 338 * and then wakes the waiting processes up.
 339 */
 340int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
 341                   u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size)
 342{
 343        struct iwm_notif *notif;
 344
 345        notif = kzalloc(sizeof(struct iwm_notif), GFP_KERNEL);
 346        if (!notif) {
 347                IWM_ERR(iwm, "Couldn't alloc memory for notification\n");
 348                return -ENOMEM;
 349        }
 350
 351        INIT_LIST_HEAD(&notif->pending);
 352        notif->cmd = cmd;
 353        notif->cmd_id = cmd_id;
 354        notif->src = source;
 355        notif->buf = kzalloc(buf_size, GFP_KERNEL);
 356        if (!notif->buf) {
 357                IWM_ERR(iwm, "Couldn't alloc notification buffer\n");
 358                kfree(notif);
 359                return -ENOMEM;
 360        }
 361        notif->buf_size = buf_size;
 362        memcpy(notif->buf, buf, buf_size);
 363        list_add_tail(&notif->pending, &iwm->pending_notif);
 364
 365        wake_up_interruptible(&iwm->notif_queue);
 366
 367        return 0;
 368}
 369
 370static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd,
 371                                        u8 source)
 372{
 373        struct iwm_notif *notif, *next;
 374
 375        list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
 376                if ((notif->cmd_id == cmd) && (notif->src == source)) {
 377                        list_del(&notif->pending);
 378                        return notif;
 379                }
 380        }
 381
 382        return NULL;
 383}
 384
 385static struct iwm_notif *iwm_notif_wait(struct iwm_priv *iwm, u32 cmd,
 386                                        u8 source, long timeout)
 387{
 388        int ret;
 389        struct iwm_notif *notif;
 390        unsigned long *map = NULL;
 391
 392        switch (source) {
 393        case IWM_SRC_LMAC:
 394                map = &iwm->lmac_handler_map[0];
 395                break;
 396        case IWM_SRC_UMAC:
 397                map = &iwm->umac_handler_map[0];
 398                break;
 399        case IWM_SRC_UDMA:
 400                map = &iwm->udma_handler_map[0];
 401                break;
 402        }
 403
 404        set_bit(cmd, map);
 405
 406        ret = wait_event_interruptible_timeout(iwm->notif_queue,
 407                         ((notif = iwm_notif_find(iwm, cmd, source)) != NULL),
 408                                               timeout);
 409        clear_bit(cmd, map);
 410
 411        if (!ret)
 412                return NULL;
 413
 414        return notif;
 415}
 416
 417int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout)
 418{
 419        int ret;
 420        struct iwm_notif *notif;
 421
 422        notif = iwm_notif_wait(iwm, cmd, source, timeout);
 423        if (!notif)
 424                return -ETIME;
 425
 426        ret = iwm_rx_handle_resp(iwm, notif->buf, notif->buf_size, notif->cmd);
 427        kfree(notif->buf);
 428        kfree(notif);
 429
 430        return ret;
 431}
 432
 433static int iwm_config_boot_params(struct iwm_priv *iwm)
 434{
 435        struct iwm_udma_nonwifi_cmd target_cmd;
 436        int ret;
 437
 438        /* check Wimax is off and config debug monitor */
 439        if (iwm->conf.wimax_not_present) {
 440                u32 data1 = 0x1f;
 441                u32 addr1 = 0x606BE258;
 442
 443                u32 data2_set = 0x0;
 444                u32 data2_clr = 0x1;
 445                u32 addr2 = 0x606BE100;
 446
 447                u32 data3 = 0x1;
 448                u32 addr3 = 0x606BEC00;
 449
 450                target_cmd.resp = 0;
 451                target_cmd.handle_by_hw = 0;
 452                target_cmd.eop = 1;
 453
 454                target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
 455                target_cmd.addr = cpu_to_le32(addr1);
 456                target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
 457                target_cmd.op2 = 0;
 458
 459                ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
 460                if (ret < 0) {
 461                        IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
 462                        return ret;
 463                }
 464
 465                target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ_MODIFY_WRITE;
 466                target_cmd.addr = cpu_to_le32(addr2);
 467                target_cmd.op1_sz = cpu_to_le32(data2_set);
 468                target_cmd.op2 = cpu_to_le32(data2_clr);
 469
 470                ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
 471                if (ret < 0) {
 472                        IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
 473                        return ret;
 474                }
 475
 476                target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
 477                target_cmd.addr = cpu_to_le32(addr3);
 478                target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
 479                target_cmd.op2 = 0;
 480
 481                ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data3);
 482                if (ret < 0) {
 483                        IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
 484                        return ret;
 485                }
 486        }
 487
 488        return 0;
 489}
 490
 491void iwm_init_default_profile(struct iwm_priv *iwm,
 492                              struct iwm_umac_profile *profile)
 493{
 494        memset(profile, 0, sizeof(struct iwm_umac_profile));
 495
 496        profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN;
 497        profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
 498        profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_NONE;
 499        profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_NONE;
 500
 501        if (iwm->conf.enable_qos)
 502                profile->flags |= cpu_to_le16(UMAC_PROFILE_QOS_ALLOWED);
 503
 504        profile->wireless_mode = iwm->conf.wireless_mode;
 505        profile->mode = cpu_to_le32(iwm->conf.mode);
 506
 507        profile->ibss.atim = 0;
 508        profile->ibss.beacon_interval = 100;
 509        profile->ibss.join_only = 0;
 510        profile->ibss.band = iwm->conf.ibss_band;
 511        profile->ibss.channel = iwm->conf.ibss_channel;
 512}
 513
 514void iwm_link_on(struct iwm_priv *iwm)
 515{
 516        netif_carrier_on(iwm_to_ndev(iwm));
 517        netif_tx_wake_all_queues(iwm_to_ndev(iwm));
 518
 519        iwm_send_umac_stats_req(iwm, 0);
 520}
 521
 522void iwm_link_off(struct iwm_priv *iwm)
 523{
 524        struct iw_statistics *wstats = &iwm->wstats;
 525        int i;
 526
 527        netif_tx_stop_all_queues(iwm_to_ndev(iwm));
 528        netif_carrier_off(iwm_to_ndev(iwm));
 529
 530        for (i = 0; i < IWM_TX_QUEUES; i++) {
 531                skb_queue_purge(&iwm->txq[i].queue);
 532
 533                iwm->txq[i].concat_count = 0;
 534                iwm->txq[i].concat_ptr = iwm->txq[i].concat_buf;
 535
 536                flush_workqueue(iwm->txq[i].wq);
 537        }
 538
 539        iwm_rx_free(iwm);
 540
 541        cancel_delayed_work_sync(&iwm->stats_request);
 542        memset(wstats, 0, sizeof(struct iw_statistics));
 543        wstats->qual.updated = IW_QUAL_ALL_INVALID;
 544
 545        kfree(iwm->req_ie);
 546        iwm->req_ie = NULL;
 547        iwm->req_ie_len = 0;
 548        kfree(iwm->resp_ie);
 549        iwm->resp_ie = NULL;
 550        iwm->resp_ie_len = 0;
 551
 552        del_timer_sync(&iwm->watchdog);
 553}
 554
 555static void iwm_bss_list_clean(struct iwm_priv *iwm)
 556{
 557        struct iwm_bss_info *bss, *next;
 558
 559        list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
 560                list_del(&bss->node);
 561                kfree(bss->bss);
 562                kfree(bss);
 563        }
 564}
 565
 566static int iwm_channels_init(struct iwm_priv *iwm)
 567{
 568        int ret;
 569
 570        ret = iwm_send_umac_channel_list(iwm);
 571        if (ret) {
 572                IWM_ERR(iwm, "Send channel list failed\n");
 573                return ret;
 574        }
 575
 576        ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST,
 577                               IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
 578        if (ret) {
 579                IWM_ERR(iwm, "Didn't get a channel list notification\n");
 580                return ret;
 581        }
 582
 583        return 0;
 584}
 585
 586static int __iwm_up(struct iwm_priv *iwm)
 587{
 588        int ret;
 589        struct iwm_notif *notif_reboot, *notif_ack = NULL;
 590
 591        ret = iwm_bus_enable(iwm);
 592        if (ret) {
 593                IWM_ERR(iwm, "Couldn't enable function\n");
 594                return ret;
 595        }
 596
 597        iwm_rx_setup_handlers(iwm);
 598
 599        /* Wait for initial BARKER_REBOOT from hardware */
 600        notif_reboot = iwm_notif_wait(iwm, IWM_BARKER_REBOOT_NOTIFICATION,
 601                                      IWM_SRC_UDMA, 2 * HZ);
 602        if (!notif_reboot) {
 603                IWM_ERR(iwm, "Wait for REBOOT_BARKER timeout\n");
 604                goto err_disable;
 605        }
 606
 607        /* We send the barker back */
 608        ret = iwm_bus_send_chunk(iwm, notif_reboot->buf, 16);
 609        if (ret) {
 610                IWM_ERR(iwm, "REBOOT barker response failed\n");
 611                kfree(notif_reboot);
 612                goto err_disable;
 613        }
 614
 615        kfree(notif_reboot->buf);
 616        kfree(notif_reboot);
 617
 618        /* Wait for ACK_BARKER from hardware */
 619        notif_ack = iwm_notif_wait(iwm, IWM_ACK_BARKER_NOTIFICATION,
 620                                   IWM_SRC_UDMA, 2 * HZ);
 621        if (!notif_ack) {
 622                IWM_ERR(iwm, "Wait for ACK_BARKER timeout\n");
 623                goto err_disable;
 624        }
 625
 626        kfree(notif_ack->buf);
 627        kfree(notif_ack);
 628
 629        /* We start to config static boot parameters */
 630        ret = iwm_config_boot_params(iwm);
 631        if (ret) {
 632                IWM_ERR(iwm, "Config boot parameters failed\n");
 633                goto err_disable;
 634        }
 635
 636        ret = iwm_read_mac(iwm, iwm_to_ndev(iwm)->dev_addr);
 637        if (ret) {
 638                IWM_ERR(iwm, "MAC reading failed\n");
 639                goto err_disable;
 640        }
 641
 642        /* We can load the FWs */
 643        ret = iwm_load_fw(iwm);
 644        if (ret) {
 645                IWM_ERR(iwm, "FW loading failed\n");
 646                goto err_disable;
 647        }
 648
 649        /* We configure the UMAC and enable the wifi module */
 650        ret = iwm_send_umac_config(iwm,
 651                        cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_CORE_EN) |
 652                        cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_LINK_EN) |
 653                        cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_MLME_EN));
 654        if (ret) {
 655                IWM_ERR(iwm, "UMAC config failed\n");
 656                goto err_fw;
 657        }
 658
 659        ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
 660                               IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
 661        if (ret) {
 662                IWM_ERR(iwm, "Didn't get a wifi core status notification\n");
 663                goto err_fw;
 664        }
 665
 666        if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
 667                                  UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
 668                IWM_DBG_BOOT(iwm, DBG, "Not all cores enabled:0x%x\n",
 669                             iwm->core_enabled);
 670                ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
 671                               IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
 672                if (ret) {
 673                        IWM_ERR(iwm, "Didn't get a core status notification\n");
 674                        goto err_fw;
 675                }
 676
 677                if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
 678                                          UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
 679                        IWM_ERR(iwm, "Not all cores enabled: 0x%x\n",
 680                                iwm->core_enabled);
 681                        goto err_fw;
 682                } else {
 683                        IWM_INFO(iwm, "All cores enabled\n");
 684                }
 685        }
 686
 687        ret = iwm_channels_init(iwm);
 688        if (ret < 0) {
 689                IWM_ERR(iwm, "Couldn't init channels\n");
 690                goto err_fw;
 691        }
 692
 693        /* Set the READY bit to indicate interface is brought up successfully */
 694        set_bit(IWM_STATUS_READY, &iwm->status);
 695
 696        return 0;
 697
 698 err_fw:
 699        iwm_eeprom_exit(iwm);
 700
 701 err_disable:
 702        ret = iwm_bus_disable(iwm);
 703        if (ret < 0)
 704                IWM_ERR(iwm, "Couldn't disable function\n");
 705
 706        return -EIO;
 707}
 708
 709int iwm_up(struct iwm_priv *iwm)
 710{
 711        int ret;
 712
 713        mutex_lock(&iwm->mutex);
 714        ret = __iwm_up(iwm);
 715        mutex_unlock(&iwm->mutex);
 716
 717        return ret;
 718}
 719
 720static int __iwm_down(struct iwm_priv *iwm)
 721{
 722        int ret;
 723
 724        /* The interface is already down */
 725        if (!test_bit(IWM_STATUS_READY, &iwm->status))
 726                return 0;
 727
 728        if (iwm->scan_request) {
 729                cfg80211_scan_done(iwm->scan_request, true);
 730                iwm->scan_request = NULL;
 731        }
 732
 733        clear_bit(IWM_STATUS_READY, &iwm->status);
 734
 735        iwm_eeprom_exit(iwm);
 736        iwm_bss_list_clean(iwm);
 737        iwm_init_default_profile(iwm, iwm->umac_profile);
 738        iwm->umac_profile_active = false;
 739        iwm->default_key = -1;
 740        iwm->core_enabled = 0;
 741
 742        ret = iwm_bus_disable(iwm);
 743        if (ret < 0) {
 744                IWM_ERR(iwm, "Couldn't disable function\n");
 745                return ret;
 746        }
 747
 748        return 0;
 749}
 750
 751int iwm_down(struct iwm_priv *iwm)
 752{
 753        int ret;
 754
 755        mutex_lock(&iwm->mutex);
 756        ret = __iwm_down(iwm);
 757        mutex_unlock(&iwm->mutex);
 758
 759        return ret;
 760}
 761