aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/mwifiex/main.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2011-10-11 15:35:42 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-10-11 15:35:42 -0400
commit094daf7db7c47861009899ce23f9177d761e20b0 (patch)
treea107065393720b80664157a035b206576e834793 /drivers/net/wireless/mwifiex/main.c
parent3ed6f6958c0ac21958285d8648f14d34da4bbcb3 (diff)
parent5f68a2b0a890d086e40fc7b55f4a0c32c28bc0d2 (diff)
Merge branch 'master' of git://git.infradead.org/users/linville/wireless-next into for-davem
Conflicts: Documentation/feature-removal-schedule.txt
Diffstat (limited to 'drivers/net/wireless/mwifiex/main.c')
-rw-r--r--drivers/net/wireless/mwifiex/main.c266
1 files changed, 53 insertions, 213 deletions
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 48b4d95219f..4c7491ec3f2 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -26,21 +26,6 @@
26 26
27const char driver_version[] = "mwifiex " VERSION " (%s) "; 27const char driver_version[] = "mwifiex " VERSION " (%s) ";
28 28
29static struct mwifiex_bss_attr mwifiex_bss_sta[] = {
30 {MWIFIEX_BSS_TYPE_STA, MWIFIEX_DATA_FRAME_TYPE_ETH_II, true, 0, 0},
31};
32
33static int drv_mode = DRV_MODE_STA;
34
35/* Supported drv_mode table */
36static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
37 {
38 .drv_mode = DRV_MODE_STA,
39 .intf_num = ARRAY_SIZE(mwifiex_bss_sta),
40 .bss_attr = mwifiex_bss_sta,
41 },
42};
43
44/* 29/*
45 * This function registers the device and performs all the necessary 30 * This function registers the device and performs all the necessary
46 * initializations. 31 * initializations.
@@ -57,7 +42,6 @@ static struct mwifiex_drv_mode mwifiex_drv_mode_tbl[] = {
57 * proper cleanup before exiting. 42 * proper cleanup before exiting.
58 */ 43 */
59static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops, 44static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
60 struct mwifiex_drv_mode *drv_mode_ptr,
61 void **padapter) 45 void **padapter)
62{ 46{
63 struct mwifiex_adapter *adapter; 47 struct mwifiex_adapter *adapter;
@@ -78,44 +62,20 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
78 goto error; 62 goto error;
79 63
80 adapter->priv_num = 0; 64 adapter->priv_num = 0;
81 for (i = 0; i < drv_mode_ptr->intf_num; i++) {
82 adapter->priv[i] = NULL;
83
84 if (!drv_mode_ptr->bss_attr[i].active)
85 continue;
86
87 /* Allocate memory for private structure */
88 adapter->priv[i] = kzalloc(sizeof(struct mwifiex_private),
89 GFP_KERNEL);
90 if (!adapter->priv[i]) {
91 dev_err(adapter->dev, "%s: failed to alloc priv[%d]\n",
92 __func__, i);
93 goto error;
94 }
95 65
96 adapter->priv_num++; 66 /* Allocate memory for private structure */
97 adapter->priv[i]->adapter = adapter; 67 adapter->priv[0] = kzalloc(sizeof(struct mwifiex_private),
98 /* Save bss_type, frame_type & bss_priority */ 68 GFP_KERNEL);
99 adapter->priv[i]->bss_type = drv_mode_ptr->bss_attr[i].bss_type; 69 if (!adapter->priv[0]) {
100 adapter->priv[i]->frame_type = 70 dev_err(adapter->dev, "%s: failed to alloc priv[0]\n",
101 drv_mode_ptr->bss_attr[i].frame_type; 71 __func__);
102 adapter->priv[i]->bss_priority = 72 goto error;
103 drv_mode_ptr->bss_attr[i].bss_priority;
104
105 if (drv_mode_ptr->bss_attr[i].bss_type == MWIFIEX_BSS_TYPE_STA)
106 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_STA;
107 else if (drv_mode_ptr->bss_attr[i].bss_type ==
108 MWIFIEX_BSS_TYPE_UAP)
109 adapter->priv[i]->bss_role = MWIFIEX_BSS_ROLE_UAP;
110
111 /* Save bss_index & bss_num */
112 adapter->priv[i]->bss_index = i;
113 adapter->priv[i]->bss_num = drv_mode_ptr->bss_attr[i].bss_num;
114 } 73 }
115 adapter->drv_mode = drv_mode_ptr;
116 74
117 if (mwifiex_init_lock_list(adapter)) 75 adapter->priv_num++;
118 goto error; 76
77 adapter->priv[0]->adapter = adapter;
78 mwifiex_init_lock_list(adapter);
119 79
120 init_timer(&adapter->cmd_timer); 80 init_timer(&adapter->cmd_timer);
121 adapter->cmd_timer.function = mwifiex_cmd_timeout_func; 81 adapter->cmd_timer.function = mwifiex_cmd_timeout_func;
@@ -126,9 +86,9 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
126error: 86error:
127 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n"); 87 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
128 88
129 mwifiex_free_lock_list(adapter); 89 for (i = 0; i < adapter->priv_num; i++)
130 for (i = 0; i < drv_mode_ptr->intf_num; i++)
131 kfree(adapter->priv[i]); 90 kfree(adapter->priv[i]);
91
132 kfree(adapter); 92 kfree(adapter);
133 93
134 return -1; 94 return -1;
@@ -316,38 +276,6 @@ exit_main_proc:
316} 276}
317 277
318/* 278/*
319 * This function initializes the software.
320 *
321 * The main work includes allocating and initializing the adapter structure
322 * and initializing the private structures.
323 */
324static int
325mwifiex_init_sw(void *card, struct mwifiex_if_ops *if_ops, void **padapter)
326{
327 int i;
328 struct mwifiex_drv_mode *drv_mode_ptr;
329
330 /* find mwifiex_drv_mode entry from mwifiex_drv_mode_tbl */
331 drv_mode_ptr = NULL;
332 for (i = 0; i < ARRAY_SIZE(mwifiex_drv_mode_tbl); i++) {
333 if (mwifiex_drv_mode_tbl[i].drv_mode == drv_mode) {
334 drv_mode_ptr = &mwifiex_drv_mode_tbl[i];
335 break;
336 }
337 }
338
339 if (!drv_mode_ptr) {
340 pr_err("invalid drv_mode=%d\n", drv_mode);
341 return -1;
342 }
343
344 if (mwifiex_register(card, if_ops, drv_mode_ptr, padapter))
345 return -1;
346
347 return 0;
348}
349
350/*
351 * This function frees the adapter structure. 279 * This function frees the adapter structure.
352 * 280 *
353 * Additionally, this closes the netlink socket, frees the timers 281 * Additionally, this closes the netlink socket, frees the timers
@@ -649,8 +577,8 @@ static const struct net_device_ops mwifiex_netdev_ops = {
649 * 577 *
650 * In addition, the CFG80211 work queue is also created. 578 * In addition, the CFG80211 work queue is also created.
651 */ 579 */
652static void 580void mwifiex_init_priv_params(struct mwifiex_private *priv,
653mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) 581 struct net_device *dev)
654{ 582{
655 dev->netdev_ops = &mwifiex_netdev_ops; 583 dev->netdev_ops = &mwifiex_netdev_ops;
656 /* Initialize private structure */ 584 /* Initialize private structure */
@@ -664,118 +592,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
664} 592}
665 593
666/* 594/*
667 * This function adds a new logical interface.
668 *
669 * It allocates, initializes and registers the interface by performing
670 * the following opearations -
671 * - Allocate a new net device structure
672 * - Assign device name
673 * - Register the new device with CFG80211 subsystem
674 * - Initialize semaphore and private structure
675 * - Register the new device with kernel
676 * - Create the complete debug FS structure if configured
677 */
678static struct mwifiex_private *mwifiex_add_interface(
679 struct mwifiex_adapter *adapter,
680 u8 bss_index, u8 bss_type)
681{
682 struct net_device *dev;
683 struct mwifiex_private *priv;
684 void *mdev_priv;
685
686 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), "mlan%d",
687 ether_setup, 1);
688 if (!dev) {
689 dev_err(adapter->dev, "no memory available for netdevice\n");
690 goto error;
691 }
692
693 if (mwifiex_register_cfg80211(dev, adapter->priv[bss_index]->curr_addr,
694 adapter->priv[bss_index]) != 0) {
695 dev_err(adapter->dev, "cannot register netdevice with cfg80211\n");
696 goto error;
697 }
698 /* Save the priv pointer in netdev */
699 priv = adapter->priv[bss_index];
700 mdev_priv = netdev_priv(dev);
701 *((unsigned long *) mdev_priv) = (unsigned long) priv;
702
703 priv->netdev = dev;
704
705 sema_init(&priv->async_sem, 1);
706 priv->scan_pending_on_block = false;
707
708 mwifiex_init_priv_params(priv, dev);
709
710 SET_NETDEV_DEV(dev, adapter->dev);
711
712 /* Register network device */
713 if (register_netdev(dev)) {
714 dev_err(adapter->dev, "cannot register virtual network device\n");
715 goto error;
716 }
717
718 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
719#ifdef CONFIG_DEBUG_FS
720 mwifiex_dev_debugfs_init(priv);
721#endif
722 return priv;
723error:
724 if (dev)
725 free_netdev(dev);
726 return NULL;
727}
728
729/*
730 * This function removes a logical interface.
731 *
732 * It deregisters, resets and frees the interface by performing
733 * the following operations -
734 * - Disconnect the device if connected, send wireless event to
735 * notify applications.
736 * - Remove the debug FS structure if configured
737 * - Unregister the device from kernel
738 * - Free the net device structure
739 * - Cancel all works and destroy work queue
740 * - Unregister and free the wireless device from CFG80211 subsystem
741 */
742static void
743mwifiex_remove_interface(struct mwifiex_adapter *adapter, u8 bss_index)
744{
745 struct net_device *dev;
746 struct mwifiex_private *priv = adapter->priv[bss_index];
747
748 if (!priv)
749 return;
750 dev = priv->netdev;
751
752 if (priv->media_connected)
753 priv->media_connected = false;
754
755#ifdef CONFIG_DEBUG_FS
756 mwifiex_dev_debugfs_remove(priv);
757#endif
758 /* Last reference is our one */
759 dev_dbg(adapter->dev, "info: %s: refcnt = %d\n",
760 dev->name, netdev_refcnt_read(dev));
761
762 if (dev->reg_state == NETREG_REGISTERED)
763 unregister_netdev(dev);
764
765 /* Clear the priv in adapter */
766 priv->netdev = NULL;
767 if (dev)
768 free_netdev(dev);
769
770 cancel_work_sync(&priv->cfg_workqueue);
771 flush_workqueue(priv->workqueue);
772 destroy_workqueue(priv->workqueue);
773 wiphy_unregister(priv->wdev->wiphy);
774 wiphy_free(priv->wdev->wiphy);
775 kfree(priv->wdev);
776}
777
778/*
779 * This function check if command is pending. 595 * This function check if command is pending.
780 */ 596 */
781int is_command_pending(struct mwifiex_adapter *adapter) 597int is_command_pending(struct mwifiex_adapter *adapter)
@@ -847,14 +663,14 @@ int
847mwifiex_add_card(void *card, struct semaphore *sem, 663mwifiex_add_card(void *card, struct semaphore *sem,
848 struct mwifiex_if_ops *if_ops) 664 struct mwifiex_if_ops *if_ops)
849{ 665{
850 int i;
851 struct mwifiex_adapter *adapter; 666 struct mwifiex_adapter *adapter;
852 char fmt[64]; 667 char fmt[64];
668 struct mwifiex_private *priv;
853 669
854 if (down_interruptible(sem)) 670 if (down_interruptible(sem))
855 goto exit_sem_err; 671 goto exit_sem_err;
856 672
857 if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) { 673 if (mwifiex_register(card, if_ops, (void **)&adapter)) {
858 pr_err("%s: software init failed\n", __func__); 674 pr_err("%s: software init failed\n", __func__);
859 goto err_init_sw; 675 goto err_init_sw;
860 } 676 }
@@ -888,14 +704,26 @@ mwifiex_add_card(void *card, struct semaphore *sem,
888 goto err_init_fw; 704 goto err_init_fw;
889 } 705 }
890 706
891 /* Add interfaces */ 707 priv = adapter->priv[0];
892 for (i = 0; i < adapter->drv_mode->intf_num; i++) { 708
893 if (!mwifiex_add_interface(adapter, i, 709 if (mwifiex_register_cfg80211(priv) != 0) {
894 adapter->drv_mode->bss_attr[i].bss_type)) { 710 dev_err(adapter->dev, "cannot register netdevice"
895 goto err_add_intf; 711 " with cfg80211\n");
896 } 712 goto err_init_fw;
713 }
714
715 rtnl_lock();
716 /* Create station interface by default */
717 if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
718 NL80211_IFTYPE_STATION, NULL, NULL)) {
719 rtnl_unlock();
720 dev_err(adapter->dev, "cannot create default station"
721 " interface\n");
722 goto err_add_intf;
897 } 723 }
898 724
725 rtnl_unlock();
726
899 up(sem); 727 up(sem);
900 728
901 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); 729 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
@@ -904,8 +732,9 @@ mwifiex_add_card(void *card, struct semaphore *sem,
904 return 0; 732 return 0;
905 733
906err_add_intf: 734err_add_intf:
907 for (i = 0; i < adapter->priv_num; i++) 735 rtnl_lock();
908 mwifiex_remove_interface(adapter, i); 736 mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
737 rtnl_unlock();
909err_init_fw: 738err_init_fw:
910 pr_debug("info: %s: unregister device\n", __func__); 739 pr_debug("info: %s: unregister device\n", __func__);
911 adapter->if_ops.unregister_dev(adapter); 740 adapter->if_ops.unregister_dev(adapter);
@@ -960,7 +789,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
960 /* Stop data */ 789 /* Stop data */
961 for (i = 0; i < adapter->priv_num; i++) { 790 for (i = 0; i < adapter->priv_num; i++) {
962 priv = adapter->priv[i]; 791 priv = adapter->priv[i];
963 if (priv) { 792 if (priv && priv->netdev) {
964 if (!netif_queue_stopped(priv->netdev)) 793 if (!netif_queue_stopped(priv->netdev))
965 netif_stop_queue(priv->netdev); 794 netif_stop_queue(priv->netdev);
966 if (netif_carrier_ok(priv->netdev)) 795 if (netif_carrier_ok(priv->netdev))
@@ -985,9 +814,20 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
985 atomic_read(&adapter->cmd_pending)); 814 atomic_read(&adapter->cmd_pending));
986 } 815 }
987 816
988 /* Remove interface */ 817 for (i = 0; i < adapter->priv_num; i++) {
989 for (i = 0; i < adapter->priv_num; i++) 818 priv = adapter->priv[i];
990 mwifiex_remove_interface(adapter, i); 819
820 if (!priv)
821 continue;
822
823 rtnl_lock();
824 mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
825 rtnl_unlock();
826 }
827
828 wiphy_unregister(priv->wdev->wiphy);
829 wiphy_free(priv->wdev->wiphy);
830 kfree(priv->wdev);
991 831
992 mwifiex_terminate_workqueue(adapter); 832 mwifiex_terminate_workqueue(adapter);
993 833