PCI endpoint corresponds to a PCI device, but such device can have one more more logical device ports associated with it. We need a way to distinguish those. Add a PCI subport in the dumps and print the info in phys_port_name appropriately.
This is not equivalent to port splitting, there is no split group. It's just a way of representing multiple netdevs on a single PCI function. Note that the quality of being multiport pertains only to the PCI function itself. A PF having multiple netdevs does not mean that its VFs will also have multiple, or that VFs are associated with any particular port of a multiport VF. Example (bus 05 device has subports, bus 82 has only one port per function): $ devlink port pci/0000:05:00.0/0: type eth netdev enp5s0np0 flavour physical pci/0000:05:00.0/10000: type eth netdev enp5s0npf0s0 flavour pci_pf pf 0 subport 0 pci/0000:05:00.0/4: type eth netdev enp5s0np1 flavour physical pci/0000:05:00.0/11000: type eth netdev enp5s0npf0s1 flavour pci_pf pf 0 subport 1 pci/0000:82:00.0/0: type eth netdev p4p1 flavour physical pci/0000:82:00.0/10000: type eth netdev eth0 flavour pci_pf pf 0 $ devlink -jp port { "port": { "pci/0000:05:00.0/0": { "type": "eth", "netdev": "enp5s0np0", "flavour": "physical" }, "pci/0000:05:00.0/10000": { "type": "eth", "netdev": "enp5s0npf0s0", "flavour": "pci_pf", "pf": 0, "subport": 0 }, "pci/0000:05:00.0/4": { "type": "eth", "netdev": "enp5s0np1", "flavour": "physical" }, "pci/0000:05:00.0/11000": { "type": "eth", "netdev": "enp5s0npf0s1", "flavour": "pci_pf", "pf": 0, "subport": 1 }, "pci/0000:82:00.0/0": { "type": "eth", "netdev": "p4p1", "flavour": "physical" }, "pci/0000:82:00.0/10000": { "type": "eth", "netdev": "eth0", "flavour": "pci_pf", "pf": 0 } } } Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com> --- .../net/ethernet/netronome/nfp/nfp_devlink.c | 3 +- include/net/devlink.h | 9 ++++-- include/uapi/linux/devlink.h | 1 + net/core/devlink.c | 29 ++++++++++++++++--- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c index 36976e37d162..bb07be4117a3 100644 --- a/drivers/net/ethernet/netronome/nfp/nfp_devlink.c +++ b/drivers/net/ethernet/netronome/nfp/nfp_devlink.c @@ -375,7 +375,8 @@ nfp_devlink_port_init_pci(struct devlink *devlink, struct nfp_port *port, { devlink_port_type_eth_set(&port->dl_port, port->netdev); devlink_port_attrs_pci_set(&port->dl_port, flavour, - port->pf_id, port->vf_id); + port->pf_id, port->vf_id, + port->pf_split, port->pf_split_id); return 0; } diff --git a/include/net/devlink.h b/include/net/devlink.h index b5376ef492f1..13e0a479c546 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -53,6 +53,8 @@ struct devlink_port_attrs { struct { u32 pf_number; u32 vf_number; + bool multiport; + u32 subport_number; } pci; }; }; @@ -580,7 +582,8 @@ void devlink_port_attrs_set(struct devlink_port *devlink_port, u32 split_subport_number); void devlink_port_attrs_pci_set(struct devlink_port *devlink_port, enum devlink_port_flavour flavour, - u32 pf_number, u32 vf_number); + u32 pf_number, u32 vf_number, + bool multiport, u32 subport_number); int devlink_port_get_phys_port_name(struct devlink_port *devlink_port, char *name, size_t len); int devlink_sb_register(struct devlink *devlink, unsigned int sb_index, @@ -797,7 +800,9 @@ static inline void devlink_port_attrs_set(struct devlink_port *devlink_port, static inline void devlink_port_attrs_pci_set(struct devlink_port *devlink_port, enum devlink_port_flavour flavour, - u32 pf_number, u32 vf_number) + u32 pf_number, u32 vf_number, + bool multiport, + u32 subport_number) { } diff --git a/include/uapi/linux/devlink.h b/include/uapi/linux/devlink.h index 9ce76d4f640d..417ae8233cce 100644 --- a/include/uapi/linux/devlink.h +++ b/include/uapi/linux/devlink.h @@ -336,6 +336,7 @@ enum devlink_attr { DEVLINK_ATTR_PORT_PCI_PF_NUMBER, /* u32 */ DEVLINK_ATTR_PORT_PCI_VF_NUMBER, /* u32 */ + DEVLINK_ATTR_PORT_PCI_SUBPORT, /* u32 */ /* add new attributes above here, update the policy in devlink.c */ diff --git a/net/core/devlink.c b/net/core/devlink.c index af177284830b..6cdf7e87d7fc 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -541,6 +541,11 @@ static int devlink_nl_port_attrs_put(struct sk_buff *msg, if (nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci.pf_number)) return -EMSGSIZE; + + if (attrs->pci.multiport && + nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SUBPORT, + attrs->pci.subport_number)) + return -EMSGSIZE; return 0; default: return -EINVAL; @@ -5449,10 +5454,13 @@ EXPORT_SYMBOL_GPL(devlink_port_attrs_set); * @pf_number: PCI PF number, in multi-host mapping to hosts depends * on the platform * @vf_number: PCI VF number within given PF (ignored for PF itself) + * @multiport: PCI function has more than one logical port + * @subport_number: PCI function has more than one logical port */ void devlink_port_attrs_pci_set(struct devlink_port *devlink_port, enum devlink_port_flavour flavour, - u32 pf_number, u32 vf_number) + u32 pf_number, u32 vf_number, + bool multiport, u32 subport_number) { struct devlink_port_attrs *attrs = &devlink_port->attrs; @@ -5463,6 +5471,8 @@ void devlink_port_attrs_pci_set(struct devlink_port *devlink_port, attrs->flavour = flavour; attrs->pci.pf_number = pf_number; attrs->pci.vf_number = vf_number; + attrs->pci.multiport = multiport; + attrs->pci.subport_number = subport_number; devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW); } EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_set); @@ -5492,11 +5502,22 @@ int devlink_port_get_phys_port_name(struct devlink_port *devlink_port, WARN_ON(1); return -EINVAL; case DEVLINK_PORT_FLAVOUR_PCI_PF: - n = snprintf(name, len, "pf%u", attrs->pci.pf_number); + if (!attrs->pci.multiport) + n = snprintf(name, len, "pf%u", attrs->pci.pf_number); + else + n = snprintf(name, len, "pf%us%u", attrs->pci.pf_number, + attrs->pci.subport_number); break; case DEVLINK_PORT_FLAVOUR_PCI_VF: - n = snprintf(name, len, "pf%uvf%u", - attrs->pf_number, attrs->pci.vf_number); + if (!attrs->pci.multiport) + n = snprintf(name, len, "pf%uvf%u", + attrs->pci.pf_number, + attrs->pci.vf_number); + else + n = snprintf(name, len, "pf%uvf%us%u", + attrs->pci.pf_number, + attrs->pci.vf_number, + attrs->pci.subport_number); break; } -- 2.19.2