fix mt76x2e hangs on U7612E mini-pcie
Lorenzo Bianconi
maintainerv3 cover fix mt76x2e hangs on U7612E mini-pcie
Various mt76x2e issues have been reported on U7612E mini-pcie card [1]. On U7612E-H1 PCIE_ASPM causes continuous mcu hangs and instability and so patch 1/2 disable it by default.
Moreover mt76 does not properly unmap dma buffers for non-linear skbs. This issue may result in hw hangs if the system relies on IOMMU. Patch 2/2 fix the problem properly unmapping data fragments on non-linear skbs.
Changes since v2:
- fix compilation error if PCI support is not compiled
Changes since v1:
- simplify buf0 unmap condition
- use IS_ENABLED(CONFIG_PCIEASPM) instead of ifdef CONFIG_PCIEASPM
- check pci_disable_link_state return value
[1]: https://lore.kernel.org/netdev/[email protected]/
Lorenzo Bianconi (2):
mt76: mt76x2e: disable pcie_aspm by default
mt76: dma: fix buffer unmap with non-linear skbs
drivers/net/wireless/mediatek/mt76/Makefile | 2 + drivers/net/wireless/mediatek/mt76/dma.c | 6 ++- drivers/net/wireless/mediatek/mt76/mt76.h | 6 ++- .../net/wireless/mediatek/mt76/mt76x2/pci.c | 2 + drivers/net/wireless/mediatek/mt76/pci.c | 46 +++++++++++++++++++ 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/pci.c
Signature · 1 line
2.21.0
Lorenzo Bianconi
maintainerPATCH v3 1/2 mt76: mt76x2e: disable pcie_aspm by default
On same device (e.g. U7612E-H1) PCIE_ASPM causes continuous mcu hangs and instability. Since mt76x2 series does not manage PCIE PS states, first we try to disable ASPM using pci_disable_link_state. If it fails, we will disable PCIE PS configuring PCI registers.
This patch has been successfully tested on U7612E-H1 mini-pice card
--- drivers/net/wireless/mediatek/mt76/Makefile | 2 + drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt76x2/pci.c | 2 + drivers/net/wireless/mediatek/mt76/pci.c | 46 +++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 drivers/net/wireless/mediatek/mt76/pci.c
drivers/net/wireless/mediatek/mt76/Makefile +2 -0
@@ -8,6 +8,8 @@ mt76-y := \ mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \ tx.o agg-rx.o mcu.o +mt76-$(CONFIG_PCI) += pci.o + mt76-usb-y := usb.o usb_trace.o CFLAGS_trace.o := -I$(src)
drivers/net/wireless/mediatek/mt76/mt76.h +1 -0
@@ -578,6 +578,7 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val,#define mt76_poll_msec (dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__)void mt76_mmio_init (struct mt76_dev *dev,void __iomem *regs); +void mt76_pci_disable_aspm (struct pci_dev *pdev);static inline u16 mt76_chip (struct mt76_dev *dev) {
drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +2 -0
@@ -81,6 +81,8 @@ mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)/* RG_SSUSB_CDR_BR_PE1D = 0x3 */ mt76_rmw_field (dev,0x15c58 ,0x3 <<6 ,0x3 ); +mt76_pci_disable_aspm (pdev); +return 0 ; error:
drivers/net/wireless/mediatek/mt76/pci.c new file +46 -0
46 lines not on this page · raw message
Signature · 1 line
2.21.0
Re: [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default
Hi.
Quoted 7 lines · Lorenzo Bianconi
On same device (e.g. U7612E-H1)
PCIE_ASPMcauses continuous mcu hangs and instability. Since mt76x2 series does not manage PCIE PS states, first we try to disable ASPM usingpci_disable_link_state. If it fails, we will disable PCIE PS configuring PCI registers.
This patch has been successfully tested on U7612E-H1 mini-pice cardTested-by Oleksandr Natalenko <[email protected]>
For this revision, not yet ;) (see below).
Quoted 61 lines
Signed-off-by Felix Fietkau <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>--- drivers/net/wireless/mediatek/mt76/Makefile | 2 + drivers/net/wireless/mediatek/mt76/mt76.h | 1 + .../net/wireless/mediatek/mt76/mt76x2/pci.c | 2 + drivers/net/wireless/mediatek/mt76/pci.c | 46 +++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 drivers/net/wireless/mediatek/mt76/pci.cdrivers/net/wireless/mediatek/mt76/Makefile +2
-0@@ -8,6 +8,8 @@ mt76-y := \ mmio.o util.o trace.o dma.o mac80211.o debugfs.o eeprom.o \ tx.o agg-rx.o mcu.o +mt76-$(CONFIG_PCI) += pci.o + mt76-usb-y := usb.o usb_trace.o CFLAGS_trace.o := -I$(src)drivers/net/wireless/mediatek/mt76/mt76.h +1
-0@@ -578,6 +578,7 @@ bool __mt76_poll_msec(struct mt76_dev *dev, u32 offset, u32 mask, u32 val, #define mt76_poll_msec(dev, ...) __mt76_poll_msec(&((dev)->mt76), __VA_ARGS__) void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); +void mt76_pci_disable_aspm (struct pci_dev *pdev);static inline u16
mt76_chip(struct mt76_dev *dev){drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +2
-0@@ -81,6 +81,8 @@ mt76pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)/* RG_SSUSB_CDR_BR_PE1D = 0x3 */ mt76_rmw_field(dev, 0x15c58, 0x3 << 6, 0x3); +mt76_pci_disable_aspm (pdev); +return 0 ;error:
drivers/net/wireless/mediatek/mt76/pci.c new file +0
-0
drivers/net/wireless/mediatek/mt76/pci.c line 6
Quoted 6 lines
drivers/net/wireless/mediatek/mt76/pci.c new file +6
-0@@ -0,0 +1,46 @@ +// SPDX-License-Identifier: ISC +/* +* Copyright (C) 2019 Lorenzo Bianconi <[email protected]> +*/ + +#include <linux/pci.h>
FYI, I had to #include <linux/pci-aspm.h> on 5.3 kernel because this is where pci_disable_link_state() is defined. It is not needed on 5.4+ since the declaration got moved to pci.h; this is just a note for those who are going to test these changes on 5.3.
I'm still building the kernel, though. Will get back with the results later.
Quoted 40 lines
drivers/net/wireless/mediatek/mt76/pci.c new file +40
-0+ +void mt76_pci_disable_aspm (struct pci_dev *pdev) +{ +struct pci_dev *parent = pdev->bus->self; +u16 aspm_conf, parent_aspm_conf =0 ; + +pcie_capability_read_word (pdev,PCI_EXP_LNKCTL , &aspm_conf); + aspm_conf &=PCI_EXP_LNKCTL_ASPMC ; +if (parent) { +pcie_capability_read_word (parent,PCI_EXP_LNKCTL , + &parent_aspm_conf); + parent_aspm_conf &=PCI_EXP_LNKCTL_ASPMC ; + } + +if (!aspm_conf && (!parent || !parent_aspm_conf)) { +/* aspm already disabled */ +return ; + } + +dev_info (&pdev->dev,"disabling ASPM %s %s\n" , + (aspm_conf &PCI_EXP_LNKCTL_ASPM_L0S ) ?"L0s" :"" , + (aspm_conf &PCI_EXP_LNKCTL_ASPM_L1 ) ?"L1" :"" ); + +if (IS_ENABLED (CONFIG_PCIEASPM )) { +int err; + + err =pci_disable_link_state (pdev, aspm_conf); +if (!err) +return ; + } + +/* both device and parent should have the same ASPM setting. +* disable ASPM in downstream component first and then upstream. +*/ +pcie_capability_clear_word (pdev,PCI_EXP_LNKCTL , aspm_conf); +if (parent) +pcie_capability_clear_word (parent,PCI_EXP_LNKCTL , + aspm_conf); +} +EXPORT_SYMBOL_GPL (mt76_pci_disable_aspm);
Signature · 1 line
Oleksandr Natalenko (post-factum)
Re: [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default
In reply to Lorenzo BianconiQuoted 9 lines · Lorenzo Bianconi
On same device (e.g. U7612E-H1)
PCIE_ASPMcauses continuous mcu hangs and instability. Since mt76x2 series does not manage PCIE PS states, first we try to disable ASPM usingpci_disable_link_state. If it fails, we will disable PCIE PS configuring PCI registers.
This patch has been successfully tested on U7612E-H1 mini-pice cardTested-by Oleksandr Natalenko <[email protected]>Signed-off-by Felix Fietkau <[email protected]>Signed-off-by Lorenzo Bianconi <[email protected]>
2 patches applied to wireless-drivers.git, thanks.
f37f05503575 mt76: mt76x2e: disable pcie_aspm by default 7bd0650be63c mt76: dma: fix buffer unmap with non-linear skbs
Signature · 3 lines
https://patchwork.kernel.org/patch/11214309/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
Lorenzo Bianconi
maintainerPATCH v3 2/2 mt76: dma: fix buffer unmap with non-linear skbs
In reply to Lorenzo Bianconimt76 dma layer is supposed to unmap skb data buffers while keep txwi mapped on hw dma ring. At the moment mt76 wrongly unmap txwi or does not unmap data fragments in even positions for non-linear skbs. This issue may result in hw hangs with A-MSDU if the system relies on IOMMU or SWIOTLB. Fix this behaviour properly unmapping data fragments on non-linear skbs.
--- drivers/net/wireless/mediatek/mt76/dma.c | 6 ++++-- drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/dma.c +4 -2
@@ -53,8 +53,10 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,u32 ctrl;int i, idx =-1 ; -if (txwi) +if (txwi) { q->entry[q->head].txwi =DMA_DUMMY_DATA ; + q->entry[q->head].skip_buf0 = true; + }for (i =0 ; i < nbufs; i +=2 , buf +=2 ) {u32 buf0 = buf[0 ].addr, buf1 =0 ;
@@ -97,7 +99,7 @@ mt76_dma_tx_cleanup_idx(struct mt76_dev *dev, struct mt76_queue *q, int idx,__le32 __ctrl =READ_ONCE (q->desc[idx].ctrl);u32 ctrl =le32_to_cpu (__ctrl); -if (!e->txwi || !e->skb) { +if (!e->skip_buf0) {__le32 addr =READ_ONCE (q->desc[idx].buf0);u32 len =FIELD_GET (MT_DMA_CTL_SD_LEN0 , ctrl);
drivers/net/wireless/mediatek/mt76/mt76.h +3 -2
@@ -93,8 +93,9 @@ struct mt76_queue_entry {struct urb *urb; };enum mt76_txq_id qid; -bool schedule; -bool done; + bool skip_buf0:1; + bool schedule:1; + bool done:1; };struct mt76_queue_regs {
Signature · 1 line
2.21.0
Quoted 24 lines · Lorenzo Bianconi
Various mt76x2e issues have been reported on U7612E mini-pcie card [1]. On U7612E-H1
PCIE_ASPMcauses continuous mcu hangs and instability and so patch 1/2 disable it by default.
Moreover mt76 does not properly unmap dma buffers for non-linear skbs. This issue may result in hw hangs if the system relies on IOMMU. Patch 2/2 fix the problem properly unmapping data fragments on non-linear skbs.Changes since v2:
- fix compilation error if PCI support is not compiledChanges since v1:
- simplify buf0 unmap condition
- useIS_ENABLED(CONFIG_PCIEASPM)instead of ifdefCONFIG_PCIEASPM
- checkpci_disable_link_statereturn value[1]:
https://lore.kernel.org/netdev/[email protected]/Lorenzo Bianconi (2):
mt76: mt76x2e: disablepcie_aspmby default
mt76: dma: fix buffer unmap with non-linear skbs
Quoted 7 lines
drivers/net/wireless/mediatek/mt76/Makefile | 2 + drivers/net/wireless/mediatek/mt76/dma.c | 6 ++- drivers/net/wireless/mediatek/mt76/mt76.h | 6 ++- .../net/wireless/mediatek/mt76/mt76x2/pci.c | 2 + drivers/net/wireless/mediatek/mt76/pci.c | 46 +++++++++++++++++++ 5 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/pci.c
So, works fine for me. Checked with 5.3 and additional include fix I've mentioned previously.
With that, for the whole series feel free to add:
Thank you.
Signature · 1 line
Oleksandr Natalenko (post-factum)