Commit 38c9d664 authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by John W. Linville

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: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarYogesh Ashok Powar <yogeshp@marvell.com>
Signed-off-by: default avatarNishant Sarmukadam <nishants@marvell.com>
Signed-off-by: default avatarKiran Divekar <dkiran@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 00918d33
...@@ -751,17 +751,13 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, ...@@ -751,17 +751,13 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
if (priv->disconnect)
return -EBUSY;
priv->disconnect = 1;
if (mwifiex_deauthenticate(priv, NULL)) if (mwifiex_deauthenticate(priv, NULL))
return -EFAULT; return -EFAULT;
wiphy_dbg(wiphy, "info: successfully disconnected from %pM:" wiphy_dbg(wiphy, "info: successfully disconnected from %pM:"
" reason code %d\n", priv->cfg_bssid, reason_code); " reason code %d\n", priv->cfg_bssid, reason_code);
queue_work(priv->workqueue, &priv->cfg_workqueue); memset(priv->cfg_bssid, 0, ETH_ALEN);
return 0; return 0;
} }
...@@ -981,27 +977,32 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, ...@@ -981,27 +977,32 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
int ret = 0; int ret = 0;
if (priv->assoc_request)
return -EBUSY;
if (priv->bss_mode == NL80211_IFTYPE_ADHOC) { if (priv->bss_mode == NL80211_IFTYPE_ADHOC) {
wiphy_err(wiphy, "received infra assoc request " wiphy_err(wiphy, "received infra assoc request "
"when station is in ibss mode\n"); "when station is in ibss mode\n");
goto done; goto done;
} }
priv->assoc_request = -EINPROGRESS;
wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n", wiphy_dbg(wiphy, "info: Trying to associate to %s and bssid %pM\n",
(char *) sme->ssid, sme->bssid); (char *) sme->ssid, sme->bssid);
ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid, ret = mwifiex_cfg80211_assoc(priv, sme->ssid_len, sme->ssid, sme->bssid,
priv->bss_mode, sme->channel, sme, 0); priv->bss_mode, sme->channel, sme, 0);
priv->assoc_request = 1;
done: done:
priv->assoc_result = ret; if (!ret) {
queue_work(priv->workqueue, &priv->cfg_workqueue); cfg80211_connect_result(priv->netdev, priv->cfg_bssid, NULL, 0,
NULL, 0, WLAN_STATUS_SUCCESS,
GFP_KERNEL);
dev_dbg(priv->adapter->dev,
"info: associated to bssid %pM successfully\n",
priv->cfg_bssid);
} else {
dev_dbg(priv->adapter->dev,
"info: association to bssid %pM failed\n",
priv->cfg_bssid);
memset(priv->cfg_bssid, 0, ETH_ALEN);
}
return ret; return ret;
} }
...@@ -1018,28 +1019,29 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, ...@@ -1018,28 +1019,29 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
int ret = 0; int ret = 0;
if (priv->ibss_join_request)
return -EBUSY;
if (priv->bss_mode != NL80211_IFTYPE_ADHOC) { if (priv->bss_mode != NL80211_IFTYPE_ADHOC) {
wiphy_err(wiphy, "request to join ibss received " wiphy_err(wiphy, "request to join ibss received "
"when station is not in ibss mode\n"); "when station is not in ibss mode\n");
goto done; goto done;
} }
priv->ibss_join_request = -EINPROGRESS;
wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n", wiphy_dbg(wiphy, "info: trying to join to %s and bssid %pM\n",
(char *) params->ssid, params->bssid); (char *) params->ssid, params->bssid);
ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid, ret = mwifiex_cfg80211_assoc(priv, params->ssid_len, params->ssid,
params->bssid, priv->bss_mode, params->bssid, priv->bss_mode,
params->channel, NULL, params->privacy); params->channel, NULL, params->privacy);
priv->ibss_join_request = 1;
done: done:
priv->ibss_join_result = ret; if (!ret) {
queue_work(priv->workqueue, &priv->cfg_workqueue); cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid, GFP_KERNEL);
dev_dbg(priv->adapter->dev,
"info: joined/created adhoc network with bssid"
" %pM successfully\n", priv->cfg_bssid);
} else {
dev_dbg(priv->adapter->dev,
"info: failed creating/joining adhoc network\n");
}
return ret; return ret;
} }
...@@ -1054,17 +1056,12 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) ...@@ -1054,17 +1056,12 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
{ {
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
if (priv->disconnect)
return -EBUSY;
priv->disconnect = 1;
wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n", wiphy_dbg(wiphy, "info: disconnecting from essid %pM\n",
priv->cfg_bssid); priv->cfg_bssid);
if (mwifiex_deauthenticate(priv, NULL)) if (mwifiex_deauthenticate(priv, NULL))
return -EFAULT; return -EFAULT;
queue_work(priv->workqueue, &priv->cfg_workqueue); memset(priv->cfg_bssid, 0, ETH_ALEN);
return 0; return 0;
} }
...@@ -1081,15 +1078,42 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev, ...@@ -1081,15 +1078,42 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request) struct cfg80211_scan_request *request)
{ {
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
int i;
struct ieee80211_channel *chan;
wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
if (priv->scan_request && priv->scan_request != request)
return -EBUSY;
priv->scan_request = request; priv->scan_request = request;
queue_work(priv->workqueue, &priv->cfg_workqueue); priv->user_scan_cfg = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
GFP_KERNEL);
if (!priv->user_scan_cfg) {
dev_err(priv->adapter->dev, "failed to alloc scan_req\n");
return -ENOMEM;
}
for (i = 0; i < request->n_ssids; i++) {
memcpy(priv->user_scan_cfg->ssid_list[i].ssid,
request->ssids[i].ssid, request->ssids[i].ssid_len);
priv->user_scan_cfg->ssid_list[i].max_len =
request->ssids[i].ssid_len;
}
for (i = 0; i < request->n_channels; i++) {
chan = request->channels[i];
priv->user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
priv->user_scan_cfg->chan_list[i].radio_type = chan->band;
if (chan->flags & IEEE80211_CHAN_PASSIVE_SCAN)
priv->user_scan_cfg->chan_list[i].scan_type =
MWIFIEX_SCAN_TYPE_PASSIVE;
else
priv->user_scan_cfg->chan_list[i].scan_type =
MWIFIEX_SCAN_TYPE_ACTIVE;
priv->user_scan_cfg->chan_list[i].scan_time = 0;
}
if (mwifiex_set_user_scan_ioctl(priv, priv->user_scan_cfg))
return -EFAULT;
return 0; return 0;
} }
...@@ -1295,10 +1319,6 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) ...@@ -1295,10 +1319,6 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
priv->media_connected = false; priv->media_connected = false;
cancel_work_sync(&priv->cfg_workqueue);
flush_workqueue(priv->workqueue);
destroy_workqueue(priv->workqueue);
priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
return 0; return 0;
...@@ -1404,100 +1424,3 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv) ...@@ -1404,100 +1424,3 @@ int mwifiex_register_cfg80211(struct mwifiex_private *priv)
return ret; return ret;
} }
/*
* This function handles the result of different pending network operations.
*
* The following operations are handled and CFG802.11 subsystem is
* notified accordingly -
* - Scan request completion
* - Association request completion
* - IBSS join request completion
* - Disconnect request completion
*/
void
mwifiex_cfg80211_results(struct work_struct *work)
{
struct mwifiex_private *priv =
container_of(work, struct mwifiex_private, cfg_workqueue);
struct mwifiex_user_scan_cfg *scan_req;
int ret = 0, i;
struct ieee80211_channel *chan;
if (priv->scan_request) {
scan_req = kzalloc(sizeof(struct mwifiex_user_scan_cfg),
GFP_KERNEL);
if (!scan_req) {
dev_err(priv->adapter->dev, "failed to alloc "
"scan_req\n");
return;
}
for (i = 0; i < priv->scan_request->n_ssids; i++) {
memcpy(scan_req->ssid_list[i].ssid,
priv->scan_request->ssids[i].ssid,
priv->scan_request->ssids[i].ssid_len);
scan_req->ssid_list[i].max_len =
priv->scan_request->ssids[i].ssid_len;
}
for (i = 0; i < priv->scan_request->n_channels; i++) {
chan = priv->scan_request->channels[i];
scan_req->chan_list[i].chan_number = chan->hw_value;
scan_req->chan_list[i].radio_type = chan->band;
if (chan->flags & IEEE80211_CHAN_DISABLED)
scan_req->chan_list[i].scan_type =
MWIFIEX_SCAN_TYPE_PASSIVE;
else
scan_req->chan_list[i].scan_type =
MWIFIEX_SCAN_TYPE_ACTIVE;
scan_req->chan_list[i].scan_time = 0;
}
if (mwifiex_set_user_scan_ioctl(priv, scan_req))
ret = -EFAULT;
priv->scan_result_status = ret;
dev_dbg(priv->adapter->dev, "info: %s: sending scan results\n",
__func__);
cfg80211_scan_done(priv->scan_request,
(priv->scan_result_status < 0));
priv->scan_request = NULL;
kfree(scan_req);
}
if (priv->assoc_request == 1) {
if (!priv->assoc_result) {
cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
NULL, 0, NULL, 0,
WLAN_STATUS_SUCCESS,
GFP_KERNEL);
dev_dbg(priv->adapter->dev,
"info: associated to bssid %pM successfully\n",
priv->cfg_bssid);
} else {
dev_dbg(priv->adapter->dev,
"info: association to bssid %pM failed\n",
priv->cfg_bssid);
memset(priv->cfg_bssid, 0, ETH_ALEN);
}
priv->assoc_request = 0;
priv->assoc_result = 0;
}
if (priv->ibss_join_request == 1) {
if (!priv->ibss_join_result) {
cfg80211_ibss_joined(priv->netdev, priv->cfg_bssid,
GFP_KERNEL);
dev_dbg(priv->adapter->dev,
"info: joined/created adhoc network with bssid"
" %pM successfully\n", priv->cfg_bssid);
} else {
dev_dbg(priv->adapter->dev,
"info: failed creating/joining adhoc network\n");
}
priv->ibss_join_request = 0;
priv->ibss_join_result = 0;
}
if (priv->disconnect) {
memset(priv->cfg_bssid, 0, ETH_ALEN);
priv->disconnect = 0;
}
}
...@@ -26,5 +26,4 @@ ...@@ -26,5 +26,4 @@
int mwifiex_register_cfg80211(struct mwifiex_private *); int mwifiex_register_cfg80211(struct mwifiex_private *);
void mwifiex_cfg80211_results(struct work_struct *work);
#endif #endif
...@@ -586,8 +586,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv, ...@@ -586,8 +586,6 @@ void mwifiex_init_priv_params(struct mwifiex_private *priv,
priv->media_connected = false; priv->media_connected = false;
memset(&priv->nick_name, 0, sizeof(priv->nick_name)); memset(&priv->nick_name, 0, sizeof(priv->nick_name));
priv->num_tx_timeout = 0; priv->num_tx_timeout = 0;
priv->workqueue = create_singlethread_workqueue("cfg80211_wq");
INIT_WORK(&priv->cfg_workqueue, mwifiex_cfg80211_results);
memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN); memcpy(dev->dev_addr, priv->curr_addr, ETH_ALEN);
} }
......
...@@ -453,15 +453,8 @@ struct mwifiex_private { ...@@ -453,15 +453,8 @@ struct mwifiex_private {
u8 scan_pending_on_block; u8 scan_pending_on_block;
u8 report_scan_result; u8 report_scan_result;
struct cfg80211_scan_request *scan_request; struct cfg80211_scan_request *scan_request;
int scan_result_status; struct mwifiex_user_scan_cfg *user_scan_cfg;
int assoc_request;
u16 assoc_result;
int ibss_join_request;
u16 ibss_join_result;
bool disconnect;
u8 cfg_bssid[6]; u8 cfg_bssid[6];
struct workqueue_struct *workqueue;
struct work_struct cfg_workqueue;
u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
struct wps wps; struct wps wps;
u8 scan_block; u8 scan_block;
......
...@@ -1391,11 +1391,8 @@ int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv, ...@@ -1391,11 +1391,8 @@ int mwifiex_set_user_scan_ioctl(struct mwifiex_private *priv,
{ {
int status; int status;
priv->adapter->scan_wait_q_woken = false;
status = mwifiex_scan_networks(priv, scan_req); status = mwifiex_scan_networks(priv, scan_req);
if (!status) queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
status = mwifiex_wait_queue_complete(priv->adapter);
return status; return status;
} }
...@@ -1796,6 +1793,14 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, ...@@ -1796,6 +1793,14 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv,
up(&priv->async_sem); up(&priv->async_sem);
} }
if (priv->user_scan_cfg) {
dev_dbg(priv->adapter->dev, "info: %s: sending scan "
"results\n", __func__);
cfg80211_scan_done(priv->scan_request, 0);
priv->scan_request = NULL;
kfree(priv->user_scan_cfg);
priv->user_scan_cfg = NULL;
}
} else { } else {
/* Get scan command from scan_pending_q and put to /* Get scan command from scan_pending_q and put to
cmd_pending_q */ cmd_pending_q */
......
...@@ -115,16 +115,15 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv) ...@@ -115,16 +115,15 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
if (adapter->num_cmd_timeout && adapter->curr_cmd) if (adapter->num_cmd_timeout && adapter->curr_cmd)
return; return;
priv->media_connected = false; priv->media_connected = false;
if (!priv->disconnect) {
priv->disconnect = 1;
dev_dbg(adapter->dev, "info: successfully disconnected from" dev_dbg(adapter->dev, "info: successfully disconnected from"
" %pM: reason code %d\n", priv->cfg_bssid, " %pM: reason code %d\n", priv->cfg_bssid,
WLAN_REASON_DEAUTH_LEAVING); WLAN_REASON_DEAUTH_LEAVING);
cfg80211_disconnected(priv->netdev, if (priv->bss_mode == NL80211_IFTYPE_STATION) {
WLAN_REASON_DEAUTH_LEAVING, NULL, 0, cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING,
GFP_KERNEL); NULL, 0, GFP_KERNEL);
queue_work(priv->workqueue, &priv->cfg_workqueue);
} }
memset(priv->cfg_bssid, 0, ETH_ALEN);
if (!netif_queue_stopped(priv->netdev)) if (!netif_queue_stopped(priv->netdev))
mwifiex_stop_net_dev_queue(priv->netdev, adapter); mwifiex_stop_net_dev_queue(priv->netdev, adapter);
if (netif_carrier_ok(priv->netdev)) if (netif_carrier_ok(priv->netdev))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment