uint8_t fw_update()

in common/util/util_spi.c [166:265]


uint8_t fw_update(uint32_t offset, uint16_t msg_len, uint8_t *msg_buf, bool update_en,
		  uint8_t spi_bus)
{
	static bool is_init = 0;
	static uint8_t *txbuf = NULL;
	static uint32_t buf_offset = 0;
	uint32_t ret = 0;
	const struct device *flash_dev;

	if (!is_init) {
		if ((offset & 0x0000) != 0) {
			return fwupdate_error_offset;
		}

		if (txbuf != NULL) {
			free(txbuf);
			txbuf = NULL;
		}
		txbuf = (uint8_t *)malloc(sector_sz_64k);
		if (txbuf == NULL) { // Retry alloc
			k_msleep(100);
			txbuf = (uint8_t *)malloc(sector_sz_64k);
		}
		if (txbuf == NULL) {
			printk("spi index%x update buffer alloc fail\n", spi_bus);
			return fwupdate_out_of_heap;
		}
		is_init = 1;
		buf_offset = 0;
		k_msleep(10);
	}

	if ((buf_offset + msg_len) > sector_sz_64k) {
		printk("spi bus%x recv data %d over sector size %d\n", spi_bus,
		       buf_offset + msg_len, sector_sz_64k);
		free(txbuf);
		txbuf = NULL;
		k_msleep(10);
		is_init = 0;
		return fwupdate_over_length;
	}

	if ((offset % sector_sz_64k) != buf_offset) {
		printk("spi bus%x recorded offset 0x%x but updating 0x%x\n", spi_bus, buf_offset,
		       offset % sector_sz_64k);
		free(txbuf);
		txbuf = NULL;
		k_msleep(10);
		is_init = 0;
		return fwupdate_repeated_updated;
	}

	if (FW_UPDATE_DEBUG) {
		printk("spi bus%x update offset %x %x, msg_len %d, update_en %d, msg_buf: %2x %2x %2x %2x\n",
		       spi_bus, offset, buf_offset, msg_len, update_en, msg_buf[0], msg_buf[1],
		       msg_buf[2], msg_buf[3]);
	}

	memcpy(&txbuf[buf_offset], msg_buf, msg_len);
	buf_offset += msg_len;

	if ((buf_offset == sector_sz_64k) ||
	    update_en) { // Update fmc while collect 64k bytes data or BMC signal last image package with target | 0x80
		flash_dev = device_get_binding(flash_device[spi_bus]);
		uint8_t sector = 16;
		uint32_t txbuf_offset;
		uint32_t update_offset;

		for (int i = 0; i < sector; i++) {
			txbuf_offset = sector_sz_4k * i;
			update_offset = (offset / sector_sz_64k) * sector_sz_64k + txbuf_offset;
			ret = do_update(flash_dev, update_offset, &txbuf[txbuf_offset],
					sector_sz_4k);
			if (ret) {
				printk("SPI update fail status: %x\n", ret);
				break;
			}
		}
		if (!ret) {
			printk("Update success\n");
		}
		free(txbuf);
		txbuf = NULL;
		k_msleep(10);
		is_init = 0;

		if (FW_UPDATE_DEBUG) {
			printk("***update %x, offset %x, sector_sz_16k %x\n",
			       (offset / sector_sz_16k) * sector_sz_16k, offset, sector_sz_16k);
		}

		if (update_en && spi_bus == (devspi_fmc_cs0)) { // reboot bic itself after fw update
			submit_bic_warm_reset();
		}

		return ret;
	}

	return fwupdate_success;
}