2014-03-26 02:01:50

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 1/3] mwifiex: corner case NULL pointer dereference fix

From: Amitkumar Karwar <[email protected]>

When next scan command is delayed due to Tx traffic and
meanwhile synchronous command is received followed by a signal,
we cance all pending commands. NULL pointer dereference is seen
in this case while queueing next command in scan delay timer.
This patch adds a check to fix this issue.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 7b4502f..77db088 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -38,7 +38,8 @@ static void scan_delay_timer_fn(unsigned long data)
if (adapter->surprise_removed)
return;

- if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT) {
+ if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT ||
+ !adapter->scan_processing) {
/*
* Abort scan operation by cancelling all pending scan
* commands
--
1.8.2.3



2014-03-26 02:01:51

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 2/3] mwifiex: correction in sleep confirm command sequence number

From: Amitkumar Karwar <[email protected]>

Incremented sequence number was not being used for SLEEP confirm
command. This patch fixes the issue.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/cmdevt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index b411558..cc81fcd 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -277,11 +277,11 @@ static int mwifiex_dnld_sleep_confirm_cmd(struct mwifiex_adapter *adapter)

priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);

+ adapter->seq_num++;
sleep_cfm_buf->seq_num =
cpu_to_le16((HostCmd_SET_SEQ_NO_BSS_INFO
(adapter->seq_num, priv->bss_num,
priv->bss_type)));
- adapter->seq_num++;

if (adapter->iface_type == MWIFIEX_USB) {
sleep_cfm_tmp =
--
1.8.2.3


2014-03-26 02:01:49

by Bing Zhao

[permalink] [raw]
Subject: [PATCH 3/3] mwifiex: cancel pending commands during host sleep

From: Amitkumar Karwar <[email protected]>

Sometimes we may end up downloading other commands when host
sleep is configured. This patch makes sure that pending
commands are cancelled and we stop queueing further commands
during host sleep.

Signed-off-by: Amitkumar Karwar <[email protected]>
Signed-off-by: Bing Zhao <[email protected]>
---
drivers/net/wireless/mwifiex/cmdevt.c | 5 +++++
drivers/net/wireless/mwifiex/main.h | 1 +
drivers/net/wireless/mwifiex/pcie.c | 1 +
drivers/net/wireless/mwifiex/sdio.c | 2 ++
drivers/net/wireless/mwifiex/sta_ioctl.c | 3 +++
drivers/net/wireless/mwifiex/usb.c | 1 +
6 files changed, 13 insertions(+)

diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index cc81fcd..a23791d 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -509,6 +509,11 @@ int mwifiex_send_cmd(struct mwifiex_private *priv, u16 cmd_no,
return -1;
}

+ if (adapter->hs_enabling && cmd_no != HostCmd_CMD_802_11_HS_CFG_ENH) {
+ dev_err(adapter->dev, "PREP_CMD: host entering sleep state\n");
+ return -1;
+ }
+
if (adapter->surprise_removed) {
dev_err(adapter->dev, "PREP_CMD: card is removed\n");
return -1;
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index a67f7da..d53e1e8 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -774,6 +774,7 @@ struct mwifiex_adapter {
u16 hs_activate_wait_q_woken;
wait_queue_head_t hs_activate_wait_q;
bool is_suspended;
+ bool hs_enabling;
u8 event_body[MAX_EVENT_SIZE];
u32 hw_dot_11n_dev_cap;
u8 hw_dev_mcs_support;
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 57c353a..38c2837 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -120,6 +120,7 @@ static int mwifiex_pcie_suspend(struct device *dev)

/* Indicate device suspended */
adapter->is_suspended = true;
+ adapter->hs_enabling = false;

return 0;
}
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index e0dcd3e..d206f04 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -237,6 +237,7 @@ static int mwifiex_sdio_suspend(struct device *dev)
/* Enable the Host Sleep */
if (!mwifiex_enable_hs(adapter)) {
dev_err(adapter->dev, "cmd: failed to suspend\n");
+ adapter->hs_enabling = false;
return -EFAULT;
}

@@ -245,6 +246,7 @@ static int mwifiex_sdio_suspend(struct device *dev)

/* Indicate device suspended */
adapter->is_suspended = true;
+ adapter->hs_enabling = false;

return ret;
}
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index fcb791c..8942706 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -509,6 +509,9 @@ int mwifiex_enable_hs(struct mwifiex_adapter *adapter)
memset(&hscfg, 0, sizeof(struct mwifiex_ds_hs_cfg));
hscfg.is_invoke_hostcmd = true;

+ adapter->hs_enabling = true;
+ mwifiex_cancel_all_pending_cmd(adapter);
+
if (mwifiex_set_hs_params(mwifiex_get_priv(adapter,
MWIFIEX_BSS_ROLE_STA),
HostCmd_ACT_GEN_SET, MWIFIEX_SYNC_CMD,
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index ae30c39..edbe4af 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -459,6 +459,7 @@ static int mwifiex_usb_suspend(struct usb_interface *intf, pm_message_t message)
* 'suspended' state and a 'disconnect' one.
*/
adapter->is_suspended = true;
+ adapter->hs_enabling = false;

if (atomic_read(&card->rx_cmd_urb_pending) && card->rx_cmd.urb)
usb_kill_urb(card->rx_cmd.urb);
--
1.8.2.3