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