summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2015-05-15 12:32:17 +0000
committermelifaro <melifaro@FreeBSD.org>2015-05-15 12:32:17 +0000
commit78a71b3a33f1b474550f3b13ff07adb1524c663f (patch)
treea97b168d27a87a89ca059c3619aad5b9254f277c
parent7baf3caf2dc21b0a1eb260dc0c31db89e4dbf114 (diff)
downloadFreeBSD-src-78a71b3a33f1b474550f3b13ff07adb1524c663f.zip
FreeBSD-src-78a71b3a33f1b474550f3b13ff07adb1524c663f.tar.gz
Simplify i2c reader: we don't need per-NIC handler anymore.
Make code use read_i2c() function instead of callback. Simplify&document struct i2c_info. Consistently use uint8_t to read from i2c.
-rw-r--r--sbin/ifconfig/sfp.c122
1 files changed, 57 insertions, 65 deletions
diff --git a/sbin/ifconfig/sfp.c b/sbin/ifconfig/sfp.c
index d4da8c3..4ceb91a 100644
--- a/sbin/ifconfig/sfp.c
+++ b/sbin/ifconfig/sfp.c
@@ -48,25 +48,16 @@ static const char rcsid[] =
#include "ifconfig.h"
-struct i2c_info;
-typedef int (read_i2c)(struct i2c_info *ii, uint8_t addr, uint8_t off,
- uint8_t len, caddr_t buf);
-
struct i2c_info {
- int s;
- int error;
- int bshift;
- int qsfp;
- int do_diag;
- struct ifreq *ifr;
- read_i2c *f;
- char *textbuf;
- size_t bufsize;
- int cfd;
- int port_id;
- int chip_id;
+ int fd; /* fd to issue SIOCGI2C */
+ int error; /* Store first error */
+ int qsfp; /* True if transceiver is QSFP */
+ int do_diag; /* True if we need to request DDM */
+ struct ifreq *ifr; /* Pointer to pre-filled ifreq */
};
+static int read_i2c(struct i2c_info *ii, uint8_t addr, uint8_t off,
+ uint8_t len, uint8_t *buf);
static void dump_i2c_data(struct i2c_info *ii, uint8_t addr, uint8_t off,
uint8_t len);
@@ -259,7 +250,7 @@ get_sfp_identifier(struct i2c_info *ii, char *buf, size_t size)
{
uint8_t data;
- ii->f(ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&data);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_ID, 1, &data);
convert_sff_identifier(buf, size, data);
}
@@ -268,7 +259,7 @@ get_sfp_connector(struct i2c_info *ii, char *buf, size_t size)
{
uint8_t data;
- ii->f(ii, SFF_8472_BASE, SFF_8472_CONNECTOR, 1, (caddr_t)&data);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_CONNECTOR, 1, &data);
convert_sff_connector(buf, size, data);
}
@@ -277,7 +268,7 @@ get_qsfp_identifier(struct i2c_info *ii, char *buf, size_t size)
{
uint8_t data;
- ii->f(ii, SFF_8436_BASE, SFF_8436_ID, 1, (caddr_t)&data);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_ID, 1, &data);
convert_sff_identifier(buf, size, data);
}
@@ -286,7 +277,7 @@ get_qsfp_connector(struct i2c_info *ii, char *buf, size_t size)
{
uint8_t data;
- ii->f(ii, SFF_8436_BASE, SFF_8436_CONNECTOR, 1, (caddr_t)&data);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_CONNECTOR, 1, &data);
convert_sff_connector(buf, size, data);
}
@@ -303,7 +294,7 @@ printf_sfp_transceiver_descr(struct i2c_info *ii, char *buf, size_t size)
tech_speed = NULL;
/* Read bytes 3-10 at once */
- ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, &xbuf[3]);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, &xbuf[3]);
/* Check 10G ethernet first */
tech_class = find_zero_bit(eth_10g, xbuf[3], 1);
@@ -331,14 +322,14 @@ get_sfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size)
uint8_t code;
unsigned char qbuf[8];
- ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, (caddr_t)qbuf);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 8, (uint8_t *)qbuf);
/* Check 10G Ethernet/IB first */
- ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 1, (caddr_t)&code);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START, 1, &code);
tech_class = find_zero_bit(eth_10g, code, 1);
if (tech_class == NULL) {
/* No match. Try Ethernet 1G */
- ii->f(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3,
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_TRANS_START + 3,
1, (caddr_t)&code);
tech_class = find_zero_bit(eth_compat, code, 1);
}
@@ -356,7 +347,7 @@ get_qsfp_transceiver_class(struct i2c_info *ii, char *buf, size_t size)
uint8_t code;
/* Check 10/40G Ethernet class only */
- ii->f(ii, SFF_8436_BASE, SFF_8436_CODE_E1040G, 1, (caddr_t)&code);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_CODE_E1040G, 1, &code);
tech_class = find_zero_bit(eth_1040g, code, 1);
if (tech_class == NULL)
tech_class = "Unknown";
@@ -393,7 +384,7 @@ get_sfp_vendor_name(struct i2c_info *ii, char *buf, size_t size)
char xbuf[17];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8472_BASE, SFF_8472_VENDOR_START, 16, xbuf);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_VENDOR_START, 16, (uint8_t *)xbuf);
convert_sff_name(buf, size, xbuf);
}
@@ -403,7 +394,7 @@ get_sfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size)
char xbuf[17];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8472_BASE, SFF_8472_PN_START, 16, xbuf);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_PN_START, 16, (uint8_t *)xbuf);
convert_sff_name(buf, size, xbuf);
}
@@ -413,7 +404,7 @@ get_sfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size)
char xbuf[17];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8472_BASE, SFF_8472_SN_START, 16, xbuf);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_SN_START, 16, (uint8_t *)xbuf);
convert_sff_name(buf, size, xbuf);
}
@@ -424,7 +415,7 @@ get_sfp_vendor_date(struct i2c_info *ii, char *buf, size_t size)
memset(xbuf, 0, sizeof(xbuf));
/* Date code, see Table 3.8 for description */
- ii->f(ii, SFF_8472_BASE, SFF_8472_DATE_START, 6, xbuf);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_DATE_START, 6, (uint8_t *)xbuf);
convert_sff_date(buf, size, xbuf);
}
@@ -434,7 +425,7 @@ get_qsfp_vendor_name(struct i2c_info *ii, char *buf, size_t size)
char xbuf[17];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_VENDOR_START, 16, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_VENDOR_START, 16, (uint8_t *)xbuf);
convert_sff_name(buf, size, xbuf);
}
@@ -444,7 +435,7 @@ get_qsfp_vendor_pn(struct i2c_info *ii, char *buf, size_t size)
char xbuf[17];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_PN_START, 16, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_PN_START, 16, (uint8_t *)xbuf);
convert_sff_name(buf, size, xbuf);
}
@@ -454,7 +445,7 @@ get_qsfp_vendor_sn(struct i2c_info *ii, char *buf, size_t size)
char xbuf[17];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_SN_START, 16, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_SN_START, 16, (uint8_t *)xbuf);
convert_sff_name(buf, size, xbuf);
}
@@ -464,7 +455,7 @@ get_qsfp_vendor_date(struct i2c_info *ii, char *buf, size_t size)
char xbuf[6];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_DATE_START, 6, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_DATE_START, 6, (uint8_t *)xbuf);
convert_sff_date(buf, size, xbuf);
}
@@ -501,12 +492,12 @@ print_sfp_vendor(struct i2c_info *ii, char *buf, size_t size)
*
*/
static void
-convert_sff_temp(char *buf, size_t size, char *xbuf)
+convert_sff_temp(char *buf, size_t size, uint8_t *xbuf)
{
double d;
- d = (double)(int8_t)xbuf[0];
- d += (double)(uint8_t)xbuf[1] / 256;
+ d = (double)xbuf[0];
+ d += (double)xbuf[1] / 256;
snprintf(buf, size, "%.2f C", d);
}
@@ -516,11 +507,11 @@ convert_sff_temp(char *buf, size_t size, char *xbuf)
* 16-bit usigned value, treated as range 0..+6.55 Volts
*/
static void
-convert_sff_voltage(char *buf, size_t size, char *xbuf)
+convert_sff_voltage(char *buf, size_t size, uint8_t *xbuf)
{
double d;
- d = (double)(((uint8_t)xbuf[0] << 8) | (uint8_t)xbuf[1]);
+ d = (double)((xbuf[0] << 8) | xbuf[1]);
snprintf(buf, size, "%.2f Volts", d / 10000);
}
@@ -529,12 +520,12 @@ convert_sff_voltage(char *buf, size_t size, char *xbuf)
* human representation.
*/
static void
-convert_sff_power(struct i2c_info *ii, char *buf, size_t size, char *xbuf)
+convert_sff_power(struct i2c_info *ii, char *buf, size_t size, uint8_t *xbuf)
{
uint16_t mW;
double dbm;
- mW = ((uint8_t)xbuf[0] << 8) + (uint8_t)xbuf[1];
+ mW = (xbuf[0] << 8) + xbuf[1];
/* Convert mw to dbm */
dbm = 10.0 * log10(1.0 * mW / 10000);
@@ -553,60 +544,60 @@ convert_sff_power(struct i2c_info *ii, char *buf, size_t size, char *xbuf)
static void
get_sfp_temp(struct i2c_info *ii, char *buf, size_t size)
{
- char xbuf[2];
+ uint8_t xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8472_DIAG, SFF_8472_TEMP, 2, xbuf);
+ read_i2c(ii, SFF_8472_DIAG, SFF_8472_TEMP, 2, xbuf);
convert_sff_temp(buf, size, xbuf);
}
static void
get_sfp_voltage(struct i2c_info *ii, char *buf, size_t size)
{
- char xbuf[2];
+ uint8_t xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8472_DIAG, SFF_8472_VCC, 2, xbuf);
+ read_i2c(ii, SFF_8472_DIAG, SFF_8472_VCC, 2, xbuf);
convert_sff_voltage(buf, size, xbuf);
}
static void
get_qsfp_temp(struct i2c_info *ii, char *buf, size_t size)
{
- char xbuf[2];
+ uint8_t xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_TEMP, 2, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_TEMP, 2, xbuf);
convert_sff_temp(buf, size, xbuf);
}
static void
get_qsfp_voltage(struct i2c_info *ii, char *buf, size_t size)
{
- char xbuf[2];
+ uint8_t xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_VCC, 2, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_VCC, 2, xbuf);
convert_sff_voltage(buf, size, xbuf);
}
static void
get_sfp_rx_power(struct i2c_info *ii, char *buf, size_t size)
{
- char xbuf[2];
+ uint8_t xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8472_DIAG, SFF_8472_RX_POWER, 2, xbuf);
+ read_i2c(ii, SFF_8472_DIAG, SFF_8472_RX_POWER, 2, xbuf);
convert_sff_power(ii, buf, size, xbuf);
}
static void
get_sfp_tx_power(struct i2c_info *ii, char *buf, size_t size)
{
- char xbuf[2];
+ uint8_t xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8472_DIAG, SFF_8472_TX_POWER, 2, xbuf);
+ read_i2c(ii, SFF_8472_DIAG, SFF_8472_TX_POWER, 2, xbuf);
convert_sff_power(ii, buf, size, xbuf);
}
@@ -616,7 +607,7 @@ get_qsfp_rx_power(struct i2c_info *ii, char *buf, size_t size, int chan)
char xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_RX_CH1_MSB + (chan - 1) * 2, 2, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_RX_CH1_MSB + (chan - 1) * 2, 2, xbuf);
convert_sff_power(ii, buf, size, xbuf);
}
@@ -626,14 +617,16 @@ get_qsfp_tx_power(struct i2c_info *ii, char *buf, size_t size, int chan)
char xbuf[2];
memset(xbuf, 0, sizeof(xbuf));
- ii->f(ii, SFF_8436_BASE, SFF_8436_TX_CH1_MSB + (chan -1) * 2, 2, xbuf);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_TX_CH1_MSB + (chan -1) * 2, 2, xbuf);
convert_sff_power(ii, buf, size, xbuf);
}
-/* Generic handler */
+/*
+ * Reads i2c data from opened kernel socket.
+ */
static int
-read_i2c_generic(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
- caddr_t buf)
+read_i2c(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
+ uint8_t *buf)
{
struct ifi2creq req;
int i, l;
@@ -653,7 +646,7 @@ read_i2c_generic(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
while (len > 0) {
l = (len > sizeof(req.data)) ? sizeof(req.data) : len;
req.len = l;
- if (ioctl(ii->s, SIOCGI2C, ii->ifr) != 0) {
+ if (ioctl(ii->fd, SIOCGI2C, ii->ifr) != 0) {
ii->error = errno;
return (errno);
}
@@ -676,7 +669,7 @@ dump_i2c_data(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len)
while (len > 0) {
memset(buf, 0, sizeof(buf));
read = (len > sizeof(buf)) ? sizeof(buf) : len;
- ii->f(ii, addr, off, read, buf);
+ read_i2c(ii, addr, off, read, buf);
if (ii->error != 0) {
fprintf(stderr, "Error reading i2c info\n");
return;
@@ -699,7 +692,7 @@ print_qsfp_status(struct i2c_info *ii, int verbose)
int i;
/* Read diagnostic monitoring type */
- ii->f(ii, SFF_8436_BASE, SFF_8436_DIAG_TYPE, 1, (caddr_t)&diag_type);
+ read_i2c(ii, SFF_8436_BASE, SFF_8436_DIAG_TYPE, 1, (caddr_t)&diag_type);
if (ii->error != 0)
return;
@@ -749,7 +742,7 @@ print_sfp_status(struct i2c_info *ii, int verbose)
uint8_t diag_type, flags;
/* Read diagnostic monitoring type */
- ii->f(ii, SFF_8472_BASE, SFF_8472_DIAG_TYPE, 1, (caddr_t)&diag_type);
+ read_i2c(ii, SFF_8472_BASE, SFF_8472_DIAG_TYPE, 1, (caddr_t)&diag_type);
if (ii->error != 0)
return;
@@ -797,11 +790,10 @@ sfp_status(int s, struct ifreq *ifr, int verbose)
struct i2c_info ii;
uint8_t id_byte;
+ /* Prepare necessary into pass to i2c reader */
memset(&ii, 0, sizeof(ii));
- /* Prepare necessary into to pass to NIC handler */
- ii.s = s;
+ ii.fd = s;
ii.ifr = ifr;
- ii.f = read_i2c_generic;
/*
* Try to read byte 0 from i2c:
@@ -811,7 +803,7 @@ sfp_status(int s, struct ifreq *ifr, int verbose)
* this might happen in case of empty transceiver slot.
*/
id_byte = 0;
- ii.f(&ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&id_byte);
+ read_i2c(&ii, SFF_8472_BASE, SFF_8472_ID, 1, (caddr_t)&id_byte);
if (ii.error != 0 || id_byte == 0)
return;
OpenPOWER on IntegriCloud