void pal_OEM_1S_GET_FW_VERSION()

in meta-facebook/yv35-cl/src/ipmi/plat_ipmi.c [1060:1240]


void pal_OEM_1S_GET_FW_VERSION(ipmi_msg *msg)
{
	if (msg->data_len != 1) {
		msg->completion_code = CC_INVALID_LENGTH;
		return;
	}

	uint8_t component, retry = 3;
	component = msg->data[0];
	I2C_MSG i2c_msg;

	if (component == CPNT_PVCCIN || component == CPNT_PVCCFA_EHV_FIVRA) {
		i2c_msg.slave_addr = PVCCIN_addr;
	}
	if (component == CPNT_PVCCD_HV) {
		i2c_msg.slave_addr = PVCCD_HV_addr;
	}
	if (component == CPNT_PVCCINFAON || component == CPNT_PVCCFA_EHV) {
		i2c_msg.slave_addr = PVCCFA_EHV_addr;
	}

	switch (component) {
	case CPNT_CPLD:
		msg->completion_code = CC_UNSPECIFIED_ERROR;
		break;
	case CPNT_BIC:
		msg->data[0] = BIC_FW_YEAR_MSB;
		msg->data[1] = BIC_FW_YEAR_LSB;
		msg->data[2] = BIC_FW_WEEK;
		msg->data[3] = BIC_FW_VER;
		msg->data[4] = BIC_FW_platform_0;
		msg->data[5] = BIC_FW_platform_1;
		msg->data[6] = BIC_FW_platform_2;
		msg->data_len = 7;
		msg->completion_code = CC_SUCCESS;
		break;
	case CPNT_ME: {
		ipmb_error status;
		ipmi_msg *bridge_msg;
		bridge_msg = (ipmi_msg *)malloc(sizeof(ipmi_msg));
		if (bridge_msg == NULL) {
			msg->completion_code = CC_OUT_OF_SPACE;
			return;
		}
		bridge_msg->data_len = 0;
		bridge_msg->seq_source = 0xff;
		bridge_msg->InF_source = Self_IFs;
		bridge_msg->InF_target = ME_IPMB_IFs;
		bridge_msg->netfn = NETFN_APP_REQ;
		bridge_msg->cmd = CMD_APP_GET_DEVICE_ID;

		status = ipmb_read(bridge_msg, IPMB_inf_index_map[bridge_msg->InF_target]);
		if (status != ipmb_error_success) {
			printf("ipmb read fail status: %x", status);
			free(bridge_msg);
			msg->completion_code = CC_BRIDGE_MSG_ERR;
			return;
		} else {
			msg->data[0] = bridge_msg->data[2] & 0x7F;
			msg->data[1] = bridge_msg->data[3] >> 4;
			msg->data[2] = bridge_msg->data[3] & 0x0F;
			msg->data[3] = bridge_msg->data[12];
			msg->data[4] = bridge_msg->data[13] >> 4;
			msg->data_len = 5;
			msg->completion_code = CC_SUCCESS;
			free(bridge_msg);
		}
		break;
	}
	case CPNT_PVCCIN:
	case CPNT_PVCCFA_EHV_FIVRA:
	case CPNT_PVCCD_HV:
	case CPNT_PVCCINFAON:
	case CPNT_PVCCFA_EHV:
		i2c_msg.tx_len = 1;
		i2c_msg.rx_len = 7;
		i2c_msg.bus = i2c_bus5;
		i2c_msg.data[0] = PMBUS_IC_DEVICE_ID;

		if (i2c_master_read(&i2c_msg, retry)) {
			msg->completion_code = CC_UNSPECIFIED_ERROR;
			return;
		}

		if (i2c_msg.data[0] == 0x04 && i2c_msg.data[1] == 0x00 && i2c_msg.data[2] == 0x81 &&
		    i2c_msg.data[3] == 0xD2 && i2c_msg.data[4] == 0x49) {
			/* Renesas isl69259 */
			i2c_msg.tx_len = 3;
			i2c_msg.data[0] = 0xC7;
			i2c_msg.data[1] = 0x94;
			i2c_msg.data[2] = 0x00;

			if (i2c_master_write(&i2c_msg, retry)) {
				msg->completion_code = CC_UNSPECIFIED_ERROR;
				return;
			}

			i2c_msg.tx_len = 1;
			i2c_msg.rx_len = 4;
			i2c_msg.data[0] = 0xC5;

			if (i2c_master_read(&i2c_msg, retry)) {
				msg->completion_code = CC_UNSPECIFIED_ERROR;
				return;
			}

			msg->data[0] = i2c_msg.data[3];
			msg->data[1] = i2c_msg.data[2];
			msg->data[2] = i2c_msg.data[1];
			msg->data[3] = i2c_msg.data[0];
			msg->data_len = 4;
			msg->completion_code = CC_SUCCESS;

		} else if (i2c_msg.data[0] == 0x06 && i2c_msg.data[1] == 0x54 &&
			   i2c_msg.data[2] == 0x49 && i2c_msg.data[3] == 0x53 &&
			   i2c_msg.data[4] == 0x68 && i2c_msg.data[5] == 0x90 &&
			   i2c_msg.data[6] == 0x00) {
			/* TI tps53689 */
			i2c_msg.tx_len = 1;
			i2c_msg.rx_len = 2;
			i2c_msg.data[0] = 0xF4;

			if (i2c_master_read(&i2c_msg, retry)) {
				msg->completion_code = CC_UNSPECIFIED_ERROR;
				return;
			}

			msg->data[0] = i2c_msg.data[1];
			msg->data[1] = i2c_msg.data[0];
			msg->data_len = 2;
			msg->completion_code = CC_SUCCESS;

		} else if (i2c_msg.data[0] == 0x02 && i2c_msg.data[2] == 0x8A) {
			/* Infineon xdpe15284 */
			i2c_msg.tx_len = 6;
			i2c_msg.data[0] = 0xFD;
			i2c_msg.data[1] = 0x04;
			i2c_msg.data[2] = 0x00;
			i2c_msg.data[3] = 0x00;
			i2c_msg.data[4] = 0x00;
			i2c_msg.data[5] = 0x00;

			if (i2c_master_write(&i2c_msg, retry)) {
				msg->completion_code = CC_UNSPECIFIED_ERROR;
				return;
			}

			i2c_msg.tx_len = 2;
			i2c_msg.data[0] = 0xFE;
			i2c_msg.data[1] = 0x2D;

			if (i2c_master_write(&i2c_msg, retry)) {
				msg->completion_code = CC_UNSPECIFIED_ERROR;
				return;
			}

			i2c_msg.tx_len = 1;
			i2c_msg.rx_len = 5;
			i2c_msg.data[0] = 0xFD;

			if (i2c_master_read(&i2c_msg, retry)) {
				msg->completion_code = CC_UNSPECIFIED_ERROR;
				return;
			}

			msg->data[0] = i2c_msg.data[4];
			msg->data[1] = i2c_msg.data[3];
			msg->data[2] = i2c_msg.data[2];
			msg->data[3] = i2c_msg.data[1];
			msg->data_len = 4;
			msg->completion_code = CC_SUCCESS;
		} else {
			msg->completion_code = CC_UNSPECIFIED_ERROR;
		}
		break;
	default:
		msg->completion_code = CC_UNSPECIFIED_ERROR;
		break;
	}
	return;
}