diff options
author | Eran Harary <eran.harary@intel.com> | 2015-04-27 10:29:31 +0300 |
---|---|---|
committer | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2015-04-28 14:58:51 +0300 |
commit | 8d193ca26cc28019e760b77830295a0c349d90dc (patch) | |
tree | a6f6ab3f1292c21106fa941c2c9827b065b45370 /drivers/net/wireless/iwlwifi/mvm/fw.c | |
parent | 553452e5ffc0ed13214a287549627d02d9d7fbdc (diff) | |
download | linux-8d193ca26cc28019e760b77830295a0c349d90dc.tar.xz |
iwlwifi: mvm: don't power off the device between INIT and OPER firmwares
Our device needs two different firmwares: the INIT firmware
and the operational (OPER) firmware. The first one is run
when the driver loads and it returns calibrations results
as well as the NVM. The second one implements the WiFi
protocol.
If the wlan interface is not brought up, the device is put
to low power state: no firmware will be running. When the
interface is brought up, we would run the OPER firmware
only and reuse the results of the run of the INIT firmware
when the driver was loaded. This is changing with this
patch.
We now run the INIT firmware every time mac80211 calls
start(). The penalty for that is minimal since the INIT
firwmare run fast. I now also avoid to power down the device
between the INIT and OPER firmware on certains buses.
The motivation for this change is that there are components
on the device (MFUART) that are triggered by the INIT
firmware and need the device to be powered up in order to
keep running. Powering the device down between the INIT and
OPER firmware would stop these components and prevent them
from running again since they are triggered by the INIT
firmware only.
The new flow allows this and also allows to trigger these
components again when the interface is brought up after
it has been brought down.
Signed-off-by: Eran Harary <eran.harary@intel.com>
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/mvm/fw.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/fw.c | 45 |
1 files changed, 21 insertions, 24 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index 9c28fe72fd74..df869633f4dd 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -6,7 +6,7 @@ * GPL LICENSE SUMMARY * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as @@ -32,7 +32,7 @@ * BSD LICENSE * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. - * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -322,7 +322,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 || mvm->calibrating)) + if (WARN_ON_ONCE(mvm->calibrating)) return 0; iwl_init_notification_wait(&mvm->notif_wait, @@ -396,8 +396,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) */ ret = iwl_wait_notification(&mvm->notif_wait, &calib_wait, 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"); @@ -649,25 +647,24 @@ int iwl_mvm_up(struct iwl_mvm *mvm) * module loading, load init ucode now * (for example, if we were in RFKILL) */ - if (!mvm->init_ucode_complete) { - ret = iwl_run_init_mvm_ucode(mvm, false); - if (ret && !iwlmvm_mod_params.init_dbg) { - IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); - /* this can't happen */ - if (WARN_ON(ret > 0)) - ret = -ERFKILL; - goto error; - } - if (!iwlmvm_mod_params.init_dbg) { - /* - * should stop and start HW since that INIT - * image just loaded - */ - iwl_trans_stop_device(mvm->trans); - ret = iwl_trans_start_hw(mvm->trans); - if (ret) - return ret; - } + ret = iwl_run_init_mvm_ucode(mvm, false); + if (ret && !iwlmvm_mod_params.init_dbg) { + IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", ret); + /* this can't happen */ + if (WARN_ON(ret > 0)) + ret = -ERFKILL; + goto error; + } + if (!iwlmvm_mod_params.init_dbg) { + /* + * Stop and start the transport without entering low power + * mode. This will save the state of other components on the + * device that are triggered by the INIT firwmare (MFUART). + */ + _iwl_trans_stop_device(mvm->trans, false); + _iwl_trans_start_hw(mvm->trans, false); + if (ret) + return ret; } if (iwlmvm_mod_params.init_dbg) |