iwlwifi: mvm: support changing band for phy context
authorSara Sharon <sara.sharon@intel.com>
Tue, 7 Feb 2017 16:37:40 +0000 (18:37 +0200)
committerLuca Coelho <luciano.coelho@intel.com>
Wed, 19 Apr 2017 19:21:49 +0000 (22:21 +0300)
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@intel.com>
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/fw-api.h
drivers/net/wireless/intel/iwlwifi/mvm/phy-ctxt.c

index 8302cf03ac28804cef3ac6e1d759063f925e8e2d..f545c5f9e4e38e8c1d565885b4b60222589b6230 100644 (file)
@@ -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,
index 95138830b9f8e4ee8ba83b68278f0478e313f47d..d59efe804356168c0ab87fbb7a3a0633b33666ef 100644 (file)
@@ -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)