Skip to content

Commit 1cf1ddc

Browse files
authored
Merge pull request #342 from BenReed161/support-diag-ltssm-cmd-for-gen5
Support diag ltssm cmd for gen5
2 parents 19a570c + 4f86533 commit 1cf1ddc

File tree

4 files changed

+214
-10
lines changed

4 files changed

+214
-10
lines changed

cli/diag.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,16 +126,20 @@ static int ltssm_log(int argc, char **argv) {
126126
DEVICE_OPTION, PORT_OPTION, {}
127127
};
128128

129-
struct switchtec_diag_ltssm_log output[128];
130129
int ret;
131130
int port;
132-
int log_count = 128;
133131
int i;
134132

135133
ret = diag_parse_common_cfg(argc, argv, CMD_DESC_LTSSM_LOG,
136134
&cfg, opts);
137135
if (ret)
138136
return ret;
137+
138+
int log_count = 512;
139+
if (switchtec_is_gen4(cfg.dev))
140+
log_count = 128;
141+
142+
struct switchtec_diag_ltssm_log output[log_count];
139143

140144
if (switchtec_is_gen3(cfg.dev)) {
141145
fprintf (stderr,

inc/switchtec/diag.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,5 +272,12 @@ struct switchtec_diag_cross_hair_get {
272272
};
273273
};
274274

275+
struct switchtec_diag_ltssm_log_dmp_out {
276+
uint32_t dw0;
277+
uint32_t ram_timestamp;
278+
uint32_t unused;
279+
uint32_t arc;
280+
};
281+
275282
#endif
276283
/**@}*/

inc/switchtec/mrpc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,12 @@ enum mrpc_sub_cmd {
277277
MRPC_CROSS_HAIR_ENABLE = 0,
278278
MRPC_CROSS_HAIR_DISABLE = 1,
279279
MRPC_CROSS_HAIR_GET = 2,
280+
281+
MRPC_LTMON_GET_STATUS_GEN4 = 13,
282+
MRPC_LTMON_FREEZE = 14,
283+
MRPC_LTMON_LOG_DUMP_GEN4 = 15,
284+
MRPC_LTMON_GET_STATUS_GEN5 = 20,
285+
MRPC_LTMON_LOG_DUMP_GEN5 = 21,
280286
};
281287

282288
#endif

lib/diag.c

Lines changed: 195 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
*/
2929

3030
#define SWITCHTEC_LIB_CORE
31+
#define SWITCHTEC_LTSSM_MAX_LOGS 61
3132

3233
#include "switchtec_priv.h"
3334
#include "switchtec/diag.h"
@@ -906,17 +907,183 @@ int switchtec_diag_refclk_ctl(struct switchtec_dev *dev, int stack_id, bool en)
906907
return switchtec_cmd(dev, MRPC_REFCLK_S, &cmd, sizeof(cmd), NULL, 0);
907908
}
908909

910+
static void switchtec_diag_ltssm_set_log_data(struct switchtec_diag_ltssm_log
911+
*log_data,
912+
struct switchtec_diag_ltssm_log_dmp_out
913+
*log_dump_out_ptr,
914+
int curr_idx, uint16_t num_of_logs)
915+
{
916+
uint32_t dw0;
917+
uint32_t timestamp;
918+
919+
int major;
920+
int minor;
921+
int rate;
922+
923+
for (int j = 0; j < num_of_logs; j++) {
924+
dw0 = log_dump_out_ptr[j].dw0;
925+
timestamp = log_dump_out_ptr[j].ram_timestamp;
926+
927+
rate = (dw0 >> 13) & 0x7;
928+
major = (dw0 >> 7) & 0x3f;
929+
minor = (dw0 >> 3) & 0xf;
930+
931+
log_data[curr_idx + j].timestamp = timestamp;
932+
log_data[curr_idx + j].link_rate = switchtec_gen_transfers[rate+1];
933+
log_data[curr_idx + j].link_state = major | (minor << 8);
934+
}
935+
}
936+
909937
/**
910-
* @brief Get the LTSSM log of a port on a switchtec device
938+
* @brief Get the LTSSM log of a port on a gen5 switchtec device
911939
* @param[in] dev Switchtec device handle
912940
* @param[in] port Switchtec Port
913941
* @param[inout] log_count number of log entries
914942
* @param[out] log A pointer to an array containing the log
915943
*
916944
*/
917-
int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
918-
int port, int *log_count,
919-
struct switchtec_diag_ltssm_log *log_data)
945+
static int switchtec_diag_ltssm_log_gen5(struct switchtec_dev *dev,
946+
int port, int *log_count,
947+
struct switchtec_diag_ltssm_log *log_data)
948+
{
949+
struct {
950+
uint8_t sub_cmd;
951+
uint8_t port;
952+
uint8_t freeze;
953+
uint8_t unused;
954+
} ltssm_freeze;
955+
956+
struct {
957+
uint8_t sub_cmd;
958+
uint8_t port;
959+
} status;
960+
961+
struct {
962+
uint16_t log_count;
963+
uint16_t w0_trigger_count;
964+
uint16_t w1_trigger_count;
965+
} status_output;
966+
967+
struct {
968+
uint8_t sub_cmd;
969+
uint8_t port;
970+
uint16_t log_index;
971+
uint16_t no_of_logs;
972+
} log_dump;
973+
974+
uint8_t log_buffer[1024];
975+
976+
struct switchtec_diag_ltssm_log_dmp_out *log_dump_out_ptr = NULL;
977+
978+
int ret;
979+
int log_dmp_size = sizeof(struct switchtec_diag_ltssm_log_dmp_out);
980+
981+
/* freeze logs */
982+
ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
983+
ltssm_freeze.port = port;
984+
ltssm_freeze.freeze = 1;
985+
986+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &ltssm_freeze,
987+
sizeof(ltssm_freeze), NULL, 0);
988+
if (ret)
989+
return ret;
990+
991+
/* get number of entries */
992+
status.sub_cmd = MRPC_LTMON_GET_STATUS_GEN5;
993+
status.port = port;
994+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &status,
995+
sizeof(status), &status_output,
996+
sizeof(status_output));
997+
if (ret)
998+
return ret;
999+
1000+
*log_count = status_output.log_count;
1001+
1002+
/* get log data */
1003+
log_dump.sub_cmd = MRPC_LTMON_LOG_DUMP_GEN5;
1004+
log_dump.port = port;
1005+
log_dump.log_index = 0;
1006+
log_dump.no_of_logs = *log_count;
1007+
1008+
if(log_dump.no_of_logs <= SWITCHTEC_LTSSM_MAX_LOGS) {
1009+
/* Single buffer log case */
1010+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &log_dump,
1011+
sizeof(log_dump), &log_buffer[0],
1012+
log_dump.no_of_logs * log_dmp_size + 4);
1013+
if (ret)
1014+
return ret;
1015+
log_dump_out_ptr =
1016+
(struct switchtec_diag_ltssm_log_dmp_out *)
1017+
&(log_buffer[4]);
1018+
1019+
switchtec_diag_ltssm_set_log_data(log_data,
1020+
log_dump_out_ptr,
1021+
0, log_dump.no_of_logs);
1022+
} else {
1023+
/* Multiple buffer log case */
1024+
int buff_count = log_dump.no_of_logs / SWITCHTEC_LTSSM_MAX_LOGS;
1025+
int curr_idx = 0;
1026+
int buffer_size = SWITCHTEC_LTSSM_MAX_LOGS * log_dmp_size + 4;
1027+
1028+
for (int i = 0; i < buff_count; i++) {
1029+
log_dump.no_of_logs = SWITCHTEC_LTSSM_MAX_LOGS;
1030+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG,
1031+
&log_dump, sizeof(log_dump),
1032+
&log_buffer[0], buffer_size);
1033+
if (ret)
1034+
return ret;
1035+
log_dump_out_ptr =
1036+
(struct switchtec_diag_ltssm_log_dmp_out *)
1037+
&(log_buffer[4]);
1038+
1039+
switchtec_diag_ltssm_set_log_data(log_data,
1040+
log_dump_out_ptr,
1041+
curr_idx,
1042+
log_dump.no_of_logs);
1043+
curr_idx += SWITCHTEC_LTSSM_MAX_LOGS;
1044+
log_dump.log_index = curr_idx;
1045+
}
1046+
if (*log_count % SWITCHTEC_LTSSM_MAX_LOGS) {
1047+
log_dump.no_of_logs = *log_count - curr_idx;
1048+
buffer_size = log_dump.no_of_logs * log_dmp_size + 4;
1049+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG,
1050+
&log_dump, sizeof(log_dump),
1051+
&log_buffer[0], buffer_size);
1052+
if (ret)
1053+
return ret;
1054+
log_dump_out_ptr =
1055+
(struct switchtec_diag_ltssm_log_dmp_out *)
1056+
&(log_buffer[4]);
1057+
1058+
switchtec_diag_ltssm_set_log_data(log_data,
1059+
log_dump_out_ptr,
1060+
curr_idx,
1061+
log_dump.no_of_logs);
1062+
}
1063+
}
1064+
1065+
/* unfreeze logs */
1066+
ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
1067+
ltssm_freeze.port = port;
1068+
ltssm_freeze.freeze = 0;
1069+
1070+
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &ltssm_freeze,
1071+
sizeof(ltssm_freeze), NULL, 0);
1072+
1073+
return ret;
1074+
}
1075+
1076+
/**
1077+
* @brief Get the LTSSM log of a port on a gen4 switchtec device
1078+
* @param[in] dev Switchtec device handle
1079+
* @param[in] port Switchtec Port
1080+
* @param[inout] log_count number of log entries
1081+
* @param[out] log A pointer to an array containing the log
1082+
*
1083+
*/
1084+
static int switchtec_diag_ltssm_log_gen4(struct switchtec_dev *dev,
1085+
int port, int *log_count,
1086+
struct switchtec_diag_ltssm_log *log_data)
9201087
{
9211088
struct {
9221089
uint8_t sub_cmd;
@@ -955,7 +1122,7 @@ int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
9551122
int i;
9561123

9571124
/* freeze logs */
958-
ltssm_freeze.sub_cmd = 14;
1125+
ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
9591126
ltssm_freeze.port = port;
9601127
ltssm_freeze.freeze = 1;
9611128

@@ -965,7 +1132,7 @@ int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
9651132
return ret;
9661133

9671134
/* get number of entries */
968-
status.sub_cmd = 13;
1135+
status.sub_cmd = MRPC_LTMON_GET_STATUS_GEN4;
9691136
status.port = port;
9701137
ret = switchtec_cmd(dev, MRPC_DIAG_PORT_LTSSM_LOG, &status,
9711138
sizeof(status), &status_output,
@@ -977,7 +1144,7 @@ int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
9771144
*log_count = status_output.log_num;
9781145

9791146
/* get log data */
980-
log_dump.sub_cmd = 15;
1147+
log_dump.sub_cmd = MRPC_LTMON_LOG_DUMP_GEN4;
9811148
log_dump.port = port;
9821149
log_dump.log_index = 0;
9831150
log_dump.no_of_logs = *log_count;
@@ -1017,7 +1184,7 @@ int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
10171184
}
10181185

10191186
/* unfreeze logs */
1020-
ltssm_freeze.sub_cmd = 14;
1187+
ltssm_freeze.sub_cmd = MRPC_LTMON_FREEZE;
10211188
ltssm_freeze.port = port;
10221189
ltssm_freeze.freeze = 0;
10231190

@@ -1027,4 +1194,24 @@ int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
10271194
return ret;
10281195
}
10291196

1197+
/**
1198+
* @brief Determine the generation and call the related LTSSM log func
1199+
* @param[in] dev Switchtec device handle
1200+
* @param[in] port Switchtec Port
1201+
* @param[inout] log_count number of log entries
1202+
* @param[out] log A pointer to an array containing the log
1203+
*
1204+
*/
1205+
int switchtec_diag_ltssm_log(struct switchtec_dev *dev,
1206+
int port, int *log_count,
1207+
struct switchtec_diag_ltssm_log *log_data)
1208+
{
1209+
int ret;
1210+
if (switchtec_is_gen5(dev))
1211+
ret = switchtec_diag_ltssm_log_gen5(dev, port, log_count, log_data);
1212+
else
1213+
ret = switchtec_diag_ltssm_log_gen4(dev, port, log_count, log_data);
1214+
return ret;
1215+
}
1216+
10301217
/**@}*/

0 commit comments

Comments
 (0)