netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Florian Fainelli <f.fainelli@gmail.com>
To: netdev@vger.kernel.org
Cc: andrew@lunn.ch, vivien.didelot@savoirfairelinux.com,
	jiri@resnulli.us, idosch@mellanox.com, Woojung.Huh@microchip.com,
	john@phrozen.org, sean.wang@mediatek.com,
	Florian Fainelli <f.fainelli@gmail.com>
Subject: [RFC net-next 3/5] net: dsa: b53: Add support for LAG
Date: Sun,  1 Oct 2017 12:46:37 -0700	[thread overview]
Message-ID: <20171001194639.8647-4-f.fainelli@gmail.com> (raw)
In-Reply-To: <20171001194639.8647-1-f.fainelli@gmail.com>

Add support for LAG in the b53 driver by implementing the port_lag_join,
port_lag_leave and port_lag_member operations. port_lag_change is not supported
since the HW does not let us change anyting regarding tx_enabled or not.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/net/dsa/b53/b53_common.c | 94 +++++++++++++++++++++++++++++++++++++++-
 drivers/net/dsa/b53/b53_priv.h   |  6 +++
 2 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index d4ce092def83..e9903947f050 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1603,6 +1603,58 @@ int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e)
 }
 EXPORT_SYMBOL(b53_set_mac_eee);
 
+bool b53_lag_member(struct dsa_switch *ds, int port, u8 lag_id)
+{
+	struct b53_device *dev = ds->priv;
+	u16 reg;
+
+	b53_read16(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_GROUP(lag_id), &reg);
+
+	return !!(BIT(port) & reg);
+}
+EXPORT_SYMBOL(b53_lag_member);
+
+int b53_lag_join(struct dsa_switch *ds, int port, u8 lag_id)
+{
+	struct b53_device *dev = ds->priv;
+	u8 trunk_ctl;
+	u16 lag;
+
+	/* Program this port and the CPU port in this trunking group */
+	b53_read16(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_GROUP(lag_id), &lag);
+	lag |= BIT(port);
+	b53_write16(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_GROUP(lag_id), lag);
+
+	/* Enable MAC DA,SA hashing, enable trunking */
+	b53_read8(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_CTRL, &trunk_ctl);
+	trunk_ctl &= ~TRK_HASH_IDX_MASK;
+	trunk_ctl |= MAC_BASE_TRNK_EN;
+	b53_write8(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_CTRL, trunk_ctl);
+
+	return 0;
+}
+EXPORT_SYMBOL(b53_lag_join);
+
+void b53_lag_leave(struct dsa_switch *ds, int port, u8 lag_id, bool lag_disable)
+{
+	struct b53_device *dev = ds->priv;
+	u8 trunk_ctl;
+	u16 lag;
+
+	/* Remove this port from the trunking group */
+	b53_read16(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_GROUP(lag_id), &lag);
+	lag &= ~BIT(port);
+	b53_write16(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_GROUP(lag_id), lag);
+
+	/* Disable trunking if the lag group is being removed */
+	if (lag_disable) {
+		b53_read8(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_CTRL, &trunk_ctl);
+		trunk_ctl &= ~(TRK_HASH_IDX_MASK | MAC_BASE_TRNK_EN);
+		b53_write8(dev, B53_TRUNK_PAGE, B53_MAC_TRUNK_CTRL, trunk_ctl);
+	}
+}
+EXPORT_SYMBOL(b53_lag_leave);
+
 static const struct dsa_switch_ops b53_switch_ops = {
 	.get_tag_protocol	= b53_get_tag_protocol,
 	.setup			= b53_setup,
@@ -1629,6 +1681,9 @@ static const struct dsa_switch_ops b53_switch_ops = {
 	.port_fdb_del		= b53_fdb_del,
 	.port_mirror_add	= b53_mirror_add,
 	.port_mirror_del	= b53_mirror_del,
+	.port_lag_member	= b53_lag_member,
+	.port_lag_join		= b53_lag_join,
+	.port_lag_leave		= b53_lag_leave,
 };
 
 struct b53_chip_data {
@@ -1642,6 +1697,8 @@ struct b53_chip_data {
 	u8 duplex_reg;
 	u8 jumbo_pm_reg;
 	u8 jumbo_size_reg;
+	unsigned int num_lags;
+	unsigned int max_lag_members;
 };
 
 #define B53_VTA_REGS	\
@@ -1681,6 +1738,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM5397_DEVICE_ID,
@@ -1693,6 +1752,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM5398_DEVICE_ID,
@@ -1705,6 +1766,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53115_DEVICE_ID,
@@ -1717,6 +1780,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53125_DEVICE_ID,
@@ -1729,6 +1794,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53128_DEVICE_ID,
@@ -1741,6 +1808,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM63XX_DEVICE_ID,
@@ -1753,6 +1822,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_63XX,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53010_DEVICE_ID,
@@ -1765,6 +1836,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53011_DEVICE_ID,
@@ -1777,6 +1850,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53012_DEVICE_ID,
@@ -1789,6 +1864,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53018_DEVICE_ID,
@@ -1801,6 +1878,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM53019_DEVICE_ID,
@@ -1813,6 +1892,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM58XX_DEVICE_ID,
@@ -1825,6 +1906,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM7445_DEVICE_ID,
@@ -1837,6 +1920,8 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 	{
 		.chip_id = BCM7278_DEVICE_ID,
@@ -1849,11 +1934,14 @@ static const struct b53_chip_data b53_switch_chips[] = {
 		.duplex_reg = B53_DUPLEX_STAT_GE,
 		.jumbo_pm_reg = B53_JUMBO_PORT_MASK,
 		.jumbo_size_reg = B53_JUMBO_MAX_SIZE,
+		.num_lags = 2,
+		.max_lag_members = 4,
 	},
 };
 
 static int b53_switch_init(struct b53_device *dev)
 {
+	struct dsa_switch *ds = dev->ds;
 	unsigned int i;
 	int ret;
 
@@ -1872,6 +1960,8 @@ static int b53_switch_init(struct b53_device *dev)
 			dev->cpu_port = chip->cpu_port;
 			dev->num_vlans = chip->vlans;
 			dev->num_arl_entries = chip->arl_entries;
+			dev->num_lags = chip->num_lags;
+			dev->max_lag_members = chip->max_lag_members;
 			break;
 		}
 	}
@@ -1933,7 +2023,9 @@ static int b53_switch_init(struct b53_device *dev)
 			return ret;
 	}
 
-	return 0;
+	ds->max_lag_members = dev->max_lag_members;
+
+	return dsa_switch_alloc_lags(ds, dev->num_lags);
 }
 
 struct b53_device *b53_switch_alloc(struct device *base,
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index 603c66d240d8..0f48184c9b54 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -118,6 +118,9 @@ struct b53_device {
 	struct b53_vlan *vlans;
 	unsigned int num_ports;
 	struct b53_port *ports;
+
+	unsigned int num_lags;
+	unsigned int max_lag_members;
 };
 
 #define b53_for_each_port(dev, i) \
@@ -318,5 +321,8 @@ void b53_eee_enable_set(struct dsa_switch *ds, int port, bool enable);
 int b53_eee_init(struct dsa_switch *ds, int port, struct phy_device *phy);
 int b53_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
 int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
+bool b53_lag_member(struct dsa_switch *ds, int port, u8 lag_id);
+int b53_lag_join(struct dsa_switch *ds, int port, u8 lag_id);
+void b53_lag_leave(struct dsa_switch *ds, int port, u8 lag_id, bool lag_disable);
 
 #endif
-- 
2.11.0

  parent reply	other threads:[~2017-10-01 19:46 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-01 19:46 [RFC net-next 0/5] net: dsa: LAG support Florian Fainelli
2017-10-01 19:46 ` [RFC net-next 1/5] net: dsa: Add infrastructure to support LAG Florian Fainelli
2017-10-02  2:03   ` Andrew Lunn
2017-10-02  7:05     ` Ido Schimmel
2017-10-02 18:19     ` Florian Fainelli
2017-10-01 19:46 ` [RFC net-next 2/5] net: dsa: b53: Define MAC trunking/bonding registers Florian Fainelli
2017-10-01 19:46 ` Florian Fainelli [this message]
2017-10-01 19:46 ` [RFC net-next 4/5] net: dsa: bcm_sf2: Add support for LAG Florian Fainelli
2017-10-01 19:46 ` [RFC net-next 5/5] net: dsa: loop: " Florian Fainelli
2017-10-02  6:50 ` [RFC net-next 0/5] net: dsa: LAG support Ido Schimmel
2017-10-02 12:59   ` Andrew Lunn
2017-10-02 13:05     ` Ido Schimmel
2017-10-02 12:51 ` 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=20171001194639.8647-4-f.fainelli@gmail.com \
    --to=f.fainelli@gmail.com \
    --cc=Woojung.Huh@microchip.com \
    --cc=andrew@lunn.ch \
    --cc=idosch@mellanox.com \
    --cc=jiri@resnulli.us \
    --cc=john@phrozen.org \
    --cc=netdev@vger.kernel.org \
    --cc=sean.wang@mediatek.com \
    --cc=vivien.didelot@savoirfairelinux.com \
    /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).