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,
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,
struct netdev_phys_item_id *ppid)
{
......@@ -10083,6 +10066,13 @@ int bnxt_get_port_parent_id(struct net_device *dev,
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 = {
.ndo_open = bnxt_open,
.ndo_start_xmit = bnxt_start_xmit,
......@@ -10115,7 +10105,7 @@ static const struct net_device_ops bnxt_netdev_ops = {
.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
.ndo_get_devlink_port = bnxt_get_devlink_port,
};
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,
}
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 =
&mlxsw_core->ports[local_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,
const char *buf, size_t size)
......
......@@ -176,8 +176,9 @@ void mlxsw_core_port_clear(struct mlxsw_core *mlxsw_core, u8 local_port,
void *port_driver_priv);
enum devlink_port_type mlxsw_core_port_type_get(struct mlxsw_core *mlxsw_core,
u8 local_port);
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);
int mlxsw_core_schedule_dw(struct delayed_work *dwork, unsigned long delay);
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)
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,
struct netdev_phys_item_id *ppid)
{
......@@ -73,11 +63,21 @@ static int mlxsw_m_port_get_port_parent_id(struct net_device *dev,
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 = {
.ndo_open = 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_devlink_port = mlxsw_m_port_get_devlink_port,
};
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,
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 *
mlxsw_sp_port_mall_tc_entry_find(struct mlxsw_sp_port *port,
unsigned long cookie) {
......@@ -1726,6 +1716,16 @@ static int mlxsw_sp_port_get_port_parent_id(struct net_device *dev,
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 = {
.ndo_open = mlxsw_sp_port_open,
.ndo_stop = mlxsw_sp_port_stop,
......@@ -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_vlan_rx_add_vid = mlxsw_sp_port_add_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_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,
......
......@@ -379,16 +379,6 @@ mlxsw_sx_port_get_stats64(struct net_device *dev,
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,
struct netdev_phys_item_id *ppid)
{
......@@ -401,14 +391,24 @@ static int mlxsw_sx_port_get_port_parent_id(struct net_device *dev,
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 = {
.ndo_open = mlxsw_sx_port_open,
.ndo_stop = mlxsw_sx_port_stop,
.ndo_start_xmit = mlxsw_sx_port_xmit,
.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,
.ndo_get_devlink_port = mlxsw_sx_port_get_devlink_port,
};
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,
int nfp_app_nic_vnic_init_phy_port(struct nfp_pf *pf, struct nfp_app *app,
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
......@@ -386,13 +386,13 @@ void nfp_devlink_port_type_clear(struct nfp_port *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);
if (!app)
port = nfp_port_from_netdev(netdev);
if (!port)
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)
struct nfp_net *nn = netdev_priv(netdev);
int n;
/* If port is defined, devlink_port is registered and devlink core
* is taking care of name formatting.
*/
if (nn->port)
return nfp_port_get_phys_port_name(netdev, name, len);
return -EOPNOTSUPP;
if (nn->dp.is_vf || nn->vnic_no_name)
return -EOPNOTSUPP;
......@@ -3531,7 +3534,7 @@ const struct net_device_ops nfp_net_netdev_ops = {
.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,
.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)
nn->id = id;
if (nn->port) {
err = nfp_devlink_port_register(pf->app, nn->port);
if (err)
return err;
}
err = nfp_net_init(nn);
if (err)
return err;
goto err_devlink_port_clean;
nfp_net_debugfs_vnic_add(nn, pf->ddir);
if (nn->port) {
err = nfp_devlink_port_register(pf->app, nn->port);
if (err)
goto err_dfs_clean;
if (nn->port)
nfp_devlink_port_type_eth_set(nn->port);
}
nfp_net_info(nn);
if (nfp_net_is_data_vnic(nn)) {
err = nfp_app_vnic_init(pf->app, nn);
if (err)
goto err_devlink_port_clean;
goto err_devlink_port_type_clean;
}
return 0;
err_devlink_port_clean:
if (nn->port) {
err_devlink_port_type_clean:
if (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_clean(nn);
err_devlink_port_clean:
if (nn->port)
nfp_devlink_port_unregister(nn->port);
return err;
}
......@@ -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))
nfp_app_vnic_clean(pf->app, nn);
if (nn->port) {
if (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_clean(nn);
if (nn->port)
nfp_devlink_port_unregister(nn->port);
}
static int nfp_net_pf_alloc_irqs(struct nfp_pf *pf)
......
......@@ -273,7 +273,7 @@ const struct net_device_ops nfp_repr_netdev_ops = {
.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,
.ndo_get_devlink = nfp_devlink_get_devlink,
.ndo_get_devlink_port = nfp_devlink_get_devlink_port,
};
void
......
......@@ -1250,8 +1250,8 @@ struct devlink;
* that got dropped are freed/returned via xdp_return_frame().
* Returns negative number, means general error invoking ndo, meaning
* no frames were xmit'ed and core-caller will free all frames.
* struct devlink *(*ndo_get_devlink)(struct net_device *dev);
* Get devlink instance associated with a given netdev.
* struct devlink_port *(*ndo_get_devlink_port)(struct net_device *dev);
* Get devlink port instance associated with a given netdev.
* Called with a reference on the netdevice and devlink locks only,
* rtnl_lock is not held.
*/
......@@ -1451,7 +1451,7 @@ struct net_device_ops {
u32 flags);
int (*ndo_xsk_async_xmit)(struct net_device *dev,
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)
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)
{
if (dev->netdev_ops->ndo_get_devlink)
return dev->netdev_ops->ndo_get_devlink(dev);
struct devlink_port *devlink_port = netdev_to_devlink_port(dev);
if (devlink_port)
return devlink_port->devlink;
return NULL;
}
......@@ -573,8 +583,6 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
enum devlink_port_flavour flavour,
u32 port_number, bool split,
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,
u32 size, u16 ingress_pools_count,
u16 egress_pools_count, u16 ingress_tc_count,
......@@ -729,6 +737,8 @@ devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
void devlink_compat_running_version(struct net_device *dev,
char *buf, size_t len);
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
......@@ -743,6 +753,13 @@ devlink_compat_flash_update(struct net_device *dev, const char *file_name)
return -EOPNOTSUPP;
}
static inline int
devlink_compat_phys_port_name_get(struct net_device *dev,
char *name, size_t len)
{
return -EOPNOTSUPP;
}
#endif
#endif /* _NET_DEVLINK_H_ */
......@@ -146,6 +146,7 @@
#include <net/udp_tunnel.h>
#include <linux/net_namespace.h>
#include <linux/indirect_call_wrapper.h>
#include <net/devlink.h>
#include "net-sysfs.h"
......@@ -7877,10 +7878,14 @@ int dev_get_phys_port_name(struct net_device *dev,
char *name, size_t len)
{
const struct net_device_ops *ops = dev->netdev_ops;
int err;
if (!ops->ndo_get_phys_port_name)
return -EOPNOTSUPP;
return ops->ndo_get_phys_port_name(dev, name, len);
if (ops->ndo_get_phys_port_name) {
err = 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);
......
......@@ -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,
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);
}
EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
......@@ -5414,8 +5432,8 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port,
}
EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
char *name, size_t len)
static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
char *name, size_t len)
{
struct devlink_port_attrs *attrs = &devlink_port->attrs;
int n = 0;
......@@ -5445,7 +5463,6 @@ int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
return 0;
}
EXPORT_SYMBOL_GPL(devlink_port_get_phys_port_name);
int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
u32 size, u16 ingress_pools_count,
......@@ -6459,6 +6476,24 @@ int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
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)
{
return genl_register_family(&devlink_nl_family);
......
......@@ -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);
/* 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)
return -EINVAL;
......@@ -1096,6 +1103,13 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
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 = {
.ndo_open = dsa_slave_open,
.ndo_stop = dsa_slave_close,
......@@ -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_vlan_rx_add_vid = dsa_slave_vlan_rx_add_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 = {
......
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