aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/realtek/files-5.4/drivers/net/dsa
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/realtek/files-5.4/drivers/net/dsa')
-rw-r--r--target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c73
-rw-r--r--target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c70
-rw-r--r--target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c2
-rw-r--r--target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl931x.c69
4 files changed, 207 insertions, 7 deletions
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c
index d0e5162b66..773225b3c4 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl838x.c
@@ -513,6 +513,79 @@ timeout:
return -ETIMEDOUT;
}
+/*
+ * Read an mmd register of a PHY
+ */
+int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
+{
+ u32 v;
+
+ mutex_lock(&smi_lock);
+
+ if (rtl838x_smi_wait_op(10000))
+ goto timeout;
+
+ sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
+ mdelay(10);
+
+ sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
+
+ v = addr << 16 | reg;
+ sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_3);
+
+ /* mmd-access | read | cmd-start */
+ v = 1 << 1 | 0 << 2 | 1;
+ sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
+
+ if (rtl838x_smi_wait_op(10000))
+ goto timeout;
+
+ *val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
+
+ mutex_unlock(&smi_lock);
+ return 0;
+
+timeout:
+ mutex_unlock(&smi_lock);
+ return -ETIMEDOUT;
+}
+
+/*
+ * Write to an mmd register of a PHY
+ */
+int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
+{
+ u32 v;
+
+ pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val);
+ val &= 0xffff;
+ mutex_lock(&smi_lock);
+
+ if (rtl838x_smi_wait_op(10000))
+ goto timeout;
+
+ sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
+ mdelay(10);
+
+ sw_w32_mask(0xffff0000, val << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
+
+ sw_w32_mask(0x1f << 16, addr << 16, RTL838X_SMI_ACCESS_PHY_CTRL_3);
+ sw_w32_mask(0xffff, reg, RTL838X_SMI_ACCESS_PHY_CTRL_3);
+ /* mmd-access | write | cmd-start */
+ v = 1 << 1 | 1 << 2 | 1;
+ sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
+
+ if (rtl838x_smi_wait_op(10000))
+ goto timeout;
+
+ mutex_unlock(&smi_lock);
+ return 0;
+
+timeout:
+ mutex_unlock(&smi_lock);
+ return -ETIMEDOUT;
+}
+
void rtl8380_get_version(struct rtl838x_switch_priv *priv)
{
u32 rw_save, info_save;
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c
index b9fdd2c955..b2846deb11 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl839x.c
@@ -321,6 +321,7 @@ int rtl8390_sds_power(int mac, int val)
return 0;
}
+
int rtl839x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
{
u32 v;
@@ -358,10 +359,9 @@ int rtl839x_write_phy(u32 port, u32 page, u32 reg, u32 val)
return -ENOTSUPP;
mutex_lock(&smi_lock);
- /* Clear both port registers */
- sw_w32(0, RTL839X_PHYREG_PORT_CTRL(0));
- sw_w32(0, RTL839X_PHYREG_PORT_CTRL(0) + 4);
- sw_w32_mask(0, BIT(port), RTL839X_PHYREG_PORT_CTRL(port));
+
+ // Set PHY to access
+ rtl839x_set_port_reg_le(BIT_ULL(port), RTL839X_PHYREG_PORT_CTRL);
sw_w32_mask(0xffff0000, val << 16, RTL839X_PHYREG_DATA_CTRL);
@@ -383,6 +383,68 @@ int rtl839x_write_phy(u32 port, u32 page, u32 reg, u32 val)
return err;
}
+/*
+ * Read an mmd register of the PHY
+ */
+int rtl839x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val)
+{
+ int err = 0;
+ u32 v;
+
+ mutex_lock(&smi_lock);
+
+ // Set PHY to access
+ sw_w32_mask(0xffff << 16, port << 16, RTL839X_PHYREG_DATA_CTRL);
+
+ // Set MMD device number and register to write to
+ sw_w32(devnum << 16 | (regnum & 0xffff), RTL839X_PHYREG_MMD_CTRL);
+
+ v = BIT(2) | BIT(0); // MMD-access | EXEC
+ sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL);
+
+ do {
+ v = sw_r32(RTL839X_PHYREG_ACCESS_CTRL);
+ } while (v & BIT(0));
+ // There is no error-checking via BIT 1 of v, as it does not seem to be set correctly
+ *val = (sw_r32(RTL839X_PHYREG_DATA_CTRL) & 0xffff);
+ pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, *val, err);
+
+ mutex_unlock(&smi_lock);
+
+ return err;
+}
+
+/*
+ * Write to an mmd register of the PHY
+ */
+int rtl839x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val)
+{
+ int err = 0;
+ u32 v;
+
+ mutex_lock(&smi_lock);
+
+ // Set PHY to access
+ rtl839x_set_port_reg_le(BIT_ULL(port), RTL839X_PHYREG_PORT_CTRL);
+
+ // Set data to write
+ sw_w32_mask(0xffff << 16, val << 16, RTL839X_PHYREG_DATA_CTRL);
+
+ // Set MMD device number and register to write to
+ sw_w32(devnum << 16 | (regnum & 0xffff), RTL839X_PHYREG_MMD_CTRL);
+
+ v = BIT(3) | BIT(2) | BIT(0); // WRITE | MMD-access | EXEC
+ sw_w32(v, RTL839X_PHYREG_ACCESS_CTRL);
+
+ do {
+ v = sw_r32(RTL839X_PHYREG_ACCESS_CTRL);
+ } while (v & BIT(0));
+
+ pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, val, err);
+ mutex_unlock(&smi_lock);
+ return err;
+}
+
void rtl8390_get_version(struct rtl838x_switch_priv *priv)
{
u32 info;
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c
index 6c2fde1040..4214c7694d 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl930x.c
@@ -382,7 +382,6 @@ int rtl9300_sds_power(int mac, int val)
return 0;
}
-
int rtl930x_write_phy(u32 port, u32 page, u32 reg, u32 val)
{
u32 v;
@@ -445,7 +444,6 @@ int rtl930x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
return err;
}
-
/*
* Write to an mmd register of the PHY
*/
diff --git a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl931x.c b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl931x.c
index a33941a0eb..f98bf7df29 100644
--- a/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl931x.c
+++ b/target/linux/realtek/files-5.4/drivers/net/dsa/rtl83xx/rtl931x.c
@@ -175,6 +175,7 @@ static u64 rtl931x_read_cam(int idx, struct rtl838x_l2_entry *e)
// TODO: Implement
return entry;
}
+
irqreturn_t rtl931x_switch_irq(int irq, void *dev_id)
{
struct dsa_switch *ds = dev_id;
@@ -199,7 +200,6 @@ irqreturn_t rtl931x_switch_irq(int irq, void *dev_id)
return IRQ_HANDLED;
}
-
int rtl931x_write_phy(u32 port, u32 page, u32 reg, u32 val)
{
u32 v;
@@ -264,6 +264,73 @@ int rtl931x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
return 0;
}
+/*
+ * Read an mmd register of the PHY
+ */
+int rtl931x_read_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 *val)
+{
+ int err = 0;
+ u32 v;
+ int type = 1; // TODO: For C45 PHYs need to set to 2
+
+ mutex_lock(&smi_lock);
+
+ // Set PHY to access via port-number
+ sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL);
+
+ // Set MMD device number and register to write to
+ sw_w32(devnum << 16 | (regnum & 0xffff), RTL931X_SMI_INDRT_ACCESS_MMD_CTRL);
+
+ v = type << 2 | BIT(0); // MMD-access-type | EXEC
+ sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+
+ do {
+ v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+ } while (v & BIT(0));
+
+ // There is no error-checking via BIT 1 of v, as it does not seem to be set correctly
+
+ *val = (sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_3) & 0xffff);
+
+ pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, *val, err);
+
+ mutex_unlock(&smi_lock);
+
+ return err;
+}
+
+/*
+ * Write to an mmd register of the PHY
+ */
+int rtl931x_write_mmd_phy(u32 port, u32 devnum, u32 regnum, u32 val)
+{
+ int err = 0;
+ u32 v;
+ int type = 1; // TODO: For C45 PHYs need to set to 2
+
+ mutex_lock(&smi_lock);
+
+ // Set PHY to access via port-number
+ sw_w32(port << 5, RTL931X_SMI_INDRT_ACCESS_BC_PHYID_CTRL);
+
+ // Set data to write
+ sw_w32_mask(0xffff << 16, val << 16, RTL931X_SMI_INDRT_ACCESS_CTRL_3);
+
+ // Set MMD device number and register to write to
+ sw_w32(devnum << 16 | (regnum & 0xffff), RTL931X_SMI_INDRT_ACCESS_MMD_CTRL);
+
+ v = BIT(4) | type << 2 | BIT(0); // WRITE | MMD-access-type | EXEC
+ sw_w32(v, RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+
+ do {
+ v = sw_r32(RTL931X_SMI_INDRT_ACCESS_CTRL_0);
+ } while (v & BIT(0));
+
+ pr_debug("%s: port %d, regnum: %x, val: %x (err %d)\n", __func__, port, regnum, val, err);
+ mutex_unlock(&smi_lock);
+ return err;
+}
+
void rtl931x_print_matrix(void)
{
volatile u64 *ptr = RTL838X_SW_BASE + RTL839X_PORT_ISO_CTRL(0);