xref: /linux/drivers/net/ethernet/sfc/efx_reflash.c (revision 1a9239bb4253f9076b5b4b2a1a4e8d7defd77a95)
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 */
efx_reflash_parse_reflash_header(const struct firmware * fw,size_t header_offset,u32 * type,u32 * subtype,const u8 ** data,size_t * data_size)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 */
efx_reflash_partition_type(u32 type,u32 subtype,u32 * partition_type,u32 * partition_subtype)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 */
efx_reflash_parse_snic_header(const struct firmware * fw,size_t header_offset,u32 * partition_type,u32 * partition_subtype,const u8 ** data,size_t * data_size)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 */
efx_reflash_parse_snic_bundle_header(const struct firmware * fw,size_t header_offset,u32 * partition_type,u32 * partition_subtype,const u8 ** data,size_t * data_size)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  */
efx_reflash_parse_firmware_data(const struct firmware * fw,u32 * partition_type,u32 * partition_subtype,const u8 ** data,size_t * data_size)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 
efx_reflash_erase_partition(struct efx_nic * efx,struct netlink_ext_ack * extack,struct devlink * devlink,u32 type,size_t partition_size,size_t align)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 
efx_reflash_write_partition(struct efx_nic * efx,struct netlink_ext_ack * extack,struct devlink * devlink,u32 type,const u8 * data,size_t data_size,size_t align)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 
efx_reflash_flash_firmware(struct efx_nic * efx,const struct firmware * fw,struct netlink_ext_ack * extack)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 	mutex_lock(&efx->reflash_mutex);
411 
412 	devlink_flash_update_status_notify(devlink, "Checking update", NULL, 0, 0);
413 
414 	if (efx->type->flash_auto_partition) {
415 		/* NIC wants entire FW file including headers;
416 		 * FW will validate 'subtype' if there is one
417 		 */
418 		type = NVRAM_PARTITION_TYPE_AUTO;
419 		data = fw->data;
420 		data_size = fw->size;
421 	} else {
422 		rc = efx_reflash_parse_firmware_data(fw, &type, &data_subtype, &data,
423 						     &data_size);
424 		if (rc) {
425 			NL_SET_ERR_MSG_MOD(extack,
426 					   "Firmware image validation check failed");
427 			goto out_unlock;
428 		}
429 
430 		rc = efx_mcdi_nvram_metadata(efx, type, &subtype, NULL, NULL, 0);
431 		if (rc) {
432 			NL_SET_ERR_MSG_FMT_MOD(extack,
433 					       "Metadata query for NVRAM partition %#x failed",
434 					       type);
435 			goto out_unlock;
436 		}
437 
438 		if (subtype != data_subtype) {
439 			NL_SET_ERR_MSG_MOD(extack,
440 					   "Firmware image is not appropriate for this adapter");
441 			rc = -EINVAL;
442 			goto out_unlock;
443 		}
444 	}
445 
446 	rc = efx_mcdi_nvram_info(efx, type, &size, &erase_align, &write_align,
447 				 &protected);
448 	if (rc) {
449 		NL_SET_ERR_MSG_FMT_MOD(extack,
450 				       "Info query for NVRAM partition %#x failed",
451 				       type);
452 		goto out_unlock;
453 	}
454 
455 	if (protected) {
456 		NL_SET_ERR_MSG_FMT_MOD(extack,
457 				       "NVRAM partition %#x is protected",
458 				       type);
459 		rc = -EPERM;
460 		goto out_unlock;
461 	}
462 
463 	if (write_align == 0) {
464 		NL_SET_ERR_MSG_FMT_MOD(extack,
465 				       "NVRAM partition %#x is not writable",
466 				       type);
467 		rc = -EACCES;
468 		goto out_unlock;
469 	}
470 
471 	if (erase_align != 0 && size % erase_align) {
472 		NL_SET_ERR_MSG_FMT_MOD(extack,
473 				       "NVRAM partition %#x has a bad partition table entry, can't erase it",
474 				       type);
475 		rc = -EACCES;
476 		goto out_unlock;
477 	}
478 
479 	if (data_size > size) {
480 		NL_SET_ERR_MSG_FMT_MOD(extack,
481 				       "Firmware image is too big for NVRAM partition %#x",
482 				       type);
483 		rc = -EFBIG;
484 		goto out_unlock;
485 	}
486 
487 	devlink_flash_update_status_notify(devlink, "Starting update", NULL, 0, 0);
488 
489 	rc = efx_mcdi_nvram_update_start(efx, type);
490 	if (rc) {
491 		NL_SET_ERR_MSG_FMT_MOD(extack,
492 				       "Update start request for NVRAM partition %#x failed",
493 				       type);
494 		goto out_unlock;
495 	}
496 
497 	rc = efx_reflash_erase_partition(efx, extack, devlink, type, size,
498 					 erase_align);
499 	if (rc)
500 		goto out_update_finish;
501 
502 	rc = efx_reflash_write_partition(efx, extack, devlink, type, data,
503 					 data_size, write_align);
504 	if (rc)
505 		goto out_update_finish;
506 
507 	devlink_flash_update_timeout_notify(devlink, "Finishing update", NULL,
508 					    EFX_DEVLINK_UPDATE_FINISH_TIMEOUT);
509 
510 out_update_finish:
511 	if (rc)
512 		/* Don't obscure the return code from an earlier failure */
513 		efx_mcdi_nvram_update_finish(efx, type, EFX_UPDATE_FINISH_ABORT);
514 	else
515 		rc = efx_mcdi_nvram_update_finish_polled(efx, type);
516 out_unlock:
517 	mutex_unlock(&efx->reflash_mutex);
518 	devlink_flash_update_status_notify(devlink, rc ? "Update failed" :
519 							 "Update complete",
520 					   NULL, 0, 0);
521 	return rc;
522 }
523