aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYogesh Ashok Powar <yogeshp@marvell.com>2011-09-26 23:37:26 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-09-30 15:57:01 -0400
commit93a1df48d224296fb527d32fbec4d5162828feb4 (patch)
tree9e99b9364d2d96e1a865425da2a68e3e3cd048c7
parent4ec6f9c0c9602bf8e6972eca470fbd1e99c5b222 (diff)
mwifiex: add cfg80211 handlers add/del_virtual_intf
Making adding and deleting virtual interfaces dynamic. Adding handlers for creating and deleting virtual interface with given name and dev respectively. Also, creating default interface of type station on insmod of the driver. Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c156
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h3
-rw-r--r--drivers/net/wireless/mwifiex/decl.h8
-rw-r--r--drivers/net/wireless/mwifiex/init.c2
-rw-r--r--drivers/net/wireless/mwifiex/main.c263
-rw-r--r--drivers/net/wireless/mwifiex/main.h18
6 files changed, 207 insertions, 243 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index e61a6c0dd0ff..462c71067bfb 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1162,8 +1162,150 @@ mwifiex_setup_ht_caps(struct ieee80211_sta_ht_cap *ht_info,
1162 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED; 1162 ht_info->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1163} 1163}
1164 1164
1165/*
1166 * create a new virtual interface with the given name
1167 */
1168struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
1169 char *name,
1170 enum nl80211_iftype type,
1171 u32 *flags,
1172 struct vif_params *params)
1173{
1174 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
1175 struct mwifiex_adapter *adapter;
1176 struct net_device *dev;
1177 void *mdev_priv;
1178
1179 if (!priv)
1180 return NULL;
1181
1182 adapter = priv->adapter;
1183 if (!adapter)
1184 return NULL;
1185
1186 switch (type) {
1187 case NL80211_IFTYPE_UNSPECIFIED:
1188 case NL80211_IFTYPE_STATION:
1189 case NL80211_IFTYPE_ADHOC:
1190 if (priv->bss_mode) {
1191 wiphy_err(wiphy, "cannot create multiple"
1192 " station/adhoc interfaces\n");
1193 return NULL;
1194 }
1195
1196 if (type == NL80211_IFTYPE_UNSPECIFIED)
1197 priv->bss_mode = NL80211_IFTYPE_STATION;
1198 else
1199 priv->bss_mode = type;
1200
1201 priv->bss_type = MWIFIEX_BSS_TYPE_STA;
1202 priv->frame_type = MWIFIEX_DATA_FRAME_TYPE_ETH_II;
1203 priv->bss_priority = 0;
1204 priv->bss_role = MWIFIEX_BSS_ROLE_STA;
1205 priv->bss_index = 0;
1206 priv->bss_num = 0;
1207
1208 break;
1209 default:
1210 wiphy_err(wiphy, "type not supported\n");
1211 return NULL;
1212 }
1213
1214 dev = alloc_netdev_mq(sizeof(struct mwifiex_private *), name,
1215 ether_setup, 1);
1216 if (!dev) {
1217 wiphy_err(wiphy, "no memory available for netdevice\n");
1218 goto error;
1219 }
1220
1221 dev_net_set(dev, wiphy_net(wiphy));
1222 dev->ieee80211_ptr = priv->wdev;
1223 dev->ieee80211_ptr->iftype = priv->bss_mode;
1224 memcpy(dev->dev_addr, wiphy->perm_addr, ETH_ALEN);
1225 memcpy(dev->perm_addr, wiphy->perm_addr, ETH_ALEN);
1226 SET_NETDEV_DEV(dev, wiphy_dev(wiphy));
1227
1228 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1229 dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
1230 dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
1231
1232 mdev_priv = netdev_priv(dev);
1233 *((unsigned long *) mdev_priv) = (unsigned long) priv;
1234
1235 priv->netdev = dev;
1236 mwifiex_init_priv_params(priv, dev);
1237
1238 SET_NETDEV_DEV(dev, adapter->dev);
1239
1240 /* Register network device */
1241 if (register_netdevice(dev)) {
1242 wiphy_err(wiphy, "cannot register virtual network device\n");
1243 goto error;
1244 }
1245
1246 sema_init(&priv->async_sem, 1);
1247 priv->scan_pending_on_block = false;
1248
1249 dev_dbg(adapter->dev, "info: %s: Marvell 802.11 Adapter\n", dev->name);
1250
1251#ifdef CONFIG_DEBUG_FS
1252 mwifiex_dev_debugfs_init(priv);
1253#endif
1254 return dev;
1255error:
1256 if (dev && (dev->reg_state == NETREG_UNREGISTERED))
1257 free_netdev(dev);
1258 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
1259
1260 return NULL;
1261}
1262EXPORT_SYMBOL_GPL(mwifiex_add_virtual_intf);
1263
1264/*
1265 * del_virtual_intf: remove the virtual interface determined by dev
1266 */
1267int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1268{
1269 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
1270
1271 if (!priv || !dev)
1272 return 0;
1273
1274#ifdef CONFIG_DEBUG_FS
1275 mwifiex_dev_debugfs_remove(priv);
1276#endif
1277
1278 if (!netif_queue_stopped(priv->netdev))
1279 netif_stop_queue(priv->netdev);
1280
1281 if (netif_carrier_ok(priv->netdev))
1282 netif_carrier_off(priv->netdev);
1283
1284 if (dev->reg_state == NETREG_REGISTERED)
1285 unregister_netdevice(dev);
1286
1287 if (dev->reg_state == NETREG_UNREGISTERED)
1288 free_netdev(dev);
1289
1290 /* Clear the priv in adapter */
1291 priv->netdev = NULL;
1292
1293 priv->media_connected = false;
1294
1295 cancel_work_sync(&priv->cfg_workqueue);
1296 flush_workqueue(priv->workqueue);
1297 destroy_workqueue(priv->workqueue);
1298
1299 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
1300
1301 return 0;
1302}
1303EXPORT_SYMBOL_GPL(mwifiex_del_virtual_intf);
1304
1165/* station cfg80211 operations */ 1305/* station cfg80211 operations */
1166static struct cfg80211_ops mwifiex_cfg80211_ops = { 1306static struct cfg80211_ops mwifiex_cfg80211_ops = {
1307 .add_virtual_intf = mwifiex_add_virtual_intf,
1308 .del_virtual_intf = mwifiex_del_virtual_intf,
1167 .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf, 1309 .change_virtual_intf = mwifiex_cfg80211_change_virtual_intf,
1168 .scan = mwifiex_cfg80211_scan, 1310 .scan = mwifiex_cfg80211_scan,
1169 .connect = mwifiex_cfg80211_connect, 1311 .connect = mwifiex_cfg80211_connect,
@@ -1188,8 +1330,7 @@ static struct cfg80211_ops mwifiex_cfg80211_ops = {
1188 * default parameters and handler function pointers, and finally 1330 * default parameters and handler function pointers, and finally
1189 * registers the device. 1331 * registers the device.
1190 */ 1332 */
1191int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac, 1333int mwifiex_register_cfg80211(struct mwifiex_private *priv)
1192 struct mwifiex_private *priv)
1193{ 1334{
1194 int ret; 1335 int ret;
1195 void *wdev_priv; 1336 void *wdev_priv;
@@ -1229,7 +1370,7 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
1229 wdev->wiphy->cipher_suites = mwifiex_cipher_suites; 1370 wdev->wiphy->cipher_suites = mwifiex_cipher_suites;
1230 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); 1371 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites);
1231 1372
1232 memcpy(wdev->wiphy->perm_addr, mac, 6); 1373 memcpy(wdev->wiphy->perm_addr, priv->curr_addr, ETH_ALEN);
1233 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 1374 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1234 1375
1235 /* We are using custom domains */ 1376 /* We are using custom domains */
@@ -1259,17 +1400,8 @@ int mwifiex_register_cfg80211(struct net_device *dev, u8 *mac,
1259 "info: successfully registered wiphy device\n"); 1400 "info: successfully registered wiphy device\n");
1260 } 1401 }
1261 1402
1262 dev_net_set(dev, wiphy_net(wdev->wiphy));
1263 dev->ieee80211_ptr = wdev;
1264 memcpy(dev->dev_addr, wdev->wiphy->perm_addr, 6);
1265 memcpy(dev->perm_addr, wdev->wiphy->perm_addr, 6);
1266 SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
1267 priv->wdev = wdev; 1403 priv->wdev = wdev;
1268 1404
1269 dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
1270 dev->watchdog_timeo = MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT;
1271 dev->hard_header_len += MWIFIEX_MIN_DATA_HEADER_LEN;
1272
1273 return ret; 1405 return ret;
1274} 1406}
1275 1407
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
index c4db8f36aa16..8d010f2500c5 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.h
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -24,8 +24,7 @@
24 24
25#include "main.h" 25#include "main.h"
26 26
27int mwifiex_register_cfg80211(struct net_device *, u8 *, 27int mwifiex_register_cfg80211(struct mwifiex_private *);
28 struct mwifiex_private *);
29 28
30void mwifiex_cfg80211_results(struct work_struct *work); 29void mwifiex_cfg80211_results(struct work_struct *work);
31#endif 30#endif
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 94ddc9038cb3..6ca62c809cb9 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -114,14 +114,6 @@ struct mwifiex_txinfo {
114 u8 bss_index; 114 u8 bss_index;
115}; 115};
116 116
117struct mwifiex_bss_attr {
118 u8 bss_type;
119 u8 frame_type;
120 u8 active;
121 u8 bss_priority;
122 u8 bss_num;
123};
124
125enum mwifiex_wmm_ac_e { 117enum mwifiex_wmm_ac_e {
126 WMM_AC_BK, 118 WMM_AC_BK,
127 WMM_AC_BE, 119 WMM_AC_BE,
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 26e685a31bc0..e1076b46401e 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -76,7 +76,7 @@ static int mwifiex_init_priv(struct mwifiex_private *priv)
76 memset(priv->curr_addr, 0xff, ETH_ALEN); 76 memset(priv->curr_addr, 0xff, ETH_ALEN);
77 77
78 priv->pkt_tx_ctrl = 0; 78 priv->pkt_tx_ctrl = 0;
79 priv->bss_mode = NL80211_IFTYPE_STATION; 79 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
80 priv->data_rate = 0; /* Initially indicate the rate as auto */ 80 priv->data_rate = 0; /* Initially indicate the rate as auto */
81 priv->is_data_rate_auto = true; 81 priv->is_data_rate_auto = true;
82 priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR; 82 priv->bcn_avg_factor = DEFAULT_BCN_AVG_FACTOR;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 53579ad83e5c..8b05b4f5ffe2 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,42 +62,19 @@ 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
75 adapter->priv_num++;
76
77 adapter->priv[0]->adapter = adapter;
117 if (mwifiex_init_lock_list(adapter)) 78 if (mwifiex_init_lock_list(adapter))
118 goto error; 79 goto error;
119 80
@@ -127,8 +88,10 @@ error:
127 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n"); 88 dev_dbg(adapter->dev, "info: leave mwifiex_register with error\n");
128 89
129 mwifiex_free_lock_list(adapter); 90 mwifiex_free_lock_list(adapter);
130 for (i = 0; i < drv_mode_ptr->intf_num; i++) 91
92 for (i = 0; i < adapter->priv_num; i++)
131 kfree(adapter->priv[i]); 93 kfree(adapter->priv[i]);
94
132 kfree(adapter); 95 kfree(adapter);
133 96
134 return -1; 97 return -1;
@@ -316,38 +279,6 @@ exit_main_proc:
316} 279}
317 280
318/* 281/*
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. 282 * This function frees the adapter structure.
352 * 283 *
353 * Additionally, this closes the netlink socket, frees the timers 284 * Additionally, this closes the netlink socket, frees the timers
@@ -649,8 +580,8 @@ static const struct net_device_ops mwifiex_netdev_ops = {
649 * 580 *
650 * In addition, the CFG80211 work queue is also created. 581 * In addition, the CFG80211 work queue is also created.
651 */ 582 */
652static void 583void mwifiex_init_priv_params(struct mwifiex_private *priv,
653mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev) 584 struct net_device *dev)
654{ 585{
655 dev->netdev_ops = &mwifiex_netdev_ops; 586 dev->netdev_ops = &mwifiex_netdev_ops;
656 /* Initialize private structure */ 587 /* Initialize private structure */
@@ -664,118 +595,6 @@ mwifiex_init_priv_params(struct mwifiex_private *priv, struct net_device *dev)
664} 595}
665 596
666/* 597/*
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. 598 * This function check if command is pending.
780 */ 599 */
781int is_command_pending(struct mwifiex_adapter *adapter) 600int is_command_pending(struct mwifiex_adapter *adapter)
@@ -847,14 +666,14 @@ int
847mwifiex_add_card(void *card, struct semaphore *sem, 666mwifiex_add_card(void *card, struct semaphore *sem,
848 struct mwifiex_if_ops *if_ops) 667 struct mwifiex_if_ops *if_ops)
849{ 668{
850 int i;
851 struct mwifiex_adapter *adapter; 669 struct mwifiex_adapter *adapter;
852 char fmt[64]; 670 char fmt[64];
671 struct mwifiex_private *priv;
853 672
854 if (down_interruptible(sem)) 673 if (down_interruptible(sem))
855 goto exit_sem_err; 674 goto exit_sem_err;
856 675
857 if (mwifiex_init_sw(card, if_ops, (void **)&adapter)) { 676 if (mwifiex_register(card, if_ops, (void **)&adapter)) {
858 pr_err("%s: software init failed\n", __func__); 677 pr_err("%s: software init failed\n", __func__);
859 goto err_init_sw; 678 goto err_init_sw;
860 } 679 }
@@ -888,14 +707,26 @@ mwifiex_add_card(void *card, struct semaphore *sem,
888 goto err_init_fw; 707 goto err_init_fw;
889 } 708 }
890 709
891 /* Add interfaces */ 710 priv = adapter->priv[0];
892 for (i = 0; i < adapter->drv_mode->intf_num; i++) { 711
893 if (!mwifiex_add_interface(adapter, i, 712 if (mwifiex_register_cfg80211(priv) != 0) {
894 adapter->drv_mode->bss_attr[i].bss_type)) { 713 dev_err(adapter->dev, "cannot register netdevice"
895 goto err_add_intf; 714 " with cfg80211\n");
896 } 715 goto err_init_fw;
716 }
717
718 rtnl_lock();
719 /* Create station interface by default */
720 if (!mwifiex_add_virtual_intf(priv->wdev->wiphy, "mlan%d",
721 NL80211_IFTYPE_STATION, NULL, NULL)) {
722 rtnl_unlock();
723 dev_err(adapter->dev, "cannot create default station"
724 " interface\n");
725 goto err_add_intf;
897 } 726 }
898 727
728 rtnl_unlock();
729
899 up(sem); 730 up(sem);
900 731
901 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1); 732 mwifiex_drv_get_driver_version(adapter, fmt, sizeof(fmt) - 1);
@@ -904,8 +735,9 @@ mwifiex_add_card(void *card, struct semaphore *sem,
904 return 0; 735 return 0;
905 736
906err_add_intf: 737err_add_intf:
907 for (i = 0; i < adapter->priv_num; i++) 738 rtnl_lock();
908 mwifiex_remove_interface(adapter, i); 739 mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
740 rtnl_unlock();
909err_init_fw: 741err_init_fw:
910 pr_debug("info: %s: unregister device\n", __func__); 742 pr_debug("info: %s: unregister device\n", __func__);
911 adapter->if_ops.unregister_dev(adapter); 743 adapter->if_ops.unregister_dev(adapter);
@@ -960,7 +792,7 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
960 /* Stop data */ 792 /* Stop data */
961 for (i = 0; i < adapter->priv_num; i++) { 793 for (i = 0; i < adapter->priv_num; i++) {
962 priv = adapter->priv[i]; 794 priv = adapter->priv[i];
963 if (priv) { 795 if (priv && priv->netdev) {
964 if (!netif_queue_stopped(priv->netdev)) 796 if (!netif_queue_stopped(priv->netdev))
965 netif_stop_queue(priv->netdev); 797 netif_stop_queue(priv->netdev);
966 if (netif_carrier_ok(priv->netdev)) 798 if (netif_carrier_ok(priv->netdev))
@@ -985,9 +817,20 @@ int mwifiex_remove_card(struct mwifiex_adapter *adapter, struct semaphore *sem)
985 atomic_read(&adapter->cmd_pending)); 817 atomic_read(&adapter->cmd_pending));
986 } 818 }
987 819
988 /* Remove interface */ 820 for (i = 0; i < adapter->priv_num; i++) {
989 for (i = 0; i < adapter->priv_num; i++) 821 priv = adapter->priv[i];
990 mwifiex_remove_interface(adapter, i); 822
823 if (!priv)
824 continue;
825
826 rtnl_lock();
827 mwifiex_del_virtual_intf(priv->wdev->wiphy, priv->netdev);
828 rtnl_unlock();
829 }
830
831 wiphy_unregister(priv->wdev->wiphy);
832 wiphy_free(priv->wdev->wiphy);
833 kfree(priv->wdev);
991 834
992 mwifiex_terminate_workqueue(adapter); 835 mwifiex_terminate_workqueue(adapter);
993 836
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 1e801328a558..4f4042809f23 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -45,15 +45,6 @@ enum {
45 MWIFIEX_SYNC_CMD 45 MWIFIEX_SYNC_CMD
46}; 46};
47 47
48#define DRV_MODE_STA 0x1
49
50struct mwifiex_drv_mode {
51 u16 drv_mode;
52 u16 intf_num;
53 struct mwifiex_bss_attr *bss_attr;
54};
55
56
57#define MWIFIEX_MAX_AP 64 48#define MWIFIEX_MAX_AP 64
58 49
59#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ) 50#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
@@ -546,7 +537,6 @@ struct mwifiex_if_ops {
546struct mwifiex_adapter { 537struct mwifiex_adapter {
547 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM]; 538 struct mwifiex_private *priv[MWIFIEX_MAX_BSS_NUM];
548 u8 priv_num; 539 u8 priv_num;
549 struct mwifiex_drv_mode *drv_mode;
550 const struct firmware *firmware; 540 const struct firmware *firmware;
551 char fw_name[32]; 541 char fw_name[32];
552 struct device *dev; 542 struct device *dev;
@@ -792,6 +782,8 @@ int mwifiex_cmd_get_hw_spec(struct mwifiex_private *priv,
792int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv, 782int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
793 struct host_cmd_ds_command *resp); 783 struct host_cmd_ds_command *resp);
794int is_command_pending(struct mwifiex_adapter *adapter); 784int is_command_pending(struct mwifiex_adapter *adapter);
785void mwifiex_init_priv_params(struct mwifiex_private *priv,
786 struct net_device *dev);
795 787
796/* 788/*
797 * This function checks if the queuing is RA based or not. 789 * This function checks if the queuing is RA based or not.
@@ -966,6 +958,12 @@ int mwifiex_update_bss_desc_with_ie(struct mwifiex_adapter *adapter,
966int mwifiex_check_network_compatibility(struct mwifiex_private *priv, 958int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
967 struct mwifiex_bssdescriptor *bss_desc); 959 struct mwifiex_bssdescriptor *bss_desc);
968 960
961struct net_device *mwifiex_add_virtual_intf(struct wiphy *wiphy,
962 char *name, enum nl80211_iftype type,
963 u32 *flags, struct vif_params *params);
964int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev);
965
966
969#ifdef CONFIG_DEBUG_FS 967#ifdef CONFIG_DEBUG_FS
970void mwifiex_debugfs_init(void); 968void mwifiex_debugfs_init(void);
971void mwifiex_debugfs_remove(void); 969void mwifiex_debugfs_remove(void);