diff options
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/agg-tx.c | 18 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 39 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 31 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 64 | ||||
-rw-r--r-- | net/mac80211/main.c | 1 | ||||
-rw-r--r-- | net/mac80211/mesh_hwmp.c | 7 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 8 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 1 | ||||
-rw-r--r-- | net/mac80211/status.c | 3 | ||||
-rw-r--r-- | net/mac80211/tx.c | 20 | ||||
-rw-r--r-- | net/mac80211/util.c | 168 |
11 files changed, 40 insertions, 320 deletions
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index c8be8eff70d..b7075f33dc0 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 86f8f49dae2..a589addf6ce 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 1425380983f..9001ff331f0 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 | ||
593 | static 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 | |||
611 | static 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 | |||
624 | static inline int drv_set_ringparam(struct ieee80211_local *local, | 593 | static 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 400c09bea63..ea741905084 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 */ | ||
1026 | struct 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 | |||
1088 | static inline struct ieee80211_local *hw_to_local( | 1024 | static 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 866f269183c..104fdd9862b 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 3460108810d..3d8e55ae6ab 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 66a1eeb279c..21588386a30 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 8b6ebee073e..0bdbf3b8f28 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 1658efaa2e8..a89cca3491b 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 8cb0d2d0ac6..69fd494f32f 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 ddeb1b99838..ce916ff6ef0 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 | ||
576 | u32 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 | |||
742 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) | 575 | void 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 | } |