2 * Marvell Wireless LAN device driver: major functions
4 * Copyright (C) 2011, Marvell International Ltd.
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.
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.
27 const char driver_version[] = "mwifiex " VERSION " (%s) ";
30 * This function registers the device and performs all the necessary
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
41 * In case of any errors during inittialization, this function also ensures
42 * proper cleanup before exiting.
44 static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
47 struct mwifiex_adapter *adapter;
50 adapter = kzalloc(sizeof(struct mwifiex_adapter), GFP_KERNEL);
57 /* Save interface specific operations in adapter */
58 memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
60 /* card specific initialization has been deferred until now .. */
61 if (adapter->if_ops.init_if)
62 if (adapter->if_ops.init_if(adapter))
65 adapter->priv_num = 0;
67 for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
68 /* Allocate memory for private structure */
70 kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL);
71 if (!adapter->priv[i])
74 adapter->priv[i]->adapter = adapter;
75 adapter->priv[i]->bss_priority = i;
78 mwifiex_init_lock_list(adapter);
80 init_timer(&adapter->cmd_timer);
81 adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
82 adapter->cmd_timer.data = (unsigned long) adapter;
87 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
89 for (i = 0; i < adapter->priv_num; i++)
90 kfree(adapter->priv[i]);
98 * This function unregisters the device and performs all the necessary
101 * The following cleanup operations are performed -
103 * - Free beacon buffers
104 * - Free private structures
105 * - Free adapter structure
107 static int mwifiex_unregister(struct mwifiex_adapter *adapter)
111 del_timer(&adapter->cmd_timer);
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]);
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.
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
140 int mwifiex_main_process(struct mwifiex_adapter *adapter)
146 spin_lock_irqsave(&adapter->main_proc_lock, flags);
148 /* Check if already processing */
149 if (adapter->mwifiex_processing) {
150 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
153 adapter->mwifiex_processing = true;
154 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
158 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
159 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
162 /* Handle pending interrupt if any */
163 if (adapter->int_status) {
164 if (adapter->hs_activated)
165 mwifiex_process_hs_config(adapter);
166 if (adapter->if_ops.process_int_status)
167 adapter->if_ops.process_int_status(adapter);
170 /* Need to wake up the card ? */
171 if ((adapter->ps_state == PS_STATE_SLEEP) &&
172 (adapter->pm_wakeup_card_req &&
173 !adapter->pm_wakeup_fw_try) &&
174 (is_command_pending(adapter) ||
175 !mwifiex_wmm_lists_empty(adapter))) {
176 adapter->pm_wakeup_fw_try = true;
177 adapter->if_ops.wakeup(adapter);
181 if (IS_CARD_RX_RCVD(adapter)) {
182 adapter->pm_wakeup_fw_try = false;
183 if (adapter->ps_state == PS_STATE_SLEEP)
184 adapter->ps_state = PS_STATE_AWAKE;
186 /* We have tried to wakeup the card already */
187 if (adapter->pm_wakeup_fw_try)
189 if (adapter->ps_state != PS_STATE_AWAKE ||
190 adapter->tx_lock_flag)
193 if ((adapter->scan_processing &&
194 !adapter->scan_delay_cnt) || adapter->data_sent ||
195 mwifiex_wmm_lists_empty(adapter)) {
196 if (adapter->cmd_sent || adapter->curr_cmd ||
197 (!is_command_pending(adapter)))
202 /* Check Rx data for USB */
203 if (adapter->iface_type == MWIFIEX_USB)
204 while ((skb = skb_dequeue(&adapter->usb_rx_data_q)))
205 mwifiex_handle_rx_packet(adapter, skb);
207 /* Check for Cmd Resp */
208 if (adapter->cmd_resp_received) {
209 adapter->cmd_resp_received = false;
210 mwifiex_process_cmdresp(adapter);
212 /* call mwifiex back when init_fw is done */
213 if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
214 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
215 mwifiex_init_fw_complete(adapter);
219 /* Check for event */
220 if (adapter->event_received) {
221 adapter->event_received = false;
222 mwifiex_process_event(adapter);
225 /* Check if we need to confirm Sleep Request
226 received previously */
227 if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
228 if (!adapter->cmd_sent && !adapter->curr_cmd)
229 mwifiex_check_ps_cond(adapter);
232 /* * The ps_state may have been changed during processing of
233 * Sleep Request event.
235 if ((adapter->ps_state == PS_STATE_SLEEP) ||
236 (adapter->ps_state == PS_STATE_PRE_SLEEP) ||
237 (adapter->ps_state == PS_STATE_SLEEP_CFM) ||
238 adapter->tx_lock_flag)
241 if (!adapter->cmd_sent && !adapter->curr_cmd) {
242 if (mwifiex_exec_next_cmd(adapter) == -1) {
248 if ((!adapter->scan_processing || adapter->scan_delay_cnt) &&
249 !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
250 mwifiex_wmm_process_tx(adapter);
251 if (adapter->hs_activated) {
252 adapter->is_hs_configured = false;
253 mwifiex_hs_activated_event
255 (adapter, MWIFIEX_BSS_ROLE_ANY),
260 if (adapter->delay_null_pkt && !adapter->cmd_sent &&
261 !adapter->curr_cmd && !is_command_pending(adapter) &&
262 mwifiex_wmm_lists_empty(adapter)) {
263 if (!mwifiex_send_null_packet
264 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
265 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
266 MWIFIEX_TxPD_POWER_MGMT_LAST_PACKET)) {
267 adapter->delay_null_pkt = false;
268 adapter->ps_state = PS_STATE_SLEEP;
274 if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
277 spin_lock_irqsave(&adapter->main_proc_lock, flags);
278 adapter->mwifiex_processing = false;
279 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
282 if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
283 mwifiex_shutdown_drv(adapter);
288 * This function frees the adapter structure.
290 * Additionally, this closes the netlink socket, frees the timers
291 * and private structures.
293 static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
296 pr_err("%s: adapter is NULL\n", __func__);
300 mwifiex_unregister(adapter);
301 pr_debug("info: %s: free adapter\n", __func__);
305 * This function gets firmware and initializes it.
307 * The main initialization steps followed are -
308 * - Download the correct firmware to card
309 * - Issue the init commands to firmware
311 static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
315 struct mwifiex_private *priv;
316 struct mwifiex_adapter *adapter = context;
317 struct mwifiex_fw_image fw;
320 dev_err(adapter->dev,
321 "Failed to get firmware %s\n", adapter->fw_name);
325 memset(&fw, 0, sizeof(struct mwifiex_fw_image));
326 adapter->firmware = firmware;
327 fw.fw_buf = (u8 *) adapter->firmware->data;
328 fw.fw_len = adapter->firmware->size;
330 if (adapter->if_ops.dnld_fw)
331 ret = adapter->if_ops.dnld_fw(adapter, &fw);
333 ret = mwifiex_dnld_fw(adapter, &fw);
337 dev_notice(adapter->dev, "WLAN FW is active\n");
339 adapter->init_wait_q_woken = false;
340 ret = mwifiex_init_fw(adapter);
344 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
347 /* Wait for mwifiex_init to complete */
348 wait_event_interruptible(adapter->init_wait_q,
349 adapter->init_wait_q_woken);
350 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
353 priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
354 if (mwifiex_register_cfg80211(adapter)) {
355 dev_err(adapter->dev, "cannot register with cfg80211\n");
360 /* Create station interface by default */
361 if (!mwifiex_add_virtual_intf(adapter->wiphy, "mlan%d",
362 NL80211_IFTYPE_STATION, NULL, NULL)) {
363 dev_err(adapter->dev, "cannot create default STA interface\n");
367 /* Create AP interface by default */
368 if (!mwifiex_add_virtual_intf(adapter->wiphy, "uap%d",
369 NL80211_IFTYPE_AP, NULL, NULL)) {
370 dev_err(adapter->dev, "cannot create default AP interface\n");
375 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
376 dev_notice(adapter->dev, "driver_version = %s\n", fmt);
380 mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
383 pr_debug("info: %s: unregister device\n", __func__);
384 adapter->if_ops.unregister_dev(adapter);
386 release_firmware(adapter->firmware);
387 complete(&adapter->fw_load);
392 * This function initializes the hardware and gets firmware.
394 static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
398 init_completion(&adapter->fw_load);
399 ret = request_firmware_nowait(THIS_MODULE, 1, adapter->fw_name,
400 adapter->dev, GFP_KERNEL, adapter,
403 dev_err(adapter->dev,
404 "request_firmware_nowait() returned error %d\n", ret);
409 * This function fills a driver buffer.
411 * The function associates a given SKB with the provided driver buffer
412 * and also updates some of the SKB parameters, including IP header,
413 * priority and timestamp.
416 mwifiex_fill_buffer(struct sk_buff *skb)
423 eth = (struct ethhdr *) skb->data;
424 switch (eth->h_proto) {
425 case __constant_htons(ETH_P_IP):
427 tid = IPTOS_PREC(iph->tos);
428 pr_debug("data: packet type ETH_P_IP: %04x, tid=%#x prio=%#x\n",
429 eth->h_proto, tid, skb->priority);
431 case __constant_htons(ETH_P_ARP):
432 pr_debug("data: ARP packet: %04x\n", eth->h_proto);
436 /* Offset for TOS field in the IP header */
437 #define IPTOS_OFFSET 5
438 tid = (tid >> IPTOS_OFFSET);
440 /* Record the current time the packet was queued; used to
441 determine the amount of time the packet was queued in
442 the driver before it was sent to the firmware.
443 The delay is then sent along with the packet to the
444 firmware for aggregate delay calculation for stats and
445 MSDU lifetime expiry.
447 do_gettimeofday(&tv);
448 skb->tstamp = timeval_to_ktime(tv);
452 * CFG802.11 network device handler for open.
454 * Starts the data queue.
457 mwifiex_open(struct net_device *dev)
459 netif_tx_start_all_queues(dev);
464 * CFG802.11 network device handler for close.
467 mwifiex_close(struct net_device *dev)
473 * CFG802.11 network device handler for data transmission.
476 mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
478 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
479 struct sk_buff *new_skb;
480 struct mwifiex_txinfo *tx_info;
482 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
483 jiffies, priv->bss_type, priv->bss_num);
485 if (priv->adapter->surprise_removed) {
487 priv->stats.tx_dropped++;
490 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
491 dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
493 priv->stats.tx_dropped++;
496 if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
497 dev_dbg(priv->adapter->dev,
498 "data: Tx: insufficient skb headroom %d\n",
500 /* Insufficient skb headroom - allocate a new skb */
502 skb_realloc_headroom(skb, MWIFIEX_MIN_DATA_HEADER_LEN);
503 if (unlikely(!new_skb)) {
504 dev_err(priv->adapter->dev, "Tx: cannot alloca new_skb\n");
506 priv->stats.tx_dropped++;
511 dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
515 tx_info = MWIFIEX_SKB_TXCB(skb);
516 tx_info->bss_num = priv->bss_num;
517 tx_info->bss_type = priv->bss_type;
518 mwifiex_fill_buffer(skb);
520 mwifiex_wmm_add_buf_txqueue(priv, skb);
521 atomic_inc(&priv->adapter->tx_pending);
523 if (atomic_read(&priv->adapter->tx_pending) >= MAX_TX_PENDING) {
524 mwifiex_set_trans_start(dev);
525 mwifiex_stop_net_dev_queue(priv->netdev, priv->adapter);
528 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
534 * CFG802.11 network device handler for setting MAC address.
537 mwifiex_set_mac_address(struct net_device *dev, void *addr)
539 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
540 struct sockaddr *hw_addr = addr;
543 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
545 /* Send request to firmware */
546 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
547 HostCmd_ACT_GEN_SET, 0, NULL);
550 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
552 dev_err(priv->adapter->dev,
553 "set mac address failed: ret=%d\n", ret);
555 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
561 * CFG802.11 network device handler for setting multicast list.
563 static void mwifiex_set_multicast_list(struct net_device *dev)
565 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
566 struct mwifiex_multicast_list mcast_list;
568 if (dev->flags & IFF_PROMISC) {
569 mcast_list.mode = MWIFIEX_PROMISC_MODE;
570 } else if (dev->flags & IFF_ALLMULTI ||
571 netdev_mc_count(dev) > MWIFIEX_MAX_MULTICAST_LIST_SIZE) {
572 mcast_list.mode = MWIFIEX_ALL_MULTI_MODE;
574 mcast_list.mode = MWIFIEX_MULTICAST_MODE;
575 if (netdev_mc_count(dev))
576 mcast_list.num_multicast_addr =
577 mwifiex_copy_mcast_addr(&mcast_list, dev);
579 mwifiex_request_set_multicast_list(priv, &mcast_list);
583 * CFG802.11 network device handler for transmission timeout.
586 mwifiex_tx_timeout(struct net_device *dev)
588 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
590 dev_err(priv->adapter->dev, "%lu : Tx timeout, bss_type-num = %d-%d\n",
591 jiffies, priv->bss_type, priv->bss_num);
592 mwifiex_set_trans_start(dev);
593 priv->num_tx_timeout++;
597 * CFG802.11 network device handler for statistics retrieval.
599 static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
601 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
606 /* Network device handlers */
607 static const struct net_device_ops mwifiex_netdev_ops = {
608 .ndo_open = mwifiex_open,
609 .ndo_stop = mwifiex_close,
610 .ndo_start_xmit = mwifiex_hard_start_xmit,
611 .ndo_set_mac_address = mwifiex_set_mac_address,
612 .ndo_tx_timeout = mwifiex_tx_timeout,
613 .ndo_get_stats = mwifiex_get_stats,
614 .ndo_set_rx_mode = mwifiex_set_multicast_list,
618 * This function initializes the private structure parameters.
620 * The following wait queues are initialized -
622 * - Command wait queue
623 * - Statistics wait queue
625 * ...and the following default parameters are set -
626 * - Current key index : Set to 0
627 * - Rate index : Set to auto
628 * - Media connected : Set to disconnected
629 * - Adhoc link sensed : Set to false
630 * - Nick name : Set to null
631 * - Number of Tx timeout : Set to 0
632 * - Device address : Set to current address
634 * In addition, the CFG80211 work queue is also created.
636 void mwifiex_init_priv_params(struct mwifiex_private *priv,
637 struct net_device *dev)
639 dev->netdev_ops = &mwifiex_netdev_ops;
640 /* Initialize private structure */
641 priv->current_key_index = 0;
642 priv->media_connected = false;
643 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
644 memset(priv->mgmt_ie, 0,
645 sizeof(struct mwifiex_ie) * MAX_MGMT_IE_INDEX);
646 priv->beacon_idx = MWIFIEX_AUTO_IDX_MASK;
647 priv->proberesp_idx = MWIFIEX_AUTO_IDX_MASK;
648 priv->assocresp_idx = MWIFIEX_AUTO_IDX_MASK;
649 priv->rsn_idx = MWIFIEX_AUTO_IDX_MASK;
650 priv->num_tx_timeout = 0;
651 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
655 * This function check if command is pending.
657 int is_command_pending(struct mwifiex_adapter *adapter)
660 int is_cmd_pend_q_empty;
662 spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
663 is_cmd_pend_q_empty = list_empty(&adapter->cmd_pending_q);
664 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
666 return !is_cmd_pend_q_empty;
670 * This is the main work queue function.
672 * It handles the main process, which in turn handles the complete
675 static void mwifiex_main_work_queue(struct work_struct *work)
677 struct mwifiex_adapter *adapter =
678 container_of(work, struct mwifiex_adapter, main_work);
680 if (adapter->surprise_removed)
682 mwifiex_main_process(adapter);
686 * This function cancels all works in the queue and destroys
687 * the main workqueue.
690 mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
692 flush_workqueue(adapter->workqueue);
693 destroy_workqueue(adapter->workqueue);
694 adapter->workqueue = NULL;
698 * This function adds the card.
700 * This function follows the following major steps to set up the device -
701 * - Initialize software. This includes probing the card, registering
702 * the interface operations table, and allocating/initializing the
704 * - Set up the netlink socket
705 * - Create and start the main work queue
706 * - Register the device
707 * - Initialize firmware and hardware
708 * - Add logical interfaces
711 mwifiex_add_card(void *card, struct semaphore *sem,
712 struct mwifiex_if_ops *if_ops, u8 iface_type)
714 struct mwifiex_adapter *adapter;
716 if (down_interruptible(sem))
719 if (mwifiex_register(card, if_ops, (void **)&adapter)) {
720 pr_err("%s: software init failed\n", __func__);
724 adapter->iface_type = iface_type;
726 adapter->hw_status = MWIFIEX_HW_STATUS_INITIALIZING;
727 adapter->surprise_removed = false;
728 init_waitqueue_head(&adapter->init_wait_q);
729 adapter->is_suspended = false;
730 adapter->hs_activated = false;
731 init_waitqueue_head(&adapter->hs_activate_wait_q);
732 adapter->cmd_wait_q_required = false;
733 init_waitqueue_head(&adapter->cmd_wait_q.wait);
734 adapter->cmd_wait_q.status = 0;
735 adapter->scan_wait_q_woken = false;
737 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
738 if (!adapter->workqueue)
741 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
743 /* Register the device. Fill up the private data structure with relevant
744 information from the card and request for the required IRQ. */
745 if (adapter->if_ops.register_dev(adapter)) {
746 pr_err("%s: failed to register mwifiex device\n", __func__);
747 goto err_registerdev;
750 if (mwifiex_init_hw_fw(adapter)) {
751 pr_err("%s: firmware init failed\n", __func__);
759 pr_debug("info: %s: unregister device\n", __func__);
760 if (adapter->if_ops.unregister_dev)
761 adapter->if_ops.unregister_dev(adapter);
763 adapter->surprise_removed = true;
764 mwifiex_terminate_workqueue(adapter);
766 if ((adapter->hw_status == MWIFIEX_HW_STATUS_FW_READY) ||
767 (adapter->hw_status == MWIFIEX_HW_STATUS_READY)) {
768 pr_debug("info: %s: shutdown mwifiex\n", __func__);
769 adapter->init_wait_q_woken = false;
771 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
772 wait_event_interruptible(adapter->init_wait_q,
773 adapter->init_wait_q_woken);
776 mwifiex_free_adapter(adapter);
784 EXPORT_SYMBOL_GPL(mwifiex_add_card);
787 * This function removes the card.
789 * This function follows the following major steps to remove the device -
790 * - Stop data traffic
791 * - Shutdown firmware
792 * - Remove the logical interfaces
793 * - Terminate the work queue
794 * - Unregister the device
795 * - Free the adapter structure
797 int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
799 struct mwifiex_private *priv = NULL;
802 if (down_interruptible(sem))
808 adapter->surprise_removed = true;
811 for (i = 0; i < adapter->priv_num; i++) {
812 priv = adapter->priv[i];
813 if (priv && priv->netdev) {
814 if (!netif_queue_stopped(priv->netdev))
815 mwifiex_stop_net_dev_queue(priv->netdev,
817 if (netif_carrier_ok(priv->netdev))
818 netif_carrier_off(priv->netdev);
822 dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
823 adapter->init_wait_q_woken = false;
825 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
826 wait_event_interruptible(adapter->init_wait_q,
827 adapter->init_wait_q_woken);
828 dev_dbg(adapter->dev, "cmd: mwifiex_shutdown_drv done\n");
829 if (atomic_read(&adapter->rx_pending) ||
830 atomic_read(&adapter->tx_pending) ||
831 atomic_read(&adapter->cmd_pending)) {
832 dev_err(adapter->dev, "rx_pending=%d, tx_pending=%d, "
834 atomic_read(&adapter->rx_pending),
835 atomic_read(&adapter->tx_pending),
836 atomic_read(&adapter->cmd_pending));
839 for (i = 0; i < adapter->priv_num; i++) {
840 priv = adapter->priv[i];
846 if (priv->wdev && priv->netdev)
847 mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
851 priv = adapter->priv[0];
852 if (!priv || !priv->wdev)
855 wiphy_unregister(priv->wdev->wiphy);
856 wiphy_free(priv->wdev->wiphy);
858 for (i = 0; i < adapter->priv_num; i++) {
859 priv = adapter->priv[i];
864 mwifiex_terminate_workqueue(adapter);
866 /* Unregister device */
867 dev_dbg(adapter->dev, "info: unregister device\n");
868 if (adapter->if_ops.unregister_dev)
869 adapter->if_ops.unregister_dev(adapter);
870 /* Free adapter structure */
871 dev_dbg(adapter->dev, "info: free adapter\n");
872 mwifiex_free_adapter(adapter);
879 EXPORT_SYMBOL_GPL(mwifiex_remove_card);
882 * This function initializes the module.
884 * The debug FS is also initialized if configured.
887 mwifiex_init_module(void)
889 #ifdef CONFIG_DEBUG_FS
890 mwifiex_debugfs_init();
896 * This function cleans up the module.
898 * The debug FS is removed if available.
901 mwifiex_cleanup_module(void)
903 #ifdef CONFIG_DEBUG_FS
904 mwifiex_debugfs_remove();
908 module_init(mwifiex_init_module);
909 module_exit(mwifiex_cleanup_module);
911 MODULE_AUTHOR("Marvell International Ltd.");
912 MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
913 MODULE_VERSION(VERSION);
914 MODULE_LICENSE("GPL v2");