Commit 600f5d90 authored by Amitkumar Karwar's avatar Amitkumar Karwar Committed by John W. Linville
Browse files

mwifiex: cleanup ioctl wait queue and abstraction layer



1) remove mwifiex_alloc_fill_wait_queue() and
mwifiex_request_ioctl()
2) avoid dynamic allocation of wait queue
3) remove unnecessary mwifiex_error_code macros that
were used mainly by the wait queue status code
4) remove some abstraction functions
5) split mwifiex_prepare_cmd() to mwifiex_send_cmd_async()
and mwifiex_send_sync() to handle asynchronous and
synchronous commands respectively
Signed-off-by: default avatarAmitkumar Karwar <akarwar@marvell.com>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3a9dddea
...@@ -541,9 +541,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv, ...@@ -541,9 +541,8 @@ mwifiex_cfg_tx_buf(struct mwifiex_private *priv,
else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K) else if (priv->adapter->curr_tx_buf_size <= MWIFIEX_TX_DATA_BUF_SIZE_8K)
curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K; curr_tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_8K;
if (curr_tx_buf_size != tx_buf) if (curr_tx_buf_size != tx_buf)
mwifiex_prepare_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, mwifiex_send_cmd_async(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
HostCmd_ACT_GEN_SET, 0, HostCmd_ACT_GEN_SET, 0, &tx_buf);
NULL, &tx_buf);
return; return;
} }
...@@ -694,8 +693,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac) ...@@ -694,8 +693,8 @@ int mwifiex_send_addba(struct mwifiex_private *priv, int tid, u8 *peer_mac)
memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN); memcpy(&add_ba_req.peer_mac_addr, peer_mac, ETH_ALEN);
/* We don't wait for the response of this command */ /* We don't wait for the response of this command */
ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_ADDBA_REQ, ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_ADDBA_REQ,
0, 0, NULL, &add_ba_req); 0, 0, &add_ba_req);
return ret; return ret;
} }
...@@ -722,8 +721,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac, ...@@ -722,8 +721,8 @@ int mwifiex_send_delba(struct mwifiex_private *priv, int tid, u8 *peer_mac,
memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN); memcpy(&delba.peer_mac_addr, peer_mac, ETH_ALEN);
/* We don't wait for the response of this command */ /* We don't wait for the response of this command */
ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA,
HostCmd_ACT_GEN_SET, 0, NULL, &delba); HostCmd_ACT_GEN_SET, 0, &delba);
return ret; return ret;
} }
......
...@@ -609,7 +609,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv, ...@@ -609,7 +609,7 @@ void mwifiex_11n_ba_stream_timeout(struct mwifiex_private *priv,
delba.del_ba_param_set |= cpu_to_le16( delba.del_ba_param_set |= cpu_to_le16(
(u16) event->origninator << DELBA_INITIATOR_POS); (u16) event->origninator << DELBA_INITIATOR_POS);
delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT); delba.reason_code = cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
mwifiex_prepare_cmd(priv, HostCmd_CMD_11N_DELBA, 0, 0, NULL, &delba); mwifiex_send_cmd_async(priv, HostCmd_CMD_11N_DELBA, 0, 0, &delba);
return; return;
} }
......
...@@ -157,7 +157,7 @@ info ...@@ -157,7 +157,7 @@ info
mp_wr_bitmap = <SDIO multi-port write bitmap> mp_wr_bitmap = <SDIO multi-port write bitmap>
cmd_resp_received = <0/1, no cmd response to process/response received and yet to process> cmd_resp_received = <0/1, no cmd response to process/response received and yet to process>
event_received = <0/1, no event to process/event received and yet to process> event_received = <0/1, no event to process/event received and yet to process>
ioctl_pending = <number of ioctl pending> cmd_pending = <number of cmd pending>
tx_pending = <number of Tx packet pending> tx_pending = <number of Tx packet pending>
rx_pending = <number of Rx packet pending> rx_pending = <number of Rx packet pending>
......
...@@ -139,8 +139,16 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy, ...@@ -139,8 +139,16 @@ mwifiex_cfg80211_set_tx_power(struct wiphy *wiphy,
{ {
int ret = 0; int ret = 0;
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
struct mwifiex_power_cfg power_cfg;
ret = mwifiex_set_tx_power(priv, type, dbm); if (type == NL80211_TX_POWER_FIXED) {
power_cfg.is_power_auto = 0;
power_cfg.power_level = dbm;
} else {
power_cfg.is_power_auto = 1;
}
ret = mwifiex_set_tx_power(priv, &power_cfg);
return ret; return ret;
} }
...@@ -157,13 +165,15 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy, ...@@ -157,13 +165,15 @@ mwifiex_cfg80211_set_power_mgmt(struct wiphy *wiphy,
{ {
int ret = 0; int ret = 0;
struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy); struct mwifiex_private *priv = mwifiex_cfg80211_get_priv(wiphy);
u32 ps_mode;
if (timeout) if (timeout)
wiphy_dbg(wiphy, wiphy_dbg(wiphy,
"info: ignoring the timeout value" "info: ignoring the timeout value"
" for IEEE power save\n"); " for IEEE power save\n");
ret = mwifiex_drv_set_power(priv, enabled); ps_mode = enabled;
ret = mwifiex_drv_set_power(priv, &ps_mode);
return ret; return ret;
} }
...@@ -291,8 +301,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy) ...@@ -291,8 +301,8 @@ static int mwifiex_send_domain_info_cmd_fw(struct wiphy *wiphy)
domain_info->no_of_triplet = no_of_triplet; domain_info->no_of_triplet = no_of_triplet;
/* Send cmd to FW to set domain info */ /* Send cmd to FW to set domain info */
ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_802_11D_DOMAIN_INFO, ret = mwifiex_send_cmd_async(priv, HostCmd_CMD_802_11D_DOMAIN_INFO,
HostCmd_ACT_GEN_SET, 0, NULL, NULL); HostCmd_ACT_GEN_SET, 0, NULL);
if (ret) if (ret)
wiphy_err(wiphy, "11D: setting domain info in FW\n"); wiphy_err(wiphy, "11D: setting domain info in FW\n");
...@@ -347,7 +357,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, ...@@ -347,7 +357,6 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
{ {
struct mwifiex_chan_freq_power cfp; struct mwifiex_chan_freq_power cfp;
int ret = 0; int ret = 0;
int status = 0;
struct mwifiex_ds_band_cfg band_cfg; struct mwifiex_ds_band_cfg band_cfg;
u32 config_bands = 0; u32 config_bands = 0;
struct wiphy *wiphy = priv->wdev->wiphy; struct wiphy *wiphy = priv->wdev->wiphy;
...@@ -370,10 +379,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, ...@@ -370,10 +379,9 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
band_cfg.sec_chan_offset = band_cfg.sec_chan_offset =
mwifiex_cfg80211_channel_type_to_mwifiex_channels mwifiex_cfg80211_channel_type_to_mwifiex_channels
(channel_type); (channel_type);
status = mwifiex_radio_ioctl_band_cfg(priv, HostCmd_ACT_GEN_SET, ret = mwifiex_set_radio_band_cfg(priv, &band_cfg);
&band_cfg);
if (status) if (ret)
return -EFAULT; return -EFAULT;
mwifiex_send_domain_info_cmd_fw(wiphy); mwifiex_send_domain_info_cmd_fw(wiphy);
} }
...@@ -389,8 +397,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv, ...@@ -389,8 +397,8 @@ mwifiex_set_rf_channel(struct mwifiex_private *priv,
/* Convert frequency to channel */ /* Convert frequency to channel */
cfp.channel = ieee80211_frequency_to_channel(chan->center_freq); cfp.channel = ieee80211_frequency_to_channel(chan->center_freq);
status = mwifiex_bss_ioctl_channel(priv, HostCmd_ACT_GEN_SET, &cfp); ret = mwifiex_bss_set_channel(priv, &cfp);
if (status) if (ret)
return -EFAULT; return -EFAULT;
ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel); ret = mwifiex_drv_change_adhoc_chan(priv, cfp.channel);
...@@ -422,66 +430,45 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev, ...@@ -422,66 +430,45 @@ mwifiex_cfg80211_set_channel(struct wiphy *wiphy, struct net_device *dev,
/* /*
* This function sets the fragmentation threshold. * This function sets the fragmentation threshold.
* *
* This function creates an IOCTL request, populates it accordingly * The fragmentation threshold value must lie between MWIFIEX_FRAG_MIN_VALUE
* and issues an IOCTL.
*
* The fragmentation threshold value must lies between MWIFIEX_FRAG_MIN_VALUE
* and MWIFIEX_FRAG_MAX_VALUE. * and MWIFIEX_FRAG_MAX_VALUE.
*/ */
static int static int
mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr) mwifiex_set_frag(struct mwifiex_private *priv, u32 frag_thr)
{ {
int ret = 0; int ret = 0;
int status = 0;
struct mwifiex_wait_queue *wait = NULL;
u8 wait_option = MWIFIEX_IOCTL_WAIT;
if (frag_thr < MWIFIEX_FRAG_MIN_VALUE if (frag_thr < MWIFIEX_FRAG_MIN_VALUE
|| frag_thr > MWIFIEX_FRAG_MAX_VALUE) || frag_thr > MWIFIEX_FRAG_MAX_VALUE)
return -EINVAL; return -EINVAL;
wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); /* Send request to firmware */
if (!wait) ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
return -ENOMEM; HostCmd_ACT_GEN_SET, FRAG_THRESH_I,
&frag_thr);
status = mwifiex_snmp_mib_ioctl(priv, wait, FRAG_THRESH_I,
HostCmd_ACT_GEN_SET, &frag_thr);
if (mwifiex_request_ioctl(priv, wait, status, wait_option))
ret = -EFAULT;
kfree(wait);
return ret; return ret;
} }
/* /*
* This function sets the RTS threshold. * This function sets the RTS threshold.
*
* This function creates an IOCTL request, populates it accordingly * The rts value must lie between MWIFIEX_RTS_MIN_VALUE
* and issues an IOCTL. * and MWIFIEX_RTS_MAX_VALUE.
*/ */
static int static int
mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr) mwifiex_set_rts(struct mwifiex_private *priv, u32 rts_thr)
{ {
int ret = 0; int ret = 0;
struct mwifiex_wait_queue *wait = NULL;
int status = 0;
u8 wait_option = MWIFIEX_IOCTL_WAIT;
if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE) if (rts_thr < MWIFIEX_RTS_MIN_VALUE || rts_thr > MWIFIEX_RTS_MAX_VALUE)
rts_thr = MWIFIEX_RTS_MAX_VALUE; rts_thr = MWIFIEX_RTS_MAX_VALUE;
wait = mwifiex_alloc_fill_wait_queue(priv, wait_option); /* Send request to firmware */
if (!wait) ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_802_11_SNMP_MIB,
return -ENOMEM; HostCmd_ACT_GEN_SET, RTS_THRESH_I,
&rts_thr);
status = mwifiex_snmp_mib_ioctl(priv, wait, RTS_THRESH_I,
HostCmd_ACT_GEN_SET, &rts_thr);
if (mwifiex_request_ioctl(priv, wait, status, wait_option))
ret = -EFAULT;
kfree(wait);
return ret; return ret;
} }
...@@ -518,7 +505,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, ...@@ -518,7 +505,6 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
{ {
int ret = 0; int ret = 0;
struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
struct mwifiex_wait_queue *wait = NULL;
if (priv->bss_mode == type) { if (priv->bss_mode == type) {
wiphy_warn(wiphy, "already set to required type\n"); wiphy_warn(wiphy, "already set to required type\n");
...@@ -545,24 +531,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy, ...@@ -545,24 +531,13 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
return -EINVAL; return -EINVAL;
} }
wait = mwifiex_alloc_fill_wait_queue(priv, MWIFIEX_IOCTL_WAIT); mwifiex_deauthenticate(priv, NULL);
if (!wait)
return -ENOMEM;
mwifiex_deauthenticate(priv, wait, NULL);
priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM; priv->sec_info.authentication_mode = NL80211_AUTHTYPE_OPEN_SYSTEM;
ret = mwifiex_prepare_cmd(priv, HostCmd_CMD_SET_BSS_MODE, ret = mwifiex_send_cmd_sync(priv, HostCmd_CMD_SET_BSS_MODE,
HostCmd_ACT_GEN_SET, 0, wait, NULL); HostCmd_ACT_GEN_SET, 0, NULL);
if (!ret)
ret = -EINPROGRESS;
ret = mwifiex_request_ioctl(priv, wait, ret, MWIFIEX_IOCTL_WAIT);
if (ret)
ret = -EFAULT;
kfree(wait);
return ret; return ret;
} }
...@@ -592,7 +567,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv, ...@@ -592,7 +567,7 @@ mwifiex_dump_station_info(struct mwifiex_private *priv,
/* Get signal information from the firmware */ /* Get signal information from the firmware */
memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal)); memset(&signal, 0, sizeof(struct mwifiex_ds_get_signal));
if (mwifiex_get_signal_info(priv, MWIFIEX_IOCTL_WAIT, &signal)) { if (mwifiex_get_signal_info(priv, &signal)) {
dev_err(priv->adapter->dev, "getting signal information\n"); dev_err(priv->adapter->dev, "getting signal information\n");
ret = -EFAULT; ret = -EFAULT;
} }
...@@ -750,7 +725,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, ...@@ -750,7 +725,7 @@ mwifiex_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
return -EBUSY; return -EBUSY;
priv->disconnect = 1; priv->disconnect = 1;
if (mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, 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:"
...@@ -838,8 +813,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv, ...@@ -838,8 +813,8 @@ static int mwifiex_inform_bss_from_scan_result(struct mwifiex_private *priv,
u8 element_id, element_len; u8 element_id, element_len;
memset(&scan_resp, 0, sizeof(scan_resp)); memset(&scan_resp, 0, sizeof(scan_resp));
if (mwifiex_get_scan_table(priv, MWIFIEX_IOCTL_WAIT, &scan_resp)) scan_resp.scan_table = (u8 *) priv->adapter->scan_table;
return -EFAULT; scan_resp.num_in_scan_table = priv->adapter->num_in_scan_table;
#define MAX_IE_BUF 2048 #define MAX_IE_BUF 2048
ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL); ie_buf = kzalloc(MAX_IE_BUF, GFP_KERNEL);
...@@ -986,7 +961,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -986,7 +961,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
} }
/* disconnect before try to associate */ /* disconnect before try to associate */
mwifiex_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL); mwifiex_deauthenticate(priv, NULL);
if (channel) if (channel)
ret = mwifiex_set_rf_channel(priv, channel, ret = mwifiex_set_rf_channel(priv, channel,
...@@ -1046,7 +1021,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid, ...@@ -1046,7 +1021,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
} }
done: done:
/* Do specific SSID scanning */ /* Do specific SSID scanning */
if (mwifiex_request_scan(priv, MWIFIEX_IOCTL_WAIT, &req_ssid)) { if (mwifiex_request_scan(priv, &req_ssid)) {
dev_err(priv->adapter->dev, "scan error\n"); dev_err(priv->adapter->dev, "scan error\n");
return -EFAULT; return -EFAULT;
} }
...@@ -1055,8 +1030,7 @@ done: ...@@ -1055,8 +1030,7 @@ done:
memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid)); memcpy(&ssid_bssid.ssid, &req_ssid, sizeof(struct mwifiex_802_11_ssid));
if (mode != NL80211_IFTYPE_ADHOC) { if (mode != NL80211_IFTYPE_ADHOC) {
if (mwifiex_find_best_bss(priv, MWIFIEX_IOCTL_WAIT, if (mwifiex_find_best_bss(priv, &ssid_bssid))
&ssid_bssid))
return -EFAULT; return -EFAULT;
/* Inform the BSS information to kernel, otherwise /* Inform the BSS information to kernel, otherwise
* kernel will give a panic after successful assoc */ * kernel will give a panic after successful assoc */
...@@ -1072,7 +1046,10 @@ done: ...@@ -1072,7 +1046,10 @@ done:
/* Connect to BSS by ESSID */ /* Connect to BSS by ESSID */
memset(&ssid_bssid.bssid, 0, ETH_ALEN); memset(&ssid_bssid.bssid, 0, ETH_ALEN);
if (mwifiex_bss_start(priv, MWIFIEX_IOCTL_WAIT, &ssid_bssid)) if (!netif_queue_stopped(priv->netdev))
netif_stop_queue(priv->netdev);
if (mwifiex_bss_start(priv, &ssid_bssid))
return -EFAULT; return -EFAULT;
if (mode == NL80211_IFTYPE_ADHOC) { if (mode == NL80211_IFTYPE_ADHOC) {
...@@ -1176,7 +1153,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) ...@@ -1176,7 +1153,7 @@ mwifiex_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
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_disconnect(priv, MWIFIEX_IOCTL_WAIT, NULL)) if (mwifiex_deauthenticate(priv, NULL))
return -EFAULT; return -EFAULT;
queue_work(priv->workqueue, &priv->cfg_workqueue); queue_work(priv->workqueue, &priv->cfg_workqueue);
......
...@@ -36,11 +36,12 @@ ...@@ -36,11 +36,12 @@
static void static void
mwifiex_init_cmd_node(struct mwifiex_private *priv, mwifiex_init_cmd_node(struct mwifiex_private *priv,
struct cmd_ctrl_node *cmd_node, struct cmd_ctrl_node *cmd_node,
u32 cmd_oid, void *wait_queue, void *data_buf) u32 cmd_oid, void *data_buf)
{ {
cmd_node->priv = priv; cmd_node->priv = priv;
cmd_node->cmd_oid = cmd_oid; cmd_node->cmd_oid = cmd_oid;
cmd_node->wq_buf = wait_queue; cmd_node->wait_q_enabled = priv->adapter->cmd_wait_q_required;
priv->adapter->cmd_wait_q_required = false;
cmd_node->data_buf = data_buf; cmd_node->data_buf = data_buf;
cmd_node->cmd_skb = cmd_node->skb; cmd_node->cmd_skb = cmd_node->skb;
} }
...@@ -86,8 +87,8 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, ...@@ -86,8 +87,8 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
{ {
cmd_node->cmd_oid = 0; cmd_node->cmd_oid = 0;
cmd_node->cmd_flag = 0; cmd_node->cmd_flag = 0;
cmd_node->wq_buf = NULL;
cmd_node->data_buf = NULL; cmd_node->data_buf = NULL;
cmd_node->wait_q_enabled = false;
if (cmd_node->resp_skb) { if (cmd_node->resp_skb) {
mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0); mwifiex_recv_complete(adapter, cmd_node->resp_skb, 0);
...@@ -97,30 +98,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter, ...@@ -97,30 +98,6 @@ mwifiex_clean_cmd_node(struct mwifiex_adapter *adapter,
return; return;
} }
/*
* This function returns a command node from the pending queue which
* matches the given IOCTL request.
*/
static struct cmd_ctrl_node *
mwifiex_get_pending_ioctl_cmd(struct mwifiex_adapter *adapter,
struct mwifiex_wait_queue *wait_queue)
{
unsigned long flags;
struct cmd_ctrl_node *cmd_node;
spin_lock_irqsave(&adapter->cmd_pending_q_lock, flags);
list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
if (cmd_node->wq_buf == wait_queue) {
spin_unlock_irqrestore(&adapter->cmd_pending_q_lock,
flags);
return cmd_node;
}
}
spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, flags);
return NULL;
}
/* /*
* This function sends a host command to the firmware. * This function sends a host command to the firmware.
* *
...@@ -155,7 +132,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, ...@@ -155,7 +132,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
struct mwifiex_adapter *adapter = priv->adapter; struct mwifiex_adapter *adapter = priv->adapter;
int ret = 0; int ret = 0;
struct host_cmd_ds_command *host_cmd; struct host_cmd_ds_command *host_cmd;
struct mwifiex_wait_queue *wait_queue = NULL;
uint16_t cmd_code; uint16_t cmd_code;
uint16_t cmd_size; uint16_t cmd_size;
struct timeval tstamp; struct timeval tstamp;
...@@ -165,15 +141,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, ...@@ -165,15 +141,13 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
return -1; return -1;
host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data); host_cmd = (struct host_cmd_ds_command *) (cmd_node->cmd_skb->data);
if (cmd_node->wq_buf)
wait_queue = (struct mwifiex_wait_queue *) cmd_node->wq_buf;
/* Sanity test */ /* Sanity test */
if (host_cmd == NULL || host_cmd->size == 0) { if (host_cmd == NULL || host_cmd->size == 0) {
dev_err(adapter->dev, "DNLD_CMD: host_cmd is null" dev_err(adapter->dev, "DNLD_CMD: host_cmd is null"
" or cmd size is 0, not sending\n"); " or cmd size is 0, not sending\n");
if (wait_queue) if (cmd_node->wait_q_enabled)
wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; adapter->cmd_wait_q.status = -1;
mwifiex_insert_cmd_to_free_q(adapter, cmd_node); mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
return -1; return -1;
} }
...@@ -210,8 +184,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, ...@@ -210,8 +184,8 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv,
if (ret == -1) { if (ret == -1) {
dev_err(adapter->dev, "DNLD_CMD: host to card failed\n"); dev_err(adapter->dev, "DNLD_CMD: host to card failed\n");
if (wait_queue) if (cmd_node->wait_q_enabled)
wait_queue->status = MWIFIEX_ERROR_CMD_DNLD_FAIL; adapter->cmd_wait_q.status = -1;
mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd);
spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
...@@ -437,7 +411,31 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter) ...@@ -437,7 +411,31 @@ int mwifiex_process_event(struct mwifiex_adapter *adapter)
} }
/* /*
* This function prepares a command before sending it to the firmware. * This function is used to send synchronous command to the firmware.
*
* it allocates a wait queue for the command and wait for the command
* response.
*/
int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no,
u16 cmd_action, u32 cmd_oid, void *data_buf)
{
int ret = 0;
struct mwifiex_adapter *adapter = priv->adapter;
adapter->cmd_wait_q_required = true;
adapter->cmd_wait_q.condition = false;
ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid,
data_buf);
if (!ret)
ret = mwifiex_wait_queue_complete(adapter);