netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: <Tristram.Ha@microchip.com>
To: Andrew Lunn <andrew@lunn.ch>,
	Florian Fainelli <f.fainelli@gmail.com>,
	Pavel Machek <pavel@ucw.cz>
Cc: Tristram Ha <Tristram.Ha@microchip.com>,
	<UNGLinuxDriver@microchip.com>, <netdev@vger.kernel.org>
Subject: [PATCH net-next 3/3] net: dsa: microchip: add other KSZ9477 switch variants
Date: Tue, 26 Feb 2019 15:37:45 -0800	[thread overview]
Message-ID: <1551224265-9304-4-git-send-email-Tristram.Ha@microchip.com> (raw)
In-Reply-To: <1551224265-9304-1-git-send-email-Tristram.Ha@microchip.com>

From: Tristram Ha <Tristram.Ha@microchip.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@microchip.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


  parent reply	other threads:[~2019-02-26 23:37 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-26 23:37 [PATCH net-next 0/3] net: dsa: microchip: add KSZ9893 switch support Tristram.Ha
2019-02-26 23:37 ` [PATCH net-next 1/3] dt-bindings: net: dsa: document additional Microchip KSZ9477 family switches Tristram.Ha
2019-02-27 12:41   ` Andrew Lunn
2019-02-26 23:37 ` [PATCH net-next 2/3] net: dsa: microchip: add KSZ9893 switch support Tristram.Ha
2019-02-27 13:14   ` Andrew Lunn
2019-02-26 23:37 ` Tristram.Ha [this message]
2019-02-27  6:47   ` [PATCH net-next 3/3] net: dsa: microchip: add other KSZ9477 switch variants kbuild test robot
2019-02-27 13:23   ` Andrew Lunn
2019-02-27 13:33   ` Andrew Lunn

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1551224265-9304-4-git-send-email-Tristram.Ha@microchip.com \
    --to=tristram.ha@microchip.com \
    --cc=UNGLinuxDriver@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=f.fainelli@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=pavel@ucw.cz \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).