mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-18 10:35:55 +00:00
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
This commit is contained in:
parent
ad15140ee7
commit
44eb893659
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=268640
@ -585,12 +585,18 @@ int t4_enable_vi_ns(struct adapter *adap, unsigned int mbox, unsigned int viid,
|
||||
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);
|
||||
|
@ -4147,36 +4147,6 @@ int t4_fwaddrspace_write(struct adapter *adap, unsigned int mbox, u32 addr, u32
|
||||
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -4236,6 +4206,87 @@ int t4_mdio_wr(struct adapter *adap, unsigned int mbox, unsigned int phy_addr,
|
||||
return t4_wr_mbox(adap, mbox, &c, sizeof(c), NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -7535,16 +7535,14 @@ read_i2c(struct adapter *sc, struct t4_i2c_data *i2cd)
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user