2014-11-03 19:48:48

by Emmanuel Grumbach

[permalink] [raw]
Subject: pull request: iwlwifi 2014-11-03

Hi John,

Here is a pull request for 3.18.

Details below, please pull.

Thanks!

The following changes since commit 7f2ac8fb31896c9fb70dbd2a2e6642b79996fc13:

iwlwifi: pcie: fix polling in various places (2014-10-23 21:21:49 +0300)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git tags/iwlwifi-for-john-2014-11-03

for you to fetch changes up to 31b8b343e019e0a0c57ca9c13520a87f9cab884b:

iwlwifi: fix RFkill while calibrating (2014-11-03 15:29:17 +0200)

----------------------------------------------------------------
I fix here two issues that are related to the firmware
loading flow. A user reported that he couldn't load the
driver because the rfkill line was pulled up while we
were running the calibrations. This was happening while
booting the system: systemd was restoring the "disable
wifi settings" and that raised an RFKILL interrupt during
the calibration. Our driver didn't handle that properly
and this is now fixed.

----------------------------------------------------------------
Emmanuel Grumbach (2):
iwlwifi: mvm: initialize the cur_ucode upon boot
iwlwifi: fix RFkill while calibrating

drivers/net/wireless/iwlwifi/mvm/fw.c | 10 +++++++++-
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 1 +
drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 +
drivers/net/wireless/iwlwifi/mvm/ops.c | 12 +++++++++++-
drivers/net/wireless/iwlwifi/pcie/trans.c | 4 ++--
5 files changed, 24 insertions(+), 4 deletions(-)


2014-11-03 19:49:57

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 2/2] iwlwifi: fix RFkill while calibrating

From: Emmanuel Grumbach <[email protected]>

If the RFkill interrupt fires while we calibrate, it would
make the firmware fail and the driver wasn't able to recover.
Change the flow so that the driver will kill the firmware
in that case.

Since we have now two flows that are calling
trans_stop_device (the RFkill interrupt and the
op_mode_mvm_start function) - we need to better sync this.
Use the STATUS_DEVICE_ENABLED in the pcie transport in an
atomic way to achieve this.

This fixes: https://bugzilla.kernel.org/show_bug.cgi?id=86231

CC: <[email protected]> [3.10+]
Reviewed-by: Johannes Berg <[email protected]>
Reviewed-by: Luciano Coelho <[email protected]>
Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/fw.c | 10 +++++++++-
drivers/net/wireless/iwlwifi/mvm/mac80211.c | 1 +
drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 +
drivers/net/wireless/iwlwifi/mvm/ops.c | 11 ++++++++++-
drivers/net/wireless/iwlwifi/pcie/trans.c | 4 ++--
5 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index e0d9f19..eb03943 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -284,7 +284,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)

lockdep_assert_held(&mvm->mutex);

- if (WARN_ON_ONCE(mvm->init_ucode_complete))
+ if (WARN_ON_ONCE(mvm->init_ucode_complete || mvm->calibrating))
return 0;

iwl_init_notification_wait(&mvm->notif_wait,
@@ -334,6 +334,8 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
goto out;
}

+ mvm->calibrating = true;
+
/* Send TX valid antennas before triggering calibrations */
ret = iwl_send_tx_ant_cfg(mvm, mvm->fw->valid_tx_ant);
if (ret)
@@ -358,11 +360,17 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
MVM_UCODE_CALIB_TIMEOUT);
if (!ret)
mvm->init_ucode_complete = true;
+
+ if (ret && iwl_mvm_is_radio_killed(mvm)) {
+ IWL_DEBUG_RF_KILL(mvm, "RFKILL while calibrating.\n");
+ ret = 1;
+ }
goto out;

error:
iwl_remove_notification(&mvm->notif_wait, &calib_wait);
out:
+ mvm->calibrating = false;
if (iwlmvm_mod_params.init_dbg && !mvm->nvm_data) {
/* we want to debug INIT and we have no NVM - fake */
mvm->nvm_data = kzalloc(sizeof(struct iwl_nvm_data) +
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 585fe5b..b624058 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -788,6 +788,7 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)

mvm->scan_status = IWL_MVM_SCAN_NONE;
mvm->ps_disabled = false;
+ mvm->calibrating = false;

/* just in case one was running */
ieee80211_remain_on_channel_expired(mvm->hw);
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index b153ced..845429c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -548,6 +548,7 @@ struct iwl_mvm {
enum iwl_ucode_type cur_ucode;
bool ucode_loaded;
bool init_ucode_complete;
+ bool calibrating;
u32 error_event_table;
u32 log_event_table;
u32 umac_error_event_table;
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 27fb0a1..5b719ee 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -753,6 +753,7 @@ void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state)
static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)
{
struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode);
+ bool calibrating = ACCESS_ONCE(mvm->calibrating);

if (state)
set_bit(IWL_MVM_STATUS_HW_RFKILL, &mvm->status);
@@ -761,7 +762,15 @@ static bool iwl_mvm_set_hw_rfkill_state(struct iwl_op_mode *op_mode, bool state)

wiphy_rfkill_set_hw_state(mvm->hw->wiphy, iwl_mvm_is_radio_killed(mvm));

- return state && mvm->cur_ucode != IWL_UCODE_INIT;
+ /* iwl_run_init_mvm_ucode is waiting for results, abort it */
+ if (calibrating)
+ iwl_abort_notification_waits(&mvm->notif_wait);
+
+ /*
+ * Stop the device if we run OPERATIONAL firmware or if we are in the
+ * middle of the calibrations.
+ */
+ return state && (mvm->cur_ucode != IWL_UCODE_INIT || calibrating);
}

static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 3781b02..160c3eb 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -915,7 +915,8 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
* restart. So don't process again if the device is
* already dead.
*/
- if (test_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+ if (test_and_clear_bit(STATUS_DEVICE_ENABLED, &trans->status)) {
+ IWL_DEBUG_INFO(trans, "DEVICE_ENABLED bit was set and is now cleared\n");
iwl_pcie_tx_stop(trans);
iwl_pcie_rx_stop(trans);

@@ -945,7 +946,6 @@ static void iwl_trans_pcie_stop_device(struct iwl_trans *trans)
/* clear all status bits */
clear_bit(STATUS_SYNC_HCMD_ACTIVE, &trans->status);
clear_bit(STATUS_INT_ENABLED, &trans->status);
- clear_bit(STATUS_DEVICE_ENABLED, &trans->status);
clear_bit(STATUS_TPOWER_PMI, &trans->status);
clear_bit(STATUS_RFKILL, &trans->status);

--
1.9.1


2014-11-03 19:49:55

by Emmanuel Grumbach

[permalink] [raw]
Subject: [PATCH 1/2] iwlwifi: mvm: initialize the cur_ucode upon boot

From: Emmanuel Grumbach <[email protected]>

mvm->cur_ucode wasn't set before we actually load the
firmware. This caused issues when we boot in RFKILL since
we get an RFKILL interrupt upon boot even before we load
any firmware.
This leads to issues since iwl_mvm_set_hw_rfkill_state
(the RFKILL interrupts handler in mvm) relies on this
variable.

Fix this.

Signed-off-by: Emmanuel Grumbach <[email protected]>
---
drivers/net/wireless/iwlwifi/mvm/ops.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 48cb25a..27fb0a1 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -424,6 +424,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
}
mvm->sf_state = SF_UNINIT;
mvm->low_latency_agg_frame_limit = 6;
+ mvm->cur_ucode = IWL_UCODE_INIT;

mutex_init(&mvm->mutex);
mutex_init(&mvm->d0i3_suspend_mutex);
--
1.9.1


2014-11-04 21:30:10

by John W. Linville

[permalink] [raw]
Subject: Re: pull request: iwlwifi 2014-11-03

On Mon, Nov 03, 2014 at 09:48:44PM +0200, Emmanuel Grumbach wrote:
> Hi John,
>
> Here is a pull request for 3.18.
>
> Details below, please pull.
>
> Thanks!
>
> The following changes since commit 7f2ac8fb31896c9fb70dbd2a2e6642b79996fc13:
>
> iwlwifi: pcie: fix polling in various places (2014-10-23 21:21:49 +0300)
>
> are available in the git repository at:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-fixes.git tags/iwlwifi-for-john-2014-11-03
>
> for you to fetch changes up to 31b8b343e019e0a0c57ca9c13520a87f9cab884b:
>
> iwlwifi: fix RFkill while calibrating (2014-11-03 15:29:17 +0200)
>
> ----------------------------------------------------------------
> I fix here two issues that are related to the firmware
> loading flow. A user reported that he couldn't load the
> driver because the rfkill line was pulled up while we
> were running the calibrations. This was happening while
> booting the system: systemd was restoring the "disable
> wifi settings" and that raised an RFKILL interrupt during
> the calibration. Our driver didn't handle that properly
> and this is now fixed.
>
> ----------------------------------------------------------------
> Emmanuel Grumbach (2):
> iwlwifi: mvm: initialize the cur_ucode upon boot
> iwlwifi: fix RFkill while calibrating
>
> drivers/net/wireless/iwlwifi/mvm/fw.c | 10 +++++++++-
> drivers/net/wireless/iwlwifi/mvm/mac80211.c | 1 +
> drivers/net/wireless/iwlwifi/mvm/mvm.h | 1 +
> drivers/net/wireless/iwlwifi/mvm/ops.c | 12 +++++++++++-
> drivers/net/wireless/iwlwifi/pcie/trans.c | 4 ++--
> 5 files changed, 24 insertions(+), 4 deletions(-)

Pulling now...

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.