From 34d57ebd8b1c5674bc59c7ab1f0dd0b3b8a50684 Mon Sep 17 00:00:00 2001
From: John Crispin <john@openwrt.org>
Date: Tue, 25 Sep 2012 14:47:08 +0000
Subject: [PATCH] add ethernet support for rt5350

SVN-Revision: 33548
---
 .../drivers/net/ethernet/ramips/ramips_eth.h  | 54 ++++++++++++++
 .../drivers/net/ethernet/ramips/ramips_main.c | 70 ++++++++++++++-----
 2 files changed, 106 insertions(+), 18 deletions(-)

diff --git a/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_eth.h b/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_eth.h
index 5f40fe1f61..66187030b9 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_eth.h
+++ b/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_eth.h
@@ -54,6 +54,9 @@
 #define RAMIPS_TX_DLY_INT		BIT(1)
 #define RAMIPS_RX_DLY_INT		BIT(0)
 
+#define RT5350_RX_DLY_INT		BIT(30)
+#define RT5350_TX_DLY_INT		BIT(28)
+
 /* registers */
 #define RAMIPS_FE_OFFSET		0x0000
 #define RAMIPS_GDMA_OFFSET		0x0020
@@ -65,6 +68,9 @@
 #define RAMIPS_CMTABLE_OFFSET		0x0400
 #define RAMIPS_POLICYTABLE_OFFSET	0x1000
 
+#define RT5350_PDMA_OFFSET		0x0800
+#define RT5350_SDM_OFFSET		0x0c00
+
 #define RAMIPS_MDIO_ACCESS		(RAMIPS_FE_OFFSET + 0x00)
 #define RAMIPS_MDIO_CFG			(RAMIPS_FE_OFFSET + 0x04)
 #define RAMIPS_FE_GLO_CFG		(RAMIPS_FE_OFFSET + 0x08)
@@ -94,6 +100,38 @@
 #define RAMIPS_CDMA_CSG_CFG		(RAMIPS_CDMA_OFFSET + 0x00)
 #define RAMIPS_CDMA_SCH_CFG		(RAMIPS_CDMA_OFFSET + 0x04)
 
+#define RT5350_TX_BASE_PTR0		(RT5350_PDMA_OFFSET + 0x00)
+#define RT5350_TX_MAX_CNT0		(RT5350_PDMA_OFFSET + 0x04)
+#define RT5350_TX_CTX_IDX0		(RT5350_PDMA_OFFSET + 0x08)
+#define RT5350_TX_DTX_IDX0		(RT5350_PDMA_OFFSET + 0x0C)
+#define RT5350_TX_BASE_PTR1		(RT5350_PDMA_OFFSET + 0x10)
+#define RT5350_TX_MAX_CNT1		(RT5350_PDMA_OFFSET + 0x14)
+#define RT5350_TX_CTX_IDX1		(RT5350_PDMA_OFFSET + 0x18)
+#define RT5350_TX_DTX_IDX1		(RT5350_PDMA_OFFSET + 0x1C)
+#define RT5350_TX_BASE_PTR2		(RT5350_PDMA_OFFSET + 0x20)
+#define RT5350_TX_MAX_CNT2		(RT5350_PDMA_OFFSET + 0x24)
+#define RT5350_TX_CTX_IDX2		(RT5350_PDMA_OFFSET + 0x28)
+#define RT5350_TX_DTX_IDX2		(RT5350_PDMA_OFFSET + 0x2C)
+#define RT5350_TX_BASE_PTR3		(RT5350_PDMA_OFFSET + 0x30)
+#define RT5350_TX_MAX_CNT3		(RT5350_PDMA_OFFSET + 0x34)
+#define RT5350_TX_CTX_IDX3		(RT5350_PDMA_OFFSET + 0x38)
+#define RT5350_TX_DTX_IDX3		(RT5350_PDMA_OFFSET + 0x3C)
+#define RT5350_RX_BASE_PTR0		(RT5350_PDMA_OFFSET + 0x100)
+#define RT5350_RX_MAX_CNT0		(RT5350_PDMA_OFFSET + 0x104)
+#define RT5350_RX_CALC_IDX0		(RT5350_PDMA_OFFSET + 0x108)
+#define RT5350_RX_DRX_IDX0		(RT5350_PDMA_OFFSET + 0x10C)
+#define RT5350_RX_BASE_PTR1		(RT5350_PDMA_OFFSET + 0x110)
+#define RT5350_RX_MAX_CNT1		(RT5350_PDMA_OFFSET + 0x114)
+#define RT5350_RX_CALC_IDX1		(RT5350_PDMA_OFFSET + 0x118)
+#define RT5350_RX_DRX_IDX1		(RT5350_PDMA_OFFSET + 0x11C)
+#define RT5350_PDMA_GLO_CFG		(RT5350_PDMA_OFFSET + 0x204)
+#define RT5350_PDMA_RST_CFG		(RT5350_PDMA_OFFSET + 0x208)
+#define RT5350_DLY_INT_CFG		(RT5350_PDMA_OFFSET + 0x20c)
+#define RT5350_FE_INT_STATUS		(RT5350_PDMA_OFFSET + 0x220)
+#define RT5350_FE_INT_ENABLE		(RT5350_PDMA_OFFSET + 0x228)
+#define RT5350_PDMA_SCH_CFG		(RT5350_PDMA_OFFSET + 0x280)
+
+
 #define RAMIPS_PDMA_GLO_CFG		(RAMIPS_PDMA_OFFSET + 0x00)
 #define RAMIPS_PDMA_RST_CFG		(RAMIPS_PDMA_OFFSET + 0x04)
 #define RAMIPS_PDMA_SCH_CFG		(RAMIPS_PDMA_OFFSET + 0x08)
@@ -123,6 +161,22 @@
 #define RAMIPS_RX_CALC_IDX1		(RAMIPS_PDMA_OFFSET + 0x68)
 #define RAMIPS_RX_DRX_IDX1		(RAMIPS_PDMA_OFFSET + 0x6C)
 
+#define RT5350_SDM_CFG			(RT5350_SDM_OFFSET + 0x00)  //Switch DMA configuration
+#define RT5350_SDM_RRING		(RT5350_SDM_OFFSET + 0x04)  //Switch DMA Rx Ring
+#define RT5350_SDM_TRING		(RT5350_SDM_OFFSET + 0x08)  //Switch DMA Tx Ring
+#define RT5350_SDM_MAC_ADRL		(RT5350_SDM_OFFSET + 0x0C)  //Switch MAC address LSB
+#define RT5350_SDM_MAC_ADRH		(RT5350_SDM_OFFSET + 0x10)  //Switch MAC Address MSB
+#define RT5350_SDM_TPCNT		(RT5350_SDM_OFFSET + 0x100) //Switch DMA Tx packet count
+#define RT5350_SDM_TBCNT		(RT5350_SDM_OFFSET + 0x104) //Switch DMA Tx byte count
+#define RT5350_SDM_RPCNT		(RT5350_SDM_OFFSET + 0x108) //Switch DMA rx packet count
+#define RT5350_SDM_RBCNT		(RT5350_SDM_OFFSET + 0x10C) //Switch DMA rx byte count
+#define RT5350_SDM_CS_ERR		(RT5350_SDM_OFFSET + 0x110) //Switch DMA rx checksum error count
+
+#define RT5350_SDM_ICS_EN		BIT(16)
+#define RT5350_SDM_TCS_EN		BIT(17)
+#define RT5350_SDM_UCS_EN		BIT(18)
+
+
 /* MDIO_CFG register bits */
 #define RAMIPS_MDIO_CFG_AUTO_POLL_EN	BIT(29)
 #define RAMIPS_MDIO_CFG_GP1_BP_EN	BIT(16)
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_main.c b/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_main.c
index 0a9b22a443..f08655383d 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_main.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ramips/ramips_main.c
@@ -33,10 +33,12 @@
 #define	MAX_RX_LENGTH	1600
 
 #ifdef CONFIG_RALINK_RT305X
+#include <rt305x.h>
 #include "ramips_esw.c"
 #else
 static inline int rt305x_esw_init(void) { return 0; }
 static inline void rt305x_esw_exit(void) { }
+static inline int soc_is_rt5350(void) { return 0; }
 #endif
 
 #define phys_to_bus(a)  (a & 0x1FFFFFFF)
@@ -47,6 +49,9 @@ static inline void rt305x_esw_exit(void) { }
 #define RADEBUG(fmt, args...)	do {} while (0)
 #endif
 
+#define RX_DLY_INT ((soc_is_rt5350())?(RT5350_RX_DLY_INT):(RAMIPS_RX_DLY_INT))
+#define TX_DLY_INT ((soc_is_rt5350())?(RT5350_TX_DLY_INT):(RAMIPS_TX_DLY_INT))
+
 enum raeth_reg {
 	RAETH_REG_PDMA_GLO_CFG = 0,
 	RAETH_REG_PDMA_RST_CFG,
@@ -76,6 +81,20 @@ static const u32 ramips_reg_table[RAETH_REG_COUNT] = {
 	[RAETH_REG_FE_INT_STATUS] = RAMIPS_FE_INT_STATUS,
 };
 
+static const u32 rt5350_reg_table[RAETH_REG_COUNT] = {
+	[RAETH_REG_PDMA_GLO_CFG] = RT5350_PDMA_GLO_CFG,
+	[RAETH_REG_PDMA_RST_CFG] = RT5350_PDMA_RST_CFG,
+	[RAETH_REG_DLY_INT_CFG] = RT5350_DLY_INT_CFG,
+	[RAETH_REG_TX_BASE_PTR0] = RT5350_TX_BASE_PTR0,
+	[RAETH_REG_TX_MAX_CNT0] = RT5350_TX_MAX_CNT0,
+	[RAETH_REG_TX_CTX_IDX0] = RT5350_TX_CTX_IDX0,
+	[RAETH_REG_RX_BASE_PTR0] = RT5350_RX_BASE_PTR0,
+	[RAETH_REG_RX_MAX_CNT0] = RT5350_RX_MAX_CNT0,
+	[RAETH_REG_RX_CALC_IDX0] = RT5350_RX_CALC_IDX0,
+	[RAETH_REG_FE_INT_ENABLE] = RT5350_FE_INT_ENABLE,
+	[RAETH_REG_FE_INT_STATUS] = RT5350_FE_INT_STATUS,
+};
+
 static struct net_device * ramips_dev;
 static void __iomem *ramips_fe_base = 0;
 
@@ -83,7 +102,10 @@ static inline u32 get_reg_offset(enum raeth_reg reg)
 {
 	const u32 *table;
 
-	table = ramips_reg_table;
+	if (soc_is_rt5350())
+		table = rt5350_reg_table;
+	else
+		table = ramips_reg_table;
 
 	return table[reg];
 }
@@ -133,9 +155,15 @@ ramips_fe_int_enable(u32 mask)
 static inline void
 ramips_hw_set_macaddr(unsigned char *mac)
 {
-	ramips_fe_wr((mac[0] << 8) | mac[1], RAMIPS_GDMA1_MAC_ADRH);
-	ramips_fe_wr((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
-		     RAMIPS_GDMA1_MAC_ADRL);
+	if (soc_is_rt5350()) {
+		ramips_fe_wr((mac[0] << 8) | mac[1], RT5350_SDM_MAC_ADRH);
+		ramips_fe_wr((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
+			     RT5350_SDM_MAC_ADRL);
+	} else {
+		ramips_fe_wr((mac[0] << 8) | mac[1], RAMIPS_GDMA1_MAC_ADRH);
+		ramips_fe_wr((mac[2] << 24) | (mac[3] << 16) | (mac[4] << 8) | mac[5],
+			     RAMIPS_GDMA1_MAC_ADRL);
+	}
 }
 
 static struct sk_buff *
@@ -825,7 +853,7 @@ ramips_eth_rx_hw(unsigned long ptr)
 	if (max_rx == 0)
 		tasklet_schedule(&re->rx_tasklet);
 	else
-		ramips_fe_int_enable(RAMIPS_RX_DLY_INT);
+		ramips_fe_int_enable(RX_DLY_INT);
 }
 
 static void
@@ -858,7 +886,7 @@ ramips_eth_tx_housekeeping(unsigned long ptr)
 	netdev_completed_queue(dev, pkts_compl, bytes_compl);
 	spin_unlock(&re->page_lock);
 
-	ramips_fe_int_enable(RAMIPS_TX_DLY_INT);
+	ramips_fe_int_enable(TX_DLY_INT);
 }
 
 static void
@@ -883,13 +911,13 @@ ramips_eth_irq(int irq, void *dev)
 
 	ramips_fe_twr(status, RAETH_REG_FE_INT_STATUS);
 
-	if (status & RAMIPS_RX_DLY_INT) {
-		ramips_fe_int_disable(RAMIPS_RX_DLY_INT);
+	if (status & RX_DLY_INT) {
+		ramips_fe_int_disable(RX_DLY_INT);
 		tasklet_schedule(&re->rx_tasklet);
 	}
 
-	if (status & RAMIPS_TX_DLY_INT) {
-		ramips_fe_int_disable(RAMIPS_TX_DLY_INT);
+	if (status & TX_DLY_INT) {
+		ramips_fe_int_disable(TX_DLY_INT);
 		tasklet_schedule(&re->tx_housekeeping_tasklet);
 	}
 
@@ -933,14 +961,20 @@ ramips_eth_open(struct net_device *dev)
 	ramips_phy_start(re);
 
 	ramips_fe_twr(RAMIPS_DELAY_INIT, RAETH_REG_DLY_INT_CFG);
-	ramips_fe_twr(RAMIPS_TX_DLY_INT | RAMIPS_RX_DLY_INT, RAETH_REG_FE_INT_ENABLE);
-	ramips_fe_wr(ramips_fe_rr(RAMIPS_GDMA1_FWD_CFG) &
-		~(RAMIPS_GDM1_ICS_EN | RAMIPS_GDM1_TCS_EN | RAMIPS_GDM1_UCS_EN | 0xffff),
-		RAMIPS_GDMA1_FWD_CFG);
-	ramips_fe_wr(ramips_fe_rr(RAMIPS_CDMA_CSG_CFG) &
-		~(RAMIPS_ICS_GEN_EN | RAMIPS_TCS_GEN_EN | RAMIPS_UCS_GEN_EN),
-		RAMIPS_CDMA_CSG_CFG);
-	ramips_fe_wr(RAMIPS_PSE_FQFC_CFG_INIT, RAMIPS_PSE_FQ_CFG);
+	ramips_fe_twr(TX_DLY_INT | RX_DLY_INT, RAETH_REG_FE_INT_ENABLE);
+	if (soc_is_rt5350()) {
+		ramips_fe_wr(ramips_fe_rr(RT5350_SDM_CFG) &
+			~(RT5350_SDM_ICS_EN | RT5350_SDM_TCS_EN | RT5350_SDM_UCS_EN | 0xffff),
+			RT5350_SDM_CFG);
+	} else {
+		ramips_fe_wr(ramips_fe_rr(RAMIPS_GDMA1_FWD_CFG) &
+			~(RAMIPS_GDM1_ICS_EN | RAMIPS_GDM1_TCS_EN | RAMIPS_GDM1_UCS_EN | 0xffff),
+			RAMIPS_GDMA1_FWD_CFG);
+		ramips_fe_wr(ramips_fe_rr(RAMIPS_CDMA_CSG_CFG) &
+			~(RAMIPS_ICS_GEN_EN | RAMIPS_TCS_GEN_EN | RAMIPS_UCS_GEN_EN),
+			RAMIPS_CDMA_CSG_CFG);
+		ramips_fe_wr(RAMIPS_PSE_FQFC_CFG_INIT, RAMIPS_PSE_FQ_CFG);
+	}
 	ramips_fe_wr(1, RAMIPS_FE_RST_GL);
 	ramips_fe_wr(0, RAMIPS_FE_RST_GL);
 
-- 
2.30.2