Skip to content

Commit 4f86533

Browse files
committed
Added support for ltssm diag command for gen5
Added new set of function to handle gen5 ltssm log requests. Data structures to handle I/O of the MRPC data have been updated to gen5 structures and offsets. Sub command ID has been updated to gen5 subcommand IDs. Added buffering option for logs larger than 61 entries to send multiple ltssm MRPC commands as per the spec.
1 parent 1c0ced0 commit 4f86533

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
@@ -276,6 +276,12 @@ enum mrpc_sub_cmd {
276276
MRPC_CROSS_HAIR_ENABLE = 0,
277277
MRPC_CROSS_HAIR_DISABLE = 1,
278278
MRPC_CROSS_HAIR_GET = 2,
279+
280+
MRPC_LTMON_GET_STATUS_GEN4 = 13,
281+
MRPC_LTMON_FREEZE = 14,
282+
MRPC_LTMON_LOG_DUMP_GEN4 = 15,
283+
MRPC_LTMON_GET_STATUS_GEN5 = 20,
284+
MRPC_LTMON_LOG_DUMP_GEN5 = 21,
279285
};
280286

281287
#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)