Fix issue #78 with patch from upstream commit d40a358136fdc19e6af13921867ed93444c08827 v1.4.6
authorRISCi_ATOM <bob@bobcall.me>
Wed, 2 Jan 2019 13:27:27 +0000 (08:27 -0500)
committerRISCi_ATOM <bob@bobcall.me>
Wed, 2 Jan 2019 13:27:27 +0000 (08:27 -0500)
The rx ring buffer can stall on small packets on QCA953x and
QCA956x. Disabling the inline checksum engine fixes the stall.
The wr, rr functions cannot be used since this hidden register
is outside of the normal ag71xx register block.

target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c
target/linux/ar71xx/files/arch/mips/include/asm/mach-ath79/ag71xx_platform.h
target/linux/ar71xx/files/drivers/net/ethernet/atheros/ag71xx/ag71xx_main.c

index 790c2d3396ffd0a0d00d13403b7f22e32863eef4..d619ade92d502e730ff7b7249afce7880777e2be 100644 (file)
@@ -975,6 +975,9 @@ void __init ath79_register_eth(unsigned int id)
                        pdata->reset_bit = AR934X_RESET_GE0_MAC |
                                           AR934X_RESET_GE0_MDIO;
                        pdata->set_speed = ar934x_set_speed_ge0;
+
+                       if (ath79_soc == ATH79_SOC_QCA9533)
+                               pdata->disable_inline_checksum_engine = 1;
                } else {
                        pdata->reset_bit = AR934X_RESET_GE1_MAC |
                                           AR934X_RESET_GE1_MDIO;
@@ -1076,6 +1079,8 @@ void __init ath79_register_eth(unsigned int id)
                                pdata->set_speed = qca956x_set_speed_sgmii;
                        else
                                pdata->set_speed = ar934x_set_speed_ge0;
+
+                       pdata->disable_inline_checksum_engine = 1;
                } else {
                        pdata->reset_bit = QCA955X_RESET_GE1_MAC |
                                           QCA955X_RESET_GE1_MDIO;
index 5fd352c638a75063945adadb64b1043cd81b506c..0e462d60f863136989291e4b48eeb7522182821e 100644 (file)
@@ -37,6 +37,7 @@ struct ag71xx_platform_data {
        u8              is_ar724x:1;
        u8              has_ar8216:1;
        u8              use_flow_control:1;
+       u8              disable_inline_checksum_engine:1;
 
        struct ag71xx_switch_platform_data *switch_data;
 
index 566e9513d8b7c6ef101902ae7d281dcc1c233893..72dd654a691355c881b15d796fad0d640e05fc15 100644 (file)
@@ -629,6 +629,22 @@ __ag71xx_link_adjust(struct ag71xx *ag, bool update)
        ag71xx_wr(ag, AG71XX_REG_MAC_CFG2, cfg2);
        ag71xx_wr(ag, AG71XX_REG_FIFO_CFG5, fifo5);
        ag71xx_wr(ag, AG71XX_REG_MAC_IFCTL, ifctl);
+
+       if (pdata->disable_inline_checksum_engine) {
+               /*
+                * The rx ring buffer can stall on small packets on QCA953x and
+                * QCA956x. Disabling the inline checksum engine fixes the stall.
+                * The wr, rr functions cannot be used since this hidden register
+                * is outside of the normal ag71xx register block.
+                */
+               void __iomem *dam = ioremap_nocache(0xb90001bc, 0x4);
+               if (dam) {
+                       __raw_writel(__raw_readl(dam) & ~BIT(27), dam);
+                       (void)__raw_readl(dam);
+                       iounmap(dam);
+               }
+       }
+
        ag71xx_hw_start(ag);
 
        netif_carrier_on(ag->dev);