Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 Aug 2014 18:02:58 +0000 (UTC)
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r270822 - in head: sbin/ifconfig sys/dev/ixgbe sys/net sys/sys
Message-ID:  <201408291802.s7TI2wdE089142@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 */



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408291802.s7TI2wdE089142>