iwlwifi: avoid sending too many commands
authorJohannes Berg <johannes.berg@intel.com>
Fri, 3 Sep 2010 13:32:21 +0000 (06:32 -0700)
committerWey-Yi Guy <wey-yi.w.guy@intel.com>
Sat, 11 Sep 2010 15:51:39 +0000 (08:51 -0700)
When the PAN context is unused, there's no
need to continually update it in the device.
So track which contexts are active (with the
special case that the WLAN context is always
active ...) and only send their commands to
the device when needed.

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-agn-hcmd.c
drivers/net/wireless/iwlwifi/iwl-agn.c
drivers/net/wireless/iwlwifi/iwl-core.c
drivers/net/wireless/iwlwifi/iwl-dev.h

index d03ba6a8e64a2d2bba3488cf0885711e49d4a131..a63582f060f1be6908fd8dc110dc04e1dcaaf5ec 100644 (file)
@@ -287,6 +287,15 @@ static int iwlagn_set_pan_params(struct iwl_priv *priv)
        ctx_bss = &priv->contexts[IWL_RXON_CTX_BSS];
        ctx_pan = &priv->contexts[IWL_RXON_CTX_PAN];
 
+       /*
+        * If the PAN context is inactive, then we don't need
+        * to update the PAN parameters, the last thing we'll
+        * have done before it goes inactive is making the PAN
+        * parameters be WLAN-only.
+        */
+       if (!ctx_pan->is_active)
+               return 0;
+
        memset(&cmd, 0, sizeof(cmd));
 
        /* only 2 slots are currently allowed */
index df2edccdf9bd8ec1fcfd8872e11e57039ef0ab54..a19671d992480b097628d237614c43782753e76d 100644 (file)
@@ -110,6 +110,9 @@ int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        if (!iwl_is_alive(priv))
                return -EBUSY;
 
+       if (!ctx->is_active)
+               return 0;
+
        /* always get timestamp with Rx frame */
        ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
 
@@ -4301,6 +4304,8 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        for (i = 0; i < NUM_IWL_RXON_CTX; i++)
                priv->contexts[i].ctxid = i;
 
+       priv->contexts[IWL_RXON_CTX_BSS].always_active = true;
+       priv->contexts[IWL_RXON_CTX_BSS].is_active = true;
        priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
        priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
        priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
index a76310311aab82318c3d35ffdc4338160adaccf6..f67cab5bc6f2b35dc7ee1419d951e3aaa48b0731 100644 (file)
@@ -196,6 +196,9 @@ static void iwl_update_qos(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        if (test_bit(STATUS_EXIT_PENDING, &priv->status))
                return;
 
+       if (!ctx->is_active)
+               return;
+
        ctx->qos_data.def_qos_parm.qos_flags = 0;
 
        if (ctx->qos_data.qos_active)
@@ -2008,9 +2011,14 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
         */
        priv->iw_mode = vif->type;
 
+       ctx->is_active = true;
+
        err = iwl_set_mode(priv, vif);
-       if (err)
+       if (err) {
+               if (!ctx->always_active)
+                       ctx->is_active = false;
                goto out_err;
+       }
 
        if (priv->cfg->advanced_bt_coexist &&
            vif->type == NL80211_IFTYPE_ADHOC) {
@@ -2052,6 +2060,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
        iwl_scan_cancel_timeout(priv, 100);
        iwl_set_mode(priv, vif);
 
+       if (!ctx->always_active)
+               ctx->is_active = false;
+
        if (priv->scan_vif == vif) {
                scan_completed = true;
                priv->scan_vif = NULL;
index 504ff0f922d942bf3826ce12c18a78161a9594d9..4e3a69271e344a47c677731c8771567062366f37 100644 (file)
@@ -1116,6 +1116,13 @@ struct iwl_rxon_context {
        const u8 *ac_to_queue;
        u8 mcast_queue;
 
+       /*
+        * We could use the vif to indicate active, but we
+        * also need it to be active during disabling when
+        * we already removed the vif for type setting.
+        */
+       bool always_active, is_active;
+
        enum iwl_rxon_context_id ctxid;
 
        u32 interface_modes, exclusive_interface_modes;