diff mbox

[LEDE-DEV,v2] ar8327: Add workarounds for AR8337 switch.

Message ID owrt-patch-20170325-1-v2@vittgam.net
State Accepted
Delegated to: John Crispin
Headers show

Commit Message

Vittorio Gambaletta March 26, 2017, 8:08 a.m. UTC
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>

---
 .../linux/generic/files/drivers/net/phy/ar8327.c   |   43 +++++++++++++++++++-
 .../linux/generic/files/drivers/net/phy/ar8327.h   |   21 ++++++++++
 2 files changed, 63 insertions(+), 1 deletion(-)

Comments

John Crispin March 29, 2017, 8:44 a.m. UTC | #1
On 26/03/17 10:08, Vittorio Gambaletta (VittGam) wrote:
> -	.phy_fixup = ar8327_phy_fixup,
> +	//.phy_fixup = ar8337_phy_fixup, // not needed at the moment
>   	.set_mirror_regs = ar8327_set_mirror_regs,
>   	.get_arl_entry = ar8327_get_arl_entry,
>   	.sw_hw_apply = ar8327_sw_hw_apply
Hi,

why is this not needed ?

     John
Vittorio Gambaletta March 30, 2017, 4:15 a.m. UTC | #2
Hello,

On 29/03/2017 10:44:36 CEST, John Crispin wrote:
> On 26/03/17 10:08, Vittorio Gambaletta (VittGam) wrote:
>> -	.phy_fixup = ar8327_phy_fixup,
>> +	//.phy_fixup = ar8337_phy_fixup, // not needed at the moment
>>   	.set_mirror_regs = ar8327_set_mirror_regs,
>>   	.get_arl_entry = ar8327_get_arl_entry,
>>   	.sw_hw_apply = ar8327_sw_hw_apply
> Hi,
> 
> why is this not needed ?

Because QCA in their QSDK only execute the AR8327 fixup function
for the AR8327 [0]. Since the fixup function does black magic with
hidden or reserved register bits (some are not even appearing in
the datasheet...), I think that it's better to leave it out
like they do...

Cheers,
Vittorio

[0] https://source.codeaurora.org/quic/qsdk/oss/system/openwrt/tree/target/linux/generic/files/drivers/net/phy/ar8216.c?h=aa%2Fbanana#n1324
diff mbox

Patch

diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.c b/target/linux/generic/files/drivers/net/phy/ar8327.c
index 8e67f4b..97cee29 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.c
@@ -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,7 @@  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,
+	//.phy_fixup = ar8337_phy_fixup, // not needed at the moment
 	.set_mirror_regs = ar8327_set_mirror_regs,
 	.get_arl_entry = ar8327_get_arl_entry,
 	.sw_hw_apply = ar8327_sw_hw_apply,
diff --git a/target/linux/generic/files/drivers/net/phy/ar8327.h b/target/linux/generic/files/drivers/net/phy/ar8327.h
index 7bce18b..828dd28 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8327.h
+++ b/target/linux/generic/files/drivers/net/phy/ar8327.h
@@ -272,7 +272,28 @@ 
 
 #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)