From: Sara Sharon <sara.sharon@xxxxxxxxx> In a000 CDB firmware, we cannot update phy context to a different band - we must first remove it and add it again. Support this flow for all a000 devices since we may have various combinations that cause us to fail regardless if CDB is active. Signed-off-by: Sara Sharon <sara.sharon@xxxxxxxxx> Signed-off-by: Luca Coelho <luciano.coelho@xxxxxxxxx> --- drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h | 2 +- drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h index 8302cf03ac28..f545c5f9e4e3 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h @@ -690,7 +690,7 @@ struct iwl_error_resp { (_color << FW_CTXT_COLOR_POS)) /* Possible actions on PHYs, MACs and Bindings */ -enum { +enum iwl_phy_ctxt_action { FW_CTXT_ACTION_STUB = 0, FW_CTXT_ACTION_ADD, FW_CTXT_ACTION_MODIFY, diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c index 95138830b9f8..d59efe804356 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c @@ -7,6 +7,7 @@ * * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH + * Copyright(c) 2017 Intel Deutschland 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 @@ -250,12 +251,30 @@ int iwl_mvm_phy_ctxt_changed(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt, struct cfg80211_chan_def *chandef, u8 chains_static, u8 chains_dynamic) { + enum iwl_phy_ctxt_action action = FW_CTXT_ACTION_MODIFY; + lockdep_assert_held(&mvm->mutex); + /* In CDB mode we cannot modify PHY context between bands so... */ + if (iwl_mvm_has_new_tx_api(mvm) && + ctxt->channel->band != chandef->chan->band) { + int ret; + + /* ... remove it here ...*/ + ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, + chains_static, chains_dynamic, + FW_CTXT_ACTION_REMOVE, 0); + if (ret) + return ret; + + /* ... and proceed to add it again */ + action = FW_CTXT_ACTION_ADD; + } + ctxt->channel = chandef->chan; return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef, chains_static, chains_dynamic, - FW_CTXT_ACTION_MODIFY, 0); + action, 0); } void iwl_mvm_phy_ctxt_unref(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt) -- 2.11.0