mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-19 00:54:41 +08:00
Merge branch 'net-Introduce-ndo_get_port_parent_id'
Florian Fainelli says: ==================== net: Introduce ndo_get_port_parent_id() Based on discussion with Ido and feedback from Jakub there are clearly two classes of users that implement SWITCHDEV_ATTR_ID_PORT_PARENT_ID: - PF/VF drivers which typically only implement return the port's parent ID, yet have to implement switchdev_port_attr_get() just for that - Ethernet switch drivers: mlxsw, ocelot, DSA, etc. which implement more attributes which we want to be able to eventually veto in the context of the caller, thus making them candidates for using a blocking notifier chain Changes in v4: - remove superfluous net/switchdev.h inclusions in a few files - added Jiri's Acked-by where given - removed err = -EOPNOTSUPP initializations - changed according to Jiri's suggestion in net/ipv4/ipmr.c Changes in v3: - keep ethsw's switchdev_ops assignment - remove inclusion of net/switchdev.h in netdevsim which is no longer necesary Changes in v2: - resolved build failures spotted by kbuild test robot - added helpers functions into the core network device layer: dev_get_port_parent_id() and netdev_port_same_parent_id(); - added support for recursion to lower devices Changes from RFC: - introduce a ndo_get_port_parent_id() and convert all relevant drivers to use it - get rid of SWITCHDEV_ATTR_ID_PORT_PARENT_ID A subsequent set of patches will convert switchdev_port_attr_set() to use a blocking notifier call, and still get rid of switchdev_port_attr_get() altogether. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
554c88ac2f
@ -9981,8 +9981,11 @@ static int bnxt_get_phys_port_name(struct net_device *dev, char *buf,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr)
|
||||
int bnxt_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct bnxt *bp = netdev_priv(dev);
|
||||
|
||||
if (bp->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
@ -9990,27 +9993,12 @@ int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr)
|
||||
if (!BNXT_PF(bp))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = sizeof(bp->switch_id);
|
||||
memcpy(attr->u.ppid.id, bp->switch_id, attr->u.ppid.id_len);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ppid->id_len = sizeof(bp->switch_id);
|
||||
memcpy(ppid->id, bp->switch_id, ppid->id_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bnxt_swdev_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
return bnxt_port_attr_get(netdev_priv(dev), attr);
|
||||
}
|
||||
|
||||
static const struct switchdev_ops bnxt_switchdev_ops = {
|
||||
.switchdev_port_attr_get = bnxt_swdev_port_attr_get
|
||||
};
|
||||
|
||||
static const struct net_device_ops bnxt_netdev_ops = {
|
||||
.ndo_open = bnxt_open,
|
||||
.ndo_start_xmit = bnxt_start_xmit,
|
||||
@ -10042,6 +10030,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
|
||||
.ndo_bpf = bnxt_xdp,
|
||||
.ndo_bridge_getlink = bnxt_bridge_getlink,
|
||||
.ndo_bridge_setlink = bnxt_bridge_setlink,
|
||||
.ndo_get_port_parent_id = bnxt_get_port_parent_id,
|
||||
.ndo_get_phys_port_name = bnxt_get_phys_port_name
|
||||
};
|
||||
|
||||
@ -10400,7 +10389,6 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
dev->netdev_ops = &bnxt_netdev_ops;
|
||||
dev->watchdog_timeo = BNXT_TX_TIMEOUT;
|
||||
dev->ethtool_ops = &bnxt_ethtool_ops;
|
||||
SWITCHDEV_SET_OPS(dev, &bnxt_switchdev_ops);
|
||||
pci_set_drvdata(pdev, dev);
|
||||
|
||||
rc = bnxt_alloc_hwrm_resources(bp);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <linux/rhashtable.h>
|
||||
#include <net/devlink.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/switchdev.h>
|
||||
#include <net/xdp.h>
|
||||
#include <linux/net_dim.h>
|
||||
|
||||
@ -1795,7 +1794,8 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
|
||||
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
|
||||
int bnxt_get_max_rings(struct bnxt *, int *, int *, bool);
|
||||
int bnxt_restore_pf_fw_resources(struct bnxt *bp);
|
||||
int bnxt_port_attr_get(struct bnxt *bp, struct switchdev_attr *attr);
|
||||
int bnxt_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid);
|
||||
void bnxt_dim_work(struct work_struct *work);
|
||||
int bnxt_hwrm_set_ring_coal(struct bnxt *bp, struct bnxt_napi *bnapi);
|
||||
|
||||
|
@ -45,7 +45,7 @@ static u16 bnxt_flow_get_dst_fid(struct bnxt *pf_bp, struct net_device *dev)
|
||||
struct bnxt *bp;
|
||||
|
||||
/* check if dev belongs to the same switch */
|
||||
if (!switchdev_port_same_parent_id(pf_bp->dev, dev)) {
|
||||
if (!netdev_port_same_parent_id(pf_bp->dev, dev)) {
|
||||
netdev_info(pf_bp->dev, "dev(ifindex=%d) not on same switch",
|
||||
dev->ifindex);
|
||||
return BNXT_FID_INVALID;
|
||||
|
@ -237,21 +237,17 @@ static void bnxt_vf_rep_get_drvinfo(struct net_device *dev,
|
||||
strlcpy(info->version, DRV_MODULE_VERSION, sizeof(info->version));
|
||||
}
|
||||
|
||||
static int bnxt_vf_rep_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
static int bnxt_vf_rep_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct bnxt_vf_rep *vf_rep = netdev_priv(dev);
|
||||
|
||||
/* as only PORT_PARENT_ID is supported currently use common code
|
||||
* between PF and VF-rep for now.
|
||||
*/
|
||||
return bnxt_port_attr_get(vf_rep->bp, attr);
|
||||
return bnxt_get_port_parent_id(vf_rep->bp->dev, ppid);
|
||||
}
|
||||
|
||||
static const struct switchdev_ops bnxt_vf_rep_switchdev_ops = {
|
||||
.switchdev_port_attr_get = bnxt_vf_rep_port_attr_get
|
||||
};
|
||||
|
||||
static const struct ethtool_ops bnxt_vf_rep_ethtool_ops = {
|
||||
.get_drvinfo = bnxt_vf_rep_get_drvinfo
|
||||
};
|
||||
@ -262,6 +258,7 @@ static const struct net_device_ops bnxt_vf_rep_netdev_ops = {
|
||||
.ndo_start_xmit = bnxt_vf_rep_xmit,
|
||||
.ndo_get_stats64 = bnxt_vf_rep_get_stats64,
|
||||
.ndo_setup_tc = bnxt_vf_rep_setup_tc,
|
||||
.ndo_get_port_parent_id = bnxt_vf_rep_get_port_parent_id,
|
||||
.ndo_get_phys_port_name = bnxt_vf_rep_get_phys_port_name
|
||||
};
|
||||
|
||||
@ -392,7 +389,6 @@ static void bnxt_vf_rep_netdev_init(struct bnxt *bp, struct bnxt_vf_rep *vf_rep,
|
||||
|
||||
dev->netdev_ops = &bnxt_vf_rep_netdev_ops;
|
||||
dev->ethtool_ops = &bnxt_vf_rep_ethtool_ops;
|
||||
SWITCHDEV_SET_OPS(dev, &bnxt_vf_rep_switchdev_ops);
|
||||
/* Just inherit all the featues of the parent PF as the VF-R
|
||||
* uses the RX/TX rings of the parent PF
|
||||
*/
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <net/vxlan.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <net/switchdev.h>
|
||||
#include "liquidio_common.h"
|
||||
#include "octeon_droq.h"
|
||||
#include "octeon_iq.h"
|
||||
@ -3184,7 +3183,8 @@ static const struct devlink_ops liquidio_devlink_ops = {
|
||||
};
|
||||
|
||||
static int
|
||||
lio_pf_switchdev_attr_get(struct net_device *dev, struct switchdev_attr *attr)
|
||||
liquidio_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct lio *lio = GET_LIO(dev);
|
||||
struct octeon_device *oct = lio->oct_dev;
|
||||
@ -3192,24 +3192,12 @@ lio_pf_switchdev_attr_get(struct net_device *dev, struct switchdev_attr *attr)
|
||||
if (oct->eswitch_mode != DEVLINK_ESWITCH_MODE_SWITCHDEV)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = ETH_ALEN;
|
||||
ether_addr_copy(attr->u.ppid.id,
|
||||
(void *)&lio->linfo.hw_addr + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ppid->id_len = ETH_ALEN;
|
||||
ether_addr_copy(ppid->id, (void *)&lio->linfo.hw_addr + 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct switchdev_ops lio_pf_switchdev_ops = {
|
||||
.switchdev_port_attr_get = lio_pf_switchdev_attr_get,
|
||||
};
|
||||
|
||||
static int liquidio_get_vf_stats(struct net_device *netdev, int vfidx,
|
||||
struct ifla_vf_stats *vf_stats)
|
||||
{
|
||||
@ -3259,6 +3247,7 @@ static const struct net_device_ops lionetdevops = {
|
||||
.ndo_set_vf_trust = liquidio_set_vf_trust,
|
||||
.ndo_set_vf_link_state = liquidio_set_vf_link_state,
|
||||
.ndo_get_vf_stats = liquidio_get_vf_stats,
|
||||
.ndo_get_port_parent_id = liquidio_get_port_parent_id,
|
||||
};
|
||||
|
||||
/** \brief Entry point for the liquidio module
|
||||
@ -3534,7 +3523,6 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
|
||||
* netdev tasks.
|
||||
*/
|
||||
netdev->netdev_ops = &lionetdevops;
|
||||
SWITCHDEV_SET_OPS(netdev, &lio_pf_switchdev_ops);
|
||||
|
||||
retval = netif_set_real_num_rx_queues(netdev, num_oqueues);
|
||||
if (retval) {
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "octeon_nic.h"
|
||||
#include "octeon_main.h"
|
||||
#include "octeon_network.h"
|
||||
#include <net/switchdev.h>
|
||||
#include "lio_vf_rep.h"
|
||||
|
||||
static int lio_vf_rep_open(struct net_device *ndev);
|
||||
@ -38,6 +37,8 @@ static int lio_vf_rep_phys_port_name(struct net_device *dev,
|
||||
static void lio_vf_rep_get_stats64(struct net_device *dev,
|
||||
struct rtnl_link_stats64 *stats64);
|
||||
static int lio_vf_rep_change_mtu(struct net_device *ndev, int new_mtu);
|
||||
static int lio_vf_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid);
|
||||
|
||||
static const struct net_device_ops lio_vf_rep_ndev_ops = {
|
||||
.ndo_open = lio_vf_rep_open,
|
||||
@ -47,6 +48,7 @@ static const struct net_device_ops lio_vf_rep_ndev_ops = {
|
||||
.ndo_get_phys_port_name = lio_vf_rep_phys_port_name,
|
||||
.ndo_get_stats64 = lio_vf_rep_get_stats64,
|
||||
.ndo_change_mtu = lio_vf_rep_change_mtu,
|
||||
.ndo_get_port_parent_id = lio_vf_get_port_parent_id,
|
||||
};
|
||||
|
||||
static int
|
||||
@ -443,31 +445,19 @@ xmit_failed:
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
lio_vf_rep_attr_get(struct net_device *dev, struct switchdev_attr *attr)
|
||||
static int lio_vf_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct lio_vf_rep_desc *vf_rep = netdev_priv(dev);
|
||||
struct net_device *parent_ndev = vf_rep->parent_ndev;
|
||||
struct lio *lio = GET_LIO(parent_ndev);
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = ETH_ALEN;
|
||||
ether_addr_copy(attr->u.ppid.id,
|
||||
(void *)&lio->linfo.hw_addr + 2);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ppid->id_len = ETH_ALEN;
|
||||
ether_addr_copy(ppid->id, (void *)&lio->linfo.hw_addr + 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct switchdev_ops lio_vf_rep_switchdev_ops = {
|
||||
.switchdev_port_attr_get = lio_vf_rep_attr_get,
|
||||
};
|
||||
|
||||
static void
|
||||
lio_vf_rep_fetch_stats(struct work_struct *work)
|
||||
{
|
||||
@ -524,7 +514,6 @@ lio_vf_rep_create(struct octeon_device *oct)
|
||||
ndev->min_mtu = LIO_MIN_MTU_SIZE;
|
||||
ndev->max_mtu = LIO_MAX_MTU_SIZE;
|
||||
ndev->netdev_ops = &lio_vf_rep_ndev_ops;
|
||||
SWITCHDEV_SET_OPS(ndev, &lio_vf_rep_switchdev_ops);
|
||||
|
||||
vf_rep = netdev_priv(ndev);
|
||||
memset(vf_rep, 0, sizeof(*vf_rep));
|
||||
|
@ -25,7 +25,7 @@ static int get_route_and_out_devs(struct mlx5e_priv *priv,
|
||||
/* if the egress device isn't on the same HW e-switch or
|
||||
* it's a LAG device, use the uplink
|
||||
*/
|
||||
if (!switchdev_port_same_parent_id(priv->netdev, dev) ||
|
||||
if (!netdev_port_same_parent_id(priv->netdev, dev) ||
|
||||
dst_is_lag_dev) {
|
||||
*route_dev = uplink_dev;
|
||||
*out_dev = *route_dev;
|
||||
|
@ -381,7 +381,8 @@ static const struct ethtool_ops mlx5e_uplink_rep_ethtool_ops = {
|
||||
.set_pauseparam = mlx5e_uplink_rep_set_pauseparam,
|
||||
};
|
||||
|
||||
static int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr)
|
||||
static int mlx5e_rep_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(dev);
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
@ -398,20 +399,14 @@ static int mlx5e_attr_get(struct net_device *dev, struct switchdev_attr *attr)
|
||||
uplink_priv = netdev_priv(uplink_dev);
|
||||
}
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = ETH_ALEN;
|
||||
if (uplink_upper && mlx5_lag_is_sriov(uplink_priv->mdev)) {
|
||||
ether_addr_copy(attr->u.ppid.id, uplink_upper->dev_addr);
|
||||
} else {
|
||||
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
||||
struct mlx5_eswitch_rep *rep = rpriv->rep;
|
||||
ppid->id_len = ETH_ALEN;
|
||||
if (uplink_upper && mlx5_lag_is_sriov(uplink_priv->mdev)) {
|
||||
ether_addr_copy(ppid->id, uplink_upper->dev_addr);
|
||||
} else {
|
||||
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
||||
struct mlx5_eswitch_rep *rep = rpriv->rep;
|
||||
|
||||
ether_addr_copy(attr->u.ppid.id, rep->hw_id);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
ether_addr_copy(ppid->id, rep->hw_id);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1284,10 +1279,6 @@ static int mlx5e_uplink_rep_set_vf_vlan(struct net_device *dev, int vf, u16 vlan
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct switchdev_ops mlx5e_rep_switchdev_ops = {
|
||||
.switchdev_port_attr_get = mlx5e_attr_get,
|
||||
};
|
||||
|
||||
static const struct net_device_ops mlx5e_netdev_ops_vf_rep = {
|
||||
.ndo_open = mlx5e_vf_rep_open,
|
||||
.ndo_stop = mlx5e_vf_rep_close,
|
||||
@ -1298,6 +1289,7 @@ static const struct net_device_ops mlx5e_netdev_ops_vf_rep = {
|
||||
.ndo_has_offload_stats = mlx5e_rep_has_offload_stats,
|
||||
.ndo_get_offload_stats = mlx5e_rep_get_offload_stats,
|
||||
.ndo_change_mtu = mlx5e_vf_rep_change_mtu,
|
||||
.ndo_get_port_parent_id = mlx5e_rep_get_port_parent_id,
|
||||
};
|
||||
|
||||
static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
|
||||
@ -1319,6 +1311,7 @@ static const struct net_device_ops mlx5e_netdev_ops_uplink_rep = {
|
||||
.ndo_get_vf_config = mlx5e_get_vf_config,
|
||||
.ndo_get_vf_stats = mlx5e_get_vf_stats,
|
||||
.ndo_set_vf_vlan = mlx5e_uplink_rep_set_vf_vlan,
|
||||
.ndo_get_port_parent_id = mlx5e_rep_get_port_parent_id,
|
||||
};
|
||||
|
||||
bool mlx5e_eswitch_rep(struct net_device *netdev)
|
||||
@ -1393,8 +1386,6 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
|
||||
netdev->watchdog_timeo = 15 * HZ;
|
||||
|
||||
|
||||
netdev->switchdev_ops = &mlx5e_rep_switchdev_ops;
|
||||
|
||||
netdev->features |= NETIF_F_HW_TC | NETIF_F_NETNS_LOCAL;
|
||||
netdev->hw_features |= NETIF_F_HW_TC;
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include <linux/mlx5/fs.h>
|
||||
#include <linux/mlx5/device.h>
|
||||
#include <linux/rhashtable.h>
|
||||
#include <net/switchdev.h>
|
||||
#include <net/tc_act/tc_mirred.h>
|
||||
#include <net/tc_act/tc_vlan.h>
|
||||
#include <net/tc_act/tc_tunnel_key.h>
|
||||
@ -2525,8 +2524,8 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
|
||||
|
||||
action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST |
|
||||
MLX5_FLOW_CONTEXT_ACTION_COUNT;
|
||||
if (switchdev_port_same_parent_id(priv->netdev,
|
||||
out_dev) ||
|
||||
if (netdev_port_same_parent_id(priv->netdev,
|
||||
out_dev) ||
|
||||
is_merged_eswitch_dev(priv, out_dev)) {
|
||||
struct mlx5_eswitch *esw = priv->mdev->priv.eswitch;
|
||||
struct net_device *uplink_dev = mlx5_eswitch_uplink_get_proto_dev(esw, REP_ETH);
|
||||
|
@ -1700,6 +1700,18 @@ static int mlxsw_sp_set_features(struct net_device *dev,
|
||||
mlxsw_sp_feature_hw_tc);
|
||||
}
|
||||
|
||||
static int mlxsw_sp_port_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
|
||||
ppid->id_len = sizeof(mlxsw_sp->base_mac);
|
||||
memcpy(&ppid->id, &mlxsw_sp->base_mac, ppid->id_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
|
||||
.ndo_open = mlxsw_sp_port_open,
|
||||
.ndo_stop = mlxsw_sp_port_stop,
|
||||
@ -1715,6 +1727,7 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
|
||||
.ndo_vlan_rx_kill_vid = mlxsw_sp_port_kill_vid,
|
||||
.ndo_get_phys_port_name = mlxsw_sp_port_get_phys_port_name,
|
||||
.ndo_set_features = mlxsw_sp_set_features,
|
||||
.ndo_get_port_parent_id = mlxsw_sp_port_get_port_parent_id,
|
||||
};
|
||||
|
||||
static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
|
||||
|
@ -451,11 +451,6 @@ static int mlxsw_sp_port_attr_get(struct net_device *dev,
|
||||
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = sizeof(mlxsw_sp->base_mac);
|
||||
memcpy(&attr->u.ppid.id, &mlxsw_sp->base_mac,
|
||||
attr->u.ppid.id_len);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||
mlxsw_sp_port_bridge_flags_get(mlxsw_sp->bridge, attr->orig_dev,
|
||||
&attr->u.brport_flags);
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/if_vlan.h>
|
||||
#include <net/switchdev.h>
|
||||
|
||||
#include "pci.h"
|
||||
#include "core.h"
|
||||
@ -390,6 +389,18 @@ static int mlxsw_sx_port_get_phys_port_name(struct net_device *dev, char *name,
|
||||
name, len);
|
||||
}
|
||||
|
||||
static int mlxsw_sx_port_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct mlxsw_sx_port *mlxsw_sx_port = netdev_priv(dev);
|
||||
struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx;
|
||||
|
||||
ppid->id_len = sizeof(mlxsw_sx->hw_id);
|
||||
memcpy(&ppid->id, &mlxsw_sx->hw_id, ppid->id_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops mlxsw_sx_port_netdev_ops = {
|
||||
.ndo_open = mlxsw_sx_port_open,
|
||||
.ndo_stop = mlxsw_sx_port_stop,
|
||||
@ -397,6 +408,7 @@ static const struct net_device_ops mlxsw_sx_port_netdev_ops = {
|
||||
.ndo_change_mtu = mlxsw_sx_port_change_mtu,
|
||||
.ndo_get_stats64 = mlxsw_sx_port_get_stats64,
|
||||
.ndo_get_phys_port_name = mlxsw_sx_port_get_phys_port_name,
|
||||
.ndo_get_port_parent_id = mlxsw_sx_port_get_port_parent_id,
|
||||
};
|
||||
|
||||
static void mlxsw_sx_port_get_drvinfo(struct net_device *dev,
|
||||
@ -901,28 +913,6 @@ static const struct ethtool_ops mlxsw_sx_port_ethtool_ops = {
|
||||
.set_link_ksettings = mlxsw_sx_port_set_link_ksettings,
|
||||
};
|
||||
|
||||
static int mlxsw_sx_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
struct mlxsw_sx_port *mlxsw_sx_port = netdev_priv(dev);
|
||||
struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = sizeof(mlxsw_sx->hw_id);
|
||||
memcpy(&attr->u.ppid.id, &mlxsw_sx->hw_id, attr->u.ppid.id_len);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct switchdev_ops mlxsw_sx_port_switchdev_ops = {
|
||||
.switchdev_port_attr_get = mlxsw_sx_port_attr_get,
|
||||
};
|
||||
|
||||
static int mlxsw_sx_hw_id_get(struct mlxsw_sx *mlxsw_sx)
|
||||
{
|
||||
char spad_pl[MLXSW_REG_SPAD_LEN] = {0};
|
||||
@ -1034,7 +1024,6 @@ static int __mlxsw_sx_port_eth_create(struct mlxsw_sx *mlxsw_sx, u8 local_port,
|
||||
|
||||
dev->netdev_ops = &mlxsw_sx_port_netdev_ops;
|
||||
dev->ethtool_ops = &mlxsw_sx_port_ethtool_ops;
|
||||
dev->switchdev_ops = &mlxsw_sx_port_switchdev_ops;
|
||||
|
||||
err = mlxsw_sx_port_dev_addr_get(mlxsw_sx_port);
|
||||
if (err) {
|
||||
|
@ -916,6 +916,18 @@ static int ocelot_set_features(struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ocelot_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct ocelot_port *ocelot_port = netdev_priv(dev);
|
||||
struct ocelot *ocelot = ocelot_port->ocelot;
|
||||
|
||||
ppid->id_len = sizeof(ocelot->base_mac);
|
||||
memcpy(&ppid->id, &ocelot->base_mac, ppid->id_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops ocelot_port_netdev_ops = {
|
||||
.ndo_open = ocelot_port_open,
|
||||
.ndo_stop = ocelot_port_stop,
|
||||
@ -930,6 +942,7 @@ static const struct net_device_ops ocelot_port_netdev_ops = {
|
||||
.ndo_vlan_rx_add_vid = ocelot_vlan_rx_add_vid,
|
||||
.ndo_vlan_rx_kill_vid = ocelot_vlan_rx_kill_vid,
|
||||
.ndo_set_features = ocelot_set_features,
|
||||
.ndo_get_port_parent_id = ocelot_get_port_parent_id,
|
||||
};
|
||||
|
||||
static void ocelot_get_strings(struct net_device *netdev, u32 sset, u8 *data)
|
||||
@ -1013,25 +1026,6 @@ static const struct ethtool_ops ocelot_ethtool_ops = {
|
||||
.set_link_ksettings = phy_ethtool_set_link_ksettings,
|
||||
};
|
||||
|
||||
static int ocelot_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
struct ocelot_port *ocelot_port = netdev_priv(dev);
|
||||
struct ocelot *ocelot = ocelot_port->ocelot;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = sizeof(ocelot->base_mac);
|
||||
memcpy(&attr->u.ppid.id, &ocelot->base_mac,
|
||||
attr->u.ppid.id_len);
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ocelot_port_attr_stp_state_set(struct ocelot_port *ocelot_port,
|
||||
struct switchdev_trans *trans,
|
||||
u8 state)
|
||||
@ -1331,7 +1325,6 @@ static int ocelot_port_obj_del(struct net_device *dev,
|
||||
}
|
||||
|
||||
static const struct switchdev_ops ocelot_port_switchdev_ops = {
|
||||
.switchdev_port_attr_get = ocelot_port_attr_get,
|
||||
.switchdev_port_attr_set = ocelot_port_attr_set,
|
||||
};
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <net/pkt_cls.h>
|
||||
#include <net/switchdev.h>
|
||||
#include <net/tc_act/tc_csum.h>
|
||||
#include <net/tc_act/tc_gact.h>
|
||||
#include <net/tc_act/tc_mirred.h>
|
||||
@ -138,7 +137,7 @@ nfp_fl_output(struct nfp_app *app, struct nfp_fl_output *output,
|
||||
|
||||
if (nfp_netdev_is_nfp_repr(in_dev)) {
|
||||
/* Confirm ingress and egress are on same device. */
|
||||
if (!switchdev_port_same_parent_id(in_dev, out_dev))
|
||||
if (!netdev_port_same_parent_id(in_dev, out_dev))
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/ktime.h>
|
||||
|
||||
#include <net/switchdev.h>
|
||||
#include <net/vxlan.h>
|
||||
|
||||
#include "nfpcore/nfp_nsp.h"
|
||||
@ -3531,6 +3530,7 @@ const struct net_device_ops nfp_net_netdev_ops = {
|
||||
.ndo_udp_tunnel_add = nfp_net_add_vxlan_port,
|
||||
.ndo_udp_tunnel_del = nfp_net_del_vxlan_port,
|
||||
.ndo_bpf = nfp_net_xdp,
|
||||
.ndo_get_port_parent_id = nfp_port_get_port_parent_id,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -3815,8 +3815,6 @@ static void nfp_net_netdev_init(struct nfp_net *nn)
|
||||
netdev->netdev_ops = &nfp_net_netdev_ops;
|
||||
netdev->watchdog_timeo = msecs_to_jiffies(5 * 1000);
|
||||
|
||||
SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops);
|
||||
|
||||
/* MTU range: 68 - hw-specific max */
|
||||
netdev->min_mtu = ETH_MIN_MTU;
|
||||
netdev->max_mtu = nn->max_mtu;
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <linux/io-64-nonatomic-hi-lo.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <net/dst_metadata.h>
|
||||
#include <net/switchdev.h>
|
||||
|
||||
#include "nfpcore/nfp_cpp.h"
|
||||
#include "nfpcore/nfp_nsp.h"
|
||||
@ -273,6 +272,7 @@ const struct net_device_ops nfp_repr_netdev_ops = {
|
||||
.ndo_fix_features = nfp_repr_fix_features,
|
||||
.ndo_set_features = nfp_port_set_features,
|
||||
.ndo_set_mac_address = eth_mac_addr,
|
||||
.ndo_get_port_parent_id = nfp_port_get_port_parent_id,
|
||||
};
|
||||
|
||||
void
|
||||
@ -336,8 +336,6 @@ int nfp_repr_init(struct nfp_app *app, struct net_device *netdev,
|
||||
|
||||
netdev->max_mtu = pf_netdev->max_mtu;
|
||||
|
||||
SWITCHDEV_SET_OPS(netdev, &nfp_port_switchdev_ops);
|
||||
|
||||
/* Set features the lower device can support with representors */
|
||||
if (repr_cap & NFP_NET_CFG_CTRL_LIVE_ADDR)
|
||||
netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
|
||||
|
@ -31,34 +31,22 @@ struct nfp_port *nfp_port_from_netdev(struct net_device *netdev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
nfp_port_attr_get(struct net_device *netdev, struct switchdev_attr *attr)
|
||||
int nfp_port_get_port_parent_id(struct net_device *netdev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct nfp_port *port;
|
||||
const u8 *serial;
|
||||
|
||||
port = nfp_port_from_netdev(netdev);
|
||||
if (!port)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID: {
|
||||
const u8 *serial;
|
||||
/* N.B: attr->u.ppid.id is binary data */
|
||||
attr->u.ppid.id_len = nfp_cpp_serial(port->app->cpp, &serial);
|
||||
memcpy(&attr->u.ppid.id, serial, attr->u.ppid.id_len);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ppid->id_len = nfp_cpp_serial(port->app->cpp, &serial);
|
||||
memcpy(&ppid->id, serial, ppid->id_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct switchdev_ops nfp_port_switchdev_ops = {
|
||||
.switchdev_port_attr_get = nfp_port_attr_get,
|
||||
};
|
||||
|
||||
int nfp_port_setup_tc(struct net_device *netdev, enum tc_setup_type type,
|
||||
void *type_data)
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <net/devlink.h>
|
||||
|
||||
struct net_device;
|
||||
struct netdev_phys_item_id;
|
||||
struct nfp_app;
|
||||
struct nfp_pf;
|
||||
struct nfp_port;
|
||||
@ -90,7 +91,6 @@ struct nfp_port {
|
||||
};
|
||||
|
||||
extern const struct ethtool_ops nfp_port_ethtool_ops;
|
||||
extern const struct switchdev_ops nfp_port_switchdev_ops;
|
||||
|
||||
__printf(2, 3) u8 *nfp_pr_et(u8 *data, const char *fmt, ...);
|
||||
|
||||
@ -106,6 +106,8 @@ int
|
||||
nfp_port_set_features(struct net_device *netdev, netdev_features_t features);
|
||||
|
||||
struct nfp_port *nfp_port_from_netdev(struct net_device *netdev);
|
||||
int nfp_port_get_port_parent_id(struct net_device *netdev,
|
||||
struct netdev_phys_item_id *ppid);
|
||||
struct nfp_port *
|
||||
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id);
|
||||
struct nfp_eth_table_port *__nfp_port_get_eth_port(struct nfp_port *port);
|
||||
|
@ -2026,6 +2026,18 @@ static void rocker_port_neigh_destroy(struct net_device *dev,
|
||||
err);
|
||||
}
|
||||
|
||||
static int rocker_port_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
const struct rocker_port *rocker_port = netdev_priv(dev);
|
||||
const struct rocker *rocker = rocker_port->rocker;
|
||||
|
||||
ppid->id_len = sizeof(rocker->hw.id);
|
||||
memcpy(&ppid->id, &rocker->hw.id, ppid->id_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops rocker_port_netdev_ops = {
|
||||
.ndo_open = rocker_port_open,
|
||||
.ndo_stop = rocker_port_stop,
|
||||
@ -2035,6 +2047,7 @@ static const struct net_device_ops rocker_port_netdev_ops = {
|
||||
.ndo_get_phys_port_name = rocker_port_get_phys_port_name,
|
||||
.ndo_change_proto_down = rocker_port_change_proto_down,
|
||||
.ndo_neigh_destroy = rocker_port_neigh_destroy,
|
||||
.ndo_get_port_parent_id = rocker_port_get_port_parent_id,
|
||||
};
|
||||
|
||||
/********************
|
||||
@ -2045,14 +2058,9 @@ static int rocker_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
const struct rocker_port *rocker_port = netdev_priv(dev);
|
||||
const struct rocker *rocker = rocker_port->rocker;
|
||||
int err = 0;
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = sizeof(rocker->hw.id);
|
||||
memcpy(&attr->u.ppid.id, &rocker->hw.id, attr->u.ppid.id_len);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||
err = rocker_world_port_attr_bridge_flags_get(rocker_port,
|
||||
&attr->u.brport_flags);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <net/netlink.h>
|
||||
#include <net/pkt_cls.h>
|
||||
#include <net/rtnetlink.h>
|
||||
#include <net/switchdev.h>
|
||||
|
||||
#include "netdevsim.h"
|
||||
|
||||
@ -148,26 +147,16 @@ static struct device_type nsim_dev_type = {
|
||||
.release = nsim_dev_release,
|
||||
};
|
||||
|
||||
static int
|
||||
nsim_port_attr_get(struct net_device *dev, struct switchdev_attr *attr)
|
||||
static int nsim_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct netdevsim *ns = netdev_priv(dev);
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = sizeof(ns->sdev->switch_id);
|
||||
memcpy(&attr->u.ppid.id, &ns->sdev->switch_id,
|
||||
attr->u.ppid.id_len);
|
||||
return 0;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ppid->id_len = sizeof(ns->sdev->switch_id);
|
||||
memcpy(&ppid->id, &ns->sdev->switch_id, ppid->id_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct switchdev_ops nsim_switchdev_ops = {
|
||||
.switchdev_port_attr_get = nsim_port_attr_get,
|
||||
};
|
||||
|
||||
static int nsim_init(struct net_device *dev)
|
||||
{
|
||||
char sdev_ddir_name[10], sdev_link_name[32];
|
||||
@ -214,7 +203,6 @@ static int nsim_init(struct net_device *dev)
|
||||
goto err_bpf_uninit;
|
||||
|
||||
SET_NETDEV_DEV(dev, &ns->dev);
|
||||
SWITCHDEV_SET_OPS(dev, &nsim_switchdev_ops);
|
||||
|
||||
err = nsim_devlink_setup(ns);
|
||||
if (err)
|
||||
@ -493,6 +481,7 @@ static const struct net_device_ops nsim_netdev_ops = {
|
||||
.ndo_setup_tc = nsim_setup_tc,
|
||||
.ndo_set_features = nsim_set_features,
|
||||
.ndo_bpf = nsim_bpf,
|
||||
.ndo_get_port_parent_id = nsim_get_port_parent_id,
|
||||
};
|
||||
|
||||
static void nsim_setup(struct net_device *dev)
|
||||
|
@ -505,6 +505,17 @@ static netdev_tx_t port_dropframe(struct sk_buff *skb,
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static int swdev_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct ethsw_port_priv *port_priv = netdev_priv(dev);
|
||||
|
||||
ppid->id_len = 1;
|
||||
ppid->id[0] = port_priv->ethsw_data->dev_id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct net_device_ops ethsw_port_ops = {
|
||||
.ndo_open = port_open,
|
||||
.ndo_stop = port_stop,
|
||||
@ -515,6 +526,7 @@ static const struct net_device_ops ethsw_port_ops = {
|
||||
.ndo_get_offload_stats = port_get_offload_stats,
|
||||
|
||||
.ndo_start_xmit = port_dropframe,
|
||||
.ndo_get_port_parent_id = swdev_get_port_parent_id,
|
||||
};
|
||||
|
||||
static void ethsw_links_state_update(struct ethsw_core *ethsw)
|
||||
@ -634,10 +646,6 @@ static int swdev_port_attr_get(struct net_device *netdev,
|
||||
struct ethsw_port_priv *port_priv = netdev_priv(netdev);
|
||||
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = 1;
|
||||
attr->u.ppid.id[0] = port_priv->ethsw_data->dev_id;
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
|
||||
attr->u.brport_flags =
|
||||
(port_priv->ethsw_data->learning ? BR_LEARNING : 0) |
|
||||
|
@ -1188,6 +1188,10 @@ struct dev_ifalias {
|
||||
* not implement this, it is assumed that the hw is not able to have
|
||||
* multiple net devices on single physical port.
|
||||
*
|
||||
* int (*ndo_get_port_parent_id)(struct net_device *dev,
|
||||
* struct netdev_phys_item_id *ppid)
|
||||
* Called to get the parent ID of the physical port of this device.
|
||||
*
|
||||
* void (*ndo_udp_tunnel_add)(struct net_device *dev,
|
||||
* struct udp_tunnel_info *ti);
|
||||
* Called by UDP tunnel to notify a driver about the UDP port and socket
|
||||
@ -1412,6 +1416,8 @@ struct net_device_ops {
|
||||
bool new_carrier);
|
||||
int (*ndo_get_phys_port_id)(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid);
|
||||
int (*ndo_get_port_parent_id)(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid);
|
||||
int (*ndo_get_phys_port_name)(struct net_device *dev,
|
||||
char *name, size_t len);
|
||||
void (*ndo_udp_tunnel_add)(struct net_device *dev,
|
||||
@ -3651,6 +3657,9 @@ int dev_get_phys_port_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid);
|
||||
int dev_get_phys_port_name(struct net_device *dev,
|
||||
char *name, size_t len);
|
||||
int dev_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid, bool recurse);
|
||||
bool netdev_port_same_parent_id(struct net_device *a, struct net_device *b);
|
||||
int dev_change_proto_down(struct net_device *dev, bool proto_down);
|
||||
struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev, bool *again);
|
||||
struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
|
||||
|
@ -43,7 +43,6 @@ static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans)
|
||||
|
||||
enum switchdev_attr_id {
|
||||
SWITCHDEV_ATTR_ID_UNDEFINED,
|
||||
SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
|
||||
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
|
||||
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT,
|
||||
@ -61,7 +60,6 @@ struct switchdev_attr {
|
||||
void *complete_priv;
|
||||
void (*complete)(struct net_device *dev, int err, void *priv);
|
||||
union {
|
||||
struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */
|
||||
u8 stp_state; /* PORT_STP_STATE */
|
||||
unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */
|
||||
unsigned long brport_flags_support; /* PORT_BRIDGE_FLAGS_SUPPORT */
|
||||
@ -208,9 +206,6 @@ void switchdev_port_fwd_mark_set(struct net_device *dev,
|
||||
struct net_device *group_dev,
|
||||
bool joining);
|
||||
|
||||
bool switchdev_port_same_parent_id(struct net_device *a,
|
||||
struct net_device *b);
|
||||
|
||||
int switchdev_handle_port_obj_add(struct net_device *dev,
|
||||
struct switchdev_notifier_port_obj_info *port_obj_info,
|
||||
bool (*check_cb)(const struct net_device *dev),
|
||||
@ -295,12 +290,6 @@ call_switchdev_blocking_notifiers(unsigned long val,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static inline bool switchdev_port_same_parent_id(struct net_device *a,
|
||||
struct net_device *b)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline int
|
||||
switchdev_handle_port_obj_add(struct net_device *dev,
|
||||
struct switchdev_notifier_port_obj_info *port_obj_info,
|
||||
|
@ -14,7 +14,7 @@ static int br_switchdev_mark_get(struct net_bridge *br, struct net_device *dev)
|
||||
|
||||
/* dev is yet to be added to the port list. */
|
||||
list_for_each_entry(p, &br->port_list, list) {
|
||||
if (switchdev_port_same_parent_id(dev, p->dev))
|
||||
if (netdev_port_same_parent_id(dev, p->dev))
|
||||
return p->offload_fwd_mark;
|
||||
}
|
||||
|
||||
@ -23,15 +23,12 @@ static int br_switchdev_mark_get(struct net_bridge *br, struct net_device *dev)
|
||||
|
||||
int nbp_switchdev_mark_set(struct net_bridge_port *p)
|
||||
{
|
||||
struct switchdev_attr attr = {
|
||||
.orig_dev = p->dev,
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
};
|
||||
struct netdev_phys_item_id ppid = { };
|
||||
int err;
|
||||
|
||||
ASSERT_RTNL();
|
||||
|
||||
err = switchdev_port_attr_get(p->dev, &attr);
|
||||
err = dev_get_port_parent_id(p->dev, &ppid, true);
|
||||
if (err) {
|
||||
if (err == -EOPNOTSUPP)
|
||||
return 0;
|
||||
|
@ -7877,6 +7877,63 @@ int dev_get_phys_port_name(struct net_device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL(dev_get_phys_port_name);
|
||||
|
||||
/**
|
||||
* dev_get_port_parent_id - Get the device's port parent identifier
|
||||
* @dev: network device
|
||||
* @ppid: pointer to a storage for the port's parent identifier
|
||||
* @recurse: allow/disallow recursion to lower devices
|
||||
*
|
||||
* Get the devices's port parent identifier
|
||||
*/
|
||||
int dev_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid,
|
||||
bool recurse)
|
||||
{
|
||||
const struct net_device_ops *ops = dev->netdev_ops;
|
||||
struct netdev_phys_item_id first = { };
|
||||
struct net_device *lower_dev;
|
||||
struct list_head *iter;
|
||||
int err = -EOPNOTSUPP;
|
||||
|
||||
if (ops->ndo_get_port_parent_id)
|
||||
return ops->ndo_get_port_parent_id(dev, ppid);
|
||||
|
||||
if (!recurse)
|
||||
return err;
|
||||
|
||||
netdev_for_each_lower_dev(dev, lower_dev, iter) {
|
||||
err = dev_get_port_parent_id(lower_dev, ppid, recurse);
|
||||
if (err)
|
||||
break;
|
||||
if (!first.id_len)
|
||||
first = *ppid;
|
||||
else if (memcmp(&first, ppid, sizeof(*ppid)))
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(dev_get_port_parent_id);
|
||||
|
||||
/**
|
||||
* netdev_port_same_parent_id - Indicate if two network devices have
|
||||
* the same port parent identifier
|
||||
* @a: first network device
|
||||
* @b: second network device
|
||||
*/
|
||||
bool netdev_port_same_parent_id(struct net_device *a, struct net_device *b)
|
||||
{
|
||||
struct netdev_phys_item_id a_id = { };
|
||||
struct netdev_phys_item_id b_id = { };
|
||||
|
||||
if (dev_get_port_parent_id(a, &a_id, true) ||
|
||||
dev_get_port_parent_id(b, &b_id, true))
|
||||
return false;
|
||||
|
||||
return netdev_phys_item_id_same(&a_id, &b_id);
|
||||
}
|
||||
EXPORT_SYMBOL(netdev_port_same_parent_id);
|
||||
|
||||
/**
|
||||
* dev_change_proto_down - update protocol port state information
|
||||
* @dev: device
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <linux/capability.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/switchdev.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched/signal.h>
|
||||
@ -501,16 +500,11 @@ static ssize_t phys_switch_id_show(struct device *dev,
|
||||
return restart_syscall();
|
||||
|
||||
if (dev_isalive(netdev)) {
|
||||
struct switchdev_attr attr = {
|
||||
.orig_dev = netdev,
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
.flags = SWITCHDEV_F_NO_RECURSE,
|
||||
};
|
||||
struct netdev_phys_item_id ppid = { };
|
||||
|
||||
ret = switchdev_port_attr_get(netdev, &attr);
|
||||
ret = dev_get_port_parent_id(netdev, &ppid, false);
|
||||
if (!ret)
|
||||
ret = sprintf(buf, "%*phN\n", attr.u.ppid.id_len,
|
||||
attr.u.ppid.id);
|
||||
ret = sprintf(buf, "%*phN\n", ppid.id_len, ppid.id);
|
||||
}
|
||||
rtnl_unlock();
|
||||
|
||||
|
@ -46,7 +46,6 @@
|
||||
|
||||
#include <linux/inet.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <net/switchdev.h>
|
||||
#include <net/ip.h>
|
||||
#include <net/protocol.h>
|
||||
#include <net/arp.h>
|
||||
@ -1146,22 +1145,17 @@ static int rtnl_phys_port_name_fill(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct netdev_phys_item_id ppid = { };
|
||||
int err;
|
||||
struct switchdev_attr attr = {
|
||||
.orig_dev = dev,
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
.flags = SWITCHDEV_F_NO_RECURSE,
|
||||
};
|
||||
|
||||
err = switchdev_port_attr_get(dev, &attr);
|
||||
err = dev_get_port_parent_id(dev, &ppid, false);
|
||||
if (err) {
|
||||
if (err == -EOPNOTSUPP)
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
if (nla_put(skb, IFLA_PHYS_SWITCH_ID, attr.u.ppid.id_len,
|
||||
attr.u.ppid.id))
|
||||
if (nla_put(skb, IFLA_PHYS_SWITCH_ID, ppid.id_len, ppid.id))
|
||||
return -EMSGSIZE;
|
||||
|
||||
return 0;
|
||||
|
@ -362,18 +362,23 @@ static int dsa_slave_port_obj_del(struct net_device *dev,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int dsa_slave_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
static int dsa_slave_get_port_parent_id(struct net_device *dev,
|
||||
struct netdev_phys_item_id *ppid)
|
||||
{
|
||||
struct dsa_port *dp = dsa_slave_to_port(dev);
|
||||
struct dsa_switch *ds = dp->ds;
|
||||
struct dsa_switch_tree *dst = ds->dst;
|
||||
|
||||
ppid->id_len = sizeof(dst->index);
|
||||
memcpy(&ppid->id, &dst->index, ppid->id_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dsa_slave_port_attr_get(struct net_device *dev,
|
||||
struct switchdev_attr *attr)
|
||||
{
|
||||
switch (attr->id) {
|
||||
case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
|
||||
attr->u.ppid.id_len = sizeof(dst->index);
|
||||
memcpy(&attr->u.ppid.id, &dst->index, attr->u.ppid.id_len);
|
||||
break;
|
||||
case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS_SUPPORT:
|
||||
attr->u.brport_flags_support = 0;
|
||||
break;
|
||||
@ -1046,6 +1051,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
|
||||
.ndo_get_phys_port_name = dsa_slave_get_phys_port_name,
|
||||
.ndo_setup_tc = dsa_slave_setup_tc,
|
||||
.ndo_get_stats64 = dsa_slave_get_stats64,
|
||||
.ndo_get_port_parent_id = dsa_slave_get_port_parent_id,
|
||||
};
|
||||
|
||||
static const struct switchdev_ops dsa_slave_switchdev_ops = {
|
||||
|
@ -67,7 +67,6 @@
|
||||
#include <net/fib_rules.h>
|
||||
#include <linux/netconf.h>
|
||||
#include <net/nexthop.h>
|
||||
#include <net/switchdev.h>
|
||||
|
||||
#include <linux/nospec.h>
|
||||
|
||||
@ -837,10 +836,8 @@ static void ipmr_update_thresholds(struct mr_table *mrt, struct mr_mfc *cache,
|
||||
static int vif_add(struct net *net, struct mr_table *mrt,
|
||||
struct vifctl *vifc, int mrtsock)
|
||||
{
|
||||
struct netdev_phys_item_id ppid = { };
|
||||
int vifi = vifc->vifc_vifi;
|
||||
struct switchdev_attr attr = {
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
};
|
||||
struct vif_device *v = &mrt->vif_table[vifi];
|
||||
struct net_device *dev;
|
||||
struct in_device *in_dev;
|
||||
@ -919,10 +916,10 @@ static int vif_add(struct net *net, struct mr_table *mrt,
|
||||
vifc->vifc_flags | (!mrtsock ? VIFF_STATIC : 0),
|
||||
(VIFF_TUNNEL | VIFF_REGISTER));
|
||||
|
||||
attr.orig_dev = dev;
|
||||
if (!switchdev_port_attr_get(dev, &attr)) {
|
||||
memcpy(v->dev_parent_id.id, attr.u.ppid.id, attr.u.ppid.id_len);
|
||||
v->dev_parent_id.id_len = attr.u.ppid.id_len;
|
||||
err = dev_get_port_parent_id(dev, &ppid, true);
|
||||
if (err == 0) {
|
||||
memcpy(v->dev_parent_id.id, ppid.id, ppid.id_len);
|
||||
v->dev_parent_id.id_len = ppid.id_len;
|
||||
} else {
|
||||
v->dev_parent_id.id_len = 0;
|
||||
}
|
||||
|
@ -592,26 +592,6 @@ int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(call_switchdev_blocking_notifiers);
|
||||
|
||||
bool switchdev_port_same_parent_id(struct net_device *a,
|
||||
struct net_device *b)
|
||||
{
|
||||
struct switchdev_attr a_attr = {
|
||||
.orig_dev = a,
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
};
|
||||
struct switchdev_attr b_attr = {
|
||||
.orig_dev = b,
|
||||
.id = SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
|
||||
};
|
||||
|
||||
if (switchdev_port_attr_get(a, &a_attr) ||
|
||||
switchdev_port_attr_get(b, &b_attr))
|
||||
return false;
|
||||
|
||||
return netdev_phys_item_id_same(&a_attr.u.ppid, &b_attr.u.ppid);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(switchdev_port_same_parent_id);
|
||||
|
||||
static int __switchdev_handle_port_obj_add(struct net_device *dev,
|
||||
struct switchdev_notifier_port_obj_info *port_obj_info,
|
||||
bool (*check_cb)(const struct net_device *dev),
|
||||
|
Loading…
Reference in New Issue
Block a user