Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[pandora-kernel.git] / drivers / net / wireless / iwlwifi / iwl-agn-rxon.c
index fbbde07..dc64f25 100644 (file)
@@ -1,6 +1,6 @@
 /******************************************************************************
  *
- * Copyright(c) 2003 - 2010 Intel Corporation. All rights reserved.
+ * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.
  *
  * 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
@@ -29,6 +29,8 @@
 #include "iwl-sta.h"
 #include "iwl-core.h"
 #include "iwl-agn-calib.h"
+#include "iwl-helpers.h"
+#include "iwl-trans.h"
 
 static int iwlagn_disable_bss(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx,
@@ -38,7 +40,8 @@ static int iwlagn_disable_bss(struct iwl_priv *priv,
        int ret;
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
-       ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+       ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd,
+                               CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
 
@@ -57,12 +60,14 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
        u8 old_dev_type = send->dev_type;
        int ret;
 
-       iwlagn_init_notification_wait(priv, &disable_wait, NULL,
-                                     REPLY_WIPAN_DEACTIVATION_COMPLETE);
+       iwlagn_init_notification_wait(priv, &disable_wait,
+                                     REPLY_WIPAN_DEACTIVATION_COMPLETE,
+                                     NULL, NULL);
 
        send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
        send->dev_type = RXON_DEV_TYPE_P2P;
-       ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd, sizeof(*send), send);
+       ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd,
+                               CMD_SYNC, sizeof(*send), send);
 
        send->filter_flags = old_filter;
        send->dev_type = old_dev_type;
@@ -71,18 +76,30 @@ static int iwlagn_disable_pan(struct iwl_priv *priv,
                IWL_ERR(priv, "Error disabling PAN (%d)\n", ret);
                iwlagn_remove_notification(priv, &disable_wait);
        } else {
-               signed long wait_res;
-
-               wait_res = iwlagn_wait_notification(priv, &disable_wait, HZ);
-               if (wait_res == 0) {
+               ret = iwlagn_wait_notification(priv, &disable_wait, HZ);
+               if (ret)
                        IWL_ERR(priv, "Timed out waiting for PAN disable\n");
-                       ret = -EIO;
-               }
        }
 
        return ret;
 }
 
+static int iwlagn_disconn_pan(struct iwl_priv *priv,
+                             struct iwl_rxon_context *ctx,
+                             struct iwl_rxon_cmd *send)
+{
+       __le32 old_filter = send->filter_flags;
+       int ret;
+
+       send->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
+                               sizeof(*send), send);
+
+       send->filter_flags = old_filter;
+
+       return ret;
+}
+
 static void iwlagn_update_qos(struct iwl_priv *priv,
                              struct iwl_rxon_context *ctx)
 {
@@ -104,7 +121,7 @@ static void iwlagn_update_qos(struct iwl_priv *priv,
                      ctx->qos_data.qos_active,
                      ctx->qos_data.def_qos_parm.qos_flags);
 
-       ret = iwl_send_cmd_pdu(priv, ctx->qos_cmd,
+       ret = trans_send_cmd_pdu(priv, ctx->qos_cmd, CMD_SYNC,
                               sizeof(struct iwl_qosparam_cmd),
                               &ctx->qos_data.def_qos_parm);
        if (ret)
@@ -123,6 +140,169 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
        return iwlagn_send_beacon_cmd(priv);
 }
 
+static int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
+                          struct iwl_rxon_context *ctx)
+{
+       int ret = 0;
+       struct iwl_rxon_assoc_cmd rxon_assoc;
+       const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
+       const struct iwl_rxon_cmd *rxon2 = &ctx->active;
+
+       if ((rxon1->flags == rxon2->flags) &&
+           (rxon1->filter_flags == rxon2->filter_flags) &&
+           (rxon1->cck_basic_rates == rxon2->cck_basic_rates) &&
+           (rxon1->ofdm_ht_single_stream_basic_rates ==
+            rxon2->ofdm_ht_single_stream_basic_rates) &&
+           (rxon1->ofdm_ht_dual_stream_basic_rates ==
+            rxon2->ofdm_ht_dual_stream_basic_rates) &&
+           (rxon1->ofdm_ht_triple_stream_basic_rates ==
+            rxon2->ofdm_ht_triple_stream_basic_rates) &&
+           (rxon1->acquisition_data == rxon2->acquisition_data) &&
+           (rxon1->rx_chain == rxon2->rx_chain) &&
+           (rxon1->ofdm_basic_rates == rxon2->ofdm_basic_rates)) {
+               IWL_DEBUG_INFO(priv, "Using current RXON_ASSOC.  Not resending.\n");
+               return 0;
+       }
+
+       rxon_assoc.flags = ctx->staging.flags;
+       rxon_assoc.filter_flags = ctx->staging.filter_flags;
+       rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
+       rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
+       rxon_assoc.reserved1 = 0;
+       rxon_assoc.reserved2 = 0;
+       rxon_assoc.reserved3 = 0;
+       rxon_assoc.ofdm_ht_single_stream_basic_rates =
+           ctx->staging.ofdm_ht_single_stream_basic_rates;
+       rxon_assoc.ofdm_ht_dual_stream_basic_rates =
+           ctx->staging.ofdm_ht_dual_stream_basic_rates;
+       rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
+       rxon_assoc.ofdm_ht_triple_stream_basic_rates =
+                ctx->staging.ofdm_ht_triple_stream_basic_rates;
+       rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
+
+       ret = trans_send_cmd_pdu(priv, ctx->rxon_assoc_cmd,
+                               CMD_ASYNC, sizeof(rxon_assoc), &rxon_assoc);
+       return ret;
+}
+
+static int iwlagn_rxon_disconn(struct iwl_priv *priv,
+                              struct iwl_rxon_context *ctx)
+{
+       int ret;
+       struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+       if (ctx->ctxid == IWL_RXON_CTX_BSS) {
+               ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
+       } else {
+               ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
+               if (ret)
+                       return ret;
+               if (ctx->vif) {
+                       ret = iwl_send_rxon_timing(priv, ctx);
+                       if (ret) {
+                               IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+                               return ret;
+                       }
+                       ret = iwlagn_disconn_pan(priv, ctx, &ctx->staging);
+               }
+       }
+       if (ret)
+               return ret;
+
+       /*
+        * Un-assoc RXON clears the station table and WEP
+        * keys, so we have to restore those afterwards.
+        */
+       iwl_clear_ucode_stations(priv, ctx);
+       /* update -- might need P2P now */
+       iwl_update_bcast_station(priv, ctx);
+       iwl_restore_stations(priv, ctx);
+       ret = iwl_restore_default_wep_keys(priv, ctx);
+       if (ret) {
+               IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
+               return ret;
+       }
+
+       memcpy(active, &ctx->staging, sizeof(*active));
+       return 0;
+}
+
+static int iwlagn_rxon_connect(struct iwl_priv *priv,
+                              struct iwl_rxon_context *ctx)
+{
+       int ret;
+       struct iwl_rxon_cmd *active = (void *)&ctx->active;
+
+       /* RXON timing must be before associated RXON */
+       if (ctx->ctxid == IWL_RXON_CTX_BSS) {
+               ret = iwl_send_rxon_timing(priv, ctx);
+               if (ret) {
+                       IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+                       return ret;
+               }
+       }
+       /* QoS info may be cleared by previous un-assoc RXON */
+       iwlagn_update_qos(priv, ctx);
+
+       /*
+        * We'll run into this code path when beaconing is
+        * enabled, but then we also need to send the beacon
+        * to the device.
+        */
+       if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
+               ret = iwlagn_update_beacon(priv, ctx->vif);
+               if (ret) {
+                       IWL_ERR(priv,
+                               "Error sending required beacon (%d)!\n",
+                               ret);
+                       return ret;
+               }
+       }
+
+       priv->start_calib = 0;
+       /*
+        * Apply the new configuration.
+        *
+        * Associated RXON doesn't clear the station table in uCode,
+        * so we don't need to restore stations etc. after this.
+        */
+       ret = trans_send_cmd_pdu(priv, ctx->rxon_cmd, CMD_SYNC,
+                     sizeof(struct iwl_rxon_cmd), &ctx->staging);
+       if (ret) {
+               IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
+               return ret;
+       }
+       memcpy(active, &ctx->staging, sizeof(*active));
+
+       iwl_reprogram_ap_sta(priv, ctx);
+
+       /* IBSS beacon needs to be sent after setting assoc */
+       if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
+               if (iwlagn_update_beacon(priv, ctx->vif))
+                       IWL_ERR(priv, "Error sending IBSS beacon\n");
+       iwl_init_sensitivity(priv);
+
+       /*
+        * If we issue a new RXON command which required a tune then
+        * we must send a new TXPOWER command or we won't be able to
+        * Tx any frames.
+        *
+        * It's expected we set power here if channel is changing.
+        */
+       ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
+       if (ret) {
+               IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+               return ret;
+       }
+
+       if ((ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) &&
+           priv->cfg->ht_params->smps_mode)
+               ieee80211_request_smps(ctx->vif,
+                                      priv->cfg->ht_params->smps_mode);
+
+       return 0;
+}
+
 /**
  * iwlagn_commit_rxon - commit staging_rxon to hardware
  *
@@ -130,13 +310,22 @@ static int iwlagn_update_beacon(struct iwl_priv *priv,
  * the active_rxon structure is updated with the new data.  This
  * function correctly transitions out of the RXON_ASSOC_MSK state if
  * a HW tune is required based on the RXON structure changes.
+ *
+ * The connect/disconnect flow should be as the following:
+ *
+ * 1. make sure send RXON command with association bit unset if not connect
+ *     this should include the channel and the band for the candidate
+ *     to be connected to
+ * 2. Add Station before RXON association with the AP
+ * 3. RXON_timing has to send before RXON for connection
+ * 4. full RXON command - associated bit set
+ * 5. use RXON_ASSOC command to update any flags changes
  */
 int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 {
        /* cast away the const for active_rxon in this function */
        struct iwl_rxon_cmd *active = (void *)&ctx->active;
        bool new_assoc = !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
-       bool old_assoc = !!(ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK);
        int ret;
 
        lockdep_assert_held(&priv->mutex);
@@ -173,12 +362,21 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
                        return 0;
        }
 
+       /*
+        * force CTS-to-self frames protection if RTS-CTS is not preferred
+        * one aggregation protection method
+        */
+       if (!(priv->cfg->ht_params &&
+             priv->cfg->ht_params->use_rts_for_aggregation))
+               ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+
        if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
            !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
                ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
        else
                ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
 
+       iwl_print_rx_config_cmd(priv, ctx);
        ret = iwl_check_rxon_cmd(priv, ctx);
        if (ret) {
                IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
@@ -189,10 +387,10 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * receive commit_rxon request
         * abort any previous channel switch if still in process
         */
-       if (priv->switch_rxon.switch_in_progress &&
-           (priv->switch_rxon.channel != ctx->staging.channel)) {
+       if (test_bit(STATUS_CHANNEL_SWITCH_PENDING, &priv->status) &&
+           (priv->switch_channel != ctx->staging.channel)) {
                IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
-                     le16_to_cpu(priv->switch_rxon.channel));
+                             le16_to_cpu(priv->switch_channel));
                iwl_chswitch_done(priv, false);
        }
 
@@ -202,24 +400,26 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * and other flags for the current radio configuration.
         */
        if (!iwl_full_rxon_required(priv, ctx)) {
-               ret = iwl_send_rxon_assoc(priv, ctx);
+               ret = iwlagn_send_rxon_assoc(priv, ctx);
                if (ret) {
                        IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
                        return ret;
                }
 
                memcpy(active, &ctx->staging, sizeof(*active));
-               iwl_print_rx_config_cmd(priv, ctx);
-               return 0;
-       }
+               /*
+                * We do not commit tx power settings while channel changing,
+                * do it now if after settings changed.
+                */
+               iwl_set_tx_power(priv, priv->tx_power_next, false);
 
-       if (priv->cfg->ops->hcmd->set_pan_params) {
-               ret = priv->cfg->ops->hcmd->set_pan_params(priv);
-               if (ret)
-                       return ret;
+               /* make sure we are in the right PS state */
+               iwl_power_update_mode(priv, true);
+
+               return 0;
        }
 
-       iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
+       iwl_set_rxon_hwcrypto(priv, ctx, !iwlagn_mod_params.sw_crypto);
 
        IWL_DEBUG_INFO(priv,
                       "Going to commit RXON\n"
@@ -236,93 +436,16 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * AP station must be done after the BSSID is set to correctly
         * set up filters in the device.
         */
-       if ((old_assoc && new_assoc) || !new_assoc) {
-               if (ctx->ctxid == IWL_RXON_CTX_BSS)
-                       ret = iwlagn_disable_bss(priv, ctx, &ctx->staging);
-               else
-                       ret = iwlagn_disable_pan(priv, ctx, &ctx->staging);
-               if (ret)
-                       return ret;
-
-               memcpy(active, &ctx->staging, sizeof(*active));
-
-               /*
-                * Un-assoc RXON clears the station table and WEP
-                * keys, so we have to restore those afterwards.
-                */
-               iwl_clear_ucode_stations(priv, ctx);
-               iwl_restore_stations(priv, ctx);
-               ret = iwl_restore_default_wep_keys(priv, ctx);
-               if (ret) {
-                       IWL_ERR(priv, "Failed to restore WEP keys (%d)\n", ret);
-                       return ret;
-               }
-       }
-
-       /* RXON timing must be before associated RXON */
-       ret = iwl_send_rxon_timing(priv, ctx);
-       if (ret) {
-               IWL_ERR(priv, "Failed to send timing (%d)!\n", ret);
+       ret = iwlagn_rxon_disconn(priv, ctx);
+       if (ret)
                return ret;
-       }
-
-       if (new_assoc) {
-               /* QoS info may be cleared by previous un-assoc RXON */
-               iwlagn_update_qos(priv, ctx);
-
-               /*
-                * We'll run into this code path when beaconing is
-                * enabled, but then we also need to send the beacon
-                * to the device.
-                */
-               if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_AP)) {
-                       ret = iwlagn_update_beacon(priv, ctx->vif);
-                       if (ret) {
-                               IWL_ERR(priv,
-                                       "Error sending required beacon (%d)!\n",
-                                       ret);
-                               return ret;
-                       }
-               }
-
-               priv->start_calib = 0;
-               /*
-                * Apply the new configuration.
-                *
-                * Associated RXON doesn't clear the station table in uCode,
-                * so we don't need to restore stations etc. after this.
-                */
-               ret = iwl_send_cmd_pdu(priv, ctx->rxon_cmd,
-                             sizeof(struct iwl_rxon_cmd), &ctx->staging);
-               if (ret) {
-                       IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
-                       return ret;
-               }
-               memcpy(active, &ctx->staging, sizeof(*active));
 
-               iwl_reprogram_ap_sta(priv, ctx);
-
-               /* IBSS beacon needs to be sent after setting assoc */
-               if (ctx->vif && (ctx->vif->type == NL80211_IFTYPE_ADHOC))
-                       if (iwlagn_update_beacon(priv, ctx->vif))
-                               IWL_ERR(priv, "Error sending IBSS beacon\n");
-       }
-
-       iwl_print_rx_config_cmd(priv, ctx);
-
-       iwl_init_sensitivity(priv);
-
-       /*
-        * If we issue a new RXON command which required a tune then we must
-        * send a new TXPOWER command or we won't be able to Tx any frames.
-        *
-        * It's expected we set power here if channel is changing.
-        */
-       ret = iwl_set_tx_power(priv, priv->tx_power_next, true);
-       if (ret) {
-               IWL_ERR(priv, "Error sending TX power (%d)\n", ret);
+       ret = iwlagn_set_pan_params(priv);
+       if (ret)
                return ret;
-       }
+
+       if (new_assoc)
+               return iwlagn_rxon_connect(priv, ctx);
 
        return 0;
 }
@@ -362,9 +485,8 @@ int iwlagn_mac_config(struct ieee80211_hw *hw, u32 changed)
                 * set up the SM PS mode to OFF if an HT channel is
                 * configured.
                 */
-               if (priv->cfg->ops->hcmd->set_rxon_chain)
-                       for_each_context(priv, ctx)
-                               priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+               for_each_context(priv, ctx)
+                       iwlagn_set_rxon_chain(priv, ctx);
        }
 
        if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
@@ -552,6 +674,38 @@ static void iwlagn_check_needed_chains(struct iwl_priv *priv,
        ht_conf->single_chain_sufficient = !need_multiple;
 }
 
+static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
+{
+       struct iwl_chain_noise_data *data = &priv->chain_noise_data;
+       int ret;
+
+       if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
+           iwl_is_any_associated(priv)) {
+               struct iwl_calib_chain_noise_reset_cmd cmd;
+
+               /* clear data for chain noise calibration algorithm */
+               data->chain_noise_a = 0;
+               data->chain_noise_b = 0;
+               data->chain_noise_c = 0;
+               data->chain_signal_a = 0;
+               data->chain_signal_b = 0;
+               data->chain_signal_c = 0;
+               data->beacon_count = 0;
+
+               memset(&cmd, 0, sizeof(cmd));
+               iwl_set_calib_hdr(&cmd.hdr,
+                       priv->_agn.phy_calib_chain_noise_reset_cmd);
+               ret = trans_send_cmd_pdu(priv,
+                                       REPLY_PHY_CALIBRATION_CMD,
+                                       CMD_SYNC, sizeof(cmd), &cmd);
+               if (ret)
+                       IWL_ERR(priv,
+                               "Could not send REPLY_PHY_CALIBRATION_CMD\n");
+               data->state = IWL_CHAIN_NOISE_ACCUMULATE;
+               IWL_DEBUG_CALIB(priv, "Run chain_noise_calibrate\n");
+       }
+}
+
 void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                             struct ieee80211_vif *vif,
                             struct ieee80211_bss_conf *bss_conf,
@@ -595,8 +749,22 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                        priv->timestamp = bss_conf->timestamp;
                        ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
                } else {
+                       /*
+                        * If we disassociate while there are pending
+                        * frames, just wake up the queues and let the
+                        * frames "escape" ... This shouldn't really
+                        * be happening to start with, but we should
+                        * not get stuck in this case either since it
+                        * can happen if userspace gets confused.
+                        */
+                       if (ctx->last_tx_rejected) {
+                               ctx->last_tx_rejected = false;
+                               iwl_wake_any_queue(priv, ctx);
+                       }
                        ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                }
+
+               iwlagn_bt_coex_rssi_monitor(priv);
        }
 
        if (ctx->ht.enabled) {
@@ -608,8 +776,7 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                iwl_set_rxon_ht(priv, &priv->current_ht_config);
        }
 
-       if (priv->cfg->ops->hcmd->set_rxon_chain)
-               priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
+       iwlagn_set_rxon_chain(priv, ctx);
 
        if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
                ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
@@ -647,7 +814,8 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
                        iwl_power_update_mode(priv, false);
 
                /* Enable RX differential gain and sensitivity calibrations */
-               iwl_chain_noise_reset(priv);
+               if (!priv->disable_chain_noise_cal)
+                       iwlagn_chain_noise_reset(priv);
                priv->start_calib = 1;
        }
 
@@ -673,6 +841,13 @@ void iwlagn_post_scan(struct iwl_priv *priv)
 {
        struct iwl_rxon_context *ctx;
 
+       /*
+        * We do not commit power settings while scan is pending,
+        * do it now if the settings changed.
+        */
+       iwl_power_set_mode(priv, &priv->power_data.sleep_cmd_next, false);
+       iwl_set_tx_power(priv, priv->tx_power_next, false);
+
        /*
         * Since setting the RXON may have been deferred while
         * performing the scan, fire one off if needed
@@ -681,6 +856,5 @@ void iwlagn_post_scan(struct iwl_priv *priv)
                if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging)))
                        iwlagn_commit_rxon(priv, ctx);
 
-       if (priv->cfg->ops->hcmd->set_pan_params)
-               priv->cfg->ops->hcmd->set_pan_params(priv);
+       iwlagn_set_pan_params(priv);
 }