Skip to content

Commit 20a041d

Browse files
committed
Merge branch 'devel'
2 parents 57b6b42 + d6048a0 commit 20a041d

File tree

9 files changed

+340
-35
lines changed

9 files changed

+340
-35
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
runs-on: ubuntu-latest
2626
steps:
2727
- name: install packages
28-
run: sudo apt-get install gcc-multilib
28+
run: sudo apt-get update; sudo apt-get install gcc-multilib
2929
- uses: actions/checkout@v2
3030
- name: configure
3131
run: ./configure

cli/diag.c

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,49 @@ static int diag_parse_common_cfg(int argc, char **argv, const char *desc,
118118
return 0;
119119
}
120120

121+
#define CMD_DESC_LTSSM_LOG "Display LTSSM log"
122+
static int ltssm_log(int argc, char **argv) {
123+
struct diag_common_cfg cfg = DEFAULT_DIAG_COMMON_CFG;
124+
125+
const struct argconfig_options opts[] = {
126+
DEVICE_OPTION, PORT_OPTION, {}
127+
};
128+
129+
struct switchtec_diag_ltssm_log output[128];
130+
int ret;
131+
int port;
132+
int log_count = 128;
133+
int i;
134+
135+
ret = diag_parse_common_cfg(argc, argv, CMD_DESC_LTSSM_LOG,
136+
&cfg, opts);
137+
if (ret)
138+
return ret;
139+
140+
if (switchtec_is_gen3(cfg.dev)) {
141+
fprintf (stderr,
142+
"This command is not supported on Gen3 devices\n");
143+
return 0;
144+
}
145+
port = cfg.port_id;
146+
ret = switchtec_diag_ltssm_log(cfg.dev, port, &log_count, output);
147+
if (ret) {
148+
switchtec_perror("ltssm_log");
149+
return ret;
150+
}
151+
152+
printf("LTSSM Log for Physical Port %d (autowrap ON)\n\n", port);
153+
printf("Idx\tDelta Time\tPCIe Rate\tState\n");
154+
for(i = 0; i < log_count ; i++) {
155+
printf("%3d\t", i);
156+
printf("%09x\t", output[i].timestamp);
157+
printf("%.1fG\t\t", output[i].link_rate);
158+
printf("%s\n", switchtec_ltssm_str(output[i].link_state, 1));
159+
}
160+
161+
return ret;
162+
}
163+
121164
static const struct argconfig_choice eye_modes[] = {
122165
{"RAW", SWITCHTEC_DIAG_EYE_RAW,
123166
"raw data mode (slow, more accurate)"},
@@ -1936,27 +1979,34 @@ static int refclk(int argc, char **argv)
19361979
int stack_id;
19371980
int enable;
19381981
int disable;
1939-
} cfg = {};
1982+
} cfg = {
1983+
.stack_id = -1
1984+
};
19401985
const struct argconfig_options opts[] = {
19411986
DEVICE_OPTION,
19421987
{"disable", 'd', "", CFG_NONE, &cfg.disable, no_argument,
19431988
"disable the rfclk output"},
19441989
{"enable", 'e', "", CFG_NONE, &cfg.enable, no_argument,
19451990
"enable the rfclk output"},
1946-
{"stack", 's', "NUM", CFG_POSITIVE, &cfg.stack_id,
1991+
{"stack", 's', "NUM", CFG_NONNEGATIVE, &cfg.stack_id,
19471992
required_argument, "stack to operate on"},
19481993
{NULL}};
19491994

19501995
argconfig_parse(argc, argv, CMD_DESC_REF_CLK, opts, &cfg,
19511996
sizeof(cfg));
19521997

19531998
if (!cfg.enable && !cfg.disable) {
1954-
fprintf(stderr, "Must set either --enable or --disable");
1999+
fprintf(stderr, "Must set either --enable or --disable\n");
19552000
return -1;
19562001
}
19572002

19582003
if (cfg.enable && cfg.disable) {
1959-
fprintf(stderr, "Must not set both --enable and --disable");
2004+
fprintf(stderr, "Must not set both --enable and --disable\n");
2005+
return -1;
2006+
}
2007+
2008+
if (cfg.stack_id == -1) {
2009+
fprintf(stderr, "Must specify stack ID using --stack or -s\n");
19602010
return -1;
19612011
}
19622012

@@ -1984,6 +2034,7 @@ static const struct cmd commands[] = {
19842034
CMD(rcvr_extended, CMD_DESC_RCVR_EXTENDED),
19852035
CMD(rcvr_obj, CMD_DESC_RCVR_OBJ),
19862036
CMD(refclk, CMD_DESC_REF_CLK),
2037+
CMD(ltssm_log, CMD_DESC_LTSSM_LOG),
19872038
{}
19882039
};
19892040

cli/main.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2123,19 +2123,20 @@ static int fw_read(int argc, char **argv)
21232123
static struct {
21242124
struct switchtec_dev *dev;
21252125
int out_fd;
2126-
const char *out_filename;
2126+
char *out_filename;
21272127
int assume_yes;
21282128
int inactive;
21292129
int data;
21302130
int bl2;
21312131
int key;
21322132
int no_progress_bar;
2133-
} cfg = {};
2133+
} cfg = {
2134+
.out_fd = -1
2135+
};
21342136
const struct argconfig_options opts[] = {
21352137
DEVICE_OPTION,
21362138
{"filename", .cfg_type=CFG_FD_WR, .value_addr=&cfg.out_fd,
21372139
.argument_type=optional_positional,
2138-
.force_default="image.pmc",
21392140
.help="image file to display information for"},
21402141
{"yes", 'y', "", CFG_NONE, &cfg.assume_yes, no_argument,
21412142
"assume yes when prompted"},
@@ -2155,6 +2156,15 @@ static int fw_read(int argc, char **argv)
21552156

21562157
argconfig_parse(argc, argv, CMD_DESC_FW_READ, opts, &cfg, sizeof(cfg));
21572158

2159+
if(cfg.out_fd == -1) {
2160+
if (switchtec_is_gen3(cfg.dev))
2161+
cfg.out_filename = "image.pmc";
2162+
else
2163+
cfg.out_filename = "image.fwimg";
2164+
2165+
cfg.out_fd = fileno(fopen(cfg.out_filename, "w"));
2166+
}
2167+
21582168
sum = switchtec_fw_part_summary(cfg.dev);
21592169
if (!sum) {
21602170
switchtec_perror("fw_part_summary");

inc/switchtec/fabric.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ struct switchtec_fab_port_info {
7676
struct switchtec_fab_topo_info {
7777
uint8_t sw_idx; //!< Switch index
7878
uint8_t rsvd[3];
79-
uint32_t stack_bif[7]; //!< Port bifurcation
79+
int num_stack_bif; //!< Number of port bifurcation fields
80+
uint32_t stack_bif[8]; //!< Port bifurcation
8081
uint8_t route_port[16]; //!< Route port
8182
uint64_t port_bitmap; //!< Enabled physical port bitmap
8283

inc/switchtec/mrpc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ enum mrpc_cmd {
116116
MRPC_SECURITY_CONFIG_GET_GEN5 = 0x10C,
117117
MRPC_SECURITY_CONFIG_SET_GEN5 = 0x10D,
118118

119-
MRPC_MAX_ID = 0x140,
119+
MRPC_MAX_ID = 0x10E,
120120
};
121121

122122
enum mrpc_bg_status {
@@ -197,6 +197,7 @@ enum mrpc_sub_cmd {
197197
MRPC_TOPO_INFO_DUMP_STATUS_GET = 2,
198198
MRPC_TOPO_INFO_DUMP_DATA_GET = 3,
199199
MRPC_TOPO_INFO_DUMP_FINISH = 4,
200+
MRPC_TOPO_INFO_DUMP_DATA_GET_GEN5 = 5,
200201

201202
MRPC_GFMS_DB_DUMP_FABRIC = 0,
202203
MRPC_GFMS_DB_DUMP_PAX_ALL,

inc/switchtec/switchtec.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,6 +1158,12 @@ enum switchtec_diag_link {
11581158
SWITCHTEC_DIAG_LINK_PREVIOUS,
11591159
};
11601160

1161+
struct switchtec_diag_ltssm_log {
1162+
unsigned int timestamp;
1163+
float link_rate;
1164+
int link_state;
1165+
};
1166+
11611167
int switchtec_diag_cross_hair_enable(struct switchtec_dev *dev, int lane_id);
11621168
int switchtec_diag_cross_hair_disable(struct switchtec_dev *dev);
11631169
int switchtec_diag_cross_hair_get(struct switchtec_dev *dev, int start_lane_id,
@@ -1209,6 +1215,9 @@ int switchtec_diag_port_eq_tx_fslf(struct switchtec_dev *dev, int port_id,
12091215
int switchtec_diag_perm_table(struct switchtec_dev *dev,
12101216
struct switchtec_mrpc table[MRPC_MAX_ID]);
12111217
int switchtec_diag_refclk_ctl(struct switchtec_dev *dev, int stack_id, bool en);
1218+
int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
1219+
int port, int *log_count,
1220+
struct switchtec_diag_ltssm_log *log_data);
12121221

12131222
#ifdef __cplusplus
12141223
}

lib/diag.c

Lines changed: 142 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,8 @@ int switchtec_diag_eye_start(struct switchtec_dev *dev, int lane_mask[4],
192192
struct range *x_range, struct range *y_range,
193193
int step_interval)
194194
{
195+
int err;
196+
int ret;
195197
struct switchtec_diag_port_eye_start in = {
196198
.sub_cmd = MRPC_EYE_OBSERVE_START,
197199
.lane_mask[0] = lane_mask[0],
@@ -207,7 +209,14 @@ int switchtec_diag_eye_start(struct switchtec_dev *dev, int lane_mask[4],
207209
.step_interval = step_interval,
208210
};
209211

210-
return switchtec_diag_eye_cmd(dev, &in, sizeof(in));
212+
ret = switchtec_diag_eye_cmd(dev, &in, sizeof(in));
213+
214+
/* Add delay so hardware has enough time to start */
215+
err = errno;
216+
usleep(200000);
217+
errno = err;
218+
219+
return ret;
211220
}
212221

213222
static uint64_t hi_lo_to_uint64(uint32_t lo, uint32_t hi)
@@ -296,11 +305,20 @@ int switchtec_diag_eye_fetch(struct switchtec_dev *dev, double *pixels,
296305
*/
297306
int switchtec_diag_eye_cancel(struct switchtec_dev *dev)
298307
{
308+
int ret;
309+
int err;
299310
struct switchtec_diag_port_eye_cmd in = {
300311
.sub_cmd = MRPC_EYE_OBSERVE_CANCEL,
301312
};
302313

303-
return switchtec_diag_eye_cmd(dev, &in, sizeof(in));
314+
ret = switchtec_diag_eye_cmd(dev, &in, sizeof(in));
315+
316+
/* Add delay so hardware can stop completely */
317+
err = errno;
318+
usleep(200000);
319+
errno = err;
320+
321+
return ret;
304322
}
305323

306324
/**
@@ -844,7 +862,7 @@ int switchtec_diag_rcvr_ext(struct switchtec_dev *dev, int port_id,
844862
int switchtec_diag_perm_table(struct switchtec_dev *dev,
845863
struct switchtec_mrpc table[MRPC_MAX_ID])
846864
{
847-
uint32_t perms[MRPC_MAX_ID / 32];
865+
uint32_t perms[(MRPC_MAX_ID + 31) / 32];
848866
int i, ret;
849867

850868
ret = switchtec_cmd(dev, MRPC_MRPC_PERM_TABLE_GET, NULL, 0,
@@ -888,4 +906,125 @@ int switchtec_diag_refclk_ctl(struct switchtec_dev *dev, int stack_id, bool en)
888906
return switchtec_cmd(dev, MRPC_REFCLK_S, &cmd, sizeof(cmd), NULL, 0);
889907
}
890908

909+
/**
910+
* @brief Get the LTSSM log of a port on a switchtec device
911+
* @param[in] dev Switchtec device handle
912+
* @param[in] port Switchtec Port
913+
* @param[inout] log_count number of log entries
914+
* @param[out] log A pointer to an array containing the log
915+
*
916+
*/
917+
int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
918+
int port, int *log_count,
919+
struct switchtec_diag_ltssm_log *log_data)
920+
{
921+
struct {
922+
uint8_t sub_cmd;
923+
uint8_t port;
924+
uint8_t freeze;
925+
uint8_t unused;
926+
} ltssm_freeze;
927+
928+
struct {
929+
uint8_t sub_cmd;
930+
uint8_t port;
931+
} status;
932+
struct {
933+
uint32_t w0_trigger_count;
934+
uint32_t w1_trigger_count;
935+
uint8_t log_num;
936+
} status_output;
937+
938+
struct {
939+
uint8_t sub_cmd;
940+
uint8_t port;
941+
uint8_t log_index;
942+
uint8_t no_of_logs;
943+
} log_dump;
944+
struct {
945+
uint32_t dw0;
946+
uint32_t dw1;
947+
} log_dump_out[256];
948+
949+
uint32_t dw1;
950+
uint32_t dw0;
951+
int major;
952+
int minor;
953+
int rate;
954+
int ret;
955+
int i;
956+
957+
/* freeze logs */
958+
ltssm_freeze.sub_cmd = 14;
959+
ltssm_freeze.port = port;
960+
ltssm_freeze.freeze = 1;
961+
962+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &ltssm_freeze,
963+
sizeof(ltssm_freeze), NULL, 0);
964+
if (ret)
965+
return ret;
966+
967+
/* get number of entries */
968+
status.sub_cmd = 13;
969+
status.port = port;
970+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &status,
971+
sizeof(status), &status_output,
972+
sizeof(status_output));
973+
if (ret)
974+
return ret;
975+
976+
if (status_output.log_num < *log_count)
977+
*log_count = status_output.log_num;
978+
979+
/* get log data */
980+
log_dump.sub_cmd = 15;
981+
log_dump.port = port;
982+
log_dump.log_index = 0;
983+
log_dump.no_of_logs = *log_count;
984+
if(log_dump.no_of_logs <= 126) {
985+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
986+
sizeof(log_dump), log_dump_out,
987+
8 * log_dump.no_of_logs);
988+
if (ret)
989+
return ret;
990+
} else {
991+
log_dump.no_of_logs = 126;
992+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
993+
sizeof(log_dump), log_dump_out,
994+
8 * log_dump.no_of_logs);
995+
if (ret)
996+
return ret;
997+
998+
log_dump.log_index = 126;
999+
log_dump.no_of_logs = *log_count - 126;
1000+
1001+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1002+
sizeof(log_dump), log_dump_out + 126,
1003+
8 * log_dump.no_of_logs);
1004+
if (ret)
1005+
return ret;
1006+
}
1007+
for (i = 0; i < *log_count; i++) {
1008+
dw1 = log_dump_out[i].dw1;
1009+
dw0 = log_dump_out[i].dw0;
1010+
rate = (dw0 >> 13) & 0x3;
1011+
major = (dw0 >> 7) & 0xf;
1012+
minor = (dw0 >> 3) & 0xf;
1013+
1014+
log_data[i].timestamp = dw1 & 0x3ffffff;
1015+
log_data[i].link_rate = switchtec_gen_transfers[rate + 1];
1016+
log_data[i].link_state = major | (minor << 8);
1017+
}
1018+
1019+
/* unfreeze logs */
1020+
ltssm_freeze.sub_cmd = 14;
1021+
ltssm_freeze.port = port;
1022+
ltssm_freeze.freeze = 0;
1023+
1024+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &ltssm_freeze,
1025+
sizeof(ltssm_freeze), NULL, 0);
1026+
1027+
return ret;
1028+
}
1029+
8911030
/**@}*/

0 commit comments

Comments
 (0)