* 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
This commit is contained in:
Alexander V. Chernikov 2014-08-29 18:02:58 +00:00
parent a10816090b
commit ea463f2dc0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=270822
5 changed files with 57 additions and 60 deletions

View File

@ -624,53 +624,41 @@ get_qsfp_tx_power(struct i2c_info *ii, char *buf, size_t size, int chan)
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
static int
read_i2c_ixgbe(struct i2c_info *ii, uint8_t addr, uint8_t off, uint8_t len,
caddr_t buf)
{
struct ixgbe_i2c_req ixreq;
int i;
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';
if (ioctl(ii->s, SIOCGI2C, ii->ifr) != 0) {
ii->error = errno;
return (errno);
}
memcpy(&buf[i], ixreq.data, 1);
}
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)
{
struct ifi2creq req;
int i, l;
ii->error = EINVAL;
return (-1);
if (ii->error != 0)
return (ii->error);
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], req.data, l);
len -= l;
i += l;
req.offset += l;
}
return (0);
}
static void
@ -766,6 +754,7 @@ sfp_status(int s, struct ifreq *ifr, int verbose)
{
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 verbose)
* 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]);

View File

@ -1068,17 +1068,24 @@ ixgbe_ioctl(struct ifnet * ifp, u_long command, caddr_t data)
}
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;
}

View File

@ -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;

View File

@ -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

View File

@ -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 */