Commit 9e03fdfd05e733e1136d431973625b174029c5e6
Committed by
John W. Linville
1 parent
90d6f92828
Exists in
master
and in
7 other branches
mac80211: Update mesh config IE to 11s draft 3.02
The mesh config information element has changed significantly since draft 1.08 This patch brings it up to date. Thanks to Sam Leffler and Rui Paulo for identifying this. Signed-off-by: Javier Cardona <javier@cozybit.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 3 changed files with 39 additions and 16 deletions Inline Diff
include/linux/ieee80211.h
1 | /* | 1 | /* |
2 | * IEEE 802.11 defines | 2 | * IEEE 802.11 defines |
3 | * | 3 | * |
4 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen | 4 | * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen |
5 | * <jkmaline@cc.hut.fi> | 5 | * <jkmaline@cc.hut.fi> |
6 | * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> | 6 | * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> |
7 | * Copyright (c) 2005, Devicescape Software, Inc. | 7 | * Copyright (c) 2005, Devicescape Software, Inc. |
8 | * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 as | 11 | * it under the terms of the GNU General Public License version 2 as |
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #ifndef LINUX_IEEE80211_H | 15 | #ifndef LINUX_IEEE80211_H |
16 | #define LINUX_IEEE80211_H | 16 | #define LINUX_IEEE80211_H |
17 | 17 | ||
18 | #include <linux/types.h> | 18 | #include <linux/types.h> |
19 | #include <asm/byteorder.h> | 19 | #include <asm/byteorder.h> |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * DS bit usage | 22 | * DS bit usage |
23 | * | 23 | * |
24 | * TA = transmitter address | 24 | * TA = transmitter address |
25 | * RA = receiver address | 25 | * RA = receiver address |
26 | * DA = destination address | 26 | * DA = destination address |
27 | * SA = source address | 27 | * SA = source address |
28 | * | 28 | * |
29 | * ToDS FromDS A1(RA) A2(TA) A3 A4 Use | 29 | * ToDS FromDS A1(RA) A2(TA) A3 A4 Use |
30 | * ----------------------------------------------------------------- | 30 | * ----------------------------------------------------------------- |
31 | * 0 0 DA SA BSSID - IBSS/DLS | 31 | * 0 0 DA SA BSSID - IBSS/DLS |
32 | * 0 1 DA BSSID SA - AP -> STA | 32 | * 0 1 DA BSSID SA - AP -> STA |
33 | * 1 0 BSSID SA DA - AP <- STA | 33 | * 1 0 BSSID SA DA - AP <- STA |
34 | * 1 1 RA TA DA SA unspecified (WDS) | 34 | * 1 1 RA TA DA SA unspecified (WDS) |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define FCS_LEN 4 | 37 | #define FCS_LEN 4 |
38 | 38 | ||
39 | #define IEEE80211_FCTL_VERS 0x0003 | 39 | #define IEEE80211_FCTL_VERS 0x0003 |
40 | #define IEEE80211_FCTL_FTYPE 0x000c | 40 | #define IEEE80211_FCTL_FTYPE 0x000c |
41 | #define IEEE80211_FCTL_STYPE 0x00f0 | 41 | #define IEEE80211_FCTL_STYPE 0x00f0 |
42 | #define IEEE80211_FCTL_TODS 0x0100 | 42 | #define IEEE80211_FCTL_TODS 0x0100 |
43 | #define IEEE80211_FCTL_FROMDS 0x0200 | 43 | #define IEEE80211_FCTL_FROMDS 0x0200 |
44 | #define IEEE80211_FCTL_MOREFRAGS 0x0400 | 44 | #define IEEE80211_FCTL_MOREFRAGS 0x0400 |
45 | #define IEEE80211_FCTL_RETRY 0x0800 | 45 | #define IEEE80211_FCTL_RETRY 0x0800 |
46 | #define IEEE80211_FCTL_PM 0x1000 | 46 | #define IEEE80211_FCTL_PM 0x1000 |
47 | #define IEEE80211_FCTL_MOREDATA 0x2000 | 47 | #define IEEE80211_FCTL_MOREDATA 0x2000 |
48 | #define IEEE80211_FCTL_PROTECTED 0x4000 | 48 | #define IEEE80211_FCTL_PROTECTED 0x4000 |
49 | #define IEEE80211_FCTL_ORDER 0x8000 | 49 | #define IEEE80211_FCTL_ORDER 0x8000 |
50 | 50 | ||
51 | #define IEEE80211_SCTL_FRAG 0x000F | 51 | #define IEEE80211_SCTL_FRAG 0x000F |
52 | #define IEEE80211_SCTL_SEQ 0xFFF0 | 52 | #define IEEE80211_SCTL_SEQ 0xFFF0 |
53 | 53 | ||
54 | #define IEEE80211_FTYPE_MGMT 0x0000 | 54 | #define IEEE80211_FTYPE_MGMT 0x0000 |
55 | #define IEEE80211_FTYPE_CTL 0x0004 | 55 | #define IEEE80211_FTYPE_CTL 0x0004 |
56 | #define IEEE80211_FTYPE_DATA 0x0008 | 56 | #define IEEE80211_FTYPE_DATA 0x0008 |
57 | 57 | ||
58 | /* management */ | 58 | /* management */ |
59 | #define IEEE80211_STYPE_ASSOC_REQ 0x0000 | 59 | #define IEEE80211_STYPE_ASSOC_REQ 0x0000 |
60 | #define IEEE80211_STYPE_ASSOC_RESP 0x0010 | 60 | #define IEEE80211_STYPE_ASSOC_RESP 0x0010 |
61 | #define IEEE80211_STYPE_REASSOC_REQ 0x0020 | 61 | #define IEEE80211_STYPE_REASSOC_REQ 0x0020 |
62 | #define IEEE80211_STYPE_REASSOC_RESP 0x0030 | 62 | #define IEEE80211_STYPE_REASSOC_RESP 0x0030 |
63 | #define IEEE80211_STYPE_PROBE_REQ 0x0040 | 63 | #define IEEE80211_STYPE_PROBE_REQ 0x0040 |
64 | #define IEEE80211_STYPE_PROBE_RESP 0x0050 | 64 | #define IEEE80211_STYPE_PROBE_RESP 0x0050 |
65 | #define IEEE80211_STYPE_BEACON 0x0080 | 65 | #define IEEE80211_STYPE_BEACON 0x0080 |
66 | #define IEEE80211_STYPE_ATIM 0x0090 | 66 | #define IEEE80211_STYPE_ATIM 0x0090 |
67 | #define IEEE80211_STYPE_DISASSOC 0x00A0 | 67 | #define IEEE80211_STYPE_DISASSOC 0x00A0 |
68 | #define IEEE80211_STYPE_AUTH 0x00B0 | 68 | #define IEEE80211_STYPE_AUTH 0x00B0 |
69 | #define IEEE80211_STYPE_DEAUTH 0x00C0 | 69 | #define IEEE80211_STYPE_DEAUTH 0x00C0 |
70 | #define IEEE80211_STYPE_ACTION 0x00D0 | 70 | #define IEEE80211_STYPE_ACTION 0x00D0 |
71 | 71 | ||
72 | /* control */ | 72 | /* control */ |
73 | #define IEEE80211_STYPE_BACK_REQ 0x0080 | 73 | #define IEEE80211_STYPE_BACK_REQ 0x0080 |
74 | #define IEEE80211_STYPE_BACK 0x0090 | 74 | #define IEEE80211_STYPE_BACK 0x0090 |
75 | #define IEEE80211_STYPE_PSPOLL 0x00A0 | 75 | #define IEEE80211_STYPE_PSPOLL 0x00A0 |
76 | #define IEEE80211_STYPE_RTS 0x00B0 | 76 | #define IEEE80211_STYPE_RTS 0x00B0 |
77 | #define IEEE80211_STYPE_CTS 0x00C0 | 77 | #define IEEE80211_STYPE_CTS 0x00C0 |
78 | #define IEEE80211_STYPE_ACK 0x00D0 | 78 | #define IEEE80211_STYPE_ACK 0x00D0 |
79 | #define IEEE80211_STYPE_CFEND 0x00E0 | 79 | #define IEEE80211_STYPE_CFEND 0x00E0 |
80 | #define IEEE80211_STYPE_CFENDACK 0x00F0 | 80 | #define IEEE80211_STYPE_CFENDACK 0x00F0 |
81 | 81 | ||
82 | /* data */ | 82 | /* data */ |
83 | #define IEEE80211_STYPE_DATA 0x0000 | 83 | #define IEEE80211_STYPE_DATA 0x0000 |
84 | #define IEEE80211_STYPE_DATA_CFACK 0x0010 | 84 | #define IEEE80211_STYPE_DATA_CFACK 0x0010 |
85 | #define IEEE80211_STYPE_DATA_CFPOLL 0x0020 | 85 | #define IEEE80211_STYPE_DATA_CFPOLL 0x0020 |
86 | #define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 | 86 | #define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 |
87 | #define IEEE80211_STYPE_NULLFUNC 0x0040 | 87 | #define IEEE80211_STYPE_NULLFUNC 0x0040 |
88 | #define IEEE80211_STYPE_CFACK 0x0050 | 88 | #define IEEE80211_STYPE_CFACK 0x0050 |
89 | #define IEEE80211_STYPE_CFPOLL 0x0060 | 89 | #define IEEE80211_STYPE_CFPOLL 0x0060 |
90 | #define IEEE80211_STYPE_CFACKPOLL 0x0070 | 90 | #define IEEE80211_STYPE_CFACKPOLL 0x0070 |
91 | #define IEEE80211_STYPE_QOS_DATA 0x0080 | 91 | #define IEEE80211_STYPE_QOS_DATA 0x0080 |
92 | #define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 | 92 | #define IEEE80211_STYPE_QOS_DATA_CFACK 0x0090 |
93 | #define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 | 93 | #define IEEE80211_STYPE_QOS_DATA_CFPOLL 0x00A0 |
94 | #define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 | 94 | #define IEEE80211_STYPE_QOS_DATA_CFACKPOLL 0x00B0 |
95 | #define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 | 95 | #define IEEE80211_STYPE_QOS_NULLFUNC 0x00C0 |
96 | #define IEEE80211_STYPE_QOS_CFACK 0x00D0 | 96 | #define IEEE80211_STYPE_QOS_CFACK 0x00D0 |
97 | #define IEEE80211_STYPE_QOS_CFPOLL 0x00E0 | 97 | #define IEEE80211_STYPE_QOS_CFPOLL 0x00E0 |
98 | #define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 | 98 | #define IEEE80211_STYPE_QOS_CFACKPOLL 0x00F0 |
99 | 99 | ||
100 | 100 | ||
101 | /* miscellaneous IEEE 802.11 constants */ | 101 | /* miscellaneous IEEE 802.11 constants */ |
102 | #define IEEE80211_MAX_FRAG_THRESHOLD 2352 | 102 | #define IEEE80211_MAX_FRAG_THRESHOLD 2352 |
103 | #define IEEE80211_MAX_RTS_THRESHOLD 2353 | 103 | #define IEEE80211_MAX_RTS_THRESHOLD 2353 |
104 | #define IEEE80211_MAX_AID 2007 | 104 | #define IEEE80211_MAX_AID 2007 |
105 | #define IEEE80211_MAX_TIM_LEN 251 | 105 | #define IEEE80211_MAX_TIM_LEN 251 |
106 | /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section | 106 | /* Maximum size for the MA-UNITDATA primitive, 802.11 standard section |
107 | 6.2.1.1.2. | 107 | 6.2.1.1.2. |
108 | 108 | ||
109 | 802.11e clarifies the figure in section 7.1.2. The frame body is | 109 | 802.11e clarifies the figure in section 7.1.2. The frame body is |
110 | up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */ | 110 | up to 2304 octets long (maximum MSDU size) plus any crypt overhead. */ |
111 | #define IEEE80211_MAX_DATA_LEN 2304 | 111 | #define IEEE80211_MAX_DATA_LEN 2304 |
112 | /* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */ | 112 | /* 30 byte 4 addr hdr, 2 byte QoS, 2304 byte MSDU, 12 byte crypt, 4 byte FCS */ |
113 | #define IEEE80211_MAX_FRAME_LEN 2352 | 113 | #define IEEE80211_MAX_FRAME_LEN 2352 |
114 | 114 | ||
115 | #define IEEE80211_MAX_SSID_LEN 32 | 115 | #define IEEE80211_MAX_SSID_LEN 32 |
116 | 116 | ||
117 | #define IEEE80211_MAX_MESH_ID_LEN 32 | 117 | #define IEEE80211_MAX_MESH_ID_LEN 32 |
118 | #define IEEE80211_MESH_CONFIG_LEN 19 | 118 | #define IEEE80211_MESH_CONFIG_LEN 24 |
119 | 119 | ||
120 | #define IEEE80211_QOS_CTL_LEN 2 | 120 | #define IEEE80211_QOS_CTL_LEN 2 |
121 | #define IEEE80211_QOS_CTL_TID_MASK 0x000F | 121 | #define IEEE80211_QOS_CTL_TID_MASK 0x000F |
122 | #define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 | 122 | #define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 |
123 | 123 | ||
124 | struct ieee80211_hdr { | 124 | struct ieee80211_hdr { |
125 | __le16 frame_control; | 125 | __le16 frame_control; |
126 | __le16 duration_id; | 126 | __le16 duration_id; |
127 | u8 addr1[6]; | 127 | u8 addr1[6]; |
128 | u8 addr2[6]; | 128 | u8 addr2[6]; |
129 | u8 addr3[6]; | 129 | u8 addr3[6]; |
130 | __le16 seq_ctrl; | 130 | __le16 seq_ctrl; |
131 | u8 addr4[6]; | 131 | u8 addr4[6]; |
132 | } __attribute__ ((packed)); | 132 | } __attribute__ ((packed)); |
133 | 133 | ||
134 | /** | 134 | /** |
135 | * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set | 135 | * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set |
136 | * @fc: frame control bytes in little-endian byteorder | 136 | * @fc: frame control bytes in little-endian byteorder |
137 | */ | 137 | */ |
138 | static inline int ieee80211_has_tods(__le16 fc) | 138 | static inline int ieee80211_has_tods(__le16 fc) |
139 | { | 139 | { |
140 | return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0; | 140 | return (fc & cpu_to_le16(IEEE80211_FCTL_TODS)) != 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | /** | 143 | /** |
144 | * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set | 144 | * ieee80211_has_fromds - check if IEEE80211_FCTL_FROMDS is set |
145 | * @fc: frame control bytes in little-endian byteorder | 145 | * @fc: frame control bytes in little-endian byteorder |
146 | */ | 146 | */ |
147 | static inline int ieee80211_has_fromds(__le16 fc) | 147 | static inline int ieee80211_has_fromds(__le16 fc) |
148 | { | 148 | { |
149 | return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0; | 149 | return (fc & cpu_to_le16(IEEE80211_FCTL_FROMDS)) != 0; |
150 | } | 150 | } |
151 | 151 | ||
152 | /** | 152 | /** |
153 | * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set | 153 | * ieee80211_has_a4 - check if IEEE80211_FCTL_TODS and IEEE80211_FCTL_FROMDS are set |
154 | * @fc: frame control bytes in little-endian byteorder | 154 | * @fc: frame control bytes in little-endian byteorder |
155 | */ | 155 | */ |
156 | static inline int ieee80211_has_a4(__le16 fc) | 156 | static inline int ieee80211_has_a4(__le16 fc) |
157 | { | 157 | { |
158 | __le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | 158 | __le16 tmp = cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); |
159 | return (fc & tmp) == tmp; | 159 | return (fc & tmp) == tmp; |
160 | } | 160 | } |
161 | 161 | ||
162 | /** | 162 | /** |
163 | * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set | 163 | * ieee80211_has_morefrags - check if IEEE80211_FCTL_MOREFRAGS is set |
164 | * @fc: frame control bytes in little-endian byteorder | 164 | * @fc: frame control bytes in little-endian byteorder |
165 | */ | 165 | */ |
166 | static inline int ieee80211_has_morefrags(__le16 fc) | 166 | static inline int ieee80211_has_morefrags(__le16 fc) |
167 | { | 167 | { |
168 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0; | 168 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREFRAGS)) != 0; |
169 | } | 169 | } |
170 | 170 | ||
171 | /** | 171 | /** |
172 | * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set | 172 | * ieee80211_has_retry - check if IEEE80211_FCTL_RETRY is set |
173 | * @fc: frame control bytes in little-endian byteorder | 173 | * @fc: frame control bytes in little-endian byteorder |
174 | */ | 174 | */ |
175 | static inline int ieee80211_has_retry(__le16 fc) | 175 | static inline int ieee80211_has_retry(__le16 fc) |
176 | { | 176 | { |
177 | return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0; | 177 | return (fc & cpu_to_le16(IEEE80211_FCTL_RETRY)) != 0; |
178 | } | 178 | } |
179 | 179 | ||
180 | /** | 180 | /** |
181 | * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set | 181 | * ieee80211_has_pm - check if IEEE80211_FCTL_PM is set |
182 | * @fc: frame control bytes in little-endian byteorder | 182 | * @fc: frame control bytes in little-endian byteorder |
183 | */ | 183 | */ |
184 | static inline int ieee80211_has_pm(__le16 fc) | 184 | static inline int ieee80211_has_pm(__le16 fc) |
185 | { | 185 | { |
186 | return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0; | 186 | return (fc & cpu_to_le16(IEEE80211_FCTL_PM)) != 0; |
187 | } | 187 | } |
188 | 188 | ||
189 | /** | 189 | /** |
190 | * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set | 190 | * ieee80211_has_moredata - check if IEEE80211_FCTL_MOREDATA is set |
191 | * @fc: frame control bytes in little-endian byteorder | 191 | * @fc: frame control bytes in little-endian byteorder |
192 | */ | 192 | */ |
193 | static inline int ieee80211_has_moredata(__le16 fc) | 193 | static inline int ieee80211_has_moredata(__le16 fc) |
194 | { | 194 | { |
195 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0; | 195 | return (fc & cpu_to_le16(IEEE80211_FCTL_MOREDATA)) != 0; |
196 | } | 196 | } |
197 | 197 | ||
198 | /** | 198 | /** |
199 | * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set | 199 | * ieee80211_has_protected - check if IEEE80211_FCTL_PROTECTED is set |
200 | * @fc: frame control bytes in little-endian byteorder | 200 | * @fc: frame control bytes in little-endian byteorder |
201 | */ | 201 | */ |
202 | static inline int ieee80211_has_protected(__le16 fc) | 202 | static inline int ieee80211_has_protected(__le16 fc) |
203 | { | 203 | { |
204 | return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0; | 204 | return (fc & cpu_to_le16(IEEE80211_FCTL_PROTECTED)) != 0; |
205 | } | 205 | } |
206 | 206 | ||
207 | /** | 207 | /** |
208 | * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set | 208 | * ieee80211_has_order - check if IEEE80211_FCTL_ORDER is set |
209 | * @fc: frame control bytes in little-endian byteorder | 209 | * @fc: frame control bytes in little-endian byteorder |
210 | */ | 210 | */ |
211 | static inline int ieee80211_has_order(__le16 fc) | 211 | static inline int ieee80211_has_order(__le16 fc) |
212 | { | 212 | { |
213 | return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0; | 213 | return (fc & cpu_to_le16(IEEE80211_FCTL_ORDER)) != 0; |
214 | } | 214 | } |
215 | 215 | ||
216 | /** | 216 | /** |
217 | * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT | 217 | * ieee80211_is_mgmt - check if type is IEEE80211_FTYPE_MGMT |
218 | * @fc: frame control bytes in little-endian byteorder | 218 | * @fc: frame control bytes in little-endian byteorder |
219 | */ | 219 | */ |
220 | static inline int ieee80211_is_mgmt(__le16 fc) | 220 | static inline int ieee80211_is_mgmt(__le16 fc) |
221 | { | 221 | { |
222 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | 222 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == |
223 | cpu_to_le16(IEEE80211_FTYPE_MGMT); | 223 | cpu_to_le16(IEEE80211_FTYPE_MGMT); |
224 | } | 224 | } |
225 | 225 | ||
226 | /** | 226 | /** |
227 | * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL | 227 | * ieee80211_is_ctl - check if type is IEEE80211_FTYPE_CTL |
228 | * @fc: frame control bytes in little-endian byteorder | 228 | * @fc: frame control bytes in little-endian byteorder |
229 | */ | 229 | */ |
230 | static inline int ieee80211_is_ctl(__le16 fc) | 230 | static inline int ieee80211_is_ctl(__le16 fc) |
231 | { | 231 | { |
232 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | 232 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == |
233 | cpu_to_le16(IEEE80211_FTYPE_CTL); | 233 | cpu_to_le16(IEEE80211_FTYPE_CTL); |
234 | } | 234 | } |
235 | 235 | ||
236 | /** | 236 | /** |
237 | * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA | 237 | * ieee80211_is_data - check if type is IEEE80211_FTYPE_DATA |
238 | * @fc: frame control bytes in little-endian byteorder | 238 | * @fc: frame control bytes in little-endian byteorder |
239 | */ | 239 | */ |
240 | static inline int ieee80211_is_data(__le16 fc) | 240 | static inline int ieee80211_is_data(__le16 fc) |
241 | { | 241 | { |
242 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == | 242 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE)) == |
243 | cpu_to_le16(IEEE80211_FTYPE_DATA); | 243 | cpu_to_le16(IEEE80211_FTYPE_DATA); |
244 | } | 244 | } |
245 | 245 | ||
246 | /** | 246 | /** |
247 | * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set | 247 | * ieee80211_is_data_qos - check if type is IEEE80211_FTYPE_DATA and IEEE80211_STYPE_QOS_DATA is set |
248 | * @fc: frame control bytes in little-endian byteorder | 248 | * @fc: frame control bytes in little-endian byteorder |
249 | */ | 249 | */ |
250 | static inline int ieee80211_is_data_qos(__le16 fc) | 250 | static inline int ieee80211_is_data_qos(__le16 fc) |
251 | { | 251 | { |
252 | /* | 252 | /* |
253 | * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need | 253 | * mask with QOS_DATA rather than IEEE80211_FCTL_STYPE as we just need |
254 | * to check the one bit | 254 | * to check the one bit |
255 | */ | 255 | */ |
256 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) == | 256 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_STYPE_QOS_DATA)) == |
257 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA); | 257 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA); |
258 | } | 258 | } |
259 | 259 | ||
260 | /** | 260 | /** |
261 | * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data | 261 | * ieee80211_is_data_present - check if type is IEEE80211_FTYPE_DATA and has data |
262 | * @fc: frame control bytes in little-endian byteorder | 262 | * @fc: frame control bytes in little-endian byteorder |
263 | */ | 263 | */ |
264 | static inline int ieee80211_is_data_present(__le16 fc) | 264 | static inline int ieee80211_is_data_present(__le16 fc) |
265 | { | 265 | { |
266 | /* | 266 | /* |
267 | * mask with 0x40 and test that that bit is clear to only return true | 267 | * mask with 0x40 and test that that bit is clear to only return true |
268 | * for the data-containing substypes. | 268 | * for the data-containing substypes. |
269 | */ | 269 | */ |
270 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) == | 270 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | 0x40)) == |
271 | cpu_to_le16(IEEE80211_FTYPE_DATA); | 271 | cpu_to_le16(IEEE80211_FTYPE_DATA); |
272 | } | 272 | } |
273 | 273 | ||
274 | /** | 274 | /** |
275 | * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ | 275 | * ieee80211_is_assoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_REQ |
276 | * @fc: frame control bytes in little-endian byteorder | 276 | * @fc: frame control bytes in little-endian byteorder |
277 | */ | 277 | */ |
278 | static inline int ieee80211_is_assoc_req(__le16 fc) | 278 | static inline int ieee80211_is_assoc_req(__le16 fc) |
279 | { | 279 | { |
280 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 280 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
281 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ); | 281 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ); |
282 | } | 282 | } |
283 | 283 | ||
284 | /** | 284 | /** |
285 | * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP | 285 | * ieee80211_is_assoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ASSOC_RESP |
286 | * @fc: frame control bytes in little-endian byteorder | 286 | * @fc: frame control bytes in little-endian byteorder |
287 | */ | 287 | */ |
288 | static inline int ieee80211_is_assoc_resp(__le16 fc) | 288 | static inline int ieee80211_is_assoc_resp(__le16 fc) |
289 | { | 289 | { |
290 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 290 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
291 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP); | 291 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP); |
292 | } | 292 | } |
293 | 293 | ||
294 | /** | 294 | /** |
295 | * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ | 295 | * ieee80211_is_reassoc_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_REQ |
296 | * @fc: frame control bytes in little-endian byteorder | 296 | * @fc: frame control bytes in little-endian byteorder |
297 | */ | 297 | */ |
298 | static inline int ieee80211_is_reassoc_req(__le16 fc) | 298 | static inline int ieee80211_is_reassoc_req(__le16 fc) |
299 | { | 299 | { |
300 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 300 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
301 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ); | 301 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ); |
302 | } | 302 | } |
303 | 303 | ||
304 | /** | 304 | /** |
305 | * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP | 305 | * ieee80211_is_reassoc_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_REASSOC_RESP |
306 | * @fc: frame control bytes in little-endian byteorder | 306 | * @fc: frame control bytes in little-endian byteorder |
307 | */ | 307 | */ |
308 | static inline int ieee80211_is_reassoc_resp(__le16 fc) | 308 | static inline int ieee80211_is_reassoc_resp(__le16 fc) |
309 | { | 309 | { |
310 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 310 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
311 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP); | 311 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP); |
312 | } | 312 | } |
313 | 313 | ||
314 | /** | 314 | /** |
315 | * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ | 315 | * ieee80211_is_probe_req - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_REQ |
316 | * @fc: frame control bytes in little-endian byteorder | 316 | * @fc: frame control bytes in little-endian byteorder |
317 | */ | 317 | */ |
318 | static inline int ieee80211_is_probe_req(__le16 fc) | 318 | static inline int ieee80211_is_probe_req(__le16 fc) |
319 | { | 319 | { |
320 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 320 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
321 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); | 321 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ); |
322 | } | 322 | } |
323 | 323 | ||
324 | /** | 324 | /** |
325 | * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP | 325 | * ieee80211_is_probe_resp - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_PROBE_RESP |
326 | * @fc: frame control bytes in little-endian byteorder | 326 | * @fc: frame control bytes in little-endian byteorder |
327 | */ | 327 | */ |
328 | static inline int ieee80211_is_probe_resp(__le16 fc) | 328 | static inline int ieee80211_is_probe_resp(__le16 fc) |
329 | { | 329 | { |
330 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 330 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
331 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); | 331 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP); |
332 | } | 332 | } |
333 | 333 | ||
334 | /** | 334 | /** |
335 | * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON | 335 | * ieee80211_is_beacon - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_BEACON |
336 | * @fc: frame control bytes in little-endian byteorder | 336 | * @fc: frame control bytes in little-endian byteorder |
337 | */ | 337 | */ |
338 | static inline int ieee80211_is_beacon(__le16 fc) | 338 | static inline int ieee80211_is_beacon(__le16 fc) |
339 | { | 339 | { |
340 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 340 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
341 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); | 341 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); |
342 | } | 342 | } |
343 | 343 | ||
344 | /** | 344 | /** |
345 | * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM | 345 | * ieee80211_is_atim - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ATIM |
346 | * @fc: frame control bytes in little-endian byteorder | 346 | * @fc: frame control bytes in little-endian byteorder |
347 | */ | 347 | */ |
348 | static inline int ieee80211_is_atim(__le16 fc) | 348 | static inline int ieee80211_is_atim(__le16 fc) |
349 | { | 349 | { |
350 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 350 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
351 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM); | 351 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ATIM); |
352 | } | 352 | } |
353 | 353 | ||
354 | /** | 354 | /** |
355 | * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC | 355 | * ieee80211_is_disassoc - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DISASSOC |
356 | * @fc: frame control bytes in little-endian byteorder | 356 | * @fc: frame control bytes in little-endian byteorder |
357 | */ | 357 | */ |
358 | static inline int ieee80211_is_disassoc(__le16 fc) | 358 | static inline int ieee80211_is_disassoc(__le16 fc) |
359 | { | 359 | { |
360 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 360 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
361 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC); | 361 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DISASSOC); |
362 | } | 362 | } |
363 | 363 | ||
364 | /** | 364 | /** |
365 | * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH | 365 | * ieee80211_is_auth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_AUTH |
366 | * @fc: frame control bytes in little-endian byteorder | 366 | * @fc: frame control bytes in little-endian byteorder |
367 | */ | 367 | */ |
368 | static inline int ieee80211_is_auth(__le16 fc) | 368 | static inline int ieee80211_is_auth(__le16 fc) |
369 | { | 369 | { |
370 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 370 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
371 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); | 371 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); |
372 | } | 372 | } |
373 | 373 | ||
374 | /** | 374 | /** |
375 | * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH | 375 | * ieee80211_is_deauth - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_DEAUTH |
376 | * @fc: frame control bytes in little-endian byteorder | 376 | * @fc: frame control bytes in little-endian byteorder |
377 | */ | 377 | */ |
378 | static inline int ieee80211_is_deauth(__le16 fc) | 378 | static inline int ieee80211_is_deauth(__le16 fc) |
379 | { | 379 | { |
380 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 380 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
381 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); | 381 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_DEAUTH); |
382 | } | 382 | } |
383 | 383 | ||
384 | /** | 384 | /** |
385 | * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION | 385 | * ieee80211_is_action - check if IEEE80211_FTYPE_MGMT && IEEE80211_STYPE_ACTION |
386 | * @fc: frame control bytes in little-endian byteorder | 386 | * @fc: frame control bytes in little-endian byteorder |
387 | */ | 387 | */ |
388 | static inline int ieee80211_is_action(__le16 fc) | 388 | static inline int ieee80211_is_action(__le16 fc) |
389 | { | 389 | { |
390 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 390 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
391 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); | 391 | cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION); |
392 | } | 392 | } |
393 | 393 | ||
394 | /** | 394 | /** |
395 | * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ | 395 | * ieee80211_is_back_req - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK_REQ |
396 | * @fc: frame control bytes in little-endian byteorder | 396 | * @fc: frame control bytes in little-endian byteorder |
397 | */ | 397 | */ |
398 | static inline int ieee80211_is_back_req(__le16 fc) | 398 | static inline int ieee80211_is_back_req(__le16 fc) |
399 | { | 399 | { |
400 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 400 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
401 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ); | 401 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK_REQ); |
402 | } | 402 | } |
403 | 403 | ||
404 | /** | 404 | /** |
405 | * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK | 405 | * ieee80211_is_back - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_BACK |
406 | * @fc: frame control bytes in little-endian byteorder | 406 | * @fc: frame control bytes in little-endian byteorder |
407 | */ | 407 | */ |
408 | static inline int ieee80211_is_back(__le16 fc) | 408 | static inline int ieee80211_is_back(__le16 fc) |
409 | { | 409 | { |
410 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 410 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
411 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK); | 411 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_BACK); |
412 | } | 412 | } |
413 | 413 | ||
414 | /** | 414 | /** |
415 | * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL | 415 | * ieee80211_is_pspoll - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_PSPOLL |
416 | * @fc: frame control bytes in little-endian byteorder | 416 | * @fc: frame control bytes in little-endian byteorder |
417 | */ | 417 | */ |
418 | static inline int ieee80211_is_pspoll(__le16 fc) | 418 | static inline int ieee80211_is_pspoll(__le16 fc) |
419 | { | 419 | { |
420 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 420 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
421 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); | 421 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); |
422 | } | 422 | } |
423 | 423 | ||
424 | /** | 424 | /** |
425 | * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS | 425 | * ieee80211_is_rts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_RTS |
426 | * @fc: frame control bytes in little-endian byteorder | 426 | * @fc: frame control bytes in little-endian byteorder |
427 | */ | 427 | */ |
428 | static inline int ieee80211_is_rts(__le16 fc) | 428 | static inline int ieee80211_is_rts(__le16 fc) |
429 | { | 429 | { |
430 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 430 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
431 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); | 431 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); |
432 | } | 432 | } |
433 | 433 | ||
434 | /** | 434 | /** |
435 | * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS | 435 | * ieee80211_is_cts - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CTS |
436 | * @fc: frame control bytes in little-endian byteorder | 436 | * @fc: frame control bytes in little-endian byteorder |
437 | */ | 437 | */ |
438 | static inline int ieee80211_is_cts(__le16 fc) | 438 | static inline int ieee80211_is_cts(__le16 fc) |
439 | { | 439 | { |
440 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 440 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
441 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); | 441 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); |
442 | } | 442 | } |
443 | 443 | ||
444 | /** | 444 | /** |
445 | * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK | 445 | * ieee80211_is_ack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_ACK |
446 | * @fc: frame control bytes in little-endian byteorder | 446 | * @fc: frame control bytes in little-endian byteorder |
447 | */ | 447 | */ |
448 | static inline int ieee80211_is_ack(__le16 fc) | 448 | static inline int ieee80211_is_ack(__le16 fc) |
449 | { | 449 | { |
450 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 450 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
451 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK); | 451 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK); |
452 | } | 452 | } |
453 | 453 | ||
454 | /** | 454 | /** |
455 | * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND | 455 | * ieee80211_is_cfend - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFEND |
456 | * @fc: frame control bytes in little-endian byteorder | 456 | * @fc: frame control bytes in little-endian byteorder |
457 | */ | 457 | */ |
458 | static inline int ieee80211_is_cfend(__le16 fc) | 458 | static inline int ieee80211_is_cfend(__le16 fc) |
459 | { | 459 | { |
460 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 460 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
461 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND); | 461 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFEND); |
462 | } | 462 | } |
463 | 463 | ||
464 | /** | 464 | /** |
465 | * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK | 465 | * ieee80211_is_cfendack - check if IEEE80211_FTYPE_CTL && IEEE80211_STYPE_CFENDACK |
466 | * @fc: frame control bytes in little-endian byteorder | 466 | * @fc: frame control bytes in little-endian byteorder |
467 | */ | 467 | */ |
468 | static inline int ieee80211_is_cfendack(__le16 fc) | 468 | static inline int ieee80211_is_cfendack(__le16 fc) |
469 | { | 469 | { |
470 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 470 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
471 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK); | 471 | cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CFENDACK); |
472 | } | 472 | } |
473 | 473 | ||
474 | /** | 474 | /** |
475 | * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC | 475 | * ieee80211_is_nullfunc - check if FTYPE=IEEE80211_FTYPE_DATA and STYPE=IEEE80211_STYPE_NULLFUNC |
476 | * @fc: frame control bytes in little-endian byteorder | 476 | * @fc: frame control bytes in little-endian byteorder |
477 | */ | 477 | */ |
478 | static inline int ieee80211_is_nullfunc(__le16 fc) | 478 | static inline int ieee80211_is_nullfunc(__le16 fc) |
479 | { | 479 | { |
480 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == | 480 | return (fc & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) == |
481 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC); | 481 | cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC); |
482 | } | 482 | } |
483 | 483 | ||
484 | struct ieee80211s_hdr { | 484 | struct ieee80211s_hdr { |
485 | u8 flags; | 485 | u8 flags; |
486 | u8 ttl; | 486 | u8 ttl; |
487 | __le32 seqnum; | 487 | __le32 seqnum; |
488 | u8 eaddr1[6]; | 488 | u8 eaddr1[6]; |
489 | u8 eaddr2[6]; | 489 | u8 eaddr2[6]; |
490 | u8 eaddr3[6]; | 490 | u8 eaddr3[6]; |
491 | } __attribute__ ((packed)); | 491 | } __attribute__ ((packed)); |
492 | 492 | ||
493 | /* Mesh flags */ | 493 | /* Mesh flags */ |
494 | #define MESH_FLAGS_AE_A4 0x1 | 494 | #define MESH_FLAGS_AE_A4 0x1 |
495 | #define MESH_FLAGS_AE_A5_A6 0x2 | 495 | #define MESH_FLAGS_AE_A5_A6 0x2 |
496 | #define MESH_FLAGS_AE 0x3 | 496 | #define MESH_FLAGS_AE 0x3 |
497 | #define MESH_FLAGS_PS_DEEP 0x4 | 497 | #define MESH_FLAGS_PS_DEEP 0x4 |
498 | 498 | ||
499 | /** | 499 | /** |
500 | * struct ieee80211_quiet_ie | 500 | * struct ieee80211_quiet_ie |
501 | * | 501 | * |
502 | * This structure refers to "Quiet information element" | 502 | * This structure refers to "Quiet information element" |
503 | */ | 503 | */ |
504 | struct ieee80211_quiet_ie { | 504 | struct ieee80211_quiet_ie { |
505 | u8 count; | 505 | u8 count; |
506 | u8 period; | 506 | u8 period; |
507 | __le16 duration; | 507 | __le16 duration; |
508 | __le16 offset; | 508 | __le16 offset; |
509 | } __attribute__ ((packed)); | 509 | } __attribute__ ((packed)); |
510 | 510 | ||
511 | /** | 511 | /** |
512 | * struct ieee80211_msrment_ie | 512 | * struct ieee80211_msrment_ie |
513 | * | 513 | * |
514 | * This structure refers to "Measurement Request/Report information element" | 514 | * This structure refers to "Measurement Request/Report information element" |
515 | */ | 515 | */ |
516 | struct ieee80211_msrment_ie { | 516 | struct ieee80211_msrment_ie { |
517 | u8 token; | 517 | u8 token; |
518 | u8 mode; | 518 | u8 mode; |
519 | u8 type; | 519 | u8 type; |
520 | u8 request[0]; | 520 | u8 request[0]; |
521 | } __attribute__ ((packed)); | 521 | } __attribute__ ((packed)); |
522 | 522 | ||
523 | /** | 523 | /** |
524 | * struct ieee80211_channel_sw_ie | 524 | * struct ieee80211_channel_sw_ie |
525 | * | 525 | * |
526 | * This structure refers to "Channel Switch Announcement information element" | 526 | * This structure refers to "Channel Switch Announcement information element" |
527 | */ | 527 | */ |
528 | struct ieee80211_channel_sw_ie { | 528 | struct ieee80211_channel_sw_ie { |
529 | u8 mode; | 529 | u8 mode; |
530 | u8 new_ch_num; | 530 | u8 new_ch_num; |
531 | u8 count; | 531 | u8 count; |
532 | } __attribute__ ((packed)); | 532 | } __attribute__ ((packed)); |
533 | 533 | ||
534 | /** | 534 | /** |
535 | * struct ieee80211_tim | 535 | * struct ieee80211_tim |
536 | * | 536 | * |
537 | * This structure refers to "Traffic Indication Map information element" | 537 | * This structure refers to "Traffic Indication Map information element" |
538 | */ | 538 | */ |
539 | struct ieee80211_tim_ie { | 539 | struct ieee80211_tim_ie { |
540 | u8 dtim_count; | 540 | u8 dtim_count; |
541 | u8 dtim_period; | 541 | u8 dtim_period; |
542 | u8 bitmap_ctrl; | 542 | u8 bitmap_ctrl; |
543 | /* variable size: 1 - 251 bytes */ | 543 | /* variable size: 1 - 251 bytes */ |
544 | u8 virtual_map[1]; | 544 | u8 virtual_map[1]; |
545 | } __attribute__ ((packed)); | 545 | } __attribute__ ((packed)); |
546 | 546 | ||
547 | #define WLAN_SA_QUERY_TR_ID_LEN 2 | 547 | #define WLAN_SA_QUERY_TR_ID_LEN 2 |
548 | 548 | ||
549 | struct ieee80211_mgmt { | 549 | struct ieee80211_mgmt { |
550 | __le16 frame_control; | 550 | __le16 frame_control; |
551 | __le16 duration; | 551 | __le16 duration; |
552 | u8 da[6]; | 552 | u8 da[6]; |
553 | u8 sa[6]; | 553 | u8 sa[6]; |
554 | u8 bssid[6]; | 554 | u8 bssid[6]; |
555 | __le16 seq_ctrl; | 555 | __le16 seq_ctrl; |
556 | union { | 556 | union { |
557 | struct { | 557 | struct { |
558 | __le16 auth_alg; | 558 | __le16 auth_alg; |
559 | __le16 auth_transaction; | 559 | __le16 auth_transaction; |
560 | __le16 status_code; | 560 | __le16 status_code; |
561 | /* possibly followed by Challenge text */ | 561 | /* possibly followed by Challenge text */ |
562 | u8 variable[0]; | 562 | u8 variable[0]; |
563 | } __attribute__ ((packed)) auth; | 563 | } __attribute__ ((packed)) auth; |
564 | struct { | 564 | struct { |
565 | __le16 reason_code; | 565 | __le16 reason_code; |
566 | } __attribute__ ((packed)) deauth; | 566 | } __attribute__ ((packed)) deauth; |
567 | struct { | 567 | struct { |
568 | __le16 capab_info; | 568 | __le16 capab_info; |
569 | __le16 listen_interval; | 569 | __le16 listen_interval; |
570 | /* followed by SSID and Supported rates */ | 570 | /* followed by SSID and Supported rates */ |
571 | u8 variable[0]; | 571 | u8 variable[0]; |
572 | } __attribute__ ((packed)) assoc_req; | 572 | } __attribute__ ((packed)) assoc_req; |
573 | struct { | 573 | struct { |
574 | __le16 capab_info; | 574 | __le16 capab_info; |
575 | __le16 status_code; | 575 | __le16 status_code; |
576 | __le16 aid; | 576 | __le16 aid; |
577 | /* followed by Supported rates */ | 577 | /* followed by Supported rates */ |
578 | u8 variable[0]; | 578 | u8 variable[0]; |
579 | } __attribute__ ((packed)) assoc_resp, reassoc_resp; | 579 | } __attribute__ ((packed)) assoc_resp, reassoc_resp; |
580 | struct { | 580 | struct { |
581 | __le16 capab_info; | 581 | __le16 capab_info; |
582 | __le16 listen_interval; | 582 | __le16 listen_interval; |
583 | u8 current_ap[6]; | 583 | u8 current_ap[6]; |
584 | /* followed by SSID and Supported rates */ | 584 | /* followed by SSID and Supported rates */ |
585 | u8 variable[0]; | 585 | u8 variable[0]; |
586 | } __attribute__ ((packed)) reassoc_req; | 586 | } __attribute__ ((packed)) reassoc_req; |
587 | struct { | 587 | struct { |
588 | __le16 reason_code; | 588 | __le16 reason_code; |
589 | } __attribute__ ((packed)) disassoc; | 589 | } __attribute__ ((packed)) disassoc; |
590 | struct { | 590 | struct { |
591 | __le64 timestamp; | 591 | __le64 timestamp; |
592 | __le16 beacon_int; | 592 | __le16 beacon_int; |
593 | __le16 capab_info; | 593 | __le16 capab_info; |
594 | /* followed by some of SSID, Supported rates, | 594 | /* followed by some of SSID, Supported rates, |
595 | * FH Params, DS Params, CF Params, IBSS Params, TIM */ | 595 | * FH Params, DS Params, CF Params, IBSS Params, TIM */ |
596 | u8 variable[0]; | 596 | u8 variable[0]; |
597 | } __attribute__ ((packed)) beacon; | 597 | } __attribute__ ((packed)) beacon; |
598 | struct { | 598 | struct { |
599 | /* only variable items: SSID, Supported rates */ | 599 | /* only variable items: SSID, Supported rates */ |
600 | u8 variable[0]; | 600 | u8 variable[0]; |
601 | } __attribute__ ((packed)) probe_req; | 601 | } __attribute__ ((packed)) probe_req; |
602 | struct { | 602 | struct { |
603 | __le64 timestamp; | 603 | __le64 timestamp; |
604 | __le16 beacon_int; | 604 | __le16 beacon_int; |
605 | __le16 capab_info; | 605 | __le16 capab_info; |
606 | /* followed by some of SSID, Supported rates, | 606 | /* followed by some of SSID, Supported rates, |
607 | * FH Params, DS Params, CF Params, IBSS Params */ | 607 | * FH Params, DS Params, CF Params, IBSS Params */ |
608 | u8 variable[0]; | 608 | u8 variable[0]; |
609 | } __attribute__ ((packed)) probe_resp; | 609 | } __attribute__ ((packed)) probe_resp; |
610 | struct { | 610 | struct { |
611 | u8 category; | 611 | u8 category; |
612 | union { | 612 | union { |
613 | struct { | 613 | struct { |
614 | u8 action_code; | 614 | u8 action_code; |
615 | u8 dialog_token; | 615 | u8 dialog_token; |
616 | u8 status_code; | 616 | u8 status_code; |
617 | u8 variable[0]; | 617 | u8 variable[0]; |
618 | } __attribute__ ((packed)) wme_action; | 618 | } __attribute__ ((packed)) wme_action; |
619 | struct{ | 619 | struct{ |
620 | u8 action_code; | 620 | u8 action_code; |
621 | u8 element_id; | 621 | u8 element_id; |
622 | u8 length; | 622 | u8 length; |
623 | struct ieee80211_channel_sw_ie sw_elem; | 623 | struct ieee80211_channel_sw_ie sw_elem; |
624 | } __attribute__((packed)) chan_switch; | 624 | } __attribute__((packed)) chan_switch; |
625 | struct{ | 625 | struct{ |
626 | u8 action_code; | 626 | u8 action_code; |
627 | u8 dialog_token; | 627 | u8 dialog_token; |
628 | u8 element_id; | 628 | u8 element_id; |
629 | u8 length; | 629 | u8 length; |
630 | struct ieee80211_msrment_ie msr_elem; | 630 | struct ieee80211_msrment_ie msr_elem; |
631 | } __attribute__((packed)) measurement; | 631 | } __attribute__((packed)) measurement; |
632 | struct{ | 632 | struct{ |
633 | u8 action_code; | 633 | u8 action_code; |
634 | u8 dialog_token; | 634 | u8 dialog_token; |
635 | __le16 capab; | 635 | __le16 capab; |
636 | __le16 timeout; | 636 | __le16 timeout; |
637 | __le16 start_seq_num; | 637 | __le16 start_seq_num; |
638 | } __attribute__((packed)) addba_req; | 638 | } __attribute__((packed)) addba_req; |
639 | struct{ | 639 | struct{ |
640 | u8 action_code; | 640 | u8 action_code; |
641 | u8 dialog_token; | 641 | u8 dialog_token; |
642 | __le16 status; | 642 | __le16 status; |
643 | __le16 capab; | 643 | __le16 capab; |
644 | __le16 timeout; | 644 | __le16 timeout; |
645 | } __attribute__((packed)) addba_resp; | 645 | } __attribute__((packed)) addba_resp; |
646 | struct{ | 646 | struct{ |
647 | u8 action_code; | 647 | u8 action_code; |
648 | __le16 params; | 648 | __le16 params; |
649 | __le16 reason_code; | 649 | __le16 reason_code; |
650 | } __attribute__((packed)) delba; | 650 | } __attribute__((packed)) delba; |
651 | struct{ | 651 | struct{ |
652 | u8 action_code; | 652 | u8 action_code; |
653 | /* capab_info for open and confirm, | 653 | /* capab_info for open and confirm, |
654 | * reason for close | 654 | * reason for close |
655 | */ | 655 | */ |
656 | __le16 aux; | 656 | __le16 aux; |
657 | /* Followed in plink_confirm by status | 657 | /* Followed in plink_confirm by status |
658 | * code, AID and supported rates, | 658 | * code, AID and supported rates, |
659 | * and directly by supported rates in | 659 | * and directly by supported rates in |
660 | * plink_open and plink_close | 660 | * plink_open and plink_close |
661 | */ | 661 | */ |
662 | u8 variable[0]; | 662 | u8 variable[0]; |
663 | } __attribute__((packed)) plink_action; | 663 | } __attribute__((packed)) plink_action; |
664 | struct{ | 664 | struct{ |
665 | u8 action_code; | 665 | u8 action_code; |
666 | u8 variable[0]; | 666 | u8 variable[0]; |
667 | } __attribute__((packed)) mesh_action; | 667 | } __attribute__((packed)) mesh_action; |
668 | struct { | 668 | struct { |
669 | u8 action; | 669 | u8 action; |
670 | u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; | 670 | u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN]; |
671 | } __attribute__ ((packed)) sa_query; | 671 | } __attribute__ ((packed)) sa_query; |
672 | } u; | 672 | } u; |
673 | } __attribute__ ((packed)) action; | 673 | } __attribute__ ((packed)) action; |
674 | } u; | 674 | } u; |
675 | } __attribute__ ((packed)); | 675 | } __attribute__ ((packed)); |
676 | 676 | ||
677 | /* mgmt header + 1 byte category code */ | 677 | /* mgmt header + 1 byte category code */ |
678 | #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) | 678 | #define IEEE80211_MIN_ACTION_SIZE offsetof(struct ieee80211_mgmt, u.action.u) |
679 | 679 | ||
680 | 680 | ||
681 | /* Management MIC information element (IEEE 802.11w) */ | 681 | /* Management MIC information element (IEEE 802.11w) */ |
682 | struct ieee80211_mmie { | 682 | struct ieee80211_mmie { |
683 | u8 element_id; | 683 | u8 element_id; |
684 | u8 length; | 684 | u8 length; |
685 | __le16 key_id; | 685 | __le16 key_id; |
686 | u8 sequence_number[6]; | 686 | u8 sequence_number[6]; |
687 | u8 mic[8]; | 687 | u8 mic[8]; |
688 | } __attribute__ ((packed)); | 688 | } __attribute__ ((packed)); |
689 | 689 | ||
690 | /* Control frames */ | 690 | /* Control frames */ |
691 | struct ieee80211_rts { | 691 | struct ieee80211_rts { |
692 | __le16 frame_control; | 692 | __le16 frame_control; |
693 | __le16 duration; | 693 | __le16 duration; |
694 | u8 ra[6]; | 694 | u8 ra[6]; |
695 | u8 ta[6]; | 695 | u8 ta[6]; |
696 | } __attribute__ ((packed)); | 696 | } __attribute__ ((packed)); |
697 | 697 | ||
698 | struct ieee80211_cts { | 698 | struct ieee80211_cts { |
699 | __le16 frame_control; | 699 | __le16 frame_control; |
700 | __le16 duration; | 700 | __le16 duration; |
701 | u8 ra[6]; | 701 | u8 ra[6]; |
702 | } __attribute__ ((packed)); | 702 | } __attribute__ ((packed)); |
703 | 703 | ||
704 | struct ieee80211_pspoll { | 704 | struct ieee80211_pspoll { |
705 | __le16 frame_control; | 705 | __le16 frame_control; |
706 | __le16 aid; | 706 | __le16 aid; |
707 | u8 bssid[6]; | 707 | u8 bssid[6]; |
708 | u8 ta[6]; | 708 | u8 ta[6]; |
709 | } __attribute__ ((packed)); | 709 | } __attribute__ ((packed)); |
710 | 710 | ||
711 | /** | 711 | /** |
712 | * struct ieee80211_bar - HT Block Ack Request | 712 | * struct ieee80211_bar - HT Block Ack Request |
713 | * | 713 | * |
714 | * This structure refers to "HT BlockAckReq" as | 714 | * This structure refers to "HT BlockAckReq" as |
715 | * described in 802.11n draft section 7.2.1.7.1 | 715 | * described in 802.11n draft section 7.2.1.7.1 |
716 | */ | 716 | */ |
717 | struct ieee80211_bar { | 717 | struct ieee80211_bar { |
718 | __le16 frame_control; | 718 | __le16 frame_control; |
719 | __le16 duration; | 719 | __le16 duration; |
720 | __u8 ra[6]; | 720 | __u8 ra[6]; |
721 | __u8 ta[6]; | 721 | __u8 ta[6]; |
722 | __le16 control; | 722 | __le16 control; |
723 | __le16 start_seq_num; | 723 | __le16 start_seq_num; |
724 | } __attribute__((packed)); | 724 | } __attribute__((packed)); |
725 | 725 | ||
726 | /* 802.11 BAR control masks */ | 726 | /* 802.11 BAR control masks */ |
727 | #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 | 727 | #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL 0x0000 |
728 | #define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 | 728 | #define IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA 0x0004 |
729 | 729 | ||
730 | 730 | ||
731 | #define IEEE80211_HT_MCS_MASK_LEN 10 | 731 | #define IEEE80211_HT_MCS_MASK_LEN 10 |
732 | 732 | ||
733 | /** | 733 | /** |
734 | * struct ieee80211_mcs_info - MCS information | 734 | * struct ieee80211_mcs_info - MCS information |
735 | * @rx_mask: RX mask | 735 | * @rx_mask: RX mask |
736 | * @rx_highest: highest supported RX rate | 736 | * @rx_highest: highest supported RX rate |
737 | * @tx_params: TX parameters | 737 | * @tx_params: TX parameters |
738 | */ | 738 | */ |
739 | struct ieee80211_mcs_info { | 739 | struct ieee80211_mcs_info { |
740 | u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; | 740 | u8 rx_mask[IEEE80211_HT_MCS_MASK_LEN]; |
741 | __le16 rx_highest; | 741 | __le16 rx_highest; |
742 | u8 tx_params; | 742 | u8 tx_params; |
743 | u8 reserved[3]; | 743 | u8 reserved[3]; |
744 | } __attribute__((packed)); | 744 | } __attribute__((packed)); |
745 | 745 | ||
746 | /* 802.11n HT capability MSC set */ | 746 | /* 802.11n HT capability MSC set */ |
747 | #define IEEE80211_HT_MCS_RX_HIGHEST_MASK 0x3ff | 747 | #define IEEE80211_HT_MCS_RX_HIGHEST_MASK 0x3ff |
748 | #define IEEE80211_HT_MCS_TX_DEFINED 0x01 | 748 | #define IEEE80211_HT_MCS_TX_DEFINED 0x01 |
749 | #define IEEE80211_HT_MCS_TX_RX_DIFF 0x02 | 749 | #define IEEE80211_HT_MCS_TX_RX_DIFF 0x02 |
750 | /* value 0 == 1 stream etc */ | 750 | /* value 0 == 1 stream etc */ |
751 | #define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK 0x0C | 751 | #define IEEE80211_HT_MCS_TX_MAX_STREAMS_MASK 0x0C |
752 | #define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2 | 752 | #define IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT 2 |
753 | #define IEEE80211_HT_MCS_TX_MAX_STREAMS 4 | 753 | #define IEEE80211_HT_MCS_TX_MAX_STREAMS 4 |
754 | #define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION 0x10 | 754 | #define IEEE80211_HT_MCS_TX_UNEQUAL_MODULATION 0x10 |
755 | 755 | ||
756 | /* | 756 | /* |
757 | * 802.11n D5.0 20.3.5 / 20.6 says: | 757 | * 802.11n D5.0 20.3.5 / 20.6 says: |
758 | * - indices 0 to 7 and 32 are single spatial stream | 758 | * - indices 0 to 7 and 32 are single spatial stream |
759 | * - 8 to 31 are multiple spatial streams using equal modulation | 759 | * - 8 to 31 are multiple spatial streams using equal modulation |
760 | * [8..15 for two streams, 16..23 for three and 24..31 for four] | 760 | * [8..15 for two streams, 16..23 for three and 24..31 for four] |
761 | * - remainder are multiple spatial streams using unequal modulation | 761 | * - remainder are multiple spatial streams using unequal modulation |
762 | */ | 762 | */ |
763 | #define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33 | 763 | #define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START 33 |
764 | #define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \ | 764 | #define IEEE80211_HT_MCS_UNEQUAL_MODULATION_START_BYTE \ |
765 | (IEEE80211_HT_MCS_UNEQUAL_MODULATION_START / 8) | 765 | (IEEE80211_HT_MCS_UNEQUAL_MODULATION_START / 8) |
766 | 766 | ||
767 | /** | 767 | /** |
768 | * struct ieee80211_ht_cap - HT capabilities | 768 | * struct ieee80211_ht_cap - HT capabilities |
769 | * | 769 | * |
770 | * This structure is the "HT capabilities element" as | 770 | * This structure is the "HT capabilities element" as |
771 | * described in 802.11n D5.0 7.3.2.57 | 771 | * described in 802.11n D5.0 7.3.2.57 |
772 | */ | 772 | */ |
773 | struct ieee80211_ht_cap { | 773 | struct ieee80211_ht_cap { |
774 | __le16 cap_info; | 774 | __le16 cap_info; |
775 | u8 ampdu_params_info; | 775 | u8 ampdu_params_info; |
776 | 776 | ||
777 | /* 16 bytes MCS information */ | 777 | /* 16 bytes MCS information */ |
778 | struct ieee80211_mcs_info mcs; | 778 | struct ieee80211_mcs_info mcs; |
779 | 779 | ||
780 | __le16 extended_ht_cap_info; | 780 | __le16 extended_ht_cap_info; |
781 | __le32 tx_BF_cap_info; | 781 | __le32 tx_BF_cap_info; |
782 | u8 antenna_selection_info; | 782 | u8 antenna_selection_info; |
783 | } __attribute__ ((packed)); | 783 | } __attribute__ ((packed)); |
784 | 784 | ||
785 | /* 802.11n HT capabilities masks (for cap_info) */ | 785 | /* 802.11n HT capabilities masks (for cap_info) */ |
786 | #define IEEE80211_HT_CAP_LDPC_CODING 0x0001 | 786 | #define IEEE80211_HT_CAP_LDPC_CODING 0x0001 |
787 | #define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 | 787 | #define IEEE80211_HT_CAP_SUP_WIDTH_20_40 0x0002 |
788 | #define IEEE80211_HT_CAP_SM_PS 0x000C | 788 | #define IEEE80211_HT_CAP_SM_PS 0x000C |
789 | #define IEEE80211_HT_CAP_GRN_FLD 0x0010 | 789 | #define IEEE80211_HT_CAP_GRN_FLD 0x0010 |
790 | #define IEEE80211_HT_CAP_SGI_20 0x0020 | 790 | #define IEEE80211_HT_CAP_SGI_20 0x0020 |
791 | #define IEEE80211_HT_CAP_SGI_40 0x0040 | 791 | #define IEEE80211_HT_CAP_SGI_40 0x0040 |
792 | #define IEEE80211_HT_CAP_TX_STBC 0x0080 | 792 | #define IEEE80211_HT_CAP_TX_STBC 0x0080 |
793 | #define IEEE80211_HT_CAP_RX_STBC 0x0300 | 793 | #define IEEE80211_HT_CAP_RX_STBC 0x0300 |
794 | #define IEEE80211_HT_CAP_DELAY_BA 0x0400 | 794 | #define IEEE80211_HT_CAP_DELAY_BA 0x0400 |
795 | #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 | 795 | #define IEEE80211_HT_CAP_MAX_AMSDU 0x0800 |
796 | #define IEEE80211_HT_CAP_DSSSCCK40 0x1000 | 796 | #define IEEE80211_HT_CAP_DSSSCCK40 0x1000 |
797 | #define IEEE80211_HT_CAP_PSMP_SUPPORT 0x2000 | 797 | #define IEEE80211_HT_CAP_PSMP_SUPPORT 0x2000 |
798 | #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 | 798 | #define IEEE80211_HT_CAP_40MHZ_INTOLERANT 0x4000 |
799 | #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 | 799 | #define IEEE80211_HT_CAP_LSIG_TXOP_PROT 0x8000 |
800 | 800 | ||
801 | /* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ | 801 | /* 802.11n HT capability AMPDU settings (for ampdu_params_info) */ |
802 | #define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 | 802 | #define IEEE80211_HT_AMPDU_PARM_FACTOR 0x03 |
803 | #define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C | 803 | #define IEEE80211_HT_AMPDU_PARM_DENSITY 0x1C |
804 | 804 | ||
805 | /* | 805 | /* |
806 | * Maximum length of AMPDU that the STA can receive. | 806 | * Maximum length of AMPDU that the STA can receive. |
807 | * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) | 807 | * Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets) |
808 | */ | 808 | */ |
809 | enum ieee80211_max_ampdu_length_exp { | 809 | enum ieee80211_max_ampdu_length_exp { |
810 | IEEE80211_HT_MAX_AMPDU_8K = 0, | 810 | IEEE80211_HT_MAX_AMPDU_8K = 0, |
811 | IEEE80211_HT_MAX_AMPDU_16K = 1, | 811 | IEEE80211_HT_MAX_AMPDU_16K = 1, |
812 | IEEE80211_HT_MAX_AMPDU_32K = 2, | 812 | IEEE80211_HT_MAX_AMPDU_32K = 2, |
813 | IEEE80211_HT_MAX_AMPDU_64K = 3 | 813 | IEEE80211_HT_MAX_AMPDU_64K = 3 |
814 | }; | 814 | }; |
815 | 815 | ||
816 | #define IEEE80211_HT_MAX_AMPDU_FACTOR 13 | 816 | #define IEEE80211_HT_MAX_AMPDU_FACTOR 13 |
817 | 817 | ||
818 | /* Minimum MPDU start spacing */ | 818 | /* Minimum MPDU start spacing */ |
819 | enum ieee80211_min_mpdu_spacing { | 819 | enum ieee80211_min_mpdu_spacing { |
820 | IEEE80211_HT_MPDU_DENSITY_NONE = 0, /* No restriction */ | 820 | IEEE80211_HT_MPDU_DENSITY_NONE = 0, /* No restriction */ |
821 | IEEE80211_HT_MPDU_DENSITY_0_25 = 1, /* 1/4 usec */ | 821 | IEEE80211_HT_MPDU_DENSITY_0_25 = 1, /* 1/4 usec */ |
822 | IEEE80211_HT_MPDU_DENSITY_0_5 = 2, /* 1/2 usec */ | 822 | IEEE80211_HT_MPDU_DENSITY_0_5 = 2, /* 1/2 usec */ |
823 | IEEE80211_HT_MPDU_DENSITY_1 = 3, /* 1 usec */ | 823 | IEEE80211_HT_MPDU_DENSITY_1 = 3, /* 1 usec */ |
824 | IEEE80211_HT_MPDU_DENSITY_2 = 4, /* 2 usec */ | 824 | IEEE80211_HT_MPDU_DENSITY_2 = 4, /* 2 usec */ |
825 | IEEE80211_HT_MPDU_DENSITY_4 = 5, /* 4 usec */ | 825 | IEEE80211_HT_MPDU_DENSITY_4 = 5, /* 4 usec */ |
826 | IEEE80211_HT_MPDU_DENSITY_8 = 6, /* 8 usec */ | 826 | IEEE80211_HT_MPDU_DENSITY_8 = 6, /* 8 usec */ |
827 | IEEE80211_HT_MPDU_DENSITY_16 = 7 /* 16 usec */ | 827 | IEEE80211_HT_MPDU_DENSITY_16 = 7 /* 16 usec */ |
828 | }; | 828 | }; |
829 | 829 | ||
830 | /** | 830 | /** |
831 | * struct ieee80211_ht_info - HT information | 831 | * struct ieee80211_ht_info - HT information |
832 | * | 832 | * |
833 | * This structure is the "HT information element" as | 833 | * This structure is the "HT information element" as |
834 | * described in 802.11n D5.0 7.3.2.58 | 834 | * described in 802.11n D5.0 7.3.2.58 |
835 | */ | 835 | */ |
836 | struct ieee80211_ht_info { | 836 | struct ieee80211_ht_info { |
837 | u8 control_chan; | 837 | u8 control_chan; |
838 | u8 ht_param; | 838 | u8 ht_param; |
839 | __le16 operation_mode; | 839 | __le16 operation_mode; |
840 | __le16 stbc_param; | 840 | __le16 stbc_param; |
841 | u8 basic_set[16]; | 841 | u8 basic_set[16]; |
842 | } __attribute__ ((packed)); | 842 | } __attribute__ ((packed)); |
843 | 843 | ||
844 | /* for ht_param */ | 844 | /* for ht_param */ |
845 | #define IEEE80211_HT_PARAM_CHA_SEC_OFFSET 0x03 | 845 | #define IEEE80211_HT_PARAM_CHA_SEC_OFFSET 0x03 |
846 | #define IEEE80211_HT_PARAM_CHA_SEC_NONE 0x00 | 846 | #define IEEE80211_HT_PARAM_CHA_SEC_NONE 0x00 |
847 | #define IEEE80211_HT_PARAM_CHA_SEC_ABOVE 0x01 | 847 | #define IEEE80211_HT_PARAM_CHA_SEC_ABOVE 0x01 |
848 | #define IEEE80211_HT_PARAM_CHA_SEC_BELOW 0x03 | 848 | #define IEEE80211_HT_PARAM_CHA_SEC_BELOW 0x03 |
849 | #define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY 0x04 | 849 | #define IEEE80211_HT_PARAM_CHAN_WIDTH_ANY 0x04 |
850 | #define IEEE80211_HT_PARAM_RIFS_MODE 0x08 | 850 | #define IEEE80211_HT_PARAM_RIFS_MODE 0x08 |
851 | #define IEEE80211_HT_PARAM_SPSMP_SUPPORT 0x10 | 851 | #define IEEE80211_HT_PARAM_SPSMP_SUPPORT 0x10 |
852 | #define IEEE80211_HT_PARAM_SERV_INTERVAL_GRAN 0xE0 | 852 | #define IEEE80211_HT_PARAM_SERV_INTERVAL_GRAN 0xE0 |
853 | 853 | ||
854 | /* for operation_mode */ | 854 | /* for operation_mode */ |
855 | #define IEEE80211_HT_OP_MODE_PROTECTION 0x0003 | 855 | #define IEEE80211_HT_OP_MODE_PROTECTION 0x0003 |
856 | #define IEEE80211_HT_OP_MODE_PROTECTION_NONE 0 | 856 | #define IEEE80211_HT_OP_MODE_PROTECTION_NONE 0 |
857 | #define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER 1 | 857 | #define IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER 1 |
858 | #define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ 2 | 858 | #define IEEE80211_HT_OP_MODE_PROTECTION_20MHZ 2 |
859 | #define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 3 | 859 | #define IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED 3 |
860 | #define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT 0x0004 | 860 | #define IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT 0x0004 |
861 | #define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT 0x0010 | 861 | #define IEEE80211_HT_OP_MODE_NON_HT_STA_PRSNT 0x0010 |
862 | 862 | ||
863 | /* for stbc_param */ | 863 | /* for stbc_param */ |
864 | #define IEEE80211_HT_STBC_PARAM_DUAL_BEACON 0x0040 | 864 | #define IEEE80211_HT_STBC_PARAM_DUAL_BEACON 0x0040 |
865 | #define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT 0x0080 | 865 | #define IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT 0x0080 |
866 | #define IEEE80211_HT_STBC_PARAM_STBC_BEACON 0x0100 | 866 | #define IEEE80211_HT_STBC_PARAM_STBC_BEACON 0x0100 |
867 | #define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT 0x0200 | 867 | #define IEEE80211_HT_STBC_PARAM_LSIG_TXOP_FULLPROT 0x0200 |
868 | #define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE 0x0400 | 868 | #define IEEE80211_HT_STBC_PARAM_PCO_ACTIVE 0x0400 |
869 | #define IEEE80211_HT_STBC_PARAM_PCO_PHASE 0x0800 | 869 | #define IEEE80211_HT_STBC_PARAM_PCO_PHASE 0x0800 |
870 | 870 | ||
871 | 871 | ||
872 | /* block-ack parameters */ | 872 | /* block-ack parameters */ |
873 | #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 | 873 | #define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002 |
874 | #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C | 874 | #define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C |
875 | #define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 | 875 | #define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0 |
876 | #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 | 876 | #define IEEE80211_DELBA_PARAM_TID_MASK 0xF000 |
877 | #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 | 877 | #define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800 |
878 | 878 | ||
879 | /* | 879 | /* |
880 | * A-PMDU buffer sizes | 880 | * A-PMDU buffer sizes |
881 | * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) | 881 | * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) |
882 | */ | 882 | */ |
883 | #define IEEE80211_MIN_AMPDU_BUF 0x8 | 883 | #define IEEE80211_MIN_AMPDU_BUF 0x8 |
884 | #define IEEE80211_MAX_AMPDU_BUF 0x40 | 884 | #define IEEE80211_MAX_AMPDU_BUF 0x40 |
885 | 885 | ||
886 | 886 | ||
887 | /* Spatial Multiplexing Power Save Modes */ | 887 | /* Spatial Multiplexing Power Save Modes */ |
888 | #define WLAN_HT_CAP_SM_PS_STATIC 0 | 888 | #define WLAN_HT_CAP_SM_PS_STATIC 0 |
889 | #define WLAN_HT_CAP_SM_PS_DYNAMIC 1 | 889 | #define WLAN_HT_CAP_SM_PS_DYNAMIC 1 |
890 | #define WLAN_HT_CAP_SM_PS_INVALID 2 | 890 | #define WLAN_HT_CAP_SM_PS_INVALID 2 |
891 | #define WLAN_HT_CAP_SM_PS_DISABLED 3 | 891 | #define WLAN_HT_CAP_SM_PS_DISABLED 3 |
892 | 892 | ||
893 | /* Authentication algorithms */ | 893 | /* Authentication algorithms */ |
894 | #define WLAN_AUTH_OPEN 0 | 894 | #define WLAN_AUTH_OPEN 0 |
895 | #define WLAN_AUTH_SHARED_KEY 1 | 895 | #define WLAN_AUTH_SHARED_KEY 1 |
896 | #define WLAN_AUTH_FT 2 | 896 | #define WLAN_AUTH_FT 2 |
897 | #define WLAN_AUTH_LEAP 128 | 897 | #define WLAN_AUTH_LEAP 128 |
898 | 898 | ||
899 | #define WLAN_AUTH_CHALLENGE_LEN 128 | 899 | #define WLAN_AUTH_CHALLENGE_LEN 128 |
900 | 900 | ||
901 | #define WLAN_CAPABILITY_ESS (1<<0) | 901 | #define WLAN_CAPABILITY_ESS (1<<0) |
902 | #define WLAN_CAPABILITY_IBSS (1<<1) | 902 | #define WLAN_CAPABILITY_IBSS (1<<1) |
903 | #define WLAN_CAPABILITY_CF_POLLABLE (1<<2) | 903 | #define WLAN_CAPABILITY_CF_POLLABLE (1<<2) |
904 | #define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) | 904 | #define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) |
905 | #define WLAN_CAPABILITY_PRIVACY (1<<4) | 905 | #define WLAN_CAPABILITY_PRIVACY (1<<4) |
906 | #define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) | 906 | #define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) |
907 | #define WLAN_CAPABILITY_PBCC (1<<6) | 907 | #define WLAN_CAPABILITY_PBCC (1<<6) |
908 | #define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) | 908 | #define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) |
909 | 909 | ||
910 | /* 802.11h */ | 910 | /* 802.11h */ |
911 | #define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) | 911 | #define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) |
912 | #define WLAN_CAPABILITY_QOS (1<<9) | 912 | #define WLAN_CAPABILITY_QOS (1<<9) |
913 | #define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) | 913 | #define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) |
914 | #define WLAN_CAPABILITY_DSSS_OFDM (1<<13) | 914 | #define WLAN_CAPABILITY_DSSS_OFDM (1<<13) |
915 | /* measurement */ | 915 | /* measurement */ |
916 | #define IEEE80211_SPCT_MSR_RPRT_MODE_LATE (1<<0) | 916 | #define IEEE80211_SPCT_MSR_RPRT_MODE_LATE (1<<0) |
917 | #define IEEE80211_SPCT_MSR_RPRT_MODE_INCAPABLE (1<<1) | 917 | #define IEEE80211_SPCT_MSR_RPRT_MODE_INCAPABLE (1<<1) |
918 | #define IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED (1<<2) | 918 | #define IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED (1<<2) |
919 | 919 | ||
920 | #define IEEE80211_SPCT_MSR_RPRT_TYPE_BASIC 0 | 920 | #define IEEE80211_SPCT_MSR_RPRT_TYPE_BASIC 0 |
921 | #define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1 | 921 | #define IEEE80211_SPCT_MSR_RPRT_TYPE_CCA 1 |
922 | #define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2 | 922 | #define IEEE80211_SPCT_MSR_RPRT_TYPE_RPI 2 |
923 | 923 | ||
924 | 924 | ||
925 | /* 802.11g ERP information element */ | 925 | /* 802.11g ERP information element */ |
926 | #define WLAN_ERP_NON_ERP_PRESENT (1<<0) | 926 | #define WLAN_ERP_NON_ERP_PRESENT (1<<0) |
927 | #define WLAN_ERP_USE_PROTECTION (1<<1) | 927 | #define WLAN_ERP_USE_PROTECTION (1<<1) |
928 | #define WLAN_ERP_BARKER_PREAMBLE (1<<2) | 928 | #define WLAN_ERP_BARKER_PREAMBLE (1<<2) |
929 | 929 | ||
930 | /* WLAN_ERP_BARKER_PREAMBLE values */ | 930 | /* WLAN_ERP_BARKER_PREAMBLE values */ |
931 | enum { | 931 | enum { |
932 | WLAN_ERP_PREAMBLE_SHORT = 0, | 932 | WLAN_ERP_PREAMBLE_SHORT = 0, |
933 | WLAN_ERP_PREAMBLE_LONG = 1, | 933 | WLAN_ERP_PREAMBLE_LONG = 1, |
934 | }; | 934 | }; |
935 | 935 | ||
936 | /* Status codes */ | 936 | /* Status codes */ |
937 | enum ieee80211_statuscode { | 937 | enum ieee80211_statuscode { |
938 | WLAN_STATUS_SUCCESS = 0, | 938 | WLAN_STATUS_SUCCESS = 0, |
939 | WLAN_STATUS_UNSPECIFIED_FAILURE = 1, | 939 | WLAN_STATUS_UNSPECIFIED_FAILURE = 1, |
940 | WLAN_STATUS_CAPS_UNSUPPORTED = 10, | 940 | WLAN_STATUS_CAPS_UNSUPPORTED = 10, |
941 | WLAN_STATUS_REASSOC_NO_ASSOC = 11, | 941 | WLAN_STATUS_REASSOC_NO_ASSOC = 11, |
942 | WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12, | 942 | WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12, |
943 | WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13, | 943 | WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13, |
944 | WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14, | 944 | WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14, |
945 | WLAN_STATUS_CHALLENGE_FAIL = 15, | 945 | WLAN_STATUS_CHALLENGE_FAIL = 15, |
946 | WLAN_STATUS_AUTH_TIMEOUT = 16, | 946 | WLAN_STATUS_AUTH_TIMEOUT = 16, |
947 | WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17, | 947 | WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17, |
948 | WLAN_STATUS_ASSOC_DENIED_RATES = 18, | 948 | WLAN_STATUS_ASSOC_DENIED_RATES = 18, |
949 | /* 802.11b */ | 949 | /* 802.11b */ |
950 | WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19, | 950 | WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19, |
951 | WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20, | 951 | WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20, |
952 | WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21, | 952 | WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21, |
953 | /* 802.11h */ | 953 | /* 802.11h */ |
954 | WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22, | 954 | WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22, |
955 | WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, | 955 | WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, |
956 | WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, | 956 | WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, |
957 | /* 802.11g */ | 957 | /* 802.11g */ |
958 | WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, | 958 | WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, |
959 | WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, | 959 | WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, |
960 | /* 802.11w */ | 960 | /* 802.11w */ |
961 | WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY = 30, | 961 | WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY = 30, |
962 | WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31, | 962 | WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31, |
963 | /* 802.11i */ | 963 | /* 802.11i */ |
964 | WLAN_STATUS_INVALID_IE = 40, | 964 | WLAN_STATUS_INVALID_IE = 40, |
965 | WLAN_STATUS_INVALID_GROUP_CIPHER = 41, | 965 | WLAN_STATUS_INVALID_GROUP_CIPHER = 41, |
966 | WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42, | 966 | WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42, |
967 | WLAN_STATUS_INVALID_AKMP = 43, | 967 | WLAN_STATUS_INVALID_AKMP = 43, |
968 | WLAN_STATUS_UNSUPP_RSN_VERSION = 44, | 968 | WLAN_STATUS_UNSUPP_RSN_VERSION = 44, |
969 | WLAN_STATUS_INVALID_RSN_IE_CAP = 45, | 969 | WLAN_STATUS_INVALID_RSN_IE_CAP = 45, |
970 | WLAN_STATUS_CIPHER_SUITE_REJECTED = 46, | 970 | WLAN_STATUS_CIPHER_SUITE_REJECTED = 46, |
971 | /* 802.11e */ | 971 | /* 802.11e */ |
972 | WLAN_STATUS_UNSPECIFIED_QOS = 32, | 972 | WLAN_STATUS_UNSPECIFIED_QOS = 32, |
973 | WLAN_STATUS_ASSOC_DENIED_NOBANDWIDTH = 33, | 973 | WLAN_STATUS_ASSOC_DENIED_NOBANDWIDTH = 33, |
974 | WLAN_STATUS_ASSOC_DENIED_LOWACK = 34, | 974 | WLAN_STATUS_ASSOC_DENIED_LOWACK = 34, |
975 | WLAN_STATUS_ASSOC_DENIED_UNSUPP_QOS = 35, | 975 | WLAN_STATUS_ASSOC_DENIED_UNSUPP_QOS = 35, |
976 | WLAN_STATUS_REQUEST_DECLINED = 37, | 976 | WLAN_STATUS_REQUEST_DECLINED = 37, |
977 | WLAN_STATUS_INVALID_QOS_PARAM = 38, | 977 | WLAN_STATUS_INVALID_QOS_PARAM = 38, |
978 | WLAN_STATUS_CHANGE_TSPEC = 39, | 978 | WLAN_STATUS_CHANGE_TSPEC = 39, |
979 | WLAN_STATUS_WAIT_TS_DELAY = 47, | 979 | WLAN_STATUS_WAIT_TS_DELAY = 47, |
980 | WLAN_STATUS_NO_DIRECT_LINK = 48, | 980 | WLAN_STATUS_NO_DIRECT_LINK = 48, |
981 | WLAN_STATUS_STA_NOT_PRESENT = 49, | 981 | WLAN_STATUS_STA_NOT_PRESENT = 49, |
982 | WLAN_STATUS_STA_NOT_QSTA = 50, | 982 | WLAN_STATUS_STA_NOT_QSTA = 50, |
983 | }; | 983 | }; |
984 | 984 | ||
985 | 985 | ||
986 | /* Reason codes */ | 986 | /* Reason codes */ |
987 | enum ieee80211_reasoncode { | 987 | enum ieee80211_reasoncode { |
988 | WLAN_REASON_UNSPECIFIED = 1, | 988 | WLAN_REASON_UNSPECIFIED = 1, |
989 | WLAN_REASON_PREV_AUTH_NOT_VALID = 2, | 989 | WLAN_REASON_PREV_AUTH_NOT_VALID = 2, |
990 | WLAN_REASON_DEAUTH_LEAVING = 3, | 990 | WLAN_REASON_DEAUTH_LEAVING = 3, |
991 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, | 991 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, |
992 | WLAN_REASON_DISASSOC_AP_BUSY = 5, | 992 | WLAN_REASON_DISASSOC_AP_BUSY = 5, |
993 | WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, | 993 | WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, |
994 | WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, | 994 | WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, |
995 | WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, | 995 | WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, |
996 | WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, | 996 | WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, |
997 | /* 802.11h */ | 997 | /* 802.11h */ |
998 | WLAN_REASON_DISASSOC_BAD_POWER = 10, | 998 | WLAN_REASON_DISASSOC_BAD_POWER = 10, |
999 | WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, | 999 | WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, |
1000 | /* 802.11i */ | 1000 | /* 802.11i */ |
1001 | WLAN_REASON_INVALID_IE = 13, | 1001 | WLAN_REASON_INVALID_IE = 13, |
1002 | WLAN_REASON_MIC_FAILURE = 14, | 1002 | WLAN_REASON_MIC_FAILURE = 14, |
1003 | WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, | 1003 | WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, |
1004 | WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, | 1004 | WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, |
1005 | WLAN_REASON_IE_DIFFERENT = 17, | 1005 | WLAN_REASON_IE_DIFFERENT = 17, |
1006 | WLAN_REASON_INVALID_GROUP_CIPHER = 18, | 1006 | WLAN_REASON_INVALID_GROUP_CIPHER = 18, |
1007 | WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, | 1007 | WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, |
1008 | WLAN_REASON_INVALID_AKMP = 20, | 1008 | WLAN_REASON_INVALID_AKMP = 20, |
1009 | WLAN_REASON_UNSUPP_RSN_VERSION = 21, | 1009 | WLAN_REASON_UNSUPP_RSN_VERSION = 21, |
1010 | WLAN_REASON_INVALID_RSN_IE_CAP = 22, | 1010 | WLAN_REASON_INVALID_RSN_IE_CAP = 22, |
1011 | WLAN_REASON_IEEE8021X_FAILED = 23, | 1011 | WLAN_REASON_IEEE8021X_FAILED = 23, |
1012 | WLAN_REASON_CIPHER_SUITE_REJECTED = 24, | 1012 | WLAN_REASON_CIPHER_SUITE_REJECTED = 24, |
1013 | /* 802.11e */ | 1013 | /* 802.11e */ |
1014 | WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32, | 1014 | WLAN_REASON_DISASSOC_UNSPECIFIED_QOS = 32, |
1015 | WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33, | 1015 | WLAN_REASON_DISASSOC_QAP_NO_BANDWIDTH = 33, |
1016 | WLAN_REASON_DISASSOC_LOW_ACK = 34, | 1016 | WLAN_REASON_DISASSOC_LOW_ACK = 34, |
1017 | WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP = 35, | 1017 | WLAN_REASON_DISASSOC_QAP_EXCEED_TXOP = 35, |
1018 | WLAN_REASON_QSTA_LEAVE_QBSS = 36, | 1018 | WLAN_REASON_QSTA_LEAVE_QBSS = 36, |
1019 | WLAN_REASON_QSTA_NOT_USE = 37, | 1019 | WLAN_REASON_QSTA_NOT_USE = 37, |
1020 | WLAN_REASON_QSTA_REQUIRE_SETUP = 38, | 1020 | WLAN_REASON_QSTA_REQUIRE_SETUP = 38, |
1021 | WLAN_REASON_QSTA_TIMEOUT = 39, | 1021 | WLAN_REASON_QSTA_TIMEOUT = 39, |
1022 | WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45, | 1022 | WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45, |
1023 | }; | 1023 | }; |
1024 | 1024 | ||
1025 | 1025 | ||
1026 | /* Information Element IDs */ | 1026 | /* Information Element IDs */ |
1027 | enum ieee80211_eid { | 1027 | enum ieee80211_eid { |
1028 | WLAN_EID_SSID = 0, | 1028 | WLAN_EID_SSID = 0, |
1029 | WLAN_EID_SUPP_RATES = 1, | 1029 | WLAN_EID_SUPP_RATES = 1, |
1030 | WLAN_EID_FH_PARAMS = 2, | 1030 | WLAN_EID_FH_PARAMS = 2, |
1031 | WLAN_EID_DS_PARAMS = 3, | 1031 | WLAN_EID_DS_PARAMS = 3, |
1032 | WLAN_EID_CF_PARAMS = 4, | 1032 | WLAN_EID_CF_PARAMS = 4, |
1033 | WLAN_EID_TIM = 5, | 1033 | WLAN_EID_TIM = 5, |
1034 | WLAN_EID_IBSS_PARAMS = 6, | 1034 | WLAN_EID_IBSS_PARAMS = 6, |
1035 | WLAN_EID_CHALLENGE = 16, | 1035 | WLAN_EID_CHALLENGE = 16, |
1036 | /* 802.11d */ | 1036 | /* 802.11d */ |
1037 | WLAN_EID_COUNTRY = 7, | 1037 | WLAN_EID_COUNTRY = 7, |
1038 | WLAN_EID_HP_PARAMS = 8, | 1038 | WLAN_EID_HP_PARAMS = 8, |
1039 | WLAN_EID_HP_TABLE = 9, | 1039 | WLAN_EID_HP_TABLE = 9, |
1040 | WLAN_EID_REQUEST = 10, | 1040 | WLAN_EID_REQUEST = 10, |
1041 | /* 802.11e */ | 1041 | /* 802.11e */ |
1042 | WLAN_EID_QBSS_LOAD = 11, | 1042 | WLAN_EID_QBSS_LOAD = 11, |
1043 | WLAN_EID_EDCA_PARAM_SET = 12, | 1043 | WLAN_EID_EDCA_PARAM_SET = 12, |
1044 | WLAN_EID_TSPEC = 13, | 1044 | WLAN_EID_TSPEC = 13, |
1045 | WLAN_EID_TCLAS = 14, | 1045 | WLAN_EID_TCLAS = 14, |
1046 | WLAN_EID_SCHEDULE = 15, | 1046 | WLAN_EID_SCHEDULE = 15, |
1047 | WLAN_EID_TS_DELAY = 43, | 1047 | WLAN_EID_TS_DELAY = 43, |
1048 | WLAN_EID_TCLAS_PROCESSING = 44, | 1048 | WLAN_EID_TCLAS_PROCESSING = 44, |
1049 | WLAN_EID_QOS_CAPA = 46, | 1049 | WLAN_EID_QOS_CAPA = 46, |
1050 | /* 802.11s | 1050 | /* 802.11s |
1051 | * | 1051 | * |
1052 | * All mesh EID numbers are pending IEEE 802.11 ANA approval. | 1052 | * All mesh EID numbers are pending IEEE 802.11 ANA approval. |
1053 | * The numbers have been incremented from those suggested in | 1053 | * The numbers have been incremented from those suggested in |
1054 | * 802.11s/D2.0 so that MESH_CONFIG does not conflict with | 1054 | * 802.11s/D2.0 so that MESH_CONFIG does not conflict with |
1055 | * EXT_SUPP_RATES. | 1055 | * EXT_SUPP_RATES. |
1056 | */ | 1056 | */ |
1057 | WLAN_EID_MESH_CONFIG = 51, | 1057 | WLAN_EID_MESH_CONFIG = 51, |
1058 | WLAN_EID_MESH_ID = 52, | 1058 | WLAN_EID_MESH_ID = 52, |
1059 | WLAN_EID_PEER_LINK = 55, | 1059 | WLAN_EID_PEER_LINK = 55, |
1060 | WLAN_EID_PREQ = 68, | 1060 | WLAN_EID_PREQ = 68, |
1061 | WLAN_EID_PREP = 69, | 1061 | WLAN_EID_PREP = 69, |
1062 | WLAN_EID_PERR = 70, | 1062 | WLAN_EID_PERR = 70, |
1063 | /* 802.11h */ | 1063 | /* 802.11h */ |
1064 | WLAN_EID_PWR_CONSTRAINT = 32, | 1064 | WLAN_EID_PWR_CONSTRAINT = 32, |
1065 | WLAN_EID_PWR_CAPABILITY = 33, | 1065 | WLAN_EID_PWR_CAPABILITY = 33, |
1066 | WLAN_EID_TPC_REQUEST = 34, | 1066 | WLAN_EID_TPC_REQUEST = 34, |
1067 | WLAN_EID_TPC_REPORT = 35, | 1067 | WLAN_EID_TPC_REPORT = 35, |
1068 | WLAN_EID_SUPPORTED_CHANNELS = 36, | 1068 | WLAN_EID_SUPPORTED_CHANNELS = 36, |
1069 | WLAN_EID_CHANNEL_SWITCH = 37, | 1069 | WLAN_EID_CHANNEL_SWITCH = 37, |
1070 | WLAN_EID_MEASURE_REQUEST = 38, | 1070 | WLAN_EID_MEASURE_REQUEST = 38, |
1071 | WLAN_EID_MEASURE_REPORT = 39, | 1071 | WLAN_EID_MEASURE_REPORT = 39, |
1072 | WLAN_EID_QUIET = 40, | 1072 | WLAN_EID_QUIET = 40, |
1073 | WLAN_EID_IBSS_DFS = 41, | 1073 | WLAN_EID_IBSS_DFS = 41, |
1074 | /* 802.11g */ | 1074 | /* 802.11g */ |
1075 | WLAN_EID_ERP_INFO = 42, | 1075 | WLAN_EID_ERP_INFO = 42, |
1076 | WLAN_EID_EXT_SUPP_RATES = 50, | 1076 | WLAN_EID_EXT_SUPP_RATES = 50, |
1077 | /* 802.11n */ | 1077 | /* 802.11n */ |
1078 | WLAN_EID_HT_CAPABILITY = 45, | 1078 | WLAN_EID_HT_CAPABILITY = 45, |
1079 | WLAN_EID_HT_INFORMATION = 61, | 1079 | WLAN_EID_HT_INFORMATION = 61, |
1080 | /* 802.11i */ | 1080 | /* 802.11i */ |
1081 | WLAN_EID_RSN = 48, | 1081 | WLAN_EID_RSN = 48, |
1082 | WLAN_EID_TIMEOUT_INTERVAL = 56, | 1082 | WLAN_EID_TIMEOUT_INTERVAL = 56, |
1083 | WLAN_EID_MMIE = 76 /* 802.11w */, | 1083 | WLAN_EID_MMIE = 76 /* 802.11w */, |
1084 | WLAN_EID_WPA = 221, | 1084 | WLAN_EID_WPA = 221, |
1085 | WLAN_EID_GENERIC = 221, | 1085 | WLAN_EID_GENERIC = 221, |
1086 | WLAN_EID_VENDOR_SPECIFIC = 221, | 1086 | WLAN_EID_VENDOR_SPECIFIC = 221, |
1087 | WLAN_EID_QOS_PARAMETER = 222 | 1087 | WLAN_EID_QOS_PARAMETER = 222 |
1088 | }; | 1088 | }; |
1089 | 1089 | ||
1090 | /* Action category code */ | 1090 | /* Action category code */ |
1091 | enum ieee80211_category { | 1091 | enum ieee80211_category { |
1092 | WLAN_CATEGORY_SPECTRUM_MGMT = 0, | 1092 | WLAN_CATEGORY_SPECTRUM_MGMT = 0, |
1093 | WLAN_CATEGORY_QOS = 1, | 1093 | WLAN_CATEGORY_QOS = 1, |
1094 | WLAN_CATEGORY_DLS = 2, | 1094 | WLAN_CATEGORY_DLS = 2, |
1095 | WLAN_CATEGORY_BACK = 3, | 1095 | WLAN_CATEGORY_BACK = 3, |
1096 | WLAN_CATEGORY_PUBLIC = 4, | 1096 | WLAN_CATEGORY_PUBLIC = 4, |
1097 | WLAN_CATEGORY_HT = 7, | 1097 | WLAN_CATEGORY_HT = 7, |
1098 | WLAN_CATEGORY_SA_QUERY = 8, | 1098 | WLAN_CATEGORY_SA_QUERY = 8, |
1099 | WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, | 1099 | WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION = 9, |
1100 | WLAN_CATEGORY_WMM = 17, | 1100 | WLAN_CATEGORY_WMM = 17, |
1101 | WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, | 1101 | WLAN_CATEGORY_VENDOR_SPECIFIC_PROTECTED = 126, |
1102 | WLAN_CATEGORY_VENDOR_SPECIFIC = 127, | 1102 | WLAN_CATEGORY_VENDOR_SPECIFIC = 127, |
1103 | }; | 1103 | }; |
1104 | 1104 | ||
1105 | /* SPECTRUM_MGMT action code */ | 1105 | /* SPECTRUM_MGMT action code */ |
1106 | enum ieee80211_spectrum_mgmt_actioncode { | 1106 | enum ieee80211_spectrum_mgmt_actioncode { |
1107 | WLAN_ACTION_SPCT_MSR_REQ = 0, | 1107 | WLAN_ACTION_SPCT_MSR_REQ = 0, |
1108 | WLAN_ACTION_SPCT_MSR_RPRT = 1, | 1108 | WLAN_ACTION_SPCT_MSR_RPRT = 1, |
1109 | WLAN_ACTION_SPCT_TPC_REQ = 2, | 1109 | WLAN_ACTION_SPCT_TPC_REQ = 2, |
1110 | WLAN_ACTION_SPCT_TPC_RPRT = 3, | 1110 | WLAN_ACTION_SPCT_TPC_RPRT = 3, |
1111 | WLAN_ACTION_SPCT_CHL_SWITCH = 4, | 1111 | WLAN_ACTION_SPCT_CHL_SWITCH = 4, |
1112 | }; | 1112 | }; |
1113 | 1113 | ||
1114 | /* Security key length */ | 1114 | /* Security key length */ |
1115 | enum ieee80211_key_len { | 1115 | enum ieee80211_key_len { |
1116 | WLAN_KEY_LEN_WEP40 = 5, | 1116 | WLAN_KEY_LEN_WEP40 = 5, |
1117 | WLAN_KEY_LEN_WEP104 = 13, | 1117 | WLAN_KEY_LEN_WEP104 = 13, |
1118 | WLAN_KEY_LEN_CCMP = 16, | 1118 | WLAN_KEY_LEN_CCMP = 16, |
1119 | WLAN_KEY_LEN_TKIP = 32, | 1119 | WLAN_KEY_LEN_TKIP = 32, |
1120 | WLAN_KEY_LEN_AES_CMAC = 16, | 1120 | WLAN_KEY_LEN_AES_CMAC = 16, |
1121 | }; | 1121 | }; |
1122 | 1122 | ||
1123 | /* | 1123 | /* |
1124 | * IEEE 802.11-2007 7.3.2.9 Country information element | 1124 | * IEEE 802.11-2007 7.3.2.9 Country information element |
1125 | * | 1125 | * |
1126 | * Minimum length is 8 octets, ie len must be evenly | 1126 | * Minimum length is 8 octets, ie len must be evenly |
1127 | * divisible by 2 | 1127 | * divisible by 2 |
1128 | */ | 1128 | */ |
1129 | 1129 | ||
1130 | /* Although the spec says 8 I'm seeing 6 in practice */ | 1130 | /* Although the spec says 8 I'm seeing 6 in practice */ |
1131 | #define IEEE80211_COUNTRY_IE_MIN_LEN 6 | 1131 | #define IEEE80211_COUNTRY_IE_MIN_LEN 6 |
1132 | 1132 | ||
1133 | /* | 1133 | /* |
1134 | * For regulatory extension stuff see IEEE 802.11-2007 | 1134 | * For regulatory extension stuff see IEEE 802.11-2007 |
1135 | * Annex I (page 1141) and Annex J (page 1147). Also | 1135 | * Annex I (page 1141) and Annex J (page 1147). Also |
1136 | * review 7.3.2.9. | 1136 | * review 7.3.2.9. |
1137 | * | 1137 | * |
1138 | * When dot11RegulatoryClassesRequired is true and the | 1138 | * When dot11RegulatoryClassesRequired is true and the |
1139 | * first_channel/reg_extension_id is >= 201 then the IE | 1139 | * first_channel/reg_extension_id is >= 201 then the IE |
1140 | * compromises of the 'ext' struct represented below: | 1140 | * compromises of the 'ext' struct represented below: |
1141 | * | 1141 | * |
1142 | * - Regulatory extension ID - when generating IE this just needs | 1142 | * - Regulatory extension ID - when generating IE this just needs |
1143 | * to be monotonically increasing for each triplet passed in | 1143 | * to be monotonically increasing for each triplet passed in |
1144 | * the IE | 1144 | * the IE |
1145 | * - Regulatory class - index into set of rules | 1145 | * - Regulatory class - index into set of rules |
1146 | * - Coverage class - index into air propagation time (Table 7-27), | 1146 | * - Coverage class - index into air propagation time (Table 7-27), |
1147 | * in microseconds, you can compute the air propagation time from | 1147 | * in microseconds, you can compute the air propagation time from |
1148 | * the index by multiplying by 3, so index 10 yields a propagation | 1148 | * the index by multiplying by 3, so index 10 yields a propagation |
1149 | * of 10 us. Valid values are 0-31, values 32-255 are not defined | 1149 | * of 10 us. Valid values are 0-31, values 32-255 are not defined |
1150 | * yet. A value of 0 inicates air propagation of <= 1 us. | 1150 | * yet. A value of 0 inicates air propagation of <= 1 us. |
1151 | * | 1151 | * |
1152 | * See also Table I.2 for Emission limit sets and table | 1152 | * See also Table I.2 for Emission limit sets and table |
1153 | * I.3 for Behavior limit sets. Table J.1 indicates how to map | 1153 | * I.3 for Behavior limit sets. Table J.1 indicates how to map |
1154 | * a reg_class to an emission limit set and behavior limit set. | 1154 | * a reg_class to an emission limit set and behavior limit set. |
1155 | */ | 1155 | */ |
1156 | #define IEEE80211_COUNTRY_EXTENSION_ID 201 | 1156 | #define IEEE80211_COUNTRY_EXTENSION_ID 201 |
1157 | 1157 | ||
1158 | /* | 1158 | /* |
1159 | * Channels numbers in the IE must be monotonically increasing | 1159 | * Channels numbers in the IE must be monotonically increasing |
1160 | * if dot11RegulatoryClassesRequired is not true. | 1160 | * if dot11RegulatoryClassesRequired is not true. |
1161 | * | 1161 | * |
1162 | * If dot11RegulatoryClassesRequired is true consecutive | 1162 | * If dot11RegulatoryClassesRequired is true consecutive |
1163 | * subband triplets following a regulatory triplet shall | 1163 | * subband triplets following a regulatory triplet shall |
1164 | * have monotonically increasing first_channel number fields. | 1164 | * have monotonically increasing first_channel number fields. |
1165 | * | 1165 | * |
1166 | * Channel numbers shall not overlap. | 1166 | * Channel numbers shall not overlap. |
1167 | * | 1167 | * |
1168 | * Note that max_power is signed. | 1168 | * Note that max_power is signed. |
1169 | */ | 1169 | */ |
1170 | struct ieee80211_country_ie_triplet { | 1170 | struct ieee80211_country_ie_triplet { |
1171 | union { | 1171 | union { |
1172 | struct { | 1172 | struct { |
1173 | u8 first_channel; | 1173 | u8 first_channel; |
1174 | u8 num_channels; | 1174 | u8 num_channels; |
1175 | s8 max_power; | 1175 | s8 max_power; |
1176 | } __attribute__ ((packed)) chans; | 1176 | } __attribute__ ((packed)) chans; |
1177 | struct { | 1177 | struct { |
1178 | u8 reg_extension_id; | 1178 | u8 reg_extension_id; |
1179 | u8 reg_class; | 1179 | u8 reg_class; |
1180 | u8 coverage_class; | 1180 | u8 coverage_class; |
1181 | } __attribute__ ((packed)) ext; | 1181 | } __attribute__ ((packed)) ext; |
1182 | }; | 1182 | }; |
1183 | } __attribute__ ((packed)); | 1183 | } __attribute__ ((packed)); |
1184 | 1184 | ||
1185 | enum ieee80211_timeout_interval_type { | 1185 | enum ieee80211_timeout_interval_type { |
1186 | WLAN_TIMEOUT_REASSOC_DEADLINE = 1 /* 802.11r */, | 1186 | WLAN_TIMEOUT_REASSOC_DEADLINE = 1 /* 802.11r */, |
1187 | WLAN_TIMEOUT_KEY_LIFETIME = 2 /* 802.11r */, | 1187 | WLAN_TIMEOUT_KEY_LIFETIME = 2 /* 802.11r */, |
1188 | WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */, | 1188 | WLAN_TIMEOUT_ASSOC_COMEBACK = 3 /* 802.11w */, |
1189 | }; | 1189 | }; |
1190 | 1190 | ||
1191 | /* BACK action code */ | 1191 | /* BACK action code */ |
1192 | enum ieee80211_back_actioncode { | 1192 | enum ieee80211_back_actioncode { |
1193 | WLAN_ACTION_ADDBA_REQ = 0, | 1193 | WLAN_ACTION_ADDBA_REQ = 0, |
1194 | WLAN_ACTION_ADDBA_RESP = 1, | 1194 | WLAN_ACTION_ADDBA_RESP = 1, |
1195 | WLAN_ACTION_DELBA = 2, | 1195 | WLAN_ACTION_DELBA = 2, |
1196 | }; | 1196 | }; |
1197 | 1197 | ||
1198 | /* BACK (block-ack) parties */ | 1198 | /* BACK (block-ack) parties */ |
1199 | enum ieee80211_back_parties { | 1199 | enum ieee80211_back_parties { |
1200 | WLAN_BACK_RECIPIENT = 0, | 1200 | WLAN_BACK_RECIPIENT = 0, |
1201 | WLAN_BACK_INITIATOR = 1, | 1201 | WLAN_BACK_INITIATOR = 1, |
1202 | WLAN_BACK_TIMER = 2, | 1202 | WLAN_BACK_TIMER = 2, |
1203 | }; | 1203 | }; |
1204 | 1204 | ||
1205 | /* SA Query action */ | 1205 | /* SA Query action */ |
1206 | enum ieee80211_sa_query_action { | 1206 | enum ieee80211_sa_query_action { |
1207 | WLAN_ACTION_SA_QUERY_REQUEST = 0, | 1207 | WLAN_ACTION_SA_QUERY_REQUEST = 0, |
1208 | WLAN_ACTION_SA_QUERY_RESPONSE = 1, | 1208 | WLAN_ACTION_SA_QUERY_RESPONSE = 1, |
1209 | }; | 1209 | }; |
1210 | 1210 | ||
1211 | 1211 | ||
1212 | /* A-MSDU 802.11n */ | 1212 | /* A-MSDU 802.11n */ |
1213 | #define IEEE80211_QOS_CONTROL_A_MSDU_PRESENT 0x0080 | 1213 | #define IEEE80211_QOS_CONTROL_A_MSDU_PRESENT 0x0080 |
1214 | 1214 | ||
1215 | /* cipher suite selectors */ | 1215 | /* cipher suite selectors */ |
1216 | #define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00 | 1216 | #define WLAN_CIPHER_SUITE_USE_GROUP 0x000FAC00 |
1217 | #define WLAN_CIPHER_SUITE_WEP40 0x000FAC01 | 1217 | #define WLAN_CIPHER_SUITE_WEP40 0x000FAC01 |
1218 | #define WLAN_CIPHER_SUITE_TKIP 0x000FAC02 | 1218 | #define WLAN_CIPHER_SUITE_TKIP 0x000FAC02 |
1219 | /* reserved: 0x000FAC03 */ | 1219 | /* reserved: 0x000FAC03 */ |
1220 | #define WLAN_CIPHER_SUITE_CCMP 0x000FAC04 | 1220 | #define WLAN_CIPHER_SUITE_CCMP 0x000FAC04 |
1221 | #define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 | 1221 | #define WLAN_CIPHER_SUITE_WEP104 0x000FAC05 |
1222 | #define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 | 1222 | #define WLAN_CIPHER_SUITE_AES_CMAC 0x000FAC06 |
1223 | 1223 | ||
1224 | /* AKM suite selectors */ | 1224 | /* AKM suite selectors */ |
1225 | #define WLAN_AKM_SUITE_8021X 0x000FAC01 | 1225 | #define WLAN_AKM_SUITE_8021X 0x000FAC01 |
1226 | #define WLAN_AKM_SUITE_PSK 0x000FAC02 | 1226 | #define WLAN_AKM_SUITE_PSK 0x000FAC02 |
1227 | 1227 | ||
1228 | #define WLAN_MAX_KEY_LEN 32 | 1228 | #define WLAN_MAX_KEY_LEN 32 |
1229 | 1229 | ||
1230 | /** | 1230 | /** |
1231 | * ieee80211_get_qos_ctl - get pointer to qos control bytes | 1231 | * ieee80211_get_qos_ctl - get pointer to qos control bytes |
1232 | * @hdr: the frame | 1232 | * @hdr: the frame |
1233 | * | 1233 | * |
1234 | * The qos ctrl bytes come after the frame_control, duration, seq_num | 1234 | * The qos ctrl bytes come after the frame_control, duration, seq_num |
1235 | * and 3 or 4 addresses of length ETH_ALEN. | 1235 | * and 3 or 4 addresses of length ETH_ALEN. |
1236 | * 3 addr: 2 + 2 + 2 + 3*6 = 24 | 1236 | * 3 addr: 2 + 2 + 2 + 3*6 = 24 |
1237 | * 4 addr: 2 + 2 + 2 + 4*6 = 30 | 1237 | * 4 addr: 2 + 2 + 2 + 4*6 = 30 |
1238 | */ | 1238 | */ |
1239 | static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr) | 1239 | static inline u8 *ieee80211_get_qos_ctl(struct ieee80211_hdr *hdr) |
1240 | { | 1240 | { |
1241 | if (ieee80211_has_a4(hdr->frame_control)) | 1241 | if (ieee80211_has_a4(hdr->frame_control)) |
1242 | return (u8 *)hdr + 30; | 1242 | return (u8 *)hdr + 30; |
1243 | else | 1243 | else |
1244 | return (u8 *)hdr + 24; | 1244 | return (u8 *)hdr + 24; |
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | /** | 1247 | /** |
1248 | * ieee80211_get_SA - get pointer to SA | 1248 | * ieee80211_get_SA - get pointer to SA |
1249 | * @hdr: the frame | 1249 | * @hdr: the frame |
1250 | * | 1250 | * |
1251 | * Given an 802.11 frame, this function returns the offset | 1251 | * Given an 802.11 frame, this function returns the offset |
1252 | * to the source address (SA). It does not verify that the | 1252 | * to the source address (SA). It does not verify that the |
1253 | * header is long enough to contain the address, and the | 1253 | * header is long enough to contain the address, and the |
1254 | * header must be long enough to contain the frame control | 1254 | * header must be long enough to contain the frame control |
1255 | * field. | 1255 | * field. |
1256 | */ | 1256 | */ |
1257 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) | 1257 | static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) |
1258 | { | 1258 | { |
1259 | if (ieee80211_has_a4(hdr->frame_control)) | 1259 | if (ieee80211_has_a4(hdr->frame_control)) |
1260 | return hdr->addr4; | 1260 | return hdr->addr4; |
1261 | if (ieee80211_has_fromds(hdr->frame_control)) | 1261 | if (ieee80211_has_fromds(hdr->frame_control)) |
1262 | return hdr->addr3; | 1262 | return hdr->addr3; |
1263 | return hdr->addr2; | 1263 | return hdr->addr2; |
1264 | } | 1264 | } |
1265 | 1265 | ||
1266 | /** | 1266 | /** |
1267 | * ieee80211_get_DA - get pointer to DA | 1267 | * ieee80211_get_DA - get pointer to DA |
1268 | * @hdr: the frame | 1268 | * @hdr: the frame |
1269 | * | 1269 | * |
1270 | * Given an 802.11 frame, this function returns the offset | 1270 | * Given an 802.11 frame, this function returns the offset |
1271 | * to the destination address (DA). It does not verify that | 1271 | * to the destination address (DA). It does not verify that |
1272 | * the header is long enough to contain the address, and the | 1272 | * the header is long enough to contain the address, and the |
1273 | * header must be long enough to contain the frame control | 1273 | * header must be long enough to contain the frame control |
1274 | * field. | 1274 | * field. |
1275 | */ | 1275 | */ |
1276 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) | 1276 | static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) |
1277 | { | 1277 | { |
1278 | if (ieee80211_has_tods(hdr->frame_control)) | 1278 | if (ieee80211_has_tods(hdr->frame_control)) |
1279 | return hdr->addr3; | 1279 | return hdr->addr3; |
1280 | else | 1280 | else |
1281 | return hdr->addr1; | 1281 | return hdr->addr1; |
1282 | } | 1282 | } |
1283 | 1283 | ||
1284 | /** | 1284 | /** |
1285 | * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame | 1285 | * ieee80211_is_robust_mgmt_frame - check if frame is a robust management frame |
1286 | * @hdr: the frame (buffer must include at least the first octet of payload) | 1286 | * @hdr: the frame (buffer must include at least the first octet of payload) |
1287 | */ | 1287 | */ |
1288 | static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) | 1288 | static inline bool ieee80211_is_robust_mgmt_frame(struct ieee80211_hdr *hdr) |
1289 | { | 1289 | { |
1290 | if (ieee80211_is_disassoc(hdr->frame_control) || | 1290 | if (ieee80211_is_disassoc(hdr->frame_control) || |
1291 | ieee80211_is_deauth(hdr->frame_control)) | 1291 | ieee80211_is_deauth(hdr->frame_control)) |
1292 | return true; | 1292 | return true; |
1293 | 1293 | ||
1294 | if (ieee80211_is_action(hdr->frame_control)) { | 1294 | if (ieee80211_is_action(hdr->frame_control)) { |
1295 | u8 *category; | 1295 | u8 *category; |
1296 | 1296 | ||
1297 | /* | 1297 | /* |
1298 | * Action frames, excluding Public Action frames, are Robust | 1298 | * Action frames, excluding Public Action frames, are Robust |
1299 | * Management Frames. However, if we are looking at a Protected | 1299 | * Management Frames. However, if we are looking at a Protected |
1300 | * frame, skip the check since the data may be encrypted and | 1300 | * frame, skip the check since the data may be encrypted and |
1301 | * the frame has already been found to be a Robust Management | 1301 | * the frame has already been found to be a Robust Management |
1302 | * Frame (by the other end). | 1302 | * Frame (by the other end). |
1303 | */ | 1303 | */ |
1304 | if (ieee80211_has_protected(hdr->frame_control)) | 1304 | if (ieee80211_has_protected(hdr->frame_control)) |
1305 | return true; | 1305 | return true; |
1306 | category = ((u8 *) hdr) + 24; | 1306 | category = ((u8 *) hdr) + 24; |
1307 | return *category != WLAN_CATEGORY_PUBLIC && | 1307 | return *category != WLAN_CATEGORY_PUBLIC && |
1308 | *category != WLAN_CATEGORY_HT && | 1308 | *category != WLAN_CATEGORY_HT && |
1309 | *category != WLAN_CATEGORY_VENDOR_SPECIFIC; | 1309 | *category != WLAN_CATEGORY_VENDOR_SPECIFIC; |
1310 | } | 1310 | } |
1311 | 1311 | ||
1312 | return false; | 1312 | return false; |
1313 | } | 1313 | } |
1314 | 1314 | ||
1315 | /** | 1315 | /** |
1316 | * ieee80211_fhss_chan_to_freq - get channel frequency | 1316 | * ieee80211_fhss_chan_to_freq - get channel frequency |
1317 | * @channel: the FHSS channel | 1317 | * @channel: the FHSS channel |
1318 | * | 1318 | * |
1319 | * Convert IEEE802.11 FHSS channel to frequency (MHz) | 1319 | * Convert IEEE802.11 FHSS channel to frequency (MHz) |
1320 | * Ref IEEE 802.11-2007 section 14.6 | 1320 | * Ref IEEE 802.11-2007 section 14.6 |
1321 | */ | 1321 | */ |
1322 | static inline int ieee80211_fhss_chan_to_freq(int channel) | 1322 | static inline int ieee80211_fhss_chan_to_freq(int channel) |
1323 | { | 1323 | { |
1324 | if ((channel > 1) && (channel < 96)) | 1324 | if ((channel > 1) && (channel < 96)) |
1325 | return channel + 2400; | 1325 | return channel + 2400; |
1326 | else | 1326 | else |
1327 | return -1; | 1327 | return -1; |
1328 | } | 1328 | } |
1329 | 1329 | ||
1330 | /** | 1330 | /** |
1331 | * ieee80211_freq_to_fhss_chan - get channel | 1331 | * ieee80211_freq_to_fhss_chan - get channel |
1332 | * @freq: the channels frequency | 1332 | * @freq: the channels frequency |
1333 | * | 1333 | * |
1334 | * Convert frequency (MHz) to IEEE802.11 FHSS channel | 1334 | * Convert frequency (MHz) to IEEE802.11 FHSS channel |
1335 | * Ref IEEE 802.11-2007 section 14.6 | 1335 | * Ref IEEE 802.11-2007 section 14.6 |
1336 | */ | 1336 | */ |
1337 | static inline int ieee80211_freq_to_fhss_chan(int freq) | 1337 | static inline int ieee80211_freq_to_fhss_chan(int freq) |
1338 | { | 1338 | { |
1339 | if ((freq > 2401) && (freq < 2496)) | 1339 | if ((freq > 2401) && (freq < 2496)) |
1340 | return freq - 2400; | 1340 | return freq - 2400; |
1341 | else | 1341 | else |
1342 | return -1; | 1342 | return -1; |
1343 | } | 1343 | } |
1344 | 1344 | ||
1345 | /** | 1345 | /** |
1346 | * ieee80211_dsss_chan_to_freq - get channel center frequency | 1346 | * ieee80211_dsss_chan_to_freq - get channel center frequency |
1347 | * @channel: the DSSS channel | 1347 | * @channel: the DSSS channel |
1348 | * | 1348 | * |
1349 | * Convert IEEE802.11 DSSS channel to the center frequency (MHz). | 1349 | * Convert IEEE802.11 DSSS channel to the center frequency (MHz). |
1350 | * Ref IEEE 802.11-2007 section 15.6 | 1350 | * Ref IEEE 802.11-2007 section 15.6 |
1351 | */ | 1351 | */ |
1352 | static inline int ieee80211_dsss_chan_to_freq(int channel) | 1352 | static inline int ieee80211_dsss_chan_to_freq(int channel) |
1353 | { | 1353 | { |
1354 | if ((channel > 0) && (channel < 14)) | 1354 | if ((channel > 0) && (channel < 14)) |
1355 | return 2407 + (channel * 5); | 1355 | return 2407 + (channel * 5); |
1356 | else if (channel == 14) | 1356 | else if (channel == 14) |
1357 | return 2484; | 1357 | return 2484; |
1358 | else | 1358 | else |
1359 | return -1; | 1359 | return -1; |
1360 | } | 1360 | } |
1361 | 1361 | ||
1362 | /** | 1362 | /** |
1363 | * ieee80211_freq_to_dsss_chan - get channel | 1363 | * ieee80211_freq_to_dsss_chan - get channel |
1364 | * @freq: the frequency | 1364 | * @freq: the frequency |
1365 | * | 1365 | * |
1366 | * Convert frequency (MHz) to IEEE802.11 DSSS channel | 1366 | * Convert frequency (MHz) to IEEE802.11 DSSS channel |
1367 | * Ref IEEE 802.11-2007 section 15.6 | 1367 | * Ref IEEE 802.11-2007 section 15.6 |
1368 | * | 1368 | * |
1369 | * This routine selects the channel with the closest center frequency. | 1369 | * This routine selects the channel with the closest center frequency. |
1370 | */ | 1370 | */ |
1371 | static inline int ieee80211_freq_to_dsss_chan(int freq) | 1371 | static inline int ieee80211_freq_to_dsss_chan(int freq) |
1372 | { | 1372 | { |
1373 | if ((freq >= 2410) && (freq < 2475)) | 1373 | if ((freq >= 2410) && (freq < 2475)) |
1374 | return (freq - 2405) / 5; | 1374 | return (freq - 2405) / 5; |
1375 | else if ((freq >= 2482) && (freq < 2487)) | 1375 | else if ((freq >= 2482) && (freq < 2487)) |
1376 | return 14; | 1376 | return 14; |
1377 | else | 1377 | else |
1378 | return -1; | 1378 | return -1; |
1379 | } | 1379 | } |
1380 | 1380 | ||
1381 | /* Convert IEEE802.11 HR DSSS channel to frequency (MHz) and back | 1381 | /* Convert IEEE802.11 HR DSSS channel to frequency (MHz) and back |
1382 | * Ref IEEE 802.11-2007 section 18.4.6.2 | 1382 | * Ref IEEE 802.11-2007 section 18.4.6.2 |
1383 | * | 1383 | * |
1384 | * The channels and frequencies are the same as those defined for DSSS | 1384 | * The channels and frequencies are the same as those defined for DSSS |
1385 | */ | 1385 | */ |
1386 | #define ieee80211_hr_chan_to_freq(chan) ieee80211_dsss_chan_to_freq(chan) | 1386 | #define ieee80211_hr_chan_to_freq(chan) ieee80211_dsss_chan_to_freq(chan) |
1387 | #define ieee80211_freq_to_hr_chan(freq) ieee80211_freq_to_dsss_chan(freq) | 1387 | #define ieee80211_freq_to_hr_chan(freq) ieee80211_freq_to_dsss_chan(freq) |
1388 | 1388 | ||
1389 | /* Convert IEEE802.11 ERP channel to frequency (MHz) and back | 1389 | /* Convert IEEE802.11 ERP channel to frequency (MHz) and back |
1390 | * Ref IEEE 802.11-2007 section 19.4.2 | 1390 | * Ref IEEE 802.11-2007 section 19.4.2 |
1391 | */ | 1391 | */ |
1392 | #define ieee80211_erp_chan_to_freq(chan) ieee80211_hr_chan_to_freq(chan) | 1392 | #define ieee80211_erp_chan_to_freq(chan) ieee80211_hr_chan_to_freq(chan) |
1393 | #define ieee80211_freq_to_erp_chan(freq) ieee80211_freq_to_hr_chan(freq) | 1393 | #define ieee80211_freq_to_erp_chan(freq) ieee80211_freq_to_hr_chan(freq) |
1394 | 1394 | ||
1395 | /** | 1395 | /** |
1396 | * ieee80211_ofdm_chan_to_freq - get channel center frequency | 1396 | * ieee80211_ofdm_chan_to_freq - get channel center frequency |
1397 | * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz | 1397 | * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz |
1398 | * @channel: the OFDM channel | 1398 | * @channel: the OFDM channel |
1399 | * | 1399 | * |
1400 | * Convert IEEE802.11 OFDM channel to center frequency (MHz) | 1400 | * Convert IEEE802.11 OFDM channel to center frequency (MHz) |
1401 | * Ref IEEE 802.11-2007 section 17.3.8.3.2 | 1401 | * Ref IEEE 802.11-2007 section 17.3.8.3.2 |
1402 | */ | 1402 | */ |
1403 | static inline int ieee80211_ofdm_chan_to_freq(int s_freq, int channel) | 1403 | static inline int ieee80211_ofdm_chan_to_freq(int s_freq, int channel) |
1404 | { | 1404 | { |
1405 | if ((channel > 0) && (channel <= 200) && | 1405 | if ((channel > 0) && (channel <= 200) && |
1406 | (s_freq >= 4000)) | 1406 | (s_freq >= 4000)) |
1407 | return s_freq + (channel * 5); | 1407 | return s_freq + (channel * 5); |
1408 | else | 1408 | else |
1409 | return -1; | 1409 | return -1; |
1410 | } | 1410 | } |
1411 | 1411 | ||
1412 | /** | 1412 | /** |
1413 | * ieee80211_freq_to_ofdm_channel - get channel | 1413 | * ieee80211_freq_to_ofdm_channel - get channel |
1414 | * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz | 1414 | * @s_freq: starting frequency == (dotChannelStartingFactor/2) MHz |
1415 | * @freq: the frequency | 1415 | * @freq: the frequency |
1416 | * | 1416 | * |
1417 | * Convert frequency (MHz) to IEEE802.11 OFDM channel | 1417 | * Convert frequency (MHz) to IEEE802.11 OFDM channel |
1418 | * Ref IEEE 802.11-2007 section 17.3.8.3.2 | 1418 | * Ref IEEE 802.11-2007 section 17.3.8.3.2 |
1419 | * | 1419 | * |
1420 | * This routine selects the channel with the closest center frequency. | 1420 | * This routine selects the channel with the closest center frequency. |
1421 | */ | 1421 | */ |
1422 | static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq) | 1422 | static inline int ieee80211_freq_to_ofdm_chan(int s_freq, int freq) |
1423 | { | 1423 | { |
1424 | if ((freq > (s_freq + 2)) && (freq <= (s_freq + 1202)) && | 1424 | if ((freq > (s_freq + 2)) && (freq <= (s_freq + 1202)) && |
1425 | (s_freq >= 4000)) | 1425 | (s_freq >= 4000)) |
1426 | return (freq + 2 - s_freq) / 5; | 1426 | return (freq + 2 - s_freq) / 5; |
1427 | else | 1427 | else |
1428 | return -1; | 1428 | return -1; |
1429 | } | 1429 | } |
1430 | 1430 | ||
1431 | /** | 1431 | /** |
1432 | * ieee80211_tu_to_usec - convert time units (TU) to microseconds | 1432 | * ieee80211_tu_to_usec - convert time units (TU) to microseconds |
1433 | * @tu: the TUs | 1433 | * @tu: the TUs |
1434 | */ | 1434 | */ |
1435 | static inline unsigned long ieee80211_tu_to_usec(unsigned long tu) | 1435 | static inline unsigned long ieee80211_tu_to_usec(unsigned long tu) |
1436 | { | 1436 | { |
1437 | return 1024 * tu; | 1437 | return 1024 * tu; |
1438 | } | 1438 | } |
1439 | 1439 | ||
1440 | /** | 1440 | /** |
1441 | * ieee80211_check_tim - check if AID bit is set in TIM | 1441 | * ieee80211_check_tim - check if AID bit is set in TIM |
1442 | * @tim: the TIM IE | 1442 | * @tim: the TIM IE |
1443 | * @tim_len: length of the TIM IE | 1443 | * @tim_len: length of the TIM IE |
1444 | * @aid: the AID to look for | 1444 | * @aid: the AID to look for |
1445 | */ | 1445 | */ |
1446 | static inline bool ieee80211_check_tim(struct ieee80211_tim_ie *tim, | 1446 | static inline bool ieee80211_check_tim(struct ieee80211_tim_ie *tim, |
1447 | u8 tim_len, u16 aid) | 1447 | u8 tim_len, u16 aid) |
1448 | { | 1448 | { |
1449 | u8 mask; | 1449 | u8 mask; |
1450 | u8 index, indexn1, indexn2; | 1450 | u8 index, indexn1, indexn2; |
1451 | 1451 | ||
1452 | if (unlikely(!tim || tim_len < sizeof(*tim))) | 1452 | if (unlikely(!tim || tim_len < sizeof(*tim))) |
1453 | return false; | 1453 | return false; |
1454 | 1454 | ||
1455 | aid &= 0x3fff; | 1455 | aid &= 0x3fff; |
1456 | index = aid / 8; | 1456 | index = aid / 8; |
1457 | mask = 1 << (aid & 7); | 1457 | mask = 1 << (aid & 7); |
1458 | 1458 | ||
1459 | indexn1 = tim->bitmap_ctrl & 0xfe; | 1459 | indexn1 = tim->bitmap_ctrl & 0xfe; |
1460 | indexn2 = tim_len + indexn1 - 4; | 1460 | indexn2 = tim_len + indexn1 - 4; |
1461 | 1461 | ||
1462 | if (index < indexn1 || index > indexn2) | 1462 | if (index < indexn1 || index > indexn2) |
1463 | return false; | 1463 | return false; |
1464 | 1464 | ||
1465 | index -= indexn1; | 1465 | index -= indexn1; |
1466 | 1466 | ||
1467 | return !!(tim->virtual_map[index] & mask); | 1467 | return !!(tim->virtual_map[index] & mask); |
1468 | } | 1468 | } |
1469 | 1469 | ||
1470 | #endif /* LINUX_IEEE80211_H */ | 1470 | #endif /* LINUX_IEEE80211_H */ |
1471 | 1471 |
net/mac80211/ieee80211_i.h
1 | /* | 1 | /* |
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 | * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> |
6 | * | 6 | * |
7 | * 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 |
8 | * 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 |
9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #ifndef IEEE80211_I_H | 12 | #ifndef IEEE80211_I_H |
13 | #define IEEE80211_I_H | 13 | #define IEEE80211_I_H |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/device.h> | 16 | #include <linux/device.h> |
17 | #include <linux/if_ether.h> | 17 | #include <linux/if_ether.h> |
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/netdevice.h> | 20 | #include <linux/netdevice.h> |
21 | #include <linux/skbuff.h> | 21 | #include <linux/skbuff.h> |
22 | #include <linux/workqueue.h> | 22 | #include <linux/workqueue.h> |
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/etherdevice.h> | 25 | #include <linux/etherdevice.h> |
26 | #include <net/cfg80211.h> | 26 | #include <net/cfg80211.h> |
27 | #include <net/mac80211.h> | 27 | #include <net/mac80211.h> |
28 | #include "key.h" | 28 | #include "key.h" |
29 | #include "sta_info.h" | 29 | #include "sta_info.h" |
30 | 30 | ||
31 | struct ieee80211_local; | 31 | struct ieee80211_local; |
32 | 32 | ||
33 | /* Maximum number of broadcast/multicast frames to buffer when some of the | 33 | /* Maximum number of broadcast/multicast frames to buffer when some of the |
34 | * associated stations are using power saving. */ | 34 | * associated stations are using power saving. */ |
35 | #define AP_MAX_BC_BUFFER 128 | 35 | #define AP_MAX_BC_BUFFER 128 |
36 | 36 | ||
37 | /* Maximum number of frames buffered to all STAs, including multicast frames. | 37 | /* Maximum number of frames buffered to all STAs, including multicast frames. |
38 | * Note: increasing this limit increases the potential memory requirement. Each | 38 | * Note: increasing this limit increases the potential memory requirement. Each |
39 | * frame can be up to about 2 kB long. */ | 39 | * frame can be up to about 2 kB long. */ |
40 | #define TOTAL_MAX_TX_BUFFER 512 | 40 | #define TOTAL_MAX_TX_BUFFER 512 |
41 | 41 | ||
42 | /* Required encryption head and tailroom */ | 42 | /* Required encryption head and tailroom */ |
43 | #define IEEE80211_ENCRYPT_HEADROOM 8 | 43 | #define IEEE80211_ENCRYPT_HEADROOM 8 |
44 | #define IEEE80211_ENCRYPT_TAILROOM 18 | 44 | #define IEEE80211_ENCRYPT_TAILROOM 18 |
45 | 45 | ||
46 | /* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent | 46 | /* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent |
47 | * reception of at least three fragmented frames. This limit can be increased | 47 | * reception of at least three fragmented frames. This limit can be increased |
48 | * by changing this define, at the cost of slower frame reassembly and | 48 | * by changing this define, at the cost of slower frame reassembly and |
49 | * increased memory use (about 2 kB of RAM per entry). */ | 49 | * increased memory use (about 2 kB of RAM per entry). */ |
50 | #define IEEE80211_FRAGMENT_MAX 4 | 50 | #define IEEE80211_FRAGMENT_MAX 4 |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * Time after which we ignore scan results and no longer report/use | 53 | * Time after which we ignore scan results and no longer report/use |
54 | * them in any way. | 54 | * them in any way. |
55 | */ | 55 | */ |
56 | #define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) | 56 | #define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) |
57 | 57 | ||
58 | #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) | 58 | #define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) |
59 | 59 | ||
60 | struct ieee80211_fragment_entry { | 60 | struct ieee80211_fragment_entry { |
61 | unsigned long first_frag_time; | 61 | unsigned long first_frag_time; |
62 | unsigned int seq; | 62 | unsigned int seq; |
63 | unsigned int rx_queue; | 63 | unsigned int rx_queue; |
64 | unsigned int last_frag; | 64 | unsigned int last_frag; |
65 | unsigned int extra_len; | 65 | unsigned int extra_len; |
66 | struct sk_buff_head skb_list; | 66 | struct sk_buff_head skb_list; |
67 | int ccmp; /* Whether fragments were encrypted with CCMP */ | 67 | int ccmp; /* Whether fragments were encrypted with CCMP */ |
68 | u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ | 68 | u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ |
69 | }; | 69 | }; |
70 | 70 | ||
71 | 71 | ||
72 | struct ieee80211_bss { | 72 | struct ieee80211_bss { |
73 | /* Yes, this is a hack */ | 73 | /* Yes, this is a hack */ |
74 | struct cfg80211_bss cbss; | 74 | struct cfg80211_bss cbss; |
75 | 75 | ||
76 | /* don't want to look up all the time */ | 76 | /* don't want to look up all the time */ |
77 | size_t ssid_len; | 77 | size_t ssid_len; |
78 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 78 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
79 | 79 | ||
80 | u8 dtim_period; | 80 | u8 dtim_period; |
81 | 81 | ||
82 | bool wmm_used; | 82 | bool wmm_used; |
83 | 83 | ||
84 | unsigned long last_probe_resp; | 84 | unsigned long last_probe_resp; |
85 | 85 | ||
86 | #ifdef CONFIG_MAC80211_MESH | 86 | #ifdef CONFIG_MAC80211_MESH |
87 | u8 *mesh_id; | 87 | u8 *mesh_id; |
88 | size_t mesh_id_len; | 88 | size_t mesh_id_len; |
89 | u8 *mesh_cfg; | 89 | u8 *mesh_cfg; |
90 | #endif | 90 | #endif |
91 | 91 | ||
92 | #define IEEE80211_MAX_SUPP_RATES 32 | 92 | #define IEEE80211_MAX_SUPP_RATES 32 |
93 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; | 93 | u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; |
94 | size_t supp_rates_len; | 94 | size_t supp_rates_len; |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * During assocation, we save an ERP value from a probe response so | 97 | * During assocation, we save an ERP value from a probe response so |
98 | * that we can feed ERP info to the driver when handling the | 98 | * that we can feed ERP info to the driver when handling the |
99 | * association completes. these fields probably won't be up-to-date | 99 | * association completes. these fields probably won't be up-to-date |
100 | * otherwise, you probably don't want to use them. | 100 | * otherwise, you probably don't want to use them. |
101 | */ | 101 | */ |
102 | bool has_erp_value; | 102 | bool has_erp_value; |
103 | u8 erp_value; | 103 | u8 erp_value; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss) | 106 | static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss) |
107 | { | 107 | { |
108 | #ifdef CONFIG_MAC80211_MESH | 108 | #ifdef CONFIG_MAC80211_MESH |
109 | return bss->mesh_cfg; | 109 | return bss->mesh_cfg; |
110 | #endif | 110 | #endif |
111 | return NULL; | 111 | return NULL; |
112 | } | 112 | } |
113 | 113 | ||
114 | static inline u8 *bss_mesh_id(struct ieee80211_bss *bss) | 114 | static inline u8 *bss_mesh_id(struct ieee80211_bss *bss) |
115 | { | 115 | { |
116 | #ifdef CONFIG_MAC80211_MESH | 116 | #ifdef CONFIG_MAC80211_MESH |
117 | return bss->mesh_id; | 117 | return bss->mesh_id; |
118 | #endif | 118 | #endif |
119 | return NULL; | 119 | return NULL; |
120 | } | 120 | } |
121 | 121 | ||
122 | static inline u8 bss_mesh_id_len(struct ieee80211_bss *bss) | 122 | static inline u8 bss_mesh_id_len(struct ieee80211_bss *bss) |
123 | { | 123 | { |
124 | #ifdef CONFIG_MAC80211_MESH | 124 | #ifdef CONFIG_MAC80211_MESH |
125 | return bss->mesh_id_len; | 125 | return bss->mesh_id_len; |
126 | #endif | 126 | #endif |
127 | return 0; | 127 | return 0; |
128 | } | 128 | } |
129 | 129 | ||
130 | 130 | ||
131 | typedef unsigned __bitwise__ ieee80211_tx_result; | 131 | typedef unsigned __bitwise__ ieee80211_tx_result; |
132 | #define TX_CONTINUE ((__force ieee80211_tx_result) 0u) | 132 | #define TX_CONTINUE ((__force ieee80211_tx_result) 0u) |
133 | #define TX_DROP ((__force ieee80211_tx_result) 1u) | 133 | #define TX_DROP ((__force ieee80211_tx_result) 1u) |
134 | #define TX_QUEUED ((__force ieee80211_tx_result) 2u) | 134 | #define TX_QUEUED ((__force ieee80211_tx_result) 2u) |
135 | 135 | ||
136 | #define IEEE80211_TX_FRAGMENTED BIT(0) | 136 | #define IEEE80211_TX_FRAGMENTED BIT(0) |
137 | #define IEEE80211_TX_UNICAST BIT(1) | 137 | #define IEEE80211_TX_UNICAST BIT(1) |
138 | #define IEEE80211_TX_PS_BUFFERED BIT(2) | 138 | #define IEEE80211_TX_PS_BUFFERED BIT(2) |
139 | 139 | ||
140 | struct ieee80211_tx_data { | 140 | struct ieee80211_tx_data { |
141 | struct sk_buff *skb; | 141 | struct sk_buff *skb; |
142 | struct net_device *dev; | 142 | struct net_device *dev; |
143 | struct ieee80211_local *local; | 143 | struct ieee80211_local *local; |
144 | struct ieee80211_sub_if_data *sdata; | 144 | struct ieee80211_sub_if_data *sdata; |
145 | struct sta_info *sta; | 145 | struct sta_info *sta; |
146 | struct ieee80211_key *key; | 146 | struct ieee80211_key *key; |
147 | 147 | ||
148 | struct ieee80211_channel *channel; | 148 | struct ieee80211_channel *channel; |
149 | 149 | ||
150 | u16 ethertype; | 150 | u16 ethertype; |
151 | unsigned int flags; | 151 | unsigned int flags; |
152 | }; | 152 | }; |
153 | 153 | ||
154 | 154 | ||
155 | typedef unsigned __bitwise__ ieee80211_rx_result; | 155 | typedef unsigned __bitwise__ ieee80211_rx_result; |
156 | #define RX_CONTINUE ((__force ieee80211_rx_result) 0u) | 156 | #define RX_CONTINUE ((__force ieee80211_rx_result) 0u) |
157 | #define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u) | 157 | #define RX_DROP_UNUSABLE ((__force ieee80211_rx_result) 1u) |
158 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) | 158 | #define RX_DROP_MONITOR ((__force ieee80211_rx_result) 2u) |
159 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) | 159 | #define RX_QUEUED ((__force ieee80211_rx_result) 3u) |
160 | 160 | ||
161 | #define IEEE80211_RX_IN_SCAN BIT(0) | 161 | #define IEEE80211_RX_IN_SCAN BIT(0) |
162 | /* frame is destined to interface currently processed (incl. multicast frames) */ | 162 | /* frame is destined to interface currently processed (incl. multicast frames) */ |
163 | #define IEEE80211_RX_RA_MATCH BIT(1) | 163 | #define IEEE80211_RX_RA_MATCH BIT(1) |
164 | #define IEEE80211_RX_AMSDU BIT(2) | 164 | #define IEEE80211_RX_AMSDU BIT(2) |
165 | #define IEEE80211_RX_CMNTR_REPORTED BIT(3) | 165 | #define IEEE80211_RX_CMNTR_REPORTED BIT(3) |
166 | #define IEEE80211_RX_FRAGMENTED BIT(4) | 166 | #define IEEE80211_RX_FRAGMENTED BIT(4) |
167 | 167 | ||
168 | struct ieee80211_rx_data { | 168 | struct ieee80211_rx_data { |
169 | struct sk_buff *skb; | 169 | struct sk_buff *skb; |
170 | struct net_device *dev; | 170 | struct net_device *dev; |
171 | struct ieee80211_local *local; | 171 | struct ieee80211_local *local; |
172 | struct ieee80211_sub_if_data *sdata; | 172 | struct ieee80211_sub_if_data *sdata; |
173 | struct sta_info *sta; | 173 | struct sta_info *sta; |
174 | struct ieee80211_key *key; | 174 | struct ieee80211_key *key; |
175 | struct ieee80211_rx_status *status; | 175 | struct ieee80211_rx_status *status; |
176 | struct ieee80211_rate *rate; | 176 | struct ieee80211_rate *rate; |
177 | 177 | ||
178 | unsigned int flags; | 178 | unsigned int flags; |
179 | int sent_ps_buffered; | 179 | int sent_ps_buffered; |
180 | int queue; | 180 | int queue; |
181 | u32 tkip_iv32; | 181 | u32 tkip_iv32; |
182 | u16 tkip_iv16; | 182 | u16 tkip_iv16; |
183 | }; | 183 | }; |
184 | 184 | ||
185 | struct beacon_data { | 185 | struct beacon_data { |
186 | u8 *head, *tail; | 186 | u8 *head, *tail; |
187 | int head_len, tail_len; | 187 | int head_len, tail_len; |
188 | int dtim_period; | 188 | int dtim_period; |
189 | }; | 189 | }; |
190 | 190 | ||
191 | struct ieee80211_if_ap { | 191 | struct ieee80211_if_ap { |
192 | struct beacon_data *beacon; | 192 | struct beacon_data *beacon; |
193 | 193 | ||
194 | struct list_head vlans; | 194 | struct list_head vlans; |
195 | 195 | ||
196 | /* yes, this looks ugly, but guarantees that we can later use | 196 | /* yes, this looks ugly, but guarantees that we can later use |
197 | * bitmap_empty :) | 197 | * bitmap_empty :) |
198 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ | 198 | * NB: don't touch this bitmap, use sta_info_{set,clear}_tim_bit */ |
199 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; | 199 | u8 tim[sizeof(unsigned long) * BITS_TO_LONGS(IEEE80211_MAX_AID + 1)]; |
200 | struct sk_buff_head ps_bc_buf; | 200 | struct sk_buff_head ps_bc_buf; |
201 | atomic_t num_sta_ps; /* number of stations in PS mode */ | 201 | atomic_t num_sta_ps; /* number of stations in PS mode */ |
202 | int dtim_count; | 202 | int dtim_count; |
203 | }; | 203 | }; |
204 | 204 | ||
205 | struct ieee80211_if_wds { | 205 | struct ieee80211_if_wds { |
206 | struct sta_info *sta; | 206 | struct sta_info *sta; |
207 | u8 remote_addr[ETH_ALEN]; | 207 | u8 remote_addr[ETH_ALEN]; |
208 | }; | 208 | }; |
209 | 209 | ||
210 | struct ieee80211_if_vlan { | 210 | struct ieee80211_if_vlan { |
211 | struct list_head list; | 211 | struct list_head list; |
212 | }; | 212 | }; |
213 | 213 | ||
214 | struct mesh_stats { | 214 | struct mesh_stats { |
215 | __u32 fwded_mcast; /* Mesh forwarded multicast frames */ | 215 | __u32 fwded_mcast; /* Mesh forwarded multicast frames */ |
216 | __u32 fwded_unicast; /* Mesh forwarded unicast frames */ | 216 | __u32 fwded_unicast; /* Mesh forwarded unicast frames */ |
217 | __u32 fwded_frames; /* Mesh total forwarded frames */ | 217 | __u32 fwded_frames; /* Mesh total forwarded frames */ |
218 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ | 218 | __u32 dropped_frames_ttl; /* Not transmitted since mesh_ttl == 0*/ |
219 | __u32 dropped_frames_no_route; /* Not transmitted, no route found */ | 219 | __u32 dropped_frames_no_route; /* Not transmitted, no route found */ |
220 | atomic_t estab_plinks; | 220 | atomic_t estab_plinks; |
221 | }; | 221 | }; |
222 | 222 | ||
223 | #define PREQ_Q_F_START 0x1 | 223 | #define PREQ_Q_F_START 0x1 |
224 | #define PREQ_Q_F_REFRESH 0x2 | 224 | #define PREQ_Q_F_REFRESH 0x2 |
225 | struct mesh_preq_queue { | 225 | struct mesh_preq_queue { |
226 | struct list_head list; | 226 | struct list_head list; |
227 | u8 dst[ETH_ALEN]; | 227 | u8 dst[ETH_ALEN]; |
228 | u8 flags; | 228 | u8 flags; |
229 | }; | 229 | }; |
230 | 230 | ||
231 | enum ieee80211_mgd_state { | 231 | enum ieee80211_mgd_state { |
232 | IEEE80211_MGD_STATE_IDLE, | 232 | IEEE80211_MGD_STATE_IDLE, |
233 | IEEE80211_MGD_STATE_PROBE, | 233 | IEEE80211_MGD_STATE_PROBE, |
234 | IEEE80211_MGD_STATE_AUTH, | 234 | IEEE80211_MGD_STATE_AUTH, |
235 | IEEE80211_MGD_STATE_ASSOC, | 235 | IEEE80211_MGD_STATE_ASSOC, |
236 | }; | 236 | }; |
237 | 237 | ||
238 | struct ieee80211_mgd_work { | 238 | struct ieee80211_mgd_work { |
239 | struct list_head list; | 239 | struct list_head list; |
240 | struct ieee80211_bss *bss; | 240 | struct ieee80211_bss *bss; |
241 | int ie_len; | 241 | int ie_len; |
242 | u8 prev_bssid[ETH_ALEN]; | 242 | u8 prev_bssid[ETH_ALEN]; |
243 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 243 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
244 | u8 ssid_len; | 244 | u8 ssid_len; |
245 | unsigned long timeout; | 245 | unsigned long timeout; |
246 | enum ieee80211_mgd_state state; | 246 | enum ieee80211_mgd_state state; |
247 | u16 auth_alg, auth_transaction; | 247 | u16 auth_alg, auth_transaction; |
248 | 248 | ||
249 | int tries; | 249 | int tries; |
250 | 250 | ||
251 | u8 key[WLAN_KEY_LEN_WEP104]; | 251 | u8 key[WLAN_KEY_LEN_WEP104]; |
252 | u8 key_len, key_idx; | 252 | u8 key_len, key_idx; |
253 | 253 | ||
254 | /* must be last */ | 254 | /* must be last */ |
255 | u8 ie[0]; /* for auth or assoc frame, not probe */ | 255 | u8 ie[0]; /* for auth or assoc frame, not probe */ |
256 | }; | 256 | }; |
257 | 257 | ||
258 | /* flags used in struct ieee80211_if_managed.flags */ | 258 | /* flags used in struct ieee80211_if_managed.flags */ |
259 | enum ieee80211_sta_flags { | 259 | enum ieee80211_sta_flags { |
260 | IEEE80211_STA_BEACON_POLL = BIT(0), | 260 | IEEE80211_STA_BEACON_POLL = BIT(0), |
261 | IEEE80211_STA_CONNECTION_POLL = BIT(1), | 261 | IEEE80211_STA_CONNECTION_POLL = BIT(1), |
262 | IEEE80211_STA_CONTROL_PORT = BIT(2), | 262 | IEEE80211_STA_CONTROL_PORT = BIT(2), |
263 | IEEE80211_STA_WMM_ENABLED = BIT(3), | 263 | IEEE80211_STA_WMM_ENABLED = BIT(3), |
264 | IEEE80211_STA_DISABLE_11N = BIT(4), | 264 | IEEE80211_STA_DISABLE_11N = BIT(4), |
265 | IEEE80211_STA_CSA_RECEIVED = BIT(5), | 265 | IEEE80211_STA_CSA_RECEIVED = BIT(5), |
266 | IEEE80211_STA_MFP_ENABLED = BIT(6), | 266 | IEEE80211_STA_MFP_ENABLED = BIT(6), |
267 | }; | 267 | }; |
268 | 268 | ||
269 | /* flags for MLME request */ | 269 | /* flags for MLME request */ |
270 | enum ieee80211_sta_request { | 270 | enum ieee80211_sta_request { |
271 | IEEE80211_STA_REQ_SCAN, | 271 | IEEE80211_STA_REQ_SCAN, |
272 | }; | 272 | }; |
273 | 273 | ||
274 | struct ieee80211_if_managed { | 274 | struct ieee80211_if_managed { |
275 | struct timer_list timer; | 275 | struct timer_list timer; |
276 | struct timer_list conn_mon_timer; | 276 | struct timer_list conn_mon_timer; |
277 | struct timer_list bcn_mon_timer; | 277 | struct timer_list bcn_mon_timer; |
278 | struct timer_list chswitch_timer; | 278 | struct timer_list chswitch_timer; |
279 | struct work_struct work; | 279 | struct work_struct work; |
280 | struct work_struct monitor_work; | 280 | struct work_struct monitor_work; |
281 | struct work_struct chswitch_work; | 281 | struct work_struct chswitch_work; |
282 | struct work_struct beacon_loss_work; | 282 | struct work_struct beacon_loss_work; |
283 | 283 | ||
284 | unsigned long probe_timeout; | 284 | unsigned long probe_timeout; |
285 | int probe_send_count; | 285 | int probe_send_count; |
286 | 286 | ||
287 | struct mutex mtx; | 287 | struct mutex mtx; |
288 | struct ieee80211_bss *associated; | 288 | struct ieee80211_bss *associated; |
289 | struct ieee80211_mgd_work *old_associate_work; | 289 | struct ieee80211_mgd_work *old_associate_work; |
290 | struct list_head work_list; | 290 | struct list_head work_list; |
291 | 291 | ||
292 | u8 bssid[ETH_ALEN]; | 292 | u8 bssid[ETH_ALEN]; |
293 | 293 | ||
294 | u16 aid; | 294 | u16 aid; |
295 | u16 capab; | 295 | u16 capab; |
296 | 296 | ||
297 | struct sk_buff_head skb_queue; | 297 | struct sk_buff_head skb_queue; |
298 | 298 | ||
299 | unsigned long timers_running; /* used for quiesce/restart */ | 299 | unsigned long timers_running; /* used for quiesce/restart */ |
300 | bool powersave; /* powersave requested for this iface */ | 300 | bool powersave; /* powersave requested for this iface */ |
301 | 301 | ||
302 | unsigned long request; | 302 | unsigned long request; |
303 | 303 | ||
304 | unsigned int flags; | 304 | unsigned int flags; |
305 | 305 | ||
306 | u32 beacon_crc; | 306 | u32 beacon_crc; |
307 | 307 | ||
308 | enum { | 308 | enum { |
309 | IEEE80211_MFP_DISABLED, | 309 | IEEE80211_MFP_DISABLED, |
310 | IEEE80211_MFP_OPTIONAL, | 310 | IEEE80211_MFP_OPTIONAL, |
311 | IEEE80211_MFP_REQUIRED | 311 | IEEE80211_MFP_REQUIRED |
312 | } mfp; /* management frame protection */ | 312 | } mfp; /* management frame protection */ |
313 | 313 | ||
314 | int wmm_last_param_set; | 314 | int wmm_last_param_set; |
315 | }; | 315 | }; |
316 | 316 | ||
317 | enum ieee80211_ibss_request { | 317 | enum ieee80211_ibss_request { |
318 | IEEE80211_IBSS_REQ_RUN = 0, | 318 | IEEE80211_IBSS_REQ_RUN = 0, |
319 | }; | 319 | }; |
320 | 320 | ||
321 | struct ieee80211_if_ibss { | 321 | struct ieee80211_if_ibss { |
322 | struct timer_list timer; | 322 | struct timer_list timer; |
323 | struct work_struct work; | 323 | struct work_struct work; |
324 | 324 | ||
325 | struct sk_buff_head skb_queue; | 325 | struct sk_buff_head skb_queue; |
326 | 326 | ||
327 | unsigned long request; | 327 | unsigned long request; |
328 | unsigned long last_scan_completed; | 328 | unsigned long last_scan_completed; |
329 | 329 | ||
330 | bool timer_running; | 330 | bool timer_running; |
331 | 331 | ||
332 | bool fixed_bssid; | 332 | bool fixed_bssid; |
333 | bool fixed_channel; | 333 | bool fixed_channel; |
334 | bool privacy; | 334 | bool privacy; |
335 | 335 | ||
336 | u8 bssid[ETH_ALEN]; | 336 | u8 bssid[ETH_ALEN]; |
337 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 337 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
338 | u8 ssid_len, ie_len; | 338 | u8 ssid_len, ie_len; |
339 | u8 *ie; | 339 | u8 *ie; |
340 | struct ieee80211_channel *channel; | 340 | struct ieee80211_channel *channel; |
341 | 341 | ||
342 | unsigned long ibss_join_req; | 342 | unsigned long ibss_join_req; |
343 | /* probe response/beacon for IBSS */ | 343 | /* probe response/beacon for IBSS */ |
344 | struct sk_buff *presp, *skb; | 344 | struct sk_buff *presp, *skb; |
345 | 345 | ||
346 | enum { | 346 | enum { |
347 | IEEE80211_IBSS_MLME_SEARCH, | 347 | IEEE80211_IBSS_MLME_SEARCH, |
348 | IEEE80211_IBSS_MLME_JOINED, | 348 | IEEE80211_IBSS_MLME_JOINED, |
349 | } state; | 349 | } state; |
350 | }; | 350 | }; |
351 | 351 | ||
352 | struct ieee80211_if_mesh { | 352 | struct ieee80211_if_mesh { |
353 | struct work_struct work; | 353 | struct work_struct work; |
354 | struct timer_list housekeeping_timer; | 354 | struct timer_list housekeeping_timer; |
355 | struct timer_list mesh_path_timer; | 355 | struct timer_list mesh_path_timer; |
356 | struct sk_buff_head skb_queue; | 356 | struct sk_buff_head skb_queue; |
357 | 357 | ||
358 | unsigned long timers_running; | 358 | unsigned long timers_running; |
359 | 359 | ||
360 | unsigned long wrkq_flags; | 360 | unsigned long wrkq_flags; |
361 | 361 | ||
362 | u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; | 362 | u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN]; |
363 | size_t mesh_id_len; | 363 | size_t mesh_id_len; |
364 | /* Active Path Selection Protocol Identifier */ | 364 | /* Active Path Selection Protocol Identifier */ |
365 | u8 mesh_pp_id[4]; | 365 | u8 mesh_pp_id[4]; |
366 | /* Active Path Selection Metric Identifier */ | 366 | /* Active Path Selection Metric Identifier */ |
367 | u8 mesh_pm_id[4]; | 367 | u8 mesh_pm_id[4]; |
368 | /* Congestion Control Mode Identifier */ | 368 | /* Congestion Control Mode Identifier */ |
369 | u8 mesh_cc_id[4]; | 369 | u8 mesh_cc_id[4]; |
370 | /* Synchronization Protocol Identifier */ | ||
371 | u8 mesh_sp_id[4]; | ||
372 | /* Authentication Protocol Identifier */ | ||
373 | u8 mesh_auth_id[4]; | ||
370 | /* Local mesh Destination Sequence Number */ | 374 | /* Local mesh Destination Sequence Number */ |
371 | u32 dsn; | 375 | u32 dsn; |
372 | /* Last used PREQ ID */ | 376 | /* Last used PREQ ID */ |
373 | u32 preq_id; | 377 | u32 preq_id; |
374 | atomic_t mpaths; | 378 | atomic_t mpaths; |
375 | /* Timestamp of last DSN update */ | 379 | /* Timestamp of last DSN update */ |
376 | unsigned long last_dsn_update; | 380 | unsigned long last_dsn_update; |
377 | /* Timestamp of last DSN sent */ | 381 | /* Timestamp of last DSN sent */ |
378 | unsigned long last_preq; | 382 | unsigned long last_preq; |
379 | struct mesh_rmc *rmc; | 383 | struct mesh_rmc *rmc; |
380 | spinlock_t mesh_preq_queue_lock; | 384 | spinlock_t mesh_preq_queue_lock; |
381 | struct mesh_preq_queue preq_queue; | 385 | struct mesh_preq_queue preq_queue; |
382 | int preq_queue_len; | 386 | int preq_queue_len; |
383 | struct mesh_stats mshstats; | 387 | struct mesh_stats mshstats; |
384 | struct mesh_config mshcfg; | 388 | struct mesh_config mshcfg; |
385 | u32 mesh_seqnum; | 389 | u32 mesh_seqnum; |
386 | bool accepting_plinks; | 390 | bool accepting_plinks; |
387 | }; | 391 | }; |
388 | 392 | ||
389 | #ifdef CONFIG_MAC80211_MESH | 393 | #ifdef CONFIG_MAC80211_MESH |
390 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ | 394 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ |
391 | do { (msh)->mshstats.name++; } while (0) | 395 | do { (msh)->mshstats.name++; } while (0) |
392 | #else | 396 | #else |
393 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ | 397 | #define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \ |
394 | do { } while (0) | 398 | do { } while (0) |
395 | #endif | 399 | #endif |
396 | 400 | ||
397 | /** | 401 | /** |
398 | * enum ieee80211_sub_if_data_flags - virtual interface flags | 402 | * enum ieee80211_sub_if_data_flags - virtual interface flags |
399 | * | 403 | * |
400 | * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets | 404 | * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets |
401 | * @IEEE80211_SDATA_PROMISC: interface is promisc | 405 | * @IEEE80211_SDATA_PROMISC: interface is promisc |
402 | * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode | 406 | * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode |
403 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between | 407 | * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between |
404 | * associated stations and deliver multicast frames both | 408 | * associated stations and deliver multicast frames both |
405 | * back to wireless media and to the local net stack. | 409 | * back to wireless media and to the local net stack. |
406 | */ | 410 | */ |
407 | enum ieee80211_sub_if_data_flags { | 411 | enum ieee80211_sub_if_data_flags { |
408 | IEEE80211_SDATA_ALLMULTI = BIT(0), | 412 | IEEE80211_SDATA_ALLMULTI = BIT(0), |
409 | IEEE80211_SDATA_PROMISC = BIT(1), | 413 | IEEE80211_SDATA_PROMISC = BIT(1), |
410 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), | 414 | IEEE80211_SDATA_OPERATING_GMODE = BIT(2), |
411 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), | 415 | IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(3), |
412 | }; | 416 | }; |
413 | 417 | ||
414 | struct ieee80211_sub_if_data { | 418 | struct ieee80211_sub_if_data { |
415 | struct list_head list; | 419 | struct list_head list; |
416 | 420 | ||
417 | struct wireless_dev wdev; | 421 | struct wireless_dev wdev; |
418 | 422 | ||
419 | /* keys */ | 423 | /* keys */ |
420 | struct list_head key_list; | 424 | struct list_head key_list; |
421 | 425 | ||
422 | struct net_device *dev; | 426 | struct net_device *dev; |
423 | struct ieee80211_local *local; | 427 | struct ieee80211_local *local; |
424 | 428 | ||
425 | unsigned int flags; | 429 | unsigned int flags; |
426 | 430 | ||
427 | int drop_unencrypted; | 431 | int drop_unencrypted; |
428 | 432 | ||
429 | /* | 433 | /* |
430 | * keep track of whether the HT opmode (stored in | 434 | * keep track of whether the HT opmode (stored in |
431 | * vif.bss_info.ht_operation_mode) is valid. | 435 | * vif.bss_info.ht_operation_mode) is valid. |
432 | */ | 436 | */ |
433 | bool ht_opmode_valid; | 437 | bool ht_opmode_valid; |
434 | 438 | ||
435 | /* Fragment table for host-based reassembly */ | 439 | /* Fragment table for host-based reassembly */ |
436 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; | 440 | struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; |
437 | unsigned int fragment_next; | 441 | unsigned int fragment_next; |
438 | 442 | ||
439 | #define NUM_DEFAULT_KEYS 4 | 443 | #define NUM_DEFAULT_KEYS 4 |
440 | #define NUM_DEFAULT_MGMT_KEYS 2 | 444 | #define NUM_DEFAULT_MGMT_KEYS 2 |
441 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; | 445 | struct ieee80211_key *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; |
442 | struct ieee80211_key *default_key; | 446 | struct ieee80211_key *default_key; |
443 | struct ieee80211_key *default_mgmt_key; | 447 | struct ieee80211_key *default_mgmt_key; |
444 | 448 | ||
445 | u16 sequence_number; | 449 | u16 sequence_number; |
446 | 450 | ||
447 | /* | 451 | /* |
448 | * AP this belongs to: self in AP mode and | 452 | * AP this belongs to: self in AP mode and |
449 | * corresponding AP in VLAN mode, NULL for | 453 | * corresponding AP in VLAN mode, NULL for |
450 | * all others (might be needed later in IBSS) | 454 | * all others (might be needed later in IBSS) |
451 | */ | 455 | */ |
452 | struct ieee80211_if_ap *bss; | 456 | struct ieee80211_if_ap *bss; |
453 | 457 | ||
454 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ | 458 | int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ |
455 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ | 459 | int max_ratectrl_rateidx; /* max TX rateidx for rate control */ |
456 | 460 | ||
457 | union { | 461 | union { |
458 | struct ieee80211_if_ap ap; | 462 | struct ieee80211_if_ap ap; |
459 | struct ieee80211_if_wds wds; | 463 | struct ieee80211_if_wds wds; |
460 | struct ieee80211_if_vlan vlan; | 464 | struct ieee80211_if_vlan vlan; |
461 | struct ieee80211_if_managed mgd; | 465 | struct ieee80211_if_managed mgd; |
462 | struct ieee80211_if_ibss ibss; | 466 | struct ieee80211_if_ibss ibss; |
463 | #ifdef CONFIG_MAC80211_MESH | 467 | #ifdef CONFIG_MAC80211_MESH |
464 | struct ieee80211_if_mesh mesh; | 468 | struct ieee80211_if_mesh mesh; |
465 | #endif | 469 | #endif |
466 | u32 mntr_flags; | 470 | u32 mntr_flags; |
467 | } u; | 471 | } u; |
468 | 472 | ||
469 | #ifdef CONFIG_MAC80211_DEBUGFS | 473 | #ifdef CONFIG_MAC80211_DEBUGFS |
470 | struct dentry *debugfsdir; | 474 | struct dentry *debugfsdir; |
471 | union { | 475 | union { |
472 | struct { | 476 | struct { |
473 | struct dentry *drop_unencrypted; | 477 | struct dentry *drop_unencrypted; |
474 | struct dentry *bssid; | 478 | struct dentry *bssid; |
475 | struct dentry *aid; | 479 | struct dentry *aid; |
476 | struct dentry *capab; | 480 | struct dentry *capab; |
477 | struct dentry *force_unicast_rateidx; | 481 | struct dentry *force_unicast_rateidx; |
478 | struct dentry *max_ratectrl_rateidx; | 482 | struct dentry *max_ratectrl_rateidx; |
479 | } sta; | 483 | } sta; |
480 | struct { | 484 | struct { |
481 | struct dentry *drop_unencrypted; | 485 | struct dentry *drop_unencrypted; |
482 | struct dentry *num_sta_ps; | 486 | struct dentry *num_sta_ps; |
483 | struct dentry *dtim_count; | 487 | struct dentry *dtim_count; |
484 | struct dentry *force_unicast_rateidx; | 488 | struct dentry *force_unicast_rateidx; |
485 | struct dentry *max_ratectrl_rateidx; | 489 | struct dentry *max_ratectrl_rateidx; |
486 | struct dentry *num_buffered_multicast; | 490 | struct dentry *num_buffered_multicast; |
487 | } ap; | 491 | } ap; |
488 | struct { | 492 | struct { |
489 | struct dentry *drop_unencrypted; | 493 | struct dentry *drop_unencrypted; |
490 | struct dentry *peer; | 494 | struct dentry *peer; |
491 | struct dentry *force_unicast_rateidx; | 495 | struct dentry *force_unicast_rateidx; |
492 | struct dentry *max_ratectrl_rateidx; | 496 | struct dentry *max_ratectrl_rateidx; |
493 | } wds; | 497 | } wds; |
494 | struct { | 498 | struct { |
495 | struct dentry *drop_unencrypted; | 499 | struct dentry *drop_unencrypted; |
496 | struct dentry *force_unicast_rateidx; | 500 | struct dentry *force_unicast_rateidx; |
497 | struct dentry *max_ratectrl_rateidx; | 501 | struct dentry *max_ratectrl_rateidx; |
498 | } vlan; | 502 | } vlan; |
499 | struct { | 503 | struct { |
500 | struct dentry *mode; | 504 | struct dentry *mode; |
501 | } monitor; | 505 | } monitor; |
502 | } debugfs; | 506 | } debugfs; |
503 | struct { | 507 | struct { |
504 | struct dentry *default_key; | 508 | struct dentry *default_key; |
505 | struct dentry *default_mgmt_key; | 509 | struct dentry *default_mgmt_key; |
506 | } common_debugfs; | 510 | } common_debugfs; |
507 | 511 | ||
508 | #ifdef CONFIG_MAC80211_MESH | 512 | #ifdef CONFIG_MAC80211_MESH |
509 | struct dentry *mesh_stats_dir; | 513 | struct dentry *mesh_stats_dir; |
510 | struct { | 514 | struct { |
511 | struct dentry *fwded_mcast; | 515 | struct dentry *fwded_mcast; |
512 | struct dentry *fwded_unicast; | 516 | struct dentry *fwded_unicast; |
513 | struct dentry *fwded_frames; | 517 | struct dentry *fwded_frames; |
514 | struct dentry *dropped_frames_ttl; | 518 | struct dentry *dropped_frames_ttl; |
515 | struct dentry *dropped_frames_no_route; | 519 | struct dentry *dropped_frames_no_route; |
516 | struct dentry *estab_plinks; | 520 | struct dentry *estab_plinks; |
517 | struct timer_list mesh_path_timer; | 521 | struct timer_list mesh_path_timer; |
518 | } mesh_stats; | 522 | } mesh_stats; |
519 | 523 | ||
520 | struct dentry *mesh_config_dir; | 524 | struct dentry *mesh_config_dir; |
521 | struct { | 525 | struct { |
522 | struct dentry *dot11MeshRetryTimeout; | 526 | struct dentry *dot11MeshRetryTimeout; |
523 | struct dentry *dot11MeshConfirmTimeout; | 527 | struct dentry *dot11MeshConfirmTimeout; |
524 | struct dentry *dot11MeshHoldingTimeout; | 528 | struct dentry *dot11MeshHoldingTimeout; |
525 | struct dentry *dot11MeshMaxRetries; | 529 | struct dentry *dot11MeshMaxRetries; |
526 | struct dentry *dot11MeshTTL; | 530 | struct dentry *dot11MeshTTL; |
527 | struct dentry *auto_open_plinks; | 531 | struct dentry *auto_open_plinks; |
528 | struct dentry *dot11MeshMaxPeerLinks; | 532 | struct dentry *dot11MeshMaxPeerLinks; |
529 | struct dentry *dot11MeshHWMPactivePathTimeout; | 533 | struct dentry *dot11MeshHWMPactivePathTimeout; |
530 | struct dentry *dot11MeshHWMPpreqMinInterval; | 534 | struct dentry *dot11MeshHWMPpreqMinInterval; |
531 | struct dentry *dot11MeshHWMPnetDiameterTraversalTime; | 535 | struct dentry *dot11MeshHWMPnetDiameterTraversalTime; |
532 | struct dentry *dot11MeshHWMPmaxPREQretries; | 536 | struct dentry *dot11MeshHWMPmaxPREQretries; |
533 | struct dentry *path_refresh_time; | 537 | struct dentry *path_refresh_time; |
534 | struct dentry *min_discovery_timeout; | 538 | struct dentry *min_discovery_timeout; |
535 | } mesh_config; | 539 | } mesh_config; |
536 | #endif | 540 | #endif |
537 | 541 | ||
538 | #endif | 542 | #endif |
539 | /* must be last, dynamically sized area in this! */ | 543 | /* must be last, dynamically sized area in this! */ |
540 | struct ieee80211_vif vif; | 544 | struct ieee80211_vif vif; |
541 | }; | 545 | }; |
542 | 546 | ||
543 | static inline | 547 | static inline |
544 | struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) | 548 | struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) |
545 | { | 549 | { |
546 | return container_of(p, struct ieee80211_sub_if_data, vif); | 550 | return container_of(p, struct ieee80211_sub_if_data, vif); |
547 | } | 551 | } |
548 | 552 | ||
549 | static inline void | 553 | static inline void |
550 | ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata, | 554 | ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata, |
551 | u8 mesh_id_len, u8 *mesh_id) | 555 | u8 mesh_id_len, u8 *mesh_id) |
552 | { | 556 | { |
553 | #ifdef CONFIG_MAC80211_MESH | 557 | #ifdef CONFIG_MAC80211_MESH |
554 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 558 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
555 | ifmsh->mesh_id_len = mesh_id_len; | 559 | ifmsh->mesh_id_len = mesh_id_len; |
556 | memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len); | 560 | memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len); |
557 | #else | 561 | #else |
558 | WARN_ON(1); | 562 | WARN_ON(1); |
559 | #endif | 563 | #endif |
560 | } | 564 | } |
561 | 565 | ||
562 | enum { | 566 | enum { |
563 | IEEE80211_RX_MSG = 1, | 567 | IEEE80211_RX_MSG = 1, |
564 | IEEE80211_TX_STATUS_MSG = 2, | 568 | IEEE80211_TX_STATUS_MSG = 2, |
565 | IEEE80211_DELBA_MSG = 3, | 569 | IEEE80211_DELBA_MSG = 3, |
566 | IEEE80211_ADDBA_MSG = 4, | 570 | IEEE80211_ADDBA_MSG = 4, |
567 | }; | 571 | }; |
568 | 572 | ||
569 | enum queue_stop_reason { | 573 | enum queue_stop_reason { |
570 | IEEE80211_QUEUE_STOP_REASON_DRIVER, | 574 | IEEE80211_QUEUE_STOP_REASON_DRIVER, |
571 | IEEE80211_QUEUE_STOP_REASON_PS, | 575 | IEEE80211_QUEUE_STOP_REASON_PS, |
572 | IEEE80211_QUEUE_STOP_REASON_CSA, | 576 | IEEE80211_QUEUE_STOP_REASON_CSA, |
573 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, | 577 | IEEE80211_QUEUE_STOP_REASON_AGGREGATION, |
574 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, | 578 | IEEE80211_QUEUE_STOP_REASON_SUSPEND, |
575 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, | 579 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD, |
576 | }; | 580 | }; |
577 | 581 | ||
578 | /** | 582 | /** |
579 | * mac80211 scan flags - currently active scan mode | 583 | * mac80211 scan flags - currently active scan mode |
580 | * | 584 | * |
581 | * @SCAN_SW_SCANNING: We're currently in the process of scanning but may as | 585 | * @SCAN_SW_SCANNING: We're currently in the process of scanning but may as |
582 | * well be on the operating channel | 586 | * well be on the operating channel |
583 | * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to | 587 | * @SCAN_HW_SCANNING: The hardware is scanning for us, we have no way to |
584 | * determine if we are on the operating channel or not | 588 | * determine if we are on the operating channel or not |
585 | * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, | 589 | * @SCAN_OFF_CHANNEL: We're off our operating channel for scanning, |
586 | * gets only set in conjunction with SCAN_SW_SCANNING | 590 | * gets only set in conjunction with SCAN_SW_SCANNING |
587 | */ | 591 | */ |
588 | enum { | 592 | enum { |
589 | SCAN_SW_SCANNING, | 593 | SCAN_SW_SCANNING, |
590 | SCAN_HW_SCANNING, | 594 | SCAN_HW_SCANNING, |
591 | SCAN_OFF_CHANNEL, | 595 | SCAN_OFF_CHANNEL, |
592 | }; | 596 | }; |
593 | 597 | ||
594 | /** | 598 | /** |
595 | * enum mac80211_scan_state - scan state machine states | 599 | * enum mac80211_scan_state - scan state machine states |
596 | * | 600 | * |
597 | * @SCAN_DECISION: Main entry point to the scan state machine, this state | 601 | * @SCAN_DECISION: Main entry point to the scan state machine, this state |
598 | * determines if we should keep on scanning or switch back to the | 602 | * determines if we should keep on scanning or switch back to the |
599 | * operating channel | 603 | * operating channel |
600 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned | 604 | * @SCAN_SET_CHANNEL: Set the next channel to be scanned |
601 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses | 605 | * @SCAN_SEND_PROBE: Send probe requests and wait for probe responses |
602 | * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP | 606 | * @SCAN_LEAVE_OPER_CHANNEL: Leave the operating channel, notify the AP |
603 | * about us leaving the channel and stop all associated STA interfaces | 607 | * about us leaving the channel and stop all associated STA interfaces |
604 | * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the | 608 | * @SCAN_ENTER_OPER_CHANNEL: Enter the operating channel again, notify the |
605 | * AP about us being back and restart all associated STA interfaces | 609 | * AP about us being back and restart all associated STA interfaces |
606 | */ | 610 | */ |
607 | enum mac80211_scan_state { | 611 | enum mac80211_scan_state { |
608 | SCAN_DECISION, | 612 | SCAN_DECISION, |
609 | SCAN_SET_CHANNEL, | 613 | SCAN_SET_CHANNEL, |
610 | SCAN_SEND_PROBE, | 614 | SCAN_SEND_PROBE, |
611 | SCAN_LEAVE_OPER_CHANNEL, | 615 | SCAN_LEAVE_OPER_CHANNEL, |
612 | SCAN_ENTER_OPER_CHANNEL, | 616 | SCAN_ENTER_OPER_CHANNEL, |
613 | }; | 617 | }; |
614 | 618 | ||
615 | struct ieee80211_local { | 619 | struct ieee80211_local { |
616 | /* embed the driver visible part. | 620 | /* embed the driver visible part. |
617 | * don't cast (use the static inlines below), but we keep | 621 | * don't cast (use the static inlines below), but we keep |
618 | * it first anyway so they become a no-op */ | 622 | * it first anyway so they become a no-op */ |
619 | struct ieee80211_hw hw; | 623 | struct ieee80211_hw hw; |
620 | 624 | ||
621 | const struct ieee80211_ops *ops; | 625 | const struct ieee80211_ops *ops; |
622 | 626 | ||
623 | /* | 627 | /* |
624 | * private workqueue to mac80211. mac80211 makes this accessible | 628 | * private workqueue to mac80211. mac80211 makes this accessible |
625 | * via ieee80211_queue_work() | 629 | * via ieee80211_queue_work() |
626 | */ | 630 | */ |
627 | struct workqueue_struct *workqueue; | 631 | struct workqueue_struct *workqueue; |
628 | 632 | ||
629 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; | 633 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; |
630 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ | 634 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ |
631 | spinlock_t queue_stop_reason_lock; | 635 | spinlock_t queue_stop_reason_lock; |
632 | 636 | ||
633 | int open_count; | 637 | int open_count; |
634 | int monitors, cooked_mntrs; | 638 | int monitors, cooked_mntrs; |
635 | /* number of interfaces with corresponding FIF_ flags */ | 639 | /* number of interfaces with corresponding FIF_ flags */ |
636 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; | 640 | int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll; |
637 | unsigned int filter_flags; /* FIF_* */ | 641 | unsigned int filter_flags; /* FIF_* */ |
638 | struct iw_statistics wstats; | 642 | struct iw_statistics wstats; |
639 | 643 | ||
640 | /* protects the aggregated multicast list and filter calls */ | 644 | /* protects the aggregated multicast list and filter calls */ |
641 | spinlock_t filter_lock; | 645 | spinlock_t filter_lock; |
642 | 646 | ||
643 | /* used for uploading changed mc list */ | 647 | /* used for uploading changed mc list */ |
644 | struct work_struct reconfig_filter; | 648 | struct work_struct reconfig_filter; |
645 | 649 | ||
646 | /* aggregated multicast list */ | 650 | /* aggregated multicast list */ |
647 | struct dev_addr_list *mc_list; | 651 | struct dev_addr_list *mc_list; |
648 | int mc_count; | 652 | int mc_count; |
649 | 653 | ||
650 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ | 654 | bool tim_in_locked_section; /* see ieee80211_beacon_get() */ |
651 | 655 | ||
652 | /* | 656 | /* |
653 | * suspended is true if we finished all the suspend _and_ we have | 657 | * suspended is true if we finished all the suspend _and_ we have |
654 | * not yet come up from resume. This is to be used by mac80211 | 658 | * not yet come up from resume. This is to be used by mac80211 |
655 | * to ensure driver sanity during suspend and mac80211's own | 659 | * to ensure driver sanity during suspend and mac80211's own |
656 | * sanity. It can eventually be used for WoW as well. | 660 | * sanity. It can eventually be used for WoW as well. |
657 | */ | 661 | */ |
658 | bool suspended; | 662 | bool suspended; |
659 | 663 | ||
660 | /* | 664 | /* |
661 | * quiescing is true during the suspend process _only_ to | 665 | * quiescing is true during the suspend process _only_ to |
662 | * ease timer cancelling etc. | 666 | * ease timer cancelling etc. |
663 | */ | 667 | */ |
664 | bool quiescing; | 668 | bool quiescing; |
665 | 669 | ||
666 | int tx_headroom; /* required headroom for hardware/radiotap */ | 670 | int tx_headroom; /* required headroom for hardware/radiotap */ |
667 | 671 | ||
668 | /* Tasklet and skb queue to process calls from IRQ mode. All frames | 672 | /* Tasklet and skb queue to process calls from IRQ mode. All frames |
669 | * added to skb_queue will be processed, but frames in | 673 | * added to skb_queue will be processed, but frames in |
670 | * skb_queue_unreliable may be dropped if the total length of these | 674 | * skb_queue_unreliable may be dropped if the total length of these |
671 | * queues increases over the limit. */ | 675 | * queues increases over the limit. */ |
672 | #define IEEE80211_IRQSAFE_QUEUE_LIMIT 128 | 676 | #define IEEE80211_IRQSAFE_QUEUE_LIMIT 128 |
673 | struct tasklet_struct tasklet; | 677 | struct tasklet_struct tasklet; |
674 | struct sk_buff_head skb_queue; | 678 | struct sk_buff_head skb_queue; |
675 | struct sk_buff_head skb_queue_unreliable; | 679 | struct sk_buff_head skb_queue_unreliable; |
676 | 680 | ||
677 | /* Station data */ | 681 | /* Station data */ |
678 | /* | 682 | /* |
679 | * The lock only protects the list, hash, timer and counter | 683 | * The lock only protects the list, hash, timer and counter |
680 | * against manipulation, reads are done in RCU. Additionally, | 684 | * against manipulation, reads are done in RCU. Additionally, |
681 | * the lock protects each BSS's TIM bitmap. | 685 | * the lock protects each BSS's TIM bitmap. |
682 | */ | 686 | */ |
683 | spinlock_t sta_lock; | 687 | spinlock_t sta_lock; |
684 | unsigned long num_sta; | 688 | unsigned long num_sta; |
685 | struct list_head sta_list; | 689 | struct list_head sta_list; |
686 | struct sta_info *sta_hash[STA_HASH_SIZE]; | 690 | struct sta_info *sta_hash[STA_HASH_SIZE]; |
687 | struct timer_list sta_cleanup; | 691 | struct timer_list sta_cleanup; |
688 | int sta_generation; | 692 | int sta_generation; |
689 | 693 | ||
690 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; | 694 | struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; |
691 | struct tasklet_struct tx_pending_tasklet; | 695 | struct tasklet_struct tx_pending_tasklet; |
692 | 696 | ||
693 | /* | 697 | /* |
694 | * This lock is used to prevent concurrent A-MPDU | 698 | * This lock is used to prevent concurrent A-MPDU |
695 | * session start/stop processing, this thus also | 699 | * session start/stop processing, this thus also |
696 | * synchronises the ->ampdu_action() callback to | 700 | * synchronises the ->ampdu_action() callback to |
697 | * drivers and limits it to one at a time. | 701 | * drivers and limits it to one at a time. |
698 | */ | 702 | */ |
699 | spinlock_t ampdu_lock; | 703 | spinlock_t ampdu_lock; |
700 | 704 | ||
701 | /* number of interfaces with corresponding IFF_ flags */ | 705 | /* number of interfaces with corresponding IFF_ flags */ |
702 | atomic_t iff_allmultis, iff_promiscs; | 706 | atomic_t iff_allmultis, iff_promiscs; |
703 | 707 | ||
704 | struct rate_control_ref *rate_ctrl; | 708 | struct rate_control_ref *rate_ctrl; |
705 | 709 | ||
706 | struct crypto_blkcipher *wep_tx_tfm; | 710 | struct crypto_blkcipher *wep_tx_tfm; |
707 | struct crypto_blkcipher *wep_rx_tfm; | 711 | struct crypto_blkcipher *wep_rx_tfm; |
708 | u32 wep_iv; | 712 | u32 wep_iv; |
709 | 713 | ||
710 | /* see iface.c */ | 714 | /* see iface.c */ |
711 | struct list_head interfaces; | 715 | struct list_head interfaces; |
712 | struct mutex iflist_mtx; | 716 | struct mutex iflist_mtx; |
713 | 717 | ||
714 | /* | 718 | /* |
715 | * Key lock, protects sdata's key_list and sta_info's | 719 | * Key lock, protects sdata's key_list and sta_info's |
716 | * key pointers (write access, they're RCU.) | 720 | * key pointers (write access, they're RCU.) |
717 | */ | 721 | */ |
718 | spinlock_t key_lock; | 722 | spinlock_t key_lock; |
719 | 723 | ||
720 | 724 | ||
721 | /* Scanning and BSS list */ | 725 | /* Scanning and BSS list */ |
722 | struct mutex scan_mtx; | 726 | struct mutex scan_mtx; |
723 | unsigned long scanning; | 727 | unsigned long scanning; |
724 | struct cfg80211_ssid scan_ssid; | 728 | struct cfg80211_ssid scan_ssid; |
725 | struct cfg80211_scan_request *int_scan_req; | 729 | struct cfg80211_scan_request *int_scan_req; |
726 | struct cfg80211_scan_request *scan_req; | 730 | struct cfg80211_scan_request *scan_req; |
727 | struct ieee80211_channel *scan_channel; | 731 | struct ieee80211_channel *scan_channel; |
728 | const u8 *orig_ies; | 732 | const u8 *orig_ies; |
729 | int orig_ies_len; | 733 | int orig_ies_len; |
730 | int scan_channel_idx; | 734 | int scan_channel_idx; |
731 | int scan_ies_len; | 735 | int scan_ies_len; |
732 | 736 | ||
733 | enum mac80211_scan_state next_scan_state; | 737 | enum mac80211_scan_state next_scan_state; |
734 | struct delayed_work scan_work; | 738 | struct delayed_work scan_work; |
735 | struct ieee80211_sub_if_data *scan_sdata; | 739 | struct ieee80211_sub_if_data *scan_sdata; |
736 | enum nl80211_channel_type oper_channel_type; | 740 | enum nl80211_channel_type oper_channel_type; |
737 | struct ieee80211_channel *oper_channel, *csa_channel; | 741 | struct ieee80211_channel *oper_channel, *csa_channel; |
738 | 742 | ||
739 | /* SNMP counters */ | 743 | /* SNMP counters */ |
740 | /* dot11CountersTable */ | 744 | /* dot11CountersTable */ |
741 | u32 dot11TransmittedFragmentCount; | 745 | u32 dot11TransmittedFragmentCount; |
742 | u32 dot11MulticastTransmittedFrameCount; | 746 | u32 dot11MulticastTransmittedFrameCount; |
743 | u32 dot11FailedCount; | 747 | u32 dot11FailedCount; |
744 | u32 dot11RetryCount; | 748 | u32 dot11RetryCount; |
745 | u32 dot11MultipleRetryCount; | 749 | u32 dot11MultipleRetryCount; |
746 | u32 dot11FrameDuplicateCount; | 750 | u32 dot11FrameDuplicateCount; |
747 | u32 dot11ReceivedFragmentCount; | 751 | u32 dot11ReceivedFragmentCount; |
748 | u32 dot11MulticastReceivedFrameCount; | 752 | u32 dot11MulticastReceivedFrameCount; |
749 | u32 dot11TransmittedFrameCount; | 753 | u32 dot11TransmittedFrameCount; |
750 | 754 | ||
751 | #ifdef CONFIG_MAC80211_LEDS | 755 | #ifdef CONFIG_MAC80211_LEDS |
752 | int tx_led_counter, rx_led_counter; | 756 | int tx_led_counter, rx_led_counter; |
753 | struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; | 757 | struct led_trigger *tx_led, *rx_led, *assoc_led, *radio_led; |
754 | char tx_led_name[32], rx_led_name[32], | 758 | char tx_led_name[32], rx_led_name[32], |
755 | assoc_led_name[32], radio_led_name[32]; | 759 | assoc_led_name[32], radio_led_name[32]; |
756 | #endif | 760 | #endif |
757 | 761 | ||
758 | #ifdef CONFIG_MAC80211_DEBUGFS | 762 | #ifdef CONFIG_MAC80211_DEBUGFS |
759 | struct work_struct sta_debugfs_add; | 763 | struct work_struct sta_debugfs_add; |
760 | #endif | 764 | #endif |
761 | 765 | ||
762 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 766 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
763 | /* TX/RX handler statistics */ | 767 | /* TX/RX handler statistics */ |
764 | unsigned int tx_handlers_drop; | 768 | unsigned int tx_handlers_drop; |
765 | unsigned int tx_handlers_queued; | 769 | unsigned int tx_handlers_queued; |
766 | unsigned int tx_handlers_drop_unencrypted; | 770 | unsigned int tx_handlers_drop_unencrypted; |
767 | unsigned int tx_handlers_drop_fragment; | 771 | unsigned int tx_handlers_drop_fragment; |
768 | unsigned int tx_handlers_drop_wep; | 772 | unsigned int tx_handlers_drop_wep; |
769 | unsigned int tx_handlers_drop_not_assoc; | 773 | unsigned int tx_handlers_drop_not_assoc; |
770 | unsigned int tx_handlers_drop_unauth_port; | 774 | unsigned int tx_handlers_drop_unauth_port; |
771 | unsigned int rx_handlers_drop; | 775 | unsigned int rx_handlers_drop; |
772 | unsigned int rx_handlers_queued; | 776 | unsigned int rx_handlers_queued; |
773 | unsigned int rx_handlers_drop_nullfunc; | 777 | unsigned int rx_handlers_drop_nullfunc; |
774 | unsigned int rx_handlers_drop_defrag; | 778 | unsigned int rx_handlers_drop_defrag; |
775 | unsigned int rx_handlers_drop_short; | 779 | unsigned int rx_handlers_drop_short; |
776 | unsigned int rx_handlers_drop_passive_scan; | 780 | unsigned int rx_handlers_drop_passive_scan; |
777 | unsigned int tx_expand_skb_head; | 781 | unsigned int tx_expand_skb_head; |
778 | unsigned int tx_expand_skb_head_cloned; | 782 | unsigned int tx_expand_skb_head_cloned; |
779 | unsigned int rx_expand_skb_head; | 783 | unsigned int rx_expand_skb_head; |
780 | unsigned int rx_expand_skb_head2; | 784 | unsigned int rx_expand_skb_head2; |
781 | unsigned int rx_handlers_fragments; | 785 | unsigned int rx_handlers_fragments; |
782 | unsigned int tx_status_drop; | 786 | unsigned int tx_status_drop; |
783 | #define I802_DEBUG_INC(c) (c)++ | 787 | #define I802_DEBUG_INC(c) (c)++ |
784 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ | 788 | #else /* CONFIG_MAC80211_DEBUG_COUNTERS */ |
785 | #define I802_DEBUG_INC(c) do { } while (0) | 789 | #define I802_DEBUG_INC(c) do { } while (0) |
786 | #endif /* CONFIG_MAC80211_DEBUG_COUNTERS */ | 790 | #endif /* CONFIG_MAC80211_DEBUG_COUNTERS */ |
787 | 791 | ||
788 | 792 | ||
789 | int total_ps_buffered; /* total number of all buffered unicast and | 793 | int total_ps_buffered; /* total number of all buffered unicast and |
790 | * multicast packets for power saving stations | 794 | * multicast packets for power saving stations |
791 | */ | 795 | */ |
792 | int wifi_wme_noack_test; | 796 | int wifi_wme_noack_test; |
793 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | 797 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ |
794 | 798 | ||
795 | bool pspolling; | 799 | bool pspolling; |
796 | /* | 800 | /* |
797 | * PS can only be enabled when we have exactly one managed | 801 | * PS can only be enabled when we have exactly one managed |
798 | * interface (and monitors) in PS, this then points there. | 802 | * interface (and monitors) in PS, this then points there. |
799 | */ | 803 | */ |
800 | struct ieee80211_sub_if_data *ps_sdata; | 804 | struct ieee80211_sub_if_data *ps_sdata; |
801 | struct work_struct dynamic_ps_enable_work; | 805 | struct work_struct dynamic_ps_enable_work; |
802 | struct work_struct dynamic_ps_disable_work; | 806 | struct work_struct dynamic_ps_disable_work; |
803 | struct timer_list dynamic_ps_timer; | 807 | struct timer_list dynamic_ps_timer; |
804 | struct notifier_block network_latency_notifier; | 808 | struct notifier_block network_latency_notifier; |
805 | 809 | ||
806 | int user_power_level; /* in dBm */ | 810 | int user_power_level; /* in dBm */ |
807 | int power_constr_level; /* in dBm */ | 811 | int power_constr_level; /* in dBm */ |
808 | 812 | ||
809 | struct work_struct restart_work; | 813 | struct work_struct restart_work; |
810 | 814 | ||
811 | #ifdef CONFIG_MAC80211_DEBUGFS | 815 | #ifdef CONFIG_MAC80211_DEBUGFS |
812 | struct local_debugfsdentries { | 816 | struct local_debugfsdentries { |
813 | struct dentry *rcdir; | 817 | struct dentry *rcdir; |
814 | struct dentry *rcname; | 818 | struct dentry *rcname; |
815 | struct dentry *frequency; | 819 | struct dentry *frequency; |
816 | struct dentry *total_ps_buffered; | 820 | struct dentry *total_ps_buffered; |
817 | struct dentry *wep_iv; | 821 | struct dentry *wep_iv; |
818 | struct dentry *tsf; | 822 | struct dentry *tsf; |
819 | struct dentry *queues; | 823 | struct dentry *queues; |
820 | struct dentry *reset; | 824 | struct dentry *reset; |
821 | struct dentry *noack; | 825 | struct dentry *noack; |
822 | struct dentry *statistics; | 826 | struct dentry *statistics; |
823 | struct local_debugfsdentries_statsdentries { | 827 | struct local_debugfsdentries_statsdentries { |
824 | struct dentry *transmitted_fragment_count; | 828 | struct dentry *transmitted_fragment_count; |
825 | struct dentry *multicast_transmitted_frame_count; | 829 | struct dentry *multicast_transmitted_frame_count; |
826 | struct dentry *failed_count; | 830 | struct dentry *failed_count; |
827 | struct dentry *retry_count; | 831 | struct dentry *retry_count; |
828 | struct dentry *multiple_retry_count; | 832 | struct dentry *multiple_retry_count; |
829 | struct dentry *frame_duplicate_count; | 833 | struct dentry *frame_duplicate_count; |
830 | struct dentry *received_fragment_count; | 834 | struct dentry *received_fragment_count; |
831 | struct dentry *multicast_received_frame_count; | 835 | struct dentry *multicast_received_frame_count; |
832 | struct dentry *transmitted_frame_count; | 836 | struct dentry *transmitted_frame_count; |
833 | struct dentry *wep_undecryptable_count; | 837 | struct dentry *wep_undecryptable_count; |
834 | struct dentry *num_scans; | 838 | struct dentry *num_scans; |
835 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | 839 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS |
836 | struct dentry *tx_handlers_drop; | 840 | struct dentry *tx_handlers_drop; |
837 | struct dentry *tx_handlers_queued; | 841 | struct dentry *tx_handlers_queued; |
838 | struct dentry *tx_handlers_drop_unencrypted; | 842 | struct dentry *tx_handlers_drop_unencrypted; |
839 | struct dentry *tx_handlers_drop_fragment; | 843 | struct dentry *tx_handlers_drop_fragment; |
840 | struct dentry *tx_handlers_drop_wep; | 844 | struct dentry *tx_handlers_drop_wep; |
841 | struct dentry *tx_handlers_drop_not_assoc; | 845 | struct dentry *tx_handlers_drop_not_assoc; |
842 | struct dentry *tx_handlers_drop_unauth_port; | 846 | struct dentry *tx_handlers_drop_unauth_port; |
843 | struct dentry *rx_handlers_drop; | 847 | struct dentry *rx_handlers_drop; |
844 | struct dentry *rx_handlers_queued; | 848 | struct dentry *rx_handlers_queued; |
845 | struct dentry *rx_handlers_drop_nullfunc; | 849 | struct dentry *rx_handlers_drop_nullfunc; |
846 | struct dentry *rx_handlers_drop_defrag; | 850 | struct dentry *rx_handlers_drop_defrag; |
847 | struct dentry *rx_handlers_drop_short; | 851 | struct dentry *rx_handlers_drop_short; |
848 | struct dentry *rx_handlers_drop_passive_scan; | 852 | struct dentry *rx_handlers_drop_passive_scan; |
849 | struct dentry *tx_expand_skb_head; | 853 | struct dentry *tx_expand_skb_head; |
850 | struct dentry *tx_expand_skb_head_cloned; | 854 | struct dentry *tx_expand_skb_head_cloned; |
851 | struct dentry *rx_expand_skb_head; | 855 | struct dentry *rx_expand_skb_head; |
852 | struct dentry *rx_expand_skb_head2; | 856 | struct dentry *rx_expand_skb_head2; |
853 | struct dentry *rx_handlers_fragments; | 857 | struct dentry *rx_handlers_fragments; |
854 | struct dentry *tx_status_drop; | 858 | struct dentry *tx_status_drop; |
855 | #endif | 859 | #endif |
856 | struct dentry *dot11ACKFailureCount; | 860 | struct dentry *dot11ACKFailureCount; |
857 | struct dentry *dot11RTSFailureCount; | 861 | struct dentry *dot11RTSFailureCount; |
858 | struct dentry *dot11FCSErrorCount; | 862 | struct dentry *dot11FCSErrorCount; |
859 | struct dentry *dot11RTSSuccessCount; | 863 | struct dentry *dot11RTSSuccessCount; |
860 | } stats; | 864 | } stats; |
861 | struct dentry *stations; | 865 | struct dentry *stations; |
862 | struct dentry *keys; | 866 | struct dentry *keys; |
863 | } debugfs; | 867 | } debugfs; |
864 | #endif | 868 | #endif |
865 | }; | 869 | }; |
866 | 870 | ||
867 | static inline struct ieee80211_sub_if_data * | 871 | static inline struct ieee80211_sub_if_data * |
868 | IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | 872 | IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) |
869 | { | 873 | { |
870 | return netdev_priv(dev); | 874 | return netdev_priv(dev); |
871 | } | 875 | } |
872 | 876 | ||
873 | /* this struct represents 802.11n's RA/TID combination */ | 877 | /* this struct represents 802.11n's RA/TID combination */ |
874 | struct ieee80211_ra_tid { | 878 | struct ieee80211_ra_tid { |
875 | u8 ra[ETH_ALEN]; | 879 | u8 ra[ETH_ALEN]; |
876 | u16 tid; | 880 | u16 tid; |
877 | }; | 881 | }; |
878 | 882 | ||
879 | /* Parsed Information Elements */ | 883 | /* Parsed Information Elements */ |
880 | struct ieee802_11_elems { | 884 | struct ieee802_11_elems { |
881 | u8 *ie_start; | 885 | u8 *ie_start; |
882 | size_t total_len; | 886 | size_t total_len; |
883 | 887 | ||
884 | /* pointers to IEs */ | 888 | /* pointers to IEs */ |
885 | u8 *ssid; | 889 | u8 *ssid; |
886 | u8 *supp_rates; | 890 | u8 *supp_rates; |
887 | u8 *fh_params; | 891 | u8 *fh_params; |
888 | u8 *ds_params; | 892 | u8 *ds_params; |
889 | u8 *cf_params; | 893 | u8 *cf_params; |
890 | struct ieee80211_tim_ie *tim; | 894 | struct ieee80211_tim_ie *tim; |
891 | u8 *ibss_params; | 895 | u8 *ibss_params; |
892 | u8 *challenge; | 896 | u8 *challenge; |
893 | u8 *wpa; | 897 | u8 *wpa; |
894 | u8 *rsn; | 898 | u8 *rsn; |
895 | u8 *erp_info; | 899 | u8 *erp_info; |
896 | u8 *ext_supp_rates; | 900 | u8 *ext_supp_rates; |
897 | u8 *wmm_info; | 901 | u8 *wmm_info; |
898 | u8 *wmm_param; | 902 | u8 *wmm_param; |
899 | struct ieee80211_ht_cap *ht_cap_elem; | 903 | struct ieee80211_ht_cap *ht_cap_elem; |
900 | struct ieee80211_ht_info *ht_info_elem; | 904 | struct ieee80211_ht_info *ht_info_elem; |
901 | u8 *mesh_config; | 905 | u8 *mesh_config; |
902 | u8 *mesh_id; | 906 | u8 *mesh_id; |
903 | u8 *peer_link; | 907 | u8 *peer_link; |
904 | u8 *preq; | 908 | u8 *preq; |
905 | u8 *prep; | 909 | u8 *prep; |
906 | u8 *perr; | 910 | u8 *perr; |
907 | u8 *ch_switch_elem; | 911 | u8 *ch_switch_elem; |
908 | u8 *country_elem; | 912 | u8 *country_elem; |
909 | u8 *pwr_constr_elem; | 913 | u8 *pwr_constr_elem; |
910 | u8 *quiet_elem; /* first quite element */ | 914 | u8 *quiet_elem; /* first quite element */ |
911 | u8 *timeout_int; | 915 | u8 *timeout_int; |
912 | 916 | ||
913 | /* length of them, respectively */ | 917 | /* length of them, respectively */ |
914 | u8 ssid_len; | 918 | u8 ssid_len; |
915 | u8 supp_rates_len; | 919 | u8 supp_rates_len; |
916 | u8 fh_params_len; | 920 | u8 fh_params_len; |
917 | u8 ds_params_len; | 921 | u8 ds_params_len; |
918 | u8 cf_params_len; | 922 | u8 cf_params_len; |
919 | u8 tim_len; | 923 | u8 tim_len; |
920 | u8 ibss_params_len; | 924 | u8 ibss_params_len; |
921 | u8 challenge_len; | 925 | u8 challenge_len; |
922 | u8 wpa_len; | 926 | u8 wpa_len; |
923 | u8 rsn_len; | 927 | u8 rsn_len; |
924 | u8 erp_info_len; | 928 | u8 erp_info_len; |
925 | u8 ext_supp_rates_len; | 929 | u8 ext_supp_rates_len; |
926 | u8 wmm_info_len; | 930 | u8 wmm_info_len; |
927 | u8 wmm_param_len; | 931 | u8 wmm_param_len; |
928 | u8 mesh_config_len; | 932 | u8 mesh_config_len; |
929 | u8 mesh_id_len; | 933 | u8 mesh_id_len; |
930 | u8 peer_link_len; | 934 | u8 peer_link_len; |
931 | u8 preq_len; | 935 | u8 preq_len; |
932 | u8 prep_len; | 936 | u8 prep_len; |
933 | u8 perr_len; | 937 | u8 perr_len; |
934 | u8 ch_switch_elem_len; | 938 | u8 ch_switch_elem_len; |
935 | u8 country_elem_len; | 939 | u8 country_elem_len; |
936 | u8 pwr_constr_elem_len; | 940 | u8 pwr_constr_elem_len; |
937 | u8 quiet_elem_len; | 941 | u8 quiet_elem_len; |
938 | u8 num_of_quiet_elem; /* can be more the one */ | 942 | u8 num_of_quiet_elem; /* can be more the one */ |
939 | u8 timeout_int_len; | 943 | u8 timeout_int_len; |
940 | }; | 944 | }; |
941 | 945 | ||
942 | static inline struct ieee80211_local *hw_to_local( | 946 | static inline struct ieee80211_local *hw_to_local( |
943 | struct ieee80211_hw *hw) | 947 | struct ieee80211_hw *hw) |
944 | { | 948 | { |
945 | return container_of(hw, struct ieee80211_local, hw); | 949 | return container_of(hw, struct ieee80211_local, hw); |
946 | } | 950 | } |
947 | 951 | ||
948 | static inline struct ieee80211_hw *local_to_hw( | 952 | static inline struct ieee80211_hw *local_to_hw( |
949 | struct ieee80211_local *local) | 953 | struct ieee80211_local *local) |
950 | { | 954 | { |
951 | return &local->hw; | 955 | return &local->hw; |
952 | } | 956 | } |
953 | 957 | ||
954 | 958 | ||
955 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) | 959 | static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr) |
956 | { | 960 | { |
957 | return compare_ether_addr(raddr, addr) == 0 || | 961 | return compare_ether_addr(raddr, addr) == 0 || |
958 | is_broadcast_ether_addr(raddr); | 962 | is_broadcast_ether_addr(raddr); |
959 | } | 963 | } |
960 | 964 | ||
961 | 965 | ||
962 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); | 966 | int ieee80211_hw_config(struct ieee80211_local *local, u32 changed); |
963 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); | 967 | void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); |
964 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 968 | void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
965 | u32 changed); | 969 | u32 changed); |
966 | void ieee80211_configure_filter(struct ieee80211_local *local); | 970 | void ieee80211_configure_filter(struct ieee80211_local *local); |
967 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); | 971 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); |
968 | 972 | ||
969 | /* STA code */ | 973 | /* STA code */ |
970 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); | 974 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); |
971 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 975 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
972 | struct cfg80211_auth_request *req); | 976 | struct cfg80211_auth_request *req); |
973 | int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | 977 | int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, |
974 | struct cfg80211_assoc_request *req); | 978 | struct cfg80211_assoc_request *req); |
975 | int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | 979 | int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, |
976 | struct cfg80211_deauth_request *req, | 980 | struct cfg80211_deauth_request *req, |
977 | void *cookie); | 981 | void *cookie); |
978 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | 982 | int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, |
979 | struct cfg80211_disassoc_request *req, | 983 | struct cfg80211_disassoc_request *req, |
980 | void *cookie); | 984 | void *cookie); |
981 | ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | 985 | ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, |
982 | struct sk_buff *skb); | 986 | struct sk_buff *skb); |
983 | void ieee80211_send_pspoll(struct ieee80211_local *local, | 987 | void ieee80211_send_pspoll(struct ieee80211_local *local, |
984 | struct ieee80211_sub_if_data *sdata); | 988 | struct ieee80211_sub_if_data *sdata); |
985 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); | 989 | void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency); |
986 | int ieee80211_max_network_latency(struct notifier_block *nb, | 990 | int ieee80211_max_network_latency(struct notifier_block *nb, |
987 | unsigned long data, void *dummy); | 991 | unsigned long data, void *dummy); |
988 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 992 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, |
989 | struct ieee80211_channel_sw_ie *sw_elem, | 993 | struct ieee80211_channel_sw_ie *sw_elem, |
990 | struct ieee80211_bss *bss); | 994 | struct ieee80211_bss *bss); |
991 | void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata); | 995 | void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata); |
992 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); | 996 | void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); |
993 | 997 | ||
994 | /* IBSS code */ | 998 | /* IBSS code */ |
995 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); | 999 | void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); |
996 | void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); | 1000 | void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata); |
997 | ieee80211_rx_result | 1001 | ieee80211_rx_result |
998 | ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 1002 | ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
999 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | 1003 | struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, |
1000 | u8 *bssid, u8 *addr, u32 supp_rates); | 1004 | u8 *bssid, u8 *addr, u32 supp_rates); |
1001 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | 1005 | int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, |
1002 | struct cfg80211_ibss_params *params); | 1006 | struct cfg80211_ibss_params *params); |
1003 | int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); | 1007 | int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); |
1004 | void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata); | 1008 | void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata); |
1005 | void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); | 1009 | void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); |
1006 | 1010 | ||
1007 | /* scan/BSS handling */ | 1011 | /* scan/BSS handling */ |
1008 | void ieee80211_scan_work(struct work_struct *work); | 1012 | void ieee80211_scan_work(struct work_struct *work); |
1009 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, | 1013 | int ieee80211_request_internal_scan(struct ieee80211_sub_if_data *sdata, |
1010 | const u8 *ssid, u8 ssid_len); | 1014 | const u8 *ssid, u8 ssid_len); |
1011 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 1015 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, |
1012 | struct cfg80211_scan_request *req); | 1016 | struct cfg80211_scan_request *req); |
1013 | void ieee80211_scan_cancel(struct ieee80211_local *local); | 1017 | void ieee80211_scan_cancel(struct ieee80211_local *local); |
1014 | ieee80211_rx_result | 1018 | ieee80211_rx_result |
1015 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | 1019 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); |
1016 | 1020 | ||
1017 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); | 1021 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); |
1018 | struct ieee80211_bss * | 1022 | struct ieee80211_bss * |
1019 | ieee80211_bss_info_update(struct ieee80211_local *local, | 1023 | ieee80211_bss_info_update(struct ieee80211_local *local, |
1020 | struct ieee80211_rx_status *rx_status, | 1024 | struct ieee80211_rx_status *rx_status, |
1021 | struct ieee80211_mgmt *mgmt, | 1025 | struct ieee80211_mgmt *mgmt, |
1022 | size_t len, | 1026 | size_t len, |
1023 | struct ieee802_11_elems *elems, | 1027 | struct ieee802_11_elems *elems, |
1024 | struct ieee80211_channel *channel, | 1028 | struct ieee80211_channel *channel, |
1025 | bool beacon); | 1029 | bool beacon); |
1026 | struct ieee80211_bss * | 1030 | struct ieee80211_bss * |
1027 | ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, | 1031 | ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq, |
1028 | u8 *ssid, u8 ssid_len); | 1032 | u8 *ssid, u8 ssid_len); |
1029 | void ieee80211_rx_bss_put(struct ieee80211_local *local, | 1033 | void ieee80211_rx_bss_put(struct ieee80211_local *local, |
1030 | struct ieee80211_bss *bss); | 1034 | struct ieee80211_bss *bss); |
1031 | 1035 | ||
1032 | /* interface handling */ | 1036 | /* interface handling */ |
1033 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1037 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1034 | struct net_device **new_dev, enum nl80211_iftype type, | 1038 | struct net_device **new_dev, enum nl80211_iftype type, |
1035 | struct vif_params *params); | 1039 | struct vif_params *params); |
1036 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 1040 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
1037 | enum nl80211_iftype type); | 1041 | enum nl80211_iftype type); |
1038 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); | 1042 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); |
1039 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 1043 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
1040 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); | 1044 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); |
1041 | void ieee80211_recalc_idle(struct ieee80211_local *local); | 1045 | void ieee80211_recalc_idle(struct ieee80211_local *local); |
1042 | 1046 | ||
1043 | /* tx handling */ | 1047 | /* tx handling */ |
1044 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); | 1048 | void ieee80211_clear_tx_pending(struct ieee80211_local *local); |
1045 | void ieee80211_tx_pending(unsigned long data); | 1049 | void ieee80211_tx_pending(unsigned long data); |
1046 | int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); | 1050 | int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); |
1047 | int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); | 1051 | int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); |
1048 | 1052 | ||
1049 | /* HT */ | 1053 | /* HT */ |
1050 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, | 1054 | void ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_supported_band *sband, |
1051 | struct ieee80211_ht_cap *ht_cap_ie, | 1055 | struct ieee80211_ht_cap *ht_cap_ie, |
1052 | struct ieee80211_sta_ht_cap *ht_cap); | 1056 | struct ieee80211_sta_ht_cap *ht_cap); |
1053 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); | 1057 | void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn); |
1054 | void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, | 1058 | void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata, |
1055 | const u8 *da, u16 tid, | 1059 | const u8 *da, u16 tid, |
1056 | u16 initiator, u16 reason_code); | 1060 | u16 initiator, u16 reason_code); |
1057 | 1061 | ||
1058 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, | 1062 | void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da, |
1059 | u16 tid, u16 initiator, u16 reason); | 1063 | u16 tid, u16 initiator, u16 reason); |
1060 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | 1064 | void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, |
1061 | u16 initiator, u16 reason); | 1065 | u16 initiator, u16 reason); |
1062 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); | 1066 | void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta); |
1063 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | 1067 | void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, |
1064 | struct sta_info *sta, | 1068 | struct sta_info *sta, |
1065 | struct ieee80211_mgmt *mgmt, size_t len); | 1069 | struct ieee80211_mgmt *mgmt, size_t len); |
1066 | void ieee80211_process_addba_resp(struct ieee80211_local *local, | 1070 | void ieee80211_process_addba_resp(struct ieee80211_local *local, |
1067 | struct sta_info *sta, | 1071 | struct sta_info *sta, |
1068 | struct ieee80211_mgmt *mgmt, | 1072 | struct ieee80211_mgmt *mgmt, |
1069 | size_t len); | 1073 | size_t len); |
1070 | void ieee80211_process_addba_request(struct ieee80211_local *local, | 1074 | void ieee80211_process_addba_request(struct ieee80211_local *local, |
1071 | struct sta_info *sta, | 1075 | struct sta_info *sta, |
1072 | struct ieee80211_mgmt *mgmt, | 1076 | struct ieee80211_mgmt *mgmt, |
1073 | size_t len); | 1077 | size_t len); |
1074 | 1078 | ||
1075 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 1079 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
1076 | enum ieee80211_back_parties initiator); | 1080 | enum ieee80211_back_parties initiator); |
1077 | 1081 | ||
1078 | /* Spectrum management */ | 1082 | /* Spectrum management */ |
1079 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 1083 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
1080 | struct ieee80211_mgmt *mgmt, | 1084 | struct ieee80211_mgmt *mgmt, |
1081 | size_t len); | 1085 | size_t len); |
1082 | 1086 | ||
1083 | /* Suspend/resume and hw reconfiguration */ | 1087 | /* Suspend/resume and hw reconfiguration */ |
1084 | int ieee80211_reconfig(struct ieee80211_local *local); | 1088 | int ieee80211_reconfig(struct ieee80211_local *local); |
1085 | 1089 | ||
1086 | #ifdef CONFIG_PM | 1090 | #ifdef CONFIG_PM |
1087 | int __ieee80211_suspend(struct ieee80211_hw *hw); | 1091 | int __ieee80211_suspend(struct ieee80211_hw *hw); |
1088 | 1092 | ||
1089 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) | 1093 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) |
1090 | { | 1094 | { |
1091 | return ieee80211_reconfig(hw_to_local(hw)); | 1095 | return ieee80211_reconfig(hw_to_local(hw)); |
1092 | } | 1096 | } |
1093 | #else | 1097 | #else |
1094 | static inline int __ieee80211_suspend(struct ieee80211_hw *hw) | 1098 | static inline int __ieee80211_suspend(struct ieee80211_hw *hw) |
1095 | { | 1099 | { |
1096 | return 0; | 1100 | return 0; |
1097 | } | 1101 | } |
1098 | 1102 | ||
1099 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) | 1103 | static inline int __ieee80211_resume(struct ieee80211_hw *hw) |
1100 | { | 1104 | { |
1101 | return 0; | 1105 | return 0; |
1102 | } | 1106 | } |
1103 | #endif | 1107 | #endif |
1104 | 1108 | ||
1105 | /* utility functions/constants */ | 1109 | /* utility functions/constants */ |
1106 | extern void *mac80211_wiphy_privid; /* for wiphy privid */ | 1110 | extern void *mac80211_wiphy_privid; /* for wiphy privid */ |
1107 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, | 1111 | u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, |
1108 | enum nl80211_iftype type); | 1112 | enum nl80211_iftype type); |
1109 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, | 1113 | int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, |
1110 | int rate, int erp, int short_preamble); | 1114 | int rate, int erp, int short_preamble); |
1111 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, | 1115 | void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx, |
1112 | struct ieee80211_hdr *hdr, const u8 *tsc, | 1116 | struct ieee80211_hdr *hdr, const u8 *tsc, |
1113 | gfp_t gfp); | 1117 | gfp_t gfp); |
1114 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); | 1118 | void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata); |
1115 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, | 1119 | void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb, |
1116 | int encrypt); | 1120 | int encrypt); |
1117 | void ieee802_11_parse_elems(u8 *start, size_t len, | 1121 | void ieee802_11_parse_elems(u8 *start, size_t len, |
1118 | struct ieee802_11_elems *elems); | 1122 | struct ieee802_11_elems *elems); |
1119 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, | 1123 | u32 ieee802_11_parse_elems_crc(u8 *start, size_t len, |
1120 | struct ieee802_11_elems *elems, | 1124 | struct ieee802_11_elems *elems, |
1121 | u64 filter, u32 crc); | 1125 | u64 filter, u32 crc); |
1122 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | 1126 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, |
1123 | enum ieee80211_band band); | 1127 | enum ieee80211_band band); |
1124 | 1128 | ||
1125 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work); | 1129 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work); |
1126 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work); | 1130 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work); |
1127 | void ieee80211_dynamic_ps_timer(unsigned long data); | 1131 | void ieee80211_dynamic_ps_timer(unsigned long data); |
1128 | void ieee80211_send_nullfunc(struct ieee80211_local *local, | 1132 | void ieee80211_send_nullfunc(struct ieee80211_local *local, |
1129 | struct ieee80211_sub_if_data *sdata, | 1133 | struct ieee80211_sub_if_data *sdata, |
1130 | int powersave); | 1134 | int powersave); |
1131 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | 1135 | void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, |
1132 | struct ieee80211_hdr *hdr); | 1136 | struct ieee80211_hdr *hdr); |
1133 | void ieee80211_beacon_loss_work(struct work_struct *work); | 1137 | void ieee80211_beacon_loss_work(struct work_struct *work); |
1134 | 1138 | ||
1135 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, | 1139 | void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw, |
1136 | enum queue_stop_reason reason); | 1140 | enum queue_stop_reason reason); |
1137 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, | 1141 | void ieee80211_stop_queues_by_reason(struct ieee80211_hw *hw, |
1138 | enum queue_stop_reason reason); | 1142 | enum queue_stop_reason reason); |
1139 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1143 | void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, |
1140 | enum queue_stop_reason reason); | 1144 | enum queue_stop_reason reason); |
1141 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | 1145 | void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, |
1142 | enum queue_stop_reason reason); | 1146 | enum queue_stop_reason reason); |
1143 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | 1147 | void ieee80211_add_pending_skb(struct ieee80211_local *local, |
1144 | struct sk_buff *skb); | 1148 | struct sk_buff *skb); |
1145 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, | 1149 | int ieee80211_add_pending_skbs(struct ieee80211_local *local, |
1146 | struct sk_buff_head *skbs); | 1150 | struct sk_buff_head *skbs); |
1147 | 1151 | ||
1148 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1152 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1149 | u16 transaction, u16 auth_alg, | 1153 | u16 transaction, u16 auth_alg, |
1150 | u8 *extra, size_t extra_len, const u8 *bssid, | 1154 | u8 *extra, size_t extra_len, const u8 *bssid, |
1151 | const u8 *key, u8 key_len, u8 key_idx); | 1155 | const u8 *key, u8 key_len, u8 key_idx); |
1152 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1156 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
1153 | const u8 *ie, size_t ie_len); | 1157 | const u8 *ie, size_t ie_len); |
1154 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1158 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1155 | const u8 *ssid, size_t ssid_len, | 1159 | const u8 *ssid, size_t ssid_len, |
1156 | const u8 *ie, size_t ie_len); | 1160 | const u8 *ie, size_t ie_len); |
1157 | 1161 | ||
1158 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | 1162 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, |
1159 | const size_t supp_rates_len, | 1163 | const size_t supp_rates_len, |
1160 | const u8 *supp_rates); | 1164 | const u8 *supp_rates); |
1161 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, | 1165 | u32 ieee80211_sta_get_rates(struct ieee80211_local *local, |
1162 | struct ieee802_11_elems *elems, | 1166 | struct ieee802_11_elems *elems, |
1163 | enum ieee80211_band band); | 1167 | enum ieee80211_band band); |
1164 | 1168 | ||
1165 | #ifdef CONFIG_MAC80211_NOINLINE | 1169 | #ifdef CONFIG_MAC80211_NOINLINE |
1166 | #define debug_noinline noinline | 1170 | #define debug_noinline noinline |
1167 | #else | 1171 | #else |
1168 | #define debug_noinline | 1172 | #define debug_noinline |
1169 | #endif | 1173 | #endif |
1170 | 1174 | ||
1171 | #endif /* IEEE80211_I_H */ | 1175 | #endif /* IEEE80211_I_H */ |
1172 | 1176 |
net/mac80211/mesh.c
1 | /* | 1 | /* |
2 | * Copyright (c) 2008 open80211s Ltd. | 2 | * Copyright (c) 2008 open80211s Ltd. |
3 | * Authors: Luis Carlos Cobo <luisca@cozybit.com> | 3 | * Authors: Luis Carlos Cobo <luisca@cozybit.com> |
4 | * Javier Cardona <javier@cozybit.com> | 4 | * Javier Cardona <javier@cozybit.com> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * 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 | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <asm/unaligned.h> | 11 | #include <asm/unaligned.h> |
12 | #include "ieee80211_i.h" | 12 | #include "ieee80211_i.h" |
13 | #include "mesh.h" | 13 | #include "mesh.h" |
14 | 14 | ||
15 | #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) | 15 | #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) |
16 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) | 16 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) |
17 | 17 | ||
18 | #define PP_OFFSET 1 /* Path Selection Protocol */ | 18 | #define PP_OFFSET 1 /* Path Selection Protocol */ |
19 | #define PM_OFFSET 5 /* Path Selection Metric */ | 19 | #define PM_OFFSET 5 /* Path Selection Metric */ |
20 | #define CC_OFFSET 9 /* Congestion Control Mode */ | 20 | #define CC_OFFSET 9 /* Congestion Control Mode */ |
21 | #define CAPAB_OFFSET 17 | 21 | #define SP_OFFSET 13 /* Synchronization Protocol */ |
22 | #define ACCEPT_PLINKS 0x80 | 22 | #define AUTH_OFFSET 17 /* Authentication Protocol */ |
23 | #define CAPAB_OFFSET 22 | ||
24 | #define CAPAB_ACCEPT_PLINKS 0x80 | ||
25 | #define CAPAB_FORWARDING 0x10 | ||
23 | 26 | ||
24 | #define TMR_RUNNING_HK 0 | 27 | #define TMR_RUNNING_HK 0 |
25 | #define TMR_RUNNING_MP 1 | 28 | #define TMR_RUNNING_MP 1 |
26 | 29 | ||
27 | int mesh_allocated; | 30 | int mesh_allocated; |
28 | static struct kmem_cache *rm_cache; | 31 | static struct kmem_cache *rm_cache; |
29 | 32 | ||
30 | void ieee80211s_init(void) | 33 | void ieee80211s_init(void) |
31 | { | 34 | { |
32 | mesh_pathtbl_init(); | 35 | mesh_pathtbl_init(); |
33 | mesh_allocated = 1; | 36 | mesh_allocated = 1; |
34 | rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry), | 37 | rm_cache = kmem_cache_create("mesh_rmc", sizeof(struct rmc_entry), |
35 | 0, 0, NULL); | 38 | 0, 0, NULL); |
36 | } | 39 | } |
37 | 40 | ||
38 | void ieee80211s_stop(void) | 41 | void ieee80211s_stop(void) |
39 | { | 42 | { |
40 | mesh_pathtbl_unregister(); | 43 | mesh_pathtbl_unregister(); |
41 | kmem_cache_destroy(rm_cache); | 44 | kmem_cache_destroy(rm_cache); |
42 | } | 45 | } |
43 | 46 | ||
44 | static void ieee80211_mesh_housekeeping_timer(unsigned long data) | 47 | static void ieee80211_mesh_housekeeping_timer(unsigned long data) |
45 | { | 48 | { |
46 | struct ieee80211_sub_if_data *sdata = (void *) data; | 49 | struct ieee80211_sub_if_data *sdata = (void *) data; |
47 | struct ieee80211_local *local = sdata->local; | 50 | struct ieee80211_local *local = sdata->local; |
48 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 51 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
49 | 52 | ||
50 | ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING; | 53 | ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING; |
51 | 54 | ||
52 | if (local->quiescing) { | 55 | if (local->quiescing) { |
53 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); | 56 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); |
54 | return; | 57 | return; |
55 | } | 58 | } |
56 | 59 | ||
57 | ieee80211_queue_work(&local->hw, &ifmsh->work); | 60 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
58 | } | 61 | } |
59 | 62 | ||
60 | /** | 63 | /** |
61 | * mesh_matches_local - check if the config of a mesh point matches ours | 64 | * mesh_matches_local - check if the config of a mesh point matches ours |
62 | * | 65 | * |
63 | * @ie: information elements of a management frame from the mesh peer | 66 | * @ie: information elements of a management frame from the mesh peer |
64 | * @sdata: local mesh subif | 67 | * @sdata: local mesh subif |
65 | * | 68 | * |
66 | * This function checks if the mesh configuration of a mesh point matches the | 69 | * This function checks if the mesh configuration of a mesh point matches the |
67 | * local mesh configuration, i.e. if both nodes belong to the same mesh network. | 70 | * local mesh configuration, i.e. if both nodes belong to the same mesh network. |
68 | */ | 71 | */ |
69 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) | 72 | bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata) |
70 | { | 73 | { |
71 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 74 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
72 | 75 | ||
73 | /* | 76 | /* |
74 | * As support for each feature is added, check for matching | 77 | * As support for each feature is added, check for matching |
75 | * - On mesh config capabilities | 78 | * - On mesh config capabilities |
76 | * - Power Save Support En | 79 | * - Power Save Support En |
77 | * - Sync support enabled | 80 | * - Sync support enabled |
78 | * - Sync support active | 81 | * - Sync support active |
79 | * - Sync support required from peer | 82 | * - Sync support required from peer |
80 | * - MDA enabled | 83 | * - MDA enabled |
81 | * - Power management control on fc | 84 | * - Power management control on fc |
82 | */ | 85 | */ |
83 | if (ifmsh->mesh_id_len == ie->mesh_id_len && | 86 | if (ifmsh->mesh_id_len == ie->mesh_id_len && |
84 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && | 87 | memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && |
85 | memcmp(ifmsh->mesh_pp_id, ie->mesh_config + PP_OFFSET, 4) == 0 && | 88 | memcmp(ifmsh->mesh_pp_id, ie->mesh_config + PP_OFFSET, 4) == 0 && |
86 | memcmp(ifmsh->mesh_pm_id, ie->mesh_config + PM_OFFSET, 4) == 0 && | 89 | memcmp(ifmsh->mesh_pm_id, ie->mesh_config + PM_OFFSET, 4) == 0 && |
87 | memcmp(ifmsh->mesh_cc_id, ie->mesh_config + CC_OFFSET, 4) == 0) | 90 | memcmp(ifmsh->mesh_cc_id, ie->mesh_config + CC_OFFSET, 4) == 0 && |
91 | memcmp(ifmsh->mesh_sp_id, ie->mesh_config + SP_OFFSET, 4) == 0 && | ||
92 | memcmp(ifmsh->mesh_auth_id, ie->mesh_config + AUTH_OFFSET, 4) == 0) | ||
88 | return true; | 93 | return true; |
89 | 94 | ||
90 | return false; | 95 | return false; |
91 | } | 96 | } |
92 | 97 | ||
93 | /** | 98 | /** |
94 | * mesh_peer_accepts_plinks - check if an mp is willing to establish peer links | 99 | * mesh_peer_accepts_plinks - check if an mp is willing to establish peer links |
95 | * | 100 | * |
96 | * @ie: information elements of a management frame from the mesh peer | 101 | * @ie: information elements of a management frame from the mesh peer |
97 | */ | 102 | */ |
98 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) | 103 | bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) |
99 | { | 104 | { |
100 | return (*(ie->mesh_config + CAPAB_OFFSET) & ACCEPT_PLINKS) != 0; | 105 | return (*(ie->mesh_config + CAPAB_OFFSET) & CAPAB_ACCEPT_PLINKS) != 0; |
101 | } | 106 | } |
102 | 107 | ||
103 | /** | 108 | /** |
104 | * mesh_accept_plinks_update: update accepting_plink in local mesh beacons | 109 | * mesh_accept_plinks_update: update accepting_plink in local mesh beacons |
105 | * | 110 | * |
106 | * @sdata: mesh interface in which mesh beacons are going to be updated | 111 | * @sdata: mesh interface in which mesh beacons are going to be updated |
107 | */ | 112 | */ |
108 | void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) | 113 | void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata) |
109 | { | 114 | { |
110 | bool free_plinks; | 115 | bool free_plinks; |
111 | 116 | ||
112 | /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0, | 117 | /* In case mesh_plink_free_count > 0 and mesh_plinktbl_capacity == 0, |
113 | * the mesh interface might be able to establish plinks with peers that | 118 | * the mesh interface might be able to establish plinks with peers that |
114 | * are already on the table but are not on PLINK_ESTAB state. However, | 119 | * are already on the table but are not on PLINK_ESTAB state. However, |
115 | * in general the mesh interface is not accepting peer link requests | 120 | * in general the mesh interface is not accepting peer link requests |
116 | * from new peers, and that must be reflected in the beacon | 121 | * from new peers, and that must be reflected in the beacon |
117 | */ | 122 | */ |
118 | free_plinks = mesh_plink_availables(sdata); | 123 | free_plinks = mesh_plink_availables(sdata); |
119 | 124 | ||
120 | if (free_plinks != sdata->u.mesh.accepting_plinks) | 125 | if (free_plinks != sdata->u.mesh.accepting_plinks) |
121 | ieee80211_mesh_housekeeping_timer((unsigned long) sdata); | 126 | ieee80211_mesh_housekeeping_timer((unsigned long) sdata); |
122 | } | 127 | } |
123 | 128 | ||
124 | void mesh_ids_set_default(struct ieee80211_if_mesh *sta) | 129 | void mesh_ids_set_default(struct ieee80211_if_mesh *sta) |
125 | { | 130 | { |
126 | u8 def_id[4] = {0x00, 0x0F, 0xAC, 0xff}; | 131 | u8 oui[3] = {0x00, 0x0F, 0xAC}; |
127 | 132 | ||
128 | memcpy(sta->mesh_pp_id, def_id, 4); | 133 | memcpy(sta->mesh_pp_id, oui, sizeof(oui)); |
129 | memcpy(sta->mesh_pm_id, def_id, 4); | 134 | memcpy(sta->mesh_pm_id, oui, sizeof(oui)); |
130 | memcpy(sta->mesh_cc_id, def_id, 4); | 135 | memcpy(sta->mesh_cc_id, oui, sizeof(oui)); |
136 | memcpy(sta->mesh_sp_id, oui, sizeof(oui)); | ||
137 | memcpy(sta->mesh_auth_id, oui, sizeof(oui)); | ||
138 | sta->mesh_pp_id[sizeof(oui)] = 0; | ||
139 | sta->mesh_pm_id[sizeof(oui)] = 0; | ||
140 | sta->mesh_cc_id[sizeof(oui)] = 0xff; | ||
141 | sta->mesh_sp_id[sizeof(oui)] = 0xff; | ||
142 | sta->mesh_auth_id[sizeof(oui)] = 0x0; | ||
131 | } | 143 | } |
132 | 144 | ||
133 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) | 145 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) |
134 | { | 146 | { |
135 | int i; | 147 | int i; |
136 | 148 | ||
137 | sdata->u.mesh.rmc = kmalloc(sizeof(struct mesh_rmc), GFP_KERNEL); | 149 | sdata->u.mesh.rmc = kmalloc(sizeof(struct mesh_rmc), GFP_KERNEL); |
138 | if (!sdata->u.mesh.rmc) | 150 | if (!sdata->u.mesh.rmc) |
139 | return -ENOMEM; | 151 | return -ENOMEM; |
140 | sdata->u.mesh.rmc->idx_mask = RMC_BUCKETS - 1; | 152 | sdata->u.mesh.rmc->idx_mask = RMC_BUCKETS - 1; |
141 | for (i = 0; i < RMC_BUCKETS; i++) | 153 | for (i = 0; i < RMC_BUCKETS; i++) |
142 | INIT_LIST_HEAD(&sdata->u.mesh.rmc->bucket[i].list); | 154 | INIT_LIST_HEAD(&sdata->u.mesh.rmc->bucket[i].list); |
143 | return 0; | 155 | return 0; |
144 | } | 156 | } |
145 | 157 | ||
146 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata) | 158 | void mesh_rmc_free(struct ieee80211_sub_if_data *sdata) |
147 | { | 159 | { |
148 | struct mesh_rmc *rmc = sdata->u.mesh.rmc; | 160 | struct mesh_rmc *rmc = sdata->u.mesh.rmc; |
149 | struct rmc_entry *p, *n; | 161 | struct rmc_entry *p, *n; |
150 | int i; | 162 | int i; |
151 | 163 | ||
152 | if (!sdata->u.mesh.rmc) | 164 | if (!sdata->u.mesh.rmc) |
153 | return; | 165 | return; |
154 | 166 | ||
155 | for (i = 0; i < RMC_BUCKETS; i++) | 167 | for (i = 0; i < RMC_BUCKETS; i++) |
156 | list_for_each_entry_safe(p, n, &rmc->bucket[i].list, list) { | 168 | list_for_each_entry_safe(p, n, &rmc->bucket[i].list, list) { |
157 | list_del(&p->list); | 169 | list_del(&p->list); |
158 | kmem_cache_free(rm_cache, p); | 170 | kmem_cache_free(rm_cache, p); |
159 | } | 171 | } |
160 | 172 | ||
161 | kfree(rmc); | 173 | kfree(rmc); |
162 | sdata->u.mesh.rmc = NULL; | 174 | sdata->u.mesh.rmc = NULL; |
163 | } | 175 | } |
164 | 176 | ||
165 | /** | 177 | /** |
166 | * mesh_rmc_check - Check frame in recent multicast cache and add if absent. | 178 | * mesh_rmc_check - Check frame in recent multicast cache and add if absent. |
167 | * | 179 | * |
168 | * @sa: source address | 180 | * @sa: source address |
169 | * @mesh_hdr: mesh_header | 181 | * @mesh_hdr: mesh_header |
170 | * | 182 | * |
171 | * Returns: 0 if the frame is not in the cache, nonzero otherwise. | 183 | * Returns: 0 if the frame is not in the cache, nonzero otherwise. |
172 | * | 184 | * |
173 | * Checks using the source address and the mesh sequence number if we have | 185 | * Checks using the source address and the mesh sequence number if we have |
174 | * received this frame lately. If the frame is not in the cache, it is added to | 186 | * received this frame lately. If the frame is not in the cache, it is added to |
175 | * it. | 187 | * it. |
176 | */ | 188 | */ |
177 | int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, | 189 | int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, |
178 | struct ieee80211_sub_if_data *sdata) | 190 | struct ieee80211_sub_if_data *sdata) |
179 | { | 191 | { |
180 | struct mesh_rmc *rmc = sdata->u.mesh.rmc; | 192 | struct mesh_rmc *rmc = sdata->u.mesh.rmc; |
181 | u32 seqnum = 0; | 193 | u32 seqnum = 0; |
182 | int entries = 0; | 194 | int entries = 0; |
183 | u8 idx; | 195 | u8 idx; |
184 | struct rmc_entry *p, *n; | 196 | struct rmc_entry *p, *n; |
185 | 197 | ||
186 | /* Don't care about endianness since only match matters */ | 198 | /* Don't care about endianness since only match matters */ |
187 | memcpy(&seqnum, &mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum)); | 199 | memcpy(&seqnum, &mesh_hdr->seqnum, sizeof(mesh_hdr->seqnum)); |
188 | idx = le32_to_cpu(mesh_hdr->seqnum) & rmc->idx_mask; | 200 | idx = le32_to_cpu(mesh_hdr->seqnum) & rmc->idx_mask; |
189 | list_for_each_entry_safe(p, n, &rmc->bucket[idx].list, list) { | 201 | list_for_each_entry_safe(p, n, &rmc->bucket[idx].list, list) { |
190 | ++entries; | 202 | ++entries; |
191 | if (time_after(jiffies, p->exp_time) || | 203 | if (time_after(jiffies, p->exp_time) || |
192 | (entries == RMC_QUEUE_MAX_LEN)) { | 204 | (entries == RMC_QUEUE_MAX_LEN)) { |
193 | list_del(&p->list); | 205 | list_del(&p->list); |
194 | kmem_cache_free(rm_cache, p); | 206 | kmem_cache_free(rm_cache, p); |
195 | --entries; | 207 | --entries; |
196 | } else if ((seqnum == p->seqnum) | 208 | } else if ((seqnum == p->seqnum) |
197 | && (memcmp(sa, p->sa, ETH_ALEN) == 0)) | 209 | && (memcmp(sa, p->sa, ETH_ALEN) == 0)) |
198 | return -1; | 210 | return -1; |
199 | } | 211 | } |
200 | 212 | ||
201 | p = kmem_cache_alloc(rm_cache, GFP_ATOMIC); | 213 | p = kmem_cache_alloc(rm_cache, GFP_ATOMIC); |
202 | if (!p) { | 214 | if (!p) { |
203 | printk(KERN_DEBUG "o11s: could not allocate RMC entry\n"); | 215 | printk(KERN_DEBUG "o11s: could not allocate RMC entry\n"); |
204 | return 0; | 216 | return 0; |
205 | } | 217 | } |
206 | p->seqnum = seqnum; | 218 | p->seqnum = seqnum; |
207 | p->exp_time = jiffies + RMC_TIMEOUT; | 219 | p->exp_time = jiffies + RMC_TIMEOUT; |
208 | memcpy(p->sa, sa, ETH_ALEN); | 220 | memcpy(p->sa, sa, ETH_ALEN); |
209 | list_add(&p->list, &rmc->bucket[idx].list); | 221 | list_add(&p->list, &rmc->bucket[idx].list); |
210 | return 0; | 222 | return 0; |
211 | } | 223 | } |
212 | 224 | ||
213 | void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) | 225 | void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata) |
214 | { | 226 | { |
215 | struct ieee80211_local *local = sdata->local; | 227 | struct ieee80211_local *local = sdata->local; |
216 | struct ieee80211_supported_band *sband; | 228 | struct ieee80211_supported_band *sband; |
217 | u8 *pos; | 229 | u8 *pos; |
218 | int len, i, rate; | 230 | int len, i, rate; |
219 | 231 | ||
220 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 232 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
221 | len = sband->n_bitrates; | 233 | len = sband->n_bitrates; |
222 | if (len > 8) | 234 | if (len > 8) |
223 | len = 8; | 235 | len = 8; |
224 | pos = skb_put(skb, len + 2); | 236 | pos = skb_put(skb, len + 2); |
225 | *pos++ = WLAN_EID_SUPP_RATES; | 237 | *pos++ = WLAN_EID_SUPP_RATES; |
226 | *pos++ = len; | 238 | *pos++ = len; |
227 | for (i = 0; i < len; i++) { | 239 | for (i = 0; i < len; i++) { |
228 | rate = sband->bitrates[i].bitrate; | 240 | rate = sband->bitrates[i].bitrate; |
229 | *pos++ = (u8) (rate / 5); | 241 | *pos++ = (u8) (rate / 5); |
230 | } | 242 | } |
231 | 243 | ||
232 | if (sband->n_bitrates > len) { | 244 | if (sband->n_bitrates > len) { |
233 | pos = skb_put(skb, sband->n_bitrates - len + 2); | 245 | pos = skb_put(skb, sband->n_bitrates - len + 2); |
234 | *pos++ = WLAN_EID_EXT_SUPP_RATES; | 246 | *pos++ = WLAN_EID_EXT_SUPP_RATES; |
235 | *pos++ = sband->n_bitrates - len; | 247 | *pos++ = sband->n_bitrates - len; |
236 | for (i = len; i < sband->n_bitrates; i++) { | 248 | for (i = len; i < sband->n_bitrates; i++) { |
237 | rate = sband->bitrates[i].bitrate; | 249 | rate = sband->bitrates[i].bitrate; |
238 | *pos++ = (u8) (rate / 5); | 250 | *pos++ = (u8) (rate / 5); |
239 | } | 251 | } |
240 | } | 252 | } |
241 | 253 | ||
242 | pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len); | 254 | pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len); |
243 | *pos++ = WLAN_EID_MESH_ID; | 255 | *pos++ = WLAN_EID_MESH_ID; |
244 | *pos++ = sdata->u.mesh.mesh_id_len; | 256 | *pos++ = sdata->u.mesh.mesh_id_len; |
245 | if (sdata->u.mesh.mesh_id_len) | 257 | if (sdata->u.mesh.mesh_id_len) |
246 | memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len); | 258 | memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len); |
247 | 259 | ||
248 | pos = skb_put(skb, 21); | 260 | pos = skb_put(skb, 2 + IEEE80211_MESH_CONFIG_LEN); |
249 | *pos++ = WLAN_EID_MESH_CONFIG; | 261 | *pos++ = WLAN_EID_MESH_CONFIG; |
250 | *pos++ = IEEE80211_MESH_CONFIG_LEN; | 262 | *pos++ = IEEE80211_MESH_CONFIG_LEN; |
251 | /* Version */ | 263 | /* Version */ |
252 | *pos++ = 1; | 264 | *pos++ = 1; |
253 | 265 | ||
254 | /* Active path selection protocol ID */ | 266 | /* Active path selection protocol ID */ |
255 | memcpy(pos, sdata->u.mesh.mesh_pp_id, 4); | 267 | memcpy(pos, sdata->u.mesh.mesh_pp_id, 4); |
256 | pos += 4; | 268 | pos += 4; |
257 | 269 | ||
258 | /* Active path selection metric ID */ | 270 | /* Active path selection metric ID */ |
259 | memcpy(pos, sdata->u.mesh.mesh_pm_id, 4); | 271 | memcpy(pos, sdata->u.mesh.mesh_pm_id, 4); |
260 | pos += 4; | 272 | pos += 4; |
261 | 273 | ||
262 | /* Congestion control mode identifier */ | 274 | /* Congestion control mode identifier */ |
263 | memcpy(pos, sdata->u.mesh.mesh_cc_id, 4); | 275 | memcpy(pos, sdata->u.mesh.mesh_cc_id, 4); |
264 | pos += 4; | 276 | pos += 4; |
265 | 277 | ||
266 | /* Channel precedence: | 278 | /* Synchronization protocol identifier */ |
267 | * Not running simple channel unification protocol | 279 | memcpy(pos, sdata->u.mesh.mesh_sp_id, 4); |
268 | */ | ||
269 | memset(pos, 0x00, 4); | ||
270 | pos += 4; | 280 | pos += 4; |
271 | 281 | ||
282 | /* Authentication Protocol identifier */ | ||
283 | memcpy(pos, sdata->u.mesh.mesh_auth_id, 4); | ||
284 | pos += 4; | ||
285 | |||
286 | /* Mesh Formation Info */ | ||
287 | memset(pos, 0x00, 1); | ||
288 | pos += 1; | ||
289 | |||
272 | /* Mesh capability */ | 290 | /* Mesh capability */ |
273 | sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata); | 291 | sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata); |
274 | *pos++ = sdata->u.mesh.accepting_plinks ? ACCEPT_PLINKS : 0x00; | 292 | *pos = CAPAB_FORWARDING; |
293 | *pos++ |= sdata->u.mesh.accepting_plinks ? CAPAB_ACCEPT_PLINKS : 0x00; | ||
275 | *pos++ = 0x00; | 294 | *pos++ = 0x00; |
276 | 295 | ||
277 | return; | 296 | return; |
278 | } | 297 | } |
279 | 298 | ||
280 | u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) | 299 | u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl) |
281 | { | 300 | { |
282 | /* Use last four bytes of hw addr and interface index as hash index */ | 301 | /* Use last four bytes of hw addr and interface index as hash index */ |
283 | return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd) | 302 | return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd) |
284 | & tbl->hash_mask; | 303 | & tbl->hash_mask; |
285 | } | 304 | } |
286 | 305 | ||
287 | struct mesh_table *mesh_table_alloc(int size_order) | 306 | struct mesh_table *mesh_table_alloc(int size_order) |
288 | { | 307 | { |
289 | int i; | 308 | int i; |
290 | struct mesh_table *newtbl; | 309 | struct mesh_table *newtbl; |
291 | 310 | ||
292 | newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL); | 311 | newtbl = kmalloc(sizeof(struct mesh_table), GFP_KERNEL); |
293 | if (!newtbl) | 312 | if (!newtbl) |
294 | return NULL; | 313 | return NULL; |
295 | 314 | ||
296 | newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * | 315 | newtbl->hash_buckets = kzalloc(sizeof(struct hlist_head) * |
297 | (1 << size_order), GFP_KERNEL); | 316 | (1 << size_order), GFP_KERNEL); |
298 | 317 | ||
299 | if (!newtbl->hash_buckets) { | 318 | if (!newtbl->hash_buckets) { |
300 | kfree(newtbl); | 319 | kfree(newtbl); |
301 | return NULL; | 320 | return NULL; |
302 | } | 321 | } |
303 | 322 | ||
304 | newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * | 323 | newtbl->hashwlock = kmalloc(sizeof(spinlock_t) * |
305 | (1 << size_order), GFP_KERNEL); | 324 | (1 << size_order), GFP_KERNEL); |
306 | if (!newtbl->hashwlock) { | 325 | if (!newtbl->hashwlock) { |
307 | kfree(newtbl->hash_buckets); | 326 | kfree(newtbl->hash_buckets); |
308 | kfree(newtbl); | 327 | kfree(newtbl); |
309 | return NULL; | 328 | return NULL; |
310 | } | 329 | } |
311 | 330 | ||
312 | newtbl->size_order = size_order; | 331 | newtbl->size_order = size_order; |
313 | newtbl->hash_mask = (1 << size_order) - 1; | 332 | newtbl->hash_mask = (1 << size_order) - 1; |
314 | atomic_set(&newtbl->entries, 0); | 333 | atomic_set(&newtbl->entries, 0); |
315 | get_random_bytes(&newtbl->hash_rnd, | 334 | get_random_bytes(&newtbl->hash_rnd, |
316 | sizeof(newtbl->hash_rnd)); | 335 | sizeof(newtbl->hash_rnd)); |
317 | for (i = 0; i <= newtbl->hash_mask; i++) | 336 | for (i = 0; i <= newtbl->hash_mask; i++) |
318 | spin_lock_init(&newtbl->hashwlock[i]); | 337 | spin_lock_init(&newtbl->hashwlock[i]); |
319 | 338 | ||
320 | return newtbl; | 339 | return newtbl; |
321 | } | 340 | } |
322 | 341 | ||
323 | 342 | ||
324 | static void ieee80211_mesh_path_timer(unsigned long data) | 343 | static void ieee80211_mesh_path_timer(unsigned long data) |
325 | { | 344 | { |
326 | struct ieee80211_sub_if_data *sdata = | 345 | struct ieee80211_sub_if_data *sdata = |
327 | (struct ieee80211_sub_if_data *) data; | 346 | (struct ieee80211_sub_if_data *) data; |
328 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 347 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
329 | struct ieee80211_local *local = sdata->local; | 348 | struct ieee80211_local *local = sdata->local; |
330 | 349 | ||
331 | if (local->quiescing) { | 350 | if (local->quiescing) { |
332 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); | 351 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); |
333 | return; | 352 | return; |
334 | } | 353 | } |
335 | 354 | ||
336 | ieee80211_queue_work(&local->hw, &ifmsh->work); | 355 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
337 | } | 356 | } |
338 | 357 | ||
339 | /** | 358 | /** |
340 | * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame | 359 | * ieee80211_fill_mesh_addresses - fill addresses of a locally originated mesh frame |
341 | * @hdr: 802.11 frame header | 360 | * @hdr: 802.11 frame header |
342 | * @fc: frame control field | 361 | * @fc: frame control field |
343 | * @meshda: destination address in the mesh | 362 | * @meshda: destination address in the mesh |
344 | * @meshsa: source address address in the mesh. Same as TA, as frame is | 363 | * @meshsa: source address address in the mesh. Same as TA, as frame is |
345 | * locally originated. | 364 | * locally originated. |
346 | * | 365 | * |
347 | * Return the length of the 802.11 (does not include a mesh control header) | 366 | * Return the length of the 802.11 (does not include a mesh control header) |
348 | */ | 367 | */ |
349 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, char | 368 | int ieee80211_fill_mesh_addresses(struct ieee80211_hdr *hdr, __le16 *fc, char |
350 | *meshda, char *meshsa) { | 369 | *meshda, char *meshsa) { |
351 | if (is_multicast_ether_addr(meshda)) { | 370 | if (is_multicast_ether_addr(meshda)) { |
352 | *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); | 371 | *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); |
353 | /* DA TA SA */ | 372 | /* DA TA SA */ |
354 | memcpy(hdr->addr1, meshda, ETH_ALEN); | 373 | memcpy(hdr->addr1, meshda, ETH_ALEN); |
355 | memcpy(hdr->addr2, meshsa, ETH_ALEN); | 374 | memcpy(hdr->addr2, meshsa, ETH_ALEN); |
356 | memcpy(hdr->addr3, meshsa, ETH_ALEN); | 375 | memcpy(hdr->addr3, meshsa, ETH_ALEN); |
357 | return 24; | 376 | return 24; |
358 | } else { | 377 | } else { |
359 | *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | | 378 | *fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | |
360 | IEEE80211_FCTL_TODS); | 379 | IEEE80211_FCTL_TODS); |
361 | /* RA TA DA SA */ | 380 | /* RA TA DA SA */ |
362 | memset(hdr->addr1, 0, ETH_ALEN); /* RA is resolved later */ | 381 | memset(hdr->addr1, 0, ETH_ALEN); /* RA is resolved later */ |
363 | memcpy(hdr->addr2, meshsa, ETH_ALEN); | 382 | memcpy(hdr->addr2, meshsa, ETH_ALEN); |
364 | memcpy(hdr->addr3, meshda, ETH_ALEN); | 383 | memcpy(hdr->addr3, meshda, ETH_ALEN); |
365 | memcpy(hdr->addr4, meshsa, ETH_ALEN); | 384 | memcpy(hdr->addr4, meshsa, ETH_ALEN); |
366 | return 30; | 385 | return 30; |
367 | } | 386 | } |
368 | } | 387 | } |
369 | 388 | ||
370 | /** | 389 | /** |
371 | * ieee80211_new_mesh_header - create a new mesh header | 390 | * ieee80211_new_mesh_header - create a new mesh header |
372 | * @meshhdr: uninitialized mesh header | 391 | * @meshhdr: uninitialized mesh header |
373 | * @sdata: mesh interface to be used | 392 | * @sdata: mesh interface to be used |
374 | * @addr4: addr4 of the mesh frame (1st in ae header) | 393 | * @addr4: addr4 of the mesh frame (1st in ae header) |
375 | * may be NULL | 394 | * may be NULL |
376 | * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) | 395 | * @addr5: addr5 of the mesh frame (1st or 2nd in ae header) |
377 | * may be NULL unless addr6 is present | 396 | * may be NULL unless addr6 is present |
378 | * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) | 397 | * @addr6: addr6 of the mesh frame (2nd or 3rd in ae header) |
379 | * may be NULL unless addr5 is present | 398 | * may be NULL unless addr5 is present |
380 | * | 399 | * |
381 | * Return the header length. | 400 | * Return the header length. |
382 | */ | 401 | */ |
383 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, | 402 | int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, |
384 | struct ieee80211_sub_if_data *sdata, char *addr4, | 403 | struct ieee80211_sub_if_data *sdata, char *addr4, |
385 | char *addr5, char *addr6) | 404 | char *addr5, char *addr6) |
386 | { | 405 | { |
387 | int aelen = 0; | 406 | int aelen = 0; |
388 | memset(meshhdr, 0, sizeof(meshhdr)); | 407 | memset(meshhdr, 0, sizeof(meshhdr)); |
389 | meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; | 408 | meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL; |
390 | put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); | 409 | put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum); |
391 | sdata->u.mesh.mesh_seqnum++; | 410 | sdata->u.mesh.mesh_seqnum++; |
392 | if (addr4) { | 411 | if (addr4) { |
393 | meshhdr->flags |= MESH_FLAGS_AE_A4; | 412 | meshhdr->flags |= MESH_FLAGS_AE_A4; |
394 | aelen += ETH_ALEN; | 413 | aelen += ETH_ALEN; |
395 | memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); | 414 | memcpy(meshhdr->eaddr1, addr4, ETH_ALEN); |
396 | } | 415 | } |
397 | if (addr5 && addr6) { | 416 | if (addr5 && addr6) { |
398 | meshhdr->flags |= MESH_FLAGS_AE_A5_A6; | 417 | meshhdr->flags |= MESH_FLAGS_AE_A5_A6; |
399 | aelen += 2 * ETH_ALEN; | 418 | aelen += 2 * ETH_ALEN; |
400 | if (!addr4) { | 419 | if (!addr4) { |
401 | memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); | 420 | memcpy(meshhdr->eaddr1, addr5, ETH_ALEN); |
402 | memcpy(meshhdr->eaddr2, addr6, ETH_ALEN); | 421 | memcpy(meshhdr->eaddr2, addr6, ETH_ALEN); |
403 | } else { | 422 | } else { |
404 | memcpy(meshhdr->eaddr2, addr5, ETH_ALEN); | 423 | memcpy(meshhdr->eaddr2, addr5, ETH_ALEN); |
405 | memcpy(meshhdr->eaddr3, addr6, ETH_ALEN); | 424 | memcpy(meshhdr->eaddr3, addr6, ETH_ALEN); |
406 | } | 425 | } |
407 | } | 426 | } |
408 | return 6 + aelen; | 427 | return 6 + aelen; |
409 | } | 428 | } |
410 | 429 | ||
411 | static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | 430 | static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, |
412 | struct ieee80211_if_mesh *ifmsh) | 431 | struct ieee80211_if_mesh *ifmsh) |
413 | { | 432 | { |
414 | bool free_plinks; | 433 | bool free_plinks; |
415 | 434 | ||
416 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 435 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
417 | printk(KERN_DEBUG "%s: running mesh housekeeping\n", | 436 | printk(KERN_DEBUG "%s: running mesh housekeeping\n", |
418 | sdata->dev->name); | 437 | sdata->dev->name); |
419 | #endif | 438 | #endif |
420 | 439 | ||
421 | ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); | 440 | ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); |
422 | mesh_path_expire(sdata); | 441 | mesh_path_expire(sdata); |
423 | 442 | ||
424 | free_plinks = mesh_plink_availables(sdata); | 443 | free_plinks = mesh_plink_availables(sdata); |
425 | if (free_plinks != sdata->u.mesh.accepting_plinks) | 444 | if (free_plinks != sdata->u.mesh.accepting_plinks) |
426 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); | 445 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
427 | 446 | ||
428 | mod_timer(&ifmsh->housekeeping_timer, | 447 | mod_timer(&ifmsh->housekeeping_timer, |
429 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); | 448 | round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL)); |
430 | } | 449 | } |
431 | 450 | ||
432 | #ifdef CONFIG_PM | 451 | #ifdef CONFIG_PM |
433 | void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) | 452 | void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata) |
434 | { | 453 | { |
435 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 454 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
436 | 455 | ||
437 | /* might restart the timer but that doesn't matter */ | 456 | /* might restart the timer but that doesn't matter */ |
438 | cancel_work_sync(&ifmsh->work); | 457 | cancel_work_sync(&ifmsh->work); |
439 | 458 | ||
440 | /* use atomic bitops in case both timers fire at the same time */ | 459 | /* use atomic bitops in case both timers fire at the same time */ |
441 | 460 | ||
442 | if (del_timer_sync(&ifmsh->housekeeping_timer)) | 461 | if (del_timer_sync(&ifmsh->housekeeping_timer)) |
443 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); | 462 | set_bit(TMR_RUNNING_HK, &ifmsh->timers_running); |
444 | if (del_timer_sync(&ifmsh->mesh_path_timer)) | 463 | if (del_timer_sync(&ifmsh->mesh_path_timer)) |
445 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); | 464 | set_bit(TMR_RUNNING_MP, &ifmsh->timers_running); |
446 | } | 465 | } |
447 | 466 | ||
448 | void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) | 467 | void ieee80211_mesh_restart(struct ieee80211_sub_if_data *sdata) |
449 | { | 468 | { |
450 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 469 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
451 | 470 | ||
452 | if (test_and_clear_bit(TMR_RUNNING_HK, &ifmsh->timers_running)) | 471 | if (test_and_clear_bit(TMR_RUNNING_HK, &ifmsh->timers_running)) |
453 | add_timer(&ifmsh->housekeeping_timer); | 472 | add_timer(&ifmsh->housekeeping_timer); |
454 | if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running)) | 473 | if (test_and_clear_bit(TMR_RUNNING_MP, &ifmsh->timers_running)) |
455 | add_timer(&ifmsh->mesh_path_timer); | 474 | add_timer(&ifmsh->mesh_path_timer); |
456 | } | 475 | } |
457 | #endif | 476 | #endif |
458 | 477 | ||
459 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | 478 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) |
460 | { | 479 | { |
461 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 480 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
462 | struct ieee80211_local *local = sdata->local; | 481 | struct ieee80211_local *local = sdata->local; |
463 | 482 | ||
464 | ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING; | 483 | ifmsh->wrkq_flags |= MESH_WORK_HOUSEKEEPING; |
465 | ieee80211_queue_work(&local->hw, &ifmsh->work); | 484 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
466 | sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; | 485 | sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; |
467 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | | 486 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | |
468 | BSS_CHANGED_BEACON_ENABLED | | 487 | BSS_CHANGED_BEACON_ENABLED | |
469 | BSS_CHANGED_BEACON_INT); | 488 | BSS_CHANGED_BEACON_INT); |
470 | } | 489 | } |
471 | 490 | ||
472 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | 491 | void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) |
473 | { | 492 | { |
474 | del_timer_sync(&sdata->u.mesh.housekeeping_timer); | 493 | del_timer_sync(&sdata->u.mesh.housekeeping_timer); |
475 | /* | 494 | /* |
476 | * If the timer fired while we waited for it, it will have | 495 | * If the timer fired while we waited for it, it will have |
477 | * requeued the work. Now the work will be running again | 496 | * requeued the work. Now the work will be running again |
478 | * but will not rearm the timer again because it checks | 497 | * but will not rearm the timer again because it checks |
479 | * whether the interface is running, which, at this point, | 498 | * whether the interface is running, which, at this point, |
480 | * it no longer is. | 499 | * it no longer is. |
481 | */ | 500 | */ |
482 | cancel_work_sync(&sdata->u.mesh.work); | 501 | cancel_work_sync(&sdata->u.mesh.work); |
483 | 502 | ||
484 | /* | 503 | /* |
485 | * When we get here, the interface is marked down. | 504 | * When we get here, the interface is marked down. |
486 | * Call synchronize_rcu() to wait for the RX path | 505 | * Call synchronize_rcu() to wait for the RX path |
487 | * should it be using the interface and enqueuing | 506 | * should it be using the interface and enqueuing |
488 | * frames at this very time on another CPU. | 507 | * frames at this very time on another CPU. |
489 | */ | 508 | */ |
490 | rcu_barrier(); /* Wait for RX path and call_rcu()'s */ | 509 | rcu_barrier(); /* Wait for RX path and call_rcu()'s */ |
491 | skb_queue_purge(&sdata->u.mesh.skb_queue); | 510 | skb_queue_purge(&sdata->u.mesh.skb_queue); |
492 | } | 511 | } |
493 | 512 | ||
494 | static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | 513 | static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, |
495 | u16 stype, | 514 | u16 stype, |
496 | struct ieee80211_mgmt *mgmt, | 515 | struct ieee80211_mgmt *mgmt, |
497 | size_t len, | 516 | size_t len, |
498 | struct ieee80211_rx_status *rx_status) | 517 | struct ieee80211_rx_status *rx_status) |
499 | { | 518 | { |
500 | struct ieee80211_local *local = sdata->local; | 519 | struct ieee80211_local *local = sdata->local; |
501 | struct ieee802_11_elems elems; | 520 | struct ieee802_11_elems elems; |
502 | struct ieee80211_channel *channel; | 521 | struct ieee80211_channel *channel; |
503 | u32 supp_rates = 0; | 522 | u32 supp_rates = 0; |
504 | size_t baselen; | 523 | size_t baselen; |
505 | int freq; | 524 | int freq; |
506 | enum ieee80211_band band = rx_status->band; | 525 | enum ieee80211_band band = rx_status->band; |
507 | 526 | ||
508 | /* ignore ProbeResp to foreign address */ | 527 | /* ignore ProbeResp to foreign address */ |
509 | if (stype == IEEE80211_STYPE_PROBE_RESP && | 528 | if (stype == IEEE80211_STYPE_PROBE_RESP && |
510 | compare_ether_addr(mgmt->da, sdata->dev->dev_addr)) | 529 | compare_ether_addr(mgmt->da, sdata->dev->dev_addr)) |
511 | return; | 530 | return; |
512 | 531 | ||
513 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; | 532 | baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; |
514 | if (baselen > len) | 533 | if (baselen > len) |
515 | return; | 534 | return; |
516 | 535 | ||
517 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, | 536 | ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, |
518 | &elems); | 537 | &elems); |
519 | 538 | ||
520 | if (elems.ds_params && elems.ds_params_len == 1) | 539 | if (elems.ds_params && elems.ds_params_len == 1) |
521 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); | 540 | freq = ieee80211_channel_to_frequency(elems.ds_params[0]); |
522 | else | 541 | else |
523 | freq = rx_status->freq; | 542 | freq = rx_status->freq; |
524 | 543 | ||
525 | channel = ieee80211_get_channel(local->hw.wiphy, freq); | 544 | channel = ieee80211_get_channel(local->hw.wiphy, freq); |
526 | 545 | ||
527 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) | 546 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) |
528 | return; | 547 | return; |
529 | 548 | ||
530 | if (elems.mesh_id && elems.mesh_config && | 549 | if (elems.mesh_id && elems.mesh_config && |
531 | mesh_matches_local(&elems, sdata)) { | 550 | mesh_matches_local(&elems, sdata)) { |
532 | supp_rates = ieee80211_sta_get_rates(local, &elems, band); | 551 | supp_rates = ieee80211_sta_get_rates(local, &elems, band); |
533 | 552 | ||
534 | mesh_neighbour_update(mgmt->sa, supp_rates, sdata, | 553 | mesh_neighbour_update(mgmt->sa, supp_rates, sdata, |
535 | mesh_peer_accepts_plinks(&elems)); | 554 | mesh_peer_accepts_plinks(&elems)); |
536 | } | 555 | } |
537 | } | 556 | } |
538 | 557 | ||
539 | static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, | 558 | static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata, |
540 | struct ieee80211_mgmt *mgmt, | 559 | struct ieee80211_mgmt *mgmt, |
541 | size_t len, | 560 | size_t len, |
542 | struct ieee80211_rx_status *rx_status) | 561 | struct ieee80211_rx_status *rx_status) |
543 | { | 562 | { |
544 | switch (mgmt->u.action.category) { | 563 | switch (mgmt->u.action.category) { |
545 | case PLINK_CATEGORY: | 564 | case PLINK_CATEGORY: |
546 | mesh_rx_plink_frame(sdata, mgmt, len, rx_status); | 565 | mesh_rx_plink_frame(sdata, mgmt, len, rx_status); |
547 | break; | 566 | break; |
548 | case MESH_PATH_SEL_CATEGORY: | 567 | case MESH_PATH_SEL_CATEGORY: |
549 | mesh_rx_path_sel_frame(sdata, mgmt, len); | 568 | mesh_rx_path_sel_frame(sdata, mgmt, len); |
550 | break; | 569 | break; |
551 | } | 570 | } |
552 | } | 571 | } |
553 | 572 | ||
554 | static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 573 | static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, |
555 | struct sk_buff *skb) | 574 | struct sk_buff *skb) |
556 | { | 575 | { |
557 | struct ieee80211_rx_status *rx_status; | 576 | struct ieee80211_rx_status *rx_status; |
558 | struct ieee80211_if_mesh *ifmsh; | 577 | struct ieee80211_if_mesh *ifmsh; |
559 | struct ieee80211_mgmt *mgmt; | 578 | struct ieee80211_mgmt *mgmt; |
560 | u16 stype; | 579 | u16 stype; |
561 | 580 | ||
562 | ifmsh = &sdata->u.mesh; | 581 | ifmsh = &sdata->u.mesh; |
563 | 582 | ||
564 | rx_status = IEEE80211_SKB_RXCB(skb); | 583 | rx_status = IEEE80211_SKB_RXCB(skb); |
565 | mgmt = (struct ieee80211_mgmt *) skb->data; | 584 | mgmt = (struct ieee80211_mgmt *) skb->data; |
566 | stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; | 585 | stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; |
567 | 586 | ||
568 | switch (stype) { | 587 | switch (stype) { |
569 | case IEEE80211_STYPE_PROBE_RESP: | 588 | case IEEE80211_STYPE_PROBE_RESP: |
570 | case IEEE80211_STYPE_BEACON: | 589 | case IEEE80211_STYPE_BEACON: |
571 | ieee80211_mesh_rx_bcn_presp(sdata, stype, mgmt, skb->len, | 590 | ieee80211_mesh_rx_bcn_presp(sdata, stype, mgmt, skb->len, |
572 | rx_status); | 591 | rx_status); |
573 | break; | 592 | break; |
574 | case IEEE80211_STYPE_ACTION: | 593 | case IEEE80211_STYPE_ACTION: |
575 | ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status); | 594 | ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status); |
576 | break; | 595 | break; |
577 | } | 596 | } |
578 | 597 | ||
579 | kfree_skb(skb); | 598 | kfree_skb(skb); |
580 | } | 599 | } |
581 | 600 | ||
582 | static void ieee80211_mesh_work(struct work_struct *work) | 601 | static void ieee80211_mesh_work(struct work_struct *work) |
583 | { | 602 | { |
584 | struct ieee80211_sub_if_data *sdata = | 603 | struct ieee80211_sub_if_data *sdata = |
585 | container_of(work, struct ieee80211_sub_if_data, u.mesh.work); | 604 | container_of(work, struct ieee80211_sub_if_data, u.mesh.work); |
586 | struct ieee80211_local *local = sdata->local; | 605 | struct ieee80211_local *local = sdata->local; |
587 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 606 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
588 | struct sk_buff *skb; | 607 | struct sk_buff *skb; |
589 | 608 | ||
590 | if (!netif_running(sdata->dev)) | 609 | if (!netif_running(sdata->dev)) |
591 | return; | 610 | return; |
592 | 611 | ||
593 | if (local->scanning) | 612 | if (local->scanning) |
594 | return; | 613 | return; |
595 | 614 | ||
596 | while ((skb = skb_dequeue(&ifmsh->skb_queue))) | 615 | while ((skb = skb_dequeue(&ifmsh->skb_queue))) |
597 | ieee80211_mesh_rx_queued_mgmt(sdata, skb); | 616 | ieee80211_mesh_rx_queued_mgmt(sdata, skb); |
598 | 617 | ||
599 | if (ifmsh->preq_queue_len && | 618 | if (ifmsh->preq_queue_len && |
600 | time_after(jiffies, | 619 | time_after(jiffies, |
601 | ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) | 620 | ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) |
602 | mesh_path_start_discovery(sdata); | 621 | mesh_path_start_discovery(sdata); |
603 | 622 | ||
604 | if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags)) | 623 | if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags)) |
605 | mesh_mpath_table_grow(); | 624 | mesh_mpath_table_grow(); |
606 | 625 | ||
607 | if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags)) | 626 | if (test_and_clear_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags)) |
608 | mesh_mpp_table_grow(); | 627 | mesh_mpp_table_grow(); |
609 | 628 | ||
610 | if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) | 629 | if (test_and_clear_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags)) |
611 | ieee80211_mesh_housekeeping(sdata, ifmsh); | 630 | ieee80211_mesh_housekeeping(sdata, ifmsh); |
612 | } | 631 | } |
613 | 632 | ||
614 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) | 633 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) |
615 | { | 634 | { |
616 | struct ieee80211_sub_if_data *sdata; | 635 | struct ieee80211_sub_if_data *sdata; |
617 | 636 | ||
618 | rcu_read_lock(); | 637 | rcu_read_lock(); |
619 | list_for_each_entry_rcu(sdata, &local->interfaces, list) | 638 | list_for_each_entry_rcu(sdata, &local->interfaces, list) |
620 | if (ieee80211_vif_is_mesh(&sdata->vif)) | 639 | if (ieee80211_vif_is_mesh(&sdata->vif)) |
621 | ieee80211_queue_work(&local->hw, &sdata->u.mesh.work); | 640 | ieee80211_queue_work(&local->hw, &sdata->u.mesh.work); |
622 | rcu_read_unlock(); | 641 | rcu_read_unlock(); |
623 | } | 642 | } |
624 | 643 | ||
625 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | 644 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) |
626 | { | 645 | { |
627 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 646 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
628 | 647 | ||
629 | INIT_WORK(&ifmsh->work, ieee80211_mesh_work); | 648 | INIT_WORK(&ifmsh->work, ieee80211_mesh_work); |
630 | setup_timer(&ifmsh->housekeeping_timer, | 649 | setup_timer(&ifmsh->housekeeping_timer, |
631 | ieee80211_mesh_housekeeping_timer, | 650 | ieee80211_mesh_housekeeping_timer, |
632 | (unsigned long) sdata); | 651 | (unsigned long) sdata); |
633 | skb_queue_head_init(&sdata->u.mesh.skb_queue); | 652 | skb_queue_head_init(&sdata->u.mesh.skb_queue); |
634 | 653 | ||
635 | ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; | 654 | ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; |
636 | ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; | 655 | ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; |
637 | ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; | 656 | ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; |
638 | ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; | 657 | ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; |
639 | ifmsh->mshcfg.dot11MeshTTL = MESH_TTL; | 658 | ifmsh->mshcfg.dot11MeshTTL = MESH_TTL; |
640 | ifmsh->mshcfg.auto_open_plinks = true; | 659 | ifmsh->mshcfg.auto_open_plinks = true; |
641 | ifmsh->mshcfg.dot11MeshMaxPeerLinks = | 660 | ifmsh->mshcfg.dot11MeshMaxPeerLinks = |
642 | MESH_MAX_ESTAB_PLINKS; | 661 | MESH_MAX_ESTAB_PLINKS; |
643 | ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout = | 662 | ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout = |
644 | MESH_PATH_TIMEOUT; | 663 | MESH_PATH_TIMEOUT; |
645 | ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval = | 664 | ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval = |
646 | MESH_PREQ_MIN_INT; | 665 | MESH_PREQ_MIN_INT; |
647 | ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime = | 666 | ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime = |
648 | MESH_DIAM_TRAVERSAL_TIME; | 667 | MESH_DIAM_TRAVERSAL_TIME; |
649 | ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries = | 668 | ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries = |
650 | MESH_MAX_PREQ_RETRIES; | 669 | MESH_MAX_PREQ_RETRIES; |
651 | ifmsh->mshcfg.path_refresh_time = | 670 | ifmsh->mshcfg.path_refresh_time = |
652 | MESH_PATH_REFRESH_TIME; | 671 | MESH_PATH_REFRESH_TIME; |
653 | ifmsh->mshcfg.min_discovery_timeout = | 672 | ifmsh->mshcfg.min_discovery_timeout = |
654 | MESH_MIN_DISCOVERY_TIMEOUT; | 673 | MESH_MIN_DISCOVERY_TIMEOUT; |
655 | ifmsh->accepting_plinks = true; | 674 | ifmsh->accepting_plinks = true; |
656 | ifmsh->preq_id = 0; | 675 | ifmsh->preq_id = 0; |
657 | ifmsh->dsn = 0; | 676 | ifmsh->dsn = 0; |
658 | atomic_set(&ifmsh->mpaths, 0); | 677 | atomic_set(&ifmsh->mpaths, 0); |
659 | mesh_rmc_init(sdata); | 678 | mesh_rmc_init(sdata); |
660 | ifmsh->last_preq = jiffies; | 679 | ifmsh->last_preq = jiffies; |
661 | /* Allocate all mesh structures when creating the first mesh interface. */ | 680 | /* Allocate all mesh structures when creating the first mesh interface. */ |
662 | if (!mesh_allocated) | 681 | if (!mesh_allocated) |
663 | ieee80211s_init(); | 682 | ieee80211s_init(); |
664 | mesh_ids_set_default(ifmsh); | 683 | mesh_ids_set_default(ifmsh); |
665 | setup_timer(&ifmsh->mesh_path_timer, | 684 | setup_timer(&ifmsh->mesh_path_timer, |
666 | ieee80211_mesh_path_timer, | 685 | ieee80211_mesh_path_timer, |
667 | (unsigned long) sdata); | 686 | (unsigned long) sdata); |
668 | INIT_LIST_HEAD(&ifmsh->preq_queue.list); | 687 | INIT_LIST_HEAD(&ifmsh->preq_queue.list); |
669 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); | 688 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); |
670 | } | 689 | } |
671 | 690 | ||
672 | ieee80211_rx_result | 691 | ieee80211_rx_result |
673 | ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | 692 | ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) |
674 | { | 693 | { |
675 | struct ieee80211_local *local = sdata->local; | 694 | struct ieee80211_local *local = sdata->local; |
676 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 695 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
677 | struct ieee80211_mgmt *mgmt; | 696 | struct ieee80211_mgmt *mgmt; |
678 | u16 fc; | 697 | u16 fc; |
679 | 698 | ||
680 | if (skb->len < 24) | 699 | if (skb->len < 24) |
681 | return RX_DROP_MONITOR; | 700 | return RX_DROP_MONITOR; |
682 | 701 | ||
683 | mgmt = (struct ieee80211_mgmt *) skb->data; | 702 | mgmt = (struct ieee80211_mgmt *) skb->data; |
684 | fc = le16_to_cpu(mgmt->frame_control); | 703 | fc = le16_to_cpu(mgmt->frame_control); |
685 | 704 | ||
686 | switch (fc & IEEE80211_FCTL_STYPE) { | 705 | switch (fc & IEEE80211_FCTL_STYPE) { |
687 | case IEEE80211_STYPE_ACTION: | 706 | case IEEE80211_STYPE_ACTION: |
688 | if (skb->len < IEEE80211_MIN_ACTION_SIZE) | 707 | if (skb->len < IEEE80211_MIN_ACTION_SIZE) |
689 | return RX_DROP_MONITOR; | 708 | return RX_DROP_MONITOR; |
690 | /* fall through */ | 709 | /* fall through */ |
691 | case IEEE80211_STYPE_PROBE_RESP: | 710 | case IEEE80211_STYPE_PROBE_RESP: |
692 | case IEEE80211_STYPE_BEACON: | 711 | case IEEE80211_STYPE_BEACON: |
693 | skb_queue_tail(&ifmsh->skb_queue, skb); | 712 | skb_queue_tail(&ifmsh->skb_queue, skb); |
694 | ieee80211_queue_work(&local->hw, &ifmsh->work); | 713 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
695 | return RX_QUEUED; | 714 | return RX_QUEUED; |
696 | } | 715 | } |
697 | 716 | ||
698 | return RX_CONTINUE; | 717 | return RX_CONTINUE; |