Register each CAN channel of the device as an devlink physical port. This makes it easier to get device information for a given network interface (i.e. can2). Example output: $ devlink dev pci/0000:07:00.0 pci/0000:08:00.0 pci/0000:09:00.0 $ devlink port pci/0000:07:00.0/0: type eth netdev can0 flavour physical port 0 splittable false pci/0000:07:00.0/1: type eth netdev can1 flavour physical port 1 splittable false pci/0000:07:00.0/2: type eth netdev can2 flavour physical port 2 splittable false pci/0000:07:00.0/3: type eth netdev can3 flavour physical port 3 splittable false pci/0000:08:00.0/0: type eth netdev can4 flavour physical port 0 splittable false pci/0000:08:00.0/1: type eth netdev can5 flavour physical port 1 splittable false pci/0000:09:00.0/0: type eth netdev can6 flavour physical port 0 splittable false pci/0000:09:00.0/1: type eth netdev can7 flavour physical port 1 splittable false pci/0000:09:00.0/2: type eth netdev can8 flavour physical port 2 splittable false pci/0000:09:00.0/3: type eth netdev can9 flavour physical port 3 splittable false $ devlink port show can2 pci/0000:07:00.0/2: type eth netdev can2 flavour physical port 2 splittable false $ devlink dev info pci/0000:07:00.0: driver kvaser_pciefd versions: running: fw 1.3.75 pci/0000:08:00.0: driver kvaser_pciefd versions: running: fw 2.4.29 pci/0000:09:00.0: driver kvaser_pciefd versions: running: fw 1.3.72 $ sudo ethtool -i can2 driver: kvaser_pciefd version: 6.8.0-40-generic firmware-version: 1.3.75 expansion-rom-version: bus-info: 0000:07:00.0 supports-statistics: no supports-test: no supports-eeprom-access: no supports-register-dump: no supports-priv-flags: no Reviewed-by: Vincent Mailhol Signed-off-by: Jimmy Assarsson --- Changes in v4: - Add tag Reviewed-by Vincent Mailhol Changes in v2: - Add two space indentation to terminal output. Suggested by Vincent Mailhol [1] - Replace netdev.dev_id with netdev.dev_port, to reflect changes in previous patch. [1] https://lore.kernel.org/linux-can/20250723083236.9-1-extja@kvaser.com/T/#m31ee4aad13ee29d5559b56fdce842609ae4f67c5 drivers/net/can/kvaser_pciefd/kvaser_pciefd.h | 4 +++ .../can/kvaser_pciefd/kvaser_pciefd_core.c | 8 ++++++ .../can/kvaser_pciefd/kvaser_pciefd_devlink.c | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/drivers/net/can/kvaser_pciefd/kvaser_pciefd.h b/drivers/net/can/kvaser_pciefd/kvaser_pciefd.h index 34ba393d6093..08c9ddc1ee85 100644 --- a/drivers/net/can/kvaser_pciefd/kvaser_pciefd.h +++ b/drivers/net/can/kvaser_pciefd/kvaser_pciefd.h @@ -59,6 +59,7 @@ struct kvaser_pciefd_fw_version { struct kvaser_pciefd_can { struct can_priv can; + struct devlink_port devlink_port; struct kvaser_pciefd *kv_pcie; void __iomem *reg_base; struct can_berr_counter bec; @@ -89,4 +90,7 @@ struct kvaser_pciefd { }; extern const struct devlink_ops kvaser_pciefd_devlink_ops; + +int kvaser_pciefd_devlink_port_register(struct kvaser_pciefd_can *can); +void kvaser_pciefd_devlink_port_unregister(struct kvaser_pciefd_can *can); #endif /* _KVASER_PCIEFD_H */ diff --git a/drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c b/drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c index 60c72ab0a5d8..86584ce7bbfa 100644 --- a/drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c +++ b/drivers/net/can/kvaser_pciefd/kvaser_pciefd_core.c @@ -943,6 +943,7 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) struct net_device *netdev; struct kvaser_pciefd_can *can; u32 status, tx_nr_packets_max; + int ret; netdev = alloc_candev(sizeof(struct kvaser_pciefd_can), roundup_pow_of_two(KVASER_PCIEFD_CAN_TX_MAX_COUNT)); @@ -1013,6 +1014,11 @@ static int kvaser_pciefd_setup_can_ctrls(struct kvaser_pciefd *pcie) pcie->can[i] = can; kvaser_pciefd_pwm_start(can); + ret = kvaser_pciefd_devlink_port_register(can); + if (ret) { + dev_err(&pcie->pci->dev, "Failed to register devlink port\n"); + return ret; + } } return 0; @@ -1732,6 +1738,7 @@ static void kvaser_pciefd_teardown_can_ctrls(struct kvaser_pciefd *pcie) if (can) { iowrite32(0, can->reg_base + KVASER_PCIEFD_KCAN_IEN_REG); kvaser_pciefd_pwm_stop(can); + kvaser_pciefd_devlink_port_unregister(can); free_candev(can->can.dev); } } @@ -1874,6 +1881,7 @@ static void kvaser_pciefd_remove(struct pci_dev *pdev) unregister_candev(can->can.dev); timer_delete(&can->bec_poll_timer); kvaser_pciefd_pwm_stop(can); + kvaser_pciefd_devlink_port_unregister(can); } kvaser_pciefd_disable_irq_srcs(pcie); diff --git a/drivers/net/can/kvaser_pciefd/kvaser_pciefd_devlink.c b/drivers/net/can/kvaser_pciefd/kvaser_pciefd_devlink.c index 1fbb40dbbb7a..1d61a8b0eeba 100644 --- a/drivers/net/can/kvaser_pciefd/kvaser_pciefd_devlink.c +++ b/drivers/net/can/kvaser_pciefd/kvaser_pciefd_devlink.c @@ -5,6 +5,7 @@ */ #include "kvaser_pciefd.h" +#include #include static int kvaser_pciefd_devlink_info_get(struct devlink *devlink, @@ -33,3 +34,27 @@ static int kvaser_pciefd_devlink_info_get(struct devlink *devlink, const struct devlink_ops kvaser_pciefd_devlink_ops = { .info_get = kvaser_pciefd_devlink_info_get, }; + +int kvaser_pciefd_devlink_port_register(struct kvaser_pciefd_can *can) +{ + int ret; + struct devlink_port_attrs attrs = { + .flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL, + .phys.port_number = can->can.dev->dev_port, + }; + devlink_port_attrs_set(&can->devlink_port, &attrs); + + ret = devlink_port_register(priv_to_devlink(can->kv_pcie), + &can->devlink_port, can->can.dev->dev_port); + if (ret) + return ret; + + SET_NETDEV_DEVLINK_PORT(can->can.dev, &can->devlink_port); + + return 0; +} + +void kvaser_pciefd_devlink_port_unregister(struct kvaser_pciefd_can *can) +{ + devlink_port_unregister(&can->devlink_port); +} -- 2.49.0