linux/drivers/net/wireless/marvell/mwifiex/init.c
<<
>>
Prefs
   1/*
   2 * Marvell Wireless LAN device driver: HW/FW Initialization
   3 *
   4 * Copyright (C) 2011-2014, Marvell International Ltd.
   5 *
   6 * This software file (the "File") is distributed by Marvell International
   7 * Ltd. under the terms of the GNU General Public License Version 2, June 1991
   8 * (the "License").  You may use, redistribute and/or modify this File in
   9 * accordance with the terms and conditions of the License, a copy of which
  10 * is available by writing to the Free Software Foundation, Inc.,
  11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
  12 * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
  13 *
  14 * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
  15 * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
  16 * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
  17 * this warranty disclaimer.
  18 */
  19
  20#include "decl.h"
  21#include "ioctl.h"
  22#include "util.h"
  23#include "fw.h"
  24#include "main.h"
  25#include "wmm.h"
  26#include "11n.h"
  27
  28/*
  29 * This function adds a BSS priority table to the table list.
  30 *
  31 * The function allocates a new BSS priority table node and adds it to
  32 * the end of BSS priority table list, kept in driver memory.
  33 */
  34static int mwifiex_add_bss_prio_tbl(struct mwifiex_private *priv)
  35{
  36        struct mwifiex_adapter *adapter = priv->adapter;
  37        struct mwifiex_bss_prio_node *bss_prio;
  38        struct mwifiex_bss_prio_tbl *tbl = adapter->bss_prio_tbl;
  39        unsigned long flags;
  40
  41        bss_prio = kzalloc(sizeof(struct mwifiex_bss_prio_node), GFP_KERNEL);
  42        if (!bss_prio)
  43                return -ENOMEM;
  44
  45        bss_prio->priv = priv;
  46        INIT_LIST_HEAD(&bss_prio->list);
  47
  48        spin_lock_irqsave(&tbl[priv->bss_priority].bss_prio_lock, flags);
  49        list_add_tail(&bss_prio->list, &tbl[priv->bss_priority].bss_prio_head);
  50        spin_unlock_irqrestore(&tbl[priv->bss_priority].bss_prio_lock, flags);
  51
  52        return 0;
  53}
  54
  55static void wakeup_timer_fn(struct timer_list *t)
  56{
  57        struct mwifiex_adapter *adapter = from_timer(adapter, t, wakeup_timer);
  58
  59        mwifiex_dbg(adapter, ERROR, "Firmware wakeup failed\n");
  60        adapter->hw_status = MWIFIEX_HW_STATUS_RESET;
  61        mwifiex_cancel_all_pending_cmd(adapter);
  62
  63        if (adapter->if_ops.card_reset && !adapter->hs_activated)
  64                adapter->if_ops.card_reset(adapter);
  65}
  66
  67static void fw_dump_timer_fn(struct timer_list *t)
  68{
  69        struct mwifiex_adapter *adapter = from_timer(adapter, t, devdump_timer);
  70
  71        mwifiex_upload_device_dump(adapter);
  72}
  73
  74/*
  75 * This function initializes the private structure and sets default
  76 * values to the members.
  77 *
  78 * Additionally, it also initializes all the locks and sets up all the
  79 * lists.
  80 */
  81int mwifiex_init_priv(struct mwifiex_private *priv)
  82{
  83        u32 i;
  84
  85        priv->media_connected = false;
  86        eth_broadcast_addr(priv->curr_addr);
  87        priv->port_open = false;
  88        priv->usb_port = MWIFIEX_USB_EP_DATA;
  89        priv->pkt_tx_ctrl = 0;
  90        priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
  91        priv->data_rate = 0;    /* Initially indicate the rate as auto */
  92        priv->is_data_rate_auto = true;
  93        priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
  94        priv->data_avg_factor = DEFAULT_DATA_AVG_FACTOR;
  95
  96        priv->sec_info.wep_enabled = 0;
  97        priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
  98        priv->sec_info.encryption_mode = 0;
  99        for (i = 0; i < ARRAY_SIZE(priv->wep_key); i++)
 100                memset(&priv->wep_key[i], 0, sizeof(struct mwifiex_wep_key));
 101        priv->wep_key_curr_index = 0;
 102        priv->curr_pkt_filter = HostCmd_ACT_MAC_DYNAMIC_BW_ENABLE |
 103                                HostCmd_ACT_MAC_RX_ON | HostCmd_ACT_MAC_TX_ON |
 104                                HostCmd_ACT_MAC_ETHERNETII_ENABLE;
 105
 106        priv->beacon_period = 100; /* beacon interval */
 107        priv->attempted_bss_desc = NULL;
 108        memset(&priv->curr_bss_params, 0, sizeof(priv->curr_bss_params));
 109        priv->listen_interval = MWIFIEX_DEFAULT_LISTEN_INTERVAL;
 110
 111        memset(&priv->prev_ssid, 0, sizeof(priv->prev_ssid));
 112        memset(&priv->prev_bssid, 0, sizeof(priv->prev_bssid));
 113        memset(&priv->assoc_rsp_buf, 0, sizeof(priv->assoc_rsp_buf));
 114        priv->assoc_rsp_size = 0;
 115        priv->adhoc_channel = DEFAULT_AD_HOC_CHANNEL;
 116        priv->atim_window = 0;
 117        priv->adhoc_state = ADHOC_IDLE;
 118        priv->tx_power_level = 0;
 119        priv->max_tx_power_level = 0;
 120        priv->min_tx_power_level = 0;
 121        priv->tx_ant = 0;
 122        priv->rx_ant = 0;
 123        priv->tx_rate = 0;
 124        priv->rxpd_htinfo = 0;
 125        priv->rxpd_rate = 0;
 126        priv->rate_bitmap = 0;
 127        priv->data_rssi_last = 0;
 128        priv->data_rssi_avg = 0;
 129        priv->data_nf_avg = 0;
 130        priv->data_nf_last = 0;
 131        priv->bcn_rssi_last = 0;
 132        priv->bcn_rssi_avg = 0;
 133        priv->bcn_nf_avg = 0;
 134        priv->bcn_nf_last = 0;
 135        memset(&priv->wpa_ie, 0, sizeof(priv->wpa_ie));
 136        memset(&priv->aes_key, 0, sizeof(priv->aes_key));
 137        priv->wpa_ie_len = 0;
 138        priv->wpa_is_gtk_set = false;
 139
 140        memset(&priv->assoc_tlv_buf, 0, sizeof(priv->assoc_tlv_buf));
 141        priv->assoc_tlv_buf_len = 0;
 142        memset(&priv->wps, 0, sizeof(priv->wps));
 143        memset(&priv->gen_ie_buf, 0, sizeof(priv->gen_ie_buf));
 144        priv->gen_ie_buf_len = 0;
 145        memset(priv->vs_ie, 0, sizeof(priv->vs_ie));
 146
 147        priv->wmm_required = true;
 148        priv->wmm_enabled = false;
 149        priv->wmm_qosinfo = 0;
 150        priv->curr_bcn_buf = NULL;
 151        priv->curr_bcn_size = 0;
 152        priv->wps_ie = NULL;
 153        priv->wps_ie_len = 0;
 154        priv->ap_11n_enabled = 0;
 155        memset(&priv->roc_cfg, 0, sizeof(priv->roc_cfg));
 156
 157        priv->scan_block = false;
 158
 159        priv->csa_chan = 0;
 160        priv->csa_expire_time = 0;
 161        priv->del_list_idx = 0;
 162        priv->hs2_enabled = false;
 163        priv->check_tdls_tx = false;
 164        memcpy(priv->tos_to_tid_inv, tos_to_tid_inv, MAX_NUM_TID);
 165
 166        mwifiex_init_11h_params(priv);
 167
 168        return mwifiex_add_bss_prio_tbl(priv);
 169}
 170
 171/*
 172 * This function allocates buffers for members of the adapter
 173 * structure.
 174 *
 175 * The memory allocated includes scan table, command buffers, and
 176 * sleep confirm command buffer. In addition, the queues are
 177 * also initialized.
 178 */
 179static int mwifiex_allocate_adapter(struct mwifiex_adapter *adapter)
 180{
 181        int ret;
 182
 183        /* Allocate command buffer */
 184        ret = mwifiex_alloc_cmd_buffer(adapter);
 185        if (ret) {
 186                mwifiex_dbg(adapter, ERROR,
 187                            "%s: failed to alloc cmd buffer\n",
 188                            __func__);
 189                return -1;
 190        }
 191
 192        adapter->sleep_cfm =
 193                dev_alloc_skb(sizeof(struct mwifiex_opt_sleep_confirm)
 194                              + INTF_HEADER_LEN);
 195
 196        if (!adapter->sleep_cfm) {
 197                mwifiex_dbg(adapter, ERROR,
 198                            "%s: failed to alloc sleep cfm\t"
 199                            " cmd buffer\n", __func__);
 200                return -1;
 201        }
 202        skb_reserve(adapter->sleep_cfm, INTF_HEADER_LEN);
 203
 204        return 0;
 205}
 206
 207/*
 208 * This function initializes the adapter structure and sets default
 209 * values to the members of adapter.
 210 *
 211 * This also initializes the WMM related parameters in the driver private
 212 * structures.
 213 */
 214static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
 215{
 216        struct mwifiex_opt_sleep_confirm *sleep_cfm_buf = NULL;
 217
 218        skb_put(adapter->sleep_cfm, sizeof(struct mwifiex_opt_sleep_confirm));
 219
 220        adapter->cmd_sent = false;
 221
 222        if (adapter->iface_type == MWIFIEX_SDIO)
 223                adapter->data_sent = true;
 224        else
 225                adapter->data_sent = false;
 226
 227        if (adapter->iface_type == MWIFIEX_USB)
 228                adapter->intf_hdr_len = 0;
 229        else
 230                adapter->intf_hdr_len = INTF_HEADER_LEN;
 231
 232        adapter->cmd_resp_received = false;
 233        adapter->event_received = false;
 234        adapter->data_received = false;
 235
 236        adapter->surprise_removed = false;
 237
 238        adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
 239
 240        adapter->ps_mode = MWIFIEX_802_11_POWER_MODE_CAM;
 241        adapter->ps_state = PS_STATE_AWAKE;
 242        adapter->need_to_wakeup = false;
 243
 244        adapter->scan_mode = HostCmd_BSS_MODE_ANY;
 245        adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
 246        adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
 247        adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
 248        adapter->scan_chan_gap_time = MWIFIEX_DEF_SCAN_CHAN_GAP_TIME;
 249
 250        adapter->scan_probes = 1;
 251
 252        adapter->multiple_dtim = 1;
 253
 254        adapter->local_listen_interval = 0;     /* default value in firmware
 255                                                   will be used */
 256
 257        adapter->is_deep_sleep = false;
 258
 259        adapter->delay_null_pkt = false;
 260        adapter->delay_to_ps = 1000;
 261        adapter->enhanced_ps_mode = PS_MODE_AUTO;
 262
 263        adapter->gen_null_pkt = false;  /* Disable NULL Pkg generation by
 264                                           default */
 265        adapter->pps_uapsd_mode = false; /* Disable pps/uapsd mode by
 266                                           default */
 267        adapter->pm_wakeup_card_req = false;
 268
 269        adapter->pm_wakeup_fw_try = false;
 270
 271        adapter->curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_2K;
 272
 273        adapter->is_hs_configured = false;
 274        adapter->hs_cfg.conditions = cpu_to_le32(HS_CFG_COND_DEF);
 275        adapter->hs_cfg.gpio = HS_CFG_GPIO_DEF;
 276        adapter->hs_cfg.gap = HS_CFG_GAP_DEF;
 277        adapter->hs_activated = false;
 278
 279        memset(adapter->event_body, 0, sizeof(adapter->event_body));
 280        adapter->hw_dot_11n_dev_cap = 0;
 281        adapter->hw_dev_mcs_support = 0;
 282        adapter->sec_chan_offset = 0;
 283        adapter->adhoc_11n_enabled = false;
 284
 285        mwifiex_wmm_init(adapter);
 286        atomic_set(&adapter->tx_hw_pending, 0);
 287
 288        sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
 289                                        adapter->sleep_cfm->data;
 290        memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
 291        sleep_cfm_buf->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
 292        sleep_cfm_buf->size = cpu_to_le16(adapter->sleep_cfm->len);
 293        sleep_cfm_buf->result = 0;
 294        sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
 295        sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
 296
 297        memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
 298        memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
 299        adapter->tx_lock_flag = false;
 300        adapter->null_pkt_interval = 0;
 301        adapter->fw_bands = 0;
 302        adapter->config_bands = 0;
 303        adapter->adhoc_start_band = 0;
 304        adapter->scan_channels = NULL;
 305        adapter->fw_release_number = 0;
 306        adapter->fw_cap_info = 0;
 307        memset(&adapter->upld_buf, 0, sizeof(adapter->upld_buf));
 308        adapter->event_cause = 0;
 309        adapter->region_code = 0;
 310        adapter->bcn_miss_time_out = DEFAULT_BCN_MISS_TIMEOUT;
 311        adapter->adhoc_awake_period = 0;
 312        memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
 313        adapter->arp_filter_size = 0;
 314        adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
 315        adapter->mfg_mode = mfg_mode;
 316        adapter->key_api_major_ver = 0;
 317        adapter->key_api_minor_ver = 0;
 318        eth_broadcast_addr(adapter->perm_addr);
 319        adapter->iface_limit.sta_intf = MWIFIEX_MAX_STA_NUM;
 320        adapter->iface_limit.uap_intf = MWIFIEX_MAX_UAP_NUM;
 321        adapter->iface_limit.p2p_intf = MWIFIEX_MAX_P2P_NUM;
 322        adapter->active_scan_triggered = false;
 323        timer_setup(&adapter->wakeup_timer, wakeup_timer_fn, 0);
 324        adapter->devdump_len = 0;
 325        timer_setup(&adapter->devdump_timer, fw_dump_timer_fn, 0);
 326}
 327
 328/*
 329 * This function sets trans_start per tx_queue
 330 */
 331void mwifiex_set_trans_start(struct net_device *dev)
 332{
 333        int i;
 334
 335        for (i = 0; i < dev->num_tx_queues; i++)
 336                netdev_get_tx_queue(dev, i)->trans_start = jiffies;
 337
 338        netif_trans_update(dev);
 339}
 340
 341/*
 342 * This function wakes up all queues in net_device
 343 */
 344void mwifiex_wake_up_net_dev_queue(struct net_device *netdev,
 345                                        struct mwifiex_adapter *adapter)
 346{
 347        unsigned long dev_queue_flags;
 348
 349        spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
 350        netif_tx_wake_all_queues(netdev);
 351        spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
 352}
 353
 354/*
 355 * This function stops all queues in net_device
 356 */
 357void mwifiex_stop_net_dev_queue(struct net_device *netdev,
 358                                        struct mwifiex_adapter *adapter)
 359{
 360        unsigned long dev_queue_flags;
 361
 362        spin_lock_irqsave(&adapter->queue_lock, dev_queue_flags);
 363        netif_tx_stop_all_queues(netdev);
 364        spin_unlock_irqrestore(&adapter->queue_lock, dev_queue_flags);
 365}
 366
 367/*
 368 * This function invalidates the list heads.
 369 */
 370static void mwifiex_invalidate_lists(struct mwifiex_adapter *adapter)
 371{
 372        struct mwifiex_private *priv;
 373        s32 i, j;
 374
 375        list_del(&adapter->cmd_free_q);
 376        list_del(&adapter->cmd_pending_q);
 377        list_del(&adapter->scan_pending_q);
 378
 379        for (i = 0; i < adapter->priv_num; i++)
 380                list_del(&adapter->bss_prio_tbl[i].bss_prio_head);
 381
 382        for (i = 0; i < adapter->priv_num; i++) {
 383                if (adapter->priv[i]) {
 384                        priv = adapter->priv[i];
 385                        for (j = 0; j < MAX_NUM_TID; ++j)
 386                                list_del(&priv->wmm.tid_tbl_ptr[j].ra_list);
 387                        list_del(&priv->tx_ba_stream_tbl_ptr);
 388                        list_del(&priv->rx_reorder_tbl_ptr);
 389                        list_del(&priv->sta_list);
 390                        list_del(&priv->auto_tdls_list);
 391                }
 392        }
 393}
 394
 395/*
 396 * This function performs cleanup for adapter structure.
 397 *
 398 * The cleanup is done recursively, by canceling all pending
 399 * commands, freeing the member buffers previously allocated
 400 * (command buffers, scan table buffer, sleep confirm command
 401 * buffer), stopping the timers and calling the cleanup routines
 402 * for every interface.
 403 */
 404static void
 405mwifiex_adapter_cleanup(struct mwifiex_adapter *adapter)
 406{
 407        del_timer(&adapter->wakeup_timer);
 408        del_timer_sync(&adapter->devdump_timer);
 409        mwifiex_cancel_all_pending_cmd(adapter);
 410        wake_up_interruptible(&adapter->cmd_wait_q.wait);
 411        wake_up_interruptible(&adapter->hs_activate_wait_q);
 412}
 413
 414void mwifiex_free_cmd_buffers(struct mwifiex_adapter *adapter)
 415{
 416        mwifiex_invalidate_lists(adapter);
 417
 418        /* Free command buffer */
 419        mwifiex_dbg(adapter, INFO, "info: free cmd buffer\n");
 420        mwifiex_free_cmd_buffer(adapter);
 421
 422        if (adapter->sleep_cfm)
 423                dev_kfree_skb_any(adapter->sleep_cfm);
 424}
 425
 426/*
 427 *  This function intializes the lock variables and
 428 *  the list heads.
 429 */
 430int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
 431{
 432        struct mwifiex_private *priv;
 433        s32 i, j;
 434
 435        spin_lock_init(&adapter->int_lock);
 436        spin_lock_init(&adapter->main_proc_lock);
 437        spin_lock_init(&adapter->mwifiex_cmd_lock);
 438        spin_lock_init(&adapter->queue_lock);
 439        for (i = 0; i < adapter->priv_num; i++) {
 440                if (adapter->priv[i]) {
 441                        priv = adapter->priv[i];
 442                        spin_lock_init(&priv->rx_pkt_lock);
 443                        spin_lock_init(&priv->wmm.ra_list_spinlock);
 444                        spin_lock_init(&priv->curr_bcn_buf_lock);
 445                        spin_lock_init(&priv->sta_list_spinlock);
 446                        spin_lock_init(&priv->auto_tdls_lock);
 447                }
 448        }
 449
 450        /* Initialize cmd_free_q */
 451        INIT_LIST_HEAD(&adapter->cmd_free_q);
 452        /* Initialize cmd_pending_q */
 453        INIT_LIST_HEAD(&adapter->cmd_pending_q);
 454        /* Initialize scan_pending_q */
 455        INIT_LIST_HEAD(&adapter->scan_pending_q);
 456
 457        spin_lock_init(&adapter->cmd_free_q_lock);
 458        spin_lock_init(&adapter->cmd_pending_q_lock);
 459        spin_lock_init(&adapter->scan_pending_q_lock);
 460        spin_lock_init(&adapter->rx_proc_lock);
 461
 462        skb_queue_head_init(&adapter->rx_data_q);
 463        skb_queue_head_init(&adapter->tx_data_q);
 464
 465        for (i = 0; i < adapter->priv_num; ++i) {
 466                INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
 467                spin_lock_init(&adapter->bss_prio_tbl[i].bss_prio_lock);
 468        }
 469
 470        for (i = 0; i < adapter->priv_num; i++) {
 471                if (!adapter->priv[i])
 472                        continue;
 473                priv = adapter->priv[i];
 474                for (j = 0; j < MAX_NUM_TID; ++j)
 475                        INIT_LIST_HEAD(&priv->wmm.tid_tbl_ptr[j].ra_list);
 476                INIT_LIST_HEAD(&priv->tx_ba_stream_tbl_ptr);
 477                INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr);
 478                INIT_LIST_HEAD(&priv->sta_list);
 479                INIT_LIST_HEAD(&priv->auto_tdls_list);
 480                skb_queue_head_init(&priv->tdls_txq);
 481                skb_queue_head_init(&priv->bypass_txq);
 482
 483                spin_lock_init(&priv->tx_ba_stream_tbl_lock);
 484                spin_lock_init(&priv->rx_reorder_tbl_lock);
 485
 486                spin_lock_init(&priv->ack_status_lock);
 487                idr_init(&priv->ack_status_frames);
 488        }
 489
 490        return 0;
 491}
 492
 493/*
 494 * This function initializes the firmware.
 495 *
 496 * The following operations are performed sequentially -
 497 *      - Allocate adapter structure
 498 *      - Initialize the adapter structure
 499 *      - Initialize the private structure
 500 *      - Add BSS priority tables to the adapter structure
 501 *      - For each interface, send the init commands to firmware
 502 *      - Send the first command in command pending queue, if available
 503 */
 504int mwifiex_init_fw(struct mwifiex_adapter *adapter)
 505{
 506        int ret;
 507        struct mwifiex_private *priv;
 508        u8 i, first_sta = true;
 509        int is_cmd_pend_q_empty;
 510        unsigned long flags;
 511
 512        adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
 513
 514        /* Allocate memory for member of adapter structure */
 515        ret = mwifiex_allocate_adapter(adapter);
 516        if (ret)
 517                return -1;
 518
 519        /* Initialize adapter structure */
 520        mwifiex_init_adapter(adapter);
 521
 522        for (i = 0; i < adapter->priv_num; i++) {
 523                if (adapter->priv[i]) {
 524                        priv = adapter->priv[i];
 525
 526                        /* Initialize private structure */
 527                        ret = mwifiex_init_priv(priv);
 528                        if (ret)
 529                                return -1;
 530                }
 531        }
 532        if (adapter->mfg_mode) {
 533                adapter->hw_status = MWIFIEX_HW_STATUS_READY;
 534                ret = -EINPROGRESS;
 535        } else {
 536                for (i = 0; i < adapter->priv_num; i++) {
 537                        if (adapter->priv[i]) {
 538                                ret = mwifiex_sta_init_cmd(adapter->priv[i],
 539                                                           first_sta, true);
 540                                if (ret == -1)
 541                                        return -1;
 542
 543                                first_sta = false;
 544                        }
 545
 546
 547
 548                }
 549        }
 550
 551        spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
 552        is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
 553        spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
 554        if (!is_cmd_pend_q_empty) {
 555                /* Send the first command in queue and return */
 556                if (mwifiex_main_process(adapter) != -1)
 557                        ret = -EINPROGRESS;
 558        } else {
 559                adapter->hw_status = MWIFIEX_HW_STATUS_READY;
 560        }
 561
 562        return ret;
 563}
 564
 565/*
 566 * This function deletes the BSS priority tables.
 567 *
 568 * The function traverses through all the allocated BSS priority nodes
 569 * in every BSS priority table and frees them.
 570 */
 571static void mwifiex_delete_bss_prio_tbl(struct mwifiex_private *priv)
 572{
 573        int i;
 574        struct mwifiex_adapter *adapter = priv->adapter;
 575        struct mwifiex_bss_prio_node *bssprio_node, *tmp_node;
 576        struct list_head *head;
 577        spinlock_t *lock; /* bss priority lock */
 578        unsigned long flags;
 579
 580        for (i = 0; i < adapter->priv_num; ++i) {
 581                head = &adapter->bss_prio_tbl[i].bss_prio_head;
 582                lock = &adapter->bss_prio_tbl[i].bss_prio_lock;
 583                mwifiex_dbg(adapter, INFO,
 584                            "info: delete BSS priority table,\t"
 585                            "bss_type = %d, bss_num = %d, i = %d,\t"
 586                            "head = %p\n",
 587                            priv->bss_type, priv->bss_num, i, head);
 588
 589                {
 590                        spin_lock_irqsave(lock, flags);
 591                        list_for_each_entry_safe(bssprio_node, tmp_node, head,
 592                                                 list) {
 593                                if (bssprio_node->priv == priv) {
 594                                        mwifiex_dbg(adapter, INFO,
 595                                                    "info: Delete\t"
 596                                                    "node %p, next = %p\n",
 597                                                    bssprio_node, tmp_node);
 598                                        list_del(&bssprio_node->list);
 599                                        kfree(bssprio_node);
 600                                }
 601                        }
 602                        spin_unlock_irqrestore(lock, flags);
 603                }
 604        }
 605}
 606
 607/*
 608 * This function frees the private structure, including cleans
 609 * up the TX and RX queues and frees the BSS priority tables.
 610 */
 611void mwifiex_free_priv(struct mwifiex_private *priv)
 612{
 613        mwifiex_clean_txrx(priv);
 614        mwifiex_delete_bss_prio_tbl(priv);
 615        mwifiex_free_curr_bcn(priv);
 616}
 617
 618/*
 619 * This function is used to shutdown the driver.
 620 *
 621 * The following operations are performed sequentially -
 622 *      - Check if already shut down
 623 *      - Make sure the main process has stopped
 624 *      - Clean up the Tx and Rx queues
 625 *      - Delete BSS priority tables
 626 *      - Free the adapter
 627 *      - Notify completion
 628 */
 629void
 630mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
 631{
 632        struct mwifiex_private *priv;
 633        s32 i;
 634        unsigned long flags;
 635        struct sk_buff *skb;
 636
 637        /* mwifiex already shutdown */
 638        if (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)
 639                return;
 640
 641        /* cancel current command */
 642        if (adapter->curr_cmd) {
 643                mwifiex_dbg(adapter, WARN,
 644                            "curr_cmd is still in processing\n");
 645                del_timer_sync(&adapter->cmd_timer);
 646                mwifiex_recycle_cmd_node(adapter, adapter->curr_cmd);
 647                adapter->curr_cmd = NULL;
 648        }
 649
 650        /* shut down mwifiex */
 651        mwifiex_dbg(adapter, MSG,
 652                    "info: shutdown mwifiex...\n");
 653
 654        /* Clean up Tx/Rx queues and delete BSS priority table */
 655        for (i = 0; i < adapter->priv_num; i++) {
 656                if (adapter->priv[i]) {
 657                        priv = adapter->priv[i];
 658
 659                        mwifiex_clean_auto_tdls(priv);
 660                        mwifiex_abort_cac(priv);
 661                        mwifiex_free_priv(priv);
 662                }
 663        }
 664
 665        atomic_set(&adapter->tx_queued, 0);
 666        while ((skb = skb_dequeue(&adapter->tx_data_q)))
 667                mwifiex_write_data_complete(adapter, skb, 0, 0);
 668
 669        spin_lock_irqsave(&adapter->rx_proc_lock, flags);
 670
 671        while ((skb = skb_dequeue(&adapter->rx_data_q))) {
 672                struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
 673
 674                atomic_dec(&adapter->rx_pending);
 675                priv = adapter->priv[rx_info->bss_num];
 676                if (priv)
 677                        priv->stats.rx_dropped++;
 678
 679                dev_kfree_skb_any(skb);
 680        }
 681
 682        spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
 683
 684        mwifiex_adapter_cleanup(adapter);
 685
 686        adapter->hw_status = MWIFIEX_HW_STATUS_NOT_READY;
 687}
 688
 689/*
 690 * This function downloads the firmware to the card.
 691 *
 692 * The actual download is preceded by two sanity checks -
 693 *      - Check if firmware is already running
 694 *      - Check if the interface is the winner to download the firmware
 695 *
 696 * ...and followed by another -
 697 *      - Check if the firmware is downloaded successfully
 698 *
 699 * After download is successfully completed, the host interrupts are enabled.
 700 */
 701int mwifiex_dnld_fw(struct mwifiex_adapter *adapter,
 702                    struct mwifiex_fw_image *pmfw)
 703{
 704        int ret;
 705        u32 poll_num = 1;
 706
 707        if (adapter->if_ops.check_fw_status) {
 708                /* check if firmware is already running */
 709                ret = adapter->if_ops.check_fw_status(adapter, poll_num);
 710                if (!ret) {
 711                        mwifiex_dbg(adapter, MSG,
 712                                    "WLAN FW already running! Skip FW dnld\n");
 713                        return 0;
 714                }
 715        }
 716
 717        /* check if we are the winner for downloading FW */
 718        if (adapter->if_ops.check_winner_status) {
 719                adapter->winner = 0;
 720                ret = adapter->if_ops.check_winner_status(adapter);
 721
 722                poll_num = MAX_FIRMWARE_POLL_TRIES;
 723                if (ret) {
 724                        mwifiex_dbg(adapter, MSG,
 725                                    "WLAN read winner status failed!\n");
 726                        return ret;
 727                }
 728
 729                if (!adapter->winner) {
 730                        mwifiex_dbg(adapter, MSG,
 731                                    "WLAN is not the winner! Skip FW dnld\n");
 732                        goto poll_fw;
 733                }
 734        }
 735
 736        if (pmfw) {
 737                /* Download firmware with helper */
 738                ret = adapter->if_ops.prog_fw(adapter, pmfw);
 739                if (ret) {
 740                        mwifiex_dbg(adapter, ERROR,
 741                                    "prog_fw failed ret=%#x\n", ret);
 742                        return ret;
 743                }
 744        }
 745
 746poll_fw:
 747        /* Check if the firmware is downloaded successfully or not */
 748        ret = adapter->if_ops.check_fw_status(adapter, poll_num);
 749        if (ret)
 750                mwifiex_dbg(adapter, ERROR,
 751                            "FW failed to be active in time\n");
 752
 753        return ret;
 754}
 755EXPORT_SYMBOL_GPL(mwifiex_dnld_fw);
 756