[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20210818120150.892647-3-vladimir.oltean@nxp.com>
Date: Wed, 18 Aug 2021 15:01:32 +0300
From: Vladimir Oltean <vladimir.oltean@....com>
To: netdev@...r.kernel.org, Jakub Kicinski <kuba@...nel.org>,
"David S. Miller" <davem@...emloft.net>
Cc: Roopa Prabhu <roopa@...dia.com>,
Nikolay Aleksandrov <nikolay@...dia.com>,
Andrew Lunn <andrew@...n.ch>,
Florian Fainelli <f.fainelli@...il.com>,
Vivien Didelot <vivien.didelot@...il.com>,
Vladimir Oltean <olteanv@...il.com>,
Vadym Kochan <vkochan@...vell.com>,
Taras Chornyi <tchornyi@...vell.com>,
Jiri Pirko <jiri@...dia.com>, Ido Schimmel <idosch@...dia.com>,
UNGLinuxDriver@...rochip.com,
Grygorii Strashko <grygorii.strashko@...com>,
Marek Behun <kabel@...ckhole.sk>,
DENG Qingfang <dqfext@...il.com>,
Kurt Kanzenbach <kurt@...utronix.de>,
Hauke Mehrtens <hauke@...ke-m.de>,
Woojung Huh <woojung.huh@...rochip.com>,
Sean Wang <sean.wang@...iatek.com>,
Landen Chao <Landen.Chao@...iatek.com>,
Claudiu Manoil <claudiu.manoil@....com>,
Alexandre Belloni <alexandre.belloni@...tlin.com>,
George McCollister <george.mccollister@...il.com>,
Ioana Ciornei <ioana.ciornei@....com>,
Saeed Mahameed <saeedm@...dia.com>,
Leon Romanovsky <leon@...nel.org>,
Lars Povlsen <lars.povlsen@...rochip.com>,
Steen Hegelund <Steen.Hegelund@...rochip.com>,
Julian Wiedmann <jwi@...ux.ibm.com>,
Karsten Graul <kgraul@...ux.ibm.com>,
Heiko Carstens <hca@...ux.ibm.com>,
Vasily Gorbik <gor@...ux.ibm.com>,
Christian Borntraeger <borntraeger@...ibm.com>,
Ivan Vecera <ivecera@...hat.com>,
Vlad Buslov <vladbu@...dia.com>,
Jianbo Liu <jianbol@...dia.com>,
Mark Bloch <mbloch@...dia.com>, Roi Dayan <roid@...dia.com>,
Tobias Waldekranz <tobias@...dekranz.com>,
Vignesh Raghavendra <vigneshr@...com>,
Jesse Brandeburg <jesse.brandeburg@...el.com>,
Peter Ujfalusi <peter.ujfalusi@...com>
Subject: [RFC PATCH net-next 02/20] net: dsa: assign a bridge number even without TX forwarding offload
The service where DSA assigns a unique bridge number for each forwarding
domain is useful even for drivers which do not implement the TX
forwarding offload feature.
For example, drivers might use the dp->bridge_num for FDB isolation.
So rename ds->num_fwd_offloading_bridges to ds->max_num_bridges, and
calculate a unique bridge_num for all drivers that set this value.
Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 4 +-
drivers/net/dsa/sja1105/sja1105_main.c | 2 +-
include/net/dsa.h | 10 ++--
net/dsa/port.c | 81 ++++++++++++++++++--------
4 files changed, 65 insertions(+), 32 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index c45ca2473743..32fd657a325a 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3090,8 +3090,8 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
* time.
*/
if (mv88e6xxx_has_pvt(chip))
- ds->num_fwd_offloading_bridges = MV88E6XXX_MAX_PVT_SWITCHES -
- ds->dst->last_switch - 1;
+ ds->max_num_bridges = MV88E6XXX_MAX_PVT_SWITCHES -
+ ds->dst->last_switch - 1;
mv88e6xxx_reg_lock(chip);
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 05ba65042b5f..715557c20cb5 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -3055,7 +3055,7 @@ static int sja1105_setup(struct dsa_switch *ds)
ds->vlan_filtering_is_global = true;
ds->untag_bridge_pvid = true;
/* tag_8021q has 3 bits for the VBID, and the value 0 is reserved */
- ds->num_fwd_offloading_bridges = 7;
+ ds->max_num_bridges = 7;
/* Advertise the 8 egress queues */
ds->num_tx_queues = SJA1105_NUM_TC;
diff --git a/include/net/dsa.h b/include/net/dsa.h
index c7ea0f61056f..62820bd1d00d 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -407,12 +407,12 @@ struct dsa_switch {
*/
unsigned int num_lag_ids;
- /* Drivers that support bridge forwarding offload should set this to
- * the maximum number of bridges spanning the same switch tree (or all
- * trees, in the case of cross-tree bridging support) that can be
- * offloaded.
+ /* Drivers that support bridge forwarding offload or FDB isolation
+ * should set this to the maximum number of bridges spanning the same
+ * switch tree (or all trees, in the case of cross-tree bridging
+ * support) that can be offloaded.
*/
- unsigned int num_fwd_offloading_bridges;
+ unsigned int max_num_bridges;
size_t num_ports;
};
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 4fbe81ffb1ce..605c6890e53b 100644
--- a/net/dsa/port.c
+++ b/net/dsa/port.c
@@ -271,19 +271,15 @@ static void dsa_port_switchdev_unsync_attrs(struct dsa_port *dp)
}
static void dsa_port_bridge_tx_fwd_unoffload(struct dsa_port *dp,
- struct net_device *bridge_dev)
+ struct net_device *bridge_dev,
+ int bridge_num)
{
- int bridge_num = dp->bridge_num;
struct dsa_switch *ds = dp->ds;
/* No bridge TX forwarding offload => do nothing */
- if (!ds->ops->port_bridge_tx_fwd_unoffload || dp->bridge_num == -1)
+ if (!ds->ops->port_bridge_tx_fwd_unoffload || bridge_num == -1)
return;
- dp->bridge_num = -1;
-
- dsa_bridge_num_put(bridge_dev, bridge_num);
-
/* Notify the chips only once the offload has been deactivated, so
* that they can update their configuration accordingly.
*/
@@ -292,32 +288,65 @@ static void dsa_port_bridge_tx_fwd_unoffload(struct dsa_port *dp,
}
static bool dsa_port_bridge_tx_fwd_offload(struct dsa_port *dp,
- struct net_device *bridge_dev)
+ struct net_device *bridge_dev,
+ int bridge_num)
{
struct dsa_switch *ds = dp->ds;
- int bridge_num, err;
-
- if (!ds->ops->port_bridge_tx_fwd_offload)
- return false;
+ int err;
- bridge_num = dsa_bridge_num_get(bridge_dev,
- ds->num_fwd_offloading_bridges);
- if (bridge_num < 0)
+ /* FDB isolation is required for TX forwarding offload */
+ if (!ds->ops->port_bridge_tx_fwd_offload || bridge_num == -1)
return false;
- dp->bridge_num = bridge_num;
-
/* Notify the driver */
err = ds->ops->port_bridge_tx_fwd_offload(ds, dp->index, bridge_dev,
bridge_num);
- if (err) {
- dsa_port_bridge_tx_fwd_unoffload(dp, bridge_dev);
+ if (err)
return false;
- }
return true;
}
+static int dsa_port_assign_bridge(struct dsa_port *dp,
+ struct net_device *br,
+ struct netlink_ext_ack *extack)
+{
+ struct dsa_switch *ds = dp->ds;
+ int bridge_num;
+
+ dp->bridge_dev = br;
+
+ if (!ds->max_num_bridges)
+ return 0;
+
+ bridge_num = dsa_bridge_num_get(br, ds->max_num_bridges);
+
+ if (bridge_num < 0) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Range of offloadable bridges exceeded");
+ return -EOPNOTSUPP;
+ }
+
+ dp->bridge_num = bridge_num;
+
+ return 0;
+}
+
+static void dsa_port_unassign_bridge(struct dsa_port *dp,
+ const struct net_device *br)
+{
+ struct dsa_switch *ds = dp->ds;
+
+ dp->bridge_dev = NULL;
+
+ if (ds->max_num_bridges) {
+ int bridge_num = dp->bridge_num;
+
+ dp->bridge_num = -1;
+ dsa_bridge_num_put(br, bridge_num);
+ }
+}
+
int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
struct netlink_ext_ack *extack)
{
@@ -335,7 +364,9 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
/* Here the interface is already bridged. Reflect the current
* configuration so that drivers can program their chips accordingly.
*/
- dp->bridge_dev = br;
+ err = dsa_port_assign_bridge(dp, br, extack);
+ if (err)
+ return err;
brport_dev = dsa_port_to_bridge_port(dp);
@@ -343,7 +374,8 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
if (err)
goto out_rollback;
- tx_fwd_offload = dsa_port_bridge_tx_fwd_offload(dp, br);
+ tx_fwd_offload = dsa_port_bridge_tx_fwd_offload(dp, br,
+ dp->bridge_num);
err = switchdev_bridge_port_offload(brport_dev, dev, dp,
&dsa_slave_switchdev_notifier,
@@ -386,14 +418,15 @@ void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br)
.port = dp->index,
.br = br,
};
+ int bridge_num = dp->bridge_num;
int err;
/* Here the port is already unbridged. Reflect the current configuration
* so that drivers can program their chips accordingly.
*/
- dp->bridge_dev = NULL;
+ dsa_port_unassign_bridge(dp, br);
- dsa_port_bridge_tx_fwd_unoffload(dp, br);
+ dsa_port_bridge_tx_fwd_unoffload(dp, br, bridge_num);
err = dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info);
if (err)
--
2.25.1
Powered by blists - more mailing lists