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.c285
1 files changed, 93 insertions, 192 deletions
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ddeb1b998383..eca0fad09709 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -13,13 +13,13 @@
13 13
14#include <net/mac80211.h> 14#include <net/mac80211.h>
15#include <linux/netdevice.h> 15#include <linux/netdevice.h>
16#include <linux/export.h>
16#include <linux/types.h> 17#include <linux/types.h>
17#include <linux/slab.h> 18#include <linux/slab.h>
18#include <linux/skbuff.h> 19#include <linux/skbuff.h>
19#include <linux/etherdevice.h> 20#include <linux/etherdevice.h>
20#include <linux/if_arp.h> 21#include <linux/if_arp.h>
21#include <linux/bitmap.h> 22#include <linux/bitmap.h>
22#include <linux/crc32.h>
23#include <net/net_namespace.h> 23#include <net/net_namespace.h>
24#include <net/cfg80211.h> 24#include <net/cfg80211.h>
25#include <net/rtnetlink.h> 25#include <net/rtnetlink.h>
@@ -368,14 +368,14 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
368 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 368 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
369} 369}
370 370
371int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, 371void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
372 struct sk_buff_head *skbs, 372 struct sk_buff_head *skbs,
373 void (*fn)(void *data), void *data) 373 void (*fn)(void *data), void *data)
374{ 374{
375 struct ieee80211_hw *hw = &local->hw; 375 struct ieee80211_hw *hw = &local->hw;
376 struct sk_buff *skb; 376 struct sk_buff *skb;
377 unsigned long flags; 377 unsigned long flags;
378 int queue, ret = 0, i; 378 int queue, i;
379 379
380 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 380 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
381 for (i = 0; i < hw->queues; i++) 381 for (i = 0; i < hw->queues; i++)
@@ -390,7 +390,6 @@ int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
390 continue; 390 continue;
391 } 391 }
392 392
393 ret++;
394 queue = skb_get_queue_mapping(skb); 393 queue = skb_get_queue_mapping(skb);
395 __skb_queue_tail(&local->pending[queue], skb); 394 __skb_queue_tail(&local->pending[queue], skb);
396 } 395 }
@@ -402,14 +401,12 @@ int ieee80211_add_pending_skbs_fn(struct ieee80211_local *local,
402 __ieee80211_wake_queue(hw, i, 401 __ieee80211_wake_queue(hw, i,
403 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 402 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
404 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 403 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
405
406 return ret;
407} 404}
408 405
409int ieee80211_add_pending_skbs(struct ieee80211_local *local, 406void ieee80211_add_pending_skbs(struct ieee80211_local *local,
410 struct sk_buff_head *skbs) 407 struct sk_buff_head *skbs)
411{ 408{
412 return ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); 409 ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL);
413} 410}
414 411
415void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, 412void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw,
@@ -573,172 +570,6 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
573 ieee802_11_parse_elems_crc(start, len, elems, 0, 0); 570 ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
574} 571}
575 572
576u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
577 struct ieee802_11_elems *elems,
578 u64 filter, u32 crc)
579{
580 size_t left = len;
581 u8 *pos = start;
582 bool calc_crc = filter != 0;
583
584 memset(elems, 0, sizeof(*elems));
585 elems->ie_start = start;
586 elems->total_len = len;
587
588 while (left >= 2) {
589 u8 id, elen;
590
591 id = *pos++;
592 elen = *pos++;
593 left -= 2;
594
595 if (elen > left)
596 break;
597
598 if (calc_crc && id < 64 && (filter & (1ULL << id)))
599 crc = crc32_be(crc, pos - 2, elen + 2);
600
601 switch (id) {
602 case WLAN_EID_SSID:
603 elems->ssid = pos;
604 elems->ssid_len = elen;
605 break;
606 case WLAN_EID_SUPP_RATES:
607 elems->supp_rates = pos;
608 elems->supp_rates_len = elen;
609 break;
610 case WLAN_EID_FH_PARAMS:
611 elems->fh_params = pos;
612 elems->fh_params_len = elen;
613 break;
614 case WLAN_EID_DS_PARAMS:
615 elems->ds_params = pos;
616 elems->ds_params_len = elen;
617 break;
618 case WLAN_EID_CF_PARAMS:
619 elems->cf_params = pos;
620 elems->cf_params_len = elen;
621 break;
622 case WLAN_EID_TIM:
623 if (elen >= sizeof(struct ieee80211_tim_ie)) {
624 elems->tim = (void *)pos;
625 elems->tim_len = elen;
626 }
627 break;
628 case WLAN_EID_IBSS_PARAMS:
629 elems->ibss_params = pos;
630 elems->ibss_params_len = elen;
631 break;
632 case WLAN_EID_CHALLENGE:
633 elems->challenge = pos;
634 elems->challenge_len = elen;
635 break;
636 case WLAN_EID_VENDOR_SPECIFIC:
637 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
638 pos[2] == 0xf2) {
639 /* Microsoft OUI (00:50:F2) */
640
641 if (calc_crc)
642 crc = crc32_be(crc, pos - 2, elen + 2);
643
644 if (pos[3] == 1) {
645 /* OUI Type 1 - WPA IE */
646 elems->wpa = pos;
647 elems->wpa_len = elen;
648 } else if (elen >= 5 && pos[3] == 2) {
649 /* OUI Type 2 - WMM IE */
650 if (pos[4] == 0) {
651 elems->wmm_info = pos;
652 elems->wmm_info_len = elen;
653 } else if (pos[4] == 1) {
654 elems->wmm_param = pos;
655 elems->wmm_param_len = elen;
656 }
657 }
658 }
659 break;
660 case WLAN_EID_RSN:
661 elems->rsn = pos;
662 elems->rsn_len = elen;
663 break;
664 case WLAN_EID_ERP_INFO:
665 elems->erp_info = pos;
666 elems->erp_info_len = elen;
667 break;
668 case WLAN_EID_EXT_SUPP_RATES:
669 elems->ext_supp_rates = pos;
670 elems->ext_supp_rates_len = elen;
671 break;
672 case WLAN_EID_HT_CAPABILITY:
673 if (elen >= sizeof(struct ieee80211_ht_cap))
674 elems->ht_cap_elem = (void *)pos;
675 break;
676 case WLAN_EID_HT_INFORMATION:
677 if (elen >= sizeof(struct ieee80211_ht_info))
678 elems->ht_info_elem = (void *)pos;
679 break;
680 case WLAN_EID_MESH_ID:
681 elems->mesh_id = pos;
682 elems->mesh_id_len = elen;
683 break;
684 case WLAN_EID_MESH_CONFIG:
685 if (elen >= sizeof(struct ieee80211_meshconf_ie))
686 elems->mesh_config = (void *)pos;
687 break;
688 case WLAN_EID_PEER_LINK:
689 elems->peer_link = pos;
690 elems->peer_link_len = elen;
691 break;
692 case WLAN_EID_PREQ:
693 elems->preq = pos;
694 elems->preq_len = elen;
695 break;
696 case WLAN_EID_PREP:
697 elems->prep = pos;
698 elems->prep_len = elen;
699 break;
700 case WLAN_EID_PERR:
701 elems->perr = pos;
702 elems->perr_len = elen;
703 break;
704 case WLAN_EID_RANN:
705 if (elen >= sizeof(struct ieee80211_rann_ie))
706 elems->rann = (void *)pos;
707 break;
708 case WLAN_EID_CHANNEL_SWITCH:
709 elems->ch_switch_elem = pos;
710 elems->ch_switch_elem_len = elen;
711 break;
712 case WLAN_EID_QUIET:
713 if (!elems->quiet_elem) {
714 elems->quiet_elem = pos;
715 elems->quiet_elem_len = elen;
716 }
717 elems->num_of_quiet_elem++;
718 break;
719 case WLAN_EID_COUNTRY:
720 elems->country_elem = pos;
721 elems->country_elem_len = elen;
722 break;
723 case WLAN_EID_PWR_CONSTRAINT:
724 elems->pwr_constr_elem = pos;
725 elems->pwr_constr_elem_len = elen;
726 break;
727 case WLAN_EID_TIMEOUT_INTERVAL:
728 elems->timeout_int = pos;
729 elems->timeout_int_len = elen;
730 break;
731 default:
732 break;
733 }
734
735 left -= elen;
736 pos += elen;
737 }
738
739 return crc;
740}
741
742void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) 573void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
743{ 574{
744 struct ieee80211_local *local = sdata->local; 575 struct ieee80211_local *local = sdata->local;
@@ -799,8 +630,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
799 630
800 qparam.uapsd = false; 631 qparam.uapsd = false;
801 632
802 local->tx_conf[queue] = qparam; 633 sdata->tx_conf[queue] = qparam;
803 drv_conf_tx(local, queue, &qparam); 634 drv_conf_tx(local, sdata, queue, &qparam);
804 } 635 }
805 636
806 /* after reinitialize QoS TX queues setting to default, 637 /* after reinitialize QoS TX queues setting to default,
@@ -874,11 +705,9 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
874 705
875 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 706 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
876 sizeof(*mgmt) + 6 + extra_len); 707 sizeof(*mgmt) + 6 + extra_len);
877 if (!skb) { 708 if (!skb)
878 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
879 "frame\n", sdata->name);
880 return; 709 return;
881 } 710
882 skb_reserve(skb, local->hw.extra_tx_headroom); 711 skb_reserve(skb, local->hw.extra_tx_headroom);
883 712
884 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); 713 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
@@ -1031,11 +860,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1031 860
1032 /* FIXME: come up with a proper value */ 861 /* FIXME: come up with a proper value */
1033 buf = kmalloc(200 + ie_len, GFP_KERNEL); 862 buf = kmalloc(200 + ie_len, GFP_KERNEL);
1034 if (!buf) { 863 if (!buf)
1035 printk(KERN_DEBUG "%s: failed to allocate temporary IE "
1036 "buffer\n", sdata->name);
1037 return NULL; 864 return NULL;
1038 }
1039 865
1040 /* 866 /*
1041 * Do not send DS Channel parameter for directed probe requests 867 * Do not send DS Channel parameter for directed probe requests
@@ -1055,6 +881,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1055 skb = ieee80211_probereq_get(&local->hw, &sdata->vif, 881 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1056 ssid, ssid_len, 882 ssid, ssid_len,
1057 buf, buf_len); 883 buf, buf_len);
884 if (!skb)
885 goto out;
1058 886
1059 if (dst) { 887 if (dst) {
1060 mgmt = (struct ieee80211_mgmt *) skb->data; 888 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -1063,6 +891,8 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1063 } 891 }
1064 892
1065 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 893 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
894
895 out:
1066 kfree(buf); 896 kfree(buf);
1067 897
1068 return skb; 898 return skb;
@@ -1071,14 +901,18 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata,
1071void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 901void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
1072 const u8 *ssid, size_t ssid_len, 902 const u8 *ssid, size_t ssid_len,
1073 const u8 *ie, size_t ie_len, 903 const u8 *ie, size_t ie_len,
1074 u32 ratemask, bool directed) 904 u32 ratemask, bool directed, bool no_cck)
1075{ 905{
1076 struct sk_buff *skb; 906 struct sk_buff *skb;
1077 907
1078 skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len, 908 skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len,
1079 ie, ie_len, directed); 909 ie, ie_len, directed);
1080 if (skb) 910 if (skb) {
911 if (no_cck)
912 IEEE80211_SKB_CB(skb)->flags |=
913 IEEE80211_TX_CTL_NO_CCK_RATE;
1081 ieee80211_tx_skb(sdata, skb); 914 ieee80211_tx_skb(sdata, skb);
915 }
1082} 916}
1083 917
1084u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 918u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
@@ -1205,14 +1039,22 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1205 struct ieee80211_sub_if_data, 1039 struct ieee80211_sub_if_data,
1206 u.ap); 1040 u.ap);
1207 1041
1042 memset(&sta->sta.drv_priv, 0, hw->sta_data_size);
1208 WARN_ON(drv_sta_add(local, sdata, &sta->sta)); 1043 WARN_ON(drv_sta_add(local, sdata, &sta->sta));
1209 } 1044 }
1210 } 1045 }
1211 mutex_unlock(&local->sta_mtx); 1046 mutex_unlock(&local->sta_mtx);
1212 1047
1213 /* reconfigure tx conf */ 1048 /* reconfigure tx conf */
1214 for (i = 0; i < hw->queues; i++) 1049 list_for_each_entry(sdata, &local->interfaces, list) {
1215 drv_conf_tx(local, i, &local->tx_conf[i]); 1050 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
1051 sdata->vif.type == NL80211_IFTYPE_MONITOR ||
1052 !ieee80211_sdata_running(sdata))
1053 continue;
1054
1055 for (i = 0; i < hw->queues; i++)
1056 drv_conf_tx(local, sdata, i, &sdata->tx_conf[i]);
1057 }
1216 1058
1217 /* reconfigure hardware */ 1059 /* reconfigure hardware */
1218 ieee80211_hw_config(local, ~0); 1060 ieee80211_hw_config(local, ~0);
@@ -1248,6 +1090,8 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1248 changed |= BSS_CHANGED_IBSS; 1090 changed |= BSS_CHANGED_IBSS;
1249 /* fall through */ 1091 /* fall through */
1250 case NL80211_IFTYPE_AP: 1092 case NL80211_IFTYPE_AP:
1093 changed |= BSS_CHANGED_SSID;
1094 /* fall through */
1251 case NL80211_IFTYPE_MESH_POINT: 1095 case NL80211_IFTYPE_MESH_POINT:
1252 changed |= BSS_CHANGED_BEACON | 1096 changed |= BSS_CHANGED_BEACON |
1253 BSS_CHANGED_BEACON_ENABLED; 1097 BSS_CHANGED_BEACON_ENABLED;
@@ -1283,7 +1127,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1283 1127
1284 list_for_each_entry(sta, &local->sta_list, list) { 1128 list_for_each_entry(sta, &local->sta_list, list) {
1285 ieee80211_sta_tear_down_BA_sessions(sta, true); 1129 ieee80211_sta_tear_down_BA_sessions(sta, true);
1286 clear_sta_flags(sta, WLAN_STA_BLOCK_BA); 1130 clear_sta_flag(sta, WLAN_STA_BLOCK_BA);
1287 } 1131 }
1288 1132
1289 mutex_unlock(&local->sta_mtx); 1133 mutex_unlock(&local->sta_mtx);
@@ -1522,3 +1366,60 @@ void ieee80211_disable_rssi_reports(struct ieee80211_vif *vif)
1522 _ieee80211_enable_rssi_reports(sdata, 0, 0); 1366 _ieee80211_enable_rssi_reports(sdata, 0, 0);
1523} 1367}
1524EXPORT_SYMBOL(ieee80211_disable_rssi_reports); 1368EXPORT_SYMBOL(ieee80211_disable_rssi_reports);
1369
1370int ieee80211_add_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
1371{
1372 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1373 struct ieee80211_local *local = sdata->local;
1374 struct ieee80211_supported_band *sband;
1375 int rate;
1376 u8 i, rates, *pos;
1377
1378 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1379 rates = sband->n_bitrates;
1380 if (rates > 8)
1381 rates = 8;
1382
1383 if (skb_tailroom(skb) < rates + 2)
1384 return -ENOMEM;
1385
1386 pos = skb_put(skb, rates + 2);
1387 *pos++ = WLAN_EID_SUPP_RATES;
1388 *pos++ = rates;
1389 for (i = 0; i < rates; i++) {
1390 rate = sband->bitrates[i].bitrate;
1391 *pos++ = (u8) (rate / 5);
1392 }
1393
1394 return 0;
1395}
1396
1397int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, struct sk_buff *skb)
1398{
1399 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1400 struct ieee80211_local *local = sdata->local;
1401 struct ieee80211_supported_band *sband;
1402 int rate;
1403 u8 i, exrates, *pos;
1404
1405 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1406 exrates = sband->n_bitrates;
1407 if (exrates > 8)
1408 exrates -= 8;
1409 else
1410 exrates = 0;
1411
1412 if (skb_tailroom(skb) < exrates + 2)
1413 return -ENOMEM;
1414
1415 if (exrates) {
1416 pos = skb_put(skb, exrates + 2);
1417 *pos++ = WLAN_EID_EXT_SUPP_RATES;
1418 *pos++ = exrates;
1419 for (i = 8; i < sband->n_bitrates; i++) {
1420 rate = sband->bitrates[i].bitrate;
1421 *pos++ = (u8) (rate / 5);
1422 }
1423 }
1424 return 0;
1425}