net/devlink: Support querying hardware address of port function
PCI PF and VF devlink port can manage the function represented by a devlink port. Enable users to query port function's hardware address. 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> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a829eb0d5d
commit
2a916ecc40
|
@ -1107,6 +1107,18 @@ struct devlink_ops {
|
|||
int (*trap_policer_counter_get)(struct devlink *devlink,
|
||||
const struct devlink_trap_policer *policer,
|
||||
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 *devlink, struct devlink_port *port,
|
||||
u8 *hw_addr, int *hw_addr_len,
|
||||
struct netlink_ext_ack *extack);
|
||||
};
|
||||
|
||||
static inline void *devlink_priv(struct devlink *devlink)
|
||||
|
|
|
@ -451,6 +451,8 @@ enum devlink_attr {
|
|||
DEVLINK_ATTR_TRAP_POLICER_RATE, /* u64 */
|
||||
DEVLINK_ATTR_TRAP_POLICER_BURST, /* u64 */
|
||||
|
||||
DEVLINK_ATTR_PORT_FUNCTION, /* nested */
|
||||
|
||||
/* add new attributes above here, update the policy in devlink.c */
|
||||
|
||||
__DEVLINK_ATTR_MAX,
|
||||
|
@ -497,4 +499,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 /* _UAPI_LINUX_DEVLINK_H_ */
|
||||
|
|
|
@ -563,6 +563,49 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct devlink *devlink = port->devlink;
|
||||
const struct devlink_ops *ops;
|
||||
struct nlattr *function_attr;
|
||||
bool empty_nest = true;
|
||||
int err = 0;
|
||||
|
||||
function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
|
||||
if (!function_attr)
|
||||
return -EMSGSIZE;
|
||||
|
||||
ops = devlink->ops;
|
||||
if (ops->port_function_hw_addr_get) {
|
||||
int uninitialized_var(hw_addr_len);
|
||||
u8 hw_addr[MAX_ADDR_LEN];
|
||||
|
||||
err = ops->port_function_hw_addr_get(devlink, port, hw_addr, &hw_addr_len, extack);
|
||||
if (err == -EOPNOTSUPP) {
|
||||
/* Port function attributes are optional for a port. If port doesn't
|
||||
* support function attribute, returning -EOPNOTSUPP is not an error.
|
||||
*/
|
||||
err = 0;
|
||||
goto out;
|
||||
} else if (err) {
|
||||
goto out;
|
||||
}
|
||||
err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
|
||||
if (err)
|
||||
goto out;
|
||||
empty_nest = false;
|
||||
}
|
||||
|
||||
out:
|
||||
if (err || empty_nest)
|
||||
nla_nest_cancel(msg, function_attr);
|
||||
else
|
||||
nla_nest_end(msg, function_attr);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
|
||||
struct devlink_port *devlink_port,
|
||||
enum devlink_command cmd, u32 portid,
|
||||
|
@ -608,6 +651,8 @@ static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
|
|||
spin_unlock_bh(&devlink_port->type_lock);
|
||||
if (devlink_nl_port_attrs_put(msg, devlink_port))
|
||||
goto nla_put_failure;
|
||||
if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue