Skip to content

Commit

Permalink
ice: add i2c write command
Browse files Browse the repository at this point in the history
Add the possibility to write to connected i2c devices using the AQ
command. FW may reject the write if the device is not on allowlist.

Signed-off-by: Karol Kolacinski <karol.kolacinski@intel.com>
Tested-by: Gurucharan <gurucharanx.g@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Karol Kolacinski authored and Tony Nguyen committed Jul 21, 2022
1 parent 5588d62 commit fcf9b69
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 4 deletions.
7 changes: 4 additions & 3 deletions drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -1395,7 +1395,7 @@ struct ice_aqc_get_link_topo {
u8 rsvd[9];
};

/* Read I2C (direct, 0x06E2) */
/* Read/Write I2C (direct, 0x06E2/0x06E3) */
struct ice_aqc_i2c {
struct ice_aqc_link_topo_addr topo_addr;
__le16 i2c_addr;
Expand All @@ -1405,7 +1405,7 @@ struct ice_aqc_i2c {

u8 rsvd;
__le16 i2c_bus_addr;
u8 rsvd2[4];
u8 i2c_data[4]; /* Used only by write command, reserved in read. */
};

/* Read I2C Response (direct, 0x06E2) */
Expand Down Expand Up @@ -2124,7 +2124,7 @@ struct ice_aq_desc {
struct ice_aqc_get_link_status get_link_status;
struct ice_aqc_event_lan_overflow lan_overflow;
struct ice_aqc_get_link_topo get_link_topo;
struct ice_aqc_i2c read_i2c;
struct ice_aqc_i2c read_write_i2c;
struct ice_aqc_read_i2c_resp read_i2c_resp;
} params;
};
Expand Down Expand Up @@ -2241,6 +2241,7 @@ enum ice_adminq_opc {
ice_aqc_opc_set_mac_lb = 0x0620,
ice_aqc_opc_get_link_topo = 0x06E0,
ice_aqc_opc_read_i2c = 0x06E2,
ice_aqc_opc_write_i2c = 0x06E3,
ice_aqc_opc_set_port_id_led = 0x06E9,
ice_aqc_opc_set_gpio = 0x06EC,
ice_aqc_opc_get_gpio = 0x06ED,
Expand Down
47 changes: 46 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -4823,7 +4823,7 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
int status;

ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_read_i2c);
cmd = &desc.params.read_i2c;
cmd = &desc.params.read_write_i2c;

if (!data)
return -EINVAL;
Expand All @@ -4850,6 +4850,51 @@ ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
return status;
}

/**
* ice_aq_write_i2c
* @hw: pointer to the hw struct
* @topo_addr: topology address for a device to communicate with
* @bus_addr: 7-bit I2C bus address
* @addr: I2C memory address (I2C offset) with up to 16 bits
* @params: I2C parameters: bit [4] - I2C address type, bits [3:0] - data size to write (0-7 bytes)
* @data: pointer to data (0 to 4 bytes) to be written to the I2C device
* @cd: pointer to command details structure or NULL
*
* Write I2C (0x06E3)
*
* * Return:
* * 0 - Successful write to the i2c device
* * -EINVAL - Data size greater than 4 bytes
* * -EIO - FW error
*/
int
ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
u16 bus_addr, __le16 addr, u8 params, u8 *data,
struct ice_sq_cd *cd)
{
struct ice_aq_desc desc = { 0 };
struct ice_aqc_i2c *cmd;
u8 data_size;

ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_write_i2c);
cmd = &desc.params.read_write_i2c;

data_size = FIELD_GET(ICE_AQC_I2C_DATA_SIZE_M, params);

/* data_size limited to 4 */
if (data_size > 4)
return -EINVAL;

cmd->i2c_bus_addr = cpu_to_le16(bus_addr);
cmd->topo_addr = topo_addr;
cmd->i2c_params = params;
cmd->i2c_addr = addr;

memcpy(cmd->i2c_data, data, data_size);

return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
}

/**
* ice_aq_set_driver_param - Set driver parameter to share via firmware
* @hw: pointer to the HW struct
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,5 +214,9 @@ int
ice_aq_read_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
u16 bus_addr, __le16 addr, u8 params, u8 *data,
struct ice_sq_cd *cd);
int
ice_aq_write_i2c(struct ice_hw *hw, struct ice_aqc_link_topo_addr topo_addr,
u16 bus_addr, __le16 addr, u8 params, u8 *data,
struct ice_sq_cd *cd);
bool ice_fw_supports_report_dflt_cfg(struct ice_hw *hw);
#endif /* _ICE_COMMON_H_ */

0 comments on commit fcf9b69

Please sign in to comment.