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)
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)
{
int i;
......@@ -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) */
inline int shw_sfp_id(int num)
{
......@@ -559,6 +582,32 @@ int shw_sfp_read_header(int num, struct shw_sfp_header *head)
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 ret;
......
......@@ -7,6 +7,8 @@
//address from AT24C01 datasheet (1k, all address lines shorted to the ground)
#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 */
#define WR_FPGA_BUS0 0
......
......@@ -64,9 +64,9 @@ struct shw_sfp_header {
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 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 reserved3;
uint8_t reserved3; /* This is now a field named transceiver */
uint8_t vendor_oui[3];
uint8_t vendor_pn[16];
uint8_t vendor_rev[4];
......@@ -84,6 +84,67 @@ struct shw_sfp_header {
uint8_t cc_ext;
} __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 */
/*
......@@ -113,6 +174,15 @@ int shw_sfp_read_db(void);
/* 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);
/* 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 */
struct shw_sfp_caldata *shw_sfp_get_cal_data(int num,
struct shw_sfp_header *head);
......
......@@ -33,11 +33,12 @@ void print_info(char *prgname)
"Optional parameters:\n"
" -p <num> Dump sfp header for specific port (1-18); dump sfp header info for all\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"
" before READs/WRITEs disable HAL and monit!\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"
" -d Dump sfp DOM data page\n"
" -x Dump sfp/DOM header also in hex\n"
" -q Decrease verbosity\n"
" -v Increase verbosity\n"
" -V Print version\n"
......@@ -280,11 +281,13 @@ int main(int argc, char **argv)
int c;
struct shw_sfp_header sfp_hdr;
struct shw_sfp_header *sfp_hdr_p;
struct shw_sfp_dom sfp_dom;
int err;
int nports;
int dump_port;
int i;
int dump_hex_header = 0;
int dump_sfp_dom = 0;
int operation = 0;
char *eeprom_file = NULL;
int sfp_data_source = 0;
......@@ -296,7 +299,7 @@ int main(int argc, char **argv)
nports = 18;
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) {
case 'p':
dump_port = atoi(optarg);
......@@ -311,6 +314,9 @@ int main(int argc, char **argv)
case 'x':
dump_hex_header = 1;
break;
case 'd':
dump_sfp_dom = 1;
break;
case 'V':
print_version(argv[0]);
exit(0);
......@@ -408,6 +414,13 @@ int main(int argc, char **argv)
if (dump_hex_header) {
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;
......
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