devlink: Supporting add and delete of devlink port
Enable user to add and delete the devlink port.
Examples for adding and deleting one SF port:
Examples of add, show and delete 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
Add devlink port of flavour 'pcipf' for PF number 0 SF number 88:
$ 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 splittable false
function:
hw_addr 00:00:00:00:00:00 state inactive opstate detached
Delete newly added devlink port
$ devlink port del pci/0000:06:00.0/32768
Signed-off-by: Parav Pandit <parav@nvidia.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
This commit is contained in:
parent
836a1365b7
commit
331bf89ad0
|
|
@ -306,6 +306,9 @@ static void ifname_map_free(struct ifname_map *ifname_map)
|
||||||
#define DL_OPT_FLASH_OVERWRITE BIT(39)
|
#define DL_OPT_FLASH_OVERWRITE BIT(39)
|
||||||
#define DL_OPT_RELOAD_ACTION BIT(40)
|
#define DL_OPT_RELOAD_ACTION BIT(40)
|
||||||
#define DL_OPT_RELOAD_LIMIT BIT(41)
|
#define DL_OPT_RELOAD_LIMIT BIT(41)
|
||||||
|
#define DL_OPT_PORT_FLAVOUR BIT(42)
|
||||||
|
#define DL_OPT_PORT_PFNUMBER BIT(43)
|
||||||
|
#define DL_OPT_PORT_SFNUMBER BIT(44)
|
||||||
|
|
||||||
struct dl_opts {
|
struct dl_opts {
|
||||||
uint64_t present; /* flags of present items */
|
uint64_t present; /* flags of present items */
|
||||||
|
|
@ -356,6 +359,9 @@ struct dl_opts {
|
||||||
uint32_t overwrite_mask;
|
uint32_t overwrite_mask;
|
||||||
enum devlink_reload_action reload_action;
|
enum devlink_reload_action reload_action;
|
||||||
enum devlink_reload_limit reload_limit;
|
enum devlink_reload_limit reload_limit;
|
||||||
|
uint32_t port_sfnumber;
|
||||||
|
uint16_t port_flavour;
|
||||||
|
uint16_t port_pfnumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dl {
|
struct dl {
|
||||||
|
|
@ -1394,6 +1400,17 @@ static struct str_num_map port_flavour_map[] = {
|
||||||
{ .str = NULL, },
|
{ .str = NULL, },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int port_flavour_parse(const char *flavour, uint16_t *value)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
|
||||||
|
num = str_map_lookup_str(port_flavour_map, flavour);
|
||||||
|
if (num < 0)
|
||||||
|
return num;
|
||||||
|
*value = num;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct dl_args_metadata {
|
struct dl_args_metadata {
|
||||||
uint64_t o_flag;
|
uint64_t o_flag;
|
||||||
char err_msg[DL_ARGS_REQUIRED_MAX_ERR_LEN];
|
char err_msg[DL_ARGS_REQUIRED_MAX_ERR_LEN];
|
||||||
|
|
@ -1425,6 +1442,8 @@ static const struct dl_args_metadata dl_args_required[] = {
|
||||||
{DL_OPT_TRAP_NAME, "Trap's name is expected."},
|
{DL_OPT_TRAP_NAME, "Trap's name is expected."},
|
||||||
{DL_OPT_TRAP_GROUP_NAME, "Trap group's name is expected."},
|
{DL_OPT_TRAP_GROUP_NAME, "Trap group's name is expected."},
|
||||||
{DL_OPT_PORT_FUNCTION_HW_ADDR, "Port function's hardware address is expected."},
|
{DL_OPT_PORT_FUNCTION_HW_ADDR, "Port function's hardware address is expected."},
|
||||||
|
{DL_OPT_PORT_FLAVOUR, "Port flavour is expected."},
|
||||||
|
{DL_OPT_PORT_PFNUMBER, "Port PCI PF number is expected."},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dl_args_finding_required_validate(uint64_t o_required,
|
static int dl_args_finding_required_validate(uint64_t o_required,
|
||||||
|
|
@ -1843,7 +1862,29 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
o_found |= DL_OPT_PORT_FUNCTION_HW_ADDR;
|
o_found |= DL_OPT_PORT_FUNCTION_HW_ADDR;
|
||||||
|
} else if (dl_argv_match(dl, "flavour") && (o_all & DL_OPT_PORT_FLAVOUR)) {
|
||||||
|
const char *flavourstr;
|
||||||
|
|
||||||
|
dl_arg_inc(dl);
|
||||||
|
err = dl_argv_str(dl, &flavourstr);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
err = port_flavour_parse(flavourstr, &opts->port_flavour);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
o_found |= DL_OPT_PORT_FLAVOUR;
|
||||||
|
} else if (dl_argv_match(dl, "pfnum") && (o_all & DL_OPT_PORT_PFNUMBER)) {
|
||||||
|
dl_arg_inc(dl);
|
||||||
|
err = dl_argv_uint16_t(dl, &opts->port_pfnumber);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
o_found |= DL_OPT_PORT_PFNUMBER;
|
||||||
|
} else if (dl_argv_match(dl, "sfnum") && (o_all & DL_OPT_PORT_SFNUMBER)) {
|
||||||
|
dl_arg_inc(dl);
|
||||||
|
err = dl_argv_uint32_t(dl, &opts->port_sfnumber);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
o_found |= DL_OPT_PORT_SFNUMBER;
|
||||||
} else {
|
} else {
|
||||||
pr_err("Unknown option \"%s\"\n", dl_argv(dl));
|
pr_err("Unknown option \"%s\"\n", dl_argv(dl));
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -2026,6 +2067,12 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
|
||||||
opts->trap_policer_burst);
|
opts->trap_policer_burst);
|
||||||
if (opts->present & DL_OPT_PORT_FUNCTION_HW_ADDR)
|
if (opts->present & DL_OPT_PORT_FUNCTION_HW_ADDR)
|
||||||
dl_function_attr_put(nlh, opts);
|
dl_function_attr_put(nlh, opts);
|
||||||
|
if (opts->present & DL_OPT_PORT_FLAVOUR)
|
||||||
|
mnl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_FLAVOUR, opts->port_flavour);
|
||||||
|
if (opts->present & DL_OPT_PORT_PFNUMBER)
|
||||||
|
mnl_attr_put_u16(nlh, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, opts->port_pfnumber);
|
||||||
|
if (opts->present & DL_OPT_PORT_SFNUMBER)
|
||||||
|
mnl_attr_put_u32(nlh, DEVLINK_ATTR_PORT_PCI_SF_NUMBER, opts->port_sfnumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
|
static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
|
||||||
|
|
@ -3713,6 +3760,8 @@ static void cmd_port_help(void)
|
||||||
pr_err(" devlink port unsplit DEV/PORT_INDEX\n");
|
pr_err(" devlink port unsplit DEV/PORT_INDEX\n");
|
||||||
pr_err(" devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ]\n");
|
pr_err(" devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ]\n");
|
||||||
pr_err(" devlink port health show [ DEV/PORT_INDEX reporter REPORTER_NAME ]\n");
|
pr_err(" devlink port health show [ DEV/PORT_INDEX reporter REPORTER_NAME ]\n");
|
||||||
|
pr_err(" devlink port add DEV/PORT_INDEX flavour FLAVOUR pfnum PFNUM [ sfnum SFNUM ]\n");
|
||||||
|
pr_err(" devlink port del DEV/PORT_INDEX\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *port_type_name(uint32_t type)
|
static const char *port_type_name(uint32_t type)
|
||||||
|
|
@ -3974,6 +4023,58 @@ static int cmd_port_function(struct dl *dl)
|
||||||
static int cmd_health(struct dl *dl);
|
static int cmd_health(struct dl *dl);
|
||||||
static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port);
|
static int __cmd_health_show(struct dl *dl, bool show_device, bool show_port);
|
||||||
|
|
||||||
|
static void cmd_port_add_help(void)
|
||||||
|
{
|
||||||
|
pr_err(" devlink port add { DEV | DEV/PORT_INDEX } flavour FLAVOUR pfnum PFNUM [ sfnum SFNUM ]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_port_add(struct dl *dl)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
|
||||||
|
cmd_port_add_help();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_NEW,
|
||||||
|
NLM_F_REQUEST | NLM_F_ACK);
|
||||||
|
|
||||||
|
err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLE | DL_OPT_HANDLEP |
|
||||||
|
DL_OPT_PORT_FLAVOUR | DL_OPT_PORT_PFNUMBER,
|
||||||
|
DL_OPT_PORT_SFNUMBER);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return _mnlg_socket_sndrcv(dl->nlg, nlh, cmd_port_show_cb, dl);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cmd_port_del_help(void)
|
||||||
|
{
|
||||||
|
pr_err(" devlink port del DEV/PORT_INDEX\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_port_del(struct dl *dl)
|
||||||
|
{
|
||||||
|
struct nlmsghdr *nlh;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
|
||||||
|
cmd_port_del_help();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_DEL,
|
||||||
|
NLM_F_REQUEST | NLM_F_ACK);
|
||||||
|
|
||||||
|
err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP, 0);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static int cmd_port(struct dl *dl)
|
static int cmd_port(struct dl *dl)
|
||||||
{
|
{
|
||||||
if (dl_argv_match(dl, "help")) {
|
if (dl_argv_match(dl, "help")) {
|
||||||
|
|
@ -4004,7 +4105,14 @@ static int cmd_port(struct dl *dl)
|
||||||
} else {
|
} else {
|
||||||
return cmd_health(dl);
|
return cmd_health(dl);
|
||||||
}
|
}
|
||||||
|
} else if (dl_argv_match(dl, "add")) {
|
||||||
|
dl_arg_inc(dl);
|
||||||
|
return cmd_port_add(dl);
|
||||||
|
} else if (dl_argv_match(dl, "del")) {
|
||||||
|
dl_arg_inc(dl);
|
||||||
|
return cmd_port_del(dl);
|
||||||
}
|
}
|
||||||
|
|
||||||
pr_err("Command \"%s\" not found\n", dl_argv(dl));
|
pr_err("Command \"%s\" not found\n", dl_argv(dl));
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,23 @@ devlink-port \- devlink port configuration
|
||||||
.B devlink port health
|
.B devlink port health
|
||||||
.RI "{ " show " | " recover " | " diagnose " | " dump " | " set " }"
|
.RI "{ " show " | " recover " | " diagnose " | " dump " | " set " }"
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.BI "devlink port add"
|
||||||
|
.RB "["
|
||||||
|
.IR "DEV | DEV/PORT_INDEX"
|
||||||
|
.RB "] "
|
||||||
|
.RB "[ " flavour
|
||||||
|
.IR FLAVOUR " ]"
|
||||||
|
.RB "[ " pcipf
|
||||||
|
.IR PFNUMBER " ]"
|
||||||
|
.RB "{ " pcisf
|
||||||
|
.IR SFNUMBER " }"
|
||||||
|
.br
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.B devlink port del
|
||||||
|
.IR DEV/PORT_INDEX
|
||||||
|
|
||||||
.ti -8
|
.ti -8
|
||||||
.B devlink port help
|
.B devlink port help
|
||||||
|
|
||||||
|
|
@ -99,6 +116,42 @@ If this argument is omitted all ports are listed.
|
||||||
Is an alias for
|
Is an alias for
|
||||||
.BR devlink-health (8).
|
.BR devlink-health (8).
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.SS devlink port add - add a devlink port
|
||||||
|
.PP
|
||||||
|
.B "DEV"
|
||||||
|
- specifies the devlink device to operate on. or
|
||||||
|
|
||||||
|
.PP
|
||||||
|
.B "DEV/PORT_INDEX"
|
||||||
|
- specifies the devlink port index to use for the requested new port.
|
||||||
|
This is optional. When ommited, driver allocates unique port index.
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR flavour " { " pcipf " | " pcisf " } "
|
||||||
|
set port flavour
|
||||||
|
|
||||||
|
.I pcipf
|
||||||
|
- PCI PF port
|
||||||
|
|
||||||
|
.I pcisf
|
||||||
|
- PCI SF port
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR pfnum " { " pfnumber " } "
|
||||||
|
Specifies PCI pfnumber to use on which a SF device to create
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.BR sfnum " { " sfnumber " } "
|
||||||
|
Specifies sfnumber to assign to the device of the SF.
|
||||||
|
This field is optional for those devices which supports auto assignment of the SF number.
|
||||||
|
|
||||||
|
.ti -8
|
||||||
|
.SS devlink port del - delete a devlink port
|
||||||
|
.PP
|
||||||
|
.B "DEV/PORT_INDEX"
|
||||||
|
- specifies the devlink port to delete.
|
||||||
|
|
||||||
.SH "EXAMPLES"
|
.SH "EXAMPLES"
|
||||||
.PP
|
.PP
|
||||||
devlink port show
|
devlink port show
|
||||||
|
|
@ -135,6 +188,16 @@ devlink port health show pci/0000:01:00.0/1 reporter tx
|
||||||
.RS 4
|
.RS 4
|
||||||
Shows status and configuration of tx reporter registered on pci/0000:01:00.0/1 devlink port.
|
Shows status and configuration of tx reporter registered on pci/0000:01:00.0/1 devlink port.
|
||||||
.RE
|
.RE
|
||||||
|
.PP
|
||||||
|
devlink port add pci/0000:06:00.0 flavour pcisf pfnum 0 sfnum 88
|
||||||
|
.RS 4
|
||||||
|
Add a devlink port of flavour PCI SF on PCI PF having number 0 with SF number 88.
|
||||||
|
.RE
|
||||||
|
.PP
|
||||||
|
devlink port del pci/0000:06:00.0/1
|
||||||
|
.RS 4
|
||||||
|
Delete previously created devlink port.
|
||||||
|
.RE
|
||||||
|
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR devlink (8),
|
.BR devlink (8),
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue