aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-05-15 03:34:44 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-15 03:34:44 -0400
commit63fe46da9c380b3f2bbdf3765044649517cc717c (patch)
tree9478c1aca1d692b408955aea20c9cd9a37e589c0 /net/mac80211/mlme.c
parent99dd1a2b8347ac2ae802300b7862f6f7bcf17139 (diff)
parent066b2118976e6e7cc50eed39e2747c75343a23c4 (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.c64
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
654static 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
655static void ieee80211_send_assoc(struct net_device *dev, 675static 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