aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@googlemail.com>2013-03-25 12:15:17 -0400
committerJohn W. Linville <linville@tuxdriver.com>2013-03-27 13:37:37 -0400
commit56771e5054463fd3ec2047ea4d4a26111ec7dbab (patch)
tree0a5bad361468da2311ee6ebc9ee08489f9eb2c70 /drivers/net/wireless/ath
parentfe21bb02ca3b312ba3b89382760e548fd8996a55 (diff)
carl9170: remove fast channel change feature
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>
Diffstat (limited to 'drivers/net/wireless/ath')
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h8
-rw-r--r--drivers/net/wireless/ath/carl9170/debug.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c2
-rw-r--r--drivers/net/wireless/ath/carl9170/phy.c81
4 files changed, 27 insertions, 66 deletions
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 25599741cd8a..9dce106cd6d4 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -70,12 +70,6 @@
70 70
71static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 }; 71static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 };
72 72
73enum carl9170_rf_init_mode {
74 CARL9170_RFI_NONE,
75 CARL9170_RFI_WARM,
76 CARL9170_RFI_COLD,
77};
78
79#define CARL9170_MAX_RX_BUFFER_SIZE 8192 73#define CARL9170_MAX_RX_BUFFER_SIZE 8192
80 74
81enum carl9170_device_state { 75enum carl9170_device_state {
@@ -599,7 +593,7 @@ int carl9170_led_set_state(struct ar9170 *ar, const u32 led_state);
599 593
600/* PHY / RF */ 594/* PHY / RF */
601int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, 595int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
602 enum nl80211_channel_type bw, enum carl9170_rf_init_mode rfi); 596 enum nl80211_channel_type bw);
603int carl9170_get_noisefloor(struct ar9170 *ar); 597int carl9170_get_noisefloor(struct ar9170 *ar);
604 598
605/* FW */ 599/* FW */
diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
index 93fe6003a493..40109be81f7c 100644
--- a/drivers/net/wireless/ath/carl9170/debug.c
+++ b/drivers/net/wireless/ath/carl9170/debug.c
@@ -655,7 +655,7 @@ static ssize_t carl9170_debugfs_bug_write(struct ar9170 *ar, const char *buf,
655 655
656 case 'P': 656 case 'P':
657 err = carl9170_set_channel(ar, ar->hw->conf.channel, 657 err = carl9170_set_channel(ar, ar->hw->conf.channel,
658 ar->hw->conf.channel_type, CARL9170_RFI_COLD); 658 ar->hw->conf.channel_type);
659 if (err < 0) 659 if (err < 0)
660 count = err; 660 count = err;
661 661
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 08b193199946..699c557bc2c7 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -939,7 +939,7 @@ static int carl9170_op_config(struct ieee80211_hw *hw, u32 changed)
939 goto out; 939 goto out;
940 940
941 err = carl9170_set_channel(ar, hw->conf.channel, 941 err = carl9170_set_channel(ar, hw->conf.channel,
942 hw->conf.channel_type, CARL9170_RFI_NONE); 942 hw->conf.channel_type);
943 if (err) 943 if (err)
944 goto out; 944 goto out;
945 945
diff --git a/drivers/net/wireless/ath/carl9170/phy.c b/drivers/net/wireless/ath/carl9170/phy.c
index b72c09cf43a4..07f82234c860 100644
--- a/drivers/net/wireless/ath/carl9170/phy.c
+++ b/drivers/net/wireless/ath/carl9170/phy.c
@@ -1569,16 +1569,14 @@ static enum carl9170_bw nl80211_to_carl(enum nl80211_channel_type type)
1569} 1569}
1570 1570
1571int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, 1571int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1572 enum nl80211_channel_type _bw, 1572 enum nl80211_channel_type _bw)
1573 enum carl9170_rf_init_mode rfi)
1574{ 1573{
1575 const struct carl9170_phy_freq_params *freqpar; 1574 const struct carl9170_phy_freq_params *freqpar;
1576 struct carl9170_rf_init_result rf_res; 1575 struct carl9170_rf_init_result rf_res;
1577 struct carl9170_rf_init rf; 1576 struct carl9170_rf_init rf;
1578 u32 cmd, tmp, offs = 0, new_ht = 0; 1577 u32 tmp, offs = 0, new_ht = 0;
1579 int err; 1578 int err;
1580 enum carl9170_bw bw; 1579 enum carl9170_bw bw;
1581 bool warm_reset;
1582 struct ieee80211_channel *old_channel = NULL; 1580 struct ieee80211_channel *old_channel = NULL;
1583 1581
1584 bw = nl80211_to_carl(_bw); 1582 bw = nl80211_to_carl(_bw);
@@ -1592,51 +1590,27 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1592 /* may be NULL at first setup */ 1590 /* may be NULL at first setup */
1593 if (ar->channel) { 1591 if (ar->channel) {
1594 old_channel = ar->channel; 1592 old_channel = ar->channel;
1595 warm_reset = (old_channel->band != channel->band) ||
1596 (old_channel->center_freq ==
1597 channel->center_freq) ||
1598 (ar->ht_settings != new_ht);
1599
1600 ar->channel = NULL; 1593 ar->channel = NULL;
1601 } else {
1602 warm_reset = true;
1603 } 1594 }
1604 1595
1605 /* HW workaround */ 1596 /* cold reset BB/ADDA */
1606 if (!ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] && 1597 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET,
1607 channel->center_freq <= 2417) 1598 AR9170_PWR_RESET_BB_COLD_RESET);
1608 warm_reset = true; 1599 if (err)
1609 1600 return err;
1610 if (rfi != CARL9170_RFI_NONE || warm_reset) {
1611 u32 val;
1612
1613 if (rfi == CARL9170_RFI_COLD)
1614 val = AR9170_PWR_RESET_BB_COLD_RESET;
1615 else
1616 val = AR9170_PWR_RESET_BB_WARM_RESET;
1617
1618 /* warm/cold reset BB/ADDA */
1619 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, val);
1620 if (err)
1621 return err;
1622
1623 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
1624 if (err)
1625 return err;
1626 1601
1627 err = carl9170_init_phy(ar, channel->band); 1602 err = carl9170_write_reg(ar, AR9170_PWR_REG_RESET, 0x0);
1628 if (err) 1603 if (err)
1629 return err; 1604 return err;
1630 1605
1631 err = carl9170_init_rf_banks_0_7(ar, 1606 err = carl9170_init_phy(ar, channel->band);
1632 channel->band == IEEE80211_BAND_5GHZ); 1607 if (err)
1633 if (err) 1608 return err;
1634 return err;
1635 1609
1636 cmd = CARL9170_CMD_RF_INIT; 1610 err = carl9170_init_rf_banks_0_7(ar,
1637 } else { 1611 channel->band == IEEE80211_BAND_5GHZ);
1638 cmd = CARL9170_CMD_FREQUENCY; 1612 if (err)
1639 } 1613 return err;
1640 1614
1641 err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL); 1615 err = carl9170_exec_cmd(ar, CARL9170_CMD_FREQ_START, 0, NULL, 0, NULL);
1642 if (err) 1616 if (err)
@@ -1648,8 +1622,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1648 return err; 1622 return err;
1649 1623
1650 err = carl9170_init_rf_bank4_pwr(ar, 1624 err = carl9170_init_rf_bank4_pwr(ar,
1651 channel->band == IEEE80211_BAND_5GHZ, 1625 channel->band == IEEE80211_BAND_5GHZ,
1652 channel->center_freq, bw); 1626 channel->center_freq, bw);
1653 if (err) 1627 if (err)
1654 return err; 1628 return err;
1655 1629
@@ -1703,13 +1677,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1703 rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man); 1677 rf.delta_slope_coeff_man = cpu_to_le32(freqpar->coeff_man);
1704 rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi); 1678 rf.delta_slope_coeff_exp_shgi = cpu_to_le32(freqpar->coeff_exp_shgi);
1705 rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi); 1679 rf.delta_slope_coeff_man_shgi = cpu_to_le32(freqpar->coeff_man_shgi);
1706 1680 rf.finiteLoopCount = cpu_to_le32(2000);
1707 if (rfi != CARL9170_RFI_NONE) 1681 err = carl9170_exec_cmd(ar, CARL9170_CMD_RF_INIT, sizeof(rf), &rf,
1708 rf.finiteLoopCount = cpu_to_le32(2000);
1709 else
1710 rf.finiteLoopCount = cpu_to_le32(1000);
1711
1712 err = carl9170_exec_cmd(ar, cmd, sizeof(rf), &rf,
1713 sizeof(rf_res), &rf_res); 1682 sizeof(rf_res), &rf_res);
1714 if (err) 1683 if (err)
1715 return err; 1684 return err;
@@ -1724,9 +1693,8 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1724 old_channel->center_freq : -1, channel->center_freq, 1693 old_channel->center_freq : -1, channel->center_freq,
1725 err); 1694 err);
1726 1695
1727 if ((rfi == CARL9170_RFI_COLD) || (ar->chan_fail > 3)) { 1696 if (ar->chan_fail > 3) {
1728 /* 1697 /* We have tried very hard to change to _another_
1729 * We have tried very hard to change to _another_
1730 * channel and we've failed to do so! 1698 * channel and we've failed to do so!
1731 * Chances are that the PHY/RF is no longer 1699 * Chances are that the PHY/RF is no longer
1732 * operable (due to corruptions/fatal events/bugs?) 1700 * operable (due to corruptions/fatal events/bugs?)
@@ -1736,8 +1704,7 @@ int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
1736 return 0; 1704 return 0;
1737 } 1705 }
1738 1706
1739 err = carl9170_set_channel(ar, channel, _bw, 1707 err = carl9170_set_channel(ar, channel, _bw);
1740 CARL9170_RFI_COLD);
1741 if (err) 1708 if (err)
1742 return err; 1709 return err;
1743 } else { 1710 } else {