Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: mt76: mt792x: fix scheduler interference in drv own process

Add some time to wait for LP engine to complete its operation
before polling pmctrl register.

Signed-off-by: Michael Lo <michael.lo@mediatek.com>
Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Tested-by: David Ruth <druth@chromium.org>
Acked-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20240523112131.31437-1-mingyen.hsieh@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>

authored by

Michael Lo and committed by
Felix Fietkau
d53ab629 86c051f2

+35
+1
drivers/net/wireless/mediatek/mt76/mt76.h
··· 1085 1085 1086 1086 void mt76_mmio_init(struct mt76_dev *dev, void __iomem *regs); 1087 1087 void mt76_pci_disable_aspm(struct pci_dev *pdev); 1088 + bool mt76_pci_aspm_supported(struct pci_dev *pdev); 1088 1089 1089 1090 static inline u16 mt76_chip(struct mt76_dev *dev) 1090 1091 {
+3
drivers/net/wireless/mediatek/mt76/mt7921/pci.c
··· 339 339 bus_ops->rmw = mt7921_rmw; 340 340 dev->mt76.bus = bus_ops; 341 341 342 + if (!mt7921_disable_aspm && mt76_pci_aspm_supported(pdev)) 343 + dev->aspm_supported = true; 344 + 342 345 ret = mt792xe_mcu_fw_pmctrl(dev); 343 346 if (ret) 344 347 goto err_free_dev;
+3
drivers/net/wireless/mediatek/mt76/mt7925/pci.c
··· 373 373 bus_ops->rmw = mt7925_rmw; 374 374 dev->mt76.bus = bus_ops; 375 375 376 + if (!mt7925_disable_aspm && mt76_pci_aspm_supported(pdev)) 377 + dev->aspm_supported = true; 378 + 376 379 ret = __mt792x_mcu_fw_pmctrl(dev); 377 380 if (ret) 378 381 goto err_free_dev;
+1
drivers/net/wireless/mediatek/mt76/mt792x.h
··· 215 215 bool fw_assert:1; 216 216 bool has_eht:1; 217 217 bool regd_in_progress:1; 218 + bool aspm_supported:1; 218 219 wait_queue_head_t wait; 219 220 220 221 struct work_struct init_work;
+4
drivers/net/wireless/mediatek/mt76/mt792x_core.c
··· 809 809 810 810 for (i = 0; i < MT792x_DRV_OWN_RETRY_COUNT; i++) { 811 811 mt76_wr(dev, MT_CONN_ON_LPCTL, PCIE_LPCR_HOST_CLR_OWN); 812 + 813 + if (dev->aspm_supported) 814 + usleep_range(2000, 3000); 815 + 812 816 if (mt76_poll_msec_tick(dev, MT_CONN_ON_LPCTL, 813 817 PCIE_LPCR_HOST_OWN_SYNC, 0, 50, 1)) 814 818 break;
+23
drivers/net/wireless/mediatek/mt76/pci.c
··· 45 45 aspm_conf); 46 46 } 47 47 EXPORT_SYMBOL_GPL(mt76_pci_disable_aspm); 48 + 49 + bool mt76_pci_aspm_supported(struct pci_dev *pdev) 50 + { 51 + struct pci_dev *parent = pdev->bus->self; 52 + u16 aspm_conf, parent_aspm_conf = 0; 53 + bool result = true; 54 + 55 + pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &aspm_conf); 56 + aspm_conf &= PCI_EXP_LNKCTL_ASPMC; 57 + if (parent) { 58 + pcie_capability_read_word(parent, PCI_EXP_LNKCTL, 59 + &parent_aspm_conf); 60 + parent_aspm_conf &= PCI_EXP_LNKCTL_ASPMC; 61 + } 62 + 63 + if (!aspm_conf && (!parent || !parent_aspm_conf)) { 64 + /* aspm already disabled */ 65 + result = false; 66 + } 67 + 68 + return result; 69 + } 70 + EXPORT_SYMBOL_GPL(mt76_pci_aspm_supported);