All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping
@ 2016-09-28 12:48 Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 2/8] mwifiex: report error to PCIe for suspend failure Amitkumar Karwar
                   ` (8 more replies)
  0 siblings, 9 replies; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless; +Cc: Cathy Luo, Nishant Sarmukadam, Amitkumar Karwar

Following is mwifiex driver-firmware host sleep handshake.
It involves three threads. suspend handler, interrupt handler, interrupt
processing in main work queue.

1) Enter suspend handler
2) Download HS_CFG command
3) Response from firmware for HS_CFG
4) Suspend thread waits until handshake completes(i.e hs_activate becomes
   true)
5) SLEEP from firmware
6) SLEEP confirm downloaded to firmware.
7) SLEEP confirm response from firmware
8) Driver processes SLEEP confirm response and set hs_activate to wake up
suspend thread
9) Exit suspend handler
10) Read sleep cookie in loop and wait until it indicates firmware is
sleep.
11) After processing SLEEP confirm response, we are at the end of interrupt
processing routine. Recheck if there are interrupts received while we were
processing them.

During suspend-resume stress test, it's been observed that we may end up
acessing PCIe hardware(in 10 and 11) when PCIe bus is closed which leads
to a kernel crash.

This patch solves the problem with below changes.
a) action 10 above can be done before 8
b) Skip 11 if hs_activated is true. SLEEP confirm response
is the last interrupt from firmware. No need to recheck for
pending interrupts.
c) Add flush_workqueue() in suspend handler.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 3c3c4f1..2833d47 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -118,6 +118,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
 	adapter = card->adapter;
 
 	hs_actived = mwifiex_enable_hs(adapter);
+	flush_workqueue(adapter->workqueue);
 
 	/* Indicate device suspended */
 	adapter->is_suspended = true;
@@ -1669,9 +1670,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
 
 	if (!adapter->curr_cmd) {
 		if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
-			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
-							   skb->len);
-			mwifiex_pcie_enable_host_int(adapter);
 			if (mwifiex_write_reg(adapter,
 					      PCIE_CPU_INT_EVENT,
 					      CPU_INTR_SLEEP_CFM_DONE)) {
@@ -1684,6 +1682,9 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
 			while (reg->sleep_cookie && (count++ < 10) &&
 			       mwifiex_pcie_ok_to_access_hw(adapter))
 				usleep_range(50, 60);
+			mwifiex_pcie_enable_host_int(adapter);
+			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
+							   skb->len);
 		} else {
 			mwifiex_dbg(adapter, ERROR,
 				    "There is no command but got cmdrsp\n");
@@ -2322,6 +2323,8 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
 			ret = mwifiex_pcie_process_cmd_complete(adapter);
 			if (ret)
 				return ret;
+			if (adapter->hs_activated)
+				return ret;
 		}
 
 		if (card->msi_enable) {
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 2/8] mwifiex: report error to PCIe for suspend failure
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
@ 2016-09-28 12:48 ` Amitkumar Karwar
  2016-10-04 22:24   ` [2/8] " Brian Norris
  2016-09-28 12:48 ` [PATCH 3/8] mwifiex: Fix NULL pointer dereference in skb_dequeue() Amitkumar Karwar
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless; +Cc: Cathy Luo, Nishant Sarmukadam, Amitkumar Karwar

When host_sleep_config command fails, we should return an error to
PCIe, instead of continuing (and possibly panicking, when we try to keep
processing a timed-out ioctl after we return "successfully" from
suspend).

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 2833d47..063c707 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -101,7 +101,6 @@ static int mwifiex_pcie_suspend(struct device *dev)
 {
 	struct mwifiex_adapter *adapter;
 	struct pcie_service_card *card;
-	int hs_actived;
 	struct pci_dev *pdev = to_pci_dev(dev);
 
 	if (pdev) {
@@ -117,7 +116,14 @@ static int mwifiex_pcie_suspend(struct device *dev)
 
 	adapter = card->adapter;
 
-	hs_actived = mwifiex_enable_hs(adapter);
+	/* Enable the Host Sleep */
+	if (!mwifiex_enable_hs(adapter)) {
+		mwifiex_dbg(adapter, ERROR,
+			    "cmd: failed to suspend\n");
+		adapter->hs_enabling = false;
+		return -EFAULT;
+	}
+
 	flush_workqueue(adapter->workqueue);
 
 	/* Indicate device suspended */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 3/8] mwifiex: Fix NULL pointer dereference in skb_dequeue()
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 2/8] mwifiex: report error to PCIe for suspend failure Amitkumar Karwar
@ 2016-09-28 12:48 ` Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 4/8] mwifiex: vendor_ie length check for parse WMM IEs Amitkumar Karwar
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless; +Cc: Cathy Luo, Nishant Sarmukadam, Amitkumar Karwar

At couple of places in cleanup path, we are just going through the
skb queue and freeing them without unlinking. This leads to a crash
when other thread tries to do skb_dequeue() and use already freed node.

The problem is freed by unlinking skb before freeing it.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/cfg80211.c |  4 +++-
 drivers/net/wireless/marvell/mwifiex/wmm.c      | 12 +++++++++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index 39ce76a..e83861f 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -3070,8 +3070,10 @@ int mwifiex_del_virtual_intf(struct wiphy *wiphy, struct wireless_dev *wdev)
 
 	mwifiex_stop_net_dev_queue(priv->netdev, adapter);
 
-	skb_queue_walk_safe(&priv->bypass_txq, skb, tmp)
+	skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) {
+		skb_unlink(skb, &priv->bypass_txq);
 		mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+	}
 
 	if (netif_carrier_ok(priv->netdev))
 		netif_carrier_off(priv->netdev);
diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c
index 0eb2465..dea2fe6 100644
--- a/drivers/net/wireless/marvell/mwifiex/wmm.c
+++ b/drivers/net/wireless/marvell/mwifiex/wmm.c
@@ -503,8 +503,10 @@ mwifiex_wmm_del_pkts_in_ralist_node(struct mwifiex_private *priv,
 	struct mwifiex_adapter *adapter = priv->adapter;
 	struct sk_buff *skb, *tmp;
 
-	skb_queue_walk_safe(&ra_list->skb_head, skb, tmp)
+	skb_queue_walk_safe(&ra_list->skb_head, skb, tmp) {
+		skb_unlink(skb, &ra_list->skb_head);
 		mwifiex_write_data_complete(adapter, skb, 0, -1);
+	}
 }
 
 /*
@@ -600,11 +602,15 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
 		priv->adapter->if_ops.clean_pcie_ring(priv->adapter);
 	spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags);
 
-	skb_queue_walk_safe(&priv->tdls_txq, skb, tmp)
+	skb_queue_walk_safe(&priv->tdls_txq, skb, tmp) {
+		skb_unlink(skb, &priv->tdls_txq);
 		mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+	}
 
-	skb_queue_walk_safe(&priv->bypass_txq, skb, tmp)
+	skb_queue_walk_safe(&priv->bypass_txq, skb, tmp) {
+		skb_unlink(skb, &priv->bypass_txq);
 		mwifiex_write_data_complete(priv->adapter, skb, 0, -1);
+	}
 	atomic_set(&priv->adapter->bypass_tx_pending, 0);
 
 	idr_for_each(&priv->ack_status_frames, mwifiex_free_ack_frame, NULL);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 4/8] mwifiex: vendor_ie length check for parse WMM IEs
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 2/8] mwifiex: report error to PCIe for suspend failure Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 3/8] mwifiex: Fix NULL pointer dereference in skb_dequeue() Amitkumar Karwar
@ 2016-09-28 12:48 ` Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 5/8] mwifiex: add memrw command information in README Amitkumar Karwar
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless
  Cc: Cathy Luo, Nishant Sarmukadam, Karthik D A, Amitkumar Karwar

From: Karthik D A <karthida@marvell.com>

While copying the vendor_ie obtained from the cfg80211_find_vendor_ie()
to the struct mwifiex_types_wmm_info, length/size was inappropriate.
This patch corrects the required length needed to the
mwifiex_types_wmm_info

Signed-off-by: Karthik D A <karthida@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/uap_cmd.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
index a7e9f54..35d8636 100644
--- a/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/marvell/mwifiex/uap_cmd.c
@@ -404,7 +404,7 @@ mwifiex_set_wmm_params(struct mwifiex_private *priv,
 		       struct cfg80211_ap_settings *params)
 {
 	const u8 *vendor_ie;
-	struct ieee_types_header *wmm_ie;
+	const u8 *wmm_ie;
 	u8 wmm_oui[] = {0x00, 0x50, 0xf2, 0x02};
 
 	vendor_ie = cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
@@ -412,9 +412,9 @@ mwifiex_set_wmm_params(struct mwifiex_private *priv,
 					    params->beacon.tail,
 					    params->beacon.tail_len);
 	if (vendor_ie) {
-		wmm_ie = (struct ieee_types_header *)vendor_ie;
-		memcpy(&bss_cfg->wmm_info, wmm_ie + 1,
-		       sizeof(bss_cfg->wmm_info));
+		wmm_ie = vendor_ie;
+		memcpy(&bss_cfg->wmm_info, wmm_ie +
+		       sizeof(struct ieee_types_header), *(wmm_ie + 1));
 		priv->wmm_enabled = 1;
 	} else {
 		memset(&bss_cfg->wmm_info, 0, sizeof(bss_cfg->wmm_info));
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 5/8] mwifiex: add memrw command information in README
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
                   ` (2 preceding siblings ...)
  2016-09-28 12:48 ` [PATCH 4/8] mwifiex: vendor_ie length check for parse WMM IEs Amitkumar Karwar
@ 2016-09-28 12:48 ` Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 6/8] mwifiex: update tx_pkts_queued for requeued packets Amitkumar Karwar
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless; +Cc: Cathy Luo, Nishant Sarmukadam, Amitkumar Karwar

Support for this debugfs command is available in driver. This patch
adds usage information in README file.

Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/README | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/README b/drivers/net/wireless/marvell/mwifiex/README
index 24e649b..588fcbe 100644
--- a/drivers/net/wireless/marvell/mwifiex/README
+++ b/drivers/net/wireless/marvell/mwifiex/README
@@ -180,6 +180,29 @@ regrdwr
 		echo "1 0xa060 0x12" > regrdwr      : Write the MAC register
 		echo "1 0xa794 0x80000000" > regrdwr
 		                                    : Write 0x80000000 to MAC register
+
+memrw
+	This command is used to read/write the firmware memory.
+
+	Usage:
+		1) For reading firmware memory location.
+			echo r <address> 0 > /sys/kernel/debug/mwifiex/mlan0/memrw
+			cat /sys/kernel/debug/mwifiex/mlan0/memrw
+		2) For writing value to firmware memory location.
+			echo w <address> [value] > /sys/kernel/debug/mwifiex/mlan0/memrw
+
+	where the parameters are,
+		<address>:  memory address
+		[value]:    value to be written
+
+	Examples:
+		echo r 0x4cf70 0 > /sys/kernel/debug/mwifiex/mlan0/memrw
+		cat /sys/kernel/debug/mwifiex/mlan0/memrw
+						: Read memory address 0x4cf70
+		iwpriv mlan0 memrdwr -0x7fff6000 -0x40000000
+		echo w 0x8000a000 0xc0000000 > /sys/kernel/debug/mwifiex/mlan0/memrw
+						: Write 0xc0000000 to memory address 0x8000a000
+
 rdeeprom
 	This command is used to read the EEPROM contents of the card.
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 6/8] mwifiex: update tx_pkts_queued for requeued packets
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
                   ` (3 preceding siblings ...)
  2016-09-28 12:48 ` [PATCH 5/8] mwifiex: add memrw command information in README Amitkumar Karwar
@ 2016-09-28 12:48 ` Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 7/8] mwifiex: fix command timeout problem seen in stress tests Amitkumar Karwar
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless
  Cc: Cathy Luo, Nishant Sarmukadam, Xinming Hu, Amitkumar Karwar

From: Xinming Hu <huxm@marvell.com>

wmm.tx_pkts_queued and ralist's total_pkt_count should be updated in
synchronization. They were not correctly updated in
mwifiex_send_processed_packet().

Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/wmm.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c
index dea2fe6..1ff3a87 100644
--- a/drivers/net/wireless/marvell/mwifiex/wmm.c
+++ b/drivers/net/wireless/marvell/mwifiex/wmm.c
@@ -1334,9 +1334,11 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
 	skb = skb_dequeue(&ptr->skb_head);
 
 	if (adapter->data_sent || adapter->tx_lock_flag) {
+		ptr->total_pkt_count--;
 		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
 				       ra_list_flags);
 		skb_queue_tail(&adapter->tx_data_q, skb);
+		atomic_dec(&priv->wmm.tx_pkts_queued);
 		atomic_inc(&adapter->tx_queued);
 		return;
 	}
@@ -1394,6 +1396,10 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
 	if (ret != -EBUSY) {
 		mwifiex_rotate_priolists(priv, ptr, ptr_index);
 		atomic_dec(&priv->wmm.tx_pkts_queued);
+		spin_lock_irqsave(&priv->wmm.ra_list_spinlock, ra_list_flags);
+		ptr->total_pkt_count--;
+		spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
+				       ra_list_flags);
 	}
 }
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 7/8] mwifiex: fix command timeout problem seen in stress tests
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
                   ` (4 preceding siblings ...)
  2016-09-28 12:48 ` [PATCH 6/8] mwifiex: update tx_pkts_queued for requeued packets Amitkumar Karwar
@ 2016-09-28 12:48 ` Amitkumar Karwar
  2016-09-28 12:48 ` [PATCH 8/8] mwifiex: fix p2p device doesn't find in scan problem Amitkumar Karwar
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless
  Cc: Cathy Luo, Nishant Sarmukadam, Xinming Hu, Amitkumar Karwar

From: Xinming Hu <huxm@marvell.com>

It is observed that if single tid 6 packet comes among with massive tid 0
packets, tid 6 packet may stay in it's queue and will never be
transmited. This is because wmm.highest_queued_prio will be set to 2
during transmission of tid 0 packets As a result, main work thread
keeps on looping without serving that packet. In this case, if command
has downloaded to firmware, driver doesn't process it's response causing
command timeout.

This patch will reset highest_queued_prio if packets exist in data
queue, and try to find a ra_list for current private.

Signed-off-by: Xinming Hu <huxm@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/main.h |  1 +
 drivers/net/wireless/marvell/mwifiex/wmm.c  | 13 ++++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/main.h b/drivers/net/wireless/marvell/mwifiex/main.h
index 26df28f..d61fe3a 100644
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -315,6 +315,7 @@ struct mwifiex_tid_tbl {
 #define WMM_HIGHEST_PRIORITY		7
 #define HIGH_PRIO_TID				7
 #define LOW_PRIO_TID				0
+#define NO_PKT_PRIO_TID				-1
 #define MWIFIEX_WMM_DRV_DELAY_MAX 510
 
 struct mwifiex_wmm_desc {
diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c
index 1ff3a87..28c2f6f 100644
--- a/drivers/net/wireless/marvell/mwifiex/wmm.c
+++ b/drivers/net/wireless/marvell/mwifiex/wmm.c
@@ -1105,6 +1105,7 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
 				    &adapter->bss_prio_tbl[j].bss_prio_head,
 				    list) {
 
+try_again:
 			priv_tmp = adapter->bss_prio_tbl[j].bss_prio_cur->priv;
 
 			if (((priv_tmp->bss_mode != NL80211_IFTYPE_ADHOC) &&
@@ -1140,8 +1141,18 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
 						       ra_list_spinlock,
 						       flags_ra);
 			}
-		}
 
+			if (atomic_read(&priv_tmp->wmm.tx_pkts_queued) != 0) {
+				atomic_set(&priv_tmp->wmm.highest_queued_prio,
+					   HIGH_PRIO_TID);
+				/* Iterate current private once more, since
+				 * there still exist packets in data queue
+				 */
+				goto try_again;
+			} else
+				atomic_set(&priv_tmp->wmm.highest_queued_prio,
+					   NO_PKT_PRIO_TID);
+		}
 	}
 
 	return NULL;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH 8/8] mwifiex: fix p2p device doesn't find in scan problem
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
                   ` (5 preceding siblings ...)
  2016-09-28 12:48 ` [PATCH 7/8] mwifiex: fix command timeout problem seen in stress tests Amitkumar Karwar
@ 2016-09-28 12:48 ` Amitkumar Karwar
  2016-10-04 22:20 ` [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Brian Norris
  2016-11-09  1:34 ` [1/8] " Kalle Valo
  8 siblings, 0 replies; 11+ messages in thread
From: Amitkumar Karwar @ 2016-09-28 12:48 UTC (permalink / raw)
  To: linux-wireless
  Cc: Cathy Luo, Nishant Sarmukadam, Karthik D A, Amitkumar Karwar

From: Karthik D A <karthida@marvell.com>

Marvell p2p device disappears from the list of p2p peers on the other
p2p device after disconnection.

It happens due to a bug in driver. When interface is changed from p2p
to station, certain variables(bss_type, bss_role etc.) aren't correctly
updated. This patch corrects them to fix the issue.

Signed-off-by: Karthik D A <karthida@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
---
 drivers/net/wireless/marvell/mwifiex/cfg80211.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
index e83861f..d9f5445 100644
--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
@@ -1203,6 +1203,12 @@ mwifiex_cfg80211_change_virtual_intf(struct wiphy *wiphy,
 			priv->adapter->curr_iface_comb.p2p_intf--;
 			priv->adapter->curr_iface_comb.sta_intf++;
 			dev->ieee80211_ptr->iftype = type;
+			if (mwifiex_deinit_priv_params(priv))
+				return -1;
+			if (mwifiex_init_new_priv_params(priv, dev, type))
+				return -1;
+			if (mwifiex_sta_init_cmd(priv, false, false))
+				return -1;
 			break;
 		case NL80211_IFTYPE_ADHOC:
 			if (mwifiex_cfg80211_deinit_p2p(priv))
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
                   ` (6 preceding siblings ...)
  2016-09-28 12:48 ` [PATCH 8/8] mwifiex: fix p2p device doesn't find in scan problem Amitkumar Karwar
@ 2016-10-04 22:20 ` Brian Norris
  2016-11-09  1:34 ` [1/8] " Kalle Valo
  8 siblings, 0 replies; 11+ messages in thread
From: Brian Norris @ 2016-10-04 22:20 UTC (permalink / raw)
  To: Amitkumar Karwar; +Cc: linux-wireless, Cathy Luo, Nishant Sarmukadam

Hi,

On Wed, Sep 28, 2016 at 06:18:21PM +0530, Amitkumar Karwar wrote:
> Following is mwifiex driver-firmware host sleep handshake.
> It involves three threads. suspend handler, interrupt handler, interrupt
> processing in main work queue.
> 
> 1) Enter suspend handler
> 2) Download HS_CFG command
> 3) Response from firmware for HS_CFG
> 4) Suspend thread waits until handshake completes(i.e hs_activate becomes
>    true)
> 5) SLEEP from firmware
> 6) SLEEP confirm downloaded to firmware.
> 7) SLEEP confirm response from firmware
> 8) Driver processes SLEEP confirm response and set hs_activate to wake up
> suspend thread
> 9) Exit suspend handler
> 10) Read sleep cookie in loop and wait until it indicates firmware is
> sleep.
> 11) After processing SLEEP confirm response, we are at the end of interrupt
> processing routine. Recheck if there are interrupts received while we were
> processing them.
> 
> During suspend-resume stress test, it's been observed that we may end up
> acessing PCIe hardware(in 10 and 11) when PCIe bus is closed which leads
> to a kernel crash.
> 
> This patch solves the problem with below changes.
> a) action 10 above can be done before 8
> b) Skip 11 if hs_activated is true. SLEEP confirm response
> is the last interrupt from firmware. No need to recheck for
> pending interrupts.
> c) Add flush_workqueue() in suspend handler.
> 
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>

Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>

> ---
>  drivers/net/wireless/marvell/mwifiex/pcie.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
> index 3c3c4f1..2833d47 100644
> --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
> +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
> @@ -118,6 +118,7 @@ static int mwifiex_pcie_suspend(struct device *dev)
>  	adapter = card->adapter;
>  
>  	hs_actived = mwifiex_enable_hs(adapter);
> +	flush_workqueue(adapter->workqueue);
>  
>  	/* Indicate device suspended */
>  	adapter->is_suspended = true;
> @@ -1669,9 +1670,6 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
>  
>  	if (!adapter->curr_cmd) {
>  		if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
> -			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
> -							   skb->len);
> -			mwifiex_pcie_enable_host_int(adapter);
>  			if (mwifiex_write_reg(adapter,
>  					      PCIE_CPU_INT_EVENT,
>  					      CPU_INTR_SLEEP_CFM_DONE)) {
> @@ -1684,6 +1682,9 @@ static int mwifiex_pcie_process_cmd_complete(struct mwifiex_adapter *adapter)
>  			while (reg->sleep_cookie && (count++ < 10) &&
>  			       mwifiex_pcie_ok_to_access_hw(adapter))
>  				usleep_range(50, 60);
> +			mwifiex_pcie_enable_host_int(adapter);
> +			mwifiex_process_sleep_confirm_resp(adapter, skb->data,
> +							   skb->len);
>  		} else {
>  			mwifiex_dbg(adapter, ERROR,
>  				    "There is no command but got cmdrsp\n");
> @@ -2322,6 +2323,8 @@ static int mwifiex_process_pcie_int(struct mwifiex_adapter *adapter)
>  			ret = mwifiex_pcie_process_cmd_complete(adapter);
>  			if (ret)
>  				return ret;
> +			if (adapter->hs_activated)
> +				return ret;
>  		}
>  
>  		if (card->msi_enable) {
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [2/8] mwifiex: report error to PCIe for suspend failure
  2016-09-28 12:48 ` [PATCH 2/8] mwifiex: report error to PCIe for suspend failure Amitkumar Karwar
@ 2016-10-04 22:24   ` Brian Norris
  0 siblings, 0 replies; 11+ messages in thread
From: Brian Norris @ 2016-10-04 22:24 UTC (permalink / raw)
  To: Amitkumar Karwar; +Cc: linux-wireless, Cathy Luo, Nishant Sarmukadam

On Wed, Sep 28, 2016 at 06:18:22PM +0530, Amitkumar Karwar wrote:
> When host_sleep_config command fails, we should return an error to
> PCIe, instead of continuing (and possibly panicking, when we try to keep
> processing a timed-out ioctl after we return "successfully" from
> suspend).
> 
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>

In case it helps to note this: this is what's already done in sdio.c,
and adding this patch prevented some crashes on my system with pcie.c.

Reviewed-by: Brian Norris <briannorris@chromium.org>
Tested-by: Brian Norris <briannorris@chromium.org>

You might want to fixup usb.c to do the same.

> ---
>  drivers/net/wireless/marvell/mwifiex/pcie.c | 10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
> index 2833d47..063c707 100644
> --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
> +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
> @@ -101,7 +101,6 @@ static int mwifiex_pcie_suspend(struct device *dev)
>  {
>  	struct mwifiex_adapter *adapter;
>  	struct pcie_service_card *card;
> -	int hs_actived;
>  	struct pci_dev *pdev = to_pci_dev(dev);
>  
>  	if (pdev) {
> @@ -117,7 +116,14 @@ static int mwifiex_pcie_suspend(struct device *dev)
>  
>  	adapter = card->adapter;
>  
> -	hs_actived = mwifiex_enable_hs(adapter);
> +	/* Enable the Host Sleep */
> +	if (!mwifiex_enable_hs(adapter)) {
> +		mwifiex_dbg(adapter, ERROR,
> +			    "cmd: failed to suspend\n");
> +		adapter->hs_enabling = false;
> +		return -EFAULT;
> +	}
> +
>  	flush_workqueue(adapter->workqueue);
>  
>  	/* Indicate device suspended */

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [1/8] mwifiex: prevent register accesses after host is sleeping
  2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
                   ` (7 preceding siblings ...)
  2016-10-04 22:20 ` [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Brian Norris
@ 2016-11-09  1:34 ` Kalle Valo
  8 siblings, 0 replies; 11+ messages in thread
From: Kalle Valo @ 2016-11-09  1:34 UTC (permalink / raw)
  To: Amitkumar Karwar
  Cc: linux-wireless, Cathy Luo, Nishant Sarmukadam, Amitkumar Karwar

Amitkumar Karwar <akarwar@marvell.com> wrote:
> Following is mwifiex driver-firmware host sleep handshake.
> It involves three threads. suspend handler, interrupt handler, interrupt
> processing in main work queue.
> 
> 1) Enter suspend handler
> 2) Download HS_CFG command
> 3) Response from firmware for HS_CFG
> 4) Suspend thread waits until handshake completes(i.e hs_activate becomes
>    true)
> 5) SLEEP from firmware
> 6) SLEEP confirm downloaded to firmware.
> 7) SLEEP confirm response from firmware
> 8) Driver processes SLEEP confirm response and set hs_activate to wake up
> suspend thread
> 9) Exit suspend handler
> 10) Read sleep cookie in loop and wait until it indicates firmware is
> sleep.
> 11) After processing SLEEP confirm response, we are at the end of interrupt
> processing routine. Recheck if there are interrupts received while we were
> processing them.
> 
> During suspend-resume stress test, it's been observed that we may end up
> acessing PCIe hardware(in 10 and 11) when PCIe bus is closed which leads
> to a kernel crash.
> 
> This patch solves the problem with below changes.
> a) action 10 above can be done before 8
> b) Skip 11 if hs_activated is true. SLEEP confirm response
> is the last interrupt from firmware. No need to recheck for
> pending interrupts.
> c) Add flush_workqueue() in suspend handler.
> 
> Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
> Reviewed-by: Brian Norris <briannorris@chromium.org>
> Tested-by: Brian Norris <briannorris@chromium.org>

8 patches applied to wireless-drivers-next.git, thanks.

ec815dd2a5f1 mwifiex: prevent register accesses after host is sleeping
5190f2e40591 mwifiex: report error to PCIe for suspend failure
c44c040300d7 mwifiex: Fix NULL pointer dereference in skb_dequeue()
113630b581d6 mwifiex: vendor_ie length check for parse WMM IEs
a936ea543657 mwifiex: add memrw command information in README
77f486c8bb39 mwifiex: update tx_pkts_queued for requeued packets
49abe5c83cd0 mwifiex: fix command timeout problem seen in stress tests
3d8bd85c2c9e mwifiex: fix p2p device doesn't find in scan problem

-- 
https://patchwork.kernel.org/patch/9353809/

Documentation about submitting wireless patches and checking status
from patchwork:

https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2016-11-09  1:34 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-28 12:48 [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Amitkumar Karwar
2016-09-28 12:48 ` [PATCH 2/8] mwifiex: report error to PCIe for suspend failure Amitkumar Karwar
2016-10-04 22:24   ` [2/8] " Brian Norris
2016-09-28 12:48 ` [PATCH 3/8] mwifiex: Fix NULL pointer dereference in skb_dequeue() Amitkumar Karwar
2016-09-28 12:48 ` [PATCH 4/8] mwifiex: vendor_ie length check for parse WMM IEs Amitkumar Karwar
2016-09-28 12:48 ` [PATCH 5/8] mwifiex: add memrw command information in README Amitkumar Karwar
2016-09-28 12:48 ` [PATCH 6/8] mwifiex: update tx_pkts_queued for requeued packets Amitkumar Karwar
2016-09-28 12:48 ` [PATCH 7/8] mwifiex: fix command timeout problem seen in stress tests Amitkumar Karwar
2016-09-28 12:48 ` [PATCH 8/8] mwifiex: fix p2p device doesn't find in scan problem Amitkumar Karwar
2016-10-04 22:20 ` [PATCH 1/8] mwifiex: prevent register accesses after host is sleeping Brian Norris
2016-11-09  1:34 ` [1/8] " Kalle Valo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.