Commit 706217c1 authored by Jakub Kicinski's avatar Jakub Kicinski

devlink: pass devlink_port to port_split / port_unsplit callbacks

Now that devlink ports are protected by the instance lock
it seems natural to pass devlink_port as an argument to
the port_split / port_unsplit callbacks.

This should save the drivers from doing a lookup.

In theory drivers may have supported unsplitting ports
which were not registered prior to this change.
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Tested-by: default avatarIdo Schimmel <idosch@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 49e83bbe
...@@ -1217,36 +1217,37 @@ static void mlxsw_core_fw_params_unregister(struct mlxsw_core *mlxsw_core) ...@@ -1217,36 +1217,37 @@ static void mlxsw_core_fw_params_unregister(struct mlxsw_core *mlxsw_core)
ARRAY_SIZE(mlxsw_core_fw_devlink_params)); ARRAY_SIZE(mlxsw_core_fw_devlink_params));
} }
static void *__dl_port(struct devlink_port *devlink_port)
{
return container_of(devlink_port, struct mlxsw_core_port, devlink_port);
}
static int mlxsw_devlink_port_split(struct devlink *devlink, static int mlxsw_devlink_port_split(struct devlink *devlink,
unsigned int port_index, struct devlink_port *port,
unsigned int count, unsigned int count,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlxsw_core_port *mlxsw_core_port = __dl_port(port);
struct mlxsw_core *mlxsw_core = devlink_priv(devlink); struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
if (port_index >= mlxsw_core->max_ports) {
NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports");
return -EINVAL;
}
if (!mlxsw_core->driver->port_split) if (!mlxsw_core->driver->port_split)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return mlxsw_core->driver->port_split(mlxsw_core, port_index, count, return mlxsw_core->driver->port_split(mlxsw_core,
extack); mlxsw_core_port->local_port,
count, extack);
} }
static int mlxsw_devlink_port_unsplit(struct devlink *devlink, static int mlxsw_devlink_port_unsplit(struct devlink *devlink,
unsigned int port_index, struct devlink_port *port,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct mlxsw_core_port *mlxsw_core_port = __dl_port(port);
struct mlxsw_core *mlxsw_core = devlink_priv(devlink); struct mlxsw_core *mlxsw_core = devlink_priv(devlink);
if (port_index >= mlxsw_core->max_ports) {
NL_SET_ERR_MSG_MOD(extack, "Port index exceeds maximum number of ports");
return -EINVAL;
}
if (!mlxsw_core->driver->port_unsplit) if (!mlxsw_core->driver->port_unsplit)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return mlxsw_core->driver->port_unsplit(mlxsw_core, port_index, return mlxsw_core->driver->port_unsplit(mlxsw_core,
mlxsw_core_port->local_port,
extack); extack);
} }
...@@ -1280,11 +1281,6 @@ mlxsw_devlink_sb_pool_set(struct devlink *devlink, ...@@ -1280,11 +1281,6 @@ mlxsw_devlink_sb_pool_set(struct devlink *devlink,
extack); extack);
} }
static void *__dl_port(struct devlink_port *devlink_port)
{
return container_of(devlink_port, struct mlxsw_core_port, devlink_port);
}
static int mlxsw_devlink_port_type_set(struct devlink_port *devlink_port, static int mlxsw_devlink_port_type_set(struct devlink_port *devlink_port,
enum devlink_port_type port_type) enum devlink_port_type port_type)
{ {
......
...@@ -26,12 +26,11 @@ nfp_devlink_fill_eth_port(struct nfp_port *port, ...@@ -26,12 +26,11 @@ nfp_devlink_fill_eth_port(struct nfp_port *port,
} }
static int static int
nfp_devlink_fill_eth_port_from_id(struct nfp_pf *pf, unsigned int port_index, nfp_devlink_fill_eth_port_from_id(struct nfp_pf *pf,
struct devlink_port *dl_port,
struct nfp_eth_table_port *copy) struct nfp_eth_table_port *copy)
{ {
struct nfp_port *port; struct nfp_port *port = container_of(dl_port, struct nfp_port, dl_port);
port = nfp_port_from_id(pf, NFP_PORT_PHYS_PORT, port_index);
return nfp_devlink_fill_eth_port(port, copy); return nfp_devlink_fill_eth_port(port, copy);
} }
...@@ -62,7 +61,7 @@ nfp_devlink_set_lanes(struct nfp_pf *pf, unsigned int idx, unsigned int lanes) ...@@ -62,7 +61,7 @@ nfp_devlink_set_lanes(struct nfp_pf *pf, unsigned int idx, unsigned int lanes)
} }
static int static int
nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index, nfp_devlink_port_split(struct devlink *devlink, struct devlink_port *port,
unsigned int count, struct netlink_ext_ack *extack) unsigned int count, struct netlink_ext_ack *extack)
{ {
struct nfp_pf *pf = devlink_priv(devlink); struct nfp_pf *pf = devlink_priv(devlink);
...@@ -71,7 +70,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index, ...@@ -71,7 +70,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
int ret; int ret;
rtnl_lock(); rtnl_lock();
ret = nfp_devlink_fill_eth_port_from_id(pf, port_index, &eth_port); ret = nfp_devlink_fill_eth_port_from_id(pf, port, &eth_port);
rtnl_unlock(); rtnl_unlock();
if (ret) if (ret)
return ret; return ret;
...@@ -88,7 +87,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index, ...@@ -88,7 +87,7 @@ nfp_devlink_port_split(struct devlink *devlink, unsigned int port_index,
} }
static int static int
nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index, nfp_devlink_port_unsplit(struct devlink *devlink, struct devlink_port *port,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
struct nfp_pf *pf = devlink_priv(devlink); struct nfp_pf *pf = devlink_priv(devlink);
...@@ -97,7 +96,7 @@ nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index, ...@@ -97,7 +96,7 @@ nfp_devlink_port_unsplit(struct devlink *devlink, unsigned int port_index,
int ret; int ret;
rtnl_lock(); rtnl_lock();
ret = nfp_devlink_fill_eth_port_from_id(pf, port_index, &eth_port); ret = nfp_devlink_fill_eth_port_from_id(pf, port, &eth_port);
rtnl_unlock(); rtnl_unlock();
if (ret) if (ret)
return ret; return ret;
......
...@@ -75,24 +75,6 @@ int nfp_port_set_features(struct net_device *netdev, netdev_features_t features) ...@@ -75,24 +75,6 @@ int nfp_port_set_features(struct net_device *netdev, netdev_features_t features)
return 0; return 0;
} }
struct nfp_port *
nfp_port_from_id(struct nfp_pf *pf, enum nfp_port_type type, unsigned int id)
{
struct devlink *devlink = priv_to_devlink(pf);
struct nfp_port *port;
devl_assert_locked(devlink);
if (type != NFP_PORT_PHYS_PORT)
return NULL;
list_for_each_entry(port, &pf->ports, port_list)
if (port->eth_id == id)
return port;
return NULL;
}
struct nfp_eth_table_port *__nfp_port_get_eth_port(struct nfp_port *port) struct nfp_eth_table_port *__nfp_port_get_eth_port(struct nfp_port *port)
{ {
if (!port) if (!port)
......
...@@ -106,8 +106,6 @@ nfp_port_set_features(struct net_device *netdev, netdev_features_t features); ...@@ -106,8 +106,6 @@ nfp_port_set_features(struct net_device *netdev, netdev_features_t features);
struct nfp_port *nfp_port_from_netdev(struct net_device *netdev); struct nfp_port *nfp_port_from_netdev(struct net_device *netdev);
int nfp_port_get_port_parent_id(struct net_device *netdev, int nfp_port_get_port_parent_id(struct net_device *netdev,
struct netdev_phys_item_id *ppid); 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); struct nfp_eth_table_port *__nfp_port_get_eth_port(struct nfp_port *port);
struct nfp_eth_table_port *nfp_port_get_eth_port(struct nfp_port *port); struct nfp_eth_table_port *nfp_port_get_eth_port(struct nfp_port *port);
......
...@@ -1197,9 +1197,9 @@ struct devlink_ops { ...@@ -1197,9 +1197,9 @@ struct devlink_ops {
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int (*port_type_set)(struct devlink_port *devlink_port, int (*port_type_set)(struct devlink_port *devlink_port,
enum devlink_port_type port_type); enum devlink_port_type port_type);
int (*port_split)(struct devlink *devlink, unsigned int port_index, int (*port_split)(struct devlink *devlink, struct devlink_port *port,
unsigned int count, struct netlink_ext_ack *extack); unsigned int count, struct netlink_ext_ack *extack);
int (*port_unsplit)(struct devlink *devlink, unsigned int port_index, int (*port_unsplit)(struct devlink *devlink, struct devlink_port *port,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int (*sb_pool_get)(struct devlink *devlink, unsigned int sb_index, int (*sb_pool_get)(struct devlink *devlink, unsigned int sb_index,
u16 pool_index, u16 pool_index,
......
...@@ -1568,35 +1568,20 @@ static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb, ...@@ -1568,35 +1568,20 @@ static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
return 0; return 0;
} }
static int devlink_port_split(struct devlink *devlink, u32 port_index,
u32 count, struct netlink_ext_ack *extack)
{
if (devlink->ops->port_split)
return devlink->ops->port_split(devlink, port_index, count,
extack);
return -EOPNOTSUPP;
}
static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
{ {
struct devlink_port *devlink_port = info->user_ptr[1];
struct devlink *devlink = info->user_ptr[0]; struct devlink *devlink = info->user_ptr[0];
struct devlink_port *devlink_port;
u32 port_index;
u32 count; u32 count;
if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] || if (!info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
!info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
return -EINVAL; return -EINVAL;
if (!devlink->ops->port_split)
return -EOPNOTSUPP;
devlink_port = devlink_port_get_from_info(devlink, info);
port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
if (IS_ERR(devlink_port))
return -EINVAL;
if (!devlink_port->attrs.splittable) { if (!devlink_port->attrs.splittable) {
/* Split ports cannot be split. */ /* Split ports cannot be split. */
if (devlink_port->attrs.split) if (devlink_port->attrs.split)
...@@ -1611,29 +1596,19 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, ...@@ -1611,29 +1596,19 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
return -EINVAL; return -EINVAL;
} }
return devlink_port_split(devlink, port_index, count, info->extack); return devlink->ops->port_split(devlink, devlink_port, count,
} info->extack);
static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
struct netlink_ext_ack *extack)
{
if (devlink->ops->port_unsplit)
return devlink->ops->port_unsplit(devlink, port_index, extack);
return -EOPNOTSUPP;
} }
static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
struct genl_info *info) struct genl_info *info)
{ {
struct devlink_port *devlink_port = info->user_ptr[1];
struct devlink *devlink = info->user_ptr[0]; struct devlink *devlink = info->user_ptr[0];
u32 port_index;
if (!info->attrs[DEVLINK_ATTR_PORT_INDEX]) if (!devlink->ops->port_unsplit)
return -EINVAL; return -EOPNOTSUPP;
return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
return devlink_port_unsplit(devlink, port_index, info->extack);
} }
static int devlink_port_new_notifiy(struct devlink *devlink, static int devlink_port_new_notifiy(struct devlink *devlink,
...@@ -8672,12 +8647,14 @@ static const struct genl_small_ops devlink_nl_ops[] = { ...@@ -8672,12 +8647,14 @@ static const struct genl_small_ops devlink_nl_ops[] = {
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_port_split_doit, .doit = devlink_nl_cmd_port_split_doit,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
}, },
{ {
.cmd = DEVLINK_CMD_PORT_UNSPLIT, .cmd = DEVLINK_CMD_PORT_UNSPLIT,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
.doit = devlink_nl_cmd_port_unsplit_doit, .doit = devlink_nl_cmd_port_unsplit_doit,
.flags = GENL_ADMIN_PERM, .flags = GENL_ADMIN_PERM,
.internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
}, },
{ {
.cmd = DEVLINK_CMD_PORT_NEW, .cmd = DEVLINK_CMD_PORT_NEW,
......
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