ixgbe: Add timeout parameter to ixgbe_host_interface_command
authorDon Skidmore <donald.c.skidmore@intel.com>
Sat, 29 Nov 2014 05:22:32 +0000 (05:22 +0000)
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>
Fri, 5 Dec 2014 17:13:06 +0000 (09:13 -0800)
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>
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
drivers/net/ethernet/intel/ixgbe/ixgbe_type.h

index 0e754b4c4220c1cc6bebe4ba9c7e49dc5b42cd92..7ed1e086c891cc995ee1d4b5f28afbcf98225a03 100644 (file)
@@ -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
  *           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) {
@@ -3470,7 +3481,12 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
                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;
 
        /*
@@ -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. */
        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;
@@ -3492,12 +3508,15 @@ static s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, u32 *buffer,
        }
 
        /* 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;
 
@@ -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;
 
index cc1ac04ce35342a133da444868ea885ebc284ad2..4ec6eadf4ed7106c95739074d46119025242943a 100644 (file)
@@ -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