diff options
author | David S. Miller <davem@davemloft.net> | 2008-05-15 03:34:44 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-05-15 03:34:44 -0400 |
commit | 63fe46da9c380b3f2bbdf3765044649517cc717c (patch) | |
tree | 9478c1aca1d692b408955aea20c9cd9a37e589c0 /net/mac80211/mlme.c | |
parent | 99dd1a2b8347ac2ae802300b7862f6f7bcf17139 (diff) | |
parent | 066b2118976e6e7cc50eed39e2747c75343a23c4 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts:
drivers/net/wireless/iwlwifi/iwl-4965-rs.c
drivers/net/wireless/rt2x00/rt61pci.c
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 64 |
1 files changed, 50 insertions, 14 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 55b85ae5bc11..5d7719f44bea 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -651,6 +651,26 @@ static void ieee80211_authenticate(struct net_device *dev, | |||
651 | mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); | 651 | mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); |
652 | } | 652 | } |
653 | 653 | ||
654 | static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss, | ||
655 | struct ieee80211_supported_band *sband, | ||
656 | u64 *rates) | ||
657 | { | ||
658 | int i, j, count; | ||
659 | *rates = 0; | ||
660 | count = 0; | ||
661 | for (i = 0; i < bss->supp_rates_len; i++) { | ||
662 | int rate = (bss->supp_rates[i] & 0x7F) * 5; | ||
663 | |||
664 | for (j = 0; j < sband->n_bitrates; j++) | ||
665 | if (sband->bitrates[j].bitrate == rate) { | ||
666 | *rates |= BIT(j); | ||
667 | count++; | ||
668 | break; | ||
669 | } | ||
670 | } | ||
671 | |||
672 | return count; | ||
673 | } | ||
654 | 674 | ||
655 | static void ieee80211_send_assoc(struct net_device *dev, | 675 | static void ieee80211_send_assoc(struct net_device *dev, |
656 | struct ieee80211_if_sta *ifsta) | 676 | struct ieee80211_if_sta *ifsta) |
@@ -659,11 +679,12 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
659 | struct sk_buff *skb; | 679 | struct sk_buff *skb; |
660 | struct ieee80211_mgmt *mgmt; | 680 | struct ieee80211_mgmt *mgmt; |
661 | u8 *pos, *ies; | 681 | u8 *pos, *ies; |
662 | int i, len; | 682 | int i, len, count, rates_len, supp_rates_len; |
663 | u16 capab; | 683 | u16 capab; |
664 | struct ieee80211_sta_bss *bss; | 684 | struct ieee80211_sta_bss *bss; |
665 | int wmm = 0; | 685 | int wmm = 0; |
666 | struct ieee80211_supported_band *sband; | 686 | struct ieee80211_supported_band *sband; |
687 | u64 rates = 0; | ||
667 | 688 | ||
668 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 689 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
669 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + | 690 | sizeof(*mgmt) + 200 + ifsta->extra_ie_len + |
@@ -725,24 +746,39 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
725 | *pos++ = ifsta->ssid_len; | 746 | *pos++ = ifsta->ssid_len; |
726 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | 747 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
727 | 748 | ||
749 | /* all supported rates should be added here but some APs | ||
750 | * (e.g. D-Link DAP 1353 in b-only mode) don't like that | ||
751 | * Therefore only add rates the AP supports */ | ||
752 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | ||
753 | supp_rates_len = rates_len; | ||
754 | if (supp_rates_len > 8) | ||
755 | supp_rates_len = 8; | ||
756 | |||
728 | len = sband->n_bitrates; | 757 | len = sband->n_bitrates; |
729 | if (len > 8) | 758 | pos = skb_put(skb, supp_rates_len + 2); |
730 | len = 8; | ||
731 | pos = skb_put(skb, len + 2); | ||
732 | *pos++ = WLAN_EID_SUPP_RATES; | 759 | *pos++ = WLAN_EID_SUPP_RATES; |
733 | *pos++ = len; | 760 | *pos++ = supp_rates_len; |
734 | for (i = 0; i < len; i++) { | ||
735 | int rate = sband->bitrates[i].bitrate; | ||
736 | *pos++ = (u8) (rate / 5); | ||
737 | } | ||
738 | 761 | ||
739 | if (sband->n_bitrates > len) { | 762 | count = 0; |
740 | pos = skb_put(skb, sband->n_bitrates - len + 2); | 763 | for (i = 0; i < sband->n_bitrates; i++) { |
741 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 764 | if (BIT(i) & rates) { |
742 | *pos++ = sband->n_bitrates - len; | ||
743 | for (i = len; i < sband->n_bitrates; i++) { | ||
744 | int rate = sband->bitrates[i].bitrate; | 765 | int rate = sband->bitrates[i].bitrate; |
745 | *pos++ = (u8) (rate / 5); | 766 | *pos++ = (u8) (rate / 5); |
767 | if (++count == 8) | ||
768 | break; | ||
769 | } | ||
770 | } | ||
771 | |||
772 | if (count == 8) { | ||
773 | pos = skb_put(skb, rates_len - count + 2); | ||
774 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
775 | *pos++ = rates_len - count; | ||
776 | |||
777 | for (i++; i < sband->n_bitrates; i++) { | ||
778 | if (BIT(i) & rates) { | ||
779 | int rate = sband->bitrates[i].bitrate; | ||
780 | *pos++ = (u8) (rate / 5); | ||
781 | } | ||
746 | } | 782 | } |
747 | } | 783 | } |
748 | 784 | ||