kernel: rtl8367b: supports rtl8367s

This commit is contained in:
Liangbin Lian 2023-12-25 18:03:37 +08:00
parent ade96808c6
commit 8bae91ed3c
2 changed files with 347 additions and 0 deletions

View File

@ -0,0 +1,262 @@
From 106c3d7fed20e51433779e94e5a73e7716f3401e Mon Sep 17 00:00:00 2001
From: Serge Vasilugin <vasilugin@yandex.ru>
Date: Thu, 15 Aug 2019 15:28:28 +0700
Subject: [PATCH] rtl8367b: initial support for rtl8367s
From driver point of view no differance between rtl8367b and rtl8367s
if it connected through EXT2 (rgmii only).
So this trivial patch add some identification and initialization only.
SGMII/HSGMII mode for EXT1 is not implemented for the sake of patch
clairity.
Signed-off-by: Serge Vasilugin <vasilugin@yandex.ru>
[Fix code format]
Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
[add flags to separate chip_num/chip_id detection; drop error print in
rtl8367b_init_regs, drop unnecessary info prints, code style fixes]
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
[rebase; use MII macros]
Signed-off-by: Gaspare Bruno <gaspare@anlix.io>
---
drivers/net/phy/rtl8366_smi.h | 1 +
drivers/net/phy/rtl8367b.c | 126 ++++++++++++++++++++++++++--------
2 files changed, 97 insertions(+), 30 deletions(-)
diff --git a/drivers/net/phy/rtl8366_smi.h b/drivers/net/phy/rtl8366_smi.h
index d1d988a37..fb57d8ba6 100644
--- a/drivers/net/phy/rtl8366_smi.h
+++ b/drivers/net/phy/rtl8366_smi.h
@@ -64,6 +64,7 @@ struct rtl8366_smi {
u8 dbg_vlan_4k_page;
#endif
struct mii_bus *ext_mbus;
+ u32 flags;
};
struct rtl8366_vlan_mc {
diff --git a/drivers/net/phy/rtl8367b.c b/drivers/net/phy/rtl8367b.c
index 3599791a5..6df6a62d4 100644
--- a/drivers/net/phy/rtl8367b.c
+++ b/drivers/net/phy/rtl8367b.c
@@ -16,6 +16,7 @@
#include <linux/of_platform.h>
#include <linux/delay.h>
#include <linux/skbuff.h>
+#include <linux/mii.h>
#include <linux/rtl8367.h>
#include "rtl8366_smi.h"
@@ -234,6 +235,7 @@
#define RTL8367B_CPU_PORT_NUM 5
#define RTL8367B_NUM_PORTS 8
+#define RTL8367B_NUM_PHYS 5
#define RTL8367B_NUM_VLANS 32
#define RTL8367B_NUM_VIDS 4096
#define RTL8367B_PRIORITYMAX 7
@@ -258,6 +260,8 @@
RTL8367B_PORT_3 | RTL8367B_PORT_4 | RTL8367B_PORT_E1 | \
RTL8367B_PORT_E2)
+#define RTL8367B_FLAG_MATCH_CHIP_NUM BIT(0)
+
struct rtl8367b_initval {
u16 reg;
u16 val;
@@ -605,6 +609,20 @@ static const struct rtl8367b_initval rtl8367r_vb_initvals_1[] = {
{0x133E, 0x000E}, {0x133F, 0x0010},
};
+static const struct rtl8367b_initval rtl8367c_initvals[] = {
+ {0x13c2, 0x0000}, {0x0018, 0x0f00}, {0x0038, 0x0f00}, {0x0058, 0x0f00},
+ {0x0078, 0x0f00}, {0x0098, 0x0f00}, {0x1d15, 0x0a69}, {0x2000, 0x1340},
+ {0x2020, 0x1340}, {0x2040, 0x1340}, {0x2060, 0x1340}, {0x2080, 0x1340},
+ {0x13eb, 0x15bb}, {0x1303, 0x06d6}, {0x1304, 0x0700}, {0x13E2, 0x003F},
+ {0x13F9, 0x0090}, {0x121e, 0x03CA}, {0x1233, 0x0352}, {0x1237, 0x00a0},
+ {0x123a, 0x0030}, {0x1239, 0x0084}, {0x0301, 0x1000}, {0x1349, 0x001F},
+ {0x18e0, 0x4004}, {0x122b, 0x641c}, {0x1305, 0xc000}, {0x1200, 0x7fcb},
+ {0x0884, 0x0003}, {0x06eb, 0x0001}, {0x00cf, 0xffff}, {0x00d0, 0x0007},
+ {0x00ce, 0x48b0}, {0x00ce, 0x48b0}, {0x0398, 0xffff}, {0x0399, 0x0007},
+ {0x0300, 0x0001}, {0x03fa, 0x0007}, {0x08c8, 0x00c0}, {0x0a30, 0x020e},
+ {0x0800, 0x0000}, {0x0802, 0x0000}, {0x09da, 0x0017}, {0x1d32, 0x0002},
+};
+
static int rtl8367b_write_initvals(struct rtl8366_smi *smi,
const struct rtl8367b_initval *initvals,
int count)
@@ -716,33 +734,46 @@ static int rtl8367b_write_phy_reg(struct rtl8366_smi *smi,
static int rtl8367b_init_regs(struct rtl8366_smi *smi)
{
const struct rtl8367b_initval *initvals;
+ u32 chip_num;
u32 chip_ver;
u32 rlvid;
int count;
int err;
REG_WR(smi, RTL8367B_RTL_MAGIC_ID_REG, RTL8367B_RTL_MAGIC_ID_VAL);
+ REG_RD(smi, RTL8367B_CHIP_NUMBER_REG, &chip_num);
REG_RD(smi, RTL8367B_CHIP_VER_REG, &chip_ver);
rlvid = (chip_ver >> RTL8367B_CHIP_VER_RLVID_SHIFT) &
RTL8367B_CHIP_VER_RLVID_MASK;
- switch (rlvid) {
- case 0:
- initvals = rtl8367r_vb_initvals_0;
- count = ARRAY_SIZE(rtl8367r_vb_initvals_0);
- break;
+ if (smi->flags & RTL8367B_FLAG_MATCH_CHIP_NUM) {
+ switch (chip_num) {
+ case 0x0276:
+ case 0x0597:
+ case 0x6367:
+ initvals = rtl8367c_initvals;
+ count = ARRAY_SIZE(rtl8367c_initvals);
+ break;
+ default:
+ return -ENODEV;
+ }
+ } else {
+ switch (rlvid) {
+ case 0:
+ initvals = rtl8367r_vb_initvals_0;
+ count = ARRAY_SIZE(rtl8367r_vb_initvals_0);
+ break;
- case 1:
- initvals = rtl8367r_vb_initvals_1;
- count = ARRAY_SIZE(rtl8367r_vb_initvals_1);
- break;
+ case 1:
+ initvals = rtl8367r_vb_initvals_1;
+ count = ARRAY_SIZE(rtl8367r_vb_initvals_1);
+ break;
- default:
- dev_err(smi->parent, "unknow rlvid %u\n", rlvid);
- return -ENODEV;
+ default:
+ return -ENODEV;
+ }
}
-
/* TODO: disable RLTP */
return rtl8367b_write_initvals(smi, initvals, count);
@@ -1021,6 +1052,16 @@ static int rtl8367b_setup(struct rtl8366_smi *smi)
RTL8367B_PORT_MISC_CFG_EGRESS_MODE_ORIGINAL <<
RTL8367B_PORT_MISC_CFG_EGRESS_MODE_SHIFT);
+ for (i = 0; i < RTL8367B_NUM_PHYS; i++) {
+ int data;
+ rtl8367b_read_phy_reg(smi, i, MII_BMCR, &data);
+ /* release phy power down */
+ data &= ~BMCR_PDOWN;
+ /* restart auto negotiation */
+ data |= BMCR_ANRESTART;
+ rtl8367b_write_phy_reg(smi, i, MII_BMCR, data);
+ }
+
return 0;
}
@@ -1509,7 +1550,7 @@ static int rtl8367b_mii_write(struct mii_bus *bus, int addr, int reg, u16 val)
static int rtl8367b_detect(struct rtl8366_smi *smi)
{
- const char *chip_name;
+ const char *chip_name = NULL;
u32 chip_num;
u32 chip_ver;
u32 chip_mode;
@@ -1540,14 +1581,26 @@ static int rtl8367b_detect(struct rtl8366_smi *smi)
return ret;
}
- switch (chip_ver) {
- case 0x1000:
- chip_name = "8367RB";
- break;
- case 0x1010:
- chip_name = "8367R-VB";
- break;
- default:
+ if (smi->flags & RTL8367B_FLAG_MATCH_CHIP_NUM) {
+ switch (chip_num) {
+ case 0x0276:
+ case 0x0597:
+ case 0x6367:
+ chip_name = "8367C";
+ break;
+ }
+ } else {
+ switch (chip_ver) {
+ case 0x1000:
+ chip_name = "8367RB";
+ break;
+ case 0x1010:
+ chip_name = "8367R-VB";
+ break;
+ }
+ }
+
+ if (!chip_name) {
dev_err(smi->parent,
"unknown chip num:%04x ver:%04x, mode:%04x\n",
chip_num, chip_ver, chip_mode);
@@ -1580,8 +1633,23 @@ static struct rtl8366_smi_ops rtl8367b_smi_ops = {
.enable_port = rtl8367b_enable_port,
};
+#ifdef CONFIG_OF
+static const struct of_device_id rtl8367b_match[] = {
+ { .compatible = "realtek,rtl8367b" },
+ {
+ .compatible = "realtek,rtl8367c",
+ .data = (void *)RTL8367B_FLAG_MATCH_CHIP_NUM,
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rtl8367b_match);
+#endif
+
static int rtl8367b_probe(struct platform_device *pdev)
{
+#ifdef CONFIG_OF
+ const struct of_device_id *match;
+#endif
struct rtl8366_smi *smi;
int err;
@@ -1589,6 +1657,12 @@ static int rtl8367b_probe(struct platform_device *pdev)
if (IS_ERR(smi))
return PTR_ERR(smi);
+#ifdef CONFIG_OF
+ match = of_match_device(rtl8367b_match, &pdev->dev);
+ if (match)
+ smi->flags = (u32)match->data;
+#endif
+
smi->clk_delay = 1500;
smi->cmd_read = 0xb9;
smi->cmd_write = 0xb8;
@@ -1643,14 +1717,6 @@ static void rtl8367b_shutdown(struct platform_device *pdev)
rtl8367b_reset_chip(smi);
}
-#ifdef CONFIG_OF
-static const struct of_device_id rtl8367b_match[] = {
- { .compatible = "realtek,rtl8367b" },
- {},
-};
-MODULE_DEVICE_TABLE(of, rtl8367b_match);
-#endif
-
static struct platform_driver rtl8367b_driver = {
.driver = {
.name = RTL8367B_DRIVER_NAME,
--
2.31.0

View File

@ -0,0 +1,85 @@
From 4198270768b18e30505423af14b6c2c075873e22 Mon Sep 17 00:00:00 2001
From: Serge Vasilugin <vasilugin@yandex.ru>
Date: Thu, 15 Aug 2019 15:27:08 +0700
Subject: [PATCH] kernel: rtl8366_smi: explicitly set phy addr for switch
By default rtl8366_smi use phy addr 0 at mii-bus to access switch registers.
This patch allow to set it explicitly in dts-file:
rtl8367 {
compatible = "realtek,rtl8367b";
phy-id = <29>; /* switch address at mii-bus */
realtek,extif2 = <1 0 1 1 1 1 1 1 2>;
mii-bus = <&mdio>;
cpu_port = <7>;
}
Use default 0 address if not set.
Backward compatibility tested on tplink archer c2 v1 (rtl8367rb switch)
Signed-off-by: Serge Vasilugin <vasilugin@yandex.ru>
[code style fixes, add explicit phy_id assignment in probe_plat, use
phy-id instead of phy_id for of property name]
Signed-off-by: Chuanhong Guo <gch981213@gmail.com>
[rebase]
Signed-off-by: Gaspare Bruno <gaspare@anlix.io>
---
drivers/net/phy/rtl8366_smi.c | 8 ++++++--
drivers/net/phy/rtl8366_smi.h | 1 +
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/phy/rtl8366_smi.c b/drivers/net/phy/rtl8366_smi.c
index 4fda16a4f..66d98b499 100644
--- a/drivers/net/phy/rtl8366_smi.c
+++ b/drivers/net/phy/rtl8366_smi.c
@@ -256,7 +256,7 @@ static int __rtl8366_smi_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
int __rtl8366_mdio_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
{
- u32 phy_id = MDC_REALTEK_PHY_ADDR;
+ u32 phy_id = smi->phy_id;
struct mii_bus *mbus = smi->ext_mbus;
BUG_ON(in_interrupt());
@@ -293,7 +293,7 @@ int __rtl8366_mdio_read_reg(struct rtl8366_smi *smi, u32 addr, u32 *data)
static int __rtl8366_mdio_write_reg(struct rtl8366_smi *smi, u32 addr, u32 data)
{
- u32 phy_id = MDC_REALTEK_PHY_ADDR;
+ u32 phy_id = smi->phy_id;
struct mii_bus *mbus = smi->ext_mbus;
BUG_ON(in_interrupt());
@@ -1540,6 +1540,9 @@ int rtl8366_smi_probe_of(struct platform_device *pdev, struct rtl8366_smi *smi)
goto try_gpio;
}
+ if (of_property_read_u32(np, "phy-id", &smi->phy_id))
+ smi->phy_id = MDC_REALTEK_PHY_ADDR;
+
return 0;
try_gpio:
@@ -1579,6 +1582,7 @@ int rtl8366_smi_probe_plat(struct platform_device *pdev, struct rtl8366_smi *smi
smi->gpio_sda = pdata->gpio_sda;
smi->gpio_sck = pdata->gpio_sck;
smi->hw_reset = pdata->hw_reset;
+ smi->phy_id = MDC_REALTEK_PHY_ADDR;
return 0;
}
diff --git a/drivers/net/phy/rtl8366_smi.h b/drivers/net/phy/rtl8366_smi.h
index fb57d8ba6..92b40414d 100644
--- a/drivers/net/phy/rtl8366_smi.h
+++ b/drivers/net/phy/rtl8366_smi.h
@@ -64,6 +64,7 @@ struct rtl8366_smi {
u8 dbg_vlan_4k_page;
#endif
struct mii_bus *ext_mbus;
+ u32 phy_id;
u32 flags;
};
--
2.31.0