[openwrt/openwrt] ath79: ag71xx: Disable napi related interrupts during probe

LEDE Commits lede-commits at lists.infradead.org
Sat Oct 23 10:32:34 PDT 2021


chunkeey pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/ac4a21141a0e091ff1e5f8e1f03dded082582f37

commit ac4a21141a0e091ff1e5f8e1f03dded082582f37
Author: Sven Eckelmann <sven at narfation.org>
AuthorDate: Sat Oct 23 11:27:35 2021 +0200

    ath79: ag71xx: Disable napi related interrupts during probe
    
    ag71xx_probe is registering ag71xx_interrupt as handler for the gmac0/gmac1
    interrupts. The handler is trying to use napi_schedule to handle the
    processing of packets. But the netif_napi_add for this device is
    called a lot later in ag71xx_probe.
    
    It can therefore happen that a still running gmac0/gmac1 is triggering the
    interrupt handler with a bit from AG71XX_INT_POLL set in
    AG71XX_REG_INT_STATUS. The handler will then call napi_schedule and the
    napi code will crash the system because the ag->napi is not yet
    initialized:
    
      libphy: Fixed MDIO Bus: probed
      CPU 0 Unable to handle kernel paging request at virtual address 00000000, epc == 00000000, ra == 81373408
      Oops[#1]:
      CPU: 0 PID: 1 Comm: swapper Not tainted 5.4.152 #0
      $ 0   : 00000000 00000001 00000000 8280bf28
      $ 4   : 82a98cb0 00000000 81620000 00200140
      $ 8   : 00000000 00000000 74657272 7570743a
      $12   : 0000005b 8280bdb9 ffffffff ffffffff
      $16   : 00000001 82a98cb0 00000000 8280bf27
      $20   : 8280bf28 81620000 ffff8b00 8280bf30
      $24   : 00000000 8125af9c
      $28   : 82828000 8280bed8 81610000 81373408
      Hi    : 00005fff
      Lo    : 2e48f657
      epc   : 00000000 0x0
      ra    : 81373408 __napi_poll+0x3c/0x11c
      Status: 1100dc03 KERNEL EXL IE
      Cause : 00800008 (ExcCode 02)
      BadVA : 00000000
      PrId  : 00019750 (MIPS 74Kc)
      Modules linked in:
      Process swapper (pid: 1, threadinfo=(ptrval), task=(ptrval), tls=00000000)
      Stack : ffff8afb ffff8afa 81620000 00200140 00000000 82a98cb0 00000008 0000012c
              81625620 81373684 ffffffff ffffffff ffffffef 00000008 816153d8 81620000
              815b0d60 815bbd54 00000000 81753700 8280bf28 8280bf28 8280bf30 8280bf30
              81753748 00000008 00000003 00000004 0000000c 00000100 3fffffff 8175373c
              816059f0 814ddb48 00000001 8160ab30 81615488 810618bc 00000006 00000000
              ...
      Call Trace:
    
      [<81373684>] net_rx_action+0xfc/0x26c
      [<814ddb48>] __do_softirq+0x118/0x2ec
      [<810618bc>] handle_percpu_irq+0x50/0x80
      [<8125ab8c>] plat_irq_dispatch+0x94/0xc8
      [<81004e98>] handle_int+0x138/0x144
    
      Code: (Bad address in epc)
    
      ---[ end trace a60d797432b656b2 ]---
    
    The gmcc0/gmac1 must be brought in a state in which it doesn't signal a
    AG71XX_INT_POLL related status bits as interrupt before registering the
    interrupt handler. ag71xx_hw_start will take care of re-initializing the
    AG71XX_REG_INT_ENABLE.
    
    Fixes: f529a3742043 ("surprise :p")
    Signed-off-by: Sven Eckelmann <sven at narfation.org>
---
 .../ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c   | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
index 607cc0b934..a38b336a8d 100644
--- a/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
+++ b/target/linux/ath79/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c
@@ -1600,6 +1600,12 @@ static int ag71xx_probe(struct platform_device *pdev)
 			return -ENOMEM;
 	}
 
+	/* ensure that HW is in manual polling mode before interrupts are
+	 * activated. Otherwise ag71xx_interrupt might call napi_schedule
+	 * before it is initialized by netif_napi_add.
+	 */
+	ag71xx_int_disable(ag, AG71XX_INT_POLL);
+
 	dev->irq = platform_get_irq(pdev, 0);
 	err = devm_request_irq(&pdev->dev, dev->irq, ag71xx_interrupt,
 			       0x0, dev_name(&pdev->dev), dev);



More information about the lede-commits mailing list