diff options
Diffstat (limited to 'net/mac80211')
40 files changed, 2347 insertions, 2474 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index a24b459dd45..11a1e7fa195 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -7,14 +7,34 @@ config MAC80211 | |||
7 | select CRC32 | 7 | select CRC32 |
8 | select WIRELESS_EXT | 8 | select WIRELESS_EXT |
9 | select CFG80211 | 9 | select CFG80211 |
10 | select NET_SCH_FIFO | ||
11 | ---help--- | 10 | ---help--- |
12 | This option enables the hardware independent IEEE 802.11 | 11 | This option enables the hardware independent IEEE 802.11 |
13 | networking stack. | 12 | networking stack. |
14 | 13 | ||
14 | config MAC80211_QOS | ||
15 | def_bool y | ||
16 | depends on MAC80211 | ||
17 | depends on NET_SCHED | ||
18 | depends on NETDEVICES_MULTIQUEUE | ||
19 | |||
20 | comment "QoS/HT support disabled" | ||
21 | depends on MAC80211 && !MAC80211_QOS | ||
22 | comment "QoS/HT support needs CONFIG_NET_SCHED" | ||
23 | depends on MAC80211 && !NET_SCHED | ||
24 | comment "QoS/HT support needs CONFIG_NETDEVICES_MULTIQUEUE" | ||
25 | depends on MAC80211 && !NETDEVICES_MULTIQUEUE | ||
26 | |||
15 | menu "Rate control algorithm selection" | 27 | menu "Rate control algorithm selection" |
16 | depends on MAC80211 != n | 28 | depends on MAC80211 != n |
17 | 29 | ||
30 | config MAC80211_RC_PID | ||
31 | bool "PID controller based rate control algorithm" if EMBEDDED | ||
32 | default y | ||
33 | ---help--- | ||
34 | This option enables a TX rate control algorithm for | ||
35 | mac80211 that uses a PID controller to select the TX | ||
36 | rate. | ||
37 | |||
18 | choice | 38 | choice |
19 | prompt "Default rate control algorithm" | 39 | prompt "Default rate control algorithm" |
20 | default MAC80211_RC_DEFAULT_PID | 40 | default MAC80211_RC_DEFAULT_PID |
@@ -26,40 +46,19 @@ choice | |||
26 | 46 | ||
27 | config MAC80211_RC_DEFAULT_PID | 47 | config MAC80211_RC_DEFAULT_PID |
28 | bool "PID controller based rate control algorithm" | 48 | bool "PID controller based rate control algorithm" |
29 | select MAC80211_RC_PID | 49 | depends on MAC80211_RC_PID |
30 | ---help--- | 50 | ---help--- |
31 | Select the PID controller based rate control as the | 51 | Select the PID controller based rate control as the |
32 | default rate control algorithm. You should choose | 52 | default rate control algorithm. You should choose |
33 | this unless you know what you are doing. | 53 | this unless you know what you are doing. |
34 | 54 | ||
35 | config MAC80211_RC_DEFAULT_NONE | ||
36 | bool "No default algorithm" | ||
37 | depends on EMBEDDED | ||
38 | help | ||
39 | Selecting this option will select no default algorithm | ||
40 | and allow you to not build any. Do not choose this | ||
41 | option unless you know your driver comes with another | ||
42 | suitable algorithm. | ||
43 | endchoice | 55 | endchoice |
44 | 56 | ||
45 | comment "Selecting 'y' for an algorithm will" | ||
46 | comment "build the algorithm into mac80211." | ||
47 | |||
48 | config MAC80211_RC_DEFAULT | 57 | config MAC80211_RC_DEFAULT |
49 | string | 58 | string |
50 | default "pid" if MAC80211_RC_DEFAULT_PID | 59 | default "pid" if MAC80211_RC_DEFAULT_PID |
51 | default "" | 60 | default "" |
52 | 61 | ||
53 | config MAC80211_RC_PID | ||
54 | tristate "PID controller based rate control algorithm" | ||
55 | ---help--- | ||
56 | This option enables a TX rate control algorithm for | ||
57 | mac80211 that uses a PID controller to select the TX | ||
58 | rate. | ||
59 | |||
60 | Say Y or M unless you're sure you want to use a | ||
61 | different rate control algorithm. | ||
62 | |||
63 | endmenu | 62 | endmenu |
64 | 63 | ||
65 | config MAC80211_MESH | 64 | config MAC80211_MESH |
@@ -89,10 +88,16 @@ config MAC80211_DEBUGFS | |||
89 | 88 | ||
90 | Say N unless you know you need this. | 89 | Say N unless you know you need this. |
91 | 90 | ||
91 | menuconfig MAC80211_DEBUG_MENU | ||
92 | bool "Select mac80211 debugging features" | ||
93 | depends on MAC80211 | ||
94 | ---help--- | ||
95 | This option collects various mac80211 debug settings. | ||
96 | |||
92 | config MAC80211_DEBUG_PACKET_ALIGNMENT | 97 | config MAC80211_DEBUG_PACKET_ALIGNMENT |
93 | bool "Enable packet alignment debugging" | 98 | bool "Enable packet alignment debugging" |
94 | depends on MAC80211 | 99 | depends on MAC80211_DEBUG_MENU |
95 | help | 100 | ---help--- |
96 | This option is recommended for driver authors and strongly | 101 | This option is recommended for driver authors and strongly |
97 | discouraged for everybody else, it will trigger a warning | 102 | discouraged for everybody else, it will trigger a warning |
98 | when a driver hands mac80211 a buffer that is aligned in | 103 | when a driver hands mac80211 a buffer that is aligned in |
@@ -101,33 +106,95 @@ config MAC80211_DEBUG_PACKET_ALIGNMENT | |||
101 | 106 | ||
102 | Say N unless you're writing a mac80211 based driver. | 107 | Say N unless you're writing a mac80211 based driver. |
103 | 108 | ||
104 | config MAC80211_DEBUG | 109 | config MAC80211_NOINLINE |
105 | bool "Enable debugging output" | 110 | bool "Do not inline TX/RX handlers" |
106 | depends on MAC80211 | 111 | depends on MAC80211_DEBUG_MENU |
112 | ---help--- | ||
113 | This option affects code generation in mac80211, when | ||
114 | selected some functions are marked "noinline" to allow | ||
115 | easier debugging of problems in the transmit and receive | ||
116 | paths. | ||
117 | |||
118 | This option increases code size a bit and inserts a lot | ||
119 | of function calls in the code, but is otherwise safe to | ||
120 | enable. | ||
121 | |||
122 | If unsure, say N unless you expect to be finding problems | ||
123 | in mac80211. | ||
124 | |||
125 | config MAC80211_VERBOSE_DEBUG | ||
126 | bool "Verbose debugging output" | ||
127 | depends on MAC80211_DEBUG_MENU | ||
107 | ---help--- | 128 | ---help--- |
108 | This option will enable debug tracing output for the | 129 | Selecting this option causes mac80211 to print out |
109 | ieee80211 network stack. | 130 | many debugging messages. It should not be selected |
131 | on production systems as some of the messages are | ||
132 | remotely triggerable. | ||
110 | 133 | ||
111 | If you are not trying to debug or develop the ieee80211 | 134 | Do not select this option. |
112 | subsystem, you most likely want to say N here. | ||
113 | 135 | ||
114 | config MAC80211_HT_DEBUG | 136 | config MAC80211_HT_DEBUG |
115 | bool "Enable HT debugging output" | 137 | bool "Verbose HT debugging" |
116 | depends on MAC80211_DEBUG | 138 | depends on MAC80211_DEBUG_MENU |
117 | ---help--- | 139 | ---help--- |
118 | This option enables 802.11n High Throughput features | 140 | This option enables 802.11n High Throughput features |
119 | debug tracing output. | 141 | debug tracing output. |
120 | 142 | ||
121 | If you are not trying to debug of develop the ieee80211 | 143 | It should not be selected on production systems as some |
122 | subsystem, you most likely want to say N here. | 144 | of the messages are remotely triggerable. |
123 | 145 | ||
124 | config MAC80211_VERBOSE_DEBUG | 146 | Do not select this option. |
125 | bool "Verbose debugging output" | 147 | |
126 | depends on MAC80211_DEBUG | 148 | config MAC80211_TKIP_DEBUG |
149 | bool "Verbose TKIP debugging" | ||
150 | depends on MAC80211_DEBUG_MENU | ||
151 | ---help--- | ||
152 | Selecting this option causes mac80211 to print out | ||
153 | very verbose TKIP debugging messages. It should not | ||
154 | be selected on production systems as those messages | ||
155 | are remotely triggerable. | ||
156 | |||
157 | Do not select this option. | ||
158 | |||
159 | config MAC80211_IBSS_DEBUG | ||
160 | bool "Verbose IBSS debugging" | ||
161 | depends on MAC80211_DEBUG_MENU | ||
162 | ---help--- | ||
163 | Selecting this option causes mac80211 to print out | ||
164 | very verbose IBSS debugging messages. It should not | ||
165 | be selected on production systems as those messages | ||
166 | are remotely triggerable. | ||
167 | |||
168 | Do not select this option. | ||
169 | |||
170 | config MAC80211_VERBOSE_PS_DEBUG | ||
171 | bool "Verbose powersave mode debugging" | ||
172 | depends on MAC80211_DEBUG_MENU | ||
173 | ---help--- | ||
174 | Selecting this option causes mac80211 to print out very | ||
175 | verbose power save mode debugging messages (when mac80211 | ||
176 | is an AP and has power saving stations.) | ||
177 | It should not be selected on production systems as those | ||
178 | messages are remotely triggerable. | ||
179 | |||
180 | Do not select this option. | ||
181 | |||
182 | config MAC80211_VERBOSE_MPL_DEBUG | ||
183 | bool "Verbose mesh peer link debugging" | ||
184 | depends on MAC80211_DEBUG_MENU | ||
185 | depends on MAC80211_MESH | ||
186 | ---help--- | ||
187 | Selecting this option causes mac80211 to print out very | ||
188 | verbose mesh peer link debugging messages (when mac80211 | ||
189 | is taking part in a mesh network). | ||
190 | It should not be selected on production systems as those | ||
191 | messages are remotely triggerable. | ||
192 | |||
193 | Do not select this option. | ||
127 | 194 | ||
128 | config MAC80211_LOWTX_FRAME_DUMP | 195 | config MAC80211_LOWTX_FRAME_DUMP |
129 | bool "Debug frame dumping" | 196 | bool "Debug frame dumping" |
130 | depends on MAC80211_DEBUG | 197 | depends on MAC80211_DEBUG_MENU |
131 | ---help--- | 198 | ---help--- |
132 | Selecting this option will cause the stack to | 199 | Selecting this option will cause the stack to |
133 | print a message for each frame that is handed | 200 | print a message for each frame that is handed |
@@ -138,30 +205,21 @@ config MAC80211_LOWTX_FRAME_DUMP | |||
138 | If unsure, say N and insert the debugging code | 205 | If unsure, say N and insert the debugging code |
139 | you require into the driver you are debugging. | 206 | you require into the driver you are debugging. |
140 | 207 | ||
141 | config TKIP_DEBUG | ||
142 | bool "TKIP debugging" | ||
143 | depends on MAC80211_DEBUG | ||
144 | |||
145 | config MAC80211_DEBUG_COUNTERS | 208 | config MAC80211_DEBUG_COUNTERS |
146 | bool "Extra statistics for TX/RX debugging" | 209 | bool "Extra statistics for TX/RX debugging" |
147 | depends on MAC80211_DEBUG | 210 | depends on MAC80211_DEBUG |
148 | 211 | depends on MAC80211_DEBUG_MENU | |
149 | config MAC80211_IBSS_DEBUG | 212 | depends on MAC80211_DEBUGFS |
150 | bool "Support for IBSS testing" | ||
151 | depends on MAC80211_DEBUG | ||
152 | ---help--- | 213 | ---help--- |
153 | Say Y here if you intend to debug the IBSS code. | 214 | Selecting this option causes mac80211 to keep additional |
215 | and very verbose statistics about TX and RX handler use | ||
216 | and show them in debugfs. | ||
154 | 217 | ||
155 | config MAC80211_VERBOSE_PS_DEBUG | 218 | If unsure, say N. |
156 | bool "Verbose powersave mode debugging" | ||
157 | depends on MAC80211_DEBUG | ||
158 | ---help--- | ||
159 | Say Y here to print out verbose powersave | ||
160 | mode debug messages. | ||
161 | 219 | ||
162 | config MAC80211_VERBOSE_MPL_DEBUG | 220 | config MAC80211_VERBOSE_SPECT_MGMT_DEBUG |
163 | bool "Verbose mesh peer link debugging" | 221 | bool "Verbose Spectrum Management (IEEE 802.11h)debugging" |
164 | depends on MAC80211_DEBUG && MAC80211_MESH | 222 | depends on MAC80211_DEBUG |
165 | ---help--- | 223 | ---help--- |
166 | Say Y here to print out verbose mesh peer link | 224 | Say Y here to print out verbose Spectrum Management (IEEE 802.11h) |
167 | debug messages. | 225 | debug messages. |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 4e5847fd316..fa47438e338 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -1,13 +1,5 @@ | |||
1 | obj-$(CONFIG_MAC80211) += mac80211.o | 1 | obj-$(CONFIG_MAC80211) += mac80211.o |
2 | 2 | ||
3 | # objects for PID algorithm | ||
4 | rc80211_pid-y := rc80211_pid_algo.o | ||
5 | rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o | ||
6 | |||
7 | # build helper for PID algorithm | ||
8 | rc-pid-y := $(rc80211_pid-y) | ||
9 | rc-pid-m := rc80211_pid.o | ||
10 | |||
11 | # mac80211 objects | 3 | # mac80211 objects |
12 | mac80211-y := \ | 4 | mac80211-y := \ |
13 | main.o \ | 5 | main.o \ |
@@ -29,7 +21,7 @@ mac80211-y := \ | |||
29 | event.o | 21 | event.o |
30 | 22 | ||
31 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o | 23 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o |
32 | mac80211-$(CONFIG_NET_SCHED) += wme.o | 24 | mac80211-$(CONFIG_MAC80211_QOS) += wme.o |
33 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ | 25 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ |
34 | debugfs.o \ | 26 | debugfs.o \ |
35 | debugfs_sta.o \ | 27 | debugfs_sta.o \ |
@@ -42,10 +34,8 @@ mac80211-$(CONFIG_MAC80211_MESH) += \ | |||
42 | mesh_plink.o \ | 34 | mesh_plink.o \ |
43 | mesh_hwmp.o | 35 | mesh_hwmp.o |
44 | 36 | ||
37 | # objects for PID algorithm | ||
38 | rc80211_pid-y := rc80211_pid_algo.o | ||
39 | rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o | ||
45 | 40 | ||
46 | # Build rate control algorithm(s) | 41 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) |
47 | CFLAGS_rc80211_pid_algo.o += -DRC80211_PID_COMPILE | ||
48 | mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc-pid-$(CONFIG_MAC80211_RC_PID)) | ||
49 | |||
50 | # Modular rate algorithms are assigned to mac80211-m - make separate modules | ||
51 | obj-m += $(mac80211-m) | ||
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index 59f1691f62c..4d4c2dfcf9a 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -134,7 +134,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
134 | } | 134 | } |
135 | 135 | ||
136 | 136 | ||
137 | struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]) | 137 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) |
138 | { | 138 | { |
139 | struct crypto_cipher *tfm; | 139 | struct crypto_cipher *tfm; |
140 | 140 | ||
diff --git a/net/mac80211/aes_ccm.h b/net/mac80211/aes_ccm.h index 885f19030b2..8cd0f14aab4 100644 --- a/net/mac80211/aes_ccm.h +++ b/net/mac80211/aes_ccm.h | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | #define AES_BLOCK_LEN 16 | 15 | #define AES_BLOCK_LEN 16 |
16 | 16 | ||
17 | struct crypto_cipher * ieee80211_aes_key_setup_encrypt(const u8 key[]); | 17 | struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]); |
18 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | 18 | void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, |
19 | u8 *b_0, u8 *aad, u8 *data, size_t data_len, | 19 | u8 *b_0, u8 *aad, u8 *data, size_t data_len, |
20 | u8 *cdata, u8 *mic); | 20 | u8 *cdata, u8 *mic); |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a9fce4afdf2..81087281b03 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -256,8 +256,8 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev, | |||
256 | case ALG_TKIP: | 256 | case ALG_TKIP: |
257 | params.cipher = WLAN_CIPHER_SUITE_TKIP; | 257 | params.cipher = WLAN_CIPHER_SUITE_TKIP; |
258 | 258 | ||
259 | iv32 = key->u.tkip.iv32; | 259 | iv32 = key->u.tkip.tx.iv32; |
260 | iv16 = key->u.tkip.iv16; | 260 | iv16 = key->u.tkip.tx.iv16; |
261 | 261 | ||
262 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && | 262 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
263 | sdata->local->ops->get_tkip_seq) | 263 | sdata->local->ops->get_tkip_seq) |
@@ -602,6 +602,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
602 | */ | 602 | */ |
603 | 603 | ||
604 | if (params->station_flags & STATION_FLAG_CHANGED) { | 604 | if (params->station_flags & STATION_FLAG_CHANGED) { |
605 | spin_lock_bh(&sta->lock); | ||
605 | sta->flags &= ~WLAN_STA_AUTHORIZED; | 606 | sta->flags &= ~WLAN_STA_AUTHORIZED; |
606 | if (params->station_flags & STATION_FLAG_AUTHORIZED) | 607 | if (params->station_flags & STATION_FLAG_AUTHORIZED) |
607 | sta->flags |= WLAN_STA_AUTHORIZED; | 608 | sta->flags |= WLAN_STA_AUTHORIZED; |
@@ -613,6 +614,7 @@ static void sta_apply_parameters(struct ieee80211_local *local, | |||
613 | sta->flags &= ~WLAN_STA_WME; | 614 | sta->flags &= ~WLAN_STA_WME; |
614 | if (params->station_flags & STATION_FLAG_WME) | 615 | if (params->station_flags & STATION_FLAG_WME) |
615 | sta->flags |= WLAN_STA_WME; | 616 | sta->flags |= WLAN_STA_WME; |
617 | spin_unlock_bh(&sta->lock); | ||
616 | } | 618 | } |
617 | 619 | ||
618 | /* | 620 | /* |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 1cccbfd781f..d20d90eead1 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -197,45 +197,6 @@ DEBUGFS_STATS_FILE(rx_handlers_fragments, 20, "%u", | |||
197 | DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u", | 197 | DEBUGFS_STATS_FILE(tx_status_drop, 20, "%u", |
198 | local->tx_status_drop); | 198 | local->tx_status_drop); |
199 | 199 | ||
200 | static ssize_t stats_wme_rx_queue_read(struct file *file, | ||
201 | char __user *userbuf, | ||
202 | size_t count, loff_t *ppos) | ||
203 | { | ||
204 | struct ieee80211_local *local = file->private_data; | ||
205 | char buf[NUM_RX_DATA_QUEUES*15], *p = buf; | ||
206 | int i; | ||
207 | |||
208 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | ||
209 | p += scnprintf(p, sizeof(buf)+buf-p, | ||
210 | "%u\n", local->wme_rx_queue[i]); | ||
211 | |||
212 | return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf); | ||
213 | } | ||
214 | |||
215 | static const struct file_operations stats_wme_rx_queue_ops = { | ||
216 | .read = stats_wme_rx_queue_read, | ||
217 | .open = mac80211_open_file_generic, | ||
218 | }; | ||
219 | |||
220 | static ssize_t stats_wme_tx_queue_read(struct file *file, | ||
221 | char __user *userbuf, | ||
222 | size_t count, loff_t *ppos) | ||
223 | { | ||
224 | struct ieee80211_local *local = file->private_data; | ||
225 | char buf[NUM_TX_DATA_QUEUES*15], *p = buf; | ||
226 | int i; | ||
227 | |||
228 | for (i = 0; i < NUM_TX_DATA_QUEUES; i++) | ||
229 | p += scnprintf(p, sizeof(buf)+buf-p, | ||
230 | "%u\n", local->wme_tx_queue[i]); | ||
231 | |||
232 | return simple_read_from_buffer(userbuf, count, ppos, buf, p-buf); | ||
233 | } | ||
234 | |||
235 | static const struct file_operations stats_wme_tx_queue_ops = { | ||
236 | .read = stats_wme_tx_queue_read, | ||
237 | .open = mac80211_open_file_generic, | ||
238 | }; | ||
239 | #endif | 200 | #endif |
240 | 201 | ||
241 | DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount); | 202 | DEBUGFS_DEVSTATS_FILE(dot11ACKFailureCount); |
@@ -303,8 +264,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
303 | DEBUGFS_STATS_ADD(rx_expand_skb_head2); | 264 | DEBUGFS_STATS_ADD(rx_expand_skb_head2); |
304 | DEBUGFS_STATS_ADD(rx_handlers_fragments); | 265 | DEBUGFS_STATS_ADD(rx_handlers_fragments); |
305 | DEBUGFS_STATS_ADD(tx_status_drop); | 266 | DEBUGFS_STATS_ADD(tx_status_drop); |
306 | DEBUGFS_STATS_ADD(wme_tx_queue); | ||
307 | DEBUGFS_STATS_ADD(wme_rx_queue); | ||
308 | #endif | 267 | #endif |
309 | DEBUGFS_STATS_ADD(dot11ACKFailureCount); | 268 | DEBUGFS_STATS_ADD(dot11ACKFailureCount); |
310 | DEBUGFS_STATS_ADD(dot11RTSFailureCount); | 269 | DEBUGFS_STATS_ADD(dot11RTSFailureCount); |
@@ -356,8 +315,6 @@ void debugfs_hw_del(struct ieee80211_local *local) | |||
356 | DEBUGFS_STATS_DEL(rx_expand_skb_head2); | 315 | DEBUGFS_STATS_DEL(rx_expand_skb_head2); |
357 | DEBUGFS_STATS_DEL(rx_handlers_fragments); | 316 | DEBUGFS_STATS_DEL(rx_handlers_fragments); |
358 | DEBUGFS_STATS_DEL(tx_status_drop); | 317 | DEBUGFS_STATS_DEL(tx_status_drop); |
359 | DEBUGFS_STATS_DEL(wme_tx_queue); | ||
360 | DEBUGFS_STATS_DEL(wme_rx_queue); | ||
361 | #endif | 318 | #endif |
362 | DEBUGFS_STATS_DEL(dot11ACKFailureCount); | 319 | DEBUGFS_STATS_DEL(dot11ACKFailureCount); |
363 | DEBUGFS_STATS_DEL(dot11RTSFailureCount); | 320 | DEBUGFS_STATS_DEL(dot11RTSFailureCount); |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 19efc3a6a93..7439b63df5d 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -97,8 +97,8 @@ static ssize_t key_tx_spec_read(struct file *file, char __user *userbuf, | |||
97 | break; | 97 | break; |
98 | case ALG_TKIP: | 98 | case ALG_TKIP: |
99 | len = scnprintf(buf, sizeof(buf), "%08x %04x\n", | 99 | len = scnprintf(buf, sizeof(buf), "%08x %04x\n", |
100 | key->u.tkip.iv32, | 100 | key->u.tkip.tx.iv32, |
101 | key->u.tkip.iv16); | 101 | key->u.tkip.tx.iv16); |
102 | break; | 102 | break; |
103 | case ALG_CCMP: | 103 | case ALG_CCMP: |
104 | tpn = key->u.ccmp.tx_pn; | 104 | tpn = key->u.ccmp.tx_pn; |
@@ -128,8 +128,8 @@ static ssize_t key_rx_spec_read(struct file *file, char __user *userbuf, | |||
128 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 128 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) |
129 | p += scnprintf(p, sizeof(buf)+buf-p, | 129 | p += scnprintf(p, sizeof(buf)+buf-p, |
130 | "%08x %04x\n", | 130 | "%08x %04x\n", |
131 | key->u.tkip.iv32_rx[i], | 131 | key->u.tkip.rx[i].iv32, |
132 | key->u.tkip.iv16_rx[i]); | 132 | key->u.tkip.rx[i].iv16); |
133 | len = p - buf; | 133 | len = p - buf; |
134 | break; | 134 | break; |
135 | case ALG_CCMP: | 135 | case ALG_CCMP: |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index e3326d04694..b2089b2da48 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -155,7 +155,6 @@ static const struct file_operations name##_ops = { \ | |||
155 | __IEEE80211_IF_WFILE(name) | 155 | __IEEE80211_IF_WFILE(name) |
156 | 156 | ||
157 | /* common attributes */ | 157 | /* common attributes */ |
158 | IEEE80211_IF_FILE(channel_use, channel_use, DEC); | ||
159 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); | 158 | IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); |
160 | 159 | ||
161 | /* STA/IBSS attributes */ | 160 | /* STA/IBSS attributes */ |
@@ -248,7 +247,6 @@ IEEE80211_IF_WFILE(min_discovery_timeout, | |||
248 | 247 | ||
249 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) | 248 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) |
250 | { | 249 | { |
251 | DEBUGFS_ADD(channel_use, sta); | ||
252 | DEBUGFS_ADD(drop_unencrypted, sta); | 250 | DEBUGFS_ADD(drop_unencrypted, sta); |
253 | DEBUGFS_ADD(state, sta); | 251 | DEBUGFS_ADD(state, sta); |
254 | DEBUGFS_ADD(bssid, sta); | 252 | DEBUGFS_ADD(bssid, sta); |
@@ -269,7 +267,6 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata) | |||
269 | 267 | ||
270 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) | 268 | static void add_ap_files(struct ieee80211_sub_if_data *sdata) |
271 | { | 269 | { |
272 | DEBUGFS_ADD(channel_use, ap); | ||
273 | DEBUGFS_ADD(drop_unencrypted, ap); | 270 | DEBUGFS_ADD(drop_unencrypted, ap); |
274 | DEBUGFS_ADD(num_sta_ps, ap); | 271 | DEBUGFS_ADD(num_sta_ps, ap); |
275 | DEBUGFS_ADD(dtim_count, ap); | 272 | DEBUGFS_ADD(dtim_count, ap); |
@@ -281,14 +278,12 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata) | |||
281 | 278 | ||
282 | static void add_wds_files(struct ieee80211_sub_if_data *sdata) | 279 | static void add_wds_files(struct ieee80211_sub_if_data *sdata) |
283 | { | 280 | { |
284 | DEBUGFS_ADD(channel_use, wds); | ||
285 | DEBUGFS_ADD(drop_unencrypted, wds); | 281 | DEBUGFS_ADD(drop_unencrypted, wds); |
286 | DEBUGFS_ADD(peer, wds); | 282 | DEBUGFS_ADD(peer, wds); |
287 | } | 283 | } |
288 | 284 | ||
289 | static void add_vlan_files(struct ieee80211_sub_if_data *sdata) | 285 | static void add_vlan_files(struct ieee80211_sub_if_data *sdata) |
290 | { | 286 | { |
291 | DEBUGFS_ADD(channel_use, vlan); | ||
292 | DEBUGFS_ADD(drop_unencrypted, vlan); | 287 | DEBUGFS_ADD(drop_unencrypted, vlan); |
293 | } | 288 | } |
294 | 289 | ||
@@ -376,7 +371,6 @@ static void add_files(struct ieee80211_sub_if_data *sdata) | |||
376 | 371 | ||
377 | static void del_sta_files(struct ieee80211_sub_if_data *sdata) | 372 | static void del_sta_files(struct ieee80211_sub_if_data *sdata) |
378 | { | 373 | { |
379 | DEBUGFS_DEL(channel_use, sta); | ||
380 | DEBUGFS_DEL(drop_unencrypted, sta); | 374 | DEBUGFS_DEL(drop_unencrypted, sta); |
381 | DEBUGFS_DEL(state, sta); | 375 | DEBUGFS_DEL(state, sta); |
382 | DEBUGFS_DEL(bssid, sta); | 376 | DEBUGFS_DEL(bssid, sta); |
@@ -397,7 +391,6 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata) | |||
397 | 391 | ||
398 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) | 392 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) |
399 | { | 393 | { |
400 | DEBUGFS_DEL(channel_use, ap); | ||
401 | DEBUGFS_DEL(drop_unencrypted, ap); | 394 | DEBUGFS_DEL(drop_unencrypted, ap); |
402 | DEBUGFS_DEL(num_sta_ps, ap); | 395 | DEBUGFS_DEL(num_sta_ps, ap); |
403 | DEBUGFS_DEL(dtim_count, ap); | 396 | DEBUGFS_DEL(dtim_count, ap); |
@@ -409,14 +402,12 @@ static void del_ap_files(struct ieee80211_sub_if_data *sdata) | |||
409 | 402 | ||
410 | static void del_wds_files(struct ieee80211_sub_if_data *sdata) | 403 | static void del_wds_files(struct ieee80211_sub_if_data *sdata) |
411 | { | 404 | { |
412 | DEBUGFS_DEL(channel_use, wds); | ||
413 | DEBUGFS_DEL(drop_unencrypted, wds); | 405 | DEBUGFS_DEL(drop_unencrypted, wds); |
414 | DEBUGFS_DEL(peer, wds); | 406 | DEBUGFS_DEL(peer, wds); |
415 | } | 407 | } |
416 | 408 | ||
417 | static void del_vlan_files(struct ieee80211_sub_if_data *sdata) | 409 | static void del_vlan_files(struct ieee80211_sub_if_data *sdata) |
418 | { | 410 | { |
419 | DEBUGFS_DEL(channel_use, vlan); | ||
420 | DEBUGFS_DEL(drop_unencrypted, vlan); | 411 | DEBUGFS_DEL(drop_unencrypted, vlan); |
421 | } | 412 | } |
422 | 413 | ||
@@ -528,7 +519,7 @@ void ieee80211_debugfs_change_if_type(struct ieee80211_sub_if_data *sdata, | |||
528 | add_files(sdata); | 519 | add_files(sdata); |
529 | } | 520 | } |
530 | 521 | ||
531 | static int netdev_notify(struct notifier_block * nb, | 522 | static int netdev_notify(struct notifier_block *nb, |
532 | unsigned long state, | 523 | unsigned long state, |
533 | void *ndev) | 524 | void *ndev) |
534 | { | 525 | { |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 6d47a1d31b3..79a062782d5 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -63,10 +63,9 @@ STA_FILE(tx_fragments, tx_fragments, LU); | |||
63 | STA_FILE(tx_filtered, tx_filtered_count, LU); | 63 | STA_FILE(tx_filtered, tx_filtered_count, LU); |
64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 64 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
65 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 65 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
66 | STA_FILE(last_rssi, last_rssi, D); | ||
67 | STA_FILE(last_signal, last_signal, D); | 66 | STA_FILE(last_signal, last_signal, D); |
67 | STA_FILE(last_qual, last_qual, D); | ||
68 | STA_FILE(last_noise, last_noise, D); | 68 | STA_FILE(last_noise, last_noise, D); |
69 | STA_FILE(channel_use, channel_use, D); | ||
70 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); | 69 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); |
71 | 70 | ||
72 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | 71 | static ssize_t sta_flags_read(struct file *file, char __user *userbuf, |
@@ -74,14 +73,15 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
74 | { | 73 | { |
75 | char buf[100]; | 74 | char buf[100]; |
76 | struct sta_info *sta = file->private_data; | 75 | struct sta_info *sta = file->private_data; |
76 | u32 staflags = get_sta_flags(sta); | ||
77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", | 77 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s", |
78 | sta->flags & WLAN_STA_AUTH ? "AUTH\n" : "", | 78 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", |
79 | sta->flags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 79 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", |
80 | sta->flags & WLAN_STA_PS ? "PS\n" : "", | 80 | staflags & WLAN_STA_PS ? "PS\n" : "", |
81 | sta->flags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 81 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", |
82 | sta->flags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 82 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", |
83 | sta->flags & WLAN_STA_WME ? "WME\n" : "", | 83 | staflags & WLAN_STA_WME ? "WME\n" : "", |
84 | sta->flags & WLAN_STA_WDS ? "WDS\n" : ""); | 84 | staflags & WLAN_STA_WDS ? "WDS\n" : ""); |
85 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); | 85 | return simple_read_from_buffer(userbuf, count, ppos, buf, res); |
86 | } | 86 | } |
87 | STA_OPS(flags); | 87 | STA_OPS(flags); |
@@ -123,36 +123,6 @@ static ssize_t sta_last_seq_ctrl_read(struct file *file, char __user *userbuf, | |||
123 | } | 123 | } |
124 | STA_OPS(last_seq_ctrl); | 124 | STA_OPS(last_seq_ctrl); |
125 | 125 | ||
126 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
127 | static ssize_t sta_wme_rx_queue_read(struct file *file, char __user *userbuf, | ||
128 | size_t count, loff_t *ppos) | ||
129 | { | ||
130 | char buf[15*NUM_RX_DATA_QUEUES], *p = buf; | ||
131 | int i; | ||
132 | struct sta_info *sta = file->private_data; | ||
133 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | ||
134 | p += scnprintf(p, sizeof(buf)+buf-p, "%u ", | ||
135 | sta->wme_rx_queue[i]); | ||
136 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | ||
137 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
138 | } | ||
139 | STA_OPS(wme_rx_queue); | ||
140 | |||
141 | static ssize_t sta_wme_tx_queue_read(struct file *file, char __user *userbuf, | ||
142 | size_t count, loff_t *ppos) | ||
143 | { | ||
144 | char buf[15*NUM_TX_DATA_QUEUES], *p = buf; | ||
145 | int i; | ||
146 | struct sta_info *sta = file->private_data; | ||
147 | for (i = 0; i < NUM_TX_DATA_QUEUES; i++) | ||
148 | p += scnprintf(p, sizeof(buf)+buf-p, "%u ", | ||
149 | sta->wme_tx_queue[i]); | ||
150 | p += scnprintf(p, sizeof(buf)+buf-p, "\n"); | ||
151 | return simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); | ||
152 | } | ||
153 | STA_OPS(wme_tx_queue); | ||
154 | #endif | ||
155 | |||
156 | static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | 126 | static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, |
157 | size_t count, loff_t *ppos) | 127 | size_t count, loff_t *ppos) |
158 | { | 128 | { |
@@ -293,10 +263,6 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
293 | DEBUGFS_ADD(num_ps_buf_frames); | 263 | DEBUGFS_ADD(num_ps_buf_frames); |
294 | DEBUGFS_ADD(inactive_ms); | 264 | DEBUGFS_ADD(inactive_ms); |
295 | DEBUGFS_ADD(last_seq_ctrl); | 265 | DEBUGFS_ADD(last_seq_ctrl); |
296 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
297 | DEBUGFS_ADD(wme_rx_queue); | ||
298 | DEBUGFS_ADD(wme_tx_queue); | ||
299 | #endif | ||
300 | DEBUGFS_ADD(agg_status); | 266 | DEBUGFS_ADD(agg_status); |
301 | } | 267 | } |
302 | 268 | ||
@@ -306,10 +272,6 @@ void ieee80211_sta_debugfs_remove(struct sta_info *sta) | |||
306 | DEBUGFS_DEL(num_ps_buf_frames); | 272 | DEBUGFS_DEL(num_ps_buf_frames); |
307 | DEBUGFS_DEL(inactive_ms); | 273 | DEBUGFS_DEL(inactive_ms); |
308 | DEBUGFS_DEL(last_seq_ctrl); | 274 | DEBUGFS_DEL(last_seq_ctrl); |
309 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
310 | DEBUGFS_DEL(wme_rx_queue); | ||
311 | DEBUGFS_DEL(wme_tx_queue); | ||
312 | #endif | ||
313 | DEBUGFS_DEL(agg_status); | 275 | DEBUGFS_DEL(agg_status); |
314 | 276 | ||
315 | debugfs_remove(sta->debugfs.dir); | 277 | debugfs_remove(sta->debugfs.dir); |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 006486b2672..f90da1bbec4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -2,6 +2,7 @@ | |||
2 | * Copyright 2002-2005, Instant802 Networks, Inc. | 2 | * Copyright 2002-2005, Instant802 Networks, Inc. |
3 | * Copyright 2005, Devicescape Software, Inc. | 3 | * Copyright 2005, Devicescape Software, Inc. |
4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 4 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
5 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -23,6 +24,7 @@ | |||
23 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
24 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
25 | #include <net/wireless.h> | 26 | #include <net/wireless.h> |
27 | #include <net/iw_handler.h> | ||
26 | #include "key.h" | 28 | #include "key.h" |
27 | #include "sta_info.h" | 29 | #include "sta_info.h" |
28 | 30 | ||
@@ -82,7 +84,7 @@ struct ieee80211_sta_bss { | |||
82 | u16 capability; /* host byte order */ | 84 | u16 capability; /* host byte order */ |
83 | enum ieee80211_band band; | 85 | enum ieee80211_band band; |
84 | int freq; | 86 | int freq; |
85 | int rssi, signal, noise; | 87 | int signal, noise, qual; |
86 | u8 *wpa_ie; | 88 | u8 *wpa_ie; |
87 | size_t wpa_ie_len; | 89 | size_t wpa_ie_len; |
88 | u8 *rsn_ie; | 90 | u8 *rsn_ie; |
@@ -91,6 +93,8 @@ struct ieee80211_sta_bss { | |||
91 | size_t wmm_ie_len; | 93 | size_t wmm_ie_len; |
92 | u8 *ht_ie; | 94 | u8 *ht_ie; |
93 | size_t ht_ie_len; | 95 | size_t ht_ie_len; |
96 | u8 *ht_add_ie; | ||
97 | size_t ht_add_ie_len; | ||
94 | #ifdef CONFIG_MAC80211_MESH | 98 | #ifdef CONFIG_MAC80211_MESH |
95 | u8 *mesh_id; | 99 | u8 *mesh_id; |
96 | size_t mesh_id_len; | 100 | size_t mesh_id_len; |
@@ -147,7 +151,6 @@ typedef unsigned __bitwise__ ieee80211_tx_result; | |||
147 | #define IEEE80211_TX_UNICAST BIT(1) | 151 | #define IEEE80211_TX_UNICAST BIT(1) |
148 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 152 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
149 | #define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) | 153 | #define IEEE80211_TX_PROBE_LAST_FRAG BIT(3) |
150 | #define IEEE80211_TX_INJECTED BIT(4) | ||
151 | 154 | ||
152 | struct ieee80211_tx_data { | 155 | struct ieee80211_tx_data { |
153 | struct sk_buff *skb; | 156 | struct sk_buff *skb; |
@@ -157,13 +160,12 @@ struct ieee80211_tx_data { | |||
157 | struct sta_info *sta; | 160 | struct sta_info *sta; |
158 | struct ieee80211_key *key; | 161 | struct ieee80211_key *key; |
159 | 162 | ||
160 | struct ieee80211_tx_control *control; | ||
161 | struct ieee80211_channel *channel; | 163 | struct ieee80211_channel *channel; |
162 | struct ieee80211_rate *rate; | 164 | s8 rate_idx; |
163 | /* use this rate (if set) for last fragment; rate can | 165 | /* use this rate (if set) for last fragment; rate can |
164 | * be set to lower rate for the first fragments, e.g., | 166 | * be set to lower rate for the first fragments, e.g., |
165 | * when using CTS protection with IEEE 802.11g. */ | 167 | * when using CTS protection with IEEE 802.11g. */ |
166 | struct ieee80211_rate *last_frag_rate; | 168 | s8 last_frag_rate_idx; |
167 | 169 | ||
168 | /* Extra fragments (in addition to the first fragment | 170 | /* Extra fragments (in addition to the first fragment |
169 | * in skb) */ | 171 | * in skb) */ |
@@ -202,32 +204,16 @@ struct ieee80211_rx_data { | |||
202 | unsigned int flags; | 204 | unsigned int flags; |
203 | int sent_ps_buffered; | 205 | int sent_ps_buffered; |
204 | int queue; | 206 | int queue; |
205 | int load; | ||
206 | u32 tkip_iv32; | 207 | u32 tkip_iv32; |
207 | u16 tkip_iv16; | 208 | u16 tkip_iv16; |
208 | }; | 209 | }; |
209 | 210 | ||
210 | /* flags used in struct ieee80211_tx_packet_data.flags */ | ||
211 | #define IEEE80211_TXPD_REQ_TX_STATUS BIT(0) | ||
212 | #define IEEE80211_TXPD_DO_NOT_ENCRYPT BIT(1) | ||
213 | #define IEEE80211_TXPD_REQUEUE BIT(2) | ||
214 | #define IEEE80211_TXPD_EAPOL_FRAME BIT(3) | ||
215 | #define IEEE80211_TXPD_AMPDU BIT(4) | ||
216 | /* Stored in sk_buff->cb */ | ||
217 | struct ieee80211_tx_packet_data { | ||
218 | int ifindex; | ||
219 | unsigned long jiffies; | ||
220 | unsigned int flags; | ||
221 | u8 queue; | ||
222 | }; | ||
223 | |||
224 | struct ieee80211_tx_stored_packet { | 211 | struct ieee80211_tx_stored_packet { |
225 | struct ieee80211_tx_control control; | ||
226 | struct sk_buff *skb; | 212 | struct sk_buff *skb; |
227 | struct sk_buff **extra_frag; | 213 | struct sk_buff **extra_frag; |
228 | struct ieee80211_rate *last_frag_rate; | 214 | s8 last_frag_rate_idx; |
229 | int num_extra_frag; | 215 | int num_extra_frag; |
230 | unsigned int last_frag_rate_ctrl_probe; | 216 | bool last_frag_rate_ctrl_probe; |
231 | }; | 217 | }; |
232 | 218 | ||
233 | struct beacon_data { | 219 | struct beacon_data { |
@@ -464,14 +450,11 @@ struct ieee80211_sub_if_data { | |||
464 | struct ieee80211_if_sta sta; | 450 | struct ieee80211_if_sta sta; |
465 | u32 mntr_flags; | 451 | u32 mntr_flags; |
466 | } u; | 452 | } u; |
467 | int channel_use; | ||
468 | int channel_use_raw; | ||
469 | 453 | ||
470 | #ifdef CONFIG_MAC80211_DEBUGFS | 454 | #ifdef CONFIG_MAC80211_DEBUGFS |
471 | struct dentry *debugfsdir; | 455 | struct dentry *debugfsdir; |
472 | union { | 456 | union { |
473 | struct { | 457 | struct { |
474 | struct dentry *channel_use; | ||
475 | struct dentry *drop_unencrypted; | 458 | struct dentry *drop_unencrypted; |
476 | struct dentry *state; | 459 | struct dentry *state; |
477 | struct dentry *bssid; | 460 | struct dentry *bssid; |
@@ -490,7 +473,6 @@ struct ieee80211_sub_if_data { | |||
490 | struct dentry *num_beacons_sta; | 473 | struct dentry *num_beacons_sta; |
491 | } sta; | 474 | } sta; |
492 | struct { | 475 | struct { |
493 | struct dentry *channel_use; | ||
494 | struct dentry *drop_unencrypted; | 476 | struct dentry *drop_unencrypted; |
495 | struct dentry *num_sta_ps; | 477 | struct dentry *num_sta_ps; |
496 | struct dentry *dtim_count; | 478 | struct dentry *dtim_count; |
@@ -500,12 +482,10 @@ struct ieee80211_sub_if_data { | |||
500 | struct dentry *num_buffered_multicast; | 482 | struct dentry *num_buffered_multicast; |
501 | } ap; | 483 | } ap; |
502 | struct { | 484 | struct { |
503 | struct dentry *channel_use; | ||
504 | struct dentry *drop_unencrypted; | 485 | struct dentry *drop_unencrypted; |
505 | struct dentry *peer; | 486 | struct dentry *peer; |
506 | } wds; | 487 | } wds; |
507 | struct { | 488 | struct { |
508 | struct dentry *channel_use; | ||
509 | struct dentry *drop_unencrypted; | 489 | struct dentry *drop_unencrypted; |
510 | } vlan; | 490 | } vlan; |
511 | struct { | 491 | struct { |
@@ -610,8 +590,8 @@ struct ieee80211_local { | |||
610 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 590 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
611 | struct timer_list sta_cleanup; | 591 | struct timer_list sta_cleanup; |
612 | 592 | ||
613 | unsigned long state[NUM_TX_DATA_QUEUES_AMPDU]; | 593 | unsigned long queues_pending[BITS_TO_LONGS(IEEE80211_MAX_QUEUES)]; |
614 | struct ieee80211_tx_stored_packet pending_packet[NUM_TX_DATA_QUEUES_AMPDU]; | 594 | struct ieee80211_tx_stored_packet pending_packet[IEEE80211_MAX_QUEUES]; |
615 | struct tasklet_struct tx_pending_tasklet; | 595 | struct tasklet_struct tx_pending_tasklet; |
616 | 596 | ||
617 | /* number of interfaces with corresponding IFF_ flags */ | 597 | /* number of interfaces with corresponding IFF_ flags */ |
@@ -677,9 +657,6 @@ struct ieee80211_local { | |||
677 | assoc_led_name[32], radio_led_name[32]; | 657 | assoc_led_name[32], radio_led_name[32]; |
678 | #endif | 658 | #endif |
679 | 659 | ||
680 | u32 channel_use; | ||
681 | u32 channel_use_raw; | ||
682 | |||
683 | #ifdef CONFIG_MAC80211_DEBUGFS | 660 | #ifdef CONFIG_MAC80211_DEBUGFS |
684 | struct work_struct sta_debugfs_add; | 661 | struct work_struct sta_debugfs_add; |
685 | #endif | 662 | #endif |
@@ -705,8 +682,6 @@ struct ieee80211_local { | |||
705 | unsigned int rx_expand_skb_head2; | 682 | unsigned int rx_expand_skb_head2; |
706 | unsigned int rx_handlers_fragments; | 683 | unsigned int rx_handlers_fragments; |
707 | unsigned int tx_status_drop; | 684 | unsigned int tx_status_drop; |
708 | unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES]; | ||
709 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; | ||
710 | #define I802_DEBUG_INC(c) (c)++ | 685 | #define I802_DEBUG_INC(c) (c)++ |
711 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ | 686 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ |
712 | #define I802_DEBUG_INC(c) do { } while (0) | 687 | #define I802_DEBUG_INC(c) do { } while (0) |
@@ -764,8 +739,6 @@ struct ieee80211_local { | |||
764 | struct dentry *rx_expand_skb_head2; | 739 | struct dentry *rx_expand_skb_head2; |
765 | struct dentry *rx_handlers_fragments; | 740 | struct dentry *rx_handlers_fragments; |
766 | struct dentry *tx_status_drop; | 741 | struct dentry *tx_status_drop; |
767 | struct dentry *wme_tx_queue; | ||
768 | struct dentry *wme_rx_queue; | ||
769 | #endif | 742 | #endif |
770 | struct dentry *dot11ACKFailureCount; | 743 | struct dentry *dot11ACKFailureCount; |
771 | struct dentry *dot11RTSFailureCount; | 744 | struct dentry *dot11RTSFailureCount; |
@@ -778,6 +751,15 @@ struct ieee80211_local { | |||
778 | #endif | 751 | #endif |
779 | }; | 752 | }; |
780 | 753 | ||
754 | static inline int ieee80211_is_multiqueue(struct ieee80211_local *local) | ||
755 | { | ||
756 | #ifdef CONFIG_MAC80211_QOS | ||
757 | return netif_is_multiqueue(local->mdev); | ||
758 | #else | ||
759 | return 0; | ||
760 | #endif | ||
761 | } | ||
762 | |||
781 | /* this struct represents 802.11n's RA/TID combination */ | 763 | /* this struct represents 802.11n's RA/TID combination */ |
782 | struct ieee80211_ra_tid { | 764 | struct ieee80211_ra_tid { |
783 | u8 ra[ETH_ALEN]; | 765 | u8 ra[ETH_ALEN]; |
@@ -809,6 +791,10 @@ struct ieee802_11_elems { | |||
809 | u8 *preq; | 791 | u8 *preq; |
810 | u8 *prep; | 792 | u8 *prep; |
811 | 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 */ | ||
812 | 798 | ||
813 | /* length of them, respectively */ | 799 | /* length of them, respectively */ |
814 | u8 ssid_len; | 800 | u8 ssid_len; |
@@ -833,6 +819,11 @@ struct ieee802_11_elems { | |||
833 | u8 preq_len; | 819 | u8 preq_len; |
834 | u8 prep_len; | 820 | u8 prep_len; |
835 | 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 */ | ||
836 | }; | 827 | }; |
837 | 828 | ||
838 | static inline struct ieee80211_local *hw_to_local( | 829 | static inline struct ieee80211_local *hw_to_local( |
@@ -847,11 +838,6 @@ static inline struct ieee80211_hw *local_to_hw( | |||
847 | return &local->hw; | 838 | return &local->hw; |
848 | } | 839 | } |
849 | 840 | ||
850 | enum ieee80211_link_state_t { | ||
851 | IEEE80211_LINK_STATE_XOFF = 0, | ||
852 | IEEE80211_LINK_STATE_PENDING, | ||
853 | }; | ||
854 | |||
855 | struct sta_attribute { | 841 | struct sta_attribute { |
856 | struct attribute attr; | 842 | struct attribute attr; |
857 | ssize_t (*show)(const struct sta_info *, char *buf); | 843 | ssize_t (*show)(const struct sta_info *, char *buf); |
@@ -877,29 +863,8 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | |||
877 | 863 | ||
878 | /* ieee80211_ioctl.c */ | 864 | /* ieee80211_ioctl.c */ |
879 | extern const struct iw_handler_def ieee80211_iw_handler_def; | 865 | extern const struct iw_handler_def ieee80211_iw_handler_def; |
880 | |||
881 | |||
882 | /* Least common multiple of the used rates (in 100 kbps). This is used to | ||
883 | * calculate rate_inv values for each rate so that only integers are needed. */ | ||
884 | #define CHAN_UTIL_RATE_LCM 95040 | ||
885 | /* 1 usec is 1/8 * (95040/10) = 1188 */ | ||
886 | #define CHAN_UTIL_PER_USEC 1188 | ||
887 | /* Amount of bits to shift the result right to scale the total utilization | ||
888 | * to values that will not wrap around 32-bit integers. */ | ||
889 | #define CHAN_UTIL_SHIFT 9 | ||
890 | /* Theoretical maximum of channel utilization counter in 10 ms (stat_time=1): | ||
891 | * (CHAN_UTIL_PER_USEC * 10000) >> CHAN_UTIL_SHIFT = 23203. So dividing the | ||
892 | * raw value with about 23 should give utilization in 10th of a percentage | ||
893 | * (1/1000). However, utilization is only estimated and not all intervals | ||
894 | * between frames etc. are calculated. 18 seems to give numbers that are closer | ||
895 | * to the real maximum. */ | ||
896 | #define CHAN_UTIL_PER_10MS 18 | ||
897 | #define CHAN_UTIL_HDR_LONG (202 * CHAN_UTIL_PER_USEC) | ||
898 | #define CHAN_UTIL_HDR_SHORT (40 * CHAN_UTIL_PER_USEC) | ||
899 | |||
900 | |||
901 | /* ieee80211_ioctl.c */ | ||
902 | int ieee80211_set_freq(struct net_device *dev, int freq); | 866 | int ieee80211_set_freq(struct net_device *dev, int freq); |
867 | |||
903 | /* ieee80211_sta.c */ | 868 | /* ieee80211_sta.c */ |
904 | void ieee80211_sta_timer(unsigned long data); | 869 | void ieee80211_sta_timer(unsigned long data); |
905 | void ieee80211_sta_work(struct work_struct *work); | 870 | void ieee80211_sta_work(struct work_struct *work); |
@@ -912,16 +877,18 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid); | |||
912 | int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); | 877 | int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); |
913 | void ieee80211_sta_req_auth(struct net_device *dev, | 878 | void ieee80211_sta_req_auth(struct net_device *dev, |
914 | struct ieee80211_if_sta *ifsta); | 879 | struct ieee80211_if_sta *ifsta); |
915 | int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len); | 880 | int ieee80211_sta_scan_results(struct net_device *dev, |
881 | struct iw_request_info *info, | ||
882 | char *buf, size_t len); | ||
916 | ieee80211_rx_result ieee80211_sta_rx_scan( | 883 | ieee80211_rx_result ieee80211_sta_rx_scan( |
917 | struct net_device *dev, struct sk_buff *skb, | 884 | struct net_device *dev, struct sk_buff *skb, |
918 | struct ieee80211_rx_status *rx_status); | 885 | struct ieee80211_rx_status *rx_status); |
919 | void ieee80211_rx_bss_list_init(struct net_device *dev); | 886 | void ieee80211_rx_bss_list_init(struct net_device *dev); |
920 | void ieee80211_rx_bss_list_deinit(struct net_device *dev); | 887 | void ieee80211_rx_bss_list_deinit(struct net_device *dev); |
921 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); | 888 | int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); |
922 | struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | 889 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, |
923 | struct sk_buff *skb, u8 *bssid, | 890 | struct sk_buff *skb, u8 *bssid, |
924 | u8 *addr); | 891 | u8 *addr, u64 supp_rates); |
925 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); | 892 | int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); |
926 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); | 893 | int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); |
927 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 894 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
@@ -940,7 +907,6 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | |||
940 | 907 | ||
941 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, | 908 | void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da, |
942 | u16 tid, u16 initiator, u16 reason); | 909 | u16 tid, u16 initiator, u16 reason); |
943 | void sta_rx_agg_session_timer_expired(unsigned long data); | ||
944 | void sta_addba_resp_timer_expired(unsigned long data); | 910 | void sta_addba_resp_timer_expired(unsigned long data); |
945 | void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr); | 911 | void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr); |
946 | u64 ieee80211_sta_get_rates(struct ieee80211_local *local, | 912 | u64 ieee80211_sta_get_rates(struct ieee80211_local *local, |
@@ -988,4 +954,10 @@ int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | |||
988 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, | 954 | void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, |
989 | struct ieee80211_hdr *hdr); | 955 | struct ieee80211_hdr *hdr); |
990 | 956 | ||
957 | #ifdef CONFIG_MAC80211_NOINLINE | ||
958 | #define debug_noinline noinline | ||
959 | #else | ||
960 | #define debug_noinline | ||
961 | #endif | ||
962 | |||
991 | #endif /* IEEE80211_I_H */ | 963 | #endif /* IEEE80211_I_H */ |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 06e88a5a036..eeb16926aa7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -33,9 +33,8 @@ static void ieee80211_if_sdata_deinit(struct ieee80211_sub_if_data *sdata) | |||
33 | { | 33 | { |
34 | int i; | 34 | int i; |
35 | 35 | ||
36 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { | 36 | for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) |
37 | __skb_queue_purge(&sdata->fragments[i].skb_list); | 37 | __skb_queue_purge(&sdata->fragments[i].skb_list); |
38 | } | ||
39 | } | 38 | } |
40 | 39 | ||
41 | /* Must be called with rtnl lock held. */ | 40 | /* Must be called with rtnl lock held. */ |
@@ -167,9 +166,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
167 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | | 166 | ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | |
168 | IEEE80211_AUTH_ALG_SHARED_KEY; | 167 | IEEE80211_AUTH_ALG_SHARED_KEY; |
169 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | | 168 | ifsta->flags |= IEEE80211_STA_CREATE_IBSS | |
170 | IEEE80211_STA_WMM_ENABLED | | ||
171 | IEEE80211_STA_AUTO_BSSID_SEL | | 169 | IEEE80211_STA_AUTO_BSSID_SEL | |
172 | IEEE80211_STA_AUTO_CHANNEL_SEL; | 170 | IEEE80211_STA_AUTO_CHANNEL_SEL; |
171 | if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4) | ||
172 | ifsta->flags |= IEEE80211_STA_WMM_ENABLED; | ||
173 | 173 | ||
174 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); | 174 | msdata = IEEE80211_DEV_TO_SUB_IF(sdata->local->mdev); |
175 | sdata->bss = &msdata->u.ap; | 175 | sdata->bss = &msdata->u.ap; |
@@ -184,9 +184,9 @@ void ieee80211_if_set_type(struct net_device *dev, int type) | |||
184 | sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | | 184 | sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | |
185 | MONITOR_FLAG_OTHER_BSS; | 185 | MONITOR_FLAG_OTHER_BSS; |
186 | break; | 186 | break; |
187 | default: | 187 | case IEEE80211_IF_TYPE_INVALID: |
188 | printk(KERN_WARNING "%s: %s: Unknown interface type 0x%x", | 188 | BUG(); |
189 | dev->name, __func__, type); | 189 | break; |
190 | } | 190 | } |
191 | ieee80211_debugfs_change_if_type(sdata, oldtype); | 191 | ieee80211_debugfs_change_if_type(sdata, oldtype); |
192 | } | 192 | } |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 220e83be3ef..6597c779e35 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -321,8 +321,15 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
321 | * some hardware cannot handle TKIP with QoS, so | 321 | * some hardware cannot handle TKIP with QoS, so |
322 | * we indicate whether QoS could be in use. | 322 | * we indicate whether QoS could be in use. |
323 | */ | 323 | */ |
324 | if (sta->flags & WLAN_STA_WME) | 324 | if (test_sta_flags(sta, WLAN_STA_WME)) |
325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; | 325 | key->conf.flags |= IEEE80211_KEY_FLAG_WMM_STA; |
326 | |||
327 | /* | ||
328 | * This key is for a specific sta interface, | ||
329 | * inform the driver that it should try to store | ||
330 | * this key as pairwise key. | ||
331 | */ | ||
332 | key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; | ||
326 | } else { | 333 | } else { |
327 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | 334 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { |
328 | struct sta_info *ap; | 335 | struct sta_info *ap; |
@@ -335,7 +342,7 @@ void ieee80211_key_link(struct ieee80211_key *key, | |||
335 | /* same here, the AP could be using QoS */ | 342 | /* same here, the AP could be using QoS */ |
336 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); | 343 | ap = sta_info_get(key->local, key->sdata->u.sta.bssid); |
337 | if (ap) { | 344 | if (ap) { |
338 | if (ap->flags & WLAN_STA_WME) | 345 | if (test_sta_flags(ap, WLAN_STA_WME)) |
339 | key->conf.flags |= | 346 | key->conf.flags |= |
340 | IEEE80211_KEY_FLAG_WMM_STA; | 347 | IEEE80211_KEY_FLAG_WMM_STA; |
341 | } | 348 | } |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index f52c3df1fe9..425816e0996 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 | ||
45 | struct ieee80211_local; | 32 | struct ieee80211_local; |
46 | struct ieee80211_sub_if_data; | 33 | struct ieee80211_sub_if_data; |
@@ -69,6 +56,13 @@ enum ieee80211_internal_key_flags { | |||
69 | KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5), | 56 | KEY_FLAG_TODO_ADD_DEBUGFS = BIT(5), |
70 | }; | 57 | }; |
71 | 58 | ||
59 | struct tkip_ctx { | ||
60 | u32 iv32; | ||
61 | u16 iv16; | ||
62 | u16 p1k[5]; | ||
63 | int initialized; | ||
64 | }; | ||
65 | |||
72 | struct ieee80211_key { | 66 | struct ieee80211_key { |
73 | struct ieee80211_local *local; | 67 | struct ieee80211_local *local; |
74 | struct ieee80211_sub_if_data *sdata; | 68 | struct ieee80211_sub_if_data *sdata; |
@@ -85,16 +79,10 @@ struct ieee80211_key { | |||
85 | union { | 79 | union { |
86 | struct { | 80 | struct { |
87 | /* last used TSC */ | 81 | /* last used TSC */ |
88 | u32 iv32; | 82 | struct tkip_ctx tx; |
89 | u16 iv16; | ||
90 | u16 p1k[5]; | ||
91 | int tx_initialized; | ||
92 | 83 | ||
93 | /* last received RSC */ | 84 | /* last received RSC */ |
94 | u32 iv32_rx[NUM_RX_DATA_QUEUES]; | 85 | struct tkip_ctx rx[NUM_RX_DATA_QUEUES]; |
95 | u16 iv16_rx[NUM_RX_DATA_QUEUES]; | ||
96 | u16 p1k_rx[NUM_RX_DATA_QUEUES][5]; | ||
97 | int rx_initialized[NUM_RX_DATA_QUEUES]; | ||
98 | } tkip; | 86 | } tkip; |
99 | struct { | 87 | struct { |
100 | u8 tx_pn[6]; | 88 | u8 tx_pn[6]; |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 98c0b5e56ec..f18cfd72787 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -35,8 +35,6 @@ | |||
35 | #include "debugfs.h" | 35 | #include "debugfs.h" |
36 | #include "debugfs_netdev.h" | 36 | #include "debugfs_netdev.h" |
37 | 37 | ||
38 | #define SUPP_MCS_SET_LEN 16 | ||
39 | |||
40 | /* | 38 | /* |
41 | * For seeing transmitted packets on monitor interfaces | 39 | * For seeing transmitted packets on monitor interfaces |
42 | * we have a radiotap header too. | 40 | * we have a radiotap header too. |
@@ -112,7 +110,13 @@ static int ieee80211_master_open(struct net_device *dev) | |||
112 | break; | 110 | break; |
113 | } | 111 | } |
114 | } | 112 | } |
115 | return res; | 113 | |
114 | if (res) | ||
115 | return res; | ||
116 | |||
117 | netif_start_queue(local->mdev); | ||
118 | |||
119 | return 0; | ||
116 | } | 120 | } |
117 | 121 | ||
118 | static int ieee80211_master_stop(struct net_device *dev) | 122 | static int ieee80211_master_stop(struct net_device *dev) |
@@ -147,9 +151,7 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
147 | /* FIX: what would be proper limits for MTU? | 151 | /* FIX: what would be proper limits for MTU? |
148 | * This interface uses 802.3 frames. */ | 152 | * This interface uses 802.3 frames. */ |
149 | if (new_mtu < 256 || | 153 | if (new_mtu < 256 || |
150 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { | 154 | new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) { |
151 | printk(KERN_WARNING "%s: invalid MTU %d\n", | ||
152 | dev->name, new_mtu); | ||
153 | return -EINVAL; | 155 | return -EINVAL; |
154 | } | 156 | } |
155 | 157 | ||
@@ -346,6 +348,7 @@ static int ieee80211_open(struct net_device *dev) | |||
346 | goto err_del_interface; | 348 | goto err_del_interface; |
347 | } | 349 | } |
348 | 350 | ||
351 | /* no locking required since STA is not live yet */ | ||
349 | sta->flags |= WLAN_STA_AUTHORIZED; | 352 | sta->flags |= WLAN_STA_AUTHORIZED; |
350 | 353 | ||
351 | res = sta_info_insert(sta); | 354 | res = sta_info_insert(sta); |
@@ -385,8 +388,8 @@ static int ieee80211_open(struct net_device *dev) | |||
385 | * yet be effective. Trigger execution of ieee80211_sta_work | 388 | * yet be effective. Trigger execution of ieee80211_sta_work |
386 | * to fix this. | 389 | * to fix this. |
387 | */ | 390 | */ |
388 | if(sdata->vif.type == IEEE80211_IF_TYPE_STA || | 391 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA || |
389 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 392 | sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
390 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 393 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
391 | queue_work(local->hw.workqueue, &ifsta->work); | 394 | queue_work(local->hw.workqueue, &ifsta->work); |
392 | } | 395 | } |
@@ -584,17 +587,19 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
584 | 587 | ||
585 | sta = sta_info_get(local, ra); | 588 | sta = sta_info_get(local, ra); |
586 | if (!sta) { | 589 | if (!sta) { |
590 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
587 | printk(KERN_DEBUG "Could not find the station\n"); | 591 | printk(KERN_DEBUG "Could not find the station\n"); |
588 | rcu_read_unlock(); | 592 | #endif |
589 | return -ENOENT; | 593 | ret = -ENOENT; |
594 | goto exit; | ||
590 | } | 595 | } |
591 | 596 | ||
592 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 597 | spin_lock_bh(&sta->lock); |
593 | 598 | ||
594 | /* we have tried too many times, receiver does not want A-MPDU */ | 599 | /* we have tried too many times, receiver does not want A-MPDU */ |
595 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { | 600 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) { |
596 | ret = -EBUSY; | 601 | ret = -EBUSY; |
597 | goto start_ba_exit; | 602 | goto err_unlock_sta; |
598 | } | 603 | } |
599 | 604 | ||
600 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 605 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
@@ -605,18 +610,20 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
605 | "idle on tid %u\n", tid); | 610 | "idle on tid %u\n", tid); |
606 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 611 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
607 | ret = -EAGAIN; | 612 | ret = -EAGAIN; |
608 | goto start_ba_exit; | 613 | goto err_unlock_sta; |
609 | } | 614 | } |
610 | 615 | ||
611 | /* prepare A-MPDU MLME for Tx aggregation */ | 616 | /* prepare A-MPDU MLME for Tx aggregation */ |
612 | sta->ampdu_mlme.tid_tx[tid] = | 617 | sta->ampdu_mlme.tid_tx[tid] = |
613 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); | 618 | kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC); |
614 | if (!sta->ampdu_mlme.tid_tx[tid]) { | 619 | if (!sta->ampdu_mlme.tid_tx[tid]) { |
620 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
615 | if (net_ratelimit()) | 621 | if (net_ratelimit()) |
616 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", | 622 | printk(KERN_ERR "allocate tx mlme to tid %d failed\n", |
617 | tid); | 623 | tid); |
624 | #endif | ||
618 | ret = -ENOMEM; | 625 | ret = -ENOMEM; |
619 | goto start_ba_exit; | 626 | goto err_unlock_sta; |
620 | } | 627 | } |
621 | /* Tx timer */ | 628 | /* Tx timer */ |
622 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = | 629 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function = |
@@ -639,7 +646,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
639 | printk(KERN_DEBUG "BA request denied - queue unavailable for" | 646 | printk(KERN_DEBUG "BA request denied - queue unavailable for" |
640 | " tid %d\n", tid); | 647 | " tid %d\n", tid); |
641 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 648 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
642 | goto start_ba_err; | 649 | goto err_unlock_queue; |
643 | } | 650 | } |
644 | sdata = sta->sdata; | 651 | sdata = sta->sdata; |
645 | 652 | ||
@@ -661,12 +668,13 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
661 | " tid %d\n", tid); | 668 | " tid %d\n", tid); |
662 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 669 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
663 | *state = HT_AGG_STATE_IDLE; | 670 | *state = HT_AGG_STATE_IDLE; |
664 | goto start_ba_err; | 671 | goto err_unlock_queue; |
665 | } | 672 | } |
666 | 673 | ||
667 | /* Will put all the packets in the new SW queue */ | 674 | /* Will put all the packets in the new SW queue */ |
668 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); | 675 | ieee80211_requeue(local, ieee802_1d_to_ac[tid]); |
669 | spin_unlock_bh(&local->mdev->queue_lock); | 676 | spin_unlock_bh(&local->mdev->queue_lock); |
677 | spin_unlock_bh(&sta->lock); | ||
670 | 678 | ||
671 | /* send an addBA request */ | 679 | /* send an addBA request */ |
672 | sta->ampdu_mlme.dialog_token_allocator++; | 680 | sta->ampdu_mlme.dialog_token_allocator++; |
@@ -674,25 +682,28 @@ int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
674 | sta->ampdu_mlme.dialog_token_allocator; | 682 | sta->ampdu_mlme.dialog_token_allocator; |
675 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; | 683 | sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num; |
676 | 684 | ||
685 | |||
677 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, | 686 | ieee80211_send_addba_request(sta->sdata->dev, ra, tid, |
678 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, | 687 | sta->ampdu_mlme.tid_tx[tid]->dialog_token, |
679 | sta->ampdu_mlme.tid_tx[tid]->ssn, | 688 | sta->ampdu_mlme.tid_tx[tid]->ssn, |
680 | 0x40, 5000); | 689 | 0x40, 5000); |
681 | |||
682 | /* activate the timer for the recipient's addBA response */ | 690 | /* activate the timer for the recipient's addBA response */ |
683 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = | 691 | sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires = |
684 | jiffies + ADDBA_RESP_INTERVAL; | 692 | jiffies + ADDBA_RESP_INTERVAL; |
685 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | 693 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); |
694 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
686 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | 695 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); |
687 | goto start_ba_exit; | 696 | #endif |
697 | goto exit; | ||
688 | 698 | ||
689 | start_ba_err: | 699 | err_unlock_queue: |
690 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 700 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
691 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 701 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
692 | spin_unlock_bh(&local->mdev->queue_lock); | 702 | spin_unlock_bh(&local->mdev->queue_lock); |
693 | ret = -EBUSY; | 703 | ret = -EBUSY; |
694 | start_ba_exit: | 704 | err_unlock_sta: |
695 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 705 | spin_unlock_bh(&sta->lock); |
706 | exit: | ||
696 | rcu_read_unlock(); | 707 | rcu_read_unlock(); |
697 | return ret; | 708 | return ret; |
698 | } | 709 | } |
@@ -720,7 +731,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
720 | 731 | ||
721 | /* check if the TID is in aggregation */ | 732 | /* check if the TID is in aggregation */ |
722 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 733 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
723 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 734 | spin_lock_bh(&sta->lock); |
724 | 735 | ||
725 | if (*state != HT_AGG_STATE_OPERATIONAL) { | 736 | if (*state != HT_AGG_STATE_OPERATIONAL) { |
726 | ret = -ENOENT; | 737 | ret = -ENOENT; |
@@ -750,7 +761,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
750 | } | 761 | } |
751 | 762 | ||
752 | stop_BA_exit: | 763 | stop_BA_exit: |
753 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 764 | spin_unlock_bh(&sta->lock); |
754 | rcu_read_unlock(); | 765 | rcu_read_unlock(); |
755 | return ret; | 766 | return ret; |
756 | } | 767 | } |
@@ -764,8 +775,10 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
764 | DECLARE_MAC_BUF(mac); | 775 | DECLARE_MAC_BUF(mac); |
765 | 776 | ||
766 | if (tid >= STA_TID_NUM) { | 777 | if (tid >= STA_TID_NUM) { |
778 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
767 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 779 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
768 | tid, STA_TID_NUM); | 780 | tid, STA_TID_NUM); |
781 | #endif | ||
769 | return; | 782 | return; |
770 | } | 783 | } |
771 | 784 | ||
@@ -773,18 +786,22 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
773 | sta = sta_info_get(local, ra); | 786 | sta = sta_info_get(local, ra); |
774 | if (!sta) { | 787 | if (!sta) { |
775 | rcu_read_unlock(); | 788 | rcu_read_unlock(); |
789 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
776 | printk(KERN_DEBUG "Could not find station: %s\n", | 790 | printk(KERN_DEBUG "Could not find station: %s\n", |
777 | print_mac(mac, ra)); | 791 | print_mac(mac, ra)); |
792 | #endif | ||
778 | return; | 793 | return; |
779 | } | 794 | } |
780 | 795 | ||
781 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 796 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
782 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 797 | spin_lock_bh(&sta->lock); |
783 | 798 | ||
784 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 799 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
800 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
785 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", | 801 | printk(KERN_DEBUG "addBA was not requested yet, state is %d\n", |
786 | *state); | 802 | *state); |
787 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 803 | #endif |
804 | spin_unlock_bh(&sta->lock); | ||
788 | rcu_read_unlock(); | 805 | rcu_read_unlock(); |
789 | return; | 806 | return; |
790 | } | 807 | } |
@@ -794,10 +811,12 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid) | |||
794 | *state |= HT_ADDBA_DRV_READY_MSK; | 811 | *state |= HT_ADDBA_DRV_READY_MSK; |
795 | 812 | ||
796 | if (*state == HT_AGG_STATE_OPERATIONAL) { | 813 | if (*state == HT_AGG_STATE_OPERATIONAL) { |
814 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
797 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); | 815 | printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid); |
816 | #endif | ||
798 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 817 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
799 | } | 818 | } |
800 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 819 | spin_unlock_bh(&sta->lock); |
801 | rcu_read_unlock(); | 820 | rcu_read_unlock(); |
802 | } | 821 | } |
803 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); | 822 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb); |
@@ -811,8 +830,10 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
811 | DECLARE_MAC_BUF(mac); | 830 | DECLARE_MAC_BUF(mac); |
812 | 831 | ||
813 | if (tid >= STA_TID_NUM) { | 832 | if (tid >= STA_TID_NUM) { |
833 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
814 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 834 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", |
815 | tid, STA_TID_NUM); | 835 | tid, STA_TID_NUM); |
836 | #endif | ||
816 | return; | 837 | return; |
817 | } | 838 | } |
818 | 839 | ||
@@ -824,17 +845,22 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
824 | rcu_read_lock(); | 845 | rcu_read_lock(); |
825 | sta = sta_info_get(local, ra); | 846 | sta = sta_info_get(local, ra); |
826 | if (!sta) { | 847 | if (!sta) { |
848 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
827 | printk(KERN_DEBUG "Could not find station: %s\n", | 849 | printk(KERN_DEBUG "Could not find station: %s\n", |
828 | print_mac(mac, ra)); | 850 | print_mac(mac, ra)); |
851 | #endif | ||
829 | rcu_read_unlock(); | 852 | rcu_read_unlock(); |
830 | return; | 853 | return; |
831 | } | 854 | } |
832 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 855 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
833 | 856 | ||
834 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 857 | /* NOTE: no need to use sta->lock in this state check, as |
858 | * ieee80211_stop_tx_ba_session will let only | ||
859 | * one stop call to pass through per sta/tid */ | ||
835 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { | 860 | if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) { |
861 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
836 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | 862 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); |
837 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 863 | #endif |
838 | rcu_read_unlock(); | 864 | rcu_read_unlock(); |
839 | return; | 865 | return; |
840 | } | 866 | } |
@@ -857,11 +883,12 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid) | |||
857 | * ieee80211_wake_queue is not used here as this queue is not | 883 | * ieee80211_wake_queue is not used here as this queue is not |
858 | * necessarily stopped */ | 884 | * necessarily stopped */ |
859 | netif_schedule(local->mdev); | 885 | netif_schedule(local->mdev); |
886 | spin_lock_bh(&sta->lock); | ||
860 | *state = HT_AGG_STATE_IDLE; | 887 | *state = HT_AGG_STATE_IDLE; |
861 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 888 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
862 | kfree(sta->ampdu_mlme.tid_tx[tid]); | 889 | kfree(sta->ampdu_mlme.tid_tx[tid]); |
863 | sta->ampdu_mlme.tid_tx[tid] = NULL; | 890 | sta->ampdu_mlme.tid_tx[tid] = NULL; |
864 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 891 | spin_unlock_bh(&sta->lock); |
865 | 892 | ||
866 | rcu_read_unlock(); | 893 | rcu_read_unlock(); |
867 | } | 894 | } |
@@ -875,9 +902,11 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
875 | struct sk_buff *skb = dev_alloc_skb(0); | 902 | struct sk_buff *skb = dev_alloc_skb(0); |
876 | 903 | ||
877 | if (unlikely(!skb)) { | 904 | if (unlikely(!skb)) { |
905 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
878 | if (net_ratelimit()) | 906 | if (net_ratelimit()) |
879 | printk(KERN_WARNING "%s: Not enough memory, " | 907 | printk(KERN_WARNING "%s: Not enough memory, " |
880 | "dropping start BA session", skb->dev->name); | 908 | "dropping start BA session", skb->dev->name); |
909 | #endif | ||
881 | return; | 910 | return; |
882 | } | 911 | } |
883 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 912 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -898,9 +927,11 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw, | |||
898 | struct sk_buff *skb = dev_alloc_skb(0); | 927 | struct sk_buff *skb = dev_alloc_skb(0); |
899 | 928 | ||
900 | if (unlikely(!skb)) { | 929 | if (unlikely(!skb)) { |
930 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
901 | if (net_ratelimit()) | 931 | if (net_ratelimit()) |
902 | printk(KERN_WARNING "%s: Not enough memory, " | 932 | printk(KERN_WARNING "%s: Not enough memory, " |
903 | "dropping stop BA session", skb->dev->name); | 933 | "dropping stop BA session", skb->dev->name); |
934 | #endif | ||
904 | return; | 935 | return; |
905 | } | 936 | } |
906 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 937 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -967,8 +998,7 @@ void ieee80211_if_setup(struct net_device *dev) | |||
967 | /* everything else */ | 998 | /* everything else */ |
968 | 999 | ||
969 | static int __ieee80211_if_config(struct net_device *dev, | 1000 | static int __ieee80211_if_config(struct net_device *dev, |
970 | struct sk_buff *beacon, | 1001 | struct sk_buff *beacon) |
971 | struct ieee80211_tx_control *control) | ||
972 | { | 1002 | { |
973 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1003 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
974 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1004 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
@@ -986,13 +1016,11 @@ static int __ieee80211_if_config(struct net_device *dev, | |||
986 | conf.ssid_len = sdata->u.sta.ssid_len; | 1016 | conf.ssid_len = sdata->u.sta.ssid_len; |
987 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 1017 | } else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
988 | conf.beacon = beacon; | 1018 | conf.beacon = beacon; |
989 | conf.beacon_control = control; | ||
990 | ieee80211_start_mesh(dev); | 1019 | ieee80211_start_mesh(dev); |
991 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { | 1020 | } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { |
992 | conf.ssid = sdata->u.ap.ssid; | 1021 | conf.ssid = sdata->u.ap.ssid; |
993 | conf.ssid_len = sdata->u.ap.ssid_len; | 1022 | conf.ssid_len = sdata->u.ap.ssid_len; |
994 | conf.beacon = beacon; | 1023 | conf.beacon = beacon; |
995 | conf.beacon_control = control; | ||
996 | } | 1024 | } |
997 | return local->ops->config_interface(local_to_hw(local), | 1025 | return local->ops->config_interface(local_to_hw(local), |
998 | &sdata->vif, &conf); | 1026 | &sdata->vif, &conf); |
@@ -1005,23 +1033,21 @@ int ieee80211_if_config(struct net_device *dev) | |||
1005 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && | 1033 | if (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT && |
1006 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1034 | (local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) |
1007 | return ieee80211_if_config_beacon(dev); | 1035 | return ieee80211_if_config_beacon(dev); |
1008 | return __ieee80211_if_config(dev, NULL, NULL); | 1036 | return __ieee80211_if_config(dev, NULL); |
1009 | } | 1037 | } |
1010 | 1038 | ||
1011 | int ieee80211_if_config_beacon(struct net_device *dev) | 1039 | int ieee80211_if_config_beacon(struct net_device *dev) |
1012 | { | 1040 | { |
1013 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1041 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1014 | struct ieee80211_tx_control control; | ||
1015 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1042 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1016 | struct sk_buff *skb; | 1043 | struct sk_buff *skb; |
1017 | 1044 | ||
1018 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) | 1045 | if (!(local->hw.flags & IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE)) |
1019 | return 0; | 1046 | return 0; |
1020 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif, | 1047 | skb = ieee80211_beacon_get(local_to_hw(local), &sdata->vif); |
1021 | &control); | ||
1022 | if (!skb) | 1048 | if (!skb) |
1023 | return -ENOMEM; | 1049 | return -ENOMEM; |
1024 | return __ieee80211_if_config(dev, skb, &control); | 1050 | return __ieee80211_if_config(dev, skb); |
1025 | } | 1051 | } |
1026 | 1052 | ||
1027 | int ieee80211_hw_config(struct ieee80211_local *local) | 1053 | int ieee80211_hw_config(struct ieee80211_local *local) |
@@ -1068,56 +1094,84 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, | |||
1068 | struct ieee80211_supported_band *sband; | 1094 | struct ieee80211_supported_band *sband; |
1069 | struct ieee80211_ht_info ht_conf; | 1095 | struct ieee80211_ht_info ht_conf; |
1070 | struct ieee80211_ht_bss_info ht_bss_conf; | 1096 | struct ieee80211_ht_bss_info ht_bss_conf; |
1071 | int i; | ||
1072 | u32 changed = 0; | 1097 | u32 changed = 0; |
1098 | int i; | ||
1099 | u8 max_tx_streams = IEEE80211_HT_CAP_MAX_STREAMS; | ||
1100 | u8 tx_mcs_set_cap; | ||
1073 | 1101 | ||
1074 | sband = local->hw.wiphy->bands[conf->channel->band]; | 1102 | sband = local->hw.wiphy->bands[conf->channel->band]; |
1075 | 1103 | ||
1104 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | ||
1105 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | ||
1106 | |||
1076 | /* HT is not supported */ | 1107 | /* HT is not supported */ |
1077 | if (!sband->ht_info.ht_supported) { | 1108 | if (!sband->ht_info.ht_supported) { |
1078 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | 1109 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; |
1079 | return 0; | 1110 | goto out; |
1080 | } | 1111 | } |
1081 | 1112 | ||
1082 | memset(&ht_conf, 0, sizeof(struct ieee80211_ht_info)); | 1113 | /* disable HT */ |
1083 | memset(&ht_bss_conf, 0, sizeof(struct ieee80211_ht_bss_info)); | 1114 | if (!enable_ht) { |
1084 | 1115 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | |
1085 | if (enable_ht) { | ||
1086 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) | ||
1087 | changed |= BSS_CHANGED_HT; | 1116 | changed |= BSS_CHANGED_HT; |
1117 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1118 | conf->ht_conf.ht_supported = 0; | ||
1119 | goto out; | ||
1120 | } | ||
1088 | 1121 | ||
1089 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1090 | ht_conf.ht_supported = 1; | ||
1091 | 1122 | ||
1092 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; | 1123 | if (!(conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE)) |
1093 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); | 1124 | changed |= BSS_CHANGED_HT; |
1094 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; | ||
1095 | 1125 | ||
1096 | for (i = 0; i < SUPP_MCS_SET_LEN; i++) | 1126 | conf->flags |= IEEE80211_CONF_SUPPORT_HT_MODE; |
1097 | ht_conf.supp_mcs_set[i] = | 1127 | ht_conf.ht_supported = 1; |
1098 | sband->ht_info.supp_mcs_set[i] & | ||
1099 | req_ht_cap->supp_mcs_set[i]; | ||
1100 | 1128 | ||
1101 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | 1129 | ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; |
1102 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | 1130 | ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); |
1103 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | 1131 | ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; |
1132 | ht_bss_conf.primary_channel = req_bss_cap->primary_channel; | ||
1133 | ht_bss_conf.bss_cap = req_bss_cap->bss_cap; | ||
1134 | ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; | ||
1104 | 1135 | ||
1105 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; | 1136 | ht_conf.ampdu_factor = req_ht_cap->ampdu_factor; |
1106 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; | 1137 | ht_conf.ampdu_density = req_ht_cap->ampdu_density; |
1107 | 1138 | ||
1108 | /* if bss configuration changed store the new one */ | 1139 | /* Bits 96-100 */ |
1109 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | 1140 | tx_mcs_set_cap = sband->ht_info.supp_mcs_set[12]; |
1110 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | 1141 | |
1111 | changed |= BSS_CHANGED_HT; | 1142 | /* configure suppoerted Tx MCS according to requested MCS |
1112 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | 1143 | * (based in most cases on Rx capabilities of peer) and self |
1113 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | 1144 | * Tx MCS capabilities (as defined by low level driver HW |
1114 | } | 1145 | * Tx capabilities) */ |
1115 | } else { | 1146 | if (!(tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_DEFINED)) |
1116 | if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) | 1147 | goto check_changed; |
1117 | changed |= BSS_CHANGED_HT; | ||
1118 | conf->flags &= ~IEEE80211_CONF_SUPPORT_HT_MODE; | ||
1119 | } | ||
1120 | 1148 | ||
1149 | /* Counting from 0 therfore + 1 */ | ||
1150 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_RX_DIFF) | ||
1151 | max_tx_streams = ((tx_mcs_set_cap & | ||
1152 | IEEE80211_HT_CAP_MCS_TX_STREAMS) >> 2) + 1; | ||
1153 | |||
1154 | for (i = 0; i < max_tx_streams; i++) | ||
1155 | ht_conf.supp_mcs_set[i] = | ||
1156 | sband->ht_info.supp_mcs_set[i] & | ||
1157 | req_ht_cap->supp_mcs_set[i]; | ||
1158 | |||
1159 | if (tx_mcs_set_cap & IEEE80211_HT_CAP_MCS_TX_UEQM) | ||
1160 | for (i = IEEE80211_SUPP_MCS_SET_UEQM; | ||
1161 | i < IEEE80211_SUPP_MCS_SET_LEN; i++) | ||
1162 | ht_conf.supp_mcs_set[i] = | ||
1163 | sband->ht_info.supp_mcs_set[i] & | ||
1164 | req_ht_cap->supp_mcs_set[i]; | ||
1165 | |||
1166 | check_changed: | ||
1167 | /* if bss configuration changed store the new one */ | ||
1168 | if (memcmp(&conf->ht_conf, &ht_conf, sizeof(ht_conf)) || | ||
1169 | memcmp(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf))) { | ||
1170 | changed |= BSS_CHANGED_HT; | ||
1171 | memcpy(&conf->ht_conf, &ht_conf, sizeof(ht_conf)); | ||
1172 | memcpy(&conf->ht_bss_conf, &ht_bss_conf, sizeof(ht_bss_conf)); | ||
1173 | } | ||
1174 | out: | ||
1121 | return changed; | 1175 | return changed; |
1122 | } | 1176 | } |
1123 | 1177 | ||
@@ -1148,38 +1202,20 @@ void ieee80211_reset_erp_info(struct net_device *dev) | |||
1148 | } | 1202 | } |
1149 | 1203 | ||
1150 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | 1204 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, |
1151 | struct sk_buff *skb, | 1205 | struct sk_buff *skb) |
1152 | struct ieee80211_tx_status *status) | ||
1153 | { | 1206 | { |
1154 | struct ieee80211_local *local = hw_to_local(hw); | 1207 | struct ieee80211_local *local = hw_to_local(hw); |
1155 | struct ieee80211_tx_status *saved; | 1208 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1156 | int tmp; | 1209 | int tmp; |
1157 | 1210 | ||
1158 | skb->dev = local->mdev; | 1211 | skb->dev = local->mdev; |
1159 | saved = kmalloc(sizeof(struct ieee80211_tx_status), GFP_ATOMIC); | ||
1160 | if (unlikely(!saved)) { | ||
1161 | if (net_ratelimit()) | ||
1162 | printk(KERN_WARNING "%s: Not enough memory, " | ||
1163 | "dropping tx status", skb->dev->name); | ||
1164 | /* should be dev_kfree_skb_irq, but due to this function being | ||
1165 | * named _irqsafe instead of just _irq we can't be sure that | ||
1166 | * people won't call it from non-irq contexts */ | ||
1167 | dev_kfree_skb_any(skb); | ||
1168 | return; | ||
1169 | } | ||
1170 | memcpy(saved, status, sizeof(struct ieee80211_tx_status)); | ||
1171 | /* copy pointer to saved status into skb->cb for use by tasklet */ | ||
1172 | memcpy(skb->cb, &saved, sizeof(saved)); | ||
1173 | |||
1174 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | 1212 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; |
1175 | skb_queue_tail(status->control.flags & IEEE80211_TXCTL_REQ_TX_STATUS ? | 1213 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? |
1176 | &local->skb_queue : &local->skb_queue_unreliable, skb); | 1214 | &local->skb_queue : &local->skb_queue_unreliable, skb); |
1177 | tmp = skb_queue_len(&local->skb_queue) + | 1215 | tmp = skb_queue_len(&local->skb_queue) + |
1178 | skb_queue_len(&local->skb_queue_unreliable); | 1216 | skb_queue_len(&local->skb_queue_unreliable); |
1179 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | 1217 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && |
1180 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | 1218 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { |
1181 | memcpy(&saved, skb->cb, sizeof(saved)); | ||
1182 | kfree(saved); | ||
1183 | dev_kfree_skb_irq(skb); | 1219 | dev_kfree_skb_irq(skb); |
1184 | tmp--; | 1220 | tmp--; |
1185 | I802_DEBUG_INC(local->tx_status_drop); | 1221 | I802_DEBUG_INC(local->tx_status_drop); |
@@ -1193,7 +1229,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1193 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 1229 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
1194 | struct sk_buff *skb; | 1230 | struct sk_buff *skb; |
1195 | struct ieee80211_rx_status rx_status; | 1231 | struct ieee80211_rx_status rx_status; |
1196 | struct ieee80211_tx_status *tx_status; | ||
1197 | struct ieee80211_ra_tid *ra_tid; | 1232 | struct ieee80211_ra_tid *ra_tid; |
1198 | 1233 | ||
1199 | while ((skb = skb_dequeue(&local->skb_queue)) || | 1234 | while ((skb = skb_dequeue(&local->skb_queue)) || |
@@ -1208,12 +1243,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1208 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); | 1243 | __ieee80211_rx(local_to_hw(local), skb, &rx_status); |
1209 | break; | 1244 | break; |
1210 | case IEEE80211_TX_STATUS_MSG: | 1245 | case IEEE80211_TX_STATUS_MSG: |
1211 | /* get pointer to saved status out of skb->cb */ | ||
1212 | memcpy(&tx_status, skb->cb, sizeof(tx_status)); | ||
1213 | skb->pkt_type = 0; | 1246 | skb->pkt_type = 0; |
1214 | ieee80211_tx_status(local_to_hw(local), | 1247 | ieee80211_tx_status(local_to_hw(local), skb); |
1215 | skb, tx_status); | ||
1216 | kfree(tx_status); | ||
1217 | break; | 1248 | break; |
1218 | case IEEE80211_DELBA_MSG: | 1249 | case IEEE80211_DELBA_MSG: |
1219 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 1250 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
@@ -1227,9 +1258,8 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1227 | ra_tid->ra, ra_tid->tid); | 1258 | ra_tid->ra, ra_tid->tid); |
1228 | dev_kfree_skb(skb); | 1259 | dev_kfree_skb(skb); |
1229 | break ; | 1260 | break ; |
1230 | default: /* should never get here! */ | 1261 | default: |
1231 | printk(KERN_ERR "%s: Unknown message type (%d)\n", | 1262 | WARN_ON(1); |
1232 | wiphy_name(local->hw.wiphy), skb->pkt_type); | ||
1233 | dev_kfree_skb(skb); | 1263 | dev_kfree_skb(skb); |
1234 | break; | 1264 | break; |
1235 | } | 1265 | } |
@@ -1242,24 +1272,15 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
1242 | * Also, tx_packet_data in cb is restored from tx_control. */ | 1272 | * Also, tx_packet_data in cb is restored from tx_control. */ |
1243 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, | 1273 | static void ieee80211_remove_tx_extra(struct ieee80211_local *local, |
1244 | struct ieee80211_key *key, | 1274 | struct ieee80211_key *key, |
1245 | struct sk_buff *skb, | 1275 | struct sk_buff *skb) |
1246 | struct ieee80211_tx_control *control) | ||
1247 | { | 1276 | { |
1248 | int hdrlen, iv_len, mic_len; | 1277 | int hdrlen, iv_len, mic_len; |
1249 | struct ieee80211_tx_packet_data *pkt_data; | 1278 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1250 | 1279 | ||
1251 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1280 | info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS | |
1252 | pkt_data->ifindex = vif_to_sdata(control->vif)->dev->ifindex; | 1281 | IEEE80211_TX_CTL_DO_NOT_ENCRYPT | |
1253 | pkt_data->flags = 0; | 1282 | IEEE80211_TX_CTL_REQUEUE | |
1254 | if (control->flags & IEEE80211_TXCTL_REQ_TX_STATUS) | 1283 | IEEE80211_TX_CTL_EAPOL_FRAME; |
1255 | pkt_data->flags |= IEEE80211_TXPD_REQ_TX_STATUS; | ||
1256 | if (control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT) | ||
1257 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | ||
1258 | if (control->flags & IEEE80211_TXCTL_REQUEUE) | ||
1259 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | ||
1260 | if (control->flags & IEEE80211_TXCTL_EAPOL_FRAME) | ||
1261 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | ||
1262 | pkt_data->queue = control->queue; | ||
1263 | 1284 | ||
1264 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); | 1285 | hdrlen = ieee80211_get_hdrlen_from_skb(skb); |
1265 | 1286 | ||
@@ -1306,9 +1327,10 @@ no_key: | |||
1306 | 1327 | ||
1307 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | 1328 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, |
1308 | struct sta_info *sta, | 1329 | struct sta_info *sta, |
1309 | struct sk_buff *skb, | 1330 | struct sk_buff *skb) |
1310 | struct ieee80211_tx_status *status) | ||
1311 | { | 1331 | { |
1332 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1333 | |||
1312 | sta->tx_filtered_count++; | 1334 | sta->tx_filtered_count++; |
1313 | 1335 | ||
1314 | /* | 1336 | /* |
@@ -1316,7 +1338,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1316 | * packet. If the STA went to power save mode, this will happen | 1338 | * packet. If the STA went to power save mode, this will happen |
1317 | * when it wakes up for the next time. | 1339 | * when it wakes up for the next time. |
1318 | */ | 1340 | */ |
1319 | sta->flags |= WLAN_STA_CLEAR_PS_FILT; | 1341 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); |
1320 | 1342 | ||
1321 | /* | 1343 | /* |
1322 | * This code races in the following way: | 1344 | * This code races in the following way: |
@@ -1348,84 +1370,72 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
1348 | * can be unknown, for example with different interrupt status | 1370 | * can be unknown, for example with different interrupt status |
1349 | * bits. | 1371 | * bits. |
1350 | */ | 1372 | */ |
1351 | if (sta->flags & WLAN_STA_PS && | 1373 | if (test_sta_flags(sta, WLAN_STA_PS) && |
1352 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 1374 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
1353 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1375 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1354 | &status->control); | ||
1355 | skb_queue_tail(&sta->tx_filtered, skb); | 1376 | skb_queue_tail(&sta->tx_filtered, skb); |
1356 | return; | 1377 | return; |
1357 | } | 1378 | } |
1358 | 1379 | ||
1359 | if (!(sta->flags & WLAN_STA_PS) && | 1380 | if (!test_sta_flags(sta, WLAN_STA_PS) && |
1360 | !(status->control.flags & IEEE80211_TXCTL_REQUEUE)) { | 1381 | !(info->flags & IEEE80211_TX_CTL_REQUEUE)) { |
1361 | /* Software retry the packet once */ | 1382 | /* Software retry the packet once */ |
1362 | status->control.flags |= IEEE80211_TXCTL_REQUEUE; | 1383 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
1363 | ieee80211_remove_tx_extra(local, sta->key, skb, | 1384 | ieee80211_remove_tx_extra(local, sta->key, skb); |
1364 | &status->control); | ||
1365 | dev_queue_xmit(skb); | 1385 | dev_queue_xmit(skb); |
1366 | return; | 1386 | return; |
1367 | } | 1387 | } |
1368 | 1388 | ||
1389 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1369 | if (net_ratelimit()) | 1390 | if (net_ratelimit()) |
1370 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | 1391 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " |
1371 | "queue_len=%d PS=%d @%lu\n", | 1392 | "queue_len=%d PS=%d @%lu\n", |
1372 | wiphy_name(local->hw.wiphy), | 1393 | wiphy_name(local->hw.wiphy), |
1373 | skb_queue_len(&sta->tx_filtered), | 1394 | skb_queue_len(&sta->tx_filtered), |
1374 | !!(sta->flags & WLAN_STA_PS), jiffies); | 1395 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); |
1396 | #endif | ||
1375 | dev_kfree_skb(skb); | 1397 | dev_kfree_skb(skb); |
1376 | } | 1398 | } |
1377 | 1399 | ||
1378 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | 1400 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) |
1379 | struct ieee80211_tx_status *status) | ||
1380 | { | 1401 | { |
1381 | struct sk_buff *skb2; | 1402 | struct sk_buff *skb2; |
1382 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 1403 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
1383 | struct ieee80211_local *local = hw_to_local(hw); | 1404 | struct ieee80211_local *local = hw_to_local(hw); |
1405 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1384 | u16 frag, type; | 1406 | u16 frag, type; |
1385 | struct ieee80211_tx_status_rtap_hdr *rthdr; | 1407 | struct ieee80211_tx_status_rtap_hdr *rthdr; |
1386 | struct ieee80211_sub_if_data *sdata; | 1408 | struct ieee80211_sub_if_data *sdata; |
1387 | struct net_device *prev_dev = NULL; | 1409 | struct net_device *prev_dev = NULL; |
1388 | 1410 | ||
1389 | if (!status) { | ||
1390 | printk(KERN_ERR | ||
1391 | "%s: ieee80211_tx_status called with NULL status\n", | ||
1392 | wiphy_name(local->hw.wiphy)); | ||
1393 | dev_kfree_skb(skb); | ||
1394 | return; | ||
1395 | } | ||
1396 | |||
1397 | rcu_read_lock(); | 1411 | rcu_read_lock(); |
1398 | 1412 | ||
1399 | if (status->excessive_retries) { | 1413 | if (info->status.excessive_retries) { |
1400 | struct sta_info *sta; | 1414 | struct sta_info *sta; |
1401 | sta = sta_info_get(local, hdr->addr1); | 1415 | sta = sta_info_get(local, hdr->addr1); |
1402 | if (sta) { | 1416 | if (sta) { |
1403 | if (sta->flags & WLAN_STA_PS) { | 1417 | if (test_sta_flags(sta, WLAN_STA_PS)) { |
1404 | /* | 1418 | /* |
1405 | * The STA is in power save mode, so assume | 1419 | * The STA is in power save mode, so assume |
1406 | * that this TX packet failed because of that. | 1420 | * that this TX packet failed because of that. |
1407 | */ | 1421 | */ |
1408 | status->excessive_retries = 0; | 1422 | ieee80211_handle_filtered_frame(local, sta, skb); |
1409 | status->flags |= IEEE80211_TX_STATUS_TX_FILTERED; | ||
1410 | ieee80211_handle_filtered_frame(local, sta, | ||
1411 | skb, status); | ||
1412 | rcu_read_unlock(); | 1423 | rcu_read_unlock(); |
1413 | return; | 1424 | return; |
1414 | } | 1425 | } |
1415 | } | 1426 | } |
1416 | } | 1427 | } |
1417 | 1428 | ||
1418 | if (status->flags & IEEE80211_TX_STATUS_TX_FILTERED) { | 1429 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { |
1419 | struct sta_info *sta; | 1430 | struct sta_info *sta; |
1420 | sta = sta_info_get(local, hdr->addr1); | 1431 | sta = sta_info_get(local, hdr->addr1); |
1421 | if (sta) { | 1432 | if (sta) { |
1422 | ieee80211_handle_filtered_frame(local, sta, skb, | 1433 | ieee80211_handle_filtered_frame(local, sta, skb); |
1423 | status); | ||
1424 | rcu_read_unlock(); | 1434 | rcu_read_unlock(); |
1425 | return; | 1435 | return; |
1426 | } | 1436 | } |
1427 | } else | 1437 | } else |
1428 | rate_control_tx_status(local->mdev, skb, status); | 1438 | rate_control_tx_status(local->mdev, skb); |
1429 | 1439 | ||
1430 | rcu_read_unlock(); | 1440 | rcu_read_unlock(); |
1431 | 1441 | ||
@@ -1439,14 +1449,14 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1439 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | 1449 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; |
1440 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | 1450 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; |
1441 | 1451 | ||
1442 | if (status->flags & IEEE80211_TX_STATUS_ACK) { | 1452 | if (info->flags & IEEE80211_TX_STAT_ACK) { |
1443 | if (frag == 0) { | 1453 | if (frag == 0) { |
1444 | local->dot11TransmittedFrameCount++; | 1454 | local->dot11TransmittedFrameCount++; |
1445 | if (is_multicast_ether_addr(hdr->addr1)) | 1455 | if (is_multicast_ether_addr(hdr->addr1)) |
1446 | local->dot11MulticastTransmittedFrameCount++; | 1456 | local->dot11MulticastTransmittedFrameCount++; |
1447 | if (status->retry_count > 0) | 1457 | if (info->status.retry_count > 0) |
1448 | local->dot11RetryCount++; | 1458 | local->dot11RetryCount++; |
1449 | if (status->retry_count > 1) | 1459 | if (info->status.retry_count > 1) |
1450 | local->dot11MultipleRetryCount++; | 1460 | local->dot11MultipleRetryCount++; |
1451 | } | 1461 | } |
1452 | 1462 | ||
@@ -1483,7 +1493,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1483 | return; | 1493 | return; |
1484 | } | 1494 | } |
1485 | 1495 | ||
1486 | rthdr = (struct ieee80211_tx_status_rtap_hdr*) | 1496 | rthdr = (struct ieee80211_tx_status_rtap_hdr *) |
1487 | skb_push(skb, sizeof(*rthdr)); | 1497 | skb_push(skb, sizeof(*rthdr)); |
1488 | 1498 | ||
1489 | memset(rthdr, 0, sizeof(*rthdr)); | 1499 | memset(rthdr, 0, sizeof(*rthdr)); |
@@ -1492,17 +1502,17 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
1492 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | 1502 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | |
1493 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); | 1503 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES)); |
1494 | 1504 | ||
1495 | if (!(status->flags & IEEE80211_TX_STATUS_ACK) && | 1505 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
1496 | !is_multicast_ether_addr(hdr->addr1)) | 1506 | !is_multicast_ether_addr(hdr->addr1)) |
1497 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | 1507 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); |
1498 | 1508 | ||
1499 | if ((status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) && | 1509 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) && |
1500 | (status->control.flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) | 1510 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) |
1501 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | 1511 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); |
1502 | else if (status->control.flags & IEEE80211_TXCTL_USE_RTS_CTS) | 1512 | else if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
1503 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | 1513 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); |
1504 | 1514 | ||
1505 | rthdr->data_retries = status->retry_count; | 1515 | rthdr->data_retries = info->status.retry_count; |
1506 | 1516 | ||
1507 | /* XXX: is this sufficient for BPF? */ | 1517 | /* XXX: is this sufficient for BPF? */ |
1508 | skb_set_mac_header(skb, 0); | 1518 | skb_set_mac_header(skb, 0); |
@@ -1652,12 +1662,32 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1652 | if (result < 0) | 1662 | if (result < 0) |
1653 | return result; | 1663 | return result; |
1654 | 1664 | ||
1665 | /* | ||
1666 | * We use the number of queues for feature tests (QoS, HT) internally | ||
1667 | * so restrict them appropriately. | ||
1668 | */ | ||
1669 | #ifdef CONFIG_MAC80211_QOS | ||
1670 | if (hw->queues > IEEE80211_MAX_QUEUES) | ||
1671 | hw->queues = IEEE80211_MAX_QUEUES; | ||
1672 | if (hw->ampdu_queues > IEEE80211_MAX_AMPDU_QUEUES) | ||
1673 | hw->ampdu_queues = IEEE80211_MAX_AMPDU_QUEUES; | ||
1674 | if (hw->queues < 4) | ||
1675 | hw->ampdu_queues = 0; | ||
1676 | #else | ||
1677 | hw->queues = 1; | ||
1678 | hw->ampdu_queues = 0; | ||
1679 | #endif | ||
1680 | |||
1655 | /* for now, mdev needs sub_if_data :/ */ | 1681 | /* for now, mdev needs sub_if_data :/ */ |
1656 | mdev = alloc_netdev(sizeof(struct ieee80211_sub_if_data), | 1682 | mdev = alloc_netdev_mq(sizeof(struct ieee80211_sub_if_data), |
1657 | "wmaster%d", ether_setup); | 1683 | "wmaster%d", ether_setup, |
1684 | ieee80211_num_queues(hw)); | ||
1658 | if (!mdev) | 1685 | if (!mdev) |
1659 | goto fail_mdev_alloc; | 1686 | goto fail_mdev_alloc; |
1660 | 1687 | ||
1688 | if (ieee80211_num_queues(hw) > 1) | ||
1689 | mdev->features |= NETIF_F_MULTI_QUEUE; | ||
1690 | |||
1661 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); | 1691 | sdata = IEEE80211_DEV_TO_SUB_IF(mdev); |
1662 | mdev->ieee80211_ptr = &sdata->wdev; | 1692 | mdev->ieee80211_ptr = &sdata->wdev; |
1663 | sdata->wdev.wiphy = local->hw.wiphy; | 1693 | sdata->wdev.wiphy = local->hw.wiphy; |
@@ -1684,7 +1714,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1684 | list_add_tail(&sdata->list, &local->interfaces); | 1714 | list_add_tail(&sdata->list, &local->interfaces); |
1685 | 1715 | ||
1686 | name = wiphy_dev(local->hw.wiphy)->driver->name; | 1716 | name = wiphy_dev(local->hw.wiphy)->driver->name; |
1687 | local->hw.workqueue = create_singlethread_workqueue(name); | 1717 | local->hw.workqueue = create_freezeable_workqueue(name); |
1688 | if (!local->hw.workqueue) { | 1718 | if (!local->hw.workqueue) { |
1689 | result = -ENOMEM; | 1719 | result = -ENOMEM; |
1690 | goto fail_workqueue; | 1720 | goto fail_workqueue; |
@@ -1700,15 +1730,16 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
1700 | 1730 | ||
1701 | debugfs_hw_add(local); | 1731 | debugfs_hw_add(local); |
1702 | 1732 | ||
1703 | local->hw.conf.beacon_int = 1000; | 1733 | if (local->hw.conf.beacon_int < 10) |
1734 | local->hw.conf.beacon_int = 100; | ||
1704 | 1735 | ||
1705 | local->wstats_flags |= local->hw.max_rssi ? | 1736 | local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | |
1706 | IW_QUAL_LEVEL_UPDATED : IW_QUAL_LEVEL_INVALID; | 1737 | IEEE80211_HW_SIGNAL_DB | |
1707 | local->wstats_flags |= local->hw.max_signal ? | 1738 | IEEE80211_HW_SIGNAL_DBM) ? |
1708 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; | 1739 | IW_QUAL_QUAL_UPDATED : IW_QUAL_QUAL_INVALID; |
1709 | local->wstats_flags |= local->hw.max_noise ? | 1740 | local->wstats_flags |= local->hw.flags & IEEE80211_HW_NOISE_DBM ? |
1710 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; | 1741 | IW_QUAL_NOISE_UPDATED : IW_QUAL_NOISE_INVALID; |
1711 | if (local->hw.max_rssi < 0 || local->hw.max_noise < 0) | 1742 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
1712 | local->wstats_flags |= IW_QUAL_DBM; | 1743 | local->wstats_flags |= IW_QUAL_DBM; |
1713 | 1744 | ||
1714 | result = sta_info_start(local); | 1745 | result = sta_info_start(local); |
@@ -1858,7 +1889,9 @@ static int __init ieee80211_init(void) | |||
1858 | struct sk_buff *skb; | 1889 | struct sk_buff *skb; |
1859 | int ret; | 1890 | int ret; |
1860 | 1891 | ||
1861 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_packet_data) > sizeof(skb->cb)); | 1892 | BUILD_BUG_ON(sizeof(struct ieee80211_tx_info) > sizeof(skb->cb)); |
1893 | BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + | ||
1894 | IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); | ||
1862 | 1895 | ||
1863 | ret = rc80211_pid_init(); | 1896 | ret = rc80211_pid_init(); |
1864 | if (ret) | 1897 | if (ret) |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 697ef67f96b..b5933b27149 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -315,6 +315,13 @@ struct mesh_table *mesh_table_alloc(int size_order) | |||
315 | return newtbl; | 315 | return newtbl; |
316 | } | 316 | } |
317 | 317 | ||
318 | static void __mesh_table_free(struct mesh_table *tbl) | ||
319 | { | ||
320 | kfree(tbl->hash_buckets); | ||
321 | kfree(tbl->hashwlock); | ||
322 | kfree(tbl); | ||
323 | } | ||
324 | |||
318 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | 325 | void mesh_table_free(struct mesh_table *tbl, bool free_leafs) |
319 | { | 326 | { |
320 | struct hlist_head *mesh_hash; | 327 | struct hlist_head *mesh_hash; |
@@ -330,9 +337,7 @@ void mesh_table_free(struct mesh_table *tbl, bool free_leafs) | |||
330 | } | 337 | } |
331 | spin_unlock(&tbl->hashwlock[i]); | 338 | spin_unlock(&tbl->hashwlock[i]); |
332 | } | 339 | } |
333 | kfree(tbl->hash_buckets); | 340 | __mesh_table_free(tbl); |
334 | kfree(tbl->hashwlock); | ||
335 | kfree(tbl); | ||
336 | } | 341 | } |
337 | 342 | ||
338 | static void ieee80211_mesh_path_timer(unsigned long data) | 343 | static void ieee80211_mesh_path_timer(unsigned long data) |
@@ -349,21 +354,16 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | |||
349 | { | 354 | { |
350 | struct mesh_table *newtbl; | 355 | struct mesh_table *newtbl; |
351 | struct hlist_head *oldhash; | 356 | struct hlist_head *oldhash; |
352 | struct hlist_node *p; | 357 | struct hlist_node *p, *q; |
353 | int err = 0; | ||
354 | int i; | 358 | int i; |
355 | 359 | ||
356 | if (atomic_read(&tbl->entries) | 360 | if (atomic_read(&tbl->entries) |
357 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) { | 361 | < tbl->mean_chain_len * (tbl->hash_mask + 1)) |
358 | err = -EPERM; | ||
359 | goto endgrow; | 362 | goto endgrow; |
360 | } | ||
361 | 363 | ||
362 | newtbl = mesh_table_alloc(tbl->size_order + 1); | 364 | newtbl = mesh_table_alloc(tbl->size_order + 1); |
363 | if (!newtbl) { | 365 | if (!newtbl) |
364 | err = -ENOMEM; | ||
365 | goto endgrow; | 366 | goto endgrow; |
366 | } | ||
367 | 367 | ||
368 | newtbl->free_node = tbl->free_node; | 368 | newtbl->free_node = tbl->free_node; |
369 | newtbl->mean_chain_len = tbl->mean_chain_len; | 369 | newtbl->mean_chain_len = tbl->mean_chain_len; |
@@ -373,13 +373,19 @@ struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | |||
373 | oldhash = tbl->hash_buckets; | 373 | oldhash = tbl->hash_buckets; |
374 | for (i = 0; i <= tbl->hash_mask; i++) | 374 | for (i = 0; i <= tbl->hash_mask; i++) |
375 | hlist_for_each(p, &oldhash[i]) | 375 | hlist_for_each(p, &oldhash[i]) |
376 | tbl->copy_node(p, newtbl); | 376 | if (tbl->copy_node(p, newtbl) < 0) |
377 | goto errcopy; | ||
377 | 378 | ||
379 | return newtbl; | ||
380 | |||
381 | errcopy: | ||
382 | for (i = 0; i <= newtbl->hash_mask; i++) { | ||
383 | hlist_for_each_safe(p, q, &newtbl->hash_buckets[i]) | ||
384 | tbl->free_node(p, 0); | ||
385 | } | ||
386 | __mesh_table_free(tbl); | ||
378 | endgrow: | 387 | endgrow: |
379 | if (err) | 388 | return NULL; |
380 | return NULL; | ||
381 | else | ||
382 | return newtbl; | ||
383 | } | 389 | } |
384 | 390 | ||
385 | /** | 391 | /** |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index 2e161f6d828..669eafafe49 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -109,7 +109,7 @@ struct mesh_table { | |||
109 | __u32 hash_rnd; /* Used for hash generation */ | 109 | __u32 hash_rnd; /* Used for hash generation */ |
110 | atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ | 110 | atomic_t entries; /* Up to MAX_MESH_NEIGHBOURS */ |
111 | void (*free_node) (struct hlist_node *p, bool free_leafs); | 111 | void (*free_node) (struct hlist_node *p, bool free_leafs); |
112 | void (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); | 112 | int (*copy_node) (struct hlist_node *p, struct mesh_table *newtbl); |
113 | int size_order; | 113 | int size_order; |
114 | int mean_chain_len; | 114 | int mean_chain_len; |
115 | }; | 115 | }; |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index af0cd1e3e21..7fa149e230e 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -26,7 +26,7 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae) | |||
26 | { | 26 | { |
27 | if (ae) | 27 | if (ae) |
28 | offset += 6; | 28 | offset += 6; |
29 | return le32_to_cpu(get_unaligned((__le32 *) (preq_elem + offset))); | 29 | return get_unaligned_le32(preq_elem + offset); |
30 | } | 30 | } |
31 | 31 | ||
32 | /* HWMP IE processing macros */ | 32 | /* HWMP IE processing macros */ |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 99c2d360888..5f88a2e6ee5 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -158,19 +158,14 @@ int mesh_path_add(u8 *dst, struct net_device *dev) | |||
158 | if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) | 158 | if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) |
159 | return -ENOSPC; | 159 | return -ENOSPC; |
160 | 160 | ||
161 | err = -ENOMEM; | ||
161 | new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL); | 162 | new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL); |
162 | if (!new_mpath) { | 163 | if (!new_mpath) |
163 | atomic_dec(&sdata->u.sta.mpaths); | 164 | goto err_path_alloc; |
164 | err = -ENOMEM; | 165 | |
165 | goto endadd2; | ||
166 | } | ||
167 | new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); | 166 | new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); |
168 | if (!new_node) { | 167 | if (!new_node) |
169 | kfree(new_mpath); | 168 | goto err_node_alloc; |
170 | atomic_dec(&sdata->u.sta.mpaths); | ||
171 | err = -ENOMEM; | ||
172 | goto endadd2; | ||
173 | } | ||
174 | 169 | ||
175 | read_lock(&pathtbl_resize_lock); | 170 | read_lock(&pathtbl_resize_lock); |
176 | memcpy(new_mpath->dst, dst, ETH_ALEN); | 171 | memcpy(new_mpath->dst, dst, ETH_ALEN); |
@@ -189,16 +184,11 @@ int mesh_path_add(u8 *dst, struct net_device *dev) | |||
189 | 184 | ||
190 | spin_lock(&mesh_paths->hashwlock[hash_idx]); | 185 | spin_lock(&mesh_paths->hashwlock[hash_idx]); |
191 | 186 | ||
187 | err = -EEXIST; | ||
192 | hlist_for_each_entry(node, n, bucket, list) { | 188 | hlist_for_each_entry(node, n, bucket, list) { |
193 | mpath = node->mpath; | 189 | mpath = node->mpath; |
194 | if (mpath->dev == dev && memcmp(dst, mpath->dst, ETH_ALEN) | 190 | if (mpath->dev == dev && memcmp(dst, mpath->dst, ETH_ALEN) == 0) |
195 | == 0) { | 191 | goto err_exists; |
196 | err = -EEXIST; | ||
197 | atomic_dec(&sdata->u.sta.mpaths); | ||
198 | kfree(new_node); | ||
199 | kfree(new_mpath); | ||
200 | goto endadd; | ||
201 | } | ||
202 | } | 192 | } |
203 | 193 | ||
204 | hlist_add_head_rcu(&new_node->list, bucket); | 194 | hlist_add_head_rcu(&new_node->list, bucket); |
@@ -206,10 +196,9 @@ int mesh_path_add(u8 *dst, struct net_device *dev) | |||
206 | mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) | 196 | mesh_paths->mean_chain_len * (mesh_paths->hash_mask + 1)) |
207 | grow = 1; | 197 | grow = 1; |
208 | 198 | ||
209 | endadd: | ||
210 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); | 199 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); |
211 | read_unlock(&pathtbl_resize_lock); | 200 | read_unlock(&pathtbl_resize_lock); |
212 | if (!err && grow) { | 201 | if (grow) { |
213 | struct mesh_table *oldtbl, *newtbl; | 202 | struct mesh_table *oldtbl, *newtbl; |
214 | 203 | ||
215 | write_lock(&pathtbl_resize_lock); | 204 | write_lock(&pathtbl_resize_lock); |
@@ -217,7 +206,7 @@ endadd: | |||
217 | newtbl = mesh_table_grow(mesh_paths); | 206 | newtbl = mesh_table_grow(mesh_paths); |
218 | if (!newtbl) { | 207 | if (!newtbl) { |
219 | write_unlock(&pathtbl_resize_lock); | 208 | write_unlock(&pathtbl_resize_lock); |
220 | return -ENOMEM; | 209 | return 0; |
221 | } | 210 | } |
222 | rcu_assign_pointer(mesh_paths, newtbl); | 211 | rcu_assign_pointer(mesh_paths, newtbl); |
223 | write_unlock(&pathtbl_resize_lock); | 212 | write_unlock(&pathtbl_resize_lock); |
@@ -225,7 +214,16 @@ endadd: | |||
225 | synchronize_rcu(); | 214 | synchronize_rcu(); |
226 | mesh_table_free(oldtbl, false); | 215 | mesh_table_free(oldtbl, false); |
227 | } | 216 | } |
228 | endadd2: | 217 | return 0; |
218 | |||
219 | err_exists: | ||
220 | spin_unlock(&mesh_paths->hashwlock[hash_idx]); | ||
221 | read_unlock(&pathtbl_resize_lock); | ||
222 | kfree(new_node); | ||
223 | err_node_alloc: | ||
224 | kfree(new_mpath); | ||
225 | err_path_alloc: | ||
226 | atomic_dec(&sdata->u.sta.mpaths); | ||
229 | return err; | 227 | return err; |
230 | } | 228 | } |
231 | 229 | ||
@@ -264,7 +262,6 @@ void mesh_plink_broken(struct sta_info *sta) | |||
264 | } | 262 | } |
265 | rcu_read_unlock(); | 263 | rcu_read_unlock(); |
266 | } | 264 | } |
267 | EXPORT_SYMBOL(mesh_plink_broken); | ||
268 | 265 | ||
269 | /** | 266 | /** |
270 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches | 267 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches |
@@ -460,25 +457,28 @@ static void mesh_path_node_free(struct hlist_node *p, bool free_leafs) | |||
460 | struct mpath_node *node = hlist_entry(p, struct mpath_node, list); | 457 | struct mpath_node *node = hlist_entry(p, struct mpath_node, list); |
461 | mpath = node->mpath; | 458 | mpath = node->mpath; |
462 | hlist_del_rcu(p); | 459 | hlist_del_rcu(p); |
463 | synchronize_rcu(); | ||
464 | if (free_leafs) | 460 | if (free_leafs) |
465 | kfree(mpath); | 461 | kfree(mpath); |
466 | kfree(node); | 462 | kfree(node); |
467 | } | 463 | } |
468 | 464 | ||
469 | static void mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) | 465 | static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl) |
470 | { | 466 | { |
471 | struct mesh_path *mpath; | 467 | struct mesh_path *mpath; |
472 | struct mpath_node *node, *new_node; | 468 | struct mpath_node *node, *new_node; |
473 | u32 hash_idx; | 469 | u32 hash_idx; |
474 | 470 | ||
471 | new_node = kmalloc(sizeof(struct mpath_node), GFP_ATOMIC); | ||
472 | if (new_node == NULL) | ||
473 | return -ENOMEM; | ||
474 | |||
475 | node = hlist_entry(p, struct mpath_node, list); | 475 | node = hlist_entry(p, struct mpath_node, list); |
476 | mpath = node->mpath; | 476 | mpath = node->mpath; |
477 | new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL); | ||
478 | new_node->mpath = mpath; | 477 | new_node->mpath = mpath; |
479 | hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl); | 478 | hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl); |
480 | hlist_add_head(&new_node->list, | 479 | hlist_add_head(&new_node->list, |
481 | &newtbl->hash_buckets[hash_idx]); | 480 | &newtbl->hash_buckets[hash_idx]); |
481 | return 0; | ||
482 | } | 482 | } |
483 | 483 | ||
484 | int mesh_pathtbl_init(void) | 484 | int mesh_pathtbl_init(void) |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 37f0c2b94ae..9efeb1f0702 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -79,7 +79,7 @@ void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) | |||
79 | * | 79 | * |
80 | * @sta: mes peer link to restart | 80 | * @sta: mes peer link to restart |
81 | * | 81 | * |
82 | * Locking: this function must be called holding sta->plink_lock | 82 | * Locking: this function must be called holding sta->lock |
83 | */ | 83 | */ |
84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) | 84 | static inline void mesh_plink_fsm_restart(struct sta_info *sta) |
85 | { | 85 | { |
@@ -105,7 +105,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
105 | if (!sta) | 105 | if (!sta) |
106 | return NULL; | 106 | return NULL; |
107 | 107 | ||
108 | sta->flags |= WLAN_STA_AUTHORIZED; | 108 | sta->flags = WLAN_STA_AUTHORIZED; |
109 | sta->supp_rates[local->hw.conf.channel->band] = rates; | 109 | sta->supp_rates[local->hw.conf.channel->band] = rates; |
110 | 110 | ||
111 | return sta; | 111 | return sta; |
@@ -118,7 +118,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
118 | * | 118 | * |
119 | * All mesh paths with this peer as next hop will be flushed | 119 | * All mesh paths with this peer as next hop will be flushed |
120 | * | 120 | * |
121 | * Locking: the caller must hold sta->plink_lock | 121 | * Locking: the caller must hold sta->lock |
122 | */ | 122 | */ |
123 | static void __mesh_plink_deactivate(struct sta_info *sta) | 123 | static void __mesh_plink_deactivate(struct sta_info *sta) |
124 | { | 124 | { |
@@ -139,9 +139,9 @@ static void __mesh_plink_deactivate(struct sta_info *sta) | |||
139 | */ | 139 | */ |
140 | void mesh_plink_deactivate(struct sta_info *sta) | 140 | void mesh_plink_deactivate(struct sta_info *sta) |
141 | { | 141 | { |
142 | spin_lock_bh(&sta->plink_lock); | 142 | spin_lock_bh(&sta->lock); |
143 | __mesh_plink_deactivate(sta); | 143 | __mesh_plink_deactivate(sta); |
144 | spin_unlock_bh(&sta->plink_lock); | 144 | spin_unlock_bh(&sta->lock); |
145 | } | 145 | } |
146 | 146 | ||
147 | static int mesh_plink_frame_tx(struct net_device *dev, | 147 | static int mesh_plink_frame_tx(struct net_device *dev, |
@@ -270,10 +270,10 @@ static void mesh_plink_timer(unsigned long data) | |||
270 | */ | 270 | */ |
271 | sta = (struct sta_info *) data; | 271 | sta = (struct sta_info *) data; |
272 | 272 | ||
273 | spin_lock_bh(&sta->plink_lock); | 273 | spin_lock_bh(&sta->lock); |
274 | if (sta->ignore_plink_timer) { | 274 | if (sta->ignore_plink_timer) { |
275 | sta->ignore_plink_timer = false; | 275 | sta->ignore_plink_timer = false; |
276 | spin_unlock_bh(&sta->plink_lock); | 276 | spin_unlock_bh(&sta->lock); |
277 | return; | 277 | return; |
278 | } | 278 | } |
279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", | 279 | mpl_dbg("Mesh plink timer for %s fired on state %d\n", |
@@ -298,7 +298,7 @@ static void mesh_plink_timer(unsigned long data) | |||
298 | rand % sta->plink_timeout; | 298 | rand % sta->plink_timeout; |
299 | ++sta->plink_retries; | 299 | ++sta->plink_retries; |
300 | mod_plink_timer(sta, sta->plink_timeout); | 300 | mod_plink_timer(sta, sta->plink_timeout); |
301 | spin_unlock_bh(&sta->plink_lock); | 301 | spin_unlock_bh(&sta->lock); |
302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 302 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
303 | 0, 0); | 303 | 0, 0); |
304 | break; | 304 | break; |
@@ -311,7 +311,7 @@ static void mesh_plink_timer(unsigned long data) | |||
311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); | 311 | reason = cpu_to_le16(MESH_CONFIRM_TIMEOUT); |
312 | sta->plink_state = PLINK_HOLDING; | 312 | sta->plink_state = PLINK_HOLDING; |
313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 313 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
314 | spin_unlock_bh(&sta->plink_lock); | 314 | spin_unlock_bh(&sta->lock); |
315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, | 315 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, |
316 | reason); | 316 | reason); |
317 | break; | 317 | break; |
@@ -319,10 +319,10 @@ static void mesh_plink_timer(unsigned long data) | |||
319 | /* holding timer */ | 319 | /* holding timer */ |
320 | del_timer(&sta->plink_timer); | 320 | del_timer(&sta->plink_timer); |
321 | mesh_plink_fsm_restart(sta); | 321 | mesh_plink_fsm_restart(sta); |
322 | spin_unlock_bh(&sta->plink_lock); | 322 | spin_unlock_bh(&sta->lock); |
323 | break; | 323 | break; |
324 | default: | 324 | default: |
325 | spin_unlock_bh(&sta->plink_lock); | 325 | spin_unlock_bh(&sta->lock); |
326 | break; | 326 | break; |
327 | } | 327 | } |
328 | } | 328 | } |
@@ -344,16 +344,16 @@ int mesh_plink_open(struct sta_info *sta) | |||
344 | DECLARE_MAC_BUF(mac); | 344 | DECLARE_MAC_BUF(mac); |
345 | #endif | 345 | #endif |
346 | 346 | ||
347 | spin_lock_bh(&sta->plink_lock); | 347 | spin_lock_bh(&sta->lock); |
348 | get_random_bytes(&llid, 2); | 348 | get_random_bytes(&llid, 2); |
349 | sta->llid = llid; | 349 | sta->llid = llid; |
350 | if (sta->plink_state != PLINK_LISTEN) { | 350 | if (sta->plink_state != PLINK_LISTEN) { |
351 | spin_unlock_bh(&sta->plink_lock); | 351 | spin_unlock_bh(&sta->lock); |
352 | return -EBUSY; | 352 | return -EBUSY; |
353 | } | 353 | } |
354 | sta->plink_state = PLINK_OPN_SNT; | 354 | sta->plink_state = PLINK_OPN_SNT; |
355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 355 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
356 | spin_unlock_bh(&sta->plink_lock); | 356 | spin_unlock_bh(&sta->lock); |
357 | mpl_dbg("Mesh plink: starting establishment with %s\n", | 357 | mpl_dbg("Mesh plink: starting establishment with %s\n", |
358 | print_mac(mac, sta->addr)); | 358 | print_mac(mac, sta->addr)); |
359 | 359 | ||
@@ -367,10 +367,10 @@ void mesh_plink_block(struct sta_info *sta) | |||
367 | DECLARE_MAC_BUF(mac); | 367 | DECLARE_MAC_BUF(mac); |
368 | #endif | 368 | #endif |
369 | 369 | ||
370 | spin_lock_bh(&sta->plink_lock); | 370 | spin_lock_bh(&sta->lock); |
371 | __mesh_plink_deactivate(sta); | 371 | __mesh_plink_deactivate(sta); |
372 | sta->plink_state = PLINK_BLOCKED; | 372 | sta->plink_state = PLINK_BLOCKED; |
373 | spin_unlock_bh(&sta->plink_lock); | 373 | spin_unlock_bh(&sta->lock); |
374 | } | 374 | } |
375 | 375 | ||
376 | int mesh_plink_close(struct sta_info *sta) | 376 | int mesh_plink_close(struct sta_info *sta) |
@@ -383,14 +383,14 @@ int mesh_plink_close(struct sta_info *sta) | |||
383 | 383 | ||
384 | mpl_dbg("Mesh plink: closing link with %s\n", | 384 | mpl_dbg("Mesh plink: closing link with %s\n", |
385 | print_mac(mac, sta->addr)); | 385 | print_mac(mac, sta->addr)); |
386 | spin_lock_bh(&sta->plink_lock); | 386 | spin_lock_bh(&sta->lock); |
387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); | 387 | sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); |
388 | reason = sta->reason; | 388 | reason = sta->reason; |
389 | 389 | ||
390 | if (sta->plink_state == PLINK_LISTEN || | 390 | if (sta->plink_state == PLINK_LISTEN || |
391 | sta->plink_state == PLINK_BLOCKED) { | 391 | sta->plink_state == PLINK_BLOCKED) { |
392 | mesh_plink_fsm_restart(sta); | 392 | mesh_plink_fsm_restart(sta); |
393 | spin_unlock_bh(&sta->plink_lock); | 393 | spin_unlock_bh(&sta->lock); |
394 | return 0; | 394 | return 0; |
395 | } else if (sta->plink_state == PLINK_ESTAB) { | 395 | } else if (sta->plink_state == PLINK_ESTAB) { |
396 | __mesh_plink_deactivate(sta); | 396 | __mesh_plink_deactivate(sta); |
@@ -402,7 +402,7 @@ int mesh_plink_close(struct sta_info *sta) | |||
402 | sta->plink_state = PLINK_HOLDING; | 402 | sta->plink_state = PLINK_HOLDING; |
403 | llid = sta->llid; | 403 | llid = sta->llid; |
404 | plid = sta->plid; | 404 | plid = sta->plid; |
405 | spin_unlock_bh(&sta->plink_lock); | 405 | spin_unlock_bh(&sta->lock); |
406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, | 406 | mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, |
407 | plid, reason); | 407 | plid, reason); |
408 | return 0; | 408 | return 0; |
@@ -490,7 +490,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
490 | /* avoid warning */ | 490 | /* avoid warning */ |
491 | break; | 491 | break; |
492 | } | 492 | } |
493 | spin_lock_bh(&sta->plink_lock); | 493 | spin_lock_bh(&sta->lock); |
494 | } else if (!sta) { | 494 | } else if (!sta) { |
495 | /* ftype == PLINK_OPEN */ | 495 | /* ftype == PLINK_OPEN */ |
496 | u64 rates; | 496 | u64 rates; |
@@ -512,9 +512,9 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
512 | return; | 512 | return; |
513 | } | 513 | } |
514 | event = OPN_ACPT; | 514 | event = OPN_ACPT; |
515 | spin_lock_bh(&sta->plink_lock); | 515 | spin_lock_bh(&sta->lock); |
516 | } else { | 516 | } else { |
517 | spin_lock_bh(&sta->plink_lock); | 517 | spin_lock_bh(&sta->lock); |
518 | switch (ftype) { | 518 | switch (ftype) { |
519 | case PLINK_OPEN: | 519 | case PLINK_OPEN: |
520 | if (!mesh_plink_free_count(sdata) || | 520 | if (!mesh_plink_free_count(sdata) || |
@@ -551,7 +551,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
551 | break; | 551 | break; |
552 | default: | 552 | default: |
553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); | 553 | mpl_dbg("Mesh plink: unknown frame subtype\n"); |
554 | spin_unlock_bh(&sta->plink_lock); | 554 | spin_unlock_bh(&sta->lock); |
555 | rcu_read_unlock(); | 555 | rcu_read_unlock(); |
556 | return; | 556 | return; |
557 | } | 557 | } |
@@ -568,7 +568,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
568 | switch (event) { | 568 | switch (event) { |
569 | case CLS_ACPT: | 569 | case CLS_ACPT: |
570 | mesh_plink_fsm_restart(sta); | 570 | mesh_plink_fsm_restart(sta); |
571 | spin_unlock_bh(&sta->plink_lock); | 571 | spin_unlock_bh(&sta->lock); |
572 | break; | 572 | break; |
573 | case OPN_ACPT: | 573 | case OPN_ACPT: |
574 | sta->plink_state = PLINK_OPN_RCVD; | 574 | sta->plink_state = PLINK_OPN_RCVD; |
@@ -576,14 +576,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
576 | get_random_bytes(&llid, 2); | 576 | get_random_bytes(&llid, 2); |
577 | sta->llid = llid; | 577 | sta->llid = llid; |
578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 578 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
579 | spin_unlock_bh(&sta->plink_lock); | 579 | spin_unlock_bh(&sta->lock); |
580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, | 580 | mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, |
581 | 0, 0); | 581 | 0, 0); |
582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, | 582 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, |
583 | llid, plid, 0); | 583 | llid, plid, 0); |
584 | break; | 584 | break; |
585 | default: | 585 | default: |
586 | spin_unlock_bh(&sta->plink_lock); | 586 | spin_unlock_bh(&sta->lock); |
587 | break; | 587 | break; |
588 | } | 588 | } |
589 | break; | 589 | break; |
@@ -603,7 +603,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
603 | sta->ignore_plink_timer = true; | 603 | sta->ignore_plink_timer = true; |
604 | 604 | ||
605 | llid = sta->llid; | 605 | llid = sta->llid; |
606 | spin_unlock_bh(&sta->plink_lock); | 606 | spin_unlock_bh(&sta->lock); |
607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 607 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
608 | plid, reason); | 608 | plid, reason); |
609 | break; | 609 | break; |
@@ -612,7 +612,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
612 | sta->plink_state = PLINK_OPN_RCVD; | 612 | sta->plink_state = PLINK_OPN_RCVD; |
613 | sta->plid = plid; | 613 | sta->plid = plid; |
614 | llid = sta->llid; | 614 | llid = sta->llid; |
615 | spin_unlock_bh(&sta->plink_lock); | 615 | spin_unlock_bh(&sta->lock); |
616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 616 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
617 | plid, 0); | 617 | plid, 0); |
618 | break; | 618 | break; |
@@ -622,10 +622,10 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
622 | dot11MeshConfirmTimeout(sdata))) | 622 | dot11MeshConfirmTimeout(sdata))) |
623 | sta->ignore_plink_timer = true; | 623 | sta->ignore_plink_timer = true; |
624 | 624 | ||
625 | spin_unlock_bh(&sta->plink_lock); | 625 | spin_unlock_bh(&sta->lock); |
626 | break; | 626 | break; |
627 | default: | 627 | default: |
628 | spin_unlock_bh(&sta->plink_lock); | 628 | spin_unlock_bh(&sta->lock); |
629 | break; | 629 | break; |
630 | } | 630 | } |
631 | break; | 631 | break; |
@@ -645,13 +645,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
645 | sta->ignore_plink_timer = true; | 645 | sta->ignore_plink_timer = true; |
646 | 646 | ||
647 | llid = sta->llid; | 647 | llid = sta->llid; |
648 | spin_unlock_bh(&sta->plink_lock); | 648 | spin_unlock_bh(&sta->lock); |
649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 649 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
650 | plid, reason); | 650 | plid, reason); |
651 | break; | 651 | break; |
652 | case OPN_ACPT: | 652 | case OPN_ACPT: |
653 | llid = sta->llid; | 653 | llid = sta->llid; |
654 | spin_unlock_bh(&sta->plink_lock); | 654 | spin_unlock_bh(&sta->lock); |
655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 655 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
656 | plid, 0); | 656 | plid, 0); |
657 | break; | 657 | break; |
@@ -659,12 +659,12 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
659 | del_timer(&sta->plink_timer); | 659 | del_timer(&sta->plink_timer); |
660 | sta->plink_state = PLINK_ESTAB; | 660 | sta->plink_state = PLINK_ESTAB; |
661 | mesh_plink_inc_estab_count(sdata); | 661 | mesh_plink_inc_estab_count(sdata); |
662 | spin_unlock_bh(&sta->plink_lock); | 662 | spin_unlock_bh(&sta->lock); |
663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 663 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
664 | print_mac(mac, sta->addr)); | 664 | print_mac(mac, sta->addr)); |
665 | break; | 665 | break; |
666 | default: | 666 | default: |
667 | spin_unlock_bh(&sta->plink_lock); | 667 | spin_unlock_bh(&sta->lock); |
668 | break; | 668 | break; |
669 | } | 669 | } |
670 | break; | 670 | break; |
@@ -684,7 +684,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
684 | sta->ignore_plink_timer = true; | 684 | sta->ignore_plink_timer = true; |
685 | 685 | ||
686 | llid = sta->llid; | 686 | llid = sta->llid; |
687 | spin_unlock_bh(&sta->plink_lock); | 687 | spin_unlock_bh(&sta->lock); |
688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 688 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
689 | plid, reason); | 689 | plid, reason); |
690 | break; | 690 | break; |
@@ -692,14 +692,14 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
692 | del_timer(&sta->plink_timer); | 692 | del_timer(&sta->plink_timer); |
693 | sta->plink_state = PLINK_ESTAB; | 693 | sta->plink_state = PLINK_ESTAB; |
694 | mesh_plink_inc_estab_count(sdata); | 694 | mesh_plink_inc_estab_count(sdata); |
695 | spin_unlock_bh(&sta->plink_lock); | 695 | spin_unlock_bh(&sta->lock); |
696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", | 696 | mpl_dbg("Mesh plink with %s ESTABLISHED\n", |
697 | print_mac(mac, sta->addr)); | 697 | print_mac(mac, sta->addr)); |
698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 698 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
699 | plid, 0); | 699 | plid, 0); |
700 | break; | 700 | break; |
701 | default: | 701 | default: |
702 | spin_unlock_bh(&sta->plink_lock); | 702 | spin_unlock_bh(&sta->lock); |
703 | break; | 703 | break; |
704 | } | 704 | } |
705 | break; | 705 | break; |
@@ -713,18 +713,18 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
713 | sta->plink_state = PLINK_HOLDING; | 713 | sta->plink_state = PLINK_HOLDING; |
714 | llid = sta->llid; | 714 | llid = sta->llid; |
715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); | 715 | mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); |
716 | spin_unlock_bh(&sta->plink_lock); | 716 | spin_unlock_bh(&sta->lock); |
717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 717 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
718 | plid, reason); | 718 | plid, reason); |
719 | break; | 719 | break; |
720 | case OPN_ACPT: | 720 | case OPN_ACPT: |
721 | llid = sta->llid; | 721 | llid = sta->llid; |
722 | spin_unlock_bh(&sta->plink_lock); | 722 | spin_unlock_bh(&sta->lock); |
723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, | 723 | mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, |
724 | plid, 0); | 724 | plid, 0); |
725 | break; | 725 | break; |
726 | default: | 726 | default: |
727 | spin_unlock_bh(&sta->plink_lock); | 727 | spin_unlock_bh(&sta->lock); |
728 | break; | 728 | break; |
729 | } | 729 | } |
730 | break; | 730 | break; |
@@ -734,7 +734,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
734 | if (del_timer(&sta->plink_timer)) | 734 | if (del_timer(&sta->plink_timer)) |
735 | sta->ignore_plink_timer = 1; | 735 | sta->ignore_plink_timer = 1; |
736 | mesh_plink_fsm_restart(sta); | 736 | mesh_plink_fsm_restart(sta); |
737 | spin_unlock_bh(&sta->plink_lock); | 737 | spin_unlock_bh(&sta->lock); |
738 | break; | 738 | break; |
739 | case OPN_ACPT: | 739 | case OPN_ACPT: |
740 | case CNF_ACPT: | 740 | case CNF_ACPT: |
@@ -742,19 +742,19 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, | |||
742 | case CNF_RJCT: | 742 | case CNF_RJCT: |
743 | llid = sta->llid; | 743 | llid = sta->llid; |
744 | reason = sta->reason; | 744 | reason = sta->reason; |
745 | spin_unlock_bh(&sta->plink_lock); | 745 | spin_unlock_bh(&sta->lock); |
746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, | 746 | mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, |
747 | plid, reason); | 747 | plid, reason); |
748 | break; | 748 | break; |
749 | default: | 749 | default: |
750 | spin_unlock_bh(&sta->plink_lock); | 750 | spin_unlock_bh(&sta->lock); |
751 | } | 751 | } |
752 | break; | 752 | break; |
753 | default: | 753 | default: |
754 | /* should not get here, PLINK_BLOCKED is dealt with at the | 754 | /* should not get here, PLINK_BLOCKED is dealt with at the |
755 | * beggining of the function | 755 | * beggining of the function |
756 | */ | 756 | */ |
757 | spin_unlock_bh(&sta->plink_lock); | 757 | spin_unlock_bh(&sta->lock); |
758 | break; | 758 | break; |
759 | } | 759 | } |
760 | 760 | ||
diff --git a/net/mac80211/michael.c b/net/mac80211/michael.c index 0f844f7895f..1fcdf38cf60 100644 --- a/net/mac80211/michael.c +++ b/net/mac80211/michael.c | |||
@@ -6,85 +6,58 @@ | |||
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | |||
10 | #include <linux/types.h> | 9 | #include <linux/types.h> |
10 | #include <linux/bitops.h> | ||
11 | #include <asm/unaligned.h> | ||
11 | 12 | ||
12 | #include "michael.h" | 13 | #include "michael.h" |
13 | 14 | ||
14 | static inline u32 rotr(u32 val, int bits) | 15 | static void michael_block(struct michael_mic_ctx *mctx, u32 val) |
15 | { | ||
16 | return (val >> bits) | (val << (32 - bits)); | ||
17 | } | ||
18 | |||
19 | |||
20 | static inline u32 rotl(u32 val, int bits) | ||
21 | { | ||
22 | return (val << bits) | (val >> (32 - bits)); | ||
23 | } | ||
24 | |||
25 | |||
26 | static inline u32 xswap(u32 val) | ||
27 | { | ||
28 | return ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); | ||
29 | } | ||
30 | |||
31 | |||
32 | #define michael_block(l, r) \ | ||
33 | do { \ | ||
34 | r ^= rotl(l, 17); \ | ||
35 | l += r; \ | ||
36 | r ^= xswap(l); \ | ||
37 | l += r; \ | ||
38 | r ^= rotl(l, 3); \ | ||
39 | l += r; \ | ||
40 | r ^= rotr(l, 2); \ | ||
41 | l += r; \ | ||
42 | } while (0) | ||
43 | |||
44 | |||
45 | static inline u32 michael_get32(u8 *data) | ||
46 | { | 16 | { |
47 | return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); | 17 | mctx->l ^= val; |
18 | mctx->r ^= rol32(mctx->l, 17); | ||
19 | mctx->l += mctx->r; | ||
20 | mctx->r ^= ((mctx->l & 0xff00ff00) >> 8) | | ||
21 | ((mctx->l & 0x00ff00ff) << 8); | ||
22 | mctx->l += mctx->r; | ||
23 | mctx->r ^= rol32(mctx->l, 3); | ||
24 | mctx->l += mctx->r; | ||
25 | mctx->r ^= ror32(mctx->l, 2); | ||
26 | mctx->l += mctx->r; | ||
48 | } | 27 | } |
49 | 28 | ||
50 | 29 | static void michael_mic_hdr(struct michael_mic_ctx *mctx, | |
51 | static inline void michael_put32(u32 val, u8 *data) | 30 | const u8 *key, const u8 *da, const u8 *sa, u8 priority) |
52 | { | 31 | { |
53 | data[0] = val & 0xff; | 32 | mctx->l = get_unaligned_le32(key); |
54 | data[1] = (val >> 8) & 0xff; | 33 | mctx->r = get_unaligned_le32(key + 4); |
55 | data[2] = (val >> 16) & 0xff; | 34 | |
56 | data[3] = (val >> 24) & 0xff; | 35 | /* |
36 | * A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC | ||
37 | * calculation, but it is _not_ transmitted | ||
38 | */ | ||
39 | michael_block(mctx, get_unaligned_le32(da)); | ||
40 | michael_block(mctx, get_unaligned_le16(&da[4]) | | ||
41 | (get_unaligned_le16(sa) << 16)); | ||
42 | michael_block(mctx, get_unaligned_le32(&sa[2])); | ||
43 | michael_block(mctx, priority); | ||
57 | } | 44 | } |
58 | 45 | ||
59 | 46 | void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, | |
60 | void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, | 47 | const u8 *data, size_t data_len, u8 *mic) |
61 | u8 *data, size_t data_len, u8 *mic) | ||
62 | { | 48 | { |
63 | u32 l, r, val; | 49 | u32 val; |
64 | size_t block, blocks, left; | 50 | size_t block, blocks, left; |
51 | struct michael_mic_ctx mctx; | ||
65 | 52 | ||
66 | l = michael_get32(key); | 53 | michael_mic_hdr(&mctx, key, da, sa, priority); |
67 | r = michael_get32(key + 4); | ||
68 | |||
69 | /* A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC | ||
70 | * calculation, but it is _not_ transmitted */ | ||
71 | l ^= michael_get32(da); | ||
72 | michael_block(l, r); | ||
73 | l ^= da[4] | (da[5] << 8) | (sa[0] << 16) | (sa[1] << 24); | ||
74 | michael_block(l, r); | ||
75 | l ^= michael_get32(&sa[2]); | ||
76 | michael_block(l, r); | ||
77 | l ^= priority; | ||
78 | michael_block(l, r); | ||
79 | 54 | ||
80 | /* Real data */ | 55 | /* Real data */ |
81 | blocks = data_len / 4; | 56 | blocks = data_len / 4; |
82 | left = data_len % 4; | 57 | left = data_len % 4; |
83 | 58 | ||
84 | for (block = 0; block < blocks; block++) { | 59 | for (block = 0; block < blocks; block++) |
85 | l ^= michael_get32(&data[block * 4]); | 60 | michael_block(&mctx, get_unaligned_le32(&data[block * 4])); |
86 | michael_block(l, r); | ||
87 | } | ||
88 | 61 | ||
89 | /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make | 62 | /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make |
90 | * total length a multiple of 4. */ | 63 | * total length a multiple of 4. */ |
@@ -94,11 +67,10 @@ void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, | |||
94 | left--; | 67 | left--; |
95 | val |= data[blocks * 4 + left]; | 68 | val |= data[blocks * 4 + left]; |
96 | } | 69 | } |
97 | l ^= val; | ||
98 | michael_block(l, r); | ||
99 | /* last block is zero, so l ^ 0 = l */ | ||
100 | michael_block(l, r); | ||
101 | 70 | ||
102 | michael_put32(l, mic); | 71 | michael_block(&mctx, val); |
103 | michael_put32(r, mic + 4); | 72 | michael_block(&mctx, 0); |
73 | |||
74 | put_unaligned_le32(mctx.l, mic); | ||
75 | put_unaligned_le32(mctx.r, mic + 4); | ||
104 | } | 76 | } |
diff --git a/net/mac80211/michael.h b/net/mac80211/michael.h index 2e6aebabeea..69b4501f13b 100644 --- a/net/mac80211/michael.h +++ b/net/mac80211/michael.h | |||
@@ -14,7 +14,11 @@ | |||
14 | 14 | ||
15 | #define MICHAEL_MIC_LEN 8 | 15 | #define MICHAEL_MIC_LEN 8 |
16 | 16 | ||
17 | void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, | 17 | struct michael_mic_ctx { |
18 | u8 *data, size_t data_len, u8 *mic); | 18 | u32 l, r; |
19 | }; | ||
20 | |||
21 | void michael_mic(const u8 *key, const u8 *da, const u8 *sa, u8 priority, | ||
22 | const u8 *data, size_t data_len, u8 *mic); | ||
19 | 23 | ||
20 | #endif /* MICHAEL_H */ | 24 | #endif /* MICHAEL_H */ |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4d2b582dd05..4a3bddd206d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -87,6 +87,7 @@ static int ieee80211_sta_start_scan(struct net_device *dev, | |||
87 | u8 *ssid, size_t ssid_len); | 87 | u8 *ssid, size_t ssid_len); |
88 | static int ieee80211_sta_config_auth(struct net_device *dev, | 88 | static int ieee80211_sta_config_auth(struct net_device *dev, |
89 | struct ieee80211_if_sta *ifsta); | 89 | struct ieee80211_if_sta *ifsta); |
90 | static void sta_rx_agg_session_timer_expired(unsigned long data); | ||
90 | 91 | ||
91 | 92 | ||
92 | void ieee802_11_parse_elems(u8 *start, size_t len, | 93 | void ieee802_11_parse_elems(u8 *start, size_t len, |
@@ -203,6 +204,25 @@ void ieee802_11_parse_elems(u8 *start, size_t len, | |||
203 | elems->perr = pos; | 204 | elems->perr = pos; |
204 | elems->perr_len = elen; | 205 | elems->perr_len = elen; |
205 | 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; | ||
206 | default: | 226 | default: |
207 | break; | 227 | break; |
208 | } | 228 | } |
@@ -256,19 +276,8 @@ static void ieee80211_sta_def_wmm_params(struct net_device *dev, | |||
256 | qparam.cw_max = 1023; | 276 | qparam.cw_max = 1023; |
257 | qparam.txop = 0; | 277 | qparam.txop = 0; |
258 | 278 | ||
259 | for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) | 279 | for (i = 0; i < local_to_hw(local)->queues; i++) |
260 | local->ops->conf_tx(local_to_hw(local), | 280 | local->ops->conf_tx(local_to_hw(local), i, &qparam); |
261 | i + IEEE80211_TX_QUEUE_DATA0, | ||
262 | &qparam); | ||
263 | |||
264 | if (ibss) { | ||
265 | /* IBSS uses different parameters for Beacon sending */ | ||
266 | qparam.cw_min++; | ||
267 | qparam.cw_min *= 2; | ||
268 | qparam.cw_min--; | ||
269 | local->ops->conf_tx(local_to_hw(local), | ||
270 | IEEE80211_TX_QUEUE_BEACON, &qparam); | ||
271 | } | ||
272 | } | 281 | } |
273 | } | 282 | } |
274 | 283 | ||
@@ -282,6 +291,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
282 | int count; | 291 | int count; |
283 | u8 *pos; | 292 | u8 *pos; |
284 | 293 | ||
294 | if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) | ||
295 | return; | ||
296 | |||
297 | if (!wmm_param) | ||
298 | return; | ||
299 | |||
285 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) | 300 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) |
286 | return; | 301 | return; |
287 | count = wmm_param[6] & 0x0f; | 302 | count = wmm_param[6] & 0x0f; |
@@ -305,29 +320,25 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
305 | 320 | ||
306 | switch (aci) { | 321 | switch (aci) { |
307 | case 1: | 322 | case 1: |
308 | queue = IEEE80211_TX_QUEUE_DATA3; | 323 | queue = 3; |
309 | if (acm) { | 324 | if (acm) |
310 | local->wmm_acm |= BIT(0) | BIT(3); | 325 | local->wmm_acm |= BIT(0) | BIT(3); |
311 | } | ||
312 | break; | 326 | break; |
313 | case 2: | 327 | case 2: |
314 | queue = IEEE80211_TX_QUEUE_DATA1; | 328 | queue = 1; |
315 | if (acm) { | 329 | if (acm) |
316 | local->wmm_acm |= BIT(4) | BIT(5); | 330 | local->wmm_acm |= BIT(4) | BIT(5); |
317 | } | ||
318 | break; | 331 | break; |
319 | case 3: | 332 | case 3: |
320 | queue = IEEE80211_TX_QUEUE_DATA0; | 333 | queue = 0; |
321 | if (acm) { | 334 | if (acm) |
322 | local->wmm_acm |= BIT(6) | BIT(7); | 335 | local->wmm_acm |= BIT(6) | BIT(7); |
323 | } | ||
324 | break; | 336 | break; |
325 | case 0: | 337 | case 0: |
326 | default: | 338 | default: |
327 | queue = IEEE80211_TX_QUEUE_DATA2; | 339 | queue = 2; |
328 | if (acm) { | 340 | if (acm) |
329 | local->wmm_acm |= BIT(1) | BIT(2); | 341 | local->wmm_acm |= BIT(1) | BIT(2); |
330 | } | ||
331 | break; | 342 | break; |
332 | } | 343 | } |
333 | 344 | ||
@@ -335,7 +346,7 @@ static void ieee80211_sta_wmm_params(struct net_device *dev, | |||
335 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); | 346 | params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); |
336 | params.cw_min = ecw2cw(pos[1] & 0x0f); | 347 | params.cw_min = ecw2cw(pos[1] & 0x0f); |
337 | params.txop = pos[2] | (pos[3] << 8); | 348 | params.txop = pos[2] | (pos[3] << 8); |
338 | #ifdef CONFIG_MAC80211_DEBUG | 349 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
339 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " | 350 | printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " |
340 | "cWmin=%d cWmax=%d txop=%d\n", | 351 | "cWmin=%d cWmax=%d txop=%d\n", |
341 | dev->name, queue, aci, acm, params.aifs, params.cw_min, | 352 | dev->name, queue, aci, acm, params.aifs, params.cw_min, |
@@ -360,6 +371,7 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
360 | u32 changed = 0; | 371 | u32 changed = 0; |
361 | 372 | ||
362 | if (use_protection != bss_conf->use_cts_prot) { | 373 | if (use_protection != bss_conf->use_cts_prot) { |
374 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
363 | if (net_ratelimit()) { | 375 | if (net_ratelimit()) { |
364 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" | 376 | printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" |
365 | "%s)\n", | 377 | "%s)\n", |
@@ -367,11 +379,13 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
367 | use_protection ? "enabled" : "disabled", | 379 | use_protection ? "enabled" : "disabled", |
368 | print_mac(mac, ifsta->bssid)); | 380 | print_mac(mac, ifsta->bssid)); |
369 | } | 381 | } |
382 | #endif | ||
370 | bss_conf->use_cts_prot = use_protection; | 383 | bss_conf->use_cts_prot = use_protection; |
371 | changed |= BSS_CHANGED_ERP_CTS_PROT; | 384 | changed |= BSS_CHANGED_ERP_CTS_PROT; |
372 | } | 385 | } |
373 | 386 | ||
374 | if (use_short_preamble != bss_conf->use_short_preamble) { | 387 | if (use_short_preamble != bss_conf->use_short_preamble) { |
388 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
375 | if (net_ratelimit()) { | 389 | if (net_ratelimit()) { |
376 | printk(KERN_DEBUG "%s: switched to %s barker preamble" | 390 | printk(KERN_DEBUG "%s: switched to %s barker preamble" |
377 | " (BSSID=%s)\n", | 391 | " (BSSID=%s)\n", |
@@ -379,6 +393,7 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, | |||
379 | use_short_preamble ? "short" : "long", | 393 | use_short_preamble ? "short" : "long", |
380 | print_mac(mac, ifsta->bssid)); | 394 | print_mac(mac, ifsta->bssid)); |
381 | } | 395 | } |
396 | #endif | ||
382 | bss_conf->use_short_preamble = use_short_preamble; | 397 | bss_conf->use_short_preamble = use_short_preamble; |
383 | changed |= BSS_CHANGED_ERP_PREAMBLE; | 398 | changed |= BSS_CHANGED_ERP_PREAMBLE; |
384 | } | 399 | } |
@@ -586,7 +601,7 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
586 | int encrypt) | 601 | int encrypt) |
587 | { | 602 | { |
588 | struct ieee80211_sub_if_data *sdata; | 603 | struct ieee80211_sub_if_data *sdata; |
589 | struct ieee80211_tx_packet_data *pkt_data; | 604 | struct ieee80211_tx_info *info; |
590 | 605 | ||
591 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 606 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
592 | skb->dev = sdata->local->mdev; | 607 | skb->dev = sdata->local->mdev; |
@@ -594,11 +609,11 @@ void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, | |||
594 | skb_set_network_header(skb, 0); | 609 | skb_set_network_header(skb, 0); |
595 | skb_set_transport_header(skb, 0); | 610 | skb_set_transport_header(skb, 0); |
596 | 611 | ||
597 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 612 | info = IEEE80211_SKB_CB(skb); |
598 | memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); | 613 | memset(info, 0, sizeof(struct ieee80211_tx_info)); |
599 | pkt_data->ifindex = sdata->dev->ifindex; | 614 | info->control.ifindex = sdata->dev->ifindex; |
600 | if (!encrypt) | 615 | if (!encrypt) |
601 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 616 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
602 | 617 | ||
603 | dev_queue_xmit(skb); | 618 | dev_queue_xmit(skb); |
604 | } | 619 | } |
@@ -727,9 +742,8 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
727 | if (bss) { | 742 | if (bss) { |
728 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) | 743 | if (bss->capability & WLAN_CAPABILITY_PRIVACY) |
729 | capab |= WLAN_CAPABILITY_PRIVACY; | 744 | capab |= WLAN_CAPABILITY_PRIVACY; |
730 | if (bss->wmm_ie) { | 745 | if (bss->wmm_ie) |
731 | wmm = 1; | 746 | wmm = 1; |
732 | } | ||
733 | 747 | ||
734 | /* get all rates supported by the device and the AP as | 748 | /* get all rates supported by the device and the AP as |
735 | * some APs don't like getting a superset of their rates | 749 | * some APs don't like getting a superset of their rates |
@@ -737,6 +751,10 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
737 | * b-only mode) */ | 751 | * b-only mode) */ |
738 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); | 752 | rates_len = ieee80211_compatible_rates(bss, sband, &rates); |
739 | 753 | ||
754 | if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && | ||
755 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | ||
756 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | ||
757 | |||
740 | ieee80211_rx_bss_put(dev, bss); | 758 | ieee80211_rx_bss_put(dev, bss); |
741 | } else { | 759 | } else { |
742 | rates = ~0; | 760 | rates = ~0; |
@@ -804,6 +822,26 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
804 | } | 822 | } |
805 | } | 823 | } |
806 | 824 | ||
825 | if (capab & WLAN_CAPABILITY_SPECTRUM_MGMT) { | ||
826 | /* 1. power capabilities */ | ||
827 | pos = skb_put(skb, 4); | ||
828 | *pos++ = WLAN_EID_PWR_CAPABILITY; | ||
829 | *pos++ = 2; | ||
830 | *pos++ = 0; /* min tx power */ | ||
831 | *pos++ = local->hw.conf.channel->max_power; /* max tx power */ | ||
832 | |||
833 | /* 2. supported channels */ | ||
834 | /* TODO: get this in reg domain format */ | ||
835 | pos = skb_put(skb, 2 * sband->n_channels + 2); | ||
836 | *pos++ = WLAN_EID_SUPPORTED_CHANNELS; | ||
837 | *pos++ = 2 * sband->n_channels; | ||
838 | for (i = 0; i < sband->n_channels; i++) { | ||
839 | *pos++ = ieee80211_frequency_to_channel( | ||
840 | sband->channels[i].center_freq); | ||
841 | *pos++ = 1; /* one channel in the subband*/ | ||
842 | } | ||
843 | } | ||
844 | |||
807 | if (ifsta->extra_ie) { | 845 | if (ifsta->extra_ie) { |
808 | pos = skb_put(skb, ifsta->extra_ie_len); | 846 | pos = skb_put(skb, ifsta->extra_ie_len); |
809 | memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len); | 847 | memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len); |
@@ -821,9 +859,32 @@ static void ieee80211_send_assoc(struct net_device *dev, | |||
821 | *pos++ = 1; /* WME ver */ | 859 | *pos++ = 1; /* WME ver */ |
822 | *pos++ = 0; | 860 | *pos++ = 0; |
823 | } | 861 | } |
862 | |||
824 | /* wmm support is a must to HT */ | 863 | /* wmm support is a must to HT */ |
825 | if (wmm && sband->ht_info.ht_supported) { | 864 | if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && |
826 | __le16 tmp = cpu_to_le16(sband->ht_info.cap); | 865 | sband->ht_info.ht_supported && bss->ht_add_ie) { |
866 | struct ieee80211_ht_addt_info *ht_add_info = | ||
867 | (struct ieee80211_ht_addt_info *)bss->ht_add_ie; | ||
868 | u16 cap = sband->ht_info.cap; | ||
869 | __le16 tmp; | ||
870 | u32 flags = local->hw.conf.channel->flags; | ||
871 | |||
872 | switch (ht_add_info->ht_param & IEEE80211_HT_IE_CHA_SEC_OFFSET) { | ||
873 | case IEEE80211_HT_IE_CHA_SEC_ABOVE: | ||
874 | if (flags & IEEE80211_CHAN_NO_FAT_ABOVE) { | ||
875 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
876 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
877 | } | ||
878 | break; | ||
879 | case IEEE80211_HT_IE_CHA_SEC_BELOW: | ||
880 | if (flags & IEEE80211_CHAN_NO_FAT_BELOW) { | ||
881 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH; | ||
882 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
883 | } | ||
884 | break; | ||
885 | } | ||
886 | |||
887 | tmp = cpu_to_le16(cap); | ||
827 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); | 888 | pos = skb_put(skb, sizeof(struct ieee80211_ht_cap)+2); |
828 | *pos++ = WLAN_EID_HT_CAPABILITY; | 889 | *pos++ = WLAN_EID_HT_CAPABILITY; |
829 | *pos++ = sizeof(struct ieee80211_ht_cap); | 890 | *pos++ = sizeof(struct ieee80211_ht_cap); |
@@ -1118,14 +1179,10 @@ static void ieee80211_auth_challenge(struct net_device *dev, | |||
1118 | u8 *pos; | 1179 | u8 *pos; |
1119 | struct ieee802_11_elems elems; | 1180 | struct ieee802_11_elems elems; |
1120 | 1181 | ||
1121 | printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); | ||
1122 | pos = mgmt->u.auth.variable; | 1182 | pos = mgmt->u.auth.variable; |
1123 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 1183 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
1124 | if (!elems.challenge) { | 1184 | if (!elems.challenge) |
1125 | printk(KERN_DEBUG "%s: no challenge IE in shared key auth " | ||
1126 | "frame\n", dev->name); | ||
1127 | return; | 1185 | return; |
1128 | } | ||
1129 | ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2, | 1186 | ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2, |
1130 | elems.challenge_len + 2, 1); | 1187 | elems.challenge_len + 2, 1); |
1131 | } | 1188 | } |
@@ -1141,8 +1198,8 @@ static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid, | |||
1141 | struct ieee80211_mgmt *mgmt; | 1198 | struct ieee80211_mgmt *mgmt; |
1142 | u16 capab; | 1199 | u16 capab; |
1143 | 1200 | ||
1144 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + | 1201 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); |
1145 | sizeof(mgmt->u.action.u.addba_resp)); | 1202 | |
1146 | if (!skb) { | 1203 | if (!skb) { |
1147 | printk(KERN_DEBUG "%s: failed to allocate buffer " | 1204 | printk(KERN_DEBUG "%s: failed to allocate buffer " |
1148 | "for addba resp frame\n", dev->name); | 1205 | "for addba resp frame\n", dev->name); |
@@ -1190,9 +1247,7 @@ void ieee80211_send_addba_request(struct net_device *dev, const u8 *da, | |||
1190 | struct ieee80211_mgmt *mgmt; | 1247 | struct ieee80211_mgmt *mgmt; |
1191 | u16 capab; | 1248 | u16 capab; |
1192 | 1249 | ||
1193 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + | 1250 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); |
1194 | sizeof(mgmt->u.action.u.addba_req)); | ||
1195 | |||
1196 | 1251 | ||
1197 | if (!skb) { | 1252 | if (!skb) { |
1198 | printk(KERN_ERR "%s: failed to allocate buffer " | 1253 | printk(KERN_ERR "%s: failed to allocate buffer " |
@@ -1293,7 +1348,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1293 | 1348 | ||
1294 | 1349 | ||
1295 | /* examine state machine */ | 1350 | /* examine state machine */ |
1296 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1351 | spin_lock_bh(&sta->lock); |
1297 | 1352 | ||
1298 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { | 1353 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { |
1299 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1354 | #ifdef CONFIG_MAC80211_HT_DEBUG |
@@ -1309,9 +1364,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1309 | sta->ampdu_mlme.tid_rx[tid] = | 1364 | sta->ampdu_mlme.tid_rx[tid] = |
1310 | kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC); | 1365 | kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC); |
1311 | if (!sta->ampdu_mlme.tid_rx[tid]) { | 1366 | if (!sta->ampdu_mlme.tid_rx[tid]) { |
1367 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1312 | if (net_ratelimit()) | 1368 | if (net_ratelimit()) |
1313 | printk(KERN_ERR "allocate rx mlme to tid %d failed\n", | 1369 | printk(KERN_ERR "allocate rx mlme to tid %d failed\n", |
1314 | tid); | 1370 | tid); |
1371 | #endif | ||
1315 | goto end; | 1372 | goto end; |
1316 | } | 1373 | } |
1317 | /* rx timer */ | 1374 | /* rx timer */ |
@@ -1327,9 +1384,11 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1327 | tid_agg_rx->reorder_buf = | 1384 | tid_agg_rx->reorder_buf = |
1328 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); | 1385 | kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC); |
1329 | if (!tid_agg_rx->reorder_buf) { | 1386 | if (!tid_agg_rx->reorder_buf) { |
1387 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1330 | if (net_ratelimit()) | 1388 | if (net_ratelimit()) |
1331 | printk(KERN_ERR "can not allocate reordering buffer " | 1389 | printk(KERN_ERR "can not allocate reordering buffer " |
1332 | "to tid %d\n", tid); | 1390 | "to tid %d\n", tid); |
1391 | #endif | ||
1333 | kfree(sta->ampdu_mlme.tid_rx[tid]); | 1392 | kfree(sta->ampdu_mlme.tid_rx[tid]); |
1334 | goto end; | 1393 | goto end; |
1335 | } | 1394 | } |
@@ -1360,7 +1419,7 @@ static void ieee80211_sta_process_addba_request(struct net_device *dev, | |||
1360 | tid_agg_rx->stored_mpdu_num = 0; | 1419 | tid_agg_rx->stored_mpdu_num = 0; |
1361 | status = WLAN_STATUS_SUCCESS; | 1420 | status = WLAN_STATUS_SUCCESS; |
1362 | end: | 1421 | end: |
1363 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1422 | spin_unlock_bh(&sta->lock); |
1364 | 1423 | ||
1365 | end_no_lock: | 1424 | end_no_lock: |
1366 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, | 1425 | ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid, |
@@ -1392,18 +1451,16 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1392 | 1451 | ||
1393 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1452 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
1394 | 1453 | ||
1395 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1454 | spin_lock_bh(&sta->lock); |
1396 | 1455 | ||
1397 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1456 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1398 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1457 | spin_unlock_bh(&sta->lock); |
1399 | printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:" | ||
1400 | "%d\n", *state); | ||
1401 | goto addba_resp_exit; | 1458 | goto addba_resp_exit; |
1402 | } | 1459 | } |
1403 | 1460 | ||
1404 | if (mgmt->u.action.u.addba_resp.dialog_token != | 1461 | if (mgmt->u.action.u.addba_resp.dialog_token != |
1405 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 1462 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
1406 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1463 | spin_unlock_bh(&sta->lock); |
1407 | #ifdef CONFIG_MAC80211_HT_DEBUG | 1464 | #ifdef CONFIG_MAC80211_HT_DEBUG |
1408 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 1465 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
1409 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1466 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
@@ -1416,26 +1473,18 @@ static void ieee80211_sta_process_addba_resp(struct net_device *dev, | |||
1416 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 1473 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
1417 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) | 1474 | if (le16_to_cpu(mgmt->u.action.u.addba_resp.status) |
1418 | == WLAN_STATUS_SUCCESS) { | 1475 | == WLAN_STATUS_SUCCESS) { |
1419 | if (*state & HT_ADDBA_RECEIVED_MSK) | ||
1420 | printk(KERN_DEBUG "double addBA response\n"); | ||
1421 | |||
1422 | *state |= HT_ADDBA_RECEIVED_MSK; | 1476 | *state |= HT_ADDBA_RECEIVED_MSK; |
1423 | sta->ampdu_mlme.addba_req_num[tid] = 0; | 1477 | sta->ampdu_mlme.addba_req_num[tid] = 0; |
1424 | 1478 | ||
1425 | if (*state == HT_AGG_STATE_OPERATIONAL) { | 1479 | if (*state == HT_AGG_STATE_OPERATIONAL) |
1426 | printk(KERN_DEBUG "Aggregation on for tid %d \n", tid); | ||
1427 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); | 1480 | ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); |
1428 | } | ||
1429 | 1481 | ||
1430 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1482 | spin_unlock_bh(&sta->lock); |
1431 | printk(KERN_DEBUG "recipient accepted agg: tid %d \n", tid); | ||
1432 | } else { | 1483 | } else { |
1433 | printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid); | ||
1434 | |||
1435 | sta->ampdu_mlme.addba_req_num[tid]++; | 1484 | sta->ampdu_mlme.addba_req_num[tid]++; |
1436 | /* this will allow the state check in stop_BA_session */ | 1485 | /* this will allow the state check in stop_BA_session */ |
1437 | *state = HT_AGG_STATE_OPERATIONAL; | 1486 | *state = HT_AGG_STATE_OPERATIONAL; |
1438 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1487 | spin_unlock_bh(&sta->lock); |
1439 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, | 1488 | ieee80211_stop_tx_ba_session(hw, sta->addr, tid, |
1440 | WLAN_BACK_INITIATOR); | 1489 | WLAN_BACK_INITIATOR); |
1441 | } | 1490 | } |
@@ -1454,8 +1503,7 @@ void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, | |||
1454 | struct ieee80211_mgmt *mgmt; | 1503 | struct ieee80211_mgmt *mgmt; |
1455 | u16 params; | 1504 | u16 params; |
1456 | 1505 | ||
1457 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom + 1 + | 1506 | skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); |
1458 | sizeof(mgmt->u.action.u.delba)); | ||
1459 | 1507 | ||
1460 | if (!skb) { | 1508 | if (!skb) { |
1461 | printk(KERN_ERR "%s: failed to allocate buffer " | 1509 | printk(KERN_ERR "%s: failed to allocate buffer " |
@@ -1506,17 +1554,17 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
1506 | } | 1554 | } |
1507 | 1555 | ||
1508 | /* check if TID is in operational state */ | 1556 | /* check if TID is in operational state */ |
1509 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 1557 | spin_lock_bh(&sta->lock); |
1510 | if (sta->ampdu_mlme.tid_state_rx[tid] | 1558 | if (sta->ampdu_mlme.tid_state_rx[tid] |
1511 | != HT_AGG_STATE_OPERATIONAL) { | 1559 | != HT_AGG_STATE_OPERATIONAL) { |
1512 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1560 | spin_unlock_bh(&sta->lock); |
1513 | rcu_read_unlock(); | 1561 | rcu_read_unlock(); |
1514 | return; | 1562 | return; |
1515 | } | 1563 | } |
1516 | sta->ampdu_mlme.tid_state_rx[tid] = | 1564 | sta->ampdu_mlme.tid_state_rx[tid] = |
1517 | HT_AGG_STATE_REQ_STOP_BA_MSK | | 1565 | HT_AGG_STATE_REQ_STOP_BA_MSK | |
1518 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); | 1566 | (initiator << HT_AGG_STATE_INITIATOR_SHIFT); |
1519 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | 1567 | spin_unlock_bh(&sta->lock); |
1520 | 1568 | ||
1521 | /* stop HW Rx aggregation. ampdu_action existence | 1569 | /* stop HW Rx aggregation. ampdu_action existence |
1522 | * already verified in session init so we add the BUG_ON */ | 1570 | * already verified in session init so we add the BUG_ON */ |
@@ -1531,7 +1579,7 @@ void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, | |||
1531 | ra, tid, NULL); | 1579 | ra, tid, NULL); |
1532 | if (ret) | 1580 | if (ret) |
1533 | printk(KERN_DEBUG "HW problem - can not stop rx " | 1581 | printk(KERN_DEBUG "HW problem - can not stop rx " |
1534 | "aggergation for tid %d\n", tid); | 1582 | "aggregation for tid %d\n", tid); |
1535 | 1583 | ||
1536 | /* shutdown timer has not expired */ | 1584 | /* shutdown timer has not expired */ |
1537 | if (initiator != WLAN_BACK_TIMER) | 1585 | if (initiator != WLAN_BACK_TIMER) |
@@ -1593,10 +1641,10 @@ static void ieee80211_sta_process_delba(struct net_device *dev, | |||
1593 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, | 1641 | ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid, |
1594 | WLAN_BACK_INITIATOR, 0); | 1642 | WLAN_BACK_INITIATOR, 0); |
1595 | else { /* WLAN_BACK_RECIPIENT */ | 1643 | else { /* WLAN_BACK_RECIPIENT */ |
1596 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1644 | spin_lock_bh(&sta->lock); |
1597 | sta->ampdu_mlme.tid_state_tx[tid] = | 1645 | sta->ampdu_mlme.tid_state_tx[tid] = |
1598 | HT_AGG_STATE_OPERATIONAL; | 1646 | HT_AGG_STATE_OPERATIONAL; |
1599 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1647 | spin_unlock_bh(&sta->lock); |
1600 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, | 1648 | ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid, |
1601 | WLAN_BACK_RECIPIENT); | 1649 | WLAN_BACK_RECIPIENT); |
1602 | } | 1650 | } |
@@ -1633,20 +1681,24 @@ void sta_addba_resp_timer_expired(unsigned long data) | |||
1633 | 1681 | ||
1634 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 1682 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
1635 | /* check if the TID waits for addBA response */ | 1683 | /* check if the TID waits for addBA response */ |
1636 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | 1684 | spin_lock_bh(&sta->lock); |
1637 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 1685 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { |
1638 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1686 | spin_unlock_bh(&sta->lock); |
1639 | *state = HT_AGG_STATE_IDLE; | 1687 | *state = HT_AGG_STATE_IDLE; |
1688 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1640 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 1689 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
1641 | "expecting addBA response there", tid); | 1690 | "expecting addBA response there", tid); |
1691 | #endif | ||
1642 | goto timer_expired_exit; | 1692 | goto timer_expired_exit; |
1643 | } | 1693 | } |
1644 | 1694 | ||
1695 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1645 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); | 1696 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); |
1697 | #endif | ||
1646 | 1698 | ||
1647 | /* go through the state check in stop_BA_session */ | 1699 | /* go through the state check in stop_BA_session */ |
1648 | *state = HT_AGG_STATE_OPERATIONAL; | 1700 | *state = HT_AGG_STATE_OPERATIONAL; |
1649 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 1701 | spin_unlock_bh(&sta->lock); |
1650 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, | 1702 | ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid, |
1651 | WLAN_BACK_INITIATOR); | 1703 | WLAN_BACK_INITIATOR); |
1652 | 1704 | ||
@@ -1659,7 +1711,7 @@ timer_expired_exit: | |||
1659 | * resetting it after each frame that arrives from the originator. | 1711 | * resetting it after each frame that arrives from the originator. |
1660 | * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. | 1712 | * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. |
1661 | */ | 1713 | */ |
1662 | void sta_rx_agg_session_timer_expired(unsigned long data) | 1714 | static void sta_rx_agg_session_timer_expired(unsigned long data) |
1663 | { | 1715 | { |
1664 | /* not an elegant detour, but there is no choice as the timer passes | 1716 | /* not an elegant detour, but there is no choice as the timer passes |
1665 | * only one argument, and various sta_info are needed here, so init | 1717 | * only one argument, and various sta_info are needed here, so init |
@@ -1670,7 +1722,9 @@ void sta_rx_agg_session_timer_expired(unsigned long data) | |||
1670 | struct sta_info *sta = container_of(timer_to_id, struct sta_info, | 1722 | struct sta_info *sta = container_of(timer_to_id, struct sta_info, |
1671 | timer_to_tid[0]); | 1723 | timer_to_tid[0]); |
1672 | 1724 | ||
1725 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
1673 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 1726 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); |
1727 | #endif | ||
1674 | ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, | 1728 | ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, |
1675 | (u16)*ptid, WLAN_BACK_TIMER, | 1729 | (u16)*ptid, WLAN_BACK_TIMER, |
1676 | WLAN_REASON_QSTA_TIMEOUT); | 1730 | WLAN_REASON_QSTA_TIMEOUT); |
@@ -1690,6 +1744,71 @@ void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr) | |||
1690 | } | 1744 | } |
1691 | } | 1745 | } |
1692 | 1746 | ||
1747 | static void ieee80211_send_refuse_measurement_request(struct net_device *dev, | ||
1748 | struct ieee80211_msrment_ie *request_ie, | ||
1749 | const u8 *da, const u8 *bssid, | ||
1750 | u8 dialog_token) | ||
1751 | { | ||
1752 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
1753 | struct sk_buff *skb; | ||
1754 | struct ieee80211_mgmt *msr_report; | ||
1755 | |||
1756 | skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + | ||
1757 | sizeof(struct ieee80211_msrment_ie)); | ||
1758 | |||
1759 | if (!skb) { | ||
1760 | printk(KERN_ERR "%s: failed to allocate buffer for " | ||
1761 | "measurement report frame\n", dev->name); | ||
1762 | return; | ||
1763 | } | ||
1764 | |||
1765 | skb_reserve(skb, local->hw.extra_tx_headroom); | ||
1766 | msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24); | ||
1767 | memset(msr_report, 0, 24); | ||
1768 | memcpy(msr_report->da, da, ETH_ALEN); | ||
1769 | memcpy(msr_report->sa, dev->dev_addr, ETH_ALEN); | ||
1770 | memcpy(msr_report->bssid, bssid, ETH_ALEN); | ||
1771 | msr_report->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | ||
1772 | IEEE80211_STYPE_ACTION); | ||
1773 | |||
1774 | skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement)); | ||
1775 | msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT; | ||
1776 | msr_report->u.action.u.measurement.action_code = | ||
1777 | WLAN_ACTION_SPCT_MSR_RPRT; | ||
1778 | msr_report->u.action.u.measurement.dialog_token = dialog_token; | ||
1779 | |||
1780 | msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT; | ||
1781 | msr_report->u.action.u.measurement.length = | ||
1782 | sizeof(struct ieee80211_msrment_ie); | ||
1783 | |||
1784 | memset(&msr_report->u.action.u.measurement.msr_elem, 0, | ||
1785 | sizeof(struct ieee80211_msrment_ie)); | ||
1786 | msr_report->u.action.u.measurement.msr_elem.token = request_ie->token; | ||
1787 | msr_report->u.action.u.measurement.msr_elem.mode |= | ||
1788 | IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED; | ||
1789 | msr_report->u.action.u.measurement.msr_elem.type = request_ie->type; | ||
1790 | |||
1791 | ieee80211_sta_tx(dev, skb, 0); | ||
1792 | } | ||
1793 | |||
1794 | static void ieee80211_sta_process_measurement_req(struct net_device *dev, | ||
1795 | struct ieee80211_mgmt *mgmt, | ||
1796 | size_t len) | ||
1797 | { | ||
1798 | /* | ||
1799 | * Ignoring measurement request is spec violation. | ||
1800 | * Mandatory measurements must be reported optional | ||
1801 | * measurements might be refused or reported incapable | ||
1802 | * For now just refuse | ||
1803 | * TODO: Answer basic measurement as unmeasured | ||
1804 | */ | ||
1805 | ieee80211_send_refuse_measurement_request(dev, | ||
1806 | &mgmt->u.action.u.measurement.msr_elem, | ||
1807 | mgmt->sa, mgmt->bssid, | ||
1808 | mgmt->u.action.u.measurement.dialog_token); | ||
1809 | } | ||
1810 | |||
1811 | |||
1693 | static void ieee80211_rx_mgmt_auth(struct net_device *dev, | 1812 | static void ieee80211_rx_mgmt_auth(struct net_device *dev, |
1694 | struct ieee80211_if_sta *ifsta, | 1813 | struct ieee80211_if_sta *ifsta, |
1695 | struct ieee80211_mgmt *mgmt, | 1814 | struct ieee80211_mgmt *mgmt, |
@@ -1700,73 +1819,41 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
1700 | DECLARE_MAC_BUF(mac); | 1819 | DECLARE_MAC_BUF(mac); |
1701 | 1820 | ||
1702 | if (ifsta->state != IEEE80211_AUTHENTICATE && | 1821 | if (ifsta->state != IEEE80211_AUTHENTICATE && |
1703 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS) { | 1822 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS) |
1704 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
1705 | "%s, but not in authenticate state - ignored\n", | ||
1706 | dev->name, print_mac(mac, mgmt->sa)); | ||
1707 | return; | 1823 | return; |
1708 | } | ||
1709 | 1824 | ||
1710 | if (len < 24 + 6) { | 1825 | if (len < 24 + 6) |
1711 | printk(KERN_DEBUG "%s: too short (%zd) authentication frame " | ||
1712 | "received from %s - ignored\n", | ||
1713 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
1714 | return; | 1826 | return; |
1715 | } | ||
1716 | 1827 | ||
1717 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 1828 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
1718 | memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1829 | memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) |
1719 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
1720 | "unknown AP (SA=%s BSSID=%s) - " | ||
1721 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1722 | print_mac(mac, mgmt->bssid)); | ||
1723 | return; | 1830 | return; |
1724 | } | ||
1725 | 1831 | ||
1726 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 1832 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
1727 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) { | 1833 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) |
1728 | printk(KERN_DEBUG "%s: authentication frame received from " | ||
1729 | "unknown BSSID (SA=%s BSSID=%s) - " | ||
1730 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1731 | print_mac(mac, mgmt->bssid)); | ||
1732 | return; | 1834 | return; |
1733 | } | ||
1734 | 1835 | ||
1735 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 1836 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
1736 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 1837 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
1737 | status_code = le16_to_cpu(mgmt->u.auth.status_code); | 1838 | status_code = le16_to_cpu(mgmt->u.auth.status_code); |
1738 | 1839 | ||
1739 | printk(KERN_DEBUG "%s: RX authentication from %s (alg=%d " | ||
1740 | "transaction=%d status=%d)\n", | ||
1741 | dev->name, print_mac(mac, mgmt->sa), auth_alg, | ||
1742 | auth_transaction, status_code); | ||
1743 | |||
1744 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { | 1840 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { |
1745 | /* IEEE 802.11 standard does not require authentication in IBSS | 1841 | /* |
1842 | * IEEE 802.11 standard does not require authentication in IBSS | ||
1746 | * networks and most implementations do not seem to use it. | 1843 | * networks and most implementations do not seem to use it. |
1747 | * However, try to reply to authentication attempts if someone | 1844 | * However, try to reply to authentication attempts if someone |
1748 | * has actually implemented this. | 1845 | * has actually implemented this. |
1749 | * TODO: Could implement shared key authentication. */ | 1846 | */ |
1750 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { | 1847 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) |
1751 | printk(KERN_DEBUG "%s: unexpected IBSS authentication " | ||
1752 | "frame (alg=%d transaction=%d)\n", | ||
1753 | dev->name, auth_alg, auth_transaction); | ||
1754 | return; | 1848 | return; |
1755 | } | ||
1756 | ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); | 1849 | ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); |
1757 | } | 1850 | } |
1758 | 1851 | ||
1759 | if (auth_alg != ifsta->auth_alg || | 1852 | if (auth_alg != ifsta->auth_alg || |
1760 | auth_transaction != ifsta->auth_transaction) { | 1853 | auth_transaction != ifsta->auth_transaction) |
1761 | printk(KERN_DEBUG "%s: unexpected authentication frame " | ||
1762 | "(alg=%d transaction=%d)\n", | ||
1763 | dev->name, auth_alg, auth_transaction); | ||
1764 | return; | 1854 | return; |
1765 | } | ||
1766 | 1855 | ||
1767 | if (status_code != WLAN_STATUS_SUCCESS) { | 1856 | if (status_code != WLAN_STATUS_SUCCESS) { |
1768 | printk(KERN_DEBUG "%s: AP denied authentication (auth_alg=%d " | ||
1769 | "code=%d)\n", dev->name, ifsta->auth_alg, status_code); | ||
1770 | if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { | 1857 | if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { |
1771 | u8 algs[3]; | 1858 | u8 algs[3]; |
1772 | const int num_algs = ARRAY_SIZE(algs); | 1859 | const int num_algs = ARRAY_SIZE(algs); |
@@ -1795,9 +1882,6 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev, | |||
1795 | !ieee80211_sta_wep_configured(dev)) | 1882 | !ieee80211_sta_wep_configured(dev)) |
1796 | continue; | 1883 | continue; |
1797 | ifsta->auth_alg = algs[pos]; | 1884 | ifsta->auth_alg = algs[pos]; |
1798 | printk(KERN_DEBUG "%s: set auth_alg=%d for " | ||
1799 | "next try\n", | ||
1800 | dev->name, ifsta->auth_alg); | ||
1801 | break; | 1885 | break; |
1802 | } | 1886 | } |
1803 | } | 1887 | } |
@@ -1827,30 +1911,16 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev, | |||
1827 | u16 reason_code; | 1911 | u16 reason_code; |
1828 | DECLARE_MAC_BUF(mac); | 1912 | DECLARE_MAC_BUF(mac); |
1829 | 1913 | ||
1830 | if (len < 24 + 2) { | 1914 | if (len < 24 + 2) |
1831 | printk(KERN_DEBUG "%s: too short (%zd) deauthentication frame " | ||
1832 | "received from %s - ignored\n", | ||
1833 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
1834 | return; | 1915 | return; |
1835 | } | ||
1836 | 1916 | ||
1837 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1917 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN)) |
1838 | printk(KERN_DEBUG "%s: deauthentication frame received from " | ||
1839 | "unknown AP (SA=%s BSSID=%s) - " | ||
1840 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1841 | print_mac(mac, mgmt->bssid)); | ||
1842 | return; | 1918 | return; |
1843 | } | ||
1844 | 1919 | ||
1845 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1920 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1846 | 1921 | ||
1847 | printk(KERN_DEBUG "%s: RX deauthentication from %s" | 1922 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) |
1848 | " (reason=%d)\n", | ||
1849 | dev->name, print_mac(mac, mgmt->sa), reason_code); | ||
1850 | |||
1851 | if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) { | ||
1852 | printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); | 1923 | printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); |
1853 | } | ||
1854 | 1924 | ||
1855 | if (ifsta->state == IEEE80211_AUTHENTICATE || | 1925 | if (ifsta->state == IEEE80211_AUTHENTICATE || |
1856 | ifsta->state == IEEE80211_ASSOCIATE || | 1926 | ifsta->state == IEEE80211_ASSOCIATE || |
@@ -1873,27 +1943,14 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, | |||
1873 | u16 reason_code; | 1943 | u16 reason_code; |
1874 | DECLARE_MAC_BUF(mac); | 1944 | DECLARE_MAC_BUF(mac); |
1875 | 1945 | ||
1876 | if (len < 24 + 2) { | 1946 | if (len < 24 + 2) |
1877 | printk(KERN_DEBUG "%s: too short (%zd) disassociation frame " | ||
1878 | "received from %s - ignored\n", | ||
1879 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
1880 | return; | 1947 | return; |
1881 | } | ||
1882 | 1948 | ||
1883 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1949 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN)) |
1884 | printk(KERN_DEBUG "%s: disassociation frame received from " | ||
1885 | "unknown AP (SA=%s BSSID=%s) - " | ||
1886 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1887 | print_mac(mac, mgmt->bssid)); | ||
1888 | return; | 1950 | return; |
1889 | } | ||
1890 | 1951 | ||
1891 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1952 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1892 | 1953 | ||
1893 | printk(KERN_DEBUG "%s: RX disassociation from %s" | ||
1894 | " (reason=%d)\n", | ||
1895 | dev->name, print_mac(mac, mgmt->sa), reason_code); | ||
1896 | |||
1897 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) | 1954 | if (ifsta->flags & IEEE80211_STA_ASSOCIATED) |
1898 | printk(KERN_DEBUG "%s: disassociated\n", dev->name); | 1955 | printk(KERN_DEBUG "%s: disassociated\n", dev->name); |
1899 | 1956 | ||
@@ -1929,27 +1986,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1929 | /* AssocResp and ReassocResp have identical structure, so process both | 1986 | /* AssocResp and ReassocResp have identical structure, so process both |
1930 | * of them in this function. */ | 1987 | * of them in this function. */ |
1931 | 1988 | ||
1932 | if (ifsta->state != IEEE80211_ASSOCIATE) { | 1989 | if (ifsta->state != IEEE80211_ASSOCIATE) |
1933 | printk(KERN_DEBUG "%s: association frame received from " | ||
1934 | "%s, but not in associate state - ignored\n", | ||
1935 | dev->name, print_mac(mac, mgmt->sa)); | ||
1936 | return; | 1990 | return; |
1937 | } | ||
1938 | 1991 | ||
1939 | if (len < 24 + 6) { | 1992 | if (len < 24 + 6) |
1940 | printk(KERN_DEBUG "%s: too short (%zd) association frame " | ||
1941 | "received from %s - ignored\n", | ||
1942 | dev->name, len, print_mac(mac, mgmt->sa)); | ||
1943 | return; | 1993 | return; |
1944 | } | ||
1945 | 1994 | ||
1946 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { | 1995 | if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) |
1947 | printk(KERN_DEBUG "%s: association frame received from " | ||
1948 | "unknown AP (SA=%s BSSID=%s) - " | ||
1949 | "ignored\n", dev->name, print_mac(mac, mgmt->sa), | ||
1950 | print_mac(mac, mgmt->bssid)); | ||
1951 | return; | 1996 | return; |
1952 | } | ||
1953 | 1997 | ||
1954 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); | 1998 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); |
1955 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 1999 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
@@ -2013,8 +2057,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2013 | local->hw.conf.channel->center_freq, | 2057 | local->hw.conf.channel->center_freq, |
2014 | ifsta->ssid, ifsta->ssid_len); | 2058 | ifsta->ssid, ifsta->ssid_len); |
2015 | if (bss) { | 2059 | if (bss) { |
2016 | sta->last_rssi = bss->rssi; | ||
2017 | sta->last_signal = bss->signal; | 2060 | sta->last_signal = bss->signal; |
2061 | sta->last_qual = bss->qual; | ||
2018 | sta->last_noise = bss->noise; | 2062 | sta->last_noise = bss->noise; |
2019 | ieee80211_rx_bss_put(dev, bss); | 2063 | ieee80211_rx_bss_put(dev, bss); |
2020 | } | 2064 | } |
@@ -2038,8 +2082,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2038 | * to between the sta_info_alloc() and sta_info_insert() above. | 2082 | * to between the sta_info_alloc() and sta_info_insert() above. |
2039 | */ | 2083 | */ |
2040 | 2084 | ||
2041 | sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | | 2085 | set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | WLAN_STA_ASSOC_AP | |
2042 | WLAN_STA_AUTHORIZED; | 2086 | WLAN_STA_AUTHORIZED); |
2043 | 2087 | ||
2044 | rates = 0; | 2088 | rates = 0; |
2045 | basic_rates = 0; | 2089 | basic_rates = 0; |
@@ -2083,7 +2127,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2083 | else | 2127 | else |
2084 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; | 2128 | sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE; |
2085 | 2129 | ||
2086 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param) { | 2130 | if (elems.ht_cap_elem && elems.ht_info_elem && elems.wmm_param && |
2131 | (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | ||
2087 | struct ieee80211_ht_bss_info bss_info; | 2132 | struct ieee80211_ht_bss_info bss_info; |
2088 | ieee80211_ht_cap_ie_to_ht_info( | 2133 | ieee80211_ht_cap_ie_to_ht_info( |
2089 | (struct ieee80211_ht_cap *) | 2134 | (struct ieee80211_ht_cap *) |
@@ -2096,8 +2141,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2096 | 2141 | ||
2097 | rate_control_rate_init(sta, local); | 2142 | rate_control_rate_init(sta, local); |
2098 | 2143 | ||
2099 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | 2144 | if (elems.wmm_param) { |
2100 | sta->flags |= WLAN_STA_WME; | 2145 | set_sta_flags(sta, WLAN_STA_WME); |
2101 | rcu_read_unlock(); | 2146 | rcu_read_unlock(); |
2102 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | 2147 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
2103 | elems.wmm_param_len); | 2148 | elems.wmm_param_len); |
@@ -2281,6 +2326,7 @@ static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) | |||
2281 | kfree(bss->rsn_ie); | 2326 | kfree(bss->rsn_ie); |
2282 | kfree(bss->wmm_ie); | 2327 | kfree(bss->wmm_ie); |
2283 | kfree(bss->ht_ie); | 2328 | kfree(bss->ht_ie); |
2329 | kfree(bss->ht_add_ie); | ||
2284 | kfree(bss_mesh_id(bss)); | 2330 | kfree(bss_mesh_id(bss)); |
2285 | kfree(bss_mesh_cfg(bss)); | 2331 | kfree(bss_mesh_cfg(bss)); |
2286 | kfree(bss); | 2332 | kfree(bss); |
@@ -2331,7 +2377,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2331 | int res, rates, i, j; | 2377 | int res, rates, i, j; |
2332 | struct sk_buff *skb; | 2378 | struct sk_buff *skb; |
2333 | struct ieee80211_mgmt *mgmt; | 2379 | struct ieee80211_mgmt *mgmt; |
2334 | struct ieee80211_tx_control control; | 2380 | struct ieee80211_tx_info *control; |
2335 | struct rate_selection ratesel; | 2381 | struct rate_selection ratesel; |
2336 | u8 *pos; | 2382 | u8 *pos; |
2337 | struct ieee80211_sub_if_data *sdata; | 2383 | struct ieee80211_sub_if_data *sdata; |
@@ -2382,6 +2428,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2382 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); | 2428 | memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); |
2383 | mgmt->u.beacon.beacon_int = | 2429 | mgmt->u.beacon.beacon_int = |
2384 | cpu_to_le16(local->hw.conf.beacon_int); | 2430 | cpu_to_le16(local->hw.conf.beacon_int); |
2431 | mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp); | ||
2385 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); | 2432 | mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); |
2386 | 2433 | ||
2387 | pos = skb_put(skb, 2 + ifsta->ssid_len); | 2434 | pos = skb_put(skb, 2 + ifsta->ssid_len); |
@@ -2419,21 +2466,22 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2419 | memcpy(pos, &bss->supp_rates[8], rates); | 2466 | memcpy(pos, &bss->supp_rates[8], rates); |
2420 | } | 2467 | } |
2421 | 2468 | ||
2422 | memset(&control, 0, sizeof(control)); | 2469 | control = IEEE80211_SKB_CB(skb); |
2470 | |||
2423 | rate_control_get_rate(dev, sband, skb, &ratesel); | 2471 | rate_control_get_rate(dev, sband, skb, &ratesel); |
2424 | if (!ratesel.rate) { | 2472 | if (ratesel.rate_idx < 0) { |
2425 | printk(KERN_DEBUG "%s: Failed to determine TX rate " | 2473 | printk(KERN_DEBUG "%s: Failed to determine TX rate " |
2426 | "for IBSS beacon\n", dev->name); | 2474 | "for IBSS beacon\n", dev->name); |
2427 | break; | 2475 | break; |
2428 | } | 2476 | } |
2429 | control.vif = &sdata->vif; | 2477 | control->control.vif = &sdata->vif; |
2430 | control.tx_rate = ratesel.rate; | 2478 | control->tx_rate_idx = ratesel.rate_idx; |
2431 | if (sdata->bss_conf.use_short_preamble && | 2479 | if (sdata->bss_conf.use_short_preamble && |
2432 | ratesel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | 2480 | sband->bitrates[ratesel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) |
2433 | control.flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 2481 | control->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; |
2434 | control.antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 2482 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; |
2435 | control.flags |= IEEE80211_TXCTL_NO_ACK; | 2483 | control->flags |= IEEE80211_TX_CTL_NO_ACK; |
2436 | control.retry_limit = 1; | 2484 | control->control.retry_limit = 1; |
2437 | 2485 | ||
2438 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); | 2486 | ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); |
2439 | if (ifsta->probe_resp) { | 2487 | if (ifsta->probe_resp) { |
@@ -2448,8 +2496,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev, | |||
2448 | } | 2496 | } |
2449 | 2497 | ||
2450 | if (local->ops->beacon_update && | 2498 | if (local->ops->beacon_update && |
2451 | local->ops->beacon_update(local_to_hw(local), | 2499 | local->ops->beacon_update(local_to_hw(local), skb) == 0) { |
2452 | skb, &control) == 0) { | ||
2453 | printk(KERN_DEBUG "%s: Configured IBSS beacon " | 2500 | printk(KERN_DEBUG "%s: Configured IBSS beacon " |
2454 | "template\n", dev->name); | 2501 | "template\n", dev->name); |
2455 | skb = NULL; | 2502 | skb = NULL; |
@@ -2525,11 +2572,10 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2525 | struct ieee80211_mgmt *mgmt, | 2572 | struct ieee80211_mgmt *mgmt, |
2526 | size_t len, | 2573 | size_t len, |
2527 | struct ieee80211_rx_status *rx_status, | 2574 | struct ieee80211_rx_status *rx_status, |
2575 | struct ieee802_11_elems *elems, | ||
2528 | int beacon) | 2576 | int beacon) |
2529 | { | 2577 | { |
2530 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 2578 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
2531 | struct ieee802_11_elems elems; | ||
2532 | size_t baselen; | ||
2533 | int freq, clen; | 2579 | int freq, clen; |
2534 | struct ieee80211_sta_bss *bss; | 2580 | struct ieee80211_sta_bss *bss; |
2535 | struct sta_info *sta; | 2581 | struct sta_info *sta; |
@@ -2542,35 +2588,24 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2542 | if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) | 2588 | if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) |
2543 | return; /* ignore ProbeResp to foreign address */ | 2589 | return; /* ignore ProbeResp to foreign address */ |
2544 | 2590 | ||
2545 | #if 0 | ||
2546 | printk(KERN_DEBUG "%s: RX %s from %s to %s\n", | ||
2547 | dev->name, beacon ? "Beacon" : "Probe Response", | ||
2548 | print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da)); | ||
2549 | #endif | ||
2550 | |||
2551 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
2552 | if (baselen > len) | ||
2553 | return; | ||
2554 | |||
2555 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); | 2591 | beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp); |
2556 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
2557 | 2592 | ||
2558 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems.mesh_id && | 2593 | if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id && |
2559 | elems.mesh_config && mesh_matches_local(&elems, dev)) { | 2594 | elems->mesh_config && mesh_matches_local(elems, dev)) { |
2560 | u64 rates = ieee80211_sta_get_rates(local, &elems, | 2595 | u64 rates = ieee80211_sta_get_rates(local, elems, |
2561 | rx_status->band); | 2596 | rx_status->band); |
2562 | 2597 | ||
2563 | mesh_neighbour_update(mgmt->sa, rates, dev, | 2598 | mesh_neighbour_update(mgmt->sa, rates, dev, |
2564 | mesh_peer_accepts_plinks(&elems, dev)); | 2599 | mesh_peer_accepts_plinks(elems, dev)); |
2565 | } | 2600 | } |
2566 | 2601 | ||
2567 | rcu_read_lock(); | 2602 | rcu_read_lock(); |
2568 | 2603 | ||
2569 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && | 2604 | if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates && |
2570 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && | 2605 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
2571 | (sta = sta_info_get(local, mgmt->sa))) { | 2606 | (sta = sta_info_get(local, mgmt->sa))) { |
2572 | u64 prev_rates; | 2607 | u64 prev_rates; |
2573 | u64 supp_rates = ieee80211_sta_get_rates(local, &elems, | 2608 | u64 supp_rates = ieee80211_sta_get_rates(local, elems, |
2574 | rx_status->band); | 2609 | rx_status->band); |
2575 | 2610 | ||
2576 | prev_rates = sta->supp_rates[rx_status->band]; | 2611 | prev_rates = sta->supp_rates[rx_status->band]; |
@@ -2582,21 +2617,12 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2582 | sta->supp_rates[rx_status->band] = | 2617 | sta->supp_rates[rx_status->band] = |
2583 | sdata->u.sta.supp_rates_bits[rx_status->band]; | 2618 | sdata->u.sta.supp_rates_bits[rx_status->band]; |
2584 | } | 2619 | } |
2585 | if (sta->supp_rates[rx_status->band] != prev_rates) { | ||
2586 | printk(KERN_DEBUG "%s: updated supp_rates set for " | ||
2587 | "%s based on beacon info (0x%llx & 0x%llx -> " | ||
2588 | "0x%llx)\n", | ||
2589 | dev->name, print_mac(mac, sta->addr), | ||
2590 | (unsigned long long) prev_rates, | ||
2591 | (unsigned long long) supp_rates, | ||
2592 | (unsigned long long) sta->supp_rates[rx_status->band]); | ||
2593 | } | ||
2594 | } | 2620 | } |
2595 | 2621 | ||
2596 | rcu_read_unlock(); | 2622 | rcu_read_unlock(); |
2597 | 2623 | ||
2598 | if (elems.ds_params && elems.ds_params_len == 1) | 2624 | if (elems->ds_params && elems->ds_params_len == 1) |
2599 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); | 2625 | freq = ieee80211_channel_to_frequency(elems->ds_params[0]); |
2600 | else | 2626 | else |
2601 | freq = rx_status->freq; | 2627 | freq = rx_status->freq; |
2602 | 2628 | ||
@@ -2606,23 +2632,23 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2606 | return; | 2632 | return; |
2607 | 2633 | ||
2608 | #ifdef CONFIG_MAC80211_MESH | 2634 | #ifdef CONFIG_MAC80211_MESH |
2609 | if (elems.mesh_config) | 2635 | if (elems->mesh_config) |
2610 | bss = ieee80211_rx_mesh_bss_get(dev, elems.mesh_id, | 2636 | bss = ieee80211_rx_mesh_bss_get(dev, elems->mesh_id, |
2611 | elems.mesh_id_len, elems.mesh_config, freq); | 2637 | elems->mesh_id_len, elems->mesh_config, freq); |
2612 | else | 2638 | else |
2613 | #endif | 2639 | #endif |
2614 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, | 2640 | bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq, |
2615 | elems.ssid, elems.ssid_len); | 2641 | elems->ssid, elems->ssid_len); |
2616 | if (!bss) { | 2642 | if (!bss) { |
2617 | #ifdef CONFIG_MAC80211_MESH | 2643 | #ifdef CONFIG_MAC80211_MESH |
2618 | if (elems.mesh_config) | 2644 | if (elems->mesh_config) |
2619 | bss = ieee80211_rx_mesh_bss_add(dev, elems.mesh_id, | 2645 | bss = ieee80211_rx_mesh_bss_add(dev, elems->mesh_id, |
2620 | elems.mesh_id_len, elems.mesh_config, | 2646 | elems->mesh_id_len, elems->mesh_config, |
2621 | elems.mesh_config_len, freq); | 2647 | elems->mesh_config_len, freq); |
2622 | else | 2648 | else |
2623 | #endif | 2649 | #endif |
2624 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, | 2650 | bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq, |
2625 | elems.ssid, elems.ssid_len); | 2651 | elems->ssid, elems->ssid_len); |
2626 | if (!bss) | 2652 | if (!bss) |
2627 | return; | 2653 | return; |
2628 | } else { | 2654 | } else { |
@@ -2635,46 +2661,66 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2635 | } | 2661 | } |
2636 | 2662 | ||
2637 | /* save the ERP value so that it is available at association time */ | 2663 | /* save the ERP value so that it is available at association time */ |
2638 | if (elems.erp_info && elems.erp_info_len >= 1) { | 2664 | if (elems->erp_info && elems->erp_info_len >= 1) { |
2639 | bss->erp_value = elems.erp_info[0]; | 2665 | bss->erp_value = elems->erp_info[0]; |
2640 | bss->has_erp_value = 1; | 2666 | bss->has_erp_value = 1; |
2641 | } | 2667 | } |
2642 | 2668 | ||
2643 | if (elems.ht_cap_elem && | 2669 | if (elems->ht_cap_elem && |
2644 | (!bss->ht_ie || bss->ht_ie_len != elems.ht_cap_elem_len || | 2670 | (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len || |
2645 | memcmp(bss->ht_ie, elems.ht_cap_elem, elems.ht_cap_elem_len))) { | 2671 | memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) { |
2646 | kfree(bss->ht_ie); | 2672 | kfree(bss->ht_ie); |
2647 | bss->ht_ie = kmalloc(elems.ht_cap_elem_len + 2, GFP_ATOMIC); | 2673 | bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC); |
2648 | if (bss->ht_ie) { | 2674 | if (bss->ht_ie) { |
2649 | memcpy(bss->ht_ie, elems.ht_cap_elem - 2, | 2675 | memcpy(bss->ht_ie, elems->ht_cap_elem - 2, |
2650 | elems.ht_cap_elem_len + 2); | 2676 | elems->ht_cap_elem_len + 2); |
2651 | bss->ht_ie_len = elems.ht_cap_elem_len + 2; | 2677 | bss->ht_ie_len = elems->ht_cap_elem_len + 2; |
2652 | } else | 2678 | } else |
2653 | bss->ht_ie_len = 0; | 2679 | bss->ht_ie_len = 0; |
2654 | } else if (!elems.ht_cap_elem && bss->ht_ie) { | 2680 | } else if (!elems->ht_cap_elem && bss->ht_ie) { |
2655 | kfree(bss->ht_ie); | 2681 | kfree(bss->ht_ie); |
2656 | bss->ht_ie = NULL; | 2682 | bss->ht_ie = NULL; |
2657 | bss->ht_ie_len = 0; | 2683 | bss->ht_ie_len = 0; |
2658 | } | 2684 | } |
2659 | 2685 | ||
2686 | if (elems->ht_info_elem && | ||
2687 | (!bss->ht_add_ie || | ||
2688 | bss->ht_add_ie_len != elems->ht_info_elem_len || | ||
2689 | memcmp(bss->ht_add_ie, elems->ht_info_elem, | ||
2690 | elems->ht_info_elem_len))) { | ||
2691 | kfree(bss->ht_add_ie); | ||
2692 | bss->ht_add_ie = | ||
2693 | kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC); | ||
2694 | if (bss->ht_add_ie) { | ||
2695 | memcpy(bss->ht_add_ie, elems->ht_info_elem - 2, | ||
2696 | elems->ht_info_elem_len + 2); | ||
2697 | bss->ht_add_ie_len = elems->ht_info_elem_len + 2; | ||
2698 | } else | ||
2699 | bss->ht_add_ie_len = 0; | ||
2700 | } else if (!elems->ht_info_elem && bss->ht_add_ie) { | ||
2701 | kfree(bss->ht_add_ie); | ||
2702 | bss->ht_add_ie = NULL; | ||
2703 | bss->ht_add_ie_len = 0; | ||
2704 | } | ||
2705 | |||
2660 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); | 2706 | bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); |
2661 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); | 2707 | bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); |
2662 | 2708 | ||
2663 | bss->supp_rates_len = 0; | 2709 | bss->supp_rates_len = 0; |
2664 | if (elems.supp_rates) { | 2710 | if (elems->supp_rates) { |
2665 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2711 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
2666 | if (clen > elems.supp_rates_len) | 2712 | if (clen > elems->supp_rates_len) |
2667 | clen = elems.supp_rates_len; | 2713 | clen = elems->supp_rates_len; |
2668 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems.supp_rates, | 2714 | memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates, |
2669 | clen); | 2715 | clen); |
2670 | bss->supp_rates_len += clen; | 2716 | bss->supp_rates_len += clen; |
2671 | } | 2717 | } |
2672 | if (elems.ext_supp_rates) { | 2718 | if (elems->ext_supp_rates) { |
2673 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; | 2719 | clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; |
2674 | if (clen > elems.ext_supp_rates_len) | 2720 | if (clen > elems->ext_supp_rates_len) |
2675 | clen = elems.ext_supp_rates_len; | 2721 | clen = elems->ext_supp_rates_len; |
2676 | memcpy(&bss->supp_rates[bss->supp_rates_len], | 2722 | memcpy(&bss->supp_rates[bss->supp_rates_len], |
2677 | elems.ext_supp_rates, clen); | 2723 | elems->ext_supp_rates, clen); |
2678 | bss->supp_rates_len += clen; | 2724 | bss->supp_rates_len += clen; |
2679 | } | 2725 | } |
2680 | 2726 | ||
@@ -2682,9 +2728,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2682 | 2728 | ||
2683 | bss->timestamp = beacon_timestamp; | 2729 | bss->timestamp = beacon_timestamp; |
2684 | bss->last_update = jiffies; | 2730 | bss->last_update = jiffies; |
2685 | bss->rssi = rx_status->ssi; | ||
2686 | bss->signal = rx_status->signal; | 2731 | bss->signal = rx_status->signal; |
2687 | bss->noise = rx_status->noise; | 2732 | bss->noise = rx_status->noise; |
2733 | bss->qual = rx_status->qual; | ||
2688 | if (!beacon && !bss->probe_resp) | 2734 | if (!beacon && !bss->probe_resp) |
2689 | bss->probe_resp = true; | 2735 | bss->probe_resp = true; |
2690 | 2736 | ||
@@ -2698,33 +2744,33 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2698 | return; | 2744 | return; |
2699 | } | 2745 | } |
2700 | 2746 | ||
2701 | if (elems.wpa && | 2747 | if (elems->wpa && |
2702 | (!bss->wpa_ie || bss->wpa_ie_len != elems.wpa_len || | 2748 | (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len || |
2703 | memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) { | 2749 | memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) { |
2704 | kfree(bss->wpa_ie); | 2750 | kfree(bss->wpa_ie); |
2705 | bss->wpa_ie = kmalloc(elems.wpa_len + 2, GFP_ATOMIC); | 2751 | bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC); |
2706 | if (bss->wpa_ie) { | 2752 | if (bss->wpa_ie) { |
2707 | memcpy(bss->wpa_ie, elems.wpa - 2, elems.wpa_len + 2); | 2753 | memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2); |
2708 | bss->wpa_ie_len = elems.wpa_len + 2; | 2754 | bss->wpa_ie_len = elems->wpa_len + 2; |
2709 | } else | 2755 | } else |
2710 | bss->wpa_ie_len = 0; | 2756 | bss->wpa_ie_len = 0; |
2711 | } else if (!elems.wpa && bss->wpa_ie) { | 2757 | } else if (!elems->wpa && bss->wpa_ie) { |
2712 | kfree(bss->wpa_ie); | 2758 | kfree(bss->wpa_ie); |
2713 | bss->wpa_ie = NULL; | 2759 | bss->wpa_ie = NULL; |
2714 | bss->wpa_ie_len = 0; | 2760 | bss->wpa_ie_len = 0; |
2715 | } | 2761 | } |
2716 | 2762 | ||
2717 | if (elems.rsn && | 2763 | if (elems->rsn && |
2718 | (!bss->rsn_ie || bss->rsn_ie_len != elems.rsn_len || | 2764 | (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len || |
2719 | memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) { | 2765 | memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) { |
2720 | kfree(bss->rsn_ie); | 2766 | kfree(bss->rsn_ie); |
2721 | bss->rsn_ie = kmalloc(elems.rsn_len + 2, GFP_ATOMIC); | 2767 | bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC); |
2722 | if (bss->rsn_ie) { | 2768 | if (bss->rsn_ie) { |
2723 | memcpy(bss->rsn_ie, elems.rsn - 2, elems.rsn_len + 2); | 2769 | memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2); |
2724 | bss->rsn_ie_len = elems.rsn_len + 2; | 2770 | bss->rsn_ie_len = elems->rsn_len + 2; |
2725 | } else | 2771 | } else |
2726 | bss->rsn_ie_len = 0; | 2772 | bss->rsn_ie_len = 0; |
2727 | } else if (!elems.rsn && bss->rsn_ie) { | 2773 | } else if (!elems->rsn && bss->rsn_ie) { |
2728 | kfree(bss->rsn_ie); | 2774 | kfree(bss->rsn_ie); |
2729 | bss->rsn_ie = NULL; | 2775 | bss->rsn_ie = NULL; |
2730 | bss->rsn_ie_len = 0; | 2776 | bss->rsn_ie_len = 0; |
@@ -2744,20 +2790,21 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2744 | * inclusion of the WMM Parameters in beacons, however, is optional. | 2790 | * inclusion of the WMM Parameters in beacons, however, is optional. |
2745 | */ | 2791 | */ |
2746 | 2792 | ||
2747 | if (elems.wmm_param && | 2793 | if (elems->wmm_param && |
2748 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_param_len || | 2794 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len || |
2749 | memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) { | 2795 | memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) { |
2750 | kfree(bss->wmm_ie); | 2796 | kfree(bss->wmm_ie); |
2751 | bss->wmm_ie = kmalloc(elems.wmm_param_len + 2, GFP_ATOMIC); | 2797 | bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC); |
2752 | if (bss->wmm_ie) { | 2798 | if (bss->wmm_ie) { |
2753 | memcpy(bss->wmm_ie, elems.wmm_param - 2, | 2799 | memcpy(bss->wmm_ie, elems->wmm_param - 2, |
2754 | elems.wmm_param_len + 2); | 2800 | elems->wmm_param_len + 2); |
2755 | bss->wmm_ie_len = elems.wmm_param_len + 2; | 2801 | bss->wmm_ie_len = elems->wmm_param_len + 2; |
2756 | } else | 2802 | } else |
2757 | bss->wmm_ie_len = 0; | 2803 | bss->wmm_ie_len = 0; |
2758 | } else if (elems.wmm_info && | 2804 | } else if (elems->wmm_info && |
2759 | (!bss->wmm_ie || bss->wmm_ie_len != elems.wmm_info_len || | 2805 | (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len || |
2760 | memcmp(bss->wmm_ie, elems.wmm_info, elems.wmm_info_len))) { | 2806 | memcmp(bss->wmm_ie, elems->wmm_info, |
2807 | elems->wmm_info_len))) { | ||
2761 | /* As for certain AP's Fifth bit is not set in WMM IE in | 2808 | /* As for certain AP's Fifth bit is not set in WMM IE in |
2762 | * beacon frames.So while parsing the beacon frame the | 2809 | * beacon frames.So while parsing the beacon frame the |
2763 | * wmm_info structure is used instead of wmm_param. | 2810 | * wmm_info structure is used instead of wmm_param. |
@@ -2767,14 +2814,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2767 | * n-band association. | 2814 | * n-band association. |
2768 | */ | 2815 | */ |
2769 | kfree(bss->wmm_ie); | 2816 | kfree(bss->wmm_ie); |
2770 | bss->wmm_ie = kmalloc(elems.wmm_info_len + 2, GFP_ATOMIC); | 2817 | bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC); |
2771 | if (bss->wmm_ie) { | 2818 | if (bss->wmm_ie) { |
2772 | memcpy(bss->wmm_ie, elems.wmm_info - 2, | 2819 | memcpy(bss->wmm_ie, elems->wmm_info - 2, |
2773 | elems.wmm_info_len + 2); | 2820 | elems->wmm_info_len + 2); |
2774 | bss->wmm_ie_len = elems.wmm_info_len + 2; | 2821 | bss->wmm_ie_len = elems->wmm_info_len + 2; |
2775 | } else | 2822 | } else |
2776 | bss->wmm_ie_len = 0; | 2823 | bss->wmm_ie_len = 0; |
2777 | } else if (!elems.wmm_param && !elems.wmm_info && bss->wmm_ie) { | 2824 | } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) { |
2778 | kfree(bss->wmm_ie); | 2825 | kfree(bss->wmm_ie); |
2779 | bss->wmm_ie = NULL; | 2826 | bss->wmm_ie = NULL; |
2780 | bss->wmm_ie_len = 0; | 2827 | bss->wmm_ie_len = 0; |
@@ -2785,8 +2832,9 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2785 | !local->sta_sw_scanning && !local->sta_hw_scanning && | 2832 | !local->sta_sw_scanning && !local->sta_hw_scanning && |
2786 | bss->capability & WLAN_CAPABILITY_IBSS && | 2833 | bss->capability & WLAN_CAPABILITY_IBSS && |
2787 | bss->freq == local->oper_channel->center_freq && | 2834 | bss->freq == local->oper_channel->center_freq && |
2788 | elems.ssid_len == sdata->u.sta.ssid_len && | 2835 | elems->ssid_len == sdata->u.sta.ssid_len && |
2789 | memcmp(elems.ssid, sdata->u.sta.ssid, sdata->u.sta.ssid_len) == 0) { | 2836 | memcmp(elems->ssid, sdata->u.sta.ssid, |
2837 | sdata->u.sta.ssid_len) == 0) { | ||
2790 | if (rx_status->flag & RX_FLAG_TSFT) { | 2838 | if (rx_status->flag & RX_FLAG_TSFT) { |
2791 | /* in order for correct IBSS merging we need mactime | 2839 | /* in order for correct IBSS merging we need mactime |
2792 | * | 2840 | * |
@@ -2824,14 +2872,14 @@ static void ieee80211_rx_bss_info(struct net_device *dev, | |||
2824 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 2872 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
2825 | if (beacon_timestamp > rx_timestamp) { | 2873 | if (beacon_timestamp > rx_timestamp) { |
2826 | #ifndef CONFIG_MAC80211_IBSS_DEBUG | 2874 | #ifndef CONFIG_MAC80211_IBSS_DEBUG |
2827 | if (net_ratelimit()) | 2875 | printk(KERN_DEBUG "%s: beacon TSF higher than " |
2876 | "local TSF - IBSS merge with BSSID %s\n", | ||
2877 | dev->name, print_mac(mac, mgmt->bssid)); | ||
2828 | #endif | 2878 | #endif |
2829 | printk(KERN_DEBUG "%s: beacon TSF higher than " | ||
2830 | "local TSF - IBSS merge with BSSID %s\n", | ||
2831 | dev->name, print_mac(mac, mgmt->bssid)); | ||
2832 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); | 2879 | ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); |
2833 | ieee80211_ibss_add_sta(dev, NULL, | 2880 | ieee80211_ibss_add_sta(dev, NULL, |
2834 | mgmt->bssid, mgmt->sa); | 2881 | mgmt->bssid, mgmt->sa, |
2882 | BIT(rx_status->rate_idx)); | ||
2835 | } | 2883 | } |
2836 | } | 2884 | } |
2837 | 2885 | ||
@@ -2844,7 +2892,17 @@ static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, | |||
2844 | size_t len, | 2892 | size_t len, |
2845 | struct ieee80211_rx_status *rx_status) | 2893 | struct ieee80211_rx_status *rx_status) |
2846 | { | 2894 | { |
2847 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 0); | 2895 | size_t baselen; |
2896 | struct ieee802_11_elems elems; | ||
2897 | |||
2898 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | ||
2899 | if (baselen > len) | ||
2900 | return; | ||
2901 | |||
2902 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | ||
2903 | &elems); | ||
2904 | |||
2905 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0); | ||
2848 | } | 2906 | } |
2849 | 2907 | ||
2850 | 2908 | ||
@@ -2861,7 +2919,14 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2861 | struct ieee80211_conf *conf = &local->hw.conf; | 2919 | struct ieee80211_conf *conf = &local->hw.conf; |
2862 | u32 changed = 0; | 2920 | u32 changed = 0; |
2863 | 2921 | ||
2864 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); | 2922 | /* Process beacon from the current BSS */ |
2923 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | ||
2924 | if (baselen > len) | ||
2925 | return; | ||
2926 | |||
2927 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
2928 | |||
2929 | ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1); | ||
2865 | 2930 | ||
2866 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2931 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
2867 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 2932 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
@@ -2872,17 +2937,8 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev, | |||
2872 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) | 2937 | memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) |
2873 | return; | 2938 | return; |
2874 | 2939 | ||
2875 | /* Process beacon from the current BSS */ | 2940 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, |
2876 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | 2941 | elems.wmm_param_len); |
2877 | if (baselen > len) | ||
2878 | return; | ||
2879 | |||
2880 | ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | ||
2881 | |||
2882 | if (elems.wmm_param && (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { | ||
2883 | ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, | ||
2884 | elems.wmm_param_len); | ||
2885 | } | ||
2886 | 2942 | ||
2887 | /* Do not send changes to driver if we are scanning. This removes | 2943 | /* Do not send changes to driver if we are scanning. This removes |
2888 | * requirement that driver's bss_info_changed function needs to be | 2944 | * requirement that driver's bss_info_changed function needs to be |
@@ -2959,11 +3015,11 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, | |||
2959 | pos = mgmt->u.probe_req.variable; | 3015 | pos = mgmt->u.probe_req.variable; |
2960 | if (pos[0] != WLAN_EID_SSID || | 3016 | if (pos[0] != WLAN_EID_SSID || |
2961 | pos + 2 + pos[1] > end) { | 3017 | pos + 2 + pos[1] > end) { |
2962 | if (net_ratelimit()) { | 3018 | #ifdef CONFIG_MAC80211_IBSS_DEBUG |
2963 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 3019 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " |
2964 | "from %s\n", | 3020 | "from %s\n", |
2965 | dev->name, print_mac(mac, mgmt->sa)); | 3021 | dev->name, print_mac(mac, mgmt->sa)); |
2966 | } | 3022 | #endif |
2967 | return; | 3023 | return; |
2968 | } | 3024 | } |
2969 | if (pos[1] != 0 && | 3025 | if (pos[1] != 0 && |
@@ -2994,11 +3050,24 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
2994 | struct ieee80211_rx_status *rx_status) | 3050 | struct ieee80211_rx_status *rx_status) |
2995 | { | 3051 | { |
2996 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 3052 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
3053 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
2997 | 3054 | ||
2998 | if (len < IEEE80211_MIN_ACTION_SIZE) | 3055 | if (len < IEEE80211_MIN_ACTION_SIZE) |
2999 | return; | 3056 | return; |
3000 | 3057 | ||
3001 | switch (mgmt->u.action.category) { | 3058 | switch (mgmt->u.action.category) { |
3059 | case WLAN_CATEGORY_SPECTRUM_MGMT: | ||
3060 | if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ) | ||
3061 | break; | ||
3062 | switch (mgmt->u.action.u.chan_switch.action_code) { | ||
3063 | case WLAN_ACTION_SPCT_MSR_REQ: | ||
3064 | if (len < (IEEE80211_MIN_ACTION_SIZE + | ||
3065 | sizeof(mgmt->u.action.u.measurement))) | ||
3066 | break; | ||
3067 | ieee80211_sta_process_measurement_req(dev, mgmt, len); | ||
3068 | break; | ||
3069 | } | ||
3070 | break; | ||
3002 | case WLAN_CATEGORY_BACK: | 3071 | case WLAN_CATEGORY_BACK: |
3003 | switch (mgmt->u.action.u.addba_req.action_code) { | 3072 | switch (mgmt->u.action.u.addba_req.action_code) { |
3004 | case WLAN_ACTION_ADDBA_REQ: | 3073 | case WLAN_ACTION_ADDBA_REQ: |
@@ -3019,11 +3088,6 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
3019 | break; | 3088 | break; |
3020 | ieee80211_sta_process_delba(dev, mgmt, len); | 3089 | ieee80211_sta_process_delba(dev, mgmt, len); |
3021 | break; | 3090 | break; |
3022 | default: | ||
3023 | if (net_ratelimit()) | ||
3024 | printk(KERN_DEBUG "%s: Rx unknown A-MPDU action\n", | ||
3025 | dev->name); | ||
3026 | break; | ||
3027 | } | 3091 | } |
3028 | break; | 3092 | break; |
3029 | case PLINK_CATEGORY: | 3093 | case PLINK_CATEGORY: |
@@ -3034,11 +3098,6 @@ static void ieee80211_rx_mgmt_action(struct net_device *dev, | |||
3034 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 3098 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
3035 | mesh_rx_path_sel_frame(dev, mgmt, len); | 3099 | mesh_rx_path_sel_frame(dev, mgmt, len); |
3036 | break; | 3100 | break; |
3037 | default: | ||
3038 | if (net_ratelimit()) | ||
3039 | printk(KERN_DEBUG "%s: Rx unknown action frame - " | ||
3040 | "category=%d\n", dev->name, mgmt->u.action.category); | ||
3041 | break; | ||
3042 | } | 3101 | } |
3043 | } | 3102 | } |
3044 | 3103 | ||
@@ -3074,11 +3133,6 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb, | |||
3074 | skb_queue_tail(&ifsta->skb_queue, skb); | 3133 | skb_queue_tail(&ifsta->skb_queue, skb); |
3075 | queue_work(local->hw.workqueue, &ifsta->work); | 3134 | queue_work(local->hw.workqueue, &ifsta->work); |
3076 | return; | 3135 | return; |
3077 | default: | ||
3078 | printk(KERN_DEBUG "%s: received unknown management frame - " | ||
3079 | "stype=%d\n", dev->name, | ||
3080 | (fc & IEEE80211_FCTL_STYPE) >> 4); | ||
3081 | break; | ||
3082 | } | 3136 | } |
3083 | 3137 | ||
3084 | fail: | 3138 | fail: |
@@ -3142,33 +3196,32 @@ ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, | |||
3142 | struct ieee80211_rx_status *rx_status) | 3196 | struct ieee80211_rx_status *rx_status) |
3143 | { | 3197 | { |
3144 | struct ieee80211_mgmt *mgmt; | 3198 | struct ieee80211_mgmt *mgmt; |
3145 | u16 fc; | 3199 | __le16 fc; |
3146 | 3200 | ||
3147 | if (skb->len < 2) | 3201 | if (skb->len < 2) |
3148 | return RX_DROP_UNUSABLE; | 3202 | return RX_DROP_UNUSABLE; |
3149 | 3203 | ||
3150 | mgmt = (struct ieee80211_mgmt *) skb->data; | 3204 | mgmt = (struct ieee80211_mgmt *) skb->data; |
3151 | fc = le16_to_cpu(mgmt->frame_control); | 3205 | fc = mgmt->frame_control; |
3152 | 3206 | ||
3153 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) | 3207 | if (ieee80211_is_ctl(fc)) |
3154 | return RX_CONTINUE; | 3208 | return RX_CONTINUE; |
3155 | 3209 | ||
3156 | if (skb->len < 24) | 3210 | if (skb->len < 24) |
3157 | return RX_DROP_MONITOR; | 3211 | return RX_DROP_MONITOR; |
3158 | 3212 | ||
3159 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) { | 3213 | if (ieee80211_is_probe_resp(fc)) { |
3160 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP) { | 3214 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status); |
3161 | ieee80211_rx_mgmt_probe_resp(dev, mgmt, | 3215 | dev_kfree_skb(skb); |
3162 | skb->len, rx_status); | 3216 | return RX_QUEUED; |
3163 | dev_kfree_skb(skb); | ||
3164 | return RX_QUEUED; | ||
3165 | } else if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { | ||
3166 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, | ||
3167 | rx_status); | ||
3168 | dev_kfree_skb(skb); | ||
3169 | return RX_QUEUED; | ||
3170 | } | ||
3171 | } | 3217 | } |
3218 | |||
3219 | if (ieee80211_is_beacon(fc)) { | ||
3220 | ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status); | ||
3221 | dev_kfree_skb(skb); | ||
3222 | return RX_QUEUED; | ||
3223 | } | ||
3224 | |||
3172 | return RX_CONTINUE; | 3225 | return RX_CONTINUE; |
3173 | } | 3226 | } |
3174 | 3227 | ||
@@ -3208,8 +3261,10 @@ static void ieee80211_sta_expire(struct net_device *dev, unsigned long exp_time) | |||
3208 | spin_lock_irqsave(&local->sta_lock, flags); | 3261 | spin_lock_irqsave(&local->sta_lock, flags); |
3209 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) | 3262 | list_for_each_entry_safe(sta, tmp, &local->sta_list, list) |
3210 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 3263 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
3264 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
3211 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", | 3265 | printk(KERN_DEBUG "%s: expiring inactive STA %s\n", |
3212 | dev->name, print_mac(mac, sta->addr)); | 3266 | dev->name, print_mac(mac, sta->addr)); |
3267 | #endif | ||
3213 | __sta_info_unlink(&sta); | 3268 | __sta_info_unlink(&sta); |
3214 | if (sta) | 3269 | if (sta) |
3215 | list_add(&sta->list, &tmp_list); | 3270 | list_add(&sta->list, &tmp_list); |
@@ -3292,13 +3347,10 @@ void ieee80211_sta_work(struct work_struct *work) | |||
3292 | if (local->sta_sw_scanning || local->sta_hw_scanning) | 3347 | if (local->sta_sw_scanning || local->sta_hw_scanning) |
3293 | return; | 3348 | return; |
3294 | 3349 | ||
3295 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && | 3350 | if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA && |
3296 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 3351 | sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
3297 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) { | 3352 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) |
3298 | printk(KERN_DEBUG "%s: ieee80211_sta_work: non-STA interface " | ||
3299 | "(type=%d)\n", dev->name, sdata->vif.type); | ||
3300 | return; | 3353 | return; |
3301 | } | ||
3302 | ifsta = &sdata->u.sta; | 3354 | ifsta = &sdata->u.sta; |
3303 | 3355 | ||
3304 | while ((skb = skb_dequeue(&ifsta->skb_queue))) | 3356 | while ((skb = skb_dequeue(&ifsta->skb_queue))) |
@@ -3352,8 +3404,7 @@ void ieee80211_sta_work(struct work_struct *work) | |||
3352 | break; | 3404 | break; |
3353 | #endif | 3405 | #endif |
3354 | default: | 3406 | default: |
3355 | printk(KERN_DEBUG "ieee80211_sta_work: Unknown state %d\n", | 3407 | WARN_ON(1); |
3356 | ifsta->state); | ||
3357 | break; | 3408 | break; |
3358 | } | 3409 | } |
3359 | 3410 | ||
@@ -3388,8 +3439,6 @@ static void ieee80211_sta_reset_auth(struct net_device *dev, | |||
3388 | ifsta->auth_alg = WLAN_AUTH_LEAP; | 3439 | ifsta->auth_alg = WLAN_AUTH_LEAP; |
3389 | else | 3440 | else |
3390 | ifsta->auth_alg = WLAN_AUTH_OPEN; | 3441 | ifsta->auth_alg = WLAN_AUTH_OPEN; |
3391 | printk(KERN_DEBUG "%s: Initial auth_alg=%d\n", dev->name, | ||
3392 | ifsta->auth_alg); | ||
3393 | ifsta->auth_transaction = -1; | 3442 | ifsta->auth_transaction = -1; |
3394 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; | 3443 | ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; |
3395 | ifsta->auth_tries = ifsta->assoc_tries = 0; | 3444 | ifsta->auth_tries = ifsta->assoc_tries = 0; |
@@ -3478,9 +3527,9 @@ static int ieee80211_sta_config_auth(struct net_device *dev, | |||
3478 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) | 3527 | !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len)) |
3479 | continue; | 3528 | continue; |
3480 | 3529 | ||
3481 | if (!selected || top_rssi < bss->rssi) { | 3530 | if (!selected || top_rssi < bss->signal) { |
3482 | selected = bss; | 3531 | selected = bss; |
3483 | top_rssi = bss->rssi; | 3532 | top_rssi = bss->signal; |
3484 | } | 3533 | } |
3485 | } | 3534 | } |
3486 | if (selected) | 3535 | if (selected) |
@@ -3553,14 +3602,16 @@ static int ieee80211_sta_create_ibss(struct net_device *dev, | |||
3553 | sband = local->hw.wiphy->bands[bss->band]; | 3602 | sband = local->hw.wiphy->bands[bss->band]; |
3554 | 3603 | ||
3555 | if (local->hw.conf.beacon_int == 0) | 3604 | if (local->hw.conf.beacon_int == 0) |
3556 | local->hw.conf.beacon_int = 10000; | 3605 | local->hw.conf.beacon_int = 100; |
3557 | bss->beacon_int = local->hw.conf.beacon_int; | 3606 | bss->beacon_int = local->hw.conf.beacon_int; |
3558 | bss->last_update = jiffies; | 3607 | bss->last_update = jiffies; |
3559 | bss->capability = WLAN_CAPABILITY_IBSS; | 3608 | bss->capability = WLAN_CAPABILITY_IBSS; |
3560 | if (sdata->default_key) { | 3609 | |
3610 | if (sdata->default_key) | ||
3561 | bss->capability |= WLAN_CAPABILITY_PRIVACY; | 3611 | bss->capability |= WLAN_CAPABILITY_PRIVACY; |
3562 | } else | 3612 | else |
3563 | sdata->drop_unencrypted = 0; | 3613 | sdata->drop_unencrypted = 0; |
3614 | |||
3564 | bss->supp_rates_len = sband->n_bitrates; | 3615 | bss->supp_rates_len = sband->n_bitrates; |
3565 | pos = bss->supp_rates; | 3616 | pos = bss->supp_rates; |
3566 | for (i = 0; i < sband->n_bitrates; i++) { | 3617 | for (i = 0; i < sband->n_bitrates; i++) { |
@@ -3744,7 +3795,7 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
3744 | { | 3795 | { |
3745 | struct sk_buff *skb; | 3796 | struct sk_buff *skb; |
3746 | struct ieee80211_hdr *nullfunc; | 3797 | struct ieee80211_hdr *nullfunc; |
3747 | u16 fc; | 3798 | __le16 fc; |
3748 | 3799 | ||
3749 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); | 3800 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); |
3750 | if (!skb) { | 3801 | if (!skb) { |
@@ -3756,11 +3807,11 @@ static void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
3756 | 3807 | ||
3757 | nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); | 3808 | nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); |
3758 | memset(nullfunc, 0, 24); | 3809 | memset(nullfunc, 0, 24); |
3759 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | | 3810 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | |
3760 | IEEE80211_FCTL_TODS; | 3811 | IEEE80211_FCTL_TODS); |
3761 | if (powersave) | 3812 | if (powersave) |
3762 | fc |= IEEE80211_FCTL_PM; | 3813 | fc |= cpu_to_le16(IEEE80211_FCTL_PM); |
3763 | nullfunc->frame_control = cpu_to_le16(fc); | 3814 | nullfunc->frame_control = fc; |
3764 | memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN); | 3815 | memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN); |
3765 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); | 3816 | memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN); |
3766 | memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN); | 3817 | memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN); |
@@ -4054,6 +4105,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) | |||
4054 | 4105 | ||
4055 | static char * | 4106 | static char * |
4056 | ieee80211_sta_scan_result(struct net_device *dev, | 4107 | ieee80211_sta_scan_result(struct net_device *dev, |
4108 | struct iw_request_info *info, | ||
4057 | struct ieee80211_sta_bss *bss, | 4109 | struct ieee80211_sta_bss *bss, |
4058 | char *current_ev, char *end_buf) | 4110 | char *current_ev, char *end_buf) |
4059 | { | 4111 | { |
@@ -4068,7 +4120,7 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4068 | iwe.cmd = SIOCGIWAP; | 4120 | iwe.cmd = SIOCGIWAP; |
4069 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 4121 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
4070 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); | 4122 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); |
4071 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4123 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4072 | IW_EV_ADDR_LEN); | 4124 | IW_EV_ADDR_LEN); |
4073 | 4125 | ||
4074 | memset(&iwe, 0, sizeof(iwe)); | 4126 | memset(&iwe, 0, sizeof(iwe)); |
@@ -4076,13 +4128,13 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4076 | if (bss_mesh_cfg(bss)) { | 4128 | if (bss_mesh_cfg(bss)) { |
4077 | iwe.u.data.length = bss_mesh_id_len(bss); | 4129 | iwe.u.data.length = bss_mesh_id_len(bss); |
4078 | iwe.u.data.flags = 1; | 4130 | iwe.u.data.flags = 1; |
4079 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4131 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4080 | bss_mesh_id(bss)); | 4132 | &iwe, bss_mesh_id(bss)); |
4081 | } else { | 4133 | } else { |
4082 | iwe.u.data.length = bss->ssid_len; | 4134 | iwe.u.data.length = bss->ssid_len; |
4083 | iwe.u.data.flags = 1; | 4135 | iwe.u.data.flags = 1; |
4084 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4136 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4085 | bss->ssid); | 4137 | &iwe, bss->ssid); |
4086 | } | 4138 | } |
4087 | 4139 | ||
4088 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) | 4140 | if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) |
@@ -4095,30 +4147,30 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4095 | iwe.u.mode = IW_MODE_MASTER; | 4147 | iwe.u.mode = IW_MODE_MASTER; |
4096 | else | 4148 | else |
4097 | iwe.u.mode = IW_MODE_ADHOC; | 4149 | iwe.u.mode = IW_MODE_ADHOC; |
4098 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4150 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
4099 | IW_EV_UINT_LEN); | 4151 | &iwe, IW_EV_UINT_LEN); |
4100 | } | 4152 | } |
4101 | 4153 | ||
4102 | memset(&iwe, 0, sizeof(iwe)); | 4154 | memset(&iwe, 0, sizeof(iwe)); |
4103 | iwe.cmd = SIOCGIWFREQ; | 4155 | iwe.cmd = SIOCGIWFREQ; |
4104 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); | 4156 | iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); |
4105 | iwe.u.freq.e = 0; | 4157 | iwe.u.freq.e = 0; |
4106 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4158 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4107 | IW_EV_FREQ_LEN); | 4159 | IW_EV_FREQ_LEN); |
4108 | 4160 | ||
4109 | memset(&iwe, 0, sizeof(iwe)); | 4161 | memset(&iwe, 0, sizeof(iwe)); |
4110 | iwe.cmd = SIOCGIWFREQ; | 4162 | iwe.cmd = SIOCGIWFREQ; |
4111 | iwe.u.freq.m = bss->freq; | 4163 | iwe.u.freq.m = bss->freq; |
4112 | iwe.u.freq.e = 6; | 4164 | iwe.u.freq.e = 6; |
4113 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4165 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4114 | IW_EV_FREQ_LEN); | 4166 | IW_EV_FREQ_LEN); |
4115 | memset(&iwe, 0, sizeof(iwe)); | 4167 | memset(&iwe, 0, sizeof(iwe)); |
4116 | iwe.cmd = IWEVQUAL; | 4168 | iwe.cmd = IWEVQUAL; |
4117 | iwe.u.qual.qual = bss->signal; | 4169 | iwe.u.qual.qual = bss->qual; |
4118 | iwe.u.qual.level = bss->rssi; | 4170 | iwe.u.qual.level = bss->signal; |
4119 | iwe.u.qual.noise = bss->noise; | 4171 | iwe.u.qual.noise = bss->noise; |
4120 | iwe.u.qual.updated = local->wstats_flags; | 4172 | iwe.u.qual.updated = local->wstats_flags; |
4121 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 4173 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
4122 | IW_EV_QUAL_LEN); | 4174 | IW_EV_QUAL_LEN); |
4123 | 4175 | ||
4124 | memset(&iwe, 0, sizeof(iwe)); | 4176 | memset(&iwe, 0, sizeof(iwe)); |
@@ -4128,27 +4180,36 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4128 | else | 4180 | else |
4129 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 4181 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
4130 | iwe.u.data.length = 0; | 4182 | iwe.u.data.length = 0; |
4131 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); | 4183 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4184 | &iwe, ""); | ||
4132 | 4185 | ||
4133 | if (bss && bss->wpa_ie) { | 4186 | if (bss && bss->wpa_ie) { |
4134 | memset(&iwe, 0, sizeof(iwe)); | 4187 | memset(&iwe, 0, sizeof(iwe)); |
4135 | iwe.cmd = IWEVGENIE; | 4188 | iwe.cmd = IWEVGENIE; |
4136 | iwe.u.data.length = bss->wpa_ie_len; | 4189 | iwe.u.data.length = bss->wpa_ie_len; |
4137 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4190 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4138 | bss->wpa_ie); | 4191 | &iwe, bss->wpa_ie); |
4139 | } | 4192 | } |
4140 | 4193 | ||
4141 | if (bss && bss->rsn_ie) { | 4194 | if (bss && bss->rsn_ie) { |
4142 | memset(&iwe, 0, sizeof(iwe)); | 4195 | memset(&iwe, 0, sizeof(iwe)); |
4143 | iwe.cmd = IWEVGENIE; | 4196 | iwe.cmd = IWEVGENIE; |
4144 | iwe.u.data.length = bss->rsn_ie_len; | 4197 | iwe.u.data.length = bss->rsn_ie_len; |
4145 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 4198 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4146 | bss->rsn_ie); | 4199 | &iwe, bss->rsn_ie); |
4200 | } | ||
4201 | |||
4202 | if (bss && bss->ht_ie) { | ||
4203 | memset(&iwe, 0, sizeof(iwe)); | ||
4204 | iwe.cmd = IWEVGENIE; | ||
4205 | iwe.u.data.length = bss->ht_ie_len; | ||
4206 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, | ||
4207 | &iwe, bss->ht_ie); | ||
4147 | } | 4208 | } |
4148 | 4209 | ||
4149 | if (bss && bss->supp_rates_len > 0) { | 4210 | if (bss && bss->supp_rates_len > 0) { |
4150 | /* display all supported rates in readable format */ | 4211 | /* display all supported rates in readable format */ |
4151 | char *p = current_ev + IW_EV_LCP_LEN; | 4212 | char *p = current_ev + iwe_stream_lcp_len(info); |
4152 | int i; | 4213 | int i; |
4153 | 4214 | ||
4154 | memset(&iwe, 0, sizeof(iwe)); | 4215 | memset(&iwe, 0, sizeof(iwe)); |
@@ -4159,7 +4220,7 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4159 | for (i = 0; i < bss->supp_rates_len; i++) { | 4220 | for (i = 0; i < bss->supp_rates_len; i++) { |
4160 | iwe.u.bitrate.value = ((bss->supp_rates[i] & | 4221 | iwe.u.bitrate.value = ((bss->supp_rates[i] & |
4161 | 0x7f) * 500000); | 4222 | 0x7f) * 500000); |
4162 | p = iwe_stream_add_value(current_ev, p, | 4223 | p = iwe_stream_add_value(info, current_ev, p, |
4163 | end_buf, &iwe, IW_EV_PARAM_LEN); | 4224 | end_buf, &iwe, IW_EV_PARAM_LEN); |
4164 | } | 4225 | } |
4165 | current_ev = p; | 4226 | current_ev = p; |
@@ -4173,8 +4234,16 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4173 | iwe.cmd = IWEVCUSTOM; | 4234 | iwe.cmd = IWEVCUSTOM; |
4174 | sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); | 4235 | sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); |
4175 | iwe.u.data.length = strlen(buf); | 4236 | iwe.u.data.length = strlen(buf); |
4176 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4237 | current_ev = iwe_stream_add_point(info, current_ev, |
4238 | end_buf, | ||
4177 | &iwe, buf); | 4239 | &iwe, buf); |
4240 | memset(&iwe, 0, sizeof(iwe)); | ||
4241 | iwe.cmd = IWEVCUSTOM; | ||
4242 | sprintf(buf, " Last beacon: %dms ago", | ||
4243 | jiffies_to_msecs(jiffies - bss->last_update)); | ||
4244 | iwe.u.data.length = strlen(buf); | ||
4245 | current_ev = iwe_stream_add_point(info, current_ev, | ||
4246 | end_buf, &iwe, buf); | ||
4178 | kfree(buf); | 4247 | kfree(buf); |
4179 | } | 4248 | } |
4180 | } | 4249 | } |
@@ -4188,31 +4257,36 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4188 | iwe.cmd = IWEVCUSTOM; | 4257 | iwe.cmd = IWEVCUSTOM; |
4189 | sprintf(buf, "Mesh network (version %d)", cfg[0]); | 4258 | sprintf(buf, "Mesh network (version %d)", cfg[0]); |
4190 | iwe.u.data.length = strlen(buf); | 4259 | iwe.u.data.length = strlen(buf); |
4191 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4260 | current_ev = iwe_stream_add_point(info, current_ev, |
4261 | end_buf, | ||
4192 | &iwe, buf); | 4262 | &iwe, buf); |
4193 | sprintf(buf, "Path Selection Protocol ID: " | 4263 | sprintf(buf, "Path Selection Protocol ID: " |
4194 | "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], | 4264 | "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], |
4195 | cfg[4]); | 4265 | cfg[4]); |
4196 | iwe.u.data.length = strlen(buf); | 4266 | iwe.u.data.length = strlen(buf); |
4197 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4267 | current_ev = iwe_stream_add_point(info, current_ev, |
4268 | end_buf, | ||
4198 | &iwe, buf); | 4269 | &iwe, buf); |
4199 | sprintf(buf, "Path Selection Metric ID: " | 4270 | sprintf(buf, "Path Selection Metric ID: " |
4200 | "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], | 4271 | "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], |
4201 | cfg[8]); | 4272 | cfg[8]); |
4202 | iwe.u.data.length = strlen(buf); | 4273 | iwe.u.data.length = strlen(buf); |
4203 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4274 | current_ev = iwe_stream_add_point(info, current_ev, |
4275 | end_buf, | ||
4204 | &iwe, buf); | 4276 | &iwe, buf); |
4205 | sprintf(buf, "Congestion Control Mode ID: " | 4277 | sprintf(buf, "Congestion Control Mode ID: " |
4206 | "0x%02X%02X%02X%02X", cfg[9], cfg[10], | 4278 | "0x%02X%02X%02X%02X", cfg[9], cfg[10], |
4207 | cfg[11], cfg[12]); | 4279 | cfg[11], cfg[12]); |
4208 | iwe.u.data.length = strlen(buf); | 4280 | iwe.u.data.length = strlen(buf); |
4209 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4281 | current_ev = iwe_stream_add_point(info, current_ev, |
4282 | end_buf, | ||
4210 | &iwe, buf); | 4283 | &iwe, buf); |
4211 | sprintf(buf, "Channel Precedence: " | 4284 | sprintf(buf, "Channel Precedence: " |
4212 | "0x%02X%02X%02X%02X", cfg[13], cfg[14], | 4285 | "0x%02X%02X%02X%02X", cfg[13], cfg[14], |
4213 | cfg[15], cfg[16]); | 4286 | cfg[15], cfg[16]); |
4214 | iwe.u.data.length = strlen(buf); | 4287 | iwe.u.data.length = strlen(buf); |
4215 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 4288 | current_ev = iwe_stream_add_point(info, current_ev, |
4289 | end_buf, | ||
4216 | &iwe, buf); | 4290 | &iwe, buf); |
4217 | kfree(buf); | 4291 | kfree(buf); |
4218 | } | 4292 | } |
@@ -4222,7 +4296,9 @@ ieee80211_sta_scan_result(struct net_device *dev, | |||
4222 | } | 4296 | } |
4223 | 4297 | ||
4224 | 4298 | ||
4225 | int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) | 4299 | int ieee80211_sta_scan_results(struct net_device *dev, |
4300 | struct iw_request_info *info, | ||
4301 | char *buf, size_t len) | ||
4226 | { | 4302 | { |
4227 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 4303 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
4228 | char *current_ev = buf; | 4304 | char *current_ev = buf; |
@@ -4235,8 +4311,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) | |||
4235 | spin_unlock_bh(&local->sta_bss_lock); | 4311 | spin_unlock_bh(&local->sta_bss_lock); |
4236 | return -E2BIG; | 4312 | return -E2BIG; |
4237 | } | 4313 | } |
4238 | current_ev = ieee80211_sta_scan_result(dev, bss, current_ev, | 4314 | current_ev = ieee80211_sta_scan_result(dev, info, bss, |
4239 | end_buf); | 4315 | current_ev, end_buf); |
4240 | } | 4316 | } |
4241 | spin_unlock_bh(&local->sta_bss_lock); | 4317 | spin_unlock_bh(&local->sta_bss_lock); |
4242 | return current_ev - buf; | 4318 | return current_ev - buf; |
@@ -4247,6 +4323,7 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) | |||
4247 | { | 4323 | { |
4248 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4324 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
4249 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4325 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
4326 | |||
4250 | kfree(ifsta->extra_ie); | 4327 | kfree(ifsta->extra_ie); |
4251 | if (len == 0) { | 4328 | if (len == 0) { |
4252 | ifsta->extra_ie = NULL; | 4329 | ifsta->extra_ie = NULL; |
@@ -4264,14 +4341,15 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) | |||
4264 | } | 4341 | } |
4265 | 4342 | ||
4266 | 4343 | ||
4267 | struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | 4344 | struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev, |
4268 | struct sk_buff *skb, u8 *bssid, | 4345 | struct sk_buff *skb, u8 *bssid, |
4269 | u8 *addr) | 4346 | u8 *addr, u64 supp_rates) |
4270 | { | 4347 | { |
4271 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 4348 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
4272 | struct sta_info *sta; | 4349 | struct sta_info *sta; |
4273 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4350 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
4274 | DECLARE_MAC_BUF(mac); | 4351 | DECLARE_MAC_BUF(mac); |
4352 | int band = local->hw.conf.channel->band; | ||
4275 | 4353 | ||
4276 | /* TODO: Could consider removing the least recently used entry and | 4354 | /* TODO: Could consider removing the least recently used entry and |
4277 | * allow new one to be added. */ | 4355 | * allow new one to be added. */ |
@@ -4283,17 +4361,24 @@ struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, | |||
4283 | return NULL; | 4361 | return NULL; |
4284 | } | 4362 | } |
4285 | 4363 | ||
4364 | if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) | ||
4365 | return NULL; | ||
4366 | |||
4367 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
4286 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", | 4368 | printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n", |
4287 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); | 4369 | wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name); |
4370 | #endif | ||
4288 | 4371 | ||
4289 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); | 4372 | sta = sta_info_alloc(sdata, addr, GFP_ATOMIC); |
4290 | if (!sta) | 4373 | if (!sta) |
4291 | return NULL; | 4374 | return NULL; |
4292 | 4375 | ||
4293 | sta->flags |= WLAN_STA_AUTHORIZED; | 4376 | set_sta_flags(sta, WLAN_STA_AUTHORIZED); |
4294 | 4377 | ||
4295 | sta->supp_rates[local->hw.conf.channel->band] = | 4378 | if (supp_rates) |
4296 | sdata->u.sta.supp_rates_bits[local->hw.conf.channel->band]; | 4379 | sta->supp_rates[band] = supp_rates; |
4380 | else | ||
4381 | sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band]; | ||
4297 | 4382 | ||
4298 | rate_control_rate_init(sta, local); | 4383 | rate_control_rate_init(sta, local); |
4299 | 4384 | ||
@@ -4309,7 +4394,7 @@ int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason) | |||
4309 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4394 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
4310 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4395 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
4311 | 4396 | ||
4312 | printk(KERN_DEBUG "%s: deauthenticate(reason=%d)\n", | 4397 | printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", |
4313 | dev->name, reason); | 4398 | dev->name, reason); |
4314 | 4399 | ||
4315 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && | 4400 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA && |
@@ -4327,7 +4412,7 @@ int ieee80211_sta_disassociate(struct net_device *dev, u16 reason) | |||
4327 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 4412 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
4328 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | 4413 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; |
4329 | 4414 | ||
4330 | printk(KERN_DEBUG "%s: disassociate(reason=%d)\n", | 4415 | printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", |
4331 | dev->name, reason); | 4416 | dev->name, reason); |
4332 | 4417 | ||
4333 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) | 4418 | if (sdata->vif.type != IEEE80211_IF_TYPE_STA) |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index 841df93807f..0388c090dfe 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -176,20 +176,24 @@ void rate_control_get_rate(struct net_device *dev, | |||
176 | rcu_read_lock(); | 176 | rcu_read_lock(); |
177 | sta = sta_info_get(local, hdr->addr1); | 177 | sta = sta_info_get(local, hdr->addr1); |
178 | 178 | ||
179 | memset(sel, 0, sizeof(struct rate_selection)); | 179 | sel->rate_idx = -1; |
180 | sel->nonerp_idx = -1; | ||
181 | sel->probe_idx = -1; | ||
180 | 182 | ||
181 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); | 183 | ref->ops->get_rate(ref->priv, dev, sband, skb, sel); |
182 | 184 | ||
185 | BUG_ON(sel->rate_idx < 0); | ||
186 | |||
183 | /* Select a non-ERP backup rate. */ | 187 | /* Select a non-ERP backup rate. */ |
184 | if (!sel->nonerp) { | 188 | if (sel->nonerp_idx < 0) { |
185 | for (i = 0; i < sband->n_bitrates; i++) { | 189 | for (i = 0; i < sband->n_bitrates; i++) { |
186 | struct ieee80211_rate *rate = &sband->bitrates[i]; | 190 | struct ieee80211_rate *rate = &sband->bitrates[i]; |
187 | if (sel->rate->bitrate < rate->bitrate) | 191 | if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) |
188 | break; | 192 | break; |
189 | 193 | ||
190 | if (rate_supported(sta, sband->band, i) && | 194 | if (rate_supported(sta, sband->band, i) && |
191 | !(rate->flags & IEEE80211_RATE_ERP_G)) | 195 | !(rate->flags & IEEE80211_RATE_ERP_G)) |
192 | sel->nonerp = rate; | 196 | sel->nonerp_idx = i; |
193 | } | 197 | } |
194 | } | 198 | } |
195 | 199 | ||
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h index 5b45f33cb76..ede7ab56f65 100644 --- a/net/mac80211/rate.h +++ b/net/mac80211/rate.h | |||
@@ -19,22 +19,22 @@ | |||
19 | #include "ieee80211_i.h" | 19 | #include "ieee80211_i.h" |
20 | #include "sta_info.h" | 20 | #include "sta_info.h" |
21 | 21 | ||
22 | /* TODO: kdoc */ | 22 | /** |
23 | * struct rate_selection - rate selection for rate control algos | ||
24 | * @rate: selected transmission rate index | ||
25 | * @nonerp: Non-ERP rate to use instead if ERP cannot be used | ||
26 | * @probe: rate for probing (or -1) | ||
27 | * | ||
28 | */ | ||
23 | struct rate_selection { | 29 | struct rate_selection { |
24 | /* Selected transmission rate */ | 30 | s8 rate_idx, nonerp_idx, probe_idx; |
25 | struct ieee80211_rate *rate; | ||
26 | /* Non-ERP rate to use if mac80211 decides it cannot use an ERP rate */ | ||
27 | struct ieee80211_rate *nonerp; | ||
28 | /* probe with this rate, or NULL for no probing */ | ||
29 | struct ieee80211_rate *probe; | ||
30 | }; | 31 | }; |
31 | 32 | ||
32 | struct rate_control_ops { | 33 | struct rate_control_ops { |
33 | struct module *module; | 34 | struct module *module; |
34 | const char *name; | 35 | const char *name; |
35 | void (*tx_status)(void *priv, struct net_device *dev, | 36 | void (*tx_status)(void *priv, struct net_device *dev, |
36 | struct sk_buff *skb, | 37 | struct sk_buff *skb); |
37 | struct ieee80211_tx_status *status); | ||
38 | void (*get_rate)(void *priv, struct net_device *dev, | 38 | void (*get_rate)(void *priv, struct net_device *dev, |
39 | struct ieee80211_supported_band *band, | 39 | struct ieee80211_supported_band *band, |
40 | struct sk_buff *skb, | 40 | struct sk_buff *skb, |
@@ -76,13 +76,12 @@ struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); | |||
76 | void rate_control_put(struct rate_control_ref *ref); | 76 | void rate_control_put(struct rate_control_ref *ref); |
77 | 77 | ||
78 | static inline void rate_control_tx_status(struct net_device *dev, | 78 | static inline void rate_control_tx_status(struct net_device *dev, |
79 | struct sk_buff *skb, | 79 | struct sk_buff *skb) |
80 | struct ieee80211_tx_status *status) | ||
81 | { | 80 | { |
82 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 81 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
83 | struct rate_control_ref *ref = local->rate_ctrl; | 82 | struct rate_control_ref *ref = local->rate_ctrl; |
84 | 83 | ||
85 | ref->ops->tx_status(ref->priv, dev, skb, status); | 84 | ref->ops->tx_status(ref->priv, dev, skb); |
86 | } | 85 | } |
87 | 86 | ||
88 | 87 | ||
@@ -138,7 +137,7 @@ static inline int rate_supported(struct sta_info *sta, | |||
138 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); | 137 | return (sta == NULL || sta->supp_rates[band] & BIT(index)); |
139 | } | 138 | } |
140 | 139 | ||
141 | static inline int | 140 | static inline s8 |
142 | rate_lowest_index(struct ieee80211_local *local, | 141 | rate_lowest_index(struct ieee80211_local *local, |
143 | struct ieee80211_supported_band *sband, | 142 | struct ieee80211_supported_band *sband, |
144 | struct sta_info *sta) | 143 | struct sta_info *sta) |
@@ -155,14 +154,6 @@ rate_lowest_index(struct ieee80211_local *local, | |||
155 | return 0; | 154 | return 0; |
156 | } | 155 | } |
157 | 156 | ||
158 | static inline struct ieee80211_rate * | ||
159 | rate_lowest(struct ieee80211_local *local, | ||
160 | struct ieee80211_supported_band *sband, | ||
161 | struct sta_info *sta) | ||
162 | { | ||
163 | return &sband->bitrates[rate_lowest_index(local, sband, sta)]; | ||
164 | } | ||
165 | |||
166 | 157 | ||
167 | /* functions for rate control related to a device */ | 158 | /* functions for rate control related to a device */ |
168 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, | 159 | int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, |
@@ -171,9 +162,7 @@ void rate_control_deinitialize(struct ieee80211_local *local); | |||
171 | 162 | ||
172 | 163 | ||
173 | /* Rate control algorithms */ | 164 | /* Rate control algorithms */ |
174 | #if defined(RC80211_PID_COMPILE) || \ | 165 | #ifdef CONFIG_MAC80211_RC_PID |
175 | (defined(CONFIG_MAC80211_RC_PID) && \ | ||
176 | !defined(CONFIG_MAC80211_RC_PID_MODULE)) | ||
177 | extern int rc80211_pid_init(void); | 166 | extern int rc80211_pid_init(void); |
178 | extern void rc80211_pid_exit(void); | 167 | extern void rc80211_pid_exit(void); |
179 | #else | 168 | #else |
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h index 04afc13ed82..2078803d358 100644 --- a/net/mac80211/rc80211_pid.h +++ b/net/mac80211/rc80211_pid.h | |||
@@ -61,7 +61,7 @@ enum rc_pid_event_type { | |||
61 | union rc_pid_event_data { | 61 | union rc_pid_event_data { |
62 | /* RC_PID_EVENT_TX_STATUS */ | 62 | /* RC_PID_EVENT_TX_STATUS */ |
63 | struct { | 63 | struct { |
64 | struct ieee80211_tx_status tx_status; | 64 | struct ieee80211_tx_info tx_status; |
65 | }; | 65 | }; |
66 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ | 66 | /* RC_PID_EVENT_TYPE_RATE_CHANGE */ |
67 | /* RC_PID_EVENT_TYPE_TX_RATE */ | 67 | /* RC_PID_EVENT_TYPE_TX_RATE */ |
@@ -158,7 +158,7 @@ struct rc_pid_debugfs_entries { | |||
158 | }; | 158 | }; |
159 | 159 | ||
160 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | 160 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, |
161 | struct ieee80211_tx_status *stat); | 161 | struct ieee80211_tx_info *stat); |
162 | 162 | ||
163 | void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf, | 163 | void rate_control_pid_event_rate_change(struct rc_pid_event_buffer *buf, |
164 | int index, int rate); | 164 | int index, int rate); |
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c index a849b745bdb..62388f8e902 100644 --- a/net/mac80211/rc80211_pid_algo.c +++ b/net/mac80211/rc80211_pid_algo.c | |||
@@ -237,8 +237,7 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo, | |||
237 | } | 237 | } |
238 | 238 | ||
239 | static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | 239 | static void rate_control_pid_tx_status(void *priv, struct net_device *dev, |
240 | struct sk_buff *skb, | 240 | struct sk_buff *skb) |
241 | struct ieee80211_tx_status *status) | ||
242 | { | 241 | { |
243 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 242 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
244 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 243 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -248,6 +247,7 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
248 | struct rc_pid_sta_info *spinfo; | 247 | struct rc_pid_sta_info *spinfo; |
249 | unsigned long period; | 248 | unsigned long period; |
250 | struct ieee80211_supported_band *sband; | 249 | struct ieee80211_supported_band *sband; |
250 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
251 | 251 | ||
252 | rcu_read_lock(); | 252 | rcu_read_lock(); |
253 | 253 | ||
@@ -266,28 +266,28 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
266 | 266 | ||
267 | /* Ignore all frames that were sent with a different rate than the rate | 267 | /* Ignore all frames that were sent with a different rate than the rate |
268 | * we currently advise mac80211 to use. */ | 268 | * we currently advise mac80211 to use. */ |
269 | if (status->control.tx_rate != &sband->bitrates[sta->txrate_idx]) | 269 | if (info->tx_rate_idx != sta->txrate_idx) |
270 | goto unlock; | 270 | goto unlock; |
271 | 271 | ||
272 | spinfo = sta->rate_ctrl_priv; | 272 | spinfo = sta->rate_ctrl_priv; |
273 | spinfo->tx_num_xmit++; | 273 | spinfo->tx_num_xmit++; |
274 | 274 | ||
275 | #ifdef CONFIG_MAC80211_DEBUGFS | 275 | #ifdef CONFIG_MAC80211_DEBUGFS |
276 | rate_control_pid_event_tx_status(&spinfo->events, status); | 276 | rate_control_pid_event_tx_status(&spinfo->events, info); |
277 | #endif | 277 | #endif |
278 | 278 | ||
279 | /* We count frames that totally failed to be transmitted as two bad | 279 | /* We count frames that totally failed to be transmitted as two bad |
280 | * frames, those that made it out but had some retries as one good and | 280 | * frames, those that made it out but had some retries as one good and |
281 | * one bad frame. */ | 281 | * one bad frame. */ |
282 | if (status->excessive_retries) { | 282 | if (info->status.excessive_retries) { |
283 | spinfo->tx_num_failed += 2; | 283 | spinfo->tx_num_failed += 2; |
284 | spinfo->tx_num_xmit++; | 284 | spinfo->tx_num_xmit++; |
285 | } else if (status->retry_count) { | 285 | } else if (info->status.retry_count) { |
286 | spinfo->tx_num_failed++; | 286 | spinfo->tx_num_failed++; |
287 | spinfo->tx_num_xmit++; | 287 | spinfo->tx_num_xmit++; |
288 | } | 288 | } |
289 | 289 | ||
290 | if (status->excessive_retries) { | 290 | if (info->status.excessive_retries) { |
291 | sta->tx_retry_failed++; | 291 | sta->tx_retry_failed++; |
292 | sta->tx_num_consecutive_failures++; | 292 | sta->tx_num_consecutive_failures++; |
293 | sta->tx_num_mpdu_fail++; | 293 | sta->tx_num_mpdu_fail++; |
@@ -295,8 +295,8 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev, | |||
295 | sta->tx_num_consecutive_failures = 0; | 295 | sta->tx_num_consecutive_failures = 0; |
296 | sta->tx_num_mpdu_ok++; | 296 | sta->tx_num_mpdu_ok++; |
297 | } | 297 | } |
298 | sta->tx_retry_count += status->retry_count; | 298 | sta->tx_retry_count += info->status.retry_count; |
299 | sta->tx_num_mpdu_fail += status->retry_count; | 299 | sta->tx_num_mpdu_fail += info->status.retry_count; |
300 | 300 | ||
301 | /* Update PID controller state. */ | 301 | /* Update PID controller state. */ |
302 | period = (HZ * pinfo->sampling_period + 500) / 1000; | 302 | period = (HZ * pinfo->sampling_period + 500) / 1000; |
@@ -330,7 +330,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
330 | fc = le16_to_cpu(hdr->frame_control); | 330 | fc = le16_to_cpu(hdr->frame_control); |
331 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || | 331 | if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || |
332 | is_multicast_ether_addr(hdr->addr1) || !sta) { | 332 | is_multicast_ether_addr(hdr->addr1) || !sta) { |
333 | sel->rate = rate_lowest(local, sband, sta); | 333 | sel->rate_idx = rate_lowest_index(local, sband, sta); |
334 | rcu_read_unlock(); | 334 | rcu_read_unlock(); |
335 | return; | 335 | return; |
336 | } | 336 | } |
@@ -349,7 +349,7 @@ static void rate_control_pid_get_rate(void *priv, struct net_device *dev, | |||
349 | 349 | ||
350 | rcu_read_unlock(); | 350 | rcu_read_unlock(); |
351 | 351 | ||
352 | sel->rate = &sband->bitrates[rateidx]; | 352 | sel->rate_idx = rateidx; |
353 | 353 | ||
354 | #ifdef CONFIG_MAC80211_DEBUGFS | 354 | #ifdef CONFIG_MAC80211_DEBUGFS |
355 | rate_control_pid_event_tx_rate( | 355 | rate_control_pid_event_tx_rate( |
@@ -540,11 +540,6 @@ static struct rate_control_ops mac80211_rcpid = { | |||
540 | #endif | 540 | #endif |
541 | }; | 541 | }; |
542 | 542 | ||
543 | MODULE_DESCRIPTION("PID controller based rate control algorithm"); | ||
544 | MODULE_AUTHOR("Stefano Brivio"); | ||
545 | MODULE_AUTHOR("Mattias Nissler"); | ||
546 | MODULE_LICENSE("GPL"); | ||
547 | |||
548 | int __init rc80211_pid_init(void) | 543 | int __init rc80211_pid_init(void) |
549 | { | 544 | { |
550 | return ieee80211_rate_control_register(&mac80211_rcpid); | 545 | return ieee80211_rate_control_register(&mac80211_rcpid); |
@@ -554,8 +549,3 @@ void rc80211_pid_exit(void) | |||
554 | { | 549 | { |
555 | ieee80211_rate_control_unregister(&mac80211_rcpid); | 550 | ieee80211_rate_control_unregister(&mac80211_rcpid); |
556 | } | 551 | } |
557 | |||
558 | #ifdef CONFIG_MAC80211_RC_PID_MODULE | ||
559 | module_init(rc80211_pid_init); | ||
560 | module_exit(rc80211_pid_exit); | ||
561 | #endif | ||
diff --git a/net/mac80211/rc80211_pid_debugfs.c b/net/mac80211/rc80211_pid_debugfs.c index ff5c380f3c1..8121d3bc683 100644 --- a/net/mac80211/rc80211_pid_debugfs.c +++ b/net/mac80211/rc80211_pid_debugfs.c | |||
@@ -39,11 +39,11 @@ static void rate_control_pid_event(struct rc_pid_event_buffer *buf, | |||
39 | } | 39 | } |
40 | 40 | ||
41 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, | 41 | void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf, |
42 | struct ieee80211_tx_status *stat) | 42 | struct ieee80211_tx_info *stat) |
43 | { | 43 | { |
44 | union rc_pid_event_data evd; | 44 | union rc_pid_event_data evd; |
45 | 45 | ||
46 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_status)); | 46 | memcpy(&evd.tx_status, stat, sizeof(struct ieee80211_tx_info)); |
47 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); | 47 | rate_control_pid_event(buf, RC_PID_EVENT_TYPE_TX_STATUS, &evd); |
48 | } | 48 | } |
49 | 49 | ||
@@ -167,8 +167,8 @@ static ssize_t rate_control_pid_events_read(struct file *file, char __user *buf, | |||
167 | switch (ev->type) { | 167 | switch (ev->type) { |
168 | case RC_PID_EVENT_TYPE_TX_STATUS: | 168 | case RC_PID_EVENT_TYPE_TX_STATUS: |
169 | p += snprintf(pb + p, length - p, "tx_status %u %u", | 169 | p += snprintf(pb + p, length - p, "tx_status %u %u", |
170 | ev->data.tx_status.excessive_retries, | 170 | ev->data.tx_status.status.excessive_retries, |
171 | ev->data.tx_status.retry_count); | 171 | ev->data.tx_status.status.retry_count); |
172 | break; | 172 | break; |
173 | case RC_PID_EVENT_TYPE_RATE_CHANGE: | 173 | case RC_PID_EVENT_TYPE_RATE_CHANGE: |
174 | p += snprintf(pb + p, length - p, "rate_change %d %d", | 174 | p += snprintf(pb + p, length - p, "rate_change %d %d", |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 0941e5d6a52..6a88e8f9bff 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -61,22 +61,147 @@ 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; |
68 | if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) | 68 | if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) |
69 | return 1; | 69 | return 1; |
70 | if (((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | 70 | if (ieee80211_is_ctl(hdr->frame_control) && |
71 | cpu_to_le16(IEEE80211_FTYPE_CTL)) && | 71 | !ieee80211_is_pspoll(hdr->frame_control) && |
72 | ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) != | 72 | !ieee80211_is_back_req(hdr->frame_control)) |
73 | cpu_to_le16(IEEE80211_STYPE_PSPOLL)) && | ||
74 | ((hdr->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE)) != | ||
75 | cpu_to_le16(IEEE80211_STYPE_BACK_REQ))) | ||
76 | return 1; | 73 | return 1; |
77 | return 0; | 74 | return 0; |
78 | } | 75 | } |
79 | 76 | ||
77 | static int | ||
78 | ieee80211_rx_radiotap_len(struct ieee80211_local *local, | ||
79 | struct ieee80211_rx_status *status) | ||
80 | { | ||
81 | int len; | ||
82 | |||
83 | /* always present fields */ | ||
84 | len = sizeof(struct ieee80211_radiotap_header) + 9; | ||
85 | |||
86 | if (status->flag & RX_FLAG_TSFT) | ||
87 | len += 8; | ||
88 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB || | ||
89 | local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
90 | len += 1; | ||
91 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
92 | len += 1; | ||
93 | |||
94 | if (len & 1) /* padding for RX_FLAGS if necessary */ | ||
95 | len++; | ||
96 | |||
97 | /* make sure radiotap starts at a naturally aligned address */ | ||
98 | if (len % 8) | ||
99 | len = roundup(len, 8); | ||
100 | |||
101 | return len; | ||
102 | } | ||
103 | |||
104 | /** | ||
105 | * ieee80211_add_rx_radiotap_header - add radiotap header | ||
106 | * | ||
107 | * add a radiotap header containing all the fields which the hardware provided. | ||
108 | */ | ||
109 | static void | ||
110 | ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | ||
111 | struct sk_buff *skb, | ||
112 | struct ieee80211_rx_status *status, | ||
113 | struct ieee80211_rate *rate, | ||
114 | int rtap_len) | ||
115 | { | ||
116 | struct ieee80211_radiotap_header *rthdr; | ||
117 | unsigned char *pos; | ||
118 | |||
119 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); | ||
120 | memset(rthdr, 0, rtap_len); | ||
121 | |||
122 | /* radiotap header, set always present flags */ | ||
123 | rthdr->it_present = | ||
124 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
125 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
126 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
127 | (1 << IEEE80211_RADIOTAP_ANTENNA) | | ||
128 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
129 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
130 | |||
131 | pos = (unsigned char *)(rthdr+1); | ||
132 | |||
133 | /* the order of the following fields is important */ | ||
134 | |||
135 | /* IEEE80211_RADIOTAP_TSFT */ | ||
136 | if (status->flag & RX_FLAG_TSFT) { | ||
137 | *(__le64 *)pos = cpu_to_le64(status->mactime); | ||
138 | rthdr->it_present |= | ||
139 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
140 | pos += 8; | ||
141 | } | ||
142 | |||
143 | /* IEEE80211_RADIOTAP_FLAGS */ | ||
144 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
145 | *pos |= IEEE80211_RADIOTAP_F_FCS; | ||
146 | pos++; | ||
147 | |||
148 | /* IEEE80211_RADIOTAP_RATE */ | ||
149 | *pos = rate->bitrate / 5; | ||
150 | pos++; | ||
151 | |||
152 | /* IEEE80211_RADIOTAP_CHANNEL */ | ||
153 | *(__le16 *)pos = cpu_to_le16(status->freq); | ||
154 | pos += 2; | ||
155 | if (status->band == IEEE80211_BAND_5GHZ) | ||
156 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
157 | IEEE80211_CHAN_5GHZ); | ||
158 | else | ||
159 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_DYN | | ||
160 | IEEE80211_CHAN_2GHZ); | ||
161 | pos += 2; | ||
162 | |||
163 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | ||
164 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) { | ||
165 | *pos = status->signal; | ||
166 | rthdr->it_present |= | ||
167 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL); | ||
168 | pos++; | ||
169 | } | ||
170 | |||
171 | /* IEEE80211_RADIOTAP_DBM_ANTNOISE */ | ||
172 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) { | ||
173 | *pos = status->noise; | ||
174 | rthdr->it_present |= | ||
175 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE); | ||
176 | pos++; | ||
177 | } | ||
178 | |||
179 | /* IEEE80211_RADIOTAP_LOCK_QUALITY is missing */ | ||
180 | |||
181 | /* IEEE80211_RADIOTAP_ANTENNA */ | ||
182 | *pos = status->antenna; | ||
183 | pos++; | ||
184 | |||
185 | /* IEEE80211_RADIOTAP_DB_ANTSIGNAL */ | ||
186 | if (local->hw.flags & IEEE80211_HW_SIGNAL_DB) { | ||
187 | *pos = status->signal; | ||
188 | rthdr->it_present |= | ||
189 | cpu_to_le32(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL); | ||
190 | pos++; | ||
191 | } | ||
192 | |||
193 | /* IEEE80211_RADIOTAP_DB_ANTNOISE is not used */ | ||
194 | |||
195 | /* IEEE80211_RADIOTAP_RX_FLAGS */ | ||
196 | /* ensure 2 byte alignment for the 2 byte field as required */ | ||
197 | if ((pos - (unsigned char *)rthdr) & 1) | ||
198 | pos++; | ||
199 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
200 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
201 | *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
202 | pos += 2; | ||
203 | } | ||
204 | |||
80 | /* | 205 | /* |
81 | * This function copies a received frame to all monitor interfaces and | 206 | * This function copies a received frame to all monitor interfaces and |
82 | * returns a cleaned-up SKB that no longer includes the FCS nor the | 207 | * returns a cleaned-up SKB that no longer includes the FCS nor the |
@@ -89,17 +214,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
89 | { | 214 | { |
90 | struct ieee80211_sub_if_data *sdata; | 215 | struct ieee80211_sub_if_data *sdata; |
91 | int needed_headroom = 0; | 216 | int needed_headroom = 0; |
92 | struct ieee80211_radiotap_header *rthdr; | ||
93 | __le64 *rttsft = NULL; | ||
94 | struct ieee80211_rtap_fixed_data { | ||
95 | u8 flags; | ||
96 | u8 rate; | ||
97 | __le16 chan_freq; | ||
98 | __le16 chan_flags; | ||
99 | u8 antsignal; | ||
100 | u8 padding_for_rxflags; | ||
101 | __le16 rx_flags; | ||
102 | } __attribute__ ((packed)) *rtfixed; | ||
103 | struct sk_buff *skb, *skb2; | 217 | struct sk_buff *skb, *skb2; |
104 | struct net_device *prev_dev = NULL; | 218 | struct net_device *prev_dev = NULL; |
105 | int present_fcs_len = 0; | 219 | int present_fcs_len = 0; |
@@ -116,8 +230,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
116 | if (status->flag & RX_FLAG_RADIOTAP) | 230 | if (status->flag & RX_FLAG_RADIOTAP) |
117 | rtap_len = ieee80211_get_radiotap_len(origskb->data); | 231 | rtap_len = ieee80211_get_radiotap_len(origskb->data); |
118 | else | 232 | else |
119 | /* room for radiotap header, always present fields and TSFT */ | 233 | /* room for the radiotap header based on driver features */ |
120 | needed_headroom = sizeof(*rthdr) + sizeof(*rtfixed) + 8; | 234 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
121 | 235 | ||
122 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | 236 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) |
123 | present_fcs_len = FCS_LEN; | 237 | present_fcs_len = FCS_LEN; |
@@ -163,55 +277,9 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
163 | } | 277 | } |
164 | 278 | ||
165 | /* if necessary, prepend radiotap information */ | 279 | /* if necessary, prepend radiotap information */ |
166 | if (!(status->flag & RX_FLAG_RADIOTAP)) { | 280 | if (!(status->flag & RX_FLAG_RADIOTAP)) |
167 | rtfixed = (void *) skb_push(skb, sizeof(*rtfixed)); | 281 | ieee80211_add_rx_radiotap_header(local, skb, status, rate, |
168 | rtap_len = sizeof(*rthdr) + sizeof(*rtfixed); | 282 | needed_headroom); |
169 | if (status->flag & RX_FLAG_TSFT) { | ||
170 | rttsft = (void *) skb_push(skb, sizeof(*rttsft)); | ||
171 | rtap_len += 8; | ||
172 | } | ||
173 | rthdr = (void *) skb_push(skb, sizeof(*rthdr)); | ||
174 | memset(rthdr, 0, sizeof(*rthdr)); | ||
175 | memset(rtfixed, 0, sizeof(*rtfixed)); | ||
176 | rthdr->it_present = | ||
177 | cpu_to_le32((1 << IEEE80211_RADIOTAP_FLAGS) | | ||
178 | (1 << IEEE80211_RADIOTAP_RATE) | | ||
179 | (1 << IEEE80211_RADIOTAP_CHANNEL) | | ||
180 | (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | | ||
181 | (1 << IEEE80211_RADIOTAP_RX_FLAGS)); | ||
182 | rtfixed->flags = 0; | ||
183 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | ||
184 | rtfixed->flags |= IEEE80211_RADIOTAP_F_FCS; | ||
185 | |||
186 | if (rttsft) { | ||
187 | *rttsft = cpu_to_le64(status->mactime); | ||
188 | rthdr->it_present |= | ||
189 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | ||
190 | } | ||
191 | |||
192 | /* FIXME: when radiotap gets a 'bad PLCP' flag use it here */ | ||
193 | rtfixed->rx_flags = 0; | ||
194 | if (status->flag & | ||
195 | (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | ||
196 | rtfixed->rx_flags |= | ||
197 | cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADFCS); | ||
198 | |||
199 | rtfixed->rate = rate->bitrate / 5; | ||
200 | |||
201 | rtfixed->chan_freq = cpu_to_le16(status->freq); | ||
202 | |||
203 | if (status->band == IEEE80211_BAND_5GHZ) | ||
204 | rtfixed->chan_flags = | ||
205 | cpu_to_le16(IEEE80211_CHAN_OFDM | | ||
206 | IEEE80211_CHAN_5GHZ); | ||
207 | else | ||
208 | rtfixed->chan_flags = | ||
209 | cpu_to_le16(IEEE80211_CHAN_DYN | | ||
210 | IEEE80211_CHAN_2GHZ); | ||
211 | |||
212 | rtfixed->antsignal = status->ssi; | ||
213 | rthdr->it_len = cpu_to_le16(rtap_len); | ||
214 | } | ||
215 | 283 | ||
216 | skb_reset_mac_header(skb); | 284 | skb_reset_mac_header(skb); |
217 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 285 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -275,11 +343,6 @@ static void ieee80211_parse_qos(struct ieee80211_rx_data *rx) | |||
275 | } | 343 | } |
276 | } | 344 | } |
277 | 345 | ||
278 | I802_DEBUG_INC(rx->local->wme_rx_queue[tid]); | ||
279 | /* only a debug counter, sta might not be assigned properly yet */ | ||
280 | if (rx->sta) | ||
281 | I802_DEBUG_INC(rx->sta->wme_rx_queue[tid]); | ||
282 | |||
283 | rx->queue = tid; | 346 | rx->queue = tid; |
284 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. | 347 | /* Set skb->priority to 1d tag if highest order bit of TID is not set. |
285 | * For now, set skb->priority to 0 for other cases. */ | 348 | * For now, set skb->priority to 0 for other cases. */ |
@@ -321,51 +384,9 @@ static void ieee80211_verify_ip_alignment(struct ieee80211_rx_data *rx) | |||
321 | } | 384 | } |
322 | 385 | ||
323 | 386 | ||
324 | static u32 ieee80211_rx_load_stats(struct ieee80211_local *local, | ||
325 | struct sk_buff *skb, | ||
326 | struct ieee80211_rx_status *status, | ||
327 | struct ieee80211_rate *rate) | ||
328 | { | ||
329 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
330 | u32 load = 0, hdrtime; | ||
331 | |||
332 | /* Estimate total channel use caused by this frame */ | ||
333 | |||
334 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | ||
335 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | ||
336 | |||
337 | if (status->band == IEEE80211_BAND_5GHZ || | ||
338 | (status->band == IEEE80211_BAND_5GHZ && | ||
339 | rate->flags & IEEE80211_RATE_ERP_G)) | ||
340 | hdrtime = CHAN_UTIL_HDR_SHORT; | ||
341 | else | ||
342 | hdrtime = CHAN_UTIL_HDR_LONG; | ||
343 | |||
344 | load = hdrtime; | ||
345 | if (!is_multicast_ether_addr(hdr->addr1)) | ||
346 | load += hdrtime; | ||
347 | |||
348 | /* TODO: optimise again */ | ||
349 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | ||
350 | |||
351 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | ||
352 | load >>= CHAN_UTIL_SHIFT; | ||
353 | |||
354 | return load; | ||
355 | } | ||
356 | |||
357 | /* rx handlers */ | 387 | /* rx handlers */ |
358 | 388 | ||
359 | static ieee80211_rx_result | 389 | static ieee80211_rx_result debug_noinline |
360 | ieee80211_rx_h_if_stats(struct ieee80211_rx_data *rx) | ||
361 | { | ||
362 | if (rx->sta) | ||
363 | rx->sta->channel_use_raw += rx->load; | ||
364 | rx->sdata->channel_use_raw += rx->load; | ||
365 | return RX_CONTINUE; | ||
366 | } | ||
367 | |||
368 | static ieee80211_rx_result | ||
369 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | 390 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) |
370 | { | 391 | { |
371 | struct ieee80211_local *local = rx->local; | 392 | struct ieee80211_local *local = rx->local; |
@@ -442,7 +463,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx) | |||
442 | } | 463 | } |
443 | 464 | ||
444 | 465 | ||
445 | static ieee80211_rx_result | 466 | static ieee80211_rx_result debug_noinline |
446 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | 467 | ieee80211_rx_h_check(struct ieee80211_rx_data *rx) |
447 | { | 468 | { |
448 | struct ieee80211_hdr *hdr; | 469 | struct ieee80211_hdr *hdr; |
@@ -484,7 +505,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
484 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && | 505 | ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL && |
485 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && | 506 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL)) && |
486 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && | 507 | rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && |
487 | (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { | 508 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { |
488 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && | 509 | if ((!(rx->fc & IEEE80211_FCTL_FROMDS) && |
489 | !(rx->fc & IEEE80211_FCTL_TODS) && | 510 | !(rx->fc & IEEE80211_FCTL_TODS) && |
490 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) | 511 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) |
@@ -501,7 +522,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
501 | } | 522 | } |
502 | 523 | ||
503 | 524 | ||
504 | static ieee80211_rx_result | 525 | static ieee80211_rx_result debug_noinline |
505 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | 526 | ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) |
506 | { | 527 | { |
507 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
@@ -592,11 +613,6 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx) | |||
592 | rx->key->tx_rx_count++; | 613 | rx->key->tx_rx_count++; |
593 | /* TODO: add threshold stuff again */ | 614 | /* TODO: add threshold stuff again */ |
594 | } else { | 615 | } else { |
595 | #ifdef CONFIG_MAC80211_DEBUG | ||
596 | if (net_ratelimit()) | ||
597 | printk(KERN_DEBUG "%s: RX protected frame," | ||
598 | " but have no key\n", rx->dev->name); | ||
599 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
600 | return RX_DROP_MONITOR; | 616 | return RX_DROP_MONITOR; |
601 | } | 617 | } |
602 | 618 | ||
@@ -635,8 +651,7 @@ static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) | |||
635 | 651 | ||
636 | if (sdata->bss) | 652 | if (sdata->bss) |
637 | atomic_inc(&sdata->bss->num_sta_ps); | 653 | atomic_inc(&sdata->bss->num_sta_ps); |
638 | sta->flags |= WLAN_STA_PS; | 654 | set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); |
639 | sta->flags &= ~WLAN_STA_PSPOLL; | ||
640 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 655 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
641 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", | 656 | printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", |
642 | dev->name, print_mac(mac, sta->addr), sta->aid); | 657 | dev->name, print_mac(mac, sta->addr), sta->aid); |
@@ -649,7 +664,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
649 | struct sk_buff *skb; | 664 | struct sk_buff *skb; |
650 | int sent = 0; | 665 | int sent = 0; |
651 | struct ieee80211_sub_if_data *sdata; | 666 | struct ieee80211_sub_if_data *sdata; |
652 | struct ieee80211_tx_packet_data *pkt_data; | 667 | struct ieee80211_tx_info *info; |
653 | DECLARE_MAC_BUF(mac); | 668 | DECLARE_MAC_BUF(mac); |
654 | 669 | ||
655 | sdata = sta->sdata; | 670 | sdata = sta->sdata; |
@@ -657,7 +672,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
657 | if (sdata->bss) | 672 | if (sdata->bss) |
658 | atomic_dec(&sdata->bss->num_sta_ps); | 673 | atomic_dec(&sdata->bss->num_sta_ps); |
659 | 674 | ||
660 | sta->flags &= ~(WLAN_STA_PS | WLAN_STA_PSPOLL); | 675 | clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); |
661 | 676 | ||
662 | if (!skb_queue_empty(&sta->ps_tx_buf)) | 677 | if (!skb_queue_empty(&sta->ps_tx_buf)) |
663 | sta_info_clear_tim_bit(sta); | 678 | sta_info_clear_tim_bit(sta); |
@@ -669,13 +684,13 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
669 | 684 | ||
670 | /* Send all buffered frames to the station */ | 685 | /* Send all buffered frames to the station */ |
671 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { | 686 | while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { |
672 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 687 | info = IEEE80211_SKB_CB(skb); |
673 | sent++; | 688 | sent++; |
674 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | 689 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
675 | dev_queue_xmit(skb); | 690 | dev_queue_xmit(skb); |
676 | } | 691 | } |
677 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { | 692 | while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { |
678 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 693 | info = IEEE80211_SKB_CB(skb); |
679 | local->total_ps_buffered--; | 694 | local->total_ps_buffered--; |
680 | sent++; | 695 | sent++; |
681 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 696 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
@@ -683,14 +698,14 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) | |||
683 | "since STA not sleeping anymore\n", dev->name, | 698 | "since STA not sleeping anymore\n", dev->name, |
684 | print_mac(mac, sta->addr), sta->aid); | 699 | print_mac(mac, sta->addr), sta->aid); |
685 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 700 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
686 | pkt_data->flags |= IEEE80211_TXPD_REQUEUE; | 701 | info->flags |= IEEE80211_TX_CTL_REQUEUE; |
687 | dev_queue_xmit(skb); | 702 | dev_queue_xmit(skb); |
688 | } | 703 | } |
689 | 704 | ||
690 | return sent; | 705 | return sent; |
691 | } | 706 | } |
692 | 707 | ||
693 | static ieee80211_rx_result | 708 | static ieee80211_rx_result debug_noinline |
694 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | 709 | ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) |
695 | { | 710 | { |
696 | struct sta_info *sta = rx->sta; | 711 | struct sta_info *sta = rx->sta; |
@@ -725,16 +740,17 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
725 | 740 | ||
726 | sta->rx_fragments++; | 741 | sta->rx_fragments++; |
727 | sta->rx_bytes += rx->skb->len; | 742 | sta->rx_bytes += rx->skb->len; |
728 | sta->last_rssi = rx->status->ssi; | ||
729 | sta->last_signal = rx->status->signal; | 743 | sta->last_signal = rx->status->signal; |
744 | sta->last_qual = rx->status->qual; | ||
730 | sta->last_noise = rx->status->noise; | 745 | sta->last_noise = rx->status->noise; |
731 | 746 | ||
732 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { | 747 | if (!(rx->fc & IEEE80211_FCTL_MOREFRAGS)) { |
733 | /* Change STA power saving mode only in the end of a frame | 748 | /* Change STA power saving mode only in the end of a frame |
734 | * exchange sequence */ | 749 | * exchange sequence */ |
735 | if ((sta->flags & WLAN_STA_PS) && !(rx->fc & IEEE80211_FCTL_PM)) | 750 | if (test_sta_flags(sta, WLAN_STA_PS) && |
751 | !(rx->fc & IEEE80211_FCTL_PM)) | ||
736 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); | 752 | rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); |
737 | else if (!(sta->flags & WLAN_STA_PS) && | 753 | else if (!test_sta_flags(sta, WLAN_STA_PS) && |
738 | (rx->fc & IEEE80211_FCTL_PM)) | 754 | (rx->fc & IEEE80211_FCTL_PM)) |
739 | ap_sta_ps_start(dev, sta); | 755 | ap_sta_ps_start(dev, sta); |
740 | } | 756 | } |
@@ -768,7 +784,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
768 | sdata->fragment_next = 0; | 784 | sdata->fragment_next = 0; |
769 | 785 | ||
770 | if (!skb_queue_empty(&entry->skb_list)) { | 786 | if (!skb_queue_empty(&entry->skb_list)) { |
771 | #ifdef CONFIG_MAC80211_DEBUG | 787 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
772 | struct ieee80211_hdr *hdr = | 788 | struct ieee80211_hdr *hdr = |
773 | (struct ieee80211_hdr *) entry->skb_list.next->data; | 789 | (struct ieee80211_hdr *) entry->skb_list.next->data; |
774 | DECLARE_MAC_BUF(mac); | 790 | DECLARE_MAC_BUF(mac); |
@@ -780,7 +796,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
780 | jiffies - entry->first_frag_time, entry->seq, | 796 | jiffies - entry->first_frag_time, entry->seq, |
781 | entry->last_frag, print_mac(mac, hdr->addr1), | 797 | entry->last_frag, print_mac(mac, hdr->addr1), |
782 | print_mac(mac2, hdr->addr2)); | 798 | print_mac(mac2, hdr->addr2)); |
783 | #endif /* CONFIG_MAC80211_DEBUG */ | 799 | #endif |
784 | __skb_queue_purge(&entry->skb_list); | 800 | __skb_queue_purge(&entry->skb_list); |
785 | } | 801 | } |
786 | 802 | ||
@@ -837,7 +853,7 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, | |||
837 | return NULL; | 853 | return NULL; |
838 | } | 854 | } |
839 | 855 | ||
840 | static ieee80211_rx_result | 856 | static ieee80211_rx_result debug_noinline |
841 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | 857 | ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) |
842 | { | 858 | { |
843 | struct ieee80211_hdr *hdr; | 859 | struct ieee80211_hdr *hdr; |
@@ -901,18 +917,8 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
901 | break; | 917 | break; |
902 | } | 918 | } |
903 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; | 919 | rpn = rx->key->u.ccmp.rx_pn[rx->queue]; |
904 | if (memcmp(pn, rpn, CCMP_PN_LEN) != 0) { | 920 | if (memcmp(pn, rpn, CCMP_PN_LEN)) |
905 | if (net_ratelimit()) | ||
906 | printk(KERN_DEBUG "%s: defrag: CCMP PN not " | ||
907 | "sequential A2=%s" | ||
908 | " PN=%02x%02x%02x%02x%02x%02x " | ||
909 | "(expected %02x%02x%02x%02x%02x%02x)\n", | ||
910 | rx->dev->name, print_mac(mac, hdr->addr2), | ||
911 | rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], | ||
912 | rpn[5], pn[0], pn[1], pn[2], pn[3], | ||
913 | pn[4], pn[5]); | ||
914 | return RX_DROP_UNUSABLE; | 921 | return RX_DROP_UNUSABLE; |
915 | } | ||
916 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); | 922 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); |
917 | } | 923 | } |
918 | 924 | ||
@@ -953,7 +959,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
953 | return RX_CONTINUE; | 959 | return RX_CONTINUE; |
954 | } | 960 | } |
955 | 961 | ||
956 | static ieee80211_rx_result | 962 | static ieee80211_rx_result debug_noinline |
957 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | 963 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) |
958 | { | 964 | { |
959 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 965 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); |
@@ -988,7 +994,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
988 | * Tell TX path to send one frame even though the STA may | 994 | * Tell TX path to send one frame even though the STA may |
989 | * still remain is PS mode after this frame exchange. | 995 | * still remain is PS mode after this frame exchange. |
990 | */ | 996 | */ |
991 | rx->sta->flags |= WLAN_STA_PSPOLL; | 997 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
992 | 998 | ||
993 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 999 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
994 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", | 1000 | printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", |
@@ -1016,7 +1022,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1016 | * have nothing buffered for it? | 1022 | * have nothing buffered for it? |
1017 | */ | 1023 | */ |
1018 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " | 1024 | printk(KERN_DEBUG "%s: STA %s sent PS Poll even " |
1019 | "though there is no buffered frames for it\n", | 1025 | "though there are no buffered frames for it\n", |
1020 | rx->dev->name, print_mac(mac, rx->sta->addr)); | 1026 | rx->dev->name, print_mac(mac, rx->sta->addr)); |
1021 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 1027 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
1022 | } | 1028 | } |
@@ -1028,7 +1034,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1028 | return RX_QUEUED; | 1034 | return RX_QUEUED; |
1029 | } | 1035 | } |
1030 | 1036 | ||
1031 | static ieee80211_rx_result | 1037 | static ieee80211_rx_result debug_noinline |
1032 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | 1038 | ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) |
1033 | { | 1039 | { |
1034 | u16 fc = rx->fc; | 1040 | u16 fc = rx->fc; |
@@ -1051,14 +1057,9 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx) | |||
1051 | static int | 1057 | static int |
1052 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) | 1058 | ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) |
1053 | { | 1059 | { |
1054 | if (unlikely(!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED))) { | 1060 | if (unlikely(!rx->sta || |
1055 | #ifdef CONFIG_MAC80211_DEBUG | 1061 | !test_sta_flags(rx->sta, WLAN_STA_AUTHORIZED))) |
1056 | if (net_ratelimit()) | ||
1057 | printk(KERN_DEBUG "%s: dropped frame " | ||
1058 | "(unauthorized port)\n", rx->dev->name); | ||
1059 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
1060 | return -EACCES; | 1062 | return -EACCES; |
1061 | } | ||
1062 | 1063 | ||
1063 | return 0; | 1064 | return 0; |
1064 | } | 1065 | } |
@@ -1138,16 +1139,8 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1138 | memcpy(src, hdr->addr2, ETH_ALEN); | 1139 | memcpy(src, hdr->addr2, ETH_ALEN); |
1139 | 1140 | ||
1140 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP && | 1141 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP && |
1141 | sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) { | 1142 | sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) |
1142 | if (net_ratelimit()) | ||
1143 | printk(KERN_DEBUG "%s: dropped ToDS frame " | ||
1144 | "(BSSID=%s SA=%s DA=%s)\n", | ||
1145 | dev->name, | ||
1146 | print_mac(mac, hdr->addr1), | ||
1147 | print_mac(mac2, hdr->addr2), | ||
1148 | print_mac(mac3, hdr->addr3)); | ||
1149 | return -1; | 1143 | return -1; |
1150 | } | ||
1151 | break; | 1144 | break; |
1152 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): | 1145 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): |
1153 | /* RA TA DA SA */ | 1146 | /* RA TA DA SA */ |
@@ -1155,17 +1148,8 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1155 | memcpy(src, hdr->addr4, ETH_ALEN); | 1148 | memcpy(src, hdr->addr4, ETH_ALEN); |
1156 | 1149 | ||
1157 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS && | 1150 | if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS && |
1158 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) { | 1151 | sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)) |
1159 | if (net_ratelimit()) | ||
1160 | printk(KERN_DEBUG "%s: dropped FromDS&ToDS " | ||
1161 | "frame (RA=%s TA=%s DA=%s SA=%s)\n", | ||
1162 | rx->dev->name, | ||
1163 | print_mac(mac, hdr->addr1), | ||
1164 | print_mac(mac2, hdr->addr2), | ||
1165 | print_mac(mac3, hdr->addr3), | ||
1166 | print_mac(mac4, hdr->addr4)); | ||
1167 | return -1; | 1152 | return -1; |
1168 | } | ||
1169 | break; | 1153 | break; |
1170 | case IEEE80211_FCTL_FROMDS: | 1154 | case IEEE80211_FCTL_FROMDS: |
1171 | /* DA BSSID SA */ | 1155 | /* DA BSSID SA */ |
@@ -1182,27 +1166,13 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx) | |||
1182 | memcpy(dst, hdr->addr1, ETH_ALEN); | 1166 | memcpy(dst, hdr->addr1, ETH_ALEN); |
1183 | memcpy(src, hdr->addr2, ETH_ALEN); | 1167 | memcpy(src, hdr->addr2, ETH_ALEN); |
1184 | 1168 | ||
1185 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS) { | 1169 | if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS) |
1186 | if (net_ratelimit()) { | ||
1187 | printk(KERN_DEBUG "%s: dropped IBSS frame " | ||
1188 | "(DA=%s SA=%s BSSID=%s)\n", | ||
1189 | dev->name, | ||
1190 | print_mac(mac, hdr->addr1), | ||
1191 | print_mac(mac2, hdr->addr2), | ||
1192 | print_mac(mac3, hdr->addr3)); | ||
1193 | } | ||
1194 | return -1; | 1170 | return -1; |
1195 | } | ||
1196 | break; | 1171 | break; |
1197 | } | 1172 | } |
1198 | 1173 | ||
1199 | if (unlikely(skb->len - hdrlen < 8)) { | 1174 | if (unlikely(skb->len - hdrlen < 8)) |
1200 | if (net_ratelimit()) { | ||
1201 | printk(KERN_DEBUG "%s: RX too short data frame " | ||
1202 | "payload\n", dev->name); | ||
1203 | } | ||
1204 | return -1; | 1175 | return -1; |
1205 | } | ||
1206 | 1176 | ||
1207 | payload = skb->data + hdrlen; | 1177 | payload = skb->data + hdrlen; |
1208 | ethertype = (payload[6] << 8) | payload[7]; | 1178 | ethertype = (payload[6] << 8) | payload[7]; |
@@ -1345,7 +1315,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1345 | } | 1315 | } |
1346 | } | 1316 | } |
1347 | 1317 | ||
1348 | static ieee80211_rx_result | 1318 | static ieee80211_rx_result debug_noinline |
1349 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | 1319 | ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) |
1350 | { | 1320 | { |
1351 | struct net_device *dev = rx->dev; | 1321 | struct net_device *dev = rx->dev; |
@@ -1394,10 +1364,8 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1394 | 1364 | ||
1395 | padding = ((4 - subframe_len) & 0x3); | 1365 | padding = ((4 - subframe_len) & 0x3); |
1396 | /* the last MSDU has no padding */ | 1366 | /* the last MSDU has no padding */ |
1397 | if (subframe_len > remaining) { | 1367 | if (subframe_len > remaining) |
1398 | printk(KERN_DEBUG "%s: wrong buffer size\n", dev->name); | ||
1399 | return RX_DROP_UNUSABLE; | 1368 | return RX_DROP_UNUSABLE; |
1400 | } | ||
1401 | 1369 | ||
1402 | skb_pull(skb, sizeof(struct ethhdr)); | 1370 | skb_pull(skb, sizeof(struct ethhdr)); |
1403 | /* if last subframe reuse skb */ | 1371 | /* if last subframe reuse skb */ |
@@ -1418,8 +1386,6 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1418 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + | 1386 | eth = (struct ethhdr *) skb_pull(skb, ntohs(len) + |
1419 | padding); | 1387 | padding); |
1420 | if (!eth) { | 1388 | if (!eth) { |
1421 | printk(KERN_DEBUG "%s: wrong buffer size\n", | ||
1422 | dev->name); | ||
1423 | dev_kfree_skb(frame); | 1389 | dev_kfree_skb(frame); |
1424 | return RX_DROP_UNUSABLE; | 1390 | return RX_DROP_UNUSABLE; |
1425 | } | 1391 | } |
@@ -1462,7 +1428,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx) | |||
1462 | return RX_QUEUED; | 1428 | return RX_QUEUED; |
1463 | } | 1429 | } |
1464 | 1430 | ||
1465 | static ieee80211_rx_result | 1431 | static ieee80211_rx_result debug_noinline |
1466 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | 1432 | ieee80211_rx_h_data(struct ieee80211_rx_data *rx) |
1467 | { | 1433 | { |
1468 | struct net_device *dev = rx->dev; | 1434 | struct net_device *dev = rx->dev; |
@@ -1493,7 +1459,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
1493 | return RX_QUEUED; | 1459 | return RX_QUEUED; |
1494 | } | 1460 | } |
1495 | 1461 | ||
1496 | static ieee80211_rx_result | 1462 | static ieee80211_rx_result debug_noinline |
1497 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 1463 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
1498 | { | 1464 | { |
1499 | struct ieee80211_local *local = rx->local; | 1465 | struct ieee80211_local *local = rx->local; |
@@ -1537,7 +1503,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
1537 | return RX_CONTINUE; | 1503 | return RX_CONTINUE; |
1538 | } | 1504 | } |
1539 | 1505 | ||
1540 | static ieee80211_rx_result | 1506 | static ieee80211_rx_result debug_noinline |
1541 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | 1507 | ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) |
1542 | { | 1508 | { |
1543 | struct ieee80211_sub_if_data *sdata; | 1509 | struct ieee80211_sub_if_data *sdata; |
@@ -1571,31 +1537,16 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1571 | else | 1537 | else |
1572 | keyidx = -1; | 1538 | keyidx = -1; |
1573 | 1539 | ||
1574 | if (net_ratelimit()) | ||
1575 | printk(KERN_DEBUG "%s: TKIP hwaccel reported Michael MIC " | ||
1576 | "failure from %s to %s keyidx=%d\n", | ||
1577 | dev->name, print_mac(mac, hdr->addr2), | ||
1578 | print_mac(mac2, hdr->addr1), keyidx); | ||
1579 | |||
1580 | if (!rx->sta) { | 1540 | if (!rx->sta) { |
1581 | /* | 1541 | /* |
1582 | * Some hardware seem to generate incorrect Michael MIC | 1542 | * Some hardware seem to generate incorrect Michael MIC |
1583 | * reports; ignore them to avoid triggering countermeasures. | 1543 | * reports; ignore them to avoid triggering countermeasures. |
1584 | */ | 1544 | */ |
1585 | if (net_ratelimit()) | ||
1586 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
1587 | "error for unknown address %s\n", | ||
1588 | dev->name, print_mac(mac, hdr->addr2)); | ||
1589 | goto ignore; | 1545 | goto ignore; |
1590 | } | 1546 | } |
1591 | 1547 | ||
1592 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) { | 1548 | if (!(rx->fc & IEEE80211_FCTL_PROTECTED)) |
1593 | if (net_ratelimit()) | ||
1594 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
1595 | "error for a frame with no PROTECTED flag (src " | ||
1596 | "%s)\n", dev->name, print_mac(mac, hdr->addr2)); | ||
1597 | goto ignore; | 1549 | goto ignore; |
1598 | } | ||
1599 | 1550 | ||
1600 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { | 1551 | if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { |
1601 | /* | 1552 | /* |
@@ -1604,24 +1555,13 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev, | |||
1604 | * group keys and only the AP is sending real multicast | 1555 | * group keys and only the AP is sending real multicast |
1605 | * frames in the BSS. | 1556 | * frames in the BSS. |
1606 | */ | 1557 | */ |
1607 | if (net_ratelimit()) | ||
1608 | printk(KERN_DEBUG "%s: ignored Michael MIC error for " | ||
1609 | "a frame with non-zero keyidx (%d)" | ||
1610 | " (src %s)\n", dev->name, keyidx, | ||
1611 | print_mac(mac, hdr->addr2)); | ||
1612 | goto ignore; | 1558 | goto ignore; |
1613 | } | 1559 | } |
1614 | 1560 | ||
1615 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && | 1561 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && |
1616 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || | 1562 | ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || |
1617 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) { | 1563 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) |
1618 | if (net_ratelimit()) | ||
1619 | printk(KERN_DEBUG "%s: ignored spurious Michael MIC " | ||
1620 | "error for a frame that cannot be encrypted " | ||
1621 | "(fc=0x%04x) (src %s)\n", | ||
1622 | dev->name, rx->fc, print_mac(mac, hdr->addr2)); | ||
1623 | goto ignore; | 1564 | goto ignore; |
1624 | } | ||
1625 | 1565 | ||
1626 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); | 1566 | mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); |
1627 | ignore: | 1567 | ignore: |
@@ -1710,67 +1650,57 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) | |||
1710 | dev_kfree_skb(skb); | 1650 | dev_kfree_skb(skb); |
1711 | } | 1651 | } |
1712 | 1652 | ||
1713 | typedef ieee80211_rx_result (*ieee80211_rx_handler)(struct ieee80211_rx_data *); | ||
1714 | static ieee80211_rx_handler ieee80211_rx_handlers[] = | ||
1715 | { | ||
1716 | ieee80211_rx_h_if_stats, | ||
1717 | ieee80211_rx_h_passive_scan, | ||
1718 | ieee80211_rx_h_check, | ||
1719 | ieee80211_rx_h_decrypt, | ||
1720 | ieee80211_rx_h_sta_process, | ||
1721 | ieee80211_rx_h_defragment, | ||
1722 | ieee80211_rx_h_ps_poll, | ||
1723 | ieee80211_rx_h_michael_mic_verify, | ||
1724 | /* this must be after decryption - so header is counted in MPDU mic | ||
1725 | * must be before pae and data, so QOS_DATA format frames | ||
1726 | * are not passed to user space by these functions | ||
1727 | */ | ||
1728 | ieee80211_rx_h_remove_qos_control, | ||
1729 | ieee80211_rx_h_amsdu, | ||
1730 | ieee80211_rx_h_data, | ||
1731 | ieee80211_rx_h_ctrl, | ||
1732 | ieee80211_rx_h_mgmt, | ||
1733 | NULL | ||
1734 | }; | ||
1735 | 1653 | ||
1736 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, | 1654 | static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata, |
1737 | struct ieee80211_rx_data *rx, | 1655 | struct ieee80211_rx_data *rx, |
1738 | struct sk_buff *skb) | 1656 | struct sk_buff *skb) |
1739 | { | 1657 | { |
1740 | ieee80211_rx_handler *handler; | ||
1741 | ieee80211_rx_result res = RX_DROP_MONITOR; | 1658 | ieee80211_rx_result res = RX_DROP_MONITOR; |
1742 | 1659 | ||
1743 | rx->skb = skb; | 1660 | rx->skb = skb; |
1744 | rx->sdata = sdata; | 1661 | rx->sdata = sdata; |
1745 | rx->dev = sdata->dev; | 1662 | rx->dev = sdata->dev; |
1746 | 1663 | ||
1747 | for (handler = ieee80211_rx_handlers; *handler != NULL; handler++) { | 1664 | #define CALL_RXH(rxh) \ |
1748 | res = (*handler)(rx); | 1665 | res = rxh(rx); \ |
1749 | 1666 | if (res != RX_CONTINUE) \ | |
1750 | switch (res) { | 1667 | goto rxh_done; |
1751 | case RX_CONTINUE: | 1668 | |
1752 | continue; | 1669 | CALL_RXH(ieee80211_rx_h_passive_scan) |
1753 | case RX_DROP_UNUSABLE: | 1670 | CALL_RXH(ieee80211_rx_h_check) |
1754 | case RX_DROP_MONITOR: | 1671 | CALL_RXH(ieee80211_rx_h_decrypt) |
1755 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | 1672 | CALL_RXH(ieee80211_rx_h_sta_process) |
1756 | if (rx->sta) | 1673 | CALL_RXH(ieee80211_rx_h_defragment) |
1757 | rx->sta->rx_dropped++; | 1674 | CALL_RXH(ieee80211_rx_h_ps_poll) |
1758 | break; | 1675 | CALL_RXH(ieee80211_rx_h_michael_mic_verify) |
1759 | case RX_QUEUED: | 1676 | /* must be after MMIC verify so header is counted in MPDU mic */ |
1760 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | 1677 | CALL_RXH(ieee80211_rx_h_remove_qos_control) |
1761 | break; | 1678 | CALL_RXH(ieee80211_rx_h_amsdu) |
1762 | } | 1679 | CALL_RXH(ieee80211_rx_h_data) |
1763 | break; | 1680 | CALL_RXH(ieee80211_rx_h_ctrl) |
1764 | } | 1681 | CALL_RXH(ieee80211_rx_h_mgmt) |
1765 | 1682 | ||
1683 | #undef CALL_RXH | ||
1684 | |||
1685 | rxh_done: | ||
1766 | switch (res) { | 1686 | switch (res) { |
1767 | case RX_CONTINUE: | ||
1768 | case RX_DROP_MONITOR: | 1687 | case RX_DROP_MONITOR: |
1688 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
1689 | if (rx->sta) | ||
1690 | rx->sta->rx_dropped++; | ||
1691 | /* fall through */ | ||
1692 | case RX_CONTINUE: | ||
1769 | ieee80211_rx_cooked_monitor(rx); | 1693 | ieee80211_rx_cooked_monitor(rx); |
1770 | break; | 1694 | break; |
1771 | case RX_DROP_UNUSABLE: | 1695 | case RX_DROP_UNUSABLE: |
1696 | I802_DEBUG_INC(sdata->local->rx_handlers_drop); | ||
1697 | if (rx->sta) | ||
1698 | rx->sta->rx_dropped++; | ||
1772 | dev_kfree_skb(rx->skb); | 1699 | dev_kfree_skb(rx->skb); |
1773 | break; | 1700 | break; |
1701 | case RX_QUEUED: | ||
1702 | I802_DEBUG_INC(sdata->local->rx_handlers_queued); | ||
1703 | break; | ||
1774 | } | 1704 | } |
1775 | } | 1705 | } |
1776 | 1706 | ||
@@ -1802,8 +1732,13 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1802 | if (!bssid) | 1732 | if (!bssid) |
1803 | return 0; | 1733 | return 0; |
1804 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && | 1734 | if ((rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT && |
1805 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) | 1735 | (rx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON) { |
1736 | if (!rx->sta) | ||
1737 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, | ||
1738 | rx->skb, bssid, hdr->addr2, | ||
1739 | BIT(rx->status->rate_idx)); | ||
1806 | return 1; | 1740 | return 1; |
1741 | } | ||
1807 | else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { | 1742 | else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { |
1808 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) | 1743 | if (!(rx->flags & IEEE80211_RX_IN_SCAN)) |
1809 | return 0; | 1744 | return 0; |
@@ -1816,7 +1751,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1816 | rx->flags &= ~IEEE80211_RX_RA_MATCH; | 1751 | rx->flags &= ~IEEE80211_RX_RA_MATCH; |
1817 | } else if (!rx->sta) | 1752 | } else if (!rx->sta) |
1818 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, | 1753 | rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, |
1819 | bssid, hdr->addr2); | 1754 | bssid, hdr->addr2, |
1755 | BIT(rx->status->rate_idx)); | ||
1820 | break; | 1756 | break; |
1821 | case IEEE80211_IF_TYPE_MESH_POINT: | 1757 | case IEEE80211_IF_TYPE_MESH_POINT: |
1822 | if (!multicast && | 1758 | if (!multicast && |
@@ -1872,7 +1808,6 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata, | |||
1872 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 1808 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
1873 | struct sk_buff *skb, | 1809 | struct sk_buff *skb, |
1874 | struct ieee80211_rx_status *status, | 1810 | struct ieee80211_rx_status *status, |
1875 | u32 load, | ||
1876 | struct ieee80211_rate *rate) | 1811 | struct ieee80211_rate *rate) |
1877 | { | 1812 | { |
1878 | struct ieee80211_local *local = hw_to_local(hw); | 1813 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -1891,7 +1826,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
1891 | rx.local = local; | 1826 | rx.local = local; |
1892 | 1827 | ||
1893 | rx.status = status; | 1828 | rx.status = status; |
1894 | rx.load = load; | ||
1895 | rx.rate = rate; | 1829 | rx.rate = rate; |
1896 | rx.fc = le16_to_cpu(hdr->frame_control); | 1830 | rx.fc = le16_to_cpu(hdr->frame_control); |
1897 | type = rx.fc & IEEE80211_FCTL_FTYPE; | 1831 | type = rx.fc & IEEE80211_FCTL_FTYPE; |
@@ -2000,7 +1934,6 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2000 | struct ieee80211_rx_status status; | 1934 | struct ieee80211_rx_status status; |
2001 | u16 head_seq_num, buf_size; | 1935 | u16 head_seq_num, buf_size; |
2002 | int index; | 1936 | int index; |
2003 | u32 pkt_load; | ||
2004 | struct ieee80211_supported_band *sband; | 1937 | struct ieee80211_supported_band *sband; |
2005 | struct ieee80211_rate *rate; | 1938 | struct ieee80211_rate *rate; |
2006 | 1939 | ||
@@ -2035,12 +1968,9 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2035 | sizeof(status)); | 1968 | sizeof(status)); |
2036 | sband = local->hw.wiphy->bands[status.band]; | 1969 | sband = local->hw.wiphy->bands[status.band]; |
2037 | rate = &sband->bitrates[status.rate_idx]; | 1970 | rate = &sband->bitrates[status.rate_idx]; |
2038 | pkt_load = ieee80211_rx_load_stats(local, | ||
2039 | tid_agg_rx->reorder_buf[index], | ||
2040 | &status, rate); | ||
2041 | __ieee80211_rx_handle_packet(hw, | 1971 | __ieee80211_rx_handle_packet(hw, |
2042 | tid_agg_rx->reorder_buf[index], | 1972 | tid_agg_rx->reorder_buf[index], |
2043 | &status, pkt_load, rate); | 1973 | &status, rate); |
2044 | tid_agg_rx->stored_mpdu_num--; | 1974 | tid_agg_rx->stored_mpdu_num--; |
2045 | tid_agg_rx->reorder_buf[index] = NULL; | 1975 | tid_agg_rx->reorder_buf[index] = NULL; |
2046 | } | 1976 | } |
@@ -2082,11 +2012,8 @@ u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
2082 | sizeof(status)); | 2012 | sizeof(status)); |
2083 | sband = local->hw.wiphy->bands[status.band]; | 2013 | sband = local->hw.wiphy->bands[status.band]; |
2084 | rate = &sband->bitrates[status.rate_idx]; | 2014 | rate = &sband->bitrates[status.rate_idx]; |
2085 | pkt_load = ieee80211_rx_load_stats(local, | ||
2086 | tid_agg_rx->reorder_buf[index], | ||
2087 | &status, rate); | ||
2088 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], | 2015 | __ieee80211_rx_handle_packet(hw, tid_agg_rx->reorder_buf[index], |
2089 | &status, pkt_load, rate); | 2016 | &status, rate); |
2090 | tid_agg_rx->stored_mpdu_num--; | 2017 | tid_agg_rx->stored_mpdu_num--; |
2091 | tid_agg_rx->reorder_buf[index] = NULL; | 2018 | tid_agg_rx->reorder_buf[index] = NULL; |
2092 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 2019 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
@@ -2103,24 +2030,21 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2103 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 2030 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
2104 | struct sta_info *sta; | 2031 | struct sta_info *sta; |
2105 | struct tid_ampdu_rx *tid_agg_rx; | 2032 | struct tid_ampdu_rx *tid_agg_rx; |
2106 | u16 fc, sc; | 2033 | u16 sc; |
2107 | u16 mpdu_seq_num; | 2034 | u16 mpdu_seq_num; |
2108 | u8 ret = 0, *qc; | 2035 | u8 ret = 0; |
2109 | int tid; | 2036 | int tid; |
2110 | 2037 | ||
2111 | sta = sta_info_get(local, hdr->addr2); | 2038 | sta = sta_info_get(local, hdr->addr2); |
2112 | if (!sta) | 2039 | if (!sta) |
2113 | return ret; | 2040 | return ret; |
2114 | 2041 | ||
2115 | fc = le16_to_cpu(hdr->frame_control); | ||
2116 | |||
2117 | /* filter the QoS data rx stream according to | 2042 | /* filter the QoS data rx stream according to |
2118 | * STA/TID and check if this STA/TID is on aggregation */ | 2043 | * STA/TID and check if this STA/TID is on aggregation */ |
2119 | if (!WLAN_FC_IS_QOS_DATA(fc)) | 2044 | if (!ieee80211_is_data_qos(hdr->frame_control)) |
2120 | goto end_reorder; | 2045 | goto end_reorder; |
2121 | 2046 | ||
2122 | qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN; | 2047 | tid = *ieee80211_get_qos_ctl(hdr) & QOS_CONTROL_TID_MASK; |
2123 | tid = qc[0] & QOS_CONTROL_TID_MASK; | ||
2124 | 2048 | ||
2125 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) | 2049 | if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL) |
2126 | goto end_reorder; | 2050 | goto end_reorder; |
@@ -2128,7 +2052,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local, | |||
2128 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; | 2052 | tid_agg_rx = sta->ampdu_mlme.tid_rx[tid]; |
2129 | 2053 | ||
2130 | /* null data frames are excluded */ | 2054 | /* null data frames are excluded */ |
2131 | if (unlikely(fc & IEEE80211_STYPE_NULLFUNC)) | 2055 | if (unlikely(ieee80211_is_nullfunc(hdr->frame_control))) |
2132 | goto end_reorder; | 2056 | goto end_reorder; |
2133 | 2057 | ||
2134 | /* new un-ordered ampdu frame - process it */ | 2058 | /* new un-ordered ampdu frame - process it */ |
@@ -2165,7 +2089,6 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2165 | struct ieee80211_rx_status *status) | 2089 | struct ieee80211_rx_status *status) |
2166 | { | 2090 | { |
2167 | struct ieee80211_local *local = hw_to_local(hw); | 2091 | struct ieee80211_local *local = hw_to_local(hw); |
2168 | u32 pkt_load; | ||
2169 | struct ieee80211_rate *rate = NULL; | 2092 | struct ieee80211_rate *rate = NULL; |
2170 | struct ieee80211_supported_band *sband; | 2093 | struct ieee80211_supported_band *sband; |
2171 | 2094 | ||
@@ -2205,11 +2128,8 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, | |||
2205 | return; | 2128 | return; |
2206 | } | 2129 | } |
2207 | 2130 | ||
2208 | pkt_load = ieee80211_rx_load_stats(local, skb, status, rate); | ||
2209 | local->channel_use_raw += pkt_load; | ||
2210 | |||
2211 | if (!ieee80211_rx_reorder_ampdu(local, skb)) | 2131 | if (!ieee80211_rx_reorder_ampdu(local, skb)) |
2212 | __ieee80211_rx_handle_packet(hw, skb, status, pkt_load, rate); | 2132 | __ieee80211_rx_handle_packet(hw, skb, status, rate); |
2213 | 2133 | ||
2214 | rcu_read_unlock(); | 2134 | rcu_read_unlock(); |
2215 | } | 2135 | } |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 7d4fe4a5292..d8a16b7f6a6 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -202,14 +202,12 @@ void sta_info_destroy(struct sta_info *sta) | |||
202 | dev_kfree_skb_any(skb); | 202 | dev_kfree_skb_any(skb); |
203 | 203 | ||
204 | for (i = 0; i < STA_TID_NUM; i++) { | 204 | for (i = 0; i < STA_TID_NUM; i++) { |
205 | spin_lock_bh(&sta->ampdu_mlme.ampdu_rx); | 205 | spin_lock_bh(&sta->lock); |
206 | if (sta->ampdu_mlme.tid_rx[i]) | 206 | if (sta->ampdu_mlme.tid_rx[i]) |
207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); | 207 | del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer); |
208 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx); | ||
209 | spin_lock_bh(&sta->ampdu_mlme.ampdu_tx); | ||
210 | if (sta->ampdu_mlme.tid_tx[i]) | 208 | if (sta->ampdu_mlme.tid_tx[i]) |
211 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); | 209 | del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer); |
212 | spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx); | 210 | spin_unlock_bh(&sta->lock); |
213 | } | 211 | } |
214 | 212 | ||
215 | __sta_info_free(local, sta); | 213 | __sta_info_free(local, sta); |
@@ -236,6 +234,9 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
236 | if (!sta) | 234 | if (!sta) |
237 | return NULL; | 235 | return NULL; |
238 | 236 | ||
237 | spin_lock_init(&sta->lock); | ||
238 | spin_lock_init(&sta->flaglock); | ||
239 | |||
239 | memcpy(sta->addr, addr, ETH_ALEN); | 240 | memcpy(sta->addr, addr, ETH_ALEN); |
240 | sta->local = local; | 241 | sta->local = local; |
241 | sta->sdata = sdata; | 242 | sta->sdata = sdata; |
@@ -249,15 +250,13 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
249 | return NULL; | 250 | return NULL; |
250 | } | 251 | } |
251 | 252 | ||
252 | spin_lock_init(&sta->ampdu_mlme.ampdu_rx); | ||
253 | spin_lock_init(&sta->ampdu_mlme.ampdu_tx); | ||
254 | for (i = 0; i < STA_TID_NUM; i++) { | 253 | for (i = 0; i < STA_TID_NUM; i++) { |
255 | /* timer_to_tid must be initialized with identity mapping to | 254 | /* timer_to_tid must be initialized with identity mapping to |
256 | * enable session_timer's data differentiation. refer to | 255 | * enable session_timer's data differentiation. refer to |
257 | * sta_rx_agg_session_timer_expired for useage */ | 256 | * sta_rx_agg_session_timer_expired for useage */ |
258 | sta->timer_to_tid[i] = i; | 257 | sta->timer_to_tid[i] = i; |
259 | /* tid to tx queue: initialize according to HW (0 is valid) */ | 258 | /* tid to tx queue: initialize according to HW (0 is valid) */ |
260 | sta->tid_to_tx_q[i] = local->hw.queues; | 259 | sta->tid_to_tx_q[i] = ieee80211_num_queues(&local->hw); |
261 | /* rx */ | 260 | /* rx */ |
262 | sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; | 261 | sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE; |
263 | sta->ampdu_mlme.tid_rx[i] = NULL; | 262 | sta->ampdu_mlme.tid_rx[i] = NULL; |
@@ -276,7 +275,6 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
276 | 275 | ||
277 | #ifdef CONFIG_MAC80211_MESH | 276 | #ifdef CONFIG_MAC80211_MESH |
278 | sta->plink_state = PLINK_LISTEN; | 277 | sta->plink_state = PLINK_LISTEN; |
279 | spin_lock_init(&sta->plink_lock); | ||
280 | init_timer(&sta->plink_timer); | 278 | init_timer(&sta->plink_timer); |
281 | #endif | 279 | #endif |
282 | 280 | ||
@@ -437,8 +435,7 @@ void __sta_info_unlink(struct sta_info **sta) | |||
437 | 435 | ||
438 | list_del(&(*sta)->list); | 436 | list_del(&(*sta)->list); |
439 | 437 | ||
440 | if ((*sta)->flags & WLAN_STA_PS) { | 438 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { |
441 | (*sta)->flags &= ~WLAN_STA_PS; | ||
442 | if (sdata->bss) | 439 | if (sdata->bss) |
443 | atomic_dec(&sdata->bss->num_sta_ps); | 440 | atomic_dec(&sdata->bss->num_sta_ps); |
444 | __sta_info_clear_tim_bit(sdata->bss, *sta); | 441 | __sta_info_clear_tim_bit(sdata->bss, *sta); |
@@ -515,20 +512,20 @@ static inline int sta_info_buffer_expired(struct ieee80211_local *local, | |||
515 | struct sta_info *sta, | 512 | struct sta_info *sta, |
516 | struct sk_buff *skb) | 513 | struct sk_buff *skb) |
517 | { | 514 | { |
518 | struct ieee80211_tx_packet_data *pkt_data; | 515 | struct ieee80211_tx_info *info; |
519 | int timeout; | 516 | int timeout; |
520 | 517 | ||
521 | if (!skb) | 518 | if (!skb) |
522 | return 0; | 519 | return 0; |
523 | 520 | ||
524 | pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; | 521 | info = IEEE80211_SKB_CB(skb); |
525 | 522 | ||
526 | /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ | 523 | /* Timeout: (2 * listen_interval * beacon_int * 1024 / 1000000) sec */ |
527 | timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / | 524 | timeout = (sta->listen_interval * local->hw.conf.beacon_int * 32 / |
528 | 15625) * HZ; | 525 | 15625) * HZ; |
529 | if (timeout < STA_TX_BUFFER_EXPIRE) | 526 | if (timeout < STA_TX_BUFFER_EXPIRE) |
530 | timeout = STA_TX_BUFFER_EXPIRE; | 527 | timeout = STA_TX_BUFFER_EXPIRE; |
531 | return time_after(jiffies, pkt_data->jiffies + timeout); | 528 | return time_after(jiffies, info->control.jiffies + timeout); |
532 | } | 529 | } |
533 | 530 | ||
534 | 531 | ||
@@ -557,8 +554,10 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, | |||
557 | 554 | ||
558 | sdata = sta->sdata; | 555 | sdata = sta->sdata; |
559 | local->total_ps_buffered--; | 556 | local->total_ps_buffered--; |
557 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
560 | printk(KERN_DEBUG "Buffered frame expired (STA " | 558 | printk(KERN_DEBUG "Buffered frame expired (STA " |
561 | "%s)\n", print_mac(mac, sta->addr)); | 559 | "%s)\n", print_mac(mac, sta->addr)); |
560 | #endif | ||
562 | dev_kfree_skb(skb); | 561 | dev_kfree_skb(skb); |
563 | 562 | ||
564 | if (skb_queue_empty(&sta->ps_tx_buf)) | 563 | if (skb_queue_empty(&sta->ps_tx_buf)) |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index f8c95bc9659..fd228c198e3 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -32,7 +32,7 @@ | |||
32 | * @WLAN_STA_WDS: Station is one of our WDS peers. | 32 | * @WLAN_STA_WDS: Station is one of our WDS peers. |
33 | * @WLAN_STA_PSPOLL: Station has just PS-polled us. | 33 | * @WLAN_STA_PSPOLL: Station has just PS-polled us. |
34 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the | 34 | * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the |
35 | * IEEE80211_TXCTL_CLEAR_PS_FILT control flag) when the next | 35 | * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next |
36 | * frame to this station is transmitted. | 36 | * frame to this station is transmitted. |
37 | */ | 37 | */ |
38 | enum ieee80211_sta_info_flags { | 38 | enum ieee80211_sta_info_flags { |
@@ -129,23 +129,19 @@ enum plink_state { | |||
129 | * | 129 | * |
130 | * @tid_state_rx: TID's state in Rx session state machine. | 130 | * @tid_state_rx: TID's state in Rx session state machine. |
131 | * @tid_rx: aggregation info for Rx per TID | 131 | * @tid_rx: aggregation info for Rx per TID |
132 | * @ampdu_rx: for locking sections in aggregation Rx flow | ||
133 | * @tid_state_tx: TID's state in Tx session state machine. | 132 | * @tid_state_tx: TID's state in Tx session state machine. |
134 | * @tid_tx: aggregation info for Tx per TID | 133 | * @tid_tx: aggregation info for Tx per TID |
135 | * @addba_req_num: number of times addBA request has been sent. | 134 | * @addba_req_num: number of times addBA request has been sent. |
136 | * @ampdu_tx: for locking sectionsi in aggregation Tx flow | ||
137 | * @dialog_token_allocator: dialog token enumerator for each new session; | 135 | * @dialog_token_allocator: dialog token enumerator for each new session; |
138 | */ | 136 | */ |
139 | struct sta_ampdu_mlme { | 137 | struct sta_ampdu_mlme { |
140 | /* rx */ | 138 | /* rx */ |
141 | u8 tid_state_rx[STA_TID_NUM]; | 139 | u8 tid_state_rx[STA_TID_NUM]; |
142 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; | 140 | struct tid_ampdu_rx *tid_rx[STA_TID_NUM]; |
143 | spinlock_t ampdu_rx; | ||
144 | /* tx */ | 141 | /* tx */ |
145 | u8 tid_state_tx[STA_TID_NUM]; | 142 | u8 tid_state_tx[STA_TID_NUM]; |
146 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; | 143 | struct tid_ampdu_tx *tid_tx[STA_TID_NUM]; |
147 | u8 addba_req_num[STA_TID_NUM]; | 144 | u8 addba_req_num[STA_TID_NUM]; |
148 | spinlock_t ampdu_tx; | ||
149 | u8 dialog_token_allocator; | 145 | u8 dialog_token_allocator; |
150 | }; | 146 | }; |
151 | 147 | ||
@@ -168,6 +164,7 @@ struct sta_ampdu_mlme { | |||
168 | * @aid: STA's unique AID (1..2007, 0 = not assigned yet), | 164 | * @aid: STA's unique AID (1..2007, 0 = not assigned yet), |
169 | * only used in AP (and IBSS?) mode | 165 | * only used in AP (and IBSS?) mode |
170 | * @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 | ||
171 | * @ps_tx_buf: buffer of frames to transmit to this station | 168 | * @ps_tx_buf: buffer of frames to transmit to this station |
172 | * when it leaves power saving state | 169 | * when it leaves power saving state |
173 | * @tx_filtered: buffer of frames we already tried to transmit | 170 | * @tx_filtered: buffer of frames we already tried to transmit |
@@ -177,6 +174,8 @@ struct sta_ampdu_mlme { | |||
177 | * @rx_bytes: Number of bytes received from this STA | 174 | * @rx_bytes: Number of bytes received from this STA |
178 | * @supp_rates: Bitmap of supported rates (per band) | 175 | * @supp_rates: Bitmap of supported rates (per band) |
179 | * @ht_info: HT capabilities of this STA | 176 | * @ht_info: HT capabilities of this STA |
177 | * @lock: used for locking all fields that require locking, see comments | ||
178 | * in the header file. | ||
180 | */ | 179 | */ |
181 | struct sta_info { | 180 | struct sta_info { |
182 | /* General information, mostly static */ | 181 | /* General information, mostly static */ |
@@ -187,6 +186,8 @@ struct sta_info { | |||
187 | struct ieee80211_key *key; | 186 | struct ieee80211_key *key; |
188 | struct rate_control_ref *rate_ctrl; | 187 | struct rate_control_ref *rate_ctrl; |
189 | void *rate_ctrl_priv; | 188 | void *rate_ctrl_priv; |
189 | spinlock_t lock; | ||
190 | spinlock_t flaglock; | ||
190 | struct ieee80211_ht_info ht_info; | 191 | struct ieee80211_ht_info ht_info; |
191 | u64 supp_rates[IEEE80211_NUM_BANDS]; | 192 | u64 supp_rates[IEEE80211_NUM_BANDS]; |
192 | u8 addr[ETH_ALEN]; | 193 | u8 addr[ETH_ALEN]; |
@@ -199,7 +200,10 @@ struct sta_info { | |||
199 | */ | 200 | */ |
200 | u8 pin_status; | 201 | u8 pin_status; |
201 | 202 | ||
202 | /* frequently updated information, needs locking? */ | 203 | /* |
204 | * frequently updated, locked with own spinlock (flaglock), | ||
205 | * use the accessors defined below | ||
206 | */ | ||
203 | u32 flags; | 207 | u32 flags; |
204 | 208 | ||
205 | /* | 209 | /* |
@@ -217,8 +221,8 @@ struct sta_info { | |||
217 | * from this STA */ | 221 | * from this STA */ |
218 | unsigned long rx_fragments; /* number of received MPDUs */ | 222 | unsigned long rx_fragments; /* number of received MPDUs */ |
219 | unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ | 223 | unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ |
220 | int last_rssi; /* RSSI of last received frame from this STA */ | ||
221 | int last_signal; /* signal of last received frame from this STA */ | 224 | int last_signal; /* signal of last received frame from this STA */ |
225 | int last_qual; /* qual of last received frame from this STA */ | ||
222 | int last_noise; /* noise of last received frame from this STA */ | 226 | int last_noise; /* noise of last received frame from this STA */ |
223 | /* last received seq/frag number from this STA (per RX queue) */ | 227 | /* last received seq/frag number from this STA (per RX queue) */ |
224 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; | 228 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; |
@@ -246,12 +250,8 @@ struct sta_info { | |||
246 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; | 250 | unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; |
247 | #endif | 251 | #endif |
248 | 252 | ||
249 | /* Debug counters, no locking doesn't matter */ | ||
250 | int channel_use; | ||
251 | int channel_use_raw; | ||
252 | |||
253 | /* | 253 | /* |
254 | * Aggregation information, comes with own locking. | 254 | * Aggregation information, locked with lock. |
255 | */ | 255 | */ |
256 | struct sta_ampdu_mlme ampdu_mlme; | 256 | struct sta_ampdu_mlme ampdu_mlme; |
257 | u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ | 257 | u8 timer_to_tid[STA_TID_NUM]; /* identity mapping to ID timers */ |
@@ -270,9 +270,6 @@ struct sta_info { | |||
270 | enum plink_state plink_state; | 270 | enum plink_state plink_state; |
271 | u32 plink_timeout; | 271 | u32 plink_timeout; |
272 | struct timer_list plink_timer; | 272 | struct timer_list plink_timer; |
273 | spinlock_t plink_lock; /* For peer_state reads / updates and other | ||
274 | updates in the structure. Ensures robust | ||
275 | transitions for the peerlink FSM */ | ||
276 | #endif | 273 | #endif |
277 | 274 | ||
278 | #ifdef CONFIG_MAC80211_DEBUGFS | 275 | #ifdef CONFIG_MAC80211_DEBUGFS |
@@ -299,6 +296,73 @@ static inline enum plink_state sta_plink_state(struct sta_info *sta) | |||
299 | return PLINK_LISTEN; | 296 | return PLINK_LISTEN; |
300 | } | 297 | } |
301 | 298 | ||
299 | static inline void set_sta_flags(struct sta_info *sta, const u32 flags) | ||
300 | { | ||
301 | unsigned long irqfl; | ||
302 | |||
303 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
304 | sta->flags |= flags; | ||
305 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
306 | } | ||
307 | |||
308 | static inline void clear_sta_flags(struct sta_info *sta, const u32 flags) | ||
309 | { | ||
310 | unsigned long irqfl; | ||
311 | |||
312 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
313 | sta->flags &= ~flags; | ||
314 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
315 | } | ||
316 | |||
317 | static inline void set_and_clear_sta_flags(struct sta_info *sta, | ||
318 | const u32 set, const u32 clear) | ||
319 | { | ||
320 | unsigned long irqfl; | ||
321 | |||
322 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
323 | sta->flags |= set; | ||
324 | sta->flags &= ~clear; | ||
325 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
326 | } | ||
327 | |||
328 | static inline u32 test_sta_flags(struct sta_info *sta, const u32 flags) | ||
329 | { | ||
330 | u32 ret; | ||
331 | unsigned long irqfl; | ||
332 | |||
333 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
334 | ret = sta->flags & flags; | ||
335 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
336 | |||
337 | return ret; | ||
338 | } | ||
339 | |||
340 | static inline u32 test_and_clear_sta_flags(struct sta_info *sta, | ||
341 | const u32 flags) | ||
342 | { | ||
343 | u32 ret; | ||
344 | unsigned long irqfl; | ||
345 | |||
346 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
347 | ret = sta->flags & flags; | ||
348 | sta->flags &= ~flags; | ||
349 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
350 | |||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | static inline u32 get_sta_flags(struct sta_info *sta) | ||
355 | { | ||
356 | u32 ret; | ||
357 | unsigned long irqfl; | ||
358 | |||
359 | spin_lock_irqsave(&sta->flaglock, irqfl); | ||
360 | ret = sta->flags; | ||
361 | spin_unlock_irqrestore(&sta->flaglock, irqfl); | ||
362 | |||
363 | return ret; | ||
364 | } | ||
365 | |||
302 | 366 | ||
303 | /* Maximum number of concurrently registered stations */ | 367 | /* Maximum number of concurrently registered stations */ |
304 | #define MAX_STA_COUNT 2007 | 368 | #define MAX_STA_COUNT 2007 |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 09093da24af..995f7af3d25 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -6,25 +6,23 @@ | |||
6 | * it under the terms of the GNU General Public License version 2 as | 6 | * it under the terms of the GNU General Public License version 2 as |
7 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
8 | */ | 8 | */ |
9 | |||
10 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/bitops.h> | ||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <asm/unaligned.h> | ||
13 | 14 | ||
14 | #include <net/mac80211.h> | 15 | #include <net/mac80211.h> |
15 | #include "key.h" | 16 | #include "key.h" |
16 | #include "tkip.h" | 17 | #include "tkip.h" |
17 | #include "wep.h" | 18 | #include "wep.h" |
18 | 19 | ||
19 | |||
20 | /* TKIP key mixing functions */ | ||
21 | |||
22 | |||
23 | #define PHASE1_LOOP_COUNT 8 | 20 | #define PHASE1_LOOP_COUNT 8 |
24 | 21 | ||
25 | 22 | /* | |
26 | /* 2-byte by 2-byte subset of the full AES S-box table; second part of this | 23 | * 2-byte by 2-byte subset of the full AES S-box table; second part of this |
27 | * table is identical to first part but byte-swapped */ | 24 | * table is identical to first part but byte-swapped |
25 | */ | ||
28 | static const u16 tkip_sbox[256] = | 26 | static const u16 tkip_sbox[256] = |
29 | { | 27 | { |
30 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, | 28 | 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, |
@@ -61,84 +59,54 @@ static const u16 tkip_sbox[256] = | |||
61 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, | 59 | 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, |
62 | }; | 60 | }; |
63 | 61 | ||
64 | 62 | static u16 tkipS(u16 val) | |
65 | static inline u16 Mk16(u8 x, u8 y) | ||
66 | { | 63 | { |
67 | return ((u16) x << 8) | (u16) y; | 64 | return tkip_sbox[val & 0xff] ^ swab16(tkip_sbox[val >> 8]); |
68 | } | 65 | } |
69 | 66 | ||
70 | 67 | static u8 *write_tkip_iv(u8 *pos, u16 iv16) | |
71 | static inline u8 Hi8(u16 v) | ||
72 | { | ||
73 | return v >> 8; | ||
74 | } | ||
75 | |||
76 | |||
77 | static inline u8 Lo8(u16 v) | ||
78 | { | ||
79 | return v & 0xff; | ||
80 | } | ||
81 | |||
82 | |||
83 | static inline u16 Hi16(u32 v) | ||
84 | { | ||
85 | return v >> 16; | ||
86 | } | ||
87 | |||
88 | |||
89 | static inline u16 Lo16(u32 v) | ||
90 | { | ||
91 | return v & 0xffff; | ||
92 | } | ||
93 | |||
94 | |||
95 | static inline u16 RotR1(u16 v) | ||
96 | { | ||
97 | return (v >> 1) | ((v & 0x0001) << 15); | ||
98 | } | ||
99 | |||
100 | |||
101 | static inline u16 tkip_S(u16 val) | ||
102 | { | 68 | { |
103 | u16 a = tkip_sbox[Hi8(val)]; | 69 | *pos++ = iv16 >> 8; |
104 | 70 | *pos++ = ((iv16 >> 8) | 0x20) & 0x7f; | |
105 | return tkip_sbox[Lo8(val)] ^ Hi8(a) ^ (Lo8(a) << 8); | 71 | *pos++ = iv16 & 0xFF; |
72 | return pos; | ||
106 | } | 73 | } |
107 | 74 | ||
108 | 75 | /* | |
109 | 76 | * P1K := Phase1(TA, TK, TSC) | |
110 | /* P1K := Phase1(TA, TK, TSC) | ||
111 | * TA = transmitter address (48 bits) | 77 | * TA = transmitter address (48 bits) |
112 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) | 78 | * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) |
113 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) | 79 | * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) |
114 | * P1K: 80 bits | 80 | * P1K: 80 bits |
115 | */ | 81 | */ |
116 | static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, | 82 | static void tkip_mixing_phase1(const u8 *tk, struct tkip_ctx *ctx, |
117 | u16 *p1k) | 83 | const u8 *ta, u32 tsc_IV32) |
118 | { | 84 | { |
119 | int i, j; | 85 | int i, j; |
86 | u16 *p1k = ctx->p1k; | ||
120 | 87 | ||
121 | p1k[0] = Lo16(tsc_IV32); | 88 | p1k[0] = tsc_IV32 & 0xFFFF; |
122 | p1k[1] = Hi16(tsc_IV32); | 89 | p1k[1] = tsc_IV32 >> 16; |
123 | p1k[2] = Mk16(ta[1], ta[0]); | 90 | p1k[2] = get_unaligned_le16(ta + 0); |
124 | p1k[3] = Mk16(ta[3], ta[2]); | 91 | p1k[3] = get_unaligned_le16(ta + 2); |
125 | p1k[4] = Mk16(ta[5], ta[4]); | 92 | p1k[4] = get_unaligned_le16(ta + 4); |
126 | 93 | ||
127 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { | 94 | for (i = 0; i < PHASE1_LOOP_COUNT; i++) { |
128 | j = 2 * (i & 1); | 95 | j = 2 * (i & 1); |
129 | p1k[0] += tkip_S(p1k[4] ^ Mk16(tk[ 1 + j], tk[ 0 + j])); | 96 | p1k[0] += tkipS(p1k[4] ^ get_unaligned_le16(tk + 0 + j)); |
130 | p1k[1] += tkip_S(p1k[0] ^ Mk16(tk[ 5 + j], tk[ 4 + j])); | 97 | p1k[1] += tkipS(p1k[0] ^ get_unaligned_le16(tk + 4 + j)); |
131 | p1k[2] += tkip_S(p1k[1] ^ Mk16(tk[ 9 + j], tk[ 8 + j])); | 98 | p1k[2] += tkipS(p1k[1] ^ get_unaligned_le16(tk + 8 + j)); |
132 | p1k[3] += tkip_S(p1k[2] ^ Mk16(tk[13 + j], tk[12 + j])); | 99 | p1k[3] += tkipS(p1k[2] ^ get_unaligned_le16(tk + 12 + j)); |
133 | p1k[4] += tkip_S(p1k[3] ^ Mk16(tk[ 1 + j], tk[ 0 + j])) + i; | 100 | p1k[4] += tkipS(p1k[3] ^ get_unaligned_le16(tk + 0 + j)) + i; |
134 | } | 101 | } |
102 | ctx->initialized = 1; | ||
135 | } | 103 | } |
136 | 104 | ||
137 | 105 | static void tkip_mixing_phase2(const u8 *tk, struct tkip_ctx *ctx, | |
138 | static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | 106 | u16 tsc_IV16, u8 *rc4key) |
139 | u8 *rc4key) | ||
140 | { | 107 | { |
141 | u16 ppk[6]; | 108 | u16 ppk[6]; |
109 | const u16 *p1k = ctx->p1k; | ||
142 | int i; | 110 | int i; |
143 | 111 | ||
144 | ppk[0] = p1k[0]; | 112 | ppk[0] = p1k[0]; |
@@ -148,70 +116,35 @@ static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, | |||
148 | ppk[4] = p1k[4]; | 116 | ppk[4] = p1k[4]; |
149 | ppk[5] = p1k[4] + tsc_IV16; | 117 | ppk[5] = p1k[4] + tsc_IV16; |
150 | 118 | ||
151 | ppk[0] += tkip_S(ppk[5] ^ Mk16(tk[ 1], tk[ 0])); | 119 | ppk[0] += tkipS(ppk[5] ^ get_unaligned_le16(tk + 0)); |
152 | ppk[1] += tkip_S(ppk[0] ^ Mk16(tk[ 3], tk[ 2])); | 120 | ppk[1] += tkipS(ppk[0] ^ get_unaligned_le16(tk + 2)); |
153 | ppk[2] += tkip_S(ppk[1] ^ Mk16(tk[ 5], tk[ 4])); | 121 | ppk[2] += tkipS(ppk[1] ^ get_unaligned_le16(tk + 4)); |
154 | ppk[3] += tkip_S(ppk[2] ^ Mk16(tk[ 7], tk[ 6])); | 122 | ppk[3] += tkipS(ppk[2] ^ get_unaligned_le16(tk + 6)); |
155 | ppk[4] += tkip_S(ppk[3] ^ Mk16(tk[ 9], tk[ 8])); | 123 | ppk[4] += tkipS(ppk[3] ^ get_unaligned_le16(tk + 8)); |
156 | ppk[5] += tkip_S(ppk[4] ^ Mk16(tk[11], tk[10])); | 124 | ppk[5] += tkipS(ppk[4] ^ get_unaligned_le16(tk + 10)); |
157 | ppk[0] += RotR1(ppk[5] ^ Mk16(tk[13], tk[12])); | 125 | ppk[0] += ror16(ppk[5] ^ get_unaligned_le16(tk + 12), 1); |
158 | ppk[1] += RotR1(ppk[0] ^ Mk16(tk[15], tk[14])); | 126 | ppk[1] += ror16(ppk[0] ^ get_unaligned_le16(tk + 14), 1); |
159 | ppk[2] += RotR1(ppk[1]); | 127 | ppk[2] += ror16(ppk[1], 1); |
160 | ppk[3] += RotR1(ppk[2]); | 128 | ppk[3] += ror16(ppk[2], 1); |
161 | ppk[4] += RotR1(ppk[3]); | 129 | ppk[4] += ror16(ppk[3], 1); |
162 | ppk[5] += RotR1(ppk[4]); | 130 | ppk[5] += ror16(ppk[4], 1); |
163 | 131 | ||
164 | rc4key[0] = Hi8(tsc_IV16); | 132 | rc4key = write_tkip_iv(rc4key, tsc_IV16); |
165 | rc4key[1] = (Hi8(tsc_IV16) | 0x20) & 0x7f; | 133 | *rc4key++ = ((ppk[5] ^ get_unaligned_le16(tk)) >> 1) & 0xFF; |
166 | rc4key[2] = Lo8(tsc_IV16); | 134 | |
167 | rc4key[3] = Lo8((ppk[5] ^ Mk16(tk[1], tk[0])) >> 1); | 135 | for (i = 0; i < 6; i++) |
168 | 136 | put_unaligned_le16(ppk[i], rc4key + 2 * i); | |
169 | for (i = 0; i < 6; i++) { | ||
170 | rc4key[4 + 2 * i] = Lo8(ppk[i]); | ||
171 | rc4key[5 + 2 * i] = Hi8(ppk[i]); | ||
172 | } | ||
173 | } | 137 | } |
174 | 138 | ||
175 | |||
176 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets | 139 | /* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets |
177 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of | 140 | * of the IV. Returns pointer to the octet following IVs (i.e., beginning of |
178 | * the packet payload). */ | 141 | * the packet payload). */ |
179 | u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | 142 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16) |
180 | u8 iv0, u8 iv1, u8 iv2) | ||
181 | { | 143 | { |
182 | *pos++ = iv0; | 144 | pos = write_tkip_iv(pos, iv16); |
183 | *pos++ = iv1; | ||
184 | *pos++ = iv2; | ||
185 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; | 145 | *pos++ = (key->conf.keyidx << 6) | (1 << 5) /* Ext IV */; |
186 | *pos++ = key->u.tkip.iv32 & 0xff; | 146 | put_unaligned_le32(key->u.tkip.tx.iv32, pos); |
187 | *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; | 147 | return pos + 4; |
188 | *pos++ = (key->u.tkip.iv32 >> 16) & 0xff; | ||
189 | *pos++ = (key->u.tkip.iv32 >> 24) & 0xff; | ||
190 | return pos; | ||
191 | } | ||
192 | |||
193 | |||
194 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, | ||
195 | u16 *phase1key) | ||
196 | { | ||
197 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
198 | key->u.tkip.iv32, phase1key); | ||
199 | } | ||
200 | |||
201 | void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, | ||
202 | u8 *rc4key) | ||
203 | { | ||
204 | /* Calculate per-packet key */ | ||
205 | if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) { | ||
206 | /* IV16 wrapped around - perform TKIP phase 1 */ | ||
207 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
208 | key->u.tkip.iv32, key->u.tkip.p1k); | ||
209 | key->u.tkip.tx_initialized = 1; | ||
210 | } | ||
211 | |||
212 | tkip_mixing_phase2(key->u.tkip.p1k, | ||
213 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
214 | key->u.tkip.iv16, rc4key); | ||
215 | } | 148 | } |
216 | 149 | ||
217 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | 150 | void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, |
@@ -220,48 +153,44 @@ void ieee80211_get_tkip_key(struct ieee80211_key_conf *keyconf, | |||
220 | { | 153 | { |
221 | struct ieee80211_key *key = (struct ieee80211_key *) | 154 | struct ieee80211_key *key = (struct ieee80211_key *) |
222 | container_of(keyconf, struct ieee80211_key, conf); | 155 | container_of(keyconf, struct ieee80211_key, conf); |
223 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 156 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
224 | u8 *data = (u8 *) hdr; | 157 | u8 *data; |
225 | u16 fc = le16_to_cpu(hdr->frame_control); | 158 | const u8 *tk; |
226 | int hdr_len = ieee80211_get_hdrlen(fc); | 159 | struct tkip_ctx *ctx; |
227 | u8 *ta = hdr->addr2; | ||
228 | u16 iv16; | 160 | u16 iv16; |
229 | u32 iv32; | 161 | u32 iv32; |
230 | 162 | ||
231 | iv16 = data[hdr_len] << 8; | 163 | data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); |
232 | iv16 += data[hdr_len + 2]; | 164 | iv16 = data[2] | (data[0] << 8); |
233 | iv32 = data[hdr_len + 4] | (data[hdr_len + 5] << 8) | | 165 | iv32 = get_unaligned_le32(&data[4]); |
234 | (data[hdr_len + 6] << 16) | (data[hdr_len + 7] << 24); | 166 | |
167 | tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
168 | ctx = &key->u.tkip.tx; | ||
235 | 169 | ||
236 | #ifdef CONFIG_TKIP_DEBUG | 170 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
237 | 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", |
238 | iv16, iv32); | 172 | iv16, iv32); |
239 | 173 | ||
240 | if (iv32 != key->u.tkip.iv32) { | 174 | if (iv32 != ctx->iv32) { |
241 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", | 175 | printk(KERN_DEBUG "skb: iv32 = 0x%08x key: iv32 = 0x%08x\n", |
242 | iv32, key->u.tkip.iv32); | 176 | iv32, ctx->iv32); |
243 | 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 " |
244 | "fragmented packet\n"); | 178 | "fragmented packet\n"); |
245 | } | 179 | } |
246 | #endif /* CONFIG_TKIP_DEBUG */ | 180 | #endif |
247 | 181 | ||
248 | /* 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 |
249 | * 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 |
250 | * fragmented packets. */ | 184 | * fragmented packets. */ |
251 | if (iv16 == 0 || !key->u.tkip.tx_initialized) { | 185 | if (iv16 == 0 || !ctx->initialized) |
252 | /* IV16 wrapped around - perform TKIP phase 1 */ | 186 | tkip_mixing_phase1(tk, ctx, hdr->addr2, iv32); |
253 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | ||
254 | iv32, key->u.tkip.p1k); | ||
255 | key->u.tkip.tx_initialized = 1; | ||
256 | } | ||
257 | 187 | ||
258 | if (type == IEEE80211_TKIP_P1_KEY) { | 188 | if (type == IEEE80211_TKIP_P1_KEY) { |
259 | memcpy(outkey, key->u.tkip.p1k, sizeof(u16) * 5); | 189 | memcpy(outkey, ctx->p1k, sizeof(u16) * 5); |
260 | return; | 190 | return; |
261 | } | 191 | } |
262 | 192 | ||
263 | tkip_mixing_phase2(key->u.tkip.p1k, | 193 | tkip_mixing_phase2(tk, ctx, iv16, outkey); |
264 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], iv16, outkey); | ||
265 | } | 194 | } |
266 | EXPORT_SYMBOL(ieee80211_get_tkip_key); | 195 | EXPORT_SYMBOL(ieee80211_get_tkip_key); |
267 | 196 | ||
@@ -275,13 +204,19 @@ void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | |||
275 | u8 *pos, size_t payload_len, u8 *ta) | 204 | u8 *pos, size_t payload_len, u8 *ta) |
276 | { | 205 | { |
277 | u8 rc4key[16]; | 206 | u8 rc4key[16]; |
207 | struct tkip_ctx *ctx = &key->u.tkip.tx; | ||
208 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
209 | |||
210 | /* Calculate per-packet key */ | ||
211 | if (ctx->iv16 == 0 || !ctx->initialized) | ||
212 | tkip_mixing_phase1(tk, ctx, ta, ctx->iv32); | ||
213 | |||
214 | tkip_mixing_phase2(tk, ctx, ctx->iv16, rc4key); | ||
278 | 215 | ||
279 | ieee80211_tkip_gen_rc4key(key, ta, rc4key); | 216 | pos = ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
280 | pos = ieee80211_tkip_add_iv(pos, key, rc4key[0], rc4key[1], rc4key[2]); | ||
281 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); | 217 | ieee80211_wep_encrypt_data(tfm, rc4key, 16, pos, payload_len); |
282 | } | 218 | } |
283 | 219 | ||
284 | |||
285 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the | 220 | /* Decrypt packet payload with TKIP using @key. @pos is a pointer to the |
286 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., | 221 | * beginning of the buffer containing IEEE 802.11 header payload, i.e., |
287 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the | 222 | * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the |
@@ -296,15 +231,16 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
296 | u32 iv16; | 231 | u32 iv16; |
297 | u8 rc4key[16], keyid, *pos = payload; | 232 | u8 rc4key[16], keyid, *pos = payload; |
298 | int res; | 233 | int res; |
234 | const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
299 | 235 | ||
300 | if (payload_len < 12) | 236 | if (payload_len < 12) |
301 | return -1; | 237 | return -1; |
302 | 238 | ||
303 | iv16 = (pos[0] << 8) | pos[2]; | 239 | iv16 = (pos[0] << 8) | pos[2]; |
304 | keyid = pos[3]; | 240 | keyid = pos[3]; |
305 | iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); | 241 | iv32 = get_unaligned_le32(pos + 4); |
306 | pos += 8; | 242 | pos += 8; |
307 | #ifdef CONFIG_TKIP_DEBUG | 243 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
308 | { | 244 | { |
309 | int i; | 245 | int i; |
310 | printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); | 246 | printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); |
@@ -314,7 +250,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
314 | printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", | 250 | printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", |
315 | iv16, iv32); | 251 | iv16, iv32); |
316 | } | 252 | } |
317 | #endif /* CONFIG_TKIP_DEBUG */ | 253 | #endif |
318 | 254 | ||
319 | if (!(keyid & (1 << 5))) | 255 | if (!(keyid & (1 << 5))) |
320 | return TKIP_DECRYPT_NO_EXT_IV; | 256 | return TKIP_DECRYPT_NO_EXT_IV; |
@@ -322,50 +258,48 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
322 | if ((keyid >> 6) != key->conf.keyidx) | 258 | if ((keyid >> 6) != key->conf.keyidx) |
323 | return TKIP_DECRYPT_INVALID_KEYIDX; | 259 | return TKIP_DECRYPT_INVALID_KEYIDX; |
324 | 260 | ||
325 | if (key->u.tkip.rx_initialized[queue] && | 261 | if (key->u.tkip.rx[queue].initialized && |
326 | (iv32 < key->u.tkip.iv32_rx[queue] || | 262 | (iv32 < key->u.tkip.rx[queue].iv32 || |
327 | (iv32 == key->u.tkip.iv32_rx[queue] && | 263 | (iv32 == key->u.tkip.rx[queue].iv32 && |
328 | iv16 <= key->u.tkip.iv16_rx[queue]))) { | 264 | iv16 <= key->u.tkip.rx[queue].iv16))) { |
329 | #ifdef CONFIG_TKIP_DEBUG | 265 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
330 | DECLARE_MAC_BUF(mac); | 266 | DECLARE_MAC_BUF(mac); |
331 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " | 267 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " |
332 | "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", | 268 | "%s (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", |
333 | print_mac(mac, ta), | 269 | print_mac(mac, ta), |
334 | iv32, iv16, key->u.tkip.iv32_rx[queue], | 270 | iv32, iv16, key->u.tkip.rx[queue].iv32, |
335 | key->u.tkip.iv16_rx[queue]); | 271 | key->u.tkip.rx[queue].iv16); |
336 | #endif /* CONFIG_TKIP_DEBUG */ | 272 | #endif |
337 | return TKIP_DECRYPT_REPLAY; | 273 | return TKIP_DECRYPT_REPLAY; |
338 | } | 274 | } |
339 | 275 | ||
340 | if (only_iv) { | 276 | if (only_iv) { |
341 | res = TKIP_DECRYPT_OK; | 277 | res = TKIP_DECRYPT_OK; |
342 | key->u.tkip.rx_initialized[queue] = 1; | 278 | key->u.tkip.rx[queue].initialized = 1; |
343 | goto done; | 279 | goto done; |
344 | } | 280 | } |
345 | 281 | ||
346 | if (!key->u.tkip.rx_initialized[queue] || | 282 | if (!key->u.tkip.rx[queue].initialized || |
347 | key->u.tkip.iv32_rx[queue] != iv32) { | 283 | key->u.tkip.rx[queue].iv32 != iv32) { |
348 | key->u.tkip.rx_initialized[queue] = 1; | ||
349 | /* IV16 wrapped around - perform TKIP phase 1 */ | 284 | /* IV16 wrapped around - perform TKIP phase 1 */ |
350 | tkip_mixing_phase1(ta, &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | 285 | tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); |
351 | iv32, key->u.tkip.p1k_rx[queue]); | 286 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
352 | #ifdef CONFIG_TKIP_DEBUG | ||
353 | { | 287 | { |
354 | int i; | 288 | int i; |
289 | u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; | ||
355 | DECLARE_MAC_BUF(mac); | 290 | DECLARE_MAC_BUF(mac); |
356 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s" | 291 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%s" |
357 | " TK=", print_mac(mac, ta)); | 292 | " TK=", print_mac(mac, ta)); |
358 | for (i = 0; i < 16; i++) | 293 | for (i = 0; i < 16; i++) |
359 | printk("%02x ", | 294 | printk("%02x ", |
360 | key->conf.key[ | 295 | key->conf.key[key_offset + i]); |
361 | ALG_TKIP_TEMP_ENCR_KEY + i]); | ||
362 | printk("\n"); | 296 | printk("\n"); |
363 | printk(KERN_DEBUG "TKIP decrypt: P1K="); | 297 | printk(KERN_DEBUG "TKIP decrypt: P1K="); |
364 | for (i = 0; i < 5; i++) | 298 | for (i = 0; i < 5; i++) |
365 | printk("%04x ", key->u.tkip.p1k_rx[queue][i]); | 299 | printk("%04x ", key->u.tkip.rx[queue].p1k[i]); |
366 | printk("\n"); | 300 | printk("\n"); |
367 | } | 301 | } |
368 | #endif /* CONFIG_TKIP_DEBUG */ | 302 | #endif |
369 | if (key->local->ops->update_tkip_key && | 303 | if (key->local->ops->update_tkip_key && |
370 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 304 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
371 | u8 bcast[ETH_ALEN] = | 305 | u8 bcast[ETH_ALEN] = |
@@ -377,14 +311,12 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
377 | 311 | ||
378 | key->local->ops->update_tkip_key( | 312 | key->local->ops->update_tkip_key( |
379 | local_to_hw(key->local), &key->conf, | 313 | local_to_hw(key->local), &key->conf, |
380 | sta_addr, iv32, key->u.tkip.p1k_rx[queue]); | 314 | sta_addr, iv32, key->u.tkip.rx[queue].p1k); |
381 | } | 315 | } |
382 | } | 316 | } |
383 | 317 | ||
384 | tkip_mixing_phase2(key->u.tkip.p1k_rx[queue], | 318 | tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); |
385 | &key->conf.key[ALG_TKIP_TEMP_ENCR_KEY], | 319 | #ifdef CONFIG_MAC80211_TKIP_DEBUG |
386 | iv16, rc4key); | ||
387 | #ifdef CONFIG_TKIP_DEBUG | ||
388 | { | 320 | { |
389 | int i; | 321 | int i; |
390 | printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); | 322 | printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); |
@@ -392,7 +324,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
392 | printk("%02x ", rc4key[i]); | 324 | printk("%02x ", rc4key[i]); |
393 | printk("\n"); | 325 | printk("\n"); |
394 | } | 326 | } |
395 | #endif /* CONFIG_TKIP_DEBUG */ | 327 | #endif |
396 | 328 | ||
397 | 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); |
398 | done: | 330 | done: |
@@ -409,5 +341,3 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm, | |||
409 | 341 | ||
410 | return res; | 342 | return res; |
411 | } | 343 | } |
412 | |||
413 | |||
diff --git a/net/mac80211/tkip.h b/net/mac80211/tkip.h index b7c2ee763d9..d4714383f5f 100644 --- a/net/mac80211/tkip.h +++ b/net/mac80211/tkip.h | |||
@@ -13,12 +13,8 @@ | |||
13 | #include <linux/crypto.h> | 13 | #include <linux/crypto.h> |
14 | #include "key.h" | 14 | #include "key.h" |
15 | 15 | ||
16 | u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, | 16 | u8 *ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, u16 iv16); |
17 | u8 iv0, u8 iv1, u8 iv2); | 17 | |
18 | void ieee80211_tkip_gen_phase1key(struct ieee80211_key *key, u8 *ta, | ||
19 | u16 *phase1key); | ||
20 | void ieee80211_tkip_gen_rc4key(struct ieee80211_key *key, u8 *ta, | ||
21 | u8 *rc4key); | ||
22 | void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, | 18 | void ieee80211_tkip_encrypt_data(struct crypto_blkcipher *tfm, |
23 | struct ieee80211_key *key, | 19 | struct ieee80211_key *key, |
24 | u8 *pos, size_t payload_len, u8 *ta); | 20 | u8 *pos, size_t payload_len, u8 *ta); |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index c80d5899f27..9bd9faac3c3 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 | |||
52 | static void ieee80211_dump_frame(const char *ifname, const char *title, | 52 | static 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,15 +85,16 @@ 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 | ||
90 | static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | 88 | static __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 = tx->rate; | 92 | struct ieee80211_rate *txrate; |
95 | struct ieee80211_local *local = tx->local; | 93 | struct ieee80211_local *local = tx->local; |
96 | struct ieee80211_supported_band *sband; | 94 | struct ieee80211_supported_band *sband; |
97 | 95 | ||
98 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 96 | sband = local->hw.wiphy->bands[tx->channel->band]; |
97 | txrate = &sband->bitrates[tx->rate_idx]; | ||
99 | 98 | ||
100 | erp = 0; | 99 | erp = 0; |
101 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 100 | if (tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
@@ -139,7 +138,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
139 | 138 | ||
140 | /* data/mgmt */ | 139 | /* data/mgmt */ |
141 | if (0 /* FIX: data/mgmt during CFP */) | 140 | if (0 /* FIX: data/mgmt during CFP */) |
142 | return 32768; | 141 | return cpu_to_le16(32768); |
143 | 142 | ||
144 | if (group_addr) /* Group address as the destination - no ACK */ | 143 | if (group_addr) /* Group address as the destination - no ACK */ |
145 | return 0; | 144 | return 0; |
@@ -209,19 +208,7 @@ static u16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, | |||
209 | tx->sdata->bss_conf.use_short_preamble); | 208 | tx->sdata->bss_conf.use_short_preamble); |
210 | } | 209 | } |
211 | 210 | ||
212 | return dur; | 211 | return cpu_to_le16(dur); |
213 | } | ||
214 | |||
215 | static inline int __ieee80211_queue_stopped(const struct ieee80211_local *local, | ||
216 | int queue) | ||
217 | { | ||
218 | return test_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); | ||
219 | } | ||
220 | |||
221 | static inline int __ieee80211_queue_pending(const struct ieee80211_local *local, | ||
222 | int queue) | ||
223 | { | ||
224 | return test_bit(IEEE80211_LINK_STATE_PENDING, &local->state[queue]); | ||
225 | } | 212 | } |
226 | 213 | ||
227 | static int inline is_ieee80211_device(struct net_device *dev, | 214 | static int inline is_ieee80211_device(struct net_device *dev, |
@@ -233,16 +220,16 @@ static int inline is_ieee80211_device(struct net_device *dev, | |||
233 | 220 | ||
234 | /* tx handlers */ | 221 | /* tx handlers */ |
235 | 222 | ||
236 | static ieee80211_tx_result | 223 | static ieee80211_tx_result debug_noinline |
237 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | 224 | ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) |
238 | { | 225 | { |
239 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 226 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
240 | struct sk_buff *skb = tx->skb; | 227 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
241 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
242 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 228 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
229 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
243 | u32 sta_flags; | 230 | u32 sta_flags; |
244 | 231 | ||
245 | if (unlikely(tx->flags & IEEE80211_TX_INJECTED)) | 232 | if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) |
246 | return TX_CONTINUE; | 233 | return TX_CONTINUE; |
247 | 234 | ||
248 | if (unlikely(tx->local->sta_sw_scanning) && | 235 | if (unlikely(tx->local->sta_sw_scanning) && |
@@ -256,7 +243,7 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
256 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) | 243 | if (tx->flags & IEEE80211_TX_PS_BUFFERED) |
257 | return TX_CONTINUE; | 244 | return TX_CONTINUE; |
258 | 245 | ||
259 | sta_flags = tx->sta ? tx->sta->flags : 0; | 246 | sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0; |
260 | 247 | ||
261 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { | 248 | if (likely(tx->flags & IEEE80211_TX_UNICAST)) { |
262 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && | 249 | if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && |
@@ -287,12 +274,12 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
287 | return TX_CONTINUE; | 274 | return TX_CONTINUE; |
288 | } | 275 | } |
289 | 276 | ||
290 | static ieee80211_tx_result | 277 | static ieee80211_tx_result debug_noinline |
291 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) | 278 | ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx) |
292 | { | 279 | { |
293 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 280 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
294 | 281 | ||
295 | if (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)) >= 24) | 282 | if (ieee80211_hdrlen(hdr->frame_control) >= 24) |
296 | ieee80211_include_sequence(tx->sdata, hdr); | 283 | ieee80211_include_sequence(tx->sdata, hdr); |
297 | 284 | ||
298 | return TX_CONTINUE; | 285 | return TX_CONTINUE; |
@@ -340,13 +327,17 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
340 | rcu_read_unlock(); | 327 | rcu_read_unlock(); |
341 | 328 | ||
342 | local->total_ps_buffered = total; | 329 | local->total_ps_buffered = total; |
330 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
343 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", | 331 | printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", |
344 | wiphy_name(local->hw.wiphy), purged); | 332 | wiphy_name(local->hw.wiphy), purged); |
333 | #endif | ||
345 | } | 334 | } |
346 | 335 | ||
347 | static ieee80211_tx_result | 336 | static ieee80211_tx_result |
348 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | 337 | ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) |
349 | { | 338 | { |
339 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
340 | |||
350 | /* | 341 | /* |
351 | * broadcast/multicast frame | 342 | * broadcast/multicast frame |
352 | * | 343 | * |
@@ -369,11 +360,13 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
369 | purge_old_ps_buffers(tx->local); | 360 | purge_old_ps_buffers(tx->local); |
370 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= | 361 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= |
371 | AP_MAX_BC_BUFFER) { | 362 | AP_MAX_BC_BUFFER) { |
363 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
372 | if (net_ratelimit()) { | 364 | if (net_ratelimit()) { |
373 | printk(KERN_DEBUG "%s: BC TX buffer full - " | 365 | printk(KERN_DEBUG "%s: BC TX buffer full - " |
374 | "dropping the oldest frame\n", | 366 | "dropping the oldest frame\n", |
375 | tx->dev->name); | 367 | tx->dev->name); |
376 | } | 368 | } |
369 | #endif | ||
377 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); | 370 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); |
378 | } else | 371 | } else |
379 | tx->local->total_ps_buffered++; | 372 | tx->local->total_ps_buffered++; |
@@ -382,7 +375,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
382 | } | 375 | } |
383 | 376 | ||
384 | /* buffered in hardware */ | 377 | /* buffered in hardware */ |
385 | tx->control->flags |= IEEE80211_TXCTL_SEND_AFTER_DTIM; | 378 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; |
386 | 379 | ||
387 | return TX_CONTINUE; | 380 | return TX_CONTINUE; |
388 | } | 381 | } |
@@ -391,6 +384,8 @@ static ieee80211_tx_result | |||
391 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | 384 | ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) |
392 | { | 385 | { |
393 | struct sta_info *sta = tx->sta; | 386 | struct sta_info *sta = tx->sta; |
387 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
388 | u32 staflags; | ||
394 | DECLARE_MAC_BUF(mac); | 389 | DECLARE_MAC_BUF(mac); |
395 | 390 | ||
396 | if (unlikely(!sta || | 391 | if (unlikely(!sta || |
@@ -398,9 +393,10 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
398 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) | 393 | (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP))) |
399 | return TX_CONTINUE; | 394 | return TX_CONTINUE; |
400 | 395 | ||
401 | if (unlikely((sta->flags & WLAN_STA_PS) && | 396 | staflags = get_sta_flags(sta); |
402 | !(sta->flags & WLAN_STA_PSPOLL))) { | 397 | |
403 | struct ieee80211_tx_packet_data *pkt_data; | 398 | if (unlikely((staflags & WLAN_STA_PS) && |
399 | !(staflags & WLAN_STA_PSPOLL))) { | ||
404 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 400 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
405 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " | 401 | printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " |
406 | "before %d)\n", | 402 | "before %d)\n", |
@@ -411,11 +407,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
411 | purge_old_ps_buffers(tx->local); | 407 | purge_old_ps_buffers(tx->local); |
412 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { | 408 | if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { |
413 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); | 409 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); |
410 | #ifdef MAC80211_VERBOSE_PS_DEBUG | ||
414 | if (net_ratelimit()) { | 411 | if (net_ratelimit()) { |
415 | printk(KERN_DEBUG "%s: STA %s TX " | 412 | printk(KERN_DEBUG "%s: STA %s TX " |
416 | "buffer full - dropping oldest frame\n", | 413 | "buffer full - dropping oldest frame\n", |
417 | tx->dev->name, print_mac(mac, sta->addr)); | 414 | tx->dev->name, print_mac(mac, sta->addr)); |
418 | } | 415 | } |
416 | #endif | ||
419 | dev_kfree_skb(old); | 417 | dev_kfree_skb(old); |
420 | } else | 418 | } else |
421 | tx->local->total_ps_buffered++; | 419 | tx->local->total_ps_buffered++; |
@@ -424,24 +422,23 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
424 | if (skb_queue_empty(&sta->ps_tx_buf)) | 422 | if (skb_queue_empty(&sta->ps_tx_buf)) |
425 | sta_info_set_tim_bit(sta); | 423 | sta_info_set_tim_bit(sta); |
426 | 424 | ||
427 | pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb; | 425 | info->control.jiffies = jiffies; |
428 | pkt_data->jiffies = jiffies; | ||
429 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); | 426 | skb_queue_tail(&sta->ps_tx_buf, tx->skb); |
430 | return TX_QUEUED; | 427 | return TX_QUEUED; |
431 | } | 428 | } |
432 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 429 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
433 | else if (unlikely(sta->flags & WLAN_STA_PS)) { | 430 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { |
434 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " | 431 | printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " |
435 | "set -> send frame\n", tx->dev->name, | 432 | "set -> send frame\n", tx->dev->name, |
436 | print_mac(mac, sta->addr)); | 433 | print_mac(mac, sta->addr)); |
437 | } | 434 | } |
438 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 435 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
439 | sta->flags &= ~WLAN_STA_PSPOLL; | 436 | clear_sta_flags(sta, WLAN_STA_PSPOLL); |
440 | 437 | ||
441 | return TX_CONTINUE; | 438 | return TX_CONTINUE; |
442 | } | 439 | } |
443 | 440 | ||
444 | static ieee80211_tx_result | 441 | static ieee80211_tx_result debug_noinline |
445 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | 442 | ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) |
446 | { | 443 | { |
447 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) | 444 | if (unlikely(tx->flags & IEEE80211_TX_PS_BUFFERED)) |
@@ -453,21 +450,22 @@ ieee80211_tx_h_ps_buf(struct ieee80211_tx_data *tx) | |||
453 | return ieee80211_tx_h_multicast_ps_buf(tx); | 450 | return ieee80211_tx_h_multicast_ps_buf(tx); |
454 | } | 451 | } |
455 | 452 | ||
456 | static ieee80211_tx_result | 453 | static ieee80211_tx_result debug_noinline |
457 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 454 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
458 | { | 455 | { |
459 | struct ieee80211_key *key; | 456 | struct ieee80211_key *key; |
457 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
460 | u16 fc = tx->fc; | 458 | u16 fc = tx->fc; |
461 | 459 | ||
462 | if (unlikely(tx->control->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) | 460 | if (unlikely(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) |
463 | tx->key = NULL; | 461 | tx->key = NULL; |
464 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) | 462 | else if (tx->sta && (key = rcu_dereference(tx->sta->key))) |
465 | tx->key = key; | 463 | tx->key = key; |
466 | else if ((key = rcu_dereference(tx->sdata->default_key))) | 464 | else if ((key = rcu_dereference(tx->sdata->default_key))) |
467 | tx->key = key; | 465 | tx->key = key; |
468 | else if (tx->sdata->drop_unencrypted && | 466 | else if (tx->sdata->drop_unencrypted && |
469 | !(tx->control->flags & IEEE80211_TXCTL_EAPOL_FRAME) && | 467 | !(info->flags & IEEE80211_TX_CTL_EAPOL_FRAME) && |
470 | !(tx->flags & IEEE80211_TX_INJECTED)) { | 468 | !(info->flags & IEEE80211_TX_CTL_INJECTED)) { |
471 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 469 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
472 | return TX_DROP; | 470 | return TX_DROP; |
473 | } else | 471 | } else |
@@ -496,15 +494,154 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
496 | } | 494 | } |
497 | 495 | ||
498 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) | 496 | if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
499 | tx->control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 497 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
500 | 498 | ||
501 | return TX_CONTINUE; | 499 | return TX_CONTINUE; |
502 | } | 500 | } |
503 | 501 | ||
504 | static ieee80211_tx_result | 502 | static ieee80211_tx_result debug_noinline |
503 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | ||
504 | { | ||
505 | struct rate_selection rsel; | ||
506 | struct ieee80211_supported_band *sband; | ||
507 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
508 | |||
509 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | ||
510 | |||
511 | if (likely(tx->rate_idx < 0)) { | ||
512 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); | ||
513 | tx->rate_idx = rsel.rate_idx; | ||
514 | if (unlikely(rsel.probe_idx >= 0)) { | ||
515 | info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
516 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
517 | info->control.alt_retry_rate_idx = tx->rate_idx; | ||
518 | tx->rate_idx = rsel.probe_idx; | ||
519 | } else | ||
520 | info->control.alt_retry_rate_idx = -1; | ||
521 | |||
522 | if (unlikely(tx->rate_idx < 0)) | ||
523 | return TX_DROP; | ||
524 | } else | ||
525 | info->control.alt_retry_rate_idx = -1; | ||
526 | |||
527 | if (tx->sdata->bss_conf.use_cts_prot && | ||
528 | (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { | ||
529 | tx->last_frag_rate_idx = tx->rate_idx; | ||
530 | if (rsel.probe_idx >= 0) | ||
531 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | ||
532 | else | ||
533 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
534 | tx->rate_idx = rsel.nonerp_idx; | ||
535 | info->tx_rate_idx = rsel.nonerp_idx; | ||
536 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | ||
537 | } else { | ||
538 | tx->last_frag_rate_idx = tx->rate_idx; | ||
539 | info->tx_rate_idx = tx->rate_idx; | ||
540 | } | ||
541 | info->tx_rate_idx = tx->rate_idx; | ||
542 | |||
543 | return TX_CONTINUE; | ||
544 | } | ||
545 | |||
546 | static ieee80211_tx_result debug_noinline | ||
547 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
548 | { | ||
549 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | ||
550 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
551 | struct ieee80211_supported_band *sband; | ||
552 | |||
553 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; | ||
554 | |||
555 | if (tx->sta) | ||
556 | info->control.aid = tx->sta->aid; | ||
557 | |||
558 | if (!info->control.retry_limit) { | ||
559 | if (!is_multicast_ether_addr(hdr->addr1)) { | ||
560 | int len = min_t(int, tx->skb->len + FCS_LEN, | ||
561 | tx->local->fragmentation_threshold); | ||
562 | if (len > tx->local->rts_threshold | ||
563 | && tx->local->rts_threshold < | ||
564 | IEEE80211_MAX_RTS_THRESHOLD) { | ||
565 | info->flags |= IEEE80211_TX_CTL_USE_RTS_CTS; | ||
566 | info->flags |= | ||
567 | IEEE80211_TX_CTL_LONG_RETRY_LIMIT; | ||
568 | info->control.retry_limit = | ||
569 | tx->local->long_retry_limit; | ||
570 | } else { | ||
571 | info->control.retry_limit = | ||
572 | tx->local->short_retry_limit; | ||
573 | } | ||
574 | } else { | ||
575 | info->control.retry_limit = 1; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | ||
580 | /* Do not use multiple retry rates when sending fragmented | ||
581 | * frames. | ||
582 | * TODO: The last fragment could still use multiple retry | ||
583 | * rates. */ | ||
584 | info->control.alt_retry_rate_idx = -1; | ||
585 | } | ||
586 | |||
587 | /* Use CTS protection for unicast frames sent using extended rates if | ||
588 | * there are associated non-ERP stations and RTS/CTS is not configured | ||
589 | * for the frame. */ | ||
590 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | ||
591 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_ERP_G) && | ||
592 | (tx->flags & IEEE80211_TX_UNICAST) && | ||
593 | tx->sdata->bss_conf.use_cts_prot && | ||
594 | !(info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)) | ||
595 | info->flags |= IEEE80211_TX_CTL_USE_CTS_PROTECT; | ||
596 | |||
597 | /* Transmit data frames using short preambles if the driver supports | ||
598 | * short preambles at the selected rate and short preambles are | ||
599 | * available on the network at the current point in time. */ | ||
600 | if (ieee80211_is_data(hdr->frame_control) && | ||
601 | (sband->bitrates[tx->rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) && | ||
602 | tx->sdata->bss_conf.use_short_preamble && | ||
603 | (!tx->sta || test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))) { | ||
604 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
605 | } | ||
606 | |||
607 | if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) || | ||
608 | (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)) { | ||
609 | struct ieee80211_rate *rate; | ||
610 | s8 baserate = -1; | ||
611 | int idx; | ||
612 | |||
613 | /* Do not use multiple retry rates when using RTS/CTS */ | ||
614 | info->control.alt_retry_rate_idx = -1; | ||
615 | |||
616 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | ||
617 | rate = &sband->bitrates[tx->rate_idx]; | ||
618 | |||
619 | for (idx = 0; idx < sband->n_bitrates; idx++) { | ||
620 | if (sband->bitrates[idx].bitrate > rate->bitrate) | ||
621 | continue; | ||
622 | if (tx->sdata->basic_rates & BIT(idx) && | ||
623 | (baserate < 0 || | ||
624 | (sband->bitrates[baserate].bitrate | ||
625 | < sband->bitrates[idx].bitrate))) | ||
626 | baserate = idx; | ||
627 | } | ||
628 | |||
629 | if (baserate >= 0) | ||
630 | info->control.rts_cts_rate_idx = baserate; | ||
631 | else | ||
632 | info->control.rts_cts_rate_idx = 0; | ||
633 | } | ||
634 | |||
635 | if (tx->sta) | ||
636 | info->control.aid = tx->sta->aid; | ||
637 | |||
638 | return TX_CONTINUE; | ||
639 | } | ||
640 | |||
641 | static ieee80211_tx_result debug_noinline | ||
505 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | 642 | ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) |
506 | { | 643 | { |
507 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | 644 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
508 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; | 645 | size_t hdrlen, per_fragm, num_fragm, payload_len, left; |
509 | struct sk_buff **frags, *first, *frag; | 646 | struct sk_buff **frags, *first, *frag; |
510 | int i; | 647 | int i; |
@@ -515,9 +652,19 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
515 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) | 652 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) |
516 | return TX_CONTINUE; | 653 | return TX_CONTINUE; |
517 | 654 | ||
655 | /* | ||
656 | * Warn when submitting a fragmented A-MPDU frame and drop it. | ||
657 | * This scenario is handled in __ieee80211_tx_prepare but extra | ||
658 | * caution taken here as fragmented ampdu may cause Tx stop. | ||
659 | */ | ||
660 | if (WARN_ON(tx->flags & IEEE80211_TX_CTL_AMPDU || | ||
661 | skb_get_queue_mapping(tx->skb) >= | ||
662 | ieee80211_num_regular_queues(&tx->local->hw))) | ||
663 | return TX_DROP; | ||
664 | |||
518 | first = tx->skb; | 665 | first = tx->skb; |
519 | 666 | ||
520 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 667 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
521 | payload_len = first->len - hdrlen; | 668 | payload_len = first->len - hdrlen; |
522 | per_fragm = frag_threshold - hdrlen - FCS_LEN; | 669 | per_fragm = frag_threshold - hdrlen - FCS_LEN; |
523 | num_fragm = DIV_ROUND_UP(payload_len, per_fragm); | 670 | num_fragm = DIV_ROUND_UP(payload_len, per_fragm); |
@@ -558,6 +705,8 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
558 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); | 705 | fhdr->seq_ctrl = cpu_to_le16(seq | ((i + 1) & IEEE80211_SCTL_FRAG)); |
559 | copylen = left > per_fragm ? per_fragm : left; | 706 | copylen = left > per_fragm ? per_fragm : left; |
560 | memcpy(skb_put(frag, copylen), pos, copylen); | 707 | memcpy(skb_put(frag, copylen), pos, copylen); |
708 | memcpy(frag->cb, first->cb, sizeof(frag->cb)); | ||
709 | skb_copy_queue_mapping(frag, first); | ||
561 | 710 | ||
562 | pos += copylen; | 711 | pos += copylen; |
563 | left -= copylen; | 712 | left -= copylen; |
@@ -570,7 +719,6 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
570 | return TX_CONTINUE; | 719 | return TX_CONTINUE; |
571 | 720 | ||
572 | fail: | 721 | fail: |
573 | printk(KERN_DEBUG "%s: failed to fragment frame\n", tx->dev->name); | ||
574 | if (frags) { | 722 | if (frags) { |
575 | for (i = 0; i < num_fragm - 1; i++) | 723 | for (i = 0; i < num_fragm - 1; i++) |
576 | if (frags[i]) | 724 | if (frags[i]) |
@@ -581,7 +729,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
581 | return TX_DROP; | 729 | return TX_DROP; |
582 | } | 730 | } |
583 | 731 | ||
584 | static ieee80211_tx_result | 732 | static ieee80211_tx_result debug_noinline |
585 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | 733 | ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) |
586 | { | 734 | { |
587 | if (!tx->key) | 735 | if (!tx->key) |
@@ -601,236 +749,57 @@ ieee80211_tx_h_encrypt(struct ieee80211_tx_data *tx) | |||
601 | return TX_DROP; | 749 | return TX_DROP; |
602 | } | 750 | } |
603 | 751 | ||
604 | static ieee80211_tx_result | 752 | static ieee80211_tx_result debug_noinline |
605 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 753 | ieee80211_tx_h_calculate_duration(struct ieee80211_tx_data *tx) |
606 | { | 754 | { |
607 | struct rate_selection rsel; | 755 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
608 | struct ieee80211_supported_band *sband; | 756 | int next_len, i; |
609 | 757 | int group_addr = is_multicast_ether_addr(hdr->addr1); | |
610 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | ||
611 | |||
612 | if (likely(!tx->rate)) { | ||
613 | rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); | ||
614 | tx->rate = rsel.rate; | ||
615 | if (unlikely(rsel.probe)) { | ||
616 | tx->control->flags |= | ||
617 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | ||
618 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
619 | tx->control->alt_retry_rate = tx->rate; | ||
620 | tx->rate = rsel.probe; | ||
621 | } else | ||
622 | tx->control->alt_retry_rate = NULL; | ||
623 | |||
624 | if (!tx->rate) | ||
625 | return TX_DROP; | ||
626 | } else | ||
627 | tx->control->alt_retry_rate = NULL; | ||
628 | 758 | ||
629 | if (tx->sdata->bss_conf.use_cts_prot && | 759 | if (!(tx->flags & IEEE80211_TX_FRAGMENTED)) { |
630 | (tx->flags & IEEE80211_TX_FRAGMENTED) && rsel.nonerp) { | 760 | hdr->duration_id = ieee80211_duration(tx, group_addr, 0); |
631 | tx->last_frag_rate = tx->rate; | 761 | return TX_CONTINUE; |
632 | if (rsel.probe) | ||
633 | tx->flags &= ~IEEE80211_TX_PROBE_LAST_FRAG; | ||
634 | else | ||
635 | tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; | ||
636 | tx->rate = rsel.nonerp; | ||
637 | tx->control->tx_rate = rsel.nonerp; | ||
638 | tx->control->flags &= ~IEEE80211_TXCTL_RATE_CTRL_PROBE; | ||
639 | } else { | ||
640 | tx->last_frag_rate = tx->rate; | ||
641 | tx->control->tx_rate = tx->rate; | ||
642 | } | 762 | } |
643 | tx->control->tx_rate = tx->rate; | ||
644 | 763 | ||
645 | return TX_CONTINUE; | 764 | hdr->duration_id = ieee80211_duration(tx, group_addr, |
646 | } | 765 | tx->extra_frag[0]->len); |
647 | |||
648 | static ieee80211_tx_result | ||
649 | ieee80211_tx_h_misc(struct ieee80211_tx_data *tx) | ||
650 | { | ||
651 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; | ||
652 | u16 fc = le16_to_cpu(hdr->frame_control); | ||
653 | u16 dur; | ||
654 | struct ieee80211_tx_control *control = tx->control; | ||
655 | 766 | ||
656 | if (!control->retry_limit) { | 767 | for (i = 0; i < tx->num_extra_frag; i++) { |
657 | if (!is_multicast_ether_addr(hdr->addr1)) { | 768 | if (i + 1 < tx->num_extra_frag) { |
658 | if (tx->skb->len + FCS_LEN > tx->local->rts_threshold | 769 | next_len = tx->extra_frag[i + 1]->len; |
659 | && tx->local->rts_threshold < | ||
660 | IEEE80211_MAX_RTS_THRESHOLD) { | ||
661 | control->flags |= | ||
662 | IEEE80211_TXCTL_USE_RTS_CTS; | ||
663 | control->flags |= | ||
664 | IEEE80211_TXCTL_LONG_RETRY_LIMIT; | ||
665 | control->retry_limit = | ||
666 | tx->local->long_retry_limit; | ||
667 | } else { | ||
668 | control->retry_limit = | ||
669 | tx->local->short_retry_limit; | ||
670 | } | ||
671 | } else { | 770 | } else { |
672 | control->retry_limit = 1; | 771 | next_len = 0; |
772 | tx->rate_idx = tx->last_frag_rate_idx; | ||
673 | } | 773 | } |
674 | } | ||
675 | 774 | ||
676 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 775 | hdr = (struct ieee80211_hdr *)tx->extra_frag[i]->data; |
677 | /* Do not use multiple retry rates when sending fragmented | 776 | hdr->duration_id = ieee80211_duration(tx, 0, next_len); |
678 | * frames. | ||
679 | * TODO: The last fragment could still use multiple retry | ||
680 | * rates. */ | ||
681 | control->alt_retry_rate = NULL; | ||
682 | } | ||
683 | |||
684 | /* Use CTS protection for unicast frames sent using extended rates if | ||
685 | * there are associated non-ERP stations and RTS/CTS is not configured | ||
686 | * for the frame. */ | ||
687 | if ((tx->sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) && | ||
688 | (tx->rate->flags & IEEE80211_RATE_ERP_G) && | ||
689 | (tx->flags & IEEE80211_TX_UNICAST) && | ||
690 | tx->sdata->bss_conf.use_cts_prot && | ||
691 | !(control->flags & IEEE80211_TXCTL_USE_RTS_CTS)) | ||
692 | control->flags |= IEEE80211_TXCTL_USE_CTS_PROTECT; | ||
693 | |||
694 | /* Transmit data frames using short preambles if the driver supports | ||
695 | * short preambles at the selected rate and short preambles are | ||
696 | * available on the network at the current point in time. */ | ||
697 | if (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | ||
698 | (tx->rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && | ||
699 | tx->sdata->bss_conf.use_short_preamble && | ||
700 | (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { | ||
701 | tx->control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | ||
702 | } | ||
703 | |||
704 | /* Setup duration field for the first fragment of the frame. Duration | ||
705 | * for remaining fragments will be updated when they are being sent | ||
706 | * to low-level driver in ieee80211_tx(). */ | ||
707 | dur = ieee80211_duration(tx, is_multicast_ether_addr(hdr->addr1), | ||
708 | (tx->flags & IEEE80211_TX_FRAGMENTED) ? | ||
709 | tx->extra_frag[0]->len : 0); | ||
710 | hdr->duration_id = cpu_to_le16(dur); | ||
711 | |||
712 | if ((control->flags & IEEE80211_TXCTL_USE_RTS_CTS) || | ||
713 | (control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT)) { | ||
714 | struct ieee80211_supported_band *sband; | ||
715 | struct ieee80211_rate *rate, *baserate; | ||
716 | int idx; | ||
717 | |||
718 | sband = tx->local->hw.wiphy->bands[ | ||
719 | tx->local->hw.conf.channel->band]; | ||
720 | |||
721 | /* Do not use multiple retry rates when using RTS/CTS */ | ||
722 | control->alt_retry_rate = NULL; | ||
723 | |||
724 | /* Use min(data rate, max base rate) as CTS/RTS rate */ | ||
725 | rate = tx->rate; | ||
726 | baserate = NULL; | ||
727 | |||
728 | for (idx = 0; idx < sband->n_bitrates; idx++) { | ||
729 | if (sband->bitrates[idx].bitrate > rate->bitrate) | ||
730 | continue; | ||
731 | if (tx->sdata->basic_rates & BIT(idx) && | ||
732 | (!baserate || | ||
733 | (baserate->bitrate < sband->bitrates[idx].bitrate))) | ||
734 | baserate = &sband->bitrates[idx]; | ||
735 | } | ||
736 | |||
737 | if (baserate) | ||
738 | control->rts_cts_rate = baserate; | ||
739 | else | ||
740 | control->rts_cts_rate = &sband->bitrates[0]; | ||
741 | } | ||
742 | |||
743 | if (tx->sta) { | ||
744 | control->aid = tx->sta->aid; | ||
745 | tx->sta->tx_packets++; | ||
746 | tx->sta->tx_fragments++; | ||
747 | tx->sta->tx_bytes += tx->skb->len; | ||
748 | if (tx->extra_frag) { | ||
749 | int i; | ||
750 | tx->sta->tx_fragments += tx->num_extra_frag; | ||
751 | for (i = 0; i < tx->num_extra_frag; i++) { | ||
752 | tx->sta->tx_bytes += | ||
753 | tx->extra_frag[i]->len; | ||
754 | } | ||
755 | } | ||
756 | } | 777 | } |
757 | 778 | ||
758 | return TX_CONTINUE; | 779 | return TX_CONTINUE; |
759 | } | 780 | } |
760 | 781 | ||
761 | static ieee80211_tx_result | 782 | static ieee80211_tx_result debug_noinline |
762 | ieee80211_tx_h_load_stats(struct ieee80211_tx_data *tx) | 783 | ieee80211_tx_h_stats(struct ieee80211_tx_data *tx) |
763 | { | 784 | { |
764 | struct ieee80211_local *local = tx->local; | 785 | int i; |
765 | struct sk_buff *skb = tx->skb; | ||
766 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
767 | u32 load = 0, hdrtime; | ||
768 | struct ieee80211_rate *rate = tx->rate; | ||
769 | |||
770 | /* TODO: this could be part of tx_status handling, so that the number | ||
771 | * of retries would be known; TX rate should in that case be stored | ||
772 | * somewhere with the packet */ | ||
773 | |||
774 | /* Estimate total channel use caused by this frame */ | ||
775 | |||
776 | /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, | ||
777 | * 1 usec = 1/8 * (1080 / 10) = 13.5 */ | ||
778 | |||
779 | if (tx->channel->band == IEEE80211_BAND_5GHZ || | ||
780 | (tx->channel->band == IEEE80211_BAND_2GHZ && | ||
781 | rate->flags & IEEE80211_RATE_ERP_G)) | ||
782 | hdrtime = CHAN_UTIL_HDR_SHORT; | ||
783 | else | ||
784 | hdrtime = CHAN_UTIL_HDR_LONG; | ||
785 | |||
786 | load = hdrtime; | ||
787 | if (!is_multicast_ether_addr(hdr->addr1)) | ||
788 | load += hdrtime; | ||
789 | |||
790 | if (tx->control->flags & IEEE80211_TXCTL_USE_RTS_CTS) | ||
791 | load += 2 * hdrtime; | ||
792 | else if (tx->control->flags & IEEE80211_TXCTL_USE_CTS_PROTECT) | ||
793 | load += hdrtime; | ||
794 | 786 | ||
795 | /* TODO: optimise again */ | 787 | if (!tx->sta) |
796 | load += skb->len * CHAN_UTIL_RATE_LCM / rate->bitrate; | 788 | return TX_CONTINUE; |
797 | 789 | ||
790 | tx->sta->tx_packets++; | ||
791 | tx->sta->tx_fragments++; | ||
792 | tx->sta->tx_bytes += tx->skb->len; | ||
798 | if (tx->extra_frag) { | 793 | if (tx->extra_frag) { |
799 | int i; | 794 | tx->sta->tx_fragments += tx->num_extra_frag; |
800 | for (i = 0; i < tx->num_extra_frag; i++) { | 795 | for (i = 0; i < tx->num_extra_frag; i++) |
801 | load += 2 * hdrtime; | 796 | tx->sta->tx_bytes += tx->extra_frag[i]->len; |
802 | load += tx->extra_frag[i]->len * | ||
803 | tx->rate->bitrate; | ||
804 | } | ||
805 | } | 797 | } |
806 | 798 | ||
807 | /* Divide channel_use by 8 to avoid wrapping around the counter */ | ||
808 | load >>= CHAN_UTIL_SHIFT; | ||
809 | local->channel_use_raw += load; | ||
810 | if (tx->sta) | ||
811 | tx->sta->channel_use_raw += load; | ||
812 | tx->sdata->channel_use_raw += load; | ||
813 | |||
814 | return TX_CONTINUE; | 799 | return TX_CONTINUE; |
815 | } | 800 | } |
816 | 801 | ||
817 | 802 | ||
818 | typedef ieee80211_tx_result (*ieee80211_tx_handler)(struct ieee80211_tx_data *); | ||
819 | static ieee80211_tx_handler ieee80211_tx_handlers[] = | ||
820 | { | ||
821 | ieee80211_tx_h_check_assoc, | ||
822 | ieee80211_tx_h_sequence, | ||
823 | ieee80211_tx_h_ps_buf, | ||
824 | ieee80211_tx_h_select_key, | ||
825 | ieee80211_tx_h_michael_mic_add, | ||
826 | ieee80211_tx_h_fragment, | ||
827 | ieee80211_tx_h_encrypt, | ||
828 | ieee80211_tx_h_rate_ctrl, | ||
829 | ieee80211_tx_h_misc, | ||
830 | ieee80211_tx_h_load_stats, | ||
831 | NULL | ||
832 | }; | ||
833 | |||
834 | /* actual transmit path */ | 803 | /* actual transmit path */ |
835 | 804 | ||
836 | /* | 805 | /* |
@@ -854,12 +823,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
854 | (struct ieee80211_radiotap_header *) skb->data; | 823 | (struct ieee80211_radiotap_header *) skb->data; |
855 | struct ieee80211_supported_band *sband; | 824 | struct ieee80211_supported_band *sband; |
856 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); | 825 | int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); |
857 | struct ieee80211_tx_control *control = tx->control; | 826 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
858 | 827 | ||
859 | sband = tx->local->hw.wiphy->bands[tx->local->hw.conf.channel->band]; | 828 | sband = tx->local->hw.wiphy->bands[tx->channel->band]; |
860 | 829 | ||
861 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 830 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
862 | tx->flags |= IEEE80211_TX_INJECTED; | 831 | info->flags |= IEEE80211_TX_CTL_INJECTED; |
863 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 832 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
864 | 833 | ||
865 | /* | 834 | /* |
@@ -896,7 +865,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
896 | r = &sband->bitrates[i]; | 865 | r = &sband->bitrates[i]; |
897 | 866 | ||
898 | if (r->bitrate == target_rate) { | 867 | if (r->bitrate == target_rate) { |
899 | tx->rate = r; | 868 | tx->rate_idx = i; |
900 | break; | 869 | break; |
901 | } | 870 | } |
902 | } | 871 | } |
@@ -907,7 +876,7 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
907 | * radiotap uses 0 for 1st ant, mac80211 is 1 for | 876 | * radiotap uses 0 for 1st ant, mac80211 is 1 for |
908 | * 1st ant | 877 | * 1st ant |
909 | */ | 878 | */ |
910 | control->antenna_sel_tx = (*iterator.this_arg) + 1; | 879 | info->antenna_sel_tx = (*iterator.this_arg) + 1; |
911 | break; | 880 | break; |
912 | 881 | ||
913 | #if 0 | 882 | #if 0 |
@@ -931,8 +900,8 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
931 | skb_trim(skb, skb->len - FCS_LEN); | 900 | skb_trim(skb, skb->len - FCS_LEN); |
932 | } | 901 | } |
933 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) | 902 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) |
934 | control->flags &= | 903 | info->flags &= |
935 | ~IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 904 | ~IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
936 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) | 905 | if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) |
937 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 906 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
938 | break; | 907 | break; |
@@ -967,12 +936,12 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx, | |||
967 | static ieee80211_tx_result | 936 | static ieee80211_tx_result |
968 | __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | 937 | __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, |
969 | struct sk_buff *skb, | 938 | struct sk_buff *skb, |
970 | struct net_device *dev, | 939 | struct net_device *dev) |
971 | struct ieee80211_tx_control *control) | ||
972 | { | 940 | { |
973 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 941 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
974 | struct ieee80211_hdr *hdr; | 942 | struct ieee80211_hdr *hdr; |
975 | struct ieee80211_sub_if_data *sdata; | 943 | struct ieee80211_sub_if_data *sdata; |
944 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
976 | 945 | ||
977 | int hdrlen; | 946 | int hdrlen; |
978 | 947 | ||
@@ -981,7 +950,9 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
981 | tx->dev = dev; /* use original interface */ | 950 | tx->dev = dev; /* use original interface */ |
982 | tx->local = local; | 951 | tx->local = local; |
983 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 952 | tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
984 | tx->control = control; | 953 | tx->channel = local->hw.conf.channel; |
954 | tx->rate_idx = -1; | ||
955 | tx->last_frag_rate_idx = -1; | ||
985 | /* | 956 | /* |
986 | * Set this flag (used below to indicate "automatic fragmentation"), | 957 | * Set this flag (used below to indicate "automatic fragmentation"), |
987 | * it will be cleared/left by radiotap as desired. | 958 | * it will be cleared/left by radiotap as desired. |
@@ -1008,34 +979,33 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1008 | 979 | ||
1009 | if (is_multicast_ether_addr(hdr->addr1)) { | 980 | if (is_multicast_ether_addr(hdr->addr1)) { |
1010 | tx->flags &= ~IEEE80211_TX_UNICAST; | 981 | tx->flags &= ~IEEE80211_TX_UNICAST; |
1011 | control->flags |= IEEE80211_TXCTL_NO_ACK; | 982 | info->flags |= IEEE80211_TX_CTL_NO_ACK; |
1012 | } else { | 983 | } else { |
1013 | tx->flags |= IEEE80211_TX_UNICAST; | 984 | tx->flags |= IEEE80211_TX_UNICAST; |
1014 | control->flags &= ~IEEE80211_TXCTL_NO_ACK; | 985 | info->flags &= ~IEEE80211_TX_CTL_NO_ACK; |
1015 | } | 986 | } |
1016 | 987 | ||
1017 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { | 988 | if (tx->flags & IEEE80211_TX_FRAGMENTED) { |
1018 | if ((tx->flags & IEEE80211_TX_UNICAST) && | 989 | if ((tx->flags & IEEE80211_TX_UNICAST) && |
1019 | skb->len + FCS_LEN > local->fragmentation_threshold && | 990 | skb->len + FCS_LEN > local->fragmentation_threshold && |
1020 | !local->ops->set_frag_threshold) | 991 | !local->ops->set_frag_threshold && |
992 | !(info->flags & IEEE80211_TX_CTL_AMPDU)) | ||
1021 | tx->flags |= IEEE80211_TX_FRAGMENTED; | 993 | tx->flags |= IEEE80211_TX_FRAGMENTED; |
1022 | else | 994 | else |
1023 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; | 995 | tx->flags &= ~IEEE80211_TX_FRAGMENTED; |
1024 | } | 996 | } |
1025 | 997 | ||
1026 | if (!tx->sta) | 998 | if (!tx->sta) |
1027 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 999 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1028 | else if (tx->sta->flags & WLAN_STA_CLEAR_PS_FILT) { | 1000 | else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) |
1029 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1001 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; |
1030 | tx->sta->flags &= ~WLAN_STA_CLEAR_PS_FILT; | ||
1031 | } | ||
1032 | 1002 | ||
1033 | hdrlen = ieee80211_get_hdrlen(tx->fc); | 1003 | hdrlen = ieee80211_get_hdrlen(tx->fc); |
1034 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { | 1004 | if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { |
1035 | u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; | 1005 | u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; |
1036 | tx->ethertype = (pos[0] << 8) | pos[1]; | 1006 | tx->ethertype = (pos[0] << 8) | pos[1]; |
1037 | } | 1007 | } |
1038 | control->flags |= IEEE80211_TXCTL_FIRST_FRAGMENT; | 1008 | info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT; |
1039 | 1009 | ||
1040 | return TX_CONTINUE; | 1010 | return TX_CONTINUE; |
1041 | } | 1011 | } |
@@ -1045,14 +1015,12 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1045 | */ | 1015 | */ |
1046 | static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | 1016 | static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, |
1047 | struct sk_buff *skb, | 1017 | struct sk_buff *skb, |
1048 | struct net_device *mdev, | 1018 | struct net_device *mdev) |
1049 | struct ieee80211_tx_control *control) | ||
1050 | { | 1019 | { |
1051 | struct ieee80211_tx_packet_data *pkt_data; | 1020 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1052 | struct net_device *dev; | 1021 | struct net_device *dev; |
1053 | 1022 | ||
1054 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1023 | dev = dev_get_by_index(&init_net, info->control.ifindex); |
1055 | dev = dev_get_by_index(&init_net, pkt_data->ifindex); | ||
1056 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { | 1024 | if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { |
1057 | dev_put(dev); | 1025 | dev_put(dev); |
1058 | dev = NULL; | 1026 | dev = NULL; |
@@ -1060,7 +1028,7 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1060 | if (unlikely(!dev)) | 1028 | if (unlikely(!dev)) |
1061 | return -ENODEV; | 1029 | return -ENODEV; |
1062 | /* initialises tx with control */ | 1030 | /* initialises tx with control */ |
1063 | __ieee80211_tx_prepare(tx, skb, dev, control); | 1031 | __ieee80211_tx_prepare(tx, skb, dev); |
1064 | dev_put(dev); | 1032 | dev_put(dev); |
1065 | return 0; | 1033 | return 0; |
1066 | } | 1034 | } |
@@ -1068,50 +1036,49 @@ static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, | |||
1068 | static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | 1036 | static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, |
1069 | struct ieee80211_tx_data *tx) | 1037 | struct ieee80211_tx_data *tx) |
1070 | { | 1038 | { |
1071 | struct ieee80211_tx_control *control = tx->control; | 1039 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1072 | int ret, i; | 1040 | int ret, i; |
1073 | 1041 | ||
1074 | if (!ieee80211_qdisc_installed(local->mdev) && | 1042 | if (netif_subqueue_stopped(local->mdev, skb)) |
1075 | __ieee80211_queue_stopped(local, 0)) { | ||
1076 | netif_stop_queue(local->mdev); | ||
1077 | return IEEE80211_TX_AGAIN; | 1043 | return IEEE80211_TX_AGAIN; |
1078 | } | 1044 | |
1079 | if (skb) { | 1045 | if (skb) { |
1080 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), | 1046 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), |
1081 | "TX to low-level driver", skb); | 1047 | "TX to low-level driver", skb); |
1082 | ret = local->ops->tx(local_to_hw(local), skb, control); | 1048 | ret = local->ops->tx(local_to_hw(local), skb); |
1083 | if (ret) | 1049 | if (ret) |
1084 | return IEEE80211_TX_AGAIN; | 1050 | return IEEE80211_TX_AGAIN; |
1085 | local->mdev->trans_start = jiffies; | 1051 | local->mdev->trans_start = jiffies; |
1086 | ieee80211_led_tx(local, 1); | 1052 | ieee80211_led_tx(local, 1); |
1087 | } | 1053 | } |
1088 | if (tx->extra_frag) { | 1054 | if (tx->extra_frag) { |
1089 | control->flags &= ~(IEEE80211_TXCTL_USE_RTS_CTS | | ||
1090 | IEEE80211_TXCTL_USE_CTS_PROTECT | | ||
1091 | IEEE80211_TXCTL_CLEAR_PS_FILT | | ||
1092 | IEEE80211_TXCTL_FIRST_FRAGMENT); | ||
1093 | for (i = 0; i < tx->num_extra_frag; i++) { | 1055 | for (i = 0; i < tx->num_extra_frag; i++) { |
1094 | if (!tx->extra_frag[i]) | 1056 | if (!tx->extra_frag[i]) |
1095 | continue; | 1057 | continue; |
1096 | if (__ieee80211_queue_stopped(local, control->queue)) | 1058 | info = IEEE80211_SKB_CB(tx->extra_frag[i]); |
1059 | info->flags &= ~(IEEE80211_TX_CTL_USE_RTS_CTS | | ||
1060 | IEEE80211_TX_CTL_USE_CTS_PROTECT | | ||
1061 | IEEE80211_TX_CTL_CLEAR_PS_FILT | | ||
1062 | IEEE80211_TX_CTL_FIRST_FRAGMENT); | ||
1063 | if (netif_subqueue_stopped(local->mdev, | ||
1064 | tx->extra_frag[i])) | ||
1097 | return IEEE80211_TX_FRAG_AGAIN; | 1065 | return IEEE80211_TX_FRAG_AGAIN; |
1098 | if (i == tx->num_extra_frag) { | 1066 | if (i == tx->num_extra_frag) { |
1099 | control->tx_rate = tx->last_frag_rate; | 1067 | info->tx_rate_idx = tx->last_frag_rate_idx; |
1100 | 1068 | ||
1101 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) | 1069 | if (tx->flags & IEEE80211_TX_PROBE_LAST_FRAG) |
1102 | control->flags |= | 1070 | info->flags |= |
1103 | IEEE80211_TXCTL_RATE_CTRL_PROBE; | 1071 | IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
1104 | else | 1072 | else |
1105 | control->flags &= | 1073 | info->flags &= |
1106 | ~IEEE80211_TXCTL_RATE_CTRL_PROBE; | 1074 | ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
1107 | } | 1075 | } |
1108 | 1076 | ||
1109 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), | 1077 | ieee80211_dump_frame(wiphy_name(local->hw.wiphy), |
1110 | "TX to low-level driver", | 1078 | "TX to low-level driver", |
1111 | tx->extra_frag[i]); | 1079 | tx->extra_frag[i]); |
1112 | ret = local->ops->tx(local_to_hw(local), | 1080 | ret = local->ops->tx(local_to_hw(local), |
1113 | tx->extra_frag[i], | 1081 | tx->extra_frag[i]); |
1114 | control); | ||
1115 | if (ret) | 1082 | if (ret) |
1116 | return IEEE80211_TX_FRAG_AGAIN; | 1083 | return IEEE80211_TX_FRAG_AGAIN; |
1117 | local->mdev->trans_start = jiffies; | 1084 | local->mdev->trans_start = jiffies; |
@@ -1124,17 +1091,65 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb, | |||
1124 | return IEEE80211_TX_OK; | 1091 | return IEEE80211_TX_OK; |
1125 | } | 1092 | } |
1126 | 1093 | ||
1127 | static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | 1094 | /* |
1128 | struct ieee80211_tx_control *control) | 1095 | * Invoke TX handlers, return 0 on success and non-zero if the |
1096 | * frame was dropped or queued. | ||
1097 | */ | ||
1098 | static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | ||
1099 | { | ||
1100 | struct sk_buff *skb = tx->skb; | ||
1101 | ieee80211_tx_result res = TX_DROP; | ||
1102 | int i; | ||
1103 | |||
1104 | #define CALL_TXH(txh) \ | ||
1105 | res = txh(tx); \ | ||
1106 | if (res != TX_CONTINUE) \ | ||
1107 | goto txh_done; | ||
1108 | |||
1109 | CALL_TXH(ieee80211_tx_h_check_assoc) | ||
1110 | CALL_TXH(ieee80211_tx_h_sequence) | ||
1111 | CALL_TXH(ieee80211_tx_h_ps_buf) | ||
1112 | CALL_TXH(ieee80211_tx_h_select_key) | ||
1113 | CALL_TXH(ieee80211_tx_h_michael_mic_add) | ||
1114 | CALL_TXH(ieee80211_tx_h_rate_ctrl) | ||
1115 | CALL_TXH(ieee80211_tx_h_misc) | ||
1116 | CALL_TXH(ieee80211_tx_h_fragment) | ||
1117 | /* handlers after fragment must be aware of tx info fragmentation! */ | ||
1118 | CALL_TXH(ieee80211_tx_h_encrypt) | ||
1119 | CALL_TXH(ieee80211_tx_h_calculate_duration) | ||
1120 | CALL_TXH(ieee80211_tx_h_stats) | ||
1121 | #undef CALL_TXH | ||
1122 | |||
1123 | txh_done: | ||
1124 | if (unlikely(res == TX_DROP)) { | ||
1125 | I802_DEBUG_INC(tx->local->tx_handlers_drop); | ||
1126 | dev_kfree_skb(skb); | ||
1127 | for (i = 0; i < tx->num_extra_frag; i++) | ||
1128 | if (tx->extra_frag[i]) | ||
1129 | dev_kfree_skb(tx->extra_frag[i]); | ||
1130 | kfree(tx->extra_frag); | ||
1131 | return -1; | ||
1132 | } else if (unlikely(res == TX_QUEUED)) { | ||
1133 | I802_DEBUG_INC(tx->local->tx_handlers_queued); | ||
1134 | return -1; | ||
1135 | } | ||
1136 | |||
1137 | return 0; | ||
1138 | } | ||
1139 | |||
1140 | static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb) | ||
1129 | { | 1141 | { |
1130 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1142 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1131 | struct sta_info *sta; | 1143 | struct sta_info *sta; |
1132 | ieee80211_tx_handler *handler; | ||
1133 | struct ieee80211_tx_data tx; | 1144 | struct ieee80211_tx_data tx; |
1134 | ieee80211_tx_result res = TX_DROP, res_prepare; | 1145 | ieee80211_tx_result res_prepare; |
1135 | int ret, i, retries = 0; | 1146 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1147 | int ret, i; | ||
1148 | u16 queue; | ||
1149 | |||
1150 | queue = skb_get_queue_mapping(skb); | ||
1136 | 1151 | ||
1137 | WARN_ON(__ieee80211_queue_pending(local, control->queue)); | 1152 | WARN_ON(test_bit(queue, local->queues_pending)); |
1138 | 1153 | ||
1139 | if (unlikely(skb->len < 10)) { | 1154 | if (unlikely(skb->len < 10)) { |
1140 | dev_kfree_skb(skb); | 1155 | dev_kfree_skb(skb); |
@@ -1144,7 +1159,7 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1144 | rcu_read_lock(); | 1159 | rcu_read_lock(); |
1145 | 1160 | ||
1146 | /* initialises tx */ | 1161 | /* initialises tx */ |
1147 | res_prepare = __ieee80211_tx_prepare(&tx, skb, dev, control); | 1162 | res_prepare = __ieee80211_tx_prepare(&tx, skb, dev); |
1148 | 1163 | ||
1149 | if (res_prepare == TX_DROP) { | 1164 | if (res_prepare == TX_DROP) { |
1150 | dev_kfree_skb(skb); | 1165 | dev_kfree_skb(skb); |
@@ -1154,86 +1169,53 @@ static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, | |||
1154 | 1169 | ||
1155 | sta = tx.sta; | 1170 | sta = tx.sta; |
1156 | tx.channel = local->hw.conf.channel; | 1171 | tx.channel = local->hw.conf.channel; |
1172 | info->band = tx.channel->band; | ||
1157 | 1173 | ||
1158 | for (handler = ieee80211_tx_handlers; *handler != NULL; | 1174 | if (invoke_tx_handlers(&tx)) |
1159 | handler++) { | 1175 | goto out; |
1160 | res = (*handler)(&tx); | ||
1161 | if (res != TX_CONTINUE) | ||
1162 | break; | ||
1163 | } | ||
1164 | |||
1165 | skb = tx.skb; /* handlers are allowed to change skb */ | ||
1166 | |||
1167 | if (unlikely(res == TX_DROP)) { | ||
1168 | I802_DEBUG_INC(local->tx_handlers_drop); | ||
1169 | goto drop; | ||
1170 | } | ||
1171 | |||
1172 | if (unlikely(res == TX_QUEUED)) { | ||
1173 | I802_DEBUG_INC(local->tx_handlers_queued); | ||
1174 | rcu_read_unlock(); | ||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | if (tx.extra_frag) { | ||
1179 | for (i = 0; i < tx.num_extra_frag; i++) { | ||
1180 | int next_len, dur; | ||
1181 | struct ieee80211_hdr *hdr = | ||
1182 | (struct ieee80211_hdr *) | ||
1183 | tx.extra_frag[i]->data; | ||
1184 | |||
1185 | if (i + 1 < tx.num_extra_frag) { | ||
1186 | next_len = tx.extra_frag[i + 1]->len; | ||
1187 | } else { | ||
1188 | next_len = 0; | ||
1189 | tx.rate = tx.last_frag_rate; | ||
1190 | } | ||
1191 | dur = ieee80211_duration(&tx, 0, next_len); | ||
1192 | hdr->duration_id = cpu_to_le16(dur); | ||
1193 | } | ||
1194 | } | ||
1195 | 1176 | ||
1196 | retry: | 1177 | retry: |
1197 | ret = __ieee80211_tx(local, skb, &tx); | 1178 | ret = __ieee80211_tx(local, skb, &tx); |
1198 | if (ret) { | 1179 | if (ret) { |
1199 | struct ieee80211_tx_stored_packet *store = | 1180 | struct ieee80211_tx_stored_packet *store; |
1200 | &local->pending_packet[control->queue]; | 1181 | |
1182 | /* | ||
1183 | * Since there are no fragmented frames on A-MPDU | ||
1184 | * queues, there's no reason for a driver to reject | ||
1185 | * a frame there, warn and drop it. | ||
1186 | */ | ||
1187 | if (WARN_ON(queue >= ieee80211_num_regular_queues(&local->hw))) | ||
1188 | goto drop; | ||
1189 | |||
1190 | store = &local->pending_packet[queue]; | ||
1201 | 1191 | ||
1202 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1192 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
1203 | skb = NULL; | 1193 | skb = NULL; |
1204 | set_bit(IEEE80211_LINK_STATE_PENDING, | 1194 | set_bit(queue, local->queues_pending); |
1205 | &local->state[control->queue]); | ||
1206 | smp_mb(); | 1195 | smp_mb(); |
1207 | /* When the driver gets out of buffers during sending of | 1196 | /* |
1208 | * fragments and calls ieee80211_stop_queue, there is | 1197 | * When the driver gets out of buffers during sending of |
1209 | * a small window between IEEE80211_LINK_STATE_XOFF and | 1198 | * fragments and calls ieee80211_stop_queue, the netif |
1210 | * IEEE80211_LINK_STATE_PENDING flags are set. If a buffer | 1199 | * subqueue is stopped. There is, however, a small window |
1200 | * in which the PENDING bit is not yet set. If a buffer | ||
1211 | * gets available in that window (i.e. driver calls | 1201 | * gets available in that window (i.e. driver calls |
1212 | * ieee80211_wake_queue), we would end up with ieee80211_tx | 1202 | * ieee80211_wake_queue), we would end up with ieee80211_tx |
1213 | * called with IEEE80211_LINK_STATE_PENDING. Prevent this by | 1203 | * called with the PENDING bit still set. Prevent this by |
1214 | * continuing transmitting here when that situation is | 1204 | * continuing transmitting here when that situation is |
1215 | * possible to have happened. */ | 1205 | * possible to have happened. |
1216 | if (!__ieee80211_queue_stopped(local, control->queue)) { | 1206 | */ |
1217 | clear_bit(IEEE80211_LINK_STATE_PENDING, | 1207 | if (!__netif_subqueue_stopped(local->mdev, queue)) { |
1218 | &local->state[control->queue]); | 1208 | clear_bit(queue, local->queues_pending); |
1219 | retries++; | ||
1220 | /* | ||
1221 | * Driver bug, it's rejecting packets but | ||
1222 | * not stopping queues. | ||
1223 | */ | ||
1224 | if (WARN_ON_ONCE(retries > 5)) | ||
1225 | goto drop; | ||
1226 | goto retry; | 1209 | goto retry; |
1227 | } | 1210 | } |
1228 | memcpy(&store->control, control, | ||
1229 | sizeof(struct ieee80211_tx_control)); | ||
1230 | store->skb = skb; | 1211 | store->skb = skb; |
1231 | store->extra_frag = tx.extra_frag; | 1212 | store->extra_frag = tx.extra_frag; |
1232 | store->num_extra_frag = tx.num_extra_frag; | 1213 | store->num_extra_frag = tx.num_extra_frag; |
1233 | store->last_frag_rate = tx.last_frag_rate; | 1214 | store->last_frag_rate_idx = tx.last_frag_rate_idx; |
1234 | store->last_frag_rate_ctrl_probe = | 1215 | store->last_frag_rate_ctrl_probe = |
1235 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); | 1216 | !!(tx.flags & IEEE80211_TX_PROBE_LAST_FRAG); |
1236 | } | 1217 | } |
1218 | out: | ||
1237 | rcu_read_unlock(); | 1219 | rcu_read_unlock(); |
1238 | return 0; | 1220 | return 0; |
1239 | 1221 | ||
@@ -1250,24 +1232,57 @@ retry: | |||
1250 | 1232 | ||
1251 | /* device xmit handlers */ | 1233 | /* device xmit handlers */ |
1252 | 1234 | ||
1235 | static int ieee80211_skb_resize(struct ieee80211_local *local, | ||
1236 | struct sk_buff *skb, | ||
1237 | int head_need, bool may_encrypt) | ||
1238 | { | ||
1239 | int tail_need = 0; | ||
1240 | |||
1241 | /* | ||
1242 | * This could be optimised, devices that do full hardware | ||
1243 | * crypto (including TKIP MMIC) need no tailroom... But we | ||
1244 | * have no drivers for such devices currently. | ||
1245 | */ | ||
1246 | if (may_encrypt) { | ||
1247 | tail_need = IEEE80211_ENCRYPT_TAILROOM; | ||
1248 | tail_need -= skb_tailroom(skb); | ||
1249 | tail_need = max_t(int, tail_need, 0); | ||
1250 | } | ||
1251 | |||
1252 | if (head_need || tail_need) { | ||
1253 | /* Sorry. Can't account for this any more */ | ||
1254 | skb_orphan(skb); | ||
1255 | } | ||
1256 | |||
1257 | if (skb_header_cloned(skb)) | ||
1258 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | ||
1259 | else | ||
1260 | I802_DEBUG_INC(local->tx_expand_skb_head); | ||
1261 | |||
1262 | if (pskb_expand_head(skb, head_need, tail_need, GFP_ATOMIC)) { | ||
1263 | printk(KERN_DEBUG "%s: failed to reallocate TX buffer\n", | ||
1264 | wiphy_name(local->hw.wiphy)); | ||
1265 | return -ENOMEM; | ||
1266 | } | ||
1267 | |||
1268 | /* update truesize too */ | ||
1269 | skb->truesize += head_need + tail_need; | ||
1270 | |||
1271 | return 0; | ||
1272 | } | ||
1273 | |||
1253 | int ieee80211_master_start_xmit(struct sk_buff *skb, | 1274 | int ieee80211_master_start_xmit(struct sk_buff *skb, |
1254 | struct net_device *dev) | 1275 | struct net_device *dev) |
1255 | { | 1276 | { |
1256 | struct ieee80211_tx_control control; | 1277 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1257 | struct ieee80211_tx_packet_data *pkt_data; | ||
1258 | struct net_device *odev = NULL; | 1278 | struct net_device *odev = NULL; |
1259 | struct ieee80211_sub_if_data *osdata; | 1279 | struct ieee80211_sub_if_data *osdata; |
1260 | int headroom; | 1280 | int headroom; |
1281 | bool may_encrypt; | ||
1261 | int ret; | 1282 | int ret; |
1262 | 1283 | ||
1263 | /* | 1284 | if (info->control.ifindex) |
1264 | * copy control out of the skb so other people can use skb->cb | 1285 | odev = dev_get_by_index(&init_net, info->control.ifindex); |
1265 | */ | ||
1266 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | ||
1267 | memset(&control, 0, sizeof(struct ieee80211_tx_control)); | ||
1268 | |||
1269 | if (pkt_data->ifindex) | ||
1270 | odev = dev_get_by_index(&init_net, pkt_data->ifindex); | ||
1271 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { | 1286 | if (unlikely(odev && !is_ieee80211_device(odev, dev))) { |
1272 | dev_put(odev); | 1287 | dev_put(odev); |
1273 | odev = NULL; | 1288 | odev = NULL; |
@@ -1280,32 +1295,25 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, | |||
1280 | dev_kfree_skb(skb); | 1295 | dev_kfree_skb(skb); |
1281 | return 0; | 1296 | return 0; |
1282 | } | 1297 | } |
1298 | |||
1283 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); | 1299 | osdata = IEEE80211_DEV_TO_SUB_IF(odev); |
1284 | 1300 | ||
1285 | headroom = osdata->local->tx_headroom + IEEE80211_ENCRYPT_HEADROOM; | 1301 | may_encrypt = !(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT); |
1286 | if (skb_headroom(skb) < headroom) { | 1302 | |
1287 | if (pskb_expand_head(skb, headroom, 0, GFP_ATOMIC)) { | 1303 | headroom = osdata->local->tx_headroom; |
1288 | dev_kfree_skb(skb); | 1304 | if (may_encrypt) |
1289 | dev_put(odev); | 1305 | headroom += IEEE80211_ENCRYPT_HEADROOM; |
1290 | return 0; | 1306 | headroom -= skb_headroom(skb); |
1291 | } | 1307 | headroom = max_t(int, 0, headroom); |
1308 | |||
1309 | if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) { | ||
1310 | dev_kfree_skb(skb); | ||
1311 | dev_put(odev); | ||
1312 | return 0; | ||
1292 | } | 1313 | } |
1293 | 1314 | ||
1294 | control.vif = &osdata->vif; | 1315 | info->control.vif = &osdata->vif; |
1295 | control.type = osdata->vif.type; | 1316 | ret = ieee80211_tx(odev, skb); |
1296 | if (pkt_data->flags & IEEE80211_TXPD_REQ_TX_STATUS) | ||
1297 | control.flags |= IEEE80211_TXCTL_REQ_TX_STATUS; | ||
1298 | if (pkt_data->flags & IEEE80211_TXPD_DO_NOT_ENCRYPT) | ||
1299 | control.flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | ||
1300 | if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) | ||
1301 | control.flags |= IEEE80211_TXCTL_REQUEUE; | ||
1302 | if (pkt_data->flags & IEEE80211_TXPD_EAPOL_FRAME) | ||
1303 | control.flags |= IEEE80211_TXCTL_EAPOL_FRAME; | ||
1304 | if (pkt_data->flags & IEEE80211_TXPD_AMPDU) | ||
1305 | control.flags |= IEEE80211_TXCTL_AMPDU; | ||
1306 | control.queue = pkt_data->queue; | ||
1307 | |||
1308 | ret = ieee80211_tx(odev, skb, &control); | ||
1309 | dev_put(odev); | 1317 | dev_put(odev); |
1310 | 1318 | ||
1311 | return ret; | 1319 | return ret; |
@@ -1315,7 +1323,7 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1315 | struct net_device *dev) | 1323 | struct net_device *dev) |
1316 | { | 1324 | { |
1317 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1325 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1318 | struct ieee80211_tx_packet_data *pkt_data; | 1326 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1319 | struct ieee80211_radiotap_header *prthdr = | 1327 | struct ieee80211_radiotap_header *prthdr = |
1320 | (struct ieee80211_radiotap_header *)skb->data; | 1328 | (struct ieee80211_radiotap_header *)skb->data; |
1321 | u16 len_rthdr; | 1329 | u16 len_rthdr; |
@@ -1337,12 +1345,12 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb, | |||
1337 | 1345 | ||
1338 | skb->dev = local->mdev; | 1346 | skb->dev = local->mdev; |
1339 | 1347 | ||
1340 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | ||
1341 | memset(pkt_data, 0, sizeof(*pkt_data)); | ||
1342 | /* needed because we set skb device to master */ | 1348 | /* needed because we set skb device to master */ |
1343 | pkt_data->ifindex = dev->ifindex; | 1349 | info->control.ifindex = dev->ifindex; |
1344 | 1350 | ||
1345 | pkt_data->flags |= IEEE80211_TXPD_DO_NOT_ENCRYPT; | 1351 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; |
1352 | /* Interfaces should always request a status report */ | ||
1353 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1346 | 1354 | ||
1347 | /* | 1355 | /* |
1348 | * fix up the pointers accounting for the radiotap | 1356 | * fix up the pointers accounting for the radiotap |
@@ -1386,10 +1394,11 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1386 | struct net_device *dev) | 1394 | struct net_device *dev) |
1387 | { | 1395 | { |
1388 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | 1396 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1389 | struct ieee80211_tx_packet_data *pkt_data; | 1397 | struct ieee80211_tx_info *info; |
1390 | struct ieee80211_sub_if_data *sdata; | 1398 | struct ieee80211_sub_if_data *sdata; |
1391 | int ret = 1, head_need; | 1399 | int ret = 1, head_need; |
1392 | u16 ethertype, hdrlen, meshhdrlen = 0, fc; | 1400 | u16 ethertype, hdrlen, meshhdrlen = 0; |
1401 | __le16 fc; | ||
1393 | struct ieee80211_hdr hdr; | 1402 | struct ieee80211_hdr hdr; |
1394 | struct ieee80211s_hdr mesh_hdr; | 1403 | struct ieee80211s_hdr mesh_hdr; |
1395 | const u8 *encaps_data; | 1404 | const u8 *encaps_data; |
@@ -1400,8 +1409,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1400 | 1409 | ||
1401 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1410 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
1402 | if (unlikely(skb->len < ETH_HLEN)) { | 1411 | if (unlikely(skb->len < ETH_HLEN)) { |
1403 | printk(KERN_DEBUG "%s: short skb (len=%d)\n", | ||
1404 | dev->name, skb->len); | ||
1405 | ret = 0; | 1412 | ret = 0; |
1406 | goto fail; | 1413 | goto fail; |
1407 | } | 1414 | } |
@@ -1412,12 +1419,12 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1412 | /* convert Ethernet header to proper 802.11 header (based on | 1419 | /* convert Ethernet header to proper 802.11 header (based on |
1413 | * operation mode) */ | 1420 | * operation mode) */ |
1414 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1421 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
1415 | fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA; | 1422 | fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); |
1416 | 1423 | ||
1417 | switch (sdata->vif.type) { | 1424 | switch (sdata->vif.type) { |
1418 | case IEEE80211_IF_TYPE_AP: | 1425 | case IEEE80211_IF_TYPE_AP: |
1419 | case IEEE80211_IF_TYPE_VLAN: | 1426 | case IEEE80211_IF_TYPE_VLAN: |
1420 | fc |= IEEE80211_FCTL_FROMDS; | 1427 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
1421 | /* DA BSSID SA */ | 1428 | /* DA BSSID SA */ |
1422 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1429 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
1423 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1430 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
@@ -1425,7 +1432,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1425 | hdrlen = 24; | 1432 | hdrlen = 24; |
1426 | break; | 1433 | break; |
1427 | case IEEE80211_IF_TYPE_WDS: | 1434 | case IEEE80211_IF_TYPE_WDS: |
1428 | fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; | 1435 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1429 | /* RA TA DA SA */ | 1436 | /* RA TA DA SA */ |
1430 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); | 1437 | memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); |
1431 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); | 1438 | memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); |
@@ -1435,7 +1442,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1435 | break; | 1442 | break; |
1436 | #ifdef CONFIG_MAC80211_MESH | 1443 | #ifdef CONFIG_MAC80211_MESH |
1437 | case IEEE80211_IF_TYPE_MESH_POINT: | 1444 | case IEEE80211_IF_TYPE_MESH_POINT: |
1438 | fc |= IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS; | 1445 | fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); |
1439 | /* RA TA DA SA */ | 1446 | /* RA TA DA SA */ |
1440 | if (is_multicast_ether_addr(skb->data)) | 1447 | if (is_multicast_ether_addr(skb->data)) |
1441 | memcpy(hdr.addr1, skb->data, ETH_ALEN); | 1448 | memcpy(hdr.addr1, skb->data, ETH_ALEN); |
@@ -1465,7 +1472,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1465 | break; | 1472 | break; |
1466 | #endif | 1473 | #endif |
1467 | case IEEE80211_IF_TYPE_STA: | 1474 | case IEEE80211_IF_TYPE_STA: |
1468 | fc |= IEEE80211_FCTL_TODS; | 1475 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); |
1469 | /* BSSID SA DA */ | 1476 | /* BSSID SA DA */ |
1470 | memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); | 1477 | memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); |
1471 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); | 1478 | memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); |
@@ -1493,13 +1500,14 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1493 | rcu_read_lock(); | 1500 | rcu_read_lock(); |
1494 | sta = sta_info_get(local, hdr.addr1); | 1501 | sta = sta_info_get(local, hdr.addr1); |
1495 | if (sta) | 1502 | if (sta) |
1496 | sta_flags = sta->flags; | 1503 | sta_flags = get_sta_flags(sta); |
1497 | rcu_read_unlock(); | 1504 | rcu_read_unlock(); |
1498 | } | 1505 | } |
1499 | 1506 | ||
1500 | /* receiver is QoS enabled, use a QoS type frame */ | 1507 | /* receiver and we are QoS enabled, use a QoS type frame */ |
1501 | if (sta_flags & WLAN_STA_WME) { | 1508 | if (sta_flags & WLAN_STA_WME && |
1502 | fc |= IEEE80211_STYPE_QOS_DATA; | 1509 | ieee80211_num_regular_queues(&local->hw) >= 4) { |
1510 | fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); | ||
1503 | hdrlen += 2; | 1511 | hdrlen += 2; |
1504 | } | 1512 | } |
1505 | 1513 | ||
@@ -1527,7 +1535,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1527 | goto fail; | 1535 | goto fail; |
1528 | } | 1536 | } |
1529 | 1537 | ||
1530 | hdr.frame_control = cpu_to_le16(fc); | 1538 | hdr.frame_control = fc; |
1531 | hdr.duration_id = 0; | 1539 | hdr.duration_id = 0; |
1532 | hdr.seq_ctrl = 0; | 1540 | hdr.seq_ctrl = 0; |
1533 | 1541 | ||
@@ -1562,32 +1570,26 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1562 | * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and | 1570 | * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and |
1563 | * alloc_skb() (net/core/skbuff.c) | 1571 | * alloc_skb() (net/core/skbuff.c) |
1564 | */ | 1572 | */ |
1565 | head_need = hdrlen + encaps_len + meshhdrlen + local->tx_headroom; | 1573 | head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); |
1566 | head_need -= skb_headroom(skb); | ||
1567 | 1574 | ||
1568 | /* We are going to modify skb data, so make a copy of it if happens to | 1575 | /* |
1569 | * be cloned. This could happen, e.g., with Linux bridge code passing | 1576 | * So we need to modify the skb header and hence need a copy of |
1570 | * us broadcast frames. */ | 1577 | * that. The head_need variable above doesn't, so far, include |
1578 | * the needed header space that we don't need right away. If we | ||
1579 | * can, then we don't reallocate right now but only after the | ||
1580 | * frame arrives at the master device (if it does...) | ||
1581 | * | ||
1582 | * If we cannot, however, then we will reallocate to include all | ||
1583 | * the ever needed space. Also, if we need to reallocate it anyway, | ||
1584 | * make it big enough for everything we may ever need. | ||
1585 | */ | ||
1571 | 1586 | ||
1572 | if (head_need > 0 || skb_cloned(skb)) { | 1587 | if (head_need > 0 || skb_cloned(skb)) { |
1573 | #if 0 | 1588 | head_need += IEEE80211_ENCRYPT_HEADROOM; |
1574 | printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes " | 1589 | head_need += local->tx_headroom; |
1575 | "of headroom\n", dev->name, head_need); | 1590 | head_need = max_t(int, 0, head_need); |
1576 | #endif | 1591 | if (ieee80211_skb_resize(local, skb, head_need, true)) |
1577 | |||
1578 | if (skb_cloned(skb)) | ||
1579 | I802_DEBUG_INC(local->tx_expand_skb_head_cloned); | ||
1580 | else | ||
1581 | I802_DEBUG_INC(local->tx_expand_skb_head); | ||
1582 | /* Since we have to reallocate the buffer, make sure that there | ||
1583 | * is enough room for possible WEP IV/ICV and TKIP (8 bytes | ||
1584 | * before payload and 12 after). */ | ||
1585 | if (pskb_expand_head(skb, (head_need > 0 ? head_need + 8 : 8), | ||
1586 | 12, GFP_ATOMIC)) { | ||
1587 | printk(KERN_DEBUG "%s: failed to reallocate TX buffer" | ||
1588 | "\n", dev->name); | ||
1589 | goto fail; | 1592 | goto fail; |
1590 | } | ||
1591 | } | 1593 | } |
1592 | 1594 | ||
1593 | if (encaps_data) { | 1595 | if (encaps_data) { |
@@ -1602,7 +1604,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1602 | h_pos += meshhdrlen; | 1604 | h_pos += meshhdrlen; |
1603 | } | 1605 | } |
1604 | 1606 | ||
1605 | if (fc & IEEE80211_STYPE_QOS_DATA) { | 1607 | if (ieee80211_is_data_qos(fc)) { |
1606 | __le16 *qos_control; | 1608 | __le16 *qos_control; |
1607 | 1609 | ||
1608 | qos_control = (__le16*) skb_push(skb, 2); | 1610 | qos_control = (__le16*) skb_push(skb, 2); |
@@ -1618,11 +1620,14 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1618 | nh_pos += hdrlen; | 1620 | nh_pos += hdrlen; |
1619 | h_pos += hdrlen; | 1621 | h_pos += hdrlen; |
1620 | 1622 | ||
1621 | pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; | 1623 | info = IEEE80211_SKB_CB(skb); |
1622 | memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); | 1624 | memset(info, 0, sizeof(*info)); |
1623 | pkt_data->ifindex = dev->ifindex; | 1625 | info->control.ifindex = dev->ifindex; |
1624 | if (ethertype == ETH_P_PAE) | 1626 | if (ethertype == ETH_P_PAE) |
1625 | pkt_data->flags |= IEEE80211_TXPD_EAPOL_FRAME; | 1627 | info->flags |= IEEE80211_TX_CTL_EAPOL_FRAME; |
1628 | |||
1629 | /* Interfaces should always request a status report */ | ||
1630 | info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
1626 | 1631 | ||
1627 | skb->dev = local->mdev; | 1632 | skb->dev = local->mdev; |
1628 | dev->stats.tx_packets++; | 1633 | dev->stats.tx_packets++; |
@@ -1647,46 +1652,55 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1647 | return ret; | 1652 | return ret; |
1648 | } | 1653 | } |
1649 | 1654 | ||
1650 | /* helper functions for pending packets for when queues are stopped */ | ||
1651 | 1655 | ||
1656 | /* | ||
1657 | * ieee80211_clear_tx_pending may not be called in a context where | ||
1658 | * it is possible that it packets could come in again. | ||
1659 | */ | ||
1652 | void ieee80211_clear_tx_pending(struct ieee80211_local *local) | 1660 | void ieee80211_clear_tx_pending(struct ieee80211_local *local) |
1653 | { | 1661 | { |
1654 | int i, j; | 1662 | int i, j; |
1655 | struct ieee80211_tx_stored_packet *store; | 1663 | struct ieee80211_tx_stored_packet *store; |
1656 | 1664 | ||
1657 | for (i = 0; i < local->hw.queues; i++) { | 1665 | for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { |
1658 | if (!__ieee80211_queue_pending(local, i)) | 1666 | if (!test_bit(i, local->queues_pending)) |
1659 | continue; | 1667 | continue; |
1660 | store = &local->pending_packet[i]; | 1668 | store = &local->pending_packet[i]; |
1661 | kfree_skb(store->skb); | 1669 | kfree_skb(store->skb); |
1662 | for (j = 0; j < store->num_extra_frag; j++) | 1670 | for (j = 0; j < store->num_extra_frag; j++) |
1663 | kfree_skb(store->extra_frag[j]); | 1671 | kfree_skb(store->extra_frag[j]); |
1664 | kfree(store->extra_frag); | 1672 | kfree(store->extra_frag); |
1665 | clear_bit(IEEE80211_LINK_STATE_PENDING, &local->state[i]); | 1673 | clear_bit(i, local->queues_pending); |
1666 | } | 1674 | } |
1667 | } | 1675 | } |
1668 | 1676 | ||
1677 | /* | ||
1678 | * Transmit all pending packets. Called from tasklet, locks master device | ||
1679 | * TX lock so that no new packets can come in. | ||
1680 | */ | ||
1669 | void ieee80211_tx_pending(unsigned long data) | 1681 | void ieee80211_tx_pending(unsigned long data) |
1670 | { | 1682 | { |
1671 | struct ieee80211_local *local = (struct ieee80211_local *)data; | 1683 | struct ieee80211_local *local = (struct ieee80211_local *)data; |
1672 | struct net_device *dev = local->mdev; | 1684 | struct net_device *dev = local->mdev; |
1673 | struct ieee80211_tx_stored_packet *store; | 1685 | struct ieee80211_tx_stored_packet *store; |
1674 | struct ieee80211_tx_data tx; | 1686 | struct ieee80211_tx_data tx; |
1675 | int i, ret, reschedule = 0; | 1687 | int i, ret; |
1676 | 1688 | ||
1677 | netif_tx_lock_bh(dev); | 1689 | netif_tx_lock_bh(dev); |
1678 | for (i = 0; i < local->hw.queues; i++) { | 1690 | for (i = 0; i < ieee80211_num_regular_queues(&local->hw); i++) { |
1679 | if (__ieee80211_queue_stopped(local, i)) | 1691 | /* Check that this queue is ok */ |
1692 | if (__netif_subqueue_stopped(local->mdev, i)) | ||
1680 | continue; | 1693 | continue; |
1681 | if (!__ieee80211_queue_pending(local, i)) { | 1694 | |
1682 | reschedule = 1; | 1695 | if (!test_bit(i, local->queues_pending)) { |
1696 | ieee80211_wake_queue(&local->hw, i); | ||
1683 | continue; | 1697 | continue; |
1684 | } | 1698 | } |
1699 | |||
1685 | store = &local->pending_packet[i]; | 1700 | store = &local->pending_packet[i]; |
1686 | tx.control = &store->control; | ||
1687 | tx.extra_frag = store->extra_frag; | 1701 | tx.extra_frag = store->extra_frag; |
1688 | tx.num_extra_frag = store->num_extra_frag; | 1702 | tx.num_extra_frag = store->num_extra_frag; |
1689 | tx.last_frag_rate = store->last_frag_rate; | 1703 | tx.last_frag_rate_idx = store->last_frag_rate_idx; |
1690 | tx.flags = 0; | 1704 | tx.flags = 0; |
1691 | if (store->last_frag_rate_ctrl_probe) | 1705 | if (store->last_frag_rate_ctrl_probe) |
1692 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; | 1706 | tx.flags |= IEEE80211_TX_PROBE_LAST_FRAG; |
@@ -1695,19 +1709,11 @@ void ieee80211_tx_pending(unsigned long data) | |||
1695 | if (ret == IEEE80211_TX_FRAG_AGAIN) | 1709 | if (ret == IEEE80211_TX_FRAG_AGAIN) |
1696 | store->skb = NULL; | 1710 | store->skb = NULL; |
1697 | } else { | 1711 | } else { |
1698 | clear_bit(IEEE80211_LINK_STATE_PENDING, | 1712 | clear_bit(i, local->queues_pending); |
1699 | &local->state[i]); | 1713 | ieee80211_wake_queue(&local->hw, i); |
1700 | reschedule = 1; | ||
1701 | } | 1714 | } |
1702 | } | 1715 | } |
1703 | netif_tx_unlock_bh(dev); | 1716 | netif_tx_unlock_bh(dev); |
1704 | if (reschedule) { | ||
1705 | if (!ieee80211_qdisc_installed(dev)) { | ||
1706 | if (!__ieee80211_queue_stopped(local, 0)) | ||
1707 | netif_wake_queue(dev); | ||
1708 | } else | ||
1709 | netif_schedule(dev); | ||
1710 | } | ||
1711 | } | 1717 | } |
1712 | 1718 | ||
1713 | /* functions for drivers to get certain frames */ | 1719 | /* functions for drivers to get certain frames */ |
@@ -1776,11 +1782,11 @@ static void ieee80211_beacon_add_tim(struct ieee80211_local *local, | |||
1776 | } | 1782 | } |
1777 | 1783 | ||
1778 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | 1784 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, |
1779 | struct ieee80211_vif *vif, | 1785 | struct ieee80211_vif *vif) |
1780 | struct ieee80211_tx_control *control) | ||
1781 | { | 1786 | { |
1782 | struct ieee80211_local *local = hw_to_local(hw); | 1787 | struct ieee80211_local *local = hw_to_local(hw); |
1783 | struct sk_buff *skb; | 1788 | struct sk_buff *skb; |
1789 | struct ieee80211_tx_info *info; | ||
1784 | struct net_device *bdev; | 1790 | struct net_device *bdev; |
1785 | struct ieee80211_sub_if_data *sdata = NULL; | 1791 | struct ieee80211_sub_if_data *sdata = NULL; |
1786 | struct ieee80211_if_ap *ap = NULL; | 1792 | struct ieee80211_if_ap *ap = NULL; |
@@ -1790,9 +1796,10 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1790 | struct ieee80211_mgmt *mgmt; | 1796 | struct ieee80211_mgmt *mgmt; |
1791 | int *num_beacons; | 1797 | int *num_beacons; |
1792 | bool err = true; | 1798 | bool err = true; |
1799 | enum ieee80211_band band = local->hw.conf.channel->band; | ||
1793 | u8 *pos; | 1800 | u8 *pos; |
1794 | 1801 | ||
1795 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1802 | sband = local->hw.wiphy->bands[band]; |
1796 | 1803 | ||
1797 | rcu_read_lock(); | 1804 | rcu_read_lock(); |
1798 | 1805 | ||
@@ -1855,8 +1862,8 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1855 | mgmt = (struct ieee80211_mgmt *) | 1862 | mgmt = (struct ieee80211_mgmt *) |
1856 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); | 1863 | skb_put(skb, 24 + sizeof(mgmt->u.beacon)); |
1857 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); | 1864 | memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); |
1858 | mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, | 1865 | mgmt->frame_control = |
1859 | IEEE80211_STYPE_BEACON); | 1866 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
1860 | memset(mgmt->da, 0xff, ETH_ALEN); | 1867 | memset(mgmt->da, 0xff, ETH_ALEN); |
1861 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); | 1868 | memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); |
1862 | /* BSSID is left zeroed, wildcard value */ | 1869 | /* BSSID is left zeroed, wildcard value */ |
@@ -1885,30 +1892,32 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
1885 | goto out; | 1892 | goto out; |
1886 | } | 1893 | } |
1887 | 1894 | ||
1888 | if (control) { | 1895 | info = IEEE80211_SKB_CB(skb); |
1889 | rate_control_get_rate(local->mdev, sband, skb, &rsel); | ||
1890 | if (!rsel.rate) { | ||
1891 | if (net_ratelimit()) { | ||
1892 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " | ||
1893 | "no rate found\n", | ||
1894 | wiphy_name(local->hw.wiphy)); | ||
1895 | } | ||
1896 | dev_kfree_skb(skb); | ||
1897 | skb = NULL; | ||
1898 | goto out; | ||
1899 | } | ||
1900 | 1896 | ||
1901 | control->vif = vif; | 1897 | info->band = band; |
1902 | control->tx_rate = rsel.rate; | 1898 | rate_control_get_rate(local->mdev, sband, skb, &rsel); |
1903 | if (sdata->bss_conf.use_short_preamble && | 1899 | |
1904 | rsel.rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) | 1900 | if (unlikely(rsel.rate_idx < 0)) { |
1905 | control->flags |= IEEE80211_TXCTL_SHORT_PREAMBLE; | 1901 | if (net_ratelimit()) { |
1906 | control->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | 1902 | printk(KERN_DEBUG "%s: ieee80211_beacon_get: " |
1907 | control->flags |= IEEE80211_TXCTL_NO_ACK; | 1903 | "no rate found\n", |
1908 | control->flags |= IEEE80211_TXCTL_DO_NOT_ENCRYPT; | 1904 | wiphy_name(local->hw.wiphy)); |
1909 | control->retry_limit = 1; | 1905 | } |
1910 | control->flags |= IEEE80211_TXCTL_CLEAR_PS_FILT; | 1906 | dev_kfree_skb(skb); |
1907 | skb = NULL; | ||
1908 | goto out; | ||
1911 | } | 1909 | } |
1910 | |||
1911 | info->control.vif = vif; | ||
1912 | info->tx_rate_idx = rsel.rate_idx; | ||
1913 | if (sdata->bss_conf.use_short_preamble && | ||
1914 | sband->bitrates[rsel.rate_idx].flags & IEEE80211_RATE_SHORT_PREAMBLE) | ||
1915 | info->flags |= IEEE80211_TX_CTL_SHORT_PREAMBLE; | ||
1916 | info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; | ||
1917 | info->flags |= IEEE80211_TX_CTL_NO_ACK; | ||
1918 | info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT; | ||
1919 | info->control.retry_limit = 1; | ||
1920 | info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; | ||
1912 | (*num_beacons)++; | 1921 | (*num_beacons)++; |
1913 | out: | 1922 | out: |
1914 | rcu_read_unlock(); | 1923 | rcu_read_unlock(); |
@@ -1918,14 +1927,13 @@ EXPORT_SYMBOL(ieee80211_beacon_get); | |||
1918 | 1927 | ||
1919 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1928 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1920 | const void *frame, size_t frame_len, | 1929 | const void *frame, size_t frame_len, |
1921 | const struct ieee80211_tx_control *frame_txctl, | 1930 | const struct ieee80211_tx_info *frame_txctl, |
1922 | struct ieee80211_rts *rts) | 1931 | struct ieee80211_rts *rts) |
1923 | { | 1932 | { |
1924 | const struct ieee80211_hdr *hdr = frame; | 1933 | const struct ieee80211_hdr *hdr = frame; |
1925 | u16 fctl; | ||
1926 | 1934 | ||
1927 | fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS; | 1935 | rts->frame_control = |
1928 | rts->frame_control = cpu_to_le16(fctl); | 1936 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); |
1929 | rts->duration = ieee80211_rts_duration(hw, vif, frame_len, | 1937 | rts->duration = ieee80211_rts_duration(hw, vif, frame_len, |
1930 | frame_txctl); | 1938 | frame_txctl); |
1931 | memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); | 1939 | memcpy(rts->ra, hdr->addr1, sizeof(rts->ra)); |
@@ -1935,14 +1943,13 @@ EXPORT_SYMBOL(ieee80211_rts_get); | |||
1935 | 1943 | ||
1936 | void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 1944 | void ieee80211_ctstoself_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
1937 | const void *frame, size_t frame_len, | 1945 | const void *frame, size_t frame_len, |
1938 | const struct ieee80211_tx_control *frame_txctl, | 1946 | const struct ieee80211_tx_info *frame_txctl, |
1939 | struct ieee80211_cts *cts) | 1947 | struct ieee80211_cts *cts) |
1940 | { | 1948 | { |
1941 | const struct ieee80211_hdr *hdr = frame; | 1949 | const struct ieee80211_hdr *hdr = frame; |
1942 | u16 fctl; | ||
1943 | 1950 | ||
1944 | fctl = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS; | 1951 | cts->frame_control = |
1945 | cts->frame_control = cpu_to_le16(fctl); | 1952 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); |
1946 | cts->duration = ieee80211_ctstoself_duration(hw, vif, | 1953 | cts->duration = ieee80211_ctstoself_duration(hw, vif, |
1947 | frame_len, frame_txctl); | 1954 | frame_len, frame_txctl); |
1948 | memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); | 1955 | memcpy(cts->ra, hdr->addr1, sizeof(cts->ra)); |
@@ -1951,23 +1958,21 @@ EXPORT_SYMBOL(ieee80211_ctstoself_get); | |||
1951 | 1958 | ||
1952 | struct sk_buff * | 1959 | struct sk_buff * |
1953 | ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | 1960 | ieee80211_get_buffered_bc(struct ieee80211_hw *hw, |
1954 | struct ieee80211_vif *vif, | 1961 | struct ieee80211_vif *vif) |
1955 | struct ieee80211_tx_control *control) | ||
1956 | { | 1962 | { |
1957 | struct ieee80211_local *local = hw_to_local(hw); | 1963 | struct ieee80211_local *local = hw_to_local(hw); |
1958 | struct sk_buff *skb; | 1964 | struct sk_buff *skb = NULL; |
1959 | struct sta_info *sta; | 1965 | struct sta_info *sta; |
1960 | ieee80211_tx_handler *handler; | ||
1961 | struct ieee80211_tx_data tx; | 1966 | struct ieee80211_tx_data tx; |
1962 | ieee80211_tx_result res = TX_DROP; | ||
1963 | struct net_device *bdev; | 1967 | struct net_device *bdev; |
1964 | struct ieee80211_sub_if_data *sdata; | 1968 | struct ieee80211_sub_if_data *sdata; |
1965 | struct ieee80211_if_ap *bss = NULL; | 1969 | struct ieee80211_if_ap *bss = NULL; |
1966 | struct beacon_data *beacon; | 1970 | struct beacon_data *beacon; |
1971 | struct ieee80211_tx_info *info; | ||
1967 | 1972 | ||
1968 | sdata = vif_to_sdata(vif); | 1973 | sdata = vif_to_sdata(vif); |
1969 | bdev = sdata->dev; | 1974 | bdev = sdata->dev; |
1970 | 1975 | bss = &sdata->u.ap; | |
1971 | 1976 | ||
1972 | if (!bss) | 1977 | if (!bss) |
1973 | return NULL; | 1978 | return NULL; |
@@ -1975,19 +1980,16 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
1975 | rcu_read_lock(); | 1980 | rcu_read_lock(); |
1976 | beacon = rcu_dereference(bss->beacon); | 1981 | beacon = rcu_dereference(bss->beacon); |
1977 | 1982 | ||
1978 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || | 1983 | if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || !beacon->head) |
1979 | !beacon->head) { | 1984 | goto out; |
1980 | rcu_read_unlock(); | ||
1981 | return NULL; | ||
1982 | } | ||
1983 | 1985 | ||
1984 | if (bss->dtim_count != 0) | 1986 | if (bss->dtim_count != 0) |
1985 | return NULL; /* send buffered bc/mc only after DTIM beacon */ | 1987 | goto out; /* send buffered bc/mc only after DTIM beacon */ |
1986 | memset(control, 0, sizeof(*control)); | 1988 | |
1987 | while (1) { | 1989 | while (1) { |
1988 | skb = skb_dequeue(&bss->ps_bc_buf); | 1990 | skb = skb_dequeue(&bss->ps_bc_buf); |
1989 | if (!skb) | 1991 | if (!skb) |
1990 | return NULL; | 1992 | goto out; |
1991 | local->total_ps_buffered--; | 1993 | local->total_ps_buffered--; |
1992 | 1994 | ||
1993 | if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { | 1995 | if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { |
@@ -2000,30 +2002,21 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw, | |||
2000 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); | 2002 | cpu_to_le16(IEEE80211_FCTL_MOREDATA); |
2001 | } | 2003 | } |
2002 | 2004 | ||
2003 | if (!ieee80211_tx_prepare(&tx, skb, local->mdev, control)) | 2005 | if (!ieee80211_tx_prepare(&tx, skb, local->mdev)) |
2004 | break; | 2006 | break; |
2005 | dev_kfree_skb_any(skb); | 2007 | dev_kfree_skb_any(skb); |
2006 | } | 2008 | } |
2009 | |||
2010 | info = IEEE80211_SKB_CB(skb); | ||
2011 | |||
2007 | sta = tx.sta; | 2012 | sta = tx.sta; |
2008 | tx.flags |= IEEE80211_TX_PS_BUFFERED; | 2013 | tx.flags |= IEEE80211_TX_PS_BUFFERED; |
2009 | tx.channel = local->hw.conf.channel; | 2014 | tx.channel = local->hw.conf.channel; |
2015 | info->band = tx.channel->band; | ||
2010 | 2016 | ||
2011 | for (handler = ieee80211_tx_handlers; *handler != NULL; handler++) { | 2017 | if (invoke_tx_handlers(&tx)) |
2012 | res = (*handler)(&tx); | ||
2013 | if (res == TX_DROP || res == TX_QUEUED) | ||
2014 | break; | ||
2015 | } | ||
2016 | skb = tx.skb; /* handlers are allowed to change skb */ | ||
2017 | |||
2018 | if (res == TX_DROP) { | ||
2019 | I802_DEBUG_INC(local->tx_handlers_drop); | ||
2020 | dev_kfree_skb(skb); | ||
2021 | skb = NULL; | ||
2022 | } else if (res == TX_QUEUED) { | ||
2023 | I802_DEBUG_INC(local->tx_handlers_queued); | ||
2024 | skb = NULL; | 2018 | skb = NULL; |
2025 | } | 2019 | out: |
2026 | |||
2027 | rcu_read_unlock(); | 2020 | rcu_read_unlock(); |
2028 | 2021 | ||
2029 | return skb; | 2022 | return skb; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 4e97b266f90..ce62b163b82 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -45,38 +45,37 @@ const unsigned char bridge_tunnel_header[] __aligned(2) = | |||
45 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 45 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
46 | enum ieee80211_if_types type) | 46 | enum ieee80211_if_types type) |
47 | { | 47 | { |
48 | u16 fc; | 48 | __le16 fc = hdr->frame_control; |
49 | 49 | ||
50 | /* drop ACK/CTS frames and incorrect hdr len (ctrl) */ | 50 | /* drop ACK/CTS frames and incorrect hdr len (ctrl) */ |
51 | if (len < 16) | 51 | if (len < 16) |
52 | return NULL; | 52 | return NULL; |
53 | 53 | ||
54 | fc = le16_to_cpu(hdr->frame_control); | 54 | if (ieee80211_is_data(fc)) { |
55 | |||
56 | switch (fc & IEEE80211_FCTL_FTYPE) { | ||
57 | case IEEE80211_FTYPE_DATA: | ||
58 | if (len < 24) /* drop incorrect hdr len (data) */ | 55 | if (len < 24) /* drop incorrect hdr len (data) */ |
59 | return NULL; | 56 | return NULL; |
60 | switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { | 57 | |
61 | case IEEE80211_FCTL_TODS: | 58 | if (ieee80211_has_a4(fc)) |
62 | return hdr->addr1; | ||
63 | case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): | ||
64 | return NULL; | 59 | return NULL; |
65 | case IEEE80211_FCTL_FROMDS: | 60 | if (ieee80211_has_tods(fc)) |
61 | return hdr->addr1; | ||
62 | if (ieee80211_has_fromds(fc)) | ||
66 | return hdr->addr2; | 63 | return hdr->addr2; |
67 | case 0: | 64 | |
68 | return hdr->addr3; | 65 | return hdr->addr3; |
69 | } | 66 | } |
70 | break; | 67 | |
71 | case IEEE80211_FTYPE_MGMT: | 68 | if (ieee80211_is_mgmt(fc)) { |
72 | if (len < 24) /* drop incorrect hdr len (mgmt) */ | 69 | if (len < 24) /* drop incorrect hdr len (mgmt) */ |
73 | return NULL; | 70 | return NULL; |
74 | return hdr->addr3; | 71 | return hdr->addr3; |
75 | case IEEE80211_FTYPE_CTL: | 72 | } |
76 | if ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL) | 73 | |
74 | if (ieee80211_is_ctl(fc)) { | ||
75 | if(ieee80211_is_pspoll(fc)) | ||
77 | return hdr->addr1; | 76 | return hdr->addr1; |
78 | else if ((fc & IEEE80211_FCTL_STYPE) == | 77 | |
79 | IEEE80211_STYPE_BACK_REQ) { | 78 | if (ieee80211_is_back_req(fc)) { |
80 | switch (type) { | 79 | switch (type) { |
81 | case IEEE80211_IF_TYPE_STA: | 80 | case IEEE80211_IF_TYPE_STA: |
82 | return hdr->addr2; | 81 | return hdr->addr2; |
@@ -84,11 +83,9 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | |||
84 | case IEEE80211_IF_TYPE_VLAN: | 83 | case IEEE80211_IF_TYPE_VLAN: |
85 | return hdr->addr1; | 84 | return hdr->addr1; |
86 | default: | 85 | default: |
87 | return NULL; | 86 | break; /* fall through to the return */ |
88 | } | 87 | } |
89 | } | 88 | } |
90 | else | ||
91 | return NULL; | ||
92 | } | 89 | } |
93 | 90 | ||
94 | return NULL; | 91 | return NULL; |
@@ -133,14 +130,46 @@ int ieee80211_get_hdrlen(u16 fc) | |||
133 | } | 130 | } |
134 | EXPORT_SYMBOL(ieee80211_get_hdrlen); | 131 | EXPORT_SYMBOL(ieee80211_get_hdrlen); |
135 | 132 | ||
136 | int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) | 133 | unsigned int ieee80211_hdrlen(__le16 fc) |
134 | { | ||
135 | unsigned int hdrlen = 24; | ||
136 | |||
137 | if (ieee80211_is_data(fc)) { | ||
138 | if (ieee80211_has_a4(fc)) | ||
139 | hdrlen = 30; | ||
140 | if (ieee80211_is_data_qos(fc)) | ||
141 | hdrlen += IEEE80211_QOS_CTL_LEN; | ||
142 | goto out; | ||
143 | } | ||
144 | |||
145 | if (ieee80211_is_ctl(fc)) { | ||
146 | /* | ||
147 | * ACK and CTS are 10 bytes, all others 16. To see how | ||
148 | * to get this condition consider | ||
149 | * subtype mask: 0b0000000011110000 (0x00F0) | ||
150 | * ACK subtype: 0b0000000011010000 (0x00D0) | ||
151 | * CTS subtype: 0b0000000011000000 (0x00C0) | ||
152 | * bits that matter: ^^^ (0x00E0) | ||
153 | * value of those: 0b0000000011000000 (0x00C0) | ||
154 | */ | ||
155 | if ((fc & cpu_to_le16(0x00E0)) == cpu_to_le16(0x00C0)) | ||
156 | hdrlen = 10; | ||
157 | else | ||
158 | hdrlen = 16; | ||
159 | } | ||
160 | out: | ||
161 | return hdrlen; | ||
162 | } | ||
163 | EXPORT_SYMBOL(ieee80211_hdrlen); | ||
164 | |||
165 | unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb) | ||
137 | { | 166 | { |
138 | const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *) skb->data; | 167 | const struct ieee80211_hdr *hdr = (const struct ieee80211_hdr *)skb->data; |
139 | int hdrlen; | 168 | unsigned int hdrlen; |
140 | 169 | ||
141 | if (unlikely(skb->len < 10)) | 170 | if (unlikely(skb->len < 10)) |
142 | return 0; | 171 | return 0; |
143 | hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | 172 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
144 | if (unlikely(hdrlen > skb->len)) | 173 | if (unlikely(hdrlen > skb->len)) |
145 | return 0; | 174 | return 0; |
146 | return hdrlen; | 175 | return hdrlen; |
@@ -258,7 +287,7 @@ EXPORT_SYMBOL(ieee80211_generic_frame_duration); | |||
258 | 287 | ||
259 | __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | 288 | __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, |
260 | struct ieee80211_vif *vif, size_t frame_len, | 289 | struct ieee80211_vif *vif, size_t frame_len, |
261 | const struct ieee80211_tx_control *frame_txctl) | 290 | const struct ieee80211_tx_info *frame_txctl) |
262 | { | 291 | { |
263 | struct ieee80211_local *local = hw_to_local(hw); | 292 | struct ieee80211_local *local = hw_to_local(hw); |
264 | struct ieee80211_rate *rate; | 293 | struct ieee80211_rate *rate; |
@@ -266,10 +295,13 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw, | |||
266 | bool short_preamble; | 295 | bool short_preamble; |
267 | int erp; | 296 | int erp; |
268 | u16 dur; | 297 | u16 dur; |
298 | struct ieee80211_supported_band *sband; | ||
299 | |||
300 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
269 | 301 | ||
270 | short_preamble = sdata->bss_conf.use_short_preamble; | 302 | short_preamble = sdata->bss_conf.use_short_preamble; |
271 | 303 | ||
272 | rate = frame_txctl->rts_cts_rate; | 304 | rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; |
273 | 305 | ||
274 | erp = 0; | 306 | erp = 0; |
275 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 307 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
@@ -292,7 +324,7 @@ EXPORT_SYMBOL(ieee80211_rts_duration); | |||
292 | __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | 324 | __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, |
293 | struct ieee80211_vif *vif, | 325 | struct ieee80211_vif *vif, |
294 | size_t frame_len, | 326 | size_t frame_len, |
295 | const struct ieee80211_tx_control *frame_txctl) | 327 | const struct ieee80211_tx_info *frame_txctl) |
296 | { | 328 | { |
297 | struct ieee80211_local *local = hw_to_local(hw); | 329 | struct ieee80211_local *local = hw_to_local(hw); |
298 | struct ieee80211_rate *rate; | 330 | struct ieee80211_rate *rate; |
@@ -300,10 +332,13 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
300 | bool short_preamble; | 332 | bool short_preamble; |
301 | int erp; | 333 | int erp; |
302 | u16 dur; | 334 | u16 dur; |
335 | struct ieee80211_supported_band *sband; | ||
336 | |||
337 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
303 | 338 | ||
304 | short_preamble = sdata->bss_conf.use_short_preamble; | 339 | short_preamble = sdata->bss_conf.use_short_preamble; |
305 | 340 | ||
306 | rate = frame_txctl->rts_cts_rate; | 341 | rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; |
307 | erp = 0; | 342 | erp = 0; |
308 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) | 343 | if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) |
309 | erp = rate->flags & IEEE80211_RATE_ERP_G; | 344 | erp = rate->flags & IEEE80211_RATE_ERP_G; |
@@ -311,7 +346,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw, | |||
311 | /* Data frame duration */ | 346 | /* Data frame duration */ |
312 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, | 347 | dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, |
313 | erp, short_preamble); | 348 | erp, short_preamble); |
314 | if (!(frame_txctl->flags & IEEE80211_TXCTL_NO_ACK)) { | 349 | if (!(frame_txctl->flags & IEEE80211_TX_CTL_NO_ACK)) { |
315 | /* ACK duration */ | 350 | /* ACK duration */ |
316 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, | 351 | dur += ieee80211_frame_duration(local, 10, rate->bitrate, |
317 | erp, short_preamble); | 352 | erp, short_preamble); |
@@ -325,17 +360,15 @@ void ieee80211_wake_queue(struct ieee80211_hw *hw, int queue) | |||
325 | { | 360 | { |
326 | struct ieee80211_local *local = hw_to_local(hw); | 361 | struct ieee80211_local *local = hw_to_local(hw); |
327 | 362 | ||
328 | if (test_and_clear_bit(IEEE80211_LINK_STATE_XOFF, | 363 | if (test_bit(queue, local->queues_pending)) { |
329 | &local->state[queue])) { | 364 | tasklet_schedule(&local->tx_pending_tasklet); |
330 | if (test_bit(IEEE80211_LINK_STATE_PENDING, | 365 | } else { |
331 | &local->state[queue])) | 366 | if (ieee80211_is_multiqueue(local)) { |
332 | tasklet_schedule(&local->tx_pending_tasklet); | 367 | netif_wake_subqueue(local->mdev, queue); |
333 | else | 368 | } else { |
334 | if (!ieee80211_qdisc_installed(local->mdev)) { | 369 | WARN_ON(queue != 0); |
335 | if (queue == 0) | 370 | netif_wake_queue(local->mdev); |
336 | netif_wake_queue(local->mdev); | 371 | } |
337 | } else | ||
338 | __netif_schedule(local->mdev); | ||
339 | } | 372 | } |
340 | } | 373 | } |
341 | EXPORT_SYMBOL(ieee80211_wake_queue); | 374 | EXPORT_SYMBOL(ieee80211_wake_queue); |
@@ -344,29 +377,20 @@ void ieee80211_stop_queue(struct ieee80211_hw *hw, int queue) | |||
344 | { | 377 | { |
345 | struct ieee80211_local *local = hw_to_local(hw); | 378 | struct ieee80211_local *local = hw_to_local(hw); |
346 | 379 | ||
347 | if (!ieee80211_qdisc_installed(local->mdev) && queue == 0) | 380 | if (ieee80211_is_multiqueue(local)) { |
381 | netif_stop_subqueue(local->mdev, queue); | ||
382 | } else { | ||
383 | WARN_ON(queue != 0); | ||
348 | netif_stop_queue(local->mdev); | 384 | netif_stop_queue(local->mdev); |
349 | set_bit(IEEE80211_LINK_STATE_XOFF, &local->state[queue]); | 385 | } |
350 | } | 386 | } |
351 | EXPORT_SYMBOL(ieee80211_stop_queue); | 387 | EXPORT_SYMBOL(ieee80211_stop_queue); |
352 | 388 | ||
353 | void ieee80211_start_queues(struct ieee80211_hw *hw) | ||
354 | { | ||
355 | struct ieee80211_local *local = hw_to_local(hw); | ||
356 | int i; | ||
357 | |||
358 | for (i = 0; i < local->hw.queues; i++) | ||
359 | clear_bit(IEEE80211_LINK_STATE_XOFF, &local->state[i]); | ||
360 | if (!ieee80211_qdisc_installed(local->mdev)) | ||
361 | netif_start_queue(local->mdev); | ||
362 | } | ||
363 | EXPORT_SYMBOL(ieee80211_start_queues); | ||
364 | |||
365 | void ieee80211_stop_queues(struct ieee80211_hw *hw) | 389 | void ieee80211_stop_queues(struct ieee80211_hw *hw) |
366 | { | 390 | { |
367 | int i; | 391 | int i; |
368 | 392 | ||
369 | for (i = 0; i < hw->queues; i++) | 393 | for (i = 0; i < ieee80211_num_queues(hw); i++) |
370 | ieee80211_stop_queue(hw, i); | 394 | ieee80211_stop_queue(hw, i); |
371 | } | 395 | } |
372 | EXPORT_SYMBOL(ieee80211_stop_queues); | 396 | EXPORT_SYMBOL(ieee80211_stop_queues); |
@@ -375,7 +399,7 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw) | |||
375 | { | 399 | { |
376 | int i; | 400 | int i; |
377 | 401 | ||
378 | for (i = 0; i < hw->queues; i++) | 402 | for (i = 0; i < hw->queues + hw->ampdu_queues; i++) |
379 | ieee80211_wake_queue(hw, i); | 403 | ieee80211_wake_queue(hw, i); |
380 | } | 404 | } |
381 | EXPORT_SYMBOL(ieee80211_wake_queues); | 405 | EXPORT_SYMBOL(ieee80211_wake_queues); |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index affcecd78c1..872d2fcd1a5 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -84,24 +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 ((skb_headroom(skb) < WEP_IV_LEN || | 93 | if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN || |
97 | skb_tailroom(skb) < WEP_ICV_LEN)) { | 94 | skb_headroom(skb) < WEP_IV_LEN)) |
98 | I802_DEBUG_INC(local->tx_expand_skb_head); | 95 | return NULL; |
99 | if (unlikely(pskb_expand_head(skb, WEP_IV_LEN, WEP_ICV_LEN, | ||
100 | GFP_ATOMIC))) | ||
101 | return NULL; | ||
102 | } | ||
103 | 96 | ||
104 | hdrlen = ieee80211_get_hdrlen(fc); | 97 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
105 | newhdr = skb_push(skb, WEP_IV_LEN); | 98 | newhdr = skb_push(skb, WEP_IV_LEN); |
106 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); | 99 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); |
107 | ieee80211_wep_get_iv(local, key, newhdr + hdrlen); | 100 | ieee80211_wep_get_iv(local, key, newhdr + hdrlen); |
@@ -113,12 +106,10 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local, | |||
113 | struct sk_buff *skb, | 106 | struct sk_buff *skb, |
114 | struct ieee80211_key *key) | 107 | struct ieee80211_key *key) |
115 | { | 108 | { |
116 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 109 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
117 | u16 fc; | 110 | unsigned int hdrlen; |
118 | int hdrlen; | ||
119 | 111 | ||
120 | fc = le16_to_cpu(hdr->frame_control); | 112 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
121 | hdrlen = ieee80211_get_hdrlen(fc); | ||
122 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); | 113 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); |
123 | skb_pull(skb, WEP_IV_LEN); | 114 | skb_pull(skb, WEP_IV_LEN); |
124 | } | 115 | } |
@@ -228,17 +219,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
228 | u32 klen; | 219 | u32 klen; |
229 | u8 *rc4key; | 220 | u8 *rc4key; |
230 | u8 keyidx; | 221 | u8 keyidx; |
231 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 222 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
232 | u16 fc; | 223 | unsigned int hdrlen; |
233 | int hdrlen; | ||
234 | size_t len; | 224 | size_t len; |
235 | int ret = 0; | 225 | int ret = 0; |
236 | 226 | ||
237 | fc = le16_to_cpu(hdr->frame_control); | 227 | if (!ieee80211_has_protected(hdr->frame_control)) |
238 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | ||
239 | return -1; | 228 | return -1; |
240 | 229 | ||
241 | hdrlen = ieee80211_get_hdrlen(fc); | 230 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
242 | 231 | ||
243 | if (skb->len < 8 + hdrlen) | 232 | if (skb->len < 8 + hdrlen) |
244 | return -1; | 233 | return -1; |
@@ -264,11 +253,8 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
264 | 253 | ||
265 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, | 254 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, |
266 | skb->data + hdrlen + WEP_IV_LEN, | 255 | skb->data + hdrlen + WEP_IV_LEN, |
267 | len)) { | 256 | len)) |
268 | if (net_ratelimit()) | ||
269 | printk(KERN_DEBUG "WEP decrypt failed (ICV)\n"); | ||
270 | ret = -1; | 257 | ret = -1; |
271 | } | ||
272 | 258 | ||
273 | kfree(rc4key); | 259 | kfree(rc4key); |
274 | 260 | ||
@@ -285,17 +271,15 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
285 | 271 | ||
286 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) | 272 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) |
287 | { | 273 | { |
288 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 274 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
289 | u16 fc; | 275 | unsigned int hdrlen; |
290 | int hdrlen; | ||
291 | u8 *ivpos; | 276 | u8 *ivpos; |
292 | u32 iv; | 277 | u32 iv; |
293 | 278 | ||
294 | fc = le16_to_cpu(hdr->frame_control); | 279 | if (!ieee80211_has_protected(hdr->frame_control)) |
295 | if (!(fc & IEEE80211_FCTL_PROTECTED)) | ||
296 | return NULL; | 280 | return NULL; |
297 | 281 | ||
298 | hdrlen = ieee80211_get_hdrlen(fc); | 282 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
299 | ivpos = skb->data + hdrlen; | 283 | ivpos = skb->data + hdrlen; |
300 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; | 284 | iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; |
301 | 285 | ||
@@ -314,14 +298,8 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
314 | return RX_CONTINUE; | 298 | return RX_CONTINUE; |
315 | 299 | ||
316 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { | 300 | if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { |
317 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { | 301 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
318 | #ifdef CONFIG_MAC80211_DEBUG | ||
319 | if (net_ratelimit()) | ||
320 | printk(KERN_DEBUG "%s: RX WEP frame, decrypt " | ||
321 | "failed\n", rx->dev->name); | ||
322 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
323 | return RX_DROP_UNUSABLE; | 302 | return RX_DROP_UNUSABLE; |
324 | } | ||
325 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { | 303 | } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { |
326 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 304 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
327 | /* remove ICV */ | 305 | /* remove ICV */ |
@@ -333,11 +311,16 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
333 | 311 | ||
334 | static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | 312 | static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
335 | { | 313 | { |
314 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
315 | |||
316 | info->control.iv_len = WEP_IV_LEN; | ||
317 | info->control.icv_len = WEP_ICV_LEN; | ||
318 | |||
336 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { | 319 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { |
337 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) | 320 | if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) |
338 | return -1; | 321 | return -1; |
339 | } else { | 322 | } else { |
340 | tx->control->key_idx = tx->key->conf.hw_key_idx; | 323 | info->control.hw_key = &tx->key->conf; |
341 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { | 324 | if (tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) { |
342 | if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) | 325 | if (!ieee80211_wep_add_iv(tx->local, skb, tx->key)) |
343 | return -1; | 326 | return -1; |
@@ -349,8 +332,6 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
349 | ieee80211_tx_result | 332 | ieee80211_tx_result |
350 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) | 333 | ieee80211_crypto_wep_encrypt(struct ieee80211_tx_data *tx) |
351 | { | 334 | { |
352 | tx->control->iv_len = WEP_IV_LEN; | ||
353 | tx->control->icv_len = WEP_ICV_LEN; | ||
354 | ieee80211_tx_set_protected(tx); | 335 | ieee80211_tx_set_protected(tx); |
355 | 336 | ||
356 | if (wep_encrypt_skb(tx, tx->skb) < 0) { | 337 | if (wep_encrypt_skb(tx, tx->skb) < 0) { |
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h index 363779c5065..e587172115b 100644 --- a/net/mac80211/wep.h +++ b/net/mac80211/wep.h | |||
@@ -26,7 +26,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, | |||
26 | struct ieee80211_key *key); | 26 | struct ieee80211_key *key); |
27 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, | 27 | int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, |
28 | struct ieee80211_key *key); | 28 | struct ieee80211_key *key); |
29 | u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); | 29 | u8 *ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); |
30 | 30 | ||
31 | ieee80211_rx_result | 31 | ieee80211_rx_result |
32 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); | 32 | ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx); |
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c index e8404212ad5..1babb979fe0 100644 --- a/net/mac80211/wext.c +++ b/net/mac80211/wext.c | |||
@@ -142,7 +142,39 @@ static int ieee80211_ioctl_giwname(struct net_device *dev, | |||
142 | struct iw_request_info *info, | 142 | struct iw_request_info *info, |
143 | char *name, char *extra) | 143 | char *name, char *extra) |
144 | { | 144 | { |
145 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); | ||
146 | struct ieee80211_supported_band *sband; | ||
147 | u8 is_ht = 0, is_a = 0, is_b = 0, is_g = 0; | ||
148 | |||
149 | |||
150 | sband = local->hw.wiphy->bands[IEEE80211_BAND_5GHZ]; | ||
151 | if (sband) { | ||
152 | is_a = 1; | ||
153 | is_ht |= sband->ht_info.ht_supported; | ||
154 | } | ||
155 | |||
156 | sband = local->hw.wiphy->bands[IEEE80211_BAND_2GHZ]; | ||
157 | if (sband) { | ||
158 | int i; | ||
159 | /* Check for mandatory rates */ | ||
160 | for (i = 0; i < sband->n_bitrates; i++) { | ||
161 | if (sband->bitrates[i].bitrate == 10) | ||
162 | is_b = 1; | ||
163 | if (sband->bitrates[i].bitrate == 60) | ||
164 | is_g = 1; | ||
165 | } | ||
166 | is_ht |= sband->ht_info.ht_supported; | ||
167 | } | ||
168 | |||
145 | strcpy(name, "IEEE 802.11"); | 169 | strcpy(name, "IEEE 802.11"); |
170 | if (is_a) | ||
171 | strcat(name, "a"); | ||
172 | if (is_b) | ||
173 | strcat(name, "b"); | ||
174 | if (is_g) | ||
175 | strcat(name, "g"); | ||
176 | if (is_ht) | ||
177 | strcat(name, "n"); | ||
146 | 178 | ||
147 | return 0; | 179 | return 0; |
148 | } | 180 | } |
@@ -176,14 +208,26 @@ static int ieee80211_ioctl_giwrange(struct net_device *dev, | |||
176 | range->num_encoding_sizes = 2; | 208 | range->num_encoding_sizes = 2; |
177 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; | 209 | range->max_encoding_tokens = NUM_DEFAULT_KEYS; |
178 | 210 | ||
179 | range->max_qual.qual = local->hw.max_signal; | 211 | if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC || |
180 | range->max_qual.level = local->hw.max_rssi; | 212 | local->hw.flags & IEEE80211_HW_SIGNAL_DB) |
181 | range->max_qual.noise = local->hw.max_noise; | 213 | range->max_qual.level = local->hw.max_signal; |
214 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | ||
215 | range->max_qual.level = -110; | ||
216 | else | ||
217 | range->max_qual.level = 0; | ||
218 | |||
219 | if (local->hw.flags & IEEE80211_HW_NOISE_DBM) | ||
220 | range->max_qual.noise = -110; | ||
221 | else | ||
222 | range->max_qual.noise = 0; | ||
223 | |||
224 | range->max_qual.qual = 100; | ||
182 | range->max_qual.updated = local->wstats_flags; | 225 | range->max_qual.updated = local->wstats_flags; |
183 | 226 | ||
184 | range->avg_qual.qual = local->hw.max_signal/2; | 227 | range->avg_qual.qual = 50; |
185 | range->avg_qual.level = 0; | 228 | /* not always true but better than nothing */ |
186 | range->avg_qual.noise = 0; | 229 | range->avg_qual.level = range->max_qual.level / 2; |
230 | range->avg_qual.noise = range->max_qual.noise / 2; | ||
187 | range->avg_qual.updated = local->wstats_flags; | 231 | range->avg_qual.updated = local->wstats_flags; |
188 | 232 | ||
189 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | | 233 | range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 | |
@@ -562,7 +606,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev, | |||
562 | if (local->sta_sw_scanning || local->sta_hw_scanning) | 606 | if (local->sta_sw_scanning || local->sta_hw_scanning) |
563 | return -EAGAIN; | 607 | return -EAGAIN; |
564 | 608 | ||
565 | res = ieee80211_sta_scan_results(dev, extra, data->length); | 609 | res = ieee80211_sta_scan_results(dev, info, extra, data->length); |
566 | if (res >= 0) { | 610 | if (res >= 0) { |
567 | data->length = res; | 611 | data->length = res; |
568 | return 0; | 612 | return 0; |
@@ -716,6 +760,9 @@ static int ieee80211_ioctl_siwrts(struct net_device *dev, | |||
716 | 760 | ||
717 | if (rts->disabled) | 761 | if (rts->disabled) |
718 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | 762 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; |
763 | else if (!rts->fixed) | ||
764 | /* if the rts value is not fixed, then take default */ | ||
765 | local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; | ||
719 | else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) | 766 | else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) |
720 | return -EINVAL; | 767 | return -EINVAL; |
721 | else | 768 | else |
@@ -944,6 +991,19 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev, | |||
944 | erq->length = sdata->keys[idx]->conf.keylen; | 991 | erq->length = sdata->keys[idx]->conf.keylen; |
945 | erq->flags |= IW_ENCODE_ENABLED; | 992 | erq->flags |= IW_ENCODE_ENABLED; |
946 | 993 | ||
994 | if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { | ||
995 | struct ieee80211_if_sta *ifsta = &sdata->u.sta; | ||
996 | switch (ifsta->auth_alg) { | ||
997 | case WLAN_AUTH_OPEN: | ||
998 | case WLAN_AUTH_LEAP: | ||
999 | erq->flags |= IW_ENCODE_OPEN; | ||
1000 | break; | ||
1001 | case WLAN_AUTH_SHARED_KEY: | ||
1002 | erq->flags |= IW_ENCODE_RESTRICTED; | ||
1003 | break; | ||
1004 | } | ||
1005 | } | ||
1006 | |||
947 | return 0; | 1007 | return 0; |
948 | } | 1008 | } |
949 | 1009 | ||
@@ -1015,8 +1075,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev | |||
1015 | wstats->qual.noise = 0; | 1075 | wstats->qual.noise = 0; |
1016 | wstats->qual.updated = IW_QUAL_ALL_INVALID; | 1076 | wstats->qual.updated = IW_QUAL_ALL_INVALID; |
1017 | } else { | 1077 | } else { |
1018 | wstats->qual.level = sta->last_rssi; | 1078 | wstats->qual.level = sta->last_signal; |
1019 | wstats->qual.qual = sta->last_signal; | 1079 | wstats->qual.qual = sta->last_qual; |
1020 | wstats->qual.noise = sta->last_noise; | 1080 | wstats->qual.noise = sta->last_noise; |
1021 | wstats->qual.updated = local->wstats_flags; | 1081 | wstats->qual.updated = local->wstats_flags; |
1022 | } | 1082 | } |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 5d09e8698b5..ffe1af82fa4 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -19,16 +19,22 @@ | |||
19 | #include "wme.h" | 19 | #include "wme.h" |
20 | 20 | ||
21 | /* maximum number of hardware queues we support. */ | 21 | /* maximum number of hardware queues we support. */ |
22 | #define TC_80211_MAX_QUEUES 16 | 22 | #define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES) |
23 | /* current number of hardware queues we support. */ | ||
24 | #define QD_NUM(hw) ((hw)->queues + (hw)->ampdu_queues) | ||
23 | 25 | ||
26 | /* | ||
27 | * Default mapping in classifier to work with default | ||
28 | * queue setup. | ||
29 | */ | ||
24 | const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; | 30 | const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; |
25 | 31 | ||
26 | struct ieee80211_sched_data | 32 | struct ieee80211_sched_data |
27 | { | 33 | { |
28 | unsigned long qdisc_pool[BITS_TO_LONGS(TC_80211_MAX_QUEUES)]; | 34 | unsigned long qdisc_pool[BITS_TO_LONGS(QD_MAX_QUEUES)]; |
29 | struct tcf_proto *filter_list; | 35 | struct tcf_proto *filter_list; |
30 | struct Qdisc *queues[TC_80211_MAX_QUEUES]; | 36 | struct Qdisc *queues[QD_MAX_QUEUES]; |
31 | struct sk_buff_head requeued[TC_80211_MAX_QUEUES]; | 37 | struct sk_buff_head requeued[QD_MAX_QUEUES]; |
32 | }; | 38 | }; |
33 | 39 | ||
34 | static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0}; | 40 | static const char llc_ip_hdr[8] = {0xAA, 0xAA, 0x3, 0, 0, 0, 0x08, 0}; |
@@ -95,28 +101,22 @@ static inline int wme_downgrade_ac(struct sk_buff *skb) | |||
95 | 101 | ||
96 | /* positive return value indicates which queue to use | 102 | /* positive return value indicates which queue to use |
97 | * negative return value indicates to drop the frame */ | 103 | * negative return value indicates to drop the frame */ |
98 | static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) | 104 | static int classify80211(struct sk_buff *skb, struct Qdisc *qd) |
99 | { | 105 | { |
100 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | 106 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); |
101 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 107 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
102 | unsigned short fc = le16_to_cpu(hdr->frame_control); | ||
103 | int qos; | ||
104 | 108 | ||
105 | /* see if frame is data or non data frame */ | 109 | if (!ieee80211_is_data(hdr->frame_control)) { |
106 | if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA)) { | ||
107 | /* management frames go on AC_VO queue, but are sent | 110 | /* management frames go on AC_VO queue, but are sent |
108 | * without QoS control fields */ | 111 | * without QoS control fields */ |
109 | return IEEE80211_TX_QUEUE_DATA0; | 112 | return 0; |
110 | } | 113 | } |
111 | 114 | ||
112 | if (0 /* injected */) { | 115 | if (0 /* injected */) { |
113 | /* use AC from radiotap */ | 116 | /* use AC from radiotap */ |
114 | } | 117 | } |
115 | 118 | ||
116 | /* is this a QoS frame? */ | 119 | if (!ieee80211_is_data_qos(hdr->frame_control)) { |
117 | qos = fc & IEEE80211_STYPE_QOS_DATA; | ||
118 | |||
119 | if (!qos) { | ||
120 | skb->priority = 0; /* required for correct WPA/11i MIC */ | 120 | skb->priority = 0; /* required for correct WPA/11i MIC */ |
121 | return ieee802_1d_to_ac[skb->priority]; | 121 | return ieee802_1d_to_ac[skb->priority]; |
122 | } | 122 | } |
@@ -141,29 +141,28 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) | |||
141 | static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | 141 | static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) |
142 | { | 142 | { |
143 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | 143 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); |
144 | struct ieee80211_hw *hw = &local->hw; | ||
144 | struct ieee80211_sched_data *q = qdisc_priv(qd); | 145 | struct ieee80211_sched_data *q = qdisc_priv(qd); |
145 | struct ieee80211_tx_packet_data *pkt_data = | 146 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
146 | (struct ieee80211_tx_packet_data *) skb->cb; | ||
147 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 147 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
148 | unsigned short fc = le16_to_cpu(hdr->frame_control); | ||
149 | struct Qdisc *qdisc; | 148 | struct Qdisc *qdisc; |
150 | int err, queue; | ||
151 | struct sta_info *sta; | 149 | struct sta_info *sta; |
150 | int err, queue; | ||
152 | u8 tid; | 151 | u8 tid; |
153 | 152 | ||
154 | if (pkt_data->flags & IEEE80211_TXPD_REQUEUE) { | 153 | if (info->flags & IEEE80211_TX_CTL_REQUEUE) { |
155 | queue = pkt_data->queue; | 154 | queue = skb_get_queue_mapping(skb); |
156 | rcu_read_lock(); | 155 | rcu_read_lock(); |
157 | sta = sta_info_get(local, hdr->addr1); | 156 | sta = sta_info_get(local, hdr->addr1); |
158 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | 157 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; |
159 | if (sta) { | 158 | if (sta) { |
160 | int ampdu_queue = sta->tid_to_tx_q[tid]; | 159 | int ampdu_queue = sta->tid_to_tx_q[tid]; |
161 | if ((ampdu_queue < local->hw.queues) && | 160 | if ((ampdu_queue < QD_NUM(hw)) && |
162 | test_bit(ampdu_queue, q->qdisc_pool)) { | 161 | test_bit(ampdu_queue, q->qdisc_pool)) { |
163 | queue = ampdu_queue; | 162 | queue = ampdu_queue; |
164 | pkt_data->flags |= IEEE80211_TXPD_AMPDU; | 163 | info->flags |= IEEE80211_TX_CTL_AMPDU; |
165 | } else { | 164 | } else { |
166 | pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; | 165 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
167 | } | 166 | } |
168 | } | 167 | } |
169 | rcu_read_unlock(); | 168 | rcu_read_unlock(); |
@@ -174,18 +173,20 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
174 | 173 | ||
175 | queue = classify80211(skb, qd); | 174 | queue = classify80211(skb, qd); |
176 | 175 | ||
176 | if (unlikely(queue >= local->hw.queues)) | ||
177 | queue = local->hw.queues - 1; | ||
178 | |||
177 | /* now we know the 1d priority, fill in the QoS header if there is one | 179 | /* now we know the 1d priority, fill in the QoS header if there is one |
178 | */ | 180 | */ |
179 | if (WLAN_FC_IS_QOS_DATA(fc)) { | 181 | if (ieee80211_is_data_qos(hdr->frame_control)) { |
180 | u8 *p = skb->data + ieee80211_get_hdrlen(fc) - 2; | 182 | u8 *p = ieee80211_get_qos_ctl(hdr); |
181 | u8 ack_policy = 0; | 183 | u8 ack_policy = 0; |
182 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | 184 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; |
183 | if (local->wifi_wme_noack_test) | 185 | if (local->wifi_wme_noack_test) |
184 | ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << | 186 | ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << |
185 | QOS_CONTROL_ACK_POLICY_SHIFT; | 187 | QOS_CONTROL_ACK_POLICY_SHIFT; |
186 | /* qos header is 2 bytes, second reserved */ | 188 | /* qos header is 2 bytes, second reserved */ |
187 | *p = ack_policy | tid; | 189 | *p++ = ack_policy | tid; |
188 | p++; | ||
189 | *p = 0; | 190 | *p = 0; |
190 | 191 | ||
191 | rcu_read_lock(); | 192 | rcu_read_lock(); |
@@ -193,35 +194,24 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
193 | sta = sta_info_get(local, hdr->addr1); | 194 | sta = sta_info_get(local, hdr->addr1); |
194 | if (sta) { | 195 | if (sta) { |
195 | int ampdu_queue = sta->tid_to_tx_q[tid]; | 196 | int ampdu_queue = sta->tid_to_tx_q[tid]; |
196 | if ((ampdu_queue < local->hw.queues) && | 197 | if ((ampdu_queue < QD_NUM(hw)) && |
197 | test_bit(ampdu_queue, q->qdisc_pool)) { | 198 | test_bit(ampdu_queue, q->qdisc_pool)) { |
198 | queue = ampdu_queue; | 199 | queue = ampdu_queue; |
199 | pkt_data->flags |= IEEE80211_TXPD_AMPDU; | 200 | info->flags |= IEEE80211_TX_CTL_AMPDU; |
200 | } else { | 201 | } else { |
201 | pkt_data->flags &= ~IEEE80211_TXPD_AMPDU; | 202 | info->flags &= ~IEEE80211_TX_CTL_AMPDU; |
202 | } | 203 | } |
203 | } | 204 | } |
204 | 205 | ||
205 | rcu_read_unlock(); | 206 | rcu_read_unlock(); |
206 | } | 207 | } |
207 | 208 | ||
208 | if (unlikely(queue >= local->hw.queues)) { | ||
209 | #if 0 | ||
210 | if (net_ratelimit()) { | ||
211 | printk(KERN_DEBUG "%s - queue=%d (hw does not " | ||
212 | "support) -> %d\n", | ||
213 | __func__, queue, local->hw.queues - 1); | ||
214 | } | ||
215 | #endif | ||
216 | queue = local->hw.queues - 1; | ||
217 | } | ||
218 | |||
219 | if (unlikely(queue < 0)) { | 209 | if (unlikely(queue < 0)) { |
220 | kfree_skb(skb); | 210 | kfree_skb(skb); |
221 | err = NET_XMIT_DROP; | 211 | err = NET_XMIT_DROP; |
222 | } else { | 212 | } else { |
223 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; | 213 | tid = skb->priority & QOS_CONTROL_TAG1D_MASK; |
224 | pkt_data->queue = (unsigned int) queue; | 214 | skb_set_queue_mapping(skb, queue); |
225 | qdisc = q->queues[queue]; | 215 | qdisc = q->queues[queue]; |
226 | err = qdisc->enqueue(skb, qdisc); | 216 | err = qdisc->enqueue(skb, qdisc); |
227 | if (err == NET_XMIT_SUCCESS) { | 217 | if (err == NET_XMIT_SUCCESS) { |
@@ -242,13 +232,11 @@ static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) | |||
242 | static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) | 232 | static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) |
243 | { | 233 | { |
244 | struct ieee80211_sched_data *q = qdisc_priv(qd); | 234 | struct ieee80211_sched_data *q = qdisc_priv(qd); |
245 | struct ieee80211_tx_packet_data *pkt_data = | ||
246 | (struct ieee80211_tx_packet_data *) skb->cb; | ||
247 | struct Qdisc *qdisc; | 235 | struct Qdisc *qdisc; |
248 | int err; | 236 | int err; |
249 | 237 | ||
250 | /* we recorded which queue to use earlier! */ | 238 | /* we recorded which queue to use earlier! */ |
251 | qdisc = q->queues[pkt_data->queue]; | 239 | qdisc = q->queues[skb_get_queue_mapping(skb)]; |
252 | 240 | ||
253 | if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) { | 241 | if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) { |
254 | qd->q.qlen++; | 242 | qd->q.qlen++; |
@@ -270,13 +258,10 @@ static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd) | |||
270 | int queue; | 258 | int queue; |
271 | 259 | ||
272 | /* check all the h/w queues in numeric/priority order */ | 260 | /* check all the h/w queues in numeric/priority order */ |
273 | for (queue = 0; queue < hw->queues; queue++) { | 261 | for (queue = 0; queue < QD_NUM(hw); queue++) { |
274 | /* see if there is room in this hardware queue */ | 262 | /* see if there is room in this hardware queue */ |
275 | if ((test_bit(IEEE80211_LINK_STATE_XOFF, | 263 | if (__netif_subqueue_stopped(local->mdev, queue) || |
276 | &local->state[queue])) || | 264 | !test_bit(queue, q->qdisc_pool)) |
277 | (test_bit(IEEE80211_LINK_STATE_PENDING, | ||
278 | &local->state[queue])) || | ||
279 | (!test_bit(queue, q->qdisc_pool))) | ||
280 | continue; | 265 | continue; |
281 | 266 | ||
282 | /* there is space - try and get a frame */ | 267 | /* there is space - try and get a frame */ |
@@ -308,7 +293,7 @@ static void wme_qdiscop_reset(struct Qdisc* qd) | |||
308 | 293 | ||
309 | /* QUESTION: should we have some hardware flush functionality here? */ | 294 | /* QUESTION: should we have some hardware flush functionality here? */ |
310 | 295 | ||
311 | for (queue = 0; queue < hw->queues; queue++) { | 296 | for (queue = 0; queue < QD_NUM(hw); queue++) { |
312 | skb_queue_purge(&q->requeued[queue]); | 297 | skb_queue_purge(&q->requeued[queue]); |
313 | qdisc_reset(q->queues[queue]); | 298 | qdisc_reset(q->queues[queue]); |
314 | } | 299 | } |
@@ -325,7 +310,7 @@ static void wme_qdiscop_destroy(struct Qdisc* qd) | |||
325 | 310 | ||
326 | tcf_destroy_chain(&q->filter_list); | 311 | tcf_destroy_chain(&q->filter_list); |
327 | 312 | ||
328 | for (queue=0; queue < hw->queues; queue++) { | 313 | for (queue = 0; queue < QD_NUM(hw); queue++) { |
329 | skb_queue_purge(&q->requeued[queue]); | 314 | skb_queue_purge(&q->requeued[queue]); |
330 | qdisc_destroy(q->queues[queue]); | 315 | qdisc_destroy(q->queues[queue]); |
331 | q->queues[queue] = &noop_qdisc; | 316 | q->queues[queue] = &noop_qdisc; |
@@ -336,17 +321,6 @@ static void wme_qdiscop_destroy(struct Qdisc* qd) | |||
336 | /* called whenever parameters are updated on existing qdisc */ | 321 | /* called whenever parameters are updated on existing qdisc */ |
337 | static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) | 322 | static int wme_qdiscop_tune(struct Qdisc *qd, struct nlattr *opt) |
338 | { | 323 | { |
339 | /* struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
340 | */ | ||
341 | /* check our options block is the right size */ | ||
342 | /* copy any options to our local structure */ | ||
343 | /* Ignore options block for now - always use static mapping | ||
344 | struct tc_ieee80211_qopt *qopt = nla_data(opt); | ||
345 | |||
346 | if (opt->nla_len < nla_attr_size(sizeof(*qopt))) | ||
347 | return -EINVAL; | ||
348 | memcpy(q->tag2queue, qopt->tag2queue, sizeof(qopt->tag2queue)); | ||
349 | */ | ||
350 | return 0; | 324 | return 0; |
351 | } | 325 | } |
352 | 326 | ||
@@ -357,7 +331,7 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) | |||
357 | struct ieee80211_sched_data *q = qdisc_priv(qd); | 331 | struct ieee80211_sched_data *q = qdisc_priv(qd); |
358 | struct net_device *dev = qd->dev; | 332 | struct net_device *dev = qd->dev; |
359 | struct ieee80211_local *local; | 333 | struct ieee80211_local *local; |
360 | int queues; | 334 | struct ieee80211_hw *hw; |
361 | int err = 0, i; | 335 | int err = 0, i; |
362 | 336 | ||
363 | /* check that device is a mac80211 device */ | 337 | /* check that device is a mac80211 device */ |
@@ -365,29 +339,26 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) | |||
365 | dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) | 339 | dev->ieee80211_ptr->wiphy->privid != mac80211_wiphy_privid) |
366 | return -EINVAL; | 340 | return -EINVAL; |
367 | 341 | ||
368 | /* check this device is an ieee80211 master type device */ | 342 | local = wdev_priv(dev->ieee80211_ptr); |
369 | if (dev->type != ARPHRD_IEEE80211) | 343 | hw = &local->hw; |
344 | |||
345 | /* only allow on master dev */ | ||
346 | if (dev != local->mdev) | ||
370 | return -EINVAL; | 347 | return -EINVAL; |
371 | 348 | ||
372 | /* check that there is no qdisc currently attached to device | 349 | /* ensure that we are root qdisc */ |
373 | * this ensures that we will be the root qdisc. (I can't find a better | 350 | if (qd->parent != TC_H_ROOT) |
374 | * way to test this explicitly) */ | ||
375 | if (dev->qdisc_sleeping != &noop_qdisc) | ||
376 | return -EINVAL; | 351 | return -EINVAL; |
377 | 352 | ||
378 | if (qd->flags & TCQ_F_INGRESS) | 353 | if (qd->flags & TCQ_F_INGRESS) |
379 | return -EINVAL; | 354 | return -EINVAL; |
380 | 355 | ||
381 | local = wdev_priv(dev->ieee80211_ptr); | ||
382 | queues = local->hw.queues; | ||
383 | |||
384 | /* if options were passed in, set them */ | 356 | /* if options were passed in, set them */ |
385 | if (opt) { | 357 | if (opt) |
386 | err = wme_qdiscop_tune(qd, opt); | 358 | err = wme_qdiscop_tune(qd, opt); |
387 | } | ||
388 | 359 | ||
389 | /* create child queues */ | 360 | /* create child queues */ |
390 | for (i = 0; i < queues; i++) { | 361 | for (i = 0; i < QD_NUM(hw); i++) { |
391 | skb_queue_head_init(&q->requeued[i]); | 362 | skb_queue_head_init(&q->requeued[i]); |
392 | q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops, | 363 | q->queues[i] = qdisc_create_dflt(qd->dev, &pfifo_qdisc_ops, |
393 | qd->handle); | 364 | qd->handle); |
@@ -398,8 +369,8 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) | |||
398 | } | 369 | } |
399 | } | 370 | } |
400 | 371 | ||
401 | /* reserve all legacy QoS queues */ | 372 | /* non-aggregation queues: reserve/mark as used */ |
402 | for (i = 0; i < min(IEEE80211_TX_QUEUE_DATA4, queues); i++) | 373 | for (i = 0; i < local->hw.queues; i++) |
403 | set_bit(i, q->qdisc_pool); | 374 | set_bit(i, q->qdisc_pool); |
404 | 375 | ||
405 | return err; | 376 | return err; |
@@ -407,16 +378,6 @@ static int wme_qdiscop_init(struct Qdisc *qd, struct nlattr *opt) | |||
407 | 378 | ||
408 | static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb) | 379 | static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb) |
409 | { | 380 | { |
410 | /* struct ieee80211_sched_data *q = qdisc_priv(qd); | ||
411 | unsigned char *p = skb->tail; | ||
412 | struct tc_ieee80211_qopt opt; | ||
413 | |||
414 | memcpy(&opt.tag2queue, q->tag2queue, TC_80211_MAX_TAG + 1); | ||
415 | NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); | ||
416 | */ return skb->len; | ||
417 | /* | ||
418 | nla_put_failure: | ||
419 | skb_trim(skb, p - skb->data);*/ | ||
420 | return -1; | 381 | return -1; |
421 | } | 382 | } |
422 | 383 | ||
@@ -429,7 +390,7 @@ static int wme_classop_graft(struct Qdisc *qd, unsigned long arg, | |||
429 | struct ieee80211_hw *hw = &local->hw; | 390 | struct ieee80211_hw *hw = &local->hw; |
430 | unsigned long queue = arg - 1; | 391 | unsigned long queue = arg - 1; |
431 | 392 | ||
432 | if (queue >= hw->queues) | 393 | if (queue >= QD_NUM(hw)) |
433 | return -EINVAL; | 394 | return -EINVAL; |
434 | 395 | ||
435 | if (!new) | 396 | if (!new) |
@@ -453,7 +414,7 @@ wme_classop_leaf(struct Qdisc *qd, unsigned long arg) | |||
453 | struct ieee80211_hw *hw = &local->hw; | 414 | struct ieee80211_hw *hw = &local->hw; |
454 | unsigned long queue = arg - 1; | 415 | unsigned long queue = arg - 1; |
455 | 416 | ||
456 | if (queue >= hw->queues) | 417 | if (queue >= QD_NUM(hw)) |
457 | return NULL; | 418 | return NULL; |
458 | 419 | ||
459 | return q->queues[queue]; | 420 | return q->queues[queue]; |
@@ -466,7 +427,7 @@ static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid) | |||
466 | struct ieee80211_hw *hw = &local->hw; | 427 | struct ieee80211_hw *hw = &local->hw; |
467 | unsigned long queue = TC_H_MIN(classid); | 428 | unsigned long queue = TC_H_MIN(classid); |
468 | 429 | ||
469 | if (queue - 1 >= hw->queues) | 430 | if (queue - 1 >= QD_NUM(hw)) |
470 | return 0; | 431 | return 0; |
471 | 432 | ||
472 | return queue; | 433 | return queue; |
@@ -492,7 +453,7 @@ static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent, | |||
492 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | 453 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); |
493 | struct ieee80211_hw *hw = &local->hw; | 454 | struct ieee80211_hw *hw = &local->hw; |
494 | 455 | ||
495 | if (cl - 1 > hw->queues) | 456 | if (cl - 1 > QD_NUM(hw)) |
496 | return -ENOENT; | 457 | return -ENOENT; |
497 | 458 | ||
498 | /* TODO: put code to program hardware queue parameters here, | 459 | /* TODO: put code to program hardware queue parameters here, |
@@ -509,7 +470,7 @@ static int wme_classop_delete(struct Qdisc *qd, unsigned long cl) | |||
509 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | 470 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); |
510 | struct ieee80211_hw *hw = &local->hw; | 471 | struct ieee80211_hw *hw = &local->hw; |
511 | 472 | ||
512 | if (cl - 1 > hw->queues) | 473 | if (cl - 1 > QD_NUM(hw)) |
513 | return -ENOENT; | 474 | return -ENOENT; |
514 | return 0; | 475 | return 0; |
515 | } | 476 | } |
@@ -522,7 +483,7 @@ static int wme_classop_dump_class(struct Qdisc *qd, unsigned long cl, | |||
522 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); | 483 | struct ieee80211_local *local = wdev_priv(qd->dev->ieee80211_ptr); |
523 | struct ieee80211_hw *hw = &local->hw; | 484 | struct ieee80211_hw *hw = &local->hw; |
524 | 485 | ||
525 | if (cl - 1 > hw->queues) | 486 | if (cl - 1 > QD_NUM(hw)) |
526 | return -ENOENT; | 487 | return -ENOENT; |
527 | tcm->tcm_handle = TC_H_MIN(cl); | 488 | tcm->tcm_handle = TC_H_MIN(cl); |
528 | tcm->tcm_parent = qd->handle; | 489 | tcm->tcm_parent = qd->handle; |
@@ -540,7 +501,7 @@ static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg) | |||
540 | if (arg->stop) | 501 | if (arg->stop) |
541 | return; | 502 | return; |
542 | 503 | ||
543 | for (queue = 0; queue < hw->queues; queue++) { | 504 | for (queue = 0; queue < QD_NUM(hw); queue++) { |
544 | if (arg->count < arg->skip) { | 505 | if (arg->count < arg->skip) { |
545 | arg->count++; | 506 | arg->count++; |
546 | continue; | 507 | continue; |
@@ -657,10 +618,13 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | |||
657 | DECLARE_MAC_BUF(mac); | 618 | DECLARE_MAC_BUF(mac); |
658 | 619 | ||
659 | /* prepare the filter and save it for the SW queue | 620 | /* prepare the filter and save it for the SW queue |
660 | * matching the recieved HW queue */ | 621 | * matching the received HW queue */ |
622 | |||
623 | if (!local->hw.ampdu_queues) | ||
624 | return -EPERM; | ||
661 | 625 | ||
662 | /* try to get a Qdisc from the pool */ | 626 | /* try to get a Qdisc from the pool */ |
663 | for (i = IEEE80211_TX_QUEUE_BEACON; i < local->hw.queues; i++) | 627 | for (i = local->hw.queues; i < QD_NUM(&local->hw); i++) |
664 | if (!test_and_set_bit(i, q->qdisc_pool)) { | 628 | if (!test_and_set_bit(i, q->qdisc_pool)) { |
665 | ieee80211_stop_queue(local_to_hw(local), i); | 629 | ieee80211_stop_queue(local_to_hw(local), i); |
666 | sta->tid_to_tx_q[tid] = i; | 630 | sta->tid_to_tx_q[tid] = i; |
@@ -689,13 +653,14 @@ void ieee80211_ht_agg_queue_remove(struct ieee80211_local *local, | |||
689 | struct sta_info *sta, u16 tid, | 653 | struct sta_info *sta, u16 tid, |
690 | u8 requeue) | 654 | u8 requeue) |
691 | { | 655 | { |
656 | struct ieee80211_hw *hw = &local->hw; | ||
692 | struct ieee80211_sched_data *q = | 657 | struct ieee80211_sched_data *q = |
693 | qdisc_priv(local->mdev->qdisc_sleeping); | 658 | qdisc_priv(local->mdev->qdisc_sleeping); |
694 | int agg_queue = sta->tid_to_tx_q[tid]; | 659 | int agg_queue = sta->tid_to_tx_q[tid]; |
695 | 660 | ||
696 | /* return the qdisc to the pool */ | 661 | /* return the qdisc to the pool */ |
697 | clear_bit(agg_queue, q->qdisc_pool); | 662 | clear_bit(agg_queue, q->qdisc_pool); |
698 | sta->tid_to_tx_q[tid] = local->hw.queues; | 663 | sta->tid_to_tx_q[tid] = QD_NUM(hw); |
699 | 664 | ||
700 | if (requeue) | 665 | if (requeue) |
701 | ieee80211_requeue(local, agg_queue); | 666 | ieee80211_requeue(local, agg_queue); |
@@ -714,7 +679,6 @@ void ieee80211_requeue(struct ieee80211_local *local, int queue) | |||
714 | if (!qdisc || !qdisc->dequeue) | 679 | if (!qdisc || !qdisc->dequeue) |
715 | return; | 680 | return; |
716 | 681 | ||
717 | printk(KERN_DEBUG "requeue: qlen = %d\n", qdisc->q.qlen); | ||
718 | for (len = qdisc->q.qlen; len > 0; len--) { | 682 | for (len = qdisc->q.qlen; len > 0; len--) { |
719 | skb = qdisc->dequeue(qdisc); | 683 | skb = qdisc->dequeue(qdisc); |
720 | root_qd->q.qlen--; | 684 | root_qd->q.qlen--; |
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index fcc6b05508c..bbdb5334481 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h | |||
@@ -31,7 +31,7 @@ static inline int WLAN_FC_IS_QOS_DATA(u16 fc) | |||
31 | return (fc & 0x8C) == 0x88; | 31 | return (fc & 0x8C) == 0x88; |
32 | } | 32 | } |
33 | 33 | ||
34 | #ifdef CONFIG_NET_SCHED | 34 | #ifdef CONFIG_MAC80211_QOS |
35 | void ieee80211_install_qdisc(struct net_device *dev); | 35 | void ieee80211_install_qdisc(struct net_device *dev); |
36 | int ieee80211_qdisc_installed(struct net_device *dev); | 36 | int ieee80211_qdisc_installed(struct net_device *dev); |
37 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, | 37 | int ieee80211_ht_agg_queue_add(struct ieee80211_local *local, |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 45709ada8fe..b414d5d92f3 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -24,46 +24,22 @@ static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, | |||
24 | { | 24 | { |
25 | struct ieee80211_hdr *hdr; | 25 | struct ieee80211_hdr *hdr; |
26 | size_t hdrlen; | 26 | size_t hdrlen; |
27 | u16 fc; | 27 | __le16 fc; |
28 | int a4_included; | ||
29 | u8 *pos; | ||
30 | 28 | ||
31 | hdr = (struct ieee80211_hdr *) skb->data; | 29 | hdr = (struct ieee80211_hdr *)skb->data; |
32 | fc = le16_to_cpu(hdr->frame_control); | 30 | fc = hdr->frame_control; |
33 | |||
34 | hdrlen = 24; | ||
35 | if ((fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) == | ||
36 | (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { | ||
37 | hdrlen += ETH_ALEN; | ||
38 | *sa = hdr->addr4; | ||
39 | *da = hdr->addr3; | ||
40 | } else if (fc & IEEE80211_FCTL_FROMDS) { | ||
41 | *sa = hdr->addr3; | ||
42 | *da = hdr->addr1; | ||
43 | } else if (fc & IEEE80211_FCTL_TODS) { | ||
44 | *sa = hdr->addr2; | ||
45 | *da = hdr->addr3; | ||
46 | } else { | ||
47 | *sa = hdr->addr2; | ||
48 | *da = hdr->addr1; | ||
49 | } | ||
50 | 31 | ||
51 | if (fc & 0x80) | 32 | hdrlen = ieee80211_hdrlen(fc); |
52 | hdrlen += 2; | 33 | |
34 | *sa = ieee80211_get_SA(hdr); | ||
35 | *da = ieee80211_get_DA(hdr); | ||
53 | 36 | ||
54 | *data = skb->data + hdrlen; | 37 | *data = skb->data + hdrlen; |
55 | *data_len = skb->len - hdrlen; | 38 | *data_len = skb->len - hdrlen; |
56 | 39 | ||
57 | a4_included = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | 40 | if (ieee80211_is_data_qos(fc)) |
58 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 41 | *qos_tid = (*ieee80211_get_qos_ctl(hdr) & 0x0f) | 0x80; |
59 | if ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 42 | else |
60 | fc & IEEE80211_STYPE_QOS_DATA) { | ||
61 | pos = (u8 *) &hdr->addr4; | ||
62 | if (a4_included) | ||
63 | pos += 6; | ||
64 | *qos_tid = pos[0] & 0x0f; | ||
65 | *qos_tid |= 0x80; /* qos_included flag */ | ||
66 | } else | ||
67 | *qos_tid = 0; | 43 | *qos_tid = 0; |
68 | 44 | ||
69 | return skb->len < hdrlen ? -1 : 0; | 45 | return skb->len < hdrlen ? -1 : 0; |
@@ -73,12 +49,13 @@ static int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, | |||
73 | ieee80211_tx_result | 49 | ieee80211_tx_result |
74 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | 50 | ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) |
75 | { | 51 | { |
76 | u8 *data, *sa, *da, *key, *mic, qos_tid; | 52 | u8 *data, *sa, *da, *key, *mic, qos_tid, key_offset; |
77 | size_t data_len; | 53 | size_t data_len; |
78 | u16 fc; | 54 | u16 fc; |
79 | struct sk_buff *skb = tx->skb; | 55 | struct sk_buff *skb = tx->skb; |
80 | int authenticator; | 56 | int authenticator; |
81 | int wpa_test = 0; | 57 | int wpa_test = 0; |
58 | int tail; | ||
82 | 59 | ||
83 | fc = tx->fc; | 60 | fc = tx->fc; |
84 | 61 | ||
@@ -98,24 +75,25 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
98 | return TX_CONTINUE; | 75 | return TX_CONTINUE; |
99 | } | 76 | } |
100 | 77 | ||
101 | if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { | 78 | tail = MICHAEL_MIC_LEN; |
102 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 79 | if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) |
103 | if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, | 80 | tail += TKIP_ICV_LEN; |
104 | MICHAEL_MIC_LEN + TKIP_ICV_LEN, | 81 | |
105 | GFP_ATOMIC))) { | 82 | if (WARN_ON(skb_tailroom(skb) < tail || |
106 | printk(KERN_DEBUG "%s: failed to allocate more memory " | 83 | skb_headroom(skb) < TKIP_IV_LEN)) |
107 | "for Michael MIC\n", tx->dev->name); | 84 | return TX_DROP; |
108 | return TX_DROP; | ||
109 | } | ||
110 | } | ||
111 | 85 | ||
112 | #if 0 | 86 | #if 0 |
113 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ | 87 | authenticator = fc & IEEE80211_FCTL_FROMDS; /* FIX */ |
114 | #else | 88 | #else |
115 | authenticator = 1; | 89 | authenticator = 1; |
116 | #endif | 90 | #endif |
117 | 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 |
118 | 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]; | ||
119 | mic = skb_put(skb, MICHAEL_MIC_LEN); | 97 | mic = skb_put(skb, MICHAEL_MIC_LEN); |
120 | 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); |
121 | 99 | ||
@@ -126,7 +104,7 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
126 | ieee80211_rx_result | 104 | ieee80211_rx_result |
127 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | 105 | ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) |
128 | { | 106 | { |
129 | u8 *data, *sa, *da, *key = NULL, qos_tid; | 107 | u8 *data, *sa, *da, *key = NULL, qos_tid, key_offset; |
130 | size_t data_len; | 108 | size_t data_len; |
131 | u16 fc; | 109 | u16 fc; |
132 | u8 mic[MICHAEL_MIC_LEN]; | 110 | u8 mic[MICHAEL_MIC_LEN]; |
@@ -157,16 +135,17 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
157 | #else | 135 | #else |
158 | authenticator = 1; | 136 | authenticator = 1; |
159 | #endif | 137 | #endif |
160 | 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 |
161 | 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]; | ||
162 | 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); |
163 | 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) { |
164 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) | 146 | if (!(rx->flags & IEEE80211_RX_RA_MATCH)) |
165 | return RX_DROP_UNUSABLE; | 147 | return RX_DROP_UNUSABLE; |
166 | 148 | ||
167 | printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " | ||
168 | "%s\n", rx->dev->name, print_mac(mac, sa)); | ||
169 | |||
170 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, | 149 | mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, |
171 | (void *) skb->data); | 150 | (void *) skb->data); |
172 | return RX_DROP_UNUSABLE; | 151 | return RX_DROP_UNUSABLE; |
@@ -176,59 +155,58 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
176 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); | 155 | skb_trim(skb, skb->len - MICHAEL_MIC_LEN); |
177 | 156 | ||
178 | /* update IV in key information to be able to detect replays */ | 157 | /* update IV in key information to be able to detect replays */ |
179 | rx->key->u.tkip.iv32_rx[rx->queue] = rx->tkip_iv32; | 158 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; |
180 | rx->key->u.tkip.iv16_rx[rx->queue] = rx->tkip_iv16; | 159 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; |
181 | 160 | ||
182 | return RX_CONTINUE; | 161 | return RX_CONTINUE; |
183 | } | 162 | } |
184 | 163 | ||
185 | 164 | ||
186 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, | 165 | static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
187 | struct sk_buff *skb, int test) | ||
188 | { | 166 | { |
189 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 167 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
190 | struct ieee80211_key *key = tx->key; | 168 | struct ieee80211_key *key = tx->key; |
191 | int hdrlen, len, tailneed; | 169 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
192 | u16 fc; | 170 | unsigned int hdrlen; |
171 | int len, tail; | ||
193 | u8 *pos; | 172 | u8 *pos; |
194 | 173 | ||
195 | fc = le16_to_cpu(hdr->frame_control); | 174 | info->control.icv_len = TKIP_ICV_LEN; |
196 | hdrlen = ieee80211_get_hdrlen(fc); | 175 | info->control.iv_len = TKIP_IV_LEN; |
176 | |||
177 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | ||
178 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
179 | /* hwaccel - with no need for preallocated room for IV/ICV */ | ||
180 | info->control.hw_key = &tx->key->conf; | ||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | ||
197 | len = skb->len - hdrlen; | 185 | len = skb->len - hdrlen; |
198 | 186 | ||
199 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 187 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
200 | tailneed = 0; | 188 | tail = 0; |
201 | else | 189 | else |
202 | tailneed = TKIP_ICV_LEN; | 190 | tail = TKIP_ICV_LEN; |
203 | 191 | ||
204 | if ((skb_headroom(skb) < TKIP_IV_LEN || | 192 | if (WARN_ON(skb_tailroom(skb) < tail || |
205 | skb_tailroom(skb) < tailneed)) { | 193 | skb_headroom(skb) < TKIP_IV_LEN)) |
206 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 194 | return -1; |
207 | if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed, | ||
208 | GFP_ATOMIC))) | ||
209 | return -1; | ||
210 | } | ||
211 | 195 | ||
212 | pos = skb_push(skb, TKIP_IV_LEN); | 196 | pos = skb_push(skb, TKIP_IV_LEN); |
213 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); | 197 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); |
214 | pos += hdrlen; | 198 | pos += hdrlen; |
215 | 199 | ||
216 | /* Increase IV for the frame */ | 200 | /* Increase IV for the frame */ |
217 | key->u.tkip.iv16++; | 201 | key->u.tkip.tx.iv16++; |
218 | if (key->u.tkip.iv16 == 0) | 202 | if (key->u.tkip.tx.iv16 == 0) |
219 | key->u.tkip.iv32++; | 203 | key->u.tkip.tx.iv32++; |
220 | 204 | ||
221 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 205 | if (tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
222 | hdr = (struct ieee80211_hdr *)skb->data; | ||
223 | |||
224 | /* hwaccel - with preallocated room for IV */ | 206 | /* hwaccel - with preallocated room for IV */ |
225 | ieee80211_tkip_add_iv(pos, key, | 207 | ieee80211_tkip_add_iv(pos, key, key->u.tkip.tx.iv16); |
226 | (u8) (key->u.tkip.iv16 >> 8), | ||
227 | (u8) (((key->u.tkip.iv16 >> 8) | 0x20) & | ||
228 | 0x7f), | ||
229 | (u8) key->u.tkip.iv16); | ||
230 | 208 | ||
231 | tx->control->key_idx = tx->key->conf.hw_key_idx; | 209 | info->control.hw_key = &tx->key->conf; |
232 | return 0; | 210 | return 0; |
233 | } | 211 | } |
234 | 212 | ||
@@ -246,28 +224,16 @@ ieee80211_tx_result | |||
246 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) | 224 | ieee80211_crypto_tkip_encrypt(struct ieee80211_tx_data *tx) |
247 | { | 225 | { |
248 | struct sk_buff *skb = tx->skb; | 226 | struct sk_buff *skb = tx->skb; |
249 | int wpa_test = 0, test = 0; | ||
250 | 227 | ||
251 | tx->control->icv_len = TKIP_ICV_LEN; | ||
252 | tx->control->iv_len = TKIP_IV_LEN; | ||
253 | ieee80211_tx_set_protected(tx); | 228 | ieee80211_tx_set_protected(tx); |
254 | 229 | ||
255 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 230 | if (tkip_encrypt_skb(tx, skb) < 0) |
256 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) && | ||
257 | !wpa_test) { | ||
258 | /* hwaccel - with no need for preallocated room for IV/ICV */ | ||
259 | tx->control->key_idx = tx->key->conf.hw_key_idx; | ||
260 | return TX_CONTINUE; | ||
261 | } | ||
262 | |||
263 | if (tkip_encrypt_skb(tx, skb, test) < 0) | ||
264 | return TX_DROP; | 231 | return TX_DROP; |
265 | 232 | ||
266 | if (tx->extra_frag) { | 233 | if (tx->extra_frag) { |
267 | int i; | 234 | int i; |
268 | for (i = 0; i < tx->num_extra_frag; i++) { | 235 | for (i = 0; i < tx->num_extra_frag; i++) { |
269 | if (tkip_encrypt_skb(tx, tx->extra_frag[i], test) | 236 | if (tkip_encrypt_skb(tx, tx->extra_frag[i]) < 0) |
270 | < 0) | ||
271 | return TX_DROP; | 237 | return TX_DROP; |
272 | } | 238 | } |
273 | } | 239 | } |
@@ -280,14 +246,12 @@ ieee80211_rx_result | |||
280 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | 246 | ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) |
281 | { | 247 | { |
282 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 248 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
283 | u16 fc; | ||
284 | int hdrlen, res, hwaccel = 0, wpa_test = 0; | 249 | int hdrlen, res, hwaccel = 0, wpa_test = 0; |
285 | struct ieee80211_key *key = rx->key; | 250 | struct ieee80211_key *key = rx->key; |
286 | struct sk_buff *skb = rx->skb; | 251 | struct sk_buff *skb = rx->skb; |
287 | DECLARE_MAC_BUF(mac); | 252 | DECLARE_MAC_BUF(mac); |
288 | 253 | ||
289 | fc = le16_to_cpu(hdr->frame_control); | 254 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
290 | hdrlen = ieee80211_get_hdrlen(fc); | ||
291 | 255 | ||
292 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 256 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) |
293 | return RX_CONTINUE; | 257 | return RX_CONTINUE; |
@@ -315,15 +279,8 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
315 | hdr->addr1, hwaccel, rx->queue, | 279 | hdr->addr1, hwaccel, rx->queue, |
316 | &rx->tkip_iv32, | 280 | &rx->tkip_iv32, |
317 | &rx->tkip_iv16); | 281 | &rx->tkip_iv16); |
318 | if (res != TKIP_DECRYPT_OK || wpa_test) { | 282 | if (res != TKIP_DECRYPT_OK || wpa_test) |
319 | #ifdef CONFIG_MAC80211_DEBUG | ||
320 | if (net_ratelimit()) | ||
321 | printk(KERN_DEBUG "%s: TKIP decrypt failed for RX " | ||
322 | "frame from %s (res=%d)\n", rx->dev->name, | ||
323 | print_mac(mac, rx->sta->addr), res); | ||
324 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
325 | return RX_DROP_UNUSABLE; | 283 | return RX_DROP_UNUSABLE; |
326 | } | ||
327 | 284 | ||
328 | /* Trim ICV */ | 285 | /* Trim ICV */ |
329 | skb_trim(skb, skb->len - TKIP_ICV_LEN); | 286 | skb_trim(skb, skb->len - TKIP_ICV_LEN); |
@@ -429,36 +386,41 @@ static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr) | |||
429 | } | 386 | } |
430 | 387 | ||
431 | 388 | ||
432 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, | 389 | static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) |
433 | struct sk_buff *skb, int test) | ||
434 | { | 390 | { |
435 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 391 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
436 | struct ieee80211_key *key = tx->key; | 392 | struct ieee80211_key *key = tx->key; |
437 | int hdrlen, len, tailneed; | 393 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
438 | u16 fc; | 394 | int hdrlen, len, tail; |
439 | u8 *pos, *pn, *b_0, *aad, *scratch; | 395 | u8 *pos, *pn, *b_0, *aad, *scratch; |
440 | int i; | 396 | int i; |
441 | 397 | ||
398 | info->control.icv_len = CCMP_MIC_LEN; | ||
399 | info->control.iv_len = CCMP_HDR_LEN; | ||
400 | |||
401 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | ||
402 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
403 | /* hwaccel - with no need for preallocated room for CCMP " | ||
404 | * header or MIC fields */ | ||
405 | info->control.hw_key = &tx->key->conf; | ||
406 | return 0; | ||
407 | } | ||
408 | |||
442 | scratch = key->u.ccmp.tx_crypto_buf; | 409 | scratch = key->u.ccmp.tx_crypto_buf; |
443 | b_0 = scratch + 3 * AES_BLOCK_LEN; | 410 | b_0 = scratch + 3 * AES_BLOCK_LEN; |
444 | aad = scratch + 4 * AES_BLOCK_LEN; | 411 | aad = scratch + 4 * AES_BLOCK_LEN; |
445 | 412 | ||
446 | fc = le16_to_cpu(hdr->frame_control); | 413 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
447 | hdrlen = ieee80211_get_hdrlen(fc); | ||
448 | len = skb->len - hdrlen; | 414 | len = skb->len - hdrlen; |
449 | 415 | ||
450 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) | 416 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) |
451 | tailneed = 0; | 417 | tail = 0; |
452 | else | 418 | else |
453 | tailneed = CCMP_MIC_LEN; | 419 | tail = CCMP_MIC_LEN; |
454 | 420 | ||
455 | if ((skb_headroom(skb) < CCMP_HDR_LEN || | 421 | if (WARN_ON(skb_tailroom(skb) < tail || |
456 | skb_tailroom(skb) < tailneed)) { | 422 | skb_headroom(skb) < CCMP_HDR_LEN)) |
457 | I802_DEBUG_INC(tx->local->tx_expand_skb_head); | 423 | return -1; |
458 | if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed, | ||
459 | GFP_ATOMIC))) | ||
460 | return -1; | ||
461 | } | ||
462 | 424 | ||
463 | pos = skb_push(skb, CCMP_HDR_LEN); | 425 | pos = skb_push(skb, CCMP_HDR_LEN); |
464 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); | 426 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); |
@@ -478,7 +440,7 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, | |||
478 | 440 | ||
479 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { | 441 | if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { |
480 | /* hwaccel - with preallocated room for CCMP header */ | 442 | /* hwaccel - with preallocated room for CCMP header */ |
481 | tx->control->key_idx = key->conf.hw_key_idx; | 443 | info->control.hw_key = &tx->key->conf; |
482 | return 0; | 444 | return 0; |
483 | } | 445 | } |
484 | 446 | ||
@@ -495,28 +457,16 @@ ieee80211_tx_result | |||
495 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) | 457 | ieee80211_crypto_ccmp_encrypt(struct ieee80211_tx_data *tx) |
496 | { | 458 | { |
497 | struct sk_buff *skb = tx->skb; | 459 | struct sk_buff *skb = tx->skb; |
498 | int test = 0; | ||
499 | 460 | ||
500 | tx->control->icv_len = CCMP_MIC_LEN; | ||
501 | tx->control->iv_len = CCMP_HDR_LEN; | ||
502 | ieee80211_tx_set_protected(tx); | 461 | ieee80211_tx_set_protected(tx); |
503 | 462 | ||
504 | if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && | 463 | if (ccmp_encrypt_skb(tx, skb) < 0) |
505 | !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { | ||
506 | /* hwaccel - with no need for preallocated room for CCMP " | ||
507 | * header or MIC fields */ | ||
508 | tx->control->key_idx = tx->key->conf.hw_key_idx; | ||
509 | return TX_CONTINUE; | ||
510 | } | ||
511 | |||
512 | if (ccmp_encrypt_skb(tx, skb, test) < 0) | ||
513 | return TX_DROP; | 464 | return TX_DROP; |
514 | 465 | ||
515 | if (tx->extra_frag) { | 466 | if (tx->extra_frag) { |
516 | int i; | 467 | int i; |
517 | for (i = 0; i < tx->num_extra_frag; i++) { | 468 | for (i = 0; i < tx->num_extra_frag; i++) { |
518 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i], test) | 469 | if (ccmp_encrypt_skb(tx, tx->extra_frag[i]) < 0) |
519 | < 0) | ||
520 | return TX_DROP; | 470 | return TX_DROP; |
521 | } | 471 | } |
522 | } | 472 | } |
@@ -529,7 +479,6 @@ ieee80211_rx_result | |||
529 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | 479 | ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) |
530 | { | 480 | { |
531 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; | 481 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; |
532 | u16 fc; | ||
533 | int hdrlen; | 482 | int hdrlen; |
534 | struct ieee80211_key *key = rx->key; | 483 | struct ieee80211_key *key = rx->key; |
535 | struct sk_buff *skb = rx->skb; | 484 | struct sk_buff *skb = rx->skb; |
@@ -537,8 +486,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
537 | int data_len; | 486 | int data_len; |
538 | DECLARE_MAC_BUF(mac); | 487 | DECLARE_MAC_BUF(mac); |
539 | 488 | ||
540 | fc = le16_to_cpu(hdr->frame_control); | 489 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
541 | hdrlen = ieee80211_get_hdrlen(fc); | ||
542 | 490 | ||
543 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) | 491 | if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) |
544 | return RX_CONTINUE; | 492 | return RX_CONTINUE; |
@@ -554,16 +502,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
554 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); | 502 | (void) ccmp_hdr2pn(pn, skb->data + hdrlen); |
555 | 503 | ||
556 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { | 504 | if (memcmp(pn, key->u.ccmp.rx_pn[rx->queue], CCMP_PN_LEN) <= 0) { |
557 | #ifdef CONFIG_MAC80211_DEBUG | ||
558 | u8 *ppn = key->u.ccmp.rx_pn[rx->queue]; | ||
559 | |||
560 | printk(KERN_DEBUG "%s: CCMP replay detected for RX frame from " | ||
561 | "%s (RX PN %02x%02x%02x%02x%02x%02x <= prev. PN " | ||
562 | "%02x%02x%02x%02x%02x%02x)\n", rx->dev->name, | ||
563 | print_mac(mac, rx->sta->addr), | ||
564 | pn[0], pn[1], pn[2], pn[3], pn[4], pn[5], | ||
565 | ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]); | ||
566 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
567 | key->u.ccmp.replays++; | 505 | key->u.ccmp.replays++; |
568 | return RX_DROP_UNUSABLE; | 506 | return RX_DROP_UNUSABLE; |
569 | } | 507 | } |
@@ -583,12 +521,6 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
583 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 521 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, |
584 | skb->data + skb->len - CCMP_MIC_LEN, | 522 | skb->data + skb->len - CCMP_MIC_LEN, |
585 | skb->data + hdrlen + CCMP_HDR_LEN)) { | 523 | skb->data + hdrlen + CCMP_HDR_LEN)) { |
586 | #ifdef CONFIG_MAC80211_DEBUG | ||
587 | if (net_ratelimit()) | ||
588 | printk(KERN_DEBUG "%s: CCMP decrypt failed " | ||
589 | "for RX frame from %s\n", rx->dev->name, | ||
590 | print_mac(mac, rx->sta->addr)); | ||
591 | #endif /* CONFIG_MAC80211_DEBUG */ | ||
592 | return RX_DROP_UNUSABLE; | 524 | return RX_DROP_UNUSABLE; |
593 | } | 525 | } |
594 | } | 526 | } |