[RFC PATCH v2 2/3] ramips: add RT6855A support to ethernet driver

Rafaël Carré funman at videolan.org
Sun Dec 27 19:24:37 EST 2020


Signed-off-by: Rafaël Carré <funman at videolan.org>
---
Changes since v1:
- Extend soc_rt3050.c rather than adding a new file
- Use .compatible rather than #ifdef in esw_rt3050.c

 .../files/drivers/net/ethernet/ralink/Kconfig |  2 +-
 .../drivers/net/ethernet/ralink/esw_rt3050.c  | 61 ++++++++++++++++---
 .../drivers/net/ethernet/ralink/mtk_eth_soc.h |  1 +
 .../drivers/net/ethernet/ralink/soc_rt3050.c  | 17 ++++++
 4 files changed, 73 insertions(+), 10 deletions(-)

diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig b/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig
index 26e5e6d73e..fddf39e3e3 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/Kconfig
@@ -17,7 +17,7 @@ config NET_RALINK_RT2880
 
 config NET_RALINK_RT3050
 	bool "RT3050/MT7628"
-	depends on MIPS && (SOC_RT305X || SOC_MT7620)
+	depends on MIPS && (SOC_RT305X || SOC_MT7620 || SOC_RT6855A)
 
 config NET_RALINK_RT3883
 	bool "RT3883"
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c
index 292f11a170..f6b30106f7 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/esw_rt3050.c
@@ -18,6 +18,7 @@
 #include <linux/platform_device.h>
 #include <asm/mach-ralink/ralink_regs.h>
 #include <linux/of_irq.h>
+#include <linux/of_device.h>
 
 #include <linux/switch.h>
 
@@ -85,6 +86,7 @@
 #define RT305X_ESW_PCR0_WT_NWAY_DATA_S	16
 #define RT305X_ESW_PCR0_WT_PHY_CMD	BIT(13)
 #define RT305X_ESW_PCR0_CPU_PHY_REG_S	8
+#define RT305X_ESW_PCR0_WT_DONE		BIT(31)
 
 #define RT305X_ESW_PCR1_WT_DONE		BIT(0)
 
@@ -211,6 +213,13 @@ enum {
 	RT305X_ESW_VLAN_CONFIG_WLLLL,
 };
 
+struct rt305x_esw;
+
+struct rt305x_pcr {
+	u32 (*pcr_value)(u32 phy_addr, u32 phy_register, u32 write_data);
+	int (*pcr_done)(struct rt305x_esw *esw);
+};
+
 struct rt305x_esw {
 	struct device		*dev;
 	void __iomem		*base;
@@ -233,8 +242,11 @@ struct rt305x_esw {
 	struct esw_vlan vlans[RT305X_ESW_NUM_VLANS];
 	struct esw_port ports[RT305X_ESW_NUM_PORTS];
 
+	struct rt305x_pcr *pcr;
 };
 
+static const struct of_device_id ralink_esw_match[];
+
 static inline void esw_w32(struct rt305x_esw *esw, u32 val, unsigned reg)
 {
 	__raw_writel(val, esw->base + reg);
@@ -264,6 +276,28 @@ static void esw_rmw(struct rt305x_esw *esw, unsigned reg,
 	spin_unlock_irqrestore(&esw->reg_rw_lock, flags);
 }
 
+static u32 rt6855a_pcr_value(u32 phy_addr, u32 phy_register, u32 write_data)
+{
+	return (write_data ) | (phy_register << 16) | (phy_addr << 24) | (3 << 30);
+}
+
+static u32 rt305x_pcr_value(u32 phy_addr, u32 phy_register, u32 write_data)
+{
+	return (write_data << RT305X_ESW_PCR0_WT_NWAY_DATA_S) |
+		      (phy_register << RT305X_ESW_PCR0_CPU_PHY_REG_S) |
+		      (phy_addr) | RT305X_ESW_PCR0_WT_PHY_CMD;
+}
+
+static int rt6855a_pcr_done(struct rt305x_esw *esw)
+{
+	return esw_r32(esw, RT305X_ESW_REG_PCR0) & RT305X_ESW_PCR0_WT_DONE;
+}
+
+static int rt305x_pcr_done(struct rt305x_esw *esw)
+{
+	return esw_r32(esw, RT305X_ESW_REG_PCR1) & RT305X_ESW_PCR1_WT_DONE;
+}
+
 static u32 rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr,
 			    u32 phy_register, u32 write_data)
 {
@@ -271,8 +305,7 @@ static u32 rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr,
 	int ret = 0;
 
 	while (1) {
-		if (!(esw_r32(esw, RT305X_ESW_REG_PCR1) &
-		      RT305X_ESW_PCR1_WT_DONE))
+		if (!esw->pcr->pcr_done(esw))
 			break;
 		if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
 			ret = 1;
@@ -281,15 +314,12 @@ static u32 rt305x_mii_write(struct rt305x_esw *esw, u32 phy_addr,
 	}
 
 	write_data &= 0xffff;
-	esw_w32(esw, (write_data << RT305X_ESW_PCR0_WT_NWAY_DATA_S) |
-		      (phy_register << RT305X_ESW_PCR0_CPU_PHY_REG_S) |
-		      (phy_addr) | RT305X_ESW_PCR0_WT_PHY_CMD,
+	esw_w32(esw, esw->pcr->pcr_value(phy_addr, phy_register, write_data),
 		RT305X_ESW_REG_PCR0);
 
 	t_start = jiffies;
 	while (1) {
-		if (esw_r32(esw, RT305X_ESW_REG_PCR1) &
-			    RT305X_ESW_PCR1_WT_DONE)
+		if (!esw->pcr->pcr_done(esw))
 			break;
 
 		if (time_after(jiffies, t_start + RT305X_ESW_PHY_TIMEOUT)) {
@@ -1349,6 +1379,7 @@ static const struct switch_dev_ops esw_ops = {
 static int esw_probe(struct platform_device *pdev)
 {
 	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	const struct of_device_id *match;
 	struct device_node *np = pdev->dev.of_node;
 	const __be32 *port_map, *port_disable, *reg_init;
 	struct switch_dev *swdev;
@@ -1359,6 +1390,9 @@ static int esw_probe(struct platform_device *pdev)
 	if (!esw)
 		return -ENOMEM;
 
+	match = of_match_device(ralink_esw_match, &pdev->dev);
+	esw->pcr = (struct rt305x_pcr *)match->data;
+
 	esw->dev = &pdev->dev;
 	esw->irq = irq_of_parse_and_map(np, 0);
 	esw->base = devm_ioremap_resource(&pdev->dev, res);
@@ -1441,8 +1475,19 @@ static int esw_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static struct rt305x_pcr rt305x_pcr = {
+	.pcr_value = rt305x_pcr_value,
+	.pcr_done = rt305x_pcr_done,
+};
+
+static struct rt305x_pcr rt6855a_pcr = {
+	.pcr_value = rt6855a_pcr_value,
+	.pcr_done = rt6855a_pcr_done,
+};
+
 static const struct of_device_id ralink_esw_match[] = {
-	{ .compatible = "ralink,rt3050-esw" },
+	{ .compatible = "ralink,rt3050-esw", .data = &rt305x_pcr },
+	{ .compatible = "ralink,rt6855a-esw", .data = &rt6855a_pcr },
 	{},
 };
 MODULE_DEVICE_TABLE(of, ralink_esw_match);
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h
index 00f1a0e7e6..19f0dacaa5 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mtk_eth_soc.h
@@ -294,6 +294,7 @@ enum fe_work_flag {
 #define FE_PDMA_SIZE_4DWORDS	(0 << 4)
 #define FE_PDMA_SIZE_8DWORDS	(1 << 4)
 #define FE_PDMA_SIZE_16DWORDS	(2 << 4)
+#define FE_PDMA_SIZE_32DWORDS	(3 << 4)
 
 #define FE_US_CYC_CNT_MASK	0xff
 #define FE_US_CYC_CNT_SHIFT	0x8
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c
index 914b81410e..8051650dbd 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/soc_rt3050.c
@@ -125,6 +125,10 @@ static void rt5350_fe_reset(void)
 	fe_reset(RT305X_RESET_FE | RT305X_RESET_ESW);
 }
 
+static void rt6855a_fe_reset(void)
+{
+}
+
 static struct fe_soc_data rt3050_data = {
 	.init_data = rt305x_init_data,
 	.reset_fe = rt305x_fe_reset,
@@ -149,9 +153,22 @@ static struct fe_soc_data rt5350_data = {
 	.tx_int = RT5350_TX_DONE_INT,
 };
 
+static struct fe_soc_data rt6855a_data = {
+	.init_data = rt5350_init_data,
+	.reg_table = rt5350_reg_table,
+	.reset_fe = rt6855a_fe_reset,
+	.set_mac = rt5350_set_mac,
+	.fwd_config = rt5350_fwd_config,
+	.pdma_glo_cfg = FE_PDMA_SIZE_32DWORDS,
+	.checksum_bit = RX_DMA_L4VALID,
+	.rx_int = RT5350_RX_DONE_INT,
+	.tx_int = RT5350_TX_DONE_INT,
+};
+
 const struct of_device_id of_fe_match[] = {
 	{ .compatible = "ralink,rt3050-eth", .data = &rt3050_data },
 	{ .compatible = "ralink,rt5350-eth", .data = &rt5350_data },
+	{ .compatible = "ralink,rt6855a-eth", .data = &rt6855a_data },
 	{},
 };
 
-- 
2.27.0




More information about the openwrt-devel mailing list