void pal_OEM_1S_FW_UPDATE()

in meta-facebook/yv35-bb/src/ipmi/plat_ipmi.c [635:707]


void pal_OEM_1S_FW_UPDATE(ipmi_msg *msg)
{
	/*********************************
 * buf 0:   target, 0x80 indicate last byte
 * buf 1~4: offset, 1 lsb
 * buf 5~6: length, 5 lsb
 * buf 7~N: data
 ***********************************/
	if (msg->data_len < 8) {
		msg->completion_code = CC_INVALID_LENGTH;
		return;
	}

	uint8_t target = msg->data[0], status = 0;
	uint32_t offset =
		((msg->data[4] << 24) | (msg->data[3] << 16) | (msg->data[2] << 8) | msg->data[1]);
	uint16_t length = ((msg->data[6] << 8) | msg->data[5]);

	if ((length == 0) || (length != msg->data_len - 7)) {
		msg->completion_code = CC_INVALID_LENGTH;
		return;
	}

	if ((target == BIC_UPDATE) || (target == (BIC_UPDATE | UPDATE_EN))) {
		if (offset > 0x50000) { // Expect BIC firmware size not bigger than 320k
			msg->completion_code = CC_PARAM_OUT_OF_RANGE;
			return;
		}
		status = fw_update(offset, length, &msg->data[7], (target & UPDATE_EN),
				   devspi_fmc_cs0);

	} else if (target & CPLD_UPDATE) {
		if (offset == 0) {
			printf("[CPLD] CPLD update start\n");
		}

		status = cpld_altera_fw_update(offset, length, &msg->data[7]);
	} else {
		return msg->completion_code = CC_PARAM_OUT_OF_RANGE;
	}

	msg->data_len = 0;

	switch (status) {
	case fwupdate_success:
		msg->completion_code = CC_SUCCESS;
		break;
	case fwupdate_out_of_heap:
		msg->completion_code = CC_LENGTH_EXCEEDED;
		break;
	case fwupdate_over_length:
		msg->completion_code = CC_OUT_OF_SPACE;
		break;
	case fwupdate_repeated_updated:
		msg->completion_code = CC_INVALID_DATA_FIELD;
		break;
	case fwupdate_update_fail:
		msg->completion_code = CC_TIMEOUT;
		break;
	case fwupdate_error_offset:
		msg->completion_code = CC_PARAM_OUT_OF_RANGE;
		break;
	default:
		msg->completion_code = CC_UNSPECIFIED_ERROR;
		break;
	}

	if (status != fwupdate_success) {
		printf("firmware (0x%02X) update failed cc: %x\n", target, msg->completion_code);
	}

	return;
}