]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge tag 'iwlwifi-fixes-for-kalle-2014-12-18' of git://git.kernel.org/pub/scm/linux...
authorKalle Valo <kvalo@codeaurora.org>
Sun, 21 Dec 2014 10:39:58 +0000 (12:39 +0200)
committerKalle Valo <kvalo@codeaurora.org>
Sun, 21 Dec 2014 10:39:58 +0000 (12:39 +0200)
I have here new device IDs and a fix for double free bug I introduced.
I also fix an issue with the RFKILL interrupt - the HW needs us to ACK
the interrupt again after we reset it.
Liad fixes an issue with the firmware debugging infrastructure.
While working on torture scenarios of firmware restarts, Eliad found an
issue which he fixed.

drivers/net/wireless/iwlwifi/iwl-drv.c
drivers/net/wireless/iwlwifi/iwl-fh.h
drivers/net/wireless/iwlwifi/mvm/mac80211.c
drivers/net/wireless/iwlwifi/pcie/drv.c
drivers/net/wireless/iwlwifi/pcie/trans.c

index 38de1513e4dedd5588367e44d2877ceed39234b6..850b85a478063b9a5fc8ddc1e31eedb5b83b18c2 100644 (file)
@@ -1323,10 +1323,10 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
 
  try_again:
        /* try next, if any */
-       kfree(pieces);
        release_firmware(ucode_raw);
        if (iwl_request_firmware(drv, false))
                goto out_unbind;
+       kfree(pieces);
        return;
 
  out_free_fw:
index 9564ae173d060a46bd34c60970ce77d6eb483a73..1f7f15eb86da208df591ae8e7ca27e52c5921acf 100644 (file)
@@ -310,6 +310,7 @@ static inline unsigned int FH_MEM_CBBC_QUEUE(unsigned int chnl)
 #define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE      (0x01000000)
 
 #define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT        28
+#define FH_MEM_TB_MAX_LENGTH                   (0x00020000)
 
 /* TFDB  Area - TFDs buffer table */
 #define FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK      (0xFFFFFFFF)
index 31a5b3f4266c3edaf26a05dfca208ddd2082f8ca..e880f9d4717ba4de642916e252bfaf7279ade237 100644 (file)
@@ -1004,8 +1004,13 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
 {
        lockdep_assert_held(&mvm->mutex);
 
-       /* disallow low power states when the FW is down */
-       iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
+       /*
+        * Disallow low power states when the FW is down by taking
+        * the UCODE_DOWN ref. in case of ongoing hw restart the
+        * ref is already taken, so don't take it again.
+        */
+       if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
+               iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
 
        /* async_handlers_wk is now blocked */
 
@@ -1023,6 +1028,12 @@ void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
        /* the fw is stopped, the aux sta is dead: clean up driver state */
        iwl_mvm_del_aux_sta(mvm);
 
+       /*
+        * Clear IN_HW_RESTART flag when stopping the hw (as restart_complete()
+        * won't be called in this case).
+        */
+       clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
+
        mvm->ucode_loaded = false;
 }
 
index 3ee8e3848876f48cce72ce98dff2e2bfde875a23..2f0c4b1703442b85b3a56bd90c0548995e0bc661 100644 (file)
@@ -367,7 +367,11 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
 
 /* 3165 Series */
        {IWL_PCI_DEVICE(0x3165, 0x4010, iwl3165_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x3165, 0x4012, iwl3165_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x3165, 0x4110, iwl3165_2ac_cfg)},
        {IWL_PCI_DEVICE(0x3165, 0x4210, iwl3165_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x3165, 0x4410, iwl3165_2ac_cfg)},
+       {IWL_PCI_DEVICE(0x3165, 0x4510, iwl3165_2ac_cfg)},
 
 /* 7265 Series */
        {IWL_PCI_DEVICE(0x095A, 0x5010, iwl7265_2ac_cfg)},
index 5d79a1f44b8e43a723b9de98ca780a9ea5bc5812..523fe0c88dcb2d464ec915085371d376aec22e28 100644 (file)
@@ -614,7 +614,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",
@@ -1012,16 +1012,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);
 
-       /* 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);