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_IDLE:
156 case SWITCHTEC_GEN5_DIAG_EYE_STATUS_DONE:
158 case SWITCHTEC_GEN5_DIAG_EYE_STATUS_TIMEOUT:
160 case SWITCHTEC_GEN5_DIAG_EYE_STATUS_ERROR:
168static int switchtec_diag_eye_status(
int status)
184static int switchtec_diag_eye_cmd_gen5(
struct switchtec_dev *dev,
void *in,
196 return switchtec_diag_eye_status_gen5(dev);
199static int switchtec_diag_eye_cmd_gen4(
struct switchtec_dev *dev,
void *in,
211 return switchtec_diag_eye_status(out.status);
222 enum switchtec_diag_eye_data_mode mode)
225 .sub_cmd = MRPC_EYE_OBSERVE_SET_DATA_MODE,
229 return switchtec_diag_eye_cmd_gen4(dev, &in,
sizeof(in));
243 int bin,
int* num_phases,
double* ber_data)
246 fprintf(stderr,
"Eye read not supported on Gen 4 switches.\n");
250 .sub_cmd = MRPC_EYE_CAP_READ_GEN5,
257 ret =
switchtec_cmd(dev, MRPC_GEN5_EYE_CAPTURE, &in,
sizeof(in),
262 *num_phases = out.num_phases;
264 for(i = 0; i < out.num_phases; i++)
265 ber_data[i] = le64toh(out.ber_data[i]) / 281474976710656.;
284 int step_interval,
int capture_depth)
289 .sub_cmd = MRPC_EYE_CAP_RUN_GEN5,
290 .capture_depth = capture_depth,
291 .timeout_disable = 1,
292 .lane_mask[0] = lane_mask[0],
293 .lane_mask[1] = lane_mask[1],
294 .lane_mask[2] = lane_mask[2],
295 .lane_mask[3] = lane_mask[3],
298 ret = switchtec_diag_eye_cmd_gen5(dev, &in,
sizeof(in));
304 .sub_cmd = MRPC_EYE_OBSERVE_START,
305 .lane_mask[0] = lane_mask[0],
306 .lane_mask[1] = lane_mask[1],
307 .lane_mask[2] = lane_mask[2],
308 .lane_mask[3] = lane_mask[3],
309 .x_start = x_range->start,
310 .y_start = y_range->start,
311 .x_end = x_range->end,
312 .y_end = y_range->end,
313 .x_step = x_range->step,
314 .y_step = y_range->step,
315 .step_interval = step_interval,
318 ret = switchtec_diag_eye_cmd_gen4(dev, &in,
sizeof(in));
328static uint64_t hi_lo_to_uint64(uint32_t lo, uint32_t hi)
353 size_t pixel_cnt,
int *lane_id)
356 .sub_cmd = MRPC_EYE_OBSERVE_FETCH,
359 uint64_t samples, errors;
360 int i, ret, data_count;
363 ret =
switchtec_cmd(dev, MRPC_EYE_OBSERVE, &in,
sizeof(in), &out,
368 if (out.status == 1) {
373 ret = switchtec_diag_eye_status(out.status);
377 for (i = 0; i < 4; i++) {
378 *lane_id = ffs(out.lane_mask[i]);
383 data_count = out.data_count_lo | ((int)out.data_count_hi << 8);
385 for (i = 0; i < data_count && i < pixel_cnt; i++) {
386 switch (out.data_mode) {
387 case SWITCHTEC_DIAG_EYE_RAW:
388 errors = hi_lo_to_uint64(out.raw[i].error_cnt_lo,
389 out.raw[i].error_cnt_hi);
390 samples = hi_lo_to_uint64(out.raw[i].sample_cnt_lo,
391 out.raw[i].sample_cnt_hi);
393 pixels[i] = (double)errors / samples;
397 case SWITCHTEC_DIAG_EYE_RATIO:
398 pixels[i] = le32toh(out.ratio[i].ratio) / 65536.;
417 .sub_cmd = MRPC_EYE_OBSERVE_CANCEL,
420 ret = switchtec_diag_eye_cmd_gen4(dev, &in,
sizeof(in));
430static int switchtec_diag_loopback_set_gen5(
struct switchtec_dev *dev,
431 int port_id,
int enable_parallel,
434 enum switchtec_diag_ltssm_speed
438 .sub_cmd = MRPC_LOOPBACK_SET_INT_LOOPBACK,
443 .sub_cmd = MRPC_LOOPBACK_SET_LTSSM_LOOPBACK,
445 .enable = enable_ltssm,
446 .speed = ltssm_speed,
450 if (enable_ltssm && !(enable_external || enable_parallel)) {
452 sizeof(ltssm_in), NULL, 0);
456 int_in.type = DIAG_LOOPBACK_PARALEL_DATAPATH;
457 int_in.enable = enable_parallel;
459 sizeof(int_in), NULL, 0);
462 if (!enable_parallel) {
463 int_in.type = DIAG_LOOPBACK_EXTERNAL_DATAPATH;
464 int_in.enable = enable_external;
466 sizeof(int_in), NULL, 0);
471 ltssm_in.enable = enable_ltssm;
473 sizeof(ltssm_in), NULL, 0);
480static int switchtec_diag_loopback_set_gen4(
struct switchtec_dev *dev,
481 int port_id,
int enable,
482 enum switchtec_diag_ltssm_speed
486 .sub_cmd = MRPC_LOOPBACK_SET_INT_LOOPBACK,
491 .sub_cmd = MRPC_LOOPBACK_SET_LTSSM_LOOPBACK,
493 .enable = !!(enable & SWITCHTEC_DIAG_LOOPBACK_LTSSM),
494 .speed = ltssm_speed,
498 int_in.type = DIAG_LOOPBACK_RX_TO_TX;
499 int_in.enable = !!(enable & SWITCHTEC_DIAG_LOOPBACK_RX_TO_TX);
502 sizeof(int_in), NULL, 0);
506 int_in.type = DIAG_LOOPBACK_TX_TO_RX;
507 int_in.enable = !!(enable & SWITCHTEC_DIAG_LOOPBACK_TX_TO_RX);
510 sizeof(int_in), NULL, 0);
515 sizeof(ltssm_in), NULL, 0);
535 int enable,
int enable_parallel,
536 int enable_external,
int enable_ltssm,
537 enum switchtec_diag_ltssm_speed ltssm_speed)
541 ret = switchtec_diag_loopback_set_gen5(dev, port_id,
550 ret = switchtec_diag_loopback_set_gen4(dev, port_id, enable,
569 int port_id,
int *enabled,
570 enum switchtec_diag_ltssm_speed *ltssm_speed)
573 .sub_cmd = MRPC_LOOPBACK_GET_INT_LOOPBACK,
577 .sub_cmd = MRPC_LOOPBACK_GET_LTSSM_LOOPBACK,
585 int_in.type = DIAG_LOOPBACK_PARALEL_DATAPATH;
587 int_in.type = DIAG_LOOPBACK_RX_TO_TX;
589 ret =
switchtec_cmd(dev, MRPC_INT_LOOPBACK, &int_in,
sizeof(int_in),
590 &int_out,
sizeof(int_out));
595 en |= SWITCHTEC_DIAG_LOOPBACK_RX_TO_TX;
598 int_in.type = DIAG_LOOPBACK_EXTERNAL_DATAPATH;
600 int_in.type = DIAG_LOOPBACK_TX_TO_RX;
602 ret =
switchtec_cmd(dev, MRPC_INT_LOOPBACK, &int_in,
sizeof(int_in),
603 &int_out,
sizeof(int_out));
608 en |= SWITCHTEC_DIAG_LOOPBACK_TX_TO_RX;
610 ret =
switchtec_cmd(dev, MRPC_INT_LOOPBACK, <_in,
sizeof(lt_in),
611 <_out,
sizeof(lt_out));
616 en |= SWITCHTEC_DIAG_LOOPBACK_LTSSM;
622 *ltssm_speed = lt_out.speed;
636 enum switchtec_diag_pattern type,
637 enum switchtec_diag_pattern_link_rate link_speed)
640 .sub_cmd = MRPC_PAT_GEN_SET_GEN,
642 .pattern_type = type,
643 .lane_id = link_speed
646 in.sub_cmd = MRPC_PAT_GEN_SET_GEN_GEN5;
648 return switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), NULL, 0);
660 enum switchtec_diag_pattern *type)
663 .sub_cmd = MRPC_PAT_GEN_GET_GEN,
669 ret =
switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), &out,
675 *type = out.pattern_type;
689 enum switchtec_diag_pattern type)
692 .sub_cmd = MRPC_PAT_GEN_SET_MON,
694 .pattern_type = type,
697 return switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), NULL, 0);
710 int lane_id,
enum switchtec_diag_pattern *type,
711 unsigned long long *err_cnt)
714 .sub_cmd = MRPC_PAT_GEN_GET_MON,
721 ret =
switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), &out,
727 *type = out.pattern_type;
730 *err_cnt = (htole32(out.err_cnt_lo) |
731 ((uint64_t)htole32(out.err_cnt_hi) << 32));
749 unsigned int err_cnt)
752 .sub_cmd = MRPC_PAT_GEN_INJ_ERR,
758 ret =
switchtec_cmd(dev, MRPC_PAT_GEN, &in,
sizeof(in), NULL, 0);
776 int lane_id,
enum switchtec_diag_link link,
785 .sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_PREV,
796 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
797 ret =
switchtec_cmd(dev, MRPC_RCVR_OBJ_DUMP, &in,
sizeof(in),
799 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
801 sizeof(ext_in), &out,
sizeof(out));
810 res->port_id = out.port_id;
811 res->lane_id = out.lane_id;
812 res->ctle = out.ctle;
813 res->target_amplitude = out.target_amplitude;
814 res->speculative_dfe = out.speculative_dfe;
815 for (i = 0; i < ARRAY_SIZE(res->dynamic_dfe); i++)
816 res->dynamic_dfe[i] = out.dynamic_dfe[i];
831 int port_id,
int prev_speed,
832 enum switchtec_diag_end end,
833 enum switchtec_diag_link link,
843 uint32_t out_size = 0;
848 fprintf(stderr,
"Error inval output buffer\n");
854 if (end == SWITCHTEC_DIAG_LOCAL) {
857 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
861 fprintf(stderr,
"Error inval end option\n");
864 buf = (uint8_t *)malloc(buf_size);
866 fprintf(stderr,
"Error in buffer alloc\n");
872 in->op_type = DIAG_PORT_EQ_STATUS_OP_PER_PORT;
873 in->phys_port_id = port_id;
877 if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
879 in->prev_rate = prev_speed;
882 if (end == SWITCHTEC_DIAG_LOCAL) {
883 in->cmd = MRPC_GEN5_PORT_EQ_LOCAL_TX_COEFF_DUMP;
888 fprintf(stderr,
"Error in switchtec cmd:%d\n", ret);
891 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
892 in->cmd = MRPC_GEN5_PORT_EQ_FAR_END_TX_COEFF_DUMP;
897 fprintf(stderr,
"Error in switchtec cmd:%d\n", ret);
901 fprintf(stderr,
"Error inval end request\n");
906 if (end == SWITCHTEC_DIAG_LOCAL) {
907 res->lane_cnt = loc_out->lane_cnt + 1;
908 for (i = 0; i < res->lane_cnt; i++) {
909 res->cursors[i].pre = loc_out->cursors[i].pre;
910 res->cursors[i].post = loc_out->cursors[i].post;
913 res->lane_cnt = rem_out->lane_cnt + 1;
914 for (i = 0; i < res->lane_cnt; i++) {
915 res->cursors[i].pre = rem_out->cursors[i].pre;
916 res->cursors[i].post = rem_out->cursors[i].post;
938 enum switchtec_diag_end end,
939 enum switchtec_diag_link link,
945 .op_type = DIAG_PORT_EQ_STATUS_OP_PER_PORT,
949 .op_type = DIAG_PORT_EQ_STATUS_OP_PER_PORT,
959 if (end == SWITCHTEC_DIAG_LOCAL) {
960 in.sub_cmd = MRPC_PORT_EQ_LOCAL_TX_COEFF_DUMP;
961 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_LOCAL_TX_COEFF_PREV;
962 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
963 in.sub_cmd = MRPC_PORT_EQ_FAR_END_TX_COEFF_DUMP;
964 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_FAR_END_TX_COEFF_PREV;
970 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
971 ret =
switchtec_cmd(dev, MRPC_PORT_EQ_STATUS, &in,
sizeof(in),
973 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
975 sizeof(in_prev), &out,
sizeof(out));
984 res->lane_cnt = out.lane_id + 1;
985 for (i = 0; i < res->lane_cnt; i++) {
986 res->cursors[i].pre = out.cursors[i].pre;
987 res->cursors[i].post = out.cursors[i].post;
1003 int prev_speed,
enum switchtec_diag_end end,
1004 enum switchtec_diag_link link,
1028 int port_id,
int prev_speed,
1029 enum switchtec_diag_link link,
1035 .sub_cmd = MRPC_GEN5_PORT_EQ_FAR_END_TX_EQ_TABLE_DUMP,
1048 if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1050 in.prev_rate = prev_speed;
1059 res->lane_id = out.lane_id;
1060 res->step_cnt = out.step_cnt;
1062 for (i = 0; i < res->step_cnt; i++) {
1063 res->steps[i].pre_cursor = out.steps[i].pre_cursor;
1064 res->steps[i].post_cursor = out.steps[i].post_cursor;
1065 res->steps[i].fom = 0;
1066 res->steps[i].pre_cursor_up = 0;
1067 res->steps[i].post_cursor_up = 0;
1068 res->steps[i].error_status = out.steps[i].error_status;
1069 res->steps[i].active_status = out.steps[i].active_status;
1070 res->steps[i].speed = out.steps[i].speed;
1086 enum switchtec_diag_link link,
1092 .sub_cmd = MRPC_PORT_EQ_FAR_END_TX_EQ_TABLE_DUMP,
1096 .sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_EQ_TX_TABLE_PREV,
1106 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1107 ret =
switchtec_cmd(dev, MRPC_PORT_EQ_STATUS, &in,
sizeof(in),
1109 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1111 sizeof(in_prev), &out,
sizeof(out));
1120 res->lane_id = out.lane_id;
1121 res->step_cnt = out.step_cnt;
1122 for (i = 0; i < res->step_cnt; i++) {
1123 res->steps[i].pre_cursor = out.steps[i].pre_cursor;
1124 res->steps[i].post_cursor = out.steps[i].post_cursor;
1125 res->steps[i].fom = out.steps[i].fom;
1126 res->steps[i].pre_cursor_up = out.steps[i].pre_cursor_up;
1127 res->steps[i].post_cursor_up = out.steps[i].post_cursor_up;
1128 res->steps[i].error_status = out.steps[i].error_status;
1129 res->steps[i].active_status = out.steps[i].active_status;
1130 res->steps[i].speed = out.steps[i].speed;
1145 enum switchtec_diag_link link,
1172 int port_id,
int prev_speed,
1174 enum switchtec_diag_end end,
1175 enum switchtec_diag_link link,
1188 in.port_id = port_id;
1189 in.lane_id = lane_id;
1192 if (end == SWITCHTEC_DIAG_LOCAL) {
1193 in.sub_cmd = MRPC_GEN5_PORT_EQ_LOCAL_TX_FSLF_DUMP;
1194 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
1195 in.sub_cmd = MRPC_GEN5_PORT_EQ_FAR_END_TX_FSLF_DUMP;
1201 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1205 in.prev_rate = prev_speed;
1231 int port_id,
int lane_id,
1232 enum switchtec_diag_end end,
1233 enum switchtec_diag_link link,
1253 if (end == SWITCHTEC_DIAG_LOCAL) {
1254 in.sub_cmd = MRPC_PORT_EQ_LOCAL_TX_FSLF_DUMP;
1255 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_LOCAL_TX_FSLF_PREV;
1256 }
else if (end == SWITCHTEC_DIAG_FAR_END) {
1257 in.sub_cmd = MRPC_PORT_EQ_FAR_END_TX_FSLF_DUMP;
1258 in_prev.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_FAR_END_TX_FSLF_PREV;
1264 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1265 ret =
switchtec_cmd(dev, MRPC_PORT_EQ_STATUS, &in,
sizeof(in),
1267 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1269 sizeof(in_prev), &out,
sizeof(out));
1295 int prev_speed,
int lane_id,
1296 enum switchtec_diag_end end,
1297 enum switchtec_diag_link link,
1304 prev_speed, lane_id,
1325 int lane_id,
enum switchtec_diag_link link,
1340 if (link == SWITCHTEC_DIAG_LINK_CURRENT) {
1341 in.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_RCVR_EXT;
1342 }
else if (link == SWITCHTEC_DIAG_LINK_PREVIOUS) {
1343 in.sub_cmd = MRPC_EXT_RCVR_OBJ_DUMP_RCVR_EXT_PREV;
1349 ret =
switchtec_cmd(dev, MRPC_EXT_RCVR_OBJ_DUMP, &in,
sizeof(in),
1354 res->ctle2_rx_mode = out.ctle2_rx_mode;
1355 res->dtclk_9 = out.dtclk_9;
1356 res->dtclk_8_6 = out.dtclk_8_6;
1357 res->dtclk_5 = out.dtclk_5;
1372 uint32_t perms[(MRPC_MAX_ID + 31) / 32];
1376 perms,
sizeof(perms));
1380 for (i = 0; i < MRPC_MAX_ID; i++) {
1381 if (perms[i >> 5] & (1 << (i & 0x1f))) {
1382 if (switchtec_mrpc_table[i].tag) {
1383 table[i] = switchtec_mrpc_table[i];
1385 table[i].tag =
"UNKNOWN";
1386 table[i].desc =
"Unknown MRPC Command";
1387 table[i].reserved =
true;
1390 table[i].tag = NULL;
1391 table[i].desc = NULL;
1409 .sub_cmd = en ? MRPC_REFCLK_S_ENABLE : MRPC_REFCLK_S_DISABLE,
1410 .stack_id = stack_id,
1413 return switchtec_cmd(dev, MRPC_REFCLK_S, &cmd,
sizeof(cmd), NULL, 0);
1425 .sub_cmd = MRPC_REFCLK_S_STATUS,
1428 return switchtec_cmd(dev, MRPC_REFCLK_S, &cmd,
sizeof(cmd), stack_info,
1429 sizeof(uint8_t) * SWITCHTEC_MAX_STACKS);
1436 int curr_idx, uint16_t num_of_logs)
1445 for (
int j = 0; j < num_of_logs; j++) {
1446 dw0 = log_dump_out_ptr[j].dw0;
1447 timestamp = log_dump_out_ptr[j].ram_timestamp;
1449 rate = (dw0 >> 13) & 0x7;
1450 major = (dw0 >> 7) & 0x3f;
1451 minor = (dw0 >> 3) & 0xf;
1453 log_data[curr_idx + j].timestamp = timestamp;
1455 log_data[curr_idx + j].link_state = major | (minor << 8);
1467 int port,
int *log_count,
1484 uint16_t w0_trigger_count;
1485 uint16_t w1_trigger_count;
1492 uint16_t no_of_logs;
1495 uint8_t log_buffer[1024];
1503 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1504 ltssm_freeze.port = port;
1505 ltssm_freeze.freeze = 1;
1507 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1508 sizeof(ltssm_freeze), NULL, 0);
1513 status.sub_cmd = MRPC_LTMON_GET_STATUS_GEN5;
1516 sizeof(status), &status_output,
1517 sizeof(status_output));
1521 *log_count = status_output.log_count;
1524 log_dump.sub_cmd = MRPC_LTMON_LOG_DUMP_GEN5;
1525 log_dump.port = port;
1526 log_dump.log_index = 0;
1527 log_dump.no_of_logs = *log_count;
1529 if(log_dump.no_of_logs <= SWITCHTEC_LTSSM_MAX_LOGS) {
1531 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1532 sizeof(log_dump), &log_buffer[0],
1533 log_dump.no_of_logs * log_dmp_size + 4);
1540 switchtec_diag_ltssm_set_log_data(log_data,
1542 0, log_dump.no_of_logs);
1545 int buff_count = log_dump.no_of_logs / SWITCHTEC_LTSSM_MAX_LOGS;
1547 int buffer_size = SWITCHTEC_LTSSM_MAX_LOGS * log_dmp_size + 4;
1549 for (
int i = 0; i < buff_count; i++) {
1550 log_dump.no_of_logs = SWITCHTEC_LTSSM_MAX_LOGS;
1552 &log_dump,
sizeof(log_dump),
1553 &log_buffer[0], buffer_size);
1560 switchtec_diag_ltssm_set_log_data(log_data,
1563 log_dump.no_of_logs);
1564 curr_idx += SWITCHTEC_LTSSM_MAX_LOGS;
1565 log_dump.log_index = curr_idx;
1567 if (*log_count % SWITCHTEC_LTSSM_MAX_LOGS) {
1568 log_dump.no_of_logs = *log_count - curr_idx;
1569 buffer_size = log_dump.no_of_logs * log_dmp_size + 4;
1571 &log_dump,
sizeof(log_dump),
1572 &log_buffer[0], buffer_size);
1579 switchtec_diag_ltssm_set_log_data(log_data,
1582 log_dump.no_of_logs);
1587 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1588 ltssm_freeze.port = port;
1589 ltssm_freeze.freeze = 0;
1591 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1592 sizeof(ltssm_freeze), NULL, 0);
1605 int port,
int *log_count,
1620 uint32_t w0_trigger_count;
1621 uint32_t w1_trigger_count;
1634 } log_dump_out[256];
1645 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1646 ltssm_freeze.port = port;
1647 ltssm_freeze.freeze = 1;
1649 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1650 sizeof(ltssm_freeze), NULL, 0);
1655 status.sub_cmd = MRPC_LTMON_GET_STATUS_GEN4;
1658 sizeof(status), &status_output,
1659 sizeof(status_output));
1663 if (status_output.log_num < *log_count)
1664 *log_count = status_output.log_num;
1667 log_dump.sub_cmd = MRPC_LTMON_LOG_DUMP_GEN4;
1668 log_dump.port = port;
1669 log_dump.log_index = 0;
1670 log_dump.no_of_logs = *log_count;
1671 if(log_dump.no_of_logs <= 126) {
1672 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1673 sizeof(log_dump), log_dump_out,
1674 8 * log_dump.no_of_logs);
1678 log_dump.no_of_logs = 126;
1679 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1680 sizeof(log_dump), log_dump_out,
1681 8 * log_dump.no_of_logs);
1685 log_dump.log_index = 126;
1686 log_dump.no_of_logs = *log_count - 126;
1688 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1689 sizeof(log_dump), log_dump_out + 126,
1690 8 * log_dump.no_of_logs);
1694 for (i = 0; i < *log_count; i++) {
1695 dw1 = log_dump_out[i].dw1;
1696 dw0 = log_dump_out[i].dw0;
1697 rate = (dw0 >> 13) & 0x3;
1698 major = (dw0 >> 7) & 0xf;
1699 minor = (dw0 >> 3) & 0xf;
1701 log_data[i].timestamp = dw1 & 0x3ffffff;
1703 log_data[i].link_state = major | (minor << 8);
1707 ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1708 ltssm_freeze.port = port;
1709 ltssm_freeze.freeze = 0;
1711 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_freeze,
1712 sizeof(ltssm_freeze), NULL, 0);
1725 int port,
int *log_count,
1750 ltssm_clear.subcmd = MRPC_LTMON_CLEAR_LOG;
1751 ltssm_clear.port_id = port;
1753 ret =
switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, <ssm_clear,
1754 sizeof(ltssm_clear), NULL, 0);
1758int switchtec_tlp_inject(
struct switchtec_dev *dev,
int port_id,
int tlp_type,
1759 int tlp_length,
int ecrc, uint32_t *raw_tlp_data)
1764 .dest_port = port_id,
1765 .tlp_type = tlp_type,
1766 .tlp_length = tlp_length,
1769 for (
int i = 0; i < tlp_in.tlp_length; i++) {
1770 tlp_in.raw_tlp_data[i] = htole32(*(raw_tlp_data + i));
1774 ret =
switchtec_cmd(dev, MRPC_DIAG_TLP_INJECT, &tlp_in,
sizeof(tlp_in),
1775 &tlp_out,
sizeof(tlp_out));
1787 int aer_error_id,
int trigger_event)
1793 .sub_cmd = trigger_event,
1794 .phys_port_id = port_id,
1795 .err_mask = aer_error_id,
1803 sizeof(sub_cmd_id), &output,
sizeof(output));
1820 .subcmd = MRPC_ERR_INJ_DLLP,
1821 .phys_port_id = phys_port_id,
1826 sizeof(cmd), &output,
sizeof(output));
1838 int phys_port_id,
int enable,
1844 .subcmd = MRPC_ERR_INJ_DLLP_CRC,
1845 .phys_port_id = phys_port_id,
1851 sizeof(cmd), &output,
sizeof(output));
1854static int switchtec_inject_err_tlp_lcrc_gen4(
struct switchtec_dev *dev,
1855 int phys_port_id,
int enable,
1861 .subcmd = MRPC_ERR_INJ_TLP_LCRC,
1862 .phys_port_id = phys_port_id,
1866 printf(
"enable: %d\n", enable);
1869 sizeof(cmd), &output,
sizeof(output));
1872static int switchtec_inject_err_tlp_lcrc_gen5(
struct switchtec_dev *dev,
1873 int phys_port_id,
int enable,
1879 .subcmd = MRPC_ERR_INJ_TLP_LCRC,
1880 .phys_port_id = phys_port_id,
1886 sizeof(cmd), &output,
sizeof(output));
1897 int enable, uint8_t rate)
1901 ret = switchtec_inject_err_tlp_lcrc_gen4(dev, phy_port, enable, rate);
1904 ret = switchtec_inject_err_tlp_lcrc_gen5(dev, phy_port, enable, rate);
1907 fprintf(stderr,
"The TLP LCRC is not supported for Gen3 switches.\n");
1922 .subcmd = MRPC_ERR_INJ_TLP_SEQ,
1923 .phys_port_id = phys_port_id,
1927 sizeof(cmd), &output,
sizeof(output));
1939 uint16_t seq_num, uint8_t count)
1944 .subcmd = MRPC_ERR_INJ_ACK_NACK,
1945 .phys_port_id = phys_port_id,
1951 sizeof(cmd), &output,
sizeof(output));
1965 .subcmd = MRPC_ERR_INJ_CTO,
1966 .phys_port_id = phys_port_id,
1970 sizeof(cmd), &output,
sizeof(output));
1973static void osa_dword_data_helper(
const uint32_t dwords[4],
char *buffer) {
1975 for (
int i = 3; i >= 0; --i) {
1976 int tmp = sprintf(ptr,
"0x%08X", dwords[i]);
1984static void print_osa_capture_data(uint32_t* entry_dwords, uint8_t entries_read)
1987 uint32_t timestamp_upper = 0;
1988 uint32_t timestamp_lower = 0;
1989 uint64_t timestamp = 0;
1990 char data_string[45];
1991 uint32_t osa_dword_data[4];
1993 printf(
"IDX\tTIMESTAMP\tCNT\tRATE\tDRP\tTRIG\tDATA\n");
1994 for (
int i = 0; i < entries_read; i++) {
1997 for (
int j = 0; j < 6; j++) {
1998 if (j >= 0 && j <= 3) {
1999 osa_dword_data[j] = entry_dwords[curr_idx];
2002 osa_dword_data_helper(osa_dword_data, data_string);
2003 timestamp_lower = (entry_dwords[curr_idx] >> 22) & 0x3FF;
2004 timestamp_upper = (entry_dwords[curr_idx+1] & 0x7FFFFFF);
2005 printf(
"time_upper: %d\n", timestamp_upper);
2006 printf(
"time_lower: %d\n", timestamp_lower);
2007 timestamp = (uint64_t)timestamp_upper << 12 | timestamp_lower;
2008 printf(
"0x%08lx\t", timestamp);
2009 printf(
"%d\t", (entry_dwords[curr_idx] >> 3) & 0x7FFFF);
2010 printf(
"%d\t", entry_dwords[curr_idx] & 0x7);
2011 printf(
"%d\t", (entry_dwords[curr_idx+1] >> 28) & 0x1);
2012 printf(
"%d\t", (entry_dwords[curr_idx+1] >> 27) & 0x1);
2013 printf(
"%s\n", data_string);
2021int switchtec_osa_capture_data(
struct switchtec_dev *dev,
int stack_id,
2022 int lane,
int direction)
2030 uint16_t start_entry;
2031 uint8_t num_entries;
2036 uint8_t entries_read;
2040 uint16_t next_entry;
2041 uint16_t entries_remaining;
2044 } osa_data_entries_out;
2046 osa_data_read_in.sub_cmd = MRPC_OSA_DATA_READ;
2047 osa_data_read_in.stack_id = stack_id;
2048 osa_data_read_in.lane = lane;
2049 osa_data_read_in.direction = direction;
2051 osa_data_read_in.start_entry = 0;
2052 osa_data_read_in.num_entries = 0;
2058 } osa_status_query_in;
2062 uint8_t trigger_lane;
2063 uint8_t trigger_dir;
2065 uint16_t trigger_reason;
2067 } osa_status_query_out;
2069 osa_status_query_in.sub_cmd = MRPC_OSA_STATUS_QUERY;
2070 osa_status_query_in.stack_id = stack_id;
2072 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_status_query_in,
2073 sizeof(osa_status_query_in), &osa_status_query_out,
2074 sizeof(osa_status_query_out));
2076 printf(
"Current status of stack %d\n", stack_id);
2077 printf(
"state: %d\n", osa_status_query_out.state);
2078 printf(
"trigger_lane: %d\n", osa_status_query_out.trigger_lane);
2079 printf(
"trigger_dir: %d\n", osa_status_query_out.trigger_dir);
2080 printf(
"trigger_reason: %d\n", osa_status_query_out.trigger_reason);
2082 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_data_read_in,
2083 sizeof(osa_data_read_in), &osa_data_entries_out,
2084 sizeof(osa_data_entries_out));
2089 printf(
"OSA: Captured Data \n");
2092 uint8_t entries_read;
2096 uint16_t next_entry;
2097 uint16_t entries_remaining;
2100 uint32_t entry_dwords[];
2101 } *osa_data_read_out = alloca(
sizeof(*osa_data_read_out) +
2102 osa_data_entries_out.entries_remaining * 6 *
2105 osa_data_read_out->entries_remaining = osa_data_entries_out.entries_remaining;
2106 osa_data_read_out->next_entry = osa_data_entries_out.next_entry;
2108 while (osa_data_read_out->entries_remaining != 0) {
2109 osa_data_read_in.num_entries = osa_data_read_out->entries_remaining;
2110 osa_data_read_in.start_entry = osa_data_read_out->next_entry;
2113 &osa_data_read_in,
sizeof(osa_data_read_in),
2114 osa_data_read_out,
sizeof(*osa_data_read_out));
2119 print_osa_capture_data(osa_data_read_out->entry_dwords,
2120 osa_data_read_out->entries_read);
2126int switchtec_osa_capture_control(
struct switchtec_dev *dev,
int stack_id,
2127 int lane_mask,
int direction,
2128 int drop_single_os,
int stop_mode,
2129 int snapshot_mode,
int post_trigger,
2152 printf(
"OSA: Configuring capture control on stack %d\n", stack_id);
2156int switchtec_osa_config_misc(
struct switchtec_dev *dev,
int stack_id,
2167 } osa_misc_config_in;
2169 osa_misc_config_in.sub_cmd = MRPC_OSA_MISC_TRIG_CONFIG;
2170 osa_misc_config_in.stack_id = stack_id;
2171 osa_misc_config_in.trigger_en = trigger_en;
2173 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_misc_config_in,
2174 sizeof(osa_misc_config_in), NULL, 0);
2179 printf(
"OSA: Enabled misc triggering config on stack %d\n", stack_id);
2183int switchtec_osa_config_pattern(
struct switchtec_dev *dev,
int stack_id,
2184 int direction,
int lane_mask,
int link_rate,
2185 uint32_t *value_data, uint32_t *mask_data)
2211 printf(
"OSA: Enabled pattern triggering config on stack %d\n", stack_id);
2215int switchtec_osa_config_type(
struct switchtec_dev *dev,
int stack_id,
2216 int direction,
int lane_mask,
int link_rate,
int os_types)
2229 printf(
"%d : %d : %d : %d : %d\n", stack_id, lane_mask, direction,
2230 link_rate, os_types);
2237 printf(
"OSA: Enabled type triggering config on stack %d\n", stack_id);
2241int switchtec_osa_dump_conf(
struct switchtec_dev *dev,
int stack_id)
2252 int16_t os_type_trig_lane_mask;
2253 uint8_t os_type_trig_dir;
2254 uint8_t os_type_trig_link_rate;
2255 uint8_t os_type_trig_os_types;
2258 uint16_t os_pat_trig_lane_mask;
2259 uint8_t os_pat_trig_dir;
2260 uint8_t os_pat_trig_link_rate;
2261 uint32_t os_pat_trig_val_dw0;
2262 uint32_t os_pat_trig_val_dw1;
2263 uint32_t os_pat_trig_val_dw2;
2264 uint32_t os_pat_trig_val_dw3;
2265 uint32_t os_pat_trig_mask_dw0;
2266 uint32_t os_pat_trig_mask_dw1;
2267 uint32_t os_pat_trig_mask_dw2;
2268 uint32_t os_pat_trig_mask_dw3;
2269 uint8_t misc_trig_en;
2272 uint16_t capture_lane_mask;
2273 uint8_t capture_dir;
2274 uint8_t capture_drop_os;
2275 uint8_t capture_stop_mode;
2276 uint8_t capture_snap_mode;
2277 uint16_t capture_post_trig_entries;
2278 uint8_t capture_os_types;
2283 osa_dmp_in.stack_id = stack_id;
2284 osa_dmp_in.sub_cmd = MRPC_OSA_CONFIG_DMP;
2286 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_dmp_in,
2287 sizeof(osa_dmp_in), &osa_dmp_out,
2288 sizeof(osa_dmp_out));
2293 printf(
"Config dump \n");
2294 printf(
"---- OS Type ---------------\n");
2295 printf(
"lane mask: \t\t%d\n", osa_dmp_out.os_type_trig_lane_mask);
2296 printf(
"direciton: \t\t%d\n", osa_dmp_out.os_type_trig_dir);
2297 printf(
"link rate: \t\t%d\n", osa_dmp_out.os_type_trig_link_rate);
2298 printf(
"os types: \t\t%d\n", osa_dmp_out.os_type_trig_os_types);
2299 printf(
"---- OS Pattern ------------\n");
2300 printf(
"lane mask: \t\t%d\n", osa_dmp_out.os_pat_trig_lane_mask);
2301 printf(
"direciton: \t\t%d\n", osa_dmp_out.os_pat_trig_dir);
2302 printf(
"link rate: \t\t%d\n", osa_dmp_out.os_pat_trig_link_rate);
2303 printf(
"patttern: \t\t%d %d %d %d\n", osa_dmp_out.os_pat_trig_val_dw0,
2304 osa_dmp_out.os_pat_trig_val_dw1, osa_dmp_out.os_pat_trig_val_dw2,
2305 osa_dmp_out.os_pat_trig_val_dw3);
2306 printf(
"mask: \t\t\t%d %d %d %d\n", osa_dmp_out.os_pat_trig_mask_dw0,
2307 osa_dmp_out.os_pat_trig_mask_dw1, osa_dmp_out.os_pat_trig_mask_dw2,
2308 osa_dmp_out.os_pat_trig_mask_dw3);
2309 printf(
"---- Misc ------------------\n");
2310 printf(
"Misc trigger enabled: \t%d\n", osa_dmp_out.misc_trig_en);
2311 printf(
"---- Capture ---------------\n");
2312 printf(
"lane mask: \t\t%d\n", osa_dmp_out.capture_lane_mask);
2313 printf(
"direciton: \t\t%d\n", osa_dmp_out.capture_dir);
2314 printf(
"drop single os: \t%d\n", osa_dmp_out.capture_drop_os);
2315 printf(
"stop mode: \t\t%d\n", osa_dmp_out.capture_stop_mode);
2316 printf(
"snaphot mode: \t\t%d\n", osa_dmp_out.capture_snap_mode);
2317 printf(
"post-trigger entries: \t%d\n", osa_dmp_out.capture_post_trig_entries);
2318 printf(
"os types: \t\t%d\n", osa_dmp_out.capture_os_types);
2322int switchtec_osa(
struct switchtec_dev *dev,
int stack_id,
int operation)
2329 } osa_rel_access_perm_in;
2335 } osa_status_query_in;
2339 uint8_t trigger_lane;
2340 uint8_t trigger_dir;
2342 uint16_t trigger_reason;
2344 } osa_status_query_out;
2353 char *valid_ops[6] = {
"stop",
"start",
"trigger",
"reset",
"release",
2355 char *states[5] = {
"Deactivated (not armed)",
"Started (armed), not triggered",
2356 "Started (armted), triggered",
"Stopped, not triggered",
2357 "Stopped, triggered"};
2358 char *directions[2] = {
"TX",
"RX"};
2359 printf(
"Attempting %s operation...\n", valid_ops[operation]);
2360 if (operation == 4) {
2361 osa_rel_access_perm_in.sub_cmd = MRPC_OSA_REL_ACCESS_PERM;
2362 osa_rel_access_perm_in.stack_id = stack_id;
2365 &osa_rel_access_perm_in,
2366 sizeof(osa_rel_access_perm_in), NULL, 0);
2368 else if (operation == 5) {
2369 osa_status_query_in.sub_cmd = MRPC_OSA_STATUS_QUERY;
2370 osa_status_query_in.stack_id = stack_id;
2373 &osa_status_query_in,
sizeof(osa_status_query_in),
2374 &osa_status_query_out,
sizeof(osa_status_query_out));
2379 printf(
"Status of stack %d\n", stack_id);
2380 printf(
"STATE: %s\n", states[osa_status_query_out.state]);
2381 printf(
"TRIGGER_LANE: %d\n", osa_status_query_out.trigger_lane);
2382 printf(
"TRIGGER_DIR: %s\n", directions[osa_status_query_out.trigger_dir]);
2383 printf(
"REASON_BITMASK: %d\n", osa_status_query_out.trigger_reason);
2386 osa_op_in.sub_cmd = MRPC_OSA_ANALYZER_OP;
2387 osa_op_in.stack_id = stack_id;
2388 osa_op_in.operation = operation;
2390 ret =
switchtec_cmd(dev, MRPC_ORDERED_SET_ANALYZER, &osa_op_in,
2391 sizeof(osa_op_in), NULL, 0);
2397 printf(
"Successful %s operation!\n", valid_ops[operation]);
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.
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_refclk_ctl(struct switchtec_dev *dev, int stack_id, bool en)
Control the refclk output for a stack.
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_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_loopback_set(struct switchtec_dev *dev, int port_id, int enable, int enable_parallel, int enable_external, int enable_ltssm, enum switchtec_diag_ltssm_speed ltssm_speed)
Setup Loopback Mode.
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_refclk_status(struct switchtec_dev *dev, uint8_t *stack_info)
Get the status of all stacks of the refclk.
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.
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.
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_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)
Start a PCIe Eye Capture.
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.
@ LANE_EQ_DUMP_TYPE_PREV
Previous link-up settings.
@ LANE_EQ_DUMP_TYPE_CURR
Current settings.
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.