Commit 1571e2fd authored by David S. Miller's avatar David S. Miller

Merge branch 'net-call-for-phys_port_name-into-devlink-directly-if-possible'

Jiri Pirko says:

===================
net: call for phys_port_name into devlink directly if possible

phys_port_name may be assembled by a helper in devlink. It is currently
the case only for mlxsw driver. Benefit from the get_devlink_port ndo
and call into devlink directly from dev_get_phys_port_name(). That saves
the trip to the driver, simplifies the code and makes it similar to
recently introduced ethtool-devlink compat helpers.

Move bnxt, partly nfp and dsa to let devlink core generate the name too.
===================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ede1fd18 746364f2
...@@ -10048,23 +10048,6 @@ static int bnxt_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh, ...@@ -10048,23 +10048,6 @@ static int bnxt_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
return rc; return rc;
} }
static int bnxt_get_phys_port_name(struct net_device *dev, char *buf,
size_t len)
{
struct bnxt *bp = netdev_priv(dev);
int rc;
/* The PF and it's VF-reps only support the switchdev framework */
if (!BNXT_PF(bp))
return -EOPNOTSUPP;
rc = snprintf(buf, len, "p%d", bp->pf.port_id);
if (rc >= len)
return -EOPNOTSUPP;
return 0;
}
int bnxt_get_port_parent_id(struct net_device *dev, int bnxt_get_port_parent_id(struct net_device *dev,
struct netdev_phys_item_id *ppid) struct netdev_phys_item_id *ppid)
{ {
...@@ -10083,6 +10066,13 @@ int bnxt_get_port_parent_id(struct net_device *dev, ...@@ -10083,6 +10066,13 @@ int bnxt_get_port_parent_id(struct net_device *dev,
return 0; return 0;
} }
static struct devlink_port *bnxt_get_devlink_port(struct net_device *dev)
{
struct bnxt *bp = netdev_priv(dev);
return &bp->dl_port;
}
static const struct net_device_ops bnxt_netdev_ops = { static const struct net_device_ops bnxt_netdev_ops = {
.ndo_open = bnxt_open, .ndo_open = bnxt_open,
.ndo_start_xmit = bnxt_start_xmit, .ndo_start_xmit = bnxt_start_xmit,
...@@ -10115,7 +10105,7 @@ static const struct net_device_ops bnxt_netdev_ops = { ...@@ -10115,7 +10105,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
.ndo_bridge_getlink = bnxt_bridge_getlink, .ndo_bridge_getlink = bnxt_bridge_getlink,
.ndo_bridge_setlink = bnxt_bridge_setlink, .ndo_bridge_setlink = bnxt_bridge_setlink,
.ndo_get_port_parent_id = bnxt_get_port_parent_id, .ndo_get_port_parent_id = bnxt_get_port_parent_id,
.ndo_get_phys_port_name = bnxt_get_phys_port_name .ndo_get_devlink_port = bnxt_get_devlink_port,
}; };
static void bnxt_remove_one(struct pci_dev *pdev) static void bnxt_remove_one(struct pci_dev *pdev)
......
...@@ -1796,16 +1796,18 @@ enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core, ...@@ -1796,16 +1796,18 @@ enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
} }
EXPORT_SYMBOL(mlxsw_core_port_type_get); EXPORT_SYMBOL(mlxsw_core_port_type_get);
int mlxsw_core_port_get_phys_port_name(struct mlxsw_core *mlxsw_core,
u8 local_port, char *name, size_t len) struct devlink_port *
mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
u8 local_port)
{ {
struct mlxsw_core_port *mlxsw_core_port = struct mlxsw_core_port *mlxsw_core_port =
&mlxsw_core->ports[local_port]; &mlxsw_core->ports[local_port];
struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port; struct devlink_port *devlink_port = &mlxsw_core_port->devlink_port;
return devlink_port_get_phys_port_name(devlink_port, name, len); return devlink_port;
} }
EXPORT_SYMBOL(mlxsw_core_port_get_phys_port_name); EXPORT_SYMBOL(mlxsw_core_port_devlink_port_get);
static void mlxsw_core_buf_dump_dbg(struct mlxsw_core *mlxsw_core, static void mlxsw_core_buf_dump_dbg(struct mlxsw_core *mlxsw_core,
const char *buf, size_t size) const char *buf, size_t size)
......
...@@ -176,8 +176,9 @@ void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port, ...@@ -176,8 +176,9 @@ void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
void *port_driver_priv); void *port_driver_priv);
enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core, enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
u8 local_port); u8 local_port);
int mlxsw_core_port_get_phys_port_name(struct mlxsw_core *mlxsw_core, struct devlink_port *
u8 local_port, char *name, size_t len); mlxsw_core_port_devlink_port_get(struct mlxsw_core *mlxsw_core,
u8 local_port);
int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay); int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
bool mlxsw_core_schedule_work(struct work_struct *work); bool mlxsw_core_schedule_work(struct work_struct *work);
......
...@@ -51,16 +51,6 @@ static int mlxsw_m_port_dummy_open_stop(struct net_device *dev) ...@@ -51,16 +51,6 @@ static int mlxsw_m_port_dummy_open_stop(struct net_device *dev)
return 0; return 0;
} }
static int
mlxsw_m_port_get_phys_port_name(struct net_device *dev, char *name, size_t len)
{
struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev);
struct mlxsw_core *core = mlxsw_m_port->mlxsw_m->core;
u8 local_port = mlxsw_m_port->local_port;
return mlxsw_core_port_get_phys_port_name(core, local_port, name, len);
}
static int mlxsw_m_port_get_port_parent_id(struct net_device *dev, static int mlxsw_m_port_get_port_parent_id(struct net_device *dev,
struct netdev_phys_item_id *ppid) struct netdev_phys_item_id *ppid)
{ {
...@@ -73,11 +63,21 @@ static int mlxsw_m_port_get_port_parent_id(struct net_device *dev, ...@@ -73,11 +63,21 @@ static int mlxsw_m_port_get_port_parent_id(struct net_device *dev,
return 0; return 0;
} }
static struct devlink_port *
mlxsw_m_port_get_devlink_port(struct net_device *dev)
{
struct mlxsw_m_port *mlxsw_m_port = netdev_priv(dev);
struct mlxsw_m *mlxsw_m = mlxsw_m_port->mlxsw_m;
return mlxsw_core_port_devlink_port_get(mlxsw_m->core,
mlxsw_m_port->local_port);
}
static const struct net_device_ops mlxsw_m_port_netdev_ops = { static const struct net_device_ops mlxsw_m_port_netdev_ops = {
.ndo_open = mlxsw_m_port_dummy_open_stop, .ndo_open = mlxsw_m_port_dummy_open_stop,
.ndo_stop = mlxsw_m_port_dummy_open_stop, .ndo_stop = mlxsw_m_port_dummy_open_stop,
.ndo_get_phys_port_name = mlxsw_m_port_get_phys_port_name,
.ndo_get_port_parent_id = mlxsw_m_port_get_port_parent_id, .ndo_get_port_parent_id = mlxsw_m_port_get_port_parent_id,
.ndo_get_devlink_port = mlxsw_m_port_get_devlink_port,
}; };
static int mlxsw_m_get_module_info(struct net_device *netdev, static int mlxsw_m_get_module_info(struct net_device *netdev,
......
...@@ -1254,16 +1254,6 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev, ...@@ -1254,16 +1254,6 @@ static int mlxsw_sp_port_kill_vid(struct net_device *dev,
return 0; return 0;
} }
static int mlxsw_sp_port_get_phys_port_name(struct net_device *dev, char *name,
size_t len)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
return mlxsw_core_port_get_phys_port_name(mlxsw_sp_port->mlxsw_sp->core,
mlxsw_sp_port->local_port,
name, len);
}
static struct mlxsw_sp_port_mall_tc_entry * static struct mlxsw_sp_port_mall_tc_entry *
mlxsw_sp_port_mall_tc_entry_find(struct mlxsw_sp_port *port, mlxsw_sp_port_mall_tc_entry_find(struct mlxsw_sp_port *port,
unsigned long cookie) { unsigned long cookie) {
...@@ -1726,6 +1716,16 @@ static int mlxsw_sp_port_get_port_parent_id(struct net_device *dev, ...@@ -1726,6 +1716,16 @@ static int mlxsw_sp_port_get_port_parent_id(struct net_device *dev,
return 0; return 0;
} }
static struct devlink_port *
mlxsw_sp_port_get_devlink_port(struct net_device *dev)
{
struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev);
struct mlxsw_sp *mlxsw_sp = mlxsw_sp_port->mlxsw_sp;
return mlxsw_core_port_devlink_port_get(mlxsw_sp->core,
mlxsw_sp_port->local_port);
}
static const struct net_device_ops mlxsw_sp_port_netdev_ops = { static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
.ndo_open = mlxsw_sp_port_open, .ndo_open = mlxsw_sp_port_open,
.ndo_stop = mlxsw_sp_port_stop, .ndo_stop = mlxsw_sp_port_stop,
...@@ -1739,9 +1739,9 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = { ...@@ -1739,9 +1739,9 @@ static const struct net_device_ops mlxsw_sp_port_netdev_ops = {
.ndo_get_offload_stats = mlxsw_sp_port_get_offload_stats, .ndo_get_offload_stats = mlxsw_sp_port_get_offload_stats,
.ndo_vlan_rx_add_vid = mlxsw_sp_port_add_vid, .ndo_vlan_rx_add_vid = mlxsw_sp_port_add_vid,
.ndo_vlan_rx_kill_vid = mlxsw_sp_port_kill_vid, .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_set_features = mlxsw_sp_set_features,
.ndo_get_port_parent_id = mlxsw_sp_port_get_port_parent_id, .ndo_get_port_parent_id = mlxsw_sp_port_get_port_parent_id,
.ndo_get_devlink_port = mlxsw_sp_port_get_devlink_port,
}; };
static void mlxsw_sp_port_get_drvinfo(struct net_device *dev, static void mlxsw_sp_port_get_drvinfo(struct net_device *dev,
......
...@@ -379,16 +379,6 @@ mlxsw_sx_port_get_stats64(struct net_device *dev, ...@@ -379,16 +379,6 @@ mlxsw_sx_port_get_stats64(struct net_device *dev,
stats->tx_dropped = tx_dropped; stats->tx_dropped = tx_dropped;
} }
static int mlxsw_sx_port_get_phys_port_name(struct net_device *dev, char *name,
size_t len)
{
struct mlxsw_sx_port *mlxsw_sx_port = netdev_priv(dev);
return mlxsw_core_port_get_phys_port_name(mlxsw_sx_port->mlxsw_sx->core,
mlxsw_sx_port->local_port,
name, len);
}
static int mlxsw_sx_port_get_port_parent_id(struct net_device *dev, static int mlxsw_sx_port_get_port_parent_id(struct net_device *dev,
struct netdev_phys_item_id *ppid) struct netdev_phys_item_id *ppid)
{ {
...@@ -401,14 +391,24 @@ static int mlxsw_sx_port_get_port_parent_id(struct net_device *dev, ...@@ -401,14 +391,24 @@ static int mlxsw_sx_port_get_port_parent_id(struct net_device *dev,
return 0; return 0;
} }
static struct devlink_port *
mlxsw_sx_port_get_devlink_port(struct net_device *dev)
{
struct mlxsw_sx_port *mlxsw_sx_port = netdev_priv(dev);
struct mlxsw_sx *mlxsw_sx = mlxsw_sx_port->mlxsw_sx;
return mlxsw_core_port_devlink_port_get(mlxsw_sx->core,
mlxsw_sx_port->local_port);
}
static const struct net_device_ops mlxsw_sx_port_netdev_ops = { static const struct net_device_ops mlxsw_sx_port_netdev_ops = {
.ndo_open = mlxsw_sx_port_open, .ndo_open = mlxsw_sx_port_open,
.ndo_stop = mlxsw_sx_port_stop, .ndo_stop = mlxsw_sx_port_stop,
.ndo_start_xmit = mlxsw_sx_port_xmit, .ndo_start_xmit = mlxsw_sx_port_xmit,
.ndo_change_mtu = mlxsw_sx_port_change_mtu, .ndo_change_mtu = mlxsw_sx_port_change_mtu,
.ndo_get_stats64 = mlxsw_sx_port_get_stats64, .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, .ndo_get_port_parent_id = mlxsw_sx_port_get_port_parent_id,
.ndo_get_devlink_port = mlxsw_sx_port_get_devlink_port,
}; };
static void mlxsw_sx_port_get_drvinfo(struct net_device *dev, static void mlxsw_sx_port_get_drvinfo(struct net_device *dev,
......
...@@ -433,6 +433,6 @@ int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn, ...@@ -433,6 +433,6 @@ int nfp_app_nic_vnic_alloc(struct nfp_app *app, struct nfp_net *nn,
int nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app, int nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
struct nfp_net *nn, unsigned int id); struct nfp_net *nn, unsigned int id);
struct devlink *nfp_devlink_get_devlink(struct net_device *netdev); struct devlink_port *nfp_devlink_get_devlink_port(struct net_device *netdev);
#endif #endif
...@@ -386,13 +386,13 @@ void nfp_devlink_port_type_clear(struct nfp_port *port) ...@@ -386,13 +386,13 @@ void nfp_devlink_port_type_clear(struct nfp_port *port)
devlink_port_type_clear(&port->dl_port); devlink_port_type_clear(&port->dl_port);
} }
struct devlink *nfp_devlink_get_devlink(struct net_device *netdev) struct devlink_port *nfp_devlink_get_devlink_port(struct net_device *netdev)
{ {
struct nfp_app *app; struct nfp_port *port;
app = nfp_app_from_netdev(netdev); port = nfp_port_from_netdev(netdev);
if (!app) if (!port)
return NULL; return NULL;
return priv_to_devlink(app->pf); return &port->dl_port;
} }
...@@ -3324,8 +3324,11 @@ nfp_net_get_phys_port_name(struct net_device *netdev, char *name, size_t len) ...@@ -3324,8 +3324,11 @@ nfp_net_get_phys_port_name(struct net_device *netdev, char *name, size_t len)
struct nfp_net *nn = netdev_priv(netdev); struct nfp_net *nn = netdev_priv(netdev);
int n; int n;
/* If port is defined, devlink_port is registered and devlink core
* is taking care of name formatting.
*/
if (nn->port) if (nn->port)
return nfp_port_get_phys_port_name(netdev, name, len); return -EOPNOTSUPP;
if (nn->dp.is_vf || nn->vnic_no_name) if (nn->dp.is_vf || nn->vnic_no_name)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -3531,7 +3534,7 @@ const struct net_device_ops nfp_net_netdev_ops = { ...@@ -3531,7 +3534,7 @@ const struct net_device_ops nfp_net_netdev_ops = {
.ndo_udp_tunnel_del = nfp_net_del_vxlan_port, .ndo_udp_tunnel_del = nfp_net_del_vxlan_port,
.ndo_bpf = nfp_net_xdp, .ndo_bpf = nfp_net_xdp,
.ndo_get_port_parent_id = nfp_port_get_port_parent_id, .ndo_get_port_parent_id = nfp_port_get_port_parent_id,
.ndo_get_devlink = nfp_devlink_get_devlink, .ndo_get_devlink_port = nfp_devlink_get_devlink_port,
}; };
/** /**
......
...@@ -150,37 +150,39 @@ nfp_net_pf_init_vnic(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id) ...@@ -150,37 +150,39 @@ nfp_net_pf_init_vnic(struct nfp_pf *pf, struct nfp_net *nn, unsigned int id)
nn->id = id; nn->id = id;
if (nn->port) {
err = nfp_devlink_port_register(pf->app, nn->port);
if (err)
return err;
}
err = nfp_net_init(nn); err = nfp_net_init(nn);
if (err) if (err)
return err; goto err_devlink_port_clean;
nfp_net_debugfs_vnic_add(nn, pf->ddir); nfp_net_debugfs_vnic_add(nn, pf->ddir);
if (nn->port) { if (nn->port)
err = nfp_devlink_port_register(pf->app, nn->port);
if (err)
goto err_dfs_clean;
nfp_devlink_port_type_eth_set(nn->port); nfp_devlink_port_type_eth_set(nn->port);
}
nfp_net_info(nn); nfp_net_info(nn);
if (nfp_net_is_data_vnic(nn)) { if (nfp_net_is_data_vnic(nn)) {
err = nfp_app_vnic_init(pf->app, nn); err = nfp_app_vnic_init(pf->app, nn);
if (err) if (err)
goto err_devlink_port_clean; goto err_devlink_port_type_clean;
} }
return 0; return 0;
err_devlink_port_clean: err_devlink_port_type_clean:
if (nn->port) { if (nn->port)
nfp_devlink_port_type_clear(nn->port); nfp_devlink_port_type_clear(nn->port);
nfp_devlink_port_unregister(nn->port);
}
err_dfs_clean:
nfp_net_debugfs_dir_clean(&nn->debugfs_dir); nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
nfp_net_clean(nn); nfp_net_clean(nn);
err_devlink_port_clean:
if (nn->port)
nfp_devlink_port_unregister(nn->port);
return err; return err;
} }
...@@ -223,12 +225,12 @@ static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn) ...@@ -223,12 +225,12 @@ static void nfp_net_pf_clean_vnic(struct nfp_pf *pf, struct nfp_net *nn)
{ {
if (nfp_net_is_data_vnic(nn)) if (nfp_net_is_data_vnic(nn))
nfp_app_vnic_clean(pf->app, nn); nfp_app_vnic_clean(pf->app, nn);
if (nn->port) { if (nn->port)
nfp_devlink_port_type_clear(nn->port); nfp_devlink_port_type_clear(nn->port);
nfp_devlink_port_unregister(nn->port);
}
nfp_net_debugfs_dir_clean(&nn->debugfs_dir); nfp_net_debugfs_dir_clean(&nn->debugfs_dir);
nfp_net_clean(nn); nfp_net_clean(nn);
if (nn->port)
nfp_devlink_port_unregister(nn->port);
} }
static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf) static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf)
......
...@@ -273,7 +273,7 @@ const struct net_device_ops nfp_repr_netdev_ops = { ...@@ -273,7 +273,7 @@ const struct net_device_ops nfp_repr_netdev_ops = {
.ndo_set_features = nfp_port_set_features, .ndo_set_features = nfp_port_set_features,
.ndo_set_mac_address = eth_mac_addr, .ndo_set_mac_address = eth_mac_addr,
.ndo_get_port_parent_id = nfp_port_get_port_parent_id, .ndo_get_port_parent_id = nfp_port_get_port_parent_id,
.ndo_get_devlink = nfp_devlink_get_devlink, .ndo_get_devlink_port = nfp_devlink_get_devlink_port,
}; };
void void
......
...@@ -1250,8 +1250,8 @@ struct devlink; ...@@ -1250,8 +1250,8 @@ struct devlink;
* that got dropped are freed/returned via xdp_return_frame(). * that got dropped are freed/returned via xdp_return_frame().
* Returns negative number, means general error invoking ndo, meaning * Returns negative number, means general error invoking ndo, meaning
* no frames were xmit'ed and core-caller will free all frames. * no frames were xmit'ed and core-caller will free all frames.
* struct devlink *(*ndo_get_devlink)(struct net_device *dev); * struct devlink_port *(*ndo_get_devlink_port)(struct net_device *dev);
* Get devlink instance associated with a given netdev. * Get devlink port instance associated with a given netdev.
* Called with a reference on the netdevice and devlink locks only, * Called with a reference on the netdevice and devlink locks only,
* rtnl_lock is not held. * rtnl_lock is not held.
*/ */
...@@ -1451,7 +1451,7 @@ struct net_device_ops { ...@@ -1451,7 +1451,7 @@ struct net_device_ops {
u32 flags); u32 flags);
int (*ndo_xsk_async_xmit)(struct net_device *dev, int (*ndo_xsk_async_xmit)(struct net_device *dev,
u32 queue_id); u32 queue_id);
struct devlink * (*ndo_get_devlink)(struct net_device *dev); struct devlink_port * (*ndo_get_devlink_port)(struct net_device *dev);
}; };
/** /**
......
...@@ -547,10 +547,20 @@ static inline struct devlink *priv_to_devlink(void *priv) ...@@ -547,10 +547,20 @@ static inline struct devlink *priv_to_devlink(void *priv)
return container_of(priv, struct devlink, priv); return container_of(priv, struct devlink, priv);
} }
static inline struct devlink_port *
netdev_to_devlink_port(struct net_device *dev)
{
if (dev->netdev_ops->ndo_get_devlink_port)
return dev->netdev_ops->ndo_get_devlink_port(dev);
return NULL;
}
static inline struct devlink *netdev_to_devlink(struct net_device *dev) static inline struct devlink *netdev_to_devlink(struct net_device *dev)
{ {
if (dev->netdev_ops->ndo_get_devlink) struct devlink_port *devlink_port = netdev_to_devlink_port(dev);
return dev->netdev_ops->ndo_get_devlink(dev);
if (devlink_port)
return devlink_port->devlink;
return NULL; return NULL;
} }
...@@ -573,8 +583,6 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port, ...@@ -573,8 +583,6 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
enum devlink_port_flavour flavour, enum devlink_port_flavour flavour,
u32 port_number, bool split, u32 port_number, bool split,
u32 split_subport_number); u32 split_subport_number);
int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
char *name, size_t len);
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
u32 size, u16 ingress_pools_count, u32 size, u16 ingress_pools_count,
u16 egress_pools_count, u16 ingress_tc_count, u16 egress_pools_count, u16 ingress_tc_count,
...@@ -729,6 +737,8 @@ devlink_health_reporter_state_update(struct devlink_health_reporter *reporter, ...@@ -729,6 +737,8 @@ devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
void devlink_compat_running_version(struct net_device *dev, void devlink_compat_running_version(struct net_device *dev,
char *buf, size_t len); char *buf, size_t len);
int devlink_compat_flash_update(struct net_device *dev, const char *file_name); int devlink_compat_flash_update(struct net_device *dev, const char *file_name);
int devlink_compat_phys_port_name_get(struct net_device *dev,
char *name, size_t len);
#else #else
...@@ -743,6 +753,13 @@ devlink_compat_flash_update(struct net_device *dev, const char *file_name) ...@@ -743,6 +753,13 @@ devlink_compat_flash_update(struct net_device *dev, const char *file_name)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int
devlink_compat_phys_port_name_get(struct net_device *dev,
char *name, size_t len)
{
return -EOPNOTSUPP;
}
#endif #endif
#endif /* _NET_DEVLINK_H_ */ #endif /* _NET_DEVLINK_H_ */
...@@ -146,6 +146,7 @@ ...@@ -146,6 +146,7 @@
#include <net/udp_tunnel.h> #include <net/udp_tunnel.h>
#include <linux/net_namespace.h> #include <linux/net_namespace.h>
#include <linux/indirect_call_wrapper.h> #include <linux/indirect_call_wrapper.h>
#include <net/devlink.h>
#include "net-sysfs.h" #include "net-sysfs.h"
...@@ -7877,10 +7878,14 @@ int dev_get_phys_port_name(struct net_device *dev, ...@@ -7877,10 +7878,14 @@ int dev_get_phys_port_name(struct net_device *dev,
char *name, size_t len) char *name, size_t len)
{ {
const struct net_device_ops *ops = dev->netdev_ops; const struct net_device_ops *ops = dev->netdev_ops;
int err;
if (!ops->ndo_get_phys_port_name) if (ops->ndo_get_phys_port_name) {
return -EOPNOTSUPP; err = ops->ndo_get_phys_port_name(dev, name, len);
return ops->ndo_get_phys_port_name(dev, name, len); if (err != -EOPNOTSUPP)
return err;
}
return devlink_compat_phys_port_name_get(dev, name, len);
} }
EXPORT_SYMBOL(dev_get_phys_port_name); EXPORT_SYMBOL(dev_get_phys_port_name);
......
...@@ -5358,6 +5358,24 @@ static void __devlink_port_type_set(struct devlink_port *devlink_port, ...@@ -5358,6 +5358,24 @@ static void __devlink_port_type_set(struct devlink_port *devlink_port,
void devlink_port_type_eth_set(struct devlink_port *devlink_port, void devlink_port_type_eth_set(struct devlink_port *devlink_port,
struct net_device *netdev) struct net_device *netdev)
{ {
/* If driver registers devlink port, it should set devlink port
* attributes accordingly so the compat functions are called
* and the original ops are not used.
*/
if (netdev->netdev_ops->ndo_get_phys_port_name) {
/* Some drivers use the same set of ndos for netdevs
* that have devlink_port registered and also for
* those who don't. Make sure that ndo_get_phys_port_name
* returns -EOPNOTSUPP here in case it is defined.
* Warn if not.
*/
const struct net_device_ops *ops = netdev->netdev_ops;
char name[IFNAMSIZ];
int err;
err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
WARN_ON(err != -EOPNOTSUPP);
}
__devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev); __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
} }
EXPORT_SYMBOL_GPL(devlink_port_type_eth_set); EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
...@@ -5414,8 +5432,8 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port, ...@@ -5414,8 +5432,8 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
} }
EXPORT_SYMBOL_GPL(devlink_port_attrs_set); EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
int devlink_port_get_phys_port_name(struct devlink_port *devlink_port, static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
char *name, size_t len) char *name, size_t len)
{ {
struct devlink_port_attrs *attrs = &devlink_port->attrs; struct devlink_port_attrs *attrs = &devlink_port->attrs;
int n = 0; int n = 0;
...@@ -5445,7 +5463,6 @@ int devlink_port_get_phys_port_name(struct devlink_port *devlink_port, ...@@ -5445,7 +5463,6 @@ int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(devlink_port_get_phys_port_name);
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
u32 size, u16 ingress_pools_count, u32 size, u16 ingress_pools_count,
...@@ -6459,6 +6476,24 @@ int devlink_compat_flash_update(struct net_device *dev, const char *file_name) ...@@ -6459,6 +6476,24 @@ int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
return ret; return ret;
} }
int devlink_compat_phys_port_name_get(struct net_device *dev,
char *name, size_t len)
{
struct devlink_port *devlink_port;
/* RTNL mutex is held here which ensures that devlink_port
* instance cannot disappear in the middle. No need to take
* any devlink lock as only permanent values are accessed.
*/
ASSERT_RTNL();
devlink_port = netdev_to_devlink_port(dev);
if (!devlink_port)
return -EOPNOTSUPP;
return __devlink_port_phys_port_name_get(devlink_port, name, len);
}
static int __init devlink_init(void) static int __init devlink_init(void)
{ {
return genl_register_family(&devlink_nl_family); return genl_register_family(&devlink_nl_family);
......
...@@ -736,6 +736,13 @@ static int dsa_slave_get_phys_port_name(struct net_device *dev, ...@@ -736,6 +736,13 @@ static int dsa_slave_get_phys_port_name(struct net_device *dev,
{ {
struct dsa_port *dp = dsa_slave_to_port(dev); struct dsa_port *dp = dsa_slave_to_port(dev);
/* For non-legacy ports, devlink is used and it takes
* care of the name generation. This ndo implementation
* should be removed with legacy support.
*/
if (dp->ds->devlink)
return -EOPNOTSUPP;
if (snprintf(name, len, "p%d", dp->index) >= len) if (snprintf(name, len, "p%d", dp->index) >= len)
return -EINVAL; return -EINVAL;
...@@ -1096,6 +1103,13 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], ...@@ -1096,6 +1103,13 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
return dsa_port_fdb_del(dp, addr, vid); return dsa_port_fdb_del(dp, addr, vid);
} }
static struct devlink_port *dsa_slave_get_devlink_port(struct net_device *dev)
{
struct dsa_port *dp = dsa_slave_to_port(dev);
return dp->ds->devlink ? &dp->devlink_port : NULL;
}
static const struct net_device_ops dsa_slave_netdev_ops = { static const struct net_device_ops dsa_slave_netdev_ops = {
.ndo_open = dsa_slave_open, .ndo_open = dsa_slave_open,
.ndo_stop = dsa_slave_close, .ndo_stop = dsa_slave_close,
...@@ -1119,6 +1133,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = { ...@@ -1119,6 +1133,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
.ndo_get_port_parent_id = dsa_slave_get_port_parent_id, .ndo_get_port_parent_id = dsa_slave_get_port_parent_id,
.ndo_vlan_rx_add_vid = dsa_slave_vlan_rx_add_vid, .ndo_vlan_rx_add_vid = dsa_slave_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid, .ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid,
.ndo_get_devlink_port = dsa_slave_get_devlink_port,
}; };
static struct device_type dsa_type = { static struct device_type dsa_type = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment