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