svn commit: r270822 - in head: sbin/ifconfig sys/dev/ixgbe sys/net sys/sys
Alexander V. Chernikov
melifaro at FreeBSD.org
Fri Aug 29 18:03:00 UTC 2014
Author: melifaro
Date: Fri Aug 29 18:02:58 2014
New Revision: 270822
URL: http://svnweb.freebsd.org/changeset/base/270822
Log:
* Add SIOCGI2C driver ioctl used to retrieve i2c info.
* Convert ixgbe to use this ioctl
* Convert ifconfig to use generic i2c handler for "ix" interfaces.
Approved by: Eric Joyner (ixgbe part)
MFC after: 2 weeks
Sponsored by: Yandex LLC
Modified:
head/sbin/ifconfig/sfp.c
head/sys/dev/ixgbe/ixgbe.c
head/sys/dev/ixgbe/ixgbe.h
head/sys/net/if.h
head/sys/sys/sockio.h
Modified: head/sbin/ifconfig/sfp.c
==============================================================================
--- head/sbin/ifconfig/sfp.c Fri Aug 29 14:47:05 2014 (r270821)
+++ head/sbin/ifconfig/sfp.c Fri Aug 29 18:02:58 2014 (r270822)
@@ -624,55 +624,43 @@ get_qsfp_tx_power(struct i2c_info *ii, c
convert_sff_power(ii, buf, size, xbuf);
}
-/* Intel ixgbe-specific structures and handlers */
-struct ixgbe_i2c_req {
- uint8_t dev_addr;
- uint8_t offset;
- uint8_t len;
- uint8_t data[8];
-};
-#define SIOCGI2C SIOCGIFGENERIC
-
+/* Generic handler */
static int
-read_i2c_ixgbe(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
+read_i2c_generic(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
caddr_t buf)
{
- struct ixgbe_i2c_req ixreq;
- int i;
+ struct ifi2creq req;
+ int i, l;
if (ii->error != 0)
return (ii->error);
- ii->ifr->ifr_data = (caddr_t)&ixreq;
-
- memset(&ixreq, 0, sizeof(ixreq));
- ixreq.dev_addr = addr;
-
- for (i = 0; i < len; i += 1) {
- ixreq.offset = off + i;
- ixreq.len = 1;
- ixreq.data[0] = '\0';
+ ii->ifr->ifr_data = (caddr_t)&req;
+ i = 0;
+ l = 0;
+ memset(&req, 0, sizeof(req));
+ req.dev_addr = addr;
+ req.offset = off;
+ req.len = len;
+
+ while (len > 0) {
+ l = (len > sizeof(req.data)) ? sizeof(req.data) : len;
+ req.len = l;
if (ioctl(ii->s, SIOCGI2C, ii->ifr) != 0) {
ii->error = errno;
return (errno);
}
- memcpy(&buf[i], ixreq.data, 1);
+
+ memcpy(&buf[i], req.data, l);
+ len -= l;
+ i += l;
+ req.offset += l;
}
return (0);
}
-/* Generic handler */
-static int
-read_i2c_generic(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
- caddr_t buf)
-{
-
- ii->error = EINVAL;
- return (-1);
-}
-
static void
print_qsfp_status(struct i2c_info *ii, int verbose)
{
@@ -766,6 +754,7 @@ sfp_status(int s, struct ifreq *ifr, int
{
struct i2c_info ii;
+ memset(&ii, 0, sizeof(ii));
/* Prepare necessary into to pass to NIC handler */
ii.s = s;
ii.ifr = ifr;
@@ -774,9 +763,8 @@ sfp_status(int s, struct ifreq *ifr, int
* Check if we have i2c support for particular driver.
* TODO: Determine driver by original name.
*/
- memset(&ii, 0, sizeof(ii));
if (strncmp(ifr->ifr_name, "ix", 2) == 0) {
- ii.f = read_i2c_ixgbe;
+ ii.f = read_i2c_generic;
print_sfp_status(&ii, verbose);
} else if (strncmp(ifr->ifr_name, "cxl", 3) == 0) {
ii.port_id = atoi(&ifr->ifr_name[3]);
Modified: head/sys/dev/ixgbe/ixgbe.c
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.c Fri Aug 29 14:47:05 2014 (r270821)
+++ head/sys/dev/ixgbe/ixgbe.c Fri Aug 29 18:02:58 2014 (r270822)
@@ -1068,17 +1068,24 @@ ixgbe_ioctl(struct ifnet * ifp, u_long c
}
case SIOCGI2C:
{
- struct ixgbe_i2c_req i2c;
+ struct ifi2creq i2c;
+ int i;
IOCTL_DEBUGOUT("ioctl: SIOCGI2C (Get I2C Data)");
error = copyin(ifr->ifr_data, &i2c, sizeof(i2c));
- if (error)
+ if (error != 0)
break;
- if ((i2c.dev_addr != 0xA0) || (i2c.dev_addr != 0xA2)){
+ if (i2c.dev_addr != 0xA0 && i2c.dev_addr != 0xA2) {
error = EINVAL;
break;
}
- hw->phy.ops.read_i2c_byte(hw, i2c.offset,
- i2c.dev_addr, i2c.data);
+ if (i2c.len > sizeof(i2c.data)) {
+ error = EINVAL;
+ break;
+ }
+
+ for (i = 0; i < i2c.len; i++)
+ hw->phy.ops.read_i2c_byte(hw, i2c.offset + i,
+ i2c.dev_addr, &i2c.data[i]);
error = copyout(&i2c, ifr->ifr_data, sizeof(i2c));
break;
}
Modified: head/sys/dev/ixgbe/ixgbe.h
==============================================================================
--- head/sys/dev/ixgbe/ixgbe.h Fri Aug 29 14:47:05 2014 (r270821)
+++ head/sys/dev/ixgbe/ixgbe.h Fri Aug 29 18:02:58 2014 (r270822)
@@ -197,9 +197,6 @@
#define IXGBE_BR_SIZE 4096
#define IXGBE_QUEUE_MIN_FREE 32
-/* IOCTL define to gather SFP+ Diagnostic data */
-#define SIOCGI2C SIOCGIFGENERIC
-
/* Offload bits in mbuf flag */
#if __FreeBSD_version >= 800000
#define CSUM_OFFLOAD (CSUM_IP|CSUM_TCP|CSUM_UDP|CSUM_SCTP)
@@ -233,15 +230,6 @@ typedef struct _ixgbe_vendor_info_t {
unsigned int index;
} ixgbe_vendor_info_t;
-
-/* This is used to get SFP+ module data */
-struct ixgbe_i2c_req {
- u8 dev_addr;
- u8 offset;
- u8 len;
- u8 data[8];
-};
-
struct ixgbe_tx_buf {
union ixgbe_adv_tx_desc *eop;
struct mbuf *m_head;
Modified: head/sys/net/if.h
==============================================================================
--- head/sys/net/if.h Fri Aug 29 14:47:05 2014 (r270821)
+++ head/sys/net/if.h Fri Aug 29 18:02:58 2014 (r270822)
@@ -510,6 +510,19 @@ struct ifgroupreq {
#define ifgr_groups ifgr_ifgru.ifgru_groups
};
+/*
+ * Structure used to request i2c data
+ * from interface transceivers.
+ */
+struct ifi2creq {
+ uint8_t dev_addr; /* i2c address (0xA0, 0xA2) */
+ uint8_t offset; /* read offset */
+ uint8_t len; /* read length */
+ uint8_t spare0;
+ uint32_t spare1;
+ uint8_t data[8]; /* read buffer */
+};
+
#endif /* __BSD_VISIBLE */
#ifdef _KERNEL
Modified: head/sys/sys/sockio.h
==============================================================================
--- head/sys/sys/sockio.h Fri Aug 29 14:47:05 2014 (r270821)
+++ head/sys/sys/sockio.h Fri Aug 29 18:02:58 2014 (r270822)
@@ -96,6 +96,7 @@
#define SIOCGIFSTATUS _IOWR('i', 59, struct ifstat) /* get IF status */
#define SIOCSIFLLADDR _IOW('i', 60, struct ifreq) /* set linklevel addr */
+#define SIOCGI2C _IOWR('i', 61, struct ifstat) /* get I2C data */
#define SIOCSIFPHYADDR _IOW('i', 70, struct ifaliasreq) /* set gif addres */
#define SIOCGIFPSRCADDR _IOWR('i', 71, struct ifreq) /* get gif psrc addr */
More information about the svn-src-all
mailing list