aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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))