Merge branch 'net-Get-rid-of-switchdev_port_attr_get'
Florian Fainelli says: ==================== net: Get rid of switchdev_port_attr_get() This patch series splits the removal of the switchdev_ops that was proposed a few times before and first tackles the easy part which is the removal of the single call to switchdev_port_attr_get() within the bridge code. As suggestd by Ido, this patch series adds a SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS which is used in the same context as the caller of switchdev_port_attr_set(), so not deferred, and then the operation is carried out in deferred context with setting a support bridge port flag. Follow-up patches will do the switchdev_ops removal after introducing the proper helpers for the switchdev blocking notifier to work across stacked devices (unlike the previous submissions). David this does depend on Russell's "[PATCH net-next v5 0/3] net: dsa: mv88e6xxx: fix IPv6". Changes in v3: - rebased against net-next/master after Russell's IPv6 changes to DSA - ignore prepare/commit phase for PRE_BRIDGE_FLAGS since we don't want to trigger the WARN() in net/switchdev/switchdev.c in the commit phase Changes in v2: - differentiate callers not supporting switchdev_port_attr_set() from the driver not being able to support specific bridge flags - pass "mask" instead of "flags" for the PRE_BRIDGE_FLAGS check - skip prepare phase for PRE_BRIDGE_FLAGS - corrected documentation a bit more - tested bridge_vlan_aware.sh with veth/VRF ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
d0e698d57a
|
@ -232,10 +232,8 @@ Learning_sync attribute enables syncing of the learned/forgotten FDB entry to
|
|||
the bridge's FDB. It's possible, but not optimal, to enable learning on the
|
||||
device port and on the bridge port, and disable learning_sync.
|
||||
|
||||
To support learning and learning_sync port attributes, the driver implements
|
||||
switchdev op switchdev_port_attr_get/set for
|
||||
SWITCHDEV_ATTR_PORT_ID_BRIDGE_FLAGS. The driver should initialize the attributes
|
||||
to the hardware defaults.
|
||||
To support learning, the driver implements switchdev op
|
||||
switchdev_port_attr_set for SWITCHDEV_ATTR_PORT_ID_{PRE}_BRIDGE_FLAGS.
|
||||
|
||||
FDB Ageing
|
||||
^^^^^^^^^^
|
||||
|
|
|
@ -431,21 +431,6 @@ static void mlxsw_sp_bridge_vlan_put(struct mlxsw_sp_bridge_vlan *bridge_vlan)
|
|||
mlxsw_sp_bridge_vlan_destroy(bridge_vlan);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
|
||||
attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD |
|
||||
BR_MCAST_FLOOD;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mlxsw_sp_port_bridge_vlan_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
struct mlxsw_sp_bridge_vlan *bridge_vlan,
|
||||
|
@ -595,6 +580,17 @@ err_port_bridge_vlan_learning_set:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_attr_br_pre_flags_set(struct mlxsw_sp_port
|
||||
*mlxsw_sp_port,
|
||||
struct switchdev_trans *trans,
|
||||
unsigned long brport_flags)
|
||||
{
|
||||
if (brport_flags & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||
struct switchdev_trans *trans,
|
||||
struct net_device *orig_dev,
|
||||
|
@ -841,6 +837,11 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev,
|
|||
attr->orig_dev,
|
||||
attr->u.stp_state);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
|
||||
err = mlxsw_sp_port_attr_br_pre_flags_set(mlxsw_sp_port,
|
||||
trans,
|
||||
attr->u.brport_flags);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||
err = mlxsw_sp_port_attr_br_flags_set(mlxsw_sp_port, trans,
|
||||
attr->orig_dev,
|
||||
|
@ -1938,7 +1939,6 @@ static struct mlxsw_sp_port *mlxsw_sp_lag_rep_port(struct mlxsw_sp *mlxsw_sp,
|
|||
}
|
||||
|
||||
static const struct switchdev_ops mlxsw_sp_port_switchdev_ops = {
|
||||
.switchdev_port_attr_get = mlxsw_sp_port_attr_get,
|
||||
.switchdev_port_attr_set = mlxsw_sp_port_attr_set,
|
||||
};
|
||||
|
||||
|
|
|
@ -1565,6 +1565,43 @@ static int rocker_world_port_attr_stp_state_set(struct rocker_port *rocker_port,
|
|||
return wops->port_attr_stp_state_set(rocker_port, state);
|
||||
}
|
||||
|
||||
static int
|
||||
rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
|
||||
rocker_port,
|
||||
unsigned long *
|
||||
p_brport_flags_support)
|
||||
{
|
||||
struct rocker_world_ops *wops = rocker_port->rocker->wops;
|
||||
|
||||
if (!wops->port_attr_bridge_flags_support_get)
|
||||
return -EOPNOTSUPP;
|
||||
return wops->port_attr_bridge_flags_support_get(rocker_port,
|
||||
p_brport_flags_support);
|
||||
}
|
||||
|
||||
static int
|
||||
rocker_world_port_attr_pre_bridge_flags_set(struct rocker_port *rocker_port,
|
||||
unsigned long brport_flags,
|
||||
struct switchdev_trans *trans)
|
||||
{
|
||||
struct rocker_world_ops *wops = rocker_port->rocker->wops;
|
||||
unsigned long brport_flags_s;
|
||||
int err;
|
||||
|
||||
if (!wops->port_attr_bridge_flags_set)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
err = rocker_world_port_attr_bridge_flags_support_get(rocker_port,
|
||||
&brport_flags_s);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (brport_flags & ~brport_flags_s)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
|
||||
unsigned long brport_flags,
|
||||
|
@ -1582,20 +1619,6 @@ rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
|
|||
trans);
|
||||
}
|
||||
|
||||
static int
|
||||
rocker_world_port_attr_bridge_flags_support_get(const struct rocker_port *
|
||||
rocker_port,
|
||||
unsigned long *
|
||||
p_brport_flags_support)
|
||||
{
|
||||
struct rocker_world_ops *wops = rocker_port->rocker->wops;
|
||||
|
||||
if (!wops->port_attr_bridge_flags_support_get)
|
||||
return -EOPNOTSUPP;
|
||||
return wops->port_attr_bridge_flags_support_get(rocker_port,
|
||||
p_brport_flags_support);
|
||||
}
|
||||
|
||||
static int
|
||||
rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
|
||||
u32 ageing_time,
|
||||
|
@ -2043,24 +2066,6 @@ static const struct net_device_ops rocker_port_netdev_ops = {
|
|||
* swdev interface
|
||||
********************/
|
||||
|
||||
static int rocker_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
const struct rocker_port *rocker_port = netdev_priv(dev);
|
||||
int err = 0;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
|
||||
err = rocker_world_port_attr_bridge_flags_support_get(rocker_port,
|
||||
&attr->u.brport_flags_support);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int rocker_port_attr_set(struct net_device *dev,
|
||||
const struct switchdev_attr *attr,
|
||||
struct switchdev_trans *trans)
|
||||
|
@ -2074,6 +2079,10 @@ static int rocker_port_attr_set(struct net_device *dev,
|
|||
attr->u.stp_state,
|
||||
trans);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
|
||||
err = rocker_world_port_attr_pre_bridge_flags_set(rocker_port,
|
||||
attr->u.brport_flags,
|
||||
trans);
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||
err = rocker_world_port_attr_bridge_flags_set(rocker_port,
|
||||
attr->u.brport_flags,
|
||||
|
@ -2133,7 +2142,6 @@ static int rocker_port_obj_del(struct net_device *dev,
|
|||
}
|
||||
|
||||
static const struct switchdev_ops rocker_port_switchdev_ops = {
|
||||
.switchdev_port_attr_get = rocker_port_attr_get,
|
||||
.switchdev_port_attr_set = rocker_port_attr_set,
|
||||
};
|
||||
|
||||
|
|
|
@ -640,20 +640,6 @@ static void ethsw_teardown_irqs(struct fsl_mc_device *sw_dev)
|
|||
fsl_mc_free_irqs(sw_dev);
|
||||
}
|
||||
|
||||
static int swdev_port_attr_get(struct net_device *netdev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
|
||||
attr->u.brport_flags_support = BR_LEARNING | BR_FLOOD;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int port_attr_stp_state_set(struct net_device *netdev,
|
||||
struct switchdev_trans *trans,
|
||||
u8 state)
|
||||
|
@ -666,6 +652,16 @@ static int port_attr_stp_state_set(struct net_device *netdev,
|
|||
return ethsw_port_set_stp_state(port_priv, state);
|
||||
}
|
||||
|
||||
static int port_attr_br_flags_pre_set(struct net_device *netdev,
|
||||
struct switchdev_trans *trans,
|
||||
unsigned long flags)
|
||||
{
|
||||
if (flags & ~(BR_LEARNING | BR_FLOOD))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int port_attr_br_flags_set(struct net_device *netdev,
|
||||
struct switchdev_trans *trans,
|
||||
unsigned long flags)
|
||||
|
@ -698,6 +694,10 @@ static int swdev_port_attr_set(struct net_device *netdev,
|
|||
err = port_attr_stp_state_set(netdev, trans,
|
||||
attr->u.stp_state);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
|
||||
err = port_attr_br_flags_pre_set(netdev, trans,
|
||||
attr->u.brport_flags);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||
err = port_attr_br_flags_set(netdev, trans,
|
||||
attr->u.brport_flags);
|
||||
|
@ -926,7 +926,6 @@ static int swdev_port_obj_del(struct net_device *netdev,
|
|||
}
|
||||
|
||||
static const struct switchdev_ops ethsw_port_switchdev_ops = {
|
||||
.switchdev_port_attr_get = swdev_port_attr_get,
|
||||
.switchdev_port_attr_set = swdev_port_attr_set,
|
||||
};
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ enum switchdev_attr_id {
|
|||
SWITCHDEV_ATTR_ID_UNDEFINED,
|
||||
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
|
||||
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
|
||||
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
|
||||
SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS,
|
||||
SWITCHDEV_ATTR_ID_PORT_MROUTER,
|
||||
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
|
||||
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
|
||||
|
@ -61,8 +61,7 @@ struct switchdev_attr {
|
|||
void (*complete)(struct net_device *dev, int err, void *priv);
|
||||
union {
|
||||
u8 stp_state; /* PORT_STP_STATE */
|
||||
unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */
|
||||
unsigned long brport_flags_support; /* PORT_BRIDGE_FLAGS_SUPPORT */
|
||||
unsigned long brport_flags; /* PORT_{PRE}_BRIDGE_FLAGS */
|
||||
bool mrouter; /* PORT_MROUTER */
|
||||
clock_t ageing_time; /* BRIDGE_AGEING_TIME */
|
||||
bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */
|
||||
|
@ -180,8 +179,6 @@ switchdev_notifier_info_to_extack(const struct switchdev_notifier_info *info)
|
|||
#ifdef CONFIG_NET_SWITCHDEV
|
||||
|
||||
void switchdev_deferred_process(void);
|
||||
int switchdev_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr);
|
||||
int switchdev_port_attr_set(struct net_device *dev,
|
||||
const struct switchdev_attr *attr);
|
||||
int switchdev_port_obj_add(struct net_device *dev,
|
||||
|
@ -226,12 +223,6 @@ static inline void switchdev_deferred_process(void)
|
|||
{
|
||||
}
|
||||
|
||||
static inline int switchdev_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int switchdev_port_attr_set(struct net_device *dev,
|
||||
const struct switchdev_attr *attr)
|
||||
{
|
||||
|
|
|
@ -64,21 +64,19 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
|
|||
{
|
||||
struct switchdev_attr attr = {
|
||||
.orig_dev = p->dev,
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS,
|
||||
.u.brport_flags = mask,
|
||||
};
|
||||
int err;
|
||||
|
||||
if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD)
|
||||
return 0;
|
||||
|
||||
err = switchdev_port_attr_get(p->dev, &attr);
|
||||
err = switchdev_port_attr_set(p->dev, &attr);
|
||||
if (err == -EOPNOTSUPP)
|
||||
return 0;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Check if specific bridge flag attribute offload is supported */
|
||||
if (!(attr.u.brport_flags_support & mask)) {
|
||||
if (err) {
|
||||
br_warn(p->br, "bridge flag offload is not supported %u(%s)\n",
|
||||
(unsigned int)p->port_no, p->dev->name);
|
||||
return -EOPNOTSUPP;
|
||||
|
@ -87,6 +85,7 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
|
|||
attr.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS;
|
||||
attr.flags = SWITCHDEV_F_DEFER;
|
||||
attr.u.brport_flags = flags;
|
||||
|
||||
err = switchdev_port_attr_set(p->dev, &attr);
|
||||
if (err) {
|
||||
br_warn(p->br, "error setting offload flag on port %u(%s)\n",
|
||||
|
|
|
@ -160,6 +160,8 @@ int dsa_port_mdb_add(const struct dsa_port *dp,
|
|||
struct switchdev_trans *trans);
|
||||
int dsa_port_mdb_del(const struct dsa_port *dp,
|
||||
const struct switchdev_obj_port_mdb *mdb);
|
||||
int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags,
|
||||
struct switchdev_trans *trans);
|
||||
int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
|
||||
struct switchdev_trans *trans);
|
||||
int dsa_port_vlan_add(struct dsa_port *dp,
|
||||
|
|
|
@ -187,6 +187,18 @@ int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
|
|||
return dsa_port_notify(dp, DSA_NOTIFIER_AGEING_TIME, &info);
|
||||
}
|
||||
|
||||
int dsa_port_pre_bridge_flags(const struct dsa_port *dp, unsigned long flags,
|
||||
struct switchdev_trans *trans)
|
||||
{
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
if (!ds->ops->port_egress_floods ||
|
||||
(flags & ~(BR_FLOOD | BR_MCAST_FLOOD)))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
|
||||
struct switchdev_trans *trans)
|
||||
{
|
||||
|
|
|
@ -295,6 +295,10 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
|
|||
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
|
||||
ret = dsa_port_ageing_time(dp, attr->u.ageing_time, trans);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_PRE_BRIDGE_FLAGS:
|
||||
ret = dsa_port_pre_bridge_flags(dp, attr->u.brport_flags,
|
||||
trans);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||
ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, trans);
|
||||
break;
|
||||
|
@ -381,26 +385,6 @@ static int dsa_slave_get_port_parent_id(struct net_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dsa_slave_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
|
||||
attr->u.brport_flags_support = 0;
|
||||
if (ds->ops->port_egress_floods)
|
||||
attr->u.brport_flags_support |= BR_FLOOD |
|
||||
BR_MCAST_FLOOD;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline netdev_tx_t dsa_slave_netpoll_send_skb(struct net_device *dev,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
|
@ -1067,7 +1051,6 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
|
|||
};
|
||||
|
||||
static const struct switchdev_ops dsa_slave_switchdev_ops = {
|
||||
.switchdev_port_attr_get = dsa_slave_port_attr_get,
|
||||
.switchdev_port_attr_set = dsa_slave_port_attr_set,
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче