Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions meta-facebook/gt-cc/src/platform/plat_fru.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,146 @@ void pal_load_fru_config(void)
{
memcpy(&fru_config, &plat_fru_config, sizeof(plat_fru_config));
}

static void decode_field(uint8_t *data, int len, char *buffer, int buffer_size)
{
CHECK_NULL_ARG(data);

if (len <= 0 || len >= buffer_size) {
buffer[0] = '\0';
return;
}

memcpy(buffer, data, len);
buffer[len] = '\0';
}

static bool get_nic_product_manufacturer(uint8_t fru_id, char *manufacturer,
uint8_t manufacturer_size)
{
CHECK_NULL_ARG_WITH_RETURN(manufacturer, false);

if (manufacturer_size == 0) {
LOG_ERR("Invalid manufacturer size: %d", manufacturer_size);
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
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 < 4) {
LOG_ERR("Invalid product area length for FRU ID %d", fru_id);
return false;
}

// Read the first field (product manufacturer) type/length
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 field for FRU ID %d", fru_id);
return false;
}

uint8_t type_length = fru_entry.data[0];
if (type_length == 0xC1) {
// End of fields marker
LOG_WRN("No product manufacturer field found for FRU ID %d", fru_id);
return false;
}

int field_len = type_length & 0x3F;
if (field_len <= 0 || field_len >= manufacturer_size) {
LOG_ERR("Invalid product manufacturer field length for FRU ID %d", fru_id);
return false;
}

// Read the product manufacturer field data
fru_entry.offset = product_area_offset + 4;
fru_entry.data_len = field_len;

if (FRU_read(&fru_entry) != FRU_READ_SUCCESS) {
LOG_ERR("Failed to read product manufacturer data for FRU ID %d", fru_id);
return false;
}

decode_field(fru_entry.data, field_len, manufacturer, manufacturer_size);

LOG_DBG("NIC FRU ID %d product manufacturer: %s", fru_id, manufacturer);
return true;
}

bool get_first_nic_manufacturer(char *manufacturer, uint8_t manufacturer_size)
{
CHECK_NULL_ARG_WITH_RETURN(manufacturer, false);

if (manufacturer_size == 0) {
LOG_ERR("Invalid manufacturer size: %d", manufacturer_size);
return false;
}

bool found_manufacturer = false;
char temp_manufacturer[32];

for (uint8_t i = 0; i < NIC_MAX_NUMBER; i++) {
// 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_manufacturer(NIC0_FRU_ID + i, temp_manufacturer,
sizeof(temp_manufacturer))) {
LOG_INF("NIC%d: Product Manufacturer = %s", i, temp_manufacturer);

// If this is the first manufacturer found, save it
if (!found_manufacturer) {
strncpy(manufacturer, temp_manufacturer, manufacturer_size - 1);
manufacturer[manufacturer_size - 1] = '\0';
found_manufacturer = true;
}
} else {
LOG_INF("NIC%d: Failed to read product manufacturer", i);
}
}

return found_manufacturer;
}
8 changes: 8 additions & 0 deletions meta-facebook/gt-cc/src/platform/plat_fru.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ enum GT_NIC_CONFIG {
#define NIC6_FRU_PORT 0x0C
#define NIC7_FRU_PORT 0x0D

typedef struct {
char product_manufacturer[32];
char product_name[32];
char product_part_number[32];
char product_version[32];
} ProductInfo;

uint8_t check_nic_type_by_fru();
bool get_first_nic_manufacturer(char *manufacturer, uint8_t manufacturer_size);

#endif
37 changes: 23 additions & 14 deletions meta-facebook/gt-cc/src/platform/plat_mctp.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
#define MCTP_EID_NIC_6 0x16
#define MCTP_EID_NIC_7 0x17

#define NVIDIA_NIC_MANUFACTURER "Nvidia"
#define BROADCOM_NIC_MANUFACTURER "Broadcom"

static uint8_t nic_config = NIC_CONFIG_UNKNOWN;

K_TIMER_DEFINE(send_cmd_timer, send_cmd_to_dev, NULL);
Expand Down Expand Up @@ -116,7 +119,7 @@
uint32_t i;

for (i = 0; i < ARRAY_SIZE(mctp_route_tbl); i++) {
mctp_route_entry *p = mctp_route_tbl + i;

Check failure on line 122 in meta-facebook/gt-cc/src/platform/plat_mctp.c

View workflow job for this annotation

GitHub Actions / Aggregate-Lint-Output

[] reported by reviewdog 🐶 Variable 'p' can be declared as pointer to const Raw Output: meta-facebook/gt-cc/src/platform/plat_mctp.c:122:21:Variable 'p' can be declared as pointer to const
if (!p) {
return MCTP_ERROR;
}
Expand Down Expand Up @@ -202,8 +205,8 @@
if (!len)
return;

mctp_route_entry *p = (mctp_route_entry *)args;

Check failure on line 208 in meta-facebook/gt-cc/src/platform/plat_mctp.c

View workflow job for this annotation

GitHub Actions / Aggregate-Lint-Output

[] reported by reviewdog 🐶 Variable 'p' can be declared as pointer to const Raw Output: meta-facebook/gt-cc/src/platform/plat_mctp.c:208:20:Variable 'p' can be declared as pointer to const
struct pldm_get_firmware_parameters_resp *response =

Check failure on line 209 in meta-facebook/gt-cc/src/platform/plat_mctp.c

View workflow job for this annotation

GitHub Actions / Aggregate-Lint-Output

[] reported by reviewdog 🐶 Variable 'response' can be declared as pointer to const Raw Output: meta-facebook/gt-cc/src/platform/plat_mctp.c:209:44:Variable 'response' can be declared as pointer to const
(struct pldm_get_firmware_parameters_resp *)buf;

uint8_t nic_index = p->endpoint - MCTP_EID_NIC_0;
Expand Down Expand Up @@ -298,7 +301,7 @@
return false;
}

struct mctp_to_ipmi_sel_resp *resp = (struct mctp_to_ipmi_sel_resp *)rbuf;

Check failure on line 304 in meta-facebook/gt-cc/src/platform/plat_mctp.c

View workflow job for this annotation

GitHub Actions / Aggregate-Lint-Output

[] reported by reviewdog 🐶 Variable 'resp' can be declared as pointer to const Raw Output: meta-facebook/gt-cc/src/platform/plat_mctp.c:304:32:Variable 'resp' can be declared as pointer to const

if ((resp->header.completion_code != MCTP_SUCCESS) ||
(resp->header.ipmi_comp_code != CC_SUCCESS)) {
Expand Down Expand Up @@ -501,26 +504,32 @@
return is_broadcom_thor2_nic;
}

void check_nic_config_by_ncsi(void)
void check_nic_config(void)
{
char nic_manufacturer[32];

bool found = get_first_nic_manufacturer(nic_manufacturer, sizeof(nic_manufacturer));

if (found) {
LOG_INF("First NIC manufacturer found: %s", nic_manufacturer);
} else {
LOG_INF("No NIC manufacturer found");
}

uint8_t config = NIC_CONFIG_UNKNOWN;
if (is_broadcom_thor2_nic_type() == true) {
if (strncmp(nic_manufacturer, NVIDIA_NIC_MANUFACTURER,
sizeof(NVIDIA_NIC_MANUFACTURER) - 1) == 0) {
LOG_INF("NVIDIA NIC detected");
config = mellanox_cx7_ncsi_get_link_type();
} else if (strncmp(nic_manufacturer, BROADCOM_NIC_MANUFACTURER,
sizeof(BROADCOM_NIC_MANUFACTURER) - 1) == 0) {
LOG_INF("Broadcom NIC detected");
set_cx7_init_arg_to_thor2();
config = NIC_CONFIG_THOR2;
} else {
// set_cx7_init_arg_to_cx7();
config = mellanox_cx7_ncsi_get_link_type();
LOG_INF("Unknown NIC manufacturer: %s", nic_manufacturer);
}

// config = mellanox_cx7_ncsi_get_link_type();

/* Remove this process for short term fix, will add back to support BMC get thor 2 type in the future */
/* Double check by fru if config is not IB_CX7 */
// if (config == NIC_CONFIG_CX7 || config == NIC_CONFIG_UNKNOWN) {
// LOG_INF("Double check nic type by fru");
// config = check_nic_type_by_fru();
// }

nic_config = config;
LOG_INF("NIC config is %d, 0: UNKNOWN, 1: CX7, 2: IB_CX7, 3: THOR2", nic_config);
}
Expand All @@ -536,7 +545,7 @@
set_dev_endpoint();

/* check nic config by ncsi */
check_nic_config_by_ncsi();
check_nic_config();

/* init mellanox cx7 ncsi */
if ((nic_config == NIC_CONFIG_IB_CX7) || (nic_config == NIC_CONFIG_CX7))
Expand Down
Loading