OSDN Git Service

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 8302cf0..f545c5f 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 9513883..d59efe8 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)