1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2020, Intel Corporation. */
6 #include "ice_devlink.h"
7 #include "ice_fw_update.h"
9 static void ice_info_get_dsn(struct ice_pf
*pf
, char *buf
, size_t len
)
13 /* Copy the DSN into an array in Big Endian format */
14 put_unaligned_be64(pci_get_dsn(pf
->pdev
), dsn
);
16 snprintf(buf
, len
, "%8phD", dsn
);
19 static int ice_info_pba(struct ice_pf
*pf
, char *buf
, size_t len
)
21 struct ice_hw
*hw
= &pf
->hw
;
22 enum ice_status status
;
24 status
= ice_read_pba_string(hw
, (u8
*)buf
, len
);
31 static int ice_info_fw_mgmt(struct ice_pf
*pf
, char *buf
, size_t len
)
33 struct ice_hw
*hw
= &pf
->hw
;
35 snprintf(buf
, len
, "%u.%u.%u", hw
->fw_maj_ver
, hw
->fw_min_ver
,
41 static int ice_info_fw_api(struct ice_pf
*pf
, char *buf
, size_t len
)
43 struct ice_hw
*hw
= &pf
->hw
;
45 snprintf(buf
, len
, "%u.%u", hw
->api_maj_ver
, hw
->api_min_ver
);
50 static int ice_info_fw_build(struct ice_pf
*pf
, char *buf
, size_t len
)
52 struct ice_hw
*hw
= &pf
->hw
;
54 snprintf(buf
, len
, "0x%08x", hw
->fw_build
);
59 static int ice_info_orom_ver(struct ice_pf
*pf
, char *buf
, size_t len
)
61 struct ice_orom_info
*orom
= &pf
->hw
.nvm
.orom
;
63 snprintf(buf
, len
, "%u.%u.%u", orom
->major
, orom
->build
, orom
->patch
);
68 static int ice_info_nvm_ver(struct ice_pf
*pf
, char *buf
, size_t len
)
70 struct ice_nvm_info
*nvm
= &pf
->hw
.nvm
;
72 snprintf(buf
, len
, "%x.%02x", nvm
->major_ver
, nvm
->minor_ver
);
77 static int ice_info_eetrack(struct ice_pf
*pf
, char *buf
, size_t len
)
79 struct ice_nvm_info
*nvm
= &pf
->hw
.nvm
;
81 snprintf(buf
, len
, "0x%08x", nvm
->eetrack
);
86 static int ice_info_ddp_pkg_name(struct ice_pf
*pf
, char *buf
, size_t len
)
88 struct ice_hw
*hw
= &pf
->hw
;
90 snprintf(buf
, len
, "%s", hw
->active_pkg_name
);
95 static int ice_info_ddp_pkg_version(struct ice_pf
*pf
, char *buf
, size_t len
)
97 struct ice_pkg_ver
*pkg
= &pf
->hw
.active_pkg_ver
;
99 snprintf(buf
, len
, "%u.%u.%u.%u", pkg
->major
, pkg
->minor
, pkg
->update
,
105 static int ice_info_ddp_pkg_bundle_id(struct ice_pf
*pf
, char *buf
, size_t len
)
107 snprintf(buf
, len
, "0x%08x", pf
->hw
.active_track_id
);
112 static int ice_info_netlist_ver(struct ice_pf
*pf
, char *buf
, size_t len
)
114 struct ice_netlist_ver_info
*netlist
= &pf
->hw
.netlist_ver
;
116 /* The netlist version fields are BCD formatted */
117 snprintf(buf
, len
, "%x.%x.%x-%x.%x.%x", netlist
->major
, netlist
->minor
,
118 netlist
->type
>> 16, netlist
->type
& 0xFFFF, netlist
->rev
,
124 static int ice_info_netlist_build(struct ice_pf
*pf
, char *buf
, size_t len
)
126 struct ice_netlist_ver_info
*netlist
= &pf
->hw
.netlist_ver
;
128 snprintf(buf
, len
, "0x%08x", netlist
->hash
);
133 #define fixed(key, getter) { ICE_VERSION_FIXED, key, getter }
134 #define running(key, getter) { ICE_VERSION_RUNNING, key, getter }
136 enum ice_version_type
{
142 static const struct ice_devlink_version
{
143 enum ice_version_type type
;
145 int (*getter
)(struct ice_pf
*pf
, char *buf
, size_t len
);
146 } ice_devlink_versions
[] = {
147 fixed(DEVLINK_INFO_VERSION_GENERIC_BOARD_ID
, ice_info_pba
),
148 running(DEVLINK_INFO_VERSION_GENERIC_FW_MGMT
, ice_info_fw_mgmt
),
149 running("fw.mgmt.api", ice_info_fw_api
),
150 running("fw.mgmt.build", ice_info_fw_build
),
151 running(DEVLINK_INFO_VERSION_GENERIC_FW_UNDI
, ice_info_orom_ver
),
152 running("fw.psid.api", ice_info_nvm_ver
),
153 running(DEVLINK_INFO_VERSION_GENERIC_FW_BUNDLE_ID
, ice_info_eetrack
),
154 running("fw.app.name", ice_info_ddp_pkg_name
),
155 running(DEVLINK_INFO_VERSION_GENERIC_FW_APP
, ice_info_ddp_pkg_version
),
156 running("fw.app.bundle_id", ice_info_ddp_pkg_bundle_id
),
157 running("fw.netlist", ice_info_netlist_ver
),
158 running("fw.netlist.build", ice_info_netlist_build
),
162 * ice_devlink_info_get - .info_get devlink handler
163 * @devlink: devlink instance structure
164 * @req: the devlink info request
165 * @extack: extended netdev ack structure
167 * Callback for the devlink .info_get operation. Reports information about the
170 * Return: zero on success or an error code on failure.
172 static int ice_devlink_info_get(struct devlink
*devlink
,
173 struct devlink_info_req
*req
,
174 struct netlink_ext_ack
*extack
)
176 struct ice_pf
*pf
= devlink_priv(devlink
);
181 err
= devlink_info_driver_name_put(req
, KBUILD_MODNAME
);
183 NL_SET_ERR_MSG_MOD(extack
, "Unable to set driver name");
187 ice_info_get_dsn(pf
, buf
, sizeof(buf
));
189 err
= devlink_info_serial_number_put(req
, buf
);
191 NL_SET_ERR_MSG_MOD(extack
, "Unable to set serial number");
195 for (i
= 0; i
< ARRAY_SIZE(ice_devlink_versions
); i
++) {
196 enum ice_version_type type
= ice_devlink_versions
[i
].type
;
197 const char *key
= ice_devlink_versions
[i
].key
;
199 err
= ice_devlink_versions
[i
].getter(pf
, buf
, sizeof(buf
));
201 NL_SET_ERR_MSG_MOD(extack
, "Unable to obtain version info");
206 case ICE_VERSION_FIXED
:
207 err
= devlink_info_version_fixed_put(req
, key
, buf
);
209 NL_SET_ERR_MSG_MOD(extack
, "Unable to set fixed version");
213 case ICE_VERSION_RUNNING
:
214 err
= devlink_info_version_running_put(req
, key
, buf
);
216 NL_SET_ERR_MSG_MOD(extack
, "Unable to set running version");
220 case ICE_VERSION_STORED
:
221 err
= devlink_info_version_stored_put(req
, key
, buf
);
223 NL_SET_ERR_MSG_MOD(extack
, "Unable to set stored version");
234 * ice_devlink_flash_update - Update firmware stored in flash on the device
235 * @devlink: pointer to devlink associated with device to update
236 * @params: flash update parameters
237 * @extack: netlink extended ACK structure
239 * Perform a device flash update. The bulk of the update logic is contained
240 * within the ice_flash_pldm_image function.
242 * Returns: zero on success, or an error code on failure.
245 ice_devlink_flash_update(struct devlink
*devlink
,
246 struct devlink_flash_update_params
*params
,
247 struct netlink_ext_ack
*extack
)
249 struct ice_pf
*pf
= devlink_priv(devlink
);
250 struct ice_hw
*hw
= &pf
->hw
;
254 if (!params
->overwrite_mask
) {
255 /* preserve all settings and identifiers */
256 preservation
= ICE_AQC_NVM_PRESERVE_ALL
;
257 } else if (params
->overwrite_mask
== DEVLINK_FLASH_OVERWRITE_SETTINGS
) {
258 /* overwrite settings, but preserve the vital device identifiers */
259 preservation
= ICE_AQC_NVM_PRESERVE_SELECTED
;
260 } else if (params
->overwrite_mask
== (DEVLINK_FLASH_OVERWRITE_SETTINGS
|
261 DEVLINK_FLASH_OVERWRITE_IDENTIFIERS
)) {
262 /* overwrite both settings and identifiers, preserve nothing */
263 preservation
= ICE_AQC_NVM_NO_PRESERVATION
;
265 NL_SET_ERR_MSG_MOD(extack
, "Requested overwrite mask is not supported");
269 if (!hw
->dev_caps
.common_cap
.nvm_unified_update
) {
270 NL_SET_ERR_MSG_MOD(extack
, "Current firmware does not support unified update");
274 err
= ice_check_for_pending_update(pf
, NULL
, extack
);
278 devlink_flash_update_status_notify(devlink
, "Preparing to flash", NULL
, 0, 0);
280 return ice_flash_pldm_image(pf
, params
->fw
, preservation
, extack
);
283 static const struct devlink_ops ice_devlink_ops
= {
284 .supported_flash_update_params
= DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK
,
285 .info_get
= ice_devlink_info_get
,
286 .flash_update
= ice_devlink_flash_update
,
289 static void ice_devlink_free(void *devlink_ptr
)
291 devlink_free((struct devlink
*)devlink_ptr
);
295 * ice_allocate_pf - Allocate devlink and return PF structure pointer
296 * @dev: the device to allocate for
298 * Allocate a devlink instance for this device and return the private area as
299 * the PF structure. The devlink memory is kept track of through devres by
300 * adding an action to remove it when unwinding.
302 struct ice_pf
*ice_allocate_pf(struct device
*dev
)
304 struct devlink
*devlink
;
306 devlink
= devlink_alloc(&ice_devlink_ops
, sizeof(struct ice_pf
));
310 /* Add an action to teardown the devlink when unwinding the driver */
311 if (devm_add_action(dev
, ice_devlink_free
, devlink
)) {
312 devlink_free(devlink
);
316 return devlink_priv(devlink
);
320 * ice_devlink_register - Register devlink interface for this PF
321 * @pf: the PF to register the devlink for.
323 * Register the devlink instance associated with this physical function.
325 * Return: zero on success or an error code on failure.
327 int ice_devlink_register(struct ice_pf
*pf
)
329 struct devlink
*devlink
= priv_to_devlink(pf
);
330 struct device
*dev
= ice_pf_to_dev(pf
);
333 err
= devlink_register(devlink
, dev
);
335 dev_err(dev
, "devlink registration failed: %d\n", err
);
343 * ice_devlink_unregister - Unregister devlink resources for this PF.
344 * @pf: the PF structure to cleanup
346 * Releases resources used by devlink and cleans up associated memory.
348 void ice_devlink_unregister(struct ice_pf
*pf
)
350 devlink_unregister(priv_to_devlink(pf
));
354 * ice_devlink_create_port - Create a devlink port for this VSI
355 * @vsi: the VSI to create a port for
357 * Create and register a devlink_port for this VSI.
359 * Return: zero on success or an error code on failure.
361 int ice_devlink_create_port(struct ice_vsi
*vsi
)
363 struct devlink_port_attrs attrs
= {};
364 struct ice_port_info
*pi
;
365 struct devlink
*devlink
;
370 /* Currently we only create devlink_port instances for PF VSIs */
371 if (vsi
->type
!= ICE_VSI_PF
)
375 devlink
= priv_to_devlink(pf
);
376 dev
= ice_pf_to_dev(pf
);
377 pi
= pf
->hw
.port_info
;
379 attrs
.flavour
= DEVLINK_PORT_FLAVOUR_PHYSICAL
;
380 attrs
.phys
.port_number
= pi
->lport
;
381 devlink_port_attrs_set(&vsi
->devlink_port
, &attrs
);
382 err
= devlink_port_register(devlink
, &vsi
->devlink_port
, vsi
->idx
);
384 dev_err(dev
, "devlink_port_register failed: %d\n", err
);
388 vsi
->devlink_port_registered
= true;
394 * ice_devlink_destroy_port - Destroy the devlink_port for this VSI
395 * @vsi: the VSI to cleanup
397 * Unregisters the devlink_port structure associated with this VSI.
399 void ice_devlink_destroy_port(struct ice_vsi
*vsi
)
401 if (!vsi
->devlink_port_registered
)
404 devlink_port_type_clear(&vsi
->devlink_port
);
405 devlink_port_unregister(&vsi
->devlink_port
);
407 vsi
->devlink_port_registered
= false;
411 * ice_devlink_nvm_snapshot - Capture a snapshot of the Shadow RAM contents
412 * @devlink: the devlink instance
413 * @ops: the devlink region being snapshotted
414 * @extack: extended ACK response structure
415 * @data: on exit points to snapshot data buffer
417 * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for
418 * the shadow-ram devlink region. It captures a snapshot of the shadow ram
419 * contents. This snapshot can later be viewed via the devlink-region
422 * @returns zero on success, and updates the data pointer. Returns a non-zero
423 * error code on failure.
425 static int ice_devlink_nvm_snapshot(struct devlink
*devlink
,
426 const struct devlink_region_ops
*ops
,
427 struct netlink_ext_ack
*extack
, u8
**data
)
429 struct ice_pf
*pf
= devlink_priv(devlink
);
430 struct device
*dev
= ice_pf_to_dev(pf
);
431 struct ice_hw
*hw
= &pf
->hw
;
432 enum ice_status status
;
436 nvm_size
= hw
->nvm
.flash_size
;
437 nvm_data
= vzalloc(nvm_size
);
441 status
= ice_acquire_nvm(hw
, ICE_RES_READ
);
443 dev_dbg(dev
, "ice_acquire_nvm failed, err %d aq_err %d\n",
444 status
, hw
->adminq
.sq_last_status
);
445 NL_SET_ERR_MSG_MOD(extack
, "Failed to acquire NVM semaphore");
450 status
= ice_read_flat_nvm(hw
, 0, &nvm_size
, nvm_data
, false);
452 dev_dbg(dev
, "ice_read_flat_nvm failed after reading %u bytes, err %d aq_err %d\n",
453 nvm_size
, status
, hw
->adminq
.sq_last_status
);
454 NL_SET_ERR_MSG_MOD(extack
, "Failed to read NVM contents");
468 * ice_devlink_devcaps_snapshot - Capture snapshot of device capabilities
469 * @devlink: the devlink instance
470 * @ops: the devlink region being snapshotted
471 * @extack: extended ACK response structure
472 * @data: on exit points to snapshot data buffer
474 * This function is called in response to the DEVLINK_CMD_REGION_TRIGGER for
475 * the device-caps devlink region. It captures a snapshot of the device
476 * capabilities reported by firmware.
478 * @returns zero on success, and updates the data pointer. Returns a non-zero
479 * error code on failure.
482 ice_devlink_devcaps_snapshot(struct devlink
*devlink
,
483 const struct devlink_region_ops
*ops
,
484 struct netlink_ext_ack
*extack
, u8
**data
)
486 struct ice_pf
*pf
= devlink_priv(devlink
);
487 struct device
*dev
= ice_pf_to_dev(pf
);
488 struct ice_hw
*hw
= &pf
->hw
;
489 enum ice_status status
;
492 devcaps
= vzalloc(ICE_AQ_MAX_BUF_LEN
);
496 status
= ice_aq_list_caps(hw
, devcaps
, ICE_AQ_MAX_BUF_LEN
, NULL
,
497 ice_aqc_opc_list_dev_caps
, NULL
);
499 dev_dbg(dev
, "ice_aq_list_caps: failed to read device capabilities, err %d aq_err %d\n",
500 status
, hw
->adminq
.sq_last_status
);
501 NL_SET_ERR_MSG_MOD(extack
, "Failed to read device capabilities");
506 *data
= (u8
*)devcaps
;
511 static const struct devlink_region_ops ice_nvm_region_ops
= {
514 .snapshot
= ice_devlink_nvm_snapshot
,
517 static const struct devlink_region_ops ice_devcaps_region_ops
= {
518 .name
= "device-caps",
520 .snapshot
= ice_devlink_devcaps_snapshot
,
524 * ice_devlink_init_regions - Initialize devlink regions
525 * @pf: the PF device structure
527 * Create devlink regions used to enable access to dump the contents of the
528 * flash memory on the device.
530 void ice_devlink_init_regions(struct ice_pf
*pf
)
532 struct devlink
*devlink
= priv_to_devlink(pf
);
533 struct device
*dev
= ice_pf_to_dev(pf
);
536 nvm_size
= pf
->hw
.nvm
.flash_size
;
537 pf
->nvm_region
= devlink_region_create(devlink
, &ice_nvm_region_ops
, 1,
539 if (IS_ERR(pf
->nvm_region
)) {
540 dev_err(dev
, "failed to create NVM devlink region, err %ld\n",
541 PTR_ERR(pf
->nvm_region
));
542 pf
->nvm_region
= NULL
;
545 pf
->devcaps_region
= devlink_region_create(devlink
,
546 &ice_devcaps_region_ops
, 10,
548 if (IS_ERR(pf
->devcaps_region
)) {
549 dev_err(dev
, "failed to create device-caps devlink region, err %ld\n",
550 PTR_ERR(pf
->devcaps_region
));
551 pf
->devcaps_region
= NULL
;
556 * ice_devlink_destroy_regions - Destroy devlink regions
557 * @pf: the PF device structure
559 * Remove previously created regions for this PF.
561 void ice_devlink_destroy_regions(struct ice_pf
*pf
)
564 devlink_region_destroy(pf
->nvm_region
);
565 if (pf
->devcaps_region
)
566 devlink_region_destroy(pf
->devcaps_region
);