diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 502 |
1 files changed, 251 insertions, 251 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 409bb7716236..4d76bf25bada 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -236,7 +236,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
236 | struct ieee80211_local *local = sdata->local; | 236 | struct ieee80211_local *local = sdata->local; |
237 | struct sk_buff *skb; | 237 | struct sk_buff *skb; |
238 | struct ieee80211_mgmt *mgmt; | 238 | struct ieee80211_mgmt *mgmt; |
239 | u8 *pos, *ies, *ht_add_ie; | 239 | u8 *pos, *ies, *ht_ie; |
240 | int i, len, count, rates_len, supp_rates_len; | 240 | int i, len, count, rates_len, supp_rates_len; |
241 | u16 capab; | 241 | u16 capab; |
242 | struct ieee80211_bss *bss; | 242 | struct ieee80211_bss *bss; |
@@ -393,24 +393,25 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
393 | 393 | ||
394 | /* wmm support is a must to HT */ | 394 | /* wmm support is a must to HT */ |
395 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && | 395 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
396 | sband->ht_info.ht_supported && | 396 | sband->ht_cap.ht_supported && |
397 | (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) { | 397 | (ht_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_INFORMATION)) && |
398 | struct ieee80211_ht_addt_info *ht_add_info = | 398 | ht_ie[1] >= sizeof(struct ieee80211_ht_info)) { |
399 | (struct ieee80211_ht_addt_info *)ht_add_ie; | 399 | struct ieee80211_ht_info *ht_info = |
400 | u16 cap = sband->ht_info.cap; | 400 | (struct ieee80211_ht_info *)(ht_ie + 2); |
401 | u16 cap = sband->ht_cap.cap; | ||
401 | __le16 tmp; | 402 | __le16 tmp; |
402 | u32 flags = local->hw.conf.channel->flags; | 403 | u32 flags = local->hw.conf.channel->flags; |
403 | 404 | ||
404 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | 405 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
405 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | 406 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
406 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | 407 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { |
407 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 408 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
408 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 409 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
409 | } | 410 | } |
410 | break; | 411 | break; |
411 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | 412 | case IEEE80211_HT_PARAM_CHA_SEC_BELOW: |
412 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | 413 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { |
413 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | 414 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
414 | cap &= ~IEEE80211_HT_CAP_SGI_40; | 415 | cap &= ~IEEE80211_HT_CAP_SGI_40; |
415 | } | 416 | } |
416 | break; | 417 | break; |
@@ -424,9 +425,9 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
424 | memcpy(pos, &tmp, sizeof(u16)); | 425 | memcpy(pos, &tmp, sizeof(u16)); |
425 | pos += sizeof(u16); | 426 | pos += sizeof(u16); |
426 | /* TODO: needs a define here for << 2 */ | 427 | /* TODO: needs a define here for << 2 */ |
427 | *pos++ = sband->ht_info.ampdu_factor | | 428 | *pos++ = sband->ht_cap.ampdu_factor | |
428 | (sband->ht_info.ampdu_density << 2); | 429 | (sband->ht_cap.ampdu_density << 2); |
429 | memcpy(pos, sband->ht_info.supp_mcs_set, 16); | 430 | memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs)); |
430 | } | 431 | } |
431 | 432 | ||
432 | kfree(ifsta->assocreq_ies); | 433 | kfree(ifsta->assocreq_ies); |
@@ -568,25 +569,35 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
568 | } | 569 | } |
569 | } | 570 | } |
570 | 571 | ||
571 | static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | 572 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, |
572 | bool use_protection, | 573 | u16 capab, bool erp_valid, u8 erp) |
573 | bool use_short_preamble) | ||
574 | { | 574 | { |
575 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 575 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
576 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 576 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
577 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 577 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
578 | DECLARE_MAC_BUF(mac); | ||
579 | #endif | 578 | #endif |
580 | u32 changed = 0; | 579 | u32 changed = 0; |
580 | bool use_protection; | ||
581 | bool use_short_preamble; | ||
582 | bool use_short_slot; | ||
583 | |||
584 | if (erp_valid) { | ||
585 | use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0; | ||
586 | use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0; | ||
587 | } else { | ||
588 | use_protection = false; | ||
589 | use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE); | ||
590 | } | ||
591 | |||
592 | use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); | ||
581 | 593 | ||
582 | if (use_protection != bss_conf->use_cts_prot) { | 594 | if (use_protection != bss_conf->use_cts_prot) { |
583 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 595 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
584 | if (net_ratelimit()) { | 596 | if (net_ratelimit()) { |
585 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 597 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=%pM)\n", |
586 | "%s)\n", | ||
587 | sdata->dev->name, | 598 | sdata->dev->name, |
588 | use_protection ? "enabled" : "disabled", | 599 | use_protection ? "enabled" : "disabled", |
589 | print_mac(mac, ifsta->bssid)); | 600 | ifsta->bssid); |
590 | } | 601 | } |
591 | #endif | 602 | #endif |
592 | bss_conf->use_cts_prot = use_protection; | 603 | bss_conf->use_cts_prot = use_protection; |
@@ -597,40 +608,28 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
597 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 608 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
598 | if (net_ratelimit()) { | 609 | if (net_ratelimit()) { |
599 | printk(KERN_DEBUG "%s: switched to %s barker preamble" | 610 | printk(KERN_DEBUG "%s: switched to %s barker preamble" |
600 | " (BSSID=%s)\n", | 611 | " (BSSID=%pM)\n", |
601 | sdata->dev->name, | 612 | sdata->dev->name, |
602 | use_short_preamble ? "short" : "long", | 613 | use_short_preamble ? "short" : "long", |
603 | print_mac(mac, ifsta->bssid)); | 614 | ifsta->bssid); |
604 | } | 615 | } |
605 | #endif | 616 | #endif |
606 | bss_conf->use_short_preamble = use_short_preamble; | 617 | bss_conf->use_short_preamble = use_short_preamble; |
607 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 618 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
608 | } | 619 | } |
609 | 620 | ||
610 | return changed; | 621 | if (use_short_slot != bss_conf->use_short_slot) { |
611 | } | 622 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
612 | 623 | if (net_ratelimit()) { | |
613 | static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, | 624 | printk(KERN_DEBUG "%s: switched to %s slot" |
614 | u8 erp_value) | 625 | " (BSSID=%s)\n", |
615 | { | 626 | sdata->dev->name, |
616 | bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; | 627 | use_short_slot ? "short" : "long", |
617 | bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; | 628 | ifsta->bssid); |
618 | 629 | } | |
619 | return ieee80211_handle_protect_preamb(sdata, | 630 | #endif |
620 | use_protection, use_short_preamble); | 631 | bss_conf->use_short_slot = use_short_slot; |
621 | } | 632 | changed |= BSS_CHANGED_ERP_SLOT; |
622 | |||
623 | static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, | ||
624 | struct ieee80211_bss *bss) | ||
625 | { | ||
626 | u32 changed = 0; | ||
627 | |||
628 | if (bss->has_erp_value) | ||
629 | changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value); | ||
630 | else { | ||
631 | u16 capab = bss->capability; | ||
632 | changed |= ieee80211_handle_protect_preamb(sdata, false, | ||
633 | (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); | ||
634 | } | 633 | } |
635 | 634 | ||
636 | return changed; | 635 | return changed; |
@@ -701,14 +700,15 @@ static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata, | |||
701 | 700 | ||
702 | 701 | ||
703 | static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | 702 | static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, |
704 | struct ieee80211_if_sta *ifsta) | 703 | struct ieee80211_if_sta *ifsta, |
704 | u32 bss_info_changed) | ||
705 | { | 705 | { |
706 | struct ieee80211_local *local = sdata->local; | 706 | struct ieee80211_local *local = sdata->local; |
707 | struct ieee80211_conf *conf = &local_to_hw(local)->conf; | 707 | struct ieee80211_conf *conf = &local_to_hw(local)->conf; |
708 | u32 changed = BSS_CHANGED_ASSOC; | ||
709 | 708 | ||
710 | struct ieee80211_bss *bss; | 709 | struct ieee80211_bss *bss; |
711 | 710 | ||
711 | bss_info_changed |= BSS_CHANGED_ASSOC; | ||
712 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; | 712 | ifsta->flags |= IEEE80211_STA_ASSOCIATED; |
713 | 713 | ||
714 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 714 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
@@ -719,22 +719,16 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
719 | ifsta->ssid, ifsta->ssid_len); | 719 | ifsta->ssid, ifsta->ssid_len); |
720 | if (bss) { | 720 | if (bss) { |
721 | /* set timing information */ | 721 | /* set timing information */ |
722 | sdata->bss_conf.beacon_int = bss->beacon_int; | 722 | sdata->vif.bss_conf.beacon_int = bss->beacon_int; |
723 | sdata->bss_conf.timestamp = bss->timestamp; | 723 | sdata->vif.bss_conf.timestamp = bss->timestamp; |
724 | sdata->bss_conf.dtim_period = bss->dtim_period; | 724 | sdata->vif.bss_conf.dtim_period = bss->dtim_period; |
725 | 725 | ||
726 | changed |= ieee80211_handle_bss_capability(sdata, bss); | 726 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
727 | bss->capability, bss->has_erp_value, bss->erp_value); | ||
727 | 728 | ||
728 | ieee80211_rx_bss_put(local, bss); | 729 | ieee80211_rx_bss_put(local, bss); |
729 | } | 730 | } |
730 | 731 | ||
731 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | ||
732 | changed |= BSS_CHANGED_HT; | ||
733 | sdata->bss_conf.assoc_ht = 1; | ||
734 | sdata->bss_conf.ht_conf = &conf->ht_conf; | ||
735 | sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; | ||
736 | } | ||
737 | |||
738 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; | 732 | ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; |
739 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); | 733 | memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); |
740 | ieee80211_sta_send_associnfo(sdata, ifsta); | 734 | ieee80211_sta_send_associnfo(sdata, ifsta); |
@@ -742,14 +736,14 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
742 | ifsta->last_probe = jiffies; | 736 | ifsta->last_probe = jiffies; |
743 | ieee80211_led_assoc(local, 1); | 737 | ieee80211_led_assoc(local, 1); |
744 | 738 | ||
745 | sdata->bss_conf.assoc = 1; | 739 | sdata->vif.bss_conf.assoc = 1; |
746 | /* | 740 | /* |
747 | * For now just always ask the driver to update the basic rateset | 741 | * For now just always ask the driver to update the basic rateset |
748 | * when we have associated, we aren't checking whether it actually | 742 | * when we have associated, we aren't checking whether it actually |
749 | * changed or not. | 743 | * changed or not. |
750 | */ | 744 | */ |
751 | changed |= BSS_CHANGED_BASIC_RATES; | 745 | bss_info_changed |= BSS_CHANGED_BASIC_RATES; |
752 | ieee80211_bss_info_change_notify(sdata, changed); | 746 | ieee80211_bss_info_change_notify(sdata, bss_info_changed); |
753 | 747 | ||
754 | netif_tx_start_all_queues(sdata->dev); | 748 | netif_tx_start_all_queues(sdata->dev); |
755 | netif_carrier_on(sdata->dev); | 749 | netif_carrier_on(sdata->dev); |
@@ -760,18 +754,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
760 | static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | 754 | static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, |
761 | struct ieee80211_if_sta *ifsta) | 755 | struct ieee80211_if_sta *ifsta) |
762 | { | 756 | { |
763 | DECLARE_MAC_BUF(mac); | ||
764 | |||
765 | ifsta->direct_probe_tries++; | 757 | ifsta->direct_probe_tries++; |
766 | if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { | 758 | if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) { |
767 | printk(KERN_DEBUG "%s: direct probe to AP %s timed out\n", | 759 | printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", |
768 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 760 | sdata->dev->name, ifsta->bssid); |
769 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 761 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
762 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
770 | return; | 763 | return; |
771 | } | 764 | } |
772 | 765 | ||
773 | printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n", | 766 | printk(KERN_DEBUG "%s: direct probe to AP %pM try %d\n", |
774 | sdata->dev->name, print_mac(mac, ifsta->bssid), | 767 | sdata->dev->name, ifsta->bssid, |
775 | ifsta->direct_probe_tries); | 768 | ifsta->direct_probe_tries); |
776 | 769 | ||
777 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; | 770 | ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE; |
@@ -791,20 +784,19 @@ static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
791 | static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | 784 | static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, |
792 | struct ieee80211_if_sta *ifsta) | 785 | struct ieee80211_if_sta *ifsta) |
793 | { | 786 | { |
794 | DECLARE_MAC_BUF(mac); | ||
795 | |||
796 | ifsta->auth_tries++; | 787 | ifsta->auth_tries++; |
797 | if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { | 788 | if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { |
798 | printk(KERN_DEBUG "%s: authentication with AP %s" | 789 | printk(KERN_DEBUG "%s: authentication with AP %pM" |
799 | " timed out\n", | 790 | " timed out\n", |
800 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 791 | sdata->dev->name, ifsta->bssid); |
801 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 792 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
793 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
802 | return; | 794 | return; |
803 | } | 795 | } |
804 | 796 | ||
805 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; | 797 | ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE; |
806 | printk(KERN_DEBUG "%s: authenticate with AP %s\n", | 798 | printk(KERN_DEBUG "%s: authenticate with AP %pM\n", |
807 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 799 | sdata->dev->name, ifsta->bssid); |
808 | 800 | ||
809 | ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0); | 801 | ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0); |
810 | 802 | ||
@@ -817,7 +809,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
817 | { | 809 | { |
818 | struct ieee80211_local *local = sdata->local; | 810 | struct ieee80211_local *local = sdata->local; |
819 | struct sta_info *sta; | 811 | struct sta_info *sta; |
820 | u32 changed = BSS_CHANGED_ASSOC; | 812 | u32 changed = 0; |
821 | 813 | ||
822 | rcu_read_lock(); | 814 | rcu_read_lock(); |
823 | 815 | ||
@@ -851,15 +843,9 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
851 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 843 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
852 | changed |= ieee80211_reset_erp_info(sdata); | 844 | changed |= ieee80211_reset_erp_info(sdata); |
853 | 845 | ||
854 | if (sdata->bss_conf.assoc_ht) | ||
855 | changed |= BSS_CHANGED_HT; | ||
856 | |||
857 | sdata->bss_conf.assoc_ht = 0; | ||
858 | sdata->bss_conf.ht_conf = NULL; | ||
859 | sdata->bss_conf.ht_bss_conf = NULL; | ||
860 | |||
861 | ieee80211_led_assoc(local, 0); | 846 | ieee80211_led_assoc(local, 0); |
862 | sdata->bss_conf.assoc = 0; | 847 | changed |= BSS_CHANGED_ASSOC; |
848 | sdata->vif.bss_conf.assoc = false; | ||
863 | 849 | ||
864 | ieee80211_sta_send_apinfo(sdata, ifsta); | 850 | ieee80211_sta_send_apinfo(sdata, ifsta); |
865 | 851 | ||
@@ -871,6 +857,11 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
871 | rcu_read_unlock(); | 857 | rcu_read_unlock(); |
872 | 858 | ||
873 | sta_info_destroy(sta); | 859 | sta_info_destroy(sta); |
860 | |||
861 | local->hw.conf.ht.enabled = false; | ||
862 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_HT); | ||
863 | |||
864 | ieee80211_bss_info_change_notify(sdata, changed); | ||
874 | } | 865 | } |
875 | 866 | ||
876 | static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata) | 867 | static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata) |
@@ -914,20 +905,19 @@ static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata, | |||
914 | static void ieee80211_associate(struct ieee80211_sub_if_data *sdata, | 905 | static void ieee80211_associate(struct ieee80211_sub_if_data *sdata, |
915 | struct ieee80211_if_sta *ifsta) | 906 | struct ieee80211_if_sta *ifsta) |
916 | { | 907 | { |
917 | DECLARE_MAC_BUF(mac); | ||
918 | |||
919 | ifsta->assoc_tries++; | 908 | ifsta->assoc_tries++; |
920 | if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { | 909 | if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { |
921 | printk(KERN_DEBUG "%s: association with AP %s" | 910 | printk(KERN_DEBUG "%s: association with AP %pM" |
922 | " timed out\n", | 911 | " timed out\n", |
923 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 912 | sdata->dev->name, ifsta->bssid); |
924 | ifsta->state = IEEE80211_STA_MLME_DISABLED; | 913 | ifsta->state = IEEE80211_STA_MLME_DISABLED; |
914 | ieee80211_sta_send_apinfo(sdata, ifsta); | ||
925 | return; | 915 | return; |
926 | } | 916 | } |
927 | 917 | ||
928 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; | 918 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; |
929 | printk(KERN_DEBUG "%s: associate with AP %s\n", | 919 | printk(KERN_DEBUG "%s: associate with AP %pM\n", |
930 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 920 | sdata->dev->name, ifsta->bssid); |
931 | if (ieee80211_privacy_mismatch(sdata, ifsta)) { | 921 | if (ieee80211_privacy_mismatch(sdata, ifsta)) { |
932 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " | 922 | printk(KERN_DEBUG "%s: mismatch in privacy configuration and " |
933 | "mixed-cell disabled - abort association\n", sdata->dev->name); | 923 | "mixed-cell disabled - abort association\n", sdata->dev->name); |
@@ -947,7 +937,6 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
947 | struct ieee80211_local *local = sdata->local; | 937 | struct ieee80211_local *local = sdata->local; |
948 | struct sta_info *sta; | 938 | struct sta_info *sta; |
949 | int disassoc; | 939 | int disassoc; |
950 | DECLARE_MAC_BUF(mac); | ||
951 | 940 | ||
952 | /* TODO: start monitoring current AP signal quality and number of | 941 | /* TODO: start monitoring current AP signal quality and number of |
953 | * missed beacons. Scan other channels every now and then and search | 942 | * missed beacons. Scan other channels every now and then and search |
@@ -960,8 +949,8 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
960 | 949 | ||
961 | sta = sta_info_get(local, ifsta->bssid); | 950 | sta = sta_info_get(local, ifsta->bssid); |
962 | if (!sta) { | 951 | if (!sta) { |
963 | printk(KERN_DEBUG "%s: No STA entry for own AP %s\n", | 952 | printk(KERN_DEBUG "%s: No STA entry for own AP %pM\n", |
964 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 953 | sdata->dev->name, ifsta->bssid); |
965 | disassoc = 1; | 954 | disassoc = 1; |
966 | } else { | 955 | } else { |
967 | disassoc = 0; | 956 | disassoc = 0; |
@@ -969,9 +958,9 @@ static void ieee80211_associated(struct ieee80211_sub_if_data *sdata, | |||
969 | sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { | 958 | sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { |
970 | if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) { | 959 | if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) { |
971 | printk(KERN_DEBUG "%s: No ProbeResp from " | 960 | printk(KERN_DEBUG "%s: No ProbeResp from " |
972 | "current AP %s - assume out of " | 961 | "current AP %pM - assume out of " |
973 | "range\n", | 962 | "range\n", |
974 | sdata->dev->name, print_mac(mac, ifsta->bssid)); | 963 | sdata->dev->name, ifsta->bssid); |
975 | disassoc = 1; | 964 | disassoc = 1; |
976 | } else | 965 | } else |
977 | ieee80211_send_probe_req(sdata, ifsta->bssid, | 966 | ieee80211_send_probe_req(sdata, ifsta->bssid, |
@@ -1032,7 +1021,6 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1032 | size_t len) | 1021 | size_t len) |
1033 | { | 1022 | { |
1034 | u16 auth_alg, auth_transaction, status_code; | 1023 | u16 auth_alg, auth_transaction, status_code; |
1035 | DECLARE_MAC_BUF(mac); | ||
1036 | 1024 | ||
1037 | if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && | 1025 | if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE && |
1038 | sdata->vif.type != NL80211_IFTYPE_ADHOC) | 1026 | sdata->vif.type != NL80211_IFTYPE_ADHOC) |
@@ -1125,7 +1113,6 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1125 | size_t len) | 1113 | size_t len) |
1126 | { | 1114 | { |
1127 | u16 reason_code; | 1115 | u16 reason_code; |
1128 | DECLARE_MAC_BUF(mac); | ||
1129 | 1116 | ||
1130 | if (len < 24 + 2) | 1117 | if (len < 24 + 2) |
1131 | return; | 1118 | return; |
@@ -1136,7 +1123,8 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1136 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1123 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1137 | 1124 | ||
1138 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) | 1125 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) |
1139 | printk(KERN_DEBUG "%s: deauthenticated\n", sdata->dev->name); | 1126 | printk(KERN_DEBUG "%s: deauthenticated (Reason: %u)\n", |
1127 | sdata->dev->name, reason_code); | ||
1140 | 1128 | ||
1141 | if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE || | 1129 | if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE || |
1142 | ifsta->state == IEEE80211_STA_MLME_ASSOCIATE || | 1130 | ifsta->state == IEEE80211_STA_MLME_ASSOCIATE || |
@@ -1157,7 +1145,6 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1157 | size_t len) | 1145 | size_t len) |
1158 | { | 1146 | { |
1159 | u16 reason_code; | 1147 | u16 reason_code; |
1160 | DECLARE_MAC_BUF(mac); | ||
1161 | 1148 | ||
1162 | if (len < 24 + 2) | 1149 | if (len < 24 + 2) |
1163 | return; | 1150 | return; |
@@ -1168,7 +1155,8 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1168 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1155 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1169 | 1156 | ||
1170 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) | 1157 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) |
1171 | printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name); | 1158 | printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", |
1159 | sdata->dev->name, reason_code); | ||
1172 | 1160 | ||
1173 | if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) { | 1161 | if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) { |
1174 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; | 1162 | ifsta->state = IEEE80211_STA_MLME_ASSOCIATE; |
@@ -1192,11 +1180,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1192 | u64 rates, basic_rates; | 1180 | u64 rates, basic_rates; |
1193 | u16 capab_info, status_code, aid; | 1181 | u16 capab_info, status_code, aid; |
1194 | struct ieee802_11_elems elems; | 1182 | struct ieee802_11_elems elems; |
1195 | struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; | 1183 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
1196 | u8 *pos; | 1184 | u8 *pos; |
1185 | u32 changed = 0; | ||
1197 | int i, j; | 1186 | int i, j; |
1198 | DECLARE_MAC_BUF(mac); | 1187 | bool have_higher_than_11mbit = false, newsta = false; |
1199 | bool have_higher_than_11mbit = false; | 1188 | u16 ap_ht_cap_flags; |
1200 | 1189 | ||
1201 | /* AssocResp and ReassocResp have identical structure, so process both | 1190 | /* AssocResp and ReassocResp have identical structure, so process both |
1202 | * of them in this function. */ | 1191 | * of them in this function. */ |
@@ -1214,9 +1203,9 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1214 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 1203 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
1215 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); | 1204 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); |
1216 | 1205 | ||
1217 | printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " | 1206 | printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x " |
1218 | "status=%d aid=%d)\n", | 1207 | "status=%d aid=%d)\n", |
1219 | sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), | 1208 | sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa, |
1220 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); | 1209 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); |
1221 | 1210 | ||
1222 | if (status_code != WLAN_STATUS_SUCCESS) { | 1211 | if (status_code != WLAN_STATUS_SUCCESS) { |
@@ -1259,7 +1248,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1259 | sta = sta_info_get(local, ifsta->bssid); | 1248 | sta = sta_info_get(local, ifsta->bssid); |
1260 | if (!sta) { | 1249 | if (!sta) { |
1261 | struct ieee80211_bss *bss; | 1250 | struct ieee80211_bss *bss; |
1262 | int err; | 1251 | |
1252 | newsta = true; | ||
1263 | 1253 | ||
1264 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); | 1254 | sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); |
1265 | if (!sta) { | 1255 | if (!sta) { |
@@ -1278,13 +1268,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1278 | ieee80211_rx_bss_put(local, bss); | 1268 | ieee80211_rx_bss_put(local, bss); |
1279 | } | 1269 | } |
1280 | 1270 | ||
1281 | err = sta_info_insert(sta); | ||
1282 | if (err) { | ||
1283 | printk(KERN_DEBUG "%s: failed to insert STA entry for" | ||
1284 | " the AP (error %d)\n", sdata->dev->name, err); | ||
1285 | rcu_read_unlock(); | ||
1286 | return; | ||
1287 | } | ||
1288 | /* update new sta with its last rx activity */ | 1271 | /* update new sta with its last rx activity */ |
1289 | sta->last_rx = jiffies; | 1272 | sta->last_rx = jiffies; |
1290 | } | 1273 | } |
@@ -1308,34 +1291,40 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1308 | 1291 | ||
1309 | for (i = 0; i < elems.supp_rates_len; i++) { | 1292 | for (i = 0; i < elems.supp_rates_len; i++) { |
1310 | int rate = (elems.supp_rates[i] & 0x7f) * 5; | 1293 | int rate = (elems.supp_rates[i] & 0x7f) * 5; |
1294 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | ||
1311 | 1295 | ||
1312 | if (rate > 110) | 1296 | if (rate > 110) |
1313 | have_higher_than_11mbit = true; | 1297 | have_higher_than_11mbit = true; |
1314 | 1298 | ||
1315 | for (j = 0; j < sband->n_bitrates; j++) { | 1299 | for (j = 0; j < sband->n_bitrates; j++) { |
1316 | if (sband->bitrates[j].bitrate == rate) | 1300 | if (sband->bitrates[j].bitrate == rate) { |
1317 | rates |= BIT(j); | 1301 | rates |= BIT(j); |
1318 | if (elems.supp_rates[i] & 0x80) | 1302 | if (is_basic) |
1319 | basic_rates |= BIT(j); | 1303 | basic_rates |= BIT(j); |
1304 | break; | ||
1305 | } | ||
1320 | } | 1306 | } |
1321 | } | 1307 | } |
1322 | 1308 | ||
1323 | for (i = 0; i < elems.ext_supp_rates_len; i++) { | 1309 | for (i = 0; i < elems.ext_supp_rates_len; i++) { |
1324 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; | 1310 | int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; |
1311 | bool is_basic = !!(elems.supp_rates[i] & 0x80); | ||
1325 | 1312 | ||
1326 | if (rate > 110) | 1313 | if (rate > 110) |
1327 | have_higher_than_11mbit = true; | 1314 | have_higher_than_11mbit = true; |
1328 | 1315 | ||
1329 | for (j = 0; j < sband->n_bitrates; j++) { | 1316 | for (j = 0; j < sband->n_bitrates; j++) { |
1330 | if (sband->bitrates[j].bitrate == rate) | 1317 | if (sband->bitrates[j].bitrate == rate) { |
1331 | rates |= BIT(j); | 1318 | rates |= BIT(j); |
1332 | if (elems.ext_supp_rates[i] & 0x80) | 1319 | if (is_basic) |
1333 | basic_rates |= BIT(j); | 1320 | basic_rates |= BIT(j); |
1321 | break; | ||
1322 | } | ||
1334 | } | 1323 | } |
1335 | } | 1324 | } |
1336 | 1325 | ||
1337 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; | 1326 | sta->sta.supp_rates[local->hw.conf.channel->band] = rates; |
1338 | sdata->bss_conf.basic_rates = basic_rates; | 1327 | sdata->vif.bss_conf.basic_rates = basic_rates; |
1339 | 1328 | ||
1340 | /* cf. IEEE 802.11 9.2.12 */ | 1329 | /* cf. IEEE 802.11 9.2.12 */ |
1341 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && | 1330 | if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && |
@@ -1344,31 +1333,43 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1344 | else | 1333 | else |
1345 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 1334 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
1346 | 1335 | ||
1347 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && | 1336 | if (elems.ht_cap_elem) |
1348 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 1337 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
1349 | struct ieee80211_ht_bss_info bss_info; | 1338 | elems.ht_cap_elem, &sta->sta.ht_cap); |
1350 | ieee80211_ht_cap_ie_to_ht_info( | 1339 | |
1351 | elems.ht_cap_elem, &sta->sta.ht_info); | 1340 | ap_ht_cap_flags = sta->sta.ht_cap.cap; |
1352 | ieee80211_ht_addt_info_ie_to_ht_bss_info( | ||
1353 | elems.ht_info_elem, &bss_info); | ||
1354 | ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info); | ||
1355 | } | ||
1356 | 1341 | ||
1357 | rate_control_rate_init(sta); | 1342 | rate_control_rate_init(sta); |
1358 | 1343 | ||
1359 | if (elems.wmm_param) { | 1344 | if (elems.wmm_param) |
1360 | set_sta_flags(sta, WLAN_STA_WME); | 1345 | set_sta_flags(sta, WLAN_STA_WME); |
1361 | rcu_read_unlock(); | 1346 | |
1347 | if (newsta) { | ||
1348 | int err = sta_info_insert(sta); | ||
1349 | if (err) { | ||
1350 | printk(KERN_DEBUG "%s: failed to insert STA entry for" | ||
1351 | " the AP (error %d)\n", sdata->dev->name, err); | ||
1352 | rcu_read_unlock(); | ||
1353 | return; | ||
1354 | } | ||
1355 | } | ||
1356 | |||
1357 | rcu_read_unlock(); | ||
1358 | |||
1359 | if (elems.wmm_param) | ||
1362 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, | 1360 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, |
1363 | elems.wmm_param_len); | 1361 | elems.wmm_param_len); |
1364 | } else | 1362 | |
1365 | rcu_read_unlock(); | 1363 | if (elems.ht_info_elem && elems.wmm_param && |
1364 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) | ||
1365 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | ||
1366 | ap_ht_cap_flags); | ||
1366 | 1367 | ||
1367 | /* set AID and assoc capability, | 1368 | /* set AID and assoc capability, |
1368 | * ieee80211_set_associated() will tell the driver */ | 1369 | * ieee80211_set_associated() will tell the driver */ |
1369 | bss_conf->aid = aid; | 1370 | bss_conf->aid = aid; |
1370 | bss_conf->assoc_capability = capab_info; | 1371 | bss_conf->assoc_capability = capab_info; |
1371 | ieee80211_set_associated(sdata, ifsta); | 1372 | ieee80211_set_associated(sdata, ifsta, changed); |
1372 | 1373 | ||
1373 | ieee80211_associated(sdata, ifsta); | 1374 | ieee80211_associated(sdata, ifsta); |
1374 | } | 1375 | } |
@@ -1386,6 +1387,13 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
1386 | struct ieee80211_supported_band *sband; | 1387 | struct ieee80211_supported_band *sband; |
1387 | union iwreq_data wrqu; | 1388 | union iwreq_data wrqu; |
1388 | 1389 | ||
1390 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
1391 | if (!skb) { | ||
1392 | printk(KERN_DEBUG "%s: failed to allocate buffer for probe " | ||
1393 | "response\n", sdata->dev->name); | ||
1394 | return -ENOMEM; | ||
1395 | } | ||
1396 | |||
1389 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1397 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1390 | 1398 | ||
1391 | /* Remove possible STA entries from other IBSS networks. */ | 1399 | /* Remove possible STA entries from other IBSS networks. */ |
@@ -1411,63 +1419,62 @@ static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
1411 | return res; | 1419 | return res; |
1412 | 1420 | ||
1413 | /* Build IBSS probe response */ | 1421 | /* Build IBSS probe response */ |
1414 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); | ||
1415 | if (skb) { | ||
1416 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1417 | 1422 | ||
1418 | mgmt = (struct ieee80211_mgmt *) | 1423 | skb_reserve(skb, local->hw.extra_tx_headroom); |
1419 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | ||
1420 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | ||
1421 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | ||
1422 | IEEE80211_STYPE_PROBE_RESP); | ||
1423 | memset(mgmt->da, 0xff, ETH_ALEN); | ||
1424 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
1425 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
1426 | mgmt->u.beacon.beacon_int = | ||
1427 | cpu_to_le16(local->hw.conf.beacon_int); | ||
1428 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
1429 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | ||
1430 | |||
1431 | pos = skb_put(skb, 2 + ifsta->ssid_len); | ||
1432 | *pos++ = WLAN_EID_SSID; | ||
1433 | *pos++ = ifsta->ssid_len; | ||
1434 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); | ||
1435 | |||
1436 | rates = bss->supp_rates_len; | ||
1437 | if (rates > 8) | ||
1438 | rates = 8; | ||
1439 | pos = skb_put(skb, 2 + rates); | ||
1440 | *pos++ = WLAN_EID_SUPP_RATES; | ||
1441 | *pos++ = rates; | ||
1442 | memcpy(pos, bss->supp_rates, rates); | ||
1443 | 1424 | ||
1444 | if (bss->band == IEEE80211_BAND_2GHZ) { | 1425 | mgmt = (struct ieee80211_mgmt *) |
1445 | pos = skb_put(skb, 2 + 1); | 1426 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
1446 | *pos++ = WLAN_EID_DS_PARAMS; | 1427 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
1447 | *pos++ = 1; | 1428 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
1448 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | 1429 | IEEE80211_STYPE_PROBE_RESP); |
1449 | } | 1430 | memset(mgmt->da, 0xff, ETH_ALEN); |
1431 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | ||
1432 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | ||
1433 | mgmt->u.beacon.beacon_int = | ||
1434 | cpu_to_le16(local->hw.conf.beacon_int); | ||
1435 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
1436 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | ||
1450 | 1437 | ||
1451 | pos = skb_put(skb, 2 + 2); | 1438 | pos = skb_put(skb, 2 + ifsta->ssid_len); |
1452 | *pos++ = WLAN_EID_IBSS_PARAMS; | 1439 | *pos++ = WLAN_EID_SSID; |
1453 | *pos++ = 2; | 1440 | *pos++ = ifsta->ssid_len; |
1454 | /* FIX: set ATIM window based on scan results */ | 1441 | memcpy(pos, ifsta->ssid, ifsta->ssid_len); |
1455 | *pos++ = 0; | ||
1456 | *pos++ = 0; | ||
1457 | 1442 | ||
1458 | if (bss->supp_rates_len > 8) { | 1443 | rates = bss->supp_rates_len; |
1459 | rates = bss->supp_rates_len - 8; | 1444 | if (rates > 8) |
1460 | pos = skb_put(skb, 2 + rates); | 1445 | rates = 8; |
1461 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 1446 | pos = skb_put(skb, 2 + rates); |
1462 | *pos++ = rates; | 1447 | *pos++ = WLAN_EID_SUPP_RATES; |
1463 | memcpy(pos, &bss->supp_rates[8], rates); | 1448 | *pos++ = rates; |
1464 | } | 1449 | memcpy(pos, bss->supp_rates, rates); |
1450 | |||
1451 | if (bss->band == IEEE80211_BAND_2GHZ) { | ||
1452 | pos = skb_put(skb, 2 + 1); | ||
1453 | *pos++ = WLAN_EID_DS_PARAMS; | ||
1454 | *pos++ = 1; | ||
1455 | *pos++ = ieee80211_frequency_to_channel(bss->freq); | ||
1456 | } | ||
1465 | 1457 | ||
1466 | ifsta->probe_resp = skb; | 1458 | pos = skb_put(skb, 2 + 2); |
1459 | *pos++ = WLAN_EID_IBSS_PARAMS; | ||
1460 | *pos++ = 2; | ||
1461 | /* FIX: set ATIM window based on scan results */ | ||
1462 | *pos++ = 0; | ||
1463 | *pos++ = 0; | ||
1467 | 1464 | ||
1468 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | 1465 | if (bss->supp_rates_len > 8) { |
1466 | rates = bss->supp_rates_len - 8; | ||
1467 | pos = skb_put(skb, 2 + rates); | ||
1468 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | ||
1469 | *pos++ = rates; | ||
1470 | memcpy(pos, &bss->supp_rates[8], rates); | ||
1469 | } | 1471 | } |
1470 | 1472 | ||
1473 | ifsta->probe_resp = skb; | ||
1474 | |||
1475 | ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON); | ||
1476 | |||
1477 | |||
1471 | rates = 0; | 1478 | rates = 0; |
1472 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1479 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1473 | for (i = 0; i < bss->supp_rates_len; i++) { | 1480 | for (i = 0; i < bss->supp_rates_len; i++) { |
@@ -1507,8 +1514,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1507 | u64 beacon_timestamp, rx_timestamp; | 1514 | u64 beacon_timestamp, rx_timestamp; |
1508 | u64 supp_rates = 0; | 1515 | u64 supp_rates = 0; |
1509 | enum ieee80211_band band = rx_status->band; | 1516 | enum ieee80211_band band = rx_status->band; |
1510 | DECLARE_MAC_BUF(mac); | ||
1511 | DECLARE_MAC_BUF(mac2); | ||
1512 | 1517 | ||
1513 | if (elems->ds_params && elems->ds_params_len == 1) | 1518 | if (elems->ds_params && elems->ds_params_len == 1) |
1514 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); | 1519 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); |
@@ -1538,10 +1543,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1538 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1543 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1539 | if (sta->sta.supp_rates[band] != prev_rates) | 1544 | if (sta->sta.supp_rates[band] != prev_rates) |
1540 | printk(KERN_DEBUG "%s: updated supp_rates set " | 1545 | printk(KERN_DEBUG "%s: updated supp_rates set " |
1541 | "for %s based on beacon info (0x%llx | " | 1546 | "for %pM based on beacon info (0x%llx | " |
1542 | "0x%llx -> 0x%llx)\n", | 1547 | "0x%llx -> 0x%llx)\n", |
1543 | sdata->dev->name, | 1548 | sdata->dev->name, |
1544 | print_mac(mac, sta->sta.addr), | 1549 | sta->sta.addr, |
1545 | (unsigned long long) prev_rates, | 1550 | (unsigned long long) prev_rates, |
1546 | (unsigned long long) supp_rates, | 1551 | (unsigned long long) supp_rates, |
1547 | (unsigned long long) sta->sta.supp_rates[band]); | 1552 | (unsigned long long) sta->sta.supp_rates[band]); |
@@ -1605,10 +1610,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1605 | /* can't merge without knowing the TSF */ | 1610 | /* can't merge without knowing the TSF */ |
1606 | rx_timestamp = -1LLU; | 1611 | rx_timestamp = -1LLU; |
1607 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1612 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1608 | printk(KERN_DEBUG "RX beacon SA=%s BSSID=" | 1613 | printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" |
1609 | "%s TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", | 1614 | "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", |
1610 | print_mac(mac, mgmt->sa), | 1615 | mgmt->sa, mgmt->bssid, |
1611 | print_mac(mac2, mgmt->bssid), | ||
1612 | (unsigned long long)rx_timestamp, | 1616 | (unsigned long long)rx_timestamp, |
1613 | (unsigned long long)beacon_timestamp, | 1617 | (unsigned long long)beacon_timestamp, |
1614 | (unsigned long long)(rx_timestamp - beacon_timestamp), | 1618 | (unsigned long long)(rx_timestamp - beacon_timestamp), |
@@ -1617,8 +1621,8 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1617 | if (beacon_timestamp > rx_timestamp) { | 1621 | if (beacon_timestamp > rx_timestamp) { |
1618 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1622 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1619 | printk(KERN_DEBUG "%s: beacon TSF higher than " | 1623 | printk(KERN_DEBUG "%s: beacon TSF higher than " |
1620 | "local TSF - IBSS merge with BSSID %s\n", | 1624 | "local TSF - IBSS merge with BSSID %pM\n", |
1621 | sdata->dev->name, print_mac(mac, mgmt->bssid)); | 1625 | sdata->dev->name, mgmt->bssid); |
1622 | #endif | 1626 | #endif |
1623 | ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); | 1627 | ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss); |
1624 | ieee80211_ibss_add_sta(sdata, NULL, | 1628 | ieee80211_ibss_add_sta(sdata, NULL, |
@@ -1671,8 +1675,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1671 | size_t baselen; | 1675 | size_t baselen; |
1672 | struct ieee802_11_elems elems; | 1676 | struct ieee802_11_elems elems; |
1673 | struct ieee80211_local *local = sdata->local; | 1677 | struct ieee80211_local *local = sdata->local; |
1674 | struct ieee80211_conf *conf = &local->hw.conf; | ||
1675 | u32 changed = 0; | 1678 | u32 changed = 0; |
1679 | bool erp_valid; | ||
1680 | u8 erp_value = 0; | ||
1676 | 1681 | ||
1677 | /* Process beacon from the current BSS */ | 1682 | /* Process beacon from the current BSS */ |
1678 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | 1683 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; |
@@ -1694,22 +1699,42 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
1694 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, | 1699 | ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, |
1695 | elems.wmm_param_len); | 1700 | elems.wmm_param_len); |
1696 | 1701 | ||
1697 | if (elems.erp_info && elems.erp_info_len >= 1) | 1702 | |
1698 | changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); | 1703 | if (elems.erp_info && elems.erp_info_len >= 1) { |
1699 | else { | 1704 | erp_valid = true; |
1700 | u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info); | 1705 | erp_value = elems.erp_info[0]; |
1701 | changed |= ieee80211_handle_protect_preamb(sdata, false, | 1706 | } else { |
1702 | (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); | 1707 | erp_valid = false; |
1703 | } | 1708 | } |
1709 | changed |= ieee80211_handle_bss_capability(sdata, | ||
1710 | le16_to_cpu(mgmt->u.beacon.capab_info), | ||
1711 | erp_valid, erp_value); | ||
1712 | |||
1713 | |||
1714 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { | ||
1715 | struct sta_info *sta; | ||
1716 | struct ieee80211_supported_band *sband; | ||
1717 | u16 ap_ht_cap_flags; | ||
1718 | |||
1719 | rcu_read_lock(); | ||
1720 | |||
1721 | sta = sta_info_get(local, ifsta->bssid); | ||
1722 | if (!sta) { | ||
1723 | rcu_read_unlock(); | ||
1724 | return; | ||
1725 | } | ||
1726 | |||
1727 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
1704 | 1728 | ||
1705 | if (elems.ht_cap_elem && elems.ht_info_elem && | 1729 | ieee80211_ht_cap_ie_to_sta_ht_cap(sband, |
1706 | elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { | 1730 | elems.ht_cap_elem, &sta->sta.ht_cap); |
1707 | struct ieee80211_ht_bss_info bss_info; | ||
1708 | 1731 | ||
1709 | ieee80211_ht_addt_info_ie_to_ht_bss_info( | 1732 | ap_ht_cap_flags = sta->sta.ht_cap.cap; |
1710 | elems.ht_info_elem, &bss_info); | 1733 | |
1711 | changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf, | 1734 | rcu_read_unlock(); |
1712 | &bss_info); | 1735 | |
1736 | changed |= ieee80211_enable_ht(sdata, elems.ht_info_elem, | ||
1737 | ap_ht_cap_flags); | ||
1713 | } | 1738 | } |
1714 | 1739 | ||
1715 | ieee80211_bss_info_change_notify(sdata, changed); | 1740 | ieee80211_bss_info_change_notify(sdata, changed); |
@@ -1727,11 +1752,6 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1727 | struct sk_buff *skb; | 1752 | struct sk_buff *skb; |
1728 | struct ieee80211_mgmt *resp; | 1753 | struct ieee80211_mgmt *resp; |
1729 | u8 *pos, *end; | 1754 | u8 *pos, *end; |
1730 | DECLARE_MAC_BUF(mac); | ||
1731 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
1732 | DECLARE_MAC_BUF(mac2); | ||
1733 | DECLARE_MAC_BUF(mac3); | ||
1734 | #endif | ||
1735 | 1755 | ||
1736 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC || | 1756 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC || |
1737 | ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED || | 1757 | ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED || |
@@ -1744,10 +1764,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1744 | tx_last_beacon = 1; | 1764 | tx_last_beacon = 1; |
1745 | 1765 | ||
1746 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1766 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1747 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID=" | 1767 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" |
1748 | "%s (tx_last_beacon=%d)\n", | 1768 | " (tx_last_beacon=%d)\n", |
1749 | sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da), | 1769 | sdata->dev->name, mgmt->sa, mgmt->da, |
1750 | print_mac(mac3, mgmt->bssid), tx_last_beacon); | 1770 | mgmt->bssid, tx_last_beacon); |
1751 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 1771 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
1752 | 1772 | ||
1753 | if (!tx_last_beacon) | 1773 | if (!tx_last_beacon) |
@@ -1763,8 +1783,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1763 | pos + 2 + pos[1] > end) { | 1783 | pos + 2 + pos[1] > end) { |
1764 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1784 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1765 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 1785 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " |
1766 | "from %s\n", | 1786 | "from %pM\n", |
1767 | sdata->dev->name, print_mac(mac, mgmt->sa)); | 1787 | sdata->dev->name, mgmt->sa); |
1768 | #endif | 1788 | #endif |
1769 | return; | 1789 | return; |
1770 | } | 1790 | } |
@@ -1783,8 +1803,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1783 | resp = (struct ieee80211_mgmt *) skb->data; | 1803 | resp = (struct ieee80211_mgmt *) skb->data; |
1784 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | 1804 | memcpy(resp->da, mgmt->sa, ETH_ALEN); |
1785 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 1805 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
1786 | printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n", | 1806 | printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", |
1787 | sdata->dev->name, print_mac(mac, resp->da)); | 1807 | sdata->dev->name, resp->da); |
1788 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 1808 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
1789 | ieee80211_tx_skb(sdata, skb, 0); | 1809 | ieee80211_tx_skb(sdata, skb, 0); |
1790 | } | 1810 | } |
@@ -1990,7 +2010,6 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, | |||
1990 | u8 bssid[ETH_ALEN], *pos; | 2010 | u8 bssid[ETH_ALEN], *pos; |
1991 | int i; | 2011 | int i; |
1992 | int ret; | 2012 | int ret; |
1993 | DECLARE_MAC_BUF(mac); | ||
1994 | 2013 | ||
1995 | #if 0 | 2014 | #if 0 |
1996 | /* Easier testing, use fixed BSSID. */ | 2015 | /* Easier testing, use fixed BSSID. */ |
@@ -2006,8 +2025,8 @@ static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata, | |||
2006 | bssid[0] |= 0x02; | 2025 | bssid[0] |= 0x02; |
2007 | #endif | 2026 | #endif |
2008 | 2027 | ||
2009 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", | 2028 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", |
2010 | sdata->dev->name, print_mac(mac, bssid)); | 2029 | sdata->dev->name, bssid); |
2011 | 2030 | ||
2012 | bss = ieee80211_rx_bss_add(local, bssid, | 2031 | bss = ieee80211_rx_bss_add(local, bssid, |
2013 | local->hw.conf.channel->center_freq, | 2032 | local->hw.conf.channel->center_freq, |
@@ -2050,8 +2069,6 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2050 | int found = 0; | 2069 | int found = 0; |
2051 | u8 bssid[ETH_ALEN]; | 2070 | u8 bssid[ETH_ALEN]; |
2052 | int active_ibss; | 2071 | int active_ibss; |
2053 | DECLARE_MAC_BUF(mac); | ||
2054 | DECLARE_MAC_BUF(mac2); | ||
2055 | 2072 | ||
2056 | if (ifsta->ssid_len == 0) | 2073 | if (ifsta->ssid_len == 0) |
2057 | return -EINVAL; | 2074 | return -EINVAL; |
@@ -2068,8 +2085,7 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2068 | || !(bss->capability & WLAN_CAPABILITY_IBSS)) | 2085 | || !(bss->capability & WLAN_CAPABILITY_IBSS)) |
2069 | continue; | 2086 | continue; |
2070 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2087 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2071 | printk(KERN_DEBUG " bssid=%s found\n", | 2088 | printk(KERN_DEBUG " bssid=%pM found\n", bss->bssid); |
2072 | print_mac(mac, bss->bssid)); | ||
2073 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2089 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2074 | memcpy(bssid, bss->bssid, ETH_ALEN); | 2090 | memcpy(bssid, bss->bssid, ETH_ALEN); |
2075 | found = 1; | 2091 | found = 1; |
@@ -2080,9 +2096,8 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2080 | 2096 | ||
2081 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 2097 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2082 | if (found) | 2098 | if (found) |
2083 | printk(KERN_DEBUG " sta_find_ibss: selected %s current " | 2099 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " |
2084 | "%s\n", print_mac(mac, bssid), | 2100 | "%pM\n", bssid, ifsta->bssid); |
2085 | print_mac(mac2, ifsta->bssid)); | ||
2086 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2101 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2087 | 2102 | ||
2088 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { | 2103 | if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { |
@@ -2099,9 +2114,9 @@ static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata, | |||
2099 | if (!bss) | 2114 | if (!bss) |
2100 | goto dont_join; | 2115 | goto dont_join; |
2101 | 2116 | ||
2102 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" | 2117 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" |
2103 | " based on configured SSID\n", | 2118 | " based on configured SSID\n", |
2104 | sdata->dev->name, print_mac(mac, bssid)); | 2119 | sdata->dev->name, bssid); |
2105 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); | 2120 | ret = ieee80211_sta_join_ibss(sdata, ifsta, bss); |
2106 | ieee80211_rx_bss_put(local, bss); | 2121 | ieee80211_rx_bss_put(local, bss); |
2107 | return ret; | 2122 | return ret; |
@@ -2343,7 +2358,6 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2343 | { | 2358 | { |
2344 | struct ieee80211_local *local = sdata->local; | 2359 | struct ieee80211_local *local = sdata->local; |
2345 | struct sta_info *sta; | 2360 | struct sta_info *sta; |
2346 | DECLARE_MAC_BUF(mac); | ||
2347 | int band = local->hw.conf.channel->band; | 2361 | int band = local->hw.conf.channel->band; |
2348 | 2362 | ||
2349 | /* TODO: Could consider removing the least recently used entry and | 2363 | /* TODO: Could consider removing the least recently used entry and |
@@ -2351,7 +2365,7 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2351 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { | 2365 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { |
2352 | if (net_ratelimit()) { | 2366 | if (net_ratelimit()) { |
2353 | printk(KERN_DEBUG "%s: No room for a new IBSS STA " | 2367 | printk(KERN_DEBUG "%s: No room for a new IBSS STA " |
2354 | "entry %s\n", sdata->dev->name, print_mac(mac, addr)); | 2368 | "entry %pM\n", sdata->dev->name, addr); |
2355 | } | 2369 | } |
2356 | return NULL; | 2370 | return NULL; |
2357 | } | 2371 | } |
@@ -2360,8 +2374,8 @@ struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
2360 | return NULL; | 2374 | return NULL; |
2361 | 2375 | ||
2362 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2376 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
2363 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 2377 | printk(KERN_DEBUG "%s: Adding new IBSS station %pM (dev=%s)\n", |
2364 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name); | 2378 | wiphy_name(local->hw.wiphy), addr, sdata->dev->name); |
2365 | #endif | 2379 | #endif |
2366 | 2380 | ||
2367 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 2381 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
@@ -2408,7 +2422,6 @@ void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata, | |||
2408 | int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len) | 2422 | int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len) |
2409 | { | 2423 | { |
2410 | struct ieee80211_if_sta *ifsta; | 2424 | struct ieee80211_if_sta *ifsta; |
2411 | int res; | ||
2412 | 2425 | ||
2413 | if (len > IEEE80211_MAX_SSID_LEN) | 2426 | if (len > IEEE80211_MAX_SSID_LEN) |
2414 | return -EINVAL; | 2427 | return -EINVAL; |
@@ -2420,19 +2433,6 @@ int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size | |||
2420 | memcpy(ifsta->ssid, ssid, len); | 2433 | memcpy(ifsta->ssid, ssid, len); |
2421 | ifsta->ssid_len = len; | 2434 | ifsta->ssid_len = len; |
2422 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; | 2435 | ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET; |
2423 | |||
2424 | res = 0; | ||
2425 | /* | ||
2426 | * Hack! MLME code needs to be cleaned up to have different | ||
2427 | * entry points for configuration and internal selection change | ||
2428 | */ | ||
2429 | if (netif_running(sdata->dev)) | ||
2430 | res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID); | ||
2431 | if (res) { | ||
2432 | printk(KERN_DEBUG "%s: Failed to config new SSID to " | ||
2433 | "the low-level driver\n", sdata->dev->name); | ||
2434 | return res; | ||
2435 | } | ||
2436 | } | 2436 | } |
2437 | 2437 | ||
2438 | if (len) | 2438 | if (len) |