Merge tag 'iwlwifi-next-for-kalle-2014-12-30' of https://git.kernel.org/pub/scm/linux...
[cascardo/linux.git] / drivers / net / wireless / iwlwifi / pcie / trans.c
index fbdbec8..9ee4ca0 100644 (file)
@@ -629,7 +629,7 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
 {
        u8 *v_addr;
        dma_addr_t p_addr;
-       u32 offset, chunk_sz = section->len;
+       u32 offset, chunk_sz = min_t(u32, FH_MEM_TB_MAX_LENGTH, section->len);
        int ret = 0;
 
        IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
@@ -908,6 +908,9 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
        if (ret)
                return ret;
 
+       if (trans->dbg_dest_tlv)
+               iwl_pcie_apply_destination(trans);
+
        /* Notify FW loading is done */
        iwl_write_direct32(trans, FH_UCODE_LOAD_STATUS, 0xFFFFFFFF);
 
@@ -1031,16 +1034,21 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
        /* Stop the device, and put it in low power state */
        iwl_pcie_apm_stop(trans, false);
 
-       /* Upon stop, the APM issues an interrupt if HW RF kill is set.
-        * Clean again the interrupt here
+       /* stop and reset the on-board processor */
+       iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
+       udelay(20);
+
+       /*
+        * Upon stop, the APM issues an interrupt if HW RF kill is set.
+        * This is a bug in certain verions of the hardware.
+        * Certain devices also keep sending HW RF kill interrupt all
+        * the time, unless the interrupt is ACKed even if the interrupt
+        * should be masked. Re-ACK all the interrupts here.
         */
        spin_lock(&trans_pcie->irq_lock);
        iwl_disable_interrupts(trans);
        spin_unlock(&trans_pcie->irq_lock);
 
-       /* stop and reset the on-board processor */
-       iwl_write32(trans, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
-       udelay(20);
 
        /* clear all status bits */
        clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
@@ -2453,6 +2461,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
        }
 
        trans_pcie->inta_mask = CSR_INI_SET_MASK;
+       trans->d0i3_mode = IWL_D0I3_MODE_ON_SUSPEND;
 
        return trans;