1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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
31
32
33
34
35
36
37
38
39
40
41
42
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
58 memmove(&adapter->if_ops, if_ops, sizeof(struct mwifiex_if_ops));
59
60
61 if (adapter->if_ops.init_if)
62 if (adapter->if_ops.init_if(adapter))
63 goto error;
64
65 adapter->priv_num = 0;
66
67 for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
68
69 adapter->priv[i] =
70 kzalloc(sizeof(struct mwifiex_private), GFP_KERNEL);
71 if (!adapter->priv[i])
72 goto error;
73
74 adapter->priv[i]->adapter = adapter;
75 adapter->priv[i]->bss_priority = i;
76 adapter->priv_num++;
77 }
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
99
100
101
102
103
104
105
106
107static int mwifiex_unregister(struct mwifiex_adapter *adapter)
108{
109 s32 i;
110
111 del_timer(&adapter->cmd_timer);
112
113
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140int mwifiex_main_process(struct mwifiex_adapter *adapter)
141{
142 int ret = 0;
143 unsigned long flags;
144 struct sk_buff *skb;
145
146 spin_lock_irqsave(&adapter->main_proc_lock, flags);
147
148
149 if (adapter->mwifiex_processing) {
150 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
151 goto exit_main_proc;
152 } else {
153 adapter->mwifiex_processing = true;
154 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
155 }
156process_start:
157 do {
158 if ((adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING) ||
159 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
160 break;
161
162
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);
168 }
169
170
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);
178 continue;
179 }
180
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;
185 } else {
186
187 if (adapter->pm_wakeup_fw_try)
188 break;
189 if (adapter->ps_state != PS_STATE_AWAKE ||
190 adapter->tx_lock_flag)
191 break;
192
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)))
198 break;
199 }
200 }
201
202
203 if (adapter->iface_type == MWIFIEX_USB)
204 while ((skb = skb_dequeue(&adapter->usb_rx_data_q)))
205 mwifiex_handle_rx_packet(adapter, skb);
206
207
208 if (adapter->cmd_resp_received) {
209 adapter->cmd_resp_received = false;
210 mwifiex_process_cmdresp(adapter);
211
212
213 if (adapter->hw_status == MWIFIEX_HW_STATUS_INIT_DONE) {
214 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
215 mwifiex_init_fw_complete(adapter);
216 }
217 }
218
219
220 if (adapter->event_received) {
221 adapter->event_received = false;
222 mwifiex_process_event(adapter);
223 }
224
225
226
227 if (adapter->ps_state == PS_STATE_PRE_SLEEP) {
228 if (!adapter->cmd_sent && !adapter->curr_cmd)
229 mwifiex_check_ps_cond(adapter);
230 }
231
232
233
234
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)
239 continue;
240
241 if (!adapter->cmd_sent && !adapter->curr_cmd) {
242 if (mwifiex_exec_next_cmd(adapter) == -1) {
243 ret = -1;
244 break;
245 }
246 }
247
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
254 (mwifiex_get_priv
255 (adapter, MWIFIEX_BSS_ROLE_ANY),
256 false);
257 }
258 }
259
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;
269 }
270 break;
271 }
272 } while (true);
273
274 if ((adapter->int_status) || IS_CARD_RX_RCVD(adapter))
275 goto process_start;
276
277 spin_lock_irqsave(&adapter->main_proc_lock, flags);
278 adapter->mwifiex_processing = false;
279 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
280
281exit_main_proc:
282 if (adapter->hw_status == MWIFIEX_HW_STATUS_CLOSING)
283 mwifiex_shutdown_drv(adapter);
284 return ret;
285}
286
287
288
289
290
291
292
293static void mwifiex_free_adapter(struct mwifiex_adapter *adapter)
294{
295 if (!adapter) {
296 pr_err("%s: adapter is NULL\n", __func__);
297 return;
298 }
299
300 mwifiex_unregister(adapter);
301 pr_debug("info: %s: free adapter\n", __func__);
302}
303
304
305
306
307
308
309
310
311static void mwifiex_fw_dpc(const struct firmware *firmware, void *context)
312{
313 int ret;
314 char fmt[64];
315 struct mwifiex_private *priv;
316 struct mwifiex_adapter *adapter = context;
317 struct mwifiex_fw_image fw;
318
319 if (!firmware) {
320 dev_err(adapter->dev,
321 "Failed to get firmware %s\n", adapter->fw_name);
322 goto done;
323 }
324
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;
329
330 if (adapter->if_ops.dnld_fw)
331 ret = adapter->if_ops.dnld_fw(adapter, &fw);
332 else
333 ret = mwifiex_dnld_fw(adapter, &fw);
334 if (ret == -1)
335 goto done;
336
337 dev_notice(adapter->dev, "WLAN FW is active\n");
338
339 adapter->init_wait_q_woken = false;
340 ret = mwifiex_init_fw(adapter);
341 if (ret == -1) {
342 goto done;
343 } else if (!ret) {
344 adapter->hw_status = MWIFIEX_HW_STATUS_READY;
345 goto done;
346 }
347
348 wait_event_interruptible(adapter->init_wait_q,
349 adapter->init_wait_q_woken);
350 if (adapter->hw_status != MWIFIEX_HW_STATUS_READY)
351 goto done;
352
353 priv = adapter->priv[MWIFIEX_BSS_ROLE_STA];
354 if (mwifiex_register_cfg80211(adapter)) {
355 dev_err(adapter->dev, "cannot register with cfg80211\n");
356 goto err_init_fw;
357 }
358
359 rtnl_lock();
360
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");
364 goto err_add_intf;
365 }
366
367
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");
371 goto err_add_intf;
372 }
373 rtnl_unlock();
374
375 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
376 dev_notice(adapter->dev, "driver_version = %s\n", fmt);
377 goto done;
378
379err_add_intf:
380 mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
381 rtnl_unlock();
382err_init_fw:
383 pr_debug("info: %s: unregister device\n", __func__);
384 adapter->if_ops.unregister_dev(adapter);
385done:
386 release_firmware(adapter->firmware);
387 complete(&adapter->fw_load);
388 return;
389}
390
391
392
393
394static int mwifiex_init_hw_fw(struct mwifiex_adapter *adapter)
395{
396 int ret;
397
398 init_completion(&adapter->fw_load);
399 ret = request_firmware_nowait(THIS_MODULE, 1, adapter->fw_name,
400 adapter->dev, GFP_KERNEL, adapter,
401 mwifiex_fw_dpc);
402 if (ret < 0)
403 dev_err(adapter->dev,
404 "request_firmware_nowait() returned error %d\n", ret);
405 return ret;
406}
407
408
409
410
411
412
413
414
415static void
416mwifiex_fill_buffer(struct sk_buff *skb)
417{
418 struct ethhdr *eth;
419 struct iphdr *iph;
420 struct timeval tv;
421 u8 tid = 0;
422
423 eth = (struct ethhdr *) skb->data;
424 switch (eth->h_proto) {
425 case __constant_htons(ETH_P_IP):
426 iph = ip_hdr(skb);
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);
430 break;
431 case __constant_htons(ETH_P_ARP):
432 pr_debug("data: ARP packet: %04x\n", eth->h_proto);
433 default:
434 break;
435 }
436
437#define IPTOS_OFFSET 5
438 tid = (tid >> IPTOS_OFFSET);
439 skb->priority = tid;
440
441
442
443
444
445
446
447 do_gettimeofday(&tv);
448 skb->tstamp = timeval_to_ktime(tv);
449}
450
451
452
453
454
455
456static int
457mwifiex_open(struct net_device *dev)
458{
459 netif_tx_start_all_queues(dev);
460 return 0;
461}
462
463
464
465
466static int
467mwifiex_close(struct net_device *dev)
468{
469 return 0;
470}
471
472
473
474
475static int
476mwifiex_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
477{
478 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
479 struct sk_buff *new_skb;
480 struct mwifiex_txinfo *tx_info;
481
482 dev_dbg(priv->adapter->dev, "data: %lu BSS(%d-%d): Data <= kernel\n",
483 jiffies, priv->bss_type, priv->bss_num);
484
485 if (priv->adapter->surprise_removed) {
486 kfree_skb(skb);
487 priv->stats.tx_dropped++;
488 return 0;
489 }
490 if (!skb->len || (skb->len > ETH_FRAME_LEN)) {
491 dev_err(priv->adapter->dev, "Tx: bad skb len %d\n", skb->len);
492 kfree_skb(skb);
493 priv->stats.tx_dropped++;
494 return 0;
495 }
496 if (skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN) {
497 dev_dbg(priv->adapter->dev,
498 "data: Tx: insufficient skb headroom %d\n",
499 skb_headroom(skb));
500
501 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");
505 kfree_skb(skb);
506 priv->stats.tx_dropped++;
507 return 0;
508 }
509 kfree_skb(skb);
510 skb = new_skb;
511 dev_dbg(priv->adapter->dev, "info: new skb headroomd %d\n",
512 skb_headroom(skb));
513 }
514
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);
519
520 mwifiex_wmm_add_buf_txqueue(priv, skb);
521 atomic_inc(&priv->adapter->tx_pending);
522
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);
526 }
527
528 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
529
530 return 0;
531}
532
533
534
535
536static int
537mwifiex_set_mac_address(struct net_device *dev, void *addr)
538{
539 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
540 struct sockaddr *hw_addr = addr;
541 int ret;
542
543 memcpy(priv->curr_addr, hw_addr->sa_data, ETH_ALEN);
544
545
546 ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_MAC_ADDRESS,
547 HostCmd_ACT_GEN_SET, 0, NULL);
548
549 if (!ret)
550 memcpy(priv->netdev->dev_addr, priv->curr_addr, ETH_ALEN);
551 else
552 dev_err(priv->adapter->dev,
553 "set mac address failed: ret=%d\n", ret);
554
555 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
556
557 return ret;
558}
559
560
561
562
563static void mwifiex_set_multicast_list(struct net_device *dev)
564{
565 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
566 struct mwifiex_multicast_list mcast_list;
567
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;
573 } else {
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);
578 }
579 mwifiex_request_set_multicast_list(priv, &mcast_list);
580}
581
582
583
584
585static void
586mwifiex_tx_timeout(struct net_device *dev)
587{
588 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
589
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++;
594}
595
596
597
598
599static struct net_device_stats *mwifiex_get_stats(struct net_device *dev)
600{
601 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
602
603 return &priv->stats;
604}
605
606
607static 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,
615};
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636void mwifiex_init_priv_params(struct mwifiex_private *priv,
637 struct net_device *dev)
638{
639 dev->netdev_ops = &mwifiex_netdev_ops;
640
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);
652}
653
654
655
656
657int is_command_pending(struct mwifiex_adapter *adapter)
658{
659 unsigned long flags;
660 int is_cmd_pend_q_empty;
661
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);
665
666 return !is_cmd_pend_q_empty;
667}
668
669
670
671
672
673
674
675static void mwifiex_main_work_queue(struct work_struct *work)
676{
677 struct mwifiex_adapter *adapter =
678 container_of(work, struct mwifiex_adapter, main_work);
679
680 if (adapter->surprise_removed)
681 return;
682 mwifiex_main_process(adapter);
683}
684
685
686
687
688
689static void
690mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
691{
692 flush_workqueue(adapter->workqueue);
693 destroy_workqueue(adapter->workqueue);
694 adapter->workqueue = NULL;
695}
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710int
711mwifiex_add_card(void *card, struct semaphore *sem,
712 struct mwifiex_if_ops *if_ops, u8 iface_type)
713{
714 struct mwifiex_adapter *adapter;
715
716 if (down_interruptible(sem))
717 goto exit_sem_err;
718
719 if (mwifiex_register(card, if_ops, (void **)&adapter)) {
720 pr_err("%s: software init failed\n", __func__);
721 goto err_init_sw;
722 }
723
724 adapter->iface_type = iface_type;
725
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;
736
737 adapter->workqueue = create_workqueue("MWIFIEX_WORK_QUEUE");
738 if (!adapter->workqueue)
739 goto err_kmalloc;
740
741 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
742
743
744
745 if (adapter->if_ops.register_dev(adapter)) {
746 pr_err("%s: failed to register mwifiex device\n", __func__);
747 goto err_registerdev;
748 }
749
750 if (mwifiex_init_hw_fw(adapter)) {
751 pr_err("%s: firmware init failed\n", __func__);
752 goto err_init_fw;
753 }
754
755 up(sem);
756 return 0;
757
758err_init_fw:
759 pr_debug("info: %s: unregister device\n", __func__);
760 if (adapter->if_ops.unregister_dev)
761 adapter->if_ops.unregister_dev(adapter);
762err_registerdev:
763 adapter->surprise_removed = true;
764 mwifiex_terminate_workqueue(adapter);
765err_kmalloc:
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;
770
771 if (mwifiex_shutdown_drv(adapter) == -EINPROGRESS)
772 wait_event_interruptible(adapter->init_wait_q,
773 adapter->init_wait_q_woken);
774 }
775
776 mwifiex_free_adapter(adapter);
777
778err_init_sw:
779 up(sem);
780
781exit_sem_err:
782 return -1;
783}
784EXPORT_SYMBOL_GPL(mwifiex_add_card);
785
786
787
788
789
790
791
792
793
794
795
796
797int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
798{
799 struct mwifiex_private *priv = NULL;
800 int i;
801
802 if (down_interruptible(sem))
803 goto exit_sem_err;
804
805 if (!adapter)
806 goto exit_remove;
807
808 adapter->surprise_removed = true;
809
810
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,
816 adapter);
817 if (netif_carrier_ok(priv->netdev))
818 netif_carrier_off(priv->netdev);
819 }
820 }
821
822 dev_dbg(adapter->dev, "cmd: calling mwifiex_shutdown_drv...\n");
823 adapter->init_wait_q_woken = false;
824
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, "
833 "cmd_pending=%d\n",
834 atomic_read(&adapter->rx_pending),
835 atomic_read(&adapter->tx_pending),
836 atomic_read(&adapter->cmd_pending));
837 }
838
839 for (i = 0; i < adapter->priv_num; i++) {
840 priv = adapter->priv[i];
841
842 if (!priv)
843 continue;
844
845 rtnl_lock();
846 if (priv->wdev && priv->netdev)
847 mwifiex_del_virtual_intf(adapter->wiphy, priv->wdev);
848 rtnl_unlock();
849 }
850
851 priv = adapter->priv[0];
852 if (!priv || !priv->wdev)
853 goto exit_remove;
854
855 wiphy_unregister(priv->wdev->wiphy);
856 wiphy_free(priv->wdev->wiphy);
857
858 for (i = 0; i < adapter->priv_num; i++) {
859 priv = adapter->priv[i];
860 if (priv)
861 kfree(priv->wdev);
862 }
863
864 mwifiex_terminate_workqueue(adapter);
865
866
867 dev_dbg(adapter->dev, "info: unregister device\n");
868 if (adapter->if_ops.unregister_dev)
869 adapter->if_ops.unregister_dev(adapter);
870
871 dev_dbg(adapter->dev, "info: free adapter\n");
872 mwifiex_free_adapter(adapter);
873
874exit_remove:
875 up(sem);
876exit_sem_err:
877 return 0;
878}
879EXPORT_SYMBOL_GPL(mwifiex_remove_card);
880
881
882
883
884
885
886static int
887mwifiex_init_module(void)
888{
889#ifdef CONFIG_DEBUG_FS
890 mwifiex_debugfs_init();
891#endif
892 return 0;
893}
894
895
896
897
898
899
900static void
901mwifiex_cleanup_module(void)
902{
903#ifdef CONFIG_DEBUG_FS
904 mwifiex_debugfs_remove();
905#endif
906}
907
908module_init(mwifiex_init_module);
909module_exit(mwifiex_cleanup_module);
910
911MODULE_AUTHOR("Marvell International Ltd.");
912MODULE_DESCRIPTION("Marvell WiFi-Ex Driver version " VERSION);
913MODULE_VERSION(VERSION);
914MODULE_LICENSE("GPL v2");
915