From ab7f16bd2f87d68e75c49c88d66cb885a9714c61 Mon Sep 17 00:00:00 2001 From: BenReed161 Date: Wed, 18 Mar 2026 14:48:23 -0700 Subject: [PATCH] cleanup OSA commands Original OSA code printf in the lib rather than in the cli code. Changed so OSA printing is handled in the CLI portion, cut down on the function size. --- cli/diag.c | 204 ++++++++++++++++++++++++++++- inc/switchtec/switchtec.h | 75 ++++++++++- lib/diag.c | 265 ++++++++++++-------------------------- 3 files changed, 358 insertions(+), 186 deletions(-) diff --git a/cli/diag.c b/cli/diag.c index f9c0ce2e..c4281ef5 100644 --- a/cli/diag.c +++ b/cli/diag.c @@ -2824,6 +2824,7 @@ static int stack_id_check(struct switchtec_dev *dev, int stack_id) static int osa(int argc, char **argv) { int ret = 0; + struct switchtec_osa_status status; static struct { struct switchtec_dev *dev; int stack_id; @@ -2836,6 +2837,15 @@ static int osa(int argc, char **argv) required_argument,"operations:\n- stop:0\n- start:1\n- trigger:2\n- reset:3\n- release:4\n- status:5"}, {NULL}}; + const char *valid_ops[6] = {"stop", "start", "trigger", "reset", + "release", "status"}; + const char *states[5] = {"Deactivated (not armed)", + "Started (armed), not triggered", + "Started (armted), triggered", + "Stopped, not triggered", + "Stopped, triggered"}; + const char *directions[2] = {"TX", "RX"}; + argconfig_parse(argc, argv, CMD_ORDERED_SET_ANALYZER, opts, &cfg, sizeof(cfg)); @@ -2848,11 +2858,25 @@ static int osa(int argc, char **argv) return -1; } - ret = switchtec_osa(cfg.dev, cfg.stack_id, cfg.operation); + printf("Attempting %s operation...\n", valid_ops[cfg.operation]); + + ret = switchtec_osa(cfg.dev, cfg.stack_id, cfg.operation, + cfg.operation == 5 ? &status : NULL); if (ret) { switchtec_perror("osa"); return -1; } + + if (cfg.operation == 5) { + printf("Status of stack %d\n", cfg.stack_id); + printf("STATE: %s\n", states[status.state]); + printf("TRIGGER_LANE: %d\n", status.trigger_lane); + printf("TRIGGER_DIR: %s\n", directions[status.trigger_dir]); + printf("REASON_BITMASK: %d\n", status.trigger_reason); + } else { + printf("Successful %s operation!\n", valid_ops[cfg.operation]); + } + return 0; } @@ -2972,6 +2996,8 @@ static int osa_config_type(int argc, char **argv) switchtec_perror("osa_config_type"); return -1; } + + printf("OSA: Enabled type triggering config on stack %d\n", cfg.stack_id); return 0; } @@ -3117,6 +3143,8 @@ static int osa_config_pat(int argc, char **argv) switchtec_perror("osa_config_pat"); return -1; } + + printf("OSA: Enabled pattern triggering config on stack %d\n", cfg.stack_id); return 0; } @@ -3169,6 +3197,8 @@ static int osa_config_misc(int argc, char **argv) switchtec_perror("osa_config_misc"); return -1; } + + printf("OSA: Enabled misc triggering config on stack %d\n", cfg.stack_id); return 0; } @@ -3288,6 +3318,8 @@ static int osa_capture_control(int argc, char **argv) switchtec_perror("osa_capture_control"); return -1; } + + printf("OSA: Configuring capture control on stack %d\n", cfg.stack_id); return 0; } @@ -3296,6 +3328,9 @@ static int osa_capture_control(int argc, char **argv) static int osa_dump_config(int argc, char **argv) { int ret = 0; + struct switchtec_osa_config config; + char lane[5]; + int i; static struct { struct switchtec_dev *dev; int stack_id; @@ -3314,11 +3349,142 @@ static int osa_dump_config(int argc, char **argv) if (ret) return ret; - ret = switchtec_osa_dump_conf(cfg.dev, cfg.stack_id); + ret = switchtec_osa_dump_conf(cfg.dev, cfg.stack_id, &config); if (ret) { switchtec_perror("osa_dump_config"); return -1; } + + /* Print OSA configuration dump */ + printf("Config dump \n"); + printf("------- OS Type ------------------------\n"); + printf("lanes: \t\t\t%s", config.os_type_lane_mask & 1 ? "0," : ""); + for (i = 1; i < 16; i++) { + if (i == 15) + sprintf(lane, "%d", i); + else + sprintf(lane, "%d,", i); + printf("%s", (config.os_type_lane_mask >> i) & 1 ? lane : ""); + } + printf("\n"); + + printf("direciton: \t\t%s", config.os_type_direction & 1 ? "RX," : ""); + printf("%s\n", (config.os_type_direction >> 1) & 1 ? "TX" : ""); + + printf("link rate: \t\t%s", config.os_type_link_rate & 1 ? "GEN1," : ""); + printf("%s", (config.os_type_link_rate >> 1) & 1 ? "GEN2," : ""); + printf("%s", (config.os_type_link_rate >> 2) & 1 ? "GEN3," : ""); + printf("%s", (config.os_type_link_rate >> 3) & 1 ? "GEN4," : ""); + printf("%s\n", (config.os_type_link_rate >> 4) & 1 ? "GEN5" : ""); + if (switchtec_is_gen6(cfg.dev)) + printf("%s\n", (config.os_type_link_rate >> 5) & 1 ? "GEN6" : ""); + + printf("os types: \t\t"); + if (switchtec_is_gen6(cfg.dev)) { + printf("%s", config.os_type_os_types & 1 ? "TS0," : ""); + printf("%s", (config.os_type_os_types >> 1) & 1 ? "TS1," : ""); + printf("%s", (config.os_type_os_types >> 2) & 1 ? "TS2," : ""); + printf("%s\n", (config.os_type_os_types >> 3) & 1 ? "FTS" : ""); + printf("%s\n", (config.os_type_os_types >> 4) & 1 ? "CTL_SKP" : ""); + } else { + printf("%s", config.os_type_os_types & 1 ? "TS1," : ""); + printf("%s", (config.os_type_os_types >> 1) & 1 ? "TS2," : ""); + printf("%s", (config.os_type_os_types >> 2) & 1 ? "FTS," : ""); + printf("%s\n", (config.os_type_os_types >> 3) & 1 ? "CTL_SKP" : ""); + } + + printf("------- OS Pattern ---------------------\n"); + printf("lanes: \t\t\t%s", config.os_pat_lane_mask & 1 ? "0," : ""); + for (i = 1; i < 16; i++) { + if (i == 15) + sprintf(lane, "%d", i); + else + sprintf(lane, "%d,", i); + printf("%s", (config.os_pat_lane_mask >> i) & 1 ? lane : ""); + } + printf("\n"); + + printf("direciton: \t\t%s", config.os_pat_direction & 1 ? "RX," : ""); + printf("%s\n", (config.os_pat_direction >> 1) & 1 ? "TX" : ""); + + printf("link rate: \t\t%s", config.os_pat_link_rate && 1 ? "GEN1," : ""); + printf("%s", (config.os_pat_link_rate >> 1) & 1 ? "GEN2," : ""); + printf("%s", (config.os_pat_link_rate >> 2) & 1 ? "GEN3," : ""); + printf("%s", (config.os_pat_link_rate >> 3) & 1 ? "GEN4," : ""); + printf("%s\n", (config.os_pat_link_rate >> 4) & 1 ? "GEN5" : ""); + if (switchtec_is_gen6(cfg.dev)) + printf("%s\n", (config.os_type_link_rate >> 5) & 1 ? "GEN6" : ""); + + printf("patttern: \t\t0x%08x %08x %08x %08x\n", config.os_pat_value[0], + config.os_pat_value[1], config.os_pat_value[2], + config.os_pat_value[3]); + printf("mask: \t\t\t0x%08x %08x %08x %08x\n", config.os_pat_mask[0], + config.os_pat_mask[1], config.os_pat_mask[2], + config.os_pat_mask[3]); + + printf("------- Misc ---------------------------\n"); + if (config.misc_trig_enable == 2 || config.misc_trig_enable == 0) + printf("Misc trigger disabled"); + else + printf("Misc trigger enabled: \t"); + printf("%s", (config.misc_trig_enable - 2) & 1 ? "LTMON/other HW blk, " : ""); + printf("%s\n", ((config.misc_trig_enable - 2) >> 2) & 1 ? "General purpose input" : ""); + + printf("------- Capture ------------------------\n"); + printf("lanes: \t\t\t%s", config.capture_lane_mask & 1 ? "0," : ""); + for (i = 1; i < 16; i++) { + if (i == 15) + sprintf(lane, "%d", i); + else + sprintf(lane, "%d,", i); + printf("%s", (config.capture_lane_mask >> i) & 1 ? lane : ""); + } + printf("\n"); + + printf("direciton: \t\t%s", config.capture_direction & 1 ? "RX," : ""); + printf("%s\n", (config.capture_direction >> 1) & 1 ? "TX" : ""); + + if (switchtec_is_gen6(cfg.dev)) + printf("drop single os: \t%d: Single TS0, TS1, TS2, FTS and CTL_SKP OS's %s in the capture\n", + config.capture_drop_single_os, + config.capture_drop_single_os ? " excluded" : "included"); + else + printf("drop single os: \t%d: Single TS1, TS2, FTS and CTL_SKP OS's %s in the capture\n", + config.capture_drop_single_os, + config.capture_drop_single_os ? " excluded" : "included"); + + printf("stop mode: \t\t%d: OSA will stop capturing after %s lane has stopped writing into %s allocated RAMs\n", + config.capture_stop_mode, + config.capture_stop_mode ? "all" : "any", + config.capture_stop_mode ? "their" : "its"); + printf("snaphot mode: \t\t%d: OSes are captured %s\n", + config.capture_snapshot_mode, + config.capture_snapshot_mode ? "until the RAM is full" : "according to the Post-Trigger Entries value"); + printf("post-trigger entries: \t%d\n", config.capture_post_trig_entries); + + printf("os types: \t\t"); + if (switchtec_is_gen6(cfg.dev)) { + printf("%s", (config.capture_os_types & 1) ? "TS0," : ""); + printf("%s", (config.capture_os_types >> 1) & 1 ? "TS2," : ""); + printf("%s", (config.capture_os_types >> 2) & 1 ? "TS2," : ""); + printf("%s", (config.capture_os_types >> 3) & 1 ? "FTS," : ""); + printf("%s", (config.capture_os_types >> 4) & 1 ? "CTL_SKP," : ""); + printf("%s", (config.capture_os_types >> 5) & 1 ? "SKP," : ""); + printf("%s", (config.capture_os_types >> 6) & 1 ? "EIEOS," : ""); + printf("%s", (config.capture_os_types >> 7) & 1 ? "EIOS," : ""); + printf("%s", (config.capture_os_types >> 8) & 1 ? "ERR_OS," : ""); + } else { + printf("%s", (config.capture_os_types & 1) ? "TS1," : ""); + printf("%s", (config.capture_os_types >> 1) & 1 ? "TS2," : ""); + printf("%s", (config.capture_os_types >> 2) & 1 ? "FTS," : ""); + printf("%s", (config.capture_os_types >> 3) & 1 ? "CTL_SKP," : ""); + printf("%s", (config.capture_os_types >> 4) & 1 ? "SKP," : ""); + printf("%s", (config.capture_os_types >> 5) & 1 ? "EIEOS," : ""); + printf("%s", (config.capture_os_types >> 6) & 1 ? "EIOS," : ""); + printf("%s", (config.capture_os_types >> 7) & 1 ? "ERR_OS," : ""); + } + printf("\n"); + return 0; } @@ -3327,6 +3493,10 @@ static int osa_dump_config(int argc, char **argv) static int osa_dump_data(int argc, char **argv) { int ret = 0; + int i; + struct switchtec_osa_capture_data *data; + const char *link_rate_str[] = {"UNKNOWN", "Gen1", "Gen2", "Gen3", + "Gen4", "Gen5", "Gen6"}; static struct { struct switchtec_dev *dev; int stack_id; @@ -3354,12 +3524,40 @@ static int osa_dump_data(int argc, char **argv) return -1; } + /* Allocate data structure on heap - it's large (~50KB) */ + data = calloc(1, sizeof(*data)); + if (!data) { + fprintf(stderr, "Failed to allocate memory for OSA capture data\n"); + return -1; + } + ret = switchtec_osa_capture_data(cfg.dev, cfg.stack_id, cfg.lane, - cfg.direction); + cfg.direction, data); if (ret) { switchtec_perror("osa_dump_data"); + free(data); return -1; } + + /* Print captured data */ + printf("OSA: Captured Data:\n"); + printf("Entry\tTimestamp\tLink Rate\tCounter\t\tTrigger Indication\tOS Dropped?\tOSA Data\n"); + + for (i = 0; i < data->entry_count; i++) { + printf("%d\t", i); + printf("%ld\t\t", (long)data->entries[i].timestamp); + printf("%s\t\t", link_rate_str[data->entries[i].link_rate]); + printf("%d\t\t", data->entries[i].counter); + printf("%s\t\t", data->entries[i].trigger_indication ? "Pre-Trigger" : "Post-Trigger"); + printf("%s\t\t", data->entries[i].os_dropped ? "Yes" : "No"); + printf("0x%08x 0x%08x 0x%08x 0x%08x\n", + data->entries[i].osa_data[0], + data->entries[i].osa_data[1], + data->entries[i].osa_data[2], + data->entries[i].osa_data[3]); + } + + free(data); return 0; } diff --git a/inc/switchtec/switchtec.h b/inc/switchtec/switchtec.h index 89dbecf0..a6fecb55 100644 --- a/inc/switchtec/switchtec.h +++ b/inc/switchtec/switchtec.h @@ -1655,6 +1655,72 @@ struct switchtec_diag_ltssm_log { int rx_minor_state; }; +/** + * @brief OSA status query result + */ +struct switchtec_osa_status { + uint8_t state; + uint8_t trigger_lane; + uint8_t trigger_dir; + uint16_t trigger_reason; +}; + +/** + * @brief OSA configuration dump result + */ +struct switchtec_osa_config { + /* OS Type Trigger */ + uint16_t os_type_lane_mask; + uint8_t os_type_direction; + uint8_t os_type_link_rate; + uint8_t os_type_os_types; + + /* OS Pattern Trigger */ + uint16_t os_pat_lane_mask; + uint8_t os_pat_direction; + uint8_t os_pat_link_rate; + uint32_t os_pat_value[4]; + uint32_t os_pat_mask[4]; + + /* Misc Trigger */ + uint8_t misc_trig_enable; + + /* Capture Config */ + uint16_t capture_lane_mask; + uint8_t capture_direction; + uint8_t capture_drop_single_os; + uint8_t capture_stop_mode; + uint8_t capture_snapshot_mode; + uint16_t capture_post_trig_entries; + uint8_t capture_os_types; +}; + +/** + * @brief OSA capture data entry + */ +struct switchtec_osa_capture_entry { + uint64_t timestamp; + uint8_t link_rate; + uint32_t counter; + uint8_t trigger_indication; + uint8_t os_dropped; + uint32_t osa_data[4]; +}; + +/** + * @brief OSA capture data collection + */ +#define SWITCHTEC_OSA_MAX_ENTRIES 1024 +struct switchtec_osa_capture_data { + uint8_t stack_id; + uint8_t lane; + uint8_t direction; + uint16_t total_entries; + uint8_t wrap_occurred; + uint16_t entry_count; + struct switchtec_osa_capture_entry entries[SWITCHTEC_OSA_MAX_ENTRIES]; +}; + int switchtec_diag_cross_hair_enable(struct switchtec_dev *dev, int lane_id); int switchtec_diag_cross_hair_disable(struct switchtec_dev *dev); int switchtec_diag_cross_hair_get(struct switchtec_dev *dev, int start_lane_id, @@ -1729,7 +1795,8 @@ int switchtec_tlp_inject(struct switchtec_dev * dev, int port_id, int tlp_type, int tlp_length, int ecrc, uint32_t * raw_tlp_data); int switchtec_aer_event_gen(struct switchtec_dev *dev, int port_id, int aer_error_id, int trigger_event); -int switchtec_osa(struct switchtec_dev * dev, int stack_id, int operation); +int switchtec_osa(struct switchtec_dev * dev, int stack_id, int operation, + struct switchtec_osa_status *status); int switchtec_osa_config_type(struct switchtec_dev * dev, int stack_id, int direction, int lane_mask, int link_rate, int os_types); @@ -1740,12 +1807,14 @@ int switchtec_osa_capture_control(struct switchtec_dev * dev, int stack_id, int drop_single_os, int stop_mode, int snapshot_mode, int post_trigger, int os_types); -int switchtec_osa_dump_conf(struct switchtec_dev * dev, int stack_id); +int switchtec_osa_dump_conf(struct switchtec_dev * dev, int stack_id, + struct switchtec_osa_config *config); int switchtec_osa_config_pattern(struct switchtec_dev * dev, int stack_id, int direction, int lane_mask,int link_rate, uint32_t * value_data, uint32_t * mask_data); int switchtec_osa_capture_data(struct switchtec_dev * dev, int stack_id, - int lane, int direction); + int lane, int direction, + struct switchtec_osa_capture_data *data); #ifdef __cplusplus } #endif diff --git a/lib/diag.c b/lib/diag.c index c7090898..3dd4d61a 100644 --- a/lib/diag.c +++ b/lib/diag.c @@ -2174,7 +2174,8 @@ int switchtec_inject_err_cto(struct switchtec_dev *dev, int phys_port_id) } int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id, - int lane, int direction) + int lane, int direction, + struct switchtec_osa_capture_data *data) { int ret = 0; struct { @@ -2237,7 +2238,6 @@ int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id, switchtec_perror("OSA data dump"); return ret; } - printf("OSA: Captured Data:\n"); struct { uint8_t entries_read; @@ -2254,32 +2254,40 @@ int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id, osa_data_read_out.entries_remaining = osa_data_entries_out.entries_remaining; osa_data_read_out.next_entry = osa_data_entries_out.next_entry; + if (data) { + data->stack_id = stack_id; + data->lane = lane; + data->direction = direction; + data->total_entries = osa_data_entries_out.entries_remaining; + data->wrap_occurred = osa_data_entries_out.wrap; + data->entry_count = 0; + } + int total_dword = 0; int total_entries = 0; int curr_entry_dword = 0; - char osa_data[100] = ""; - char buffer[50] = ""; uint64_t timestamp; uint32_t timestamp_lower, timestamp_upper, counter; uint8_t link_rate, trigger, os_droppped; + uint32_t osa_data_dwords[4]; + int osa_data_idx = 0; - char *link_rate_str[5] = {"Gen1", "Gen2", "Gen3", "Gen4", "Gen5"}; - - printf("Entry\tTimestamp\tLink Rate\tCounter\t\tTrigger Indication\tOS Dropped?\tOSA Data\n"); while (osa_data_read_out.entries_remaining != 0) { + if (data && total_entries >= SWITCHTEC_OSA_MAX_ENTRIES) + break; + osa_data_read_in.num_entries = osa_data_read_out.entries_remaining; osa_data_read_in.start_entry = osa_data_read_out.next_entry; ret = switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_data_read_in, sizeof(osa_data_read_in), &osa_data_read_out, sizeof(osa_data_read_out)); - if (ret) { + if (ret) return -1; - } + for (int i = total_dword; i < total_dword + (osa_data_read_out.entries_read * 6); i++) { if (curr_entry_dword < 4) { - snprintf(buffer, sizeof(buffer), "0x%08x ", osa_data_read_out.entry_dwords[i]); - strncat(osa_data, buffer, sizeof(osa_data) - strlen(osa_data) - 1); + osa_data_dwords[osa_data_idx++] = osa_data_read_out.entry_dwords[i]; } else if (curr_entry_dword == 4) { timestamp_lower = (osa_data_read_out.entry_dwords[i] >> 22) & 0x3FF; timestamp_upper = (osa_data_read_out.entry_dwords[i+1] & 0x1A); @@ -2290,15 +2298,20 @@ int switchtec_osa_capture_data(struct switchtec_dev *dev, int stack_id, trigger = (osa_data_read_out.entry_dwords[i+1] >> 28) & 0x1; os_droppped = (osa_data_read_out.entry_dwords[i+1] >> 29) & 0x1; - printf("%d\t", total_entries); - printf("%ld\t\t", timestamp); - printf("%s\t\t", link_rate_str[link_rate]); - printf("%d\t\t", counter); - printf("%s\t\t", trigger ? "Pre-Trigger" : "Post-Trigger"); - printf("%s\t\t", os_droppped ? "Yes" : "No"); - printf("%s\n", osa_data); - osa_data[0] = '\0'; - buffer[0] = '\0'; + if (data && total_entries < SWITCHTEC_OSA_MAX_ENTRIES) { + data->entries[total_entries].timestamp = timestamp; + data->entries[total_entries].link_rate = link_rate; + data->entries[total_entries].counter = counter; + data->entries[total_entries].trigger_indication = trigger; + data->entries[total_entries].os_dropped = os_droppped; + data->entries[total_entries].osa_data[0] = osa_data_dwords[0]; + data->entries[total_entries].osa_data[1] = osa_data_dwords[1]; + data->entries[total_entries].osa_data[2] = osa_data_dwords[2]; + data->entries[total_entries].osa_data[3] = osa_data_dwords[3]; + data->entry_count++; + } + + osa_data_idx = 0; total_entries++; } curr_entry_dword++; @@ -2336,11 +2349,9 @@ int switchtec_osa_capture_control(struct switchtec_dev *dev, int stack_id, ret = switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_capture_ctrl_in, sizeof(osa_capture_ctrl_in), NULL, 0); - if (ret) { + if (ret) switchtec_perror("OSA capture control"); - return ret; - } - printf("OSA: Configuring capture control on stack %d\n", stack_id); + return ret; } @@ -2363,11 +2374,9 @@ int switchtec_osa_config_misc(struct switchtec_dev *dev, int stack_id, ret = switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_misc_config_in, sizeof(osa_misc_config_in), NULL, 0); - if (ret) { + if (ret) switchtec_perror("OSA misc config"); - return ret; - } - printf("OSA: Enabled misc triggering config on stack %d\n", stack_id); + return ret; } @@ -2395,11 +2404,9 @@ int switchtec_osa_config_pattern(struct switchtec_dev *dev, int stack_id, ret = switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_pattern_config_in, sizeof(osa_pattern_config_in), NULL, 0); - if (ret) { + if (ret) switchtec_perror("OSA pattern config"); - return ret; - } - printf("OSA: Enabled pattern triggering config on stack %d\n", stack_id); + return ret; } @@ -2421,15 +2428,14 @@ int switchtec_osa_config_type(struct switchtec_dev *dev, int stack_id, ret = switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_type_config_in, sizeof(osa_type_config_in), NULL, 0); - if (ret) { + if (ret) switchtec_perror("OSA type config"); - return ret; - } - printf("OSA: Enabled type triggering config on stack %d\n", stack_id); + return ret; } -int switchtec_osa_dump_conf(struct switchtec_dev *dev, int stack_id) +int switchtec_osa_dump_conf(struct switchtec_dev *dev, int stack_id, + struct switchtec_osa_config *config) { int ret = 0; @@ -2483,139 +2489,45 @@ int switchtec_osa_dump_conf(struct switchtec_dev *dev, int stack_id) switchtec_perror("OSA config dump"); return ret; } - printf("Config dump \n"); - printf("------- OS Type ------------------------\n"); - printf("lanes: \t\t\t%s", osa_dmp_out.os_type_trig_lane_mask & 1 ? "0," : ""); - char lane[5]; - for (int i = 1; i < 16; i++) { - if (i == 15) - sprintf(lane, "%d", i); - else - sprintf(lane, "%d,", i); - printf("%s", (osa_dmp_out.os_type_trig_lane_mask >> i) & 1 ? lane : ""); - } - printf("\n"); - printf("direciton: \t\t%s", osa_dmp_out.os_type_trig_dir & 1 ? "RX," : ""); - printf("%s\n", (osa_dmp_out.os_type_trig_dir >> 1) & 1 ? "TX" : ""); - - printf("link rate: \t\t%s", osa_dmp_out.os_type_trig_link_rate & 1 ? "GEN1," : ""); - printf("%s", (osa_dmp_out.os_type_trig_link_rate >> 1) & 1 ? "GEN2," : ""); - printf("%s", (osa_dmp_out.os_type_trig_link_rate >> 2) & 1 ? "GEN3," : ""); - printf("%s", (osa_dmp_out.os_type_trig_link_rate >> 3) & 1 ? "GEN4," : ""); - printf("%s\n", (osa_dmp_out.os_type_trig_link_rate >> 4) & 1 ? "GEN5" : ""); - if (switchtec_is_gen6(dev)) - printf("%s\n", (osa_dmp_out.os_type_trig_link_rate >> 5) & 1 ? "GEN6" : ""); - - printf("os types: \t\t"); - if (switchtec_is_gen6(dev)) { - printf("%s", osa_dmp_out.os_type_trig_os_types & 1 ? "TS0," : ""); - printf("%s", (osa_dmp_out.os_type_trig_os_types >> 1) & 1 ? "TS1," : ""); - printf("%s", (osa_dmp_out.os_type_trig_os_types >> 2) & 1 ? "TS2," : ""); - printf("%s\n", (osa_dmp_out.os_type_trig_os_types >> 3) & 1 ? "FTS" : ""); - printf("%s\n", (osa_dmp_out.os_type_trig_os_types >> 4) & 1 ? "CTL_SKP" : ""); - } else { - printf("%s", osa_dmp_out.os_type_trig_os_types & 1 ? "TS1," : ""); - printf("%s", (osa_dmp_out.os_type_trig_os_types >> 1) & 1 ? "TS2," : ""); - printf("%s", (osa_dmp_out.os_type_trig_os_types >> 2) & 1 ? "FTS," : ""); - printf("%s\n", (osa_dmp_out.os_type_trig_os_types >> 3) & 1 ? "CTL_SKP" : ""); - } - - printf("------- OS Pattern ---------------------\n"); - printf("lanes: \t\t\t%s", osa_dmp_out.os_pat_trig_lane_mask & 1 ? "0," : ""); - for (int i = 1; i < 16; i++) { - if (i == 15) - sprintf(lane, "%d", i); - else - sprintf(lane, "%d,", i); - printf("%s", (osa_dmp_out.os_pat_trig_lane_mask >> i) & 1 ? lane : ""); - } - printf("\n"); - - printf("direciton: \t\t%s", osa_dmp_out.os_pat_trig_dir & 1 ? "RX," : ""); - printf("%s\n", (osa_dmp_out.os_pat_trig_dir >> 1) & 1 ? "TX" : ""); - - printf("link rate: \t\t%s", osa_dmp_out.os_pat_trig_link_rate && 1 ? "GEN1," : ""); - printf("%s", (osa_dmp_out.os_pat_trig_link_rate >> 1) & 1 ? "GEN2," : ""); - printf("%s", (osa_dmp_out.os_pat_trig_link_rate >> 2) & 1 ? "GEN3," : ""); - printf("%s", (osa_dmp_out.os_pat_trig_link_rate >> 3) & 1 ? "GEN4," : ""); - printf("%s\n", (osa_dmp_out.os_pat_trig_link_rate >> 4) & 1 ? "GEN5" : ""); - if (switchtec_is_gen6(dev)) - printf("%s\n", (osa_dmp_out.os_type_trig_link_rate >> 5) & 1 ? "GEN6" : ""); - - printf("patttern: \t\t0x%08x %08x %08x %08x\n", osa_dmp_out.os_pat_trig_val_dw0, - osa_dmp_out.os_pat_trig_val_dw1, osa_dmp_out.os_pat_trig_val_dw2, - osa_dmp_out.os_pat_trig_val_dw3); - printf("mask: \t\t\t0x%08x %08x %08x %08x\n", osa_dmp_out.os_pat_trig_mask_dw0, - osa_dmp_out.os_pat_trig_mask_dw1, osa_dmp_out.os_pat_trig_mask_dw2, - osa_dmp_out.os_pat_trig_mask_dw3); - - printf("------- Misc ---------------------------\n"); - if (osa_dmp_out.misc_trig_en == 2 || osa_dmp_out.misc_trig_en == 0) - printf("Misc trigger disabled"); - else - printf("Misc trigger enabled: \t"); - printf("%s", (osa_dmp_out.misc_trig_en - 2) & 1 ? "LTMON/other HW blk, " : ""); - printf("%s\n", ((osa_dmp_out.misc_trig_en - 2) >> 2 ) & 1 ? "General purpose input" : ""); - - printf("------- Capture ------------------------\n"); - printf("lanes: \t\t\t%s", osa_dmp_out.capture_lane_mask & 1 ? "0," : ""); - for (int i = 1; i < 16; i++) { - if (i == 15) - sprintf(lane, "%d", i); - else - sprintf(lane, "%d,", i); - printf("%s", (osa_dmp_out.capture_lane_mask >> i) & 1 ? lane : ""); + if (config) { + /* OS Type Trigger */ + config->os_type_lane_mask = osa_dmp_out.os_type_trig_lane_mask; + config->os_type_direction = osa_dmp_out.os_type_trig_dir; + config->os_type_link_rate = osa_dmp_out.os_type_trig_link_rate; + config->os_type_os_types = osa_dmp_out.os_type_trig_os_types; + + /* OS Pattern Trigger */ + config->os_pat_lane_mask = osa_dmp_out.os_pat_trig_lane_mask; + config->os_pat_direction = osa_dmp_out.os_pat_trig_dir; + config->os_pat_link_rate = osa_dmp_out.os_pat_trig_link_rate; + config->os_pat_value[0] = osa_dmp_out.os_pat_trig_val_dw0; + config->os_pat_value[1] = osa_dmp_out.os_pat_trig_val_dw1; + config->os_pat_value[2] = osa_dmp_out.os_pat_trig_val_dw2; + config->os_pat_value[3] = osa_dmp_out.os_pat_trig_val_dw3; + config->os_pat_mask[0] = osa_dmp_out.os_pat_trig_mask_dw0; + config->os_pat_mask[1] = osa_dmp_out.os_pat_trig_mask_dw1; + config->os_pat_mask[2] = osa_dmp_out.os_pat_trig_mask_dw2; + config->os_pat_mask[3] = osa_dmp_out.os_pat_trig_mask_dw3; + + /* Misc Trigger */ + config->misc_trig_enable = osa_dmp_out.misc_trig_en; + + /* Capture Config */ + config->capture_lane_mask = osa_dmp_out.capture_lane_mask; + config->capture_direction = osa_dmp_out.capture_dir; + config->capture_drop_single_os = osa_dmp_out.capture_drop_os; + config->capture_stop_mode = osa_dmp_out.capture_stop_mode; + config->capture_snapshot_mode = osa_dmp_out.capture_snap_mode; + config->capture_post_trig_entries = osa_dmp_out.capture_post_trig_entries; + config->capture_os_types = osa_dmp_out.capture_os_types; } - printf("\n"); - - printf("direciton: \t\t%s", osa_dmp_out.capture_dir & 1 ? "RX," : ""); - printf("%s\n", (osa_dmp_out.capture_dir >> 1) & 1 ? "TX" : ""); - if (switchtec_is_gen6(dev)) - printf("drop single os: \t%d: Single TS0, TS1, TS2, FTS and CTL_SKP OS's %s in the capture\n", - osa_dmp_out.capture_drop_os, - osa_dmp_out.capture_drop_os ? " excluded" : "included"); - else - printf("drop single os: \t%d: Single TS1, TS2, FTS and CTL_SKP OS's %s in the capture\n", - osa_dmp_out.capture_drop_os, - osa_dmp_out.capture_drop_os ? " excluded" : "included"); - - printf("stop mode: \t\t%d: OSA will stop capturing after %s lane has stopped writing into %s allocated RAMs\n", - osa_dmp_out.capture_stop_mode, - osa_dmp_out.capture_stop_mode ? "all" : "any", - osa_dmp_out.capture_stop_mode ? "their" : "its"); - printf("snaphot mode: \t\t%d: OSes are captured %s\n", - osa_dmp_out.capture_snap_mode, - osa_dmp_out.capture_snap_mode ? "until the RAM is full" : "according to the Post-Trigger Entries value"); - printf("post-trigger entries: \t%d\n", osa_dmp_out.capture_post_trig_entries); - - printf("os types: \t\t"); - if (switchtec_is_gen6(dev)) { - printf("%s", (osa_dmp_out.capture_os_types & 1) ? "TS0," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 1) & 1 ? "TS2," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 2) & 1 ? "TS2," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 3) & 1 ? "FTS," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 4) & 1 ? "CTL_SKP," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 5) & 1 ? "SKP," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 6) & 1 ? "EIEOS," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 7) & 1 ? "EIOS," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 8) & 1 ? "ERR_OS," : ""); - } else { - printf("%s", (osa_dmp_out.capture_os_types & 1) ? "TS1," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 1) & 1 ? "TS2," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 2) & 1 ? "FTS," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 3) & 1 ? "CTL_SKP," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 4) & 1 ? "SKP," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 5) & 1 ? "EIEOS," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 6) & 1 ? "EIOS," : ""); - printf("%s", (osa_dmp_out.capture_os_types >> 7) & 1 ? "ERR_OS," : ""); - } - printf("\n"); return ret; } -int switchtec_osa(struct switchtec_dev *dev, int stack_id, int operation) +int switchtec_osa(struct switchtec_dev *dev, int stack_id, int operation, + struct switchtec_osa_status *status) { int ret = 0; struct { @@ -2646,13 +2558,6 @@ int switchtec_osa(struct switchtec_dev *dev, int stack_id, int operation) uint8_t reserved; } osa_op_in; - char *valid_ops[6] = {"stop", "start", "trigger", "reset", "release", - "status"}; - char *states[5] = {"Deactivated (not armed)", "Started (armed), not triggered", - "Started (armted), triggered", "Stopped, not triggered", - "Stopped, triggered"}; - char *directions[2] = {"TX", "RX"}; - printf("Attempting %s operation...\n", valid_ops[operation]); if (operation == 4) { osa_rel_access_perm_in.sub_cmd = MRPC_OSA_REL_ACCESS_PERM; osa_rel_access_perm_in.stack_id = stack_id; @@ -2674,11 +2579,13 @@ int switchtec_osa(struct switchtec_dev *dev, int stack_id, int operation) switchtec_perror("OSA operation"); return ret; } - printf("Status of stack %d\n", stack_id); - printf("STATE: %s\n", states[osa_status_query_out.state]); - printf("TRIGGER_LANE: %d\n", osa_status_query_out.trigger_lane); - printf("TRIGGER_DIR: %s\n", directions[osa_status_query_out.trigger_dir]); - printf("REASON_BITMASK: %d\n", osa_status_query_out.trigger_reason); + + if (status) { + status->state = osa_status_query_out.state; + status->trigger_lane = osa_status_query_out.trigger_lane; + status->trigger_dir = osa_status_query_out.trigger_dir; + status->trigger_reason = osa_status_query_out.trigger_reason; + } } else { osa_op_in.sub_cmd = MRPC_OSA_ANALYZER_OP; @@ -2688,11 +2595,9 @@ int switchtec_osa(struct switchtec_dev *dev, int stack_id, int operation) ret = switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_op_in, sizeof(osa_op_in), NULL, 0); } - if (ret) { + + if (ret) switchtec_perror("OSA operation"); - return ret; - } - printf("Successful %s operation!\n", valid_ops[operation]); return ret; }