diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/base.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index ce67ab791eae..48161edec8de 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c @@ -56,6 +56,7 @@ #include <linux/etherdevice.h> #include <linux/nl80211.h> +#include <net/cfg80211.h> #include <net/ieee80211_radiotap.h> #include <asm/unaligned.h> @@ -165,28 +166,36 @@ static const struct ieee80211_rate ath5k_rates[] = { .flags = IEEE80211_RATE_SHORT_PREAMBLE }, { .bitrate = 60, .hw_value = ATH5K_RATE_CODE_6M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, { .bitrate = 90, .hw_value = ATH5K_RATE_CODE_9M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, { .bitrate = 120, .hw_value = ATH5K_RATE_CODE_12M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, { .bitrate = 180, .hw_value = ATH5K_RATE_CODE_18M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, { .bitrate = 240, .hw_value = ATH5K_RATE_CODE_24M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, { .bitrate = 360, .hw_value = ATH5K_RATE_CODE_36M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, { .bitrate = 480, .hw_value = ATH5K_RATE_CODE_48M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, { .bitrate = 540, .hw_value = ATH5K_RATE_CODE_54M, - .flags = 0 }, + .flags = IEEE80211_RATE_SUPPORTS_5MHZ | + IEEE80211_RATE_SUPPORTS_10MHZ }, }; static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp) @@ -435,11 +444,27 @@ ath5k_setup_bands(struct ieee80211_hw *hw) * Called with ah->lock. */ int -ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan) +ath5k_chan_set(struct ath5k_hw *ah, struct cfg80211_chan_def *chandef) { ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "channel set, resetting (%u -> %u MHz)\n", - ah->curchan->center_freq, chan->center_freq); + ah->curchan->center_freq, chandef->chan->center_freq); + + switch (chandef->width) { + case NL80211_CHAN_WIDTH_20: + case NL80211_CHAN_WIDTH_20_NOHT: + ah->ah_bwmode = AR5K_BWMODE_DEFAULT; + break; + case NL80211_CHAN_WIDTH_5: + ah->ah_bwmode = AR5K_BWMODE_5MHZ; + break; + case NL80211_CHAN_WIDTH_10: + ah->ah_bwmode = AR5K_BWMODE_10MHZ; + break; + default: + WARN_ON(1); + return -EINVAL; + } /* * To switch channels clear any pending DMA operations; @@ -447,7 +472,7 @@ ath5k_chan_set(struct ath5k_hw *ah, struct ieee80211_channel *chan) * hardware at the new frequency, and then re-enable * the relevant bits of the h/w. */ - return ath5k_reset(ah, chan, true); + return ath5k_reset(ah, chandef->chan, true); } void ath5k_vif_iter(void *data, u8 *mac, struct ieee80211_vif *vif) @@ -1400,6 +1425,16 @@ ath5k_receive_frame(struct ath5k_hw *ah, struct sk_buff *skb, rxs->rate_idx = ath5k_hw_to_driver_rix(ah, rs->rs_rate); rxs->flag |= ath5k_rx_decrypted(ah, skb, rs); + switch (ah->ah_bwmode) { + case AR5K_BWMODE_5MHZ: + rxs->flag |= RX_FLAG_5MHZ; + break; + case AR5K_BWMODE_10MHZ: + rxs->flag |= RX_FLAG_10MHZ; + break; + default: + break; + } if (rxs->rate_idx >= 0 && rs->rs_rate == ah->sbands[ah->curchan->band].bitrates[rxs->rate_idx].hw_value_short) @@ -2507,6 +2542,8 @@ ath5k_init_ah(struct ath5k_hw *ah, const struct ath_bus_ops *bus_ops) /* SW support for IBSS_RSN is provided by mac80211 */ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; + hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ; + /* both antennas can be configured as RX or TX */ hw->wiphy->available_antennas_tx = 0x3; hw->wiphy->available_antennas_rx = 0x3; |