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        .ct_kill_entry          = 110,
  68        .ct_kill_exit           = 110,
  69        .reset_on_fatal_err     = 1,
  70        .auto_connect           = 1,
  71        .enable_qos             = 1,
  72        .mode                   = UMAC_MODE_BSS,
  73
  74        /* UMAC configuration */
  75        .power_index            = 0,
  76        .frag_threshold         = IEEE80211_MAX_FRAG_THRESHOLD,
  77        .rts_threshold          = IEEE80211_MAX_RTS_THRESHOLD,
  78        .cts_to_self            = 0,
  79
  80        .assoc_timeout          = 2,
  81        .roam_timeout           = 10,
  82        .wireless_mode          = WIRELESS_MODE_11A | WIRELESS_MODE_11G |
  83                                  WIRELESS_MODE_11N,
  84
  85        /* IBSS */
  86        .ibss_band              = UMAC_BAND_2GHZ,
  87        .ibss_channel           = 1,
  88
  89        .mac_addr               = {0x00, 0x02, 0xb3, 0x01, 0x02, 0x03},
  90};
  91
  92static int modparam_reset;
  93module_param_named(reset, modparam_reset, bool, 0644);
  94MODULE_PARM_DESC(reset, "reset on firmware errors (default 0 [not reset])");
  95
  96static int modparam_wimax_enable = 1;
  97module_param_named(wimax_enable, modparam_wimax_enable, bool, 0644);
  98MODULE_PARM_DESC(wimax_enable, "Enable wimax core (default 1 [wimax enabled])");
  99
 100int iwm_mode_to_nl80211_iftype(int mode)
 101{
 102        switch (mode) {
 103        case UMAC_MODE_BSS:
 104                return NL80211_IFTYPE_STATION;
 105        case UMAC_MODE_IBSS:
 106                return NL80211_IFTYPE_ADHOC;
 107        default:
 108                return NL80211_IFTYPE_UNSPECIFIED;
 109        }
 110
 111        return 0;
 112}
 113
 114static void iwm_statistics_request(struct work_struct *work)
 115{
 116        struct iwm_priv *iwm =
 117                container_of(work, struct iwm_priv, stats_request.work);
 118
 119        iwm_send_umac_stats_req(iwm, 0);
 120}
 121
 122static void iwm_disconnect_work(struct work_struct *work)
 123{
 124        struct iwm_priv *iwm =
 125                container_of(work, struct iwm_priv, disconnect.work);
 126
 127        if (iwm->umac_profile_active)
 128                iwm_invalidate_mlme_profile(iwm);
 129
 130        clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
 131        iwm->umac_profile_active = 0;
 132        memset(iwm->bssid, 0, ETH_ALEN);
 133        iwm->channel = 0;
 134
 135        iwm_link_off(iwm);
 136
 137        wake_up_interruptible(&iwm->mlme_queue);
 138
 139        cfg80211_disconnected(iwm_to_ndev(iwm), 0, NULL, 0, GFP_KERNEL);
 140}
 141
 142static void iwm_ct_kill_work(struct work_struct *work)
 143{
 144        struct iwm_priv *iwm =
 145                container_of(work, struct iwm_priv, ct_kill_delay.work);
 146        struct wiphy *wiphy = iwm_to_wiphy(iwm);
 147
 148        IWM_INFO(iwm, "CT kill delay timeout\n");
 149
 150        wiphy_rfkill_set_hw_state(wiphy, false);
 151}
 152
 153static int __iwm_up(struct iwm_priv *iwm);
 154static int __iwm_down(struct iwm_priv *iwm);
 155
 156static void iwm_reset_worker(struct work_struct *work)
 157{
 158        struct iwm_priv *iwm;
 159        struct iwm_umac_profile *profile = NULL;
 160        int uninitialized_var(ret), retry = 0;
 161
 162        iwm = container_of(work, struct iwm_priv, reset_worker);
 163
 164        /*
 165         * XXX: The iwm->mutex is introduced purely for this reset work,
 166         * because the other users for iwm_up and iwm_down are only netdev
 167         * ndo_open and ndo_stop which are already protected by rtnl.
 168         * Please remove iwm->mutex together if iwm_reset_worker() is not
 169         * required in the future.
 170         */
 171        if (!mutex_trylock(&iwm->mutex)) {
 172                IWM_WARN(iwm, "We are in the middle of interface bringing "
 173                         "UP/DOWN. Skip driver resetting.\n");
 174                return;
 175        }
 176
 177        if (iwm->umac_profile_active) {
 178                profile = kmalloc(sizeof(struct iwm_umac_profile), GFP_KERNEL);
 179                if (profile)
 180                        memcpy(profile, iwm->umac_profile, sizeof(*profile));
 181                else
 182                        IWM_ERR(iwm, "Couldn't alloc memory for profile\n");
 183        }
 184
 185        __iwm_down(iwm);
 186
 187        while (retry++ < 3) {
 188                ret = __iwm_up(iwm);
 189                if (!ret)
 190                        break;
 191
 192                schedule_timeout_uninterruptible(10 * HZ);
 193        }
 194
 195        if (ret) {
 196                IWM_WARN(iwm, "iwm_up() failed: %d\n", ret);
 197
 198                kfree(profile);
 199                goto out;
 200        }
 201
 202        if (profile) {
 203                IWM_DBG_MLME(iwm, DBG, "Resend UMAC profile\n");
 204                memcpy(iwm->umac_profile, profile, sizeof(*profile));
 205                iwm_send_mlme_profile(iwm);
 206                kfree(profile);
 207        } else
 208                clear_bit(IWM_STATUS_RESETTING, &iwm->status);
 209
 210 out:
 211        mutex_unlock(&iwm->mutex);
 212}
 213
 214static void iwm_auth_retry_worker(struct work_struct *work)
 215{
 216        struct iwm_priv *iwm;
 217        int i, ret;
 218
 219        iwm = container_of(work, struct iwm_priv, auth_retry_worker);
 220        if (iwm->umac_profile_active) {
 221                ret = iwm_invalidate_mlme_profile(iwm);
 222                if (ret < 0)
 223                        return;
 224        }
 225
 226        iwm->umac_profile->sec.auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
 227
 228        ret = iwm_send_mlme_profile(iwm);
 229        if (ret < 0)
 230                return;
 231
 232        for (i = 0; i < IWM_NUM_KEYS; i++)
 233                if (iwm->keys[i].key_len)
 234                        iwm_set_key(iwm, 0, &iwm->keys[i]);
 235
 236        iwm_set_tx_key(iwm, iwm->default_key);
 237}
 238
 239
 240
 241static void iwm_watchdog(unsigned long data)
 242{
 243        struct iwm_priv *iwm = (struct iwm_priv *)data;
 244
 245        IWM_WARN(iwm, "Watchdog expired: UMAC stalls!\n");
 246
 247        if (modparam_reset)
 248                iwm_resetting(iwm);
 249}
 250
 251int iwm_priv_init(struct iwm_priv *iwm)
 252{
 253        int i, j;
 254        char name[32];
 255
 256        iwm->status = 0;
 257        INIT_LIST_HEAD(&iwm->pending_notif);
 258        init_waitqueue_head(&iwm->notif_queue);
 259        init_waitqueue_head(&iwm->nonwifi_queue);
 260        init_waitqueue_head(&iwm->wifi_ntfy_queue);
 261        init_waitqueue_head(&iwm->mlme_queue);
 262        memcpy(&iwm->conf, &def_iwm_conf, sizeof(struct iwm_conf));
 263        spin_lock_init(&iwm->tx_credit.lock);
 264        INIT_LIST_HEAD(&iwm->wifi_pending_cmd);
 265        INIT_LIST_HEAD(&iwm->nonwifi_pending_cmd);
 266        iwm->wifi_seq_num = UMAC_WIFI_SEQ_NUM_BASE;
 267        iwm->nonwifi_seq_num = UMAC_NONWIFI_SEQ_NUM_BASE;
 268        spin_lock_init(&iwm->cmd_lock);
 269        iwm->scan_id = 1;
 270        INIT_DELAYED_WORK(&iwm->stats_request, iwm_statistics_request);
 271        INIT_DELAYED_WORK(&iwm->disconnect, iwm_disconnect_work);
 272        INIT_DELAYED_WORK(&iwm->ct_kill_delay, iwm_ct_kill_work);
 273        INIT_WORK(&iwm->reset_worker, iwm_reset_worker);
 274        INIT_WORK(&iwm->auth_retry_worker, iwm_auth_retry_worker);
 275        INIT_LIST_HEAD(&iwm->bss_list);
 276
 277        skb_queue_head_init(&iwm->rx_list);
 278        INIT_LIST_HEAD(&iwm->rx_tickets);
 279        for (i = 0; i < IWM_RX_ID_HASH; i++)
 280                INIT_LIST_HEAD(&iwm->rx_packets[i]);
 281
 282        INIT_WORK(&iwm->rx_worker, iwm_rx_worker);
 283
 284        iwm->rx_wq = create_singlethread_workqueue(KBUILD_MODNAME "_rx");
 285        if (!iwm->rx_wq)
 286                return -EAGAIN;
 287
 288        for (i = 0; i < IWM_TX_QUEUES; i++) {
 289                INIT_WORK(&iwm->txq[i].worker, iwm_tx_worker);
 290                snprintf(name, 32, KBUILD_MODNAME "_tx_%d", i);
 291                iwm->txq[i].id = i;
 292                iwm->txq[i].wq = create_singlethread_workqueue(name);
 293                if (!iwm->txq[i].wq)
 294                        return -EAGAIN;
 295
 296                skb_queue_head_init(&iwm->txq[i].queue);
 297                skb_queue_head_init(&iwm->txq[i].stopped_queue);
 298                spin_lock_init(&iwm->txq[i].lock);
 299        }
 300
 301        for (i = 0; i < IWM_NUM_KEYS; i++)
 302                memset(&iwm->keys[i], 0, sizeof(struct iwm_key));
 303
 304        iwm->default_key = -1;
 305
 306        for (i = 0; i < IWM_STA_TABLE_NUM; i++)
 307                for (j = 0; j < IWM_UMAC_TID_NR; j++) {
 308                        mutex_init(&iwm->sta_table[i].tid_info[j].mutex);
 309                        iwm->sta_table[i].tid_info[j].stopped = false;
 310                }
 311
 312        init_timer(&iwm->watchdog);
 313        iwm->watchdog.function = iwm_watchdog;
 314        iwm->watchdog.data = (unsigned long)iwm;
 315        mutex_init(&iwm->mutex);
 316
 317        iwm->last_fw_err = kzalloc(sizeof(struct iwm_fw_error_hdr),
 318                                   GFP_KERNEL);
 319        if (iwm->last_fw_err == NULL)
 320                return -ENOMEM;
 321
 322        return 0;
 323}
 324
 325void iwm_priv_deinit(struct iwm_priv *iwm)
 326{
 327        int i;
 328
 329        for (i = 0; i < IWM_TX_QUEUES; i++)
 330                destroy_workqueue(iwm->txq[i].wq);
 331
 332        destroy_workqueue(iwm->rx_wq);
 333        kfree(iwm->last_fw_err);
 334}
 335
 336/*
 337 * We reset all the structures, and we reset the UMAC.
 338 * After calling this routine, you're expected to reload
 339 * the firmware.
 340 */
 341void iwm_reset(struct iwm_priv *iwm)
 342{
 343        struct iwm_notif *notif, *next;
 344
 345        if (test_bit(IWM_STATUS_READY, &iwm->status))
 346                iwm_target_reset(iwm);
 347
 348        if (test_bit(IWM_STATUS_RESETTING, &iwm->status)) {
 349                iwm->status = 0;
 350                set_bit(IWM_STATUS_RESETTING, &iwm->status);
 351        } else
 352                iwm->status = 0;
 353        iwm->scan_id = 1;
 354
 355        list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
 356                list_del(&notif->pending);
 357                kfree(notif->buf);
 358                kfree(notif);
 359        }
 360
 361        iwm_cmd_flush(iwm);
 362
 363        flush_workqueue(iwm->rx_wq);
 364
 365        iwm_link_off(iwm);
 366}
 367
 368void iwm_resetting(struct iwm_priv *iwm)
 369{
 370        set_bit(IWM_STATUS_RESETTING, &iwm->status);
 371
 372        schedule_work(&iwm->reset_worker);
 373}
 374
 375/*
 376 * Notification code:
 377 *
 378 * We're faced with the following issue: Any host command can
 379 * have an answer or not, and if there's an answer to expect,
 380 * it can be treated synchronously or asynchronously.
 381 * To work around the synchronous answer case, we implemented
 382 * our notification mechanism.
 383 * When a code path needs to wait for a command response
 384 * synchronously, it calls notif_handle(), which waits for the
 385 * right notification to show up, and then process it. Before
 386 * starting to wait, it registered as a waiter for this specific
 387 * answer (by toggling a bit in on of the handler_map), so that
 388 * the rx code knows that it needs to send a notification to the
 389 * waiting processes. It does so by calling iwm_notif_send(),
 390 * which adds the notification to the pending notifications list,
 391 * and then wakes the waiting processes up.
 392 */
 393int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd,
 394                   u8 cmd_id, u8 source, u8 *buf, unsigned long buf_size)
 395{
 396        struct iwm_notif *notif;
 397
 398        notif = kzalloc(sizeof(struct iwm_notif), GFP_KERNEL);
 399        if (!notif) {
 400                IWM_ERR(iwm, "Couldn't alloc memory for notification\n");
 401                return -ENOMEM;
 402        }
 403
 404        INIT_LIST_HEAD(&notif->pending);
 405        notif->cmd = cmd;
 406        notif->cmd_id = cmd_id;
 407        notif->src = source;
 408        notif->buf = kzalloc(buf_size, GFP_KERNEL);
 409        if (!notif->buf) {
 410                IWM_ERR(iwm, "Couldn't alloc notification buffer\n");
 411                kfree(notif);
 412                return -ENOMEM;
 413        }
 414        notif->buf_size = buf_size;
 415        memcpy(notif->buf, buf, buf_size);
 416        list_add_tail(&notif->pending, &iwm->pending_notif);
 417
 418        wake_up_interruptible(&iwm->notif_queue);
 419
 420        return 0;
 421}
 422
 423static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd,
 424                                        u8 source)
 425{
 426        struct iwm_notif *notif, *next;
 427
 428        list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) {
 429                if ((notif->cmd_id == cmd) && (notif->src == source)) {
 430                        list_del(&notif->pending);
 431                        return notif;
 432                }
 433        }
 434
 435        return NULL;
 436}
 437
 438static struct iwm_notif *iwm_notif_wait(struct iwm_priv *iwm, u32 cmd,
 439                                        u8 source, long timeout)
 440{
 441        int ret;
 442        struct iwm_notif *notif;
 443        unsigned long *map = NULL;
 444
 445        switch (source) {
 446        case IWM_SRC_LMAC:
 447                map = &iwm->lmac_handler_map[0];
 448                break;
 449        case IWM_SRC_UMAC:
 450                map = &iwm->umac_handler_map[0];
 451                break;
 452        case IWM_SRC_UDMA:
 453                map = &iwm->udma_handler_map[0];
 454                break;
 455        }
 456
 457        set_bit(cmd, map);
 458
 459        ret = wait_event_interruptible_timeout(iwm->notif_queue,
 460                         ((notif = iwm_notif_find(iwm, cmd, source)) != NULL),
 461                                               timeout);
 462        clear_bit(cmd, map);
 463
 464        if (!ret)
 465                return NULL;
 466
 467        return notif;
 468}
 469
 470int iwm_notif_handle(struct iwm_priv *iwm, u32 cmd, u8 source, long timeout)
 471{
 472        int ret;
 473        struct iwm_notif *notif;
 474
 475        notif = iwm_notif_wait(iwm, cmd, source, timeout);
 476        if (!notif)
 477                return -ETIME;
 478
 479        ret = iwm_rx_handle_resp(iwm, notif->buf, notif->buf_size, notif->cmd);
 480        kfree(notif->buf);
 481        kfree(notif);
 482
 483        return ret;
 484}
 485
 486static int iwm_config_boot_params(struct iwm_priv *iwm)
 487{
 488        struct iwm_udma_nonwifi_cmd target_cmd;
 489        int ret;
 490
 491        /* check Wimax is off and config debug monitor */
 492        if (!modparam_wimax_enable) {
 493                u32 data1 = 0x1f;
 494                u32 addr1 = 0x606BE258;
 495
 496                u32 data2_set = 0x0;
 497                u32 data2_clr = 0x1;
 498                u32 addr2 = 0x606BE100;
 499
 500                u32 data3 = 0x1;
 501                u32 addr3 = 0x606BEC00;
 502
 503                target_cmd.resp = 0;
 504                target_cmd.handle_by_hw = 0;
 505                target_cmd.eop = 1;
 506
 507                target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
 508                target_cmd.addr = cpu_to_le32(addr1);
 509                target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
 510                target_cmd.op2 = 0;
 511
 512                ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
 513                if (ret < 0) {
 514                        IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
 515                        return ret;
 516                }
 517
 518                target_cmd.opcode = UMAC_HDI_OUT_OPCODE_READ_MODIFY_WRITE;
 519                target_cmd.addr = cpu_to_le32(addr2);
 520                target_cmd.op1_sz = cpu_to_le32(data2_set);
 521                target_cmd.op2 = cpu_to_le32(data2_clr);
 522
 523                ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data1);
 524                if (ret < 0) {
 525                        IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
 526                        return ret;
 527                }
 528
 529                target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
 530                target_cmd.addr = cpu_to_le32(addr3);
 531                target_cmd.op1_sz = cpu_to_le32(sizeof(u32));
 532                target_cmd.op2 = 0;
 533
 534                ret = iwm_hal_send_target_cmd(iwm, &target_cmd, &data3);
 535                if (ret < 0) {
 536                        IWM_ERR(iwm, "iwm_hal_send_target_cmd failed\n");
 537                        return ret;
 538                }
 539        }
 540
 541        return 0;
 542}
 543
 544void iwm_init_default_profile(struct iwm_priv *iwm,
 545                              struct iwm_umac_profile *profile)
 546{
 547        memset(profile, 0, sizeof(struct iwm_umac_profile));
 548
 549        profile->sec.auth_type = UMAC_AUTH_TYPE_OPEN;
 550        profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
 551        profile->sec.ucast_cipher = UMAC_CIPHER_TYPE_NONE;
 552        profile->sec.mcast_cipher = UMAC_CIPHER_TYPE_NONE;
 553
 554        if (iwm->conf.enable_qos)
 555                profile->flags |= cpu_to_le16(UMAC_PROFILE_QOS_ALLOWED);
 556
 557        profile->wireless_mode = iwm->conf.wireless_mode;
 558        profile->mode = cpu_to_le32(iwm->conf.mode);
 559
 560        profile->ibss.atim = 0;
 561        profile->ibss.beacon_interval = 100;
 562        profile->ibss.join_only = 0;
 563        profile->ibss.band = iwm->conf.ibss_band;
 564        profile->ibss.channel = iwm->conf.ibss_channel;
 565}
 566
 567void iwm_link_on(struct iwm_priv *iwm)
 568{
 569        netif_carrier_on(iwm_to_ndev(iwm));
 570        netif_tx_wake_all_queues(iwm_to_ndev(iwm));
 571
 572        iwm_send_umac_stats_req(iwm, 0);
 573}
 574
 575void iwm_link_off(struct iwm_priv *iwm)
 576{
 577        struct iw_statistics *wstats = &iwm->wstats;
 578        int i;
 579
 580        netif_tx_stop_all_queues(iwm_to_ndev(iwm));
 581        netif_carrier_off(iwm_to_ndev(iwm));
 582
 583        for (i = 0; i < IWM_TX_QUEUES; i++) {
 584                skb_queue_purge(&iwm->txq[i].queue);
 585                skb_queue_purge(&iwm->txq[i].stopped_queue);
 586
 587                iwm->txq[i].concat_count = 0;
 588                iwm->txq[i].concat_ptr = iwm->txq[i].concat_buf;
 589
 590                flush_workqueue(iwm->txq[i].wq);
 591        }
 592
 593        iwm_rx_free(iwm);
 594
 595        cancel_delayed_work_sync(&iwm->stats_request);
 596        memset(wstats, 0, sizeof(struct iw_statistics));
 597        wstats->qual.updated = IW_QUAL_ALL_INVALID;
 598
 599        kfree(iwm->req_ie);
 600        iwm->req_ie = NULL;
 601        iwm->req_ie_len = 0;
 602        kfree(iwm->resp_ie);
 603        iwm->resp_ie = NULL;
 604        iwm->resp_ie_len = 0;
 605
 606        del_timer_sync(&iwm->watchdog);
 607}
 608
 609static void iwm_bss_list_clean(struct iwm_priv *iwm)
 610{
 611        struct iwm_bss_info *bss, *next;
 612
 613        list_for_each_entry_safe(bss, next, &iwm->bss_list, node) {
 614                list_del(&bss->node);
 615                kfree(bss->bss);
 616                kfree(bss);
 617        }
 618}
 619
 620static int iwm_channels_init(struct iwm_priv *iwm)
 621{
 622        int ret;
 623
 624        ret = iwm_send_umac_channel_list(iwm);
 625        if (ret) {
 626                IWM_ERR(iwm, "Send channel list failed\n");
 627                return ret;
 628        }
 629
 630        ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_GET_CHAN_INFO_LIST,
 631                               IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
 632        if (ret) {
 633                IWM_ERR(iwm, "Didn't get a channel list notification\n");
 634                return ret;
 635        }
 636
 637        return 0;
 638}
 639
 640static int __iwm_up(struct iwm_priv *iwm)
 641{
 642        int ret;
 643        struct iwm_notif *notif_reboot, *notif_ack = NULL;
 644        struct wiphy *wiphy = iwm_to_wiphy(iwm);
 645        u32 wireless_mode;
 646
 647        ret = iwm_bus_enable(iwm);
 648        if (ret) {
 649                IWM_ERR(iwm, "Couldn't enable function\n");
 650                return ret;
 651        }
 652
 653        iwm_rx_setup_handlers(iwm);
 654
 655        /* Wait for initial BARKER_REBOOT from hardware */
 656        notif_reboot = iwm_notif_wait(iwm, IWM_BARKER_REBOOT_NOTIFICATION,
 657                                      IWM_SRC_UDMA, 2 * HZ);
 658        if (!notif_reboot) {
 659                IWM_ERR(iwm, "Wait for REBOOT_BARKER timeout\n");
 660                goto err_disable;
 661        }
 662
 663        /* We send the barker back */
 664        ret = iwm_bus_send_chunk(iwm, notif_reboot->buf, 16);
 665        if (ret) {
 666                IWM_ERR(iwm, "REBOOT barker response failed\n");
 667                kfree(notif_reboot);
 668                goto err_disable;
 669        }
 670
 671        kfree(notif_reboot->buf);
 672        kfree(notif_reboot);
 673
 674        /* Wait for ACK_BARKER from hardware */
 675        notif_ack = iwm_notif_wait(iwm, IWM_ACK_BARKER_NOTIFICATION,
 676                                   IWM_SRC_UDMA, 2 * HZ);
 677        if (!notif_ack) {
 678                IWM_ERR(iwm, "Wait for ACK_BARKER timeout\n");
 679                goto err_disable;
 680        }
 681
 682        kfree(notif_ack->buf);
 683        kfree(notif_ack);
 684
 685        /* We start to config static boot parameters */
 686        ret = iwm_config_boot_params(iwm);
 687        if (ret) {
 688                IWM_ERR(iwm, "Config boot parameters failed\n");
 689                goto err_disable;
 690        }
 691
 692        ret = iwm_read_mac(iwm, iwm_to_ndev(iwm)->dev_addr);
 693        if (ret) {
 694                IWM_ERR(iwm, "MAC reading failed\n");
 695                goto err_disable;
 696        }
 697        memcpy(iwm_to_ndev(iwm)->perm_addr, iwm_to_ndev(iwm)->dev_addr,
 698                ETH_ALEN);
 699
 700        /* We can load the FWs */
 701        ret = iwm_load_fw(iwm);
 702        if (ret) {
 703                IWM_ERR(iwm, "FW loading failed\n");
 704                goto err_disable;
 705        }
 706
 707        ret = iwm_eeprom_fat_channels(iwm);
 708        if (ret) {
 709                IWM_ERR(iwm, "Couldnt read HT channels EEPROM entries\n");
 710                goto err_fw;
 711        }
 712
 713        /*
 714         * Read our SKU capabilities.
 715         * If it's valid, we AND the configured wireless mode with the
 716         * device EEPROM value as the current profile wireless mode.
 717         */
 718        wireless_mode = iwm_eeprom_wireless_mode(iwm);
 719        if (wireless_mode) {
 720                iwm->conf.wireless_mode &= wireless_mode;
 721                if (iwm->umac_profile)
 722                        iwm->umac_profile->wireless_mode =
 723                                        iwm->conf.wireless_mode;
 724        } else
 725                IWM_ERR(iwm, "Wrong SKU capabilities: 0x%x\n",
 726                        *((u16 *)iwm_eeprom_access(iwm, IWM_EEPROM_SKU_CAP)));
 727
 728        snprintf(wiphy->fw_version, sizeof(wiphy->fw_version), "L%s_U%s",
 729                 iwm->lmac_version, iwm->umac_version);
 730
 731        /* We configure the UMAC and enable the wifi module */
 732        ret = iwm_send_umac_config(iwm,
 733                        cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_CORE_EN) |
 734                        cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_LINK_EN) |
 735                        cpu_to_le32(UMAC_RST_CTRL_FLG_WIFI_MLME_EN));
 736        if (ret) {
 737                IWM_ERR(iwm, "UMAC config failed\n");
 738                goto err_fw;
 739        }
 740
 741        ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
 742                               IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
 743        if (ret) {
 744                IWM_ERR(iwm, "Didn't get a wifi core status notification\n");
 745                goto err_fw;
 746        }
 747
 748        if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
 749                                  UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
 750                IWM_DBG_BOOT(iwm, DBG, "Not all cores enabled:0x%x\n",
 751                             iwm->core_enabled);
 752                ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_WIFI_CORE_STATUS,
 753                               IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
 754                if (ret) {
 755                        IWM_ERR(iwm, "Didn't get a core status notification\n");
 756                        goto err_fw;
 757                }
 758
 759                if (iwm->core_enabled != (UMAC_NTFY_WIFI_CORE_STATUS_LINK_EN |
 760                                          UMAC_NTFY_WIFI_CORE_STATUS_MLME_EN)) {
 761                        IWM_ERR(iwm, "Not all cores enabled: 0x%x\n",
 762                                iwm->core_enabled);
 763                        goto err_fw;
 764                } else {
 765                        IWM_INFO(iwm, "All cores enabled\n");
 766                }
 767        }
 768
 769        ret = iwm_channels_init(iwm);
 770        if (ret < 0) {
 771                IWM_ERR(iwm, "Couldn't init channels\n");
 772                goto err_fw;
 773        }
 774
 775        /* Set the READY bit to indicate interface is brought up successfully */
 776        set_bit(IWM_STATUS_READY, &iwm->status);
 777
 778        return 0;
 779
 780 err_fw:
 781        iwm_eeprom_exit(iwm);
 782
 783 err_disable:
 784        ret = iwm_bus_disable(iwm);
 785        if (ret < 0)
 786                IWM_ERR(iwm, "Couldn't disable function\n");
 787
 788        return -EIO;
 789}
 790
 791int iwm_up(struct iwm_priv *iwm)
 792{
 793        int ret;
 794
 795        mutex_lock(&iwm->mutex);
 796        ret = __iwm_up(iwm);
 797        mutex_unlock(&iwm->mutex);
 798
 799        return ret;
 800}
 801
 802static int __iwm_down(struct iwm_priv *iwm)
 803{
 804        int ret;
 805
 806        /* The interface is already down */
 807        if (!test_bit(IWM_STATUS_READY, &iwm->status))
 808                return 0;
 809
 810        if (iwm->scan_request) {
 811                cfg80211_scan_done(iwm->scan_request, true);
 812                iwm->scan_request = NULL;
 813        }
 814
 815        clear_bit(IWM_STATUS_READY, &iwm->status);
 816
 817        iwm_eeprom_exit(iwm);
 818        iwm_bss_list_clean(iwm);
 819        iwm_init_default_profile(iwm, iwm->umac_profile);
 820        iwm->umac_profile_active = false;
 821        iwm->default_key = -1;
 822        iwm->core_enabled = 0;
 823
 824        ret = iwm_bus_disable(iwm);
 825        if (ret < 0) {
 826                IWM_ERR(iwm, "Couldn't disable function\n");
 827                return ret;
 828        }
 829
 830        return 0;
 831}
 832
 833int iwm_down(struct iwm_priv *iwm)
 834{
 835        int ret;
 836
 837        mutex_lock(&iwm->mutex);
 838        ret = __iwm_down(iwm);
 839        mutex_unlock(&iwm->mutex);
 840
 841        return ret;
 842}
 843
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.