Message ID | 70e27cbc652cbdb78277b9c691a3a5ba02653afb.1641540175.git.objelf@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mt76: mt7921e: fix possible probe failure after reboot | expand |
On 1/7/22 12:30 AM, sean.wang@mediatek.com wrote: > From: Sean Wang <sean.wang@mediatek.com> > > It doesn't guarantee the mt7921e gets started with ASPM L0 after each > machine reboot on every platform. > > If mt7921e gets started with not ASPM L0, it would be possible that the > driver encounters time to time failure in mt7921_pci_probe, like a > weird chip identifier is read > > [ 215.514503] mt7921e 0000:05:00.0: ASIC revision: feed0000 > [ 216.604741] mt7921e: probe of 0000:05:00.0 failed with error -110 > > or failing to init hardware because the driver is not allowed to access the > register until the device is in ASPM L0 state. So, we call > __mt7921e_mcu_drv_pmctrl in early mt7921_pci_probe to force the device > to bring back to the L0 state for we can safely access registers in any > case. > > In the patch, we move all functions from dma.c to pci.c and register mt76 > bus operation earilier, that is the __mt7921e_mcu_drv_pmctrl depends on. > > Fixes: bf3747ae2e25 ("mt76: mt7921: enable aspm by default") > Reported-by: Kai-Chuan Hsieh <kaichuan.hsieh@canonical.com> > Co-developed-by: Deren Wu <deren.wu@mediatek.com> > Signed-off-by: Deren Wu <deren.wu@mediatek.com> > Signed-off-by: Sean Wang <sean.wang@mediatek.com> Tested-by: Khalid Aziz <khalid@gonehiking.org> -- Khalid > --- > .../net/wireless/mediatek/mt76/mt7921/dma.c | 119 ----------------- > .../wireless/mediatek/mt76/mt7921/mt7921.h | 1 + > .../net/wireless/mediatek/mt76/mt7921/pci.c | 124 ++++++++++++++++++ > .../wireless/mediatek/mt76/mt7921/pci_mcu.c | 18 ++- > 4 files changed, 139 insertions(+), 123 deletions(-) > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c > index cdff1fd52d93..39d6ce4ecddd 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c > @@ -78,110 +78,6 @@ static void mt7921_dma_prefetch(struct mt7921_dev *dev) > mt76_wr(dev, MT_WFDMA0_TX_RING17_EXT_CTRL, PREFETCH(0x380, 0x4)); > } > > -static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) > -{ > - static const struct { > - u32 phys; > - u32 mapped; > - u32 size; > - } fixed_map[] = { > - { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ > - { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ > - { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ > - { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ > - { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ > - { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ > - { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ > - { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ > - { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ > - { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure register) */ > - { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ > - { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ > - { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ > - { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ > - { 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */ > - { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ > - { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ > - { 0x7c060000, 0xe0000, 0x10000 }, /* CONN_INFRA, conn_host_csr_top */ > - { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ > - { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ > - { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ > - { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ > - { 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */ > - { 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */ > - { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ > - { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ > - { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ > - { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ > - { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ > - { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ > - { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ > - { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ > - { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ > - { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ > - { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ > - { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ > - { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ > - { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ > - { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ > - { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ > - { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ > - { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ > - { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ > - }; > - int i; > - > - if (addr < 0x100000) > - return addr; > - > - for (i = 0; i < ARRAY_SIZE(fixed_map); i++) { > - u32 ofs; > - > - if (addr < fixed_map[i].phys) > - continue; > - > - ofs = addr - fixed_map[i].phys; > - if (ofs > fixed_map[i].size) > - continue; > - > - return fixed_map[i].mapped + ofs; > - } > - > - if ((addr >= 0x18000000 && addr < 0x18c00000) || > - (addr >= 0x70000000 && addr < 0x78000000) || > - (addr >= 0x7c000000 && addr < 0x7c400000)) > - return mt7921_reg_map_l1(dev, addr); > - > - dev_err(dev->mt76.dev, "Access currently unsupported address %08x\n", > - addr); > - > - return 0; > -} > - > -static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) > -{ > - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > - u32 addr = __mt7921_reg_addr(dev, offset); > - > - return dev->bus_ops->rr(mdev, addr); > -} > - > -static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) > -{ > - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > - u32 addr = __mt7921_reg_addr(dev, offset); > - > - dev->bus_ops->wr(mdev, addr, val); > -} > - > -static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) > -{ > - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > - u32 addr = __mt7921_reg_addr(dev, offset); > - > - return dev->bus_ops->rmw(mdev, addr, mask, val); > -} > - > static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) > { > if (force) { > @@ -341,23 +237,8 @@ int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev) > > int mt7921_dma_init(struct mt7921_dev *dev) > { > - struct mt76_bus_ops *bus_ops; > int ret; > > - dev->phy.dev = dev; > - dev->phy.mt76 = &dev->mt76.phy; > - dev->mt76.phy.priv = &dev->phy; > - dev->bus_ops = dev->mt76.bus; > - bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), > - GFP_KERNEL); > - if (!bus_ops) > - return -ENOMEM; > - > - bus_ops->rr = mt7921_rr; > - bus_ops->wr = mt7921_wr; > - bus_ops->rmw = mt7921_rmw; > - dev->mt76.bus = bus_ops; > - > mt76_dma_attach(&dev->mt76); > > ret = mt7921_dma_disable(dev, true); > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > index 8b674e042568..63e3c7ef5e89 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > @@ -443,6 +443,7 @@ int mt7921e_mcu_init(struct mt7921_dev *dev); > int mt7921s_wfsys_reset(struct mt7921_dev *dev); > int mt7921s_mac_reset(struct mt7921_dev *dev); > int mt7921s_init_reset(struct mt7921_dev *dev); > +int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); > int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); > int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev); > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > index 1ae0d5826ca7..a0c82d19c4d9 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > @@ -121,6 +121,110 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) > mt76_free_device(&dev->mt76); > } > > +static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) > +{ > + static const struct { > + u32 phys; > + u32 mapped; > + u32 size; > + } fixed_map[] = { > + { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ > + { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ > + { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ > + { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ > + { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ > + { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ > + { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ > + { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ > + { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ > + { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure register) */ > + { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ > + { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ > + { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ > + { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ > + { 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */ > + { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ > + { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ > + { 0x7c060000, 0xe0000, 0x10000 }, /* CONN_INFRA, conn_host_csr_top */ > + { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ > + { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ > + { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ > + { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ > + { 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */ > + { 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */ > + { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ > + { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ > + { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ > + { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ > + { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ > + { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ > + { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ > + { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ > + { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ > + { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ > + { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ > + { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ > + { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ > + { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ > + { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ > + { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ > + { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ > + { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ > + { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ > + }; > + int i; > + > + if (addr < 0x100000) > + return addr; > + > + for (i = 0; i < ARRAY_SIZE(fixed_map); i++) { > + u32 ofs; > + > + if (addr < fixed_map[i].phys) > + continue; > + > + ofs = addr - fixed_map[i].phys; > + if (ofs > fixed_map[i].size) > + continue; > + > + return fixed_map[i].mapped + ofs; > + } > + > + if ((addr >= 0x18000000 && addr < 0x18c00000) || > + (addr >= 0x70000000 && addr < 0x78000000) || > + (addr >= 0x7c000000 && addr < 0x7c400000)) > + return mt7921_reg_map_l1(dev, addr); > + > + dev_err(dev->mt76.dev, "Access currently unsupported address %08x\n", > + addr); > + > + return 0; > +} > + > +static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) > +{ > + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > + u32 addr = __mt7921_reg_addr(dev, offset); > + > + return dev->bus_ops->rr(mdev, addr); > +} > + > +static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) > +{ > + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > + u32 addr = __mt7921_reg_addr(dev, offset); > + > + dev->bus_ops->wr(mdev, addr, val); > +} > + > +static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) > +{ > + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > + u32 addr = __mt7921_reg_addr(dev, offset); > + > + return dev->bus_ops->rmw(mdev, addr, mask, val); > +} > + > static int mt7921_pci_probe(struct pci_dev *pdev, > const struct pci_device_id *id) > { > @@ -152,6 +256,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev, > .fw_own = mt7921e_mcu_fw_pmctrl, > }; > > + struct mt76_bus_ops *bus_ops; > struct mt7921_dev *dev; > struct mt76_dev *mdev; > int ret; > @@ -189,6 +294,25 @@ static int mt7921_pci_probe(struct pci_dev *pdev, > > mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); > tasklet_init(&dev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev); > + > + dev->phy.dev = dev; > + dev->phy.mt76 = &dev->mt76.phy; > + dev->mt76.phy.priv = &dev->phy; > + dev->bus_ops = dev->mt76.bus; > + bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), > + GFP_KERNEL); > + if (!bus_ops) > + return -ENOMEM; > + > + bus_ops->rr = mt7921_rr; > + bus_ops->wr = mt7921_wr; > + bus_ops->rmw = mt7921_rmw; > + dev->mt76.bus = bus_ops; > + > + ret = __mt7921e_mcu_drv_pmctrl(dev); > + if (ret) > + return ret; > + > mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) | > (mt7921_l1_rr(dev, MT_HW_REV) & 0xff); > dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev); > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c > index f9e350b67fdc..36669e5aeef3 100644 > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c > @@ -59,10 +59,8 @@ int mt7921e_mcu_init(struct mt7921_dev *dev) > return err; > } > > -int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > +int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > { > - struct mt76_phy *mphy = &dev->mt76.phy; > - struct mt76_connac_pm *pm = &dev->pm; > int i, err = 0; > > for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) { > @@ -75,9 +73,21 @@ int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > if (i == MT7921_DRV_OWN_RETRY_COUNT) { > dev_err(dev->mt76.dev, "driver own failed\n"); > err = -EIO; > - goto out; > } > > + return err; > +} > + > +int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > +{ > + struct mt76_phy *mphy = &dev->mt76.phy; > + struct mt76_connac_pm *pm = &dev->pm; > + int err; > + > + err = __mt7921e_mcu_drv_pmctrl(dev); > + if (err < 0) > + goto out; > + > mt7921_wpdma_reinit_cond(dev); > clear_bit(MT76_STATE_PM, &mphy->state); >
Hi I get a BUG and the kernel resuses to boot with this patch when mt76 is compiled into the kernel https://bugzilla.kernel.org/show_bug.cgi?id=214557 I don't see this issue when mt76 is compiled as a module My .config is at https://github.com/FireBurn/KernelStuff/blob/master/dot_config_tip Let me know if you'd like any more info Cheers Mike
pt., 21 sty 2022 o 00:23 Khalid Aziz <khalid@gonehiking.org> napisaĆ(a): > > On 1/7/22 12:30 AM, sean.wang@mediatek.com wrote: > > From: Sean Wang <sean.wang@mediatek.com> > > > > It doesn't guarantee the mt7921e gets started with ASPM L0 after each > > machine reboot on every platform. > > > > If mt7921e gets started with not ASPM L0, it would be possible that the > > driver encounters time to time failure in mt7921_pci_probe, like a > > weird chip identifier is read > > > > [ 215.514503] mt7921e 0000:05:00.0: ASIC revision: feed0000 > > [ 216.604741] mt7921e: probe of 0000:05:00.0 failed with error -110 > > > > or failing to init hardware because the driver is not allowed to access the > > register until the device is in ASPM L0 state. So, we call > > __mt7921e_mcu_drv_pmctrl in early mt7921_pci_probe to force the device > > to bring back to the L0 state for we can safely access registers in any > > case. > > BTW, probably I see something similar with mt7915e (inside ramips): Have mt7915e in my mt7621 (mt7621-pci) router (pandora box/ramips). After fresh start (disconnect/connect power supply/cold reset) works correctly. After reboot seems to always fail with: Sat Dec 18 08:43:58 2021 kern.info kernel: [ 14.552269] mt7621-pci 1e140000.pcie: bus=3 slot=2 irq=25 Sat Dec 18 08:43:58 2021 kern.info kernel: [ 14.557823] pci 0000:00:02.0: enabling device (0000 -> 0003) Sat Dec 18 08:43:58 2021 kern.info kernel: [ 14.563499] mt7915e 0000:03:00.0: enabling device (0000 -> 0002) Sat Dec 18 08:43:58 2021 kern.err kernel: [ 35.094270] mt7915e 0000:03:00.0: Message 00000010 (seq 1) timeout Sat Dec 18 08:43:58 2021 kern.err kernel: [ 35.100457] mt7915e 0000:03:00.0: Failed to get patch semaphore Sat Dec 18 08:43:58 2021 kern.err kernel: [ 55.574220] mt7915e 0000:03:00.0: Message 00000010 (seq 2) timeout Sat Dec 18 08:43:58 2021 kern.err kernel: [ 55.580380] mt7915e 0000:03:00.0: Failed to get patch semaphore Sat Dec 18 08:43:58 2021 kern.warn kernel: [ 55.586529] mt7915e: probe of 0000:03:00.0 failed with error -11 This is lspci output: 02:00.0 Network controller: MEDIATEK Corp. MT7612E 802.11acbgn PCI Express Wireless Network Adapter 03:00.0 Unclassified device [0002]: MEDIATEK Corp. MT7915E 802.11ax PCI Express Wireless Network Adapter Detection works correctly after disconnect/connect power supply (cold reboot). I don't see this issue (same HW/card) with. - my laptop x86_64 - banana_pi aarch64 Any idea this could be same/similar issue and there is possible fix for that? BR Janusz > > In the patch, we move all functions from dma.c to pci.c and register mt76 > > bus operation earilier, that is the __mt7921e_mcu_drv_pmctrl depends on. > > > > Fixes: bf3747ae2e25 ("mt76: mt7921: enable aspm by default") > > Reported-by: Kai-Chuan Hsieh <kaichuan.hsieh@canonical.com> > > Co-developed-by: Deren Wu <deren.wu@mediatek.com> > > Signed-off-by: Deren Wu <deren.wu@mediatek.com> > > Signed-off-by: Sean Wang <sean.wang@mediatek.com> > > > Tested-by: Khalid Aziz <khalid@gonehiking.org> > > -- > Khalid > > --- > > .../net/wireless/mediatek/mt76/mt7921/dma.c | 119 ----------------- > > .../wireless/mediatek/mt76/mt7921/mt7921.h | 1 + > > .../net/wireless/mediatek/mt76/mt7921/pci.c | 124 ++++++++++++++++++ > > .../wireless/mediatek/mt76/mt7921/pci_mcu.c | 18 ++- > > 4 files changed, 139 insertions(+), 123 deletions(-) > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c > > index cdff1fd52d93..39d6ce4ecddd 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c > > @@ -78,110 +78,6 @@ static void mt7921_dma_prefetch(struct mt7921_dev *dev) > > mt76_wr(dev, MT_WFDMA0_TX_RING17_EXT_CTRL, PREFETCH(0x380, 0x4)); > > } > > > > -static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) > > -{ > > - static const struct { > > - u32 phys; > > - u32 mapped; > > - u32 size; > > - } fixed_map[] = { > > - { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ > > - { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ > > - { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ > > - { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ > > - { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ > > - { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ > > - { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ > > - { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ > > - { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ > > - { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure register) */ > > - { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ > > - { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ > > - { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ > > - { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ > > - { 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */ > > - { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ > > - { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ > > - { 0x7c060000, 0xe0000, 0x10000 }, /* CONN_INFRA, conn_host_csr_top */ > > - { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ > > - { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ > > - { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ > > - { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ > > - { 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */ > > - { 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */ > > - { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ > > - { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ > > - { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ > > - { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ > > - { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ > > - { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ > > - { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ > > - { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ > > - { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ > > - { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ > > - { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ > > - { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ > > - { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ > > - { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ > > - { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ > > - { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ > > - { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ > > - { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ > > - { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ > > - }; > > - int i; > > - > > - if (addr < 0x100000) > > - return addr; > > - > > - for (i = 0; i < ARRAY_SIZE(fixed_map); i++) { > > - u32 ofs; > > - > > - if (addr < fixed_map[i].phys) > > - continue; > > - > > - ofs = addr - fixed_map[i].phys; > > - if (ofs > fixed_map[i].size) > > - continue; > > - > > - return fixed_map[i].mapped + ofs; > > - } > > - > > - if ((addr >= 0x18000000 && addr < 0x18c00000) || > > - (addr >= 0x70000000 && addr < 0x78000000) || > > - (addr >= 0x7c000000 && addr < 0x7c400000)) > > - return mt7921_reg_map_l1(dev, addr); > > - > > - dev_err(dev->mt76.dev, "Access currently unsupported address %08x\n", > > - addr); > > - > > - return 0; > > -} > > - > > -static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) > > -{ > > - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > > - u32 addr = __mt7921_reg_addr(dev, offset); > > - > > - return dev->bus_ops->rr(mdev, addr); > > -} > > - > > -static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) > > -{ > > - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > > - u32 addr = __mt7921_reg_addr(dev, offset); > > - > > - dev->bus_ops->wr(mdev, addr, val); > > -} > > - > > -static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) > > -{ > > - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > > - u32 addr = __mt7921_reg_addr(dev, offset); > > - > > - return dev->bus_ops->rmw(mdev, addr, mask, val); > > -} > > - > > static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) > > { > > if (force) { > > @@ -341,23 +237,8 @@ int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev) > > > > int mt7921_dma_init(struct mt7921_dev *dev) > > { > > - struct mt76_bus_ops *bus_ops; > > int ret; > > > > - dev->phy.dev = dev; > > - dev->phy.mt76 = &dev->mt76.phy; > > - dev->mt76.phy.priv = &dev->phy; > > - dev->bus_ops = dev->mt76.bus; > > - bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), > > - GFP_KERNEL); > > - if (!bus_ops) > > - return -ENOMEM; > > - > > - bus_ops->rr = mt7921_rr; > > - bus_ops->wr = mt7921_wr; > > - bus_ops->rmw = mt7921_rmw; > > - dev->mt76.bus = bus_ops; > > - > > mt76_dma_attach(&dev->mt76); > > > > ret = mt7921_dma_disable(dev, true); > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > index 8b674e042568..63e3c7ef5e89 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h > > @@ -443,6 +443,7 @@ int mt7921e_mcu_init(struct mt7921_dev *dev); > > int mt7921s_wfsys_reset(struct mt7921_dev *dev); > > int mt7921s_mac_reset(struct mt7921_dev *dev); > > int mt7921s_init_reset(struct mt7921_dev *dev); > > +int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); > > int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); > > int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev); > > > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > index 1ae0d5826ca7..a0c82d19c4d9 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c > > @@ -121,6 +121,110 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) > > mt76_free_device(&dev->mt76); > > } > > > > +static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) > > +{ > > + static const struct { > > + u32 phys; > > + u32 mapped; > > + u32 size; > > + } fixed_map[] = { > > + { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ > > + { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ > > + { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ > > + { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ > > + { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ > > + { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ > > + { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ > > + { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ > > + { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ > > + { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure register) */ > > + { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ > > + { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ > > + { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ > > + { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ > > + { 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */ > > + { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ > > + { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ > > + { 0x7c060000, 0xe0000, 0x10000 }, /* CONN_INFRA, conn_host_csr_top */ > > + { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ > > + { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ > > + { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ > > + { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ > > + { 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */ > > + { 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */ > > + { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ > > + { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ > > + { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ > > + { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ > > + { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ > > + { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ > > + { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ > > + { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ > > + { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ > > + { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ > > + { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ > > + { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ > > + { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ > > + { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ > > + { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ > > + { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ > > + { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ > > + { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ > > + { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ > > + }; > > + int i; > > + > > + if (addr < 0x100000) > > + return addr; > > + > > + for (i = 0; i < ARRAY_SIZE(fixed_map); i++) { > > + u32 ofs; > > + > > + if (addr < fixed_map[i].phys) > > + continue; > > + > > + ofs = addr - fixed_map[i].phys; > > + if (ofs > fixed_map[i].size) > > + continue; > > + > > + return fixed_map[i].mapped + ofs; > > + } > > + > > + if ((addr >= 0x18000000 && addr < 0x18c00000) || > > + (addr >= 0x70000000 && addr < 0x78000000) || > > + (addr >= 0x7c000000 && addr < 0x7c400000)) > > + return mt7921_reg_map_l1(dev, addr); > > + > > + dev_err(dev->mt76.dev, "Access currently unsupported address %08x\n", > > + addr); > > + > > + return 0; > > +} > > + > > +static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) > > +{ > > + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > > + u32 addr = __mt7921_reg_addr(dev, offset); > > + > > + return dev->bus_ops->rr(mdev, addr); > > +} > > + > > +static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) > > +{ > > + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > > + u32 addr = __mt7921_reg_addr(dev, offset); > > + > > + dev->bus_ops->wr(mdev, addr, val); > > +} > > + > > +static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) > > +{ > > + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); > > + u32 addr = __mt7921_reg_addr(dev, offset); > > + > > + return dev->bus_ops->rmw(mdev, addr, mask, val); > > +} > > + > > static int mt7921_pci_probe(struct pci_dev *pdev, > > const struct pci_device_id *id) > > { > > @@ -152,6 +256,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev, > > .fw_own = mt7921e_mcu_fw_pmctrl, > > }; > > > > + struct mt76_bus_ops *bus_ops; > > struct mt7921_dev *dev; > > struct mt76_dev *mdev; > > int ret; > > @@ -189,6 +294,25 @@ static int mt7921_pci_probe(struct pci_dev *pdev, > > > > mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); > > tasklet_init(&dev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev); > > + > > + dev->phy.dev = dev; > > + dev->phy.mt76 = &dev->mt76.phy; > > + dev->mt76.phy.priv = &dev->phy; > > + dev->bus_ops = dev->mt76.bus; > > + bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), > > + GFP_KERNEL); > > + if (!bus_ops) > > + return -ENOMEM; > > + > > + bus_ops->rr = mt7921_rr; > > + bus_ops->wr = mt7921_wr; > > + bus_ops->rmw = mt7921_rmw; > > + dev->mt76.bus = bus_ops; > > + > > + ret = __mt7921e_mcu_drv_pmctrl(dev); > > + if (ret) > > + return ret; > > + > > mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) | > > (mt7921_l1_rr(dev, MT_HW_REV) & 0xff); > > dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev); > > diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c > > index f9e350b67fdc..36669e5aeef3 100644 > > --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c > > +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c > > @@ -59,10 +59,8 @@ int mt7921e_mcu_init(struct mt7921_dev *dev) > > return err; > > } > > > > -int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > > +int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > > { > > - struct mt76_phy *mphy = &dev->mt76.phy; > > - struct mt76_connac_pm *pm = &dev->pm; > > int i, err = 0; > > > > for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) { > > @@ -75,9 +73,21 @@ int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > > if (i == MT7921_DRV_OWN_RETRY_COUNT) { > > dev_err(dev->mt76.dev, "driver own failed\n"); > > err = -EIO; > > - goto out; > > } > > > > + return err; > > +} > > + > > +int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) > > +{ > > + struct mt76_phy *mphy = &dev->mt76.phy; > > + struct mt76_connac_pm *pm = &dev->pm; > > + int err; > > + > > + err = __mt7921e_mcu_drv_pmctrl(dev); > > + if (err < 0) > > + goto out; > > + > > mt7921_wpdma_reinit_cond(dev); > > clear_bit(MT76_STATE_PM, &mphy->state); > > > > -- Janusz Dziedzic
On Thu, 20 Jan 2022 at 09:56, Mike Lothian <mike@fireburn.co.uk> wrote: > > Hi > > I get a BUG and the kernel resuses to boot with this patch when mt76 is compiled into the kernel > > https://bugzilla.kernel.org/show_bug.cgi?id=214557 > > I don't see this issue when mt76 is compiled as a module > > My .config is at https://github.com/FireBurn/KernelStuff/blob/master/dot_config_tip > > Let me know if you'd like any more info > > Cheers > > Mike The bug I was hitting was due to a different change introduced in rc1, with that reverted your patches work great Though I am seeing lots of these messages from the bluetooth device: Bluetooth: hci0: unexpected event 0xff length: 5 > 0 I'll bisect that next Thanks Mike
On 1/25/22 6:16 AM, Mike Lothian wrote: > On Thu, 20 Jan 2022 at 09:56, Mike Lothian <mike@fireburn.co.uk> wrote: >> >> Hi >> >> I get a BUG and the kernel resuses to boot with this patch when mt76 is compiled into the kernel >> >> https://bugzilla.kernel.org/show_bug.cgi?id=214557 >> >> I don't see this issue when mt76 is compiled as a module >> >> My .config is at https://github.com/FireBurn/KernelStuff/blob/master/dot_config_tip >> >> Let me know if you'd like any more info >> >> Cheers >> >> Mike > > The bug I was hitting was due to a different change introduced in rc1, > with that reverted your patches work great What patch did you revert? Thanks, Ben > > Though I am seeing lots of these messages from the bluetooth device: > > Bluetooth: hci0: unexpected event 0xff length: 5 > 0 > > I'll bisect that next > > Thanks > > Mike >
On Tue, 25 Jan 2022 at 18:09, Ben Greear <greearb@candelatech.com> wrote: > > On 1/25/22 6:16 AM, Mike Lothian wrote: > > On Thu, 20 Jan 2022 at 09:56, Mike Lothian <mike@fireburn.co.uk> wrote: > >> > >> Hi > >> > >> I get a BUG and the kernel resuses to boot with this patch when mt76 is compiled into the kernel > >> > >> https://bugzilla.kernel.org/show_bug.cgi?id=214557 > >> > >> I don't see this issue when mt76 is compiled as a module > >> > >> My .config is at https://github.com/FireBurn/KernelStuff/blob/master/dot_config_tip > >> > >> Let me know if you'd like any more info > >> > >> Cheers > >> > >> Mike > > > > The bug I was hitting was due to a different change introduced in rc1, > > with that reverted your patches work great > > What patch did you revert? > > Thanks, > Ben > Hi I reverted both 730b49aac426e1e8016d3c2dd6b407e500423821 and 510a0bdb2bfcff8d7be822c72adc3add7a97d559 But there's a fix now, https://patchwork.kernel.org/project/linux-usb/patch/20220124090228.41396-2-heikki.krogerus@linux.intel.com/ I'm able to load mt76 as a module or built in Cheers Mike
Hi Has this patch made it into any upstream trees and is it likely to be backported? Cheers Mike On Tue, 25 Jan 2022 at 22:56, Mike Lothian <mike@fireburn.co.uk> wrote: > > On Tue, 25 Jan 2022 at 18:09, Ben Greear <greearb@candelatech.com> wrote: > > > > On 1/25/22 6:16 AM, Mike Lothian wrote: > > > On Thu, 20 Jan 2022 at 09:56, Mike Lothian <mike@fireburn.co.uk> wrote: > > >> > > >> Hi > > >> > > >> I get a BUG and the kernel resuses to boot with this patch when mt76 is compiled into the kernel > > >> > > >> https://bugzilla.kernel.org/show_bug.cgi?id=214557 > > >> > > >> I don't see this issue when mt76 is compiled as a module > > >> > > >> My .config is at https://github.com/FireBurn/KernelStuff/blob/master/dot_config_tip > > >> > > >> Let me know if you'd like any more info > > >> > > >> Cheers > > >> > > >> Mike > > > > > > The bug I was hitting was due to a different change introduced in rc1, > > > with that reverted your patches work great > > > > What patch did you revert? > > > > Thanks, > > Ben > > > > Hi > > I reverted both 730b49aac426e1e8016d3c2dd6b407e500423821 and > 510a0bdb2bfcff8d7be822c72adc3add7a97d559 > > But there's a fix now, > https://patchwork.kernel.org/project/linux-usb/patch/20220124090228.41396-2-heikki.krogerus@linux.intel.com/ > > I'm able to load mt76 as a module or built in > > Cheers > > Mike
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c index cdff1fd52d93..39d6ce4ecddd 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c @@ -78,110 +78,6 @@ static void mt7921_dma_prefetch(struct mt7921_dev *dev) mt76_wr(dev, MT_WFDMA0_TX_RING17_EXT_CTRL, PREFETCH(0x380, 0x4)); } -static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) -{ - static const struct { - u32 phys; - u32 mapped; - u32 size; - } fixed_map[] = { - { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ - { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ - { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ - { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ - { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ - { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ - { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ - { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ - { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ - { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure register) */ - { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ - { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ - { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ - { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ - { 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */ - { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ - { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ - { 0x7c060000, 0xe0000, 0x10000 }, /* CONN_INFRA, conn_host_csr_top */ - { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ - { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ - { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ - { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ - { 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */ - { 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */ - { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ - { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ - { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ - { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ - { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ - { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ - { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ - { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ - { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ - { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ - { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ - { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ - { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ - { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ - { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ - { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ - { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ - { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ - { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ - }; - int i; - - if (addr < 0x100000) - return addr; - - for (i = 0; i < ARRAY_SIZE(fixed_map); i++) { - u32 ofs; - - if (addr < fixed_map[i].phys) - continue; - - ofs = addr - fixed_map[i].phys; - if (ofs > fixed_map[i].size) - continue; - - return fixed_map[i].mapped + ofs; - } - - if ((addr >= 0x18000000 && addr < 0x18c00000) || - (addr >= 0x70000000 && addr < 0x78000000) || - (addr >= 0x7c000000 && addr < 0x7c400000)) - return mt7921_reg_map_l1(dev, addr); - - dev_err(dev->mt76.dev, "Access currently unsupported address %08x\n", - addr); - - return 0; -} - -static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) -{ - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - u32 addr = __mt7921_reg_addr(dev, offset); - - return dev->bus_ops->rr(mdev, addr); -} - -static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) -{ - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - u32 addr = __mt7921_reg_addr(dev, offset); - - dev->bus_ops->wr(mdev, addr, val); -} - -static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) -{ - struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); - u32 addr = __mt7921_reg_addr(dev, offset); - - return dev->bus_ops->rmw(mdev, addr, mask, val); -} - static int mt7921_dma_disable(struct mt7921_dev *dev, bool force) { if (force) { @@ -341,23 +237,8 @@ int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev) int mt7921_dma_init(struct mt7921_dev *dev) { - struct mt76_bus_ops *bus_ops; int ret; - dev->phy.dev = dev; - dev->phy.mt76 = &dev->mt76.phy; - dev->mt76.phy.priv = &dev->phy; - dev->bus_ops = dev->mt76.bus; - bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), - GFP_KERNEL); - if (!bus_ops) - return -ENOMEM; - - bus_ops->rr = mt7921_rr; - bus_ops->wr = mt7921_wr; - bus_ops->rmw = mt7921_rmw; - dev->mt76.bus = bus_ops; - mt76_dma_attach(&dev->mt76); ret = mt7921_dma_disable(dev, true); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h index 8b674e042568..63e3c7ef5e89 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h +++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h @@ -443,6 +443,7 @@ int mt7921e_mcu_init(struct mt7921_dev *dev); int mt7921s_wfsys_reset(struct mt7921_dev *dev); int mt7921s_mac_reset(struct mt7921_dev *dev); int mt7921s_init_reset(struct mt7921_dev *dev); +int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev); int mt7921e_mcu_fw_pmctrl(struct mt7921_dev *dev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c index 1ae0d5826ca7..a0c82d19c4d9 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c @@ -121,6 +121,110 @@ static void mt7921e_unregister_device(struct mt7921_dev *dev) mt76_free_device(&dev->mt76); } +static u32 __mt7921_reg_addr(struct mt7921_dev *dev, u32 addr) +{ + static const struct { + u32 phys; + u32 mapped; + u32 size; + } fixed_map[] = { + { 0x820d0000, 0x30000, 0x10000 }, /* WF_LMAC_TOP (WF_WTBLON) */ + { 0x820ed000, 0x24800, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_MIB) */ + { 0x820e4000, 0x21000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_TMAC) */ + { 0x820e7000, 0x21e00, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_DMA) */ + { 0x820eb000, 0x24200, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_LPON) */ + { 0x820e2000, 0x20800, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_AGG) */ + { 0x820e3000, 0x20c00, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_ARB) */ + { 0x820e5000, 0x21400, 0x0800 }, /* WF_LMAC_TOP BN0 (WF_RMAC) */ + { 0x00400000, 0x80000, 0x10000 }, /* WF_MCU_SYSRAM */ + { 0x00410000, 0x90000, 0x10000 }, /* WF_MCU_SYSRAM (configure register) */ + { 0x40000000, 0x70000, 0x10000 }, /* WF_UMAC_SYSRAM */ + { 0x54000000, 0x02000, 0x1000 }, /* WFDMA PCIE0 MCU DMA0 */ + { 0x55000000, 0x03000, 0x1000 }, /* WFDMA PCIE0 MCU DMA1 */ + { 0x58000000, 0x06000, 0x1000 }, /* WFDMA PCIE1 MCU DMA0 (MEM_DMA) */ + { 0x59000000, 0x07000, 0x1000 }, /* WFDMA PCIE1 MCU DMA1 */ + { 0x7c000000, 0xf0000, 0x10000 }, /* CONN_INFRA */ + { 0x7c020000, 0xd0000, 0x10000 }, /* CONN_INFRA, WFDMA */ + { 0x7c060000, 0xe0000, 0x10000 }, /* CONN_INFRA, conn_host_csr_top */ + { 0x80020000, 0xb0000, 0x10000 }, /* WF_TOP_MISC_OFF */ + { 0x81020000, 0xc0000, 0x10000 }, /* WF_TOP_MISC_ON */ + { 0x820c0000, 0x08000, 0x4000 }, /* WF_UMAC_TOP (PLE) */ + { 0x820c8000, 0x0c000, 0x2000 }, /* WF_UMAC_TOP (PSE) */ + { 0x820cc000, 0x0e000, 0x1000 }, /* WF_UMAC_TOP (PP) */ + { 0x820cd000, 0x0f000, 0x1000 }, /* WF_MDP_TOP */ + { 0x820ce000, 0x21c00, 0x0200 }, /* WF_LMAC_TOP (WF_SEC) */ + { 0x820cf000, 0x22000, 0x1000 }, /* WF_LMAC_TOP (WF_PF) */ + { 0x820e0000, 0x20000, 0x0400 }, /* WF_LMAC_TOP BN0 (WF_CFG) */ + { 0x820e1000, 0x20400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_TRB) */ + { 0x820e9000, 0x23400, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_WTBLOFF) */ + { 0x820ea000, 0x24000, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_ETBF) */ + { 0x820ec000, 0x24600, 0x0200 }, /* WF_LMAC_TOP BN0 (WF_INT) */ + { 0x820f0000, 0xa0000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_CFG) */ + { 0x820f1000, 0xa0600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_TRB) */ + { 0x820f2000, 0xa0800, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_AGG) */ + { 0x820f3000, 0xa0c00, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_ARB) */ + { 0x820f4000, 0xa1000, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_TMAC) */ + { 0x820f5000, 0xa1400, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_RMAC) */ + { 0x820f7000, 0xa1e00, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_DMA) */ + { 0x820f9000, 0xa3400, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_WTBLOFF) */ + { 0x820fa000, 0xa4000, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_ETBF) */ + { 0x820fb000, 0xa4200, 0x0400 }, /* WF_LMAC_TOP BN1 (WF_LPON) */ + { 0x820fc000, 0xa4600, 0x0200 }, /* WF_LMAC_TOP BN1 (WF_INT) */ + { 0x820fd000, 0xa4800, 0x0800 }, /* WF_LMAC_TOP BN1 (WF_MIB) */ + }; + int i; + + if (addr < 0x100000) + return addr; + + for (i = 0; i < ARRAY_SIZE(fixed_map); i++) { + u32 ofs; + + if (addr < fixed_map[i].phys) + continue; + + ofs = addr - fixed_map[i].phys; + if (ofs > fixed_map[i].size) + continue; + + return fixed_map[i].mapped + ofs; + } + + if ((addr >= 0x18000000 && addr < 0x18c00000) || + (addr >= 0x70000000 && addr < 0x78000000) || + (addr >= 0x7c000000 && addr < 0x7c400000)) + return mt7921_reg_map_l1(dev, addr); + + dev_err(dev->mt76.dev, "Access currently unsupported address %08x\n", + addr); + + return 0; +} + +static u32 mt7921_rr(struct mt76_dev *mdev, u32 offset) +{ + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + u32 addr = __mt7921_reg_addr(dev, offset); + + return dev->bus_ops->rr(mdev, addr); +} + +static void mt7921_wr(struct mt76_dev *mdev, u32 offset, u32 val) +{ + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + u32 addr = __mt7921_reg_addr(dev, offset); + + dev->bus_ops->wr(mdev, addr, val); +} + +static u32 mt7921_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val) +{ + struct mt7921_dev *dev = container_of(mdev, struct mt7921_dev, mt76); + u32 addr = __mt7921_reg_addr(dev, offset); + + return dev->bus_ops->rmw(mdev, addr, mask, val); +} + static int mt7921_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -152,6 +256,7 @@ static int mt7921_pci_probe(struct pci_dev *pdev, .fw_own = mt7921e_mcu_fw_pmctrl, }; + struct mt76_bus_ops *bus_ops; struct mt7921_dev *dev; struct mt76_dev *mdev; int ret; @@ -189,6 +294,25 @@ static int mt7921_pci_probe(struct pci_dev *pdev, mt76_mmio_init(&dev->mt76, pcim_iomap_table(pdev)[0]); tasklet_init(&dev->irq_tasklet, mt7921_irq_tasklet, (unsigned long)dev); + + dev->phy.dev = dev; + dev->phy.mt76 = &dev->mt76.phy; + dev->mt76.phy.priv = &dev->phy; + dev->bus_ops = dev->mt76.bus; + bus_ops = devm_kmemdup(dev->mt76.dev, dev->bus_ops, sizeof(*bus_ops), + GFP_KERNEL); + if (!bus_ops) + return -ENOMEM; + + bus_ops->rr = mt7921_rr; + bus_ops->wr = mt7921_wr; + bus_ops->rmw = mt7921_rmw; + dev->mt76.bus = bus_ops; + + ret = __mt7921e_mcu_drv_pmctrl(dev); + if (ret) + return ret; + mdev->rev = (mt7921_l1_rr(dev, MT_HW_CHIPID) << 16) | (mt7921_l1_rr(dev, MT_HW_REV) & 0xff); dev_info(mdev->dev, "ASIC revision: %04x\n", mdev->rev); diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c index f9e350b67fdc..36669e5aeef3 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci_mcu.c @@ -59,10 +59,8 @@ int mt7921e_mcu_init(struct mt7921_dev *dev) return err; } -int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) +int __mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) { - struct mt76_phy *mphy = &dev->mt76.phy; - struct mt76_connac_pm *pm = &dev->pm; int i, err = 0; for (i = 0; i < MT7921_DRV_OWN_RETRY_COUNT; i++) { @@ -75,9 +73,21 @@ int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) if (i == MT7921_DRV_OWN_RETRY_COUNT) { dev_err(dev->mt76.dev, "driver own failed\n"); err = -EIO; - goto out; } + return err; +} + +int mt7921e_mcu_drv_pmctrl(struct mt7921_dev *dev) +{ + struct mt76_phy *mphy = &dev->mt76.phy; + struct mt76_connac_pm *pm = &dev->pm; + int err; + + err = __mt7921e_mcu_drv_pmctrl(dev); + if (err < 0) + goto out; + mt7921_wpdma_reinit_cond(dev); clear_bit(MT76_STATE_PM, &mphy->state);