1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2023 Intel Corporation. */
4 #include <net/devlink.h>
6 #include "i40e_devlink.h"
8 static void i40e_info_get_dsn(struct i40e_pf
*pf
, char *buf
, size_t len
)
12 put_unaligned_be64(pci_get_dsn(pf
->pdev
), dsn
);
14 snprintf(buf
, len
, "%8phD", dsn
);
17 static void i40e_info_fw_mgmt(struct i40e_hw
*hw
, char *buf
, size_t len
)
19 struct i40e_adminq_info
*aq
= &hw
->aq
;
21 snprintf(buf
, len
, "%u.%u", aq
->fw_maj_ver
, aq
->fw_min_ver
);
24 static void i40e_info_fw_mgmt_build(struct i40e_hw
*hw
, char *buf
, size_t len
)
26 struct i40e_adminq_info
*aq
= &hw
->aq
;
28 snprintf(buf
, len
, "%05d", aq
->fw_build
);
31 static void i40e_info_fw_api(struct i40e_hw
*hw
, char *buf
, size_t len
)
33 struct i40e_adminq_info
*aq
= &hw
->aq
;
35 snprintf(buf
, len
, "%u.%u", aq
->api_maj_ver
, aq
->api_min_ver
);
38 static void i40e_info_pba(struct i40e_hw
*hw
, char *buf
, size_t len
)
42 strscpy(buf
, hw
->pba_id
, len
);
45 enum i40e_devlink_version_type
{
46 I40E_DL_VERSION_FIXED
,
47 I40E_DL_VERSION_RUNNING
,
50 static int i40e_devlink_info_put(struct devlink_info_req
*req
,
51 enum i40e_devlink_version_type type
,
52 const char *key
, const char *value
)
58 case I40E_DL_VERSION_FIXED
:
59 return devlink_info_version_fixed_put(req
, key
, value
);
60 case I40E_DL_VERSION_RUNNING
:
61 return devlink_info_version_running_put(req
, key
, value
);
66 static int i40e_devlink_info_get(struct devlink
*dl
,
67 struct devlink_info_req
*req
,
68 struct netlink_ext_ack
*extack
)
70 struct i40e_pf
*pf
= devlink_priv(dl
);
71 struct i40e_hw
*hw
= &pf
->hw
;
75 i40e_info_get_dsn(pf
, buf
, sizeof(buf
));
76 err
= devlink_info_serial_number_put(req
, buf
);
80 i40e_info_fw_mgmt(hw
, buf
, sizeof(buf
));
81 err
= i40e_devlink_info_put(req
, I40E_DL_VERSION_RUNNING
,
82 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT
, buf
);
86 i40e_info_fw_mgmt_build(hw
, buf
, sizeof(buf
));
87 err
= i40e_devlink_info_put(req
, I40E_DL_VERSION_RUNNING
,
88 "fw.mgmt.build", buf
);
92 i40e_info_fw_api(hw
, buf
, sizeof(buf
));
93 err
= i40e_devlink_info_put(req
, I40E_DL_VERSION_RUNNING
,
94 DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API
,
99 i40e_info_nvm_ver(hw
, buf
, sizeof(buf
));
100 err
= i40e_devlink_info_put(req
, I40E_DL_VERSION_RUNNING
,
105 i40e_info_eetrack(hw
, buf
, sizeof(buf
));
106 err
= i40e_devlink_info_put(req
, I40E_DL_VERSION_RUNNING
,
107 DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID
,
112 i40e_info_civd_ver(hw
, buf
, sizeof(buf
));
113 err
= i40e_devlink_info_put(req
, I40E_DL_VERSION_RUNNING
,
114 DEVLINK_INFO_VERSION_GENERIC_FW_UNDI
, buf
);
118 i40e_info_pba(hw
, buf
, sizeof(buf
));
119 err
= i40e_devlink_info_put(req
, I40E_DL_VERSION_FIXED
,
120 DEVLINK_INFO_VERSION_GENERIC_BOARD_ID
, buf
);
125 static const struct devlink_ops i40e_devlink_ops
= {
126 .info_get
= i40e_devlink_info_get
,
130 * i40e_alloc_pf - Allocate devlink and return i40e_pf structure pointer
131 * @dev: the device to allocate for
133 * Allocate a devlink instance for this device and return the private
134 * area as the i40e_pf structure.
136 struct i40e_pf
*i40e_alloc_pf(struct device
*dev
)
138 struct devlink
*devlink
;
140 devlink
= devlink_alloc(&i40e_devlink_ops
, sizeof(struct i40e_pf
), dev
);
144 return devlink_priv(devlink
);
148 * i40e_free_pf - Free i40e_pf structure and associated devlink
149 * @pf: the PF structure
151 * Free i40e_pf structure and devlink allocated by devlink_alloc.
153 void i40e_free_pf(struct i40e_pf
*pf
)
155 struct devlink
*devlink
= priv_to_devlink(pf
);
157 devlink_free(devlink
);
161 * i40e_devlink_register - Register devlink interface for this PF
162 * @pf: the PF to register the devlink for.
164 * Register the devlink instance associated with this physical function.
166 void i40e_devlink_register(struct i40e_pf
*pf
)
168 devlink_register(priv_to_devlink(pf
));
172 * i40e_devlink_unregister - Unregister devlink resources for this PF.
173 * @pf: the PF structure to cleanup
175 * Releases resources used by devlink and cleans up associated memory.
177 void i40e_devlink_unregister(struct i40e_pf
*pf
)
179 devlink_unregister(priv_to_devlink(pf
));
183 * i40e_devlink_set_switch_id - Set unique switch id based on pci dsn
184 * @pf: the PF to create a devlink port for
185 * @ppid: struct with switch id information
187 static void i40e_devlink_set_switch_id(struct i40e_pf
*pf
,
188 struct netdev_phys_item_id
*ppid
)
190 u64 id
= pci_get_dsn(pf
->pdev
);
192 ppid
->id_len
= sizeof(id
);
193 put_unaligned_be64(id
, &ppid
->id
);
197 * i40e_devlink_create_port - Create a devlink port for this PF
198 * @pf: the PF to create a port for
200 * Create and register a devlink_port for this PF. Note that although each
201 * physical function is connected to a separate devlink instance, the port
202 * will still be numbered according to the physical function id.
204 * Return: zero on success or an error code on failure.
206 int i40e_devlink_create_port(struct i40e_pf
*pf
)
208 struct devlink
*devlink
= priv_to_devlink(pf
);
209 struct devlink_port_attrs attrs
= {};
210 struct device
*dev
= &pf
->pdev
->dev
;
213 attrs
.flavour
= DEVLINK_PORT_FLAVOUR_PHYSICAL
;
214 attrs
.phys
.port_number
= pf
->hw
.pf_id
;
215 i40e_devlink_set_switch_id(pf
, &attrs
.switch_id
);
216 devlink_port_attrs_set(&pf
->devlink_port
, &attrs
);
217 err
= devlink_port_register(devlink
, &pf
->devlink_port
, pf
->hw
.pf_id
);
219 dev_err(dev
, "devlink_port_register failed: %d\n", err
);
227 * i40e_devlink_destroy_port - Destroy the devlink_port for this PF
228 * @pf: the PF to cleanup
230 * Unregisters the devlink_port structure associated with this PF.
232 void i40e_devlink_destroy_port(struct i40e_pf
*pf
)
234 devlink_port_unregister(&pf
->devlink_port
);