Commit de57d4ae authored by Adam Wujek's avatar Adam Wujek 💬

userspace/libwr: read temperatures from SFPs

Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent 79f88bdf
...@@ -318,6 +318,15 @@ void shw_sfp_print_header(struct shw_sfp_header *head) ...@@ -318,6 +318,15 @@ void shw_sfp_print_header(struct shw_sfp_header *head)
printf("\n"); printf("\n");
} }
void shw_sfp_print_dom(struct shw_sfp_dom * dom)
{
printf("Temperature: %.3f C\n", (int8_t)dom->temp[0] + dom->temp[1]/(float)256);
printf("Voltage: %.3f V\n", (dom->vcc[0]*256 + dom->vcc[1])/(float)10000);
printf("Bias Current: %.3f uA\n", (dom->tx_bias[0]*256+dom->tx_bias[1])/(float)500000);
printf("TX power: %.3f mW\n", (dom->tx_pow[0]*256 + dom->tx_pow[1])/(float)100000);
printf("RX power: %.3f mW\n", (dom->rx_pow[0]*256 + dom->rx_pow[1])/(float)100000);
}
void shw_sfp_header_dump(struct shw_sfp_header *head) void shw_sfp_header_dump(struct shw_sfp_header *head)
{ {
int i; int i;
...@@ -332,6 +341,20 @@ void shw_sfp_header_dump(struct shw_sfp_header *head) ...@@ -332,6 +341,20 @@ void shw_sfp_header_dump(struct shw_sfp_header *head)
} }
void shw_sfp_dom_dump(struct shw_sfp_dom *dom)
{
int i;
uint8_t *dump = (uint8_t *) dom;
printf("Dom Dump:");
for (i = 0; i < sizeof(struct shw_sfp_dom); i++) {
if (i % 8 == 0)
printf("\n");
printf("%02X ", dump[i]);
}
printf("\n");
}
/* Get the SFP ID from the SFP number (0 to 17) */ /* Get the SFP ID from the SFP number (0 to 17) */
inline int shw_sfp_id(int num) inline int shw_sfp_id(int num)
{ {
...@@ -559,6 +582,32 @@ int shw_sfp_read_header(int num, struct shw_sfp_header *head) ...@@ -559,6 +582,32 @@ int shw_sfp_read_header(int num, struct shw_sfp_header *head)
return 0; return 0;
} }
int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom)
{
int ret;
if (shw_sfp_id(num) < 0) {
pr_error("shw_sfp_read_header: wrong SFP num %d\n", num + 1);
return -1;
}
ret = shw_sfp_module_scan();
if (!(ret & (1 << num))) {
pr_error("shw_sfp_read_header: SFP not present %d\n", num + 1);
return -2;
}
ret =
shw_sfp_read(num, I2C_SFP_DOM_ADDRESS, 0x0,
sizeof(struct shw_sfp_dom), (uint8_t *) dom);
if (ret == I2C_DEV_NOT_FOUND) {
pr_error("shw_sfp_read_header: I2C_DEV_NOT_FOUND\n");
return -ENODEV;
}
return 0;
}
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;
......
...@@ -7,6 +7,8 @@ ...@@ -7,6 +7,8 @@
//address from AT24C01 datasheet (1k, all address lines shorted to the ground) //address from AT24C01 datasheet (1k, all address lines shorted to the ground)
#define I2C_SFP_ADDRESS 0x50 #define I2C_SFP_ADDRESS 0x50
// From SFF-8472, but right-shifted one bit as I2C addresses are only 7 bits.
#define I2C_SFP_DOM_ADDRESS 0x51
/* The two FPGA buses */ /* The two FPGA buses */
#define WR_FPGA_BUS0 0 #define WR_FPGA_BUS0 0
......
...@@ -64,9 +64,9 @@ struct shw_sfp_header { ...@@ -64,9 +64,9 @@ struct shw_sfp_header {
uint8_t length3; /* Link length supported for 50/125 mm fiber (10m) */ uint8_t length3; /* Link length supported for 50/125 mm fiber (10m) */
uint8_t length4; /* Link length supported for 62.5/125 mm fiber (10m) */ uint8_t length4; /* Link length supported for 62.5/125 mm fiber (10m) */
uint8_t length5; /* Link length supported for copper (1m) */ uint8_t length5; /* Link length supported for copper (1m) */
uint8_t reserved2; uint8_t length6; /* Link length supported on OM3 (1m) */
uint8_t vendor_name[16]; uint8_t vendor_name[16];
uint8_t reserved3; uint8_t reserved3; /* This is now a field named transceiver */
uint8_t vendor_oui[3]; uint8_t vendor_oui[3];
uint8_t vendor_pn[16]; uint8_t vendor_pn[16];
uint8_t vendor_rev[4]; uint8_t vendor_rev[4];
...@@ -84,6 +84,67 @@ struct shw_sfp_header { ...@@ -84,6 +84,67 @@ struct shw_sfp_header {
uint8_t cc_ext; uint8_t cc_ext;
} __attribute__ ((packed)); } __attribute__ ((packed));
struct shw_sfp_dom {
/* Treshold values, 0 - 55 */
uint8_t temp_high_alarm[2];
uint8_t temp_low_alarm[2];
uint8_t temp_high_warn[2];
uint8_t temp_low_warn[2];
uint8_t volt_high_alarm[2];
uint8_t volt_low_alarm[2];
uint8_t volt_high_warn[2];
uint8_t volt_low_warn[2];
uint8_t bias_high_alarm[2];
uint8_t bias_low_alarm[2];
uint8_t bias_high_warn[2];
uint8_t bias_low_warn[2];
uint8_t tx_pow_high_alarm[2];
uint8_t tx_pow_low_alarm[2];
uint8_t tx_pow_high_warn[2];
uint8_t tx_pow_low_warn[2];
uint8_t rx_pow_high_alarm[2];
uint8_t rx_pow_log_alarm[2];
uint8_t rx_power_high_warn[2];
uint8_t rx_power_low_warn[2];
uint8_t unalloc0[16];
/* Calibration data, 56-91 */
uint8_t cal_rx_pwr4[4];
uint8_t cal_rx_pwr3[4];
uint8_t cal_rx_pwr2[4];
uint8_t cal_rx_pwr1[4];
uint8_t cal_rx_pwr0[4];
uint8_t cal_tx_i_slope[2];
uint8_t cal_tx_i_offset[2];
uint8_t cal_tx_pow_slope[2];
uint8_t cal_tx_pow_offset[2];
uint8_t cal_T_slope[2];
uint8_t cal_T_offset[2];
uint8_t cal_V_slope[2];
uint8_t cal_V_offset[2];
/* Unallocated and checksum, 92-95 */
uint8_t cal_unalloc[3];
uint8_t CC_DMI;
/* Real Time Diagnostics, 96-111 */
uint8_t temp[2];
uint8_t vcc[2];
uint8_t tx_bias[2];
uint8_t tx_pow[2];
uint8_t rx_pow[2];
uint8_t rtd_unalloc0[4];
uint8_t OSCB;
uint8_t rtd_unalloc1;
/* Alarms and Warnings, 112 - 117 */
uint8_t alw[6];
/* Extended Module Control/Status bytes 118 - 119 */
uint8_t emcsb[2];
/* Vendor locations 120 - 127 */
uint8_t vendor_locations[8];
/* User data 128 - 247 */
uint8_t dom_user[120];
/* Vendor specific control function locations 248 - 255 */
uint8_t vendor_functions[8];
} __attribute__ ((packed));
/* Public API */ /* Public API */
/* /*
...@@ -113,6 +174,15 @@ int shw_sfp_read_db(void); ...@@ -113,6 +174,15 @@ int shw_sfp_read_db(void);
/* Read and verify the header all at once. returns -1 on failure */ /* Read and verify the header all at once. returns -1 on failure */
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);
/* Read the SFP diagnostics page */
int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom);
/* Decode and print the SFP real time diagnostics */
void shw_sfp_print_dom(struct shw_sfp_dom * dom);
/* Dump the SFP diagnostics page in hex */
void shw_sfp_dom_dump(struct shw_sfp_dom * dom);
/* return NULL if no data found */ /* return NULL if no data found */
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num, struct shw_sfp_caldata *shw_sfp_get_cal_data(int num,
struct shw_sfp_header *head); struct shw_sfp_header *head);
......
...@@ -33,11 +33,12 @@ void print_info(char *prgname) ...@@ -33,11 +33,12 @@ void print_info(char *prgname)
"Optional parameters:\n" "Optional parameters:\n"
" -p <num> Dump sfp header for specific port (1-18); dump sfp header info for all\n" " -p <num> Dump sfp header for specific port (1-18); dump sfp header info for all\n"
" ports if no <-p> specified\n" " ports if no <-p> specified\n"
" -x Dump sfp header also in hex\n"
" -a <READ|WRITE> Read/write SFP's eeprom; works only with <-I>;\n" " -a <READ|WRITE> Read/write SFP's eeprom; works only with <-I>;\n"
" before READs/WRITEs disable HAL and monit!\n" " before READs/WRITEs disable HAL and monit!\n"
" -f <file> File to READ/WRITE SFP's eeprom\n" " -f <file> File to READ/WRITE SFP's eeprom\n"
" -H <dir> Open shmem dumps from the given directory; works only with <-L>\n" " -H <dir> Open shmem dumps from the given directory; works only with <-L>\n"
" -d Dump sfp DOM data page\n"
" -x Dump sfp/DOM header also in hex\n"
" -q Decrease verbosity\n" " -q Decrease verbosity\n"
" -v Increase verbosity\n" " -v Increase verbosity\n"
" -V Print version\n" " -V Print version\n"
...@@ -280,11 +281,13 @@ int main(int argc, char **argv) ...@@ -280,11 +281,13 @@ int main(int argc, char **argv)
int c; int c;
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;
int err; int err;
int nports; int nports;
int dump_port; int dump_port;
int i; int i;
int dump_hex_header = 0; int dump_hex_header = 0;
int dump_sfp_dom = 0;
int operation = 0; int operation = 0;
char *eeprom_file = NULL; char *eeprom_file = NULL;
int sfp_data_source = 0; int sfp_data_source = 0;
...@@ -296,7 +299,7 @@ int main(int argc, char **argv) ...@@ -296,7 +299,7 @@ int main(int argc, char **argv)
nports = 18; nports = 18;
dump_port = 1; dump_port = 1;
while ((c = getopt(argc, argv, "a:hqvp:xVf:LIH:")) != -1) { while ((c = getopt(argc, argv, "a:hqvp:xVf:LIdH:")) != -1) {
switch (c) { switch (c) {
case 'p': case 'p':
dump_port = atoi(optarg); dump_port = atoi(optarg);
...@@ -311,6 +314,9 @@ int main(int argc, char **argv) ...@@ -311,6 +314,9 @@ int main(int argc, char **argv)
case 'x': case 'x':
dump_hex_header = 1; dump_hex_header = 1;
break; break;
case 'd':
dump_sfp_dom = 1;
break;
case 'V': case 'V':
print_version(argv[0]); print_version(argv[0]);
exit(0); exit(0);
...@@ -408,6 +414,13 @@ int main(int argc, char **argv) ...@@ -408,6 +414,13 @@ int main(int argc, char **argv)
if (dump_hex_header) { if (dump_hex_header) {
shw_sfp_header_dump(sfp_hdr_p); shw_sfp_header_dump(sfp_hdr_p);
} }
if(dump_sfp_dom) {
shw_sfp_read_dom(i - 1, &sfp_dom);
shw_sfp_print_dom(&sfp_dom);
if(dump_hex_header) {
shw_sfp_dom_dump(&sfp_dom);
}
}
} }
} }
return 0; return 0;
......
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