ar8327: Add workarounds for AR8337 switch.
authorVittorio Gambaletta <openwrt@vittgam.net>
Sun, 26 Mar 2017 08:08:20 +0000 (10:08 +0200)
committerJohn Crispin <john@phrozen.org>
Thu, 30 Mar 2017 07:48:52 +0000 (09:48 +0200)
RGMII RX delay setting needs to be always specified for AR8337 to
avoid port 5 RX hang on high traffic / flood conditions.

Also, the HOL registers that set per-port and per-packet-priority
buffer sizes are updated with the reduced values suggested by the
QCA switch team.

Finally, AR8327 reserved register fixups are disabled for the AR8337.

This patch is adapted from the Code Aurora QSDK, but with magic
values mapped to proper defines.

Signed-off-by: Vittorio Gambaletta <openwrt@vittgam.net>
target/linux/generic/files/drivers/net/phy/ar8327.c
target/linux/generic/files/drivers/net/phy/ar8327.h

index 8e67f4b17df04d4ea1c7a214a6d12855853ac5f7..24a13c6418cd392a23c7a84db1266003c86b0306 100644 (file)
@@ -506,6 +506,14 @@ ar8327_hw_config_pdata(struct ar8xxx_priv *priv,
        ar8xxx_write(priv, AR8327_REG_PAD0_MODE, t);
 
        t = ar8327_get_pad_cfg(pdata->pad5_cfg);
+       if (chip_is_ar8337(priv)) {
+               /*
+                * Workaround: RGMII RX delay setting needs to be
+                * always specified for AR8337 to avoid port 5
+                * RX hang on high traffic / flood conditions
+                */
+               t |= AR8327_PAD_RGMII_RXCLK_DELAY_EN;
+       }
        ar8xxx_write(priv, AR8327_REG_PAD5_MODE, t);
        t = ar8327_get_pad_cfg(pdata->pad6_cfg);
        ar8xxx_write(priv, AR8327_REG_PAD6_MODE, t);
@@ -670,6 +678,39 @@ ar8327_init_globals(struct ar8xxx_priv *priv)
        /* Disable EEE on all phy's due to stability issues */
        for (i = 0; i < AR8XXX_NUM_PHYS; i++)
                data->eee[i] = false;
+
+       if (chip_is_ar8337(priv)) {
+               /* Update HOL registers with values suggested by QCA switch team */
+               for (i = 0; i < AR8327_NUM_PORTS; i++) {
+                       if (i == AR8216_PORT_CPU || i == 5 || i == 6) {
+                               t = 0x3 << AR8327_PORT_HOL_CTRL0_EG_PRI0_BUF_S;
+                               t |= 0x4 << AR8327_PORT_HOL_CTRL0_EG_PRI1_BUF_S;
+                               t |= 0x4 << AR8327_PORT_HOL_CTRL0_EG_PRI2_BUF_S;
+                               t |= 0x4 << AR8327_PORT_HOL_CTRL0_EG_PRI3_BUF_S;
+                               t |= 0x6 << AR8327_PORT_HOL_CTRL0_EG_PRI4_BUF_S;
+                               t |= 0x8 << AR8327_PORT_HOL_CTRL0_EG_PRI5_BUF_S;
+                               t |= 0x1e << AR8327_PORT_HOL_CTRL0_EG_PORT_BUF_S;
+                       } else {
+                               t = 0x3 << AR8327_PORT_HOL_CTRL0_EG_PRI0_BUF_S;
+                               t |= 0x4 << AR8327_PORT_HOL_CTRL0_EG_PRI1_BUF_S;
+                               t |= 0x6 << AR8327_PORT_HOL_CTRL0_EG_PRI2_BUF_S;
+                               t |= 0x8 << AR8327_PORT_HOL_CTRL0_EG_PRI3_BUF_S;
+                               t |= 0x19 << AR8327_PORT_HOL_CTRL0_EG_PORT_BUF_S;
+                       }
+                       ar8xxx_write(priv, AR8327_REG_PORT_HOL_CTRL0(i), t);
+
+                       t = 0x6 << AR8327_PORT_HOL_CTRL1_ING_BUF_S;
+                       t |= AR8327_PORT_HOL_CTRL1_EG_PRI_BUF_EN;
+                       t |= AR8327_PORT_HOL_CTRL1_EG_PORT_BUF_EN;
+                       t |= AR8327_PORT_HOL_CTRL1_WRED_EN;
+                       ar8xxx_rmw(priv, AR8327_REG_PORT_HOL_CTRL1(i),
+                                  AR8327_PORT_HOL_CTRL1_ING_BUF |
+                                  AR8327_PORT_HOL_CTRL1_EG_PRI_BUF_EN |
+                                  AR8327_PORT_HOL_CTRL1_EG_PORT_BUF_EN |
+                                  AR8327_PORT_HOL_CTRL1_WRED_EN,
+                                  t);
+               }
+       }
 }
 
 static void
@@ -1397,7 +1438,6 @@ const struct ar8xxx_chip ar8327_chip = {
        .atu_flush_port = ar8327_atu_flush_port,
        .vtu_flush = ar8327_vtu_flush,
        .vtu_load_vlan = ar8327_vtu_load_vlan,
-       .phy_fixup = ar8327_phy_fixup,
        .set_mirror_regs = ar8327_set_mirror_regs,
        .get_arl_entry = ar8327_get_arl_entry,
        .sw_hw_apply = ar8327_sw_hw_apply,
index 7bce18bfb81ecb0d219daf1423c8329f9a8a0783..828dd28f38617a2256948b8b46460ba459199e73 100644 (file)
 
 #define AR8327_REG_PORT_PRIO(_i)               (0x664 + (_i) * 0xc)
 
+#define AR8327_REG_PORT_HOL_CTRL0(_i)          (0x970 + (_i) * 0x8)
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI0_BUF    BITS(0, 4)
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI0_BUF_S  0
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI1_BUF    BITS(4, 4)
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI1_BUF_S  4
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI2_BUF    BITS(8, 4)
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI2_BUF_S  8
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI3_BUF    BITS(12, 4)
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI3_BUF_S  12
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI4_BUF    BITS(16, 4)
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI4_BUF_S  16
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI5_BUF    BITS(20, 4)
+#define   AR8327_PORT_HOL_CTRL0_EG_PRI5_BUF_S  20
+#define   AR8327_PORT_HOL_CTRL0_EG_PORT_BUF    BITS(24, 6)
+#define   AR8327_PORT_HOL_CTRL0_EG_PORT_BUF_S  24
+
 #define AR8327_REG_PORT_HOL_CTRL1(_i)          (0x974 + (_i) * 0x8)
+#define   AR8327_PORT_HOL_CTRL1_ING_BUF                BITS(0, 4)
+#define   AR8327_PORT_HOL_CTRL1_ING_BUF_S      0
+#define   AR8327_PORT_HOL_CTRL1_EG_PRI_BUF_EN  BIT(6)
+#define   AR8327_PORT_HOL_CTRL1_EG_PORT_BUF_EN BIT(7)
+#define   AR8327_PORT_HOL_CTRL1_WRED_EN                BIT(8)
 #define   AR8327_PORT_HOL_CTRL1_EG_MIRROR_EN   BIT(16)
 
 #define AR8337_PAD_MAC06_EXCHANGE_EN           BIT(31)