30#define SWITCHTEC_LIB_CORE
31#define SWITCHTEC_LTSSM_MAX_LOGS 61
33#include "switchtec_priv.h"
35#include "switchtec/endian.h"
37#include "switchtec/utils.h"
56 .sub_cmd = MRPC_CROSS_HAIR_ENABLE,
58 .all_lanes = lane_id == SWITCHTEC_DIAG_CROSS_HAIR_ALL_LANES,
61 return switchtec_cmd(dev, MRPC_CROSS_HAIR, &in,
sizeof(in), NULL, 0);
73 .sub_cmd = MRPC_CROSS_HAIR_DISABLE,
76 return switchtec_cmd(dev, MRPC_CROSS_HAIR, &in,
sizeof(in), NULL, 0);
92 .sub_cmd = MRPC_CROSS_HAIR_GET,
93 .lane_id = start_lane_id,
94 .num_lanes = num_lanes,
99 ret =
switchtec_cmd(dev, MRPC_CROSS_HAIR, &in,
sizeof(in), &out,
104 for (i = 0; i < num_lanes; i++) {
105 memset(&res[i], 0,
sizeof(res[i]));
106 res[i].state = out[i].state;
107 res[i].lane_id = out[i].lane_id;
109 if (out[i].state <= SWITCHTEC_DIAG_CROSS_HAIR_WAITING) {
111 }
else if (out[i].state < SWITCHTEC_DIAG_CROSS_HAIR_DONE) {
112 res[i].x_pos = out[i].x_pos;
113 res[i].y_pos = out[i].y_pos;
114 }
else if (out[i].state == SWITCHTEC_DIAG_CROSS_HAIR_DONE) {
115 res[i].eye_left_lim = out[i].eye_left_lim;
116 res[i].eye_right_lim = out[i].eye_right_lim;
117 res[i].eye_bot_left_lim = out[i].eye_bot_left_lim;
118 res[i].eye_bot_right_lim = out[i].eye_bot_right_lim;
119 res[i].eye_top_left_lim = out[i].eye_top_left_lim;
120 res[i].eye_top_right_lim = out[i].eye_top_right_lim;
121 }
else if (out[i].state == SWITCHTEC_DIAG_CROSS_HAIR_ERROR) {
122 res[i].x_pos = out[i].x_pos;
123 res[i].y_pos = out[i].y_pos;
124 res[i].prev_state = out[i].prev_state;
131static int switchtec_diag_eye_status_gen5(
struct switchtec_dev *dev)
137 .sub_cmd = MRPC_EYE_CAP_STATUS_GEN5,
142 ret =
switchtec_cmd(dev, MRPC_GEN5_EYE_CAPTURE, &in,
sizeof(in),
148 eye_status = out.status;
150 }
while (eye_status == SWITCHTEC_GEN5_DIAG_EYE_STATUS_IN_PROGRESS ||
151 eye_status == SWITCHTEC_GEN5_DIAG_EYE_STATUS_PENDING);
153 switch (eye_status) {
154 case SWITCHTEC_GEN5_DIAG_EYE_STATUS_DONE:
156 case SWITCHTEC_GEN5_DIAG_EYE_STATUS_IDLE:
160 case SWITCHTEC_GEN5_DIAG_EYE_STATUS_TIMEOUT:
164 case SWITCHTEC_GEN5_DIAG_EYE_STATUS_ERROR:
174static int switchtec_diag_eye_status(
int status)
190static int switchtec_diag_eye_cmd_gen5(
struct switchtec_dev *dev,
void *in,
202 return switchtec_diag_eye_status_gen5(dev);
205static int switchtec_diag_eye_cmd_gen4(
struct switchtec_dev *dev,
void *in,
217 return switchtec_diag_eye_status(out.status);
228 enum switchtec_diag_eye_data_mode mode)
231 .sub_cmd = MRPC_EYE_OBSERVE_SET_DATA_MODE,
235 return switchtec_diag_eye_cmd_gen4(dev, &in,
sizeof(in));
249 int bin,
int *num_phases,
double *ber_data)
255 .sub_cmd = MRPC_EYE_CAP_READ_GEN6,
262 sizeof(in), &out,
sizeof(out));
266 *num_phases = out.num_phases;
268 for (i = 0; i < out.num_phases; i++)
269 ber_data[i] = (
double)le32toh(out.ndes_data[i]);
274 .sub_cmd = MRPC_EYE_CAP_READ_GEN5,
281 sizeof(in), &out,
sizeof(out));
285 *num_phases = out.num_phases;
287 for (i = 0; i < out.num_phases; i++)
288 ber_data[i] = le64toh(out.ber_data[i]) / 281474976710656.;
293 fprintf(stderr,
"Eye read not supported on Gen 4 switches.\n");
311 int step_interval,
int capture_depth,
int sar_sel,
312 int intleav_sel,
int hstep,
int data_mode,
313 int eye_mode, uint64_t refclk,
int vstep)
318 .sub_cmd = MRPC_EYE_CAP_RUN_GEN5,
319 .capture_depth = capture_depth,
320 .timeout_disable = 1,
321 .lane_mask[0] = lane_mask[0],
322 .lane_mask[1] = lane_mask[1],
323 .lane_mask[2] = lane_mask[2],
324 .lane_mask[3] = lane_mask[3],
327 ret = switchtec_diag_eye_cmd_gen5(dev, &in,
sizeof(in));
333 .sub_cmd = MRPC_EYE_CAP_RUN_GEN6,
334 .timeout_disable = 1,
335 .lane_mask[0] = lane_mask[0],
336 .lane_mask[1] = lane_mask[1],
337 .lane_mask[2] = lane_mask[2],
338 .lane_mask[3] = lane_mask[3],
340 .intleav_sel = intleav_sel,
343 .data_mode = data_mode,
344 .eye_mode = eye_mode,
345 .ref_timer_lwr = refclk & 0xFFFFFFFF,
346 .ref_timer_upp = refclk >> 32,
349 ret = switchtec_diag_eye_cmd_gen5(dev, &in,
sizeof(in));
355 .sub_cmd = MRPC_EYE_OBSERVE_START,
356 .lane_mask[0] = lane_mask[0],
357 .lane_mask[1] = lane_mask[1],
358 .lane_mask[2] = lane_mask[2],
359 .lane_mask[3] = lane_mask[3],
360 .x_start = x_range->start,
361 .y_start = y_range->start,
362 .x_end = x_range->end,
363 .y_end = y_range->end,
364 .x_step = x_range->step,
365 .y_step = y_range->step,
366 .step_interval = step_interval,
369 ret = switchtec_diag_eye_cmd_gen4(dev, &in,
sizeof(in));
379static uint64_t hi_lo_to_uint64(uint32_t lo, uint32_t hi)
404 size_t pixel_cnt,
int *lane_id)
407 .sub_cmd = MRPC_EYE_OBSERVE_FETCH,
410 uint64_t samples, errors;
411 int i, ret, data_count;
414 ret =
switchtec_cmd(dev, MRPC_EYE_OBSERVE, &in,
sizeof(in), &out,
419 if (out.status == 1) {
424 ret = switchtec_diag_eye_status(out.status);
428 for (i = 0; i < 4; i++) {
429 *lane_id = ffs(out.lane_mask[i]);
434 data_count = out.data_count_lo | ((int)out.data_count_hi << 8);
436 for (i = 0; i < data_count && i < pixel_cnt; i++) {
437 switch (out.data_mode) {
438 case SWITCHTEC_DIAG_EYE_RAW:
439 errors = hi_lo_to_uint64(out.raw[i].error_cnt_lo,
440 out.raw[i].error_cnt_hi);
441 samples = hi_lo_to_uint64(out.raw[i].sample_cnt_lo,
442 out.raw[i].sample_cnt_hi);
444 pixels[i] = (double)errors / samples;
448 case SWITCHTEC_DIAG_EYE_RATIO:
449 pixels[i] = le32toh(out.ratio[i].ratio) / 65536.;
468 .sub_cmd = MRPC_EYE_OBSERVE_CANCEL,
471 ret = switchtec_diag_eye_cmd_gen4(dev, &in,
sizeof(in));
481static int switchtec_diag_loopback_set_gen56(
struct switchtec_dev *dev,
482 int port_id,
int enable_parallel,
484 int enable_ltssm,
int enable_pipe,
485 enum switchtec_diag_ltssm_speed ltssm_speed)
488 .sub_cmd = MRPC_LOOPBACK_SET_INT_LOOPBACK,
493 .sub_cmd = MRPC_LOOPBACK_SET_LTSSM_LOOPBACK,
495 .enable = enable_ltssm,
496 .speed = ltssm_speed,
500 if (enable_ltssm && !(enable_external || enable_parallel)) {
502 sizeof(ltssm_in), NULL, 0);
506 int_in.type = DIAG_LOOPBACK_PARALEL_DATAPATH;
507 int_in.enable = enable_parallel;
509 sizeof(int_in), NULL, 0);
512 if (!enable_parallel) {
513 int_in.type = DIAG_LOOPBACK_EXTERNAL_DATAPATH;
514 int_in.enable = enable_external;
516 sizeof(int_in), NULL, 0);
520 int_in.type = DIAG_LOOPBACK_PIPE_DATAPATH;
521 int_in.enable = enable_pipe;
523 sizeof(int_in), NULL, 0);
527 ltssm_in.enable = enable_ltssm;
529 sizeof(ltssm_in), NULL, 0);
536static int switchtec_diag_loopback_set_gen4(
struct switchtec_dev *dev,
537 int port_id,
int enable,
538 enum switchtec_diag_ltssm_speed
542 .sub_cmd = MRPC_LOOPBACK_SET_INT_LOOPBACK,
547 .sub_cmd = MRPC_LOOPBACK_SET_LTSSM_LOOPBACK,
549 .enable = !!(enable & SWITCHTEC_DIAG_LOOPBACK_LTSSM),
550 .speed = ltssm_speed,
554 int_in.type = DIAG_LOOPBACK_RX_TO_TX;
555 int_in.enable = !!(enable & SWITCHTEC_DIAG_LOOPBACK_RX_TO_TX);
558 sizeof(int_in), NULL, 0);
562 int_in.type = DIAG_LOOPBACK_TX_TO_RX;
563 int_in.enable = !!(enable & SWITCHTEC_DIAG_LOOPBACK_TX_TO_RX);
566 sizeof(int_in), NULL, 0);
571 sizeof(ltssm_in), NULL, 0);
591 int enable,
int enable_parallel,
592 int enable_external,
int enable_ltssm,
594 enum switchtec_diag_ltssm_speed ltssm_speed)
598 ret = switchtec_diag_loopback_set_gen56(dev, port_id, enable_parallel,
599 enable_external, enable_ltssm,
600 enable_pipe, ltssm_speed);
605 ret = switchtec_diag_loopback_set_gen4(dev, port_id, enable,
624 int port_id,
int *enabled,
625 enum switchtec_diag_ltssm_speed *ltssm_speed)
628 .sub_cmd = MRPC_LOOPBACK_GET_INT_LOOPBACK,
632 .sub_cmd = MRPC_LOOPBACK_GET_LTSSM_LOOPBACK,
640 int_in.type = DIAG_LOOPBACK_PARALEL_DATAPATH;
642 int_in.type = DIAG_LOOPBACK_RX_TO_TX;
644 ret =
switchtec_cmd(dev, MRPC_INT_LOOPBACK, &int_in,
sizeof(int_in),
645 &int_out,
sizeof(int_out));
650 en |= SWITCHTEC_DIAG_LOOPBACK_RX_TO_TX;
653 int_in.type = DIAG_LOOPBACK_EXTERNAL_DATAPATH;
655 int_in.type = DIAG_LOOPBACK_TX_TO_RX;
657 ret =
switchtec_cmd(dev, MRPC_INT_LOOPBACK, &int_in,
sizeof(int_in),
658 &int_out,
sizeof(int_out));
663 en |= SWITCHTEC_DIAG_LOOPBACK_TX_TO_RX;
665 ret =
switchtec_cmd(dev, MRPC_INT_LOOPBACK, <_in,
sizeof(lt_in),
666 <_out,
sizeof(lt_out));
671 en |= SWITCHTEC_DIAG_LOOPBACK_LTSSM;
677 *ltssm_speed = lt_out.speed;
691 enum switchtec_diag_pattern type,
692 enum switchtec_diag_pattern_link_rate link_speed)
695 .sub_cmd = MRPC_PAT_GEN_SET_GEN,
697 .pattern_type = type,
698 .lane_id = link_speed
701 in.sub_cmd = MRPC_PAT_GEN_SET_GEN_GEN5;
703 in.sub_cmd = MRPC_PAT_GEN_SET_GEN_GEN6;
705 return switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), NULL, 0);
717 enum switchtec_diag_pattern *type)
720 .sub_cmd = MRPC_PAT_GEN_GET_GEN,
724 in.sub_cmd = MRPC_PAT_GEN_GET_GEN_GEN6;
728 ret =
switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), &out,
734 *type = out.pattern_type;
748 enum switchtec_diag_pattern type)
751 .sub_cmd = MRPC_PAT_GEN_SET_MON,
753 .pattern_type = type,
756 in.sub_cmd = MRPC_PAT_GEN_SET_MON_GEN6;
758 return switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), NULL, 0);
771 int lane_id,
enum switchtec_diag_pattern *type,
772 unsigned long long *err_cnt)
775 .sub_cmd = MRPC_PAT_GEN_GET_MON,
780 in.sub_cmd = MRPC_PAT_GEN_GET_MON_GEN6;
784 ret =
switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), &out,
790 *type = out.pattern_type;
793 *err_cnt = (htole32(out.err_cnt_lo) |
794 ((uint64_t)htole32(out.err_cnt_hi) << 32));
812 unsigned int err_cnt)
815 .sub_cmd = MRPC_PAT_GEN_INJ_ERR,
821 ret =
switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), NULL, 0);
839 int lane_id,
enum switchtec_diag_link link,
848 .sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_PREV,
859 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
860 ret =
switchtec_cmd(dev, MRPC_RCVR_OBJ_DUMP, &in,
sizeof(in),
862 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
864 sizeof(ext_in), &out,
sizeof(out));
873 res->port_id = out.port_id;
874 res->lane_id = out.lane_id;
875 res->ctle = out.ctle;
876 res->target_amplitude = out.target_amplitude;
877 res->speculative_dfe = out.speculative_dfe;
878 for (i = 0; i < ARRAY_SIZE(res->dynamic_dfe); i++)
879 res->dynamic_dfe[i] = out.dynamic_dfe[i];
894 int port_id,
int prev_speed,
895 enum switchtec_diag_end end,
896 enum switchtec_diag_link link,
906 uint32_t out_size = 0;
911 fprintf(stderr,
"Error inval output buffer\n");
917 if (end == SWITCHTEC_DIAG_LOCAL) {
920 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
924 fprintf(stderr,
"Error inval end option\n");
927 buf = (uint8_t *)malloc(buf_size);
929 fprintf(stderr,
"Error in buffer alloc\n");
935 in->op_type = DIAG_PORT_EQ_STATUS_OP_PER_PORT;
936 in->phys_port_id = port_id;
940 if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
942 in->prev_rate = prev_speed;
945 if (end == SWITCHTEC_DIAG_LOCAL) {
946 in->cmd = MRPC_GEN5_PORT_EQ_LOCAL_TX_COEFF_DUMP;
951 fprintf(stderr,
"Error in switchtec cmd:%d\n", ret);
954 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
955 in->cmd = MRPC_GEN5_PORT_EQ_FAR_END_TX_COEFF_DUMP;
960 fprintf(stderr,
"Error in switchtec cmd:%d\n", ret);
964 fprintf(stderr,
"Error inval end request\n");
969 if (end == SWITCHTEC_DIAG_LOCAL) {
970 res->lane_cnt = loc_out->lane_cnt + 1;
971 for (i = 0; i < res->lane_cnt; i++) {
972 res->cursors[i].pre = loc_out->cursors[i].pre;
973 res->cursors[i].post = loc_out->cursors[i].post;
976 res->lane_cnt = rem_out->lane_cnt + 1;
977 for (i = 0; i < res->lane_cnt; i++) {
978 res->cursors[i].pre = rem_out->cursors[i].pre;
979 res->cursors[i].post = rem_out->cursors[i].post;
1001 enum switchtec_diag_end end,
1002 enum switchtec_diag_link link,
1008 .op_type = DIAG_PORT_EQ_STATUS_OP_PER_PORT,
1012 .op_type = DIAG_PORT_EQ_STATUS_OP_PER_PORT,
1022 if (end == SWITCHTEC_DIAG_LOCAL) {
1023 in.sub_cmd = MRPC_PORT_EQ_LOCAL_TX_COEFF_DUMP;
1024 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_LOCAL_TX_COEFF_PREV;
1025 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
1026 in.sub_cmd = MRPC_PORT_EQ_FAR_END_TX_COEFF_DUMP;
1027 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_FAR_END_TX_COEFF_PREV;
1033 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1034 ret =
switchtec_cmd(dev, MRPC_PORT_EQ_STATUS, &in,
sizeof(in),
1036 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1038 sizeof(in_prev), &out,
sizeof(out));
1047 res->lane_cnt = out.lane_id + 1;
1048 for (i = 0; i < res->lane_cnt; i++) {
1049 res->cursors[i].pre = out.cursors[i].pre;
1050 res->cursors[i].post = out.cursors[i].post;
1056static int switchtec_gen6_diag_port_eq_tx_coeff(
struct switchtec_dev *dev,
1057 int port_id,
int prev_speed,
1058 enum switchtec_diag_end end,
1059 enum switchtec_diag_link link,
1069 uint32_t out_size = 0;
1079 if (end == SWITCHTEC_DIAG_LOCAL) {
1082 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
1090 buf = (uint8_t *)malloc(buf_size);
1097 in->op_type = DIAG_PORT_EQ_STATUS_OP_PER_PORT;
1098 in->phys_port_id = port_id;
1102 if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1104 in->prev_rate = prev_speed;
1107 if (end == SWITCHTEC_DIAG_LOCAL) {
1108 in->cmd = MRPC_GEN6_PORT_EQ_LOCAL_TX_COEFF_DUMP;
1115 in->cmd = MRPC_GEN6_PORT_EQ_FAR_END_TX_COEFF_DUMP;
1123 if (end == SWITCHTEC_DIAG_LOCAL) {
1124 res->lane_cnt = loc_out->lane_cnt + 1;
1125 for (i = 0; i < res->lane_cnt; i++) {
1126 res->cursors[i].pre = loc_out->cursors[i].pre;
1127 res->cursors[i].post = loc_out->cursors[i].post;
1130 res->lane_cnt = rem_out->lane_cnt + 1;
1131 for (i = 0; i < res->lane_cnt; i++) {
1132 res->cursors[i].pre = rem_out->cursors[i].pre;
1133 res->cursors[i].post = rem_out->cursors[i].post;
1152 int prev_speed,
enum switchtec_diag_end end,
1153 enum switchtec_diag_link link,
1159 ret = switchtec_gen6_diag_port_eq_tx_coeff(dev, port_id,
1184 int port_id,
int prev_speed,
1185 enum switchtec_diag_link link,
1191 .sub_cmd = MRPC_GEN5_PORT_EQ_FAR_END_TX_EQ_TABLE_DUMP,
1204 if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1206 in.prev_rate = prev_speed;
1215 res->lane_id = out.lane_id;
1216 res->step_cnt = out.step_cnt;
1218 for (i = 0; i < res->step_cnt; i++) {
1219 res->steps[i].pre_cursor = out.steps[i].pre_cursor;
1220 res->steps[i].post_cursor = out.steps[i].post_cursor;
1221 res->steps[i].fom = 0;
1222 res->steps[i].pre_cursor_up = 0;
1223 res->steps[i].post_cursor_up = 0;
1224 res->steps[i].error_status = out.steps[i].error_status;
1225 res->steps[i].active_status = out.steps[i].active_status;
1226 res->steps[i].speed = out.steps[i].speed;
1242 enum switchtec_diag_link link,
1248 .sub_cmd = MRPC_PORT_EQ_FAR_END_TX_EQ_TABLE_DUMP,
1252 .sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_EQ_TX_TABLE_PREV,
1262 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1263 ret =
switchtec_cmd(dev, MRPC_PORT_EQ_STATUS, &in,
sizeof(in),
1265 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1267 sizeof(in_prev), &out,
sizeof(out));
1276 res->lane_id = out.lane_id;
1277 res->step_cnt = out.step_cnt;
1278 for (i = 0; i < res->step_cnt; i++) {
1279 res->steps[i].pre_cursor = out.steps[i].pre_cursor;
1280 res->steps[i].post_cursor = out.steps[i].post_cursor;
1281 res->steps[i].fom = out.steps[i].fom;
1282 res->steps[i].pre_cursor_up = out.steps[i].pre_cursor_up;
1283 res->steps[i].post_cursor_up = out.steps[i].post_cursor_up;
1284 res->steps[i].error_status = out.steps[i].error_status;
1285 res->steps[i].active_status = out.steps[i].active_status;
1286 res->steps[i].speed = out.steps[i].speed;
1301 enum switchtec_diag_link link,
1334 int port_id,
int prev_speed,
1336 enum switchtec_diag_end end,
1337 enum switchtec_diag_link link,
1350 in.port_id = port_id;
1351 in.lane_id = lane_id;
1354 if (end == SWITCHTEC_DIAG_LOCAL) {
1355 in.sub_cmd = MRPC_GEN5_PORT_EQ_LOCAL_TX_FSLF_DUMP;
1356 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
1357 in.sub_cmd = MRPC_GEN5_PORT_EQ_FAR_END_TX_FSLF_DUMP;
1363 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1367 in.prev_rate = prev_speed;
1393 int port_id,
int lane_id,
1394 enum switchtec_diag_end end,
1395 enum switchtec_diag_link link,
1415 if (end == SWITCHTEC_DIAG_LOCAL) {
1416 in.sub_cmd = MRPC_PORT_EQ_LOCAL_TX_FSLF_DUMP;
1417 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_LOCAL_TX_FSLF_PREV;
1418 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
1419 in.sub_cmd = MRPC_PORT_EQ_FAR_END_TX_FSLF_DUMP;
1420 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_FAR_END_TX_FSLF_PREV;
1426 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1427 ret =
switchtec_cmd(dev, MRPC_PORT_EQ_STATUS, &in,
sizeof(in),
1429 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1431 sizeof(in_prev), &out,
sizeof(out));
1446static int switchtec_gen6_diag_port_eq_tx_fslf(
struct switchtec_dev *dev,
1447 int port_id,
int prev_speed,
1449 enum switchtec_diag_end end,
1450 enum switchtec_diag_link link,
1463 in.port_id = port_id;
1464 in.lane_id = lane_id;
1466 if (end == SWITCHTEC_DIAG_LOCAL) {
1467 in.sub_cmd = MRPC_GEN6_PORT_EQ_LOCAL_TX_FSLF_DUMP;
1468 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
1469 in.sub_cmd = MRPC_GEN6_PORT_EQ_FAR_END_TX_FSLF_DUMP;
1475 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1479 in.prev_rate = prev_speed;
1505 int prev_speed,
int lane_id,
1506 enum switchtec_diag_end end,
1507 enum switchtec_diag_link link,
1513 ret = switchtec_gen6_diag_port_eq_tx_fslf(dev, port_id,
1514 prev_speed, lane_id,
1518 prev_speed, lane_id,
1541 int lane_id,
enum switchtec_diag_link link,
1556 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1557 in.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_RCVR_EXT;
1558 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1559 in.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_RCVR_EXT_PREV;
1565 ret =
switchtec_cmd(dev, MRPC_EXT_RCVR_OBJ_DUMP, &in,
sizeof(in),
1570 res->ctle2_rx_mode = out.ctle2_rx_mode;
1571 res->dtclk_9 = out.dtclk_9;
1572 res->dtclk_8_6 = out.dtclk_8_6;
1573 res->dtclk_5 = out.dtclk_5;
1588 uint32_t perms[(MRPC_MAX_ID + 31) / 32];
1592 perms,
sizeof(perms));
1596 for (i = 0; i < MRPC_MAX_ID; i++) {
1597 if (perms[i >> 5] & (1 << (i & 0x1f))) {
1598 if (switchtec_mrpc_table[i].tag) {
1599 table[i] = switchtec_mrpc_table[i];
1601 table[i].tag =
"UNKNOWN";
1602 table[i].desc =
"Unknown MRPC Command";
1603 table[i].reserved =
true;
1606 table[i].tag = NULL;
1607 table[i].desc = NULL;
1626 .sub_cmd = en ? MRPC_REFCLK_S_ENABLE_GEN6 :
1627 MRPC_REFCLK_S_DISABLE_GEN6,
1635 .sub_cmd = en ? MRPC_REFCLK_S_ENABLE :
1636 MRPC_REFCLK_S_DISABLE,
1655 .sub_cmd = MRPC_REFCLK_S_STATUS_GEN6,
1660 sizeof(uint8_t) * SWITCHTEC_MAX_STACKS_GEN6);
1663 .sub_cmd = MRPC_REFCLK_S_STATUS,
1668 sizeof(uint8_t) * SWITCHTEC_MAX_STACKS);
1676 int curr_idx, uint16_t num_of_logs)
1685 for (
int j = 0; j < num_of_logs; j++) {
1686 dw0 = log_dump_out_ptr[j].dw0;
1687 timestamp = log_dump_out_ptr[j].ram_timestamp;
1689 rate = (dw0 >> 13) & 0x7;
1690 major = (dw0 >> 7) & 0x3f;
1691 minor = (dw0 >> 3) & 0xf;
1693 log_data[curr_idx + j].timestamp = timestamp;
1695 log_data[curr_idx + j].link_state = major | (minor << 8);
1703 int curr_idx, uint16_t num_of_logs)
1712 for (
int j = 0; j < num_of_logs; j++) {
1713 dw0 = log_dump_out_ptr[j].dw0;
1714 timestamp = log_dump_out_ptr[j].ram_timestamp;
1716 link_width = (dw0 >> 16) & 0x3f;
1717 rate = (dw0 >> 12) & 0x7;
1718 major = (dw0 >> 6) & 0x3f;
1720 log_data[curr_idx + j].timestamp = timestamp;
1722 log_data[curr_idx + j].link_state = major;
1723 log_data[curr_idx + j].link_width = link_width;
1735 int port,
int *log_count,
1752 uint16_t w0_trigger_count;
1753 uint16_t w1_trigger_count;
1760 uint16_t no_of_logs;
1763 uint8_t log_buffer[1024];
1771 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1772 ltssm_freeze.port = port;
1773 ltssm_freeze.freeze = 1;
1775 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1776 sizeof(ltssm_freeze), NULL, 0);
1781 status.sub_cmd = MRPC_LTMON_GET_STATUS_GEN5;
1784 sizeof(status), &status_output,
1785 sizeof(status_output));
1789 *log_count = status_output.log_count;
1792 log_dump.sub_cmd = MRPC_LTMON_LOG_DUMP_GEN5;
1793 log_dump.port = port;
1794 log_dump.log_index = 0;
1795 log_dump.no_of_logs = *log_count;
1797 if (log_dump.no_of_logs <= SWITCHTEC_LTSSM_MAX_LOGS) {
1799 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1800 sizeof(log_dump), &log_buffer[0],
1801 log_dump.no_of_logs * log_dmp_size + 4);
1808 switchtec_diag_ltssm_set_log_data_gen5(log_data,
1810 0, log_dump.no_of_logs);
1813 int buff_count = log_dump.no_of_logs / SWITCHTEC_LTSSM_MAX_LOGS;
1815 int buffer_size = SWITCHTEC_LTSSM_MAX_LOGS * log_dmp_size + 4;
1817 for (
int i = 0; i < buff_count; i++) {
1818 log_dump.no_of_logs = SWITCHTEC_LTSSM_MAX_LOGS;
1820 &log_dump,
sizeof(log_dump),
1821 &log_buffer[0], buffer_size);
1828 switchtec_diag_ltssm_set_log_data_gen5(log_data,
1831 log_dump.no_of_logs);
1832 curr_idx += SWITCHTEC_LTSSM_MAX_LOGS;
1833 log_dump.log_index = curr_idx;
1835 if (*log_count % SWITCHTEC_LTSSM_MAX_LOGS) {
1836 log_dump.no_of_logs = *log_count - curr_idx;
1837 buffer_size = log_dump.no_of_logs * log_dmp_size + 4;
1839 &log_dump,
sizeof(log_dump),
1840 &log_buffer[0], buffer_size);
1847 switchtec_diag_ltssm_set_log_data_gen5(log_data,
1850 log_dump.no_of_logs);
1855 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1856 ltssm_freeze.port = port;
1857 ltssm_freeze.freeze = 0;
1859 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1860 sizeof(ltssm_freeze), NULL, 0);
1873 int port,
int *log_count,
1890 uint16_t w0_trigger_count;
1891 uint16_t w1_trigger_count;
1898 uint16_t no_of_logs;
1901 uint8_t log_buffer[1024];
1909 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1910 ltssm_freeze.port = port;
1911 ltssm_freeze.freeze = 1;
1913 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1914 sizeof(ltssm_freeze), NULL, 0);
1919 status.sub_cmd = MRPC_LTMON_GET_STATUS_GEN5;
1922 sizeof(status), &status_output,
1923 sizeof(status_output));
1927 *log_count = status_output.log_count;
1930 log_dump.sub_cmd = MRPC_LTMON_LOG_DUMP_GEN5;
1931 log_dump.port = port;
1932 log_dump.log_index = 0;
1933 log_dump.no_of_logs = *log_count;
1935 if (log_dump.no_of_logs <= SWITCHTEC_LTSSM_MAX_LOGS) {
1937 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1938 sizeof(log_dump), &log_buffer[0],
1939 log_dump.no_of_logs * log_dmp_size + 4);
1946 switchtec_diag_ltssm_set_log_data_gen6(log_data,
1948 0, log_dump.no_of_logs);
1951 int buff_count = log_dump.no_of_logs / SWITCHTEC_LTSSM_MAX_LOGS;
1953 int buffer_size = SWITCHTEC_LTSSM_MAX_LOGS * log_dmp_size + 4;
1955 for (
int i = 0; i < buff_count; i++) {
1956 log_dump.no_of_logs = SWITCHTEC_LTSSM_MAX_LOGS;
1958 &log_dump,
sizeof(log_dump),
1959 &log_buffer[0], buffer_size);
1966 switchtec_diag_ltssm_set_log_data_gen6(log_data,
1969 log_dump.no_of_logs);
1970 curr_idx += SWITCHTEC_LTSSM_MAX_LOGS;
1971 log_dump.log_index = curr_idx;
1973 if (*log_count % SWITCHTEC_LTSSM_MAX_LOGS) {
1974 log_dump.no_of_logs = *log_count - curr_idx;
1975 buffer_size = log_dump.no_of_logs * log_dmp_size + 4;
1977 &log_dump,
sizeof(log_dump),
1978 &log_buffer[0], buffer_size);
1985 switchtec_diag_ltssm_set_log_data_gen6(log_data,
1988 log_dump.no_of_logs);
1993 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1994 ltssm_freeze.port = port;
1995 ltssm_freeze.freeze = 0;
1997 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1998 sizeof(ltssm_freeze), NULL, 0);
2011 int port,
int *log_count,
2026 uint32_t w0_trigger_count;
2027 uint32_t w1_trigger_count;
2040 } log_dump_out[256];
2051 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
2052 ltssm_freeze.port = port;
2053 ltssm_freeze.freeze = 1;
2055 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
2056 sizeof(ltssm_freeze), NULL, 0);
2061 status.sub_cmd = MRPC_LTMON_GET_STATUS_GEN4;
2064 sizeof(status), &status_output,
2065 sizeof(status_output));
2069 if (status_output.log_num < *log_count)
2070 *log_count = status_output.log_num;
2073 log_dump.sub_cmd = MRPC_LTMON_LOG_DUMP_GEN4;
2074 log_dump.port = port;
2075 log_dump.log_index = 0;
2076 log_dump.no_of_logs = *log_count;
2077 if (log_dump.no_of_logs <= 126) {
2078 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
2079 sizeof(log_dump), log_dump_out,
2080 8 * log_dump.no_of_logs);
2084 log_dump.no_of_logs = 126;
2085 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
2086 sizeof(log_dump), log_dump_out,
2087 8 * log_dump.no_of_logs);
2091 log_dump.log_index = 126;
2092 log_dump.no_of_logs = *log_count - 126;
2094 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
2095 sizeof(log_dump), log_dump_out + 126,
2096 8 * log_dump.no_of_logs);
2100 for (i = 0; i < *log_count; i++) {
2101 dw1 = log_dump_out[i].dw1;
2102 dw0 = log_dump_out[i].dw0;
2103 rate = (dw0 >> 13) & 0x3;
2104 major = (dw0 >> 7) & 0xf;
2105 minor = (dw0 >> 3) & 0xf;
2107 log_data[i].timestamp = dw1 & 0x3ffffff;
2109 log_data[i].link_state = major | (minor << 8);
2113 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
2114 ltssm_freeze.port = port;
2115 ltssm_freeze.freeze = 0;
2117 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
2118 sizeof(ltssm_freeze), NULL, 0);
2131 int port,
int *log_count,
2158 ltssm_clear.subcmd = MRPC_LTMON_CLEAR_LOG;
2159 ltssm_clear.port_id = port;
2161 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_clear,
2162 sizeof(ltssm_clear), NULL, 0);
2166int switchtec_tlp_inject(
struct switchtec_dev *dev,
int port_id,
int tlp_type,
2167 int tlp_length,
int ecrc, uint32_t *raw_tlp_data)
2172 .dest_port = port_id,
2173 .tlp_type = tlp_type,
2174 .tlp_length = tlp_length,
2177 for (
int i = 0; i < tlp_in.tlp_length; i++) {
2178 tlp_in.raw_tlp_data[i] = htole32(*(raw_tlp_data + i));
2182 ret =
switchtec_cmd(dev, MRPC_DIAG_TLP_INJECT, &tlp_in,
sizeof(tlp_in),
2183 &tlp_out,
sizeof(tlp_out));
2195 int aer_error_id,
int trigger_event)
2201 .sub_cmd = trigger_event,
2202 .phys_port_id = port_id,
2203 .err_mask = aer_error_id,
2211 sizeof(sub_cmd_id), &output,
sizeof(output));
2228 .subcmd = MRPC_ERR_INJ_DLLP,
2229 .phys_port_id = phys_port_id,
2234 sizeof(cmd), &output,
sizeof(output));
2246 int phys_port_id,
int enable,
2252 .subcmd = MRPC_ERR_INJ_DLLP_CRC,
2253 .phys_port_id = phys_port_id,
2259 sizeof(cmd), &output,
sizeof(output));
2262static int switchtec_inject_err_tlp_lcrc_gen4(
struct switchtec_dev *dev,
2263 int phys_port_id,
int enable,
2269 .subcmd = MRPC_ERR_INJ_TLP_LCRC,
2270 .phys_port_id = phys_port_id,
2275 sizeof(cmd), &output,
sizeof(output));
2278static int switchtec_inject_err_tlp_lcrc_gen5(
struct switchtec_dev *dev,
2279 int phys_port_id,
int enable,
2285 .subcmd = MRPC_ERR_INJ_TLP_LCRC,
2286 .phys_port_id = phys_port_id,
2292 sizeof(cmd), &output,
sizeof(output));
2303 int enable, uint8_t rate)
2307 ret = switchtec_inject_err_tlp_lcrc_gen4(dev, phy_port, enable, rate);
2310 ret = switchtec_inject_err_tlp_lcrc_gen5(dev, phy_port, enable, rate);
2313 fprintf(stderr,
"TLP LCRC error injection is not supported on this device.\n");
2328 .subcmd = MRPC_ERR_INJ_TLP_SEQ,
2329 .phys_port_id = phys_port_id,
2333 sizeof(cmd), &output,
sizeof(output));
2345 uint16_t seq_num, uint8_t count)
2350 .subcmd = MRPC_ERR_INJ_ACK_NACK,
2351 .phys_port_id = phys_port_id,
2357 sizeof(cmd), &output,
sizeof(output));
2371 .subcmd = MRPC_ERR_INJ_CTO,
2372 .phys_port_id = phys_port_id,
2376 sizeof(cmd), &output,
sizeof(output));
2380 int lane,
int direction,
2389 uint16_t start_entry;
2390 uint8_t num_entries;
2395 uint8_t entries_read;
2399 uint16_t next_entry;
2400 uint16_t entries_remaining;
2403 } osa_data_entries_out;
2405 osa_data_read_in.sub_cmd = MRPC_OSA_DATA_READ;
2406 osa_data_read_in.stack_id = stack_id;
2407 osa_data_read_in.lane = lane;
2408 osa_data_read_in.direction = direction;
2410 osa_data_read_in.start_entry = 0;
2411 osa_data_read_in.num_entries = 0;
2417 } osa_status_query_in;
2421 uint8_t trigger_lane;
2422 uint8_t trigger_dir;
2424 uint16_t trigger_reason;
2426 } osa_status_query_out;
2428 osa_status_query_in.sub_cmd = MRPC_OSA_STATUS_QUERY;
2430 osa_status_query_in.sub_cmd = MRPC_OSA_STATUS_QUERY_GEN6;
2431 osa_status_query_in.stack_id = stack_id;
2433 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_status_query_in,
2434 sizeof(osa_status_query_in), &osa_status_query_out,
2435 sizeof(osa_status_query_out));
2437 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_data_read_in,
2438 sizeof(osa_data_read_in), &osa_data_entries_out,
2439 sizeof(osa_data_entries_out));
2446 uint8_t entries_read;
2450 uint16_t next_entry;
2451 uint16_t entries_remaining;
2454 uint32_t entry_dwords[osa_data_entries_out.entries_remaining * 6];
2455 } osa_data_read_out;
2457 osa_data_read_out.entries_remaining = osa_data_entries_out.entries_remaining;
2458 osa_data_read_out.next_entry = osa_data_entries_out.next_entry;
2461 data->stack_id = stack_id;
2463 data->direction = direction;
2464 data->total_entries = osa_data_entries_out.entries_remaining;
2465 data->wrap_occurred = osa_data_entries_out.wrap;
2466 data->entry_count = 0;
2469 int total_dword = 0;
2470 int total_entries = 0;
2471 int curr_entry_dword = 0;
2473 uint32_t timestamp_lower, timestamp_upper, counter;
2474 uint8_t link_rate, trigger, os_droppped;
2475 uint32_t osa_data_dwords[4];
2476 int osa_data_idx = 0;
2478 while (osa_data_read_out.entries_remaining != 0) {
2482 osa_data_read_in.num_entries = osa_data_read_out.entries_remaining;
2483 osa_data_read_in.start_entry = osa_data_read_out.next_entry;
2486 &osa_data_read_in,
sizeof(osa_data_read_in),
2487 &osa_data_read_out,
sizeof(osa_data_read_out));
2491 for (
int i = total_dword; i < total_dword + (osa_data_read_out.entries_read * 6); i++) {
2492 if (curr_entry_dword < 4) {
2493 osa_data_dwords[osa_data_idx++] = osa_data_read_out.entry_dwords[i];
2494 }
else if (curr_entry_dword == 4) {
2495 timestamp_lower = (osa_data_read_out.entry_dwords[i] >> 22) & 0x3FF;
2496 timestamp_upper = (osa_data_read_out.entry_dwords[i+1] & 0x1A);
2497 timestamp = timestamp_upper | timestamp_lower;
2499 link_rate = osa_data_read_out.entry_dwords[i] & 0x3;
2500 counter = (osa_data_read_out.entry_dwords[i] >> 3) & 0x12;
2501 trigger = (osa_data_read_out.entry_dwords[i+1] >> 28) & 0x1;
2502 os_droppped = (osa_data_read_out.entry_dwords[i+1] >> 29) & 0x1;
2505 data->entries[total_entries].timestamp = timestamp;
2506 data->entries[total_entries].link_rate = link_rate;
2507 data->entries[total_entries].counter = counter;
2508 data->entries[total_entries].trigger_indication = trigger;
2509 data->entries[total_entries].os_dropped = os_droppped;
2510 data->entries[total_entries].osa_data[0] = osa_data_dwords[0];
2511 data->entries[total_entries].osa_data[1] = osa_data_dwords[1];
2512 data->entries[total_entries].osa_data[2] = osa_data_dwords[2];
2513 data->entries[total_entries].osa_data[3] = osa_data_dwords[3];
2514 data->entry_count++;
2521 if (i != 0 && i % 5 == 0) {
2522 curr_entry_dword = 0;
2525 total_dword += osa_data_read_out.entries_read;
2531int switchtec_osa_capture_control(
struct switchtec_dev *dev,
int stack_id,
2532 int lane_mask,
int direction,
2533 int drop_single_os,
int stop_mode,
2534 int snapshot_mode,
int post_trigger,
2561int switchtec_osa_config_misc(
struct switchtec_dev *dev,
int stack_id,
2572 } osa_misc_config_in;
2574 osa_misc_config_in.sub_cmd = MRPC_OSA_MISC_TRIG_CONFIG;
2575 osa_misc_config_in.stack_id = stack_id;
2576 osa_misc_config_in.trigger_en = trigger_en;
2578 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_misc_config_in,
2579 sizeof(osa_misc_config_in), NULL, 0);
2586int switchtec_osa_config_pattern(
struct switchtec_dev *dev,
int stack_id,
2587 int direction,
int lane_mask,
int link_rate,
2588 uint32_t *value_data, uint32_t *mask_data)
2616int switchtec_osa_config_type(
struct switchtec_dev *dev,
int stack_id,
2617 int direction,
int lane_mask,
int link_rate,
int os_types)
2640int switchtec_osa_dump_conf(
struct switchtec_dev *dev,
int stack_id,
2652 int16_t os_type_trig_lane_mask;
2653 uint8_t os_type_trig_dir;
2654 uint8_t os_type_trig_link_rate;
2655 uint16_t os_type_trig_os_types;
2657 uint16_t os_pat_trig_lane_mask;
2658 uint8_t os_pat_trig_dir;
2659 uint8_t os_pat_trig_link_rate;
2660 uint32_t os_pat_trig_val_dw0;
2661 uint32_t os_pat_trig_val_dw1;
2662 uint32_t os_pat_trig_val_dw2;
2663 uint32_t os_pat_trig_val_dw3;
2664 uint32_t os_pat_trig_mask_dw0;
2665 uint32_t os_pat_trig_mask_dw1;
2666 uint32_t os_pat_trig_mask_dw2;
2667 uint32_t os_pat_trig_mask_dw3;
2668 uint8_t misc_trig_en;
2671 uint16_t capture_lane_mask;
2672 uint8_t capture_dir;
2673 uint8_t capture_drop_os;
2674 uint8_t capture_stop_mode;
2675 uint8_t capture_snap_mode;
2676 uint16_t capture_post_trig_entries;
2677 uint16_t capture_os_types;
2681 osa_dmp_in.stack_id = stack_id;
2682 osa_dmp_in.sub_cmd = MRPC_OSA_CONFIG_DMP;
2684 osa_dmp_in.sub_cmd = MRPC_OSA_CONFIG_DMP_GEN6;
2686 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_dmp_in,
2687 sizeof(osa_dmp_in), &osa_dmp_out,
2688 sizeof(osa_dmp_out));
2696 config->os_type_lane_mask = osa_dmp_out.os_type_trig_lane_mask;
2697 config->os_type_direction = osa_dmp_out.os_type_trig_dir;
2698 config->os_type_link_rate = osa_dmp_out.os_type_trig_link_rate;
2699 config->os_type_os_types = osa_dmp_out.os_type_trig_os_types;
2702 config->os_pat_lane_mask = osa_dmp_out.os_pat_trig_lane_mask;
2703 config->os_pat_direction = osa_dmp_out.os_pat_trig_dir;
2704 config->os_pat_link_rate = osa_dmp_out.os_pat_trig_link_rate;
2705 config->os_pat_value[0] = osa_dmp_out.os_pat_trig_val_dw0;
2706 config->os_pat_value[1] = osa_dmp_out.os_pat_trig_val_dw1;
2707 config->os_pat_value[2] = osa_dmp_out.os_pat_trig_val_dw2;
2708 config->os_pat_value[3] = osa_dmp_out.os_pat_trig_val_dw3;
2709 config->os_pat_mask[0] = osa_dmp_out.os_pat_trig_mask_dw0;
2710 config->os_pat_mask[1] = osa_dmp_out.os_pat_trig_mask_dw1;
2711 config->os_pat_mask[2] = osa_dmp_out.os_pat_trig_mask_dw2;
2712 config->os_pat_mask[3] = osa_dmp_out.os_pat_trig_mask_dw3;
2715 config->misc_trig_enable = osa_dmp_out.misc_trig_en;
2718 config->capture_lane_mask = osa_dmp_out.capture_lane_mask;
2719 config->capture_direction = osa_dmp_out.capture_dir;
2720 config->capture_drop_single_os = osa_dmp_out.capture_drop_os;
2721 config->capture_stop_mode = osa_dmp_out.capture_stop_mode;
2722 config->capture_snapshot_mode = osa_dmp_out.capture_snap_mode;
2723 config->capture_post_trig_entries = osa_dmp_out.capture_post_trig_entries;
2724 config->capture_os_types = osa_dmp_out.capture_os_types;
2730int switchtec_osa(
struct switchtec_dev *dev,
int stack_id,
int operation,
2738 } osa_rel_access_perm_in;
2744 } osa_status_query_in;
2748 uint8_t trigger_lane;
2749 uint8_t trigger_dir;
2751 uint16_t trigger_reason;
2753 } osa_status_query_out;
2762 if (operation == 4) {
2763 osa_rel_access_perm_in.sub_cmd = MRPC_OSA_REL_ACCESS_PERM;
2764 osa_rel_access_perm_in.stack_id = stack_id;
2767 &osa_rel_access_perm_in,
2768 sizeof(osa_rel_access_perm_in), NULL, 0);
2770 else if (operation == 5) {
2771 osa_status_query_in.sub_cmd = MRPC_OSA_STATUS_QUERY;
2773 osa_status_query_in.sub_cmd = MRPC_OSA_STATUS_QUERY_GEN6;
2774 osa_status_query_in.stack_id = stack_id;
2777 &osa_status_query_in,
sizeof(osa_status_query_in),
2778 &osa_status_query_out,
sizeof(osa_status_query_out));
2785 status->state = osa_status_query_out.state;
2786 status->trigger_lane = osa_status_query_out.trigger_lane;
2787 status->trigger_dir = osa_status_query_out.trigger_dir;
2788 status->trigger_reason = osa_status_query_out.trigger_reason;
2792 osa_op_in.sub_cmd = MRPC_OSA_ANALYZER_OP;
2793 osa_op_in.stack_id = stack_id;
2794 osa_op_in.operation = operation;
2796 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_op_in,
2797 sizeof(osa_op_in), NULL, 0);
int switchtec_diag_rcvr_ext(struct switchtec_dev *dev, int port_id, int lane_id, enum switchtec_diag_link link, struct switchtec_rcvr_ext *res)
Get the Extended Receiver Object.
static int switchtec_gen5_diag_port_eq_tx_table(struct switchtec_dev *dev, int port_id, int prev_speed, enum switchtec_diag_link link, struct switchtec_port_eq_table *res)
Get the Gen5 far end TX equalization table.
int switchtec_diag_cross_hair_disable(struct switchtec_dev *dev)
Disable active cross hair.
int switchtec_diag_pattern_mon_get(struct switchtec_dev *dev, int port_id, int lane_id, enum switchtec_diag_pattern *type, unsigned long long *err_cnt)
Get Pattern Monitor.
static int switchtec_diag_ltssm_log_gen6(struct switchtec_dev *dev, int port, int *log_count, struct switchtec_diag_ltssm_log *log_data)
Get the LTSSM log of a port on a gen6 switchtec device.
int switchtec_diag_pattern_gen_get(struct switchtec_dev *dev, int port_id, enum switchtec_diag_pattern *type)
Get Pattern Generator set on port.
int switchtec_diag_port_eq_tx_table(struct switchtec_dev *dev, int port_id, int prev_speed, enum switchtec_diag_link link, struct switchtec_port_eq_table *res)
Get the far end TX equalization table.
int switchtec_diag_port_eq_tx_fslf(struct switchtec_dev *dev, int port_id, int prev_speed, int lane_id, enum switchtec_diag_end end, enum switchtec_diag_link link, struct switchtec_port_eq_tx_fslf *res)
Get the equalization FS/LF.
static int switchtec_diag_ltssm_log_gen4(struct switchtec_dev *dev, int port, int *log_count, struct switchtec_diag_ltssm_log *log_data)
Get the LTSSM log of a port on a gen4 switchtec device.
int switchtec_diag_loopback_get(struct switchtec_dev *dev, int port_id, int *enabled, enum switchtec_diag_ltssm_speed *ltssm_speed)
Setup Loopback Mode.
int switchtec_inject_err_dllp_crc(struct switchtec_dev *dev, int phys_port_id, int enable, uint16_t rate)
Inject a DLLP CRC error into a physical port.
int switchtec_diag_eye_read(struct switchtec_dev *dev, int lane_id, int bin, int *num_phases, double *ber_data)
Start a PCIe Eye Read Gen5.
int switchtec_diag_eye_fetch(struct switchtec_dev *dev, double *pixels, size_t pixel_cnt, int *lane_id)
Start a PCIe Eye Capture.
static int switchtec_gen4_diag_port_eq_tx_fslf(struct switchtec_dev *dev, int port_id, int lane_id, enum switchtec_diag_end end, enum switchtec_diag_link link, struct switchtec_port_eq_tx_fslf *res)
Get the Gen4 equalization FS/LF.
int switchtec_diag_pattern_inject(struct switchtec_dev *dev, int port_id, unsigned int err_cnt)
Inject error into pattern generator.
int switchtec_diag_rcvr_obj(struct switchtec_dev *dev, int port_id, int lane_id, enum switchtec_diag_link link, struct switchtec_rcvr_obj *res)
Get the receiver object.
int switchtec_diag_eye_start(struct switchtec_dev *dev, int lane_mask[4], struct range *x_range, struct range *y_range, int step_interval, int capture_depth, int sar_sel, int intleav_sel, int hstep, int data_mode, int eye_mode, uint64_t refclk, int vstep)
Start a PCIe Eye Capture.
int switchtec_diag_perm_table(struct switchtec_dev *dev, struct switchtec_mrpc table[MRPC_MAX_ID])
Get the permission table.
static int switchtec_diag_ltssm_log_gen5(struct switchtec_dev *dev, int port, int *log_count, struct switchtec_diag_ltssm_log *log_data)
Get the LTSSM log of a port on a gen5 switchtec device.
int switchtec_inject_err_tlp_lcrc(struct switchtec_dev *dev, int phy_port, int enable, uint8_t rate)
Inject a TLP LCRC error into a physical port.
int switchtec_diag_ltssm_log(struct switchtec_dev *dev, int port, int *log_count, struct switchtec_diag_ltssm_log *log_data)
Determine the generation and call the related LTSSM log func.
int switchtec_inject_err_ack_nack(struct switchtec_dev *dev, int phys_port_id, uint16_t seq_num, uint8_t count)
Inject an ACK to NACK error into a physical port.
int switchtec_diag_refclk_status(struct switchtec_dev *dev, uint8_t *info)
Get the status of all stacks/CSUs of the refclk.
int switchtec_aer_event_gen(struct switchtec_dev *dev, int port_id, int aer_error_id, int trigger_event)
Call the aer event gen function to generate AER events.
int switchtec_diag_cross_hair_enable(struct switchtec_dev *dev, int lane_id)
Enable cross hair on specified lane.
static int switchtec_gen5_diag_port_eq_tx_fslf(struct switchtec_dev *dev, int port_id, int prev_speed, int lane_id, enum switchtec_diag_end end, enum switchtec_diag_link link, struct switchtec_port_eq_tx_fslf *res)
Get the Gen5 equalization FS/LF.
int switchtec_diag_eye_cancel(struct switchtec_dev *dev)
Cancel in-progress eye capture.
int switchtec_diag_pattern_gen_set(struct switchtec_dev *dev, int port_id, enum switchtec_diag_pattern type, enum switchtec_diag_pattern_link_rate link_speed)
Setup Pattern Generator.
int switchtec_diag_port_eq_tx_coeff(struct switchtec_dev *dev, int port_id, int prev_speed, enum switchtec_diag_end end, enum switchtec_diag_link link, struct switchtec_port_eq_coeff *res)
Get the port equalization TX coefficients.
int switchtec_inject_err_dllp(struct switchtec_dev *dev, int phys_port_id, int data)
Inject a DLLP into a physical port.
int switchtec_diag_eye_set_mode(struct switchtec_dev *dev, enum switchtec_diag_eye_data_mode mode)
Set the data mode for the next Eye Capture.
int switchtec_diag_cross_hair_get(struct switchtec_dev *dev, int start_lane_id, int num_lanes, struct switchtec_diag_cross_hair *res)
Disable active cross hair.
int switchtec_diag_loopback_set(struct switchtec_dev *dev, int port_id, int enable, int enable_parallel, int enable_external, int enable_ltssm, int enable_pipe, enum switchtec_diag_ltssm_speed ltssm_speed)
Setup Loopback Mode.
static int switchtec_gen5_diag_port_eq_tx_coeff(struct switchtec_dev *dev, int port_id, int prev_speed, enum switchtec_diag_end end, enum switchtec_diag_link link, struct switchtec_port_eq_coeff *res)
Get the Gen5 port equalization TX coefficients.
int switchtec_inject_err_cto(struct switchtec_dev *dev, int phys_port_id)
Inject Credit Timeout error into a physical port.
int switchtec_inject_err_tlp_seq_num(struct switchtec_dev *dev, int phys_port_id)
Inject a TLP Sequence Number error into a physical port.
int switchtec_diag_ltssm_clear(struct switchtec_dev *dev, int port)
Call the LTSSM clear MRPC command.
int switchtec_diag_refclk_ctl(struct switchtec_dev *dev, int id, bool en)
Control the refclk output for a stack or CSU.
static int switchtec_gen4_diag_port_eq_tx_table(struct switchtec_dev *dev, int port_id, enum switchtec_diag_link link, struct switchtec_port_eq_table *res)
Get the Gen4 far end TX equalization table.
int switchtec_diag_pattern_mon_set(struct switchtec_dev *dev, int port_id, enum switchtec_diag_pattern type)
Setup Pattern Monitor.
static int switchtec_gen4_diag_port_eq_tx_coeff(struct switchtec_dev *dev, int port_id, enum switchtec_diag_end end, enum switchtec_diag_link link, struct switchtec_port_eq_coeff *res)
Get the Gen4 port equalization TX coefficients.
int switchtec_cmd(struct switchtec_dev *dev, uint32_t cmd, const void *payload, size_t payload_len, void *resp, size_t resp_len)
Execute an MRPC command.
void switchtec_perror(const char *str)
Print an error string to stdout.
OSA configuration dump result.
@ LANE_EQ_DUMP_TYPE_PREV
Previous link-up settings.
@ LANE_EQ_DUMP_TYPE_CURR
Current settings.
static int switchtec_is_gen6(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 6 device.
static const float switchtec_gen_transfers[]
Number of GT/s capable for each PCI generation or link_rate.
static int switchtec_is_gen4(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 4 device.
static int switchtec_is_gen5(struct switchtec_dev *dev)
Return whether a Switchtec device is a Gen 5 device.
#define SWITCHTEC_OSA_MAX_ENTRIES
OSA capture data collection.