[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