Skip to content

Commit f0aed95

Browse files
Chetana2791BenReed161
authored andcommitted
Add support for Gen5 Eye capture
Updated eye command gen5 mrpc. Add gen5 eye mrpc calls to original switchtec user eye command and added gen5 detection as part of the function. Added additional API function for calling the gen5 read functionality for reading the status since the gen5 eye observe has no output unlike gen4 to denote the status.
1 parent 70eaa45 commit f0aed95

File tree

7 files changed

+352
-50
lines changed

7 files changed

+352
-50
lines changed

cli/diag.c

Lines changed: 111 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131

3232
#include <switchtec/switchtec.h>
3333
#include <switchtec/utils.h>
34+
#include <switchtec/endian.h>
3435

3536
#include <limits.h>
3637
#include <locale.h>
@@ -325,7 +326,9 @@ static void print_eye_csv(FILE *f, struct range *X, struct range *Y,
325326
int x, y, i, j = 0;
326327

327328
fprintf(f, "%s\n", title);
328-
fprintf(f, "interval_ms, %d\n", interval);
329+
330+
if (interval > -1)
331+
fprintf(f, "interval_ms, %d\n", interval);
329332

330333
for_range(x, X)
331334
fprintf(f, ", %d", x);
@@ -1190,7 +1193,7 @@ static double *eye_observe_dev(struct switchtec_dev *dev, int port_id,
11901193
goto out_err;
11911194
}
11921195

1193-
ret = switchtec_diag_eye_start(dev, lane_mask, X, Y, interval);
1196+
ret = switchtec_diag_eye_start(dev, lane_mask, X, Y, interval, 0);
11941197
if (ret) {
11951198
switchtec_perror("eye_start");
11961199
goto out_err;
@@ -1249,7 +1252,8 @@ static double *eye_observe_dev(struct switchtec_dev *dev, int port_id,
12491252

12501253
static int eye_graph(enum output_format fmt, struct range *X, struct range *Y,
12511254
double *pixels, const char *title,
1252-
struct switchtec_diag_cross_hair *ch)
1255+
struct switchtec_diag_cross_hair *ch,
1256+
struct switchtec_dev *dev)
12531257
{
12541258
size_t pixel_cnt = RANGE_CNT(X) * RANGE_CNT(Y);
12551259
int data[pixel_cnt], shades[pixel_cnt];
@@ -1277,14 +1281,77 @@ static int eye_graph(enum output_format fmt, struct range *X, struct range *Y,
12771281
}
12781282

12791283
if (fmt == FMT_TEXT) {
1280-
graph_draw_text(X, Y, data, title, 'T', 'V');
1284+
if (switchtec_is_gen5(dev))
1285+
graph_draw_text_no_invert(X, Y, data, title, 'P', 'B');
1286+
else
1287+
graph_draw_text(X, Y, data, title, 'T', 'V');
12811288
if (status_ptr)
12821289
printf("\n %s\n", status_ptr);
12831290
return 0;
12841291
}
12851292

1286-
return graph_draw_win(X, Y, data, shades, title, 'T', 'V',
1287-
status_ptr, NULL, NULL);
1293+
if (switchtec_is_gen5(dev))
1294+
return graph_draw_win(X, Y, data, shades, title, 'P', 'B',
1295+
status_ptr, NULL, NULL);
1296+
else
1297+
return graph_draw_win(X, Y, data, shades, title, 'T', 'V',
1298+
status_ptr, NULL, NULL);
1299+
}
1300+
1301+
static double *eye_capture_dev_gen5(struct switchtec_dev *dev,
1302+
int port_id, int lane_id, int num_lanes,
1303+
int capture_depth, int* num_phases, int* gen)
1304+
{
1305+
int bin, j, ret, first_lane, num_phases_l, stride;
1306+
int lane_mask[4] = {};
1307+
struct switchtec_status sw_status;
1308+
double tmp[60];
1309+
double* ber_data = NULL;
1310+
1311+
ret = switchtec_calc_lane_mask(dev, port_id, lane_id, num_lanes,
1312+
lane_mask, &sw_status);
1313+
if (ret < 0) {
1314+
switchtec_perror("Invalid lane");
1315+
return NULL;
1316+
}
1317+
1318+
ret = switchtec_diag_eye_start(dev, lane_mask, NULL, NULL, 0,
1319+
capture_depth);
1320+
if (ret) {
1321+
switchtec_perror("eye_run");
1322+
return NULL;
1323+
}
1324+
1325+
first_lane = switchtec_calc_lane_id(dev, port_id, lane_id, NULL);
1326+
for (j = 0; j < num_lanes; j++) {
1327+
for (bin = 0; bin < 64; bin++) {
1328+
ret = switchtec_diag_eye_read(dev, first_lane + j, bin,
1329+
&num_phases_l, tmp);
1330+
if (ret) {
1331+
switchtec_perror("eye_read");
1332+
if (ber_data)
1333+
free(ber_data);
1334+
return NULL;
1335+
}
1336+
1337+
if (!ber_data) {
1338+
stride = 64 * num_phases_l;
1339+
ber_data = calloc(num_lanes * stride,
1340+
sizeof(double));
1341+
if (!ber_data) {
1342+
perror("allocating BER data");
1343+
return NULL;
1344+
}
1345+
}
1346+
1347+
memcpy(&ber_data[(j * stride) + (bin * num_phases_l)],
1348+
tmp, num_phases_l * sizeof(double));
1349+
}
1350+
}
1351+
1352+
*gen = sw_status.link_rate;
1353+
*num_phases = num_phases_l;
1354+
return ber_data;
12881355
}
12891356

12901357
#define CMD_DESC_EYE "Capture PCIe Eye Errors"
@@ -1294,13 +1361,14 @@ static int eye(int argc, char **argv)
12941361
struct switchtec_diag_cross_hair ch = {}, *ch_ptr = NULL;
12951362
char title[128], subtitle[50];
12961363
double *pixels = NULL;
1297-
int ret, gen;
1364+
int num_phases, ret, gen;
12981365

12991366
static struct {
13001367
struct switchtec_dev *dev;
13011368
int fmt;
13021369
int port_id;
13031370
int lane_id;
1371+
int capture_depth;
13041372
int num_lanes;
13051373
int mode;
13061374
struct range x_range, y_range;
@@ -1313,6 +1381,7 @@ static int eye(int argc, char **argv)
13131381
.fmt = FMT_DEFAULT,
13141382
.port_id = -1,
13151383
.lane_id = 0,
1384+
.capture_depth = 24,
13161385
.num_lanes = 1,
13171386
.mode = SWITCHTEC_DIAG_EYE_RAW,
13181387
.x_range.start = 0,
@@ -1327,7 +1396,7 @@ static int eye(int argc, char **argv)
13271396
DEVICE_OPTION_OPTIONAL,
13281397
{"crosshair", 'C', "FILE", CFG_FILE_R, &cfg.crosshair_file,
13291398
required_argument,
1330-
"optionally, superimpose a crosshair CSV onto the result"},
1399+
"optionally, superimpose a crosshair CSV onto the result (Not supported in Gen 5)"},
13311400
{"format", 'f', "FMT", CFG_CHOICES, &cfg.fmt, required_argument,
13321401
"output format (default: " FMT_DEFAULT_STR ")",
13331402
.choices=output_fmt_choices},
@@ -1357,12 +1426,24 @@ static int eye(int argc, char **argv)
13571426
required_argument, "voltage step (default: 5)"},
13581427
{"interval", 'i', "NUM", CFG_NONNEGATIVE, &cfg.step_interval,
13591428
required_argument, "step interval in ms (default: 1ms)"},
1429+
{"capture-depth", 'd', "NUM", CFG_POSITIVE, &cfg.capture_depth,
1430+
required_argument, "capture depth (6 to 40; default: 24)"},
13601431
{NULL}};
13611432

13621433
argconfig_parse(argc, argv, CMD_DESC_EYE, opts, &cfg,
13631434
sizeof(cfg));
13641435

1436+
if (cfg.dev != NULL && switchtec_is_gen5(cfg.dev)) {
1437+
cfg.y_range.start = 0;
1438+
cfg.y_range.end = 63;
1439+
cfg.y_range.step = 1;
1440+
}
1441+
13651442
if (cfg.crosshair_file) {
1443+
if (switchtec_is_gen5(cfg.dev)) {
1444+
fprintf(stderr, "Crosshair superimpose not suppored in Gen 5\n");
1445+
return -1;
1446+
}
13661447
ret = load_crosshair_csv(cfg.crosshair_file, &ch, subtitle,
13671448
sizeof(subtitle));
13681449
if (ret) {
@@ -1373,11 +1454,11 @@ static int eye(int argc, char **argv)
13731454

13741455
ch_ptr = &ch;
13751456
}
1376-
1457+
13771458
if (cfg.plot_file) {
13781459
pixels = load_eye_csv(cfg.plot_file, &cfg.x_range,
1379-
&cfg.y_range, subtitle, sizeof(subtitle),
1380-
&cfg.step_interval);
1460+
&cfg.y_range, subtitle, sizeof(subtitle),
1461+
&cfg.step_interval);
13811462
if (!pixels) {
13821463
fprintf(stderr, "Unable to parse CSV file: %s\n",
13831464
cfg.plot_filename);
@@ -1433,12 +1514,25 @@ static int eye(int argc, char **argv)
14331514
}
14341515

14351516
if (!pixels) {
1436-
pixels = eye_observe_dev(cfg.dev, cfg.port_id, cfg.lane_id,
1437-
cfg.num_lanes, cfg.mode, cfg.step_interval,
1438-
&cfg.x_range, &cfg.y_range, &gen);
1439-
if (!pixels)
1440-
return -1;
1517+
if (switchtec_is_gen5(cfg.dev)) {
1518+
pixels = eye_capture_dev_gen5(cfg.dev, cfg.port_id,
1519+
cfg.lane_id, cfg.num_lanes,
1520+
cfg.capture_depth,
1521+
&num_phases, &gen);
1522+
if (!pixels)
1523+
return -1;
14411524

1525+
cfg.x_range.end = num_phases - 1;
1526+
}
1527+
else {
1528+
pixels = eye_observe_dev(cfg.dev, cfg.port_id,
1529+
cfg.lane_id, cfg.num_lanes,
1530+
cfg.mode, cfg.step_interval,
1531+
&cfg.x_range, &cfg.y_range,
1532+
&gen);
1533+
if (!pixels)
1534+
return -1;
1535+
}
14421536
eye_set_title(title, cfg.port_id, cfg.lane_id, gen);
14431537
}
14441538

@@ -1451,7 +1545,7 @@ static int eye(int argc, char **argv)
14511545
}
14521546

14531547
ret = eye_graph(cfg.fmt, &cfg.x_range, &cfg.y_range, pixels, title,
1454-
ch_ptr);
1548+
ch_ptr, cfg.dev);
14551549

14561550
free(pixels);
14571551
return ret;

cli/graph.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,16 @@ void graph_init(void)
390390

391391
#endif /* defined(HAVE_LIBCURSES) || defined(HAVE_LIBNCURSES) */
392392

393+
int graph_draw_win_no_invert(struct range *X, struct range *Y, int *data,
394+
int *shades, const char *title, char x_title,
395+
char y_title, char *status, graph_anim_fn *anim,
396+
void *opaque)
397+
{
398+
graph_draw_text_no_invert(X, Y, data, title, x_title, y_title);
399+
return 0;
400+
}
401+
402+
393403
void graph_draw_text(struct range *X, struct range *Y, int *data,
394404
const char *title, char x_title, char y_title)
395405
{
@@ -428,3 +438,43 @@ void graph_draw_text(struct range *X, struct range *Y, int *data,
428438
j--;
429439
}
430440
}
441+
442+
void graph_draw_text_no_invert(struct range *X, struct range *Y, int *data,
443+
const char *title, char x_title, char y_title)
444+
{
445+
int stride = RANGE_CNT(X);
446+
int x, y, i = RANGE_CNT(Y) - 1;
447+
int j = Y->start;
448+
int space_ch;
449+
450+
printf(" %s\n\n", title);
451+
452+
printf(" ");
453+
for_range(x, X)
454+
printf("%d ", x / 10);
455+
printf("\n");
456+
457+
printf(" ");
458+
for_range(x, X)
459+
printf("%d ", x % 10);
460+
printf("\n\n");
461+
462+
for_range(y, Y) {
463+
printf("%5d ", y);
464+
i = 0;
465+
for_range(x, X) {
466+
space_ch = ' ';
467+
if (data[j * stride + i] == GRAPH_TEXT_HLINE ||
468+
data[j * stride + i] == GRAPH_TEXT_PLUS)
469+
space_ch = GRAPH_TEXT_HLINE;
470+
else if (data[j * stride + i] == '-' ||
471+
data[j * stride + i] == '+')
472+
space_ch = '-';
473+
474+
printf("%lc%lc", data[j * stride + i], space_ch);
475+
i++;
476+
}
477+
printf("\n");
478+
j++;
479+
}
480+
}

cli/graph.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,10 @@ void graph_draw_text(struct range *X, struct range *Y, int *data,
6868
int graph_draw_win(struct range *X, struct range *Y, int *data, int *shades,
6969
const char *title, char x_title, char y_title, char *status,
7070
graph_anim_fn *anim, void *opaque);
71-
71+
void graph_draw_text_no_invert(struct range *X, struct range *Y, int *data,
72+
const char *title, char x_title, char y_title);
73+
int graph_draw_win_no_invert(struct range *X, struct range *Y, int *data,
74+
int *shades, const char *title, char x_title,
75+
char y_title, char *status, graph_anim_fn *anim,
76+
void *opaque);
7277
#endif

inc/switchtec/diag.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,15 @@ struct switchtec_diag_port_eye_fetch {
242242
};
243243
};
244244

245+
246+
struct switchtec_gen5_diag_eye_run_in {
247+
uint8_t sub_cmd;
248+
uint8_t capture_depth;
249+
uint8_t timeout_disable;
250+
uint8_t resvd1;
251+
uint32_t lane_mask[4];
252+
};
253+
245254
struct switchtec_diag_cross_hair_in {
246255
uint8_t sub_cmd;
247256
uint8_t lane_id;

inc/switchtec/mrpc.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ enum mrpc_cmd {
124124
MRPC_SN_VER_GET_GEN5 = 0x119,
125125
MRPC_DBG_UNLOCK_GEN5 = 0x11A,
126126
MRPC_BOOTUP_RESUME_GEN5 = 0x11B,
127+
MRPC_GEN5_EYE_CAPTURE = 0x142,
127128
MRPC_FTDC_LOG_DUMP = 0x147,
128-
129129
MRPC_MAX_ID = 0x148,
130130
};
131131

@@ -280,6 +280,10 @@ enum mrpc_sub_cmd {
280280
MRPC_EYE_OBSERVE_SET_DATA_MODE = 3,
281281
MRPC_EYE_OBSERVE_GET_DATA_MODE = 4,
282282

283+
MRPC_EYE_CAP_RUN_GEN5 = 0,
284+
MRPC_EYE_CAP_STATUS_GEN5 = 1,
285+
MRPC_EYE_CAP_READ_GEN5 = 2,
286+
283287
MRPC_CROSS_HAIR_ENABLE = 0,
284288
MRPC_CROSS_HAIR_DISABLE = 1,
285289
MRPC_CROSS_HAIR_GET = 2,

0 commit comments

Comments
 (0)