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>