Re: [PATCH 1/2] mwifiex: Use non-posted PCI register writes
From: Andy Shevchenko
Date: Mon Aug 30 2021 - 08:49:51 EST
On Mon, Aug 30, 2021 at 3:38 PM Jonas Dreßler <verdre@xxxxxxx> wrote:
>
> On the 88W8897 card it's very important the TX ring write pointer is
> updated correctly to its new value before setting the TX ready
> interrupt, otherwise the firmware appears to crash (probably because
> it's trying to DMA-read from the wrong place).
>
> Since PCI uses "posted writes" when writing to a register, it's not
> guaranteed that a write will happen immediately. That means the pointer
> might be outdated when setting the TX ready interrupt, leading to
> firmware crashes especially when ASPM L1 and L1 substates are enabled
> (because of the higher link latency, the write will probably take
> longer).
>
> So fix those firmware crashes by always forcing non-posted writes. We do
> that by simply reading back the register after writing it, just as a lot
> of other drivers do.
>
> There are two reproducers that are fixed with this patch:
>
> 1) During rx/tx traffic and with ASPM L1 substates enabled (the enabled
> substates are platform dependent), the firmware crashes and eventually a
> command timeout appears in the logs. That crash is fixed by using a
> non-posted write in mwifiex_pcie_send_data().
>
> 2) When sending lots of commands to the card, waking it up from sleep in
> very quick intervals, the firmware eventually crashes. That crash
> appears to be fixed by some other non-posted write included here.
Thanks for all this work!
Nevertheless, do we have any commits that may be a good candidate to
be in the Fixes tag here?
> Signed-off-by: Jonas Dreßler <verdre@xxxxxxx>
> ---
> drivers/net/wireless/marvell/mwifiex/pcie.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/wireless/marvell/mwifiex/pcie.c b/drivers/net/wireless/marvell/mwifiex/pcie.c
> index c6ccce426b49..bfd6e135ed99 100644
> --- a/drivers/net/wireless/marvell/mwifiex/pcie.c
> +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c
> @@ -237,6 +237,12 @@ static int mwifiex_write_reg(struct mwifiex_adapter *adapter, int reg, u32 data)
>
> iowrite32(data, card->pci_mmap1 + reg);
>
> + /* Do a read-back, which makes the write non-posted, ensuring the
> + * completion before returning.
> + * The firmware of the 88W8897 card is buggy and this avoids crashes.
Any firmware version reference? Would be nice to have just for the
sake of record.
> + */
> + ioread32(card->pci_mmap1 + reg);
> +
> return 0;
> }
--
With Best Regards,
Andy Shevchenko