2014-12-18 07:53:52

by Grumbach, Emmanuel

[permalink] [raw]
Subject: pull request: iwlwifi 2014-12-18

Hi Kalle,

First congrats on your new role - I am sure we'll find the way to work together in the new layout.
John - it was a pleasure. I stepped up as a maintainer of iwlwifi only a bit more than a year ago.
You had the patience to bear with me while I was doing my mistakes of the beginning.
Your signature is: "One day - the world will need a hero and you might be all we have - be ready".
Wireless used to be like Jeff described in the post you sent, but then came the "hero" and said:
https://lkml.org/lkml/2006/1/10/458
Thank you John - take care of yourself and who knows... we might see you again around :)

Back to work. This is for 3.19.
As usual, the details are below - let me know if you have issues.
Thanks!

The following changes since commit 70e71ca0af244f48a5dcf56dc435243792e3a495:

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next (2014-12-11 14:27:06 -0800)

are available in the git repository at:


git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git tags/iwlwifi-fixes-for-kalle-2014-12-18

for you to fetch changes up to baa21e834941ee5fbe4bd421c871f7c0c5f9a086:

iwlwifi: pcie: limit fw chunk sizes given to fh (2014-12-14 10:20:30 +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.

----------------------------------------------------------------
Eliad Peller (1):
iwlwifi: mvm: clear IN_HW_RESTART flag on stop()

Emmanuel Grumbach (3):
iwlwifi: pcie: re-ACK all interrupts after device reset
iwlwifi: don't double free a pointer if no FW was found
iwlwifi: add new device IDs for 3165

Liad Kaufman (1):
iwlwifi: pcie: limit fw chunk sizes given to fh

drivers/net/wireless/iwlwifi/iwl-drv.c | 2 +-
drivers/net/wireless/iwlwifi/iwl-fh.h | 1 +
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 15 +++++++++++++--
drivers/net/wireless/iwlwifi/pcie/drv.c | 4 ++++
drivers/net/wireless/iwlwifi/pcie/trans.c | 17 +++++++++++------
5 files changed, 30 insertions(+), 9 deletions(-)


2014-12-22 08:08:04

by Kalle Valo

[permalink] [raw]
Subject: Re: pull request: iwlwifi 2014-12-18

"Grumbach, Emmanuel" <[email protected]> writes:

> First congrats on your new role - I am sure we'll find the way to work
> together in the new layout.

Thanks!

> Back to work. This is for 3.19. As usual, the details are below - let
> me know if you have issues.

Pulled to wireless-drivers. I'll send this to Dave once kbuild bot has
done it's magic.

--
Kalle Valo

2014-12-18 08:11:25

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 4/5] iwlwifi: add new device IDs for 3165

From: Emmanuel Grumbach <[email protected]>

A few device IDs were added, reflect this change in the
driver.

Cc; <[email protected]> [3.13+]
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/pcie/drv.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index 3ee8e38..2f0c4b1 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -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)},
--
1.9.1


2014-12-18 08:11:21

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 1/5] iwlwifi: mvm: clear IN_HW_RESTART flag on stop()

From: Eliad Peller <[email protected]>

On stop(), we already cleared our internal state,
and the restart_complete() callback won't be
called, so simply clear the IN_HW_RESTART flag.

Keeping the flag might result in invalid state
on the next start(), preventing the driver starting
properly.

Additionally, don't take IWL_MVM_REF_UCODE_DOWN on stop()
if hw restart was requested, as the ref was already
taken in this case.

Signed-off-by: Eliad Peller <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 31a5b3f..e880f9d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -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;
}

--
1.9.1


2014-12-18 08:11:24

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 3/5] iwlwifi: don't double free a pointer if no FW was found

From: Emmanuel Grumbach <[email protected]>

In the very unlikely case in which no firmware could be,
found. the same pointer was freed twice. Fix that.

Fixes: 490fefebb6db ("iwlwifi: define the .ucode file format for debug")
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-drv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 38de151..850b85a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -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:
--
1.9.1


2014-12-18 08:11:26

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 5/5] iwlwifi: pcie: limit fw chunk sizes given to fh

From: Liad Kaufman <[email protected]>

New FW has chunks that are larger than the size limit of the
FH's DMA. To make sure we don't crash it - actively limit the
max size of each chunk.

Signed-off-by: Liad Kaufman <[email protected]>
Reviewed-by: Johannes Berg <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/iwl-fh.h | 1 +
drivers/net/wireless/iwlwifi/pcie/trans.c | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/net/wireless/iwlwifi/iwl-fh.h b/drivers/net/wireless/iwlwifi/iwl-fh.h
index 9564ae1..1f7f15e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fh.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fh.h
@@ -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)
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index d151af3..523fe0c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -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",
--
1.9.1


2014-12-18 08:11:22

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 2/5] iwlwifi: pcie: re-ACK all interrupts after device reset

From: Emmanuel Grumbach <[email protected]>

When we reset the device, the CSR_INT gets cleared as well
as CSR_INT_MASK. Meaning that we shouldn't get any interrupt
but, due to a hardware bug, recent devices will keep sending
interrupts. This leads to an interrupt storm while stopping
the device.
The way to fix this is to ACK all the interrupts after the
device is reset so that the value of CSR_INT will stay
0xffffffff.

Fixes: 522713c81e4e ("iwlwifi: pcie: properly reset the device")
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/pcie/trans.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 5d79a1f..d151af3 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -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);
--
1.9.1