From: Vladimir Oltean <vladimir.oltean@nxp.com>
To: netdev@vger.kernel.org
Cc: "Florian Fainelli" <f.fainelli@gmail.com>,
"Andrew Lunn" <andrew@lunn.ch>,
"Vivien Didelot" <vivien.didelot@gmail.com>,
"Tobias Waldekranz" <tobias@waldekranz.com>,
"DENG Qingfang" <dqfext@gmail.com>,
"Alvin Šipraga" <alsi@bang-olufsen.dk>,
"Kurt Kanzenbach" <kurt@linutronix.de>,
"Hauke Mehrtens" <hauke@hauke-m.de>,
"Woojung Huh" <woojung.huh@microchip.com>,
UNGLinuxDriver@microchip.com,
"Sean Wang" <sean.wang@mediatek.com>,
"Landen Chao" <Landen.Chao@mediatek.com>,
"Matthias Brugger" <matthias.bgg@gmail.com>,
"Claudiu Manoil" <claudiu.manoil@nxp.com>,
"Alexandre Belloni" <alexandre.belloni@bootlin.com>,
"Linus Walleij" <linus.walleij@linaro.org>,
"George McCollister" <george.mccollister@gmail.com>
Subject: [PATCH v2 net-next 2/7] net: dsa: assign a bridge number even without TX forwarding offload
Date: Sat, 4 Dec 2021 22:11:41 +0200 [thread overview]
Message-ID: <20211204201146.4088103-3-vladimir.oltean@nxp.com> (raw)
In-Reply-To: <20211204201146.4088103-1-vladimir.oltean@nxp.com>
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@nxp.com>
Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>
---
v1->v2: update the comment in dsa_bridge_num_get() about bridge_num's
new role as per Alvin's suggestion
drivers/net/dsa/mv88e6xxx/chip.c | 4 +-
drivers/net/dsa/sja1105/sja1105_main.c | 2 +-
include/net/dsa.h | 10 ++--
net/dsa/dsa2.c | 4 +-
net/dsa/port.c | 81 +++++++++++++++++---------
5 files changed, 66 insertions(+), 35 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index de3401b2c86c..a818df35b239 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3186,8 +3186,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 c343effe2e96..355b56cf94d8 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -3139,7 +3139,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 a23cfbaa09d6..00fbd87ae4ff 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -413,12 +413,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/dsa2.c b/net/dsa/dsa2.c
index 9606e56710a5..4901cdc264ee 100644
--- a/net/dsa/dsa2.c
+++ b/net/dsa/dsa2.c
@@ -152,7 +152,9 @@ unsigned int dsa_bridge_num_get(const struct net_device *bridge_dev, int max)
unsigned int bridge_num = dsa_bridge_num_find(bridge_dev);
if (!bridge_num) {
- /* First port that offloads TX forwarding for this bridge */
+ /* First port that requests FDB isolation or TX forwarding
+ * offload for this bridge
+ */
bridge_num = find_next_zero_bit(&dsa_fwd_offloading_bridges,
DSA_MAX_NUM_OFFLOADING_BRIDGES,
1);
diff --git a/net/dsa/port.c b/net/dsa/port.c
index 9a77bd1373e2..199a56faf460 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,
+ unsigned int bridge_num)
{
- unsigned 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)
+ if (!ds->ops->port_bridge_tx_fwd_unoffload || !bridge_num)
return;
- dp->bridge_num = 0;
-
- 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,31 +288,60 @@ 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,
+ unsigned int bridge_num)
{
struct dsa_switch *ds = dp->ds;
- unsigned int bridge_num;
int err;
- if (!ds->ops->port_bridge_tx_fwd_offload)
- return false;
-
- bridge_num = dsa_bridge_num_get(bridge_dev,
- ds->num_fwd_offloading_bridges);
- if (!bridge_num)
+ /* FDB isolation is required for TX forwarding offload */
+ if (!ds->ops->port_bridge_tx_fwd_offload || !bridge_num)
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);
- return false;
+
+ return err ? false : true;
+}
+
+static int dsa_port_bridge_create(struct dsa_port *dp,
+ struct net_device *br,
+ struct netlink_ext_ack *extack)
+{
+ struct dsa_switch *ds = dp->ds;
+ unsigned 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) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Range of offloadable bridges exceeded");
+ return -EOPNOTSUPP;
}
- return true;
+ dp->bridge_num = bridge_num;
+
+ return 0;
+}
+
+static void dsa_port_bridge_destroy(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 = 0;
+ dsa_bridge_num_put(br, bridge_num);
+ }
}
int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
@@ -336,7 +361,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_bridge_create(dp, br, extack);
+ if (err)
+ return err;
brport_dev = dsa_port_to_bridge_port(dp);
@@ -344,7 +371,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,
@@ -366,7 +394,7 @@ int dsa_port_bridge_join(struct dsa_port *dp, struct net_device *br,
out_rollback_unbridge:
dsa_broadcast(DSA_NOTIFIER_BRIDGE_LEAVE, &info);
out_rollback:
- dp->bridge_dev = NULL;
+ dsa_port_bridge_destroy(dp, br);
return err;
}
@@ -393,14 +421,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_bridge_destroy(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
next prev parent reply other threads:[~2021-12-04 20:12 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-04 20:11 [PATCH v2 net-next 0/7] Rework DSA bridge TX forwarding offload API Vladimir Oltean
2021-12-04 20:11 ` [PATCH v2 net-next 1/7] net: dsa: make dp->bridge_num one-based Vladimir Oltean
2021-12-04 20:11 ` Vladimir Oltean [this message]
2021-12-04 20:11 ` [PATCH v2 net-next 3/7] net: dsa: hide dp->bridge_dev and dp->bridge_num behind helpers Vladimir Oltean
2021-12-04 23:27 ` Vladimir Oltean
2021-12-04 20:11 ` [PATCH v2 net-next 4/7] net: dsa: rename dsa_port_offloads_bridge to dsa_port_offloads_bridge_dev Vladimir Oltean
2021-12-04 20:11 ` [PATCH v2 net-next 5/7] net: dsa: keep the bridge_dev and bridge_num as part of the same structure Vladimir Oltean
2021-12-04 23:18 ` Vladimir Oltean
2021-12-04 20:11 ` [PATCH v2 net-next 6/7] net: dsa: add a "tx_fwd_offload" argument to ->port_bridge_join Vladimir Oltean
2021-12-06 11:01 ` Alvin Šipraga
2021-12-04 20:11 ` [PATCH v2 net-next 7/7] net: dsa: eliminate dsa_switch_ops :: port_bridge_tx_fwd_{,un}offload Vladimir Oltean
2021-12-06 11:01 ` Alvin Šipraga
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=20211204201146.4088103-3-vladimir.oltean@nxp.com \
--to=vladimir.oltean@nxp.com \
--cc=Landen.Chao@mediatek.com \
--cc=UNGLinuxDriver@microchip.com \
--cc=alexandre.belloni@bootlin.com \
--cc=alsi@bang-olufsen.dk \
--cc=andrew@lunn.ch \
--cc=claudiu.manoil@nxp.com \
--cc=dqfext@gmail.com \
--cc=f.fainelli@gmail.com \
--cc=george.mccollister@gmail.com \
--cc=hauke@hauke-m.de \
--cc=kurt@linutronix.de \
--cc=linus.walleij@linaro.org \
--cc=matthias.bgg@gmail.com \
--cc=netdev@vger.kernel.org \
--cc=sean.wang@mediatek.com \
--cc=tobias@waldekranz.com \
--cc=vivien.didelot@gmail.com \
--cc=woojung.huh@microchip.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