diff mbox series

[v2,net-next,6/7] net: dsa: add a "tx_fwd_offload" argument to ->port_bridge_join

Message ID 20211204201146.4088103-7-vladimir.oltean@nxp.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series Rework DSA bridge TX forwarding offload API | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 9 this patch: 9
netdev/cc_maintainers warning 5 maintainers not CCed: linux-mediatek@lists.infradead.org olteanv@gmail.com linux-arm-kernel@lists.infradead.org kuba@kernel.org davem@davemloft.net
netdev/build_clang success Errors and warnings before: 29 this patch: 29
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 11 this patch: 11
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 156 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Vladimir Oltean Dec. 4, 2021, 8:11 p.m. UTC
This is a preparation patch for the removal of the DSA switch methods
->port_bridge_tx_fwd_offload() and ->port_bridge_tx_fwd_unoffload().
The plan is for the switch to report whether it offloads TX forwarding
directly as a response to the ->port_bridge_join() method.

This change deals with the noisy portion of converting all existing
function prototypes to take this new boolean pointer argument.
The bool is placed in the cross-chip notifier structure for bridge join,
and a reference to it is provided to drivers. In the next change, DSA
will then actually look at this value instead of calling
->port_bridge_tx_fwd_offload().

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
v1->v2: patch is kind of new, the noisy conversion from v1's patch 6/6
        has been split into a separate change. Had to drop Alvin's
        Reviewed-by tag because he technically did not review the change
        in this form.

 drivers/net/dsa/b53/b53_common.c       | 3 ++-
 drivers/net/dsa/b53/b53_priv.h         | 3 ++-
 drivers/net/dsa/dsa_loop.c             | 3 ++-
 drivers/net/dsa/hirschmann/hellcreek.c | 3 ++-
 drivers/net/dsa/lan9303-core.c         | 3 ++-
 drivers/net/dsa/lantiq_gswip.c         | 3 ++-
 drivers/net/dsa/microchip/ksz_common.c | 3 ++-
 drivers/net/dsa/microchip/ksz_common.h | 2 +-
 drivers/net/dsa/mt7530.c               | 2 +-
 drivers/net/dsa/mv88e6xxx/chip.c       | 3 ++-
 drivers/net/dsa/ocelot/felix.c         | 2 +-
 drivers/net/dsa/qca8k.c                | 3 ++-
 drivers/net/dsa/rtl8366rb.c            | 3 ++-
 drivers/net/dsa/sja1105/sja1105_main.c | 3 ++-
 drivers/net/dsa/xrs700x/xrs700x.c      | 2 +-
 include/net/dsa.h                      | 3 ++-
 net/dsa/dsa_priv.h                     | 1 +
 net/dsa/switch.c                       | 3 ++-
 18 files changed, 31 insertions(+), 17 deletions(-)

Comments

Alvin Šipraga Dec. 6, 2021, 11:01 a.m. UTC | #1
On 12/4/21 21:11, Vladimir Oltean wrote:
> This is a preparation patch for the removal of the DSA switch methods
> ->port_bridge_tx_fwd_offload() and ->port_bridge_tx_fwd_unoffload().
> The plan is for the switch to report whether it offloads TX forwarding
> directly as a response to the ->port_bridge_join() method.
> 
> This change deals with the noisy portion of converting all existing
> function prototypes to take this new boolean pointer argument.
> The bool is placed in the cross-chip notifier structure for bridge join,
> and a reference to it is provided to drivers. In the next change, DSA
> will then actually look at this value instead of calling
> ->port_bridge_tx_fwd_offload().
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---

Reviewed-by: Alvin Šipraga <alsi@bang-olufsen.dk>

> v1->v2: patch is kind of new, the noisy conversion from v1's patch 6/6
>          has been split into a separate change. Had to drop Alvin's
>          Reviewed-by tag because he technically did not review the change
>          in this form.
> 
>   drivers/net/dsa/b53/b53_common.c       | 3 ++-
>   drivers/net/dsa/b53/b53_priv.h         | 3 ++-
>   drivers/net/dsa/dsa_loop.c             | 3 ++-
>   drivers/net/dsa/hirschmann/hellcreek.c | 3 ++-
>   drivers/net/dsa/lan9303-core.c         | 3 ++-
>   drivers/net/dsa/lantiq_gswip.c         | 3 ++-
>   drivers/net/dsa/microchip/ksz_common.c | 3 ++-
>   drivers/net/dsa/microchip/ksz_common.h | 2 +-
>   drivers/net/dsa/mt7530.c               | 2 +-
>   drivers/net/dsa/mv88e6xxx/chip.c       | 3 ++-
>   drivers/net/dsa/ocelot/felix.c         | 2 +-
>   drivers/net/dsa/qca8k.c                | 3 ++-
>   drivers/net/dsa/rtl8366rb.c            | 3 ++-
>   drivers/net/dsa/sja1105/sja1105_main.c | 3 ++-
>   drivers/net/dsa/xrs700x/xrs700x.c      | 2 +-
>   include/net/dsa.h                      | 3 ++-
>   net/dsa/dsa_priv.h                     | 1 +
>   net/dsa/switch.c                       | 3 ++-
>   18 files changed, 31 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
> index 4e41b1a63108..3867f3d4545f 100644
> --- a/drivers/net/dsa/b53/b53_common.c
> +++ b/drivers/net/dsa/b53/b53_common.c
> @@ -1860,7 +1860,8 @@ int b53_mdb_del(struct dsa_switch *ds, int port,
>   }
>   EXPORT_SYMBOL(b53_mdb_del);
>   
> -int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
> +int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
> +		bool *tx_fwd_offload)
>   {
>   	struct b53_device *dev = ds->priv;
>   	s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
> diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
> index ee17f8b516ca..b41dc8ac2ca8 100644
> --- a/drivers/net/dsa/b53/b53_priv.h
> +++ b/drivers/net/dsa/b53/b53_priv.h
> @@ -324,7 +324,8 @@ void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
>   void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
>   int b53_get_sset_count(struct dsa_switch *ds, int port, int sset);
>   void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data);
> -int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
> +int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
> +		bool *tx_fwd_offload);
>   void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
>   void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
>   void b53_br_fast_age(struct dsa_switch *ds, int port);
> diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
> index 70db3a9aa355..33daaf10c488 100644
> --- a/drivers/net/dsa/dsa_loop.c
> +++ b/drivers/net/dsa/dsa_loop.c
> @@ -167,7 +167,8 @@ static int dsa_loop_phy_write(struct dsa_switch *ds, int port,
>   }
>   
>   static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
> -				     struct dsa_bridge bridge)
> +				     struct dsa_bridge bridge,
> +				     bool *tx_fwd_offload)
>   {
>   	dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
>   		__func__, port, bridge.dev->name);
> diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c
> index c8dc83c69147..9eecb7529573 100644
> --- a/drivers/net/dsa/hirschmann/hellcreek.c
> +++ b/drivers/net/dsa/hirschmann/hellcreek.c
> @@ -674,7 +674,8 @@ static int hellcreek_bridge_flags(struct dsa_switch *ds, int port,
>   }
>   
>   static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
> -				      struct dsa_bridge bridge)
> +				      struct dsa_bridge bridge,
> +				      bool *tx_fwd_offload)
>   {
>   	struct hellcreek *hellcreek = ds->priv;
>   
> diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
> index 29d909484275..d55784d19fa4 100644
> --- a/drivers/net/dsa/lan9303-core.c
> +++ b/drivers/net/dsa/lan9303-core.c
> @@ -1103,7 +1103,8 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port)
>   }
>   
>   static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
> -				    struct dsa_bridge bridge)
> +				    struct dsa_bridge bridge,
> +				    bool *tx_fwd_offload)
>   {
>   	struct lan9303 *chip = ds->priv;
>   
> diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
> index 1f59fefc29c1..46ed953e787e 100644
> --- a/drivers/net/dsa/lantiq_gswip.c
> +++ b/drivers/net/dsa/lantiq_gswip.c
> @@ -1146,7 +1146,8 @@ static int gswip_vlan_remove(struct gswip_priv *priv,
>   }
>   
>   static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
> -				  struct dsa_bridge bridge)
> +				  struct dsa_bridge bridge,
> +				  bool *tx_fwd_offload)
>   {
>   	struct net_device *br = bridge.dev;
>   	struct gswip_priv *priv = ds->priv;
> diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
> index 40d6e3f4deb5..47a856533cff 100644
> --- a/drivers/net/dsa/microchip/ksz_common.c
> +++ b/drivers/net/dsa/microchip/ksz_common.c
> @@ -192,7 +192,8 @@ void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf)
>   EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);
>   
>   int ksz_port_bridge_join(struct dsa_switch *ds, int port,
> -			 struct dsa_bridge bridge)
> +			 struct dsa_bridge bridge,
> +			 bool *tx_fwd_offload)
>   {
>   	/* port_stp_state_set() will be called after to put the port in
>   	 * appropriate state so there is no need to do anything.
> diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
> index 88e5a5d56219..df8ae59c8525 100644
> --- a/drivers/net/dsa/microchip/ksz_common.h
> +++ b/drivers/net/dsa/microchip/ksz_common.h
> @@ -155,7 +155,7 @@ void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
>   int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
>   void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
>   int ksz_port_bridge_join(struct dsa_switch *ds, int port,
> -			 struct dsa_bridge bridge);
> +			 struct dsa_bridge bridge, bool *tx_fwd_offload);
>   void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
>   			   struct dsa_bridge bridge);
>   void ksz_port_fast_age(struct dsa_switch *ds, int port);
> diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
> index 85cc5aca7f96..dcd1a3932cfb 100644
> --- a/drivers/net/dsa/mt7530.c
> +++ b/drivers/net/dsa/mt7530.c
> @@ -1186,7 +1186,7 @@ mt7530_port_bridge_flags(struct dsa_switch *ds, int port,
>   
>   static int
>   mt7530_port_bridge_join(struct dsa_switch *ds, int port,
> -			struct dsa_bridge bridge)
> +			struct dsa_bridge bridge, bool *tx_fwd_offload)
>   {
>   	struct mt7530_priv *priv = ds->priv;
>   	u32 port_bitmap = BIT(MT7530_CPU_PORT);
> diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
> index b06ac29a1f7b..c30d1f825776 100644
> --- a/drivers/net/dsa/mv88e6xxx/chip.c
> +++ b/drivers/net/dsa/mv88e6xxx/chip.c
> @@ -2452,7 +2452,8 @@ static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
>   }
>   
>   static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
> -				      struct dsa_bridge bridge)
> +				      struct dsa_bridge bridge,
> +				      bool *tx_fwd_offload)
>   {
>   	struct mv88e6xxx_chip *chip = ds->priv;
>   	int err;
> diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
> index e563bafca74f..f76dcf0d369f 100644
> --- a/drivers/net/dsa/ocelot/felix.c
> +++ b/drivers/net/dsa/ocelot/felix.c
> @@ -706,7 +706,7 @@ static int felix_bridge_flags(struct dsa_switch *ds, int port,
>   }
>   
>   static int felix_bridge_join(struct dsa_switch *ds, int port,
> -			     struct dsa_bridge bridge)
> +			     struct dsa_bridge bridge, bool *tx_fwd_offload)
>   {
>   	struct ocelot *ocelot = ds->priv;
>   
> diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
> index dc983f79f0d6..039694518788 100644
> --- a/drivers/net/dsa/qca8k.c
> +++ b/drivers/net/dsa/qca8k.c
> @@ -1811,7 +1811,8 @@ qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
>   }
>   
>   static int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
> -				  struct dsa_bridge bridge)
> +				  struct dsa_bridge bridge,
> +				  bool *tx_fwd_offload)
>   {
>   	struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
>   	int port_mask, cpu_port;
> diff --git a/drivers/net/dsa/rtl8366rb.c b/drivers/net/dsa/rtl8366rb.c
> index fac2333a3f5e..ecc19bd5115f 100644
> --- a/drivers/net/dsa/rtl8366rb.c
> +++ b/drivers/net/dsa/rtl8366rb.c
> @@ -1186,7 +1186,8 @@ rtl8366rb_port_disable(struct dsa_switch *ds, int port)
>   
>   static int
>   rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port,
> -			   struct dsa_bridge bridge)
> +			   struct dsa_bridge bridge,
> +			   bool *tx_fwd_offload)
>   {
>   	struct realtek_smi *smi = ds->priv;
>   	unsigned int port_bitmap = 0;
> diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
> index 24584fe2e760..21622c60faab 100644
> --- a/drivers/net/dsa/sja1105/sja1105_main.c
> +++ b/drivers/net/dsa/sja1105/sja1105_main.c
> @@ -2074,7 +2074,8 @@ static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
>   }
>   
>   static int sja1105_bridge_join(struct dsa_switch *ds, int port,
> -			       struct dsa_bridge bridge)
> +			       struct dsa_bridge bridge,
> +			       bool *tx_fwd_offload)
>   {
>   	return sja1105_bridge_member(ds, port, bridge, true);
>   }
> diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
> index ebb55dfd9c4e..35fa19ddaf19 100644
> --- a/drivers/net/dsa/xrs700x/xrs700x.c
> +++ b/drivers/net/dsa/xrs700x/xrs700x.c
> @@ -540,7 +540,7 @@ static int xrs700x_bridge_common(struct dsa_switch *ds, int port,
>   }
>   
>   static int xrs700x_bridge_join(struct dsa_switch *ds, int port,
> -			       struct dsa_bridge bridge)
> +			       struct dsa_bridge bridge, bool *tx_fwd_offload)
>   {
>   	return xrs700x_bridge_common(ds, port, bridge, true);
>   }
> diff --git a/include/net/dsa.h b/include/net/dsa.h
> index b9789c0cd5e3..584b3f9462a0 100644
> --- a/include/net/dsa.h
> +++ b/include/net/dsa.h
> @@ -822,7 +822,8 @@ struct dsa_switch_ops {
>   	 */
>   	int	(*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
>   	int	(*port_bridge_join)(struct dsa_switch *ds, int port,
> -				    struct dsa_bridge bridge);
> +				    struct dsa_bridge bridge,
> +				    bool *tx_fwd_offload);
>   	void	(*port_bridge_leave)(struct dsa_switch *ds, int port,
>   				     struct dsa_bridge bridge);
>   	/* Called right after .port_bridge_join() */
> diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
> index da6ff99ba5ed..38ce5129a33d 100644
> --- a/net/dsa/dsa_priv.h
> +++ b/net/dsa/dsa_priv.h
> @@ -56,6 +56,7 @@ struct dsa_notifier_bridge_info {
>   	int tree_index;
>   	int sw_index;
>   	int port;
> +	bool tx_fwd_offload;
>   };
>   
>   /* DSA_NOTIFIER_FDB_* */
> diff --git a/net/dsa/switch.c b/net/dsa/switch.c
> index cd0630dd5417..9c92edd96961 100644
> --- a/net/dsa/switch.c
> +++ b/net/dsa/switch.c
> @@ -95,7 +95,8 @@ static int dsa_switch_bridge_join(struct dsa_switch *ds,
>   		if (!ds->ops->port_bridge_join)
>   			return -EOPNOTSUPP;
>   
> -		err = ds->ops->port_bridge_join(ds, info->port, info->bridge);
> +		err = ds->ops->port_bridge_join(ds, info->port, info->bridge,
> +						&info->tx_fwd_offload);
>   		if (err)
>   			return err;
>   	}
>
diff mbox series

Patch

diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
index 4e41b1a63108..3867f3d4545f 100644
--- a/drivers/net/dsa/b53/b53_common.c
+++ b/drivers/net/dsa/b53/b53_common.c
@@ -1860,7 +1860,8 @@  int b53_mdb_del(struct dsa_switch *ds, int port,
 }
 EXPORT_SYMBOL(b53_mdb_del);
 
-int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge)
+int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
+		bool *tx_fwd_offload)
 {
 	struct b53_device *dev = ds->priv;
 	s8 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
diff --git a/drivers/net/dsa/b53/b53_priv.h b/drivers/net/dsa/b53/b53_priv.h
index ee17f8b516ca..b41dc8ac2ca8 100644
--- a/drivers/net/dsa/b53/b53_priv.h
+++ b/drivers/net/dsa/b53/b53_priv.h
@@ -324,7 +324,8 @@  void b53_get_strings(struct dsa_switch *ds, int port, u32 stringset,
 void b53_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *data);
 int b53_get_sset_count(struct dsa_switch *ds, int port, int sset);
 void b53_get_ethtool_phy_stats(struct dsa_switch *ds, int port, uint64_t *data);
-int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
+int b53_br_join(struct dsa_switch *ds, int port, struct dsa_bridge bridge,
+		bool *tx_fwd_offload);
 void b53_br_leave(struct dsa_switch *ds, int port, struct dsa_bridge bridge);
 void b53_br_set_stp_state(struct dsa_switch *ds, int port, u8 state);
 void b53_br_fast_age(struct dsa_switch *ds, int port);
diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
index 70db3a9aa355..33daaf10c488 100644
--- a/drivers/net/dsa/dsa_loop.c
+++ b/drivers/net/dsa/dsa_loop.c
@@ -167,7 +167,8 @@  static int dsa_loop_phy_write(struct dsa_switch *ds, int port,
 }
 
 static int dsa_loop_port_bridge_join(struct dsa_switch *ds, int port,
-				     struct dsa_bridge bridge)
+				     struct dsa_bridge bridge,
+				     bool *tx_fwd_offload)
 {
 	dev_dbg(ds->dev, "%s: port: %d, bridge: %s\n",
 		__func__, port, bridge.dev->name);
diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c
index c8dc83c69147..9eecb7529573 100644
--- a/drivers/net/dsa/hirschmann/hellcreek.c
+++ b/drivers/net/dsa/hirschmann/hellcreek.c
@@ -674,7 +674,8 @@  static int hellcreek_bridge_flags(struct dsa_switch *ds, int port,
 }
 
 static int hellcreek_port_bridge_join(struct dsa_switch *ds, int port,
-				      struct dsa_bridge bridge)
+				      struct dsa_bridge bridge,
+				      bool *tx_fwd_offload)
 {
 	struct hellcreek *hellcreek = ds->priv;
 
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 29d909484275..d55784d19fa4 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -1103,7 +1103,8 @@  static void lan9303_port_disable(struct dsa_switch *ds, int port)
 }
 
 static int lan9303_port_bridge_join(struct dsa_switch *ds, int port,
-				    struct dsa_bridge bridge)
+				    struct dsa_bridge bridge,
+				    bool *tx_fwd_offload)
 {
 	struct lan9303 *chip = ds->priv;
 
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c
index 1f59fefc29c1..46ed953e787e 100644
--- a/drivers/net/dsa/lantiq_gswip.c
+++ b/drivers/net/dsa/lantiq_gswip.c
@@ -1146,7 +1146,8 @@  static int gswip_vlan_remove(struct gswip_priv *priv,
 }
 
 static int gswip_port_bridge_join(struct dsa_switch *ds, int port,
-				  struct dsa_bridge bridge)
+				  struct dsa_bridge bridge,
+				  bool *tx_fwd_offload)
 {
 	struct net_device *br = bridge.dev;
 	struct gswip_priv *priv = ds->priv;
diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 40d6e3f4deb5..47a856533cff 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -192,7 +192,8 @@  void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf)
 EXPORT_SYMBOL_GPL(ksz_get_ethtool_stats);
 
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
-			 struct dsa_bridge bridge)
+			 struct dsa_bridge bridge,
+			 bool *tx_fwd_offload)
 {
 	/* port_stp_state_set() will be called after to put the port in
 	 * appropriate state so there is no need to do anything.
diff --git a/drivers/net/dsa/microchip/ksz_common.h b/drivers/net/dsa/microchip/ksz_common.h
index 88e5a5d56219..df8ae59c8525 100644
--- a/drivers/net/dsa/microchip/ksz_common.h
+++ b/drivers/net/dsa/microchip/ksz_common.h
@@ -155,7 +155,7 @@  void ksz_mac_link_down(struct dsa_switch *ds, int port, unsigned int mode,
 int ksz_sset_count(struct dsa_switch *ds, int port, int sset);
 void ksz_get_ethtool_stats(struct dsa_switch *ds, int port, uint64_t *buf);
 int ksz_port_bridge_join(struct dsa_switch *ds, int port,
-			 struct dsa_bridge bridge);
+			 struct dsa_bridge bridge, bool *tx_fwd_offload);
 void ksz_port_bridge_leave(struct dsa_switch *ds, int port,
 			   struct dsa_bridge bridge);
 void ksz_port_fast_age(struct dsa_switch *ds, int port);
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 85cc5aca7f96..dcd1a3932cfb 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -1186,7 +1186,7 @@  mt7530_port_bridge_flags(struct dsa_switch *ds, int port,
 
 static int
 mt7530_port_bridge_join(struct dsa_switch *ds, int port,
-			struct dsa_bridge bridge)
+			struct dsa_bridge bridge, bool *tx_fwd_offload)
 {
 	struct mt7530_priv *priv = ds->priv;
 	u32 port_bitmap = BIT(MT7530_CPU_PORT);
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index b06ac29a1f7b..c30d1f825776 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2452,7 +2452,8 @@  static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip,
 }
 
 static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port,
-				      struct dsa_bridge bridge)
+				      struct dsa_bridge bridge,
+				      bool *tx_fwd_offload)
 {
 	struct mv88e6xxx_chip *chip = ds->priv;
 	int err;
diff --git a/drivers/net/dsa/ocelot/felix.c b/drivers/net/dsa/ocelot/felix.c
index e563bafca74f..f76dcf0d369f 100644
--- a/drivers/net/dsa/ocelot/felix.c
+++ b/drivers/net/dsa/ocelot/felix.c
@@ -706,7 +706,7 @@  static int felix_bridge_flags(struct dsa_switch *ds, int port,
 }
 
 static int felix_bridge_join(struct dsa_switch *ds, int port,
-			     struct dsa_bridge bridge)
+			     struct dsa_bridge bridge, bool *tx_fwd_offload)
 {
 	struct ocelot *ocelot = ds->priv;
 
diff --git a/drivers/net/dsa/qca8k.c b/drivers/net/dsa/qca8k.c
index dc983f79f0d6..039694518788 100644
--- a/drivers/net/dsa/qca8k.c
+++ b/drivers/net/dsa/qca8k.c
@@ -1811,7 +1811,8 @@  qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
 }
 
 static int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
-				  struct dsa_bridge bridge)
+				  struct dsa_bridge bridge,
+				  bool *tx_fwd_offload)
 {
 	struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
 	int port_mask, cpu_port;
diff --git a/drivers/net/dsa/rtl8366rb.c b/drivers/net/dsa/rtl8366rb.c
index fac2333a3f5e..ecc19bd5115f 100644
--- a/drivers/net/dsa/rtl8366rb.c
+++ b/drivers/net/dsa/rtl8366rb.c
@@ -1186,7 +1186,8 @@  rtl8366rb_port_disable(struct dsa_switch *ds, int port)
 
 static int
 rtl8366rb_port_bridge_join(struct dsa_switch *ds, int port,
-			   struct dsa_bridge bridge)
+			   struct dsa_bridge bridge,
+			   bool *tx_fwd_offload)
 {
 	struct realtek_smi *smi = ds->priv;
 	unsigned int port_bitmap = 0;
diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c
index 24584fe2e760..21622c60faab 100644
--- a/drivers/net/dsa/sja1105/sja1105_main.c
+++ b/drivers/net/dsa/sja1105/sja1105_main.c
@@ -2074,7 +2074,8 @@  static void sja1105_bridge_stp_state_set(struct dsa_switch *ds, int port,
 }
 
 static int sja1105_bridge_join(struct dsa_switch *ds, int port,
-			       struct dsa_bridge bridge)
+			       struct dsa_bridge bridge,
+			       bool *tx_fwd_offload)
 {
 	return sja1105_bridge_member(ds, port, bridge, true);
 }
diff --git a/drivers/net/dsa/xrs700x/xrs700x.c b/drivers/net/dsa/xrs700x/xrs700x.c
index ebb55dfd9c4e..35fa19ddaf19 100644
--- a/drivers/net/dsa/xrs700x/xrs700x.c
+++ b/drivers/net/dsa/xrs700x/xrs700x.c
@@ -540,7 +540,7 @@  static int xrs700x_bridge_common(struct dsa_switch *ds, int port,
 }
 
 static int xrs700x_bridge_join(struct dsa_switch *ds, int port,
-			       struct dsa_bridge bridge)
+			       struct dsa_bridge bridge, bool *tx_fwd_offload)
 {
 	return xrs700x_bridge_common(ds, port, bridge, true);
 }
diff --git a/include/net/dsa.h b/include/net/dsa.h
index b9789c0cd5e3..584b3f9462a0 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -822,7 +822,8 @@  struct dsa_switch_ops {
 	 */
 	int	(*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
 	int	(*port_bridge_join)(struct dsa_switch *ds, int port,
-				    struct dsa_bridge bridge);
+				    struct dsa_bridge bridge,
+				    bool *tx_fwd_offload);
 	void	(*port_bridge_leave)(struct dsa_switch *ds, int port,
 				     struct dsa_bridge bridge);
 	/* Called right after .port_bridge_join() */
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
index da6ff99ba5ed..38ce5129a33d 100644
--- a/net/dsa/dsa_priv.h
+++ b/net/dsa/dsa_priv.h
@@ -56,6 +56,7 @@  struct dsa_notifier_bridge_info {
 	int tree_index;
 	int sw_index;
 	int port;
+	bool tx_fwd_offload;
 };
 
 /* DSA_NOTIFIER_FDB_* */
diff --git a/net/dsa/switch.c b/net/dsa/switch.c
index cd0630dd5417..9c92edd96961 100644
--- a/net/dsa/switch.c
+++ b/net/dsa/switch.c
@@ -95,7 +95,8 @@  static int dsa_switch_bridge_join(struct dsa_switch *ds,
 		if (!ds->ops->port_bridge_join)
 			return -EOPNOTSUPP;
 
-		err = ds->ops->port_bridge_join(ds, info->port, info->bridge);
+		err = ds->ops->port_bridge_join(ds, info->port, info->bridge,
+						&info->tx_fwd_offload);
 		if (err)
 			return err;
 	}