* [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie
@ 2019-10-27 19:53 Lorenzo Bianconi
2019-10-27 19:53 ` [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default Lorenzo Bianconi
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Lorenzo Bianconi @ 2019-10-27 19:53 UTC (permalink / raw)
To: kvalo
Cc: linux-wireless, nbd, hkallweit1, sgruszka, lorenzo.bianconi,
oleksandr, netdev
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/deaafa7a3e9ea2111ebb5106430849c6@natalenko.name/
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
--
2.21.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default 2019-10-27 19:53 [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie Lorenzo Bianconi @ 2019-10-27 19:53 ` Lorenzo Bianconi 2019-10-27 21:40 ` Oleksandr Natalenko 2019-10-30 15:00 ` Kalle Valo 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 2/2] mt76: dma: fix buffer unmap with non-linear skbs Lorenzo Bianconi 2019-10-28 7:17 ` [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie Oleksandr Natalenko 2 siblings, 2 replies; 6+ messages in thread From: Lorenzo Bianconi @ 2019-10-27 19:53 UTC (permalink / raw) To: kvalo Cc: linux-wireless, nbd, hkallweit1, sgruszka, lorenzo.bianconi, oleksandr, netdev 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 Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> Signed-off-by: Felix Fietkau <nbd@nbd.name> Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> --- 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 diff --git a/drivers/net/wireless/mediatek/mt76/Makefile b/drivers/net/wireless/mediatek/mt76/Makefile index 4d03596e891f..d7a1ddc9e407 100644 --- a/drivers/net/wireless/mediatek/mt76/Makefile +++ b/drivers/net/wireless/mediatek/mt76/Makefile @@ -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) diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index 570c159515a0..dc468ed9434a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -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) { diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c index 73c3104f8858..cf611d1b817c 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c @@ -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: diff --git a/drivers/net/wireless/mediatek/mt76/pci.c b/drivers/net/wireless/mediatek/mt76/pci.c new file mode 100644 index 000000000000..04c5a692bc85 --- /dev/null +++ b/drivers/net/wireless/mediatek/mt76/pci.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: ISC +/* + * Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org> + */ + +#include <linux/pci.h> + +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); -- 2.21.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default Lorenzo Bianconi @ 2019-10-27 21:40 ` Oleksandr Natalenko 2019-10-30 15:00 ` Kalle Valo 1 sibling, 0 replies; 6+ messages in thread From: Oleksandr Natalenko @ 2019-10-27 21:40 UTC (permalink / raw) To: Lorenzo Bianconi Cc: kvalo, linux-wireless, nbd, hkallweit1, sgruszka, lorenzo.bianconi, netdev Hi. On 27.10.2019 20:53, Lorenzo Bianconi wrote: > 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 > > Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> For this revision, not yet ;) (see below). > Signed-off-by: Felix Fietkau <nbd@nbd.name> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> > --- > 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 > > diff --git a/drivers/net/wireless/mediatek/mt76/Makefile > b/drivers/net/wireless/mediatek/mt76/Makefile > index 4d03596e891f..d7a1ddc9e407 100644 > --- a/drivers/net/wireless/mediatek/mt76/Makefile > +++ b/drivers/net/wireless/mediatek/mt76/Makefile > @@ -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) > diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h > b/drivers/net/wireless/mediatek/mt76/mt76.h > index 570c159515a0..dc468ed9434a 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt76.h > +++ b/drivers/net/wireless/mediatek/mt76/mt76.h > @@ -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) > { > diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c > b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c > index 73c3104f8858..cf611d1b817c 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c > +++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c > @@ -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: > diff --git a/drivers/net/wireless/mediatek/mt76/pci.c > b/drivers/net/wireless/mediatek/mt76/pci.c > new file mode 100644 > index 000000000000..04c5a692bc85 > --- /dev/null > +++ b/drivers/net/wireless/mediatek/mt76/pci.c > @@ -0,0 +1,46 @@ > +// SPDX-License-Identifier: ISC > +/* > + * Copyright (C) 2019 Lorenzo Bianconi <lorenzo@kernel.org> > + */ > + > +#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. > + > +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); -- Oleksandr Natalenko (post-factum) ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default Lorenzo Bianconi 2019-10-27 21:40 ` Oleksandr Natalenko @ 2019-10-30 15:00 ` Kalle Valo 1 sibling, 0 replies; 6+ messages in thread From: Kalle Valo @ 2019-10-30 15:00 UTC (permalink / raw) To: Lorenzo Bianconi Cc: linux-wireless, nbd, hkallweit1, sgruszka, lorenzo.bianconi, oleksandr, netdev Lorenzo Bianconi <lorenzo@kernel.org> wrote: > 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 > > Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> > Signed-off-by: Felix Fietkau <nbd@nbd.name> > Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> 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 -- https://patchwork.kernel.org/patch/11214309/ https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v3 wireless-drivers 2/2] mt76: dma: fix buffer unmap with non-linear skbs 2019-10-27 19:53 [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie Lorenzo Bianconi 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default Lorenzo Bianconi @ 2019-10-27 19:53 ` Lorenzo Bianconi 2019-10-28 7:17 ` [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie Oleksandr Natalenko 2 siblings, 0 replies; 6+ messages in thread From: Lorenzo Bianconi @ 2019-10-27 19:53 UTC (permalink / raw) To: kvalo Cc: linux-wireless, nbd, hkallweit1, sgruszka, lorenzo.bianconi, oleksandr, netdev mt76 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. Fixes: 17f1de56df05 ("mt76: add common code shared between multiple chipsets") Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> --- drivers/net/wireless/mediatek/mt76/dma.c | 6 ++++-- drivers/net/wireless/mediatek/mt76/mt76.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/dma.c b/drivers/net/wireless/mediatek/mt76/dma.c index c747eb24581c..8f69d00bd940 100644 --- a/drivers/net/wireless/mediatek/mt76/dma.c +++ b/drivers/net/wireless/mediatek/mt76/dma.c @@ -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); diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h index dc468ed9434a..8aec7ccf2d79 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76.h +++ b/drivers/net/wireless/mediatek/mt76/mt76.h @@ -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 { -- 2.21.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie 2019-10-27 19:53 [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie Lorenzo Bianconi 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default Lorenzo Bianconi 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 2/2] mt76: dma: fix buffer unmap with non-linear skbs Lorenzo Bianconi @ 2019-10-28 7:17 ` Oleksandr Natalenko 2 siblings, 0 replies; 6+ messages in thread From: Oleksandr Natalenko @ 2019-10-28 7:17 UTC (permalink / raw) To: Lorenzo Bianconi Cc: kvalo, linux-wireless, nbd, hkallweit1, sgruszka, lorenzo.bianconi, netdev On 27.10.2019 20:53, Lorenzo Bianconi wrote: > 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/deaafa7a3e9ea2111ebb5106430849c6@natalenko.name/ > > > 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 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: Reported-by: Oleksandr Natalenko <oleksandr@natalenko.name> Tested-by: Oleksandr Natalenko <oleksandr@natalenko.name> Thank you. -- Oleksandr Natalenko (post-factum) ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-10-30 15:00 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2019-10-27 19:53 [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie Lorenzo Bianconi 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 1/2] mt76: mt76x2e: disable pcie_aspm by default Lorenzo Bianconi 2019-10-27 21:40 ` Oleksandr Natalenko 2019-10-30 15:00 ` Kalle Valo 2019-10-27 19:53 ` [PATCH v3 wireless-drivers 2/2] mt76: dma: fix buffer unmap with non-linear skbs Lorenzo Bianconi 2019-10-28 7:17 ` [PATCH v3 wireless-drivers 0/2] fix mt76x2e hangs on U7612E mini-pcie Oleksandr Natalenko
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).