diff --git a/cli/main.c b/cli/main.c index db2eda7a..cfde38e8 100644 --- a/cli/main.c +++ b/cli/main.c @@ -189,27 +189,31 @@ static int print_dev_info(struct switchtec_dev *dev) int ret; int device_id; char version[64]; + enum switchtec_boot_phase phase; enum switchtec_rev hw_rev; device_id = switchtec_device_id(dev); ret = switchtec_get_fw_version(dev, version, sizeof(version)); - if (ret < 0) { - switchtec_perror("dev info"); - return ret; - } + if (ret < 0) + strcpy(version, "N/A"); - ret = switchtec_get_device_info(dev, NULL, NULL, &hw_rev); + ret = switchtec_get_device_info(dev, &phase, NULL, &hw_rev); if (ret) { switchtec_perror("dev info"); return ret; } - printf("%s:\n", switchtec_name(dev)); + printf("%s (%s):\n", switchtec_name(dev), + switchtec_phase_id_str(phase)); printf(" Generation: %s\n", switchtec_gen_str(dev)); printf(" HW Revision: %s\n", switchtec_rev_str(hw_rev)); - printf(" Variant: %s\n", switchtec_variant_str(dev)); - printf(" Device ID: 0x%04x\n", device_id); + printf(" Variant: %s\n", + device_id ? switchtec_variant_str(dev) : "N/A"); + if (device_id) + printf(" Device ID: 0x%04x\n", device_id); + else + printf(" Device ID: %s\n", "N/A"); printf(" FW Version: %s\n", version); return 0; diff --git a/cli/mfg.c b/cli/mfg.c index b46935ad..dfb1f078 100644 --- a/cli/mfg.c +++ b/cli/mfg.c @@ -64,20 +64,6 @@ static const struct argconfig_choice secure_state_choices[] = { {} }; -static const char* phase_id_to_string(enum switchtec_boot_phase phase_id) -{ - switch(phase_id) { - case SWITCHTEC_BOOT_PHASE_BL1: - return "BL1"; - case SWITCHTEC_BOOT_PHASE_BL2: - return "BL2"; - case SWITCHTEC_BOOT_PHASE_FW: - return "Main Firmware"; - default: - return "Unknown Phase"; - } -} - #define CMD_DESC_PING "ping device and get current boot phase" static int ping(int argc, char **argv) @@ -282,7 +268,8 @@ static int info(int argc, char **argv) } phase_id = switchtec_boot_phase(cfg.dev); - printf("Current Boot Phase: \t\t\t%s\n", phase_id_to_string(phase_id)); + printf("Current Boot Phase: \t\t\t%s\n", + switchtec_phase_id_str(phase_id)); ret = switchtec_sn_ver_get(cfg.dev, &sn_info); if (ret) { diff --git a/inc/switchtec/switchtec.h b/inc/switchtec/switchtec.h index 0bcb317e..9fa07e2b 100644 --- a/inc/switchtec/switchtec.h +++ b/inc/switchtec/switchtec.h @@ -610,6 +610,24 @@ static inline const char *switchtec_variant_str(struct switchtec_dev *dev) return str; } +/** + * @brief Return the phase string for a phase id. + */ +static inline const char* switchtec_phase_id_str( + enum switchtec_boot_phase phase_id) +{ + switch(phase_id) { + case SWITCHTEC_BOOT_PHASE_BL1: + return "BL1"; + case SWITCHTEC_BOOT_PHASE_BL2: + return "BL2"; + case SWITCHTEC_BOOT_PHASE_FW: + return "Main Firmware"; + default: + return "Unknown Phase"; + } +} + /** @brief Number of GT/s capable for each PCI generation or \p link_rate */ static const float switchtec_gen_transfers[] = {0, 2.5, 5, 8, 16, 32}; /** @brief Number of GB/s capable for each PCI generation or \p link_rate */ @@ -835,6 +853,8 @@ int switchtec_fw_read(struct switchtec_dev *dev, unsigned long addr, size_t len, void *buf); void switchtec_fw_perror(const char *s, int ret); int switchtec_fw_file_info(int fd, struct switchtec_fw_image_info *info); +int switchtec_get_device_id_bl2(struct switchtec_dev *dev, + unsigned short *device_id); int switchtec_fw_file_secure_version_newer(struct switchtec_dev *dev, int img_fd); const char *switchtec_fw_image_type(const struct switchtec_fw_image_info *info); diff --git a/lib/fw.c b/lib/fw.c index 2a4b7560..d7eab3d7 100644 --- a/lib/fw.c +++ b/lib/fw.c @@ -1097,6 +1097,27 @@ static int switchtec_fw_part_info(struct switchtec_dev *dev, int nr_info, return nr_info; } +int switchtec_get_device_id_bl2(struct switchtec_dev *dev, + unsigned short *device_id) +{ + int ret; + uint8_t subcmd = MRPC_PART_INFO_GET_ALL_INFO; + struct switchtec_flash_info_gen4 all_info; + + if (dev->gen != SWITCHTEC_GEN_UNKNOWN) + return -EINVAL; + + ret = switchtec_cmd(dev, MRPC_PART_INFO, &subcmd, + sizeof(subcmd), &all_info, + sizeof(all_info)); + if (ret) + return ret; + + *device_id = le16toh(all_info.device_id); + + return 0; +} + static long multicfg_subcmd(struct switchtec_dev *dev, uint32_t subcmd, uint8_t index) { diff --git a/lib/platform/linux.c b/lib/platform/linux.c index 8fa42be8..c7f63627 100644 --- a/lib/platform/linux.c +++ b/lib/platform/linux.c @@ -829,6 +829,9 @@ static void event_summary_copy(struct switchtec_event_summary *dst, for (i = 0; i < SWITCHTEC_MAX_PFF_CSR && i < size; i++) dst->pff[i] = src->pff[i]; + + for (; i < SWITCHTEC_MAX_PFF_CSR; i++) + dst->pff[i] = 0; } #define EV(t, n)[SWITCHTEC_ ## t ## _EVT_ ## n] = \ diff --git a/lib/switchtec.c b/lib/switchtec.c index 854f5ec7..5254c7e7 100644 --- a/lib/switchtec.c +++ b/lib/switchtec.c @@ -186,13 +186,16 @@ static int set_gen_variant(struct switchtec_dev * dev) dev->gen = SWITCHTEC_GEN_UNKNOWN; dev->var = SWITCHTEC_VAR_UNKNOWN; dev->device_id = dev->ops->get_device_id(dev); + if (!dev->device_id) + switchtec_get_device_id_bl2(dev, + (unsigned short *)&dev->device_id); while (id->device_id) { if (id->device_id == dev->device_id) { dev->gen = id->gen; dev->var = id->var; - return 0; + break; } id++;