Skip to content

Commit

Permalink
ixgbe: Add timeout parameter to ixgbe_host_interface_command
Browse files Browse the repository at this point in the history
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: Don Skidmore <donald.c.skidmore@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Don Skidmore authored and Jeff Kirsher committed Dec 5, 2014
1 parent 0f9b232 commit b48e4aa
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
41 changes: 31 additions & 10 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -3446,31 +3446,47 @@ static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
* @buffer: contains the command to write and where the return status will
* be placed
* @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
* else return IXGBE_ERR_HOST_INTERFACE_COMMAND.
**/
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);
u8 buf_len, dword_len;
u16 buf_len, dword_len;

if (length == 0 || length & 0x3 ||
length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
hw_dbg(hw, "Buffer length failure.\n");
if (length == 0 || length > IXGBE_HI_MAX_BLOCK_BYTE_LENGTH) {
hw_dbg(hw, "Buffer length failure buffersize-%d.\n", length);
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. */
hicr = IXGBE_READ_REG(hw, IXGBE_HICR);
if ((hicr & IXGBE_HICR_EN) == 0) {
hw_dbg(hw, "IXGBE_HOST_EN bit disabled.\n");
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;

/*
Expand All @@ -3484,20 +3500,23 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
/* Setting this bit tells the ARC that a new command is pending. */
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);
if (!(hicr & IXGBE_HICR_C))
break;
usleep_range(1000, 2000);
}

/* Check command successful completion. */
if (i == IXGBE_HI_COMMAND_TIMEOUT ||
if ((timeout != 0 && i == timeout) ||
(!(IXGBE_READ_REG(hw, IXGBE_HICR) & IXGBE_HICR_SV))) {
hw_dbg(hw, "Command has failed with no status valid.\n");
return IXGBE_ERR_HOST_INTERFACE_COMMAND;
}

if (!return_data)
return 0;

/* Calculate length in DWORDs */
dword_len = hdr_size >> 2;

Expand Down Expand Up @@ -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++) {
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)
continue;

Expand Down
9 changes: 6 additions & 3 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -2314,9 +2314,12 @@ enum ixgbe_fdir_pballoc_type {
#define IXGBE_FDIR_DROP_QUEUE 127

/* Manageablility Host Interface defines */
#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_COMMAND_TIMEOUT 500 /* Process HI command limit */
#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_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 */
#define FW_CEM_HDR_LEN 0x4
Expand Down

0 comments on commit b48e4aa

Please sign in to comment.