| From e5f4eb8223aa740237cd463246a7debcddf4eda1 Mon Sep 17 00:00:00 2001 |
| From: =?UTF-8?q?Jonas=20Dre=C3=9Fler?= <verdre@v0yd.nl> |
| Date: Mon, 11 Oct 2021 15:32:23 +0200 |
| Subject: mwifiex: Read a PCI register after writing the TX ring write pointer |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Jonas Dreßler <verdre@v0yd.nl> |
| |
| commit e5f4eb8223aa740237cd463246a7debcddf4eda1 upstream. |
| |
| On the 88W8897 PCIe+USB card the firmware randomly crashes after setting |
| the TX ring write pointer. The issue is present in the latest firmware |
| version 15.68.19.p21 of the PCIe+USB card. |
| |
| Those firmware crashes can be worked around by reading any PCI register |
| of the card after setting that register, so read the PCI_VENDOR_ID |
| register here. The reason this works is probably because we keep the bus |
| from entering an ASPM state for a bit longer, because that's what causes |
| the cards firmware to crash. |
| |
| This fixes a bug where during RX/TX traffic and with ASPM L1 substates |
| enabled (the specific substates where the issue happens appear to be |
| platform dependent), the firmware crashes and eventually a command |
| timeout appears in the logs. |
| |
| BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=109681 |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Jonas Dreßler <verdre@v0yd.nl> |
| Signed-off-by: Kalle Valo <kvalo@codeaurora.org> |
| Link: https://lore.kernel.org/r/20211011133224.15561-2-verdre@v0yd.nl |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/net/wireless/marvell/mwifiex/pcie.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/drivers/net/wireless/marvell/mwifiex/pcie.c |
| +++ b/drivers/net/wireless/marvell/mwifiex/pcie.c |
| @@ -1326,6 +1326,14 @@ mwifiex_pcie_send_data(struct mwifiex_ad |
| ret = -1; |
| goto done_unmap; |
| } |
| + |
| + /* The firmware (latest version 15.68.19.p21) of the 88W8897 PCIe+USB card |
| + * seems to crash randomly after setting the TX ring write pointer when |
| + * ASPM powersaving is enabled. A workaround seems to be keeping the bus |
| + * busy by reading a random register afterwards. |
| + */ |
| + mwifiex_read_reg(adapter, PCI_VENDOR_ID, &rx_val); |
| + |
| if ((mwifiex_pcie_txbd_not_full(card)) && |
| tx_param->next_pkt_len) { |
| /* have more packets and TxBD still can hold more */ |