mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-03-28 10:04:14 +00:00
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:
commit
d0e698d57a
9 changed files with 98 additions and 106 deletions
|
@ -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
|
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.
|
device port and on the bridge port, and disable learning_sync.
|
||||||
|
|
||||||
To support learning and learning_sync port attributes, the driver implements
|
To support learning, the driver implements switchdev op
|
||||||
switchdev op switchdev_port_attr_get/set for
|
switchdev_port_attr_set for SWITCHDEV_ATTR_PORT_ID_{PRE}_BRIDGE_FLAGS.
|
||||||
SWITCHDEV_ATTR_PORT_ID_BRIDGE_FLAGS. The driver should initialize the attributes
|
|
||||||
to the hardware defaults.
|
|
||||||
|
|
||||||
FDB Ageing
|
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);
|
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
|
static int
|
||||||
mlxsw_sp_port_bridge_vlan_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
mlxsw_sp_port_bridge_vlan_stp_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
struct mlxsw_sp_bridge_vlan *bridge_vlan,
|
struct mlxsw_sp_bridge_vlan *bridge_vlan,
|
||||||
|
@ -595,6 +580,17 @@ err_port_bridge_vlan_learning_set:
|
||||||
return err;
|
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,
|
static int mlxsw_sp_port_attr_br_flags_set(struct mlxsw_sp_port *mlxsw_sp_port,
|
||||||
struct switchdev_trans *trans,
|
struct switchdev_trans *trans,
|
||||||
struct net_device *orig_dev,
|
struct net_device *orig_dev,
|
||||||
|
@ -841,6 +837,11 @@ static int mlxsw_sp_port_attr_set(struct net_device *dev,
|
||||||
attr->orig_dev,
|
attr->orig_dev,
|
||||||
attr->u.stp_state);
|
attr->u.stp_state);
|
||||||
break;
|
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:
|
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||||
err = mlxsw_sp_port_attr_br_flags_set(mlxsw_sp_port, trans,
|
err = mlxsw_sp_port_attr_br_flags_set(mlxsw_sp_port, trans,
|
||||||
attr->orig_dev,
|
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 = {
|
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,
|
.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);
|
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
|
static int
|
||||||
rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
|
rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
|
||||||
unsigned long brport_flags,
|
unsigned long brport_flags,
|
||||||
|
@ -1582,20 +1619,6 @@ rocker_world_port_attr_bridge_flags_set(struct rocker_port *rocker_port,
|
||||||
trans);
|
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
|
static int
|
||||||
rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
|
rocker_world_port_attr_bridge_ageing_time_set(struct rocker_port *rocker_port,
|
||||||
u32 ageing_time,
|
u32 ageing_time,
|
||||||
|
@ -2043,24 +2066,6 @@ static const struct net_device_ops rocker_port_netdev_ops = {
|
||||||
* swdev interface
|
* 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,
|
static int rocker_port_attr_set(struct net_device *dev,
|
||||||
const struct switchdev_attr *attr,
|
const struct switchdev_attr *attr,
|
||||||
struct switchdev_trans *trans)
|
struct switchdev_trans *trans)
|
||||||
|
@ -2074,6 +2079,10 @@ static int rocker_port_attr_set(struct net_device *dev,
|
||||||
attr->u.stp_state,
|
attr->u.stp_state,
|
||||||
trans);
|
trans);
|
||||||
break;
|
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:
|
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||||
err = rocker_world_port_attr_bridge_flags_set(rocker_port,
|
err = rocker_world_port_attr_bridge_flags_set(rocker_port,
|
||||||
attr->u.brport_flags,
|
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 = {
|
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,
|
.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);
|
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,
|
static int port_attr_stp_state_set(struct net_device *netdev,
|
||||||
struct switchdev_trans *trans,
|
struct switchdev_trans *trans,
|
||||||
u8 state)
|
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);
|
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,
|
static int port_attr_br_flags_set(struct net_device *netdev,
|
||||||
struct switchdev_trans *trans,
|
struct switchdev_trans *trans,
|
||||||
unsigned long flags)
|
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,
|
err = port_attr_stp_state_set(netdev, trans,
|
||||||
attr->u.stp_state);
|
attr->u.stp_state);
|
||||||
break;
|
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:
|
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||||
err = port_attr_br_flags_set(netdev, trans,
|
err = port_attr_br_flags_set(netdev, trans,
|
||||||
attr->u.brport_flags);
|
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 = {
|
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,
|
.switchdev_port_attr_set = swdev_port_attr_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ enum switchdev_attr_id {
|
||||||
SWITCHDEV_ATTR_ID_UNDEFINED,
|
SWITCHDEV_ATTR_ID_UNDEFINED,
|
||||||
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
|
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
|
||||||
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
|
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_PORT_MROUTER,
|
||||||
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
|
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
|
||||||
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
|
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
|
||||||
|
@ -61,8 +61,7 @@ struct switchdev_attr {
|
||||||
void (*complete)(struct net_device *dev, int err, void *priv);
|
void (*complete)(struct net_device *dev, int err, void *priv);
|
||||||
union {
|
union {
|
||||||
u8 stp_state; /* PORT_STP_STATE */
|
u8 stp_state; /* PORT_STP_STATE */
|
||||||
unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */
|
unsigned long brport_flags; /* PORT_{PRE}_BRIDGE_FLAGS */
|
||||||
unsigned long brport_flags_support; /* PORT_BRIDGE_FLAGS_SUPPORT */
|
|
||||||
bool mrouter; /* PORT_MROUTER */
|
bool mrouter; /* PORT_MROUTER */
|
||||||
clock_t ageing_time; /* BRIDGE_AGEING_TIME */
|
clock_t ageing_time; /* BRIDGE_AGEING_TIME */
|
||||||
bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */
|
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
|
#ifdef CONFIG_NET_SWITCHDEV
|
||||||
|
|
||||||
void switchdev_deferred_process(void);
|
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,
|
int switchdev_port_attr_set(struct net_device *dev,
|
||||||
const struct switchdev_attr *attr);
|
const struct switchdev_attr *attr);
|
||||||
int switchdev_port_obj_add(struct net_device *dev,
|
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,
|
static inline int switchdev_port_attr_set(struct net_device *dev,
|
||||||
const struct switchdev_attr *attr)
|
const struct switchdev_attr *attr)
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,21 +64,19 @@ int br_switchdev_set_port_flag(struct net_bridge_port *p,
|
||||||
{
|
{
|
||||||
struct switchdev_attr attr = {
|
struct switchdev_attr attr = {
|
||||||
.orig_dev = p->dev,
|
.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;
|
int err;
|
||||||
|
|
||||||
if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD)
|
if (mask & ~BR_PORT_FLAGS_HW_OFFLOAD)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err = switchdev_port_attr_get(p->dev, &attr);
|
err = switchdev_port_attr_set(p->dev, &attr);
|
||||||
if (err == -EOPNOTSUPP)
|
if (err == -EOPNOTSUPP)
|
||||||
return 0;
|
return 0;
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* Check if specific bridge flag attribute offload is supported */
|
if (err) {
|
||||||
if (!(attr.u.brport_flags_support & mask)) {
|
|
||||||
br_warn(p->br, "bridge flag offload is not supported %u(%s)\n",
|
br_warn(p->br, "bridge flag offload is not supported %u(%s)\n",
|
||||||
(unsigned int)p->port_no, p->dev->name);
|
(unsigned int)p->port_no, p->dev->name);
|
||||||
return -EOPNOTSUPP;
|
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.id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS;
|
||||||
attr.flags = SWITCHDEV_F_DEFER;
|
attr.flags = SWITCHDEV_F_DEFER;
|
||||||
attr.u.brport_flags = flags;
|
attr.u.brport_flags = flags;
|
||||||
|
|
||||||
err = switchdev_port_attr_set(p->dev, &attr);
|
err = switchdev_port_attr_set(p->dev, &attr);
|
||||||
if (err) {
|
if (err) {
|
||||||
br_warn(p->br, "error setting offload flag on port %u(%s)\n",
|
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);
|
struct switchdev_trans *trans);
|
||||||
int dsa_port_mdb_del(const struct dsa_port *dp,
|
int dsa_port_mdb_del(const struct dsa_port *dp,
|
||||||
const struct switchdev_obj_port_mdb *mdb);
|
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,
|
int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
|
||||||
struct switchdev_trans *trans);
|
struct switchdev_trans *trans);
|
||||||
int dsa_port_vlan_add(struct dsa_port *dp,
|
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);
|
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,
|
int dsa_port_bridge_flags(const struct dsa_port *dp, unsigned long flags,
|
||||||
struct switchdev_trans *trans)
|
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:
|
case SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME:
|
||||||
ret = dsa_port_ageing_time(dp, attr->u.ageing_time, trans);
|
ret = dsa_port_ageing_time(dp, attr->u.ageing_time, trans);
|
||||||
break;
|
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:
|
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||||
ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, trans);
|
ret = dsa_port_bridge_flags(dp, attr->u.brport_flags, trans);
|
||||||
break;
|
break;
|
||||||
|
@ -381,26 +385,6 @@ static int dsa_slave_get_port_parent_id(struct net_device *dev,
|
||||||
return 0;
|
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,
|
static inline netdev_tx_t dsa_slave_netpoll_send_skb(struct net_device *dev,
|
||||||
struct sk_buff *skb)
|
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 = {
|
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,
|
.switchdev_port_attr_set = dsa_slave_port_attr_set,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue