efx_reflash.c 16 KB

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