Commit b48e4aa3 authored by Don Skidmore's avatar Don Skidmore Committed by Jeff Kirsher

ixgbe: Add timeout parameter to ixgbe_host_interface_command

Since on X550 we use host interface commands to read,write and erase
some commands require more time to complete. So this adds a timeout
parameter to ixgbe_host_interface_command as wells as a return_data
parameter allowing us to return with any data.
Signed-off-by: default avatarDon Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 0f9b232b
...@@ -3446,23 +3446,34 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length) ...@@ -3446,23 +3446,34 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
* @buffer: contains the command to write and where the return status will * @buffer: contains the command to write and where the return status will
* be placed * be placed
* @length: length of buffer, must be multiple of 4 bytes * @length: length of buffer, must be multiple of 4 bytes
* @timeout: time in ms to wait for command completion
* @return_data: read and return data from the buffer (true) or not (false)
* Needed because FW structures are big endian and decoding of
* these fields can be 8 bit or 16 bit based on command. Decoding
* is not easily understood without making a table of commands.
* So we will leave this up to the caller to read back the data
* in these cases.
* *
* Communicates with the manageability block. On success return 0 * Communicates with the manageability block. On success return 0
* else return IXGBE_ERR_HOST_INTERFACE_COMMAND. * else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
**/ **/
static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
u32 length) u32 length, u32 timeout,
bool return_data)
{ {
u32 hicr, i, bi; u32 hicr, i, bi, fwsts;
u32 hdr_size = sizeof(struct ixgbe_hic_hdr); u32 hdr_size = sizeof(struct ixgbe_hic_hdr);
u8 buf_len, dword_len; u16 buf_len, dword_len;
if (length == 0 || length & 0x3 || if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length);
hw_dbg(hw, "Buffer length failure.\n");
return IXGBE_ERR_HOST_INTERFACE_COMMAND; return IXGBE_ERR_HOST_INTERFACE_COMMAND;
} }
/* Set bit 9 of FWSTS clearing FW reset indication */
fwsts = IXGBE_READ_REG(hw, IXGBE_FWSTS);
IXGBE_WRITE_REG(hw, IXGBE_FWSTS, fwsts | IXGBE_FWSTS_FWRI);
/* Check that the host interface is enabled. */ /* Check that the host interface is enabled. */
hicr = IXGBE_READ_REG(hw, IXGBE_HICR); hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if ((hicr & IXGBE_HICR_EN) == 0) { if ((hicr & IXGBE_HICR_EN) == 0) {
...@@ -3470,7 +3481,12 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ...@@ -3470,7 +3481,12 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
return IXGBE_ERR_HOST_INTERFACE_COMMAND; return IXGBE_ERR_HOST_INTERFACE_COMMAND;
} }
/* Calculate length in DWORDs */ /* Calculate length in DWORDs. We must be DWORD aligned */
if ((length % (sizeof(u32))) != 0) {
hw_dbg(hw, "Buffer length failure, not aligned to dword");
return IXGBE_ERR_INVALID_ARGUMENT;
}
dword_len = length >> 2; dword_len = length >> 2;
/* /*
...@@ -3484,7 +3500,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ...@@ -3484,7 +3500,7 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
/* Setting this bit tells the ARC that a new command is pending. */ /* Setting this bit tells the ARC that a new command is pending. */
IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C); IXGBE_WRITE_REG(hw, IXGBE_HICR, hicr | IXGBE_HICR_C);
for (i = 0; i < IXGBE_HI_COMMAND_TIMEOUT; i++) { for (i = 0; i < timeout; i++) {
hicr = IXGBE_READ_REG(hw, IXGBE_HICR); hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if (!(hicr & IXGBE_HICR_C)) if (!(hicr & IXGBE_HICR_C))
break; break;
...@@ -3492,12 +3508,15 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer, ...@@ -3492,12 +3508,15 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
} }
/* Check command successful completion. */ /* Check command successful completion. */
if (i == IXGBE_HI_COMMAND_TIMEOUT || if ((timeout != 0 && i == timeout) ||
(!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) { (!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) {
hw_dbg(hw, "Command has failed with no status valid.\n"); hw_dbg(hw, "Command has failed with no status valid.\n");
return IXGBE_ERR_HOST_INTERFACE_COMMAND; return IXGBE_ERR_HOST_INTERFACE_COMMAND;
} }
if (!return_data)
return 0;
/* Calculate length in DWORDs */ /* Calculate length in DWORDs */
dword_len = hdr_size >> 2; dword_len = hdr_size >> 2;
...@@ -3568,7 +3587,9 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min, ...@@ -3568,7 +3587,9 @@ s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) { for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd, ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
sizeof(fw_cmd)); sizeof(fw_cmd),
IXGBE_HI_COMMAND_TIMEOUT,
true);
if (ret_val != 0) if (ret_val != 0)
continue; continue;
......
...@@ -2314,9 +2314,12 @@ enum ixgbe_fdir_pballoc_type { ...@@ -2314,9 +2314,12 @@ enum ixgbe_fdir_pballoc_type {
#define IXGBE_FDIR_DROP_QUEUE 127 #define IXGBE_FDIR_DROP_QUEUE 127
/* Manageablility Host Interface defines */ /* Manageablility Host Interface defines */
#define IXGBE_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */ #define IXGBE_HI_MAX_BLOCK_BYTE_LENGTH 1792 /* Num of bytes in range */
#define IXGBE_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */ #define IXGBE_HI_MAX_BLOCK_DWORD_LENGTH 448 /* Num of dwords in range */
#define IXGBE_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */ #define IXGBE_HI_COMMAND_TIMEOUT 500 /* Process HI command limit */
#define IXGBE_HI_FLASH_ERASE_TIMEOUT 1000 /* Process Erase command limit */
#define IXGBE_HI_FLASH_UPDATE_TIMEOUT 5000 /* Process Update command limit */
#define IXGBE_HI_FLASH_APPLY_TIMEOUT 0 /* Process Apply command limit */
/* CEM Support */ /* CEM Support */
#define FW_CEM_HDR_LEN 0x4 #define FW_CEM_HDR_LEN 0x4
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment