xref: /linux/drivers/net/ethernet/intel/ixd/ixd_devlink.c (revision 91ec2035134982b98fab0609a9fd8480e8217dc1)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2025, Intel Corporation. */
3 
4 #include "ixd.h"
5 #include "ixd_devlink.h"
6 
7 #define IXD_DEVLINK_INFO_LEN	128
8 
9 /**
10  * ixd_fill_dsn - Get the serial number for the ixd device
11  * @adapter: adapter to query
12  * @buf: storage buffer for the info request
13  */
ixd_fill_dsn(struct ixd_adapter * adapter,char * buf)14 static void ixd_fill_dsn(struct ixd_adapter *adapter, char *buf)
15 {
16 	u8 dsn[8];
17 
18 	/* Copy the DSN into an array in Big Endian format */
19 	put_unaligned_be64(pci_get_dsn(adapter->cp_ctx.mmio_info.pdev), dsn);
20 
21 	snprintf(buf, IXD_DEVLINK_INFO_LEN, "%8phD", dsn);
22 }
23 
24 /**
25  * ixd_fill_device_name - Get the name of the underlying hardware
26  * @adapter: adapter to query
27  * @buf: storage buffer for the info request
28  * @buf_size: size of the storage buffer
29  */
ixd_fill_device_name(struct ixd_adapter * adapter,char * buf,size_t buf_size)30 static void ixd_fill_device_name(struct ixd_adapter *adapter, char *buf,
31 				 size_t buf_size)
32 {
33 	if (adapter->caps.device_type == cpu_to_le32(VIRTCHNL2_MEV_DEVICE))
34 		snprintf(buf, buf_size, "%s", "MEV");
35 	else
36 		snprintf(buf, buf_size, "%s", "UNKNOWN");
37 }
38 
39 /**
40  * ixd_devlink_info_get - .info_get devlink handler
41  * @devlink: devlink instance structure
42  * @req: the devlink info request
43  * @extack: extended netdev ack structure
44  *
45  * Callback for the devlink .info_get operation. Reports information about the
46  * device.
47  *
48  * Return: zero on success or an error code on failure.
49  */
ixd_devlink_info_get(struct devlink * devlink,struct devlink_info_req * req,struct netlink_ext_ack * extack)50 static int ixd_devlink_info_get(struct devlink *devlink,
51 				struct devlink_info_req *req,
52 				struct netlink_ext_ack *extack)
53 {
54 	struct ixd_adapter *adapter = devlink_priv(devlink);
55 	char buf[IXD_DEVLINK_INFO_LEN];
56 	int err;
57 
58 	ixd_fill_dsn(adapter, buf);
59 	err = devlink_info_serial_number_put(req, buf);
60 	if (err)
61 		return err;
62 
63 	ixd_fill_device_name(adapter, buf, IXD_DEVLINK_INFO_LEN);
64 	err = devlink_info_version_fixed_put(req, "device.type", buf);
65 	if (err)
66 		return err;
67 
68 	snprintf(buf, sizeof(buf), "%u.%u",
69 		 adapter->vc_ver.major, adapter->vc_ver.minor);
70 
71 	return devlink_info_version_running_put(req,
72 						DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API,
73 						buf);
74 }
75 
76 static const struct devlink_ops ixd_devlink_ops = {
77 	.info_get = ixd_devlink_info_get,
78 };
79 
80 /**
81  * ixd_adapter_alloc - Allocate devlink and return adapter pointer
82  * @dev: the device to allocate for
83  *
84  * Allocate a devlink instance for this device and return the private area as
85  * the adapter structure.
86  *
87  * Return: adapter structure on success, NULL on failure
88  */
ixd_adapter_alloc(struct device * dev)89 struct ixd_adapter *ixd_adapter_alloc(struct device *dev)
90 {
91 	struct devlink *devlink;
92 
93 	devlink = devlink_alloc(&ixd_devlink_ops, sizeof(struct ixd_adapter),
94 				dev);
95 	if (!devlink)
96 		return NULL;
97 
98 	return devlink_priv(devlink);
99 }
100