linux/drivers/net/wireless/mwifiex/main.c
<<
>>
Prefs
   1/*
   2 * Marvell Wireless LAN device driver: major functions
   3 *
   4 * Copyright (C) 2011, 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 "main.h"
  21#include "wmm.h"
  22#include "cfg80211.h"
  23#include "11n.h"
  24
  25#define VERSION "1.0"
  26
  27const char driver_version[] = "mwifiex " VERSION " (%s) ";
  28
  29/*
  30 * This function registers the device and performs all the necessary
  31 * initializations.
  32 *
  33 * The following initialization operations are performed -
  34 *      - Allocate adapter structure
  35 *      - Save interface specific operations table in adapter
  36 *      - Call interface specific initialization routine
  37 *      - Allocate private structures
  38 *      - Set default adapter structure parameters
  39 *      - Initialize locks
  40 *
  41 * In case of any errors during inittialization, this function also ensures
  42 * proper cleanup before exiting.
  43 */
  44static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
  45                            void **padapter)
  46{
  47        struct mwifiex_adapter *adapter;
  48        int i;
  49
  50        adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
  51        if (!adapter)
  52                return -ENOMEM;
  53
  54        *padapter = adapter;
  55        adapter->card = card;
  56
  57        /* Save interface specific operations in adapter */
  58        memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
  59
  60        /* card specific initialization has been deferred until now .. */
  61        if (adapter->if_ops.init_if(adapter))
  62                goto error;
  63
  64        adapter->priv_num = 0;
  65
  66        /* Allocate memory for private structure */
  67        adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private),
  68                        GFP_KERNEL);
  69        if (!adapter->priv[0]) {
  70                dev_err(adapter->dev, "%s: failed to alloc priv[0]\n",
  71                       __func__);
  72                goto error;
  73        }
  74
  75        adapter->priv_num++;
  76
  77        adapter->priv[0]->adapter = adapter;
  78        mwifiex_init_lock_list(adapter);
  79
  80        init_timer(&adapter->cmd_timer);
  81        adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
  82        adapter->cmd_timer.data = (unsigned long) adapter;
  83
  84        return 0;
  85
  86error:
  87        dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
  88
  89        for (i = 0; i < adapter->priv_num; i++)
  90                kfree(adapter->priv[i]);
  91
  92        kfree(adapter);
  93
  94        return -1;
  95}
  96
  97/*
  98 * This function unregisters the device and performs all the necessary
  99 * cleanups.
 100 *
 101 * The following cleanup operations are performed -
 102 *      - Free the timers
 103 *      - Free beacon buffers
 104 *      - Free private structures
 105 *      - Free adapter structure
 106 */
 107static int mwifiex_unregister(struct mwifiex_adapter *adapter)
 108{
 109        s32 i;
 110
 111        del_timer(&adapter->cmd_timer);
 112
 113        /* Free private structures */
 114        for (i = 0; i < adapter->priv_num; i++) {
 115                if (adapter->priv[i]) {
 116                        mwifiex_free_curr_bcn(adapter->priv[i]);
 117                        kfree(adapter->priv[i]);
 118                }
 119        }
 120
 121        kfree(adapter);
 122        return 0;
 123}
 124
 125/*
 126 * The main process.
 127 *
 128 * This function is the main procedure of the driver and handles various driver
 129 * operations. It runs in a loop and provides the core functionalities.
 130 *
 131 * The main responsibilities of this function are -
 132 *      - Ensure concurrency control
 133 *      - Handle pending interrupts and call interrupt handlers
 134 *      - Wake up the card if required
 135 *      - Handle command responses and call response handlers
 136 *      - Handle events and call event handlers
 137 *      - Execute pending commands
 138 *      - Transmit pending data packets
 139 */
 140int mwifiex_main_process(struct mwifiex_adapter *adapter)
 141{
 142        int ret = 0;
 143        unsigned long flags;
 144
 145        spin_lock_irqsave(&adapter->main_proc_lock, flags);
 146
 147        /* Check if already processing */
 148        if (adapter->mwifiex_processing) {
 149                spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
 150                goto exit_main_proc;
 151        } else {
 152                adapter->mwifiex_processing = true;
 153                spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
 154        }
 155process_start:
 156        do {
 157                if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
 158                    (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
 159                        break;
 160
 161                /* Handle pending interrupt if any */
 162                if (adapter->int_status) {
 163                        if (adapter->hs_activated)
 164                                mwifiex_process_hs_config(adapter);
 165                        adapter->if_ops.process_int_status(adapter);
 166                }
 167
 168                /* Need to wake up the card ? */
 169                if ((adapter->ps_state == PS_STATE_SLEEP) &&
 170                    (adapter->pm_wakeup_card_req &&
 171                     !adapter->pm_wakeup_fw_try) &&
 172                    (is_command_pending(adapter)
 173                     || !mwifiex_wmm_lists_empty(adapter))) {
 174                        adapter->pm_wakeup_fw_try = true;
 175                        adapter->if_ops.wakeup(adapter);
 176                        continue;
 177                }
 178                if (IS_CARD_RX_RCVD(adapter)) {
 179                        adapter->pm_wakeup_fw_try = false;
 180                        if (adapter->ps_state == PS_STATE_SLEEP)
 181                                adapter->ps_state = PS_STATE_AWAKE;
 182                } else {
 183                        /* We have tried to wakeup the card already */
 184                        if (adapter->pm_wakeup_fw_try)
 185                                break;
 186                        if (adapter->ps_state != PS_STATE_AWAKE ||
 187                            adapter->tx_lock_flag)
 188                                break;
 189
 190                        if (adapter->scan_processing || adapter->data_sent
 191                            || mwifiex_wmm_lists_empty(adapter)) {
 192                                if (adapter->cmd_sent || adapter->curr_cmd
 193                                    || (!is_command_pending(adapter)))
 194                                        break;
 195                        }
 196                }
 197
 198                /* Check for Cmd Resp */
 199                if (adapter->cmd_resp_received) {
 200                        adapter->cmd_resp_received = false;
 201                        mwifiex_process_cmdresp(adapter);
 202
 203                        /* call mwifiex back when init_fw is done */
 204                        if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
 205                                adapter->hw_status = MWIFIEX_HW_STATUS_READY;
 206                                mwifiex_init_fw_complete(adapter);
 207                        }
 208                }
 209
 210                /* Check for event */
 211                if (adapter->event_received) {
 212                        adapter->event_received = false;
 213                        mwifiex_process_event(adapter);
 214                }
 215
 216                /* Check if we need to confirm Sleep Request
 217                   received previously */
 218                if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
 219                        if (!adapter->cmd_sent && !adapter->curr_cmd)
 220                                mwifiex_check_ps_cond(adapter);
 221                }
 222
 223                /* * The ps_state may have been changed during processing of
 224                 * Sleep Request event.
 225                 */
 226                if ((adapter->ps_state == PS_STATE_SLEEP)
 227                    || (adapter->ps_state == PS_STATE_PRE_SLEEP)
 228                    || (adapter->ps_state == PS_STATE_SLEEP_CFM)
 229                    || adapter->tx_lock_flag)
 230                        continue;
 231
 232                if (!adapter->cmd_sent && !adapter->curr_cmd) {
 233                        if (mwifiex_exec_next_cmd(adapter) == -1) {
 234                                ret = -1;
 235                                break;
 236                        }
 237                }
 238
 239                if (!adapter->scan_processing && !adapter->data_sent &&
 240                    !mwifiex_wmm_lists_empty(adapter)) {
 241                        mwifiex_wmm_process_tx(adapter);
 242                        if (adapter->hs_activated) {
 243                                adapter->is_hs_configured = false;
 244                                mwifiex_hs_activated_event
 245                                        (mwifiex_get_priv
 246                                         (adapter, MWIFIEX_BSS_ROLE_ANY),
 247                                         false);
 248                        }
 249                }
 250
 251                if (adapter->delay_null_pkt && !adapter->cmd_sent &&
 252                    !adapter->curr_cmd && !is_command_pending(adapter)
 253                    && mwifiex_wmm_lists_empty(adapter)) {
 254                        if (!mwifiex_send_null_packet
 255                            (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
 256                             MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
 257                             MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) {
 258                                adapter->delay_null_pkt = false;
 259                                adapter->ps_state = PS_STATE_SLEEP;
 260                        }
 261                        break;
 262                }
 263        } while (true);
 264
 265        if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
 266                goto process_start;
 267
 268        spin_lock_irqsave(&adapter->main_proc_lock, flags);
 269        adapter->mwifiex_processing = false;
 270        spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
 271
 272exit_main_proc:
 273        if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
 274                mwifiex_shutdown_drv(adapter);
 275        return ret;
 276}
 277
 278/*
 279 * This function frees the adapter structure.
 280 *
 281 * Additionally, this closes the netlink socket, frees the timers
 282 * and private structures.
 283 */
 284static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
 285{
 286        if (!adapter) {
 287                pr_err("%s: adapter is NULL\n", __func__);
 288                return;
 289        }
 290
 291        mwifiex_unregister(adapter);
 292        pr_debug("info: %s: free adapter\n", __func__);
 293}
 294
 295/*
 296 * This function initializes the hardware and firmware.
 297 *
 298 * The main initialization steps followed are -
 299 *      - Download the correct firmware to card
 300 *      - Allocate and initialize the adapter structure
 301 *      - Initialize the private structures
 302 *      - Issue the init commands to firmware
 303 */
 304static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
 305{
 306        int ret, err;
 307        struct mwifiex_fw_image fw;
 308
 309        memset(&fw, 0, sizeof(struct mwifiex_fw_image));
 310
 311        err = request_firmware(&adapter->firmware, adapter->fw_name,
 312                               adapter->dev);
 313        if (err < 0) {
 314                dev_err(adapter->dev, "request_firmware() returned"
 315                                " error code %#x\n", err);
 316                ret = -1;
 317                goto done;
 318        }
 319        fw.fw_buf = (u8 *) adapter->firmware->data;
 320        fw.fw_len = adapter->firmware->size;
 321
 322        ret = mwifiex_dnld_fw(adapter, &fw);
 323        if (ret == -1)
 324                goto done;
 325
 326        dev_notice(adapter->dev, "WLAN FW is active\n");
 327
 328        adapter->init_wait_q_woken = false;
 329        ret = mwifiex_init_fw(adapter);
 330        if (ret == -1) {
 331                goto done;
 332        } else if (!ret) {
 333                adapter->hw_status = MWIFIEX_HW_STATUS_READY;
 334                goto done;
 335        }
 336        /* Wait for mwifiex_init to complete */
 337        wait_event_interruptible(adapter->init_wait_q,
 338                                 adapter->init_wait_q_woken);
 339        if (adapter->hw_status != MWIFIEX_HW_STATUS_READY) {
 340                ret = -1;
 341                goto done;
 342        }
 343        ret = 0;
 344
 345done:
 346        if (adapter->firmware)
 347                release_firmware(adapter->firmware);
 348        if (ret)
 349                ret = -1;
 350        return ret;
 351}
 352
 353/*
 354 * This function fills a driver buffer.
 355 *
 356 * The function associates a given SKB with the provided driver buffer
 357 * and also updates some of the SKB parameters, including IP header,
 358 * priority and timestamp.
 359 */
 360static void
 361mwifiex_fill_buffer(struct sk_buff *skb)
 362{
 363        struct ethhdr *eth;
 364        struct iphdr *iph;
 365        struct timeval tv;
 366        u8 tid = 0;
 367
 368        eth = (struct ethhdr *) skb->data;
 369        switch (eth->h_proto) {
 370        case __constant_htons(ETH_P_IP):
 371                iph = ip_hdr(skb);
 372                tid = IPTOS_PREC(iph->tos);
 373                pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
 374                       eth->h_proto, tid, skb->priority);
 375                break;
 376        case __constant_htons(ETH_P_ARP):
 377                pr_debug("data: ARP packet: %04x\n", eth->h_proto);
 378        default:
 379                break;
 380        }
 381/* Offset for TOS field in the IP header */
 382#define IPTOS_OFFSET 5
 383        tid = (tid >> IPTOS_OFFSET);
 384        skb->priority = tid;
 385        /* Record the current time the packet was queued; used to
 386           determine the amount of time the packet was queued in
 387           the driver before it was sent to the firmware.
 388           The delay is then sent along with the packet to the
 389           firmware for aggregate delay calculation for stats and
 390           MSDU lifetime expiry.
 391         */
 392        do_gettimeofday(&tv);
 393        skb->tstamp = timeval_to_ktime(tv);
 394}
 395
 396/*
 397 * CFG802.11 network device handler for open.
 398 *
 399 * Starts the data queue.
 400 */
 401static int
 402mwifiex_open(struct net_device *dev)
 403{
 404        netif_start_queue(dev);
 405        return 0;
 406}
 407
 408/*
 409 * CFG802.11 network device handler for close.
 410 */
 411static int
 412mwifiex_close(struct net_device *dev)
 413{
 414        return 0;
 415}
 416
 417/*
 418 * CFG802.11 network device handler for data transmission.
 419 */
 420static int
 421mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
 422{
 423        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 424        struct sk_buff *new_skb;
 425        struct mwifiex_txinfo *tx_info;
 426
 427        dev_dbg(priv->adapter->dev, "data: %lu BSS(%d): Data <= kernel\n",
 428                                jiffies, priv->bss_index);
 429
 430        if (priv->adapter->surprise_removed) {
 431                kfree_skb(skb);
 432                priv->stats.tx_dropped++;
 433                return 0;
 434        }
 435        if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
 436                dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
 437                kfree_skb(skb);
 438                priv->stats.tx_dropped++;
 439                return 0;
 440        }
 441        if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
 442                dev_dbg(priv->adapter->dev,
 443                        "data: Tx: insufficient skb headroom %d\n",
 444                       skb_headroom(skb));
 445                /* Insufficient skb headroom - allocate a new skb */
 446                new_skb =
 447                        skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
 448                if (unlikely(!new_skb)) {
 449                        dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
 450                        kfree_skb(skb);
 451                        priv->stats.tx_dropped++;
 452                        return 0;
 453                }
 454                kfree_skb(skb);
 455                skb = new_skb;
 456                dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
 457                                skb_headroom(skb));
 458        }
 459
 460        tx_info = MWIFIEX_SKB_TXCB(skb);
 461        tx_info->bss_index = priv->bss_index;
 462        mwifiex_fill_buffer(skb);
 463
 464        mwifiex_wmm_add_buf_txqueue(priv->adapter, skb);
 465        atomic_inc(&priv->adapter->tx_pending);
 466
 467        if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
 468                netif_stop_queue(priv->netdev);
 469                dev->trans_start = jiffies;
 470        }
 471
 472        queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
 473
 474        return 0;
 475}
 476
 477/*
 478 * CFG802.11 network device handler for setting MAC address.
 479 */
 480static int
 481mwifiex_set_mac_address(struct net_device *dev, void *addr)
 482{
 483        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 484        struct sockaddr *hw_addr = addr;
 485        int ret;
 486
 487        memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
 488
 489        /* Send request to firmware */
 490        ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
 491                                    HostCmd_ACT_GEN_SET, 0, NULL);
 492
 493        if (!ret)
 494                memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
 495        else
 496                dev_err(priv->adapter->dev, "set mac address failed: ret=%d"
 497                                            "\n", ret);
 498
 499        memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
 500
 501        return ret;
 502}
 503
 504/*
 505 * CFG802.11 network device handler for setting multicast list.
 506 */
 507static void mwifiex_set_multicast_list(struct net_device *dev)
 508{
 509        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 510        struct mwifiex_multicast_list mcast_list;
 511
 512        if (dev->flags & IFF_PROMISC) {
 513                mcast_list.mode = MWIFIEX_PROMISC_MODE;
 514        } else if (dev->flags & IFF_ALLMULTI ||
 515                   netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
 516                mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
 517        } else {
 518                mcast_list.mode = MWIFIEX_MULTICAST_MODE;
 519                if (netdev_mc_count(dev))
 520                        mcast_list.num_multicast_addr =
 521                                mwifiex_copy_mcast_addr(&mcast_list, dev);
 522        }
 523        mwifiex_request_set_multicast_list(priv, &mcast_list);
 524}
 525
 526/*
 527 * CFG802.11 network device handler for transmission timeout.
 528 */
 529static void
 530mwifiex_tx_timeout(struct net_device *dev)
 531{
 532        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 533
 534        dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_index=%d\n",
 535                                jiffies, priv->bss_index);
 536        dev->trans_start = jiffies;
 537        priv->num_tx_timeout++;
 538}
 539
 540/*
 541 * CFG802.11 network device handler for statistics retrieval.
 542 */
 543static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
 544{
 545        struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
 546
 547        return &priv->stats;
 548}
 549
 550/* Network device handlers */
 551static const struct net_device_ops mwifiex_netdev_ops = {
 552        .ndo_open = mwifiex_open,
 553        .ndo_stop = mwifiex_close,
 554        .ndo_start_xmit = mwifiex_hard_start_xmit,
 555        .ndo_set_mac_address = mwifiex_set_mac_address,
 556        .ndo_tx_timeout = mwifiex_tx_timeout,
 557        .ndo_get_stats = mwifiex_get_stats,
 558        .ndo_set_rx_mode = mwifiex_set_multicast_list,
 559};
 560
 561/*
 562 * This function initializes the private structure parameters.
 563 *
 564 * The following wait queues are initialized -
 565 *      - IOCTL wait queue
 566 *      - Command wait queue
 567 *      - Statistics wait queue
 568 *
 569 * ...and the following default parameters are set -
 570 *      - Current key index     : Set to 0
 571 *      - Rate index            : Set to auto
 572 *      - Media connected       : Set to disconnected
 573 *      - Adhoc link sensed     : Set to false
 574 *      - Nick name             : Set to null
 575 *      - Number of Tx timeout  : Set to 0
 576 *      - Device address        : Set to current address
 577 *
 578 * In addition, the CFG80211 work queue is also created.
 579 */
 580void mwifiex_init_priv_params(struct mwifiex_private *priv,
 581                                                struct net_device *dev)
 582{
 583        dev->netdev_ops = &mwifiex_netdev_ops;
 584        /* Initialize private structure */
 585        priv->current_key_index = 0;
 586        priv->media_connected = false;
 587        memset(&priv->nick_name, 0, sizeof(priv->nick_name));
 588        priv->num_tx_timeout = 0;
 589        priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
 590        INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
 591        memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
 592}
 593
 594/*
 595 * This function check if command is pending.
 596 */
 597int is_command_pending(struct mwifiex_adapter *adapter)
 598{
 599        unsigned long flags;
 600        int is_cmd_pend_q_empty;
 601
 602        spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
 603        is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
 604        spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
 605
 606        return !is_cmd_pend_q_empty;
 607}
 608
 609/*
 610 * This function returns the correct private structure pointer based
 611 * upon the BSS number.
 612 */
 613struct mwifiex_private *
 614mwifiex_bss_index_to_priv(struct mwifiex_adapter *adapter, u8 bss_index)
 615{
 616        if (!adapter || (bss_index >= adapter->priv_num))
 617                return NULL;
 618        return adapter->priv[bss_index];
 619}
 620
 621/*
 622 * This is the main work queue function.
 623 *
 624 * It handles the main process, which in turn handles the complete
 625 * driver operations.
 626 */
 627static void mwifiex_main_work_queue(struct work_struct *work)
 628{
 629        struct mwifiex_adapter *adapter =
 630                container_of(work, struct mwifiex_adapter, main_work);
 631
 632        if (adapter->surprise_removed)
 633                return;
 634        mwifiex_main_process(adapter);
 635}
 636
 637/*
 638 * This function cancels all works in the queue and destroys
 639 * the main workqueue.
 640 */
 641static void
 642mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
 643{
 644        flush_workqueue(adapter->workqueue);
 645        destroy_workqueue(adapter->workqueue);
 646        adapter->workqueue = NULL;
 647}
 648
 649/*
 650 * This function adds the card.
 651 *
 652 * This function follows the following major steps to set up the device -
 653 *      - Initialize software. This includes probing the card, registering
 654 *        the interface operations table, and allocating/initializing the
 655 *        adapter structure
 656 *      - Set up the netlink socket
 657 *      - Create and start the main work queue
 658 *      - Register the device
 659 *      - Initialize firmware and hardware
 660 *      - Add logical interfaces
 661 */
 662int
 663mwifiex_add_card(void *card, struct semaphore *sem,
 664                 struct mwifiex_if_ops *if_ops, u8 iface_type)
 665{
 666        struct mwifiex_adapter *adapter;
 667        char fmt[64];
 668        struct mwifiex_private *priv;
 669
 670        if (down_interruptible(sem))
 671                goto exit_sem_err;
 672
 673        if (mwifiex_register(card, if_ops, (void **)&adapter)) {
 674                pr_err("%s: software init failed\n", __func__);
 675                goto err_init_sw;
 676        }
 677
 678        adapter->iface_type = iface_type;
 679
 680        adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
 681        adapter->surprise_removed = false;
 682        init_waitqueue_head(&adapter->init_wait_q);
 683        adapter->is_suspended = false;
 684        adapter->hs_activated = false;
 685        init_waitqueue_head(&adapter->hs_activate_wait_q);
 686        adapter->cmd_wait_q_required = false;
 687        init_waitqueue_head(&adapter->cmd_wait_q.wait);
 688        adapter->cmd_wait_q.status = 0;
 689        adapter->scan_wait_q_woken = false;
 690
 691        adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
 692        if (!adapter->workqueue)
 693                goto err_kmalloc;
 694
 695        INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
 696
 697        /* Register the device. Fill up the private data structure with relevant
 698           information from the card and request for the required IRQ. */
 699        if (adapter->if_ops.register_dev(adapter)) {
 700                pr_err("%s: failed to register mwifiex device\n", __func__);
 701                goto err_registerdev;
 702        }
 703
 704        if (mwifiex_init_hw_fw(adapter)) {
 705                pr_err("%s: firmware init failed\n", __func__);
 706                goto err_init_fw;
 707        }
 708
 709        priv = adapter->priv[0];
 710
 711        if (mwifiex_register_cfg80211(priv) != 0) {
 712                dev_err(adapter->dev, "cannot register netdevice"
 713                               " with cfg80211\n");
 714                        goto err_init_fw;
 715        }
 716
 717        rtnl_lock();
 718        /* Create station interface by default */
 719        if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
 720                                NL80211_IFTYPE_STATION, NULL, NULL)) {
 721                rtnl_unlock();
 722                dev_err(adapter->dev, "cannot create default station"
 723                                " interface\n");
 724                goto err_add_intf;
 725        }
 726
 727        rtnl_unlock();
 728
 729        up(sem);
 730
 731        mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
 732        dev_notice(adapter->dev, "driver_version = %s\n", fmt);
 733
 734        return 0;
 735
 736err_add_intf:
 737        rtnl_lock();
 738        mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
 739        rtnl_unlock();
 740err_init_fw:
 741        pr_debug("info: %s: unregister device\n", __func__);
 742        adapter->if_ops.unregister_dev(adapter);
 743err_registerdev:
 744        adapter->surprise_removed = true;
 745        mwifiex_terminate_workqueue(adapter);
 746err_kmalloc:
 747        if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
 748            (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
 749                pr_debug("info: %s: shutdown mwifiex\n", __func__);
 750                adapter->init_wait_q_woken = false;
 751
 752                if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
 753                        wait_event_interruptible(adapter->init_wait_q,
 754                                                 adapter->init_wait_q_woken);
 755        }
 756
 757        mwifiex_free_adapter(adapter);
 758
 759err_init_sw:
 760        up(sem);
 761
 762exit_sem_err:
 763        return -1;
 764}
 765EXPORT_SYMBOL_GPL(mwifiex_add_card);
 766
 767/*
 768 * This function removes the card.
 769 *
 770 * This function follows the following major steps to remove the device -
 771 *      - Stop data traffic
 772 *      - Shutdown firmware
 773 *      - Remove the logical interfaces
 774 *      - Terminate the work queue
 775 *      - Unregister the device
 776 *      - Free the adapter structure
 777 */
 778int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
 779{
 780        struct mwifiex_private *priv = NULL;
 781        int i;
 782
 783        if (down_interruptible(sem))
 784                goto exit_sem_err;
 785
 786        if (!adapter)
 787                goto exit_remove;
 788
 789        adapter->surprise_removed = true;
 790
 791        /* Stop data */
 792        for (i = 0; i < adapter->priv_num; i++) {
 793                priv = adapter->priv[i];
 794                if (priv && priv->netdev) {
 795                        if (!netif_queue_stopped(priv->netdev))
 796                                netif_stop_queue(priv->netdev);
 797                        if (netif_carrier_ok(priv->netdev))
 798                                netif_carrier_off(priv->netdev);
 799                }
 800        }
 801
 802        dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
 803        adapter->init_wait_q_woken = false;
 804
 805        if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
 806                wait_event_interruptible(adapter->init_wait_q,
 807                                         adapter->init_wait_q_woken);
 808        dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
 809        if (atomic_read(&adapter->rx_pending) ||
 810            atomic_read(&adapter->tx_pending) ||
 811            atomic_read(&adapter->cmd_pending)) {
 812                dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
 813                       "cmd_pending=%d\n",
 814                       atomic_read(&adapter->rx_pending),
 815                       atomic_read(&adapter->tx_pending),
 816                       atomic_read(&adapter->cmd_pending));
 817        }
 818
 819        for (i = 0; i < adapter->priv_num; i++) {
 820                priv = adapter->priv[i];
 821
 822                if (!priv)
 823                        continue;
 824
 825                rtnl_lock();
 826                mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
 827                rtnl_unlock();
 828        }
 829
 830        priv = adapter->priv[0];
 831        if (!priv)
 832                goto exit_remove;
 833
 834        wiphy_unregister(priv->wdev->wiphy);
 835        wiphy_free(priv->wdev->wiphy);
 836        kfree(priv->wdev);
 837
 838        mwifiex_terminate_workqueue(adapter);
 839
 840        /* Unregister device */
 841        dev_dbg(adapter->dev, "info: unregister device\n");
 842        adapter->if_ops.unregister_dev(adapter);
 843        /* Free adapter structure */
 844        dev_dbg(adapter->dev, "info: free adapter\n");
 845        mwifiex_free_adapter(adapter);
 846
 847exit_remove:
 848        up(sem);
 849exit_sem_err:
 850        return 0;
 851}
 852EXPORT_SYMBOL_GPL(mwifiex_remove_card);
 853
 854/*
 855 * This function initializes the module.
 856 *
 857 * The debug FS is also initialized if configured.
 858 */
 859static int
 860mwifiex_init_module(void)
 861{
 862#ifdef CONFIG_DEBUG_FS
 863        mwifiex_debugfs_init();
 864#endif
 865        return 0;
 866}
 867
 868/*
 869 * This function cleans up the module.
 870 *
 871 * The debug FS is removed if available.
 872 */
 873static void
 874mwifiex_cleanup_module(void)
 875{
 876#ifdef CONFIG_DEBUG_FS
 877        mwifiex_debugfs_remove();
 878#endif
 879}
 880
 881module_init(mwifiex_init_module);
 882module_exit(mwifiex_cleanup_module);
 883
 884MODULE_AUTHOR("Marvell International Ltd.");
 885MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
 886MODULE_VERSION(VERSION);
 887MODULE_LICENSE("GPL v2");
 888