Commit 3f05b29c authored by Adam Wujek's avatar Adam Wujek 💬

userspace/wrsw_hal: save Diagnostic Monitoring data from SFP in HAL

Kconfig:
--add CONFIG_READ_SFP_DIAG_ENABLE
libwr:
--add the function shw_sfp_update_dom to update only needed values in the future
--increase HAL_SHMEM_VERSION due to the changes in structures
wrs_dump_shmem
--add new fields
HAL:
--read DOM (Diagnostic Monitoring data) from SFP's eeprom at plug and once
  per second
PPSI:
--uplift hal shmem header
wrs_sfp_dump:
--support reading SFP's DOM from HAL
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent de57d4ae
...@@ -860,7 +860,11 @@ config FAN_HYSTERESIS_PWM_VAL ...@@ -860,7 +860,11 @@ config FAN_HYSTERESIS_PWM_VAL
PWM value used to drive fans. Range from 4 to 1000. PWM value used to drive fans. Range from 4 to 1000.
endmenu endmenu
config READ_SFP_DIAG_ENABLE
bool "Read SFPs Diagnostic Monitoring"
default n
help
Let HAL to read Diagnostic Monitoring from SFP's eeprom.
endmenu endmenu
menu "RTU HP mask" menu "RTU HP mask"
......
...@@ -834,6 +834,11 @@ value is changed by the web interface, proper action is taken. ...@@ -834,6 +834,11 @@ value is changed by the web interface, proper action is taken.
below @t{CONFIG_FAN_HYSTERESIS_T_DISABLE}. These options are intended to below @t{CONFIG_FAN_HYSTERESIS_T_DISABLE}. These options are intended to
be used during development to reduce noise generated by switch. be used during development to reduce noise generated by switch.
@item CONFIG_READ_SFP_DIAG_ENABLE
Let HAL to read Diagnostic Monitoring from SFP's eeprom like
temperature, TX/RX power etc.
@item CONFIG_RTU_HP_MASK_ENABLE @item CONFIG_RTU_HP_MASK_ENABLE
@itemx CONFIG_RTU_HP_MASK_VAL @itemx CONFIG_RTU_HP_MASK_VAL
......
...@@ -608,6 +608,13 @@ int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom) ...@@ -608,6 +608,13 @@ int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom)
return 0; return 0;
} }
/* Function to update SFP's Diagnostic Monitoring data from SFP's eeprom */
int shw_sfp_update_dom(int num, struct shw_sfp_dom *dom)
{
/* For now copy entire eeprom */
return shw_sfp_read_dom(num, dom);
}
int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head) int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head)
{ {
int ret; int ret;
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
#define HAL_PORT_STATE_CALIBRATION 3 #define HAL_PORT_STATE_CALIBRATION 3
#define HAL_PORT_STATE_LOCKING 4 #define HAL_PORT_STATE_LOCKING 4
/* Read temperature from SFPs */
#define READ_SFP_DIAG_ENABLE 1
#define READ_SFP_DIAG_DISABLE 0
#define DEFAULT_T2_PHASE_TRANS 0 #define DEFAULT_T2_PHASE_TRANS 0
#define DEFAULT_T4_PHASE_TRANS 0 #define DEFAULT_T4_PHASE_TRANS 0
...@@ -46,6 +50,7 @@ typedef struct hal_port_calibration { ...@@ -46,6 +50,7 @@ typedef struct hal_port_calibration {
struct shw_sfp_caldata sfp; struct shw_sfp_caldata sfp;
struct shw_sfp_header sfp_header_raw; struct shw_sfp_header sfp_header_raw;
struct shw_sfp_dom sfp_dom_raw;
} hal_port_calibration_t; } hal_port_calibration_t;
/* Internal port state structure */ /* Internal port state structure */
...@@ -100,6 +105,9 @@ struct hal_port_state { ...@@ -100,6 +105,9 @@ struct hal_port_state {
/* Endpoint's base address */ /* Endpoint's base address */
uint32_t ep_base; uint32_t ep_base;
/* whether SFP has diagnostic Monitoring capability */
int has_sfp_diag;
}; };
struct hal_temp_sensors { struct hal_temp_sensors {
...@@ -110,13 +118,15 @@ struct hal_temp_sensors { ...@@ -110,13 +118,15 @@ struct hal_temp_sensors {
}; };
/* This is the overall structure stored in shared memory */ /* This is the overall structure stored in shared memory */
#define HAL_SHMEM_VERSION 9 /* Version 9 because of adding sfp_header_raw */ #define HAL_SHMEM_VERSION 10 /* Version 10 because of adding sfp_dom_raw
has_sfp_diag and read_sfp_diag */
struct hal_shmem_header { struct hal_shmem_header {
int nports; int nports;
int hal_mode; int hal_mode;
struct hal_port_state *ports; struct hal_port_state *ports;
struct hal_temp_sensors temp; struct hal_temp_sensors temp;
int read_sfp_diag;
}; };
static inline int state_up(int state) static inline int state_up(int state)
......
...@@ -30,6 +30,16 @@ ...@@ -30,6 +30,16 @@
#define SFP_SPEED_1Gb_10 0x0A /* Unfortunatelly the above is not always true, #define SFP_SPEED_1Gb_10 0x0A /* Unfortunatelly the above is not always true,
* e.g. Cisco copper SFP (MGBT1) says simply 10 and not 13.*/ * e.g. Cisco copper SFP (MGBT1) says simply 10 and not 13.*/
#define SFP_DIAGNOSTIC_IMPLEMENTED (1 << 6) /* Digital diagnostic monitoring
implemented. "1" for compliance
with SFF-8472 */
#define SFP_ADDR_CHANGE_REQ (1 << 2) /* Bit 2 indicates whether or not it is
necessary for the host to perform an
address change sequence before
accessing information at 2-wire serial
address A2h. */
struct shw_sfp_caldata { struct shw_sfp_caldata {
uint32_t flags; uint32_t flags;
/* /*
...@@ -80,7 +90,9 @@ struct shw_sfp_header { ...@@ -80,7 +90,9 @@ struct shw_sfp_header {
uint8_t br_min; uint8_t br_min;
uint8_t vendor_serial[16]; uint8_t vendor_serial[16];
uint8_t date_code[8]; uint8_t date_code[8];
uint8_t reserved[3]; uint8_t diagnostic_monitoring_type;
uint8_t enhanced_options;
uint8_t sff_8472_compliance;
uint8_t cc_ext; uint8_t cc_ext;
} __attribute__ ((packed)); } __attribute__ ((packed));
...@@ -177,6 +189,9 @@ int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head); ...@@ -177,6 +189,9 @@ int shw_sfp_read_verify_header(int num, struct shw_sfp_header *head);
/* Read the SFP diagnostics page */ /* Read the SFP diagnostics page */
int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom); int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom);
/* Update the SFP diagnostics page */
int shw_sfp_update_dom(int num, struct shw_sfp_dom *dom);
/* Decode and print the SFP real time diagnostics */ /* Decode and print the SFP real time diagnostics */
void shw_sfp_print_dom(struct shw_sfp_dom * dom); void shw_sfp_print_dom(struct shw_sfp_dom * dom);
......
ppsi @ 6f9508cf
Subproject commit 3ece12b3824d42910145fe0fa622d00cac1597ef Subproject commit 6f9508cfb22a78f00fab8db6ff2e6c84441dcb3a
...@@ -382,6 +382,7 @@ void dump_many_fields(void *addr, struct dump_info *info, int ninfo) ...@@ -382,6 +382,7 @@ void dump_many_fields(void *addr, struct dump_info *info, int ninfo)
struct dump_info hal_shmem_info [] = { struct dump_info hal_shmem_info [] = {
DUMP_FIELD(int, nports), DUMP_FIELD(int, nports),
DUMP_FIELD(int, hal_mode), DUMP_FIELD(int, hal_mode),
DUMP_FIELD(int, read_sfp_diag),
DUMP_FIELD(sensor_temp, temp.fpga), DUMP_FIELD(sensor_temp, temp.fpga),
DUMP_FIELD(sensor_temp, temp.pll), DUMP_FIELD(sensor_temp, temp.pll),
DUMP_FIELD(sensor_temp, temp.psl), DUMP_FIELD(sensor_temp, temp.psl),
...@@ -433,6 +434,7 @@ struct dump_info hal_port_info [] = { ...@@ -433,6 +434,7 @@ struct dump_info hal_port_info [] = {
DUMP_FIELD(uint32_t, t2_phase_transition), DUMP_FIELD(uint32_t, t2_phase_transition),
DUMP_FIELD(uint32_t, t4_phase_transition), DUMP_FIELD(uint32_t, t4_phase_transition),
DUMP_FIELD(uint32_t, ep_base), DUMP_FIELD(uint32_t, ep_base),
DUMP_FIELD(int, has_sfp_diag),
}; };
int dump_hal_mem(struct wrs_shm_head *head) int dump_hal_mem(struct wrs_shm_head *head)
......
...@@ -202,7 +202,8 @@ void print_version(char *prgname) ...@@ -202,7 +202,8 @@ void print_version(char *prgname)
__GIT_USR__); __GIT_USR__);
} }
int hal_read(struct shw_sfp_header *sfp_header_local_copy) { int hal_read(struct shw_sfp_header *sfp_header_local_copy,
struct shw_sfp_dom *sfp_dom) {
unsigned ii; unsigned ii;
unsigned retries = 0; unsigned retries = 0;
int port; int port;
...@@ -215,7 +216,12 @@ int hal_read(struct shw_sfp_header *sfp_header_local_copy) { ...@@ -215,7 +216,12 @@ int hal_read(struct shw_sfp_header *sfp_header_local_copy) {
&hal_ports[port].calib.sfp_header_raw, &hal_ports[port].calib.sfp_header_raw,
sizeof(struct shw_sfp_header)); sizeof(struct shw_sfp_header));
} }
if (sfp_dom)
for (port = 0; port < hal_nports_local; port++) {
memcpy(&sfp_dom[port],
&hal_ports[port].calib.sfp_dom_raw,
sizeof(struct shw_sfp_dom));
}
retries++; retries++;
if (retries > 100) if (retries > 100)
return -1; return -1;
...@@ -282,6 +288,7 @@ int main(int argc, char **argv) ...@@ -282,6 +288,7 @@ int main(int argc, char **argv)
struct shw_sfp_header sfp_hdr; struct shw_sfp_header sfp_hdr;
struct shw_sfp_header *sfp_hdr_p; struct shw_sfp_header *sfp_hdr_p;
struct shw_sfp_dom sfp_dom; struct shw_sfp_dom sfp_dom;
struct shw_sfp_dom *sfp_dom_p;
int err; int err;
int nports; int nports;
int dump_port; int dump_port;
...@@ -293,6 +300,7 @@ int main(int argc, char **argv) ...@@ -293,6 +300,7 @@ int main(int argc, char **argv)
int sfp_data_source = 0; int sfp_data_source = 0;
/* local copy of sfp eeprom */ /* local copy of sfp eeprom */
struct shw_sfp_header hal_sfp_raw_header_lc[HAL_MAX_PORTS]; struct shw_sfp_header hal_sfp_raw_header_lc[HAL_MAX_PORTS];
struct shw_sfp_dom hal_sfp_raw_dom_lc[HAL_MAX_PORTS];
wrs_msg_init(argc, argv); wrs_msg_init(argc, argv);
...@@ -369,7 +377,7 @@ int main(int argc, char **argv) ...@@ -369,7 +377,7 @@ int main(int argc, char **argv)
if (sfp_data_source == READ_HAL) { if (sfp_data_source == READ_HAL) {
hal_init_shm(); hal_init_shm();
hal_read(hal_sfp_raw_header_lc); hal_read(hal_sfp_raw_header_lc, hal_sfp_raw_dom_lc);
printf("Reading SFP eeprom from HAL\n"); printf("Reading SFP eeprom from HAL\n");
} }
...@@ -398,9 +406,13 @@ int main(int argc, char **argv) ...@@ -398,9 +406,13 @@ int main(int argc, char **argv)
memset(&sfp_hdr, 0, sizeof(sfp_hdr)); memset(&sfp_hdr, 0, sizeof(sfp_hdr));
sfp_hdr_p = &sfp_hdr; sfp_hdr_p = &sfp_hdr;
err = shw_sfp_read_header(i - 1, sfp_hdr_p); err = shw_sfp_read_header(i - 1, sfp_hdr_p);
memset(&sfp_dom, 0, sizeof(sfp_dom));
sfp_dom_p = &sfp_dom;
shw_sfp_read_dom(i - 1, sfp_dom_p);
} }
if (sfp_data_source == READ_HAL) { if (sfp_data_source == READ_HAL) {
sfp_hdr_p = &hal_sfp_raw_header_lc[i - 1]; sfp_hdr_p = &hal_sfp_raw_header_lc[i - 1];
sfp_dom_p = &hal_sfp_raw_dom_lc[i - 1];
} }
err = shw_sfp_header_verify(sfp_hdr_p); err = shw_sfp_header_verify(sfp_hdr_p);
if (err == -2) { if (err == -2) {
...@@ -415,10 +427,9 @@ int main(int argc, char **argv) ...@@ -415,10 +427,9 @@ int main(int argc, char **argv)
shw_sfp_header_dump(sfp_hdr_p); shw_sfp_header_dump(sfp_hdr_p);
} }
if(dump_sfp_dom) { if(dump_sfp_dom) {
shw_sfp_read_dom(i - 1, &sfp_dom); shw_sfp_print_dom(sfp_dom_p);
shw_sfp_print_dom(&sfp_dom);
if(dump_hex_header) { if(dump_hex_header) {
shw_sfp_dom_dump(&sfp_dom); shw_sfp_dom_dump(sfp_dom_p);
} }
} }
} }
......
...@@ -211,6 +211,7 @@ static int hal_port_init(int index) ...@@ -211,6 +211,7 @@ static int hal_port_init(int index)
int hal_port_init_shmem(char *logfilename) int hal_port_init_shmem(char *logfilename)
{ {
int index; int index;
char *ret;
pr_info("Initializing switch ports...\n"); pr_info("Initializing switch ports...\n");
/* default timeouts */ /* default timeouts */
...@@ -255,6 +256,14 @@ int hal_port_init_shmem(char *logfilename) ...@@ -255,6 +256,14 @@ int hal_port_init_shmem(char *logfilename)
hal_shmem->nports = hal_port_nports; hal_shmem->nports = hal_port_nports;
hal_shmem_hdr->version = HAL_SHMEM_VERSION; hal_shmem_hdr->version = HAL_SHMEM_VERSION;
hal_shmem->hal_mode = hal_get_timing_mode(); hal_shmem->hal_mode = hal_get_timing_mode();
ret = libwr_cfg_get("READ_SFP_DIAG_ENABLE");
if (ret && !strcmp(ret, "y")) {
pr_info("Read SFP Diagnostic Monitoring enabled\n");
hal_shmem->read_sfp_diag = READ_SFP_DIAG_ENABLE;
} else
hal_shmem->read_sfp_diag = READ_SFP_DIAG_DISABLE;
/* Release processes waiting for HAL's to fill shm with correct data /* Release processes waiting for HAL's to fill shm with correct data
When shm is opened successfully data in shm is still not populated! When shm is opened successfully data in shm is still not populated!
Read data with wrs_shm_seqbegin and wrs_shm_seqend! Read data with wrs_shm_seqbegin and wrs_shm_seqend!
...@@ -478,6 +487,7 @@ static void hal_port_insert_sfp(struct hal_port_state * p) ...@@ -478,6 +487,7 @@ static void hal_port_insert_sfp(struct hal_port_state * p)
int err; int err;
memset(&shdr, 0, sizeof(struct shw_sfp_header)); memset(&shdr, 0, sizeof(struct shw_sfp_header));
memset(&p->calib.sfp_dom_raw, 0, sizeof(struct shw_sfp_dom));
err = shw_sfp_read_verify_header(p->hw_index, &shdr); err = shw_sfp_read_verify_header(p->hw_index, &shdr);
memcpy(&p->calib.sfp_header_raw, &shdr, sizeof(struct shw_sfp_header)); memcpy(&p->calib.sfp_header_raw, &shdr, sizeof(struct shw_sfp_header));
if (err == -2) { if (err == -2) {
...@@ -489,7 +499,27 @@ static void hal_port_insert_sfp(struct hal_port_state * p) ...@@ -489,7 +499,27 @@ static void hal_port_insert_sfp(struct hal_port_state * p)
p->name); p->name);
return; return;
} }
if (hal_shmem->read_sfp_diag == READ_SFP_DIAG_ENABLE
&& shdr.diagnostic_monitoring_type & SFP_DIAGNOSTIC_IMPLEMENTED) {
pr_info("SFP Diagnostic Monitoring implemented in SFP plugged"
" to port %d (%s)\n", p->hw_index + 1, p->name);
if (shdr.diagnostic_monitoring_type & SFP_ADDR_CHANGE_REQ) {
pr_warning("SFP in port %d (%s) requires special "
"address change before accessing Diagnostic"
" Monitoring, which is not implemented "
"right now\n", p->hw_index + 1, p->name);
} else {
/* copy coontent of SFP's Diagnostic Monitoring */
shw_sfp_read_dom(p->hw_index, &p->calib.sfp_dom_raw);
if (err < 0) {
pr_error("Failed to read SFP Diagnostic "
"Monitoring for port %d (%s)\n",
p->hw_index + 1, p->name);
}
p->has_sfp_diag = 1;
}
}
pr_info("SFP Info: Manufacturer: %.16s P/N: %.16s, S/N: %.16s\n", pr_info("SFP Info: Manufacturer: %.16s P/N: %.16s, S/N: %.16s\n",
shdr.vendor_name, shdr.vendor_pn, shdr.vendor_serial); shdr.vendor_name, shdr.vendor_pn, shdr.vendor_serial);
cdata = shw_sfp_get_cal_data(p->hw_index, &shdr); cdata = shw_sfp_get_cal_data(p->hw_index, &shdr);
...@@ -570,6 +600,8 @@ static void hal_port_remove_sfp(struct hal_port_state * p) ...@@ -570,6 +600,8 @@ static void hal_port_remove_sfp(struct hal_port_state * p)
/* clean SFP's details when removing SFP */ /* clean SFP's details when removing SFP */
memset(&p->calib.sfp, 0, sizeof(p->calib.sfp)); memset(&p->calib.sfp, 0, sizeof(p->calib.sfp));
memset(&p->calib.sfp_header_raw, 0, sizeof(struct shw_sfp_header)); memset(&p->calib.sfp_header_raw, 0, sizeof(struct shw_sfp_header));
memset(&p->calib.sfp_dom_raw, 0, sizeof(struct shw_sfp_dom));
p->has_sfp_diag = 0;
} }
/* detects insertion/removal of SFP transceivers */ /* detects insertion/removal of SFP transceivers */
...@@ -615,10 +647,20 @@ void hal_port_update_all() ...@@ -615,10 +647,20 @@ void hal_port_update_all()
hal_port_poll_sfp(); hal_port_poll_sfp();
for (i = 0; i < HAL_MAX_PORTS; i++) for (i = 0; i < HAL_MAX_PORTS; i++)
if (ports[i].in_use) if (ports[i].in_use) {
hal_port_fsm(&ports[i]); hal_port_fsm(&ports[i]);
/* update DOM only for plugged ports with DOM
* capabilities */
if (ports[i].state != HAL_PORT_STATE_DISABLED
&& hal_shmem->read_sfp_diag == READ_SFP_DIAG_ENABLE
&& (ports[i].has_sfp_diag)) {
shw_sfp_update_dom(ports[i].hw_index,
&ports[i].calib.sfp_dom_raw);
}
}
/* unlock shmem */ /* unlock shmem */
wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END); wrs_shm_write(hal_shmem_hdr, WRS_SHM_WRITE_END);
} }
int hal_port_enable_tracking(const char *port_name) int hal_port_enable_tracking(const char *port_name)
......
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