diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2013-03-25 12:15:17 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-03-27 13:37:37 -0400 |
commit | 56771e5054463fd3ec2047ea4d4a26111ec7dbab (patch) | |
tree | 0a5bad361468da2311ee6ebc9ee08489f9eb2c70 /drivers/net/wireless/ath | |
parent | fe21bb02ca3b312ba3b89382760e548fd8996a55 (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.h | 8 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/debug.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/carl9170/phy.c | 81 |
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 | ||
71 | static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 }; | 71 | static const u8 ar9170_qmap[__AR9170_NUM_TXQ] = { 3, 2, 1, 0 }; |
72 | 72 | ||
73 | enum 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 | ||
81 | enum carl9170_device_state { | 75 | enum 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 */ |
601 | int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | 595 | int 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); |
603 | int carl9170_get_noisefloor(struct ar9170 *ar); | 597 | int 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 | ||
1571 | int carl9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel, | 1571 | int 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 { |