[net-next,2/3] net: dsa: qca8k: make learning configurable and keep off if standalone
Commit Message
Address learning should initially be turned off by the driver for port
operation in standalone mode, then the DSA core handles changes to it
via ds->ops->port_bridge_flags().
Currently this is not the case for qca8k where learning is enabled
unconditionally in qca8k_setup for every user port.
Handle ports configured in standalone mode by making the learning
configurable and not enabling it by default.
Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
enable learning for bridge that request it and tweak
.port_stp_state_set to correctly disable learning when port is
configured in standalone mode.
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
---
drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++--
drivers/net/dsa/qca/qca8k-common.c | 44 ++++++++++++++++++++++++++++++
drivers/net/dsa/qca/qca8k.h | 6 ++++
3 files changed, 54 insertions(+), 3 deletions(-)
Comments
On Mon, Jul 24, 2023 at 05:30:57AM +0200, Christian Marangi wrote:
> Address learning should initially be turned off by the driver for port
> operation in standalone mode, then the DSA core handles changes to it
> via ds->ops->port_bridge_flags().
>
> Currently this is not the case for qca8k where learning is enabled
> unconditionally in qca8k_setup for every user port.
>
> Handle ports configured in standalone mode by making the learning
> configurable and not enabling it by default.
>
> Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
> enable learning for bridge that request it and tweak
> .port_stp_state_set to correctly disable learning when port is
> configured in standalone mode.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
...
> @@ -1978,6 +1977,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
> .port_change_mtu = qca8k_port_change_mtu,
> .port_max_mtu = qca8k_port_max_mtu,
> .port_stp_state_set = qca8k_port_stp_state_set,
> + .port_pre_bridge_flags = qca8k_port_pre_bridge_flags,
> + .port_bridge_flags = qca8k_port_bridge_flags,
> .port_bridge_join = qca8k_port_bridge_join,
> .port_bridge_leave = qca8k_port_bridge_leave,
> .port_fast_age = qca8k_port_fast_age,
> diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
...
> @@ -591,6 +611,30 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
>
> qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
> QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
> +
> + qca8k_port_configure_learning(ds, port, learning);
> +}
> +
> +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
> + struct switchdev_brport_flags flags,
> + struct netlink_ext_ack *extack)
> +{
> + if (flags.mask & ~BR_LEARNING)
> + return -EINVAL;
If I am reading things right then some implementation of this callback
return -EINVAL when they see unexpected flags. And some seem not to
- possibly because all flags are expected.
So I'm slightly unsure if this is correct or not.
> +
> + return 0;
> +}
...
On Mon, Jul 24, 2023 at 05:30:57AM +0200, Christian Marangi wrote:
> Address learning should initially be turned off by the driver for port
> operation in standalone mode, then the DSA core handles changes to it
> via ds->ops->port_bridge_flags().
>
> Currently this is not the case for qca8k where learning is enabled
> unconditionally in qca8k_setup for every user port.
>
> Handle ports configured in standalone mode by making the learning
> configurable and not enabling it by default.
>
> Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
> enable learning for bridge that request it and tweak
> .port_stp_state_set to correctly disable learning when port is
> configured in standalone mode.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
Small nitpick below.
> drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++--
> drivers/net/dsa/qca/qca8k-common.c | 44 ++++++++++++++++++++++++++++++
> drivers/net/dsa/qca/qca8k.h | 6 ++++
> 3 files changed, 54 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
> index ae088a4df794..31552853fdd4 100644
> --- a/drivers/net/dsa/qca/qca8k-8xxx.c
> +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
> @@ -1870,9 +1870,8 @@ qca8k_setup(struct dsa_switch *ds)
> if (ret)
> return ret;
>
> - /* Enable ARP Auto-learning by default */
> - ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
> - QCA8K_PORT_LOOKUP_LEARN);
> + ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
> + QCA8K_PORT_LOOKUP_LEARN);
> if (ret)
> return ret;
>
> @@ -1978,6 +1977,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
> .port_change_mtu = qca8k_port_change_mtu,
> .port_max_mtu = qca8k_port_max_mtu,
> .port_stp_state_set = qca8k_port_stp_state_set,
> + .port_pre_bridge_flags = qca8k_port_pre_bridge_flags,
> + .port_bridge_flags = qca8k_port_bridge_flags,
> .port_bridge_join = qca8k_port_bridge_join,
> .port_bridge_leave = qca8k_port_bridge_leave,
> .port_fast_age = qca8k_port_fast_age,
> diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
> index 13b8452ce5b2..e53694d2852a 100644
> --- a/drivers/net/dsa/qca/qca8k-common.c
> +++ b/drivers/net/dsa/qca/qca8k-common.c
> @@ -565,9 +565,26 @@ int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
> return 0;
> }
>
> +static int qca8k_port_configure_learning(struct dsa_switch *ds, int port,
> + bool learning)
> +{
> + struct qca8k_priv *priv = ds->priv;
> +
> + if (learning)
> + return regmap_set_bits(priv->regmap,
> + QCA8K_PORT_LOOKUP_CTRL(port),
> + QCA8K_PORT_LOOKUP_LEARN);
> + else
> + return regmap_clear_bits(priv->regmap,
> + QCA8K_PORT_LOOKUP_CTRL(port),
> + QCA8K_PORT_LOOKUP_LEARN);
> +}
> +
> void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
> {
> + struct dsa_port *dp = dsa_to_port(ds, port);
> struct qca8k_priv *priv = ds->priv;
> + bool learning = false;
> u32 stp_state;
>
> switch (state) {
> @@ -582,8 +599,11 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
> break;
> case BR_STATE_LEARNING:
> stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
> + learning = dp->learning;
> break;
> case BR_STATE_FORWARDING:
> + learning = dp->learning;
> + fallthrough;
> default:
> stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
> break;
> @@ -591,6 +611,30 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
>
> qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
> QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
> +
> + qca8k_port_configure_learning(ds, port, learning);
> +}
> +
> +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
> + struct switchdev_brport_flags flags,
> + struct netlink_ext_ack *extack)
> +{
> + if (flags.mask & ~BR_LEARNING)
> + return -EINVAL;
> +
> + return 0;
> +}
> +
> +int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
> + struct switchdev_brport_flags flags,
> + struct netlink_ext_ack *extack)
> +{
> + int ret;
> +
> + ret = qca8k_port_configure_learning(ds, port,
> + flags.val & BR_LEARNING);
> +
> + return ret;
I worry that the way in this is formulated will attract patches from
kernel janitors to simplify it to:
return qca8k_port_configure_learning(...)
I agree that it's not strictly necessary to check flags.mask when
port_pre_bridge_flags supports a single flag, but if you did that and
structured the code for more future flags, you could avoid that.
int ret;
if (flags.mask & BR_LEARNING) {
ret = qca8k_port_configure_learning(...,
flags.val & BR_LEARNING);
if (ret)
return ret;
}
return 0;
Anyway, probably not a big deal.
> }
>
> int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
> diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
> index c5cc8a172d65..8f88b7db384d 100644
> --- a/drivers/net/dsa/qca/qca8k.h
> +++ b/drivers/net/dsa/qca/qca8k.h
> @@ -522,6 +522,12 @@ int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
>
> /* Common bridge function */
> void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
> +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
> + struct switchdev_brport_flags flags,
> + struct netlink_ext_ack *extack);
> +int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
> + struct switchdev_brport_flags flags,
> + struct netlink_ext_ack *extack);
> int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
> struct dsa_bridge bridge,
> bool *tx_fwd_offload,
> --
> 2.40.1
>
On Wed, Jul 26, 2023 at 10:19:34AM +0200, Simon Horman wrote:
> > +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
> > + struct switchdev_brport_flags flags,
> > + struct netlink_ext_ack *extack)
> > +{
> > + if (flags.mask & ~BR_LEARNING)
> > + return -EINVAL;
>
> If I am reading things right then some implementation of this callback
> return -EINVAL when they see unexpected flags. And some seem not to
> - possibly because all flags are expected.
>
> So I'm slightly unsure if this is correct or not.
Which ones don't? All handlers of SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS
should return -EINVAL for changes made to bridge port flags that aren't
supported.
On Wed, Jul 26, 2023 at 03:14:35PM +0300, Vladimir Oltean wrote:
> On Wed, Jul 26, 2023 at 10:19:34AM +0200, Simon Horman wrote:
> > > +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
> > > + struct switchdev_brport_flags flags,
> > > + struct netlink_ext_ack *extack)
> > > +{
> > > + if (flags.mask & ~BR_LEARNING)
> > > + return -EINVAL;
> >
> > If I am reading things right then some implementation of this callback
> > return -EINVAL when they see unexpected flags. And some seem not to
> > - possibly because all flags are expected.
> >
> > So I'm slightly unsure if this is correct or not.
>
> Which ones don't? All handlers of SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS
> should return -EINVAL for changes made to bridge port flags that aren't
> supported.
Sorry, on a second look I see that my statement above is incorrect.
I do wonder what it was I saw this morning. But this afternoon
I see that all users check flags and return -EINVAL as appropriate.
On 7/23/23 20:30, Christian Marangi wrote:
> Address learning should initially be turned off by the driver for port
> operation in standalone mode, then the DSA core handles changes to it
> via ds->ops->port_bridge_flags().
>
> Currently this is not the case for qca8k where learning is enabled
> unconditionally in qca8k_setup for every user port.
>
> Handle ports configured in standalone mode by making the learning
> configurable and not enabling it by default.
>
> Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
> enable learning for bridge that request it and tweak
> .port_stp_state_set to correctly disable learning when port is
> configured in standalone mode.
>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
With the feedback from Vladimir being addressed:
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
On Wed, Jul 26, 2023 at 03:12:13PM +0300, Vladimir Oltean wrote:
> On Mon, Jul 24, 2023 at 05:30:57AM +0200, Christian Marangi wrote:
> > Address learning should initially be turned off by the driver for port
> > operation in standalone mode, then the DSA core handles changes to it
> > via ds->ops->port_bridge_flags().
> >
> > Currently this is not the case for qca8k where learning is enabled
> > unconditionally in qca8k_setup for every user port.
> >
> > Handle ports configured in standalone mode by making the learning
> > configurable and not enabling it by default.
> >
> > Implement .port_pre_bridge_flags and .port_bridge_flags dsa ops to
> > enable learning for bridge that request it and tweak
> > .port_stp_state_set to correctly disable learning when port is
> > configured in standalone mode.
> >
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
>
> Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
>
> Small nitpick below.
>
> > drivers/net/dsa/qca/qca8k-8xxx.c | 7 +++--
> > drivers/net/dsa/qca/qca8k-common.c | 44 ++++++++++++++++++++++++++++++
> > drivers/net/dsa/qca/qca8k.h | 6 ++++
> > 3 files changed, 54 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/net/dsa/qca/qca8k-8xxx.c b/drivers/net/dsa/qca/qca8k-8xxx.c
> > index ae088a4df794..31552853fdd4 100644
> > --- a/drivers/net/dsa/qca/qca8k-8xxx.c
> > +++ b/drivers/net/dsa/qca/qca8k-8xxx.c
> > @@ -1870,9 +1870,8 @@ qca8k_setup(struct dsa_switch *ds)
> > if (ret)
> > return ret;
> >
> > - /* Enable ARP Auto-learning by default */
> > - ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
> > - QCA8K_PORT_LOOKUP_LEARN);
> > + ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
> > + QCA8K_PORT_LOOKUP_LEARN);
> > if (ret)
> > return ret;
> >
> > @@ -1978,6 +1977,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
> > .port_change_mtu = qca8k_port_change_mtu,
> > .port_max_mtu = qca8k_port_max_mtu,
> > .port_stp_state_set = qca8k_port_stp_state_set,
> > + .port_pre_bridge_flags = qca8k_port_pre_bridge_flags,
> > + .port_bridge_flags = qca8k_port_bridge_flags,
> > .port_bridge_join = qca8k_port_bridge_join,
> > .port_bridge_leave = qca8k_port_bridge_leave,
> > .port_fast_age = qca8k_port_fast_age,
> > diff --git a/drivers/net/dsa/qca/qca8k-common.c b/drivers/net/dsa/qca/qca8k-common.c
> > index 13b8452ce5b2..e53694d2852a 100644
> > --- a/drivers/net/dsa/qca/qca8k-common.c
> > +++ b/drivers/net/dsa/qca/qca8k-common.c
> > @@ -565,9 +565,26 @@ int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
> > return 0;
> > }
> >
> > +static int qca8k_port_configure_learning(struct dsa_switch *ds, int port,
> > + bool learning)
> > +{
> > + struct qca8k_priv *priv = ds->priv;
> > +
> > + if (learning)
> > + return regmap_set_bits(priv->regmap,
> > + QCA8K_PORT_LOOKUP_CTRL(port),
> > + QCA8K_PORT_LOOKUP_LEARN);
> > + else
> > + return regmap_clear_bits(priv->regmap,
> > + QCA8K_PORT_LOOKUP_CTRL(port),
> > + QCA8K_PORT_LOOKUP_LEARN);
> > +}
> > +
> > void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
> > {
> > + struct dsa_port *dp = dsa_to_port(ds, port);
> > struct qca8k_priv *priv = ds->priv;
> > + bool learning = false;
> > u32 stp_state;
> >
> > switch (state) {
> > @@ -582,8 +599,11 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
> > break;
> > case BR_STATE_LEARNING:
> > stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
> > + learning = dp->learning;
> > break;
> > case BR_STATE_FORWARDING:
> > + learning = dp->learning;
> > + fallthrough;
> > default:
> > stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
> > break;
> > @@ -591,6 +611,30 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
> >
> > qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
> > QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
> > +
> > + qca8k_port_configure_learning(ds, port, learning);
> > +}
> > +
> > +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
> > + struct switchdev_brport_flags flags,
> > + struct netlink_ext_ack *extack)
> > +{
> > + if (flags.mask & ~BR_LEARNING)
> > + return -EINVAL;
> > +
> > + return 0;
> > +}
> > +
> > +int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
> > + struct switchdev_brport_flags flags,
> > + struct netlink_ext_ack *extack)
> > +{
> > + int ret;
> > +
> > + ret = qca8k_port_configure_learning(ds, port,
> > + flags.val & BR_LEARNING);
> > +
> > + return ret;
>
> I worry that the way in this is formulated will attract patches from
> kernel janitors to simplify it to:
>
> return qca8k_port_configure_learning(...)
>
> I agree that it's not strictly necessary to check flags.mask when
> port_pre_bridge_flags supports a single flag, but if you did that and
> structured the code for more future flags, you could avoid that.
>
> int ret;
>
> if (flags.mask & BR_LEARNING) {
> ret = qca8k_port_configure_learning(...,
> flags.val & BR_LEARNING);
> if (ret)
> return ret;
> }
>
> return 0;
>
> Anyway, probably not a big deal.
>
> > }
I hope and expect to send fbd isolation later with FLOOD flags so I will
send v2 of this with the suggested format.
> >
> > int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
> > diff --git a/drivers/net/dsa/qca/qca8k.h b/drivers/net/dsa/qca/qca8k.h
> > index c5cc8a172d65..8f88b7db384d 100644
> > --- a/drivers/net/dsa/qca/qca8k.h
> > +++ b/drivers/net/dsa/qca/qca8k.h
> > @@ -522,6 +522,12 @@ int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
> >
> > /* Common bridge function */
> > void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
> > +int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
> > + struct switchdev_brport_flags flags,
> > + struct netlink_ext_ack *extack);
> > +int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
> > + struct switchdev_brport_flags flags,
> > + struct netlink_ext_ack *extack);
> > int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
> > struct dsa_bridge bridge,
> > bool *tx_fwd_offload,
> > --
> > 2.40.1
> >
>
@@ -1870,9 +1870,8 @@ qca8k_setup(struct dsa_switch *ds)
if (ret)
return ret;
- /* Enable ARP Auto-learning by default */
- ret = regmap_set_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
- QCA8K_PORT_LOOKUP_LEARN);
+ ret = regmap_clear_bits(priv->regmap, QCA8K_PORT_LOOKUP_CTRL(i),
+ QCA8K_PORT_LOOKUP_LEARN);
if (ret)
return ret;
@@ -1978,6 +1977,8 @@ static const struct dsa_switch_ops qca8k_switch_ops = {
.port_change_mtu = qca8k_port_change_mtu,
.port_max_mtu = qca8k_port_max_mtu,
.port_stp_state_set = qca8k_port_stp_state_set,
+ .port_pre_bridge_flags = qca8k_port_pre_bridge_flags,
+ .port_bridge_flags = qca8k_port_bridge_flags,
.port_bridge_join = qca8k_port_bridge_join,
.port_bridge_leave = qca8k_port_bridge_leave,
.port_fast_age = qca8k_port_fast_age,
@@ -565,9 +565,26 @@ int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
return 0;
}
+static int qca8k_port_configure_learning(struct dsa_switch *ds, int port,
+ bool learning)
+{
+ struct qca8k_priv *priv = ds->priv;
+
+ if (learning)
+ return regmap_set_bits(priv->regmap,
+ QCA8K_PORT_LOOKUP_CTRL(port),
+ QCA8K_PORT_LOOKUP_LEARN);
+ else
+ return regmap_clear_bits(priv->regmap,
+ QCA8K_PORT_LOOKUP_CTRL(port),
+ QCA8K_PORT_LOOKUP_LEARN);
+}
+
void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
{
+ struct dsa_port *dp = dsa_to_port(ds, port);
struct qca8k_priv *priv = ds->priv;
+ bool learning = false;
u32 stp_state;
switch (state) {
@@ -582,8 +599,11 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
break;
case BR_STATE_LEARNING:
stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
+ learning = dp->learning;
break;
case BR_STATE_FORWARDING:
+ learning = dp->learning;
+ fallthrough;
default:
stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
break;
@@ -591,6 +611,30 @@ void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
+
+ qca8k_port_configure_learning(ds, port, learning);
+}
+
+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
+ struct switchdev_brport_flags flags,
+ struct netlink_ext_ack *extack)
+{
+ if (flags.mask & ~BR_LEARNING)
+ return -EINVAL;
+
+ return 0;
+}
+
+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
+ struct switchdev_brport_flags flags,
+ struct netlink_ext_ack *extack)
+{
+ int ret;
+
+ ret = qca8k_port_configure_learning(ds, port,
+ flags.val & BR_LEARNING);
+
+ return ret;
}
int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
@@ -522,6 +522,12 @@ int qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e);
/* Common bridge function */
void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state);
+int qca8k_port_pre_bridge_flags(struct dsa_switch *ds, int port,
+ struct switchdev_brport_flags flags,
+ struct netlink_ext_ack *extack);
+int qca8k_port_bridge_flags(struct dsa_switch *ds, int port,
+ struct switchdev_brport_flags flags,
+ struct netlink_ext_ack *extack);
int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
struct dsa_bridge bridge,
bool *tx_fwd_offload,