Commit 2e246bca authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'devlink-move-port-ops-into-separate-structure'

Jiri Pirko says:

====================
devlink: move port ops into separate structure

In devlink, some of the objects have separate ops registered alongside
with the object itself. Port however have ops in devlink_ops structure.
For drivers what register multiple kinds of ports with different ops
this is not convenient.

This patchset changes does following changes:
1) Introduces devlink_port_ops with functions that allow devlink port
   to be registered passing a pointer to driver port ops. (patch #1)
2) Converts drivers to define port_ops and register ports passing the
   ops pointer. (patches #2, #3, #4, #6, #8, and #9)
3) Moves ops from devlink_ops struct to devlink_port_ops.
   (patches #5, #7, #10-15)

No functional changes.
====================

Link: https://lore.kernel.org/r/20230526102841.2226553-1-jiri@resnulli.usSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents bc638eab 4b5ed2b5
...@@ -1256,8 +1256,6 @@ static const struct devlink_ops ice_devlink_ops = { ...@@ -1256,8 +1256,6 @@ static const struct devlink_ops ice_devlink_ops = {
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
.reload_down = ice_devlink_reload_down, .reload_down = ice_devlink_reload_down,
.reload_up = ice_devlink_reload_up, .reload_up = ice_devlink_reload_up,
.port_split = ice_devlink_port_split,
.port_unsplit = ice_devlink_port_unsplit,
.eswitch_mode_get = ice_eswitch_mode_get, .eswitch_mode_get = ice_eswitch_mode_get,
.eswitch_mode_set = ice_eswitch_mode_set, .eswitch_mode_set = ice_eswitch_mode_set,
.info_get = ice_devlink_info_get, .info_get = ice_devlink_info_get,
...@@ -1512,6 +1510,11 @@ ice_devlink_set_port_split_options(struct ice_pf *pf, ...@@ -1512,6 +1510,11 @@ ice_devlink_set_port_split_options(struct ice_pf *pf,
ice_active_port_option = active_idx; ice_active_port_option = active_idx;
} }
static const struct devlink_port_ops ice_devlink_port_ops = {
.port_split = ice_devlink_port_split,
.port_unsplit = ice_devlink_port_unsplit,
};
/** /**
* ice_devlink_create_pf_port - Create a devlink port for this PF * ice_devlink_create_pf_port - Create a devlink port for this PF
* @pf: the PF to create a devlink port for * @pf: the PF to create a devlink port for
...@@ -1551,7 +1554,8 @@ int ice_devlink_create_pf_port(struct ice_pf *pf) ...@@ -1551,7 +1554,8 @@ int ice_devlink_create_pf_port(struct ice_pf *pf)
devlink_port_attrs_set(devlink_port, &attrs); devlink_port_attrs_set(devlink_port, &attrs);
devlink = priv_to_devlink(pf); devlink = priv_to_devlink(pf);
err = devlink_port_register(devlink, devlink_port, vsi->idx); err = devlink_port_register_with_ops(devlink, devlink_port, vsi->idx,
&ice_devlink_port_ops);
if (err) { if (err) {
dev_err(dev, "Failed to create devlink port for PF %d, error %d\n", dev_err(dev, "Failed to create devlink port for PF %d, error %d\n",
pf->hw.pf_id, err); pf->hw.pf_id, err);
......
...@@ -3024,13 +3024,43 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev) ...@@ -3024,13 +3024,43 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
} }
} }
static int mlx4_devlink_port_type_set(struct devlink_port *devlink_port,
enum devlink_port_type port_type)
{
struct mlx4_port_info *info = container_of(devlink_port,
struct mlx4_port_info,
devlink_port);
enum mlx4_port_type mlx4_port_type;
switch (port_type) {
case DEVLINK_PORT_TYPE_AUTO:
mlx4_port_type = MLX4_PORT_TYPE_AUTO;
break;
case DEVLINK_PORT_TYPE_ETH:
mlx4_port_type = MLX4_PORT_TYPE_ETH;
break;
case DEVLINK_PORT_TYPE_IB:
mlx4_port_type = MLX4_PORT_TYPE_IB;
break;
default:
return -EOPNOTSUPP;
}
return __set_port_type(info, mlx4_port_type);
}
static const struct devlink_port_ops mlx4_devlink_port_ops = {
.port_type_set = mlx4_devlink_port_type_set,
};
static int mlx4_init_port_info(struct mlx4_dev *dev, int port) static int mlx4_init_port_info(struct mlx4_dev *dev, int port)
{ {
struct devlink *devlink = priv_to_devlink(mlx4_priv(dev)); struct devlink *devlink = priv_to_devlink(mlx4_priv(dev));
struct mlx4_port_info *info = &mlx4_priv(dev)->port[port]; struct mlx4_port_info *info = &mlx4_priv(dev)->port[port];
int err; int err;
err = devl_port_register(devlink, &info->devlink_port, port); err = devl_port_register_with_ops(devlink, &info->devlink_port, port,
&mlx4_devlink_port_ops);
if (err) if (err)
return err; return err;
...@@ -3874,31 +3904,6 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data, ...@@ -3874,31 +3904,6 @@ static int __mlx4_init_one(struct pci_dev *pdev, int pci_dev_data,
return err; return err;
} }
static int mlx4_devlink_port_type_set(struct devlink_port *devlink_port,
enum devlink_port_type port_type)
{
struct mlx4_port_info *info = container_of(devlink_port,
struct mlx4_port_info,
devlink_port);
enum mlx4_port_type mlx4_port_type;
switch (port_type) {
case DEVLINK_PORT_TYPE_AUTO:
mlx4_port_type = MLX4_PORT_TYPE_AUTO;
break;
case DEVLINK_PORT_TYPE_ETH:
mlx4_port_type = MLX4_PORT_TYPE_ETH;
break;
case DEVLINK_PORT_TYPE_IB:
mlx4_port_type = MLX4_PORT_TYPE_IB;
break;
default:
return -EOPNOTSUPP;
}
return __set_port_type(info, mlx4_port_type);
}
static void mlx4_devlink_param_load_driverinit_values(struct devlink *devlink) static void mlx4_devlink_param_load_driverinit_values(struct devlink *devlink)
{ {
struct mlx4_priv *priv = devlink_priv(devlink); struct mlx4_priv *priv = devlink_priv(devlink);
...@@ -3983,7 +3988,6 @@ static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a ...@@ -3983,7 +3988,6 @@ static int mlx4_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
} }
static const struct devlink_ops mlx4_devlink_ops = { static const struct devlink_ops mlx4_devlink_ops = {
.port_type_set = mlx4_devlink_port_type_set,
.reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT), .reload_actions = BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT),
.reload_down = mlx4_devlink_reload_down, .reload_down = mlx4_devlink_reload_down,
.reload_up = mlx4_devlink_reload_up, .reload_up = mlx4_devlink_reload_up,
......
...@@ -310,8 +310,6 @@ static const struct devlink_ops mlx5_devlink_ops = { ...@@ -310,8 +310,6 @@ static const struct devlink_ops mlx5_devlink_ops = {
.eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get, .eswitch_inline_mode_get = mlx5_devlink_eswitch_inline_mode_get,
.eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set, .eswitch_encap_mode_set = mlx5_devlink_eswitch_encap_mode_set,
.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get, .eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
.port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
.port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
.rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set, .rate_leaf_tx_share_set = mlx5_esw_devlink_rate_leaf_tx_share_set,
.rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set, .rate_leaf_tx_max_set = mlx5_esw_devlink_rate_leaf_tx_max_set,
.rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set, .rate_node_tx_share_set = mlx5_esw_devlink_rate_node_tx_share_set,
...@@ -319,16 +317,9 @@ static const struct devlink_ops mlx5_devlink_ops = { ...@@ -319,16 +317,9 @@ static const struct devlink_ops mlx5_devlink_ops = {
.rate_node_new = mlx5_esw_devlink_rate_node_new, .rate_node_new = mlx5_esw_devlink_rate_node_new,
.rate_node_del = mlx5_esw_devlink_rate_node_del, .rate_node_del = mlx5_esw_devlink_rate_node_del,
.rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set, .rate_leaf_parent_set = mlx5_esw_devlink_rate_parent_set,
.port_fn_roce_get = mlx5_devlink_port_fn_roce_get,
.port_fn_roce_set = mlx5_devlink_port_fn_roce_set,
.port_fn_migratable_get = mlx5_devlink_port_fn_migratable_get,
.port_fn_migratable_set = mlx5_devlink_port_fn_migratable_set,
#endif #endif
#ifdef CONFIG_MLX5_SF_MANAGER #ifdef CONFIG_MLX5_SF_MANAGER
.port_new = mlx5_devlink_sf_port_new, .port_new = mlx5_devlink_sf_port_new,
.port_del = mlx5_devlink_sf_port_del,
.port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
.port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
#endif #endif
.flash_update = mlx5_devlink_flash_update, .flash_update = mlx5_devlink_flash_update,
.info_get = mlx5_devlink_info_get, .info_get = mlx5_devlink_info_get,
......
...@@ -65,6 +65,15 @@ static void mlx5_esw_dl_port_free(struct devlink_port *dl_port) ...@@ -65,6 +65,15 @@ static void mlx5_esw_dl_port_free(struct devlink_port *dl_port)
kfree(dl_port); kfree(dl_port);
} }
static const struct devlink_port_ops mlx5_esw_dl_port_ops = {
.port_fn_hw_addr_get = mlx5_devlink_port_fn_hw_addr_get,
.port_fn_hw_addr_set = mlx5_devlink_port_fn_hw_addr_set,
.port_fn_roce_get = mlx5_devlink_port_fn_roce_get,
.port_fn_roce_set = mlx5_devlink_port_fn_roce_set,
.port_fn_migratable_get = mlx5_devlink_port_fn_migratable_get,
.port_fn_migratable_set = mlx5_devlink_port_fn_migratable_set,
};
int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_num) int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_num)
{ {
struct mlx5_core_dev *dev = esw->dev; struct mlx5_core_dev *dev = esw->dev;
...@@ -87,7 +96,8 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_ ...@@ -87,7 +96,8 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_
devlink = priv_to_devlink(dev); devlink = priv_to_devlink(dev);
dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, vport_num); dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, vport_num);
err = devl_port_register(devlink, dl_port, dl_port_index); err = devl_port_register_with_ops(devlink, dl_port, dl_port_index,
&mlx5_esw_dl_port_ops);
if (err) if (err)
goto reg_err; goto reg_err;
...@@ -134,6 +144,20 @@ struct devlink_port *mlx5_esw_offloads_devlink_port(struct mlx5_eswitch *esw, u1 ...@@ -134,6 +144,20 @@ struct devlink_port *mlx5_esw_offloads_devlink_port(struct mlx5_eswitch *esw, u1
return IS_ERR(vport) ? ERR_CAST(vport) : vport->dl_port; return IS_ERR(vport) ? ERR_CAST(vport) : vport->dl_port;
} }
static const struct devlink_port_ops mlx5_esw_dl_sf_port_ops = {
#ifdef CONFIG_MLX5_SF_MANAGER
.port_del = mlx5_devlink_sf_port_del,
#endif
.port_fn_hw_addr_get = mlx5_devlink_port_fn_hw_addr_get,
.port_fn_hw_addr_set = mlx5_devlink_port_fn_hw_addr_set,
.port_fn_roce_get = mlx5_devlink_port_fn_roce_get,
.port_fn_roce_set = mlx5_devlink_port_fn_roce_set,
#ifdef CONFIG_MLX5_SF_MANAGER
.port_fn_state_get = mlx5_devlink_sf_port_fn_state_get,
.port_fn_state_set = mlx5_devlink_sf_port_fn_state_set,
#endif
};
int mlx5_esw_devlink_sf_port_register(struct mlx5_eswitch *esw, struct devlink_port *dl_port, int mlx5_esw_devlink_sf_port_register(struct mlx5_eswitch *esw, struct devlink_port *dl_port,
u16 vport_num, u32 controller, u32 sfnum) u16 vport_num, u32 controller, u32 sfnum)
{ {
...@@ -156,7 +180,8 @@ int mlx5_esw_devlink_sf_port_register(struct mlx5_eswitch *esw, struct devlink_p ...@@ -156,7 +180,8 @@ int mlx5_esw_devlink_sf_port_register(struct mlx5_eswitch *esw, struct devlink_p
devlink_port_attrs_pci_sf_set(dl_port, controller, pfnum, sfnum, !!controller); devlink_port_attrs_pci_sf_set(dl_port, controller, pfnum, sfnum, !!controller);
devlink = priv_to_devlink(dev); devlink = priv_to_devlink(dev);
dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, vport_num); dl_port_index = mlx5_esw_vport_to_devlink_port_index(dev, vport_num);
err = devl_port_register(devlink, dl_port, dl_port_index); err = devl_port_register_with_ops(devlink, dl_port, dl_port_index,
&mlx5_esw_dl_sf_port_ops);
if (err) if (err)
return err; return err;
......
...@@ -506,10 +506,10 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink, ...@@ -506,10 +506,10 @@ int mlx5_devlink_eswitch_encap_mode_set(struct devlink *devlink,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink,
enum devlink_eswitch_encap_mode *encap); enum devlink_eswitch_encap_mode *encap);
int mlx5_devlink_port_function_hw_addr_get(struct devlink_port *port, int mlx5_devlink_port_fn_hw_addr_get(struct devlink_port *port,
u8 *hw_addr, int *hw_addr_len, u8 *hw_addr, int *hw_addr_len,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int mlx5_devlink_port_function_hw_addr_set(struct devlink_port *port, int mlx5_devlink_port_fn_hw_addr_set(struct devlink_port *port,
const u8 *hw_addr, int hw_addr_len, const u8 *hw_addr, int hw_addr_len,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int mlx5_devlink_port_fn_roce_get(struct devlink_port *port, bool *is_enabled, int mlx5_devlink_port_fn_roce_get(struct devlink_port *port, bool *is_enabled,
......
...@@ -3957,7 +3957,7 @@ is_port_function_supported(struct mlx5_eswitch *esw, u16 vport_num) ...@@ -3957,7 +3957,7 @@ is_port_function_supported(struct mlx5_eswitch *esw, u16 vport_num)
mlx5_esw_is_sf_vport(esw, vport_num); mlx5_esw_is_sf_vport(esw, vport_num);
} }
int mlx5_devlink_port_function_hw_addr_get(struct devlink_port *port, int mlx5_devlink_port_fn_hw_addr_get(struct devlink_port *port,
u8 *hw_addr, int *hw_addr_len, u8 *hw_addr, int *hw_addr_len,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
...@@ -3986,7 +3986,7 @@ int mlx5_devlink_port_function_hw_addr_get(struct devlink_port *port, ...@@ -3986,7 +3986,7 @@ int mlx5_devlink_port_function_hw_addr_get(struct devlink_port *port,
return 0; return 0;
} }
int mlx5_devlink_port_function_hw_addr_set(struct devlink_port *port, int mlx5_devlink_port_fn_hw_addr_set(struct devlink_port *port,
const u8 *hw_addr, int hw_addr_len, const u8 *hw_addr, int hw_addr_len,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
......
...@@ -1723,8 +1723,6 @@ static const struct devlink_ops mlxsw_devlink_ops = { ...@@ -1723,8 +1723,6 @@ static const struct devlink_ops mlxsw_devlink_ops = {
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE), BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE),
.reload_down = mlxsw_devlink_core_bus_device_reload_down, .reload_down = mlxsw_devlink_core_bus_device_reload_down,
.reload_up = mlxsw_devlink_core_bus_device_reload_up, .reload_up = mlxsw_devlink_core_bus_device_reload_up,
.port_split = mlxsw_devlink_port_split,
.port_unsplit = mlxsw_devlink_port_unsplit,
.sb_pool_get = mlxsw_devlink_sb_pool_get, .sb_pool_get = mlxsw_devlink_sb_pool_get,
.sb_pool_set = mlxsw_devlink_sb_pool_set, .sb_pool_set = mlxsw_devlink_sb_pool_set,
.sb_port_pool_get = mlxsw_devlink_sb_port_pool_get, .sb_port_pool_get = mlxsw_devlink_sb_port_pool_get,
...@@ -3116,6 +3114,11 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core, ...@@ -3116,6 +3114,11 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
} }
EXPORT_SYMBOL(mlxsw_core_res_get); EXPORT_SYMBOL(mlxsw_core_res_get);
static const struct devlink_port_ops mlxsw_devlink_port_ops = {
.port_split = mlxsw_devlink_port_split,
.port_unsplit = mlxsw_devlink_port_unsplit,
};
static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u16 local_port, static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u16 local_port,
enum devlink_port_flavour flavour, enum devlink_port_flavour flavour,
u8 slot_index, u32 port_number, bool split, u8 slot_index, u32 port_number, bool split,
...@@ -3150,7 +3153,8 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u16 local_port, ...@@ -3150,7 +3153,8 @@ static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u16 local_port,
devlink_port_linecard_set(devlink_port, devlink_port_linecard_set(devlink_port,
linecard->devlink_linecard); linecard->devlink_linecard);
} }
err = devl_port_register(devlink, devlink_port, local_port); err = devl_port_register_with_ops(devlink, devlink_port, local_port,
&mlxsw_devlink_port_ops);
if (err) if (err)
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port)); memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
return err; return err;
......
...@@ -311,8 +311,6 @@ nfp_devlink_flash_update(struct devlink *devlink, ...@@ -311,8 +311,6 @@ nfp_devlink_flash_update(struct devlink *devlink,
} }
const struct devlink_ops nfp_devlink_ops = { const struct devlink_ops nfp_devlink_ops = {
.port_split = nfp_devlink_port_split,
.port_unsplit = nfp_devlink_port_unsplit,
.sb_pool_get = nfp_devlink_sb_pool_get, .sb_pool_get = nfp_devlink_sb_pool_get,
.sb_pool_set = nfp_devlink_sb_pool_set, .sb_pool_set = nfp_devlink_sb_pool_set,
.eswitch_mode_get = nfp_devlink_eswitch_mode_get, .eswitch_mode_get = nfp_devlink_eswitch_mode_get,
...@@ -321,6 +319,11 @@ const struct devlink_ops nfp_devlink_ops = { ...@@ -321,6 +319,11 @@ const struct devlink_ops nfp_devlink_ops = {
.flash_update = nfp_devlink_flash_update, .flash_update = nfp_devlink_flash_update,
}; };
static const struct devlink_port_ops nfp_devlink_port_ops = {
.port_split = nfp_devlink_port_split,
.port_unsplit = nfp_devlink_port_unsplit,
};
int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port) int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
{ {
struct devlink_port_attrs attrs = {}; struct devlink_port_attrs attrs = {};
...@@ -351,7 +354,8 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port) ...@@ -351,7 +354,8 @@ int nfp_devlink_port_register(struct nfp_app *app, struct nfp_port *port)
devlink = priv_to_devlink(app->pf); devlink = priv_to_devlink(app->pf);
return devl_port_register(devlink, &port->dl_port, port->eth_id); return devl_port_register_with_ops(devlink, &port->dl_port,
port->eth_id, &nfp_devlink_port_ops);
} }
void nfp_devlink_port_unregister(struct nfp_port *port) void nfp_devlink_port_unregister(struct nfp_port *port)
......
...@@ -25,40 +25,6 @@ struct efx_devlink { ...@@ -25,40 +25,6 @@ struct efx_devlink {
}; };
#ifdef CONFIG_SFC_SRIOV #ifdef CONFIG_SFC_SRIOV
static void efx_devlink_del_port(struct devlink_port *dl_port)
{
if (!dl_port)
return;
devl_port_unregister(dl_port);
}
static int efx_devlink_add_port(struct efx_nic *efx,
struct mae_mport_desc *mport)
{
bool external = false;
if (!ef100_mport_on_local_intf(efx, mport))
external = true;
switch (mport->mport_type) {
case MAE_MPORT_DESC_MPORT_TYPE_VNIC:
if (mport->vf_idx != MAE_MPORT_DESC_VF_IDX_NULL)
devlink_port_attrs_pci_vf_set(&mport->dl_port, 0, mport->pf_idx,
mport->vf_idx,
external);
else
devlink_port_attrs_pci_pf_set(&mport->dl_port, 0, mport->pf_idx,
external);
break;
default:
/* MAE_MPORT_DESC_MPORT_ALIAS and UNDEFINED */
return 0;
}
mport->dl_port.index = mport->mport_id;
return devl_port_register(efx->devlink, &mport->dl_port, mport->mport_id);
}
static int efx_devlink_port_addr_get(struct devlink_port *port, u8 *hw_addr, static int efx_devlink_port_addr_get(struct devlink_port *port, u8 *hw_addr,
int *hw_addr_len, int *hw_addr_len,
...@@ -158,6 +124,48 @@ static int efx_devlink_port_addr_set(struct devlink_port *port, ...@@ -158,6 +124,48 @@ static int efx_devlink_port_addr_set(struct devlink_port *port,
return rc; return rc;
} }
static const struct devlink_port_ops sfc_devlink_port_ops = {
.port_fn_hw_addr_get = efx_devlink_port_addr_get,
.port_fn_hw_addr_set = efx_devlink_port_addr_set,
};
static void efx_devlink_del_port(struct devlink_port *dl_port)
{
if (!dl_port)
return;
devl_port_unregister(dl_port);
}
static int efx_devlink_add_port(struct efx_nic *efx,
struct mae_mport_desc *mport)
{
bool external = false;
if (!ef100_mport_on_local_intf(efx, mport))
external = true;
switch (mport->mport_type) {
case MAE_MPORT_DESC_MPORT_TYPE_VNIC:
if (mport->vf_idx != MAE_MPORT_DESC_VF_IDX_NULL)
devlink_port_attrs_pci_vf_set(&mport->dl_port, 0, mport->pf_idx,
mport->vf_idx,
external);
else
devlink_port_attrs_pci_pf_set(&mport->dl_port, 0, mport->pf_idx,
external);
break;
default:
/* MAE_MPORT_DESC_MPORT_ALIAS and UNDEFINED */
return 0;
}
mport->dl_port.index = mport->mport_id;
return devl_port_register_with_ops(efx->devlink, &mport->dl_port,
mport->mport_id,
&sfc_devlink_port_ops);
}
#endif #endif
static int efx_devlink_info_nvram_partition(struct efx_nic *efx, static int efx_devlink_info_nvram_partition(struct efx_nic *efx,
...@@ -609,10 +617,6 @@ static int efx_devlink_info_get(struct devlink *devlink, ...@@ -609,10 +617,6 @@ static int efx_devlink_info_get(struct devlink *devlink,
static const struct devlink_ops sfc_devlink_ops = { static const struct devlink_ops sfc_devlink_ops = {
.info_get = efx_devlink_info_get, .info_get = efx_devlink_info_get,
#ifdef CONFIG_SFC_SRIOV
.port_function_hw_addr_get = efx_devlink_port_addr_get,
.port_function_hw_addr_set = efx_devlink_port_addr_set,
#endif
}; };
#ifdef CONFIG_SFC_SRIOV #ifdef CONFIG_SFC_SRIOV
......
...@@ -123,6 +123,7 @@ struct devlink_port { ...@@ -123,6 +123,7 @@ struct devlink_port {
struct list_head list; struct list_head list;
struct list_head region_list; struct list_head region_list;
struct devlink *devlink; struct devlink *devlink;
const struct devlink_port_ops *ops;
unsigned int index; unsigned int index;
spinlock_t type_lock; /* Protects type and type_eth/ib spinlock_t type_lock; /* Protects type and type_eth/ib
* structures consistency. * structures consistency.
...@@ -1273,12 +1274,6 @@ struct devlink_ops { ...@@ -1273,12 +1274,6 @@ struct devlink_ops {
int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action, int (*reload_up)(struct devlink *devlink, enum devlink_reload_action action,
enum devlink_reload_limit limit, u32 *actions_performed, enum devlink_reload_limit limit, u32 *actions_performed,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int (*port_type_set)(struct devlink_port *devlink_port,
enum devlink_port_type port_type);
int (*port_split)(struct devlink *devlink, struct devlink_port *port,
unsigned int count, struct netlink_ext_ack *extack);
int (*port_unsplit)(struct devlink *devlink, struct devlink_port *port,
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,
struct devlink_sb_pool_info *pool_info); struct devlink_sb_pool_info *pool_info);
...@@ -1434,67 +1429,6 @@ struct devlink_ops { ...@@ -1434,67 +1429,6 @@ struct devlink_ops {
int (*trap_policer_counter_get)(struct devlink *devlink, int (*trap_policer_counter_get)(struct devlink *devlink,
const struct devlink_trap_policer *policer, const struct devlink_trap_policer *policer,
u64 *p_drops); u64 *p_drops);
/**
* @port_function_hw_addr_get: Port function's hardware address get function.
*
* Should be used by device drivers to report the hardware address of a function managed
* by the devlink port. Driver should return -EOPNOTSUPP if it doesn't support port
* function handling for a particular port.
*
* Note: @extack can be NULL when port notifier queries the port function.
*/
int (*port_function_hw_addr_get)(struct devlink_port *port, u8 *hw_addr,
int *hw_addr_len,
struct netlink_ext_ack *extack);
/**
* @port_function_hw_addr_set: Port function's hardware address set function.
*
* Should be used by device drivers to set the hardware address of a function managed
* by the devlink port. Driver should return -EOPNOTSUPP if it doesn't support port
* function handling for a particular port.
*/
int (*port_function_hw_addr_set)(struct devlink_port *port,
const u8 *hw_addr, int hw_addr_len,
struct netlink_ext_ack *extack);
/**
* @port_fn_roce_get: Port function's roce get function.
*
* Query RoCE state of a function managed by the devlink port.
* Return -EOPNOTSUPP if port function RoCE handling is not supported.
*/
int (*port_fn_roce_get)(struct devlink_port *devlink_port,
bool *is_enable,
struct netlink_ext_ack *extack);
/**
* @port_fn_roce_set: Port function's roce set function.
*
* Enable/Disable the RoCE state of a function managed by the devlink
* port.
* Return -EOPNOTSUPP if port function RoCE handling is not supported.
*/
int (*port_fn_roce_set)(struct devlink_port *devlink_port,
bool enable, struct netlink_ext_ack *extack);
/**
* @port_fn_migratable_get: Port function's migratable get function.
*
* Query migratable state of a function managed by the devlink port.
* Return -EOPNOTSUPP if port function migratable handling is not
* supported.
*/
int (*port_fn_migratable_get)(struct devlink_port *devlink_port,
bool *is_enable,
struct netlink_ext_ack *extack);
/**
* @port_fn_migratable_set: Port function's migratable set function.
*
* Enable/Disable migratable state of a function managed by the devlink
* port.
* Return -EOPNOTSUPP if port function migratable handling is not
* supported.
*/
int (*port_fn_migratable_set)(struct devlink_port *devlink_port,
bool enable,
struct netlink_ext_ack *extack);
/** /**
* port_new() - Add a new port function of a specified flavor * port_new() - Add a new port function of a specified flavor
* @devlink: Devlink instance * @devlink: Devlink instance
...@@ -1513,53 +1447,6 @@ struct devlink_ops { ...@@ -1513,53 +1447,6 @@ struct devlink_ops {
int (*port_new)(struct devlink *devlink, int (*port_new)(struct devlink *devlink,
const struct devlink_port_new_attrs *attrs, const struct devlink_port_new_attrs *attrs,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
/**
* port_del() - Delete a port function
* @devlink: Devlink instance
* @port: The devlink port
* @extack: extack for reporting error messages
*
* Devlink core will call this device driver function upon user request
* to delete a previously created port function
*
* Notes:
* - On success, drivers must unregister the corresponding devlink
* port
*
* Return: 0 on success, negative value otherwise.
*/
int (*port_del)(struct devlink *devlink, struct devlink_port *port,
struct netlink_ext_ack *extack);
/**
* port_fn_state_get() - Get the state of a port function
* @devlink: Devlink instance
* @port: The devlink port
* @state: Admin configured state
* @opstate: Current operational state
* @extack: extack for reporting error messages
*
* Reports the admin and operational state of a devlink port function
*
* Return: 0 on success, negative value otherwise.
*/
int (*port_fn_state_get)(struct devlink_port *port,
enum devlink_port_fn_state *state,
enum devlink_port_fn_opstate *opstate,
struct netlink_ext_ack *extack);
/**
* port_fn_state_set() - Set the admin state of a port function
* @devlink: Devlink instance
* @port: The devlink port
* @state: Admin state
* @extack: extack for reporting error messages
*
* Set the admin state of a devlink port function
*
* Return: 0 on success, negative value otherwise.
*/
int (*port_fn_state_set)(struct devlink_port *port,
enum devlink_port_fn_state state,
struct netlink_ext_ack *extack);
/** /**
* Rate control callbacks. * Rate control callbacks.
...@@ -1649,15 +1536,116 @@ void devl_unregister(struct devlink *devlink); ...@@ -1649,15 +1536,116 @@ void devl_unregister(struct devlink *devlink);
void devlink_register(struct devlink *devlink); void devlink_register(struct devlink *devlink);
void devlink_unregister(struct devlink *devlink); void devlink_unregister(struct devlink *devlink);
void devlink_free(struct devlink *devlink); void devlink_free(struct devlink *devlink);
/**
* struct devlink_port_ops - Port operations
* @port_split: Callback used to split the port into multiple ones.
* @port_unsplit: Callback used to unsplit the port group back into
* a single port.
* @port_type_set: Callback used to set a type of a port.
* @port_del: Callback used to delete selected port along with related function.
* Devlink core calls this upon user request to delete
* a port previously created by devlink_ops->port_new().
* @port_fn_hw_addr_get: Callback used to set port function's hardware address.
* Should be used by device drivers to report
* the hardware address of a function managed
* by the devlink port.
* @port_fn_hw_addr_set: Callback used to set port function's hardware address.
* Should be used by device drivers to set the hardware
* address of a function managed by the devlink port.
* @port_fn_roce_get: Callback used to get port function's RoCE capability.
* Should be used by device drivers to report
* the current state of RoCE capability of a function
* managed by the devlink port.
* @port_fn_roce_set: Callback used to set port function's RoCE capability.
* Should be used by device drivers to enable/disable
* RoCE capability of a function managed
* by the devlink port.
* @port_fn_migratable_get: Callback used to get port function's migratable
* capability. Should be used by device drivers
* to report the current state of migratable capability
* of a function managed by the devlink port.
* @port_fn_migratable_set: Callback used to set port function's migratable
* capability. Should be used by device drivers
* to enable/disable migratable capability of
* a function managed by the devlink port.
* @port_fn_state_get: Callback used to get port function's state.
* Should be used by device drivers to report
* the current admin and operational state of a
* function managed by the devlink port.
* @port_fn_state_set: Callback used to get port function's state.
* Should be used by device drivers set
* the admin state of a function managed
* by the devlink port.
*
* Note: Driver should return -EOPNOTSUPP if it doesn't support
* port function (@port_fn_*) handling for a particular port.
*/
struct devlink_port_ops {
int (*port_split)(struct devlink *devlink, struct devlink_port *port,
unsigned int count, struct netlink_ext_ack *extack);
int (*port_unsplit)(struct devlink *devlink, struct devlink_port *port,
struct netlink_ext_ack *extack);
int (*port_type_set)(struct devlink_port *devlink_port,
enum devlink_port_type port_type);
int (*port_del)(struct devlink *devlink, struct devlink_port *port,
struct netlink_ext_ack *extack);
int (*port_fn_hw_addr_get)(struct devlink_port *port, u8 *hw_addr,
int *hw_addr_len,
struct netlink_ext_ack *extack);
int (*port_fn_hw_addr_set)(struct devlink_port *port,
const u8 *hw_addr, int hw_addr_len,
struct netlink_ext_ack *extack);
int (*port_fn_roce_get)(struct devlink_port *devlink_port,
bool *is_enable,
struct netlink_ext_ack *extack);
int (*port_fn_roce_set)(struct devlink_port *devlink_port,
bool enable, struct netlink_ext_ack *extack);
int (*port_fn_migratable_get)(struct devlink_port *devlink_port,
bool *is_enable,
struct netlink_ext_ack *extack);
int (*port_fn_migratable_set)(struct devlink_port *devlink_port,
bool enable,
struct netlink_ext_ack *extack);
int (*port_fn_state_get)(struct devlink_port *port,
enum devlink_port_fn_state *state,
enum devlink_port_fn_opstate *opstate,
struct netlink_ext_ack *extack);
int (*port_fn_state_set)(struct devlink_port *port,
enum devlink_port_fn_state state,
struct netlink_ext_ack *extack);
};
void devlink_port_init(struct devlink *devlink, void devlink_port_init(struct devlink *devlink,
struct devlink_port *devlink_port); struct devlink_port *devlink_port);
void devlink_port_fini(struct devlink_port *devlink_port); void devlink_port_fini(struct devlink_port *devlink_port);
int devl_port_register(struct devlink *devlink,
int devl_port_register_with_ops(struct devlink *devlink,
struct devlink_port *devlink_port, struct devlink_port *devlink_port,
unsigned int port_index); unsigned int port_index,
int devlink_port_register(struct devlink *devlink, const struct devlink_port_ops *ops);
static inline int devl_port_register(struct devlink *devlink,
struct devlink_port *devlink_port, struct devlink_port *devlink_port,
unsigned int port_index); unsigned int port_index)
{
return devl_port_register_with_ops(devlink, devlink_port,
port_index, NULL);
}
int devlink_port_register_with_ops(struct devlink *devlink,
struct devlink_port *devlink_port,
unsigned int port_index,
const struct devlink_port_ops *ops);
static inline int devlink_port_register(struct devlink *devlink,
struct devlink_port *devlink_port,
unsigned int port_index)
{
return devlink_port_register_with_ops(devlink, devlink_port,
port_index, NULL);
}
void devl_port_unregister(struct devlink_port *devlink_port); void devl_port_unregister(struct devlink_port *devlink_port);
void devlink_port_unregister(struct devlink_port *devlink_port); void devlink_port_unregister(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);
......
...@@ -447,18 +447,18 @@ static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps, ...@@ -447,18 +447,18 @@ static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps,
caps->value |= cap; caps->value |= cap;
} }
static int devlink_port_fn_roce_fill(const struct devlink_ops *ops, static int devlink_port_fn_roce_fill(struct devlink_port *devlink_port,
struct devlink_port *devlink_port,
struct nla_bitfield32 *caps, struct nla_bitfield32 *caps,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
bool is_enable; bool is_enable;
int err; int err;
if (!ops->port_fn_roce_get) if (!devlink_port->ops->port_fn_roce_get)
return 0; return 0;
err = ops->port_fn_roce_get(devlink_port, &is_enable, extack); err = devlink_port->ops->port_fn_roce_get(devlink_port, &is_enable,
extack);
if (err) { if (err) {
if (err == -EOPNOTSUPP) if (err == -EOPNOTSUPP)
return 0; return 0;
...@@ -469,19 +469,19 @@ static int devlink_port_fn_roce_fill(const struct devlink_ops *ops, ...@@ -469,19 +469,19 @@ static int devlink_port_fn_roce_fill(const struct devlink_ops *ops,
return 0; return 0;
} }
static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops, static int devlink_port_fn_migratable_fill(struct devlink_port *devlink_port,
struct devlink_port *devlink_port,
struct nla_bitfield32 *caps, struct nla_bitfield32 *caps,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
bool is_enable; bool is_enable;
int err; int err;
if (!ops->port_fn_migratable_get || if (!devlink_port->ops->port_fn_migratable_get ||
devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
return 0; return 0;
err = ops->port_fn_migratable_get(devlink_port, &is_enable, extack); err = devlink_port->ops->port_fn_migratable_get(devlink_port,
&is_enable, extack);
if (err) { if (err) {
if (err == -EOPNOTSUPP) if (err == -EOPNOTSUPP)
return 0; return 0;
...@@ -492,8 +492,7 @@ static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops, ...@@ -492,8 +492,7 @@ static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops,
return 0; return 0;
} }
static int devlink_port_fn_caps_fill(const struct devlink_ops *ops, static int devlink_port_fn_caps_fill(struct devlink_port *devlink_port,
struct devlink_port *devlink_port,
struct sk_buff *msg, struct sk_buff *msg,
struct netlink_ext_ack *extack, struct netlink_ext_ack *extack,
bool *msg_updated) bool *msg_updated)
...@@ -501,11 +500,11 @@ static int devlink_port_fn_caps_fill(const struct devlink_ops *ops, ...@@ -501,11 +500,11 @@ static int devlink_port_fn_caps_fill(const struct devlink_ops *ops,
struct nla_bitfield32 caps = {}; struct nla_bitfield32 caps = {};
int err; int err;
err = devlink_port_fn_roce_fill(ops, devlink_port, &caps, extack); err = devlink_port_fn_roce_fill(devlink_port, &caps, extack);
if (err) if (err)
return err; return err;
err = devlink_port_fn_migratable_fill(ops, devlink_port, &caps, extack); err = devlink_port_fn_migratable_fill(devlink_port, &caps, extack);
if (err) if (err)
return err; return err;
...@@ -691,8 +690,7 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg, ...@@ -691,8 +690,7 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
return 0; return 0;
} }
static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops, static int devlink_port_fn_hw_addr_fill(struct devlink_port *port,
struct devlink_port *port,
struct sk_buff *msg, struct sk_buff *msg,
struct netlink_ext_ack *extack, struct netlink_ext_ack *extack,
bool *msg_updated) bool *msg_updated)
...@@ -701,10 +699,10 @@ static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops, ...@@ -701,10 +699,10 @@ static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
int hw_addr_len; int hw_addr_len;
int err; int err;
if (!ops->port_function_hw_addr_get) if (!port->ops->port_fn_hw_addr_get)
return 0; return 0;
err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len, err = port->ops->port_fn_hw_addr_get(port, hw_addr, &hw_addr_len,
extack); extack);
if (err) { if (err) {
if (err == -EOPNOTSUPP) if (err == -EOPNOTSUPP)
...@@ -789,8 +787,7 @@ devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate) ...@@ -789,8 +787,7 @@ devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED; opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
} }
static int devlink_port_fn_state_fill(const struct devlink_ops *ops, static int devlink_port_fn_state_fill(struct devlink_port *port,
struct devlink_port *port,
struct sk_buff *msg, struct sk_buff *msg,
struct netlink_ext_ack *extack, struct netlink_ext_ack *extack,
bool *msg_updated) bool *msg_updated)
...@@ -799,10 +796,10 @@ static int devlink_port_fn_state_fill(const struct devlink_ops *ops, ...@@ -799,10 +796,10 @@ static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
enum devlink_port_fn_state state; enum devlink_port_fn_state state;
int err; int err;
if (!ops->port_fn_state_get) if (!port->ops->port_fn_state_get)
return 0; return 0;
err = ops->port_fn_state_get(port, &state, &opstate, extack); err = port->ops->port_fn_state_get(port, &state, &opstate, extack);
if (err) { if (err) {
if (err == -EOPNOTSUPP) if (err == -EOPNOTSUPP)
return 0; return 0;
...@@ -829,18 +826,16 @@ static int ...@@ -829,18 +826,16 @@ static int
devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable, devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct devlink_ops *ops = devlink_port->devlink->ops; return devlink_port->ops->port_fn_migratable_set(devlink_port, enable,
extack);
return ops->port_fn_migratable_set(devlink_port, enable, extack);
} }
static int static int
devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable, devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct devlink_ops *ops = devlink_port->devlink->ops; return devlink_port->ops->port_fn_roce_set(devlink_port, enable,
extack);
return ops->port_fn_roce_set(devlink_port, enable, extack);
} }
static int devlink_port_fn_caps_set(struct devlink_port *devlink_port, static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
...@@ -874,7 +869,6 @@ static int ...@@ -874,7 +869,6 @@ static int
devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port, devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct devlink_ops *ops;
struct nlattr *function_attr; struct nlattr *function_attr;
bool msg_updated = false; bool msg_updated = false;
int err; int err;
...@@ -883,16 +877,13 @@ devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *por ...@@ -883,16 +877,13 @@ devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *por
if (!function_attr) if (!function_attr)
return -EMSGSIZE; return -EMSGSIZE;
ops = port->devlink->ops; err = devlink_port_fn_hw_addr_fill(port, msg, extack, &msg_updated);
err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
&msg_updated);
if (err) if (err)
goto out; goto out;
err = devlink_port_fn_caps_fill(ops, port, msg, extack, err = devlink_port_fn_caps_fill(port, msg, extack, &msg_updated);
&msg_updated);
if (err) if (err)
goto out; goto out;
err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated); err = devlink_port_fn_state_fill(port, msg, extack, &msg_updated);
out: out:
if (err || !msg_updated) if (err || !msg_updated)
nla_nest_cancel(msg, function_attr); nla_nest_cancel(msg, function_attr);
...@@ -1137,14 +1128,13 @@ static int devlink_port_type_set(struct devlink_port *devlink_port, ...@@ -1137,14 +1128,13 @@ static int devlink_port_type_set(struct devlink_port *devlink_port,
{ {
int err; int err;
if (!devlink_port->devlink->ops->port_type_set) if (!devlink_port->ops->port_type_set)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (port_type == devlink_port->type) if (port_type == devlink_port->type)
return 0; return 0;
err = devlink_port->devlink->ops->port_type_set(devlink_port, err = devlink_port->ops->port_type_set(devlink_port, port_type);
port_type);
if (err) if (err)
return err; return err;
...@@ -1157,7 +1147,6 @@ static int devlink_port_function_hw_addr_set(struct devlink_port *port, ...@@ -1157,7 +1147,6 @@ static int devlink_port_function_hw_addr_set(struct devlink_port *port,
const struct nlattr *attr, const struct nlattr *attr,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct devlink_ops *ops = port->devlink->ops;
const u8 *hw_addr; const u8 *hw_addr;
int hw_addr_len; int hw_addr_len;
...@@ -1178,7 +1167,7 @@ static int devlink_port_function_hw_addr_set(struct devlink_port *port, ...@@ -1178,7 +1167,7 @@ static int devlink_port_function_hw_addr_set(struct devlink_port *port,
} }
} }
return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len, return port->ops->port_fn_hw_addr_set(port, hw_addr, hw_addr_len,
extack); extack);
} }
...@@ -1187,22 +1176,20 @@ static int devlink_port_fn_state_set(struct devlink_port *port, ...@@ -1187,22 +1176,20 @@ static int devlink_port_fn_state_set(struct devlink_port *port,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
enum devlink_port_fn_state state; enum devlink_port_fn_state state;
const struct devlink_ops *ops;
state = nla_get_u8(attr); state = nla_get_u8(attr);
ops = port->devlink->ops; return port->ops->port_fn_state_set(port, state, extack);
return ops->port_fn_state_set(port, state, extack);
} }
static int devlink_port_function_validate(struct devlink_port *devlink_port, static int devlink_port_function_validate(struct devlink_port *devlink_port,
struct nlattr **tb, struct nlattr **tb,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
const struct devlink_ops *ops = devlink_port->devlink->ops; const struct devlink_port_ops *ops = devlink_port->ops;
struct nlattr *attr; struct nlattr *attr;
if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] && if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] &&
!ops->port_function_hw_addr_set) { !ops->port_fn_hw_addr_set) {
NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR], NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
"Port doesn't support function attributes"); "Port doesn't support function attributes");
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -1320,7 +1307,7 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, ...@@ -1320,7 +1307,7 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT)) if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
return -EINVAL; return -EINVAL;
if (!devlink->ops->port_split) if (!devlink_port->ops->port_split)
return -EOPNOTSUPP; return -EOPNOTSUPP;
count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]); count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
...@@ -1339,7 +1326,7 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb, ...@@ -1339,7 +1326,7 @@ static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
return -EINVAL; return -EINVAL;
} }
return devlink->ops->port_split(devlink, devlink_port, count, return devlink_port->ops->port_split(devlink, devlink_port, count,
info->extack); info->extack);
} }
...@@ -1349,9 +1336,9 @@ static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb, ...@@ -1349,9 +1336,9 @@ static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
struct devlink_port *devlink_port = info->user_ptr[1]; struct devlink_port *devlink_port = info->user_ptr[1];
struct devlink *devlink = info->user_ptr[0]; struct devlink *devlink = info->user_ptr[0];
if (!devlink->ops->port_unsplit) if (!devlink_port->ops->port_unsplit)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return devlink->ops->port_unsplit(devlink, devlink_port, info->extack); return devlink_port->ops->port_unsplit(devlink, devlink_port, info->extack);
} }
static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb, static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
...@@ -1361,7 +1348,7 @@ static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb, ...@@ -1361,7 +1348,7 @@ static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
struct devlink_port_new_attrs new_attrs = {}; struct devlink_port_new_attrs new_attrs = {};
struct devlink *devlink = info->user_ptr[0]; struct devlink *devlink = info->user_ptr[0];
if (!devlink->ops->port_new || !devlink->ops->port_del) if (!devlink->ops->port_new)
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] || if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
...@@ -1400,10 +1387,10 @@ static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb, ...@@ -1400,10 +1387,10 @@ static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
struct netlink_ext_ack *extack = info->extack; struct netlink_ext_ack *extack = info->extack;
struct devlink *devlink = info->user_ptr[0]; struct devlink *devlink = info->user_ptr[0];
if (!devlink->ops->port_del) if (!devlink_port->ops->port_del)
return -EOPNOTSUPP; return -EOPNOTSUPP;
return devlink->ops->port_del(devlink, devlink_port, extack); return devlink_port->ops->port_del(devlink, devlink_port, extack);
} }
static int static int
...@@ -6793,12 +6780,15 @@ void devlink_port_fini(struct devlink_port *devlink_port) ...@@ -6793,12 +6780,15 @@ void devlink_port_fini(struct devlink_port *devlink_port)
} }
EXPORT_SYMBOL_GPL(devlink_port_fini); EXPORT_SYMBOL_GPL(devlink_port_fini);
static const struct devlink_port_ops devlink_port_dummy_ops = {};
/** /**
* devl_port_register() - Register devlink port * devl_port_register_with_ops() - Register devlink port
* *
* @devlink: devlink * @devlink: devlink
* @devlink_port: devlink port * @devlink_port: devlink port
* @port_index: driver-specific numerical identifier of the port * @port_index: driver-specific numerical identifier of the port
* @ops: port ops
* *
* Register devlink port with provided port index. User can use * Register devlink port with provided port index. User can use
* any indexing, even hw-related one. devlink_port structure * any indexing, even hw-related one. devlink_port structure
...@@ -6806,9 +6796,10 @@ EXPORT_SYMBOL_GPL(devlink_port_fini); ...@@ -6806,9 +6796,10 @@ EXPORT_SYMBOL_GPL(devlink_port_fini);
* Note that the caller should take care of zeroing the devlink_port * Note that the caller should take care of zeroing the devlink_port
* structure. * structure.
*/ */
int devl_port_register(struct devlink *devlink, int devl_port_register_with_ops(struct devlink *devlink,
struct devlink_port *devlink_port, struct devlink_port *devlink_port,
unsigned int port_index) unsigned int port_index,
const struct devlink_port_ops *ops)
{ {
int err; int err;
...@@ -6819,6 +6810,7 @@ int devl_port_register(struct devlink *devlink, ...@@ -6819,6 +6810,7 @@ int devl_port_register(struct devlink *devlink,
devlink_port_init(devlink, devlink_port); devlink_port_init(devlink, devlink_port);
devlink_port->registered = true; devlink_port->registered = true;
devlink_port->index = port_index; devlink_port->index = port_index;
devlink_port->ops = ops ? ops : &devlink_port_dummy_ops;
spin_lock_init(&devlink_port->type_lock); spin_lock_init(&devlink_port->type_lock);
INIT_LIST_HEAD(&devlink_port->reporter_list); INIT_LIST_HEAD(&devlink_port->reporter_list);
err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL); err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
...@@ -6830,14 +6822,15 @@ int devl_port_register(struct devlink *devlink, ...@@ -6830,14 +6822,15 @@ int devl_port_register(struct devlink *devlink,
devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(devl_port_register); EXPORT_SYMBOL_GPL(devl_port_register_with_ops);
/** /**
* devlink_port_register - Register devlink port * devlink_port_register_with_ops - Register devlink port
* *
* @devlink: devlink * @devlink: devlink
* @devlink_port: devlink port * @devlink_port: devlink port
* @port_index: driver-specific numerical identifier of the port * @port_index: driver-specific numerical identifier of the port
* @ops: port ops
* *
* Register devlink port with provided port index. User can use * Register devlink port with provided port index. User can use
* any indexing, even hw-related one. devlink_port structure * any indexing, even hw-related one. devlink_port structure
...@@ -6847,18 +6840,20 @@ EXPORT_SYMBOL_GPL(devl_port_register); ...@@ -6847,18 +6840,20 @@ EXPORT_SYMBOL_GPL(devl_port_register);
* *
* Context: Takes and release devlink->lock <mutex>. * Context: Takes and release devlink->lock <mutex>.
*/ */
int devlink_port_register(struct devlink *devlink, int devlink_port_register_with_ops(struct devlink *devlink,
struct devlink_port *devlink_port, struct devlink_port *devlink_port,
unsigned int port_index) unsigned int port_index,
const struct devlink_port_ops *ops)
{ {
int err; int err;
devl_lock(devlink); devl_lock(devlink);
err = devl_port_register(devlink, devlink_port, port_index); err = devl_port_register_with_ops(devlink, devlink_port,
port_index, ops);
devl_unlock(devlink); devl_unlock(devlink);
return err; return err;
} }
EXPORT_SYMBOL_GPL(devlink_port_register); EXPORT_SYMBOL_GPL(devlink_port_register_with_ops);
/** /**
* devl_port_unregister() - Unregister devlink port * devl_port_unregister() - Unregister devlink port
......
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