aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/agg-tx.c18
-rw-r--r--net/mac80211/cfg.c39
-rw-r--r--net/mac80211/driver-ops.h31
-rw-r--r--net/mac80211/ieee80211_i.h64
-rw-r--r--net/mac80211/main.c1
-rw-r--r--net/mac80211/mesh_hwmp.c7
-rw-r--r--net/mac80211/rc80211_minstrel_ht.c8
-rw-r--r--net/mac80211/sta_info.c1
-rw-r--r--net/mac80211/status.c3
-rw-r--r--net/mac80211/tx.c20
-rw-r--r--net/mac80211/util.c168
-rw-r--r--net/wireless/lib80211.c15
-rw-r--r--net/wireless/nl80211.c86
-rw-r--r--net/wireless/reg.c14
-rw-r--r--net/wireless/scan.c1
-rw-r--r--net/wireless/util.c168
-rw-r--r--net/wireless/wext-compat.c137
-rw-r--r--net/wireless/wext-compat.h8
-rw-r--r--net/wireless/wext-sme.c3
19 files changed, 375 insertions, 417 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index c8be8eff70da..b7075f33dc06 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -777,18 +777,14 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
777#ifdef CONFIG_MAC80211_HT_DEBUG 777#ifdef CONFIG_MAC80211_HT_DEBUG
778 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); 778 printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
779#endif 779#endif
780 780 /*
781 * IEEE 802.11-2007 7.3.1.14:
782 * In an ADDBA Response frame, when the Status Code field
783 * is set to 0, the Buffer Size subfield is set to a value
784 * of at least 1.
785 */
781 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) 786 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
782 == WLAN_STATUS_SUCCESS) { 787 == WLAN_STATUS_SUCCESS && buf_size) {
783 /*
784 * IEEE 802.11-2007 7.3.1.14:
785 * In an ADDBA Response frame, when the Status Code field
786 * is set to 0, the Buffer Size subfield is set to a value
787 * of at least 1.
788 */
789 if (!buf_size)
790 goto out;
791
792 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED, 788 if (test_and_set_bit(HT_AGG_STATE_RESPONSE_RECEIVED,
793 &tid_tx->state)) { 789 &tid_tx->state)) {
794 /* ignore duplicate response */ 790 /* ignore duplicate response */
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 86f8f49dae2f..a589addf6ce1 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1898,33 +1898,6 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1898 1898
1899 *cookie = (unsigned long) skb; 1899 *cookie = (unsigned long) skb;
1900 1900
1901 if (is_offchan && local->ops->offchannel_tx) {
1902 int ret;
1903
1904 IEEE80211_SKB_CB(skb)->band = chan->band;
1905
1906 mutex_lock(&local->mtx);
1907
1908 if (local->hw_offchan_tx_cookie) {
1909 mutex_unlock(&local->mtx);
1910 return -EBUSY;
1911 }
1912
1913 /* TODO: bitrate control, TX processing? */
1914 ret = drv_offchannel_tx(local, skb, chan, channel_type, wait);
1915
1916 if (ret == 0)
1917 local->hw_offchan_tx_cookie = *cookie;
1918 mutex_unlock(&local->mtx);
1919
1920 /*
1921 * Allow driver to return 1 to indicate it wants to have the
1922 * frame transmitted with a remain_on_channel + regular TX.
1923 */
1924 if (ret != 1)
1925 return ret;
1926 }
1927
1928 if (is_offchan && local->ops->remain_on_channel) { 1901 if (is_offchan && local->ops->remain_on_channel) {
1929 unsigned int duration; 1902 unsigned int duration;
1930 int ret; 1903 int ret;
@@ -2011,18 +1984,6 @@ static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy,
2011 1984
2012 mutex_lock(&local->mtx); 1985 mutex_lock(&local->mtx);
2013 1986
2014 if (local->ops->offchannel_tx_cancel_wait &&
2015 local->hw_offchan_tx_cookie == cookie) {
2016 ret = drv_offchannel_tx_cancel_wait(local);
2017
2018 if (!ret)
2019 local->hw_offchan_tx_cookie = 0;
2020
2021 mutex_unlock(&local->mtx);
2022
2023 return ret;
2024 }
2025
2026 if (local->ops->cancel_remain_on_channel) { 1987 if (local->ops->cancel_remain_on_channel) {
2027 cookie ^= 2; 1988 cookie ^= 2;
2028 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); 1989 ret = ieee80211_cancel_remain_on_channel_hw(local, cookie);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 1425380983f7..9001ff331f0a 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -590,37 +590,6 @@ static inline int drv_cancel_remain_on_channel(struct ieee80211_local *local)
590 return ret; 590 return ret;
591} 591}
592 592
593static inline int drv_offchannel_tx(struct ieee80211_local *local,
594 struct sk_buff *skb,
595 struct ieee80211_channel *chan,
596 enum nl80211_channel_type channel_type,
597 unsigned int wait)
598{
599 int ret;
600
601 might_sleep();
602
603 trace_drv_offchannel_tx(local, skb, chan, channel_type, wait);
604 ret = local->ops->offchannel_tx(&local->hw, skb, chan,
605 channel_type, wait);
606 trace_drv_return_int(local, ret);
607
608 return ret;
609}
610
611static inline int drv_offchannel_tx_cancel_wait(struct ieee80211_local *local)
612{
613 int ret;
614
615 might_sleep();
616
617 trace_drv_offchannel_tx_cancel_wait(local);
618 ret = local->ops->offchannel_tx_cancel_wait(&local->hw);
619 trace_drv_return_int(local, ret);
620
621 return ret;
622}
623
624static inline int drv_set_ringparam(struct ieee80211_local *local, 593static inline int drv_set_ringparam(struct ieee80211_local *local,
625 u32 tx, u32 rx) 594 u32 tx, u32 rx)
626{ 595{
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 400c09bea639..ea7419050846 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1002,7 +1002,6 @@ struct ieee80211_local {
1002 unsigned int hw_roc_duration; 1002 unsigned int hw_roc_duration;
1003 u32 hw_roc_cookie; 1003 u32 hw_roc_cookie;
1004 bool hw_roc_for_tx; 1004 bool hw_roc_for_tx;
1005 unsigned long hw_offchan_tx_cookie;
1006 1005
1007 /* dummy netdev for use w/ NAPI */ 1006 /* dummy netdev for use w/ NAPI */
1008 struct net_device napi_dev; 1007 struct net_device napi_dev;
@@ -1022,69 +1021,6 @@ struct ieee80211_ra_tid {
1022 u16 tid; 1021 u16 tid;
1023}; 1022};
1024 1023
1025/* Parsed Information Elements */
1026struct ieee802_11_elems {
1027 u8 *ie_start;
1028 size_t total_len;
1029
1030 /* pointers to IEs */
1031 u8 *ssid;
1032 u8 *supp_rates;
1033 u8 *fh_params;
1034 u8 *ds_params;
1035 u8 *cf_params;
1036 struct ieee80211_tim_ie *tim;
1037 u8 *ibss_params;
1038 u8 *challenge;
1039 u8 *wpa;
1040 u8 *rsn;
1041 u8 *erp_info;
1042 u8 *ext_supp_rates;
1043 u8 *wmm_info;
1044 u8 *wmm_param;
1045 struct ieee80211_ht_cap *ht_cap_elem;
1046 struct ieee80211_ht_info *ht_info_elem;
1047 struct ieee80211_meshconf_ie *mesh_config;
1048 u8 *mesh_id;
1049 u8 *peer_link;
1050 u8 *preq;
1051 u8 *prep;
1052 u8 *perr;
1053 struct ieee80211_rann_ie *rann;
1054 u8 *ch_switch_elem;
1055 u8 *country_elem;
1056 u8 *pwr_constr_elem;
1057 u8 *quiet_elem; /* first quite element */
1058 u8 *timeout_int;
1059
1060 /* length of them, respectively */
1061 u8 ssid_len;
1062 u8 supp_rates_len;
1063 u8 fh_params_len;
1064 u8 ds_params_len;
1065 u8 cf_params_len;
1066 u8 tim_len;
1067 u8 ibss_params_len;
1068 u8 challenge_len;
1069 u8 wpa_len;
1070 u8 rsn_len;
1071 u8 erp_info_len;
1072 u8 ext_supp_rates_len;
1073 u8 wmm_info_len;
1074 u8 wmm_param_len;
1075 u8 mesh_id_len;
1076 u8 peer_link_len;
1077 u8 preq_len;
1078 u8 prep_len;
1079 u8 perr_len;
1080 u8 ch_switch_elem_len;
1081 u8 country_elem_len;
1082 u8 pwr_constr_elem_len;
1083 u8 quiet_elem_len;
1084 u8 num_of_quiet_elem; /* can be more the one */
1085 u8 timeout_int_len;
1086};
1087
1088static inline struct ieee80211_local *hw_to_local( 1024static inline struct ieee80211_local *hw_to_local(
1089 struct ieee80211_hw *hw) 1025 struct ieee80211_hw *hw)
1090{ 1026{
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 866f269183cf..104fdd9862bd 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -608,6 +608,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
608 local->hw.max_rates = 1; 608 local->hw.max_rates = 1;
609 local->hw.max_report_rates = 0; 609 local->hw.max_report_rates = 0;
610 local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF; 610 local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
611 local->hw.max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
611 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 612 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
612 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 613 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
613 local->user_power_level = -1; 614 local->user_power_level = -1;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 3460108810d5..3d8e55ae6ab6 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -449,7 +449,6 @@ static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
449 449
450 if (fresh_info) { 450 if (fresh_info) {
451 mesh_path_assign_nexthop(mpath, sta); 451 mesh_path_assign_nexthop(mpath, sta);
452 mpath->flags &= ~MESH_PATH_SN_VALID;
453 mpath->metric = last_hop_metric; 452 mpath->metric = last_hop_metric;
454 mpath->exp_time = time_after(mpath->exp_time, exp_time) 453 mpath->exp_time = time_after(mpath->exp_time, exp_time)
455 ? mpath->exp_time : exp_time; 454 ? mpath->exp_time : exp_time;
@@ -792,9 +791,9 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
792 return; 791 return;
793 } 792 }
794 793
795 spin_lock(&ifmsh->mesh_preq_queue_lock); 794 spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
796 if (ifmsh->preq_queue_len == MAX_PREQ_QUEUE_LEN) { 795 if (ifmsh->preq_queue_len == MAX_PREQ_QUEUE_LEN) {
797 spin_unlock(&ifmsh->mesh_preq_queue_lock); 796 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
798 kfree(preq_node); 797 kfree(preq_node);
799 if (printk_ratelimit()) 798 if (printk_ratelimit())
800 mhwmp_dbg("PREQ node queue full\n"); 799 mhwmp_dbg("PREQ node queue full\n");
@@ -806,7 +805,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
806 805
807 list_add_tail(&preq_node->list, &ifmsh->preq_queue.list); 806 list_add_tail(&preq_node->list, &ifmsh->preq_queue.list);
808 ++ifmsh->preq_queue_len; 807 ++ifmsh->preq_queue_len;
809 spin_unlock(&ifmsh->mesh_preq_queue_lock); 808 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
810 809
811 if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) 810 if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
812 ieee80211_queue_work(&sdata->local->hw, &sdata->work); 811 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c
index 66a1eeb279c6..21588386a302 100644
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -608,7 +608,13 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
608 return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc); 608 return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
609 609
610 info->flags |= mi->tx_flags; 610 info->flags |= mi->tx_flags;
611 sample_idx = minstrel_get_sample_rate(mp, mi); 611
612 /* Don't use EAPOL frames for sampling on non-mrr hw */
613 if (mp->hw->max_rates == 1 &&
614 txrc->skb->protocol == cpu_to_be16(ETH_P_PAE))
615 sample_idx = -1;
616 else
617 sample_idx = minstrel_get_sample_rate(mp, mi);
612 618
613#ifdef CONFIG_MAC80211_DEBUGFS 619#ifdef CONFIG_MAC80211_DEBUGFS
614 /* use fixed index if set */ 620 /* use fixed index if set */
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 8b6ebee073e2..0bdbf3b8f28b 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -330,6 +330,7 @@ static int sta_info_finish_insert(struct sta_info *sta, bool async)
330 ieee80211_sta_debugfs_add(sta); 330 ieee80211_sta_debugfs_add(sta);
331 rate_control_add_sta_debugfs(sta); 331 rate_control_add_sta_debugfs(sta);
332 332
333 memset(&sinfo, 0, sizeof(sinfo));
333 sinfo.filled = 0; 334 sinfo.filled = 0;
334 sinfo.generation = local->sta_generation; 335 sinfo.generation = local->sta_generation;
335 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL); 336 cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index 1658efaa2e8e..a89cca3491b4 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -345,9 +345,6 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
345 local->hw_roc_skb_for_status = NULL; 345 local->hw_roc_skb_for_status = NULL;
346 } 346 }
347 347
348 if (cookie == local->hw_offchan_tx_cookie)
349 local->hw_offchan_tx_cookie = 0;
350
351 cfg80211_mgmt_tx_status( 348 cfg80211_mgmt_tx_status(
352 skb->dev, cookie, skb->data, skb->len, 349 skb->dev, cookie, skb->data, skb->len,
353 !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC); 350 !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 8cb0d2d0ac69..69fd494f32f9 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1608,7 +1608,9 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1608 struct ieee80211_radiotap_header *prthdr = 1608 struct ieee80211_radiotap_header *prthdr =
1609 (struct ieee80211_radiotap_header *)skb->data; 1609 (struct ieee80211_radiotap_header *)skb->data;
1610 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1610 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1611 struct ieee80211_hdr *hdr;
1611 u16 len_rthdr; 1612 u16 len_rthdr;
1613 u8 *payload;
1612 1614
1613 /* 1615 /*
1614 * Frame injection is not allowed if beaconing is not allowed 1616 * Frame injection is not allowed if beaconing is not allowed
@@ -1659,6 +1661,24 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
1659 skb_set_network_header(skb, len_rthdr); 1661 skb_set_network_header(skb, len_rthdr);
1660 skb_set_transport_header(skb, len_rthdr); 1662 skb_set_transport_header(skb, len_rthdr);
1661 1663
1664 /*
1665 * Initialize skb->protocol if the injected frame is a data frame
1666 * carrying a rfc1042 header
1667 */
1668 if (skb->len > len_rthdr + 2) {
1669 hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr);
1670 if (ieee80211_is_data(hdr->frame_control) &&
1671 skb->len >= len_rthdr +
1672 ieee80211_hdrlen(hdr->frame_control) +
1673 sizeof(rfc1042_header) + 2) {
1674 payload = (u8 *)hdr +
1675 ieee80211_hdrlen(hdr->frame_control);
1676 if (compare_ether_addr(payload, rfc1042_header) == 0)
1677 skb->protocol = cpu_to_be16((payload[6] << 8) |
1678 payload[7]);
1679 }
1680 }
1681
1662 memset(info, 0, sizeof(*info)); 1682 memset(info, 0, sizeof(*info));
1663 1683
1664 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 1684 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index ddeb1b998383..ce916ff6ef08 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -19,7 +19,6 @@
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/bitmap.h> 21#include <linux/bitmap.h>
22#include <linux/crc32.h>
23#include <net/net_namespace.h> 22#include <net/net_namespace.h>
24#include <net/cfg80211.h> 23#include <net/cfg80211.h>
25#include <net/rtnetlink.h> 24#include <net/rtnetlink.h>
@@ -573,172 +572,6 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
573 ieee802_11_parse_elems_crc(start, len, elems, 0, 0); 572 ieee802_11_parse_elems_crc(start, len, elems, 0, 0);
574} 573}
575 574
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) 575void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
743{ 576{
744 struct ieee80211_local *local = sdata->local; 577 struct ieee80211_local *local = sdata->local;
@@ -1205,6 +1038,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1205 struct ieee80211_sub_if_data, 1038 struct ieee80211_sub_if_data,
1206 u.ap); 1039 u.ap);
1207 1040
1041 memset(&sta->sta.drv_priv, 0, hw->sta_data_size);
1208 WARN_ON(drv_sta_add(local, sdata, &sta->sta)); 1042 WARN_ON(drv_sta_add(local, sdata, &sta->sta));
1209 } 1043 }
1210 } 1044 }
diff --git a/net/wireless/lib80211.c b/net/wireless/lib80211.c
index 3268fac5ab22..a55c27b75ee5 100644
--- a/net/wireless/lib80211.c
+++ b/net/wireless/lib80211.c
@@ -41,6 +41,11 @@ struct lib80211_crypto_alg {
41static LIST_HEAD(lib80211_crypto_algs); 41static LIST_HEAD(lib80211_crypto_algs);
42static DEFINE_SPINLOCK(lib80211_crypto_lock); 42static DEFINE_SPINLOCK(lib80211_crypto_lock);
43 43
44static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
45 int force);
46static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info);
47static void lib80211_crypt_deinit_handler(unsigned long data);
48
44const char *print_ssid(char *buf, const char *ssid, u8 ssid_len) 49const char *print_ssid(char *buf, const char *ssid, u8 ssid_len)
45{ 50{
46 const char *s = ssid; 51 const char *s = ssid;
@@ -111,7 +116,8 @@ void lib80211_crypt_info_free(struct lib80211_crypt_info *info)
111} 116}
112EXPORT_SYMBOL(lib80211_crypt_info_free); 117EXPORT_SYMBOL(lib80211_crypt_info_free);
113 118
114void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force) 119static void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info,
120 int force)
115{ 121{
116 struct lib80211_crypt_data *entry, *next; 122 struct lib80211_crypt_data *entry, *next;
117 unsigned long flags; 123 unsigned long flags;
@@ -131,10 +137,9 @@ void lib80211_crypt_deinit_entries(struct lib80211_crypt_info *info, int force)
131 } 137 }
132 spin_unlock_irqrestore(info->lock, flags); 138 spin_unlock_irqrestore(info->lock, flags);
133} 139}
134EXPORT_SYMBOL(lib80211_crypt_deinit_entries);
135 140
136/* After this, crypt_deinit_list won't accept new members */ 141/* After this, crypt_deinit_list won't accept new members */
137void lib80211_crypt_quiescing(struct lib80211_crypt_info *info) 142static void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
138{ 143{
139 unsigned long flags; 144 unsigned long flags;
140 145
@@ -142,9 +147,8 @@ void lib80211_crypt_quiescing(struct lib80211_crypt_info *info)
142 info->crypt_quiesced = 1; 147 info->crypt_quiesced = 1;
143 spin_unlock_irqrestore(info->lock, flags); 148 spin_unlock_irqrestore(info->lock, flags);
144} 149}
145EXPORT_SYMBOL(lib80211_crypt_quiescing);
146 150
147void lib80211_crypt_deinit_handler(unsigned long data) 151static void lib80211_crypt_deinit_handler(unsigned long data)
148{ 152{
149 struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data; 153 struct lib80211_crypt_info *info = (struct lib80211_crypt_info *)data;
150 unsigned long flags; 154 unsigned long flags;
@@ -160,7 +164,6 @@ void lib80211_crypt_deinit_handler(unsigned long data)
160 } 164 }
161 spin_unlock_irqrestore(info->lock, flags); 165 spin_unlock_irqrestore(info->lock, flags);
162} 166}
163EXPORT_SYMBOL(lib80211_crypt_deinit_handler);
164 167
165void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info, 168void lib80211_crypt_delayed_deinit(struct lib80211_crypt_info *info,
166 struct lib80211_crypt_data **crypt) 169 struct lib80211_crypt_data **crypt)
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e83e7fee3bc0..2aa6a2189842 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -23,6 +23,12 @@
23#include "nl80211.h" 23#include "nl80211.h"
24#include "reg.h" 24#include "reg.h"
25 25
26static bool nl80211_valid_auth_type(enum nl80211_auth_type auth_type);
27static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
28 struct genl_info *info,
29 struct cfg80211_crypto_settings *settings,
30 int cipher_limit);
31
26static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, 32static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
27 struct genl_info *info); 33 struct genl_info *info);
28static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 34static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
@@ -178,6 +184,11 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
178 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, 184 [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 },
179 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, 185 [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED },
180 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, 186 [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED },
187 [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 },
188 [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY,
189 .len = IEEE80211_MAX_DATA_LEN },
190 [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
191 .len = IEEE80211_MAX_DATA_LEN },
181}; 192};
182 193
183/* policy for the key attributes */ 194/* policy for the key attributes */
@@ -871,8 +882,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
871 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, 882 NLA_PUT_U32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION,
872 dev->wiphy.max_remain_on_channel_duration); 883 dev->wiphy.max_remain_on_channel_duration);
873 884
874 /* for now at least assume all drivers have it */ 885 if (dev->ops->mgmt_tx_cancel_wait)
875 if (dev->ops->mgmt_tx)
876 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK); 886 NLA_PUT_FLAG(msg, NL80211_ATTR_OFFCHANNEL_TX_OK);
877 887
878 if (mgmt_stypes) { 888 if (mgmt_stypes) {
@@ -1985,7 +1995,10 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
1985 struct beacon_parameters params; 1995 struct beacon_parameters params;
1986 int haveinfo = 0, err; 1996 int haveinfo = 0, err;
1987 1997
1988 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL])) 1998 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) ||
1999 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) ||
2000 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) ||
2001 !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]))
1989 return -EINVAL; 2002 return -EINVAL;
1990 2003
1991 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && 2004 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP &&
@@ -2011,6 +2024,49 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
2011 if (err) 2024 if (err)
2012 return err; 2025 return err;
2013 2026
2027 /*
2028 * In theory, some of these attributes could be required for
2029 * NEW_BEACON, but since they were not used when the command was
2030 * originally added, keep them optional for old user space
2031 * programs to work with drivers that do not need the additional
2032 * information.
2033 */
2034 if (info->attrs[NL80211_ATTR_SSID]) {
2035 params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
2036 params.ssid_len =
2037 nla_len(info->attrs[NL80211_ATTR_SSID]);
2038 if (params.ssid_len == 0 ||
2039 params.ssid_len > IEEE80211_MAX_SSID_LEN)
2040 return -EINVAL;
2041 }
2042
2043 if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) {
2044 params.hidden_ssid = nla_get_u32(
2045 info->attrs[NL80211_ATTR_HIDDEN_SSID]);
2046 if (params.hidden_ssid !=
2047 NL80211_HIDDEN_SSID_NOT_IN_USE &&
2048 params.hidden_ssid !=
2049 NL80211_HIDDEN_SSID_ZERO_LEN &&
2050 params.hidden_ssid !=
2051 NL80211_HIDDEN_SSID_ZERO_CONTENTS)
2052 return -EINVAL;
2053 }
2054
2055 params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
2056
2057 if (info->attrs[NL80211_ATTR_AUTH_TYPE]) {
2058 params.auth_type = nla_get_u32(
2059 info->attrs[NL80211_ATTR_AUTH_TYPE]);
2060 if (!nl80211_valid_auth_type(params.auth_type))
2061 return -EINVAL;
2062 } else
2063 params.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
2064
2065 err = nl80211_crypto_settings(rdev, info, &params.crypto,
2066 NL80211_MAX_NR_CIPHER_SUITES);
2067 if (err)
2068 return err;
2069
2014 call = rdev->ops->add_beacon; 2070 call = rdev->ops->add_beacon;
2015 break; 2071 break;
2016 case NL80211_CMD_SET_BEACON: 2072 case NL80211_CMD_SET_BEACON:
@@ -2041,6 +2097,25 @@ static int nl80211_addset_beacon(struct sk_buff *skb, struct genl_info *info)
2041 if (!haveinfo) 2097 if (!haveinfo)
2042 return -EINVAL; 2098 return -EINVAL;
2043 2099
2100 if (info->attrs[NL80211_ATTR_IE]) {
2101 params.beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]);
2102 params.beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]);
2103 }
2104
2105 if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) {
2106 params.proberesp_ies =
2107 nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
2108 params.proberesp_ies_len =
2109 nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]);
2110 }
2111
2112 if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) {
2113 params.assocresp_ies =
2114 nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2115 params.assocresp_ies_len =
2116 nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]);
2117 }
2118
2044 err = call(&rdev->wiphy, dev, &params); 2119 err = call(&rdev->wiphy, dev, &params);
2045 if (!err && params.interval) 2120 if (!err && params.interval)
2046 wdev->beacon_interval = params.interval; 2121 wdev->beacon_interval = params.interval;
@@ -2237,6 +2312,10 @@ static int nl80211_send_station(struct sk_buff *msg, u32 pid, u32 seq,
2237 } 2312 }
2238 nla_nest_end(msg, sinfoattr); 2313 nla_nest_end(msg, sinfoattr);
2239 2314
2315 if (sinfo->filled & STATION_INFO_ASSOC_REQ_IES)
2316 NLA_PUT(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len,
2317 sinfo->assoc_req_ies);
2318
2240 return genlmsg_end(msg, hdr); 2319 return genlmsg_end(msg, hdr);
2241 2320
2242 nla_put_failure: 2321 nla_put_failure:
@@ -2264,6 +2343,7 @@ static int nl80211_dump_station(struct sk_buff *skb,
2264 } 2343 }
2265 2344
2266 while (1) { 2345 while (1) {
2346 memset(&sinfo, 0, sizeof(sinfo));
2267 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx, 2347 err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,
2268 mac_addr, &sinfo); 2348 mac_addr, &sinfo);
2269 if (err == -ENOENT) 2349 if (err == -ENOENT)
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 02751dbc5a97..9f3aa5cabdef 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -49,10 +49,8 @@
49#include "nl80211.h" 49#include "nl80211.h"
50 50
51#ifdef CONFIG_CFG80211_REG_DEBUG 51#ifdef CONFIG_CFG80211_REG_DEBUG
52#define REG_DBG_PRINT(format, args...) \ 52#define REG_DBG_PRINT(format, args...) \
53 do { \ 53 printk(KERN_DEBUG pr_fmt(format), ##args)
54 printk(KERN_DEBUG pr_fmt(format), ##args); \
55 } while (0)
56#else 54#else
57#define REG_DBG_PRINT(args...) 55#define REG_DBG_PRINT(args...)
58#endif 56#endif
@@ -890,7 +888,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
890 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) { 888 wiphy->flags & WIPHY_FLAG_CUSTOM_REGULATORY) {
891 REG_DBG_PRINT("Ignoring regulatory request %s " 889 REG_DBG_PRINT("Ignoring regulatory request %s "
892 "since the driver uses its own custom " 890 "since the driver uses its own custom "
893 "regulatory domain ", 891 "regulatory domain\n",
894 reg_initiator_name(initiator)); 892 reg_initiator_name(initiator));
895 return true; 893 return true;
896 } 894 }
@@ -904,7 +902,7 @@ static bool ignore_reg_update(struct wiphy *wiphy,
904 !is_world_regdom(last_request->alpha2)) { 902 !is_world_regdom(last_request->alpha2)) {
905 REG_DBG_PRINT("Ignoring regulatory request %s " 903 REG_DBG_PRINT("Ignoring regulatory request %s "
906 "since the driver requires its own regulatory " 904 "since the driver requires its own regulatory "
907 "domain to be set first", 905 "domain to be set first\n",
908 reg_initiator_name(initiator)); 906 reg_initiator_name(initiator));
909 return true; 907 return true;
910 } 908 }
@@ -1474,7 +1472,7 @@ static void reg_process_pending_hints(void)
1474 /* When last_request->processed becomes true this will be rescheduled */ 1472 /* When last_request->processed becomes true this will be rescheduled */
1475 if (last_request && !last_request->processed) { 1473 if (last_request && !last_request->processed) {
1476 REG_DBG_PRINT("Pending regulatory request, waiting " 1474 REG_DBG_PRINT("Pending regulatory request, waiting "
1477 "for it to be processed..."); 1475 "for it to be processed...\n");
1478 goto out; 1476 goto out;
1479 } 1477 }
1480 1478
@@ -2187,7 +2185,7 @@ out:
2187static void reg_timeout_work(struct work_struct *work) 2185static void reg_timeout_work(struct work_struct *work)
2188{ 2186{
2189 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, " 2187 REG_DBG_PRINT("Timeout while waiting for CRDA to reply, "
2190 "restoring regulatory settings"); 2188 "restoring regulatory settings\n");
2191 restore_regulatory_settings(true); 2189 restore_regulatory_settings(true);
2192} 2190}
2193 2191
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 2936cb809152..b0f003966953 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -12,6 +12,7 @@
12#include <linux/etherdevice.h> 12#include <linux/etherdevice.h>
13#include <net/arp.h> 13#include <net/arp.h>
14#include <net/cfg80211.h> 14#include <net/cfg80211.h>
15#include <net/cfg80211-wext.h>
15#include <net/iw_handler.h> 16#include <net/iw_handler.h>
16#include "core.h" 17#include "core.h"
17#include "nl80211.h" 18#include "nl80211.h"
diff --git a/net/wireless/util.c b/net/wireless/util.c
index be75a3a0424e..844ddb0aa653 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -6,6 +6,7 @@
6#include <linux/bitops.h> 6#include <linux/bitops.h>
7#include <linux/etherdevice.h> 7#include <linux/etherdevice.h>
8#include <linux/slab.h> 8#include <linux/slab.h>
9#include <linux/crc32.h>
9#include <net/cfg80211.h> 10#include <net/cfg80211.h>
10#include <net/ip.h> 11#include <net/ip.h>
11#include "core.h" 12#include "core.h"
@@ -1044,3 +1045,170 @@ int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
1044 1045
1045 return 0; 1046 return 0;
1046} 1047}
1048
1049u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
1050 struct ieee802_11_elems *elems,
1051 u64 filter, u32 crc)
1052{
1053 size_t left = len;
1054 u8 *pos = start;
1055 bool calc_crc = filter != 0;
1056
1057 memset(elems, 0, sizeof(*elems));
1058 elems->ie_start = start;
1059 elems->total_len = len;
1060
1061 while (left >= 2) {
1062 u8 id, elen;
1063
1064 id = *pos++;
1065 elen = *pos++;
1066 left -= 2;
1067
1068 if (elen > left)
1069 break;
1070
1071 if (calc_crc && id < 64 && (filter & (1ULL << id)))
1072 crc = crc32_be(crc, pos - 2, elen + 2);
1073
1074 switch (id) {
1075 case WLAN_EID_SSID:
1076 elems->ssid = pos;
1077 elems->ssid_len = elen;
1078 break;
1079 case WLAN_EID_SUPP_RATES:
1080 elems->supp_rates = pos;
1081 elems->supp_rates_len = elen;
1082 break;
1083 case WLAN_EID_FH_PARAMS:
1084 elems->fh_params = pos;
1085 elems->fh_params_len = elen;
1086 break;
1087 case WLAN_EID_DS_PARAMS:
1088 elems->ds_params = pos;
1089 elems->ds_params_len = elen;
1090 break;
1091 case WLAN_EID_CF_PARAMS:
1092 elems->cf_params = pos;
1093 elems->cf_params_len = elen;
1094 break;
1095 case WLAN_EID_TIM:
1096 if (elen >= sizeof(struct ieee80211_tim_ie)) {
1097 elems->tim = (void *)pos;
1098 elems->tim_len = elen;
1099 }
1100 break;
1101 case WLAN_EID_IBSS_PARAMS:
1102 elems->ibss_params = pos;
1103 elems->ibss_params_len = elen;
1104 break;
1105 case WLAN_EID_CHALLENGE:
1106 elems->challenge = pos;
1107 elems->challenge_len = elen;
1108 break;
1109 case WLAN_EID_VENDOR_SPECIFIC:
1110 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
1111 pos[2] == 0xf2) {
1112 /* Microsoft OUI (00:50:F2) */
1113
1114 if (calc_crc)
1115 crc = crc32_be(crc, pos - 2, elen + 2);
1116
1117 if (pos[3] == 1) {
1118 /* OUI Type 1 - WPA IE */
1119 elems->wpa = pos;
1120 elems->wpa_len = elen;
1121 } else if (elen >= 5 && pos[3] == 2) {
1122 /* OUI Type 2 - WMM IE */
1123 if (pos[4] == 0) {
1124 elems->wmm_info = pos;
1125 elems->wmm_info_len = elen;
1126 } else if (pos[4] == 1) {
1127 elems->wmm_param = pos;
1128 elems->wmm_param_len = elen;
1129 }
1130 }
1131 }
1132 break;
1133 case WLAN_EID_RSN:
1134 elems->rsn = pos;
1135 elems->rsn_len = elen;
1136 break;
1137 case WLAN_EID_ERP_INFO:
1138 elems->erp_info = pos;
1139 elems->erp_info_len = elen;
1140 break;
1141 case WLAN_EID_EXT_SUPP_RATES:
1142 elems->ext_supp_rates = pos;
1143 elems->ext_supp_rates_len = elen;
1144 break;
1145 case WLAN_EID_HT_CAPABILITY:
1146 if (elen >= sizeof(struct ieee80211_ht_cap))
1147 elems->ht_cap_elem = (void *)pos;
1148 break;
1149 case WLAN_EID_HT_INFORMATION:
1150 if (elen >= sizeof(struct ieee80211_ht_info))
1151 elems->ht_info_elem = (void *)pos;
1152 break;
1153 case WLAN_EID_MESH_ID:
1154 elems->mesh_id = pos;
1155 elems->mesh_id_len = elen;
1156 break;
1157 case WLAN_EID_MESH_CONFIG:
1158 if (elen >= sizeof(struct ieee80211_meshconf_ie))
1159 elems->mesh_config = (void *)pos;
1160 break;
1161 case WLAN_EID_PEER_LINK:
1162 elems->peer_link = pos;
1163 elems->peer_link_len = elen;
1164 break;
1165 case WLAN_EID_PREQ:
1166 elems->preq = pos;
1167 elems->preq_len = elen;
1168 break;
1169 case WLAN_EID_PREP:
1170 elems->prep = pos;
1171 elems->prep_len = elen;
1172 break;
1173 case WLAN_EID_PERR:
1174 elems->perr = pos;
1175 elems->perr_len = elen;
1176 break;
1177 case WLAN_EID_RANN:
1178 if (elen >= sizeof(struct ieee80211_rann_ie))
1179 elems->rann = (void *)pos;
1180 break;
1181 case WLAN_EID_CHANNEL_SWITCH:
1182 elems->ch_switch_elem = pos;
1183 elems->ch_switch_elem_len = elen;
1184 break;
1185 case WLAN_EID_QUIET:
1186 if (!elems->quiet_elem) {
1187 elems->quiet_elem = pos;
1188 elems->quiet_elem_len = elen;
1189 }
1190 elems->num_of_quiet_elem++;
1191 break;
1192 case WLAN_EID_COUNTRY:
1193 elems->country_elem = pos;
1194 elems->country_elem_len = elen;
1195 break;
1196 case WLAN_EID_PWR_CONSTRAINT:
1197 elems->pwr_constr_elem = pos;
1198 elems->pwr_constr_elem_len = elen;
1199 break;
1200 case WLAN_EID_TIMEOUT_INTERVAL:
1201 elems->timeout_int = pos;
1202 elems->timeout_int_len = elen;
1203 break;
1204 default:
1205 break;
1206 }
1207
1208 left -= elen;
1209 pos += elen;
1210 }
1211
1212 return crc;
1213}
1214EXPORT_SYMBOL(ieee802_11_parse_elems_crc);
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 0bf169bb770e..62f121d1d9cb 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <net/iw_handler.h> 16#include <net/iw_handler.h>
17#include <net/cfg80211.h> 17#include <net/cfg80211.h>
18#include <net/cfg80211-wext.h>
18#include "wext-compat.h" 19#include "wext-compat.h"
19#include "core.h" 20#include "core.h"
20 21
@@ -363,9 +364,9 @@ int cfg80211_wext_giwfrag(struct net_device *dev,
363} 364}
364EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag); 365EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag);
365 366
366int cfg80211_wext_siwretry(struct net_device *dev, 367static int cfg80211_wext_siwretry(struct net_device *dev,
367 struct iw_request_info *info, 368 struct iw_request_info *info,
368 struct iw_param *retry, char *extra) 369 struct iw_param *retry, char *extra)
369{ 370{
370 struct wireless_dev *wdev = dev->ieee80211_ptr; 371 struct wireless_dev *wdev = dev->ieee80211_ptr;
371 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 372 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -402,7 +403,6 @@ int cfg80211_wext_siwretry(struct net_device *dev,
402 403
403 return err; 404 return err;
404} 405}
405EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry);
406 406
407int cfg80211_wext_giwretry(struct net_device *dev, 407int cfg80211_wext_giwretry(struct net_device *dev,
408 struct iw_request_info *info, 408 struct iw_request_info *info,
@@ -593,9 +593,9 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
593 return err; 593 return err;
594} 594}
595 595
596int cfg80211_wext_siwencode(struct net_device *dev, 596static int cfg80211_wext_siwencode(struct net_device *dev,
597 struct iw_request_info *info, 597 struct iw_request_info *info,
598 struct iw_point *erq, char *keybuf) 598 struct iw_point *erq, char *keybuf)
599{ 599{
600 struct wireless_dev *wdev = dev->ieee80211_ptr; 600 struct wireless_dev *wdev = dev->ieee80211_ptr;
601 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 601 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -652,11 +652,10 @@ int cfg80211_wext_siwencode(struct net_device *dev,
652 wdev->wext.default_key == -1, 652 wdev->wext.default_key == -1,
653 idx, &params); 653 idx, &params);
654} 654}
655EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode);
656 655
657int cfg80211_wext_siwencodeext(struct net_device *dev, 656static int cfg80211_wext_siwencodeext(struct net_device *dev,
658 struct iw_request_info *info, 657 struct iw_request_info *info,
659 struct iw_point *erq, char *extra) 658 struct iw_point *erq, char *extra)
660{ 659{
661 struct wireless_dev *wdev = dev->ieee80211_ptr; 660 struct wireless_dev *wdev = dev->ieee80211_ptr;
662 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 661 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -744,11 +743,10 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
744 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY, 743 ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY,
745 idx, &params); 744 idx, &params);
746} 745}
747EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
748 746
749int cfg80211_wext_giwencode(struct net_device *dev, 747static int cfg80211_wext_giwencode(struct net_device *dev,
750 struct iw_request_info *info, 748 struct iw_request_info *info,
751 struct iw_point *erq, char *keybuf) 749 struct iw_point *erq, char *keybuf)
752{ 750{
753 struct wireless_dev *wdev = dev->ieee80211_ptr; 751 struct wireless_dev *wdev = dev->ieee80211_ptr;
754 int idx; 752 int idx;
@@ -782,11 +780,10 @@ int cfg80211_wext_giwencode(struct net_device *dev,
782 780
783 return 0; 781 return 0;
784} 782}
785EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
786 783
787int cfg80211_wext_siwfreq(struct net_device *dev, 784static int cfg80211_wext_siwfreq(struct net_device *dev,
788 struct iw_request_info *info, 785 struct iw_request_info *info,
789 struct iw_freq *wextfreq, char *extra) 786 struct iw_freq *wextfreq, char *extra)
790{ 787{
791 struct wireless_dev *wdev = dev->ieee80211_ptr; 788 struct wireless_dev *wdev = dev->ieee80211_ptr;
792 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 789 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -815,11 +812,10 @@ int cfg80211_wext_siwfreq(struct net_device *dev,
815 return -EOPNOTSUPP; 812 return -EOPNOTSUPP;
816 } 813 }
817} 814}
818EXPORT_SYMBOL_GPL(cfg80211_wext_siwfreq);
819 815
820int cfg80211_wext_giwfreq(struct net_device *dev, 816static int cfg80211_wext_giwfreq(struct net_device *dev,
821 struct iw_request_info *info, 817 struct iw_request_info *info,
822 struct iw_freq *freq, char *extra) 818 struct iw_freq *freq, char *extra)
823{ 819{
824 struct wireless_dev *wdev = dev->ieee80211_ptr; 820 struct wireless_dev *wdev = dev->ieee80211_ptr;
825 821
@@ -836,11 +832,10 @@ int cfg80211_wext_giwfreq(struct net_device *dev,
836 return 0; 832 return 0;
837 } 833 }
838} 834}
839EXPORT_SYMBOL_GPL(cfg80211_wext_giwfreq);
840 835
841int cfg80211_wext_siwtxpower(struct net_device *dev, 836static int cfg80211_wext_siwtxpower(struct net_device *dev,
842 struct iw_request_info *info, 837 struct iw_request_info *info,
843 union iwreq_data *data, char *extra) 838 union iwreq_data *data, char *extra)
844{ 839{
845 struct wireless_dev *wdev = dev->ieee80211_ptr; 840 struct wireless_dev *wdev = dev->ieee80211_ptr;
846 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 841 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -889,11 +884,10 @@ int cfg80211_wext_siwtxpower(struct net_device *dev,
889 884
890 return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm)); 885 return rdev->ops->set_tx_power(wdev->wiphy, type, DBM_TO_MBM(dbm));
891} 886}
892EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower);
893 887
894int cfg80211_wext_giwtxpower(struct net_device *dev, 888static int cfg80211_wext_giwtxpower(struct net_device *dev,
895 struct iw_request_info *info, 889 struct iw_request_info *info,
896 union iwreq_data *data, char *extra) 890 union iwreq_data *data, char *extra)
897{ 891{
898 struct wireless_dev *wdev = dev->ieee80211_ptr; 892 struct wireless_dev *wdev = dev->ieee80211_ptr;
899 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 893 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -919,7 +913,6 @@ int cfg80211_wext_giwtxpower(struct net_device *dev,
919 913
920 return 0; 914 return 0;
921} 915}
922EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower);
923 916
924static int cfg80211_set_auth_alg(struct wireless_dev *wdev, 917static int cfg80211_set_auth_alg(struct wireless_dev *wdev,
925 s32 auth_alg) 918 s32 auth_alg)
@@ -1070,9 +1063,9 @@ static int cfg80211_set_key_mgt(struct wireless_dev *wdev, u32 key_mgt)
1070 return 0; 1063 return 0;
1071} 1064}
1072 1065
1073int cfg80211_wext_siwauth(struct net_device *dev, 1066static int cfg80211_wext_siwauth(struct net_device *dev,
1074 struct iw_request_info *info, 1067 struct iw_request_info *info,
1075 struct iw_param *data, char *extra) 1068 struct iw_param *data, char *extra)
1076{ 1069{
1077 struct wireless_dev *wdev = dev->ieee80211_ptr; 1070 struct wireless_dev *wdev = dev->ieee80211_ptr;
1078 1071
@@ -1102,21 +1095,19 @@ int cfg80211_wext_siwauth(struct net_device *dev,
1102 return -EOPNOTSUPP; 1095 return -EOPNOTSUPP;
1103 } 1096 }
1104} 1097}
1105EXPORT_SYMBOL_GPL(cfg80211_wext_siwauth);
1106 1098
1107int cfg80211_wext_giwauth(struct net_device *dev, 1099static int cfg80211_wext_giwauth(struct net_device *dev,
1108 struct iw_request_info *info, 1100 struct iw_request_info *info,
1109 struct iw_param *data, char *extra) 1101 struct iw_param *data, char *extra)
1110{ 1102{
1111 /* XXX: what do we need? */ 1103 /* XXX: what do we need? */
1112 1104
1113 return -EOPNOTSUPP; 1105 return -EOPNOTSUPP;
1114} 1106}
1115EXPORT_SYMBOL_GPL(cfg80211_wext_giwauth);
1116 1107
1117int cfg80211_wext_siwpower(struct net_device *dev, 1108static int cfg80211_wext_siwpower(struct net_device *dev,
1118 struct iw_request_info *info, 1109 struct iw_request_info *info,
1119 struct iw_param *wrq, char *extra) 1110 struct iw_param *wrq, char *extra)
1120{ 1111{
1121 struct wireless_dev *wdev = dev->ieee80211_ptr; 1112 struct wireless_dev *wdev = dev->ieee80211_ptr;
1122 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1113 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1160,11 +1151,10 @@ int cfg80211_wext_siwpower(struct net_device *dev,
1160 return 0; 1151 return 0;
1161 1152
1162} 1153}
1163EXPORT_SYMBOL_GPL(cfg80211_wext_siwpower);
1164 1154
1165int cfg80211_wext_giwpower(struct net_device *dev, 1155static int cfg80211_wext_giwpower(struct net_device *dev,
1166 struct iw_request_info *info, 1156 struct iw_request_info *info,
1167 struct iw_param *wrq, char *extra) 1157 struct iw_param *wrq, char *extra)
1168{ 1158{
1169 struct wireless_dev *wdev = dev->ieee80211_ptr; 1159 struct wireless_dev *wdev = dev->ieee80211_ptr;
1170 1160
@@ -1172,7 +1162,6 @@ int cfg80211_wext_giwpower(struct net_device *dev,
1172 1162
1173 return 0; 1163 return 0;
1174} 1164}
1175EXPORT_SYMBOL_GPL(cfg80211_wext_giwpower);
1176 1165
1177static int cfg80211_wds_wext_siwap(struct net_device *dev, 1166static int cfg80211_wds_wext_siwap(struct net_device *dev,
1178 struct iw_request_info *info, 1167 struct iw_request_info *info,
@@ -1218,9 +1207,9 @@ static int cfg80211_wds_wext_giwap(struct net_device *dev,
1218 return 0; 1207 return 0;
1219} 1208}
1220 1209
1221int cfg80211_wext_siwrate(struct net_device *dev, 1210static int cfg80211_wext_siwrate(struct net_device *dev,
1222 struct iw_request_info *info, 1211 struct iw_request_info *info,
1223 struct iw_param *rate, char *extra) 1212 struct iw_param *rate, char *extra)
1224{ 1213{
1225 struct wireless_dev *wdev = dev->ieee80211_ptr; 1214 struct wireless_dev *wdev = dev->ieee80211_ptr;
1226 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1215 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1268,11 +1257,10 @@ int cfg80211_wext_siwrate(struct net_device *dev,
1268 1257
1269 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); 1258 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask);
1270} 1259}
1271EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);
1272 1260
1273int cfg80211_wext_giwrate(struct net_device *dev, 1261static int cfg80211_wext_giwrate(struct net_device *dev,
1274 struct iw_request_info *info, 1262 struct iw_request_info *info,
1275 struct iw_param *rate, char *extra) 1263 struct iw_param *rate, char *extra)
1276{ 1264{
1277 struct wireless_dev *wdev = dev->ieee80211_ptr; 1265 struct wireless_dev *wdev = dev->ieee80211_ptr;
1278 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1266 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1308,10 +1296,9 @@ int cfg80211_wext_giwrate(struct net_device *dev,
1308 1296
1309 return 0; 1297 return 0;
1310} 1298}
1311EXPORT_SYMBOL_GPL(cfg80211_wext_giwrate);
1312 1299
1313/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */ 1300/* Get wireless statistics. Called by /proc/net/wireless and by SIOCGIWSTATS */
1314struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev) 1301static struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1315{ 1302{
1316 struct wireless_dev *wdev = dev->ieee80211_ptr; 1303 struct wireless_dev *wdev = dev->ieee80211_ptr;
1317 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1304 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1376,11 +1363,10 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1376 1363
1377 return &wstats; 1364 return &wstats;
1378} 1365}
1379EXPORT_SYMBOL_GPL(cfg80211_wireless_stats);
1380 1366
1381int cfg80211_wext_siwap(struct net_device *dev, 1367static int cfg80211_wext_siwap(struct net_device *dev,
1382 struct iw_request_info *info, 1368 struct iw_request_info *info,
1383 struct sockaddr *ap_addr, char *extra) 1369 struct sockaddr *ap_addr, char *extra)
1384{ 1370{
1385 struct wireless_dev *wdev = dev->ieee80211_ptr; 1371 struct wireless_dev *wdev = dev->ieee80211_ptr;
1386 1372
@@ -1395,11 +1381,10 @@ int cfg80211_wext_siwap(struct net_device *dev,
1395 return -EOPNOTSUPP; 1381 return -EOPNOTSUPP;
1396 } 1382 }
1397} 1383}
1398EXPORT_SYMBOL_GPL(cfg80211_wext_siwap);
1399 1384
1400int cfg80211_wext_giwap(struct net_device *dev, 1385static int cfg80211_wext_giwap(struct net_device *dev,
1401 struct iw_request_info *info, 1386 struct iw_request_info *info,
1402 struct sockaddr *ap_addr, char *extra) 1387 struct sockaddr *ap_addr, char *extra)
1403{ 1388{
1404 struct wireless_dev *wdev = dev->ieee80211_ptr; 1389 struct wireless_dev *wdev = dev->ieee80211_ptr;
1405 1390
@@ -1414,11 +1399,10 @@ int cfg80211_wext_giwap(struct net_device *dev,
1414 return -EOPNOTSUPP; 1399 return -EOPNOTSUPP;
1415 } 1400 }
1416} 1401}
1417EXPORT_SYMBOL_GPL(cfg80211_wext_giwap);
1418 1402
1419int cfg80211_wext_siwessid(struct net_device *dev, 1403static int cfg80211_wext_siwessid(struct net_device *dev,
1420 struct iw_request_info *info, 1404 struct iw_request_info *info,
1421 struct iw_point *data, char *ssid) 1405 struct iw_point *data, char *ssid)
1422{ 1406{
1423 struct wireless_dev *wdev = dev->ieee80211_ptr; 1407 struct wireless_dev *wdev = dev->ieee80211_ptr;
1424 1408
@@ -1431,11 +1415,10 @@ int cfg80211_wext_siwessid(struct net_device *dev,
1431 return -EOPNOTSUPP; 1415 return -EOPNOTSUPP;
1432 } 1416 }
1433} 1417}
1434EXPORT_SYMBOL_GPL(cfg80211_wext_siwessid);
1435 1418
1436int cfg80211_wext_giwessid(struct net_device *dev, 1419static int cfg80211_wext_giwessid(struct net_device *dev,
1437 struct iw_request_info *info, 1420 struct iw_request_info *info,
1438 struct iw_point *data, char *ssid) 1421 struct iw_point *data, char *ssid)
1439{ 1422{
1440 struct wireless_dev *wdev = dev->ieee80211_ptr; 1423 struct wireless_dev *wdev = dev->ieee80211_ptr;
1441 1424
@@ -1451,11 +1434,10 @@ int cfg80211_wext_giwessid(struct net_device *dev,
1451 return -EOPNOTSUPP; 1434 return -EOPNOTSUPP;
1452 } 1435 }
1453} 1436}
1454EXPORT_SYMBOL_GPL(cfg80211_wext_giwessid);
1455 1437
1456int cfg80211_wext_siwpmksa(struct net_device *dev, 1438static int cfg80211_wext_siwpmksa(struct net_device *dev,
1457 struct iw_request_info *info, 1439 struct iw_request_info *info,
1458 struct iw_point *data, char *extra) 1440 struct iw_point *data, char *extra)
1459{ 1441{
1460 struct wireless_dev *wdev = dev->ieee80211_ptr; 1442 struct wireless_dev *wdev = dev->ieee80211_ptr;
1461 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1443 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
@@ -1493,7 +1475,6 @@ int cfg80211_wext_siwpmksa(struct net_device *dev,
1493 return -EOPNOTSUPP; 1475 return -EOPNOTSUPP;
1494 } 1476 }
1495} 1477}
1496EXPORT_SYMBOL_GPL(cfg80211_wext_siwpmksa);
1497 1478
1498static const iw_handler cfg80211_handlers[] = { 1479static const iw_handler cfg80211_handlers[] = {
1499 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname, 1480 [IW_IOCTL_IDX(SIOCGIWNAME)] = (iw_handler) cfg80211_wext_giwname,
diff --git a/net/wireless/wext-compat.h b/net/wireless/wext-compat.h
index 20b3daef6964..5d766b0118e8 100644
--- a/net/wireless/wext-compat.h
+++ b/net/wireless/wext-compat.h
@@ -42,6 +42,14 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
42 struct iw_request_info *info, 42 struct iw_request_info *info,
43 struct iw_point *data, char *ssid); 43 struct iw_point *data, char *ssid);
44 44
45int cfg80211_wext_siwmlme(struct net_device *dev,
46 struct iw_request_info *info,
47 struct iw_point *data, char *extra);
48int cfg80211_wext_siwgenie(struct net_device *dev,
49 struct iw_request_info *info,
50 struct iw_point *data, char *extra);
51
52
45int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq); 53int cfg80211_wext_freq(struct wiphy *wiphy, struct iw_freq *freq);
46 54
47 55
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 6fffe62d7c25..0d4b8c3033ff 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -9,6 +9,7 @@
9#include <linux/if_arp.h> 9#include <linux/if_arp.h>
10#include <linux/slab.h> 10#include <linux/slab.h>
11#include <net/cfg80211.h> 11#include <net/cfg80211.h>
12#include <net/cfg80211-wext.h>
12#include "wext-compat.h" 13#include "wext-compat.h"
13#include "nl80211.h" 14#include "nl80211.h"
14 15
@@ -365,7 +366,6 @@ int cfg80211_wext_siwgenie(struct net_device *dev,
365 wdev_unlock(wdev); 366 wdev_unlock(wdev);
366 return err; 367 return err;
367} 368}
368EXPORT_SYMBOL_GPL(cfg80211_wext_siwgenie);
369 369
370int cfg80211_wext_siwmlme(struct net_device *dev, 370int cfg80211_wext_siwmlme(struct net_device *dev,
371 struct iw_request_info *info, 371 struct iw_request_info *info,
@@ -402,4 +402,3 @@ int cfg80211_wext_siwmlme(struct net_device *dev,
402 402
403 return err; 403 return err;
404} 404}
405EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);