aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ieee80211/ieee80211_wx.c48
-rw-r--r--net/mac80211/Kconfig2
-rw-r--r--net/mac80211/ieee80211_i.h14
-rw-r--r--net/mac80211/key.h37
-rw-r--r--net/mac80211/main.c2
-rw-r--r--net/mac80211/mlme.c207
-rw-r--r--net/mac80211/rx.c7
-rw-r--r--net/mac80211/sta_info.c1
-rw-r--r--net/mac80211/sta_info.h40
-rw-r--r--net/mac80211/tkip.c30
-rw-r--r--net/mac80211/tx.c204
-rw-r--r--net/mac80211/wep.c39
-rw-r--r--net/mac80211/wext.c50
-rw-r--r--net/mac80211/wpa.c20
-rw-r--r--net/rfkill/rfkill-input.c98
-rw-r--r--net/rfkill/rfkill-input.h1
-rw-r--r--net/rfkill/rfkill.c304
-rw-r--r--net/socket.c10
-rw-r--r--net/wireless/wext.c582
19 files changed, 1151 insertions, 545 deletions
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 822606b615ca..973832dd7faf 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -43,8 +43,9 @@ static const char *ieee80211_modes[] = {
43 43
44#define MAX_CUSTOM_LEN 64 44#define MAX_CUSTOM_LEN 64
45static char *ieee80211_translate_scan(struct ieee80211_device *ieee, 45static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
46 char *start, char *stop, 46 char *start, char *stop,
47 struct ieee80211_network *network) 47 struct ieee80211_network *network,
48 struct iw_request_info *info)
48{ 49{
49 char custom[MAX_CUSTOM_LEN]; 50 char custom[MAX_CUSTOM_LEN];
50 char *p; 51 char *p;
@@ -57,7 +58,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
57 iwe.cmd = SIOCGIWAP; 58 iwe.cmd = SIOCGIWAP;
58 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 59 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
59 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); 60 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
60 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); 61 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
61 62
62 /* Remaining entries will be displayed in the order we provide them */ 63 /* Remaining entries will be displayed in the order we provide them */
63 64
@@ -66,17 +67,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
66 iwe.u.data.flags = 1; 67 iwe.u.data.flags = 1;
67 if (network->flags & NETWORK_EMPTY_ESSID) { 68 if (network->flags & NETWORK_EMPTY_ESSID) {
68 iwe.u.data.length = sizeof("<hidden>"); 69 iwe.u.data.length = sizeof("<hidden>");
69 start = iwe_stream_add_point(start, stop, &iwe, "<hidden>"); 70 start = iwe_stream_add_point(info, start, stop,
71 &iwe, "<hidden>");
70 } else { 72 } else {
71 iwe.u.data.length = min(network->ssid_len, (u8) 32); 73 iwe.u.data.length = min(network->ssid_len, (u8) 32);
72 start = iwe_stream_add_point(start, stop, &iwe, network->ssid); 74 start = iwe_stream_add_point(info, start, stop,
75 &iwe, network->ssid);
73 } 76 }
74 77
75 /* Add the protocol name */ 78 /* Add the protocol name */
76 iwe.cmd = SIOCGIWNAME; 79 iwe.cmd = SIOCGIWNAME;
77 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", 80 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
78 ieee80211_modes[network->mode]); 81 ieee80211_modes[network->mode]);
79 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN); 82 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
80 83
81 /* Add mode */ 84 /* Add mode */
82 iwe.cmd = SIOCGIWMODE; 85 iwe.cmd = SIOCGIWMODE;
@@ -86,7 +89,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
86 else 89 else
87 iwe.u.mode = IW_MODE_ADHOC; 90 iwe.u.mode = IW_MODE_ADHOC;
88 91
89 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); 92 start = iwe_stream_add_event(info, start, stop,
93 &iwe, IW_EV_UINT_LEN);
90 } 94 }
91 95
92 /* Add channel and frequency */ 96 /* Add channel and frequency */
@@ -95,7 +99,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
95 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel); 99 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
96 iwe.u.freq.e = 6; 100 iwe.u.freq.e = 6;
97 iwe.u.freq.i = 0; 101 iwe.u.freq.i = 0;
98 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); 102 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
99 103
100 /* Add encryption capability */ 104 /* Add encryption capability */
101 iwe.cmd = SIOCGIWENCODE; 105 iwe.cmd = SIOCGIWENCODE;
@@ -104,12 +108,13 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
104 else 108 else
105 iwe.u.data.flags = IW_ENCODE_DISABLED; 109 iwe.u.data.flags = IW_ENCODE_DISABLED;
106 iwe.u.data.length = 0; 110 iwe.u.data.length = 0;
107 start = iwe_stream_add_point(start, stop, &iwe, network->ssid); 111 start = iwe_stream_add_point(info, start, stop,
112 &iwe, network->ssid);
108 113
109 /* Add basic and extended rates */ 114 /* Add basic and extended rates */
110 /* Rate : stuffing multiple values in a single event require a bit 115 /* Rate : stuffing multiple values in a single event require a bit
111 * more of magic - Jean II */ 116 * more of magic - Jean II */
112 current_val = start + IW_EV_LCP_LEN; 117 current_val = start + iwe_stream_lcp_len(info);
113 iwe.cmd = SIOCGIWRATE; 118 iwe.cmd = SIOCGIWRATE;
114 /* Those two flags are ignored... */ 119 /* Those two flags are ignored... */
115 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 120 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
@@ -124,17 +129,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
124 /* Bit rate given in 500 kb/s units (+ 0x80) */ 129 /* Bit rate given in 500 kb/s units (+ 0x80) */
125 iwe.u.bitrate.value = ((rate & 0x7f) * 500000); 130 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
126 /* Add new value to event */ 131 /* Add new value to event */
127 current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN); 132 current_val = iwe_stream_add_value(info, start, current_val,
133 stop, &iwe, IW_EV_PARAM_LEN);
128 } 134 }
129 for (; j < network->rates_ex_len; j++) { 135 for (; j < network->rates_ex_len; j++) {
130 rate = network->rates_ex[j] & 0x7F; 136 rate = network->rates_ex[j] & 0x7F;
131 /* Bit rate given in 500 kb/s units (+ 0x80) */ 137 /* Bit rate given in 500 kb/s units (+ 0x80) */
132 iwe.u.bitrate.value = ((rate & 0x7f) * 500000); 138 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
133 /* Add new value to event */ 139 /* Add new value to event */
134 current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN); 140 current_val = iwe_stream_add_value(info, start, current_val,
141 stop, &iwe, IW_EV_PARAM_LEN);
135 } 142 }
136 /* Check if we added any rate */ 143 /* Check if we added any rate */
137 if((current_val - start) > IW_EV_LCP_LEN) 144 if ((current_val - start) > iwe_stream_lcp_len(info))
138 start = current_val; 145 start = current_val;
139 146
140 /* Add quality statistics */ 147 /* Add quality statistics */
@@ -181,14 +188,14 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
181 iwe.u.qual.level = network->stats.signal; 188 iwe.u.qual.level = network->stats.signal;
182 } 189 }
183 190
184 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); 191 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
185 192
186 iwe.cmd = IWEVCUSTOM; 193 iwe.cmd = IWEVCUSTOM;
187 p = custom; 194 p = custom;
188 195
189 iwe.u.data.length = p - custom; 196 iwe.u.data.length = p - custom;
190 if (iwe.u.data.length) 197 if (iwe.u.data.length)
191 start = iwe_stream_add_point(start, stop, &iwe, custom); 198 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
192 199
193 memset(&iwe, 0, sizeof(iwe)); 200 memset(&iwe, 0, sizeof(iwe));
194 if (network->wpa_ie_len) { 201 if (network->wpa_ie_len) {
@@ -196,7 +203,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
196 memcpy(buf, network->wpa_ie, network->wpa_ie_len); 203 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
197 iwe.cmd = IWEVGENIE; 204 iwe.cmd = IWEVGENIE;
198 iwe.u.data.length = network->wpa_ie_len; 205 iwe.u.data.length = network->wpa_ie_len;
199 start = iwe_stream_add_point(start, stop, &iwe, buf); 206 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
200 } 207 }
201 208
202 memset(&iwe, 0, sizeof(iwe)); 209 memset(&iwe, 0, sizeof(iwe));
@@ -205,7 +212,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
205 memcpy(buf, network->rsn_ie, network->rsn_ie_len); 212 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
206 iwe.cmd = IWEVGENIE; 213 iwe.cmd = IWEVGENIE;
207 iwe.u.data.length = network->rsn_ie_len; 214 iwe.u.data.length = network->rsn_ie_len;
208 start = iwe_stream_add_point(start, stop, &iwe, buf); 215 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
209 } 216 }
210 217
211 /* Add EXTRA: Age to display seconds since last beacon/probe response 218 /* Add EXTRA: Age to display seconds since last beacon/probe response
@@ -217,7 +224,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
217 jiffies_to_msecs(jiffies - network->last_scanned)); 224 jiffies_to_msecs(jiffies - network->last_scanned));
218 iwe.u.data.length = p - custom; 225 iwe.u.data.length = p - custom;
219 if (iwe.u.data.length) 226 if (iwe.u.data.length)
220 start = iwe_stream_add_point(start, stop, &iwe, custom); 227 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
221 228
222 /* Add spectrum management information */ 229 /* Add spectrum management information */
223 iwe.cmd = -1; 230 iwe.cmd = -1;
@@ -238,7 +245,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
238 245
239 if (iwe.cmd == IWEVCUSTOM) { 246 if (iwe.cmd == IWEVCUSTOM) {
240 iwe.u.data.length = p - custom; 247 iwe.u.data.length = p - custom;
241 start = iwe_stream_add_point(start, stop, &iwe, custom); 248 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
242 } 249 }
243 250
244 return start; 251 return start;
@@ -272,7 +279,8 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
272 279
273 if (ieee->scan_age == 0 || 280 if (ieee->scan_age == 0 ||
274 time_after(network->last_scanned + ieee->scan_age, jiffies)) 281 time_after(network->last_scanned + ieee->scan_age, jiffies))
275 ev = ieee80211_translate_scan(ieee, ev, stop, network); 282 ev = ieee80211_translate_scan(ieee, ev, stop, network,
283 info);
276 else 284 else
277 IEEE80211_DEBUG_SCAN("Not showing network '%s (" 285 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
278 "%s)' due to age (%dms).\n", 286 "%s)' due to age (%dms).\n",
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 590e00b2766c..0d3661d9b6a0 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -150,7 +150,7 @@ config MAC80211_LOWTX_FRAME_DUMP
150 If unsure, say N and insert the debugging code 150 If unsure, say N and insert the debugging code
151 you require into the driver you are debugging. 151 you require into the driver you are debugging.
152 152
153config TKIP_DEBUG 153config MAC80211_TKIP_DEBUG
154 bool "TKIP debugging" 154 bool "TKIP debugging"
155 depends on MAC80211_DEBUG 155 depends on MAC80211_DEBUG
156 156
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 14fccf16b80f..af352c05c983 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -24,6 +24,7 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <net/wireless.h> 26#include <net/wireless.h>
27#include <net/iw_handler.h>
27#include "key.h" 28#include "key.h"
28#include "sta_info.h" 29#include "sta_info.h"
29 30
@@ -790,6 +791,10 @@ struct ieee802_11_elems {
790 u8 *preq; 791 u8 *preq;
791 u8 *prep; 792 u8 *prep;
792 u8 *perr; 793 u8 *perr;
794 u8 *ch_switch_elem;
795 u8 *country_elem;
796 u8 *pwr_constr_elem;
797 u8 *quiet_elem; /* first quite element */
793 798
794 /* length of them, respectively */ 799 /* length of them, respectively */
795 u8 ssid_len; 800 u8 ssid_len;
@@ -814,6 +819,11 @@ struct ieee802_11_elems {
814 u8 preq_len; 819 u8 preq_len;
815 u8 prep_len; 820 u8 prep_len;
816 u8 perr_len; 821 u8 perr_len;
822 u8 ch_switch_elem_len;
823 u8 country_elem_len;
824 u8 pwr_constr_elem_len;
825 u8 quiet_elem_len;
826 u8 num_of_quiet_elem; /* can be more the one */
817}; 827};
818 828
819static inline struct ieee80211_local *hw_to_local( 829static inline struct ieee80211_local *hw_to_local(
@@ -867,7 +877,9 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid);
867int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); 877int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
868void ieee80211_sta_req_auth(struct net_device *dev, 878void ieee80211_sta_req_auth(struct net_device *dev,
869 struct ieee80211_if_sta *ifsta); 879 struct ieee80211_if_sta *ifsta);
870int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len); 880int ieee80211_sta_scan_results(struct net_device *dev,
881 struct iw_request_info *info,
882 char *buf, size_t len);
871ieee80211_rx_result ieee80211_sta_rx_scan( 883ieee80211_rx_result ieee80211_sta_rx_scan(
872 struct net_device *dev, struct sk_buff *skb, 884 struct net_device *dev, struct sk_buff *skb,
873 struct ieee80211_rx_status *rx_status); 885 struct ieee80211_rx_status *rx_status);
diff --git a/net/mac80211/key.h b/net/mac80211/key.h
index a0f774aafa45..425816e0996c 100644
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -16,31 +16,18 @@
16#include <linux/rcupdate.h> 16#include <linux/rcupdate.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18 18
19/* ALG_TKIP 19#define WEP_IV_LEN 4
20 * struct ieee80211_key::key is encoded as a 256-bit (32 byte) data block: 20#define WEP_ICV_LEN 4
21 * Temporal Encryption Key (128 bits) 21#define ALG_TKIP_KEY_LEN 32
22 * Temporal Authenticator Tx MIC Key (64 bits) 22#define ALG_CCMP_KEY_LEN 16
23 * Temporal Authenticator Rx MIC Key (64 bits) 23#define CCMP_HDR_LEN 8
24 */ 24#define CCMP_MIC_LEN 8
25 25#define CCMP_TK_LEN 16
26#define WEP_IV_LEN 4 26#define CCMP_PN_LEN 6
27#define WEP_ICV_LEN 4 27#define TKIP_IV_LEN 8
28 28#define TKIP_ICV_LEN 4
29#define ALG_TKIP_KEY_LEN 32 29
30/* Starting offsets for each key */ 30#define NUM_RX_DATA_QUEUES 17
31#define ALG_TKIP_TEMP_ENCR_KEY 0
32#define ALG_TKIP_TEMP_AUTH_TX_MIC_KEY 16
33#define ALG_TKIP_TEMP_AUTH_RX_MIC_KEY 24
34#define TKIP_IV_LEN 8
35#define TKIP_ICV_LEN 4
36
37#define ALG_CCMP_KEY_LEN 16
38#define CCMP_HDR_LEN 8
39#define CCMP_MIC_LEN 8
40#define CCMP_TK_LEN 16
41#define CCMP_PN_LEN 6
42
43#define NUM_RX_DATA_QUEUES 17
44 31
45struct ieee80211_local; 32struct ieee80211_local;
46struct ieee80211_sub_if_data; 33struct ieee80211_sub_if_data;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5c5396edad32..b661ee5bb824 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1691,7 +1691,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1691 list_add_tail(&sdata->list, &local->interfaces); 1691 list_add_tail(&sdata->list, &local->interfaces);
1692 1692
1693 name = wiphy_dev(local->hw.wiphy)->driver->name; 1693 name = wiphy_dev(local->hw.wiphy)->driver->name;
1694 local->hw.workqueue = create_singlethread_workqueue(name); 1694 local->hw.workqueue = create_freezeable_workqueue(name);
1695 if (!local->hw.workqueue) { 1695 if (!local->hw.workqueue) {
1696 result = -ENOMEM; 1696 result = -ENOMEM;
1697 goto fail_workqueue; 1697 goto fail_workqueue;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 55659a730dc1..7b4d4d46843b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -204,6 +204,25 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
204 elems->perr = pos; 204 elems->perr = pos;
205 elems->perr_len = elen; 205 elems->perr_len = elen;
206 break; 206 break;
207 case WLAN_EID_CHANNEL_SWITCH:
208 elems->ch_switch_elem = pos;
209 elems->ch_switch_elem_len = elen;
210 break;
211 case WLAN_EID_QUIET:
212 if (!elems->quiet_elem) {
213 elems->quiet_elem = pos;
214 elems->quiet_elem_len = elen;
215 }
216 elems->num_of_quiet_elem++;
217 break;
218 case WLAN_EID_COUNTRY:
219 elems->country_elem = pos;
220 elems->country_elem_len = elen;
221 break;
222 case WLAN_EID_PWR_CONSTRAINT:
223 elems->pwr_constr_elem = pos;
224 elems->pwr_constr_elem_len = elen;
225 break;
207 default: 226 default:
208 break; 227 break;
209 } 228 }
@@ -1701,6 +1720,71 @@ void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr)
1701 } 1720 }
1702} 1721}
1703 1722
1723static void ieee80211_send_refuse_measurement_request(struct net_device *dev,
1724 struct ieee80211_msrment_ie *request_ie,
1725 const u8 *da, const u8 *bssid,
1726 u8 dialog_token)
1727{
1728 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1729 struct sk_buff *skb;
1730 struct ieee80211_mgmt *msr_report;
1731
1732 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
1733 sizeof(struct ieee80211_msrment_ie));
1734
1735 if (!skb) {
1736 printk(KERN_ERR "%s: failed to allocate buffer for "
1737 "measurement report frame\n", dev->name);
1738 return;
1739 }
1740
1741 skb_reserve(skb, local->hw.extra_tx_headroom);
1742 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
1743 memset(msr_report, 0, 24);
1744 memcpy(msr_report->da, da, ETH_ALEN);
1745 memcpy(msr_report->sa, dev->dev_addr, ETH_ALEN);
1746 memcpy(msr_report->bssid, bssid, ETH_ALEN);
1747 msr_report->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1748 IEEE80211_STYPE_ACTION);
1749
1750 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
1751 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
1752 msr_report->u.action.u.measurement.action_code =
1753 WLAN_ACTION_SPCT_MSR_RPRT;
1754 msr_report->u.action.u.measurement.dialog_token = dialog_token;
1755
1756 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
1757 msr_report->u.action.u.measurement.length =
1758 sizeof(struct ieee80211_msrment_ie);
1759
1760 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
1761 sizeof(struct ieee80211_msrment_ie));
1762 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
1763 msr_report->u.action.u.measurement.msr_elem.mode |=
1764 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
1765 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
1766
1767 ieee80211_sta_tx(dev, skb, 0);
1768}
1769
1770static void ieee80211_sta_process_measurement_req(struct net_device *dev,
1771 struct ieee80211_mgmt *mgmt,
1772 size_t len)
1773{
1774 /*
1775 * Ignoring measurement request is spec violation.
1776 * Mandatory measurements must be reported optional
1777 * measurements might be refused or reported incapable
1778 * For now just refuse
1779 * TODO: Answer basic measurement as unmeasured
1780 */
1781 ieee80211_send_refuse_measurement_request(dev,
1782 &mgmt->u.action.u.measurement.msr_elem,
1783 mgmt->sa, mgmt->bssid,
1784 mgmt->u.action.u.measurement.dialog_token);
1785}
1786
1787
1704static void ieee80211_rx_mgmt_auth(struct net_device *dev, 1788static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1705 struct ieee80211_if_sta *ifsta, 1789 struct ieee80211_if_sta *ifsta,
1706 struct ieee80211_mgmt *mgmt, 1790 struct ieee80211_mgmt *mgmt,
@@ -1753,11 +1837,12 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1753 auth_transaction, status_code); 1837 auth_transaction, status_code);
1754 1838
1755 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 1839 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
1756 /* IEEE 802.11 standard does not require authentication in IBSS 1840 /*
1841 * IEEE 802.11 standard does not require authentication in IBSS
1757 * networks and most implementations do not seem to use it. 1842 * networks and most implementations do not seem to use it.
1758 * However, try to reply to authentication attempts if someone 1843 * However, try to reply to authentication attempts if someone
1759 * has actually implemented this. 1844 * has actually implemented this.
1760 * TODO: Could implement shared key authentication. */ 1845 */
1761 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { 1846 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) {
1762 printk(KERN_DEBUG "%s: unexpected IBSS authentication " 1847 printk(KERN_DEBUG "%s: unexpected IBSS authentication "
1763 "frame (alg=%d transaction=%d)\n", 1848 "frame (alg=%d transaction=%d)\n",
@@ -3025,11 +3110,24 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev,
3025 struct ieee80211_rx_status *rx_status) 3110 struct ieee80211_rx_status *rx_status)
3026{ 3111{
3027 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 3112 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3113 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3028 3114
3029 if (len < IEEE80211_MIN_ACTION_SIZE) 3115 if (len < IEEE80211_MIN_ACTION_SIZE)
3030 return; 3116 return;
3031 3117
3032 switch (mgmt->u.action.category) { 3118 switch (mgmt->u.action.category) {
3119 case WLAN_CATEGORY_SPECTRUM_MGMT:
3120 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
3121 break;
3122 switch (mgmt->u.action.u.chan_switch.action_code) {
3123 case WLAN_ACTION_SPCT_MSR_REQ:
3124 if (len < (IEEE80211_MIN_ACTION_SIZE +
3125 sizeof(mgmt->u.action.u.measurement)))
3126 break;
3127 ieee80211_sta_process_measurement_req(dev, mgmt, len);
3128 break;
3129 }
3130 break;
3033 case WLAN_CATEGORY_BACK: 3131 case WLAN_CATEGORY_BACK:
3034 switch (mgmt->u.action.u.addba_req.action_code) { 3132 switch (mgmt->u.action.u.addba_req.action_code) {
3035 case WLAN_ACTION_ADDBA_REQ: 3133 case WLAN_ACTION_ADDBA_REQ:
@@ -3173,33 +3271,32 @@ ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
3173 struct ieee80211_rx_status *rx_status) 3271 struct ieee80211_rx_status *rx_status)
3174{ 3272{
3175 struct ieee80211_mgmt *mgmt; 3273 struct ieee80211_mgmt *mgmt;
3176 u16 fc; 3274 __le16 fc;
3177 3275
3178 if (skb->len < 2) 3276 if (skb->len < 2)
3179 return RX_DROP_UNUSABLE; 3277 return RX_DROP_UNUSABLE;
3180 3278
3181 mgmt = (struct ieee80211_mgmt *) skb->data; 3279 mgmt = (struct ieee80211_mgmt *) skb->data;
3182 fc = le16_to_cpu(mgmt->frame_control); 3280 fc = mgmt->frame_control;
3183 3281
3184 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) 3282 if (ieee80211_is_ctl(fc))
3185 return RX_CONTINUE; 3283 return RX_CONTINUE;
3186 3284
3187 if (skb->len < 24) 3285 if (skb->len < 24)
3188 return RX_DROP_MONITOR; 3286 return RX_DROP_MONITOR;
3189 3287
3190 if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { 3288 if (ieee80211_is_probe_resp(fc)) {
3191 if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) { 3289 ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status);
3192 ieee80211_rx_mgmt_probe_resp(dev, mgmt, 3290 dev_kfree_skb(skb);
3193 skb->len, rx_status); 3291 return RX_QUEUED;
3194 dev_kfree_skb(skb);
3195 return RX_QUEUED;
3196 } else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) {
3197 ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len,
3198 rx_status);
3199 dev_kfree_skb(skb);
3200 return RX_QUEUED;
3201 }
3202 } 3292 }
3293
3294 if (ieee80211_is_beacon(fc)) {
3295 ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status);
3296 dev_kfree_skb(skb);
3297 return RX_QUEUED;
3298 }
3299
3203 return RX_CONTINUE; 3300 return RX_CONTINUE;
3204} 3301}
3205 3302
@@ -3777,7 +3874,7 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local,
3777{ 3874{
3778 struct sk_buff *skb; 3875 struct sk_buff *skb;
3779 struct ieee80211_hdr *nullfunc; 3876 struct ieee80211_hdr *nullfunc;
3780 u16 fc; 3877 __le16 fc;
3781 3878
3782 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); 3879 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
3783 if (!skb) { 3880 if (!skb) {
@@ -3789,11 +3886,11 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local,
3789 3886
3790 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); 3887 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
3791 memset(nullfunc, 0, 24); 3888 memset(nullfunc, 0, 24);
3792 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | 3889 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
3793 IEEE80211_FCTL_TODS; 3890 IEEE80211_FCTL_TODS);
3794 if (powersave) 3891 if (powersave)
3795 fc |= IEEE80211_FCTL_PM; 3892 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
3796 nullfunc->frame_control = cpu_to_le16(fc); 3893 nullfunc->frame_control = fc;
3797 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN); 3894 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
3798 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); 3895 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
3799 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN); 3896 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
@@ -4087,6 +4184,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
4087 4184
4088static char * 4185static char *
4089ieee80211_sta_scan_result(struct net_device *dev, 4186ieee80211_sta_scan_result(struct net_device *dev,
4187 struct iw_request_info *info,
4090 struct ieee80211_sta_bss *bss, 4188 struct ieee80211_sta_bss *bss,
4091 char *current_ev, char *end_buf) 4189 char *current_ev, char *end_buf)
4092{ 4190{
@@ -4101,7 +4199,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
4101 iwe.cmd = SIOCGIWAP; 4199 iwe.cmd = SIOCGIWAP;
4102 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 4200 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4103 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); 4201 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4104 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4202 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4105 IW_EV_ADDR_LEN); 4203 IW_EV_ADDR_LEN);
4106 4204
4107 memset(&iwe, 0, sizeof(iwe)); 4205 memset(&iwe, 0, sizeof(iwe));
@@ -4109,13 +4207,13 @@ ieee80211_sta_scan_result(struct net_device *dev,
4109 if (bss_mesh_cfg(bss)) { 4207 if (bss_mesh_cfg(bss)) {
4110 iwe.u.data.length = bss_mesh_id_len(bss); 4208 iwe.u.data.length = bss_mesh_id_len(bss);
4111 iwe.u.data.flags = 1; 4209 iwe.u.data.flags = 1;
4112 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4210 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4113 bss_mesh_id(bss)); 4211 &iwe, bss_mesh_id(bss));
4114 } else { 4212 } else {
4115 iwe.u.data.length = bss->ssid_len; 4213 iwe.u.data.length = bss->ssid_len;
4116 iwe.u.data.flags = 1; 4214 iwe.u.data.flags = 1;
4117 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4215 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4118 bss->ssid); 4216 &iwe, bss->ssid);
4119 } 4217 }
4120 4218
4121 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) 4219 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
@@ -4128,22 +4226,22 @@ ieee80211_sta_scan_result(struct net_device *dev,
4128 iwe.u.mode = IW_MODE_MASTER; 4226 iwe.u.mode = IW_MODE_MASTER;
4129 else 4227 else
4130 iwe.u.mode = IW_MODE_ADHOC; 4228 iwe.u.mode = IW_MODE_ADHOC;
4131 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4229 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4132 IW_EV_UINT_LEN); 4230 &iwe, IW_EV_UINT_LEN);
4133 } 4231 }
4134 4232
4135 memset(&iwe, 0, sizeof(iwe)); 4233 memset(&iwe, 0, sizeof(iwe));
4136 iwe.cmd = SIOCGIWFREQ; 4234 iwe.cmd = SIOCGIWFREQ;
4137 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); 4235 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
4138 iwe.u.freq.e = 0; 4236 iwe.u.freq.e = 0;
4139 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4237 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4140 IW_EV_FREQ_LEN); 4238 IW_EV_FREQ_LEN);
4141 4239
4142 memset(&iwe, 0, sizeof(iwe)); 4240 memset(&iwe, 0, sizeof(iwe));
4143 iwe.cmd = SIOCGIWFREQ; 4241 iwe.cmd = SIOCGIWFREQ;
4144 iwe.u.freq.m = bss->freq; 4242 iwe.u.freq.m = bss->freq;
4145 iwe.u.freq.e = 6; 4243 iwe.u.freq.e = 6;
4146 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4244 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4147 IW_EV_FREQ_LEN); 4245 IW_EV_FREQ_LEN);
4148 memset(&iwe, 0, sizeof(iwe)); 4246 memset(&iwe, 0, sizeof(iwe));
4149 iwe.cmd = IWEVQUAL; 4247 iwe.cmd = IWEVQUAL;
@@ -4151,7 +4249,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
4151 iwe.u.qual.level = bss->signal; 4249 iwe.u.qual.level = bss->signal;
4152 iwe.u.qual.noise = bss->noise; 4250 iwe.u.qual.noise = bss->noise;
4153 iwe.u.qual.updated = local->wstats_flags; 4251 iwe.u.qual.updated = local->wstats_flags;
4154 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4252 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4155 IW_EV_QUAL_LEN); 4253 IW_EV_QUAL_LEN);
4156 4254
4157 memset(&iwe, 0, sizeof(iwe)); 4255 memset(&iwe, 0, sizeof(iwe));
@@ -4161,35 +4259,36 @@ ieee80211_sta_scan_result(struct net_device *dev,
4161 else 4259 else
4162 iwe.u.data.flags = IW_ENCODE_DISABLED; 4260 iwe.u.data.flags = IW_ENCODE_DISABLED;
4163 iwe.u.data.length = 0; 4261 iwe.u.data.length = 0;
4164 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); 4262 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4263 &iwe, "");
4165 4264
4166 if (bss && bss->wpa_ie) { 4265 if (bss && bss->wpa_ie) {
4167 memset(&iwe, 0, sizeof(iwe)); 4266 memset(&iwe, 0, sizeof(iwe));
4168 iwe.cmd = IWEVGENIE; 4267 iwe.cmd = IWEVGENIE;
4169 iwe.u.data.length = bss->wpa_ie_len; 4268 iwe.u.data.length = bss->wpa_ie_len;
4170 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4269 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4171 bss->wpa_ie); 4270 &iwe, bss->wpa_ie);
4172 } 4271 }
4173 4272
4174 if (bss && bss->rsn_ie) { 4273 if (bss && bss->rsn_ie) {
4175 memset(&iwe, 0, sizeof(iwe)); 4274 memset(&iwe, 0, sizeof(iwe));
4176 iwe.cmd = IWEVGENIE; 4275 iwe.cmd = IWEVGENIE;
4177 iwe.u.data.length = bss->rsn_ie_len; 4276 iwe.u.data.length = bss->rsn_ie_len;
4178 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4277 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4179 bss->rsn_ie); 4278 &iwe, bss->rsn_ie);
4180 } 4279 }
4181 4280
4182 if (bss && bss->ht_ie) { 4281 if (bss && bss->ht_ie) {
4183 memset(&iwe, 0, sizeof(iwe)); 4282 memset(&iwe, 0, sizeof(iwe));
4184 iwe.cmd = IWEVGENIE; 4283 iwe.cmd = IWEVGENIE;
4185 iwe.u.data.length = bss->ht_ie_len; 4284 iwe.u.data.length = bss->ht_ie_len;
4186 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4285 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4187 bss->ht_ie); 4286 &iwe, bss->ht_ie);
4188 } 4287 }
4189 4288
4190 if (bss && bss->supp_rates_len > 0) { 4289 if (bss && bss->supp_rates_len > 0) {
4191 /* display all supported rates in readable format */ 4290 /* display all supported rates in readable format */
4192 char *p = current_ev + IW_EV_LCP_LEN; 4291 char *p = current_ev + iwe_stream_lcp_len(info);
4193 int i; 4292 int i;
4194 4293
4195 memset(&iwe, 0, sizeof(iwe)); 4294 memset(&iwe, 0, sizeof(iwe));
@@ -4200,7 +4299,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
4200 for (i = 0; i < bss->supp_rates_len; i++) { 4299 for (i = 0; i < bss->supp_rates_len; i++) {
4201 iwe.u.bitrate.value = ((bss->supp_rates[i] & 4300 iwe.u.bitrate.value = ((bss->supp_rates[i] &
4202 0x7f) * 500000); 4301 0x7f) * 500000);
4203 p = iwe_stream_add_value(current_ev, p, 4302 p = iwe_stream_add_value(info, current_ev, p,
4204 end_buf, &iwe, IW_EV_PARAM_LEN); 4303 end_buf, &iwe, IW_EV_PARAM_LEN);
4205 } 4304 }
4206 current_ev = p; 4305 current_ev = p;
@@ -4214,7 +4313,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
4214 iwe.cmd = IWEVCUSTOM; 4313 iwe.cmd = IWEVCUSTOM;
4215 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); 4314 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
4216 iwe.u.data.length = strlen(buf); 4315 iwe.u.data.length = strlen(buf);
4217 current_ev = iwe_stream_add_point(current_ev, end_buf, 4316 current_ev = iwe_stream_add_point(info, current_ev,
4317 end_buf,
4218 &iwe, buf); 4318 &iwe, buf);
4219 kfree(buf); 4319 kfree(buf);
4220 } 4320 }
@@ -4229,31 +4329,36 @@ ieee80211_sta_scan_result(struct net_device *dev,
4229 iwe.cmd = IWEVCUSTOM; 4329 iwe.cmd = IWEVCUSTOM;
4230 sprintf(buf, "Mesh network (version %d)", cfg[0]); 4330 sprintf(buf, "Mesh network (version %d)", cfg[0]);
4231 iwe.u.data.length = strlen(buf); 4331 iwe.u.data.length = strlen(buf);
4232 current_ev = iwe_stream_add_point(current_ev, end_buf, 4332 current_ev = iwe_stream_add_point(info, current_ev,
4333 end_buf,
4233 &iwe, buf); 4334 &iwe, buf);
4234 sprintf(buf, "Path Selection Protocol ID: " 4335 sprintf(buf, "Path Selection Protocol ID: "
4235 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], 4336 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
4236 cfg[4]); 4337 cfg[4]);
4237 iwe.u.data.length = strlen(buf); 4338 iwe.u.data.length = strlen(buf);
4238 current_ev = iwe_stream_add_point(current_ev, end_buf, 4339 current_ev = iwe_stream_add_point(info, current_ev,
4340 end_buf,
4239 &iwe, buf); 4341 &iwe, buf);
4240 sprintf(buf, "Path Selection Metric ID: " 4342 sprintf(buf, "Path Selection Metric ID: "
4241 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], 4343 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
4242 cfg[8]); 4344 cfg[8]);
4243 iwe.u.data.length = strlen(buf); 4345 iwe.u.data.length = strlen(buf);
4244 current_ev = iwe_stream_add_point(current_ev, end_buf, 4346 current_ev = iwe_stream_add_point(info, current_ev,
4347 end_buf,
4245 &iwe, buf); 4348 &iwe, buf);
4246 sprintf(buf, "Congestion Control Mode ID: " 4349 sprintf(buf, "Congestion Control Mode ID: "
4247 "0x%02X%02X%02X%02X", cfg[9], cfg[10], 4350 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
4248 cfg[11], cfg[12]); 4351 cfg[11], cfg[12]);
4249 iwe.u.data.length = strlen(buf); 4352 iwe.u.data.length = strlen(buf);
4250 current_ev = iwe_stream_add_point(current_ev, end_buf, 4353 current_ev = iwe_stream_add_point(info, current_ev,
4354 end_buf,
4251 &iwe, buf); 4355 &iwe, buf);
4252 sprintf(buf, "Channel Precedence: " 4356 sprintf(buf, "Channel Precedence: "
4253 "0x%02X%02X%02X%02X", cfg[13], cfg[14], 4357 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
4254 cfg[15], cfg[16]); 4358 cfg[15], cfg[16]);
4255 iwe.u.data.length = strlen(buf); 4359 iwe.u.data.length = strlen(buf);
4256 current_ev = iwe_stream_add_point(current_ev, end_buf, 4360 current_ev = iwe_stream_add_point(info, current_ev,
4361 end_buf,
4257 &iwe, buf); 4362 &iwe, buf);
4258 kfree(buf); 4363 kfree(buf);
4259 } 4364 }
@@ -4263,7 +4368,9 @@ ieee80211_sta_scan_result(struct net_device *dev,
4263} 4368}
4264 4369
4265 4370
4266int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) 4371int ieee80211_sta_scan_results(struct net_device *dev,
4372 struct iw_request_info *info,
4373 char *buf, size_t len)
4267{ 4374{
4268 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 4375 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
4269 char *current_ev = buf; 4376 char *current_ev = buf;
@@ -4276,8 +4383,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
4276 spin_unlock_bh(&local->sta_bss_lock); 4383 spin_unlock_bh(&local->sta_bss_lock);
4277 return -E2BIG; 4384 return -E2BIG;
4278 } 4385 }
4279 current_ev = ieee80211_sta_scan_result(dev, bss, current_ev, 4386 current_ev = ieee80211_sta_scan_result(dev, info, bss,
4280 end_buf); 4387 current_ev, end_buf);
4281 } 4388 }
4282 spin_unlock_bh(&local->sta_bss_lock); 4389 spin_unlock_bh(&local->sta_bss_lock);
4283 return current_ev - buf; 4390 return current_ev - buf;
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c32a0bcd53b7..8962d1355f04 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -61,7 +61,7 @@ static inline int should_drop_frame(struct ieee80211_rx_status *status,
61 int present_fcs_len, 61 int present_fcs_len,
62 int radiotap_len) 62 int radiotap_len)
63{ 63{
64 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 64 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
65 65
66 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) 66 if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC))
67 return 1; 67 return 1;
@@ -2123,7 +2123,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2123 struct tid_ampdu_rx *tid_agg_rx; 2123 struct tid_ampdu_rx *tid_agg_rx;
2124 u16 sc; 2124 u16 sc;
2125 u16 mpdu_seq_num; 2125 u16 mpdu_seq_num;
2126 u8 ret = 0, *qc; 2126 u8 ret = 0;
2127 int tid; 2127 int tid;
2128 2128
2129 sta = sta_info_get(local, hdr->addr2); 2129 sta = sta_info_get(local, hdr->addr2);
@@ -2135,8 +2135,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2135 if (!ieee80211_is_data_qos(hdr->frame_control)) 2135 if (!ieee80211_is_data_qos(hdr->frame_control))
2136 goto end_reorder; 2136 goto end_reorder;
2137 2137
2138 qc = ieee80211_get_qos_ctl(hdr); 2138 tid = *ieee80211_get_qos_ctl(hdr) & QOS_CONTROL_TID_MASK;
2139 tid = qc[0] & QOS_CONTROL_TID_MASK;
2140 2139
2141 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) 2140 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
2142 goto end_reorder; 2141 goto end_reorder;
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c24770cb02c5..b3c733162fc1 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -235,6 +235,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
235 return NULL; 235 return NULL;
236 236
237 spin_lock_init(&sta->lock); 237 spin_lock_init(&sta->lock);
238 spin_lock_init(&sta->flaglock);
238 239
239 memcpy(sta->addr, addr, ETH_ALEN); 240 memcpy(sta->addr, addr, ETH_ALEN);
240 sta->local = local; 241 sta->local = local;
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 95753f860acf..fd228c198e31 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -164,6 +164,7 @@ struct sta_ampdu_mlme {
164 * @aid: STA's unique AID (1..2007, 0 = not assigned yet), 164 * @aid: STA's unique AID (1..2007, 0 = not assigned yet),
165 * only used in AP (and IBSS?) mode 165 * only used in AP (and IBSS?) mode
166 * @flags: STA flags, see &enum ieee80211_sta_info_flags 166 * @flags: STA flags, see &enum ieee80211_sta_info_flags
167 * @flaglock: spinlock for flags accesses
167 * @ps_tx_buf: buffer of frames to transmit to this station 168 * @ps_tx_buf: buffer of frames to transmit to this station
168 * when it leaves power saving state 169 * when it leaves power saving state
169 * @tx_filtered: buffer of frames we already tried to transmit 170 * @tx_filtered: buffer of frames we already tried to transmit
@@ -186,6 +187,7 @@ struct sta_info {
186 struct rate_control_ref *rate_ctrl; 187 struct rate_control_ref *rate_ctrl;
187 void *rate_ctrl_priv; 188 void *rate_ctrl_priv;
188 spinlock_t lock; 189 spinlock_t lock;
190 spinlock_t flaglock;
189 struct ieee80211_ht_info ht_info; 191 struct ieee80211_ht_info ht_info;
190 u64 supp_rates[IEEE80211_NUM_BANDS]; 192 u64 supp_rates[IEEE80211_NUM_BANDS];
191 u8 addr[ETH_ALEN]; 193 u8 addr[ETH_ALEN];
@@ -198,7 +200,10 @@ struct sta_info {
198 */ 200 */
199 u8 pin_status; 201 u8 pin_status;
200 202
201 /* frequently updated information, locked with lock spinlock */ 203 /*
204 * frequently updated, locked with own spinlock (flaglock),
205 * use the accessors defined below
206 */
202 u32 flags; 207 u32 flags;
203 208
204 /* 209 /*
@@ -293,34 +298,41 @@ static inline enum plink_state sta_plink_state(struct sta_info *sta)
293 298
294static inline void set_sta_flags(struct sta_info *sta, const u32 flags) 299static inline void set_sta_flags(struct sta_info *sta, const u32 flags)
295{ 300{
296 spin_lock_bh(&sta->lock); 301 unsigned long irqfl;
302
303 spin_lock_irqsave(&sta->flaglock, irqfl);
297 sta->flags |= flags; 304 sta->flags |= flags;
298 spin_unlock_bh(&sta->lock); 305 spin_unlock_irqrestore(&sta->flaglock, irqfl);
299} 306}
300 307
301static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) 308static inline void clear_sta_flags(struct sta_info *sta, const u32 flags)
302{ 309{
303 spin_lock_bh(&sta->lock); 310 unsigned long irqfl;
311
312 spin_lock_irqsave(&sta->flaglock, irqfl);
304 sta->flags &= ~flags; 313 sta->flags &= ~flags;
305 spin_unlock_bh(&sta->lock); 314 spin_unlock_irqrestore(&sta->flaglock, irqfl);
306} 315}
307 316
308static inline void set_and_clear_sta_flags(struct sta_info *sta, 317static inline void set_and_clear_sta_flags(struct sta_info *sta,
309 const u32 set, const u32 clear) 318 const u32 set, const u32 clear)
310{ 319{
311 spin_lock_bh(&sta->lock); 320 unsigned long irqfl;
321
322 spin_lock_irqsave(&sta->flaglock, irqfl);
312 sta->flags |= set; 323 sta->flags |= set;
313 sta->flags &= ~clear; 324 sta->flags &= ~clear;
314 spin_unlock_bh(&sta->lock); 325 spin_unlock_irqrestore(&sta->flaglock, irqfl);
315} 326}
316 327
317static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) 328static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags)
318{ 329{
319 u32 ret; 330 u32 ret;
331 unsigned long irqfl;
320 332
321 spin_lock_bh(&sta->lock); 333 spin_lock_irqsave(&sta->flaglock, irqfl);
322 ret = sta->flags & flags; 334 ret = sta->flags & flags;
323 spin_unlock_bh(&sta->lock); 335 spin_unlock_irqrestore(&sta->flaglock, irqfl);
324 336
325 return ret; 337 return ret;
326} 338}
@@ -329,11 +341,12 @@ static inline u32 test_and_clear_sta_flags(struct sta_info *sta,
329 const u32 flags) 341 const u32 flags)
330{ 342{
331 u32 ret; 343 u32 ret;
344 unsigned long irqfl;
332 345
333 spin_lock_bh(&sta->lock); 346 spin_lock_irqsave(&sta->flaglock, irqfl);
334 ret = sta->flags & flags; 347 ret = sta->flags & flags;
335 sta->flags &= ~flags; 348 sta->flags &= ~flags;
336 spin_unlock_bh(&sta->lock); 349 spin_unlock_irqrestore(&sta->flaglock, irqfl);
337 350
338 return ret; 351 return ret;
339} 352}
@@ -341,10 +354,11 @@ static inline u32 test_and_clear_sta_flags(struct sta_info *sta,
341static inline u32 get_sta_flags(struct sta_info *sta) 354static inline u32 get_sta_flags(struct sta_info *sta)
342{ 355{
343 u32 ret; 356 u32 ret;
357 unsigned long irqfl;
344 358
345 spin_lock_bh(&sta->lock); 359 spin_lock_irqsave(&sta->flaglock, irqfl);
346 ret = sta->flags; 360 ret = sta->flags;
347 spin_unlock_bh(&sta->lock); 361 spin_unlock_irqrestore(&sta->flaglock, irqfl);
348 362
349 return ret; 363 return ret;
350} 364}
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index e710243d82e2..995f7af3d25e 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -164,10 +164,10 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
164 iv16 = data[2] | (data[0] << 8); 164 iv16 = data[2] | (data[0] << 8);
165 iv32 = get_unaligned_le32(&data[4]); 165 iv32 = get_unaligned_le32(&data[4]);
166 166
167 tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; 167 tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
168 ctx = &key->u.tkip.tx; 168 ctx = &key->u.tkip.tx;
169 169
170#ifdef CONFIG_TKIP_DEBUG 170#ifdef CONFIG_MAC80211_TKIP_DEBUG
171 printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n", 171 printk(KERN_DEBUG "TKIP encrypt: iv16 = 0x%04x, iv32 = 0x%08x\n",
172 iv16, iv32); 172 iv16, iv32);
173 173
@@ -177,7 +177,7 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf,
177 printk(KERN_DEBUG "Wrap around of iv16 in the middle of a " 177 printk(KERN_DEBUG "Wrap around of iv16 in the middle of a "
178 "fragmented packet\n"); 178 "fragmented packet\n");
179 } 179 }
180#endif /* CONFIG_TKIP_DEBUG */ 180#endif
181 181
182 /* Update the p1k only when the iv16 in the packet wraps around, this 182 /* Update the p1k only when the iv16 in the packet wraps around, this
183 * might occur after the wrap around of iv16 in the key in case of 183 * might occur after the wrap around of iv16 in the key in case of
@@ -205,7 +205,7 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm,
205{ 205{
206 u8 rc4key[16]; 206 u8 rc4key[16];
207 struct tkip_ctx *ctx = &key->u.tkip.tx; 207 struct tkip_ctx *ctx = &key->u.tkip.tx;
208 const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; 208 const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
209 209
210 /* Calculate per-packet key */ 210 /* Calculate per-packet key */
211 if (ctx->iv16 == 0 || !ctx->initialized) 211 if (ctx->iv16 == 0 || !ctx->initialized)
@@ -231,7 +231,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
231 u32 iv16; 231 u32 iv16;
232 u8 rc4key[16], keyid, *pos = payload; 232 u8 rc4key[16], keyid, *pos = payload;
233 int res; 233 int res;
234 const u8 *tk = &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY]; 234 const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY];
235 235
236 if (payload_len < 12) 236 if (payload_len < 12)
237 return -1; 237 return -1;
@@ -240,7 +240,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
240 keyid = pos[3]; 240 keyid = pos[3];
241 iv32 = get_unaligned_le32(pos + 4); 241 iv32 = get_unaligned_le32(pos + 4);
242 pos += 8; 242 pos += 8;
243#ifdef CONFIG_TKIP_DEBUG 243#ifdef CONFIG_MAC80211_TKIP_DEBUG
244 { 244 {
245 int i; 245 int i;
246 printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); 246 printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len);
@@ -250,7 +250,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
250 printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", 250 printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n",
251 iv16, iv32); 251 iv16, iv32);
252 } 252 }
253#endif /* CONFIG_TKIP_DEBUG */ 253#endif
254 254
255 if (!(keyid & (1 << 5))) 255 if (!(keyid & (1 << 5)))
256 return TKIP_DECRYPT_NO_EXT_IV; 256 return TKIP_DECRYPT_NO_EXT_IV;
@@ -262,14 +262,14 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
262 (iv32 < key->u.tkip.rx[queue].iv32 || 262 (iv32 < key->u.tkip.rx[queue].iv32 ||
263 (iv32 == key->u.tkip.rx[queue].iv32 && 263 (iv32 == key->u.tkip.rx[queue].iv32 &&
264 iv16 <= key->u.tkip.rx[queue].iv16))) { 264 iv16 <= key->u.tkip.rx[queue].iv16))) {
265#ifdef CONFIG_TKIP_DEBUG 265#ifdef CONFIG_MAC80211_TKIP_DEBUG
266 DECLARE_MAC_BUF(mac); 266 DECLARE_MAC_BUF(mac);
267 printk(KERN_DEBUG "TKIP replay detected for RX frame from " 267 printk(KERN_DEBUG "TKIP replay detected for RX frame from "
268 "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", 268 "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n",
269 print_mac(mac, ta), 269 print_mac(mac, ta),
270 iv32, iv16, key->u.tkip.rx[queue].iv32, 270 iv32, iv16, key->u.tkip.rx[queue].iv32,
271 key->u.tkip.rx[queue].iv16); 271 key->u.tkip.rx[queue].iv16);
272#endif /* CONFIG_TKIP_DEBUG */ 272#endif
273 return TKIP_DECRYPT_REPLAY; 273 return TKIP_DECRYPT_REPLAY;
274 } 274 }
275 275
@@ -283,23 +283,23 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
283 key->u.tkip.rx[queue].iv32 != iv32) { 283 key->u.tkip.rx[queue].iv32 != iv32) {
284 /* IV16 wrapped around - perform TKIP phase 1 */ 284 /* IV16 wrapped around - perform TKIP phase 1 */
285 tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); 285 tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32);
286#ifdef CONFIG_TKIP_DEBUG 286#ifdef CONFIG_MAC80211_TKIP_DEBUG
287 { 287 {
288 int i; 288 int i;
289 u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY;
289 DECLARE_MAC_BUF(mac); 290 DECLARE_MAC_BUF(mac);
290 printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s" 291 printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s"
291 " TK=", print_mac(mac, ta)); 292 " TK=", print_mac(mac, ta));
292 for (i = 0; i < 16; i++) 293 for (i = 0; i < 16; i++)
293 printk("%02x ", 294 printk("%02x ",
294 key->conf.key[ 295 key->conf.key[key_offset + i]);
295 ALG_TKIP_TEMP_ENCR_KEY + i]);
296 printk("\n"); 296 printk("\n");
297 printk(KERN_DEBUG "TKIP decrypt: P1K="); 297 printk(KERN_DEBUG "TKIP decrypt: P1K=");
298 for (i = 0; i < 5; i++) 298 for (i = 0; i < 5; i++)
299 printk("%04x ", key->u.tkip.rx[queue].p1k[i]); 299 printk("%04x ", key->u.tkip.rx[queue].p1k[i]);
300 printk("\n"); 300 printk("\n");
301 } 301 }
302#endif /* CONFIG_TKIP_DEBUG */ 302#endif
303 if (key->local->ops->update_tkip_key && 303 if (key->local->ops->update_tkip_key &&
304 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 304 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
305 u8 bcast[ETH_ALEN] = 305 u8 bcast[ETH_ALEN] =
@@ -316,7 +316,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
316 } 316 }
317 317
318 tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); 318 tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key);
319#ifdef CONFIG_TKIP_DEBUG 319#ifdef CONFIG_MAC80211_TKIP_DEBUG
320 { 320 {
321 int i; 321 int i;
322 printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); 322 printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key=");
@@ -324,7 +324,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
324 printk("%02x ", rc4key[i]); 324 printk("%02x ", rc4key[i]);
325 printk("\n"); 325 printk("\n");
326 } 326 }
327#endif /* CONFIG_TKIP_DEBUG */ 327#endif
328 328
329 res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); 329 res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12);
330 done: 330 done:
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index ce06e791bf43..52ab85c4341b 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -52,9 +52,8 @@ static inline void ieee80211_include_sequence(struct ieee80211_sub_if_data *sdat
52static void ieee80211_dump_frame(const char *ifname, const char *title, 52static void ieee80211_dump_frame(const char *ifname, const char *title,
53 const struct sk_buff *skb) 53 const struct sk_buff *skb)
54{ 54{
55 const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 55 const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
56 u16 fc; 56 unsigned int hdrlen;
57 int hdrlen;
58 DECLARE_MAC_BUF(mac); 57 DECLARE_MAC_BUF(mac);
59 58
60 printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len); 59 printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len);
@@ -63,13 +62,12 @@ static void ieee80211_dump_frame(const char *ifname, const char *title,
63 return; 62 return;
64 } 63 }
65 64
66 fc = le16_to_cpu(hdr->frame_control); 65 hdrlen = ieee80211_hdrlen(hdr->frame_control);
67 hdrlen = ieee80211_get_hdrlen(fc);
68 if (hdrlen > skb->len) 66 if (hdrlen > skb->len)
69 hdrlen = skb->len; 67 hdrlen = skb->len;
70 if (hdrlen >= 4) 68 if (hdrlen >= 4)
71 printk(" FC=0x%04x DUR=0x%04x", 69 printk(" FC=0x%04x DUR=0x%04x",
72 fc, le16_to_cpu(hdr->duration_id)); 70 le16_to_cpu(hdr->frame_control), le16_to_cpu(hdr->duration_id));
73 if (hdrlen >= 10) 71 if (hdrlen >= 10)
74 printk(" A1=%s", print_mac(mac, hdr->addr1)); 72 printk(" A1=%s", print_mac(mac, hdr->addr1));
75 if (hdrlen >= 16) 73 if (hdrlen >= 16)
@@ -87,8 +85,8 @@ static inline void ieee80211_dump_frame(const char *ifname, const char *title,
87} 85}
88#endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */ 86#endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */
89 87
90static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, 88static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
91 int next_frag_len) 89 int next_frag_len)
92{ 90{
93 int rate, mrate, erp, dur, i; 91 int rate, mrate, erp, dur, i;
94 struct ieee80211_rate *txrate; 92 struct ieee80211_rate *txrate;
@@ -140,7 +138,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
140 138
141 /* data/mgmt */ 139 /* data/mgmt */
142 if (0 /* FIX: data/mgmt during CFP */) 140 if (0 /* FIX: data/mgmt during CFP */)
143 return 32768; 141 return cpu_to_le16(32768);
144 142
145 if (group_addr) /* Group address as the destination - no ACK */ 143 if (group_addr) /* Group address as the destination - no ACK */
146 return 0; 144 return 0;
@@ -210,7 +208,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
210 tx->sdata->bss_conf.use_short_preamble); 208 tx->sdata->bss_conf.use_short_preamble);
211 } 209 }
212 210
213 return dur; 211 return cpu_to_le16(dur);
214} 212}
215 213
216static int inline is_ieee80211_device(struct net_device *dev, 214static int inline is_ieee80211_device(struct net_device *dev,
@@ -281,7 +279,7 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
281{ 279{
282 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 280 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
283 281
284 if (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)) >= 24) 282 if (ieee80211_hdrlen(hdr->frame_control) >= 24)
285 ieee80211_include_sequence(tx->sdata, hdr); 283 ieee80211_include_sequence(tx->sdata, hdr);
286 284
287 return TX_CONTINUE; 285 return TX_CONTINUE;
@@ -542,9 +540,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
542static ieee80211_tx_result 540static ieee80211_tx_result
543ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) 541ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
544{ 542{
545 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 543 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
546 u16 fc = le16_to_cpu(hdr->frame_control);
547 u16 dur;
548 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 544 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
549 struct ieee80211_supported_band *sband; 545 struct ieee80211_supported_band *sband;
550 546
@@ -595,21 +591,13 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
595 /* Transmit data frames using short preambles if the driver supports 591 /* Transmit data frames using short preambles if the driver supports
596 * short preambles at the selected rate and short preambles are 592 * short preambles at the selected rate and short preambles are
597 * available on the network at the current point in time. */ 593 * available on the network at the current point in time. */
598 if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && 594 if (ieee80211_is_data(hdr->frame_control) &&
599 (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && 595 (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) &&
600 tx->sdata->bss_conf.use_short_preamble && 596 tx->sdata->bss_conf.use_short_preamble &&
601 (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { 597 (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) {
602 info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; 598 info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE;
603 } 599 }
604 600
605 /* Setup duration field for the first fragment of the frame. Duration
606 * for remaining fragments will be updated when they are being sent
607 * to low-level driver in ieee80211_tx(). */
608 dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1),
609 (tx->flags & IEEE80211_TX_FRAGMENTED) ?
610 tx->extra_frag[0]->len : 0);
611 hdr->duration_id = cpu_to_le16(dur);
612
613 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || 601 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
614 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { 602 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) {
615 struct ieee80211_rate *rate; 603 struct ieee80211_rate *rate;
@@ -647,7 +635,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
647static ieee80211_tx_result 635static ieee80211_tx_result
648ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) 636ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
649{ 637{
650 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; 638 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
651 size_t hdrlen, per_fragm, num_fragm, payload_len, left; 639 size_t hdrlen, per_fragm, num_fragm, payload_len, left;
652 struct sk_buff **frags, *first, *frag; 640 struct sk_buff **frags, *first, *frag;
653 int i; 641 int i;
@@ -670,7 +658,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
670 658
671 first = tx->skb; 659 first = tx->skb;
672 660
673 hdrlen = ieee80211_get_hdrlen(tx->fc); 661 hdrlen = ieee80211_hdrlen(hdr->frame_control);
674 payload_len = first->len - hdrlen; 662 payload_len = first->len - hdrlen;
675 per_fragm = frag_threshold - hdrlen - FCS_LEN; 663 per_fragm = frag_threshold - hdrlen - FCS_LEN;
676 num_fragm = DIV_ROUND_UP(payload_len, per_fragm); 664 num_fragm = DIV_ROUND_UP(payload_len, per_fragm);
@@ -711,6 +699,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
711 fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); 699 fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG));
712 copylen = left > per_fragm ? per_fragm : left; 700 copylen = left > per_fragm ? per_fragm : left;
713 memcpy(skb_put(frag, copylen), pos, copylen); 701 memcpy(skb_put(frag, copylen), pos, copylen);
702 memcpy(frag->cb, first->cb, sizeof(frag->cb));
703 skb_copy_queue_mapping(frag, first);
714 704
715 pos += copylen; 705 pos += copylen;
716 left -= copylen; 706 left -= copylen;
@@ -755,6 +745,36 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx)
755} 745}
756 746
757static ieee80211_tx_result 747static ieee80211_tx_result
748ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx)
749{
750 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
751 int next_len, i;
752 int group_addr = is_multicast_ether_addr(hdr->addr1);
753
754 if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) {
755 hdr->duration_id = ieee80211_duration(tx, group_addr, 0);
756 return TX_CONTINUE;
757 }
758
759 hdr->duration_id = ieee80211_duration(tx, group_addr,
760 tx->extra_frag[0]->len);
761
762 for (i = 0; i < tx->num_extra_frag; i++) {
763 if (i + 1 < tx->num_extra_frag) {
764 next_len = tx->extra_frag[i + 1]->len;
765 } else {
766 next_len = 0;
767 tx->rate_idx = tx->last_frag_rate_idx;
768 }
769
770 hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data;
771 hdr->duration_id = ieee80211_duration(tx, 0, next_len);
772 }
773
774 return TX_CONTINUE;
775}
776
777static ieee80211_tx_result
758ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) 778ieee80211_tx_h_stats(struct ieee80211_tx_data *tx)
759{ 779{
760 int i; 780 int i;
@@ -788,6 +808,7 @@ static ieee80211_tx_handler ieee80211_tx_handlers[] =
788 ieee80211_tx_h_fragment, 808 ieee80211_tx_h_fragment,
789 /* handlers after fragment must be aware of tx info fragmentation! */ 809 /* handlers after fragment must be aware of tx info fragmentation! */
790 ieee80211_tx_h_encrypt, 810 ieee80211_tx_h_encrypt,
811 ieee80211_tx_h_calculate_duration,
791 ieee80211_tx_h_stats, 812 ieee80211_tx_h_stats,
792 NULL 813 NULL
793}; 814};
@@ -1083,13 +1104,46 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1083 return IEEE80211_TX_OK; 1104 return IEEE80211_TX_OK;
1084} 1105}
1085 1106
1107/*
1108 * Invoke TX handlers, return 0 on success and non-zero if the
1109 * frame was dropped or queued.
1110 */
1111static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1112{
1113 struct ieee80211_local *local = tx->local;
1114 struct sk_buff *skb = tx->skb;
1115 ieee80211_tx_handler *handler;
1116 ieee80211_tx_result res = TX_DROP;
1117 int i;
1118
1119 for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) {
1120 res = (*handler)(tx);
1121 if (res != TX_CONTINUE)
1122 break;
1123 }
1124
1125 if (unlikely(res == TX_DROP)) {
1126 I802_DEBUG_INC(local->tx_handlers_drop);
1127 dev_kfree_skb(skb);
1128 for (i = 0; i < tx->num_extra_frag; i++)
1129 if (tx->extra_frag[i])
1130 dev_kfree_skb(tx->extra_frag[i]);
1131 kfree(tx->extra_frag);
1132 return -1;
1133 } else if (unlikely(res == TX_QUEUED)) {
1134 I802_DEBUG_INC(local->tx_handlers_queued);
1135 return -1;
1136 }
1137
1138 return 0;
1139}
1140
1086static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb) 1141static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
1087{ 1142{
1088 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1143 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1089 struct sta_info *sta; 1144 struct sta_info *sta;
1090 ieee80211_tx_handler *handler;
1091 struct ieee80211_tx_data tx; 1145 struct ieee80211_tx_data tx;
1092 ieee80211_tx_result res = TX_DROP, res_prepare; 1146 ieee80211_tx_result res_prepare;
1093 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1147 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1094 int ret, i; 1148 int ret, i;
1095 u16 queue; 1149 u16 queue;
@@ -1118,44 +1172,8 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb)
1118 tx.channel = local->hw.conf.channel; 1172 tx.channel = local->hw.conf.channel;
1119 info->band = tx.channel->band; 1173 info->band = tx.channel->band;
1120 1174
1121 for (handler = ieee80211_tx_handlers; *handler != NULL; 1175 if (invoke_tx_handlers(&tx))
1122 handler++) { 1176 goto out;
1123 res = (*handler)(&tx);
1124 if (res != TX_CONTINUE)
1125 break;
1126 }
1127
1128 if (WARN_ON(tx.skb != skb))
1129 goto drop;
1130
1131 if (unlikely(res == TX_DROP)) {
1132 I802_DEBUG_INC(local->tx_handlers_drop);
1133 goto drop;
1134 }
1135
1136 if (unlikely(res == TX_QUEUED)) {
1137 I802_DEBUG_INC(local->tx_handlers_queued);
1138 rcu_read_unlock();
1139 return 0;
1140 }
1141
1142 if (tx.extra_frag) {
1143 for (i = 0; i < tx.num_extra_frag; i++) {
1144 int next_len, dur;
1145 struct ieee80211_hdr *hdr =
1146 (struct ieee80211_hdr *)
1147 tx.extra_frag[i]->data;
1148
1149 if (i + 1 < tx.num_extra_frag) {
1150 next_len = tx.extra_frag[i + 1]->len;
1151 } else {
1152 next_len = 0;
1153 tx.rate_idx = tx.last_frag_rate_idx;
1154 }
1155 dur = ieee80211_duration(&tx, 0, next_len);
1156 hdr->duration_id = cpu_to_le16(dur);
1157 }
1158 }
1159 1177
1160retry: 1178retry:
1161 ret = __ieee80211_tx(local, skb, &tx); 1179 ret = __ieee80211_tx(local, skb, &tx);
@@ -1198,6 +1216,7 @@ retry:
1198 store->last_frag_rate_ctrl_probe = 1216 store->last_frag_rate_ctrl_probe =
1199 !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); 1217 !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG);
1200 } 1218 }
1219 out:
1201 rcu_read_unlock(); 1220 rcu_read_unlock();
1202 return 0; 1221 return 0;
1203 1222
@@ -1379,7 +1398,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1379 struct ieee80211_tx_info *info; 1398 struct ieee80211_tx_info *info;
1380 struct ieee80211_sub_if_data *sdata; 1399 struct ieee80211_sub_if_data *sdata;
1381 int ret = 1, head_need; 1400 int ret = 1, head_need;
1382 u16 ethertype, hdrlen, meshhdrlen = 0, fc; 1401 u16 ethertype, hdrlen, meshhdrlen = 0;
1402 __le16 fc;
1383 struct ieee80211_hdr hdr; 1403 struct ieee80211_hdr hdr;
1384 struct ieee80211s_hdr mesh_hdr; 1404 struct ieee80211s_hdr mesh_hdr;
1385 const u8 *encaps_data; 1405 const u8 *encaps_data;
@@ -1402,12 +1422,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1402 /* convert Ethernet header to proper 802.11 header (based on 1422 /* convert Ethernet header to proper 802.11 header (based on
1403 * operation mode) */ 1423 * operation mode) */
1404 ethertype = (skb->data[12] << 8) | skb->data[13]; 1424 ethertype = (skb->data[12] << 8) | skb->data[13];
1405 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; 1425 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
1406 1426
1407 switch (sdata->vif.type) { 1427 switch (sdata->vif.type) {
1408 case IEEE80211_IF_TYPE_AP: 1428 case IEEE80211_IF_TYPE_AP:
1409 case IEEE80211_IF_TYPE_VLAN: 1429 case IEEE80211_IF_TYPE_VLAN:
1410 fc |= IEEE80211_FCTL_FROMDS; 1430 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
1411 /* DA BSSID SA */ 1431 /* DA BSSID SA */
1412 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1432 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1413 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); 1433 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
@@ -1415,7 +1435,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1415 hdrlen = 24; 1435 hdrlen = 24;
1416 break; 1436 break;
1417 case IEEE80211_IF_TYPE_WDS: 1437 case IEEE80211_IF_TYPE_WDS:
1418 fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; 1438 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1419 /* RA TA DA SA */ 1439 /* RA TA DA SA */
1420 memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); 1440 memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN);
1421 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); 1441 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
@@ -1425,7 +1445,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1425 break; 1445 break;
1426#ifdef CONFIG_MAC80211_MESH 1446#ifdef CONFIG_MAC80211_MESH
1427 case IEEE80211_IF_TYPE_MESH_POINT: 1447 case IEEE80211_IF_TYPE_MESH_POINT:
1428 fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; 1448 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1429 /* RA TA DA SA */ 1449 /* RA TA DA SA */
1430 if (is_multicast_ether_addr(skb->data)) 1450 if (is_multicast_ether_addr(skb->data))
1431 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1451 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -1455,7 +1475,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1455 break; 1475 break;
1456#endif 1476#endif
1457 case IEEE80211_IF_TYPE_STA: 1477 case IEEE80211_IF_TYPE_STA:
1458 fc |= IEEE80211_FCTL_TODS; 1478 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
1459 /* BSSID SA DA */ 1479 /* BSSID SA DA */
1460 memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); 1480 memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN);
1461 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 1481 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
@@ -1490,7 +1510,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1490 /* receiver and we are QoS enabled, use a QoS type frame */ 1510 /* receiver and we are QoS enabled, use a QoS type frame */
1491 if (sta_flags & WLAN_STA_WME && 1511 if (sta_flags & WLAN_STA_WME &&
1492 ieee80211_num_regular_queues(&local->hw) >= 4) { 1512 ieee80211_num_regular_queues(&local->hw) >= 4) {
1493 fc |= IEEE80211_STYPE_QOS_DATA; 1513 fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
1494 hdrlen += 2; 1514 hdrlen += 2;
1495 } 1515 }
1496 1516
@@ -1518,7 +1538,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1518 goto fail; 1538 goto fail;
1519 } 1539 }
1520 1540
1521 hdr.frame_control = cpu_to_le16(fc); 1541 hdr.frame_control = fc;
1522 hdr.duration_id = 0; 1542 hdr.duration_id = 0;
1523 hdr.seq_ctrl = 0; 1543 hdr.seq_ctrl = 0;
1524 1544
@@ -1587,7 +1607,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1587 h_pos += meshhdrlen; 1607 h_pos += meshhdrlen;
1588 } 1608 }
1589 1609
1590 if (fc & IEEE80211_STYPE_QOS_DATA) { 1610 if (ieee80211_is_data_qos(fc)) {
1591 __le16 *qos_control; 1611 __le16 *qos_control;
1592 1612
1593 qos_control = (__le16*) skb_push(skb, 2); 1613 qos_control = (__le16*) skb_push(skb, 2);
@@ -1845,8 +1865,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1845 mgmt = (struct ieee80211_mgmt *) 1865 mgmt = (struct ieee80211_mgmt *)
1846 skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 1866 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
1847 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 1867 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
1848 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 1868 mgmt->frame_control =
1849 IEEE80211_STYPE_BEACON); 1869 cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
1850 memset(mgmt->da, 0xff, ETH_ALEN); 1870 memset(mgmt->da, 0xff, ETH_ALEN);
1851 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 1871 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
1852 /* BSSID is left zeroed, wildcard value */ 1872 /* BSSID is left zeroed, wildcard value */
@@ -1914,10 +1934,9 @@ void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1914 struct ieee80211_rts *rts) 1934 struct ieee80211_rts *rts)
1915{ 1935{
1916 const struct ieee80211_hdr *hdr = frame; 1936 const struct ieee80211_hdr *hdr = frame;
1917 u16 fctl;
1918 1937
1919 fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS; 1938 rts->frame_control =
1920 rts->frame_control = cpu_to_le16(fctl); 1939 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS);
1921 rts->duration = ieee80211_rts_duration(hw, vif, frame_len, 1940 rts->duration = ieee80211_rts_duration(hw, vif, frame_len,
1922 frame_txctl); 1941 frame_txctl);
1923 memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); 1942 memcpy(rts->ra, hdr->addr1, sizeof(rts->ra));
@@ -1931,10 +1950,9 @@ void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1931 struct ieee80211_cts *cts) 1950 struct ieee80211_cts *cts)
1932{ 1951{
1933 const struct ieee80211_hdr *hdr = frame; 1952 const struct ieee80211_hdr *hdr = frame;
1934 u16 fctl;
1935 1953
1936 fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS; 1954 cts->frame_control =
1937 cts->frame_control = cpu_to_le16(fctl); 1955 cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS);
1938 cts->duration = ieee80211_ctstoself_duration(hw, vif, 1956 cts->duration = ieee80211_ctstoself_duration(hw, vif,
1939 frame_len, frame_txctl); 1957 frame_len, frame_txctl);
1940 memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); 1958 memcpy(cts->ra, hdr->addr1, sizeof(cts->ra));
@@ -1948,9 +1966,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
1948 struct ieee80211_local *local = hw_to_local(hw); 1966 struct ieee80211_local *local = hw_to_local(hw);
1949 struct sk_buff *skb = NULL; 1967 struct sk_buff *skb = NULL;
1950 struct sta_info *sta; 1968 struct sta_info *sta;
1951 ieee80211_tx_handler *handler;
1952 struct ieee80211_tx_data tx; 1969 struct ieee80211_tx_data tx;
1953 ieee80211_tx_result res = TX_DROP;
1954 struct net_device *bdev; 1970 struct net_device *bdev;
1955 struct ieee80211_sub_if_data *sdata; 1971 struct ieee80211_sub_if_data *sdata;
1956 struct ieee80211_if_ap *bss = NULL; 1972 struct ieee80211_if_ap *bss = NULL;
@@ -2001,25 +2017,9 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2001 tx.channel = local->hw.conf.channel; 2017 tx.channel = local->hw.conf.channel;
2002 info->band = tx.channel->band; 2018 info->band = tx.channel->band;
2003 2019
2004 for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { 2020 if (invoke_tx_handlers(&tx))
2005 res = (*handler)(&tx);
2006 if (res == TX_DROP || res == TX_QUEUED)
2007 break;
2008 }
2009
2010 if (WARN_ON(tx.skb != skb))
2011 res = TX_DROP;
2012
2013 if (res == TX_DROP) {
2014 I802_DEBUG_INC(local->tx_handlers_drop);
2015 dev_kfree_skb(skb);
2016 skb = NULL; 2021 skb = NULL;
2017 } else if (res == TX_QUEUED) { 2022 out:
2018 I802_DEBUG_INC(local->tx_handlers_queued);
2019 skb = NULL;
2020 }
2021
2022out:
2023 rcu_read_unlock(); 2023 rcu_read_unlock();
2024 2024
2025 return skb; 2025 return skb;
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index e7b6344c900a..35b664d00e23 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -84,20 +84,17 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local,
84 struct sk_buff *skb, 84 struct sk_buff *skb,
85 struct ieee80211_key *key) 85 struct ieee80211_key *key)
86{ 86{
87 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 87 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
88 u16 fc; 88 unsigned int hdrlen;
89 int hdrlen;
90 u8 *newhdr; 89 u8 *newhdr;
91 90
92 fc = le16_to_cpu(hdr->frame_control); 91 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
93 fc |= IEEE80211_FCTL_PROTECTED;
94 hdr->frame_control = cpu_to_le16(fc);
95 92
96 if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN || 93 if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN ||
97 skb_headroom(skb) < WEP_IV_LEN)) 94 skb_headroom(skb) < WEP_IV_LEN))
98 return NULL; 95 return NULL;
99 96
100 hdrlen = ieee80211_get_hdrlen(fc); 97 hdrlen = ieee80211_hdrlen(hdr->frame_control);
101 newhdr = skb_push(skb, WEP_IV_LEN); 98 newhdr = skb_push(skb, WEP_IV_LEN);
102 memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); 99 memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen);
103 ieee80211_wep_get_iv(local, key, newhdr + hdrlen); 100 ieee80211_wep_get_iv(local, key, newhdr + hdrlen);
@@ -109,12 +106,10 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local,
109 struct sk_buff *skb, 106 struct sk_buff *skb,
110 struct ieee80211_key *key) 107 struct ieee80211_key *key)
111{ 108{
112 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 109 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
113 u16 fc; 110 unsigned int hdrlen;
114 int hdrlen;
115 111
116 fc = le16_to_cpu(hdr->frame_control); 112 hdrlen = ieee80211_hdrlen(hdr->frame_control);
117 hdrlen = ieee80211_get_hdrlen(fc);
118 memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); 113 memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen);
119 skb_pull(skb, WEP_IV_LEN); 114 skb_pull(skb, WEP_IV_LEN);
120} 115}
@@ -224,17 +219,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
224 u32 klen; 219 u32 klen;
225 u8 *rc4key; 220 u8 *rc4key;
226 u8 keyidx; 221 u8 keyidx;
227 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 222 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
228 u16 fc; 223 unsigned int hdrlen;
229 int hdrlen;
230 size_t len; 224 size_t len;
231 int ret = 0; 225 int ret = 0;
232 226
233 fc = le16_to_cpu(hdr->frame_control); 227 if (!ieee80211_has_protected(hdr->frame_control))
234 if (!(fc & IEEE80211_FCTL_PROTECTED))
235 return -1; 228 return -1;
236 229
237 hdrlen = ieee80211_get_hdrlen(fc); 230 hdrlen = ieee80211_hdrlen(hdr->frame_control);
238 231
239 if (skb->len < 8 + hdrlen) 232 if (skb->len < 8 + hdrlen)
240 return -1; 233 return -1;
@@ -281,17 +274,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
281 274
282u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) 275u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
283{ 276{
284 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 277 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
285 u16 fc; 278 unsigned int hdrlen;
286 int hdrlen;
287 u8 *ivpos; 279 u8 *ivpos;
288 u32 iv; 280 u32 iv;
289 281
290 fc = le16_to_cpu(hdr->frame_control); 282 if (!ieee80211_has_protected(hdr->frame_control))
291 if (!(fc & IEEE80211_FCTL_PROTECTED))
292 return NULL; 283 return NULL;
293 284
294 hdrlen = ieee80211_get_hdrlen(fc); 285 hdrlen = ieee80211_hdrlen(hdr->frame_control);
295 ivpos = skb->data + hdrlen; 286 ivpos = skb->data + hdrlen;
296 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; 287 iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2];
297 288
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 5af3862e7191..df0531c28141 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -135,7 +135,39 @@ static int ieee80211_ioctl_giwname(struct net_device *dev,
135 struct iw_request_info *info, 135 struct iw_request_info *info,
136 char *name, char *extra) 136 char *name, char *extra)
137{ 137{
138 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
139 struct ieee80211_supported_band *sband;
140 u8 is_ht = 0, is_a = 0, is_b = 0, is_g = 0;
141
142
143 sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ];
144 if (sband) {
145 is_a = 1;
146 is_ht |= sband->ht_info.ht_supported;
147 }
148
149 sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ];
150 if (sband) {
151 int i;
152 /* Check for mandatory rates */
153 for (i = 0; i < sband->n_bitrates; i++) {
154 if (sband->bitrates[i].bitrate == 10)
155 is_b = 1;
156 if (sband->bitrates[i].bitrate == 60)
157 is_g = 1;
158 }
159 is_ht |= sband->ht_info.ht_supported;
160 }
161
138 strcpy(name, "IEEE 802.11"); 162 strcpy(name, "IEEE 802.11");
163 if (is_a)
164 strcat(name, "a");
165 if (is_b)
166 strcat(name, "b");
167 if (is_g)
168 strcat(name, "g");
169 if (is_ht)
170 strcat(name, "n");
139 171
140 return 0; 172 return 0;
141} 173}
@@ -567,7 +599,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
567 if (local->sta_sw_scanning || local->sta_hw_scanning) 599 if (local->sta_sw_scanning || local->sta_hw_scanning)
568 return -EAGAIN; 600 return -EAGAIN;
569 601
570 res = ieee80211_sta_scan_results(dev, extra, data->length); 602 res = ieee80211_sta_scan_results(dev, info, extra, data->length);
571 if (res >= 0) { 603 if (res >= 0) {
572 data->length = res; 604 data->length = res;
573 return 0; 605 return 0;
@@ -721,6 +753,9 @@ static int ieee80211_ioctl_siwrts(struct net_device *dev,
721 753
722 if (rts->disabled) 754 if (rts->disabled)
723 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 755 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
756 else if (!rts->fixed)
757 /* if the rts value is not fixed, then take default */
758 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
724 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) 759 else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD)
725 return -EINVAL; 760 return -EINVAL;
726 else 761 else
@@ -949,6 +984,19 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
949 erq->length = sdata->keys[idx]->conf.keylen; 984 erq->length = sdata->keys[idx]->conf.keylen;
950 erq->flags |= IW_ENCODE_ENABLED; 985 erq->flags |= IW_ENCODE_ENABLED;
951 986
987 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
988 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
989 switch (ifsta->auth_alg) {
990 case WLAN_AUTH_OPEN:
991 case WLAN_AUTH_LEAP:
992 erq->flags |= IW_ENCODE_OPEN;
993 break;
994 case WLAN_AUTH_SHARED_KEY:
995 erq->flags |= IW_ENCODE_RESTRICTED;
996 break;
997 }
998 }
999
952 return 0; 1000 return 0;
953} 1001}
954 1002
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 345e10e9b313..f809761fbfb5 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -49,7 +49,7 @@ static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da,
49ieee80211_tx_result 49ieee80211_tx_result
50ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) 50ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
51{ 51{
52 u8 *data, *sa, *da, *key, *mic, qos_tid; 52 u8 *data, *sa, *da, *key, *mic, qos_tid, key_offset;
53 size_t data_len; 53 size_t data_len;
54 u16 fc; 54 u16 fc;
55 struct sk_buff *skb = tx->skb; 55 struct sk_buff *skb = tx->skb;
@@ -88,8 +88,12 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
88#else 88#else
89 authenticator = 1; 89 authenticator = 1;
90#endif 90#endif
91 key = &tx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY : 91 /* At this point we know we're using ALG_TKIP. To get the MIC key
92 ALG_TKIP_TEMP_AUTH_RX_MIC_KEY]; 92 * we now will rely on the offset from the ieee80211_key_conf::key */
93 key_offset = authenticator ?
94 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY :
95 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
96 key = &tx->key->conf.key[key_offset];
93 mic = skb_put(skb, MICHAEL_MIC_LEN); 97 mic = skb_put(skb, MICHAEL_MIC_LEN);
94 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 98 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
95 99
@@ -100,7 +104,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx)
100ieee80211_rx_result 104ieee80211_rx_result
101ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) 105ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
102{ 106{
103 u8 *data, *sa, *da, *key = NULL, qos_tid; 107 u8 *data, *sa, *da, *key = NULL, qos_tid, key_offset;
104 size_t data_len; 108 size_t data_len;
105 u16 fc; 109 u16 fc;
106 u8 mic[MICHAEL_MIC_LEN]; 110 u8 mic[MICHAEL_MIC_LEN];
@@ -131,8 +135,12 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
131#else 135#else
132 authenticator = 1; 136 authenticator = 1;
133#endif 137#endif
134 key = &rx->key->conf.key[authenticator ? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY : 138 /* At this point we know we're using ALG_TKIP. To get the MIC key
135 ALG_TKIP_TEMP_AUTH_TX_MIC_KEY]; 139 * we now will rely on the offset from the ieee80211_key_conf::key */
140 key_offset = authenticator ?
141 NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY :
142 NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
143 key = &rx->key->conf.key[key_offset];
136 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); 144 michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic);
137 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { 145 if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) {
138 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 146 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
diff --git a/net/rfkill/rfkill-input.c b/net/rfkill/rfkill-input.c
index e4b051dbed61..8aa822730145 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -30,39 +30,62 @@ struct rfkill_task {
30 spinlock_t lock; /* for accessing last and desired state */ 30 spinlock_t lock; /* for accessing last and desired state */
31 unsigned long last; /* last schedule */ 31 unsigned long last; /* last schedule */
32 enum rfkill_state desired_state; /* on/off */ 32 enum rfkill_state desired_state; /* on/off */
33 enum rfkill_state current_state; /* on/off */
34}; 33};
35 34
36static void rfkill_task_handler(struct work_struct *work) 35static void rfkill_task_handler(struct work_struct *work)
37{ 36{
38 struct rfkill_task *task = container_of(work, struct rfkill_task, work); 37 struct rfkill_task *task = container_of(work, struct rfkill_task, work);
39 enum rfkill_state state;
40 38
41 mutex_lock(&task->mutex); 39 mutex_lock(&task->mutex);
42 40
43 /* 41 rfkill_switch_all(task->type, task->desired_state);
44 * Use temp variable to fetch desired state to keep it
45 * consistent even if rfkill_schedule_toggle() runs in
46 * another thread or interrupts us.
47 */
48 state = task->desired_state;
49 42
50 if (state != task->current_state) { 43 mutex_unlock(&task->mutex);
51 rfkill_switch_all(task->type, state); 44}
52 task->current_state = state; 45
46static void rfkill_task_epo_handler(struct work_struct *work)
47{
48 rfkill_epo();
49}
50
51static DECLARE_WORK(epo_work, rfkill_task_epo_handler);
52
53static void rfkill_schedule_epo(void)
54{
55 schedule_work(&epo_work);
56}
57
58static void rfkill_schedule_set(struct rfkill_task *task,
59 enum rfkill_state desired_state)
60{
61 unsigned long flags;
62
63 if (unlikely(work_pending(&epo_work)))
64 return;
65
66 spin_lock_irqsave(&task->lock, flags);
67
68 if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
69 task->desired_state = desired_state;
70 task->last = jiffies;
71 schedule_work(&task->work);
53 } 72 }
54 73
55 mutex_unlock(&task->mutex); 74 spin_unlock_irqrestore(&task->lock, flags);
56} 75}
57 76
58static void rfkill_schedule_toggle(struct rfkill_task *task) 77static void rfkill_schedule_toggle(struct rfkill_task *task)
59{ 78{
60 unsigned long flags; 79 unsigned long flags;
61 80
81 if (unlikely(work_pending(&epo_work)))
82 return;
83
62 spin_lock_irqsave(&task->lock, flags); 84 spin_lock_irqsave(&task->lock, flags);
63 85
64 if (time_after(jiffies, task->last + msecs_to_jiffies(200))) { 86 if (time_after(jiffies, task->last + msecs_to_jiffies(200))) {
65 task->desired_state = !task->desired_state; 87 task->desired_state =
88 rfkill_state_complement(task->desired_state);
66 task->last = jiffies; 89 task->last = jiffies;
67 schedule_work(&task->work); 90 schedule_work(&task->work);
68 } 91 }
@@ -70,26 +93,26 @@ static void rfkill_schedule_toggle(struct rfkill_task *task)
70 spin_unlock_irqrestore(&task->lock, flags); 93 spin_unlock_irqrestore(&task->lock, flags);
71} 94}
72 95
73#define DEFINE_RFKILL_TASK(n, t) \ 96#define DEFINE_RFKILL_TASK(n, t) \
74 struct rfkill_task n = { \ 97 struct rfkill_task n = { \
75 .work = __WORK_INITIALIZER(n.work, \ 98 .work = __WORK_INITIALIZER(n.work, \
76 rfkill_task_handler), \ 99 rfkill_task_handler), \
77 .type = t, \ 100 .type = t, \
78 .mutex = __MUTEX_INITIALIZER(n.mutex), \ 101 .mutex = __MUTEX_INITIALIZER(n.mutex), \
79 .lock = __SPIN_LOCK_UNLOCKED(n.lock), \ 102 .lock = __SPIN_LOCK_UNLOCKED(n.lock), \
80 .desired_state = RFKILL_STATE_ON, \ 103 .desired_state = RFKILL_STATE_UNBLOCKED, \
81 .current_state = RFKILL_STATE_ON, \
82 } 104 }
83 105
84static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN); 106static DEFINE_RFKILL_TASK(rfkill_wlan, RFKILL_TYPE_WLAN);
85static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH); 107static DEFINE_RFKILL_TASK(rfkill_bt, RFKILL_TYPE_BLUETOOTH);
86static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB); 108static DEFINE_RFKILL_TASK(rfkill_uwb, RFKILL_TYPE_UWB);
87static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX); 109static DEFINE_RFKILL_TASK(rfkill_wimax, RFKILL_TYPE_WIMAX);
110static DEFINE_RFKILL_TASK(rfkill_wwan, RFKILL_TYPE_WWAN);
88 111
89static void rfkill_event(struct input_handle *handle, unsigned int type, 112static void rfkill_event(struct input_handle *handle, unsigned int type,
90 unsigned int code, int down) 113 unsigned int code, int data)
91{ 114{
92 if (type == EV_KEY && down == 1) { 115 if (type == EV_KEY && data == 1) {
93 switch (code) { 116 switch (code) {
94 case KEY_WLAN: 117 case KEY_WLAN:
95 rfkill_schedule_toggle(&rfkill_wlan); 118 rfkill_schedule_toggle(&rfkill_wlan);
@@ -106,6 +129,28 @@ static void rfkill_event(struct input_handle *handle, unsigned int type,
106 default: 129 default:
107 break; 130 break;
108 } 131 }
132 } else if (type == EV_SW) {
133 switch (code) {
134 case SW_RFKILL_ALL:
135 /* EVERY radio type. data != 0 means radios ON */
136 /* handle EPO (emergency power off) through shortcut */
137 if (data) {
138 rfkill_schedule_set(&rfkill_wwan,
139 RFKILL_STATE_UNBLOCKED);
140 rfkill_schedule_set(&rfkill_wimax,
141 RFKILL_STATE_UNBLOCKED);
142 rfkill_schedule_set(&rfkill_uwb,
143 RFKILL_STATE_UNBLOCKED);
144 rfkill_schedule_set(&rfkill_bt,
145 RFKILL_STATE_UNBLOCKED);
146 rfkill_schedule_set(&rfkill_wlan,
147 RFKILL_STATE_UNBLOCKED);
148 } else
149 rfkill_schedule_epo();
150 break;
151 default:
152 break;
153 }
109 } 154 }
110} 155}
111 156
@@ -168,6 +213,11 @@ static const struct input_device_id rfkill_ids[] = {
168 .evbit = { BIT_MASK(EV_KEY) }, 213 .evbit = { BIT_MASK(EV_KEY) },
169 .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) }, 214 .keybit = { [BIT_WORD(KEY_WIMAX)] = BIT_MASK(KEY_WIMAX) },
170 }, 215 },
216 {
217 .flags = INPUT_DEVICE_ID_MATCH_EVBIT | INPUT_DEVICE_ID_MATCH_SWBIT,
218 .evbit = { BIT(EV_SW) },
219 .swbit = { [BIT_WORD(SW_RFKILL_ALL)] = BIT_MASK(SW_RFKILL_ALL) },
220 },
171 { } 221 { }
172}; 222};
173 223
diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h
index 4dae5006fc77..f63d05045685 100644
--- a/net/rfkill/rfkill-input.h
+++ b/net/rfkill/rfkill-input.h
@@ -12,5 +12,6 @@
12#define __RFKILL_INPUT_H 12#define __RFKILL_INPUT_H
13 13
14void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state); 14void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
15void rfkill_epo(void);
15 16
16#endif /* __RFKILL_INPUT_H */ 17#endif /* __RFKILL_INPUT_H */
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 4e10a95de832..ce0e23148cdd 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -39,8 +39,56 @@ MODULE_LICENSE("GPL");
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_mutex);
41 41
42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
43module_param_named(default_state, rfkill_default_state, uint, 0444);
44MODULE_PARM_DESC(default_state,
45 "Default initial state for all radio types, 0 = radio off");
46
42static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX]; 47static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX];
43 48
49static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
50
51
52/**
53 * register_rfkill_notifier - Add notifier to rfkill notifier chain
54 * @nb: pointer to the new entry to add to the chain
55 *
56 * See blocking_notifier_chain_register() for return value and further
57 * observations.
58 *
59 * Adds a notifier to the rfkill notifier chain. The chain will be
60 * called with a pointer to the relevant rfkill structure as a parameter,
61 * refer to include/linux/rfkill.h for the possible events.
62 *
63 * Notifiers added to this chain are to always return NOTIFY_DONE. This
64 * chain is a blocking notifier chain: notifiers can sleep.
65 *
66 * Calls to this chain may have been done through a workqueue. One must
67 * assume unordered asynchronous behaviour, there is no way to know if
68 * actions related to the event that generated the notification have been
69 * carried out already.
70 */
71int register_rfkill_notifier(struct notifier_block *nb)
72{
73 return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
74}
75EXPORT_SYMBOL_GPL(register_rfkill_notifier);
76
77/**
78 * unregister_rfkill_notifier - remove notifier from rfkill notifier chain
79 * @nb: pointer to the entry to remove from the chain
80 *
81 * See blocking_notifier_chain_unregister() for return value and further
82 * observations.
83 *
84 * Removes a notifier from the rfkill notifier chain.
85 */
86int unregister_rfkill_notifier(struct notifier_block *nb)
87{
88 return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
89}
90EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
91
44 92
45static void rfkill_led_trigger(struct rfkill *rfkill, 93static void rfkill_led_trigger(struct rfkill *rfkill,
46 enum rfkill_state state) 94 enum rfkill_state state)
@@ -50,24 +98,99 @@ static void rfkill_led_trigger(struct rfkill *rfkill,
50 98
51 if (!led->name) 99 if (!led->name)
52 return; 100 return;
53 if (state == RFKILL_STATE_OFF) 101 if (state != RFKILL_STATE_UNBLOCKED)
54 led_trigger_event(led, LED_OFF); 102 led_trigger_event(led, LED_OFF);
55 else 103 else
56 led_trigger_event(led, LED_FULL); 104 led_trigger_event(led, LED_FULL);
57#endif /* CONFIG_RFKILL_LEDS */ 105#endif /* CONFIG_RFKILL_LEDS */
58} 106}
59 107
108static void notify_rfkill_state_change(struct rfkill *rfkill)
109{
110 blocking_notifier_call_chain(&rfkill_notifier_list,
111 RFKILL_STATE_CHANGED,
112 rfkill);
113}
114
115static void update_rfkill_state(struct rfkill *rfkill)
116{
117 enum rfkill_state newstate, oldstate;
118
119 if (rfkill->get_state) {
120 mutex_lock(&rfkill->mutex);
121 if (!rfkill->get_state(rfkill->data, &newstate)) {
122 oldstate = rfkill->state;
123 rfkill->state = newstate;
124 if (oldstate != newstate)
125 notify_rfkill_state_change(rfkill);
126 }
127 mutex_unlock(&rfkill->mutex);
128 }
129}
130
131/**
132 * rfkill_toggle_radio - wrapper for toggle_radio hook
133 * calls toggle_radio taking into account a lot of "small"
134 * details.
135 * @rfkill: the rfkill struct to use
136 * @force: calls toggle_radio even if cache says it is not needed,
137 * and also makes sure notifications of the state will be
138 * sent even if it didn't change
139 * @state: the new state to call toggle_radio() with
140 *
141 * This wrappen protects and enforces the API for toggle_radio
142 * calls. Note that @force cannot override a (possibly cached)
143 * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of
144 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or
145 * rfkill_force_state(), so the cache either is bypassed or valid.
146 *
147 * Note that we do call toggle_radio for RFKILL_STATE_SOFT_BLOCKED
148 * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to
149 * give the driver a hint that it should double-BLOCK the transmitter.
150 *
151 * Caller must have aquired rfkill_mutex.
152 */
60static int rfkill_toggle_radio(struct rfkill *rfkill, 153static int rfkill_toggle_radio(struct rfkill *rfkill,
61 enum rfkill_state state) 154 enum rfkill_state state,
155 int force)
62{ 156{
63 int retval = 0; 157 int retval = 0;
158 enum rfkill_state oldstate, newstate;
159
160 oldstate = rfkill->state;
64 161
65 if (state != rfkill->state) { 162 if (rfkill->get_state && !force &&
163 !rfkill->get_state(rfkill->data, &newstate))
164 rfkill->state = newstate;
165
166 switch (state) {
167 case RFKILL_STATE_HARD_BLOCKED:
168 /* typically happens when refreshing hardware state,
169 * such as on resume */
170 state = RFKILL_STATE_SOFT_BLOCKED;
171 break;
172 case RFKILL_STATE_UNBLOCKED:
173 /* force can't override this, only rfkill_force_state() can */
174 if (rfkill->state == RFKILL_STATE_HARD_BLOCKED)
175 return -EPERM;
176 break;
177 case RFKILL_STATE_SOFT_BLOCKED:
178 /* nothing to do, we want to give drivers the hint to double
179 * BLOCK even a transmitter that is already in state
180 * RFKILL_STATE_HARD_BLOCKED */
181 break;
182 }
183
184 if (force || state != rfkill->state) {
66 retval = rfkill->toggle_radio(rfkill->data, state); 185 retval = rfkill->toggle_radio(rfkill->data, state);
67 if (!retval) { 186 /* never allow a HARD->SOFT downgrade! */
187 if (!retval && rfkill->state != RFKILL_STATE_HARD_BLOCKED)
68 rfkill->state = state; 188 rfkill->state = state;
69 rfkill_led_trigger(rfkill, state); 189 }
70 } 190
191 if (force || rfkill->state != oldstate) {
192 rfkill_led_trigger(rfkill, rfkill->state);
193 notify_rfkill_state_change(rfkill);
71 } 194 }
72 195
73 return retval; 196 return retval;
@@ -82,7 +205,6 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
82 * a specific switch is claimed by userspace in which case it is 205 * a specific switch is claimed by userspace in which case it is
83 * left alone. 206 * left alone.
84 */ 207 */
85
86void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) 208void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
87{ 209{
88 struct rfkill *rfkill; 210 struct rfkill *rfkill;
@@ -93,13 +215,66 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
93 215
94 list_for_each_entry(rfkill, &rfkill_list, node) { 216 list_for_each_entry(rfkill, &rfkill_list, node) {
95 if ((!rfkill->user_claim) && (rfkill->type == type)) 217 if ((!rfkill->user_claim) && (rfkill->type == type))
96 rfkill_toggle_radio(rfkill, state); 218 rfkill_toggle_radio(rfkill, state, 0);
97 } 219 }
98 220
99 mutex_unlock(&rfkill_mutex); 221 mutex_unlock(&rfkill_mutex);
100} 222}
101EXPORT_SYMBOL(rfkill_switch_all); 223EXPORT_SYMBOL(rfkill_switch_all);
102 224
225/**
226 * rfkill_epo - emergency power off all transmitters
227 *
228 * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring
229 * everything in its path but rfkill_mutex.
230 */
231void rfkill_epo(void)
232{
233 struct rfkill *rfkill;
234
235 mutex_lock(&rfkill_mutex);
236 list_for_each_entry(rfkill, &rfkill_list, node) {
237 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
238 }
239 mutex_unlock(&rfkill_mutex);
240}
241EXPORT_SYMBOL_GPL(rfkill_epo);
242
243/**
244 * rfkill_force_state - Force the internal rfkill radio state
245 * @rfkill: pointer to the rfkill class to modify.
246 * @state: the current radio state the class should be forced to.
247 *
248 * This function updates the internal state of the radio cached
249 * by the rfkill class. It should be used when the driver gets
250 * a notification by the firmware/hardware of the current *real*
251 * state of the radio rfkill switch.
252 *
253 * It may not be called from an atomic context.
254 */
255int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
256{
257 enum rfkill_state oldstate;
258
259 if (state != RFKILL_STATE_SOFT_BLOCKED &&
260 state != RFKILL_STATE_UNBLOCKED &&
261 state != RFKILL_STATE_HARD_BLOCKED)
262 return -EINVAL;
263
264 mutex_lock(&rfkill->mutex);
265
266 oldstate = rfkill->state;
267 rfkill->state = state;
268
269 if (state != oldstate)
270 notify_rfkill_state_change(rfkill);
271
272 mutex_unlock(&rfkill->mutex);
273
274 return 0;
275}
276EXPORT_SYMBOL(rfkill_force_state);
277
103static ssize_t rfkill_name_show(struct device *dev, 278static ssize_t rfkill_name_show(struct device *dev,
104 struct device_attribute *attr, 279 struct device_attribute *attr,
105 char *buf) 280 char *buf)
@@ -109,31 +284,31 @@ static ssize_t rfkill_name_show(struct device *dev,
109 return sprintf(buf, "%s\n", rfkill->name); 284 return sprintf(buf, "%s\n", rfkill->name);
110} 285}
111 286
112static ssize_t rfkill_type_show(struct device *dev, 287static const char *rfkill_get_type_str(enum rfkill_type type)
113 struct device_attribute *attr,
114 char *buf)
115{ 288{
116 struct rfkill *rfkill = to_rfkill(dev); 289 switch (type) {
117 const char *type;
118
119 switch (rfkill->type) {
120 case RFKILL_TYPE_WLAN: 290 case RFKILL_TYPE_WLAN:
121 type = "wlan"; 291 return "wlan";
122 break;
123 case RFKILL_TYPE_BLUETOOTH: 292 case RFKILL_TYPE_BLUETOOTH:
124 type = "bluetooth"; 293 return "bluetooth";
125 break;
126 case RFKILL_TYPE_UWB: 294 case RFKILL_TYPE_UWB:
127 type = "ultrawideband"; 295 return "ultrawideband";
128 break;
129 case RFKILL_TYPE_WIMAX: 296 case RFKILL_TYPE_WIMAX:
130 type = "wimax"; 297 return "wimax";
131 break; 298 case RFKILL_TYPE_WWAN:
299 return "wwan";
132 default: 300 default:
133 BUG(); 301 BUG();
134 } 302 }
303}
304
305static ssize_t rfkill_type_show(struct device *dev,
306 struct device_attribute *attr,
307 char *buf)
308{
309 struct rfkill *rfkill = to_rfkill(dev);
135 310
136 return sprintf(buf, "%s\n", type); 311 return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type));
137} 312}
138 313
139static ssize_t rfkill_state_show(struct device *dev, 314static ssize_t rfkill_state_show(struct device *dev,
@@ -142,6 +317,7 @@ static ssize_t rfkill_state_show(struct device *dev,
142{ 317{
143 struct rfkill *rfkill = to_rfkill(dev); 318 struct rfkill *rfkill = to_rfkill(dev);
144 319
320 update_rfkill_state(rfkill);
145 return sprintf(buf, "%d\n", rfkill->state); 321 return sprintf(buf, "%d\n", rfkill->state);
146} 322}
147 323
@@ -156,10 +332,14 @@ static ssize_t rfkill_state_store(struct device *dev,
156 if (!capable(CAP_NET_ADMIN)) 332 if (!capable(CAP_NET_ADMIN))
157 return -EPERM; 333 return -EPERM;
158 334
335 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
336 if (state != RFKILL_STATE_UNBLOCKED &&
337 state != RFKILL_STATE_SOFT_BLOCKED)
338 return -EINVAL;
339
159 if (mutex_lock_interruptible(&rfkill->mutex)) 340 if (mutex_lock_interruptible(&rfkill->mutex))
160 return -ERESTARTSYS; 341 return -ERESTARTSYS;
161 error = rfkill_toggle_radio(rfkill, 342 error = rfkill_toggle_radio(rfkill, state, 0);
162 state ? RFKILL_STATE_ON : RFKILL_STATE_OFF);
163 mutex_unlock(&rfkill->mutex); 343 mutex_unlock(&rfkill->mutex);
164 344
165 return error ? error : count; 345 return error ? error : count;
@@ -200,7 +380,8 @@ static ssize_t rfkill_claim_store(struct device *dev,
200 if (rfkill->user_claim != claim) { 380 if (rfkill->user_claim != claim) {
201 if (!claim) 381 if (!claim)
202 rfkill_toggle_radio(rfkill, 382 rfkill_toggle_radio(rfkill,
203 rfkill_states[rfkill->type]); 383 rfkill_states[rfkill->type],
384 0);
204 rfkill->user_claim = claim; 385 rfkill->user_claim = claim;
205 } 386 }
206 387
@@ -233,12 +414,12 @@ static int rfkill_suspend(struct device *dev, pm_message_t state)
233 414
234 if (dev->power.power_state.event != state.event) { 415 if (dev->power.power_state.event != state.event) {
235 if (state.event & PM_EVENT_SLEEP) { 416 if (state.event & PM_EVENT_SLEEP) {
236 mutex_lock(&rfkill->mutex); 417 /* Stop transmitter, keep state, no notifies */
237 418 update_rfkill_state(rfkill);
238 if (rfkill->state == RFKILL_STATE_ON)
239 rfkill->toggle_radio(rfkill->data,
240 RFKILL_STATE_OFF);
241 419
420 mutex_lock(&rfkill->mutex);
421 rfkill->toggle_radio(rfkill->data,
422 RFKILL_STATE_SOFT_BLOCKED);
242 mutex_unlock(&rfkill->mutex); 423 mutex_unlock(&rfkill->mutex);
243 } 424 }
244 425
@@ -255,8 +436,8 @@ static int rfkill_resume(struct device *dev)
255 if (dev->power.power_state.event != PM_EVENT_ON) { 436 if (dev->power.power_state.event != PM_EVENT_ON) {
256 mutex_lock(&rfkill->mutex); 437 mutex_lock(&rfkill->mutex);
257 438
258 if (rfkill->state == RFKILL_STATE_ON) 439 /* restore radio state AND notify everybody */
259 rfkill->toggle_radio(rfkill->data, RFKILL_STATE_ON); 440 rfkill_toggle_radio(rfkill, rfkill->state, 1);
260 441
261 mutex_unlock(&rfkill->mutex); 442 mutex_unlock(&rfkill->mutex);
262 } 443 }
@@ -269,12 +450,51 @@ static int rfkill_resume(struct device *dev)
269#define rfkill_resume NULL 450#define rfkill_resume NULL
270#endif 451#endif
271 452
453static int rfkill_blocking_uevent_notifier(struct notifier_block *nb,
454 unsigned long eventid,
455 void *data)
456{
457 struct rfkill *rfkill = (struct rfkill *)data;
458
459 switch (eventid) {
460 case RFKILL_STATE_CHANGED:
461 kobject_uevent(&rfkill->dev.kobj, KOBJ_CHANGE);
462 break;
463 default:
464 break;
465 }
466
467 return NOTIFY_DONE;
468}
469
470static struct notifier_block rfkill_blocking_uevent_nb = {
471 .notifier_call = rfkill_blocking_uevent_notifier,
472 .priority = 0,
473};
474
475static int rfkill_dev_uevent(struct device *dev, struct kobj_uevent_env *env)
476{
477 struct rfkill *rfkill = to_rfkill(dev);
478 int error;
479
480 error = add_uevent_var(env, "RFKILL_NAME=%s", rfkill->name);
481 if (error)
482 return error;
483 error = add_uevent_var(env, "RFKILL_TYPE=%s",
484 rfkill_get_type_str(rfkill->type));
485 if (error)
486 return error;
487 error = add_uevent_var(env, "RFKILL_STATE=%d", rfkill->state);
488 return error;
489}
490
272static struct class rfkill_class = { 491static struct class rfkill_class = {
273 .name = "rfkill", 492 .name = "rfkill",
274 .dev_release = rfkill_release, 493 .dev_release = rfkill_release,
275 .dev_attrs = rfkill_dev_attrs, 494 .dev_attrs = rfkill_dev_attrs,
276 .suspend = rfkill_suspend, 495 .suspend = rfkill_suspend,
277 .resume = rfkill_resume, 496 .resume = rfkill_resume,
497 .dev_uevent = rfkill_dev_uevent,
278}; 498};
279 499
280static int rfkill_add_switch(struct rfkill *rfkill) 500static int rfkill_add_switch(struct rfkill *rfkill)
@@ -283,7 +503,7 @@ static int rfkill_add_switch(struct rfkill *rfkill)
283 503
284 mutex_lock(&rfkill_mutex); 504 mutex_lock(&rfkill_mutex);
285 505
286 error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type]); 506 error = rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0);
287 if (!error) 507 if (!error)
288 list_add_tail(&rfkill->node, &rfkill_list); 508 list_add_tail(&rfkill->node, &rfkill_list);
289 509
@@ -296,7 +516,7 @@ static void rfkill_remove_switch(struct rfkill *rfkill)
296{ 516{
297 mutex_lock(&rfkill_mutex); 517 mutex_lock(&rfkill_mutex);
298 list_del_init(&rfkill->node); 518 list_del_init(&rfkill->node);
299 rfkill_toggle_radio(rfkill, RFKILL_STATE_OFF); 519 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
300 mutex_unlock(&rfkill_mutex); 520 mutex_unlock(&rfkill_mutex);
301} 521}
302 522
@@ -412,7 +632,7 @@ int rfkill_register(struct rfkill *rfkill)
412EXPORT_SYMBOL(rfkill_register); 632EXPORT_SYMBOL(rfkill_register);
413 633
414/** 634/**
415 * rfkill_unregister - Uegister a rfkill structure. 635 * rfkill_unregister - Unregister a rfkill structure.
416 * @rfkill: rfkill structure to be unregistered 636 * @rfkill: rfkill structure to be unregistered
417 * 637 *
418 * This function should be called by the network driver during device 638 * This function should be called by the network driver during device
@@ -436,8 +656,13 @@ static int __init rfkill_init(void)
436 int error; 656 int error;
437 int i; 657 int i;
438 658
659 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
660 if (rfkill_default_state != RFKILL_STATE_SOFT_BLOCKED &&
661 rfkill_default_state != RFKILL_STATE_UNBLOCKED)
662 return -EINVAL;
663
439 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++) 664 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++)
440 rfkill_states[i] = RFKILL_STATE_ON; 665 rfkill_states[i] = rfkill_default_state;
441 666
442 error = class_register(&rfkill_class); 667 error = class_register(&rfkill_class);
443 if (error) { 668 if (error) {
@@ -445,11 +670,14 @@ static int __init rfkill_init(void)
445 return error; 670 return error;
446 } 671 }
447 672
673 register_rfkill_notifier(&rfkill_blocking_uevent_nb);
674
448 return 0; 675 return 0;
449} 676}
450 677
451static void __exit rfkill_exit(void) 678static void __exit rfkill_exit(void)
452{ 679{
680 unregister_rfkill_notifier(&rfkill_blocking_uevent_nb);
453 class_unregister(&rfkill_class); 681 class_unregister(&rfkill_class);
454} 682}
455 683
diff --git a/net/socket.c b/net/socket.c
index 66c4a8cf6db9..81fe82513046 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -90,6 +90,7 @@
90#include <asm/unistd.h> 90#include <asm/unistd.h>
91 91
92#include <net/compat.h> 92#include <net/compat.h>
93#include <net/wext.h>
93 94
94#include <net/sock.h> 95#include <net/sock.h>
95#include <linux/netfilter.h> 96#include <linux/netfilter.h>
@@ -2210,10 +2211,19 @@ static long compat_sock_ioctl(struct file *file, unsigned cmd,
2210{ 2211{
2211 struct socket *sock = file->private_data; 2212 struct socket *sock = file->private_data;
2212 int ret = -ENOIOCTLCMD; 2213 int ret = -ENOIOCTLCMD;
2214 struct sock *sk;
2215 struct net *net;
2216
2217 sk = sock->sk;
2218 net = sock_net(sk);
2213 2219
2214 if (sock->ops->compat_ioctl) 2220 if (sock->ops->compat_ioctl)
2215 ret = sock->ops->compat_ioctl(sock, cmd, arg); 2221 ret = sock->ops->compat_ioctl(sock, cmd, arg);
2216 2222
2223 if (ret == -ENOIOCTLCMD &&
2224 (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST))
2225 ret = compat_wext_handle_ioctl(net, cmd, arg);
2226
2217 return ret; 2227 return ret;
2218} 2228}
2219#endif 2229#endif
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index 947188a5b937..273a84359998 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -500,7 +500,7 @@ static int call_commit_handler(struct net_device *dev)
500/* 500/*
501 * Calculate size of private arguments 501 * Calculate size of private arguments
502 */ 502 */
503static inline int get_priv_size(__u16 args) 503static int get_priv_size(__u16 args)
504{ 504{
505 int num = args & IW_PRIV_SIZE_MASK; 505 int num = args & IW_PRIV_SIZE_MASK;
506 int type = (args & IW_PRIV_TYPE_MASK) >> 12; 506 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
@@ -512,10 +512,9 @@ static inline int get_priv_size(__u16 args)
512/* 512/*
513 * Re-calculate the size of private arguments 513 * Re-calculate the size of private arguments
514 */ 514 */
515static inline int adjust_priv_size(__u16 args, 515static int adjust_priv_size(__u16 args, struct iw_point *iwp)
516 union iwreq_data * wrqu)
517{ 516{
518 int num = wrqu->data.length; 517 int num = iwp->length;
519 int max = args & IW_PRIV_SIZE_MASK; 518 int max = args & IW_PRIV_SIZE_MASK;
520 int type = (args & IW_PRIV_TYPE_MASK) >> 12; 519 int type = (args & IW_PRIV_TYPE_MASK) >> 12;
521 520
@@ -695,19 +694,150 @@ void wext_proc_exit(struct net *net)
695 */ 694 */
696 695
697/* ---------------------------------------------------------------- */ 696/* ---------------------------------------------------------------- */
697static int ioctl_standard_iw_point(struct iw_point *iwp, unsigned int cmd,
698 const struct iw_ioctl_description *descr,
699 iw_handler handler, struct net_device *dev,
700 struct iw_request_info *info)
701{
702 int err, extra_size, user_length = 0, essid_compat = 0;
703 char *extra;
704
705 /* Calculate space needed by arguments. Always allocate
706 * for max space.
707 */
708 extra_size = descr->max_tokens * descr->token_size;
709
710 /* Check need for ESSID compatibility for WE < 21 */
711 switch (cmd) {
712 case SIOCSIWESSID:
713 case SIOCGIWESSID:
714 case SIOCSIWNICKN:
715 case SIOCGIWNICKN:
716 if (iwp->length == descr->max_tokens + 1)
717 essid_compat = 1;
718 else if (IW_IS_SET(cmd) && (iwp->length != 0)) {
719 char essid[IW_ESSID_MAX_SIZE + 1];
720
721 err = copy_from_user(essid, iwp->pointer,
722 iwp->length *
723 descr->token_size);
724 if (err)
725 return -EFAULT;
726
727 if (essid[iwp->length - 1] == '\0')
728 essid_compat = 1;
729 }
730 break;
731 default:
732 break;
733 }
734
735 iwp->length -= essid_compat;
736
737 /* Check what user space is giving us */
738 if (IW_IS_SET(cmd)) {
739 /* Check NULL pointer */
740 if (!iwp->pointer && iwp->length != 0)
741 return -EFAULT;
742 /* Check if number of token fits within bounds */
743 if (iwp->length > descr->max_tokens)
744 return -E2BIG;
745 if (iwp->length < descr->min_tokens)
746 return -EINVAL;
747 } else {
748 /* Check NULL pointer */
749 if (!iwp->pointer)
750 return -EFAULT;
751 /* Save user space buffer size for checking */
752 user_length = iwp->length;
753
754 /* Don't check if user_length > max to allow forward
755 * compatibility. The test user_length < min is
756 * implied by the test at the end.
757 */
758
759 /* Support for very large requests */
760 if ((descr->flags & IW_DESCR_FLAG_NOMAX) &&
761 (user_length > descr->max_tokens)) {
762 /* Allow userspace to GET more than max so
763 * we can support any size GET requests.
764 * There is still a limit : -ENOMEM.
765 */
766 extra_size = user_length * descr->token_size;
767
768 /* Note : user_length is originally a __u16,
769 * and token_size is controlled by us,
770 * so extra_size won't get negative and
771 * won't overflow...
772 */
773 }
774 }
775
776 /* kzalloc() ensures NULL-termination for essid_compat. */
777 extra = kzalloc(extra_size, GFP_KERNEL);
778 if (!extra)
779 return -ENOMEM;
780
781 /* If it is a SET, get all the extra data in here */
782 if (IW_IS_SET(cmd) && (iwp->length != 0)) {
783 if (copy_from_user(extra, iwp->pointer,
784 iwp->length *
785 descr->token_size)) {
786 err = -EFAULT;
787 goto out;
788 }
789 }
790
791 err = handler(dev, info, (union iwreq_data *) iwp, extra);
792
793 iwp->length += essid_compat;
794
795 /* If we have something to return to the user */
796 if (!err && IW_IS_GET(cmd)) {
797 /* Check if there is enough buffer up there */
798 if (user_length < iwp->length) {
799 err = -E2BIG;
800 goto out;
801 }
802
803 if (copy_to_user(iwp->pointer, extra,
804 iwp->length *
805 descr->token_size)) {
806 err = -EFAULT;
807 goto out;
808 }
809 }
810
811 /* Generate an event to notify listeners of the change */
812 if ((descr->flags & IW_DESCR_FLAG_EVENT) && err == -EIWCOMMIT) {
813 union iwreq_data *data = (union iwreq_data *) iwp;
814
815 if (descr->flags & IW_DESCR_FLAG_RESTRICT)
816 /* If the event is restricted, don't
817 * export the payload.
818 */
819 wireless_send_event(dev, cmd, data, NULL);
820 else
821 wireless_send_event(dev, cmd, data, extra);
822 }
823
824out:
825 kfree(extra);
826 return err;
827}
828
698/* 829/*
699 * Wrapper to call a standard Wireless Extension handler. 830 * Wrapper to call a standard Wireless Extension handler.
700 * We do various checks and also take care of moving data between 831 * We do various checks and also take care of moving data between
701 * user space and kernel space. 832 * user space and kernel space.
702 */ 833 */
703static int ioctl_standard_call(struct net_device * dev, 834static int ioctl_standard_call(struct net_device * dev,
704 struct ifreq * ifr, 835 struct iwreq *iwr,
705 unsigned int cmd, 836 unsigned int cmd,
837 struct iw_request_info *info,
706 iw_handler handler) 838 iw_handler handler)
707{ 839{
708 struct iwreq * iwr = (struct iwreq *) ifr;
709 const struct iw_ioctl_description * descr; 840 const struct iw_ioctl_description * descr;
710 struct iw_request_info info;
711 int ret = -EINVAL; 841 int ret = -EINVAL;
712 842
713 /* Get the description of the IOCTL */ 843 /* Get the description of the IOCTL */
@@ -715,145 +845,19 @@ static int ioctl_standard_call(struct net_device * dev,
715 return -EOPNOTSUPP; 845 return -EOPNOTSUPP;
716 descr = &(standard_ioctl[cmd - SIOCIWFIRST]); 846 descr = &(standard_ioctl[cmd - SIOCIWFIRST]);
717 847
718 /* Prepare the call */
719 info.cmd = cmd;
720 info.flags = 0;
721
722 /* Check if we have a pointer to user space data or not */ 848 /* Check if we have a pointer to user space data or not */
723 if (descr->header_type != IW_HEADER_TYPE_POINT) { 849 if (descr->header_type != IW_HEADER_TYPE_POINT) {
724 850
725 /* No extra arguments. Trivial to handle */ 851 /* No extra arguments. Trivial to handle */
726 ret = handler(dev, &info, &(iwr->u), NULL); 852 ret = handler(dev, info, &(iwr->u), NULL);
727 853
728 /* Generate an event to notify listeners of the change */ 854 /* Generate an event to notify listeners of the change */
729 if ((descr->flags & IW_DESCR_FLAG_EVENT) && 855 if ((descr->flags & IW_DESCR_FLAG_EVENT) &&
730 ((ret == 0) || (ret == -EIWCOMMIT))) 856 ((ret == 0) || (ret == -EIWCOMMIT)))
731 wireless_send_event(dev, cmd, &(iwr->u), NULL); 857 wireless_send_event(dev, cmd, &(iwr->u), NULL);
732 } else { 858 } else {
733 char * extra; 859 ret = ioctl_standard_iw_point(&iwr->u.data, cmd, descr,
734 int extra_size; 860 handler, dev, info);
735 int user_length = 0;
736 int err;
737 int essid_compat = 0;
738
739 /* Calculate space needed by arguments. Always allocate
740 * for max space. Easier, and won't last long... */
741 extra_size = descr->max_tokens * descr->token_size;
742
743 /* Check need for ESSID compatibility for WE < 21 */
744 switch (cmd) {
745 case SIOCSIWESSID:
746 case SIOCGIWESSID:
747 case SIOCSIWNICKN:
748 case SIOCGIWNICKN:
749 if (iwr->u.data.length == descr->max_tokens + 1)
750 essid_compat = 1;
751 else if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
752 char essid[IW_ESSID_MAX_SIZE + 1];
753
754 err = copy_from_user(essid, iwr->u.data.pointer,
755 iwr->u.data.length *
756 descr->token_size);
757 if (err)
758 return -EFAULT;
759
760 if (essid[iwr->u.data.length - 1] == '\0')
761 essid_compat = 1;
762 }
763 break;
764 default:
765 break;
766 }
767
768 iwr->u.data.length -= essid_compat;
769
770 /* Check what user space is giving us */
771 if (IW_IS_SET(cmd)) {
772 /* Check NULL pointer */
773 if ((iwr->u.data.pointer == NULL) &&
774 (iwr->u.data.length != 0))
775 return -EFAULT;
776 /* Check if number of token fits within bounds */
777 if (iwr->u.data.length > descr->max_tokens)
778 return -E2BIG;
779 if (iwr->u.data.length < descr->min_tokens)
780 return -EINVAL;
781 } else {
782 /* Check NULL pointer */
783 if (iwr->u.data.pointer == NULL)
784 return -EFAULT;
785 /* Save user space buffer size for checking */
786 user_length = iwr->u.data.length;
787
788 /* Don't check if user_length > max to allow forward
789 * compatibility. The test user_length < min is
790 * implied by the test at the end. */
791
792 /* Support for very large requests */
793 if ((descr->flags & IW_DESCR_FLAG_NOMAX) &&
794 (user_length > descr->max_tokens)) {
795 /* Allow userspace to GET more than max so
796 * we can support any size GET requests.
797 * There is still a limit : -ENOMEM. */
798 extra_size = user_length * descr->token_size;
799 /* Note : user_length is originally a __u16,
800 * and token_size is controlled by us,
801 * so extra_size won't get negative and
802 * won't overflow... */
803 }
804 }
805
806 /* Create the kernel buffer */
807 /* kzalloc ensures NULL-termination for essid_compat */
808 extra = kzalloc(extra_size, GFP_KERNEL);
809 if (extra == NULL)
810 return -ENOMEM;
811
812 /* If it is a SET, get all the extra data in here */
813 if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
814 err = copy_from_user(extra, iwr->u.data.pointer,
815 iwr->u.data.length *
816 descr->token_size);
817 if (err) {
818 kfree(extra);
819 return -EFAULT;
820 }
821 }
822
823 /* Call the handler */
824 ret = handler(dev, &info, &(iwr->u), extra);
825
826 iwr->u.data.length += essid_compat;
827
828 /* If we have something to return to the user */
829 if (!ret && IW_IS_GET(cmd)) {
830 /* Check if there is enough buffer up there */
831 if (user_length < iwr->u.data.length) {
832 kfree(extra);
833 return -E2BIG;
834 }
835
836 err = copy_to_user(iwr->u.data.pointer, extra,
837 iwr->u.data.length *
838 descr->token_size);
839 if (err)
840 ret = -EFAULT;
841 }
842
843 /* Generate an event to notify listeners of the change */
844 if ((descr->flags & IW_DESCR_FLAG_EVENT) &&
845 ((ret == 0) || (ret == -EIWCOMMIT))) {
846 if (descr->flags & IW_DESCR_FLAG_RESTRICT)
847 /* If the event is restricted, don't
848 * export the payload */
849 wireless_send_event(dev, cmd, &(iwr->u), NULL);
850 else
851 wireless_send_event(dev, cmd, &(iwr->u),
852 extra);
853 }
854
855 /* Cleanup - I told you it wasn't that long ;-) */
856 kfree(extra);
857 } 861 }
858 862
859 /* Call commit handler if needed and defined */ 863 /* Call commit handler if needed and defined */
@@ -881,25 +885,22 @@ static int ioctl_standard_call(struct net_device * dev,
881 * a iw_handler but process it in your ioctl handler (i.e. use the 885 * a iw_handler but process it in your ioctl handler (i.e. use the
882 * old driver API). 886 * old driver API).
883 */ 887 */
884static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr, 888static int get_priv_descr_and_size(struct net_device *dev, unsigned int cmd,
885 unsigned int cmd, iw_handler handler) 889 const struct iw_priv_args **descrp)
886{ 890{
887 struct iwreq * iwr = (struct iwreq *) ifr; 891 const struct iw_priv_args *descr;
888 const struct iw_priv_args * descr = NULL; 892 int i, extra_size;
889 struct iw_request_info info;
890 int extra_size = 0;
891 int i;
892 int ret = -EINVAL;
893 893
894 /* Get the description of the IOCTL */ 894 descr = NULL;
895 for (i = 0; i < dev->wireless_handlers->num_private_args; i++) 895 for (i = 0; i < dev->wireless_handlers->num_private_args; i++) {
896 if (cmd == dev->wireless_handlers->private_args[i].cmd) { 896 if (cmd == dev->wireless_handlers->private_args[i].cmd) {
897 descr = &(dev->wireless_handlers->private_args[i]); 897 descr = &dev->wireless_handlers->private_args[i];
898 break; 898 break;
899 } 899 }
900 }
900 901
901 /* Compute the size of the set/get arguments */ 902 extra_size = 0;
902 if (descr != NULL) { 903 if (descr) {
903 if (IW_IS_SET(cmd)) { 904 if (IW_IS_SET(cmd)) {
904 int offset = 0; /* For sub-ioctls */ 905 int offset = 0; /* For sub-ioctls */
905 /* Check for sub-ioctl handler */ 906 /* Check for sub-ioctl handler */
@@ -924,72 +925,77 @@ static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr,
924 extra_size = 0; 925 extra_size = 0;
925 } 926 }
926 } 927 }
928 *descrp = descr;
929 return extra_size;
930}
927 931
928 /* Prepare the call */ 932static int ioctl_private_iw_point(struct iw_point *iwp, unsigned int cmd,
929 info.cmd = cmd; 933 const struct iw_priv_args *descr,
930 info.flags = 0; 934 iw_handler handler, struct net_device *dev,
935 struct iw_request_info *info, int extra_size)
936{
937 char *extra;
938 int err;
931 939
932 /* Check if we have a pointer to user space data or not. */ 940 /* Check what user space is giving us */
933 if (extra_size == 0) { 941 if (IW_IS_SET(cmd)) {
934 /* No extra arguments. Trivial to handle */ 942 if (!iwp->pointer && iwp->length != 0)
935 ret = handler(dev, &info, &(iwr->u), (char *) &(iwr->u)); 943 return -EFAULT;
936 } else {
937 char * extra;
938 int err;
939 944
940 /* Check what user space is giving us */ 945 if (iwp->length > (descr->set_args & IW_PRIV_SIZE_MASK))
941 if (IW_IS_SET(cmd)) { 946 return -E2BIG;
942 /* Check NULL pointer */ 947 } else if (!iwp->pointer)
943 if ((iwr->u.data.pointer == NULL) && 948 return -EFAULT;
944 (iwr->u.data.length != 0))
945 return -EFAULT;
946 949
947 /* Does it fits within bounds ? */ 950 extra = kmalloc(extra_size, GFP_KERNEL);
948 if (iwr->u.data.length > (descr->set_args & 951 if (!extra)
949 IW_PRIV_SIZE_MASK)) 952 return -ENOMEM;
950 return -E2BIG;
951 } else if (iwr->u.data.pointer == NULL)
952 return -EFAULT;
953 953
954 /* Always allocate for max space. Easier, and won't last 954 /* If it is a SET, get all the extra data in here */
955 * long... */ 955 if (IW_IS_SET(cmd) && (iwp->length != 0)) {
956 extra = kmalloc(extra_size, GFP_KERNEL); 956 if (copy_from_user(extra, iwp->pointer, extra_size)) {
957 if (extra == NULL) 957 err = -EFAULT;
958 return -ENOMEM; 958 goto out;
959
960 /* If it is a SET, get all the extra data in here */
961 if (IW_IS_SET(cmd) && (iwr->u.data.length != 0)) {
962 err = copy_from_user(extra, iwr->u.data.pointer,
963 extra_size);
964 if (err) {
965 kfree(extra);
966 return -EFAULT;
967 }
968 } 959 }
960 }
969 961
970 /* Call the handler */ 962 /* Call the handler */
971 ret = handler(dev, &info, &(iwr->u), extra); 963 err = handler(dev, info, (union iwreq_data *) iwp, extra);
972 964
973 /* If we have something to return to the user */ 965 /* If we have something to return to the user */
974 if (!ret && IW_IS_GET(cmd)) { 966 if (!err && IW_IS_GET(cmd)) {
967 /* Adjust for the actual length if it's variable,
968 * avoid leaking kernel bits outside.
969 */
970 if (!(descr->get_args & IW_PRIV_SIZE_FIXED))
971 extra_size = adjust_priv_size(descr->get_args, iwp);
975 972
976 /* Adjust for the actual length if it's variable, 973 if (copy_to_user(iwp->pointer, extra, extra_size))
977 * avoid leaking kernel bits outside. */ 974 err = -EFAULT;
978 if (!(descr->get_args & IW_PRIV_SIZE_FIXED)) { 975 }
979 extra_size = adjust_priv_size(descr->get_args,
980 &(iwr->u));
981 }
982 976
983 err = copy_to_user(iwr->u.data.pointer, extra, 977out:
984 extra_size); 978 kfree(extra);
985 if (err) 979 return err;
986 ret = -EFAULT; 980}
987 }
988 981
989 /* Cleanup - I told you it wasn't that long ;-) */ 982static int ioctl_private_call(struct net_device *dev, struct iwreq *iwr,
990 kfree(extra); 983 unsigned int cmd, struct iw_request_info *info,
991 } 984 iw_handler handler)
985{
986 int extra_size = 0, ret = -EINVAL;
987 const struct iw_priv_args *descr;
992 988
989 extra_size = get_priv_descr_and_size(dev, cmd, &descr);
990
991 /* Check if we have a pointer to user space data or not. */
992 if (extra_size == 0) {
993 /* No extra arguments. Trivial to handle */
994 ret = handler(dev, info, &(iwr->u), (char *) &(iwr->u));
995 } else {
996 ret = ioctl_private_iw_point(&iwr->u.data, cmd, descr,
997 handler, dev, info, extra_size);
998 }
993 999
994 /* Call commit handler if needed and defined */ 1000 /* Call commit handler if needed and defined */
995 if (ret == -EIWCOMMIT) 1001 if (ret == -EIWCOMMIT)
@@ -999,12 +1005,21 @@ static int ioctl_private_call(struct net_device *dev, struct ifreq *ifr,
999} 1005}
1000 1006
1001/* ---------------------------------------------------------------- */ 1007/* ---------------------------------------------------------------- */
1008typedef int (*wext_ioctl_func)(struct net_device *, struct iwreq *,
1009 unsigned int, struct iw_request_info *,
1010 iw_handler);
1011
1002/* 1012/*
1003 * Main IOCTl dispatcher. 1013 * Main IOCTl dispatcher.
1004 * Check the type of IOCTL and call the appropriate wrapper... 1014 * Check the type of IOCTL and call the appropriate wrapper...
1005 */ 1015 */
1006static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd) 1016static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
1017 unsigned int cmd,
1018 struct iw_request_info *info,
1019 wext_ioctl_func standard,
1020 wext_ioctl_func private)
1007{ 1021{
1022 struct iwreq *iwr = (struct iwreq *) ifr;
1008 struct net_device *dev; 1023 struct net_device *dev;
1009 iw_handler handler; 1024 iw_handler handler;
1010 1025
@@ -1019,12 +1034,12 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned i
1019 * Note that 'cmd' is already filtered in dev_ioctl() with 1034 * Note that 'cmd' is already filtered in dev_ioctl() with
1020 * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */ 1035 * (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) */
1021 if (cmd == SIOCGIWSTATS) 1036 if (cmd == SIOCGIWSTATS)
1022 return ioctl_standard_call(dev, ifr, cmd, 1037 return standard(dev, iwr, cmd, info,
1023 &iw_handler_get_iwstats); 1038 &iw_handler_get_iwstats);
1024 1039
1025 if (cmd == SIOCGIWPRIV && dev->wireless_handlers) 1040 if (cmd == SIOCGIWPRIV && dev->wireless_handlers)
1026 return ioctl_standard_call(dev, ifr, cmd, 1041 return standard(dev, iwr, cmd, info,
1027 &iw_handler_get_private); 1042 &iw_handler_get_private);
1028 1043
1029 /* Basic check */ 1044 /* Basic check */
1030 if (!netif_device_present(dev)) 1045 if (!netif_device_present(dev))
@@ -1035,9 +1050,9 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned i
1035 if (handler) { 1050 if (handler) {
1036 /* Standard and private are not the same */ 1051 /* Standard and private are not the same */
1037 if (cmd < SIOCIWFIRSTPRIV) 1052 if (cmd < SIOCIWFIRSTPRIV)
1038 return ioctl_standard_call(dev, ifr, cmd, handler); 1053 return standard(dev, iwr, cmd, info, handler);
1039 else 1054 else
1040 return ioctl_private_call(dev, ifr, cmd, handler); 1055 return private(dev, iwr, cmd, info, handler);
1041 } 1056 }
1042 /* Old driver API : call driver ioctl handler */ 1057 /* Old driver API : call driver ioctl handler */
1043 if (dev->do_ioctl) 1058 if (dev->do_ioctl)
@@ -1045,27 +1060,154 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr, unsigned i
1045 return -EOPNOTSUPP; 1060 return -EOPNOTSUPP;
1046} 1061}
1047 1062
1048/* entry point from dev ioctl */ 1063/* If command is `set a parameter', or `get the encoding parameters',
1049int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd, 1064 * check if the user has the right to do it.
1050 void __user *arg) 1065 */
1066static int wext_permission_check(unsigned int cmd)
1051{ 1067{
1052 int ret;
1053
1054 /* If command is `set a parameter', or
1055 * `get the encoding parameters', check if
1056 * the user has the right to do it */
1057 if ((IW_IS_SET(cmd) || cmd == SIOCGIWENCODE || cmd == SIOCGIWENCODEEXT) 1068 if ((IW_IS_SET(cmd) || cmd == SIOCGIWENCODE || cmd == SIOCGIWENCODEEXT)
1058 && !capable(CAP_NET_ADMIN)) 1069 && !capable(CAP_NET_ADMIN))
1059 return -EPERM; 1070 return -EPERM;
1060 1071
1072 return 0;
1073}
1074
1075/* entry point from dev ioctl */
1076static int wext_ioctl_dispatch(struct net *net, struct ifreq *ifr,
1077 unsigned int cmd, struct iw_request_info *info,
1078 wext_ioctl_func standard,
1079 wext_ioctl_func private)
1080{
1081 int ret = wext_permission_check(cmd);
1082
1083 if (ret)
1084 return ret;
1085
1061 dev_load(net, ifr->ifr_name); 1086 dev_load(net, ifr->ifr_name);
1062 rtnl_lock(); 1087 rtnl_lock();
1063 ret = wireless_process_ioctl(net, ifr, cmd); 1088 ret = wireless_process_ioctl(net, ifr, cmd, info, standard, private);
1064 rtnl_unlock(); 1089 rtnl_unlock();
1065 if (IW_IS_GET(cmd) && copy_to_user(arg, ifr, sizeof(struct iwreq))) 1090
1091 return ret;
1092}
1093
1094int wext_handle_ioctl(struct net *net, struct ifreq *ifr, unsigned int cmd,
1095 void __user *arg)
1096{
1097 struct iw_request_info info = { .cmd = cmd, .flags = 0 };
1098 int ret;
1099
1100 ret = wext_ioctl_dispatch(net, ifr, cmd, &info,
1101 ioctl_standard_call,
1102 ioctl_private_call);
1103 if (ret >= 0 &&
1104 IW_IS_GET(cmd) &&
1105 copy_to_user(arg, ifr, sizeof(struct iwreq)))
1106 return -EFAULT;
1107
1108 return ret;
1109}
1110
1111#ifdef CONFIG_COMPAT
1112static int compat_standard_call(struct net_device *dev,
1113 struct iwreq *iwr,
1114 unsigned int cmd,
1115 struct iw_request_info *info,
1116 iw_handler handler)
1117{
1118 const struct iw_ioctl_description *descr;
1119 struct compat_iw_point *iwp_compat;
1120 struct iw_point iwp;
1121 int err;
1122
1123 descr = standard_ioctl + (cmd - SIOCIWFIRST);
1124
1125 if (descr->header_type != IW_HEADER_TYPE_POINT)
1126 return ioctl_standard_call(dev, iwr, cmd, info, handler);
1127
1128 iwp_compat = (struct compat_iw_point *) &iwr->u.data;
1129 iwp.pointer = compat_ptr(iwp_compat->pointer);
1130 iwp.length = iwp_compat->length;
1131 iwp.flags = iwp_compat->flags;
1132
1133 err = ioctl_standard_iw_point(&iwp, cmd, descr, handler, dev, info);
1134
1135 iwp_compat->pointer = ptr_to_compat(iwp.pointer);
1136 iwp_compat->length = iwp.length;
1137 iwp_compat->flags = iwp.flags;
1138
1139 return err;
1140}
1141
1142static int compat_private_call(struct net_device *dev, struct iwreq *iwr,
1143 unsigned int cmd, struct iw_request_info *info,
1144 iw_handler handler)
1145{
1146 const struct iw_priv_args *descr;
1147 int ret, extra_size;
1148
1149 extra_size = get_priv_descr_and_size(dev, cmd, &descr);
1150
1151 /* Check if we have a pointer to user space data or not. */
1152 if (extra_size == 0) {
1153 /* No extra arguments. Trivial to handle */
1154 ret = handler(dev, info, &(iwr->u), (char *) &(iwr->u));
1155 } else {
1156 struct compat_iw_point *iwp_compat;
1157 struct iw_point iwp;
1158
1159 iwp_compat = (struct compat_iw_point *) &iwr->u.data;
1160 iwp.pointer = compat_ptr(iwp_compat->pointer);
1161 iwp.length = iwp_compat->length;
1162 iwp.flags = iwp_compat->flags;
1163
1164 ret = ioctl_private_iw_point(&iwp, cmd, descr,
1165 handler, dev, info, extra_size);
1166
1167 iwp_compat->pointer = ptr_to_compat(iwp.pointer);
1168 iwp_compat->length = iwp.length;
1169 iwp_compat->flags = iwp.flags;
1170 }
1171
1172 /* Call commit handler if needed and defined */
1173 if (ret == -EIWCOMMIT)
1174 ret = call_commit_handler(dev);
1175
1176 return ret;
1177}
1178
1179int compat_wext_handle_ioctl(struct net *net, unsigned int cmd,
1180 unsigned long arg)
1181{
1182 void __user *argp = (void __user *)arg;
1183 struct iw_request_info info;
1184 struct iwreq iwr;
1185 char *colon;
1186 int ret;
1187
1188 if (copy_from_user(&iwr, argp, sizeof(struct iwreq)))
1189 return -EFAULT;
1190
1191 iwr.ifr_name[IFNAMSIZ-1] = 0;
1192 colon = strchr(iwr.ifr_name, ':');
1193 if (colon)
1194 *colon = 0;
1195
1196 info.cmd = cmd;
1197 info.flags = IW_REQUEST_FLAG_COMPAT;
1198
1199 ret = wext_ioctl_dispatch(net, (struct ifreq *) &iwr, cmd, &info,
1200 compat_standard_call,
1201 compat_private_call);
1202
1203 if (ret >= 0 &&
1204 IW_IS_GET(cmd) &&
1205 copy_to_user(argp, &iwr, sizeof(struct iwreq)))
1066 return -EFAULT; 1206 return -EFAULT;
1207
1067 return ret; 1208 return ret;
1068} 1209}
1210#endif
1069 1211
1070/************************* EVENT PROCESSING *************************/ 1212/************************* EVENT PROCESSING *************************/
1071/* 1213/*