]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/net/ethernet/intel/i40e/i40e_adminq.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[karo-tx-linux.git] / drivers / net / ethernet / intel / i40e / i40e_adminq.c
index c0e943aecd1394262757e790b04a6ce1eccda72a..0ff8f01e57ee5a4a7de890485e5987fd9eec7f8a 100644 (file)
@@ -482,8 +482,12 @@ static i40e_status i40e_shutdown_asq(struct i40e_hw *hw)
 {
        i40e_status ret_code = 0;
 
-       if (hw->aq.asq.count == 0)
-               return I40E_ERR_NOT_READY;
+       mutex_lock(&hw->aq.asq_mutex);
+
+       if (hw->aq.asq.count == 0) {
+               ret_code = I40E_ERR_NOT_READY;
+               goto shutdown_asq_out;
+       }
 
        /* Stop firmware AdminQ processing */
        wr32(hw, hw->aq.asq.head, 0);
@@ -492,16 +496,13 @@ static i40e_status i40e_shutdown_asq(struct i40e_hw *hw)
        wr32(hw, hw->aq.asq.bal, 0);
        wr32(hw, hw->aq.asq.bah, 0);
 
-       /* make sure lock is available */
-       mutex_lock(&hw->aq.asq_mutex);
-
        hw->aq.asq.count = 0; /* to indicate uninitialized queue */
 
        /* free ring buffers */
        i40e_free_asq_bufs(hw);
 
+shutdown_asq_out:
        mutex_unlock(&hw->aq.asq_mutex);
-
        return ret_code;
 }
 
@@ -515,8 +516,12 @@ static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
 {
        i40e_status ret_code = 0;
 
-       if (hw->aq.arq.count == 0)
-               return I40E_ERR_NOT_READY;
+       mutex_lock(&hw->aq.arq_mutex);
+
+       if (hw->aq.arq.count == 0) {
+               ret_code = I40E_ERR_NOT_READY;
+               goto shutdown_arq_out;
+       }
 
        /* Stop firmware AdminQ processing */
        wr32(hw, hw->aq.arq.head, 0);
@@ -525,16 +530,13 @@ static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
        wr32(hw, hw->aq.arq.bal, 0);
        wr32(hw, hw->aq.arq.bah, 0);
 
-       /* make sure lock is available */
-       mutex_lock(&hw->aq.arq_mutex);
-
        hw->aq.arq.count = 0; /* to indicate uninitialized queue */
 
        /* free ring buffers */
        i40e_free_arq_bufs(hw);
 
+shutdown_arq_out:
        mutex_unlock(&hw->aq.arq_mutex);
-
        return ret_code;
 }
 
@@ -551,8 +553,9 @@ static i40e_status i40e_shutdown_arq(struct i40e_hw *hw)
  **/
 i40e_status i40e_init_adminq(struct i40e_hw *hw)
 {
-       i40e_status ret_code;
+       u16 cfg_ptr, oem_hi, oem_lo;
        u16 eetrack_lo, eetrack_hi;
+       i40e_status ret_code;
        int retry = 0;
 
        /* verify input for valid configuration */
@@ -611,6 +614,12 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
        i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
        i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
        hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
+       i40e_read_nvm_word(hw, I40E_SR_BOOT_CONFIG_PTR, &cfg_ptr);
+       i40e_read_nvm_word(hw, (cfg_ptr + I40E_NVM_OEM_VER_OFF),
+                          &oem_hi);
+       i40e_read_nvm_word(hw, (cfg_ptr + (I40E_NVM_OEM_VER_OFF + 1)),
+                          &oem_lo);
+       hw->nvm.oem_ver = ((u32)oem_hi << 16) | oem_lo;
 
        if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) {
                ret_code = I40E_ERR_FIRMWARE_API_VERSION;
@@ -657,6 +666,9 @@ i40e_status i40e_shutdown_adminq(struct i40e_hw *hw)
 
        /* destroy the locks */
 
+       if (hw->nvm_buff.va)
+               i40e_free_virt_mem(hw, &hw->nvm_buff);
+
        return ret_code;
 }
 
@@ -678,8 +690,7 @@ static u16 i40e_clean_asq(struct i40e_hw *hw)
        details = I40E_ADMINQ_DETAILS(*asq, ntc);
        while (rd32(hw, hw->aq.asq.head) != ntc) {
                i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
-                          "%s: ntc %d head %d.\n", __func__, ntc,
-                          rd32(hw, hw->aq.asq.head));
+                          "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));
 
                if (details->callback) {
                        I40E_ADMINQ_CALLBACK cb_func =
@@ -742,19 +753,23 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
        u16  retval = 0;
        u32  val = 0;
 
-       val = rd32(hw, hw->aq.asq.head);
-       if (val >= hw->aq.num_asq_entries) {
+       mutex_lock(&hw->aq.asq_mutex);
+
+       if (hw->aq.asq.count == 0) {
                i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
-                          "AQTX: head overrun at %d\n", val);
+                          "AQTX: Admin queue not initialized.\n");
                status = I40E_ERR_QUEUE_EMPTY;
-               goto asq_send_command_exit;
+               goto asq_send_command_error;
        }
 
-       if (hw->aq.asq.count == 0) {
+       hw->aq.asq_last_status = I40E_AQ_RC_OK;
+
+       val = rd32(hw, hw->aq.asq.head);
+       if (val >= hw->aq.num_asq_entries) {
                i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
-                          "AQTX: Admin queue not initialized.\n");
+                          "AQTX: head overrun at %d\n", val);
                status = I40E_ERR_QUEUE_EMPTY;
-               goto asq_send_command_exit;
+               goto asq_send_command_error;
        }
 
        details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
@@ -779,8 +794,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
        desc->flags &= ~cpu_to_le16(details->flags_dis);
        desc->flags |= cpu_to_le16(details->flags_ena);
 
-       mutex_lock(&hw->aq.asq_mutex);
-
        if (buff_size > hw->aq.asq_buf_size) {
                i40e_debug(hw,
                           I40E_DEBUG_AQ_MESSAGE,
@@ -889,6 +902,10 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
                   "AQTX: desc and buffer writeback:\n");
        i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size);
 
+       /* save writeback aq if requested */
+       if (details->wb_desc)
+               *details->wb_desc = *desc_on_ring;
+
        /* update the error if time out occurred */
        if ((!cmd_completed) &&
            (!details->async && !details->postpone)) {
@@ -900,7 +917,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
 
 asq_send_command_error:
        mutex_unlock(&hw->aq.asq_mutex);
-asq_send_command_exit:
        return status;
 }
 
@@ -1023,6 +1039,19 @@ clean_arq_element_err:
                        i40e_release_nvm(hw);
                        hw->aq.nvm_release_on_done = false;
                }
+
+               switch (hw->nvmupd_state) {
+               case I40E_NVMUPD_STATE_INIT_WAIT:
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+                       break;
+
+               case I40E_NVMUPD_STATE_WRITE_WAIT:
+                       hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+                       break;
+
+               default:
+                       break;
+               }
        }
 
        return ret_code;