Search Linux Wireless

Re: [PATCH 7/7] rt2x00: Fix HT40 operation in rt2800.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Am Mittwoch 19 Mai 2010 schrieb Gertjan van Wingerde:
> Closer inspection of the legacy Ralink driver reveals that in case of HT40+
> or HT40- we must adjust the frequency settings that we program to the device.
> Implement the same adjustment in the rt2x00 code.
> 
> With this HT40 seems to work for all devices supported by rt2800pci and
> rt2800usb.

Awesome, I'll give it a shot tomorrow.

Helmut

> Signed-off-by: Gertjan van Wingerde <gwingerde@xxxxxxxxx>
> ---
>  drivers/net/wireless/rt2x00/rt2800lib.c    |    5 +----
>  drivers/net/wireless/rt2x00/rt2x00config.c |   12 ++++++++----
>  drivers/net/wireless/rt2x00/rt2x00ht.c     |   27 +++++++++++++++++++++++++++
>  drivers/net/wireless/rt2x00/rt2x00lib.h    |    9 +++++++++
>  4 files changed, 45 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index 8ffbc3c..15322f0 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -2530,11 +2530,8 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
>  	else
>  		spec->ht.ht_supported = false;
>  
> -	/*
> -	 * Don't set IEEE80211_HT_CAP_SUP_WIDTH_20_40 for now as it causes
> -	 * reception problems with HT40 capable 11n APs
> -	 */
>  	spec->ht.cap =
> +	    IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
>  	    IEEE80211_HT_CAP_GRN_FLD |
>  	    IEEE80211_HT_CAP_SGI_20 |
>  	    IEEE80211_HT_CAP_SGI_40 |
> diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
> index 098315a..8dbd634 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00config.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00config.c
> @@ -170,23 +170,27 @@ void rt2x00lib_config(struct rt2x00_dev *rt2x00dev,
>  		      unsigned int ieee80211_flags)
>  {
>  	struct rt2x00lib_conf libconf;
> +	u16 hw_value;
>  
>  	memset(&libconf, 0, sizeof(libconf));
>  
>  	libconf.conf = conf;
>  
>  	if (ieee80211_flags & IEEE80211_CONF_CHANGE_CHANNEL) {
> -		if (conf_is_ht40(conf))
> +		if (conf_is_ht40(conf)) {
>  			__set_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
> -		else
> +			hw_value = rt2x00ht_center_channel(rt2x00dev, conf);
> +		} else {
>  			__clear_bit(CONFIG_CHANNEL_HT40, &rt2x00dev->flags);
> +			hw_value = conf->channel->hw_value;
> +		}
>  
>  		memcpy(&libconf.rf,
> -		       &rt2x00dev->spec.channels[conf->channel->hw_value],
> +		       &rt2x00dev->spec.channels[hw_value],
>  		       sizeof(libconf.rf));
>  
>  		memcpy(&libconf.channel,
> -		       &rt2x00dev->spec.channels_info[conf->channel->hw_value],
> +		       &rt2x00dev->spec.channels_info[hw_value],
>  		       sizeof(libconf.channel));
>  	}
>  
> diff --git a/drivers/net/wireless/rt2x00/rt2x00ht.c b/drivers/net/wireless/rt2x00/rt2x00ht.c
> index 5a40760..588c766 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00ht.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00ht.c
> @@ -84,3 +84,30 @@ void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
>  	else
>  		txdesc->txop = TXOP_HTTXOP;
>  }
> +
> +u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> +			    struct ieee80211_conf *conf)
> +{
> +	struct hw_mode_spec *spec = &rt2x00dev->spec;
> +	int center_channel;
> +	u16 i;
> +
> +	/*
> +	 * Initialize center channel to current channel.
> +	 */
> +	center_channel = spec->channels[conf->channel->hw_value].channel;
> +
> +	/*
> +	 * Adjust center channel to HT40+ and HT40- operation.
> +	 */
> +	if (conf_is_ht40_plus(conf))
> +		center_channel += 2;
> +	else if (conf_is_ht40_minus(conf))
> +		center_channel -= (center_channel == 14) ? 1 : 2;
> +
> +	for (i = 0; i < spec->num_channels; i++)
> +		if (spec->channels[i].channel == center_channel)
> +			return i;
> +
> +	BUG();
> +}
> diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h
> index 822affc..ed27de1 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00lib.h
> +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h
> @@ -367,12 +367,21 @@ static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
>  void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
>  				   struct txentry_desc *txdesc,
>  				   const struct rt2x00_rate *hwrate);
> +
> +u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> +			    struct ieee80211_conf *conf);
>  #else
>  static inline void rt2x00ht_create_tx_descriptor(struct queue_entry *entry,
>  						 struct txentry_desc *txdesc,
>  						 const struct rt2x00_rate *hwrate)
>  {
>  }
> +
> +static inline u16 rt2x00ht_center_channel(struct rt2x00_dev *rt2x00dev,
> +					  struct ieee80211_conf *conf)
> +{
> +	return conf->channel->hw_value;
> +}
>  #endif /* CONFIG_RT2X00_LIB_HT */
>  
>  /*
> 

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux