Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jul 2014 01:03:30 +0000 (UTC)
From:      Navdeep Parhar <np@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r268640 - in head/sys/dev/cxgbe: . common
Message-ID:  <201407150103.s6F13UH2010287@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: np
Date: Tue Jul 15 01:03:29 2014
New Revision: 268640
URL: http://svnweb.freebsd.org/changeset/base/268640

Log:
  Allow multi-byte reads in the private CHELSIO_T4_GET_I2C ioctl.  The
  firmware allows up to 48B to be read this way but the driver limits
  itself to 8B at a time to remain compatible with old cxgbetool
  binaries.
  
  MFC after:	1 week

Modified:
  head/sys/dev/cxgbe/common/common.h
  head/sys/dev/cxgbe/common/t4_hw.c
  head/sys/dev/cxgbe/t4_main.c

Modified: head/sys/dev/cxgbe/common/common.h
==============================================================================
--- head/sys/dev/cxgbe/common/common.h	Tue Jul 15 00:27:08 2014	(r268639)
+++ head/sys/dev/cxgbe/common/common.h	Tue Jul 15 01:03:29 2014	(r268640)
@@ -585,12 +585,18 @@ int t4_enable_vi_ns(struct adapter *adap
 		 bool rx_en, bool tx_en);
 int t4_identify_port(struct adapter *adap, unsigned int mbox, unsigned int viid,
 		     unsigned int nblinks);
-int t4_i2c_rd(struct adapter *adap, unsigned int mbox, unsigned int port_id,
-	      u8 dev_addr, u8 offset, u8 *valp);
 int t4_mdio_rd(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
 	       unsigned int mmd, unsigned int reg, unsigned int *valp);
 int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
 	       unsigned int mmd, unsigned int reg, unsigned int val);
+int t4_i2c_rd(struct adapter *adap, unsigned int mbox,
+	      int port, unsigned int devid,
+	      unsigned int offset, unsigned int len,
+	      u8 *buf);
+int t4_i2c_wr(struct adapter *adap, unsigned int mbox,
+	      int port, unsigned int devid,
+	      unsigned int offset, unsigned int len,
+	      u8 *buf);
 int t4_iq_start_stop(struct adapter *adap, unsigned int mbox, bool start,
 		     unsigned int pf, unsigned int vf, unsigned int iqid,
 		     unsigned int fl0id, unsigned int fl1id);

Modified: head/sys/dev/cxgbe/common/t4_hw.c
==============================================================================
--- head/sys/dev/cxgbe/common/t4_hw.c	Tue Jul 15 00:27:08 2014	(r268639)
+++ head/sys/dev/cxgbe/common/t4_hw.c	Tue Jul 15 01:03:29 2014	(r268640)
@@ -4148,36 +4148,6 @@ int t4_fwaddrspace_write(struct adapter 
 }
 
 /**
- *	t4_i2c_rd - read a byte from an i2c addressable device
- *	@adap: the adapter
- *	@mbox: mailbox to use for the FW command
- *	@port_id: the port id
- *	@dev_addr: the i2c device address
- *	@offset: the byte offset to read from
- *	@valp: where to store the value
- */
-int t4_i2c_rd(struct adapter *adap, unsigned int mbox, unsigned int port_id,
-	       u8 dev_addr, u8 offset, u8 *valp)
-{
-	int ret;
-	struct fw_ldst_cmd c;
-
-	memset(&c, 0, sizeof(c));
-	c.op_to_addrspace = htonl(V_FW_CMD_OP(FW_LDST_CMD) | F_FW_CMD_REQUEST |
-		F_FW_CMD_READ |
-		V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_FUNC_I2C));
-	c.cycles_to_len16 = htonl(FW_LEN16(c));
-	c.u.i2c_deprecated.pid_pkd = V_FW_LDST_CMD_PID(port_id);
-	c.u.i2c_deprecated.base = dev_addr;
-	c.u.i2c_deprecated.boffset = offset;
-
-	ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
-	if (ret == 0)
-		*valp = c.u.i2c_deprecated.data;
-	return ret;
-}
-
-/**
  *	t4_mdio_rd - read a PHY register through MDIO
  *	@adap: the adapter
  *	@mbox: mailbox to use for the FW command
@@ -4237,6 +4207,87 @@ int t4_mdio_wr(struct adapter *adap, uns
 }
 
 /**
+ *	t4_i2c_rd - read I2C data from adapter
+ *	@adap: the adapter
+ *	@port: Port number if per-port device; <0 if not
+ *	@devid: per-port device ID or absolute device ID
+ *	@offset: byte offset into device I2C space
+ *	@len: byte length of I2C space data
+ *	@buf: buffer in which to return I2C data
+ *
+ *	Reads the I2C data from the indicated device and location.
+ */
+int t4_i2c_rd(struct adapter *adap, unsigned int mbox,
+	      int port, unsigned int devid,
+	      unsigned int offset, unsigned int len,
+	      u8 *buf)
+{
+	struct fw_ldst_cmd ldst;
+	int ret;
+
+	if (port >= 4 ||
+	    devid >= 256 ||
+	    offset >= 256 ||
+	    len > sizeof ldst.u.i2c.data)
+		return -EINVAL;
+
+	memset(&ldst, 0, sizeof ldst);
+	ldst.op_to_addrspace =
+		cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) |
+			    F_FW_CMD_REQUEST |
+			    F_FW_CMD_READ |
+			    V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_I2C));
+	ldst.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst));
+	ldst.u.i2c.pid = (port < 0 ? 0xff : port);
+	ldst.u.i2c.did = devid;
+	ldst.u.i2c.boffset = offset;
+	ldst.u.i2c.blen = len;
+	ret = t4_wr_mbox(adap, mbox, &ldst, sizeof ldst, &ldst);
+	if (!ret)
+		memcpy(buf, ldst.u.i2c.data, len);
+	return ret;
+}
+
+/**
+ *	t4_i2c_wr - write I2C data to adapter
+ *	@adap: the adapter
+ *	@port: Port number if per-port device; <0 if not
+ *	@devid: per-port device ID or absolute device ID
+ *	@offset: byte offset into device I2C space
+ *	@len: byte length of I2C space data
+ *	@buf: buffer containing new I2C data
+ *
+ *	Write the I2C data to the indicated device and location.
+ */
+int t4_i2c_wr(struct adapter *adap, unsigned int mbox,
+	      int port, unsigned int devid,
+	      unsigned int offset, unsigned int len,
+	      u8 *buf)
+{
+	struct fw_ldst_cmd ldst;
+
+	if (port >= 4 ||
+	    devid >= 256 ||
+	    offset >= 256 ||
+	    len > sizeof ldst.u.i2c.data)
+		return -EINVAL;
+
+	memset(&ldst, 0, sizeof ldst);
+	ldst.op_to_addrspace =
+		cpu_to_be32(V_FW_CMD_OP(FW_LDST_CMD) |
+			    F_FW_CMD_REQUEST |
+			    F_FW_CMD_WRITE |
+			    V_FW_LDST_CMD_ADDRSPACE(FW_LDST_ADDRSPC_I2C));
+	ldst.cycles_to_len16 = cpu_to_be32(FW_LEN16(ldst));
+	ldst.u.i2c.pid = (port < 0 ? 0xff : port);
+	ldst.u.i2c.did = devid;
+	ldst.u.i2c.boffset = offset;
+	ldst.u.i2c.blen = len;
+	memcpy(ldst.u.i2c.data, buf, len);
+	return t4_wr_mbox(adap, mbox, &ldst, sizeof ldst, &ldst);
+}
+
+/**
  *	t4_sge_ctxt_flush - flush the SGE context cache
  *	@adap: the adapter
  *	@mbox: mailbox to use for the FW command

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c	Tue Jul 15 00:27:08 2014	(r268639)
+++ head/sys/dev/cxgbe/t4_main.c	Tue Jul 15 01:03:29 2014	(r268640)
@@ -7535,16 +7535,14 @@ read_i2c(struct adapter *sc, struct t4_i
 	if (i2cd->len == 0 || i2cd->port_id >= sc->params.nports)
 		return (EINVAL);
 
-	if (i2cd->len > 1) {
-		/* XXX: need fw support for longer reads in one go */
-		return (ENOTSUP);
-	}
+	if (i2cd->len > sizeof(i2cd->data))
+		return (EFBIG);
 
 	rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4i2crd");
 	if (rc)
 		return (rc);
 	rc = -t4_i2c_rd(sc, sc->mbox, i2cd->port_id, i2cd->dev_addr,
-	    i2cd->offset, &i2cd->data[0]);
+	    i2cd->offset, i2cd->len, &i2cd->data[0]);
 	end_synchronized_op(sc, 0);
 
 	return (rc);



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