aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAmitkumar Karwar <akarwar@marvell.com>2011-12-13 23:43:17 -0500
committerJohn W. Linville <linville@tuxdriver.com>2011-12-14 14:50:11 -0500
commit38c9d6641ff0664911aebe4ba67124f28169a972 (patch)
tree3811428abd934e0ff69a2182e66def04b39bb6f4 /drivers/net
parent00918d33c0e9966392e5a13aeacd712b9da473c9 (diff)
mwifiex: remove cfg_workqueue
cfg_workqueue was added to notify cfg80211 that scan, connect or disconnect is done by calling respective completion handlers. We can avoid use of this workqueue by calling those handlers from other places. 1) Call connect, disconnect completion handlers in their callback functions. ex. Call cfg80211_connect_result() in mwifiex_cfg80211_connect() 2) Call scan completion handler after parsing response of last scan command in a queue. After removing the workqueue, variables (assoc_request etc.) and checks used for mutual exclusion become redundant. Those are also removed in this patch. Signed-off-by: Amitkumar Karwar <akarwar@marvell.com> Signed-off-by: Yogesh Ashok Powar <yogeshp@marvell.com> Signed-off-by: Nishant Sarmukadam <nishants@marvell.com> Signed-off-by: Kiran Divekar <dkiran@marvell.com> Signed-off-by: Bing Zhao <bzhao@marvell.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c191
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.h1
-rw-r--r--drivers/net/wireless/mwifiex/main.c2
-rw-r--r--drivers/net/wireless/mwifiex/main.h9
-rw-r--r--drivers/net/wireless/mwifiex/scan.c13
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c17
6 files changed, 75 insertions, 158 deletions
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index ffd293e2b87f..787dbe2aa408 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -751,17 +751,13 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
751{ 751{
752 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 752 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
753 753
754 if (priv->disconnect)
755 return -EBUSY;
756
757 priv->disconnect = 1;
758 if (mwifiex_deauthenticate(priv, NULL)) 754 if (mwifiex_deauthenticate(priv, NULL))
759 return -EFAULT; 755 return -EFAULT;
760 756
761 wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" 757 wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
762 " reason code %d\n", priv->cfg_bssid, reason_code); 758 " reason code %d\n", priv->cfg_bssid, reason_code);
763 759
764 queue_work(priv->workqueue, &priv->cfg_workqueue); 760 memset(priv->cfg_bssid, 0, ETH_ALEN);
765 761
766 return 0; 762 return 0;
767} 763}
@@ -981,27 +977,32 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
981 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 977 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
982 int ret = 0; 978 int ret = 0;
983 979
984 if (priv->assoc_request)
985 return -EBUSY;
986
987 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { 980 if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
988 wiphy_err(wiphy, "received infra assoc request " 981 wiphy_err(wiphy, "received infra assoc request "
989 "when station is in ibss mode\n"); 982 "when station is in ibss mode\n");
990 goto done; 983 goto done;
991 } 984 }
992 985
993 priv->assoc_request = -EINPROGRESS;
994
995 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", 986 wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
996 (char *) sme->ssid, sme->bssid); 987 (char *) sme->ssid, sme->bssid);
997 988
998 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, 989 ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
999 priv->bss_mode, sme->channel, sme, 0); 990 priv->bss_mode, sme->channel, sme, 0);
1000
1001 priv->assoc_request = 1;
1002done: 991done:
1003 priv->assoc_result = ret; 992 if (!ret) {
1004 queue_work(priv->workqueue, &priv->cfg_workqueue); 993 cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
994 NULL, 0, WLAN_STATUS_SUCCESS,
995 GFP_KERNEL);
996 dev_dbg(priv->adapter->dev,
997 "info: associated to bssid %pM successfully\n",
998 priv->cfg_bssid);
999 } else {
1000 dev_dbg(priv->adapter->dev,
1001 "info: association to bssid %pM failed\n",
1002 priv->cfg_bssid);
1003 memset(priv->cfg_bssid, 0, ETH_ALEN);
1004 }
1005
1005 return ret; 1006 return ret;
1006} 1007}
1007 1008
@@ -1018,28 +1019,29 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1018 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 1019 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
1019 int ret = 0; 1020 int ret = 0;
1020 1021
1021 if (priv->ibss_join_request)
1022 return -EBUSY;
1023
1024 if (priv->bss_mode != NL80211_IFTYPE_ADHOC) { 1022 if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
1025 wiphy_err(wiphy, "request to join ibss received " 1023 wiphy_err(wiphy, "request to join ibss received "
1026 "when station is not in ibss mode\n"); 1024 "when station is not in ibss mode\n");
1027 goto done; 1025 goto done;
1028 } 1026 }
1029 1027
1030 priv->ibss_join_request = -EINPROGRESS;
1031
1032 wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", 1028 wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
1033 (char *) params->ssid, params->bssid); 1029 (char *) params->ssid, params->bssid);
1034 1030
1035 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, 1031 ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
1036 params->bssid, priv->bss_mode, 1032 params->bssid, priv->bss_mode,
1037 params->channel, NULL, params->privacy); 1033 params->channel, NULL, params->privacy);
1038
1039 priv->ibss_join_request = 1;
1040done: 1034done:
1041 priv->ibss_join_result = ret; 1035 if (!ret) {
1042 queue_work(priv->workqueue, &priv->cfg_workqueue); 1036 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
1037 dev_dbg(priv->adapter->dev,
1038 "info: joined/created adhoc network with bssid"
1039 " %pM successfully\n", priv->cfg_bssid);
1040 } else {
1041 dev_dbg(priv->adapter->dev,
1042 "info: failed creating/joining adhoc network\n");
1043 }
1044
1043 return ret; 1045 return ret;
1044} 1046}
1045 1047
@@ -1054,17 +1056,12 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1054{ 1056{
1055 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); 1057 struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
1056 1058
1057 if (priv->disconnect)
1058 return -EBUSY;
1059
1060 priv->disconnect = 1;
1061
1062 wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", 1059 wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
1063 priv->cfg_bssid); 1060 priv->cfg_bssid);
1064 if (mwifiex_deauthenticate(priv, NULL)) 1061 if (mwifiex_deauthenticate(priv, NULL))
1065 return -EFAULT; 1062 return -EFAULT;
1066 1063
1067 queue_work(priv->workqueue, &priv->cfg_workqueue); 1064 memset(priv->cfg_bssid, 0, ETH_ALEN);
1068 1065
1069 return 0; 1066 return 0;
1070} 1067}
@@ -1081,15 +1078,42 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
1081 struct cfg80211_scan_request *request) 1078 struct cfg80211_scan_request *request)
1082{ 1079{
1083 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1080 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1081 int i;
1082 struct ieee80211_channel *chan;
1084 1083
1085 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); 1084 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1086 1085
1087 if (priv->scan_request && priv->scan_request != request)
1088 return -EBUSY;
1089
1090 priv->scan_request = request; 1086 priv->scan_request = request;
1091 1087
1092 queue_work(priv->workqueue, &priv->cfg_workqueue); 1088 priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
1089 GFP_KERNEL);
1090 if (!priv->user_scan_cfg) {
1091 dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
1092 return -ENOMEM;
1093 }
1094 for (i = 0; i < request->n_ssids; i++) {
1095 memcpy(priv->user_scan_cfg->ssid_list[i].ssid,
1096 request->ssids[i].ssid, request->ssids[i].ssid_len);
1097 priv->user_scan_cfg->ssid_list[i].max_len =
1098 request->ssids[i].ssid_len;
1099 }
1100 for (i = 0; i < request->n_channels; i++) {
1101 chan = request->channels[i];
1102 priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1103 priv->user_scan_cfg->chan_list[i].radio_type = chan->band;
1104
1105 if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
1106 priv->user_scan_cfg->chan_list[i].scan_type =
1107 MWIFIEX_SCAN_TYPE_PASSIVE;
1108 else
1109 priv->user_scan_cfg->chan_list[i].scan_type =
1110 MWIFIEX_SCAN_TYPE_ACTIVE;
1111
1112 priv->user_scan_cfg->chan_list[i].scan_time = 0;
1113 }
1114 if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg))
1115 return -EFAULT;
1116
1093 return 0; 1117 return 0;
1094} 1118}
1095 1119
@@ -1295,10 +1319,6 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1295 1319
1296 priv->media_connected = false; 1320 priv->media_connected = false;
1297 1321
1298 cancel_work_sync(&priv->cfg_workqueue);
1299 flush_workqueue(priv->workqueue);
1300 destroy_workqueue(priv->workqueue);
1301
1302 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 1322 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
1303 1323
1304 return 0; 1324 return 0;
@@ -1404,100 +1424,3 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
1404 1424
1405 return ret; 1425 return ret;
1406} 1426}
1407
1408/*
1409 * This function handles the result of different pending network operations.
1410 *
1411 * The following operations are handled and CFG802.11 subsystem is
1412 * notified accordingly -
1413 * - Scan request completion
1414 * - Association request completion
1415 * - IBSS join request completion
1416 * - Disconnect request completion
1417 */
1418void
1419mwifiex_cfg80211_results(struct work_struct *work)
1420{
1421 struct mwifiex_private *priv =
1422 container_of(work, struct mwifiex_private, cfg_workqueue);
1423 struct mwifiex_user_scan_cfg *scan_req;
1424 int ret = 0, i;
1425 struct ieee80211_channel *chan;
1426
1427 if (priv->scan_request) {
1428 scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
1429 GFP_KERNEL);
1430 if (!scan_req) {
1431 dev_err(priv->adapter->dev, "failed to alloc "
1432 "scan_req\n");
1433 return;
1434 }
1435 for (i = 0; i < priv->scan_request->n_ssids; i++) {
1436 memcpy(scan_req->ssid_list[i].ssid,
1437 priv->scan_request->ssids[i].ssid,
1438 priv->scan_request->ssids[i].ssid_len);
1439 scan_req->ssid_list[i].max_len =
1440 priv->scan_request->ssids[i].ssid_len;
1441 }
1442 for (i = 0; i < priv->scan_request->n_channels; i++) {
1443 chan = priv->scan_request->channels[i];
1444 scan_req->chan_list[i].chan_number = chan->hw_value;
1445 scan_req->chan_list[i].radio_type = chan->band;
1446 if (chan->flags & IEEE80211_CHAN_DISABLED)
1447 scan_req->chan_list[i].scan_type =
1448 MWIFIEX_SCAN_TYPE_PASSIVE;
1449 else
1450 scan_req->chan_list[i].scan_type =
1451 MWIFIEX_SCAN_TYPE_ACTIVE;
1452 scan_req->chan_list[i].scan_time = 0;
1453 }
1454 if (mwifiex_set_user_scan_ioctl(priv, scan_req))
1455 ret = -EFAULT;
1456 priv->scan_result_status = ret;
1457 dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
1458 __func__);
1459 cfg80211_scan_done(priv->scan_request,
1460 (priv->scan_result_status < 0));
1461 priv->scan_request = NULL;
1462 kfree(scan_req);
1463 }
1464
1465 if (priv->assoc_request == 1) {
1466 if (!priv->assoc_result) {
1467 cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
1468 NULL, 0, NULL, 0,
1469 WLAN_STATUS_SUCCESS,
1470 GFP_KERNEL);
1471 dev_dbg(priv->adapter->dev,
1472 "info: associated to bssid %pM successfully\n",
1473 priv->cfg_bssid);
1474 } else {
1475 dev_dbg(priv->adapter->dev,
1476 "info: association to bssid %pM failed\n",
1477 priv->cfg_bssid);
1478 memset(priv->cfg_bssid, 0, ETH_ALEN);
1479 }
1480 priv->assoc_request = 0;
1481 priv->assoc_result = 0;
1482 }
1483
1484 if (priv->ibss_join_request == 1) {
1485 if (!priv->ibss_join_result) {
1486 cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
1487 GFP_KERNEL);
1488 dev_dbg(priv->adapter->dev,
1489 "info: joined/created adhoc network with bssid"
1490 " %pM successfully\n", priv->cfg_bssid);
1491 } else {
1492 dev_dbg(priv->adapter->dev,
1493 "info: failed creating/joining adhoc network\n");
1494 }
1495 priv->ibss_join_request = 0;
1496 priv->ibss_join_result = 0;
1497 }
1498
1499 if (priv->disconnect) {
1500 memset(priv->cfg_bssid, 0, ETH_ALEN);
1501 priv->disconnect = 0;
1502 }
1503}
diff --git a/drivers/net/wireless/mwifiex/cfg80211.h b/drivers/net/wireless/mwifiex/cfg80211.h
index 8d010f2500c5..76c76c60438b 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.h
+++ b/drivers/net/wireless/mwifiex/cfg80211.h
@@ -26,5 +26,4 @@
26 26
27int mwifiex_register_cfg80211(struct mwifiex_private *); 27int mwifiex_register_cfg80211(struct mwifiex_private *);
28 28
29void mwifiex_cfg80211_results(struct work_struct *work);
30#endif 29#endif
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index d21cd4707f01..84be196188cc 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -586,8 +586,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
586 priv->media_connected = false; 586 priv->media_connected = false;
587 memset(&priv->nick_name, 0, sizeof(priv->nick_name)); 587 memset(&priv->nick_name, 0, sizeof(priv->nick_name));
588 priv->num_tx_timeout = 0; 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); 589 memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
592} 590}
593 591
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 41f88631763c..9207fc64641e 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -453,15 +453,8 @@ struct mwifiex_private {
453 u8 scan_pending_on_block; 453 u8 scan_pending_on_block;
454 u8 report_scan_result; 454 u8 report_scan_result;
455 struct cfg80211_scan_request *scan_request; 455 struct cfg80211_scan_request *scan_request;
456 int scan_result_status; 456 struct mwifiex_user_scan_cfg *user_scan_cfg;
457 int assoc_request;
458 u16 assoc_result;
459 int ibss_join_request;
460 u16 ibss_join_result;
461 bool disconnect;
462 u8 cfg_bssid[6]; 457 u8 cfg_bssid[6];
463 struct workqueue_struct *workqueue;
464 struct work_struct cfg_workqueue;
465 u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; 458 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
466 struct wps wps; 459 struct wps wps;
467 u8 scan_block; 460 u8 scan_block;
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index b8b9d37b01a9..e2e715666bca 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1391,11 +1391,8 @@ int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
1391{ 1391{
1392 int status; 1392 int status;
1393 1393
1394 priv->adapter->scan_wait_q_woken = false;
1395
1396 status = mwifiex_scan_networks(priv, scan_req); 1394 status = mwifiex_scan_networks(priv, scan_req);
1397 if (!status) 1395 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
1398 status = mwifiex_wait_queue_complete(priv->adapter);
1399 1396
1400 return status; 1397 return status;
1401} 1398}
@@ -1796,6 +1793,14 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
1796 up(&priv->async_sem); 1793 up(&priv->async_sem);
1797 } 1794 }
1798 1795
1796 if (priv->user_scan_cfg) {
1797 dev_dbg(priv->adapter->dev, "info: %s: sending scan "
1798 "results\n", __func__);
1799 cfg80211_scan_done(priv->scan_request, 0);
1800 priv->scan_request = NULL;
1801 kfree(priv->user_scan_cfg);
1802 priv->user_scan_cfg = NULL;
1803 }
1799 } else { 1804 } else {
1800 /* Get scan command from scan_pending_q and put to 1805 /* Get scan command from scan_pending_q and put to
1801 cmd_pending_q */ 1806 cmd_pending_q */
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 40205f60be4d..d7aa21da84d0 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -115,16 +115,15 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
115 if (adapter->num_cmd_timeout && adapter->curr_cmd) 115 if (adapter->num_cmd_timeout && adapter->curr_cmd)
116 return; 116 return;
117 priv->media_connected = false; 117 priv->media_connected = false;
118 if (!priv->disconnect) { 118 dev_dbg(adapter->dev, "info: successfully disconnected from"
119 priv->disconnect = 1; 119 " %pM: reason code %d\n", priv->cfg_bssid,
120 dev_dbg(adapter->dev, "info: successfully disconnected from" 120 WLAN_REASON_DEAUTH_LEAVING);
121 " %pM: reason code %d\n", priv->cfg_bssid, 121 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
122 WLAN_REASON_DEAUTH_LEAVING); 122 cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING,
123 cfg80211_disconnected(priv->netdev, 123 NULL, 0, GFP_KERNEL);
124 WLAN_REASON_DEAUTH_LEAVING, NULL, 0,
125 GFP_KERNEL);
126 queue_work(priv->workqueue, &priv->cfg_workqueue);
127 } 124 }
125 memset(priv->cfg_bssid, 0, ETH_ALEN);
126
128 if (!netif_queue_stopped(priv->netdev)) 127 if (!netif_queue_stopped(priv->netdev))
129 mwifiex_stop_net_dev_queue(priv->netdev, adapter); 128 mwifiex_stop_net_dev_queue(priv->netdev, adapter);
130 if (netif_carrier_ok(priv->netdev)) 129 if (netif_carrier_ok(priv->netdev))