blob: 1974d2701437b07a37fa8c0aeefacacffb1f46a9 [file] [log] [blame]
/*
* (C) Copyright 2015 Google, Inc.
* All rights reserved.
*
*/
#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../common/io.h"
#include "../common/util.h"
#include "i2c.h"
#define SFP_BUS 0
#define SFP_A0_ADDR 0x50
#define SFP_A2_ADDR 0x51
#define SFP_ADDR_LEN 1
#define SFP_REG_LEN 1
#define SFP_MAX_DATA_LEN 128
#define SFP_INFO_REG_ADDR 0x60
#define SFP_INFO_REG_LEN 16
#define SFP_VENDOR_REG_ADDR 20
#define SFP_VENDOR_REG_LEN 16
#define SFP_PN_REG_ADDR 40
#define SFP_PN_REG_LEN 16
#define SFP_SN_REG_ADDR 68
#define SFP_SN_REG_LEN 16
#define SFP_DATE_REG_ADDR 84
#define SFP_DATE_REG_LEN 8
#define SFP_WL_REG_ADDR 144
#define SFP_WL_REG_LEN 2
#define SFP_PW_REG 0x7B
#define SFP_PW_REG_LEN 4
static void sfp_reg_read_usage(void) {
printf("sfp_reg_read <addr>\n");
printf("read SFP registers\n");
printf("Example:\n");
printf("sfp_reg_read 0x40\n");
}
int sfp_reg_read(int argc, char *argv[]) {
unsigned int reg_addr;
uint8_t value;
if (argc != 2) {
sfp_reg_read_usage();
return -1;
}
reg_addr = get_num(argv[1]);
if (i2cr(SFP_BUS, SFP_A0_ADDR, reg_addr, SFP_ADDR_LEN, SFP_REG_LEN, &value) !=
0) {
printf("SFP read address 0x%x failed\n", reg_addr);
return -1;
}
printf("SFP 0x%x = 0x%x\n", reg_addr, value);
return 0;
}
static void sfp_reg_write_usage(void) {
printf("sfp_reg_write <addr> <data>\n");
printf("write SFP registers\n");
printf("Example:\n");
printf("sfp_reg_write 0x60 0x0\n");
}
int sfp_reg_write(int argc, char *argv[]) {
unsigned int reg_addr;
uint8_t value;
if (argc != 3) {
sfp_reg_write_usage();
return -1;
}
reg_addr = get_num(argv[1]);
value = get_num(argv[2]);
if (i2cw(SFP_BUS, SFP_A0_ADDR, reg_addr, SFP_ADDR_LEN, SFP_REG_LEN, &value) !=
0) {
printf("SFP write address 0x%x value 0x%x failed\n", reg_addr, value);
return -1;
}
printf("SFP 0x%x set to 0x%x\n", reg_addr, value);
return 0;
}
static void sfp_diags_reg_read_usage(void) {
printf("sfp_diags_reg_read <addr>\n");
printf("read SFP 0xA2 registers\n");
printf("Example:\n");
printf("sfp_diags_reg_read 0x40\n");
}
int sfp_diags_reg_read(int argc, char *argv[]) {
unsigned int reg_addr;
uint8_t value;
if (argc != 2) {
sfp_diags_reg_read_usage();
return -1;
}
reg_addr = get_num(argv[1]);
if (i2cr(SFP_BUS, SFP_A2_ADDR, reg_addr, SFP_ADDR_LEN, SFP_REG_LEN, &value) !=
0) {
printf("SFP 0xA2 read address 0x%x failed\n", reg_addr);
return -1;
}
printf("SFP 0xA2 0x%x = 0x%x\n", reg_addr, value);
return 0;
}
static void sfp_diags_reg_write_usage(void) {
printf("sfp_diags_reg_write <addr> <data>\n");
printf("write SFP 0xA2 registers\n");
printf("Example:\n");
printf("sfp_diags_reg_write 0x60 0x0\n");
}
int sfp_diags_reg_write(int argc, char *argv[]) {
unsigned int reg_addr;
uint8_t value;
if (argc != 3) {
sfp_diags_reg_write_usage();
return -1;
}
reg_addr = get_num(argv[1]);
value = get_num(argv[2]);
if (i2cw(SFP_BUS, SFP_A2_ADDR, reg_addr, SFP_ADDR_LEN, SFP_REG_LEN, &value) !=
0) {
printf("SFP write 0xA2 address 0x%x value 0x%x failed\n", reg_addr, value);
return -1;
}
printf("SFP 0xA2 0x%x set to 0x%x\n", reg_addr, value);
return 0;
}
static void sfp_info_usage(void) {
printf("sfp_info\n");
printf("read SFP info\n");
printf("Example:\n");
printf("sfp_info\n");
}
int sfp_info(int argc, char *argv[]) {
uint8_t value[SFP_INFO_REG_LEN];
float temp;
float vcc, tx_bias, tx_power, rx_power, mod_curr;
if (argc != 1 || argv == NULL) {
sfp_info_usage();
return -1;
}
if (i2cr(SFP_BUS, SFP_A2_ADDR, SFP_INFO_REG_ADDR, SFP_ADDR_LEN,
SFP_INFO_REG_LEN, value) != 0) {
printf("SFP read address %d failed\n", SFP_INFO_REG_ADDR);
return -1;
}
if (value[0] & 0x80) {
value[0] &= 0x7F;
temp = -128.0 + value[0] + ((float)value[1]) / 256.0;
} else {
temp = value[0] + ((float)value[1]) / 256.0;
}
vcc = ((float)((value[2] << 8) + value[3])) / 10000.0;
tx_bias = (((float)((value[4] << 8) + value[5])) * 2) / 1000.0;
tx_power = ((float)((value[6] << 8) + value[7])) / 10000.0;
rx_power = ((float)((value[8] << 8) + value[9])) / 10000.0;
mod_curr = ((float)((value[12] << 8) + value[13])) / 1000.0;
printf("SFP temp: %f, Vcc: %3.3f V, TX bias %3.3f mA\n", temp, vcc, tx_bias);
printf(" TX power: %3.3f mW, RX power: %3.3f mW, mod curr: %3.3f mA\n",
tx_power, rx_power, mod_curr);
return 0;
}
static void sfp_vendor_usage(void) {
printf("sfp_vendor\n");
printf("read SFP vendor\n");
printf("Example:\n");
printf("sfp_vendor\n");
}
int sfp_vendor(int argc, char *argv[]) {
uint8_t value[SFP_MAX_DATA_LEN];
if (argc != 1 || argv == NULL) {
sfp_vendor_usage();
return -1;
}
printf("SFP vendor:\n");
if (i2cr(SFP_BUS, SFP_A0_ADDR, SFP_VENDOR_REG_ADDR, SFP_ADDR_LEN,
SFP_VENDOR_REG_LEN, value) != 0) {
printf("SFP read address %d failed\n", SFP_VENDOR_REG_ADDR);
return -1;
}
value[SFP_VENDOR_REG_LEN] = '\0';
printf(" Name: %s\n", value);
if (i2cr(SFP_BUS, SFP_A0_ADDR, SFP_PN_REG_ADDR, SFP_ADDR_LEN, SFP_PN_REG_LEN,
value) != 0) {
printf("SFP read address %d failed\n", SFP_PN_REG_ADDR);
return -1;
}
value[SFP_PN_REG_LEN] = '\0';
printf(" PN: %s\n", value);
if (i2cr(SFP_BUS, SFP_A0_ADDR, SFP_SN_REG_ADDR, SFP_ADDR_LEN, SFP_SN_REG_LEN,
value) != 0) {
printf("SFP read address %d failed\n", SFP_SN_REG_ADDR);
return -1;
}
value[SFP_SN_REG_LEN] = '\0';
printf(" SN: %s\n", value);
if (i2cr(SFP_BUS, SFP_A0_ADDR, SFP_DATE_REG_ADDR, SFP_ADDR_LEN,
SFP_DATE_REG_LEN, value) != 0) {
printf("SFP read address %d failed\n", SFP_DATE_REG_ADDR);
return -1;
}
value[SFP_DATE_REG_LEN] = '\0';
printf(" Date: %s\n", value);
return 0;
}
static void sfp_pn_usage(void) {
printf("sfp_pn\n");
printf("read SFP part number\n");
printf("Example:\n");
printf("sfp_pn\n");
}
int sfp_pn(int argc, char *argv[]) {
uint8_t value[SFP_MAX_DATA_LEN];
if (argc != 1 || argv == NULL) {
sfp_pn_usage();
return -1;
}
if (i2cr(SFP_BUS, SFP_A0_ADDR, SFP_PN_REG_ADDR, SFP_ADDR_LEN, SFP_PN_REG_LEN,
value) != 0) {
printf("SFP read address %d failed\n", SFP_PN_REG_ADDR);
return -1;
}
value[SFP_PN_REG_LEN] = '\0';
printf("SFP part number: %s\n", value);
return 0;
}
static void sfp_wavelength_usage(void) {
printf("sfp_wavelength\n");
printf("read SFP laser wavelength\n");
printf("Example:\n");
printf("sfp_wavelength\n");
}
int sfp_wavelength(int argc, char *argv[]) {
uint8_t value[SFP_MAX_DATA_LEN];
unsigned int data;
if (argc != 1 || argv == NULL) {
sfp_wavelength_usage();
return -1;
}
if (i2cr(SFP_BUS, SFP_A2_ADDR, SFP_WL_REG_ADDR, SFP_ADDR_LEN, SFP_WL_REG_LEN,
value) != 0) {
printf("SFP read address %d failed\n", SFP_WL_REG_ADDR);
return -1;
}
data = (value[0] << 8) + value[1];
printf("SFP wavelength: %d\n", data);
return 0;
}
static void sfp_set_wavelength_usage(void) {
printf("sfp_set_wavelength <wavelength>\n");
printf("set SFP laser wavelength\n");
printf("Example:\n");
printf("sfp_set_wavelength 1520\n");
}
int sfp_set_wavelength(int argc, char *argv[]) {
uint8_t value[SFP_MAX_DATA_LEN];
unsigned int data;
if (argc != 2) {
sfp_set_wavelength_usage();
return -1;
}
data = get_num(argv[1]);
value[0] = (data >> 8);
value[1] = data & 0xFF;
if (i2cw(SFP_BUS, SFP_A2_ADDR, SFP_WL_REG_ADDR, SFP_ADDR_LEN, SFP_WL_REG_LEN,
value) != 0) {
printf("SFP write address %d of %d failed\n", SFP_WL_REG_ADDR, data);
return -1;
}
data = (value[0] << 8) + value[1];
printf("SFP wavelength: %d\n", data);
return 0;
}
static void sfp_set_pw_usage(void) {
printf("sfp_set_pw <password>\n");
printf("set SFP access password\n");
printf("Example:\n");
printf("sfp_set_pw 0x80818283\n");
}
int sfp_set_pw(int argc, char *argv[]) {
uint8_t value[SFP_MAX_DATA_LEN];
unsigned int data;
if (argc != 2) {
sfp_set_pw_usage();
return -1;
}
data = get_num(argv[1]);
value[0] = (data >> 24) & 0xFF;
value[1] = (data >> 16) & 0xFF;
value[2] = (data >> 8) & 0xFF;
value[3] = data & 0xFF;
if (i2cw(SFP_BUS, SFP_A2_ADDR, SFP_PW_REG, SFP_ADDR_LEN, SFP_PW_REG_LEN,
value) != 0) {
printf("SFP write address %d of %d failed\n", SFP_PW_REG, data);
return -1;
}
printf("SFP password set to 0x%2x%2x%2x%2x\n", value[0], value[1], value[2],
value[3]);
return 0;
}