aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-29 17:02:13 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 17:02:13 -0400
commit143b11c03cd42f2284efe5128afc057d8fc86c78 (patch)
tree8186830c461b7933c26cdd00b69e4c737c5c88e7 /net
parentaf01d537463714e36e2c96d2da35902b76cd6827 (diff)
parent18c8adeb0244f823ba78a51e23f813fe68bc3c54 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c42
-rw-r--r--net/mac80211/ieee80211_i.h18
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/mlme.c230
-rw-r--r--net/mac80211/wme.c2
-rw-r--r--net/rfkill/rfkill.c104
-rw-r--r--net/wireless/nl80211.c62
7 files changed, 267 insertions, 196 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6d2ad2bf3ab5..928813ce08e2 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -674,6 +674,11 @@ static void sta_apply_parameters(struct ieee80211_local *local,
674 sta->supp_rates[local->oper_channel->band] = rates; 674 sta->supp_rates[local->oper_channel->band] = rates;
675 } 675 }
676 676
677 if (params->ht_capa) {
678 ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
679 &sta->ht_info);
680 }
681
677 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 682 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
678 switch (params->plink_action) { 683 switch (params->plink_action) {
679 case PLINK_ACTION_OPEN: 684 case PLINK_ACTION_OPEN:
@@ -1010,6 +1015,42 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1010} 1015}
1011#endif 1016#endif
1012 1017
1018static int ieee80211_change_bss(struct wiphy *wiphy,
1019 struct net_device *dev,
1020 struct bss_parameters *params)
1021{
1022 struct ieee80211_local *local = wiphy_priv(wiphy);
1023 struct ieee80211_sub_if_data *sdata;
1024 u32 changed = 0;
1025
1026 if (dev == local->mdev)
1027 return -EOPNOTSUPP;
1028
1029 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1030
1031 if (sdata->vif.type != IEEE80211_IF_TYPE_AP)
1032 return -EINVAL;
1033
1034 if (params->use_cts_prot >= 0) {
1035 sdata->bss_conf.use_cts_prot = params->use_cts_prot;
1036 changed |= BSS_CHANGED_ERP_CTS_PROT;
1037 }
1038 if (params->use_short_preamble >= 0) {
1039 sdata->bss_conf.use_short_preamble =
1040 params->use_short_preamble;
1041 changed |= BSS_CHANGED_ERP_PREAMBLE;
1042 }
1043 if (params->use_short_slot_time >= 0) {
1044 sdata->bss_conf.use_short_slot =
1045 params->use_short_slot_time;
1046 changed |= BSS_CHANGED_ERP_SLOT;
1047 }
1048
1049 ieee80211_bss_info_change_notify(sdata, changed);
1050
1051 return 0;
1052}
1053
1013struct cfg80211_ops mac80211_config_ops = { 1054struct cfg80211_ops mac80211_config_ops = {
1014 .add_virtual_intf = ieee80211_add_iface, 1055 .add_virtual_intf = ieee80211_add_iface,
1015 .del_virtual_intf = ieee80211_del_iface, 1056 .del_virtual_intf = ieee80211_del_iface,
@@ -1033,4 +1074,5 @@ struct cfg80211_ops mac80211_config_ops = {
1033 .get_mpath = ieee80211_get_mpath, 1074 .get_mpath = ieee80211_get_mpath,
1034 .dump_mpath = ieee80211_dump_mpath, 1075 .dump_mpath = ieee80211_dump_mpath,
1035#endif 1076#endif
1077 .change_bss = ieee80211_change_bss,
1036}; 1078};
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 8361054fb7cf..2bb546744b94 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -79,16 +79,11 @@ struct ieee80211_sta_bss {
79 enum ieee80211_band band; 79 enum ieee80211_band band;
80 int freq; 80 int freq;
81 int signal, noise, qual; 81 int signal, noise, qual;
82 u8 *wpa_ie; 82 u8 *ies; /* all information elements from the last Beacon or Probe
83 size_t wpa_ie_len; 83 * Response frames; note Beacon frame is not allowed to
84 u8 *rsn_ie; 84 * override values from Probe Response */
85 size_t rsn_ie_len; 85 size_t ies_len;
86 u8 *wmm_ie; 86 bool wmm_used;
87 size_t wmm_ie_len;
88 u8 *ht_ie;
89 size_t ht_ie_len;
90 u8 *ht_add_ie;
91 size_t ht_add_ie_len;
92#ifdef CONFIG_MAC80211_MESH 87#ifdef CONFIG_MAC80211_MESH
93 u8 *mesh_id; 88 u8 *mesh_id;
94 size_t mesh_id_len; 89 size_t mesh_id_len;
@@ -773,6 +768,9 @@ struct ieee80211_ra_tid {
773 768
774/* Parsed Information Elements */ 769/* Parsed Information Elements */
775struct ieee802_11_elems { 770struct ieee802_11_elems {
771 u8 *ie_start;
772 size_t total_len;
773
776 /* pointers to IEs */ 774 /* pointers to IEs */
777 u8 *ssid; 775 u8 *ssid;
778 u8 *supp_rates; 776 u8 *supp_rates;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 398ca66bdfcb..638b75f36e23 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -598,7 +598,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
598 struct ieee80211_local *local = hw_to_local(hw); 598 struct ieee80211_local *local = hw_to_local(hw);
599 struct sta_info *sta; 599 struct sta_info *sta;
600 struct ieee80211_sub_if_data *sdata; 600 struct ieee80211_sub_if_data *sdata;
601 u16 start_seq_num = 0; 601 u16 start_seq_num;
602 u8 *state; 602 u8 *state;
603 int ret; 603 int ret;
604 DECLARE_MAC_BUF(mac); 604 DECLARE_MAC_BUF(mac);
@@ -678,6 +678,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
678 * call back right away, it must see that the flow has begun */ 678 * call back right away, it must see that the flow has begun */
679 *state |= HT_ADDBA_REQUESTED_MSK; 679 *state |= HT_ADDBA_REQUESTED_MSK;
680 680
681 /* This is slightly racy because the queue isn't stopped */
682 start_seq_num = sta->tid_seq[tid];
683
681 if (local->ops->ampdu_action) 684 if (local->ops->ampdu_action)
682 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START, 685 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
683 ra, tid, &start_seq_num); 686 ra, tid, &start_seq_num);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 84999791a332..e088b440aafa 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -98,6 +98,8 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
98 u8 *pos = start; 98 u8 *pos = start;
99 99
100 memset(elems, 0, sizeof(*elems)); 100 memset(elems, 0, sizeof(*elems));
101 elems->ie_start = start;
102 elems->total_len = len;
101 103
102 while (left >= 2) { 104 while (left >= 2) {
103 u8 id, elen; 105 u8 id, elen;
@@ -234,6 +236,27 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
234} 236}
235 237
236 238
239static u8 * ieee80211_bss_get_ie(struct ieee80211_sta_bss *bss, u8 ie)
240{
241 u8 *end, *pos;
242
243 pos = bss->ies;
244 if (pos == NULL)
245 return NULL;
246 end = pos + bss->ies_len;
247
248 while (pos + 1 < end) {
249 if (pos + 2 + pos[1] > end)
250 break;
251 if (pos[0] == ie)
252 return pos;
253 pos += 2 + pos[1];
254 }
255
256 return NULL;
257}
258
259
237static int ecw2cw(int ecw) 260static int ecw2cw(int ecw)
238{ 261{
239 return (1 << ecw) - 1; 262 return (1 << ecw) - 1;
@@ -737,7 +760,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
737 struct ieee80211_local *local = sdata->local; 760 struct ieee80211_local *local = sdata->local;
738 struct sk_buff *skb; 761 struct sk_buff *skb;
739 struct ieee80211_mgmt *mgmt; 762 struct ieee80211_mgmt *mgmt;
740 u8 *pos, *ies; 763 u8 *pos, *ies, *ht_add_ie;
741 int i, len, count, rates_len, supp_rates_len; 764 int i, len, count, rates_len, supp_rates_len;
742 u16 capab; 765 u16 capab;
743 struct ieee80211_sta_bss *bss; 766 struct ieee80211_sta_bss *bss;
@@ -772,7 +795,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
772 if (bss) { 795 if (bss) {
773 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 796 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
774 capab |= WLAN_CAPABILITY_PRIVACY; 797 capab |= WLAN_CAPABILITY_PRIVACY;
775 if (bss->wmm_ie) 798 if (bss->wmm_used)
776 wmm = 1; 799 wmm = 1;
777 800
778 /* get all rates supported by the device and the AP as 801 /* get all rates supported by the device and the AP as
@@ -894,9 +917,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
894 917
895 /* wmm support is a must to HT */ 918 /* wmm support is a must to HT */
896 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && 919 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
897 sband->ht_info.ht_supported && bss->ht_add_ie) { 920 sband->ht_info.ht_supported &&
921 (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
898 struct ieee80211_ht_addt_info *ht_add_info = 922 struct ieee80211_ht_addt_info *ht_add_info =
899 (struct ieee80211_ht_addt_info *)bss->ht_add_ie; 923 (struct ieee80211_ht_addt_info *)ht_add_ie;
900 u16 cap = sband->ht_info.cap; 924 u16 cap = sband->ht_info.cap;
901 __le16 tmp; 925 __le16 tmp;
902 u32 flags = local->hw.conf.channel->flags; 926 u32 flags = local->hw.conf.channel->flags;
@@ -2372,11 +2396,7 @@ ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_i
2372 2396
2373static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) 2397static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
2374{ 2398{
2375 kfree(bss->wpa_ie); 2399 kfree(bss->ies);
2376 kfree(bss->rsn_ie);
2377 kfree(bss->wmm_ie);
2378 kfree(bss->ht_ie);
2379 kfree(bss->ht_add_ie);
2380 kfree(bss_mesh_id(bss)); 2400 kfree(bss_mesh_id(bss));
2381 kfree(bss_mesh_cfg(bss)); 2401 kfree(bss_mesh_cfg(bss));
2382 kfree(bss); 2402 kfree(bss);
@@ -2662,43 +2682,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2662 bss->has_erp_value = 1; 2682 bss->has_erp_value = 1;
2663 } 2683 }
2664 2684
2665 if (elems->ht_cap_elem &&
2666 (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len ||
2667 memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) {
2668 kfree(bss->ht_ie);
2669 bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC);
2670 if (bss->ht_ie) {
2671 memcpy(bss->ht_ie, elems->ht_cap_elem - 2,
2672 elems->ht_cap_elem_len + 2);
2673 bss->ht_ie_len = elems->ht_cap_elem_len + 2;
2674 } else
2675 bss->ht_ie_len = 0;
2676 } else if (!elems->ht_cap_elem && bss->ht_ie) {
2677 kfree(bss->ht_ie);
2678 bss->ht_ie = NULL;
2679 bss->ht_ie_len = 0;
2680 }
2681
2682 if (elems->ht_info_elem &&
2683 (!bss->ht_add_ie ||
2684 bss->ht_add_ie_len != elems->ht_info_elem_len ||
2685 memcmp(bss->ht_add_ie, elems->ht_info_elem,
2686 elems->ht_info_elem_len))) {
2687 kfree(bss->ht_add_ie);
2688 bss->ht_add_ie =
2689 kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC);
2690 if (bss->ht_add_ie) {
2691 memcpy(bss->ht_add_ie, elems->ht_info_elem - 2,
2692 elems->ht_info_elem_len + 2);
2693 bss->ht_add_ie_len = elems->ht_info_elem_len + 2;
2694 } else
2695 bss->ht_add_ie_len = 0;
2696 } else if (!elems->ht_info_elem && bss->ht_add_ie) {
2697 kfree(bss->ht_add_ie);
2698 bss->ht_add_ie = NULL;
2699 bss->ht_add_ie_len = 0;
2700 }
2701
2702 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); 2685 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
2703 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); 2686 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
2704 2687
@@ -2749,88 +2732,17 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2749 return; 2732 return;
2750 } 2733 }
2751 2734
2752 if (elems->wpa && 2735 if (bss->ies == NULL || bss->ies_len < elems->total_len) {
2753 (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len || 2736 kfree(bss->ies);
2754 memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) { 2737 bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
2755 kfree(bss->wpa_ie);
2756 bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC);
2757 if (bss->wpa_ie) {
2758 memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2);
2759 bss->wpa_ie_len = elems->wpa_len + 2;
2760 } else
2761 bss->wpa_ie_len = 0;
2762 } else if (!elems->wpa && bss->wpa_ie) {
2763 kfree(bss->wpa_ie);
2764 bss->wpa_ie = NULL;
2765 bss->wpa_ie_len = 0;
2766 }
2767
2768 if (elems->rsn &&
2769 (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len ||
2770 memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) {
2771 kfree(bss->rsn_ie);
2772 bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC);
2773 if (bss->rsn_ie) {
2774 memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2);
2775 bss->rsn_ie_len = elems->rsn_len + 2;
2776 } else
2777 bss->rsn_ie_len = 0;
2778 } else if (!elems->rsn && bss->rsn_ie) {
2779 kfree(bss->rsn_ie);
2780 bss->rsn_ie = NULL;
2781 bss->rsn_ie_len = 0;
2782 } 2738 }
2739 if (bss->ies) {
2740 memcpy(bss->ies, elems->ie_start, elems->total_len);
2741 bss->ies_len = elems->total_len;
2742 } else
2743 bss->ies_len = 0;
2783 2744
2784 /* 2745 bss->wmm_used = elems->wmm_param || elems->wmm_info;
2785 * Cf.
2786 * http://www.wipo.int/pctdb/en/wo.jsp?wo=2007047181&IA=WO2007047181&DISPLAY=DESC
2787 *
2788 * quoting:
2789 *
2790 * In particular, "Wi-Fi CERTIFIED for WMM - Support for Multimedia
2791 * Applications with Quality of Service in Wi-Fi Networks," Wi- Fi
2792 * Alliance (September 1, 2004) is incorporated by reference herein.
2793 * The inclusion of the WMM Parameters in probe responses and
2794 * association responses is mandatory for WMM enabled networks. The
2795 * inclusion of the WMM Parameters in beacons, however, is optional.
2796 */
2797
2798 if (elems->wmm_param &&
2799 (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len ||
2800 memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) {
2801 kfree(bss->wmm_ie);
2802 bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC);
2803 if (bss->wmm_ie) {
2804 memcpy(bss->wmm_ie, elems->wmm_param - 2,
2805 elems->wmm_param_len + 2);
2806 bss->wmm_ie_len = elems->wmm_param_len + 2;
2807 } else
2808 bss->wmm_ie_len = 0;
2809 } else if (elems->wmm_info &&
2810 (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len ||
2811 memcmp(bss->wmm_ie, elems->wmm_info,
2812 elems->wmm_info_len))) {
2813 /* As for certain AP's Fifth bit is not set in WMM IE in
2814 * beacon frames.So while parsing the beacon frame the
2815 * wmm_info structure is used instead of wmm_param.
2816 * wmm_info structure was never used to set bss->wmm_ie.
2817 * This code fixes this problem by copying the WME
2818 * information from wmm_info to bss->wmm_ie and enabling
2819 * n-band association.
2820 */
2821 kfree(bss->wmm_ie);
2822 bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC);
2823 if (bss->wmm_ie) {
2824 memcpy(bss->wmm_ie, elems->wmm_info - 2,
2825 elems->wmm_info_len + 2);
2826 bss->wmm_ie_len = elems->wmm_info_len + 2;
2827 } else
2828 bss->wmm_ie_len = 0;
2829 } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) {
2830 kfree(bss->wmm_ie);
2831 bss->wmm_ie = NULL;
2832 bss->wmm_ie_len = 0;
2833 }
2834 2746
2835 /* check if we need to merge IBSS */ 2747 /* check if we need to merge IBSS */
2836 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon && 2748 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon &&
@@ -4146,6 +4058,48 @@ int ieee80211_sta_req_scan(struct ieee80211_sub_if_data *sdata, u8 *ssid, size_t
4146 return 0; 4058 return 0;
4147} 4059}
4148 4060
4061
4062static void ieee80211_sta_add_scan_ies(struct iw_request_info *info,
4063 struct ieee80211_sta_bss *bss,
4064 char **current_ev, char *end_buf)
4065{
4066 u8 *pos, *end, *next;
4067 struct iw_event iwe;
4068
4069 if (bss == NULL || bss->ies == NULL)
4070 return;
4071
4072 /*
4073 * If needed, fragment the IEs buffer (at IE boundaries) into short
4074 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
4075 */
4076 pos = bss->ies;
4077 end = pos + bss->ies_len;
4078
4079 while (end - pos > IW_GENERIC_IE_MAX) {
4080 next = pos + 2 + pos[1];
4081 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
4082 next = next + 2 + next[1];
4083
4084 memset(&iwe, 0, sizeof(iwe));
4085 iwe.cmd = IWEVGENIE;
4086 iwe.u.data.length = next - pos;
4087 *current_ev = iwe_stream_add_point(info, *current_ev,
4088 end_buf, &iwe, pos);
4089
4090 pos = next;
4091 }
4092
4093 if (end > pos) {
4094 memset(&iwe, 0, sizeof(iwe));
4095 iwe.cmd = IWEVGENIE;
4096 iwe.u.data.length = end - pos;
4097 *current_ev = iwe_stream_add_point(info, *current_ev,
4098 end_buf, &iwe, pos);
4099 }
4100}
4101
4102
4149static char * 4103static char *
4150ieee80211_sta_scan_result(struct ieee80211_local *local, 4104ieee80211_sta_scan_result(struct ieee80211_local *local,
4151 struct iw_request_info *info, 4105 struct iw_request_info *info,
@@ -4225,29 +4179,7 @@ ieee80211_sta_scan_result(struct ieee80211_local *local,
4225 current_ev = iwe_stream_add_point(info, current_ev, end_buf, 4179 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4226 &iwe, ""); 4180 &iwe, "");
4227 4181
4228 if (bss && bss->wpa_ie) { 4182 ieee80211_sta_add_scan_ies(info, bss, &current_ev, end_buf);
4229 memset(&iwe, 0, sizeof(iwe));
4230 iwe.cmd = IWEVGENIE;
4231 iwe.u.data.length = bss->wpa_ie_len;
4232 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4233 &iwe, bss->wpa_ie);
4234 }
4235
4236 if (bss && bss->rsn_ie) {
4237 memset(&iwe, 0, sizeof(iwe));
4238 iwe.cmd = IWEVGENIE;
4239 iwe.u.data.length = bss->rsn_ie_len;
4240 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4241 &iwe, bss->rsn_ie);
4242 }
4243
4244 if (bss && bss->ht_ie) {
4245 memset(&iwe, 0, sizeof(iwe));
4246 iwe.cmd = IWEVGENIE;
4247 iwe.u.data.length = bss->ht_ie_len;
4248 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4249 &iwe, bss->ht_ie);
4250 }
4251 4183
4252 if (bss && bss->supp_rates_len > 0) { 4184 if (bss && bss->supp_rates_len > 0) {
4253 /* display all supported rates in readable format */ 4185 /* display all supported rates in readable format */
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 4310e2f65661..7229e958879d 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -47,8 +47,6 @@ static unsigned int classify_1d(struct sk_buff *skb)
47 return 0; 47 return 0;
48 } 48 }
49 49
50 if (dscp & 0x1c)
51 return 0;
52 return dscp >> 5; 50 return dscp >> 5;
53} 51}
54 52
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 47e0b2d232e3..d5735799ccd9 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -37,7 +37,7 @@ MODULE_DESCRIPTION("RF switch support");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39static LIST_HEAD(rfkill_list); /* list of registered rf switches */ 39static LIST_HEAD(rfkill_list); /* list of registered rf switches */
40static DEFINE_MUTEX(rfkill_mutex); 40static DEFINE_MUTEX(rfkill_global_mutex);
41 41
42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED; 42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
43module_param_named(default_state, rfkill_default_state, uint, 0444); 43module_param_named(default_state, rfkill_default_state, uint, 0444);
@@ -76,6 +76,7 @@ static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
76 */ 76 */
77int register_rfkill_notifier(struct notifier_block *nb) 77int register_rfkill_notifier(struct notifier_block *nb)
78{ 78{
79 BUG_ON(!nb);
79 return blocking_notifier_chain_register(&rfkill_notifier_list, nb); 80 return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
80} 81}
81EXPORT_SYMBOL_GPL(register_rfkill_notifier); 82EXPORT_SYMBOL_GPL(register_rfkill_notifier);
@@ -91,6 +92,7 @@ EXPORT_SYMBOL_GPL(register_rfkill_notifier);
91 */ 92 */
92int unregister_rfkill_notifier(struct notifier_block *nb) 93int unregister_rfkill_notifier(struct notifier_block *nb)
93{ 94{
95 BUG_ON(!nb);
94 return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb); 96 return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
95} 97}
96EXPORT_SYMBOL_GPL(unregister_rfkill_notifier); 98EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
@@ -202,6 +204,9 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
202 * RFKILL_STATE_HARD_BLOCKED */ 204 * RFKILL_STATE_HARD_BLOCKED */
203 break; 205 break;
204 default: 206 default:
207 WARN(1, KERN_WARNING
208 "rfkill: illegal state %d passed as parameter "
209 "to rfkill_toggle_radio\n", state);
205 return -EINVAL; 210 return -EINVAL;
206 } 211 }
207 212
@@ -229,14 +234,18 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
229 * unless a specific switch is claimed by userspace (in which case, 234 * unless a specific switch is claimed by userspace (in which case,
230 * that switch is left alone) or suspended. 235 * that switch is left alone) or suspended.
231 * 236 *
232 * Caller must have acquired rfkill_mutex. 237 * Caller must have acquired rfkill_global_mutex.
233 */ 238 */
234static void __rfkill_switch_all(const enum rfkill_type type, 239static void __rfkill_switch_all(const enum rfkill_type type,
235 const enum rfkill_state state) 240 const enum rfkill_state state)
236{ 241{
237 struct rfkill *rfkill; 242 struct rfkill *rfkill;
238 243
239 if (unlikely(state >= RFKILL_STATE_MAX)) 244 if (WARN((state >= RFKILL_STATE_MAX || type >= RFKILL_TYPE_MAX),
245 KERN_WARNING
246 "rfkill: illegal state %d or type %d "
247 "passed as parameter to __rfkill_switch_all\n",
248 state, type))
240 return; 249 return;
241 250
242 rfkill_global_states[type].current_state = state; 251 rfkill_global_states[type].current_state = state;
@@ -254,14 +263,14 @@ static void __rfkill_switch_all(const enum rfkill_type type,
254 * @type: type of interfaces to be affected 263 * @type: type of interfaces to be affected
255 * @state: the new state 264 * @state: the new state
256 * 265 *
257 * Acquires rfkill_mutex and calls __rfkill_switch_all(@type, @state). 266 * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
258 * Please refer to __rfkill_switch_all() for details. 267 * Please refer to __rfkill_switch_all() for details.
259 */ 268 */
260void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) 269void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
261{ 270{
262 mutex_lock(&rfkill_mutex); 271 mutex_lock(&rfkill_global_mutex);
263 __rfkill_switch_all(type, state); 272 __rfkill_switch_all(type, state);
264 mutex_unlock(&rfkill_mutex); 273 mutex_unlock(&rfkill_global_mutex);
265} 274}
266EXPORT_SYMBOL(rfkill_switch_all); 275EXPORT_SYMBOL(rfkill_switch_all);
267 276
@@ -269,7 +278,7 @@ EXPORT_SYMBOL(rfkill_switch_all);
269 * rfkill_epo - emergency power off all transmitters 278 * rfkill_epo - emergency power off all transmitters
270 * 279 *
271 * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED, 280 * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
272 * ignoring everything in its path but rfkill_mutex and rfkill->mutex. 281 * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.
273 * 282 *
274 * The global state before the EPO is saved and can be restored later 283 * The global state before the EPO is saved and can be restored later
275 * using rfkill_restore_states(). 284 * using rfkill_restore_states().
@@ -279,7 +288,8 @@ void rfkill_epo(void)
279 struct rfkill *rfkill; 288 struct rfkill *rfkill;
280 int i; 289 int i;
281 290
282 mutex_lock(&rfkill_mutex); 291 mutex_lock(&rfkill_global_mutex);
292
283 list_for_each_entry(rfkill, &rfkill_list, node) { 293 list_for_each_entry(rfkill, &rfkill_list, node) {
284 mutex_lock(&rfkill->mutex); 294 mutex_lock(&rfkill->mutex);
285 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); 295 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
@@ -291,7 +301,7 @@ void rfkill_epo(void)
291 rfkill_global_states[i].current_state = 301 rfkill_global_states[i].current_state =
292 RFKILL_STATE_SOFT_BLOCKED; 302 RFKILL_STATE_SOFT_BLOCKED;
293 } 303 }
294 mutex_unlock(&rfkill_mutex); 304 mutex_unlock(&rfkill_global_mutex);
295} 305}
296EXPORT_SYMBOL_GPL(rfkill_epo); 306EXPORT_SYMBOL_GPL(rfkill_epo);
297 307
@@ -306,10 +316,11 @@ void rfkill_restore_states(void)
306{ 316{
307 int i; 317 int i;
308 318
309 mutex_lock(&rfkill_mutex); 319 mutex_lock(&rfkill_global_mutex);
320
310 for (i = 0; i < RFKILL_TYPE_MAX; i++) 321 for (i = 0; i < RFKILL_TYPE_MAX; i++)
311 __rfkill_switch_all(i, rfkill_global_states[i].default_state); 322 __rfkill_switch_all(i, rfkill_global_states[i].default_state);
312 mutex_unlock(&rfkill_mutex); 323 mutex_unlock(&rfkill_global_mutex);
313} 324}
314EXPORT_SYMBOL_GPL(rfkill_restore_states); 325EXPORT_SYMBOL_GPL(rfkill_restore_states);
315 326
@@ -334,7 +345,11 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
334{ 345{
335 enum rfkill_state oldstate; 346 enum rfkill_state oldstate;
336 347
337 if (unlikely(state >= RFKILL_STATE_MAX)) 348 BUG_ON(!rfkill);
349 if (WARN((state >= RFKILL_STATE_MAX),
350 KERN_WARNING
351 "rfkill: illegal state %d passed as parameter "
352 "to rfkill_force_state\n", state))
338 return -EINVAL; 353 return -EINVAL;
339 354
340 mutex_lock(&rfkill->mutex); 355 mutex_lock(&rfkill->mutex);
@@ -402,12 +417,16 @@ static ssize_t rfkill_state_store(struct device *dev,
402 const char *buf, size_t count) 417 const char *buf, size_t count)
403{ 418{
404 struct rfkill *rfkill = to_rfkill(dev); 419 struct rfkill *rfkill = to_rfkill(dev);
405 unsigned int state = simple_strtoul(buf, NULL, 0); 420 unsigned long state;
406 int error; 421 int error;
407 422
408 if (!capable(CAP_NET_ADMIN)) 423 if (!capable(CAP_NET_ADMIN))
409 return -EPERM; 424 return -EPERM;
410 425
426 error = strict_strtoul(buf, 0, &state);
427 if (error)
428 return error;
429
411 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */ 430 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
412 if (state != RFKILL_STATE_UNBLOCKED && 431 if (state != RFKILL_STATE_UNBLOCKED &&
413 state != RFKILL_STATE_SOFT_BLOCKED) 432 state != RFKILL_STATE_SOFT_BLOCKED)
@@ -427,7 +446,7 @@ static ssize_t rfkill_claim_show(struct device *dev,
427{ 446{
428 struct rfkill *rfkill = to_rfkill(dev); 447 struct rfkill *rfkill = to_rfkill(dev);
429 448
430 return sprintf(buf, "%d", rfkill->user_claim); 449 return sprintf(buf, "%d\n", rfkill->user_claim);
431} 450}
432 451
433static ssize_t rfkill_claim_store(struct device *dev, 452static ssize_t rfkill_claim_store(struct device *dev,
@@ -435,7 +454,8 @@ static ssize_t rfkill_claim_store(struct device *dev,
435 const char *buf, size_t count) 454 const char *buf, size_t count)
436{ 455{
437 struct rfkill *rfkill = to_rfkill(dev); 456 struct rfkill *rfkill = to_rfkill(dev);
438 bool claim = !!simple_strtoul(buf, NULL, 0); 457 unsigned long claim_tmp;
458 bool claim;
439 int error; 459 int error;
440 460
441 if (!capable(CAP_NET_ADMIN)) 461 if (!capable(CAP_NET_ADMIN))
@@ -444,11 +464,16 @@ static ssize_t rfkill_claim_store(struct device *dev,
444 if (rfkill->user_claim_unsupported) 464 if (rfkill->user_claim_unsupported)
445 return -EOPNOTSUPP; 465 return -EOPNOTSUPP;
446 466
467 error = strict_strtoul(buf, 0, &claim_tmp);
468 if (error)
469 return error;
470 claim = !!claim_tmp;
471
447 /* 472 /*
448 * Take the global lock to make sure the kernel is not in 473 * Take the global lock to make sure the kernel is not in
449 * the middle of rfkill_switch_all 474 * the middle of rfkill_switch_all
450 */ 475 */
451 error = mutex_lock_interruptible(&rfkill_mutex); 476 error = mutex_lock_interruptible(&rfkill_global_mutex);
452 if (error) 477 if (error)
453 return error; 478 return error;
454 479
@@ -463,7 +488,7 @@ static ssize_t rfkill_claim_store(struct device *dev,
463 rfkill->user_claim = claim; 488 rfkill->user_claim = claim;
464 } 489 }
465 490
466 mutex_unlock(&rfkill_mutex); 491 mutex_unlock(&rfkill_global_mutex);
467 492
468 return error ? error : count; 493 return error ? error : count;
469} 494}
@@ -583,10 +608,10 @@ static int rfkill_check_duplicity(const struct rfkill *rfkill)
583 memset(seen, 0, sizeof(seen)); 608 memset(seen, 0, sizeof(seen));
584 609
585 list_for_each_entry(p, &rfkill_list, node) { 610 list_for_each_entry(p, &rfkill_list, node) {
586 if (p == rfkill) { 611 if (WARN((p == rfkill), KERN_WARNING
587 WARN_ON(1); 612 "rfkill: illegal attempt to register "
613 "an already registered rfkill struct\n"))
588 return -EEXIST; 614 return -EEXIST;
589 }
590 set_bit(p->type, seen); 615 set_bit(p->type, seen);
591 } 616 }
592 617
@@ -598,7 +623,7 @@ static int rfkill_add_switch(struct rfkill *rfkill)
598{ 623{
599 int error; 624 int error;
600 625
601 mutex_lock(&rfkill_mutex); 626 mutex_lock(&rfkill_global_mutex);
602 627
603 error = rfkill_check_duplicity(rfkill); 628 error = rfkill_check_duplicity(rfkill);
604 if (error < 0) 629 if (error < 0)
@@ -619,16 +644,16 @@ static int rfkill_add_switch(struct rfkill *rfkill)
619 644
620 error = 0; 645 error = 0;
621unlock_out: 646unlock_out:
622 mutex_unlock(&rfkill_mutex); 647 mutex_unlock(&rfkill_global_mutex);
623 648
624 return error; 649 return error;
625} 650}
626 651
627static void rfkill_remove_switch(struct rfkill *rfkill) 652static void rfkill_remove_switch(struct rfkill *rfkill)
628{ 653{
629 mutex_lock(&rfkill_mutex); 654 mutex_lock(&rfkill_global_mutex);
630 list_del_init(&rfkill->node); 655 list_del_init(&rfkill->node);
631 mutex_unlock(&rfkill_mutex); 656 mutex_unlock(&rfkill_global_mutex);
632 657
633 mutex_lock(&rfkill->mutex); 658 mutex_lock(&rfkill->mutex);
634 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); 659 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
@@ -654,6 +679,12 @@ struct rfkill * __must_check rfkill_allocate(struct device *parent,
654 struct rfkill *rfkill; 679 struct rfkill *rfkill;
655 struct device *dev; 680 struct device *dev;
656 681
682 if (WARN((type >= RFKILL_TYPE_MAX),
683 KERN_WARNING
684 "rfkill: illegal type %d passed as parameter "
685 "to rfkill_allocate\n", type))
686 return NULL;
687
657 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL); 688 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
658 if (!rfkill) 689 if (!rfkill)
659 return NULL; 690 return NULL;
@@ -726,11 +757,12 @@ int __must_check rfkill_register(struct rfkill *rfkill)
726 struct device *dev = &rfkill->dev; 757 struct device *dev = &rfkill->dev;
727 int error; 758 int error;
728 759
729 if (!rfkill->toggle_radio) 760 if (WARN((!rfkill || !rfkill->toggle_radio ||
730 return -EINVAL; 761 rfkill->type >= RFKILL_TYPE_MAX ||
731 if (rfkill->type >= RFKILL_TYPE_MAX) 762 rfkill->state >= RFKILL_STATE_MAX),
732 return -EINVAL; 763 KERN_WARNING
733 if (rfkill->state >= RFKILL_STATE_MAX) 764 "rfkill: attempt to register a "
765 "badly initialized rfkill struct\n"))
734 return -EINVAL; 766 return -EINVAL;
735 767
736 snprintf(dev->bus_id, sizeof(dev->bus_id), 768 snprintf(dev->bus_id, sizeof(dev->bus_id),
@@ -765,6 +797,7 @@ EXPORT_SYMBOL(rfkill_register);
765 */ 797 */
766void rfkill_unregister(struct rfkill *rfkill) 798void rfkill_unregister(struct rfkill *rfkill)
767{ 799{
800 BUG_ON(!rfkill);
768 device_del(&rfkill->dev); 801 device_del(&rfkill->dev);
769 rfkill_remove_switch(rfkill); 802 rfkill_remove_switch(rfkill);
770 rfkill_led_trigger_unregister(rfkill); 803 rfkill_led_trigger_unregister(rfkill);
@@ -801,12 +834,15 @@ int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)
801{ 834{
802 int error; 835 int error;
803 836
804 if (type >= RFKILL_TYPE_MAX || 837 if (WARN((type >= RFKILL_TYPE_MAX ||
805 (state != RFKILL_STATE_SOFT_BLOCKED && 838 (state != RFKILL_STATE_SOFT_BLOCKED &&
806 state != RFKILL_STATE_UNBLOCKED)) 839 state != RFKILL_STATE_UNBLOCKED)),
840 KERN_WARNING
841 "rfkill: illegal state %d or type %d passed as "
842 "parameter to rfkill_set_default\n", state, type))
807 return -EINVAL; 843 return -EINVAL;
808 844
809 mutex_lock(&rfkill_mutex); 845 mutex_lock(&rfkill_global_mutex);
810 846
811 if (!test_and_set_bit(type, rfkill_states_lockdflt)) { 847 if (!test_and_set_bit(type, rfkill_states_lockdflt)) {
812 rfkill_global_states[type].default_state = state; 848 rfkill_global_states[type].default_state = state;
@@ -814,7 +850,7 @@ int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)
814 } else 850 } else
815 error = -EPERM; 851 error = -EPERM;
816 852
817 mutex_unlock(&rfkill_mutex); 853 mutex_unlock(&rfkill_global_mutex);
818 return error; 854 return error;
819} 855}
820EXPORT_SYMBOL_GPL(rfkill_set_default); 856EXPORT_SYMBOL_GPL(rfkill_set_default);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 59eb2cf42e5f..4d6c02afd6f5 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -87,6 +87,13 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
87 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, 87 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
88 .len = IEEE80211_MAX_MESH_ID_LEN }, 88 .len = IEEE80211_MAX_MESH_ID_LEN },
89 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, 89 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
90
91 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
92 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
93 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
94
95 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
96 .len = NL80211_HT_CAPABILITY_LEN },
90}; 97};
91 98
92/* message building helper */ 99/* message building helper */
@@ -1125,6 +1132,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1125 params.listen_interval = 1132 params.listen_interval =
1126 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1133 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1127 1134
1135 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1136 params.ht_capa =
1137 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1138
1128 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1139 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1129 &params.station_flags)) 1140 &params.station_flags))
1130 return -EINVAL; 1141 return -EINVAL;
@@ -1188,6 +1199,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1188 params.listen_interval = 1199 params.listen_interval =
1189 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1200 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1190 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 1201 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1202 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1203 params.ht_capa =
1204 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1191 1205
1192 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1206 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1193 &params.station_flags)) 1207 &params.station_flags))
@@ -1525,6 +1539,48 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1525 return err; 1539 return err;
1526} 1540}
1527 1541
1542static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1543{
1544 struct cfg80211_registered_device *drv;
1545 int err;
1546 struct net_device *dev;
1547 struct bss_parameters params;
1548
1549 memset(&params, 0, sizeof(params));
1550 /* default to not changing parameters */
1551 params.use_cts_prot = -1;
1552 params.use_short_preamble = -1;
1553 params.use_short_slot_time = -1;
1554
1555 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
1556 params.use_cts_prot =
1557 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
1558 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
1559 params.use_short_preamble =
1560 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
1561 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1562 params.use_short_slot_time =
1563 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1564
1565 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1566 if (err)
1567 return err;
1568
1569 if (!drv->ops->change_bss) {
1570 err = -EOPNOTSUPP;
1571 goto out;
1572 }
1573
1574 rtnl_lock();
1575 err = drv->ops->change_bss(&drv->wiphy, dev, &params);
1576 rtnl_unlock();
1577
1578 out:
1579 cfg80211_put_dev(drv);
1580 dev_put(dev);
1581 return err;
1582}
1583
1528static struct genl_ops nl80211_ops[] = { 1584static struct genl_ops nl80211_ops[] = {
1529 { 1585 {
1530 .cmd = NL80211_CMD_GET_WIPHY, 1586 .cmd = NL80211_CMD_GET_WIPHY,
@@ -1656,6 +1712,12 @@ static struct genl_ops nl80211_ops[] = {
1656 .policy = nl80211_policy, 1712 .policy = nl80211_policy,
1657 .flags = GENL_ADMIN_PERM, 1713 .flags = GENL_ADMIN_PERM,
1658 }, 1714 },
1715 {
1716 .cmd = NL80211_CMD_SET_BSS,
1717 .doit = nl80211_set_bss,
1718 .policy = nl80211_policy,
1719 .flags = GENL_ADMIN_PERM,
1720 },
1659}; 1721};
1660 1722
1661/* multicast groups */ 1723/* multicast groups */