With the addition of offloading support for upper bond devices we have to let the switchdev framework know if a specific bridge port is offloaded or not, even if that port is bond device. For this to happen, create the dpaa2_switch_port_to_bridge_port function which will determine the bridge port corresponding to a particulat DPAA2 switch interface and use it in the switchdev_bridge_port_offload call. Signed-off-by: Ioana Ciornei --- Changes in v3: - Access lag field through rtnl_dereference() so that we adapt to the __rcu change. - Check that the brport is non-NULL before calling switchdev_bridge_port_unoffload() on it. Changes in v2: - none --- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index b851376b8e1b..87cb8270f30e 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -2105,6 +2105,21 @@ static int dpaa2_switch_port_attr_set_event(struct net_device *netdev, return notifier_from_errno(err); } +static struct net_device * +dpaa2_switch_port_to_bridge_port(struct ethsw_port_priv *port_priv) +{ + struct dpaa2_switch_lag *lag; + + if (!port_priv->fdb->bridge_dev) + return NULL; + + lag = rtnl_dereference(port_priv->lag); + if (lag) + return lag->bond_dev; + + return port_priv->netdev; +} + static int dpaa2_switch_port_bridge_join(struct net_device *netdev, struct net_device *upper_dev, struct netlink_ext_ack *extack) @@ -2112,6 +2127,7 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev, struct ethsw_port_priv *port_priv = netdev_priv(netdev); struct dpaa2_switch_fdb *old_fdb = port_priv->fdb; struct ethsw_core *ethsw = port_priv->ethsw_data; + struct net_device *brport_dev; bool learn_ena; int err; @@ -2123,7 +2139,8 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev, dpaa2_switch_port_set_fdb(port_priv, upper_dev, true); /* Inherit the initial bridge port learning state */ - learn_ena = br_port_flag_is_set(netdev, BR_LEARNING); + brport_dev = dpaa2_switch_port_to_bridge_port(port_priv); + learn_ena = br_port_flag_is_set(brport_dev, BR_LEARNING); err = dpaa2_switch_port_set_learning(port_priv, learn_ena); port_priv->learn_ena = learn_ena; @@ -2137,7 +2154,8 @@ static int dpaa2_switch_port_bridge_join(struct net_device *netdev, if (err) goto err_egress_flood; - err = switchdev_bridge_port_offload(netdev, netdev, NULL, + brport_dev = dpaa2_switch_port_to_bridge_port(port_priv); + err = switchdev_bridge_port_offload(brport_dev, netdev, NULL, NULL, NULL, false, extack); if (err) goto err_switchdev_offload; @@ -2172,7 +2190,14 @@ static int dpaa2_switch_port_restore_rxvlan(struct net_device *vdev, int vid, vo static void dpaa2_switch_port_pre_bridge_leave(struct net_device *netdev) { - switchdev_bridge_port_unoffload(netdev, NULL, NULL, NULL); + struct ethsw_port_priv *port_priv = netdev_priv(netdev); + struct net_device *brport_dev; + + brport_dev = dpaa2_switch_port_to_bridge_port(port_priv); + if (!brport_dev) + return; + + switchdev_bridge_port_unoffload(brport_dev, NULL, NULL, NULL); } static int dpaa2_switch_port_bridge_leave(struct net_device *netdev) -- 2.25.1