Search Linux Wireless

Re: [PATCH/RFC v2] mac80211: fix association with some APs

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

 



On Thu, 2008-05-08 at 13:34 +0200, Helmut Schaa wrote:
> Some APs refuse association if the supported rates contained in the
> association request do not match its own supported rates. This patch
> introduces a new function which builds the intersection between the AP's
> supported rates and the client's supported rates to work around such
> problems. The same approach is already used in ipw2200 for example.
> 
> Signed-off-by: Helmut Schaa <hschaa@xxxxxxx>

Thanks. Looks ok to me.

> ---
> diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
> index cb01995..91d96d9 100644
> --- a/net/mac80211/mlme.c
> +++ b/net/mac80211/mlme.c
> @@ -650,6 +650,26 @@ static void ieee80211_authenticate(struct net_device *dev,
>  	mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
>  }
>  
> +static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
> +				      struct ieee80211_supported_band *sband,
> +				      u64 *rates)
> +{
> +	int i, j, count;
> +	*rates = 0;
> +	count = 0;
> +	for (i = 0; i < bss->supp_rates_len; i++) {
> +		int rate = (bss->supp_rates[i] & 0x7F) * 5;
> +
> +		for (j = 0; j < sband->n_bitrates; j++)
> +			if (sband->bitrates[j].bitrate == rate) {
> +				*rates |= BIT(j);
> +				count++;
> +				break;
> +			}
> +	}
> +
> +	return count;
> +}
>  
>  static void ieee80211_send_assoc(struct net_device *dev,
>  				 struct ieee80211_if_sta *ifsta)
> @@ -658,11 +678,12 @@ static void ieee80211_send_assoc(struct net_device *dev,
>  	struct sk_buff *skb;
>  	struct ieee80211_mgmt *mgmt;
>  	u8 *pos, *ies;
> -	int i, len;
> +	int i, len, count, rates_len, supp_rates_len;
>  	u16 capab;
>  	struct ieee80211_sta_bss *bss;
>  	int wmm = 0;
>  	struct ieee80211_supported_band *sband;
> +	u64 rates = 0;
>  
>  	skb = dev_alloc_skb(local->hw.extra_tx_headroom +
>  			    sizeof(*mgmt) + 200 + ifsta->extra_ie_len +
> @@ -724,24 +745,39 @@ static void ieee80211_send_assoc(struct net_device *dev,
>  	*pos++ = ifsta->ssid_len;
>  	memcpy(pos, ifsta->ssid, ifsta->ssid_len);
>  
> +	/* all supported rates should be added here but some APs
> +	 * (e.g. D-Link DAP 1353 in b-only mode) don't like that
> +	 * Therefore only add rates the AP supports */
> +	rates_len = ieee80211_compatible_rates(bss, sband, &rates);
> +	supp_rates_len = rates_len;
> +	if (supp_rates_len > 8)
> +		supp_rates_len = 8;
> +
>  	len = sband->n_bitrates;
> -	if (len > 8)
> -		len = 8;
> -	pos = skb_put(skb, len + 2);
> +	pos = skb_put(skb, supp_rates_len + 2);
>  	*pos++ = WLAN_EID_SUPP_RATES;
> -	*pos++ = len;
> -	for (i = 0; i < len; i++) {
> -		int rate = sband->bitrates[i].bitrate;
> -		*pos++ = (u8) (rate / 5);
> -	}
> +	*pos++ = supp_rates_len;
>  
> -	if (sband->n_bitrates > len) {
> -		pos = skb_put(skb, sband->n_bitrates - len + 2);
> -		*pos++ = WLAN_EID_EXT_SUPP_RATES;
> -		*pos++ = sband->n_bitrates - len;
> -		for (i = len; i < sband->n_bitrates; i++) {
> +	count = 0;
> +	for (i = 0; i < sband->n_bitrates; i++) {
> +		if (BIT(i) & rates) {
>  			int rate = sband->bitrates[i].bitrate;
>  			*pos++ = (u8) (rate / 5);
> +			if (++count == 8)
> +				break;
> +		}
> +	}
> +
> +	if (count == 8) {
> +		pos = skb_put(skb, rates_len - count + 2);
> +		*pos++ = WLAN_EID_EXT_SUPP_RATES;
> +		*pos++ = rates_len - count;
> +
> +		for (i++; i < sband->n_bitrates; i++) {
> +			if (BIT(i) & rates) {
> +				int rate = sband->bitrates[i].bitrate;
> +				*pos++ = (u8) (rate / 5);
> +			}
>  		}
>  	}
>  
> 

Attachment: signature.asc
Description: This is a digitally signed message part


[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