Commit 3521d348 authored by Adam Wujek's avatar Adam Wujek 💬

Merge branch 'adam-wrs_sfp_dump'

Add a new tool "wrs_sfp_dump" to dump SFP's memory.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parents 6b2888d9 ffa8a089
......@@ -1198,6 +1198,12 @@ The following tools and scripts are provided:
The tool allows to setup the parameters of a clock generated on the @i{clk2}
SMC.
@item wrs_sfp_dump
Dump the content of SFPs internal memory. Please note that this tool
cannot be used in production due to the race condition of i2c
transactions. The race can cause errors while reading SFPs memory,
wrong notification of LEDs, the false insert/remove SFP notifications.
@c FIXME: document lm32-vuart rtu_stat spll_dbg_proxy
@c FIXME: document wrs_pstats
@end table
......
......@@ -232,7 +232,17 @@ int shw_sfp_header_verify_base(struct shw_sfp_header *head)
sum += ((uint8_t *) head)[i];
sum &= 0xff;
return (sum == head->cc_base) ? 0 : -1;
if (sum != head->cc_base) {
pr_error("shw_sfp_header_verify_base: Wrong base checksum! "
"(expected 0x%02x, calculated 0x%02x)\n",
head->cc_base, sum);
if (wrs_msg_level >= LOG_DEBUG) {
shw_sfp_print_header(head);
shw_sfp_header_dump(head);
}
return -1;
}
return 0;
}
int shw_sfp_header_verify_ext(struct shw_sfp_header *head)
......@@ -244,7 +254,17 @@ int shw_sfp_header_verify_ext(struct shw_sfp_header *head)
sum += ((uint8_t *) head)[i];
sum &= 0xff;
return (sum == head->cc_ext) ? 0 : -1;
if (sum != head->cc_ext) {
pr_error("shw_sfp_header_verify_ext: Wrong ext checksum! "
"(expected 0x%02x, calculated 0x%02x)\n",
head->cc_ext, sum);
if (wrs_msg_level >= LOG_DEBUG) {
shw_sfp_print_header(head);
shw_sfp_header_dump(head);
}
return -1;
}
return 0;
}
int shw_sfp_header_verify(struct shw_sfp_header *head)
......@@ -516,18 +536,24 @@ int shw_sfp_read_header(int num, struct shw_sfp_header *head)
{
int ret;
if (shw_sfp_id(num) < 0)
if (shw_sfp_id(num) < 0) {
pr_error("shw_sfp_read_header: wrong SFP num %d\n", num);
return -1;
}
ret = shw_sfp_module_scan();
if (!(ret & (1 << num)))
if (!(ret & (1 << num))) {
pr_error("shw_sfp_read_header: SFP not present %d\n", num);
return -2;
}
ret =
shw_sfp_read(num, I2C_SFP_ADDRESS, 0x0,
sizeof(struct shw_sfp_header), (uint8_t *) head);
if (ret == I2C_DEV_NOT_FOUND)
if (ret == I2C_DEV_NOT_FOUND) {
pr_error("shw_sfp_read_header: I2C_DEV_NOT_FOUND\n");
return -ENODEV;
}
return 0;
}
......
......@@ -21,4 +21,5 @@ nbtee
wrs_auxclk
wrs_checkcfg
mkpasswd
wrs_status_led
\ No newline at end of file
wrs_status_led
wrs_sfp_dump
......@@ -8,6 +8,7 @@ TOOLS += wrs_auxclk
TOOLS += wrs_checkcfg
TOOLS += wrs_status_led
TOOLS += mkpasswd
TOOLS += wrs_sfp_dump
PPSI_CONFIG = ../ppsi/include/generated/autoconf.h
WR_INSTALL_ROOT ?= /usr/lib/white-rabbit
......
#include <stdlib.h>
#include <unistd.h>
#include <libwr/switch_hw.h>
#include <libwr/wrs-msg.h>
#include <libwr/shw_io.h>
/* for shw_sfp_buses_init and shw_sfp_print_header*/
#include "../libwr/i2c_sfp.h"
void print_info(char *prgname)
{
printf("usage: %s [parameters]\n", prgname);
printf(""
" Dump sfp header info for all ports\n"
" -p <num> Dump sfp header for specific port (1-18)\n"
" -x Dump sfp header also in hex\n"
" -h Show this message\n"
" -q Decrease verbosity\n"
" -v Increase verbosity\n"
"\n"
"NOTE: Be carefull! All reads (i2c transfers) are in race with hal!\n"
);
}
int main(int argc, char **argv)
{
int c;
struct shw_sfp_header shdr;
int err;
int nports;
int dump_port;
int i;
int dump_hex_header = 0;
wrs_msg_init(argc, argv);
nports = 18;
dump_port = 1;
while ((c = getopt(argc, argv, "ahqvp:x")) != -1) {
switch (c) {
case 'p':
dump_port = atoi(optarg);
if (dump_port) {
nports = dump_port;
} else {
printf("Wrong port number!\n");
print_info(argv[0]);
exit(1);
}
break;
case 'x':
dump_hex_header = 1;
break;
case 'q': break; /* done in wrs_msg_init() */
case 'v': break; /* done in wrs_msg_init() */
case 'h':
default:
print_info(argv[0]);
exit(1);
}
}
/* init i2c, be carefull all i2c transfers are in race with hal! */
assert_init(shw_io_init());
assert_init(shw_fpga_mmap_init());
assert_init(shw_sfp_buses_init());
for (i = dump_port; i <= nports; i++) {
printf("========= port %d =========\n", i);
err = shw_sfp_read_verify_header(i - 1, &shdr);
if (err == -2) {
pr_error("SFP module not inserted in port %d. Failed "
"to read SFP configuration header\n", i);
} else if (err < 0) {
pr_error("Failed to read SFP configuration header on "
"port %d\n", i);
} else {
shw_sfp_print_header(&shdr);
if (dump_hex_header) {
shw_sfp_header_dump(&shdr);
}
}
}
return 0;
}
......@@ -82,7 +82,9 @@ void usage(char *name)
"\t-h help\n"
"\t-p polynomial for hash calculation. Possible values are CCITT, IBM, DECT\n"
"\t-r aging resolution (in sec). 20 sec by default\n"
"\t-t aging time (10 to 10000 sec). 300 sec by default.\n",
"\t-t aging time (10 to 10000 sec). 300 sec by default.\n"
"\t-q decrease verbosity\n"
"\t-v dncrease verbosity\n",
name);
exit(1);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment