Skip to content

Commit 8f01054

Browse files
paravmellanoxSaeed Mahameed
authored andcommitted
net/mlx5: SF, Add port add delete functionality
To handle SF port management outside of the eswitch as independent software layer, introduce eswitch notifier APIs so that mlx5 upper layer who wish to support sf port management in switchdev mode can perform its task whenever eswitch mode is set to switchdev or before eswitch is disabled. Initialize sf port table on such eswitch event. Add SF port add and delete functionality in switchdev mode. Destroy all SF ports when eswitch is disabled. Expose SF port add and delete to user via devlink commands. $ devlink dev eswitch set pci/0000:06:00.0 mode switchdev $ devlink port show pci/0000:06:00.0/65535: type eth netdev ens2f0np0 flavour physical port 0 splittable false $ devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88 pci/0000:06:00.0/32768: type eth netdev eth6 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false function: hw_addr 00:00:00:00:00:00 state inactive opstate detached $ devlink port show ens2f0npf0sf88 pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false function: hw_addr 00:00:00:00:00:00 state inactive opstate detached or by its unique port index: $ devlink port show pci/0000:06:00.0/32768 pci/0000:06:00.0/32768: type eth netdev ens2f0npf0sf88 flavour pcisf controller 0 pfnum 0 sfnum 88 external false splittable false function: hw_addr 00:00:00:00:00:00 state inactive opstate detached $ devlink port show ens2f0npf0sf88 -jp { "port": { "pci/0000:06:00.0/32768": { "type": "eth", "netdev": "ens2f0npf0sf88", "flavour": "pcisf", "controller": 0, "pfnum": 0, "sfnum": 88, "external": false, "splittable": false, "function": { "hw_addr": "00:00:00:00:00:00", "state": "inactive", "opstate": "detached" } } } } Signed-off-by: Parav Pandit <[email protected]> Reviewed-by: Vu Pham <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent d970812 commit 8f01054

File tree

13 files changed

+607
-0
lines changed

13 files changed

+607
-0
lines changed

drivers/net/ethernet/mellanox/mlx5/core/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,13 @@ config MLX5_SF
212212
Build support for subfuction device in the NIC. A Mellanox subfunction
213213
device can support RDMA, netdevice and vdpa device.
214214
It is similar to a SRIOV VF but it doesn't require SRIOV support.
215+
216+
config MLX5_SF_MANAGER
217+
bool
218+
depends on MLX5_SF && MLX5_ESWITCH
219+
default y
220+
help
221+
Build support for subfuction port in the NIC. A Mellanox subfunction
222+
port is managed through devlink. A subfunction supports RDMA, netdevice
223+
and vdpa device. It is similar to a SRIOV VF but it doesn't require
224+
SRIOV support.

drivers/net/ethernet/mellanox/mlx5/core/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,8 @@ mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o
9090
# SF device
9191
#
9292
mlx5_core-$(CONFIG_MLX5_SF) += sf/vhca_event.o sf/dev/dev.o sf/dev/driver.o
93+
94+
#
95+
# SF manager
96+
#
97+
mlx5_core-$(CONFIG_MLX5_SF_MANAGER) += sf/cmd.o sf/hw_table.o sf/devlink.o

drivers/net/ethernet/mellanox/mlx5/core/cmd.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
333333
case MLX5_CMD_OP_DEALLOC_MEMIC:
334334
case MLX5_CMD_OP_PAGE_FAULT_RESUME:
335335
case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS:
336+
case MLX5_CMD_OP_DEALLOC_SF:
336337
return MLX5_CMD_STAT_OK;
337338

338339
case MLX5_CMD_OP_QUERY_HCA_CAP:
@@ -466,6 +467,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
466467
case MLX5_CMD_OP_RELEASE_XRQ_ERROR:
467468
case MLX5_CMD_OP_QUERY_VHCA_STATE:
468469
case MLX5_CMD_OP_MODIFY_VHCA_STATE:
470+
case MLX5_CMD_OP_ALLOC_SF:
469471
*status = MLX5_DRIVER_STATUS_ABORTED;
470472
*synd = MLX5_DRIVER_SYND;
471473
return -EIO;
@@ -661,6 +663,8 @@ const char *mlx5_command_str(int command)
661663
MLX5_COMMAND_STR_CASE(MODIFY_XRQ);
662664
MLX5_COMMAND_STR_CASE(QUERY_VHCA_STATE);
663665
MLX5_COMMAND_STR_CASE(MODIFY_VHCA_STATE);
666+
MLX5_COMMAND_STR_CASE(ALLOC_SF);
667+
MLX5_COMMAND_STR_CASE(DEALLOC_SF);
664668
default: return "unknown command opcode";
665669
}
666670
}

drivers/net/ethernet/mellanox/mlx5/core/devlink.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "fs_core.h"
99
#include "eswitch.h"
1010
#include "sf/dev/dev.h"
11+
#include "sf/sf.h"
1112

1213
static int mlx5_devlink_flash_update(struct devlink *devlink,
1314
struct devlink_flash_update_params *params,
@@ -190,6 +191,10 @@ static const struct devlink_ops mlx5_devlink_ops = {
190191
.eswitch_encap_mode_get = mlx5_devlink_eswitch_encap_mode_get,
191192
.port_function_hw_addr_get = mlx5_devlink_port_function_hw_addr_get,
192193
.port_function_hw_addr_set = mlx5_devlink_port_function_hw_addr_set,
194+
#endif
195+
#ifdef CONFIG_MLX5_SF_MANAGER
196+
.port_new = mlx5_devlink_sf_port_new,
197+
.port_del = mlx5_devlink_sf_port_del,
193198
#endif
194199
.flash_update = mlx5_devlink_flash_update,
195200
.info_get = mlx5_devlink_info_get,

drivers/net/ethernet/mellanox/mlx5/core/eswitch.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,6 +1599,15 @@ mlx5_eswitch_update_num_of_vfs(struct mlx5_eswitch *esw, int num_vfs)
15991599
kvfree(out);
16001600
}
16011601

1602+
static void mlx5_esw_mode_change_notify(struct mlx5_eswitch *esw, u16 mode)
1603+
{
1604+
struct mlx5_esw_event_info info = {};
1605+
1606+
info.new_mode = mode;
1607+
1608+
blocking_notifier_call_chain(&esw->n_head, 0, &info);
1609+
}
1610+
16021611
/**
16031612
* mlx5_eswitch_enable_locked - Enable eswitch
16041613
* @esw: Pointer to eswitch
@@ -1659,6 +1668,8 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int mode, int num_vfs)
16591668
mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS",
16601669
esw->esw_funcs.num_vfs, esw->enabled_vports);
16611670

1671+
mlx5_esw_mode_change_notify(esw, mode);
1672+
16621673
return 0;
16631674

16641675
abort:
@@ -1715,6 +1726,11 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw, bool clear_vf)
17151726
esw->mode == MLX5_ESWITCH_LEGACY ? "LEGACY" : "OFFLOADS",
17161727
esw->esw_funcs.num_vfs, esw->enabled_vports);
17171728

1729+
/* Notify eswitch users that it is exiting from current mode.
1730+
* So that it can do necessary cleanup before the eswitch is disabled.
1731+
*/
1732+
mlx5_esw_mode_change_notify(esw, MLX5_ESWITCH_NONE);
1733+
17181734
mlx5_eswitch_event_handlers_unregister(esw);
17191735

17201736
if (esw->mode == MLX5_ESWITCH_LEGACY)
@@ -1815,6 +1831,7 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
18151831
esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE;
18161832

18171833
dev->priv.eswitch = esw;
1834+
BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head);
18181835
return 0;
18191836
abort:
18201837
if (esw->work_queue)
@@ -2506,4 +2523,12 @@ bool mlx5_esw_multipath_prereq(struct mlx5_core_dev *dev0,
25062523
dev1->priv.eswitch->mode == MLX5_ESWITCH_OFFLOADS);
25072524
}
25082525

2526+
int mlx5_esw_event_notifier_register(struct mlx5_eswitch *esw, struct notifier_block *nb)
2527+
{
2528+
return blocking_notifier_chain_register(&esw->n_head, nb);
2529+
}
25092530

2531+
void mlx5_esw_event_notifier_unregister(struct mlx5_eswitch *esw, struct notifier_block *nb)
2532+
{
2533+
blocking_notifier_chain_unregister(&esw->n_head, nb);
2534+
}

drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ struct mlx5_eswitch {
278278
struct {
279279
u32 large_group_num;
280280
} params;
281+
struct blocking_notifier_head n_head;
281282
};
282283

283284
void esw_offloads_disable(struct mlx5_eswitch *esw);
@@ -733,6 +734,17 @@ int mlx5_esw_offloads_sf_vport_enable(struct mlx5_eswitch *esw, struct devlink_p
733734
u16 vport_num, u32 sfnum);
734735
void mlx5_esw_offloads_sf_vport_disable(struct mlx5_eswitch *esw, u16 vport_num);
735736

737+
/**
738+
* mlx5_esw_event_info - Indicates eswitch mode changed/changing.
739+
*
740+
* @new_mode: New mode of eswitch.
741+
*/
742+
struct mlx5_esw_event_info {
743+
u16 new_mode;
744+
};
745+
746+
int mlx5_esw_event_notifier_register(struct mlx5_eswitch *esw, struct notifier_block *n);
747+
void mlx5_esw_event_notifier_unregister(struct mlx5_eswitch *esw, struct notifier_block *n);
736748
#else /* CONFIG_MLX5_ESWITCH */
737749
/* eswitch API stubs */
738750
static inline int mlx5_eswitch_init(struct mlx5_core_dev *dev) { return 0; }

drivers/net/ethernet/mellanox/mlx5/core/main.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,18 @@ static int mlx5_init_once(struct mlx5_core_dev *dev)
893893
goto err_fpga_cleanup;
894894
}
895895

896+
err = mlx5_sf_hw_table_init(dev);
897+
if (err) {
898+
mlx5_core_err(dev, "Failed to init SF HW table %d\n", err);
899+
goto err_sf_hw_table_cleanup;
900+
}
901+
902+
err = mlx5_sf_table_init(dev);
903+
if (err) {
904+
mlx5_core_err(dev, "Failed to init SF table %d\n", err);
905+
goto err_sf_table_cleanup;
906+
}
907+
896908
dev->dm = mlx5_dm_create(dev);
897909
if (IS_ERR(dev->dm))
898910
mlx5_core_warn(dev, "Failed to init device memory%d\n", err);
@@ -903,6 +915,10 @@ static int mlx5_init_once(struct mlx5_core_dev *dev)
903915

904916
return 0;
905917

918+
err_sf_table_cleanup:
919+
mlx5_sf_hw_table_cleanup(dev);
920+
err_sf_hw_table_cleanup:
921+
mlx5_vhca_event_cleanup(dev);
906922
err_fpga_cleanup:
907923
mlx5_fpga_cleanup(dev);
908924
err_eswitch_cleanup:
@@ -936,6 +952,8 @@ static void mlx5_cleanup_once(struct mlx5_core_dev *dev)
936952
mlx5_hv_vhca_destroy(dev->hv_vhca);
937953
mlx5_fw_tracer_destroy(dev->tracer);
938954
mlx5_dm_cleanup(dev);
955+
mlx5_sf_table_cleanup(dev);
956+
mlx5_sf_hw_table_cleanup(dev);
939957
mlx5_vhca_event_cleanup(dev);
940958
mlx5_fpga_cleanup(dev);
941959
mlx5_eswitch_cleanup(dev->priv.eswitch);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2+
/* Copyright (c) 2020 Mellanox Technologies Ltd */
3+
4+
#include <linux/mlx5/driver.h>
5+
#include "priv.h"
6+
7+
int mlx5_cmd_alloc_sf(struct mlx5_core_dev *dev, u16 function_id)
8+
{
9+
u32 out[MLX5_ST_SZ_DW(alloc_sf_out)] = {};
10+
u32 in[MLX5_ST_SZ_DW(alloc_sf_in)] = {};
11+
12+
MLX5_SET(alloc_sf_in, in, opcode, MLX5_CMD_OP_ALLOC_SF);
13+
MLX5_SET(alloc_sf_in, in, function_id, function_id);
14+
15+
return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
16+
}
17+
18+
int mlx5_cmd_dealloc_sf(struct mlx5_core_dev *dev, u16 function_id)
19+
{
20+
u32 out[MLX5_ST_SZ_DW(dealloc_sf_out)] = {};
21+
u32 in[MLX5_ST_SZ_DW(dealloc_sf_in)] = {};
22+
23+
MLX5_SET(dealloc_sf_in, in, opcode, MLX5_CMD_OP_DEALLOC_SF);
24+
MLX5_SET(dealloc_sf_in, in, function_id, function_id);
25+
26+
return mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
27+
}

0 commit comments

Comments
 (0)