carl9170: remove fast channel change feature
authorChristian Lamparter <chunkeey@googlemail.com>
Mon, 25 Mar 2013 16:15:17 +0000 (17:15 +0100)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 27 Mar 2013 17:37:37 +0000 (13:37 -0400)
Marco Fonseca reported a issue with his carl9170 device:
"I'm seeing a problem with the carl driver. If I change channels
repeatedly on the 2.4ghz band, monitoring (e.g. tcpdump) will
eventually halt.  I've seen this on various versions of the carl
driver/firmware (both from 1.9.4 to 1.9.7)"
<http://marc.info/?l=linux-wireless&m=136381302428113>

The culprit was identified as "fast channel change feature" which
according to Adrian Chadd is: "... notoriously unreliable and
really only fully debugged on some very later chips."
<http://marc.info/?l=linux-wireless&m=136416984531380>

Therefore, this patch removes the fast channel change feature.
The phy will now always have to go through a cold reset when
changing channels, but it should no longer become deaf.

Cc: Marco Fonseca <marco@tampabay.rr.com>
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/carl9170/carl9170.h
drivers/net/wireless/ath/carl9170/debug.c
drivers/net/wireless/ath/carl9170/main.c
drivers/net/wireless/ath/carl9170/phy.c

index 2559974..9dce106 100644 (file)
 
 static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };
 
-enum carl9170_rf_init_mode {
-       CARL9170_RFI_NONE,
-       CARL9170_RFI_WARM,
-       CARL9170_RFI_COLD,
-};
-
 #define CARL9170_MAX_RX_BUFFER_SIZE            8192
 
 enum carl9170_device_state {
@@ -599,7 +593,7 @@ int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state);
 
 /* PHY / RF */
 int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-       enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi);
+                        enum nl80211_channel_type bw);
 int carl9170_get_noisefloor(struct ar9170 *ar);
 
 /* FW */
index 93fe600..40109be 100644 (file)
@@ -655,7 +655,7 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
 
        case 'P':
                err = carl9170_set_channel(ar, ar->hw->conf.channel,
-                       ar->hw->conf.channel_type, CARL9170_RFI_COLD);
+                                          ar->hw->conf.channel_type);
                if (err < 0)
                        count = err;
 
index 08b1931..699c557 100644 (file)
@@ -939,7 +939,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
                        goto out;
 
                err = carl9170_set_channel(ar, hw->conf.channel,
-                       hw->conf.channel_type, CARL9170_RFI_NONE);
+                                          hw->conf.channel_type);
                if (err)
                        goto out;
 
index b72c09c..07f8223 100644 (file)
@@ -1569,16 +1569,14 @@ static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type)
 }
 
 int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
-                        enum nl80211_channel_type _bw,
-                        enum carl9170_rf_init_mode rfi)
+                        enum nl80211_channel_type _bw)
 {
        const struct carl9170_phy_freq_params *freqpar;
        struct carl9170_rf_init_result rf_res;
        struct carl9170_rf_init rf;
-       u32 cmd, tmp, offs = 0, new_ht = 0;
+       u32 tmp, offs = 0, new_ht = 0;
        int err;
        enum carl9170_bw bw;
-       bool warm_reset;
        struct ieee80211_channel *old_channel = NULL;
 
        bw = nl80211_to_carl(_bw);
@@ -1592,51 +1590,27 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
        /* may be NULL at first setup */
        if (ar->channel) {
                old_channel = ar->channel;
-               warm_reset = (old_channel->band != channel->band) ||
-                            (old_channel->center_freq ==
-                             channel->center_freq) ||
-                            (ar->ht_settings != new_ht);
-
                ar->channel = NULL;
-       } else {
-               warm_reset = true;
        }
 
-       /* HW workaround */
-       if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] &&
-           channel->center_freq <= 2417)
-               warm_reset = true;
-
-       if (rfi != CARL9170_RFI_NONE || warm_reset) {
-               u32 val;
-
-               if (rfi == CARL9170_RFI_COLD)
-                       val = AR9170_PWR_RESET_BB_COLD_RESET;
-               else
-                       val = AR9170_PWR_RESET_BB_WARM_RESET;
-
-               /* warm/cold reset BB/ADDA */
-               err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val);
-               if (err)
-                       return err;
-
-               err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
-               if (err)
-                       return err;
+       /* cold reset BB/ADDA */
+       err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET,
+                                AR9170_PWR_RESET_BB_COLD_RESET);
+       if (err)
+               return err;
 
-               err = carl9170_init_phy(ar, channel->band);
-               if (err)
-                       return err;
+       err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
+       if (err)
+               return err;
 
-               err = carl9170_init_rf_banks_0_7(ar,
-                       channel->band == IEEE80211_BAND_5GHZ);
-               if (err)
-                       return err;
+       err = carl9170_init_phy(ar, channel->band);
+       if (err)
+               return err;
 
-               cmd = CARL9170_CMD_RF_INIT;
-       } else {
-               cmd = CARL9170_CMD_FREQUENCY;
-       }
+       err = carl9170_init_rf_banks_0_7(ar,
+                                        channel->band == IEEE80211_BAND_5GHZ);
+       if (err)
+               return err;
 
        err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL);
        if (err)
@@ -1648,8 +1622,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
                return err;
 
        err = carl9170_init_rf_bank4_pwr(ar,
-               channel->band == IEEE80211_BAND_5GHZ,
-               channel->center_freq, bw);
+                                        channel->band == IEEE80211_BAND_5GHZ,
+                                        channel->center_freq, bw);
        if (err)
                return err;
 
@@ -1703,13 +1677,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
        rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man);
        rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi);
        rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi);
-
-       if (rfi != CARL9170_RFI_NONE)
-               rf.finiteLoopCount = cpu_to_le32(2000);
-       else
-               rf.finiteLoopCount = cpu_to_le32(1000);
-
-       err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf,
+       rf.finiteLoopCount = cpu_to_le32(2000);
+       err = carl9170_exec_cmd(ar, CARL9170_CMD_RF_INIT, sizeof(rf), &rf,
                                sizeof(rf_res), &rf_res);
        if (err)
                return err;
@@ -1724,9 +1693,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
                          old_channel->center_freq : -1, channel->center_freq,
                          err);
 
-               if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) {
-                       /*
-                        * We have tried very hard to change to _another_
+               if (ar->chan_fail > 3) {
+                       /* We have tried very hard to change to _another_
                         * channel and we've failed to do so!
                         * Chances are that the PHY/RF is no longer
                         * operable (due to corruptions/fatal events/bugs?)
@@ -1736,8 +1704,7 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
                        return 0;
                }
 
-               err = carl9170_set_channel(ar, channel, _bw,
-                                          CARL9170_RFI_COLD);
+               err = carl9170_set_channel(ar, channel, _bw);
                if (err)
                        return err;
        } else {