1 // SPDX-License-Identifier: GPL-2.0-only 2 /**************************************************************************** 3 * Driver for AMD network controllers and boards 4 * Copyright (C) 2025, Advanced Micro Devices, Inc. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 as published 8 * by the Free Software Foundation, incorporated herein by reference. 9 */ 10 11 #include <linux/crc32.h> 12 #include <net/devlink.h> 13 #include "efx_reflash.h" 14 #include "net_driver.h" 15 #include "fw_formats.h" 16 #include "mcdi_pcol.h" 17 #include "mcdi.h" 18 19 /* Try to parse a Reflash header at the specified offset */ 20 static bool efx_reflash_parse_reflash_header(const struct firmware *fw, 21 size_t header_offset, u32 *type, 22 u32 *subtype, const u8 **data, 23 size_t *data_size) 24 { 25 size_t header_end, trailer_offset, trailer_end; 26 u32 magic, version, payload_size, header_len; 27 const u8 *header, *trailer; 28 u32 expected_crc, crc; 29 30 if (check_add_overflow(header_offset, EFX_REFLASH_HEADER_LENGTH_OFST + 31 EFX_REFLASH_HEADER_LENGTH_LEN, 32 &header_end)) 33 return false; 34 if (fw->size < header_end) 35 return false; 36 37 header = fw->data + header_offset; 38 magic = get_unaligned_le32(header + EFX_REFLASH_HEADER_MAGIC_OFST); 39 if (magic != EFX_REFLASH_HEADER_MAGIC_VALUE) 40 return false; 41 42 version = get_unaligned_le32(header + EFX_REFLASH_HEADER_VERSION_OFST); 43 if (version != EFX_REFLASH_HEADER_VERSION_VALUE) 44 return false; 45 46 payload_size = get_unaligned_le32(header + EFX_REFLASH_HEADER_PAYLOAD_SIZE_OFST); 47 header_len = get_unaligned_le32(header + EFX_REFLASH_HEADER_LENGTH_OFST); 48 if (check_add_overflow(header_offset, header_len, &trailer_offset) || 49 check_add_overflow(trailer_offset, payload_size, &trailer_offset) || 50 check_add_overflow(trailer_offset, EFX_REFLASH_TRAILER_LEN, 51 &trailer_end)) 52 return false; 53 if (fw->size < trailer_end) 54 return false; 55 56 trailer = fw->data + trailer_offset; 57 expected_crc = get_unaligned_le32(trailer + EFX_REFLASH_TRAILER_CRC_OFST); 58 /* Addition could overflow u32, but not size_t since we already 59 * checked trailer_offset didn't overflow. So cast to size_t first. 60 */ 61 crc = crc32_le(0, header, (size_t)header_len + payload_size); 62 if (crc != expected_crc) 63 return false; 64 65 *type = get_unaligned_le32(header + EFX_REFLASH_HEADER_FIRMWARE_TYPE_OFST); 66 *subtype = get_unaligned_le32(header + EFX_REFLASH_HEADER_FIRMWARE_SUBTYPE_OFST); 67 if (*type == EFX_REFLASH_FIRMWARE_TYPE_BUNDLE) { 68 /* All the bundle data is written verbatim to NVRAM */ 69 *data = fw->data; 70 *data_size = fw->size; 71 } else { 72 /* Other payload types strip the reflash header and trailer 73 * from the data written to NVRAM 74 */ 75 *data = header + header_len; 76 *data_size = payload_size; 77 } 78 79 return true; 80 } 81 82 /* Map from FIRMWARE_TYPE to NVRAM_PARTITION_TYPE */ 83 static int efx_reflash_partition_type(u32 type, u32 subtype, 84 u32 *partition_type, 85 u32 *partition_subtype) 86 { 87 int rc = 0; 88 89 switch (type) { 90 case EFX_REFLASH_FIRMWARE_TYPE_BOOTROM: 91 *partition_type = NVRAM_PARTITION_TYPE_EXPANSION_ROM; 92 *partition_subtype = subtype; 93 break; 94 case EFX_REFLASH_FIRMWARE_TYPE_BUNDLE: 95 *partition_type = NVRAM_PARTITION_TYPE_BUNDLE; 96 *partition_subtype = subtype; 97 break; 98 default: 99 /* Not supported */ 100 rc = -EINVAL; 101 } 102 103 return rc; 104 } 105 106 /* Try to parse a SmartNIC image header at the specified offset */ 107 static bool efx_reflash_parse_snic_header(const struct firmware *fw, 108 size_t header_offset, 109 u32 *partition_type, 110 u32 *partition_subtype, 111 const u8 **data, size_t *data_size) 112 { 113 u32 magic, version, payload_size, header_len, expected_crc, crc; 114 size_t header_end, payload_end; 115 const u8 *header; 116 117 if (check_add_overflow(header_offset, EFX_SNICIMAGE_HEADER_MINLEN, 118 &header_end) || 119 fw->size < header_end) 120 return false; 121 122 header = fw->data + header_offset; 123 magic = get_unaligned_le32(header + EFX_SNICIMAGE_HEADER_MAGIC_OFST); 124 if (magic != EFX_SNICIMAGE_HEADER_MAGIC_VALUE) 125 return false; 126 127 version = get_unaligned_le32(header + EFX_SNICIMAGE_HEADER_VERSION_OFST); 128 if (version != EFX_SNICIMAGE_HEADER_VERSION_VALUE) 129 return false; 130 131 header_len = get_unaligned_le32(header + EFX_SNICIMAGE_HEADER_LENGTH_OFST); 132 if (check_add_overflow(header_offset, header_len, &header_end)) 133 return false; 134 payload_size = get_unaligned_le32(header + EFX_SNICIMAGE_HEADER_PAYLOAD_SIZE_OFST); 135 if (check_add_overflow(header_end, payload_size, &payload_end) || 136 fw->size < payload_end) 137 return false; 138 139 expected_crc = get_unaligned_le32(header + EFX_SNICIMAGE_HEADER_CRC_OFST); 140 141 /* Calculate CRC omitting the expected CRC field itself */ 142 crc = crc32_le(~0, header, EFX_SNICIMAGE_HEADER_CRC_OFST); 143 crc = ~crc32_le(crc, 144 header + EFX_SNICIMAGE_HEADER_CRC_OFST + 145 EFX_SNICIMAGE_HEADER_CRC_LEN, 146 header_len + payload_size - EFX_SNICIMAGE_HEADER_CRC_OFST - 147 EFX_SNICIMAGE_HEADER_CRC_LEN); 148 if (crc != expected_crc) 149 return false; 150 151 *partition_type = 152 get_unaligned_le32(header + EFX_SNICIMAGE_HEADER_PARTITION_TYPE_OFST); 153 *partition_subtype = 154 get_unaligned_le32(header + EFX_SNICIMAGE_HEADER_PARTITION_SUBTYPE_OFST); 155 *data = fw->data; 156 *data_size = fw->size; 157 return true; 158 } 159 160 /* Try to parse a SmartNIC bundle header at the specified offset */ 161 static bool efx_reflash_parse_snic_bundle_header(const struct firmware *fw, 162 size_t header_offset, 163 u32 *partition_type, 164 u32 *partition_subtype, 165 const u8 **data, 166 size_t *data_size) 167 { 168 u32 magic, version, bundle_type, header_len, expected_crc, crc; 169 size_t header_end; 170 const u8 *header; 171 172 if (check_add_overflow(header_offset, EFX_SNICBUNDLE_HEADER_LEN, 173 &header_end)) 174 return false; 175 if (fw->size < header_end) 176 return false; 177 178 header = fw->data + header_offset; 179 magic = get_unaligned_le32(header + EFX_SNICBUNDLE_HEADER_MAGIC_OFST); 180 if (magic != EFX_SNICBUNDLE_HEADER_MAGIC_VALUE) 181 return false; 182 183 version = get_unaligned_le32(header + EFX_SNICBUNDLE_HEADER_VERSION_OFST); 184 if (version != EFX_SNICBUNDLE_HEADER_VERSION_VALUE) 185 return false; 186 187 bundle_type = get_unaligned_le32(header + EFX_SNICBUNDLE_HEADER_BUNDLE_TYPE_OFST); 188 if (bundle_type != NVRAM_PARTITION_TYPE_BUNDLE) 189 return false; 190 191 header_len = get_unaligned_le32(header + EFX_SNICBUNDLE_HEADER_LENGTH_OFST); 192 if (header_len != EFX_SNICBUNDLE_HEADER_LEN) 193 return false; 194 195 expected_crc = get_unaligned_le32(header + EFX_SNICBUNDLE_HEADER_CRC_OFST); 196 crc = ~crc32_le(~0, header, EFX_SNICBUNDLE_HEADER_CRC_OFST); 197 if (crc != expected_crc) 198 return false; 199 200 *partition_type = NVRAM_PARTITION_TYPE_BUNDLE; 201 *partition_subtype = get_unaligned_le32(header + EFX_SNICBUNDLE_HEADER_BUNDLE_SUBTYPE_OFST); 202 *data = fw->data; 203 *data_size = fw->size; 204 return true; 205 } 206 207 /* Try to find a valid firmware payload in the firmware data. 208 * When we recognise a valid header, we parse it for the partition type 209 * (so we know where to ask the MC to write it to) and the location of 210 * the data blob to write. 211 */ 212 static int efx_reflash_parse_firmware_data(const struct firmware *fw, 213 u32 *partition_type, 214 u32 *partition_subtype, 215 const u8 **data, size_t *data_size) 216 { 217 size_t header_offset; 218 u32 type, subtype; 219 220 /* Some packaging formats (such as CMS/PKCS#7 signed images) 221 * prepend a header for which finding the size is a non-trivial 222 * task, so step through the firmware data until we find a valid 223 * header. 224 * 225 * The checks are intended to reject firmware data that is clearly not 226 * in the expected format. They do not need to be exhaustive as the 227 * running firmware will perform its own comprehensive validity and 228 * compatibility checks during the update procedure. 229 * 230 * Firmware packages may contain multiple reflash images, e.g. a 231 * bundle containing one or more other images. Only check the 232 * outermost container by stopping after the first candidate image 233 * found even it is for an unsupported partition type. 234 */ 235 for (header_offset = 0; header_offset < fw->size; header_offset++) { 236 if (efx_reflash_parse_snic_bundle_header(fw, header_offset, 237 partition_type, 238 partition_subtype, 239 data, data_size)) 240 return 0; 241 242 if (efx_reflash_parse_snic_header(fw, header_offset, 243 partition_type, 244 partition_subtype, data, 245 data_size)) 246 return 0; 247 248 if (efx_reflash_parse_reflash_header(fw, header_offset, &type, 249 &subtype, data, data_size)) 250 return efx_reflash_partition_type(type, subtype, 251 partition_type, 252 partition_subtype); 253 } 254 255 return -EINVAL; 256 } 257 258 /* Limit the number of status updates during the erase or write phases */ 259 #define EFX_DEVLINK_STATUS_UPDATE_COUNT 50 260 261 /* Expected timeout for the efx_mcdi_nvram_update_finish_polled() */ 262 #define EFX_DEVLINK_UPDATE_FINISH_TIMEOUT 900 263 264 /* Ideal erase chunk size. This is a balance between minimising the number of 265 * MCDI requests to erase an entire partition whilst avoiding tripping the MCDI 266 * RPC timeout. 267 */ 268 #define EFX_NVRAM_ERASE_IDEAL_CHUNK_SIZE (64 * 1024) 269 270 static int efx_reflash_erase_partition(struct efx_nic *efx, 271 struct netlink_ext_ack *extack, 272 struct devlink *devlink, u32 type, 273 size_t partition_size, 274 size_t align) 275 { 276 size_t chunk, offset, next_update; 277 int rc; 278 279 /* Partitions that cannot be erased or do not require erase before 280 * write are advertised with a erase alignment/sector size of zero. 281 */ 282 if (align == 0) 283 /* Nothing to do */ 284 return 0; 285 286 if (partition_size % align) 287 return -EINVAL; 288 289 /* Erase the entire NVRAM partition a chunk at a time to avoid 290 * potentially tripping the MCDI RPC timeout. 291 */ 292 if (align >= EFX_NVRAM_ERASE_IDEAL_CHUNK_SIZE) 293 chunk = align; 294 else 295 chunk = rounddown(EFX_NVRAM_ERASE_IDEAL_CHUNK_SIZE, align); 296 297 for (offset = 0, next_update = 0; offset < partition_size; offset += chunk) { 298 if (offset >= next_update) { 299 devlink_flash_update_status_notify(devlink, "Erasing", 300 NULL, offset, 301 partition_size); 302 next_update += partition_size / EFX_DEVLINK_STATUS_UPDATE_COUNT; 303 } 304 305 chunk = min_t(size_t, partition_size - offset, chunk); 306 rc = efx_mcdi_nvram_erase(efx, type, offset, chunk); 307 if (rc) { 308 NL_SET_ERR_MSG_FMT_MOD(extack, 309 "Erase failed for NVRAM partition %#x at %#zx-%#zx", 310 type, offset, offset + chunk - 1); 311 return rc; 312 } 313 } 314 315 devlink_flash_update_status_notify(devlink, "Erasing", NULL, 316 partition_size, partition_size); 317 318 return 0; 319 } 320 321 static int efx_reflash_write_partition(struct efx_nic *efx, 322 struct netlink_ext_ack *extack, 323 struct devlink *devlink, u32 type, 324 const u8 *data, size_t data_size, 325 size_t align) 326 { 327 size_t write_max, chunk, offset, next_update; 328 int rc; 329 330 if (align == 0) 331 return -EINVAL; 332 333 /* Write the NVRAM partition in chunks that are the largest multiple 334 * of the partition's required write alignment that will fit into the 335 * MCDI NVRAM_WRITE RPC payload. 336 */ 337 if (efx->type->mcdi_max_ver < 2) 338 write_max = MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN * 339 MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM; 340 else 341 write_max = MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_LEN * 342 MC_CMD_NVRAM_WRITE_IN_WRITE_BUFFER_MAXNUM_MCDI2; 343 chunk = rounddown(write_max, align); 344 345 for (offset = 0, next_update = 0; offset + chunk <= data_size; offset += chunk) { 346 if (offset >= next_update) { 347 devlink_flash_update_status_notify(devlink, "Writing", 348 NULL, offset, 349 data_size); 350 next_update += data_size / EFX_DEVLINK_STATUS_UPDATE_COUNT; 351 } 352 353 rc = efx_mcdi_nvram_write(efx, type, offset, data + offset, chunk); 354 if (rc) { 355 NL_SET_ERR_MSG_FMT_MOD(extack, 356 "Write failed for NVRAM partition %#x at %#zx-%#zx", 357 type, offset, offset + chunk - 1); 358 return rc; 359 } 360 } 361 362 /* Round up left over data to satisfy write alignment */ 363 if (offset < data_size) { 364 size_t remaining = data_size - offset; 365 u8 *buf; 366 367 if (offset >= next_update) 368 devlink_flash_update_status_notify(devlink, "Writing", 369 NULL, offset, 370 data_size); 371 372 chunk = roundup(remaining, align); 373 buf = kmalloc(chunk, GFP_KERNEL); 374 if (!buf) 375 return -ENOMEM; 376 377 memcpy(buf, data + offset, remaining); 378 memset(buf + remaining, 0xFF, chunk - remaining); 379 rc = efx_mcdi_nvram_write(efx, type, offset, buf, chunk); 380 kfree(buf); 381 if (rc) { 382 NL_SET_ERR_MSG_FMT_MOD(extack, 383 "Write failed for NVRAM partition %#x at %#zx-%#zx", 384 type, offset, offset + chunk - 1); 385 return rc; 386 } 387 } 388 389 devlink_flash_update_status_notify(devlink, "Writing", NULL, data_size, 390 data_size); 391 392 return 0; 393 } 394 395 int efx_reflash_flash_firmware(struct efx_nic *efx, const struct firmware *fw, 396 struct netlink_ext_ack *extack) 397 { 398 size_t data_size, size, erase_align, write_align; 399 struct devlink *devlink = efx->devlink; 400 u32 type, data_subtype, subtype; 401 const u8 *data; 402 bool protected; 403 int rc; 404 405 if (!efx_has_cap(efx, BUNDLE_UPDATE)) { 406 NL_SET_ERR_MSG_MOD(extack, "NVRAM bundle updates are not supported by the firmware"); 407 return -EOPNOTSUPP; 408 } 409 410 devlink_flash_update_status_notify(devlink, "Checking update", NULL, 0, 0); 411 412 rc = efx_reflash_parse_firmware_data(fw, &type, &data_subtype, &data, 413 &data_size); 414 if (rc) { 415 NL_SET_ERR_MSG_MOD(extack, 416 "Firmware image validation check failed"); 417 goto out; 418 } 419 420 mutex_lock(&efx->reflash_mutex); 421 422 rc = efx_mcdi_nvram_metadata(efx, type, &subtype, NULL, NULL, 0); 423 if (rc) { 424 NL_SET_ERR_MSG_FMT_MOD(extack, 425 "Metadata query for NVRAM partition %#x failed", 426 type); 427 goto out_unlock; 428 } 429 430 if (subtype != data_subtype) { 431 NL_SET_ERR_MSG_MOD(extack, 432 "Firmware image is not appropriate for this adapter"); 433 rc = -EINVAL; 434 goto out_unlock; 435 } 436 437 rc = efx_mcdi_nvram_info(efx, type, &size, &erase_align, &write_align, 438 &protected); 439 if (rc) { 440 NL_SET_ERR_MSG_FMT_MOD(extack, 441 "Info query for NVRAM partition %#x failed", 442 type); 443 goto out_unlock; 444 } 445 446 if (protected) { 447 NL_SET_ERR_MSG_FMT_MOD(extack, 448 "NVRAM partition %#x is protected", 449 type); 450 rc = -EPERM; 451 goto out_unlock; 452 } 453 454 if (write_align == 0) { 455 NL_SET_ERR_MSG_FMT_MOD(extack, 456 "NVRAM partition %#x is not writable", 457 type); 458 rc = -EACCES; 459 goto out_unlock; 460 } 461 462 if (erase_align != 0 && size % erase_align) { 463 NL_SET_ERR_MSG_FMT_MOD(extack, 464 "NVRAM partition %#x has a bad partition table entry, can't erase it", 465 type); 466 rc = -EACCES; 467 goto out_unlock; 468 } 469 470 if (data_size > size) { 471 NL_SET_ERR_MSG_FMT_MOD(extack, 472 "Firmware image is too big for NVRAM partition %#x", 473 type); 474 rc = -EFBIG; 475 goto out_unlock; 476 } 477 478 devlink_flash_update_status_notify(devlink, "Starting update", NULL, 0, 0); 479 480 rc = efx_mcdi_nvram_update_start(efx, type); 481 if (rc) { 482 NL_SET_ERR_MSG_FMT_MOD(extack, 483 "Update start request for NVRAM partition %#x failed", 484 type); 485 goto out_unlock; 486 } 487 488 rc = efx_reflash_erase_partition(efx, extack, devlink, type, size, 489 erase_align); 490 if (rc) 491 goto out_update_finish; 492 493 rc = efx_reflash_write_partition(efx, extack, devlink, type, data, 494 data_size, write_align); 495 if (rc) 496 goto out_update_finish; 497 498 devlink_flash_update_timeout_notify(devlink, "Finishing update", NULL, 499 EFX_DEVLINK_UPDATE_FINISH_TIMEOUT); 500 501 out_update_finish: 502 if (rc) 503 /* Don't obscure the return code from an earlier failure */ 504 efx_mcdi_nvram_update_finish(efx, type, EFX_UPDATE_FINISH_ABORT); 505 else 506 rc = efx_mcdi_nvram_update_finish_polled(efx, type); 507 out_unlock: 508 mutex_unlock(&efx->reflash_mutex); 509 out: 510 devlink_flash_update_status_notify(devlink, rc ? "Update failed" : 511 "Update complete", 512 NULL, 0, 0); 513 return rc; 514 } 515