From 3514553072581ee3684df3d90d717b63c01b2257 Mon Sep 17 00:00:00 2001 From: victor Date: Thu, 19 Mar 2026 09:26:24 +0800 Subject: [PATCH] gt/support_AMD_Vulcano_NIC --- common/dev/cx7.c | 58 +++++- common/dev/include/cx7.h | 22 +++ meta-facebook/gt-cc/src/platform/plat_fru.c | 183 +++++++++++++++++- meta-facebook/gt-cc/src/platform/plat_fru.h | 2 + meta-facebook/gt-cc/src/platform/plat_hook.c | 121 ++++++++++++ meta-facebook/gt-cc/src/platform/plat_hook.h | 5 + meta-facebook/gt-cc/src/platform/plat_mctp.c | 145 ++++++++++---- .../gt-cc/src/platform/plat_pldm_monitor.c | 5 + .../gt-cc/src/platform/plat_pldm_monitor.h | 1 + .../gt-cc/src/platform/plat_sensor_table.c | 91 +++++++++ .../gt-cc/src/platform/plat_sensor_table.h | 1 + 11 files changed, 587 insertions(+), 47 deletions(-) create mode 100644 common/dev/include/cx7.h diff --git a/common/dev/cx7.c b/common/dev/cx7.c index 473ba3d29a..8746b52755 100644 --- a/common/dev/cx7.c +++ b/common/dev/cx7.c @@ -59,12 +59,12 @@ uint8_t cx7_read(sensor_cfg *cfg, int *reading) (uint8_t *)&req, req_len, resp_buf, sizeof(resp_buf)); if (resp_len == 0) { - LOG_ERR("Failed to get CX7 sensor #%d reading", init_arg->sensor_id); - - LOG_INF("Attempting to re-initialize EID 0x%x for CX7 device due to sensor read failure", - mctp_dest_eid); + LOG_ERR("Failed to get sensor num 0x%x CX7 sensor #%x reading", cfg->num, + init_arg->sensor_id); if (init_arg->re_init_eid_fn) { + LOG_INF("Attempting to re-initialize EID 0x%x for CX7 device due to sensor read failure", + mctp_dest_eid); init_arg->re_init_eid_fn(); } @@ -75,14 +75,18 @@ uint8_t cx7_read(sensor_cfg *cfg, int *reading) sizeof(resp_buf)); if (resp_len == 0) { - LOG_ERR("Failed to get CX7 sensor #%d reading after EID re-initialization", - init_arg->sensor_id); + LOG_ERR("Failed to get sensor num 0x%x CX7 sensor #%d reading after EID re-initialization", + cfg->num, init_arg->sensor_id); return SENSOR_FAIL_TO_ACCESS; } } struct pldm_get_sensor_reading_resp *res = (struct pldm_get_sensor_reading_resp *)resp_buf; + LOG_DBG("sensor num 0x%x, CX7 sensor 0x%x reading response - completion_code: 0x%x, sensor_operational_state: 0x%x, sensor_data_size: 0x%x \n", + cfg->num, init_arg->sensor_id, res->completion_code, res->sensor_operational_state, + res->sensor_data_size); + if ((res->completion_code != PLDM_SUCCESS)) { LOG_ERR("Failed to get get sensor reading, completion_code = 0x%x", res->completion_code); @@ -91,20 +95,54 @@ uint8_t cx7_read(sensor_cfg *cfg, int *reading) sensor_val *sval = (sensor_val *)reading; if (res->sensor_operational_state == PLDM_SENSOR_ENABLED) { - if (res->sensor_data_size != PLDM_SENSOR_DATA_SIZE_SINT16) { + switch (res->sensor_data_size) { + case PLDM_SENSOR_DATA_SIZE_UINT8: + sval->integer = res->present_reading[0]; + sval->fraction = 0; + return SENSOR_READ_SUCCESS; + + case PLDM_SENSOR_DATA_SIZE_SINT8: + sval->integer = (int8_t)res->present_reading[0]; + sval->fraction = 0; + return SENSOR_READ_SUCCESS; + + case PLDM_SENSOR_DATA_SIZE_UINT16: sval->integer = (res->present_reading[1] << 8) | res->present_reading[0]; sval->fraction = 0; return SENSOR_READ_SUCCESS; - } else if (res->sensor_data_size != PLDM_SENSOR_DATA_SIZE_SINT8) { - sval->integer = res->present_reading[0]; + + case PLDM_SENSOR_DATA_SIZE_SINT16: + sval->integer = + (int16_t)((res->present_reading[1] << 8) | res->present_reading[0]); + sval->fraction = 0; + return SENSOR_READ_SUCCESS; + + case PLDM_SENSOR_DATA_SIZE_UINT32: + sval->integer = (res->present_reading[3] << 24) | + (res->present_reading[2] << 16) | + (res->present_reading[1] << 8) | res->present_reading[0]; + sval->fraction = 0; + return SENSOR_READ_SUCCESS; + + case PLDM_SENSOR_DATA_SIZE_SINT32: + sval->integer = + (int32_t)((res->present_reading[3] << 24) | + (res->present_reading[2] << 16) | + (res->present_reading[1] << 8) | res->present_reading[0]); sval->fraction = 0; return SENSOR_READ_SUCCESS; + + LOG_DBG("CX7 sensor reading: %d.%d", sval->integer, sval->fraction); + + default: + LOG_ERR("Unsupported sensor data size: 0x%x", res->sensor_data_size); + return SENSOR_FAIL_TO_ACCESS; } } else if (res->sensor_operational_state == PLDM_SENSOR_UNAVAILABLE) { return SENSOR_UNAVAILABLE; } - LOG_ERR("CX7 Failed to get get sensor reading, sensor operational state=0x%x", + LOG_ERR("CX7 Failed to get sensor reading, sensor operational state=0x%x", res->sensor_operational_state); return SENSOR_FAIL_TO_ACCESS; } diff --git a/common/dev/include/cx7.h b/common/dev/include/cx7.h new file mode 100644 index 0000000000..f6cd0b0881 --- /dev/null +++ b/common/dev/include/cx7.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef CX7_H +#define CX7_H + +uint8_t cx7_init(sensor_cfg *cfg); + +#endif \ No newline at end of file diff --git a/meta-facebook/gt-cc/src/platform/plat_fru.c b/meta-facebook/gt-cc/src/platform/plat_fru.c index 140e3c555f..e20e386a0c 100644 --- a/meta-facebook/gt-cc/src/platform/plat_fru.c +++ b/meta-facebook/gt-cc/src/platform/plat_fru.c @@ -259,6 +259,12 @@ static bool get_nic_product_manufacturer(uint8_t fru_id, char *manufacturer, return false; } + // Validate FRU ID before accessing fru_config array + if (fru_id >= MAX_FRU_ID) { + LOG_ERR("Invalid FRU ID %d (MAX: %d)", fru_id, MAX_FRU_ID); + return false; + } + EEPROM_ENTRY fru_entry; memset(&fru_entry, 0, sizeof(fru_entry)); @@ -338,10 +344,185 @@ static bool get_nic_product_manufacturer(uint8_t fru_id, char *manufacturer, decode_field(fru_entry.data, field_len, manufacturer, manufacturer_size); - LOG_DBG("NIC FRU ID %d product manufacturer: %s", fru_id, manufacturer); + LOG_INF("NIC FRU ID %d product manufacturer: %s", fru_id, manufacturer); + return true; +} + +static bool get_nic_product_name(uint8_t fru_id, char *name, uint8_t name_size) +{ + CHECK_NULL_ARG_WITH_RETURN(name, false); + + if (name_size == 0) { + LOG_ERR("Invalid name size: %d", name_size); + return false; + } + + // Validate FRU ID before accessing fru_config array + if (fru_id >= MAX_FRU_ID) { + LOG_ERR("Invalid FRU ID %d (MAX: %d)", fru_id, MAX_FRU_ID); + return false; + } + + EEPROM_ENTRY fru_entry; + memset(&fru_entry, 0, sizeof(fru_entry)); + + fru_entry.config = fru_config[fru_id]; + fru_entry.offset = 0; + fru_entry.data_len = 8; + + if (FRU_read(&fru_entry) != FRU_READ_SUCCESS) { + LOG_ERR("Failed to read FRU header for FRU ID %d", fru_id); + return false; + } + + // Check FRU common header format identifier + if (fru_entry.data[0] != 0x01) { + LOG_ERR("Invalid FRU format for FRU ID %d", fru_id); + return false; + } + + // Get product area offset (5th byte * 8) + uint16_t product_area_offset = fru_entry.data[4] * 8; + if (product_area_offset == 0) { + LOG_ERR("No product area found for FRU ID %d", fru_id); + return false; + } + + // Read product area header (format, length, language) + fru_entry.offset = product_area_offset; + fru_entry.data_len = 3; + + if (FRU_read(&fru_entry) != FRU_READ_SUCCESS) { + LOG_ERR("Failed to read product area header for FRU ID %d", fru_id); + return false; + } + + // Check product area format version + if (fru_entry.data[0] != 0x01) { + LOG_ERR("Invalid product area format for FRU ID %d", fru_id); + return false; + } + + uint16_t area_len = fru_entry.data[1] * 8; + if (area_len < 5) { + LOG_ERR("Product area too short for FRU ID %d", fru_id); + return false; + } + + // Read Field 1 (product manufacturer) type/length byte at offset+3 + fru_entry.offset = product_area_offset + 3; + fru_entry.data_len = 1; + + if (FRU_read(&fru_entry) != FRU_READ_SUCCESS) { + LOG_ERR("Failed to read product manufacturer type/length for FRU ID %d", fru_id); + return false; + } + + uint8_t mfr_type_length = fru_entry.data[0]; + if (mfr_type_length == 0xC1) { + LOG_WRN("No product manufacturer field for FRU ID %d, cannot reach product name", + fru_id); + return false; + } + + int mfr_len = mfr_type_length & 0x3F; + // Bounds check: manufacturer field must not exceed the area + if ((3 + 1 + mfr_len + 1) > area_len) { + LOG_ERR("Manufacturer field overflows product area for FRU ID %d", fru_id); + return false; + } + + // Field 2 (product name) type/length byte is right after manufacturer data + uint16_t name_tl_offset = product_area_offset + 3 + 1 + mfr_len; + fru_entry.offset = name_tl_offset; + fru_entry.data_len = 1; + + if (FRU_read(&fru_entry) != FRU_READ_SUCCESS) { + LOG_ERR("Failed to read product name type/length for FRU ID %d", fru_id); + return false; + } + + uint8_t name_type_length = fru_entry.data[0]; + if (name_type_length == 0xC1) { + LOG_WRN("No product name field found for FRU ID %d", fru_id); + return false; + } + + int field_len = name_type_length & 0x3F; + if (field_len <= 0) { + LOG_WRN("Product name field is empty for FRU ID %d", fru_id); + return false; + } + + // Cap read length to fit in caller's buffer (leave room for NUL terminator) + int read_len = (field_len < (name_size - 1)) ? field_len : (name_size - 1); + + // Bounds check: product name field must not exceed the area + if ((name_tl_offset - product_area_offset + 1 + read_len) > area_len) { + LOG_ERR("Product name field overflows product area for FRU ID %d", fru_id); + return false; + } + + // Read the product name field data + fru_entry.offset = name_tl_offset + 1; + fru_entry.data_len = read_len; + + if (FRU_read(&fru_entry) != FRU_READ_SUCCESS) { + LOG_ERR("Failed to read product name data for FRU ID %d", fru_id); + return false; + } + + decode_field(fru_entry.data, read_len, name, name_size); + + LOG_INF("NIC FRU ID %d product name: %s", fru_id, name); return true; } +bool get_first_nic_name(char *name, uint8_t name_size) +{ + CHECK_NULL_ARG_WITH_RETURN(name, false); + + if (name_size == 0) { + LOG_ERR("Invalid name size: %d", name_size); + return false; + } + + bool found_name = false; + char temp_name[32]; + + for (uint8_t i = 0; i < NIC_MAX_NUMBER; i++) { + // Validate FRU ID before use to prevent accessing invalid memory + uint8_t fru_id = NIC0_FRU_ID + i; + if (fru_id >= MAX_FRU_ID) { + LOG_ERR("Invalid FRU ID %d for NIC%d, skipping", fru_id, i); + continue; + } + + // Check if NIC is present (presence pin is active low) + if (gpio_get(nic_prsnt_pin[i])) { + LOG_INF("NIC%d: Not present", i); + continue; + } + + if (get_nic_product_name(fru_id, temp_name, sizeof(temp_name))) { + LOG_INF("NIC%d: Product Name = %s", i, temp_name); + + // Found the first name, save it and return immediately + // Use the smaller of the two buffer sizes to prevent overflow + uint8_t copy_size = + (sizeof(temp_name) < name_size) ? sizeof(temp_name) : name_size; + strncpy(name, temp_name, copy_size - 1); + name[copy_size - 1] = '\0'; + found_name = true; + break; + } else { + LOG_INF("NIC%d: Failed to read product name", i); + } + } + + return found_name; +} + bool get_first_nic_manufacturer(char *manufacturer, uint8_t manufacturer_size) { CHECK_NULL_ARG_WITH_RETURN(manufacturer, false); diff --git a/meta-facebook/gt-cc/src/platform/plat_fru.h b/meta-facebook/gt-cc/src/platform/plat_fru.h index 4842f4ea05..ab995b8d8f 100644 --- a/meta-facebook/gt-cc/src/platform/plat_fru.h +++ b/meta-facebook/gt-cc/src/platform/plat_fru.h @@ -39,6 +39,7 @@ enum GT_NIC_CONFIG { NIC_CONFIG_IB_CX7 = 2, NIC_CONFIG_THOR2 = 3, NIC_CONFIG_POLLARA = 4, + NIC_CONFIG_VULCANO = 5, }; #define FRU_CFG_NUM MAX_FRU_ID @@ -73,5 +74,6 @@ typedef struct { uint8_t check_nic_type_by_fru(); bool get_first_nic_manufacturer(char *manufacturer, uint8_t manufacturer_size); +bool get_first_nic_name(char *name, uint8_t name_size); #endif diff --git a/meta-facebook/gt-cc/src/platform/plat_hook.c b/meta-facebook/gt-cc/src/platform/plat_hook.c index 159b3891bf..21b1decb03 100644 --- a/meta-facebook/gt-cc/src/platform/plat_hook.c +++ b/meta-facebook/gt-cc/src/platform/plat_hook.c @@ -32,6 +32,7 @@ #include "plat_fru.h" #include "plat_class.h" #include "tmp75.h" +#include "cx7.h" #include @@ -970,6 +971,76 @@ cx7_init_arg cx7_init_args[] = { .re_init_eid_fn = plat_set_dev_endpoint }, }; +cx7_init_arg vulcano_init_args[] = { + [0] = { .is_init = false, + .endpoint = 0x10, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, + [1] = { .is_init = false, + .endpoint = 0x11, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, + [2] = { .is_init = false, + .endpoint = 0x12, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, + [3] = { .is_init = false, + .endpoint = 0x13, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, + [4] = { .is_init = false, + .endpoint = 0x14, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, + [5] = { .is_init = false, + .endpoint = 0x15, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, + [6] = { .is_init = false, + .endpoint = 0x16, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, + [7] = { .is_init = false, + .endpoint = 0x17, + .sensor_id = 0x003D, + .re_init_eid_fn = plat_set_dev_endpoint }, +}; + +cx7_init_arg vulcano_optics_init_args[] = { + [0] = { .is_init = false, + .endpoint = 0x10, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, + [1] = { .is_init = false, + .endpoint = 0x11, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, + [2] = { .is_init = false, + .endpoint = 0x12, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, + [3] = { .is_init = false, + .endpoint = 0x13, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, + [4] = { .is_init = false, + .endpoint = 0x14, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, + [5] = { .is_init = false, + .endpoint = 0x15, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, + [6] = { .is_init = false, + .endpoint = 0x16, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, + [7] = { .is_init = false, + .endpoint = 0x17, + .sensor_id = 0x0041, + .re_init_eid_fn = plat_set_dev_endpoint }, +}; + /************************************************************************************************** * PRE-HOOK/POST-HOOK ARGS **************************************************************************************************/ @@ -1324,6 +1395,56 @@ void nic_optics_drive_reinit_for_pollara(void) enable_sensor_poll(); } +void nic_drive_reinit_for_vulcano(void) +{ + if (get_nic_config() != NIC_CONFIG_VULCANO) + return; + + LOG_INF("NIC_CONFIG_VULCANO detected, do nic drive reinit"); + + disable_sensor_poll(); + + for (uint8_t i = 0; i < ARRAY_SIZE(nic_temp_sensor_table); i++) { + uint8_t sensor_num = nic_temp_sensor_table[i]; + sensor_cfg *cfg = &sensor_config[sensor_config_index_map[sensor_num]]; + + if (!cfg) { + LOG_ERR("The pointer to sensor number 0x%x cfg is NULL", sensor_num); + continue; + } + + if (cx7_init(cfg)) { + LOG_ERR("sensor number 0x%x cfg->read reinit fail", cfg->num); + } + } + enable_sensor_poll(); +} + +void nic_optics_drive_reinit_for_vulcano(void) +{ + if (get_nic_config() != NIC_CONFIG_VULCANO) + return; + + LOG_INF("NIC_CONFIG_VULCANO detected, do nic optics drive reinit"); + + disable_sensor_poll(); + + for (uint8_t i = 0; i < ARRAY_SIZE(nic_optics_sensor_table); i++) { + uint8_t sensor_num = nic_optics_sensor_table[i]; + sensor_cfg *cfg = &sensor_config[sensor_config_index_map[sensor_num]]; + + if (!cfg) { + LOG_ERR("The pointer to sensor number 0x%x cfg is NULL", sensor_num); + continue; + } + + if (cx7_init(cfg)) { + LOG_ERR("sensor number 0x%x cfg->read reinit fail", cfg->num); + } + } + enable_sensor_poll(); +} + bool is_mb_dc_on() { /* SYS_PWR_READY_N is low active, diff --git a/meta-facebook/gt-cc/src/platform/plat_hook.h b/meta-facebook/gt-cc/src/platform/plat_hook.h index 6462bf9b07..40f68f1faf 100644 --- a/meta-facebook/gt-cc/src/platform/plat_hook.h +++ b/meta-facebook/gt-cc/src/platform/plat_hook.h @@ -48,6 +48,9 @@ extern ltc4282_init_arg ltc4282_hsc_init_args[]; extern ltc4286_init_arg ltc4286_hsc_init_args[]; extern nct7718w_init_arg nct7718w_init_args[]; extern cx7_init_arg cx7_init_args[]; +extern cx7_init_arg vulcano_init_args[]; +extern cx7_init_arg vulcano_optics_init_args[]; + /************************************************************************************************** * PRE-HOOK/POST-HOOK ARGS **************************************************************************************************/ @@ -71,6 +74,8 @@ struct k_mutex *find_bus_mutex(sensor_cfg *cfg); void ssd_drive_reinit(void); void nic_drive_reinit_for_pollara(void); void nic_optics_drive_reinit_for_pollara(void); +void nic_drive_reinit_for_vulcano(void); +void nic_optics_drive_reinit_for_vulcano(void); bool is_mb_dc_on(); void set_cx7_init_arg_to_thor2(); diff --git a/meta-facebook/gt-cc/src/platform/plat_mctp.c b/meta-facebook/gt-cc/src/platform/plat_mctp.c index 533c7ba82b..c86b849915 100644 --- a/meta-facebook/gt-cc/src/platform/plat_mctp.c +++ b/meta-facebook/gt-cc/src/platform/plat_mctp.c @@ -138,22 +138,10 @@ uint8_t get_mctp_info(uint8_t dest_endpoint, mctp **mctp_inst, mctp_ext_params * return rc; } -static void set_endpoint_resp_handler(void *args, uint8_t *buf, uint16_t len) -{ - if (!buf || !len) - return; - LOG_HEXDUMP_WRN(buf, len, __func__); -} - -static void set_endpoint_resp_timeout(void *args) -{ - mctp_route_entry *p = (mctp_route_entry *)args; - printk("[%s] Endpoint 0x%x set endpoint failed on bus %d \n", __func__, p->endpoint, - p->bus); -} - static void set_dev_endpoint(void) { + LOG_INF("Setting MCTP endpoint for devices"); + for (uint8_t i = 0; i < ARRAY_SIZE(mctp_route_tbl); i++) { mctp_route_entry *p = mctp_route_tbl + i; @@ -164,30 +152,71 @@ static void set_dev_endpoint(void) if (gpio_get(p->dev_present_pin)) continue; - for (uint8_t j = 0; j < ARRAY_SIZE(smbus_port); j++) { - if (p->bus != smbus_port[j].conf.smbus_conf.bus) - continue; + uint8_t ret = 0; + mctp *mctp_inst = NULL; + mctp_ctrl_msg msg = { 0 }; - struct _set_eid_req req = { 0 }; - req.op = SET_EID_REQ_OP_SET_EID; - req.eid = p->endpoint; + ret = get_mctp_info(p->endpoint, &mctp_inst, &msg.ext_params); + if (ret != MCTP_SUCCESS) { + LOG_ERR("Get mctp route info fail for endpoint 0x%x", p->endpoint); + continue; + } - mctp_ctrl_msg msg; - memset(&msg, 0, sizeof(msg)); - msg.ext_params.type = MCTP_MEDIUM_TYPE_SMBUS; - msg.ext_params.smbus_ext_params.addr = p->addr; + if (!mctp_inst) { + LOG_ERR("mctp_inst is NULL for endpoint 0x%x", p->endpoint); + continue; + } - msg.hdr.cmd = MCTP_CTRL_CMD_SET_ENDPOINT_ID; - msg.hdr.rq = 1; + /** Set eid directly without checking **/ + memset(&msg, 0, sizeof(mctp_ctrl_msg)); + msg.ext_params.type = MCTP_MEDIUM_TYPE_SMBUS; + msg.ext_params.smbus_ext_params.addr = p->addr; - msg.cmd_data = (uint8_t *)&req; - msg.cmd_data_len = sizeof(req); + struct _set_eid_req set_eid_req = { 0 }; + struct _set_eid_resp set_eid_resp = { 0 }; + set_eid_req.op = SET_EID_REQ_OP_SET_EID; + set_eid_req.eid = p->endpoint; + + msg.hdr.cmd = MCTP_CTRL_CMD_SET_ENDPOINT_ID; + msg.hdr.rq = MCTP_REQUEST; + msg.cmd_data = (uint8_t *)&set_eid_req; + msg.cmd_data_len = sizeof(set_eid_req); + + ret = mctp_ctrl_read(mctp_inst, &msg, (uint8_t *)&set_eid_resp, + sizeof(set_eid_resp)); + if (ret != MCTP_SUCCESS) { + LOG_ERR("Fail to set eid, endpoint: 0x%x, bus: %d, ret: 0x%x", p->endpoint, + p->bus, ret); + continue; + } + LOG_INF("Successfully set eid 0x%x on bus %d", p->endpoint, p->bus); - msg.recv_resp_cb_fn = set_endpoint_resp_handler; - msg.timeout_cb_fn = set_endpoint_resp_timeout; - msg.timeout_cb_fn_args = p; + k_msleep(50); // wait for the device to process the set eid command - mctp_ctrl_send_msg(find_mctp_by_smbus(p->bus), &msg); + /** Read back eid to verify **/ + memset(&msg, 0, sizeof(mctp_ctrl_msg)); + msg.ext_params.type = MCTP_MEDIUM_TYPE_SMBUS; + msg.ext_params.smbus_ext_params.addr = p->addr; + + msg.hdr.cmd = MCTP_CTRL_CMD_GET_ENDPOINT_ID; + msg.hdr.rq = MCTP_REQUEST; + msg.cmd_data_len = 0; + + struct _get_eid_resp get_eid_resp = { 0 }; + ret = mctp_ctrl_read(mctp_inst, &msg, (uint8_t *)&get_eid_resp, + sizeof(get_eid_resp)); + if (ret != MCTP_SUCCESS) { + LOG_ERR("Fail to get eid after setting, endpoint: 0x%x, bus: %d, ret: 0x%x", + p->endpoint, p->bus, ret); + continue; + } + + if (get_eid_resp.eid == p->endpoint) { + LOG_INF("Verified: Endpoint 0x%x has correct eid on bus %d", p->endpoint, + p->bus); + } else { + LOG_WRN("Warning: Endpoint 0x%x eid mismatch, expected 0x%x but got 0x%x", + p->endpoint, p->endpoint, get_eid_resp.eid); } } } @@ -220,12 +249,35 @@ static void get_dev_firmware_resp_handler(void *args, uint8_t *buf, uint16_t len uint8_t nic_index = p->endpoint - MCTP_EID_NIC_0; + //check completion code + if (response->completion_code != PLDM_SUCCESS) { + LOG_ERR("Failed to get firmware parameters for NIC%d, completion_code = 0x%x", + nic_index, response->completion_code); + return; + } + + /* Sanity check for version string length */ + if (response->active_comp_image_set_ver_str_len == 0) { + LOG_WRN("NIC%d firmware version string length is 0", nic_index); + return; + } + + if (response->active_comp_image_set_ver_str_len > 256) { + LOG_ERR("NIC%d firmware version string length too large: %d, possibly corrupted data", + nic_index, response->active_comp_image_set_ver_str_len); + return; + } + + LOG_DBG("NIC%d allocating %d bytes for firmware version", nic_index, + response->active_comp_image_set_ver_str_len); + SAFE_FREE(nic_vesion[nic_index].ptr); nic_vesion[nic_index].ptr = (uint8_t *)malloc(sizeof(uint8_t) * response->active_comp_image_set_ver_str_len); if (!nic_vesion[nic_index].ptr) { - LOG_ERR("The buffer of NIC%d version memory allocate failed", nic_index); + LOG_ERR("The buffer of NIC%d version memory allocate failed, requested size: %d", + nic_index, response->active_comp_image_set_ver_str_len); return; } @@ -538,16 +590,31 @@ void check_nic_config(void) } else if (strncmp(nic_manufacturer, AMD_NIC_MANUFACTURER, sizeof(AMD_NIC_MANUFACTURER) - 1) == 0) { LOG_INF("AMD NIC detected"); - config = NIC_CONFIG_POLLARA; + char nic_name[32]; + memset(nic_name, 0, sizeof(nic_name)); + bool found_name = get_first_nic_name(nic_name, sizeof(nic_name)); + if (found_name) { + LOG_INF("First NIC name found: %s", nic_name); + if (strstr(nic_name, "VULCANO") != NULL) { + LOG_INF("VULCANO NIC detected based on NIC name"); + config = NIC_CONFIG_VULCANO; + } else { + LOG_INF("Unknown AMD NIC type based on NIC name, default to POLLARA config"); + config = NIC_CONFIG_POLLARA; + } + } else { + LOG_INF("No NIC name found for AMD NIC, default to POLLARA config"); + config = NIC_CONFIG_POLLARA; + } } else { LOG_INF("Unknown NIC manufacturer: %s", nic_manufacturer); } nic_config = config; - LOG_INF("NIC config is %d, 0: UNKNOWN, 1: CX7, 2: IB_CX7, 3: THOR2, 4: POLLARA", + LOG_INF("NIC config is %d, 0: UNKNOWN, 1: CX7, 2: IB_CX7, 3: THOR2, 4: POLLARA, 5: VULCANO", nic_config); - is_nic_config_set = true; + // is_nic_config_set = true; } uint8_t get_nic_config(void) @@ -572,6 +639,12 @@ void send_cmd_to_dev_handler(struct k_work *work) nic_drive_reinit_for_pollara(); nic_optics_drive_reinit_for_pollara(); + update_nic_sensor_config_for_vulcano(); + nic_drive_reinit_for_vulcano(); + nic_optics_drive_reinit_for_vulcano(); + + is_nic_config_set = true; + /* init mellanox cx7 ncsi */ if ((nic_config == NIC_CONFIG_IB_CX7) || (nic_config == NIC_CONFIG_CX7)) mellanox_cx7_ncsi_init(); diff --git a/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.c b/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.c index fad233615e..89f148efb2 100644 --- a/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.c +++ b/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.c @@ -878,6 +878,11 @@ static void plat_get_effecter_nic_type_handler(const uint8_t *buf, uint16_t len, state->effecter_op_state = PLDM_EFFECTER_ENABLED_NOUPDATEPENDING; state->present_state = state->pending_state = EFFECTER_STATE_NIC_TYPE_POLLARA; break; + case NIC_CONFIG_VULCANO: + state->effecter_op_state = PLDM_EFFECTER_ENABLED_NOUPDATEPENDING; + state->present_state = state->pending_state = EFFECTER_STATE_NIC_TYPE_VULCANO; + break; + default: state->effecter_op_state = PLDM_EFFECTER_STATUSUNKNOWN; state->present_state = state->pending_state = EFFECTER_STATE_NIC_TYPE_UNKNOWN; diff --git a/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.h b/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.h index 77e21d39d8..589bac8f38 100644 --- a/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.h +++ b/meta-facebook/gt-cc/src/platform/plat_pldm_monitor.h @@ -107,6 +107,7 @@ enum plat_effecter_states_nic_type_value { EFFECTER_STATE_NIC_TYPE_CX7_IB = 0x02, EFFECTER_STATE_NIC_TYPE_THOR2 = 0x03, EFFECTER_STATE_NIC_TYPE_POLLARA = 0x04, + EFFECTER_STATE_NIC_TYPE_VULCANO = 0x05, EFFECTER_STATE_NIC_TYPE_MAX, }; diff --git a/meta-facebook/gt-cc/src/platform/plat_sensor_table.c b/meta-facebook/gt-cc/src/platform/plat_sensor_table.c index ae259bdc01..a642f149c0 100644 --- a/meta-facebook/gt-cc/src/platform/plat_sensor_table.c +++ b/meta-facebook/gt-cc/src/platform/plat_sensor_table.c @@ -1390,6 +1390,97 @@ void update_nic_sensor_config_for_pollara(void) } } +void update_nic_sensor_config_for_vulcano(void) +{ + if (get_nic_config() != NIC_CONFIG_VULCANO) + return; + + LOG_INF("NIC_CONFIG_VULCANO detected, updating NIC sensor configurations"); + + // Update NIC temperature and optics sensor configurations + for (int i = 0; i < sensor_config_count; i++) { + switch (sensor_config[i].num) { + // NIC temperature sensors (0-7) + case SENSOR_NUM_TEMP_NIC_0: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[0]; + break; + + case SENSOR_NUM_TEMP_NIC_1: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[1]; + break; + + case SENSOR_NUM_TEMP_NIC_2: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[2]; + break; + + case SENSOR_NUM_TEMP_NIC_3: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[3]; + break; + + case SENSOR_NUM_TEMP_NIC_4: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[4]; + break; + + case SENSOR_NUM_TEMP_NIC_5: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[5]; + break; + + case SENSOR_NUM_TEMP_NIC_6: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[6]; + break; + + case SENSOR_NUM_TEMP_NIC_7: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_init_args[7]; + break; + + // NIC optics sensors (0-7) + case SENSOR_NUM_TEMP_NIC_OPTICS_0: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[0]; + break; + case SENSOR_NUM_TEMP_NIC_OPTICS_1: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[1]; + break; + case SENSOR_NUM_TEMP_NIC_OPTICS_2: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[2]; + break; + case SENSOR_NUM_TEMP_NIC_OPTICS_3: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[3]; + break; + case SENSOR_NUM_TEMP_NIC_OPTICS_4: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[4]; + break; + case SENSOR_NUM_TEMP_NIC_OPTICS_5: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[5]; + break; + case SENSOR_NUM_TEMP_NIC_OPTICS_6: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[6]; + break; + case SENSOR_NUM_TEMP_NIC_OPTICS_7: + sensor_config[i].type = sensor_dev_cx7; + sensor_config[i].init_args = &vulcano_optics_init_args[7]; + break; + + default: + break; + } + } +} + void load_sensor_config(void) { memcpy(sensor_config, plat_sensor_config, sizeof(plat_sensor_config)); diff --git a/meta-facebook/gt-cc/src/platform/plat_sensor_table.h b/meta-facebook/gt-cc/src/platform/plat_sensor_table.h index cf0542a420..1d3da14f24 100644 --- a/meta-facebook/gt-cc/src/platform/plat_sensor_table.h +++ b/meta-facebook/gt-cc/src/platform/plat_sensor_table.h @@ -289,6 +289,7 @@ uint8_t plat_get_config_size(); void load_sensor_config(void); void update_nic_sensor_config_for_pollara(void); +void update_nic_sensor_config_for_vulcano(void); bool is_e1s_access(uint8_t sensor_num); bool is_nic_access(uint8_t sensor_num); bool is_nic_optics_access(uint8_t sensor_num);