[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1551224265-9304-4-git-send-email-Tristram.Ha@microchip.com>
Date: Tue, 26 Feb 2019 15:37:45 -0800
From: <Tristram.Ha@...rochip.com>
To: Andrew Lunn <andrew@...n.ch>,
Florian Fainelli <f.fainelli@...il.com>,
Pavel Machek <pavel@....cz>
CC: Tristram Ha <Tristram.Ha@...rochip.com>,
<UNGLinuxDriver@...rochip.com>, <netdev@...r.kernel.org>
Subject: [PATCH net-next 3/3] net: dsa: microchip: add other KSZ9477 switch variants
From: Tristram Ha <Tristram.Ha@...rochip.com>
Add other switches in KSZ9477 family.
KSZ9896 is a switch with 6 ports; the last one is typically used to
connect to MAC.
KSZ9567 is same as KSZ9897 but with 1588 PTP capability.
KSZ8567 is same as KSZ9567 but without gigabit capability.
KSZ9563 is same as KSZ9893 but with 1588 PTP capability.
KSZ8563 is same as KSZ9563 but without gigabit capability.
KSZ8565 is a switch with 5 ports; however, port 7 has to be used to
connect to MAC. This chip can only be set through device tree.
Signed-off-by: Tristram Ha <Tristram.Ha@...rochip.com>
---
drivers/net/dsa/microchip/ksz9477.c | 93 ++++++++++++++++++++++++++++++++-
drivers/net/dsa/microchip/ksz9477_spi.c | 3 ++
drivers/net/dsa/microchip/ksz_common.c | 4 ++
3 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/microchip/ksz9477.c b/drivers/net/dsa/microchip/ksz9477.c
index 3bb548a..81e7c2f 100644
--- a/drivers/net/dsa/microchip/ksz9477.c
+++ b/drivers/net/dsa/microchip/ksz9477.c
@@ -1264,6 +1264,32 @@ static void ksz9477_port_setup(struct ksz_device *dev, int port, bool cpu_port)
ksz_pread16(dev, port, REG_PORT_PHY_INT_ENABLE, &data16);
}
+#define KSZ_CHIP_NAME_SIZE 18
+
+static char *ksz9477_chip_names[KSZ_CHIP_NAME_SIZE] = {
+ "Microchip KSZ9477",
+ "Microchip KSZ9897",
+ "Microchip KSZ9896",
+ "Microchip KSZ9567",
+ "Microchip KSZ8567",
+ "Microchip KSZ8565",
+ "Microchip KSZ9893",
+ "Microchip KSZ9563",
+ "Microchip KSZ8563",
+};
+
+enum {
+ KSZ9477_SW_CHIP,
+ KSZ9897_SW_CHIP,
+ KSZ9896_SW_CHIP,
+ KSZ9567_SW_CHIP,
+ KSZ8567_SW_CHIP,
+ KSZ8565_SW_CHIP,
+ KSZ9893_SW_CHIP,
+ KSZ9563_SW_CHIP,
+ KSZ8563_SW_CHIP,
+};
+
static void ksz9477_config_cpu_port(struct dsa_switch *ds)
{
struct ksz_device *dev = ds->priv;
@@ -1314,7 +1340,8 @@ static void ksz9477_config_cpu_port(struct dsa_switch *ds)
p->vid_member = (1 << i);
p->member = dev->port_mask;
ksz9477_port_stp_state_set(ds, i, BR_STATE_DISABLED);
- p->on = 1;
+ if (!dsa_is_unused_port(ds, i))
+ p->on = 1;
if (i < dev->phy_port_cnt)
p->phy = 1;
if (dev->chip_id == 0x00947700 && i == 6) {
@@ -1406,6 +1433,7 @@ static u32 ksz9477_get_port_addr(int port, int offset)
static int ksz9477_switch_detect(struct ksz_device *dev)
{
+ int chip = -1;
u8 data8;
u8 id_hi;
u8 id_lo;
@@ -1448,6 +1476,12 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
dev->features &= ~GBIT_SUPPORT;
dev->mib_port_cnt = 3;
dev->phy_port_cnt = 2;
+ if (!(data8 & SW_AVB_ABLE))
+ chip = KSZ9893_SW_CHIP;
+ else if (data8 & SW_QW_ABLE)
+ chip = KSZ8563_SW_CHIP;
+ else
+ chip = KSZ9563_SW_CHIP;
} else {
/* Chip uses new XMII register definitions. */
dev->features |= NEW_XMII;
@@ -1455,6 +1489,37 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
/* Chip does not support gigabit. */
if (!(data8 & SW_GIGABIT_ABLE))
dev->features &= ~GBIT_SUPPORT;
+ if ((id_lo & 0xf) == 6)
+ dev->mib_port_cnt = 6;
+ if (id_hi == FAMILY_ID_94)
+ chip = KSZ9477_SW_CHIP;
+ else if (id_hi == FAMILY_ID_98 && id_lo == CHIP_ID_97)
+ chip = KSZ9897_SW_CHIP;
+ else if (id_hi == FAMILY_ID_98 && id_lo == CHIP_ID_96)
+ chip = KSZ9896_SW_CHIP;
+ else if (id_hi == FAMILY_ID_95 && id_lo == CHIP_ID_67)
+ chip = KSZ9567_SW_CHIP;
+ else if (id_hi == FAMILY_ID_85 && id_lo == CHIP_ID_67)
+ chip = KSZ8567_SW_CHIP;
+ if (id_lo == CHIP_ID_67) {
+ id_hi = FAMILY_ID_98;
+ id_lo = CHIP_ID_97;
+ } else if (id_lo == CHIP_ID_66) {
+ id_hi = FAMILY_ID_98;
+ id_lo = CHIP_ID_96;
+ }
+ }
+ if (dev->dev->of_node) {
+ char name[80];
+
+ /* KSZ8565 chip can only be set through device tree. */
+ if (!of_modalias_node(dev->dev->of_node, name, sizeof(name))) {
+ if (!strcmp(name, "ksz8565")) {
+ chip = KSZ8565_SW_CHIP;
+ id_hi = FAMILY_ID_98;
+ id_lo = 0x95;
+ }
+ }
}
/* Change chip id to known ones so it can be matched against them. */
@@ -1462,6 +1527,10 @@ static int ksz9477_switch_detect(struct ksz_device *dev)
dev->chip_id = id32;
+ /* Update switch device name to matched chip. */
+ if (chip >= 0)
+ dev->name = ksz9477_chip_names[chip];
+
return 0;
}
@@ -1495,6 +1564,15 @@ struct ksz_chip_data {
.port_cnt = 7, /* total physical port count */
},
{
+ .chip_id = 0x00989600,
+ .dev_name = "KSZ9896",
+ .num_vlans = 4096,
+ .num_alus = 4096,
+ .num_statics = 16,
+ .cpu_ports = 0x3F, /* can be configured as cpu port */
+ .port_cnt = 6, /* total port count */
+ },
+ {
.chip_id = 0x00989300,
.dev_name = "KSZ9893",
.num_vlans = 4096,
@@ -1503,6 +1581,15 @@ struct ksz_chip_data {
.cpu_ports = 0x07, /* can be configured as cpu port */
.port_cnt = 3, /* total port count */
},
+ {
+ .chip_id = 0x00989500,
+ .dev_name = "KSZ8565",
+ .num_vlans = 4096,
+ .num_alus = 4096,
+ .num_statics = 16,
+ .cpu_ports = 0x4F, /* can be configured as cpu port */
+ .port_cnt = 7, /* total port count */
+ },
};
static int ksz9477_switch_init(struct ksz_device *dev)
@@ -1515,7 +1602,8 @@ static int ksz9477_switch_init(struct ksz_device *dev)
const struct ksz_chip_data *chip = &ksz9477_switch_chips[i];
if (dev->chip_id == chip->chip_id) {
- dev->name = chip->dev_name;
+ if (!dev->name)
+ dev->name = chip->dev_name;
dev->num_vlans = chip->num_vlans;
dev->num_alus = chip->num_alus;
dev->num_statics = chip->num_statics;
@@ -1531,6 +1619,7 @@ static int ksz9477_switch_init(struct ksz_device *dev)
return -ENODEV;
dev->port_mask = (1 << dev->port_cnt) - 1;
+ dev->port_mask &= dev->cpu_ports;
dev->reg_mib_cnt = SWITCH_COUNTER_NUM;
dev->mib_cnt = TOTAL_SWITCH_COUNTER_NUM;
diff --git a/drivers/net/dsa/microchip/ksz9477_spi.c b/drivers/net/dsa/microchip/ksz9477_spi.c
index 7517862..878dd64 100644
--- a/drivers/net/dsa/microchip/ksz9477_spi.c
+++ b/drivers/net/dsa/microchip/ksz9477_spi.c
@@ -155,6 +155,9 @@ static void ksz9477_spi_shutdown(struct spi_device *spi)
static const struct of_device_id ksz9477_dt_ids[] = {
{ .compatible = "microchip,ksz9477" },
{ .compatible = "microchip,ksz9897" },
+ { .compatible = "microchip,ksz9896" },
+ { .compatible = "microchip,ksz9567" },
+ { .compatible = "microchip,ksz8565" },
{ .compatible = "microchip,ksz9893" },
{ .compatible = "microchip,ksz9563" },
{},
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 39dace8..826e046 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -84,6 +84,10 @@ static void ksz_mib_read_work(struct work_struct *work)
for (i = 0; i < dev->mib_port_cnt; i++) {
p = &dev->ports[i];
+
+ /* Port is not being used. */
+ if (!p->on)
+ continue;
mib = &p->mib;
mutex_lock(&mib->cnt_mutex);
--
1.9.1
Powered by blists - more mailing lists