All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function
@ 2020-06-23 10:44 Parav Pandit
  2020-06-23 10:44 ` [PATCH iproute2-next 1/4] Update kernel headers Parav Pandit
                   ` (5 more replies)
  0 siblings, 6 replies; 7+ messages in thread
From: Parav Pandit @ 2020-06-23 10:44 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jiri, dsahern, Parav Pandit

Currently ip link set dev <pfndev> vf <vf_num> <param> <value> has
few below limitations.

1. Command is limited to set VF parameters only.
It cannot set the default MAC address for the PCI PF.

2. It can be set only on system where PCI SR-IOV is supported.
In smartnic based system, eswitch of a NIC resides on a different
embedded cpu which has the VF and PF representors for the SR-IOV
support on a host system in which this smartnic is plugged-in.

3. It cannot setup the function attributes of sub-function described
in detail in comprehensive RFC [1] and [2].

This series covers the first small part to let user query and set MAC
address (hardware address) of a PCI PF/VF which is represented by
devlink port.

Patch summary:
Patch-1 Sync kernel header
Patch-2 Move devlink port code at start to reuse
Patch-3 Extends port dump command to query additional port function
attribute(s)
Patch-4 Enables user to set port function hardware address

[1] https://lore.kernel.org/netdev/20200519092258.GF4655@nanopsycho/
[2] https://marc.info/?l=linux-netdev&m=158555928517777&w=2

Parav Pandit (4):
  Update kernel headers
  devlink: Move devlink port code at start to reuse
  devlink: Support querying hardware address of port function
  devlink: Support setting port function hardware address

 devlink/devlink.c            | 378 ++++++++++++++++++++++++-----------
 include/uapi/linux/devlink.h |  12 ++
 2 files changed, 269 insertions(+), 121 deletions(-)

-- 
2.25.4


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH iproute2-next 1/4] Update kernel headers
  2020-06-23 10:44 [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
@ 2020-06-23 10:44 ` Parav Pandit
  2020-06-23 10:44 ` [PATCH iproute2-next 2/4] devlink: Move devlink port code at start to reuse Parav Pandit
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Parav Pandit @ 2020-06-23 10:44 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jiri, dsahern, Parav Pandit

Update kernel headers to commit:
   b5872cd0e823e4 ("devlink: Add support for board.serial_number to info_get cb.")

Signed-off-by: Parav Pandit <parav@mellanox.com>
---
 include/uapi/linux/devlink.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h
index 7b600bf1..d3ee69ba 100644
--- a/include/uapi/linux/devlink.h
+++ b/include/uapi/linux/devlink.h
@@ -451,6 +451,10 @@ enum devlink_attr {
 	DEVLINK_ATTR_TRAP_POLICER_RATE,			/* u64 */
 	DEVLINK_ATTR_TRAP_POLICER_BURST,		/* u64 */
 
+	DEVLINK_ATTR_PORT_FUNCTION,			/* nested */
+
+	DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,	/* string */
+
 	/* add new attributes above here, update the policy in devlink.c */
 
 	__DEVLINK_ATTR_MAX,
@@ -497,4 +501,12 @@ enum devlink_resource_unit {
 	DEVLINK_RESOURCE_UNIT_ENTRY,
 };
 
+enum devlink_port_function_attr {
+	DEVLINK_PORT_FUNCTION_ATTR_UNSPEC,
+	DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR,	/* binary */
+
+	__DEVLINK_PORT_FUNCTION_ATTR_MAX,
+	DEVLINK_PORT_FUNCTION_ATTR_MAX = __DEVLINK_PORT_FUNCTION_ATTR_MAX - 1
+};
+
 #endif /* _LINUX_DEVLINK_H_ */
-- 
2.25.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH iproute2-next 2/4] devlink: Move devlink port code at start to reuse
  2020-06-23 10:44 [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
  2020-06-23 10:44 ` [PATCH iproute2-next 1/4] Update kernel headers Parav Pandit
@ 2020-06-23 10:44 ` Parav Pandit
  2020-06-23 10:44 ` [PATCH iproute2-next 3/4] devlink: Support querying hardware address of port function Parav Pandit
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Parav Pandit @ 2020-06-23 10:44 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jiri, dsahern, Parav Pandit

To reuse print routines for port function in subsequent patch, move
print routine specific to devlink device at start of the file.

Signed-off-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 devlink/devlink.c | 242 +++++++++++++++++++++++-----------------------
 1 file changed, 121 insertions(+), 121 deletions(-)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 507972c3..b7699f30 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -429,6 +429,127 @@ static void __pr_out_indent_newline(struct dl *dl)
 		pr_out(" ");
 }
 
+static bool is_binary_eol(int i)
+{
+	return !(i%16);
+}
+
+static void pr_out_binary_value(struct dl *dl, uint8_t *data, uint32_t len)
+{
+	int i = 0;
+
+	while (i < len) {
+		if (dl->json_output)
+			print_int(PRINT_JSON, NULL, NULL, data[i]);
+		else
+			pr_out("%02x ", data[i]);
+		i++;
+		if (!dl->json_output && is_binary_eol(i))
+			__pr_out_newline();
+	}
+	if (!dl->json_output && !is_binary_eol(i))
+		__pr_out_newline();
+}
+
+static void pr_out_name(struct dl *dl, const char *name)
+{
+	__pr_out_indent_newline(dl);
+	if (dl->json_output)
+		print_string(PRINT_JSON, name, NULL, NULL);
+	else
+		pr_out("%s:", name);
+}
+
+static void pr_out_u64(struct dl *dl, const char *name, uint64_t val)
+{
+	__pr_out_indent_newline(dl);
+	if (val == (uint64_t) -1)
+		return print_string_name_value(name, "unlimited");
+
+	if (dl->json_output)
+		print_u64(PRINT_JSON, name, NULL, val);
+	else
+		pr_out("%s %"PRIu64, name, val);
+}
+
+static void pr_out_section_start(struct dl *dl, const char *name)
+{
+	if (dl->json_output) {
+		open_json_object(NULL);
+		open_json_object(name);
+	}
+}
+
+static void pr_out_section_end(struct dl *dl)
+{
+	if (dl->json_output) {
+		if (dl->arr_last.present)
+			close_json_array(PRINT_JSON, NULL);
+		close_json_object();
+		close_json_object();
+	}
+}
+
+static void pr_out_array_start(struct dl *dl, const char *name)
+{
+	if (dl->json_output) {
+		open_json_array(PRINT_JSON, name);
+	} else {
+		__pr_out_indent_inc();
+		__pr_out_newline();
+		pr_out("%s:", name);
+		__pr_out_indent_inc();
+		__pr_out_newline();
+	}
+}
+
+static void pr_out_array_end(struct dl *dl)
+{
+	if (dl->json_output) {
+		close_json_array(PRINT_JSON, NULL);
+	} else {
+		__pr_out_indent_dec();
+		__pr_out_indent_dec();
+	}
+}
+
+static void pr_out_object_start(struct dl *dl, const char *name)
+{
+	if (dl->json_output) {
+		open_json_object(name);
+	} else {
+		__pr_out_indent_inc();
+		__pr_out_newline();
+		pr_out("%s:", name);
+		__pr_out_indent_inc();
+		__pr_out_newline();
+	}
+}
+
+static void pr_out_object_end(struct dl *dl)
+{
+	if (dl->json_output) {
+		close_json_object();
+	} else {
+		__pr_out_indent_dec();
+		__pr_out_indent_dec();
+	}
+}
+
+static void pr_out_entry_start(struct dl *dl)
+{
+	if (dl->json_output)
+		open_json_object(NULL);
+}
+
+static void pr_out_entry_end(struct dl *dl)
+{
+	if (dl->json_output)
+		close_json_object();
+	else
+		__pr_out_newline();
+}
+
 static void check_indent_newline(struct dl *dl)
 {
 	__pr_out_indent_newline(dl);
@@ -1950,49 +2071,6 @@ static void pr_out_port_handle_end(struct dl *dl)
 		pr_out("\n");
 }
 
-static void pr_out_u64(struct dl *dl, const char *name, uint64_t val)
-{
-	__pr_out_indent_newline(dl);
-	if (val == (uint64_t) -1)
-		return print_string_name_value(name, "unlimited");
-
-	if (dl->json_output)
-		print_u64(PRINT_JSON, name, NULL, val);
-	else
-		pr_out("%s %"PRIu64, name, val);
-}
-
-static bool is_binary_eol(int i)
-{
-	return !(i%16);
-}
-
-static void pr_out_binary_value(struct dl *dl, uint8_t *data, uint32_t len)
-{
-	int i = 0;
-
-	while (i < len) {
-		if (dl->json_output)
-			print_int(PRINT_JSON, NULL, NULL, data[i]);
-		else
-			pr_out("%02x ", data[i]);
-		i++;
-		if (!dl->json_output && is_binary_eol(i))
-			__pr_out_newline();
-	}
-	if (!dl->json_output && !is_binary_eol(i))
-		__pr_out_newline();
-}
-
-static void pr_out_name(struct dl *dl, const char *name)
-{
-	__pr_out_indent_newline(dl);
-	if (dl->json_output)
-		print_string(PRINT_JSON, name, NULL, NULL);
-	else
-		pr_out("%s:", name);
-}
-
 static void pr_out_region_chunk_start(struct dl *dl, uint64_t addr)
 {
 	if (dl->json_output) {
@@ -2034,84 +2112,6 @@ static void pr_out_region_chunk(struct dl *dl, uint8_t *data, uint32_t len,
 	pr_out_region_chunk_end(dl);
 }
 
-static void pr_out_section_start(struct dl *dl, const char *name)
-{
-	if (dl->json_output) {
-		open_json_object(NULL);
-		open_json_object(name);
-	}
-}
-
-static void pr_out_section_end(struct dl *dl)
-{
-	if (dl->json_output) {
-		if (dl->arr_last.present)
-			close_json_array(PRINT_JSON, NULL);
-		close_json_object();
-		close_json_object();
-	}
-}
-
-static void pr_out_array_start(struct dl *dl, const char *name)
-{
-	if (dl->json_output) {
-		open_json_array(PRINT_JSON, name);
-	} else {
-		__pr_out_indent_inc();
-		__pr_out_newline();
-		pr_out("%s:", name);
-		__pr_out_indent_inc();
-		__pr_out_newline();
-	}
-}
-
-static void pr_out_array_end(struct dl *dl)
-{
-	if (dl->json_output) {
-		close_json_array(PRINT_JSON, NULL);
-	} else {
-		__pr_out_indent_dec();
-		__pr_out_indent_dec();
-	}
-}
-
-static void pr_out_object_start(struct dl *dl, const char *name)
-{
-	if (dl->json_output) {
-		open_json_object(name);
-	} else {
-		__pr_out_indent_inc();
-		__pr_out_newline();
-		pr_out("%s:", name);
-		__pr_out_indent_inc();
-		__pr_out_newline();
-	}
-}
-
-static void pr_out_object_end(struct dl *dl)
-{
-	if (dl->json_output) {
-		close_json_object();
-	} else {
-		__pr_out_indent_dec();
-		__pr_out_indent_dec();
-	}
-}
-
-static void pr_out_entry_start(struct dl *dl)
-{
-	if (dl->json_output)
-		open_json_object(NULL);
-}
-
-static void pr_out_entry_end(struct dl *dl)
-{
-	if (dl->json_output)
-		close_json_object();
-	else
-		__pr_out_newline();
-}
-
 static void pr_out_stats(struct dl *dl, struct nlattr *nla_stats)
 {
 	struct nlattr *tb[DEVLINK_ATTR_STATS_MAX + 1] = {};
-- 
2.25.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH iproute2-next 3/4] devlink: Support querying hardware address of port function
  2020-06-23 10:44 [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
  2020-06-23 10:44 ` [PATCH iproute2-next 1/4] Update kernel headers Parav Pandit
  2020-06-23 10:44 ` [PATCH iproute2-next 2/4] devlink: Move devlink port code at start to reuse Parav Pandit
@ 2020-06-23 10:44 ` Parav Pandit
  2020-06-23 10:44 ` [PATCH iproute2-next 4/4] devlink: Support setting port function hardware address Parav Pandit
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 7+ messages in thread
From: Parav Pandit @ 2020-06-23 10:44 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jiri, dsahern, Parav Pandit

Add support to query the hardware address of function represented
by devlink port function.

Example of a PCI VF port which supports a port function:
$ devlink port show pci/0000:06:00.0/2
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
  function:
    hw_addr 00:11:22:33:44:66

$ devlink port show pci/0000:06:00.0/2 -jp
{
    "port": {
        "pci/0000:06:00.0/2": {
            "type": "eth",
            "netdev": "enp6s0pf0vf1",
            "flavour": "pcivf",
            "pfnum": 0,
            "vfnum": 1,
            "function": {
                "hw_addr": "00:11:22:33:44:66"
            }
        }
    }
}

Signed-off-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 devlink/devlink.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index b7699f30..16fc834e 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -26,6 +26,7 @@
 #include <libmnl/libmnl.h>
 #include <netinet/ether.h>
 #include <sys/types.h>
+#include <rt_names.h>
 
 #include "SNAPSHOT.h"
 #include "list.h"
@@ -708,6 +709,30 @@ static int attr_stats_cb(const struct nlattr *attr, void *data)
 	return MNL_CB_OK;
 }
 
+static const enum mnl_attr_data_type
+devlink_function_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
+	[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR ] = MNL_TYPE_BINARY,
+};
+
+static int function_attr_cb(const struct nlattr *attr, void *data)
+{
+	const struct nlattr **tb = data;
+	int type;
+
+	/* Allow the tool to work on top of newer kernels that might contain
+	 * more attributes.
+	 */
+	if (mnl_attr_type_valid(attr, DEVLINK_PORT_FUNCTION_ATTR_MAX) < 0)
+		return MNL_CB_OK;
+
+	type = mnl_attr_get_type(attr);
+	if (mnl_attr_validate(attr, devlink_function_policy[type]) < 0)
+		return MNL_CB_ERROR;
+
+	tb[type] = attr;
+	return MNL_CB_OK;
+}
+
 static int ifname_map_cb(const struct nlmsghdr *nlh, void *data)
 {
 	struct nlattr *tb[DEVLINK_ATTR_MAX + 1] = {};
@@ -3243,6 +3268,37 @@ static void pr_out_port_pfvf_num(struct dl *dl, struct nlattr **tb)
 	}
 }
 
+static void pr_out_port_function(struct dl *dl, struct nlattr **tb_port)
+{
+	struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {};
+	unsigned char *data;
+	SPRINT_BUF(hw_addr);
+	uint32_t len;
+	int err;
+
+	if (!tb_port[DEVLINK_ATTR_PORT_FUNCTION])
+		return;
+
+	err = mnl_attr_parse_nested(tb_port[DEVLINK_ATTR_PORT_FUNCTION],
+				    function_attr_cb, tb);
+	if (err != MNL_CB_OK)
+		return;
+
+	if (!tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR])
+		return;
+
+	len = mnl_attr_get_payload_len(tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR]);
+	data = mnl_attr_get_payload(tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR]);
+
+	pr_out_object_start(dl, "function");
+	check_indent_newline(dl);
+	print_string(PRINT_ANY, "hw_addr", "hw_addr %s",
+		     ll_addr_n2a(data, len, 0, hw_addr, sizeof(hw_addr)));
+	if (!dl->json_output)
+		__pr_out_indent_dec();
+	pr_out_object_end(dl);
+}
+
 static void pr_out_port(struct dl *dl, struct nlattr **tb)
 {
 	struct nlattr *pt_attr = tb[DEVLINK_ATTR_PORT_TYPE];
@@ -3296,6 +3352,7 @@ static void pr_out_port(struct dl *dl, struct nlattr **tb)
 	if (tb[DEVLINK_ATTR_PORT_SPLIT_GROUP])
 		print_uint(PRINT_ANY, "split_group", " split_group %u",
 			   mnl_attr_get_u32(tb[DEVLINK_ATTR_PORT_SPLIT_GROUP]));
+	pr_out_port_function(dl, tb);
 	pr_out_port_handle_end(dl);
 }
 
-- 
2.25.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH iproute2-next 4/4] devlink: Support setting port function hardware address
  2020-06-23 10:44 [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
                   ` (2 preceding siblings ...)
  2020-06-23 10:44 ` [PATCH iproute2-next 3/4] devlink: Support querying hardware address of port function Parav Pandit
@ 2020-06-23 10:44 ` Parav Pandit
  2020-06-26  5:13 ` [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
  2020-07-05 14:56 ` David Ahern
  5 siblings, 0 replies; 7+ messages in thread
From: Parav Pandit @ 2020-06-23 10:44 UTC (permalink / raw)
  To: netdev; +Cc: stephen, jiri, dsahern, Parav Pandit

Support setting devlink port function hardware address.

Example of a PCI VF port which supports a port function:
Set hardware address of the VF's port function.

$ devlink port show pci/0000:06:00.0/2
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
  function:
    hw_addr 00:00:00:00:00:00

$ devlink port function set pci/0000:06:00.0/2 hw_addr 00:11:22:33:44:55

$ devlink port show pci/0000:06:00.0/2
pci/0000:06:00.0/2: type eth netdev enp6s0pf0vf1 flavour pcivf pfnum 0 vfnum 1
  function:
    hw_addr 00:11:22:33:44:55

Signed-off-by: Parav Pandit <parav@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
---
 devlink/devlink.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)

diff --git a/devlink/devlink.c b/devlink/devlink.c
index 16fc834e..75182cac 100644
--- a/devlink/devlink.c
+++ b/devlink/devlink.c
@@ -294,6 +294,7 @@ static void ifname_map_free(struct ifname_map *ifname_map)
 #define DL_OPT_TRAP_POLICER_RATE	BIT(35)
 #define DL_OPT_TRAP_POLICER_BURST	BIT(36)
 #define DL_OPT_HEALTH_REPORTER_AUTO_DUMP     BIT(37)
+#define DL_OPT_PORT_FUNCTION_HW_ADDR BIT(38)
 
 struct dl_opts {
 	uint64_t present; /* flags of present items */
@@ -339,6 +340,8 @@ struct dl_opts {
 	uint32_t trap_policer_id;
 	uint64_t trap_policer_rate;
 	uint64_t trap_policer_burst;
+	char port_function_hw_addr[MAX_ADDR_LEN];
+	uint32_t port_function_hw_addr_len;
 };
 
 struct dl {
@@ -1302,6 +1305,17 @@ static int trap_action_get(const char *actionstr,
 	return 0;
 }
 
+static int hw_addr_parse(const char *addrstr, char *hw_addr, uint32_t *len)
+{
+	int alen;
+
+	alen = ll_addr_a2n(hw_addr, MAX_ADDR_LEN, addrstr);
+	if (alen < 0)
+		return -EINVAL;
+	*len = alen;
+	return 0;
+}
+
 struct dl_args_metadata {
 	uint64_t o_flag;
 	char err_msg[DL_ARGS_REQUIRED_MAX_ERR_LEN];
@@ -1332,6 +1346,7 @@ static const struct dl_args_metadata dl_args_required[] = {
 	{DL_OPT_HEALTH_REPORTER_NAME, "Reporter'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_PORT_FUNCTION_HW_ADDR, "Port function's hardware address is expected."},
 };
 
 static int dl_args_finding_required_validate(uint64_t o_required,
@@ -1698,6 +1713,20 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 			if (err)
 				return err;
 			o_found |= DL_OPT_TRAP_POLICER_BURST;
+		} else if (dl_argv_match(dl, "hw_addr") &&
+			   (o_all & DL_OPT_PORT_FUNCTION_HW_ADDR)) {
+			const char *addrstr;
+
+			dl_arg_inc(dl);
+			err = dl_argv_str(dl, &addrstr);
+			if (err)
+				return err;
+			err = hw_addr_parse(addrstr, opts->port_function_hw_addr,
+					    &opts->port_function_hw_addr_len);
+			if (err)
+				return err;
+			o_found |= DL_OPT_PORT_FUNCTION_HW_ADDR;
+
 		} else {
 			pr_err("Unknown option \"%s\"\n", dl_argv(dl));
 			return -EINVAL;
@@ -1714,6 +1743,18 @@ static int dl_argv_parse(struct dl *dl, uint64_t o_required,
 	return dl_args_finding_required_validate(o_required, o_found);
 }
 
+static void
+dl_function_attr_put(struct nlmsghdr *nlh, const struct dl_opts *opts)
+{
+	struct nlattr *nest;
+
+	nest = mnl_attr_nest_start(nlh, DEVLINK_ATTR_PORT_FUNCTION);
+	mnl_attr_put(nlh, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR,
+		     opts->port_function_hw_addr_len,
+		     opts->port_function_hw_addr);
+	mnl_attr_nest_end(nlh, nest);
+}
+
 static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
 {
 	struct dl_opts *opts = &dl->opts;
@@ -1837,6 +1878,8 @@ static void dl_opts_put(struct nlmsghdr *nlh, struct dl *dl)
 	if (opts->present & DL_OPT_TRAP_POLICER_BURST)
 		mnl_attr_put_u64(nlh, DEVLINK_ATTR_TRAP_POLICER_BURST,
 				 opts->trap_policer_burst);
+	if (opts->present & DL_OPT_PORT_FUNCTION_HW_ADDR)
+		dl_function_attr_put(nlh, opts);
 }
 
 static int dl_argv_parse_put(struct nlmsghdr *nlh, struct dl *dl,
@@ -3221,6 +3264,7 @@ static void cmd_port_help(void)
 	pr_err("       devlink port set DEV/PORT_INDEX [ type { eth | ib | auto} ]\n");
 	pr_err("       devlink port split DEV/PORT_INDEX count COUNT\n");
 	pr_err("       devlink port unsplit DEV/PORT_INDEX\n");
+	pr_err("       devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ]\n");
 }
 
 static const char *port_type_name(uint32_t type)
@@ -3438,6 +3482,38 @@ static int cmd_port_unsplit(struct dl *dl)
 	return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
 }
 
+static void cmd_port_function_help(void)
+{
+	pr_err("Usage: devlink port function set DEV/PORT_INDEX [ hw_addr ADDR ]\n");
+}
+
+static int cmd_port_function_set(struct dl *dl)
+{
+	struct nlmsghdr *nlh;
+	int err;
+
+	nlh = mnlg_msg_prepare(dl->nlg, DEVLINK_CMD_PORT_SET, NLM_F_REQUEST | NLM_F_ACK);
+
+	err = dl_argv_parse_put(nlh, dl, DL_OPT_HANDLEP | DL_OPT_PORT_FUNCTION_HW_ADDR, 0);
+	if (err)
+		return err;
+
+	return _mnlg_socket_sndrcv(dl->nlg, nlh, NULL, NULL);
+}
+
+static int cmd_port_function(struct dl *dl)
+{
+	if (dl_argv_match(dl, "help") || dl_no_arg(dl)) {
+		cmd_port_function_help();
+		return 0;
+	} else if (dl_argv_match(dl, "set")) {
+		dl_arg_inc(dl);
+		return cmd_port_function_set(dl);
+	}
+	pr_err("Command \"%s\" not found\n", dl_argv(dl));
+	return -ENOENT;
+}
+
 static int cmd_port(struct dl *dl)
 {
 	if (dl_argv_match(dl, "help")) {
@@ -3456,6 +3532,9 @@ static int cmd_port(struct dl *dl)
 	} else if (dl_argv_match(dl, "unsplit")) {
 		dl_arg_inc(dl);
 		return cmd_port_unsplit(dl);
+	} else if (dl_argv_match(dl, "function")) {
+		dl_arg_inc(dl);
+		return cmd_port_function(dl);
 	}
 	pr_err("Command \"%s\" not found\n", dl_argv(dl));
 	return -ENOENT;
-- 
2.25.4


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* RE: [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function
  2020-06-23 10:44 [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
                   ` (3 preceding siblings ...)
  2020-06-23 10:44 ` [PATCH iproute2-next 4/4] devlink: Support setting port function hardware address Parav Pandit
@ 2020-06-26  5:13 ` Parav Pandit
  2020-07-05 14:56 ` David Ahern
  5 siblings, 0 replies; 7+ messages in thread
From: Parav Pandit @ 2020-06-26  5:13 UTC (permalink / raw)
  To: netdev; +Cc: stephen, Jiri Pirko, dsahern

Hi David,

> From: Parav Pandit <parav@mellanox.com>
> Sent: Tuesday, June 23, 2020 4:14 PM
> 
> Currently ip link set dev <pfndev> vf <vf_num> <param> <value> has few below
> limitations.
> 
> 1. Command is limited to set VF parameters only.
> It cannot set the default MAC address for the PCI PF.
> 
> 2. It can be set only on system where PCI SR-IOV is supported.
> In smartnic based system, eswitch of a NIC resides on a different embedded cpu
> which has the VF and PF representors for the SR-IOV support on a host system in
> which this smartnic is plugged-in.
> 
> 3. It cannot setup the function attributes of sub-function described in detail in
> comprehensive RFC [1] and [2].
> 
> This series covers the first small part to let user query and set MAC address
> (hardware address) of a PCI PF/VF which is represented by devlink port.
> 
> Patch summary:
> Patch-1 Sync kernel header
> Patch-2 Move devlink port code at start to reuse
> Patch-3 Extends port dump command to query additional port function
> attribute(s)
> Patch-4 Enables user to set port function hardware address
> 
> [1] https://lore.kernel.org/netdev/20200519092258.GF4655@nanopsycho/
> [2] https://marc.info/?l=linux-netdev&m=158555928517777&w=2
> 

Did you get a chance to review this short series?



> Parav Pandit (4):
>   Update kernel headers
>   devlink: Move devlink port code at start to reuse
>   devlink: Support querying hardware address of port function
>   devlink: Support setting port function hardware address
> 
>  devlink/devlink.c            | 378 ++++++++++++++++++++++++-----------
>  include/uapi/linux/devlink.h |  12 ++
>  2 files changed, 269 insertions(+), 121 deletions(-)
> 
> --
> 2.25.4


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function
  2020-06-23 10:44 [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
                   ` (4 preceding siblings ...)
  2020-06-26  5:13 ` [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
@ 2020-07-05 14:56 ` David Ahern
  5 siblings, 0 replies; 7+ messages in thread
From: David Ahern @ 2020-07-05 14:56 UTC (permalink / raw)
  To: Parav Pandit, netdev; +Cc: stephen, jiri, dsahern

On 6/23/20 4:44 AM, Parav Pandit wrote:
> Currently ip link set dev <pfndev> vf <vf_num> <param> <value> has
> few below limitations.
> 
> 1. Command is limited to set VF parameters only.
> It cannot set the default MAC address for the PCI PF.
> 
> 2. It can be set only on system where PCI SR-IOV is supported.
> In smartnic based system, eswitch of a NIC resides on a different
> embedded cpu which has the VF and PF representors for the SR-IOV
> support on a host system in which this smartnic is plugged-in.
> 
> 3. It cannot setup the function attributes of sub-function described
> in detail in comprehensive RFC [1] and [2].
> 
> This series covers the first small part to let user query and set MAC
> address (hardware address) of a PCI PF/VF which is represented by
> devlink port.
> 
> Patch summary:
> Patch-1 Sync kernel header
> Patch-2 Move devlink port code at start to reuse
> Patch-3 Extends port dump command to query additional port function
> attribute(s)
> Patch-4 Enables user to set port function hardware address
> 
> [1] https://lore.kernel.org/netdev/20200519092258.GF4655@nanopsycho/
> [2] https://marc.info/?l=linux-netdev&m=158555928517777&w=2
> 
> Parav Pandit (4):
>   Update kernel headers
>   devlink: Move devlink port code at start to reuse
>   devlink: Support querying hardware address of port function
>   devlink: Support setting port function hardware address
> 
>  devlink/devlink.c            | 378 ++++++++++++++++++++++++-----------
>  include/uapi/linux/devlink.h |  12 ++
>  2 files changed, 269 insertions(+), 121 deletions(-)
> 

applied to iproute2-next. Thanks

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-07-05 14:56 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-23 10:44 [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
2020-06-23 10:44 ` [PATCH iproute2-next 1/4] Update kernel headers Parav Pandit
2020-06-23 10:44 ` [PATCH iproute2-next 2/4] devlink: Move devlink port code at start to reuse Parav Pandit
2020-06-23 10:44 ` [PATCH iproute2-next 3/4] devlink: Support querying hardware address of port function Parav Pandit
2020-06-23 10:44 ` [PATCH iproute2-next 4/4] devlink: Support setting port function hardware address Parav Pandit
2020-06-26  5:13 ` [PATCH iproute2-next 0/4] devlink: Support get,set mac address of a port function Parav Pandit
2020-07-05 14:56 ` David Ahern

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.