#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
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;
{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)
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);
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, 0, &data);
+ /* release phy power down */
+ data &= ~BIT(11);
+ /* restart auto negotiation */
+ data |= BIT(9);
+ rtl8367b_write_phy_reg(smi, i, 0, data);
+ }
+
return 0;
}
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;
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);
.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;
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;
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,