| 1 | --- a/drivers/net/wireless/ath/ath9k/ath9k.h |
| 2 | +++ b/drivers/net/wireless/ath/ath9k/ath9k.h |
| 3 | @@ -587,6 +587,7 @@ struct ath_softc { |
| 4 | struct ieee80211_hw *hw; |
| 5 | struct device *dev; |
| 6 | |
| 7 | + u32 chan_bw; |
| 8 | int chan_idx; |
| 9 | int chan_is_ht; |
| 10 | struct survey_info *cur_survey; |
| 11 | --- a/drivers/net/wireless/ath/ath9k/debug.c |
| 12 | +++ b/drivers/net/wireless/ath/ath9k/debug.c |
| 13 | @@ -1718,6 +1718,9 @@ int ath9k_init_debug(struct ath_hw *ah) |
| 14 | debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, |
| 15 | &fops_eeprom); |
| 16 | |
| 17 | + debugfs_create_u32("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy, |
| 18 | + &sc->chan_bw); |
| 19 | + |
| 20 | sc->debug.regidx = 0; |
| 21 | memset(&sc->debug.bb_mac_samp, 0, sizeof(sc->debug.bb_mac_samp)); |
| 22 | sc->debug.sampidx = 0; |
| 23 | --- a/drivers/net/wireless/ath/ath9k/main.c |
| 24 | +++ b/drivers/net/wireless/ath/ath9k/main.c |
| 25 | @@ -1649,9 +1649,10 @@ static int ath9k_config(struct ieee80211 |
| 26 | |
| 27 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| 28 | struct ieee80211_channel *curchan = hw->conf.channel; |
| 29 | - struct ath9k_channel old_chan; |
| 30 | + struct ath9k_channel old_chan, *hchan; |
| 31 | int pos = curchan->hw_value; |
| 32 | int old_pos = -1; |
| 33 | + u32 oldflags; |
| 34 | unsigned long flags; |
| 35 | |
| 36 | if (ah->curchan) |
| 37 | @@ -1704,7 +1705,23 @@ static int ath9k_config(struct ieee80211 |
| 38 | memset(&sc->survey[pos], 0, sizeof(struct survey_info)); |
| 39 | } |
| 40 | |
| 41 | - if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) { |
| 42 | + hchan = &sc->sc_ah->channels[pos]; |
| 43 | + oldflags = hchan->channelFlags; |
| 44 | + switch (sc->chan_bw) { |
| 45 | + case 5: |
| 46 | + hchan->channelFlags &= ~CHANNEL_HALF; |
| 47 | + hchan->channelFlags |= CHANNEL_QUARTER; |
| 48 | + break; |
| 49 | + case 10: |
| 50 | + hchan->channelFlags &= ~CHANNEL_QUARTER; |
| 51 | + hchan->channelFlags |= CHANNEL_HALF; |
| 52 | + break; |
| 53 | + default: |
| 54 | + hchan->channelFlags &= ~(CHANNEL_HALF | CHANNEL_QUARTER); |
| 55 | + break; |
| 56 | + } |
| 57 | + |
| 58 | + if (ath_set_channel(sc, hw, hchan) < 0) { |
| 59 | ath_err(common, "Unable to set channel\n"); |
| 60 | mutex_unlock(&sc->mutex); |
| 61 | return -EINVAL; |
| 62 | --- a/drivers/net/wireless/ath/ath9k/hw.c |
| 63 | +++ b/drivers/net/wireless/ath/ath9k/hw.c |
| 64 | @@ -1548,6 +1548,10 @@ int ath9k_hw_reset(struct ath_hw *ah, st |
| 65 | caldata->rtt_hist.num_readings) |
| 66 | allow_fbs = true; |
| 67 | |
| 68 | + if (!ah->curchan || ((ah->curchan->channelFlags ^ chan->channelFlags) & |
| 69 | + (CHANNEL_HALF | CHANNEL_QUARTER))) |
| 70 | + bChannelChange = false; |
| 71 | + |
| 72 | if (bChannelChange && |
| 73 | (ah->chip_fullsleep != true) && |
| 74 | (ah->curchan != NULL) && |
| 75 | |