xref: /linux/drivers/net/can/usb/kvaser_usb/kvaser_usb_devlink.c (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
1 // SPDX-License-Identifier: GPL-2.0
2 /* kvaser_usb devlink functions
3  *
4  * Copyright (C) 2025 KVASER AB, Sweden. All rights reserved.
5  */
6 #include "kvaser_usb.h"
7 
8 #include <linux/netdevice.h>
9 #include <net/devlink.h>
10 
11 #define KVASER_USB_EAN_MSB 0x00073301
12 
kvaser_usb_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)13 static int kvaser_usb_devlink_info_get(struct devlink *devlink,
14 				       struct devlink_info_req *req,
15 				       struct netlink_ext_ack *extack)
16 {
17 	struct kvaser_usb *dev = devlink_priv(devlink);
18 	char buf[] = "73301XXXXXXXXXX";
19 	int ret;
20 
21 	if (dev->serial_number) {
22 		snprintf(buf, sizeof(buf), "%u", dev->serial_number);
23 		ret = devlink_info_serial_number_put(req, buf);
24 		if (ret)
25 			return ret;
26 	}
27 
28 	if (dev->fw_version.major) {
29 		snprintf(buf, sizeof(buf), "%u.%u.%u",
30 			 dev->fw_version.major,
31 			 dev->fw_version.minor,
32 			 dev->fw_version.build);
33 		ret = devlink_info_version_running_put(req,
34 						       DEVLINK_INFO_VERSION_GENERIC_FW,
35 						       buf);
36 		if (ret)
37 			return ret;
38 	}
39 
40 	if (dev->hw_revision) {
41 		snprintf(buf, sizeof(buf), "%u", dev->hw_revision);
42 		ret = devlink_info_version_fixed_put(req,
43 						     DEVLINK_INFO_VERSION_GENERIC_BOARD_REV,
44 						     buf);
45 		if (ret)
46 			return ret;
47 	}
48 
49 	if (dev->ean[1] == KVASER_USB_EAN_MSB) {
50 		snprintf(buf, sizeof(buf), "%x%08x", dev->ean[1], dev->ean[0]);
51 		ret = devlink_info_version_fixed_put(req,
52 						     DEVLINK_INFO_VERSION_GENERIC_BOARD_ID,
53 						     buf);
54 		if (ret)
55 			return ret;
56 	}
57 
58 	return 0;
59 }
60 
61 const struct devlink_ops kvaser_usb_devlink_ops = {
62 	.info_get = kvaser_usb_devlink_info_get,
63 };
64 
kvaser_usb_devlink_port_register(struct kvaser_usb_net_priv * priv)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 
kvaser_usb_devlink_port_unregister(struct kvaser_usb_net_priv * priv)84 void kvaser_usb_devlink_port_unregister(struct kvaser_usb_net_priv *priv)
85 {
86 	devlink_port_unregister(&priv->devlink_port);
87 }
88