ag71xx: Fix rx ring buffer stall on small packets flood on qca956x and qca953x.
[openwrt/staging/lynxis.git] / target / linux / ar71xx / files / arch / mips / ath79 / dev-eth.c
index 7d641d4f096e6b135ca833358b16056d9731c8fc..427de6a50d0fcbc9dae11f8e6921194c0a5b09ed 100644 (file)
@@ -686,7 +686,6 @@ static int __init ath79_setup_phy_if_mode(unsigned int id,
                case ATH79_SOC_AR7241:
                case ATH79_SOC_AR9330:
                case ATH79_SOC_AR9331:
-               case ATH79_SOC_QCA956X:
                case ATH79_SOC_TP9343:
                        pdata->phy_if_mode = PHY_INTERFACE_MODE_GMII;
                        break;
@@ -698,6 +697,7 @@ static int __init ath79_setup_phy_if_mode(unsigned int id,
                case ATH79_SOC_AR9342:
                case ATH79_SOC_AR9344:
                case ATH79_SOC_QCA9533:
+               case ATH79_SOC_QCA956X:
                        switch (pdata->phy_if_mode) {
                        case PHY_INTERFACE_MODE_MII:
                        case PHY_INTERFACE_MODE_GMII:
@@ -814,6 +814,27 @@ void __init ath79_setup_qca955x_eth_cfg(u32 mask)
        iounmap(base);
 }
 
+void __init ath79_setup_qca956x_eth_cfg(u32 mask)
+{
+       void __iomem *base;
+       u32 t;
+
+       base = ioremap(QCA956X_GMAC_BASE, QCA956X_GMAC_SIZE);
+
+       t = __raw_readl(base + QCA956X_GMAC_REG_ETH_CFG);
+
+       t &= ~(QCA956X_ETH_CFG_SW_ONLY_MODE |
+              QCA956X_ETH_CFG_SW_PHY_SWAP);
+
+       t |= mask;
+
+       __raw_writel(t, base + QCA956X_GMAC_REG_ETH_CFG);
+       /* flush write */
+       __raw_readl(base + QCA956X_GMAC_REG_ETH_CFG);
+
+       iounmap(base);
+}
+
 static int ath79_eth_instance __initdata;
 void __init ath79_register_eth(unsigned int id)
 {
@@ -907,7 +928,7 @@ void __init ath79_register_eth(unsigned int id)
                        pdata->speed = SPEED_1000;
                        pdata->duplex = DUPLEX_FULL;
                        pdata->switch_data = &ath79_switch_data;
-                       pdata->builtin_switch = 1;
+                       pdata->use_flow_control = 1;
 
                        ath79_switch_data.phy_poll_mask |= BIT(4);
                }
@@ -952,7 +973,7 @@ void __init ath79_register_eth(unsigned int id)
                        pdata->has_gbit = 1;
                        pdata->duplex = DUPLEX_FULL;
                        pdata->switch_data = &ath79_switch_data;
-                       pdata->builtin_switch = 1;
+                       pdata->use_flow_control = 1;
 
                        ath79_switch_data.phy_poll_mask |= BIT(4);
                }
@@ -975,13 +996,15 @@ 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;
                        pdata->set_speed = ath79_set_speed_dummy;
 
                        pdata->switch_data = &ath79_switch_data;
-                       pdata->builtin_switch = 1;
 
                        /* reset the built-in switch */
                        ath79_device_reset_set(AR934X_RESET_ETH_SWITCH);
@@ -1018,7 +1041,7 @@ void __init ath79_register_eth(unsigned int id)
                        pdata->speed = SPEED_1000;
                        pdata->duplex = DUPLEX_FULL;
                        pdata->switch_data = &ath79_switch_data;
-                       pdata->builtin_switch = 1;
+                       pdata->use_flow_control = 1;
 
                        ath79_switch_data.phy_poll_mask |= BIT(4);
                }
@@ -1044,7 +1067,6 @@ void __init ath79_register_eth(unsigned int id)
                        pdata->reset_bit = QCA955X_RESET_GE1_MAC |
                                           QCA955X_RESET_GE1_MDIO;
                        pdata->set_speed = qca955x_set_speed_sgmii;
-                       pdata->builtin_switch = 1;
                }
 
                pdata->has_gbit = 1;
@@ -1077,7 +1099,9 @@ void __init ath79_register_eth(unsigned int id)
                        if (pdata->phy_if_mode == PHY_INTERFACE_MODE_SGMII)
                                pdata->set_speed = qca956x_set_speed_sgmii;
                        else
-                               pdata->set_speed = ath79_set_speed_ge0;
+                               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;
@@ -1088,7 +1112,7 @@ void __init ath79_register_eth(unsigned int id)
 
                        pdata->speed = SPEED_1000;
                        pdata->duplex = DUPLEX_FULL;
-                       pdata->builtin_switch = 1;
+                       pdata->use_flow_control = 1;
 
                        /* reset the built-in switch */
                        ath79_device_reset_set(AR934X_RESET_ETH_SWITCH);