Skip to content

Commit aa6a5c9

Browse files
Jimmy Assarssonmarckleinebudde
authored andcommitted
can: kvaser_usb: Add devlink port support
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 usb/1-1.3:1.0 $ devlink port usb/1-1.3:1.0/0: type eth netdev can0 flavour physical port 0 splittable false usb/1-1.3:1.0/1: type eth netdev can1 flavour physical port 1 splittable false $ devlink port show can1 usb/1-1.3:1.0/1: type eth netdev can1 flavour physical port 0 splittable false $ devlink dev info usb/1-1.3:1.0: driver kvaser_usb serial_number 1020 versions: fixed: board.rev 1 board.id 7330130009653 running: fw 3.22.527 $ ethtool -i can1 driver: kvaser_usb version: 6.12.10-arch1-1 firmware-version: 3.22.527 expansion-rom-version: bus-info: 1-1.3:1.0 supports-statistics: no supports-test: no supports-eeprom-access: no supports-register-dump: no supports-priv-flags: no Reviewed-by: Vincent Mailhol <mailhol.vincent@wanadoo.fr> Signed-off-by: Jimmy Assarsson <extja@kvaser.com> Link: https://patch.msgid.link/20250725123452.41-11-extja@kvaser.com Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
1 parent 8720aed commit aa6a5c9

3 files changed

Lines changed: 41 additions & 3 deletions

File tree

drivers/net/can/usb/kvaser_usb/kvaser_usb.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ struct kvaser_usb {
131131

132132
struct kvaser_usb_net_priv {
133133
struct can_priv can;
134+
struct devlink_port devlink_port;
134135
struct can_berr_counter bec;
135136

136137
/* subdriver-specific data */
@@ -229,6 +230,9 @@ extern const struct kvaser_usb_dev_ops kvaser_usb_leaf_dev_ops;
229230

230231
extern const struct devlink_ops kvaser_usb_devlink_ops;
231232

233+
int kvaser_usb_devlink_port_register(struct kvaser_usb_net_priv *priv);
234+
void kvaser_usb_devlink_port_unregister(struct kvaser_usb_net_priv *priv);
235+
232236
void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv);
233237

234238
int kvaser_usb_recv_cmd(const struct kvaser_usb *dev, void *cmd, int len,

drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,7 @@ static void kvaser_usb_remove_interfaces(struct kvaser_usb *dev)
818818
if (ops->dev_remove_channel)
819819
ops->dev_remove_channel(priv);
820820

821+
kvaser_usb_devlink_port_unregister(priv);
821822
free_candev(priv->netdev);
822823
}
823824
}
@@ -891,20 +892,28 @@ static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)
891892
if (ops->dev_init_channel) {
892893
err = ops->dev_init_channel(priv);
893894
if (err)
894-
goto err;
895+
goto candev_free;
896+
}
897+
898+
err = kvaser_usb_devlink_port_register(priv);
899+
if (err) {
900+
dev_err(&dev->intf->dev, "Failed to register devlink port\n");
901+
goto candev_free;
895902
}
896903

897904
err = register_candev(netdev);
898905
if (err) {
899906
dev_err(&dev->intf->dev, "Failed to register CAN device\n");
900-
goto err;
907+
goto unregister_devlink_port;
901908
}
902909

903910
netdev_dbg(netdev, "device registered\n");
904911

905912
return 0;
906913

907-
err:
914+
unregister_devlink_port:
915+
kvaser_usb_devlink_port_unregister(priv);
916+
candev_free:
908917
free_candev(netdev);
909918
dev->nets[channel] = NULL;
910919
return err;

drivers/net/can/usb/kvaser_usb/kvaser_usb_devlink.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
#include "kvaser_usb.h"
77

8+
#include <linux/netdevice.h>
89
#include <net/devlink.h>
910

1011
#define KVASER_USB_EAN_MSB 0x00073301
@@ -60,3 +61,27 @@ static int kvaser_usb_devlink_info_get(struct devlink *devlink,
6061
const struct devlink_ops kvaser_usb_devlink_ops = {
6162
.info_get = kvaser_usb_devlink_info_get,
6263
};
64+
65+
int kvaser_usb_devlink_port_register(struct kvaser_usb_net_priv *priv)
66+
{
67+
int ret;
68+
struct devlink_port_attrs attrs = {
69+
.flavour = DEVLINK_PORT_FLAVOUR_PHYSICAL,
70+
.phys.port_number = priv->channel,
71+
};
72+
devlink_port_attrs_set(&priv->devlink_port, &attrs);
73+
74+
ret = devlink_port_register(priv_to_devlink(priv->dev),
75+
&priv->devlink_port, priv->channel);
76+
if (ret)
77+
return ret;
78+
79+
SET_NETDEV_DEVLINK_PORT(priv->netdev, &priv->devlink_port);
80+
81+
return 0;
82+
}
83+
84+
void kvaser_usb_devlink_port_unregister(struct kvaser_usb_net_priv *priv)
85+
{
86+
devlink_port_unregister(&priv->devlink_port);
87+
}

0 commit comments

Comments
 (0)