]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
iwlagn: prefer BSS context
authorJohannes Berg <johannes.berg@intel.com>
Wed, 27 Apr 2011 12:19:34 +0000 (05:19 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Sat, 30 Apr 2011 15:57:32 +0000 (08:57 -0700)
If an interface type changes from a type that is
only supported on the PAN context (e.g. P2P GO)
to a type that is supported on the BSS context,
and the BSS context is not in use, then we need
to use the BSS context instead of changing the
device type within the context. To achieve this,
refuse the type change, which causes a down/up
cycle that will allocate the BSS context for the
interface.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
drivers/net/wireless/iwlwifi/iwl-core.c

index 98cfbb6d2369eefbb4a8d45c1a5dcadc0452f7f2..4653deada05b48b1383f1cda6b33c7477a1717d3 100644 (file)
@@ -1765,6 +1765,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 {
        struct iwl_priv *priv = hw->priv;
        struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
+       struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS];
        struct iwl_rxon_context *tmp;
        u32 interface_modes;
        int err;
@@ -1789,6 +1790,19 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                goto out;
        }
 
+       /*
+        * Refuse a change that should be done by moving from the PAN
+        * context to the BSS context instead, if the BSS context is
+        * available and can support the new interface type.
+        */
+       if (ctx->ctxid == IWL_RXON_CTX_PAN && !bss_ctx->vif &&
+           (bss_ctx->interface_modes & BIT(newtype) ||
+            bss_ctx->exclusive_interface_modes & BIT(newtype))) {
+               BUILD_BUG_ON(NUM_IWL_RXON_CTX != 2);
+               err = -EBUSY;
+               goto out;
+       }
+
        if (ctx->exclusive_interface_modes & BIT(newtype)) {
                for_each_context(priv, tmp) {
                        if (ctx == tmp)