iwlwifi: do not set tx power when channel is changing
authorStanislaw Gruszka <sgruszka@redhat.com>
Fri, 28 Jan 2011 15:47:44 +0000 (16:47 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Fri, 28 Jan 2011 20:46:24 +0000 (15:46 -0500)
Mac80211 can request for tx power and channel change in one ->config
call. If that happens, *_send_tx_power functions will try to setup tx
power for old channel, what can be not correct because we already change
the band. I.e  error  "Failed to get channel info for channel 140 [0]",
can be printed frequently when operating in software scanning mode.

Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
Acked-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/iwlwifi/iwl-3945.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl-agn-rxon.c
drivers/net/wireless/iwlwifi/iwl-core.c

index 1d9dcd7e3b829f499dbb14c7e93a01263d19e37d..294221b068130fd9e6f8c833d2254cf5b184c14f 100644 (file)
@@ -1890,7 +1890,7 @@ int iwl3945_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
 
        /* 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 */
-       rc = priv->cfg->ops->lib->send_tx_power(priv);
+       rc = iwl_set_tx_power(priv, priv->tx_power_next, true);
        if (rc) {
                IWL_ERR(priv, "Error setting Tx power (%d).\n", rc);
                return rc;
index d9a7d93def6cf914ac3772e2e91d22f5a969096f..053240642b507890616abf28c478942c04b40082 100644 (file)
@@ -1571,7 +1571,7 @@ static int iwl4965_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *c
 
        /* 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 */
-       ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+       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;
index 2a4ff832fbb8f2e1bee12c011f5fe3e7be219cda..6c2adc58d654a16c00f2b68146532235d0843a47 100644 (file)
@@ -316,10 +316,9 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
         * 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.
         *
-        * FIXME: which RXON requires a tune? Can we optimise this out in
-        *        some cases?
+        * It's expected we set power here if channel is changing.
         */
-       ret = iwl_set_tx_power(priv, priv->tx_power_user_lmt, true);
+       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;
index a46ad60216a0c6a317769526c9f85cff6cbd78f4..92724cbf18ca24da438abb82c6dbca3f23dd1bf2 100644 (file)
@@ -1162,6 +1162,8 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
 {
        int ret;
        s8 prev_tx_power;
+       bool defer;
+       struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
 
        lockdep_assert_held(&priv->mutex);
 
@@ -1189,10 +1191,15 @@ int iwl_set_tx_power(struct iwl_priv *priv, s8 tx_power, bool force)
        if (!iwl_is_ready_rf(priv))
                return -EIO;
 
-       /* scan complete use tx_power_next, need to be updated */
+       /* scan complete and commit_rxon use tx_power_next value,
+        * it always need to be updated for newest request */
        priv->tx_power_next = tx_power;
-       if (test_bit(STATUS_SCANNING, &priv->status) && !force) {
-               IWL_DEBUG_INFO(priv, "Deferring tx power set while scanning\n");
+
+       /* do not set tx power when scanning or channel changing */
+       defer = test_bit(STATUS_SCANNING, &priv->status) ||
+               memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging));
+       if (defer && !force) {
+               IWL_DEBUG_INFO(priv, "Deferring tx power set\n");
                return 0;
        }