aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/util.c')
-rw-r--r--net/mac80211/util.c451
1 files changed, 333 insertions, 118 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index fdf432f14554..66ce96a69f31 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -20,27 +20,21 @@
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <linux/bitmap.h> 22#include <linux/bitmap.h>
23#include <linux/crc32.h>
23#include <net/net_namespace.h> 24#include <net/net_namespace.h>
24#include <net/cfg80211.h> 25#include <net/cfg80211.h>
25#include <net/rtnetlink.h> 26#include <net/rtnetlink.h>
26 27
27#include "ieee80211_i.h" 28#include "ieee80211_i.h"
29#include "driver-ops.h"
28#include "rate.h" 30#include "rate.h"
29#include "mesh.h" 31#include "mesh.h"
30#include "wme.h" 32#include "wme.h"
33#include "led.h"
31 34
32/* privid for wiphys to determine whether they belong to us or not */ 35/* privid for wiphys to determine whether they belong to us or not */
33void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 36void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
34 37
35/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
36/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
37const unsigned char rfc1042_header[] __aligned(2) =
38 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
39
40/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
41const unsigned char bridge_tunnel_header[] __aligned(2) =
42 { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
43
44struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy) 38struct ieee80211_hw *wiphy_to_ieee80211_hw(struct wiphy *wiphy)
45{ 39{
46 struct ieee80211_local *local; 40 struct ieee80211_local *local;
@@ -100,70 +94,6 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
100 return NULL; 94 return NULL;
101} 95}
102 96
103unsigned int ieee80211_hdrlen(__le16 fc)
104{
105 unsigned int hdrlen = 24;
106
107 if (ieee80211_is_data(fc)) {
108 if (ieee80211_has_a4(fc))
109 hdrlen = 30;
110 if (ieee80211_is_data_qos(fc))
111 hdrlen += IEEE80211_QOS_CTL_LEN;
112 goto out;
113 }
114
115 if (ieee80211_is_ctl(fc)) {
116 /*
117 * ACK and CTS are 10 bytes, all others 16. To see how
118 * to get this condition consider
119 * subtype mask: 0b0000000011110000 (0x00F0)
120 * ACK subtype: 0b0000000011010000 (0x00D0)
121 * CTS subtype: 0b0000000011000000 (0x00C0)
122 * bits that matter: ^^^ (0x00E0)
123 * value of those: 0b0000000011000000 (0x00C0)
124 */
125 if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0))
126 hdrlen = 10;
127 else
128 hdrlen = 16;
129 }
130out:
131 return hdrlen;
132}
133EXPORT_SYMBOL(ieee80211_hdrlen);
134
135unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb)
136{
137 const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data;
138 unsigned int hdrlen;
139
140 if (unlikely(skb->len < 10))
141 return 0;
142 hdrlen = ieee80211_hdrlen(hdr->frame_control);
143 if (unlikely(hdrlen > skb->len))
144 return 0;
145 return hdrlen;
146}
147EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb);
148
149int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr)
150{
151 int ae = meshhdr->flags & IEEE80211S_FLAGS_AE;
152 /* 7.1.3.5a.2 */
153 switch (ae) {
154 case 0:
155 return 6;
156 case 1:
157 return 12;
158 case 2:
159 return 18;
160 case 3:
161 return 24;
162 default:
163 return 6;
164 }
165}
166
167void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx) 97void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx)
168{ 98{
169 struct sk_buff *skb = tx->skb; 99 struct sk_buff *skb = tx->skb;
@@ -411,6 +341,52 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue)
411} 341}
412EXPORT_SYMBOL(ieee80211_stop_queue); 342EXPORT_SYMBOL(ieee80211_stop_queue);
413 343
344void ieee80211_add_pending_skb(struct ieee80211_local *local,
345 struct sk_buff *skb)
346{
347 struct ieee80211_hw *hw = &local->hw;
348 unsigned long flags;
349 int queue = skb_get_queue_mapping(skb);
350
351 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
352 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
353 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING);
354 skb_queue_tail(&local->pending[queue], skb);
355 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
356 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
357}
358
359int ieee80211_add_pending_skbs(struct ieee80211_local *local,
360 struct sk_buff_head *skbs)
361{
362 struct ieee80211_hw *hw = &local->hw;
363 struct sk_buff *skb;
364 unsigned long flags;
365 int queue, ret = 0, i;
366
367 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
368 for (i = 0; i < hw->queues; i++)
369 __ieee80211_stop_queue(hw, i,
370 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
371
372 while ((skb = skb_dequeue(skbs))) {
373 ret++;
374 queue = skb_get_queue_mapping(skb);
375 skb_queue_tail(&local->pending[queue], skb);
376 }
377
378 for (i = 0; i < hw->queues; i++) {
379 if (ret)
380 __ieee80211_stop_queue(hw, i,
381 IEEE80211_QUEUE_STOP_REASON_PENDING);
382 __ieee80211_wake_queue(hw, i,
383 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
384 }
385 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
386
387 return ret;
388}
389
414void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 390void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
415 enum queue_stop_reason reason) 391 enum queue_stop_reason reason)
416{ 392{
@@ -536,8 +512,16 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
536void ieee802_11_parse_elems(u8 *start, size_t len, 512void ieee802_11_parse_elems(u8 *start, size_t len,
537 struct ieee802_11_elems *elems) 513 struct ieee802_11_elems *elems)
538{ 514{
515 ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
516}
517
518u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
519 struct ieee802_11_elems *elems,
520 u64 filter, u32 crc)
521{
539 size_t left = len; 522 size_t left = len;
540 u8 *pos = start; 523 u8 *pos = start;
524 bool calc_crc = filter != 0;
541 525
542 memset(elems, 0, sizeof(*elems)); 526 memset(elems, 0, sizeof(*elems));
543 elems->ie_start = start; 527 elems->ie_start = start;
@@ -551,7 +535,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
551 left -= 2; 535 left -= 2;
552 536
553 if (elen > left) 537 if (elen > left)
554 return; 538 break;
539
540 if (calc_crc && id < 64 && (filter & BIT(id)))
541 crc = crc32_be(crc, pos - 2, elen + 2);
555 542
556 switch (id) { 543 switch (id) {
557 case WLAN_EID_SSID: 544 case WLAN_EID_SSID:
@@ -575,8 +562,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
575 elems->cf_params_len = elen; 562 elems->cf_params_len = elen;
576 break; 563 break;
577 case WLAN_EID_TIM: 564 case WLAN_EID_TIM:
578 elems->tim = pos; 565 if (elen >= sizeof(struct ieee80211_tim_ie)) {
579 elems->tim_len = elen; 566 elems->tim = (void *)pos;
567 elems->tim_len = elen;
568 }
580 break; 569 break;
581 case WLAN_EID_IBSS_PARAMS: 570 case WLAN_EID_IBSS_PARAMS:
582 elems->ibss_params = pos; 571 elems->ibss_params = pos;
@@ -586,15 +575,20 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
586 elems->challenge = pos; 575 elems->challenge = pos;
587 elems->challenge_len = elen; 576 elems->challenge_len = elen;
588 break; 577 break;
589 case WLAN_EID_WPA: 578 case WLAN_EID_VENDOR_SPECIFIC:
590 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && 579 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
591 pos[2] == 0xf2) { 580 pos[2] == 0xf2) {
592 /* Microsoft OUI (00:50:F2) */ 581 /* Microsoft OUI (00:50:F2) */
582
583 if (calc_crc)
584 crc = crc32_be(crc, pos - 2, elen + 2);
585
593 if (pos[3] == 1) { 586 if (pos[3] == 1) {
594 /* OUI Type 1 - WPA IE */ 587 /* OUI Type 1 - WPA IE */
595 elems->wpa = pos; 588 elems->wpa = pos;
596 elems->wpa_len = elen; 589 elems->wpa_len = elen;
597 } else if (elen >= 5 && pos[3] == 2) { 590 } else if (elen >= 5 && pos[3] == 2) {
591 /* OUI Type 2 - WMM IE */
598 if (pos[4] == 0) { 592 if (pos[4] == 0) {
599 elems->wmm_info = pos; 593 elems->wmm_info = pos;
600 elems->wmm_info_len = elen; 594 elems->wmm_info_len = elen;
@@ -679,32 +673,70 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
679 left -= elen; 673 left -= elen;
680 pos += elen; 674 pos += elen;
681 } 675 }
676
677 return crc;
682} 678}
683 679
684void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) 680void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
685{ 681{
686 struct ieee80211_local *local = sdata->local; 682 struct ieee80211_local *local = sdata->local;
687 struct ieee80211_tx_queue_params qparam; 683 struct ieee80211_tx_queue_params qparam;
688 int i; 684 int queue;
685 bool use_11b;
686 int aCWmin, aCWmax;
689 687
690 if (!local->ops->conf_tx) 688 if (!local->ops->conf_tx)
691 return; 689 return;
692 690
693 memset(&qparam, 0, sizeof(qparam)); 691 memset(&qparam, 0, sizeof(qparam));
694 692
695 qparam.aifs = 2; 693 use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) &&
694 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE);
696 695
697 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 696 for (queue = 0; queue < local_to_hw(local)->queues; queue++) {
698 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)) 697 /* Set defaults according to 802.11-2007 Table 7-37 */
699 qparam.cw_min = 31; 698 aCWmax = 1023;
700 else 699 if (use_11b)
701 qparam.cw_min = 15; 700 aCWmin = 31;
702 701 else
703 qparam.cw_max = 1023; 702 aCWmin = 15;
704 qparam.txop = 0; 703
704 switch (queue) {
705 case 3: /* AC_BK */
706 qparam.cw_max = aCWmax;
707 qparam.cw_min = aCWmin;
708 qparam.txop = 0;
709 qparam.aifs = 7;
710 break;
711 default: /* never happens but let's not leave undefined */
712 case 2: /* AC_BE */
713 qparam.cw_max = aCWmax;
714 qparam.cw_min = aCWmin;
715 qparam.txop = 0;
716 qparam.aifs = 3;
717 break;
718 case 1: /* AC_VI */
719 qparam.cw_max = aCWmin;
720 qparam.cw_min = (aCWmin + 1) / 2 - 1;
721 if (use_11b)
722 qparam.txop = 6016/32;
723 else
724 qparam.txop = 3008/32;
725 qparam.aifs = 2;
726 break;
727 case 0: /* AC_VO */
728 qparam.cw_max = (aCWmin + 1) / 2 - 1;
729 qparam.cw_min = (aCWmin + 1) / 4 - 1;
730 if (use_11b)
731 qparam.txop = 3264/32;
732 else
733 qparam.txop = 1504/32;
734 qparam.aifs = 2;
735 break;
736 }
705 737
706 for (i = 0; i < local_to_hw(local)->queues; i++) 738 drv_conf_tx(local, queue, &qparam);
707 local->ops->conf_tx(local_to_hw(local), i, &qparam); 739 }
708} 740}
709 741
710void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, 742void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
@@ -831,16 +863,73 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
831 ieee80211_tx_skb(sdata, skb, encrypt); 863 ieee80211_tx_skb(sdata, skb, encrypt);
832} 864}
833 865
866int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
867 const u8 *ie, size_t ie_len)
868{
869 struct ieee80211_supported_band *sband;
870 u8 *pos, *supp_rates_len, *esupp_rates_len = NULL;
871 int i;
872
873 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
874
875 pos = buffer;
876
877 *pos++ = WLAN_EID_SUPP_RATES;
878 supp_rates_len = pos;
879 *pos++ = 0;
880
881 for (i = 0; i < sband->n_bitrates; i++) {
882 struct ieee80211_rate *rate = &sband->bitrates[i];
883
884 if (esupp_rates_len) {
885 *esupp_rates_len += 1;
886 } else if (*supp_rates_len == 8) {
887 *pos++ = WLAN_EID_EXT_SUPP_RATES;
888 esupp_rates_len = pos;
889 *pos++ = 1;
890 } else
891 *supp_rates_len += 1;
892
893 *pos++ = rate->bitrate / 5;
894 }
895
896 if (sband->ht_cap.ht_supported) {
897 __le16 tmp = cpu_to_le16(sband->ht_cap.cap);
898
899 *pos++ = WLAN_EID_HT_CAPABILITY;
900 *pos++ = sizeof(struct ieee80211_ht_cap);
901 memset(pos, 0, sizeof(struct ieee80211_ht_cap));
902 memcpy(pos, &tmp, sizeof(u16));
903 pos += sizeof(u16);
904 /* TODO: needs a define here for << 2 */
905 *pos++ = sband->ht_cap.ampdu_factor |
906 (sband->ht_cap.ampdu_density << 2);
907 memcpy(pos, &sband->ht_cap.mcs, sizeof(sband->ht_cap.mcs));
908 pos += sizeof(sband->ht_cap.mcs);
909 pos += 2 + 4 + 1; /* ext info, BF cap, antsel */
910 }
911
912 /*
913 * If adding more here, adjust code in main.c
914 * that calculates local->scan_ies_len.
915 */
916
917 if (ie) {
918 memcpy(pos, ie, ie_len);
919 pos += ie_len;
920 }
921
922 return pos - buffer;
923}
924
834void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 925void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
835 u8 *ssid, size_t ssid_len, 926 const u8 *ssid, size_t ssid_len,
836 u8 *ie, size_t ie_len) 927 const u8 *ie, size_t ie_len)
837{ 928{
838 struct ieee80211_local *local = sdata->local; 929 struct ieee80211_local *local = sdata->local;
839 struct ieee80211_supported_band *sband;
840 struct sk_buff *skb; 930 struct sk_buff *skb;
841 struct ieee80211_mgmt *mgmt; 931 struct ieee80211_mgmt *mgmt;
842 u8 *pos, *supp_rates, *esupp_rates = NULL; 932 u8 *pos;
843 int i;
844 933
845 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + 934 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
846 ie_len); 935 ie_len);
@@ -867,31 +956,9 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
867 *pos++ = WLAN_EID_SSID; 956 *pos++ = WLAN_EID_SSID;
868 *pos++ = ssid_len; 957 *pos++ = ssid_len;
869 memcpy(pos, ssid, ssid_len); 958 memcpy(pos, ssid, ssid_len);
959 pos += ssid_len;
870 960
871 supp_rates = skb_put(skb, 2); 961 skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len));
872 supp_rates[0] = WLAN_EID_SUPP_RATES;
873 supp_rates[1] = 0;
874 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
875
876 for (i = 0; i < sband->n_bitrates; i++) {
877 struct ieee80211_rate *rate = &sband->bitrates[i];
878 if (esupp_rates) {
879 pos = skb_put(skb, 1);
880 esupp_rates[1]++;
881 } else if (supp_rates[1] == 8) {
882 esupp_rates = skb_put(skb, 3);
883 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
884 esupp_rates[1] = 1;
885 pos = &esupp_rates[2];
886 } else {
887 pos = skb_put(skb, 1);
888 supp_rates[1]++;
889 }
890 *pos = rate->bitrate / 5;
891 }
892
893 if (ie)
894 memcpy(skb_put(skb, ie_len), ie, ie_len);
895 962
896 ieee80211_tx_skb(sdata, skb, 0); 963 ieee80211_tx_skb(sdata, skb, 0);
897} 964}
@@ -931,3 +998,151 @@ u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
931 } 998 }
932 return supp_rates; 999 return supp_rates;
933} 1000}
1001
1002int ieee80211_reconfig(struct ieee80211_local *local)
1003{
1004 struct ieee80211_hw *hw = &local->hw;
1005 struct ieee80211_sub_if_data *sdata;
1006 struct ieee80211_if_init_conf conf;
1007 struct sta_info *sta;
1008 unsigned long flags;
1009 int res;
1010 bool from_suspend = local->suspended;
1011
1012 /*
1013 * We're going to start the hardware, at that point
1014 * we are no longer suspended and can RX frames.
1015 */
1016 local->suspended = false;
1017
1018 /* restart hardware */
1019 if (local->open_count) {
1020 res = drv_start(local);
1021
1022 ieee80211_led_radio(local, true);
1023 }
1024
1025 /* add interfaces */
1026 list_for_each_entry(sdata, &local->interfaces, list) {
1027 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
1028 sdata->vif.type != NL80211_IFTYPE_MONITOR &&
1029 netif_running(sdata->dev)) {
1030 conf.vif = &sdata->vif;
1031 conf.type = sdata->vif.type;
1032 conf.mac_addr = sdata->dev->dev_addr;
1033 res = drv_add_interface(local, &conf);
1034 }
1035 }
1036
1037 /* add STAs back */
1038 if (local->ops->sta_notify) {
1039 spin_lock_irqsave(&local->sta_lock, flags);
1040 list_for_each_entry(sta, &local->sta_list, list) {
1041 sdata = sta->sdata;
1042 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1043 sdata = container_of(sdata->bss,
1044 struct ieee80211_sub_if_data,
1045 u.ap);
1046
1047 drv_sta_notify(local, &sdata->vif, STA_NOTIFY_ADD,
1048 &sta->sta);
1049 }
1050 spin_unlock_irqrestore(&local->sta_lock, flags);
1051 }
1052
1053 /* Clear Suspend state so that ADDBA requests can be processed */
1054
1055 rcu_read_lock();
1056
1057 if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) {
1058 list_for_each_entry_rcu(sta, &local->sta_list, list) {
1059 clear_sta_flags(sta, WLAN_STA_SUSPEND);
1060 }
1061 }
1062
1063 rcu_read_unlock();
1064
1065 /* setup RTS threshold */
1066 drv_set_rts_threshold(local, hw->wiphy->rts_threshold);
1067
1068 /* reconfigure hardware */
1069 ieee80211_hw_config(local, ~0);
1070
1071 netif_addr_lock_bh(local->mdev);
1072 ieee80211_configure_filter(local);
1073 netif_addr_unlock_bh(local->mdev);
1074
1075 /* Finally also reconfigure all the BSS information */
1076 list_for_each_entry(sdata, &local->interfaces, list) {
1077 u32 changed = ~0;
1078 if (!netif_running(sdata->dev))
1079 continue;
1080 switch (sdata->vif.type) {
1081 case NL80211_IFTYPE_STATION:
1082 /* disable beacon change bits */
1083 changed &= ~(BSS_CHANGED_BEACON |
1084 BSS_CHANGED_BEACON_ENABLED);
1085 /* fall through */
1086 case NL80211_IFTYPE_ADHOC:
1087 case NL80211_IFTYPE_AP:
1088 case NL80211_IFTYPE_MESH_POINT:
1089 ieee80211_bss_info_change_notify(sdata, changed);
1090 break;
1091 case NL80211_IFTYPE_WDS:
1092 break;
1093 case NL80211_IFTYPE_AP_VLAN:
1094 case NL80211_IFTYPE_MONITOR:
1095 /* ignore virtual */
1096 break;
1097 case NL80211_IFTYPE_UNSPECIFIED:
1098 case __NL80211_IFTYPE_AFTER_LAST:
1099 WARN_ON(1);
1100 break;
1101 }
1102 }
1103
1104 /* add back keys */
1105 list_for_each_entry(sdata, &local->interfaces, list)
1106 if (netif_running(sdata->dev))
1107 ieee80211_enable_keys(sdata);
1108
1109 ieee80211_wake_queues_by_reason(hw,
1110 IEEE80211_QUEUE_STOP_REASON_SUSPEND);
1111
1112 /*
1113 * If this is for hw restart things are still running.
1114 * We may want to change that later, however.
1115 */
1116 if (!from_suspend)
1117 return 0;
1118
1119#ifdef CONFIG_PM
1120 local->suspended = false;
1121
1122 list_for_each_entry(sdata, &local->interfaces, list) {
1123 switch(sdata->vif.type) {
1124 case NL80211_IFTYPE_STATION:
1125 ieee80211_sta_restart(sdata);
1126 break;
1127 case NL80211_IFTYPE_ADHOC:
1128 ieee80211_ibss_restart(sdata);
1129 break;
1130 case NL80211_IFTYPE_MESH_POINT:
1131 ieee80211_mesh_restart(sdata);
1132 break;
1133 default:
1134 break;
1135 }
1136 }
1137
1138 add_timer(&local->sta_cleanup);
1139
1140 spin_lock_irqsave(&local->sta_lock, flags);
1141 list_for_each_entry(sta, &local->sta_list, list)
1142 mesh_plink_restart(sta);
1143 spin_unlock_irqrestore(&local->sta_lock, flags);
1144#else
1145 WARN_ON(1);
1146#endif
1147 return 0;
1148}