1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright(c) 2025 Intel Corporation. */ 3 4 #include <linux/crc32.h> 5 #include <linux/pldmfw.h> 6 #include <linux/uuid.h> 7 8 #include "ixgbe.h" 9 #include "ixgbe_fw_update.h" 10 11 struct ixgbe_fwu_priv { 12 struct pldmfw context; 13 14 struct ixgbe_adapter *adapter; 15 struct netlink_ext_ack *extack; 16 17 /* Track which NVM banks to activate at the end of the update */ 18 u8 activate_flags; 19 bool emp_reset_available; 20 }; 21 22 /** 23 * ixgbe_send_package_data - Send record package data to firmware 24 * @context: PLDM fw update structure 25 * @data: pointer to the package data 26 * @length: length of the package data 27 * 28 * Send a copy of the package data associated with the PLDM record matching 29 * this device to the firmware. 30 * 31 * Note that this function sends an AdminQ command that will fail unless the 32 * NVM resource has been acquired. 33 * 34 * Return: zero on success, or a negative error code on failure. 35 */ 36 static int ixgbe_send_package_data(struct pldmfw *context, 37 const u8 *data, u16 length) 38 { 39 struct ixgbe_fwu_priv *priv = container_of(context, 40 struct ixgbe_fwu_priv, 41 context); 42 struct ixgbe_adapter *adapter = priv->adapter; 43 struct ixgbe_hw *hw = &adapter->hw; 44 u8 *package_data; 45 int err; 46 47 package_data = kmemdup(data, length, GFP_KERNEL); 48 if (!package_data) 49 return -ENOMEM; 50 51 err = ixgbe_nvm_set_pkg_data(hw, false, package_data, length); 52 53 kfree(package_data); 54 55 return err; 56 } 57 58 /** 59 * ixgbe_check_component_response - Report firmware response to a component 60 * @adapter: device private data structure 61 * @response: indicates whether this component can be updated 62 * @code: code indicating reason for response 63 * @extack: netlink extended ACK structure 64 * 65 * Check whether firmware indicates if this component can be updated. Report 66 * a suitable error message over the netlink extended ACK if the component 67 * cannot be updated. 68 * 69 * Return: 0 if the component can be updated, or -ECANCELED if the 70 * firmware indicates the component cannot be updated. 71 */ 72 static int ixgbe_check_component_response(struct ixgbe_adapter *adapter, 73 u8 response, u8 code, 74 struct netlink_ext_ack *extack) 75 { 76 switch (response) { 77 case IXGBE_ACI_NVM_PASS_COMP_CAN_BE_UPDATED: 78 /* Firmware indicated this update is good to proceed. */ 79 return 0; 80 case IXGBE_ACI_NVM_PASS_COMP_CAN_MAY_BE_UPDATEABLE: 81 NL_SET_ERR_MSG_MOD(extack, 82 "Firmware recommends not updating, as it may result in a downgrade. Continuing anyways"); 83 return 0; 84 case IXGBE_ACI_NVM_PASS_COMP_CAN_NOT_BE_UPDATED: 85 NL_SET_ERR_MSG_MOD(extack, "Firmware has rejected updating."); 86 break; 87 } 88 89 switch (code) { 90 case IXGBE_ACI_NVM_PASS_COMP_STAMP_IDENTICAL_CODE: 91 NL_SET_ERR_MSG_MOD(extack, 92 "Component comparison stamp is identical to running image"); 93 break; 94 case IXGBE_ACI_NVM_PASS_COMP_STAMP_LOWER: 95 NL_SET_ERR_MSG_MOD(extack, 96 "Component comparison stamp is lower than running image"); 97 break; 98 case IXGBE_ACI_NVM_PASS_COMP_INVALID_STAMP_CODE: 99 NL_SET_ERR_MSG_MOD(extack, 100 "Component comparison stamp is invalid"); 101 break; 102 case IXGBE_ACI_NVM_PASS_COMP_CONFLICT_CODE: 103 NL_SET_ERR_MSG_MOD(extack, 104 "Component table conflict occurred"); 105 break; 106 case IXGBE_ACI_NVM_PASS_COMP_PRE_REQ_NOT_MET_CODE: 107 NL_SET_ERR_MSG_MOD(extack, "Component pre-requisites not met"); 108 break; 109 case IXGBE_ACI_NVM_PASS_COMP_NOT_SUPPORTED_CODE: 110 NL_SET_ERR_MSG_MOD(extack, "Component not supported"); 111 break; 112 case IXGBE_ACI_NVM_PASS_COMP_CANNOT_DOWNGRADE_CODE: 113 NL_SET_ERR_MSG_MOD(extack, "Component cannot be downgraded"); 114 break; 115 case IXGBE_ACI_NVM_PASS_COMP_INCOMPLETE_IMAGE_CODE: 116 NL_SET_ERR_MSG_MOD(extack, "Incomplete component image"); 117 break; 118 case IXGBE_ACI_NVM_PASS_COMP_VER_STR_IDENTICAL_CODE: 119 NL_SET_ERR_MSG_MOD(extack, 120 "Component version is identical to running image"); 121 break; 122 case IXGBE_ACI_NVM_PASS_COMP_VER_STR_LOWER_CODE: 123 NL_SET_ERR_MSG_MOD(extack, 124 "Component version is lower than the running image"); 125 break; 126 default: 127 NL_SET_ERR_MSG_MOD(extack, 128 "Received unexpected response code from firmware"); 129 break; 130 } 131 132 return -ECANCELED; 133 } 134 135 /** 136 * ixgbe_send_component_table - Send PLDM component table to firmware 137 * @context: PLDM fw update structure 138 * @component: the component to process 139 * @transfer_flag: relative transfer order of this component 140 * 141 * Read relevant data from the component and forward it to the device 142 * firmware. Check the response to determine if the firmware indicates that 143 * the update can proceed. 144 * 145 * This function sends ACI commands related to the NVM, and assumes that 146 * the NVM resource has been acquired. 147 * 148 * Return: 0 on success, or a negative error code on failure. 149 */ 150 static int ixgbe_send_component_table(struct pldmfw *context, 151 struct pldmfw_component *component, 152 u8 transfer_flag) 153 { 154 struct ixgbe_fwu_priv *priv = container_of(context, 155 struct ixgbe_fwu_priv, 156 context); 157 struct ixgbe_adapter *adapter = priv->adapter; 158 struct netlink_ext_ack *extack = priv->extack; 159 struct ixgbe_aci_cmd_nvm_comp_tbl *comp_tbl; 160 u8 comp_response, comp_response_code; 161 struct ixgbe_hw *hw = &adapter->hw; 162 size_t length; 163 int err; 164 165 switch (component->identifier) { 166 case NVM_COMP_ID_OROM: 167 case NVM_COMP_ID_NVM: 168 case NVM_COMP_ID_NETLIST: 169 break; 170 default: 171 NL_SET_ERR_MSG_MOD(extack, 172 "Unable to update due to unknown firmware component"); 173 return -EOPNOTSUPP; 174 } 175 176 length = struct_size(comp_tbl, cvs, component->version_len); 177 comp_tbl = kzalloc(length, GFP_KERNEL); 178 if (!comp_tbl) 179 return -ENOMEM; 180 181 comp_tbl->comp_class = cpu_to_le16(component->classification); 182 comp_tbl->comp_id = cpu_to_le16(component->identifier); 183 comp_tbl->comp_class_idx = FWU_COMP_CLASS_IDX_NOT_USE; 184 comp_tbl->comp_cmp_stamp = cpu_to_le32(component->comparison_stamp); 185 comp_tbl->cvs_type = component->version_type; 186 comp_tbl->cvs_len = component->version_len; 187 188 memcpy(comp_tbl->cvs, component->version_string, 189 component->version_len); 190 191 err = ixgbe_nvm_pass_component_tbl(hw, (u8 *)comp_tbl, length, 192 transfer_flag, &comp_response, 193 &comp_response_code); 194 195 kfree(comp_tbl); 196 197 if (err) { 198 NL_SET_ERR_MSG_MOD(extack, 199 "Failed to transfer component table to firmware"); 200 return -EIO; 201 } 202 203 return ixgbe_check_component_response(adapter, 204 comp_response, 205 comp_response_code, extack); 206 } 207 208 /** 209 * ixgbe_write_one_nvm_block - Write an NVM block and await completion response 210 * @adapter: the PF data structure 211 * @module: the module to write to 212 * @offset: offset in bytes 213 * @block_size: size of the block to write, up to 4k 214 * @block: pointer to block of data to write 215 * @last_cmd: whether this is the last command 216 * @extack: netlink extended ACK structure 217 * 218 * Write a block of data to a flash module, and await for the completion 219 * response message from firmware. 220 * 221 * Note this function assumes the caller has acquired the NVM resource. 222 * 223 * On successful return, reset level indicates the device reset required to 224 * complete the update. 225 * 226 * 0 - IXGBE_ACI_NVM_POR_FLAG - A full power on is required 227 * 1 - IXGBE_ACI_NVM_PERST_FLAG - A cold PCIe reset is required 228 * 2 - IXGBE_ACI_NVM_EMPR_FLAG - An EMP reset is required 229 * 230 * Return: 0 on success, or a negative error code on failure. 231 */ 232 static int ixgbe_write_one_nvm_block(struct ixgbe_adapter *adapter, 233 u16 module, u32 offset, 234 u16 block_size, u8 *block, bool last_cmd, 235 struct netlink_ext_ack *extack) 236 { 237 struct ixgbe_hw *hw = &adapter->hw; 238 239 return ixgbe_aci_update_nvm(hw, module, offset, block_size, block, 240 last_cmd, 0); 241 } 242 243 /** 244 * ixgbe_write_nvm_module - Write data to an NVM module 245 * @adapter: the PF driver structure 246 * @module: the module id to program 247 * @component: the name of the component being updated 248 * @image: buffer of image data to write to the NVM 249 * @length: length of the buffer 250 * @extack: netlink extended ACK structure 251 * 252 * Loop over the data for a given NVM module and program it in 4 Kb 253 * blocks. Notify devlink core of progress after each block is programmed. 254 * Loops over a block of data and programs the NVM in 4k block chunks. 255 * 256 * Note this function assumes the caller has acquired the NVM resource. 257 * 258 * Return: 0 on success, or a negative error code on failure. 259 */ 260 static int ixgbe_write_nvm_module(struct ixgbe_adapter *adapter, u16 module, 261 const char *component, const u8 *image, 262 u32 length, 263 struct netlink_ext_ack *extack) 264 { 265 struct devlink *devlink = adapter->devlink; 266 u32 offset = 0; 267 bool last_cmd; 268 u8 *block; 269 int err; 270 271 devlink_flash_update_status_notify(devlink, "Flashing", 272 component, 0, length); 273 274 block = kzalloc(IXGBE_ACI_MAX_BUFFER_SIZE, GFP_KERNEL); 275 if (!block) 276 return -ENOMEM; 277 278 do { 279 u32 block_size; 280 281 block_size = min_t(u32, IXGBE_ACI_MAX_BUFFER_SIZE, 282 length - offset); 283 last_cmd = !(offset + block_size < length); 284 285 memcpy(block, image + offset, block_size); 286 287 err = ixgbe_write_one_nvm_block(adapter, module, offset, 288 block_size, block, last_cmd, 289 extack); 290 if (err) 291 break; 292 293 offset += block_size; 294 295 devlink_flash_update_status_notify(devlink, "Flashing", 296 component, offset, length); 297 } while (!last_cmd); 298 299 if (err) 300 devlink_flash_update_status_notify(devlink, "Flashing failed", 301 component, length, length); 302 else 303 devlink_flash_update_status_notify(devlink, "Flashing done", 304 component, length, length); 305 306 kfree(block); 307 308 return err; 309 } 310 311 /* Length in seconds to wait before timing out when erasing a flash module. 312 * Yes, erasing really can take minutes to complete. 313 */ 314 #define IXGBE_FW_ERASE_TIMEOUT 300 315 316 /** 317 * ixgbe_erase_nvm_module - Erase an NVM module and await firmware completion 318 * @adapter: the PF data structure 319 * @module: the module to erase 320 * @component: name of the component being updated 321 * @extack: netlink extended ACK structure 322 * 323 * Erase the inactive NVM bank associated with this module, and await for 324 * a completion response message from firmware. 325 * 326 * Note this function assumes the caller has acquired the NVM resource. 327 * 328 * Return: 0 on success, or a negative error code on failure. 329 */ 330 static int ixgbe_erase_nvm_module(struct ixgbe_adapter *adapter, u16 module, 331 const char *component, 332 struct netlink_ext_ack *extack) 333 { 334 struct devlink *devlink = adapter->devlink; 335 struct ixgbe_hw *hw = &adapter->hw; 336 int err; 337 338 devlink_flash_update_timeout_notify(devlink, "Erasing", component, 339 IXGBE_FW_ERASE_TIMEOUT); 340 341 err = ixgbe_aci_erase_nvm(hw, module); 342 if (err) 343 devlink_flash_update_status_notify(devlink, "Erasing failed", 344 component, 0, 0); 345 else 346 devlink_flash_update_status_notify(devlink, "Erasing done", 347 component, 0, 0); 348 349 return err; 350 } 351 352 /** 353 * ixgbe_switch_flash_banks - Tell firmware to switch NVM banks 354 * @adapter: Pointer to the PF data structure 355 * @activate_flags: flags used for the activation command 356 * @emp_reset_available: on return, indicates if EMP reset is available 357 * @extack: netlink extended ACK structure 358 * 359 * Notify firmware to activate the newly written flash banks, and wait for the 360 * firmware response. 361 * 362 * Return: 0 on success or an error code on failure. 363 */ 364 static int ixgbe_switch_flash_banks(struct ixgbe_adapter *adapter, 365 u8 activate_flags, 366 bool *emp_reset_available, 367 struct netlink_ext_ack *extack) 368 { 369 struct ixgbe_hw *hw = &adapter->hw; 370 u8 response_flags; 371 int err; 372 373 err = ixgbe_nvm_write_activate(hw, activate_flags, &response_flags); 374 if (err) { 375 NL_SET_ERR_MSG_MOD(extack, 376 "Failed to switch active flash banks"); 377 return err; 378 } 379 380 if (emp_reset_available) { 381 if (hw->dev_caps.common_cap.reset_restrict_support) 382 *emp_reset_available = 383 response_flags & IXGBE_ACI_NVM_EMPR_ENA; 384 else 385 *emp_reset_available = true; 386 } 387 388 return 0; 389 } 390 391 /** 392 * ixgbe_flash_component - Flash a component of the NVM 393 * @context: PLDM fw update structure 394 * @component: the component table to program 395 * 396 * Program the flash contents for a given component. First, determine the 397 * module id. Then, erase the secondary bank for this module. Finally, write 398 * the contents of the component to the NVM. 399 * 400 * Note this function assumes the caller has acquired the NVM resource. 401 * 402 * Return: 0 on success, or a negative error code on failure. 403 */ 404 static int ixgbe_flash_component(struct pldmfw *context, 405 struct pldmfw_component *component) 406 { 407 struct ixgbe_fwu_priv *priv = container_of(context, 408 struct ixgbe_fwu_priv, 409 context); 410 struct netlink_ext_ack *extack = priv->extack; 411 struct ixgbe_adapter *adapter = priv->adapter; 412 const char *name; 413 u16 module; 414 int err; 415 u8 flag; 416 417 switch (component->identifier) { 418 case NVM_COMP_ID_OROM: 419 module = IXGBE_E610_SR_1ST_OROM_BANK_PTR; 420 flag = IXGBE_ACI_NVM_ACTIV_SEL_OROM; 421 name = "fw.undi"; 422 break; 423 case NVM_COMP_ID_NVM: 424 module = IXGBE_E610_SR_1ST_NVM_BANK_PTR; 425 flag = IXGBE_ACI_NVM_ACTIV_SEL_NVM; 426 name = "fw.mgmt"; 427 break; 428 case NVM_COMP_ID_NETLIST: 429 module = IXGBE_E610_SR_NETLIST_BANK_PTR; 430 flag = IXGBE_ACI_NVM_ACTIV_SEL_NETLIST; 431 name = "fw.netlist"; 432 break; 433 434 default: 435 return -EOPNOTSUPP; 436 } 437 438 /* Mark this component for activating at the end. */ 439 priv->activate_flags |= flag; 440 441 err = ixgbe_erase_nvm_module(adapter, module, name, extack); 442 if (err) 443 return err; 444 445 return ixgbe_write_nvm_module(adapter, module, name, 446 component->component_data, 447 component->component_size, extack); 448 } 449 450 /** 451 * ixgbe_finalize_update - Perform last steps to complete device update 452 * @context: PLDM fw update structure 453 * 454 * Called as the last step of the update process. Complete the update by 455 * telling the firmware to switch active banks, and perform a reset of 456 * configured. 457 * 458 * Return: 0 on success, or an error code on failure. 459 */ 460 static int ixgbe_finalize_update(struct pldmfw *context) 461 { 462 struct ixgbe_fwu_priv *priv = container_of(context, 463 struct ixgbe_fwu_priv, 464 context); 465 struct ixgbe_adapter *adapter = priv->adapter; 466 struct netlink_ext_ack *extack = priv->extack; 467 struct devlink *devlink = adapter->devlink; 468 int err; 469 470 /* Finally, notify firmware to activate the written NVM banks */ 471 err = ixgbe_switch_flash_banks(adapter, priv->activate_flags, 472 &priv->emp_reset_available, extack); 473 if (err) 474 return err; 475 476 adapter->fw_emp_reset_disabled = !priv->emp_reset_available; 477 478 if (!adapter->fw_emp_reset_disabled) 479 devlink_flash_update_status_notify(devlink, 480 "Suggested is to activate new firmware by devlink reload, if it doesn't work then a power cycle is required", 481 NULL, 0, 0); 482 483 return 0; 484 } 485 486 static const struct pldmfw_ops ixgbe_fwu_ops_e610 = { 487 .match_record = &pldmfw_op_pci_match_record, 488 .send_package_data = &ixgbe_send_package_data, 489 .send_component_table = &ixgbe_send_component_table, 490 .flash_component = &ixgbe_flash_component, 491 .finalize_update = &ixgbe_finalize_update, 492 }; 493 494 /** 495 * ixgbe_get_pending_updates - Check if the component has a pending update 496 * @adapter: the PF driver structure 497 * @pending: on return, bitmap of updates pending 498 * @extack: Netlink extended ACK 499 * 500 * Check if the device has any pending updates on any flash components. 501 * 502 * Return: 0 on success, or a negative error code on failure. Update 503 * pending with the bitmap of pending updates. 504 */ 505 int ixgbe_get_pending_updates(struct ixgbe_adapter *adapter, u8 *pending, 506 struct netlink_ext_ack *extack) 507 { 508 struct ixgbe_hw_dev_caps *dev_caps; 509 struct ixgbe_hw *hw = &adapter->hw; 510 int err; 511 512 dev_caps = kzalloc(sizeof(*dev_caps), GFP_KERNEL); 513 if (!dev_caps) 514 return -ENOMEM; 515 516 err = ixgbe_discover_dev_caps(hw, dev_caps); 517 if (err) { 518 NL_SET_ERR_MSG_MOD(extack, 519 "Unable to read device capabilities"); 520 kfree(dev_caps); 521 return -EIO; 522 } 523 524 *pending = 0; 525 526 if (dev_caps->common_cap.nvm_update_pending_nvm) 527 *pending |= IXGBE_ACI_NVM_ACTIV_SEL_NVM; 528 529 if (dev_caps->common_cap.nvm_update_pending_orom) 530 *pending |= IXGBE_ACI_NVM_ACTIV_SEL_OROM; 531 532 if (dev_caps->common_cap.nvm_update_pending_netlist) 533 *pending |= IXGBE_ACI_NVM_ACTIV_SEL_NETLIST; 534 535 kfree(dev_caps); 536 537 return 0; 538 } 539 540 /** 541 * ixgbe_cancel_pending_update - Cancel any pending update for a component 542 * @adapter: the PF driver structure 543 * @component: if not NULL, the name of the component being updated 544 * @extack: Netlink extended ACK structure 545 * 546 * Cancel any pending update for the specified component. If component is 547 * NULL, all device updates will be canceled. 548 * 549 * Return: 0 on success, or a negative error code on failure. 550 */ 551 static int ixgbe_cancel_pending_update(struct ixgbe_adapter *adapter, 552 const char *component, 553 struct netlink_ext_ack *extack) 554 { 555 struct devlink *devlink = adapter->devlink; 556 struct ixgbe_hw *hw = &adapter->hw; 557 u8 pending; 558 int err; 559 560 err = ixgbe_get_pending_updates(adapter, &pending, extack); 561 if (err) 562 return err; 563 564 /* If the flash_update request is for a specific component, ignore all 565 * of the other components. 566 */ 567 if (component) { 568 if (strcmp(component, "fw.mgmt") == 0) 569 pending &= IXGBE_ACI_NVM_ACTIV_SEL_NVM; 570 else if (strcmp(component, "fw.undi") == 0) 571 pending &= IXGBE_ACI_NVM_ACTIV_SEL_OROM; 572 else if (strcmp(component, "fw.netlist") == 0) 573 pending &= IXGBE_ACI_NVM_ACTIV_SEL_NETLIST; 574 else 575 return -EINVAL; 576 } 577 578 /* There is no previous pending update, so this request may continue */ 579 if (!pending) 580 return 0; 581 582 /* In order to allow overwriting a previous pending update, notify 583 * firmware to cancel that update by issuing the appropriate command. 584 */ 585 devlink_flash_update_status_notify(devlink, 586 "Canceling previous pending update", 587 component, 0, 0); 588 589 err = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE); 590 if (err) { 591 NL_SET_ERR_MSG_MOD(extack, 592 "Failed to acquire device flash lock"); 593 return -EIO; 594 } 595 596 pending |= IXGBE_ACI_NVM_REVERT_LAST_ACTIV; 597 err = ixgbe_switch_flash_banks(adapter, pending, NULL, extack); 598 599 ixgbe_release_nvm(hw); 600 601 return err; 602 } 603 604 /** 605 * ixgbe_flash_pldm_image - Write a PLDM-formatted firmware image to the device 606 * @devlink: pointer to devlink associated with the device to update 607 * @params: devlink flash update parameters 608 * @extack: netlink extended ACK structure 609 * 610 * Parse the data for a given firmware file, verifying that it is a valid PLDM 611 * formatted image that matches this device. 612 * 613 * Extract the device record Package Data and Component Tables and send them 614 * to the firmware. Extract and write the flash data for each of the three 615 * main flash components, "fw.mgmt", "fw.undi", and "fw.netlist". Notify 616 * firmware once the data is written to the inactive banks. 617 * 618 * Return: 0 on success or a negative error code on failure. 619 */ 620 int ixgbe_flash_pldm_image(struct devlink *devlink, 621 struct devlink_flash_update_params *params, 622 struct netlink_ext_ack *extack) 623 { 624 struct ixgbe_adapter *adapter = devlink_priv(devlink); 625 struct device *dev = &adapter->pdev->dev; 626 struct ixgbe_hw *hw = &adapter->hw; 627 struct ixgbe_fwu_priv priv; 628 u8 preservation; 629 int err; 630 631 if (hw->mac.type != ixgbe_mac_e610) 632 return -EOPNOTSUPP; 633 634 switch (params->overwrite_mask) { 635 case 0: 636 /* preserve all settings and identifiers */ 637 preservation = IXGBE_ACI_NVM_PRESERVE_ALL; 638 break; 639 case DEVLINK_FLASH_OVERWRITE_SETTINGS: 640 /* Overwrite settings, but preserve vital information such as 641 * device identifiers. 642 */ 643 preservation = IXGBE_ACI_NVM_PRESERVE_SELECTED; 644 break; 645 case (DEVLINK_FLASH_OVERWRITE_SETTINGS | 646 DEVLINK_FLASH_OVERWRITE_IDENTIFIERS): 647 /* overwrite both settings and identifiers, preserve nothing */ 648 preservation = IXGBE_ACI_NVM_NO_PRESERVATION; 649 break; 650 default: 651 NL_SET_ERR_MSG_MOD(extack, 652 "Requested overwrite mask is not supported"); 653 return -EOPNOTSUPP; 654 } 655 656 if (!hw->dev_caps.common_cap.nvm_unified_update) { 657 NL_SET_ERR_MSG_MOD(extack, 658 "Current firmware does not support unified update"); 659 return -EOPNOTSUPP; 660 } 661 662 memset(&priv, 0, sizeof(priv)); 663 664 priv.context.ops = &ixgbe_fwu_ops_e610; 665 priv.context.dev = dev; 666 priv.extack = extack; 667 priv.adapter = adapter; 668 priv.activate_flags = preservation; 669 670 devlink_flash_update_status_notify(devlink, 671 "Preparing to flash", NULL, 0, 0); 672 673 err = ixgbe_cancel_pending_update(adapter, NULL, extack); 674 if (err) 675 return err; 676 677 err = ixgbe_acquire_nvm(hw, IXGBE_RES_WRITE); 678 if (err) { 679 NL_SET_ERR_MSG_MOD(extack, 680 "Failed to acquire device flash lock"); 681 return -EIO; 682 } 683 684 err = pldmfw_flash_image(&priv.context, params->fw); 685 if (err == -ENOENT) { 686 NL_SET_ERR_MSG_MOD(extack, 687 "Firmware image has no record matching this device"); 688 } else if (err) { 689 NL_SET_ERR_MSG_MOD(extack, "Failed to flash PLDM image"); 690 } 691 692 ixgbe_release_nvm(hw); 693 694 return err; 695 } 696