All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] mwifiex: pcie: implement timeout loop for FW programming doorbell
@ 2016-11-23  2:39 Brian Norris
  2016-11-24 13:16 ` Amitkumar Karwar
  2016-11-29 15:28 ` Kalle Valo
  0 siblings, 2 replies; 3+ messages in thread
From: Brian Norris @ 2016-11-23  2:39 UTC (permalink / raw)
  To: Amitkumar Karwar, Nishant Sarmukadam
  Cc: linux-kernel, Kalle Valo, linux-wireless, Cathy Luo,
	Dmitry Torokhov, Brian Norris

Marvell Wifi PCIe modules don't always behave nicely for PCIe power
management when their firmware hasn't been loaded, particularly after
suspending the PCIe link one or more times. When this happens, we might
end up spinning forever in this status-polling tight loop. Let's make
this less tight by adding a timeout and by sleeping a bit in between
reads, as we do with the other similar loops.

This prevents us from hogging a CPU even in such pathological cases, and
allows the FW initialization to just fail gracefully instead.

I chose the same polling parameters as the earlier loop in this
function, and empirically, I found that this loop never makes it more
than about 12 cycles in a sane FW init sequence. I had no official
information on the actual intended latency for this portion of the
download.

Signed-off-by: Brian Norris <briannorris@chromium.org>
---
 drivers/net/wireless/marvell/mwifiex/pcie.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
index 4b89f557d0b6..9f9ea1350591 100644
--- a/drivers/net/wireless/marvell/mwifiex/pcie.c
+++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
@@ -2050,7 +2050,7 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 		}
 
 		/* Wait for the command done interrupt */
-		do {
+		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
 			if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
 					     &ireg_intr)) {
 				mwifiex_dbg(adapter, ERROR,
@@ -2062,8 +2062,18 @@ static int mwifiex_prog_fw_w_helper(struct mwifiex_adapter *adapter,
 				ret = -1;
 				goto done;
 			}
-		} while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
-			 CPU_INTR_DOOR_BELL);
+			if (!(ireg_intr & CPU_INTR_DOOR_BELL))
+				break;
+			usleep_range(10, 20);
+		}
+		if (ireg_intr & CPU_INTR_DOOR_BELL) {
+			mwifiex_dbg(adapter, ERROR, "%s: Card failed to ACK download\n",
+				    __func__);
+			mwifiex_unmap_pci_memory(adapter, skb,
+						 PCI_DMA_TODEVICE);
+			ret = -1;
+			goto done;
+		}
 
 		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
 
-- 
2.8.0.rc3.226.g39d4020

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

* RE: [PATCH] mwifiex: pcie: implement timeout loop for FW programming doorbell
  2016-11-23  2:39 [PATCH] mwifiex: pcie: implement timeout loop for FW programming doorbell Brian Norris
@ 2016-11-24 13:16 ` Amitkumar Karwar
  2016-11-29 15:28 ` Kalle Valo
  1 sibling, 0 replies; 3+ messages in thread
From: Amitkumar Karwar @ 2016-11-24 13:16 UTC (permalink / raw)
  To: Brian Norris, Nishant Sarmukadam
  Cc: linux-kernel, Kalle Valo, linux-wireless, Cathy Luo, Dmitry Torokhov

> From: Brian Norris [mailto:briannorris@chromium.org]
> Sent: Wednesday, November 23, 2016 8:10 AM
> To: Amitkumar Karwar; Nishant Sarmukadam
> Cc: linux-kernel@vger.kernel.org; Kalle Valo; linux-
> wireless@vger.kernel.org; Cathy Luo; Dmitry Torokhov; Brian Norris
> Subject: [PATCH] mwifiex: pcie: implement timeout loop for FW
> programming doorbell
> 
> Marvell Wifi PCIe modules don't always behave nicely for PCIe power
> management when their firmware hasn't been loaded, particularly after
> suspending the PCIe link one or more times. When this happens, we might
> end up spinning forever in this status-polling tight loop. Let's make
> this less tight by adding a timeout and by sleeping a bit in between
> reads, as we do with the other similar loops.
> 
> This prevents us from hogging a CPU even in such pathological cases,
> and allows the FW initialization to just fail gracefully instead.
> 
> I chose the same polling parameters as the earlier loop in this
> function, and empirically, I found that this loop never makes it more
> than about 12 cycles in a sane FW init sequence. I had no official
> information on the actual intended latency for this portion of the
> download.
> 
> Signed-off-by: Brian Norris <briannorris@chromium.org>
> ---
>  drivers/net/wireless/marvell/mwifiex/pcie.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c
> b/drivers/net/wireless/marvell/mwifiex/pcie.c
> index 4b89f557d0b6..9f9ea1350591 100644
> --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
> +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
> @@ -2050,7 +2050,7 @@ static int mwifiex_prog_fw_w_helper(struct
> mwifiex_adapter *adapter,
>  		}
> 
>  		/* Wait for the command done interrupt */
> -		do {
> +		for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
>  			if (mwifiex_read_reg(adapter, PCIE_CPU_INT_STATUS,
>  					     &ireg_intr)) {
>  				mwifiex_dbg(adapter, ERROR,
> @@ -2062,8 +2062,18 @@ static int mwifiex_prog_fw_w_helper(struct
> mwifiex_adapter *adapter,
>  				ret = -1;
>  				goto done;
>  			}
> -		} while ((ireg_intr & CPU_INTR_DOOR_BELL) ==
> -			 CPU_INTR_DOOR_BELL);
> +			if (!(ireg_intr & CPU_INTR_DOOR_BELL))
> +				break;
> +			usleep_range(10, 20);
> +		}
> +		if (ireg_intr & CPU_INTR_DOOR_BELL) {
> +			mwifiex_dbg(adapter, ERROR, "%s: Card failed to ACK
> download\n",
> +				    __func__);
> +			mwifiex_unmap_pci_memory(adapter, skb,
> +						 PCI_DMA_TODEVICE);
> +			ret = -1;
> +			goto done;
> +		}
> 
>  		mwifiex_unmap_pci_memory(adapter, skb, PCI_DMA_TODEVICE);
> 

Patch looks fine to me.

Acked-by: Amitkumar Karwar <akarwar@marvell.com>

Regards,
Amitkumar

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

* Re: mwifiex: pcie: implement timeout loop for FW programming doorbell
  2016-11-23  2:39 [PATCH] mwifiex: pcie: implement timeout loop for FW programming doorbell Brian Norris
  2016-11-24 13:16 ` Amitkumar Karwar
@ 2016-11-29 15:28 ` Kalle Valo
  1 sibling, 0 replies; 3+ messages in thread
From: Kalle Valo @ 2016-11-29 15:28 UTC (permalink / raw)
  To: Brian Norris
  Cc: Amitkumar Karwar, Nishant Sarmukadam, linux-kernel,
	linux-wireless, Cathy Luo, Dmitry Torokhov, Brian Norris

Brian Norris <briannorris@chromium.org> wrote:
> Marvell Wifi PCIe modules don't always behave nicely for PCIe power
> management when their firmware hasn't been loaded, particularly after
> suspending the PCIe link one or more times. When this happens, we might
> end up spinning forever in this status-polling tight loop. Let's make
> this less tight by adding a timeout and by sleeping a bit in between
> reads, as we do with the other similar loops.
> 
> This prevents us from hogging a CPU even in such pathological cases, and
> allows the FW initialization to just fail gracefully instead.
> 
> I chose the same polling parameters as the earlier loop in this
> function, and empirically, I found that this loop never makes it more
> than about 12 cycles in a sane FW init sequence. I had no official
> information on the actual intended latency for this portion of the
> download.
> 
> Signed-off-by: Brian Norris <briannorris@chromium.org>
> Acked-by: Amitkumar Karwar <akarwar@marvell.com>

Patch applied to wireless-drivers-next.git, thanks.

22dde1ed5a48 mwifiex: pcie: implement timeout loop for FW programming doorbell

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

Documentation about submitting wireless patches and checking status
from patchwork:

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

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

end of thread, other threads:[~2016-11-29 15:28 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-11-23  2:39 [PATCH] mwifiex: pcie: implement timeout loop for FW programming doorbell Brian Norris
2016-11-24 13:16 ` Amitkumar Karwar
2016-11-29 15:28 ` 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.