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 */
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to