Commit 3b1c5a5307fb5277f395efdcf330c064d79df07d
Committed by
Johannes Berg
1 parent
9bdbf04db0
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
{cfg,nl}80211: mesh power mode primitives and userspace access
Add the nl80211_mesh_power_mode enumeration which holds possible values for the mesh power mode. These modes are unknown, active, light sleep and deep sleep. Add power_mode entry to the mesh config structure to hold the user-configured default mesh power mode. This value will be used for new peer links. Add the dot11MeshAwakeWindowDuration value to the mesh config. The awake window is a duration in TU describing how long the STA will stay awake after transmitting its beacon in PS mode. Add access routines to: - get/set local link-specific power mode (STA) - get remote STA's link-specific power mode (STA) - get remote STA's non-peer power mode (STA) - get/set default mesh power mode (mesh config) - get/set mesh awake window duration (mesh config) All config changes may be done at mesh runtime and take effect immediately. Signed-off-by: Marco Porsch <marco@cozybit.com> Signed-off-by: Ivan Bezyazychnyy <ivan.bezyazychnyy@gmail.com> Signed-off-by: Mike Krinkin <krinkin.m.u@gmail.com> [fix commit message line length, error handling in set station] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Showing 4 changed files with 113 additions and 1 deletions Inline Diff
include/net/cfg80211.h
1 | #ifndef __NET_CFG80211_H | 1 | #ifndef __NET_CFG80211_H |
2 | #define __NET_CFG80211_H | 2 | #define __NET_CFG80211_H |
3 | /* | 3 | /* |
4 | * 802.11 device and configuration interface | 4 | * 802.11 device and configuration interface |
5 | * | 5 | * |
6 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/netdevice.h> | 13 | #include <linux/netdevice.h> |
14 | #include <linux/debugfs.h> | 14 | #include <linux/debugfs.h> |
15 | #include <linux/list.h> | 15 | #include <linux/list.h> |
16 | #include <linux/bug.h> | 16 | #include <linux/bug.h> |
17 | #include <linux/netlink.h> | 17 | #include <linux/netlink.h> |
18 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
19 | #include <linux/nl80211.h> | 19 | #include <linux/nl80211.h> |
20 | #include <linux/if_ether.h> | 20 | #include <linux/if_ether.h> |
21 | #include <linux/ieee80211.h> | 21 | #include <linux/ieee80211.h> |
22 | #include <net/regulatory.h> | 22 | #include <net/regulatory.h> |
23 | 23 | ||
24 | /** | 24 | /** |
25 | * DOC: Introduction | 25 | * DOC: Introduction |
26 | * | 26 | * |
27 | * cfg80211 is the configuration API for 802.11 devices in Linux. It bridges | 27 | * cfg80211 is the configuration API for 802.11 devices in Linux. It bridges |
28 | * userspace and drivers, and offers some utility functionality associated | 28 | * userspace and drivers, and offers some utility functionality associated |
29 | * with 802.11. cfg80211 must, directly or indirectly via mac80211, be used | 29 | * with 802.11. cfg80211 must, directly or indirectly via mac80211, be used |
30 | * by all modern wireless drivers in Linux, so that they offer a consistent | 30 | * by all modern wireless drivers in Linux, so that they offer a consistent |
31 | * API through nl80211. For backward compatibility, cfg80211 also offers | 31 | * API through nl80211. For backward compatibility, cfg80211 also offers |
32 | * wireless extensions to userspace, but hides them from drivers completely. | 32 | * wireless extensions to userspace, but hides them from drivers completely. |
33 | * | 33 | * |
34 | * Additionally, cfg80211 contains code to help enforce regulatory spectrum | 34 | * Additionally, cfg80211 contains code to help enforce regulatory spectrum |
35 | * use restrictions. | 35 | * use restrictions. |
36 | */ | 36 | */ |
37 | 37 | ||
38 | 38 | ||
39 | /** | 39 | /** |
40 | * DOC: Device registration | 40 | * DOC: Device registration |
41 | * | 41 | * |
42 | * In order for a driver to use cfg80211, it must register the hardware device | 42 | * In order for a driver to use cfg80211, it must register the hardware device |
43 | * with cfg80211. This happens through a number of hardware capability structs | 43 | * with cfg80211. This happens through a number of hardware capability structs |
44 | * described below. | 44 | * described below. |
45 | * | 45 | * |
46 | * The fundamental structure for each device is the 'wiphy', of which each | 46 | * The fundamental structure for each device is the 'wiphy', of which each |
47 | * instance describes a physical wireless device connected to the system. Each | 47 | * instance describes a physical wireless device connected to the system. Each |
48 | * such wiphy can have zero, one, or many virtual interfaces associated with | 48 | * such wiphy can have zero, one, or many virtual interfaces associated with |
49 | * it, which need to be identified as such by pointing the network interface's | 49 | * it, which need to be identified as such by pointing the network interface's |
50 | * @ieee80211_ptr pointer to a &struct wireless_dev which further describes | 50 | * @ieee80211_ptr pointer to a &struct wireless_dev which further describes |
51 | * the wireless part of the interface, normally this struct is embedded in the | 51 | * the wireless part of the interface, normally this struct is embedded in the |
52 | * network interface's private data area. Drivers can optionally allow creating | 52 | * network interface's private data area. Drivers can optionally allow creating |
53 | * or destroying virtual interfaces on the fly, but without at least one or the | 53 | * or destroying virtual interfaces on the fly, but without at least one or the |
54 | * ability to create some the wireless device isn't useful. | 54 | * ability to create some the wireless device isn't useful. |
55 | * | 55 | * |
56 | * Each wiphy structure contains device capability information, and also has | 56 | * Each wiphy structure contains device capability information, and also has |
57 | * a pointer to the various operations the driver offers. The definitions and | 57 | * a pointer to the various operations the driver offers. The definitions and |
58 | * structures here describe these capabilities in detail. | 58 | * structures here describe these capabilities in detail. |
59 | */ | 59 | */ |
60 | 60 | ||
61 | struct wiphy; | 61 | struct wiphy; |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * wireless hardware capability structures | 64 | * wireless hardware capability structures |
65 | */ | 65 | */ |
66 | 66 | ||
67 | /** | 67 | /** |
68 | * enum ieee80211_band - supported frequency bands | 68 | * enum ieee80211_band - supported frequency bands |
69 | * | 69 | * |
70 | * The bands are assigned this way because the supported | 70 | * The bands are assigned this way because the supported |
71 | * bitrates differ in these bands. | 71 | * bitrates differ in these bands. |
72 | * | 72 | * |
73 | * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band | 73 | * @IEEE80211_BAND_2GHZ: 2.4GHz ISM band |
74 | * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) | 74 | * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) |
75 | * @IEEE80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) | 75 | * @IEEE80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) |
76 | * @IEEE80211_NUM_BANDS: number of defined bands | 76 | * @IEEE80211_NUM_BANDS: number of defined bands |
77 | */ | 77 | */ |
78 | enum ieee80211_band { | 78 | enum ieee80211_band { |
79 | IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ, | 79 | IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ, |
80 | IEEE80211_BAND_5GHZ = NL80211_BAND_5GHZ, | 80 | IEEE80211_BAND_5GHZ = NL80211_BAND_5GHZ, |
81 | IEEE80211_BAND_60GHZ = NL80211_BAND_60GHZ, | 81 | IEEE80211_BAND_60GHZ = NL80211_BAND_60GHZ, |
82 | 82 | ||
83 | /* keep last */ | 83 | /* keep last */ |
84 | IEEE80211_NUM_BANDS | 84 | IEEE80211_NUM_BANDS |
85 | }; | 85 | }; |
86 | 86 | ||
87 | /** | 87 | /** |
88 | * enum ieee80211_channel_flags - channel flags | 88 | * enum ieee80211_channel_flags - channel flags |
89 | * | 89 | * |
90 | * Channel flags set by the regulatory control code. | 90 | * Channel flags set by the regulatory control code. |
91 | * | 91 | * |
92 | * @IEEE80211_CHAN_DISABLED: This channel is disabled. | 92 | * @IEEE80211_CHAN_DISABLED: This channel is disabled. |
93 | * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted | 93 | * @IEEE80211_CHAN_PASSIVE_SCAN: Only passive scanning is permitted |
94 | * on this channel. | 94 | * on this channel. |
95 | * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. | 95 | * @IEEE80211_CHAN_NO_IBSS: IBSS is not allowed on this channel. |
96 | * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. | 96 | * @IEEE80211_CHAN_RADAR: Radar detection is required on this channel. |
97 | * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel | 97 | * @IEEE80211_CHAN_NO_HT40PLUS: extension channel above this channel |
98 | * is not permitted. | 98 | * is not permitted. |
99 | * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel | 99 | * @IEEE80211_CHAN_NO_HT40MINUS: extension channel below this channel |
100 | * is not permitted. | 100 | * is not permitted. |
101 | * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel. | 101 | * @IEEE80211_CHAN_NO_OFDM: OFDM is not allowed on this channel. |
102 | */ | 102 | */ |
103 | enum ieee80211_channel_flags { | 103 | enum ieee80211_channel_flags { |
104 | IEEE80211_CHAN_DISABLED = 1<<0, | 104 | IEEE80211_CHAN_DISABLED = 1<<0, |
105 | IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, | 105 | IEEE80211_CHAN_PASSIVE_SCAN = 1<<1, |
106 | IEEE80211_CHAN_NO_IBSS = 1<<2, | 106 | IEEE80211_CHAN_NO_IBSS = 1<<2, |
107 | IEEE80211_CHAN_RADAR = 1<<3, | 107 | IEEE80211_CHAN_RADAR = 1<<3, |
108 | IEEE80211_CHAN_NO_HT40PLUS = 1<<4, | 108 | IEEE80211_CHAN_NO_HT40PLUS = 1<<4, |
109 | IEEE80211_CHAN_NO_HT40MINUS = 1<<5, | 109 | IEEE80211_CHAN_NO_HT40MINUS = 1<<5, |
110 | IEEE80211_CHAN_NO_OFDM = 1<<6, | 110 | IEEE80211_CHAN_NO_OFDM = 1<<6, |
111 | }; | 111 | }; |
112 | 112 | ||
113 | #define IEEE80211_CHAN_NO_HT40 \ | 113 | #define IEEE80211_CHAN_NO_HT40 \ |
114 | (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) | 114 | (IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS) |
115 | 115 | ||
116 | /** | 116 | /** |
117 | * struct ieee80211_channel - channel definition | 117 | * struct ieee80211_channel - channel definition |
118 | * | 118 | * |
119 | * This structure describes a single channel for use | 119 | * This structure describes a single channel for use |
120 | * with cfg80211. | 120 | * with cfg80211. |
121 | * | 121 | * |
122 | * @center_freq: center frequency in MHz | 122 | * @center_freq: center frequency in MHz |
123 | * @hw_value: hardware-specific value for the channel | 123 | * @hw_value: hardware-specific value for the channel |
124 | * @flags: channel flags from &enum ieee80211_channel_flags. | 124 | * @flags: channel flags from &enum ieee80211_channel_flags. |
125 | * @orig_flags: channel flags at registration time, used by regulatory | 125 | * @orig_flags: channel flags at registration time, used by regulatory |
126 | * code to support devices with additional restrictions | 126 | * code to support devices with additional restrictions |
127 | * @band: band this channel belongs to. | 127 | * @band: band this channel belongs to. |
128 | * @max_antenna_gain: maximum antenna gain in dBi | 128 | * @max_antenna_gain: maximum antenna gain in dBi |
129 | * @max_power: maximum transmission power (in dBm) | 129 | * @max_power: maximum transmission power (in dBm) |
130 | * @max_reg_power: maximum regulatory transmission power (in dBm) | 130 | * @max_reg_power: maximum regulatory transmission power (in dBm) |
131 | * @beacon_found: helper to regulatory code to indicate when a beacon | 131 | * @beacon_found: helper to regulatory code to indicate when a beacon |
132 | * has been found on this channel. Use regulatory_hint_found_beacon() | 132 | * has been found on this channel. Use regulatory_hint_found_beacon() |
133 | * to enable this, this is useful only on 5 GHz band. | 133 | * to enable this, this is useful only on 5 GHz band. |
134 | * @orig_mag: internal use | 134 | * @orig_mag: internal use |
135 | * @orig_mpwr: internal use | 135 | * @orig_mpwr: internal use |
136 | */ | 136 | */ |
137 | struct ieee80211_channel { | 137 | struct ieee80211_channel { |
138 | enum ieee80211_band band; | 138 | enum ieee80211_band band; |
139 | u16 center_freq; | 139 | u16 center_freq; |
140 | u16 hw_value; | 140 | u16 hw_value; |
141 | u32 flags; | 141 | u32 flags; |
142 | int max_antenna_gain; | 142 | int max_antenna_gain; |
143 | int max_power; | 143 | int max_power; |
144 | int max_reg_power; | 144 | int max_reg_power; |
145 | bool beacon_found; | 145 | bool beacon_found; |
146 | u32 orig_flags; | 146 | u32 orig_flags; |
147 | int orig_mag, orig_mpwr; | 147 | int orig_mag, orig_mpwr; |
148 | }; | 148 | }; |
149 | 149 | ||
150 | /** | 150 | /** |
151 | * enum ieee80211_rate_flags - rate flags | 151 | * enum ieee80211_rate_flags - rate flags |
152 | * | 152 | * |
153 | * Hardware/specification flags for rates. These are structured | 153 | * Hardware/specification flags for rates. These are structured |
154 | * in a way that allows using the same bitrate structure for | 154 | * in a way that allows using the same bitrate structure for |
155 | * different bands/PHY modes. | 155 | * different bands/PHY modes. |
156 | * | 156 | * |
157 | * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short | 157 | * @IEEE80211_RATE_SHORT_PREAMBLE: Hardware can send with short |
158 | * preamble on this bitrate; only relevant in 2.4GHz band and | 158 | * preamble on this bitrate; only relevant in 2.4GHz band and |
159 | * with CCK rates. | 159 | * with CCK rates. |
160 | * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate | 160 | * @IEEE80211_RATE_MANDATORY_A: This bitrate is a mandatory rate |
161 | * when used with 802.11a (on the 5 GHz band); filled by the | 161 | * when used with 802.11a (on the 5 GHz band); filled by the |
162 | * core code when registering the wiphy. | 162 | * core code when registering the wiphy. |
163 | * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate | 163 | * @IEEE80211_RATE_MANDATORY_B: This bitrate is a mandatory rate |
164 | * when used with 802.11b (on the 2.4 GHz band); filled by the | 164 | * when used with 802.11b (on the 2.4 GHz band); filled by the |
165 | * core code when registering the wiphy. | 165 | * core code when registering the wiphy. |
166 | * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate | 166 | * @IEEE80211_RATE_MANDATORY_G: This bitrate is a mandatory rate |
167 | * when used with 802.11g (on the 2.4 GHz band); filled by the | 167 | * when used with 802.11g (on the 2.4 GHz band); filled by the |
168 | * core code when registering the wiphy. | 168 | * core code when registering the wiphy. |
169 | * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. | 169 | * @IEEE80211_RATE_ERP_G: This is an ERP rate in 802.11g mode. |
170 | */ | 170 | */ |
171 | enum ieee80211_rate_flags { | 171 | enum ieee80211_rate_flags { |
172 | IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, | 172 | IEEE80211_RATE_SHORT_PREAMBLE = 1<<0, |
173 | IEEE80211_RATE_MANDATORY_A = 1<<1, | 173 | IEEE80211_RATE_MANDATORY_A = 1<<1, |
174 | IEEE80211_RATE_MANDATORY_B = 1<<2, | 174 | IEEE80211_RATE_MANDATORY_B = 1<<2, |
175 | IEEE80211_RATE_MANDATORY_G = 1<<3, | 175 | IEEE80211_RATE_MANDATORY_G = 1<<3, |
176 | IEEE80211_RATE_ERP_G = 1<<4, | 176 | IEEE80211_RATE_ERP_G = 1<<4, |
177 | }; | 177 | }; |
178 | 178 | ||
179 | /** | 179 | /** |
180 | * struct ieee80211_rate - bitrate definition | 180 | * struct ieee80211_rate - bitrate definition |
181 | * | 181 | * |
182 | * This structure describes a bitrate that an 802.11 PHY can | 182 | * This structure describes a bitrate that an 802.11 PHY can |
183 | * operate with. The two values @hw_value and @hw_value_short | 183 | * operate with. The two values @hw_value and @hw_value_short |
184 | * are only for driver use when pointers to this structure are | 184 | * are only for driver use when pointers to this structure are |
185 | * passed around. | 185 | * passed around. |
186 | * | 186 | * |
187 | * @flags: rate-specific flags | 187 | * @flags: rate-specific flags |
188 | * @bitrate: bitrate in units of 100 Kbps | 188 | * @bitrate: bitrate in units of 100 Kbps |
189 | * @hw_value: driver/hardware value for this rate | 189 | * @hw_value: driver/hardware value for this rate |
190 | * @hw_value_short: driver/hardware value for this rate when | 190 | * @hw_value_short: driver/hardware value for this rate when |
191 | * short preamble is used | 191 | * short preamble is used |
192 | */ | 192 | */ |
193 | struct ieee80211_rate { | 193 | struct ieee80211_rate { |
194 | u32 flags; | 194 | u32 flags; |
195 | u16 bitrate; | 195 | u16 bitrate; |
196 | u16 hw_value, hw_value_short; | 196 | u16 hw_value, hw_value_short; |
197 | }; | 197 | }; |
198 | 198 | ||
199 | /** | 199 | /** |
200 | * struct ieee80211_sta_ht_cap - STA's HT capabilities | 200 | * struct ieee80211_sta_ht_cap - STA's HT capabilities |
201 | * | 201 | * |
202 | * This structure describes most essential parameters needed | 202 | * This structure describes most essential parameters needed |
203 | * to describe 802.11n HT capabilities for an STA. | 203 | * to describe 802.11n HT capabilities for an STA. |
204 | * | 204 | * |
205 | * @ht_supported: is HT supported by the STA | 205 | * @ht_supported: is HT supported by the STA |
206 | * @cap: HT capabilities map as described in 802.11n spec | 206 | * @cap: HT capabilities map as described in 802.11n spec |
207 | * @ampdu_factor: Maximum A-MPDU length factor | 207 | * @ampdu_factor: Maximum A-MPDU length factor |
208 | * @ampdu_density: Minimum A-MPDU spacing | 208 | * @ampdu_density: Minimum A-MPDU spacing |
209 | * @mcs: Supported MCS rates | 209 | * @mcs: Supported MCS rates |
210 | */ | 210 | */ |
211 | struct ieee80211_sta_ht_cap { | 211 | struct ieee80211_sta_ht_cap { |
212 | u16 cap; /* use IEEE80211_HT_CAP_ */ | 212 | u16 cap; /* use IEEE80211_HT_CAP_ */ |
213 | bool ht_supported; | 213 | bool ht_supported; |
214 | u8 ampdu_factor; | 214 | u8 ampdu_factor; |
215 | u8 ampdu_density; | 215 | u8 ampdu_density; |
216 | struct ieee80211_mcs_info mcs; | 216 | struct ieee80211_mcs_info mcs; |
217 | }; | 217 | }; |
218 | 218 | ||
219 | /** | 219 | /** |
220 | * struct ieee80211_sta_vht_cap - STA's VHT capabilities | 220 | * struct ieee80211_sta_vht_cap - STA's VHT capabilities |
221 | * | 221 | * |
222 | * This structure describes most essential parameters needed | 222 | * This structure describes most essential parameters needed |
223 | * to describe 802.11ac VHT capabilities for an STA. | 223 | * to describe 802.11ac VHT capabilities for an STA. |
224 | * | 224 | * |
225 | * @vht_supported: is VHT supported by the STA | 225 | * @vht_supported: is VHT supported by the STA |
226 | * @cap: VHT capabilities map as described in 802.11ac spec | 226 | * @cap: VHT capabilities map as described in 802.11ac spec |
227 | * @vht_mcs: Supported VHT MCS rates | 227 | * @vht_mcs: Supported VHT MCS rates |
228 | */ | 228 | */ |
229 | struct ieee80211_sta_vht_cap { | 229 | struct ieee80211_sta_vht_cap { |
230 | bool vht_supported; | 230 | bool vht_supported; |
231 | u32 cap; /* use IEEE80211_VHT_CAP_ */ | 231 | u32 cap; /* use IEEE80211_VHT_CAP_ */ |
232 | struct ieee80211_vht_mcs_info vht_mcs; | 232 | struct ieee80211_vht_mcs_info vht_mcs; |
233 | }; | 233 | }; |
234 | 234 | ||
235 | /** | 235 | /** |
236 | * struct ieee80211_supported_band - frequency band definition | 236 | * struct ieee80211_supported_band - frequency band definition |
237 | * | 237 | * |
238 | * This structure describes a frequency band a wiphy | 238 | * This structure describes a frequency band a wiphy |
239 | * is able to operate in. | 239 | * is able to operate in. |
240 | * | 240 | * |
241 | * @channels: Array of channels the hardware can operate in | 241 | * @channels: Array of channels the hardware can operate in |
242 | * in this band. | 242 | * in this band. |
243 | * @band: the band this structure represents | 243 | * @band: the band this structure represents |
244 | * @n_channels: Number of channels in @channels | 244 | * @n_channels: Number of channels in @channels |
245 | * @bitrates: Array of bitrates the hardware can operate with | 245 | * @bitrates: Array of bitrates the hardware can operate with |
246 | * in this band. Must be sorted to give a valid "supported | 246 | * in this band. Must be sorted to give a valid "supported |
247 | * rates" IE, i.e. CCK rates first, then OFDM. | 247 | * rates" IE, i.e. CCK rates first, then OFDM. |
248 | * @n_bitrates: Number of bitrates in @bitrates | 248 | * @n_bitrates: Number of bitrates in @bitrates |
249 | * @ht_cap: HT capabilities in this band | 249 | * @ht_cap: HT capabilities in this band |
250 | * @vht_cap: VHT capabilities in this band | 250 | * @vht_cap: VHT capabilities in this band |
251 | */ | 251 | */ |
252 | struct ieee80211_supported_band { | 252 | struct ieee80211_supported_band { |
253 | struct ieee80211_channel *channels; | 253 | struct ieee80211_channel *channels; |
254 | struct ieee80211_rate *bitrates; | 254 | struct ieee80211_rate *bitrates; |
255 | enum ieee80211_band band; | 255 | enum ieee80211_band band; |
256 | int n_channels; | 256 | int n_channels; |
257 | int n_bitrates; | 257 | int n_bitrates; |
258 | struct ieee80211_sta_ht_cap ht_cap; | 258 | struct ieee80211_sta_ht_cap ht_cap; |
259 | struct ieee80211_sta_vht_cap vht_cap; | 259 | struct ieee80211_sta_vht_cap vht_cap; |
260 | }; | 260 | }; |
261 | 261 | ||
262 | /* | 262 | /* |
263 | * Wireless hardware/device configuration structures and methods | 263 | * Wireless hardware/device configuration structures and methods |
264 | */ | 264 | */ |
265 | 265 | ||
266 | /** | 266 | /** |
267 | * DOC: Actions and configuration | 267 | * DOC: Actions and configuration |
268 | * | 268 | * |
269 | * Each wireless device and each virtual interface offer a set of configuration | 269 | * Each wireless device and each virtual interface offer a set of configuration |
270 | * operations and other actions that are invoked by userspace. Each of these | 270 | * operations and other actions that are invoked by userspace. Each of these |
271 | * actions is described in the operations structure, and the parameters these | 271 | * actions is described in the operations structure, and the parameters these |
272 | * operations use are described separately. | 272 | * operations use are described separately. |
273 | * | 273 | * |
274 | * Additionally, some operations are asynchronous and expect to get status | 274 | * Additionally, some operations are asynchronous and expect to get status |
275 | * information via some functions that drivers need to call. | 275 | * information via some functions that drivers need to call. |
276 | * | 276 | * |
277 | * Scanning and BSS list handling with its associated functionality is described | 277 | * Scanning and BSS list handling with its associated functionality is described |
278 | * in a separate chapter. | 278 | * in a separate chapter. |
279 | */ | 279 | */ |
280 | 280 | ||
281 | /** | 281 | /** |
282 | * struct vif_params - describes virtual interface parameters | 282 | * struct vif_params - describes virtual interface parameters |
283 | * @use_4addr: use 4-address frames | 283 | * @use_4addr: use 4-address frames |
284 | */ | 284 | */ |
285 | struct vif_params { | 285 | struct vif_params { |
286 | int use_4addr; | 286 | int use_4addr; |
287 | }; | 287 | }; |
288 | 288 | ||
289 | /** | 289 | /** |
290 | * struct key_params - key information | 290 | * struct key_params - key information |
291 | * | 291 | * |
292 | * Information about a key | 292 | * Information about a key |
293 | * | 293 | * |
294 | * @key: key material | 294 | * @key: key material |
295 | * @key_len: length of key material | 295 | * @key_len: length of key material |
296 | * @cipher: cipher suite selector | 296 | * @cipher: cipher suite selector |
297 | * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used | 297 | * @seq: sequence counter (IV/PN) for TKIP and CCMP keys, only used |
298 | * with the get_key() callback, must be in little endian, | 298 | * with the get_key() callback, must be in little endian, |
299 | * length given by @seq_len. | 299 | * length given by @seq_len. |
300 | * @seq_len: length of @seq. | 300 | * @seq_len: length of @seq. |
301 | */ | 301 | */ |
302 | struct key_params { | 302 | struct key_params { |
303 | u8 *key; | 303 | u8 *key; |
304 | u8 *seq; | 304 | u8 *seq; |
305 | int key_len; | 305 | int key_len; |
306 | int seq_len; | 306 | int seq_len; |
307 | u32 cipher; | 307 | u32 cipher; |
308 | }; | 308 | }; |
309 | 309 | ||
310 | /** | 310 | /** |
311 | * struct cfg80211_chan_def - channel definition | 311 | * struct cfg80211_chan_def - channel definition |
312 | * @chan: the (control) channel | 312 | * @chan: the (control) channel |
313 | * @width: channel width | 313 | * @width: channel width |
314 | * @center_freq1: center frequency of first segment | 314 | * @center_freq1: center frequency of first segment |
315 | * @center_freq2: center frequency of second segment | 315 | * @center_freq2: center frequency of second segment |
316 | * (only with 80+80 MHz) | 316 | * (only with 80+80 MHz) |
317 | */ | 317 | */ |
318 | struct cfg80211_chan_def { | 318 | struct cfg80211_chan_def { |
319 | struct ieee80211_channel *chan; | 319 | struct ieee80211_channel *chan; |
320 | enum nl80211_chan_width width; | 320 | enum nl80211_chan_width width; |
321 | u32 center_freq1; | 321 | u32 center_freq1; |
322 | u32 center_freq2; | 322 | u32 center_freq2; |
323 | }; | 323 | }; |
324 | 324 | ||
325 | /** | 325 | /** |
326 | * cfg80211_get_chandef_type - return old channel type from chandef | 326 | * cfg80211_get_chandef_type - return old channel type from chandef |
327 | * @chandef: the channel definition | 327 | * @chandef: the channel definition |
328 | * | 328 | * |
329 | * Return: The old channel type (NOHT, HT20, HT40+/-) from a given | 329 | * Return: The old channel type (NOHT, HT20, HT40+/-) from a given |
330 | * chandef, which must have a bandwidth allowing this conversion. | 330 | * chandef, which must have a bandwidth allowing this conversion. |
331 | */ | 331 | */ |
332 | static inline enum nl80211_channel_type | 332 | static inline enum nl80211_channel_type |
333 | cfg80211_get_chandef_type(const struct cfg80211_chan_def *chandef) | 333 | cfg80211_get_chandef_type(const struct cfg80211_chan_def *chandef) |
334 | { | 334 | { |
335 | switch (chandef->width) { | 335 | switch (chandef->width) { |
336 | case NL80211_CHAN_WIDTH_20_NOHT: | 336 | case NL80211_CHAN_WIDTH_20_NOHT: |
337 | return NL80211_CHAN_NO_HT; | 337 | return NL80211_CHAN_NO_HT; |
338 | case NL80211_CHAN_WIDTH_20: | 338 | case NL80211_CHAN_WIDTH_20: |
339 | return NL80211_CHAN_HT20; | 339 | return NL80211_CHAN_HT20; |
340 | case NL80211_CHAN_WIDTH_40: | 340 | case NL80211_CHAN_WIDTH_40: |
341 | if (chandef->center_freq1 > chandef->chan->center_freq) | 341 | if (chandef->center_freq1 > chandef->chan->center_freq) |
342 | return NL80211_CHAN_HT40PLUS; | 342 | return NL80211_CHAN_HT40PLUS; |
343 | return NL80211_CHAN_HT40MINUS; | 343 | return NL80211_CHAN_HT40MINUS; |
344 | default: | 344 | default: |
345 | WARN_ON(1); | 345 | WARN_ON(1); |
346 | return NL80211_CHAN_NO_HT; | 346 | return NL80211_CHAN_NO_HT; |
347 | } | 347 | } |
348 | } | 348 | } |
349 | 349 | ||
350 | /** | 350 | /** |
351 | * cfg80211_chandef_create - create channel definition using channel type | 351 | * cfg80211_chandef_create - create channel definition using channel type |
352 | * @chandef: the channel definition struct to fill | 352 | * @chandef: the channel definition struct to fill |
353 | * @channel: the control channel | 353 | * @channel: the control channel |
354 | * @chantype: the channel type | 354 | * @chantype: the channel type |
355 | * | 355 | * |
356 | * Given a channel type, create a channel definition. | 356 | * Given a channel type, create a channel definition. |
357 | */ | 357 | */ |
358 | void cfg80211_chandef_create(struct cfg80211_chan_def *chandef, | 358 | void cfg80211_chandef_create(struct cfg80211_chan_def *chandef, |
359 | struct ieee80211_channel *channel, | 359 | struct ieee80211_channel *channel, |
360 | enum nl80211_channel_type chantype); | 360 | enum nl80211_channel_type chantype); |
361 | 361 | ||
362 | /** | 362 | /** |
363 | * cfg80211_chandef_identical - check if two channel definitions are identical | 363 | * cfg80211_chandef_identical - check if two channel definitions are identical |
364 | * @chandef1: first channel definition | 364 | * @chandef1: first channel definition |
365 | * @chandef2: second channel definition | 365 | * @chandef2: second channel definition |
366 | * | 366 | * |
367 | * Return: %true if the channels defined by the channel definitions are | 367 | * Return: %true if the channels defined by the channel definitions are |
368 | * identical, %false otherwise. | 368 | * identical, %false otherwise. |
369 | */ | 369 | */ |
370 | static inline bool | 370 | static inline bool |
371 | cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1, | 371 | cfg80211_chandef_identical(const struct cfg80211_chan_def *chandef1, |
372 | const struct cfg80211_chan_def *chandef2) | 372 | const struct cfg80211_chan_def *chandef2) |
373 | { | 373 | { |
374 | return (chandef1->chan == chandef2->chan && | 374 | return (chandef1->chan == chandef2->chan && |
375 | chandef1->width == chandef2->width && | 375 | chandef1->width == chandef2->width && |
376 | chandef1->center_freq1 == chandef2->center_freq1 && | 376 | chandef1->center_freq1 == chandef2->center_freq1 && |
377 | chandef1->center_freq2 == chandef2->center_freq2); | 377 | chandef1->center_freq2 == chandef2->center_freq2); |
378 | } | 378 | } |
379 | 379 | ||
380 | /** | 380 | /** |
381 | * cfg80211_chandef_compatible - check if two channel definitions are compatible | 381 | * cfg80211_chandef_compatible - check if two channel definitions are compatible |
382 | * @chandef1: first channel definition | 382 | * @chandef1: first channel definition |
383 | * @chandef2: second channel definition | 383 | * @chandef2: second channel definition |
384 | * | 384 | * |
385 | * Return: %NULL if the given channel definitions are incompatible, | 385 | * Return: %NULL if the given channel definitions are incompatible, |
386 | * chandef1 or chandef2 otherwise. | 386 | * chandef1 or chandef2 otherwise. |
387 | */ | 387 | */ |
388 | const struct cfg80211_chan_def * | 388 | const struct cfg80211_chan_def * |
389 | cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1, | 389 | cfg80211_chandef_compatible(const struct cfg80211_chan_def *chandef1, |
390 | const struct cfg80211_chan_def *chandef2); | 390 | const struct cfg80211_chan_def *chandef2); |
391 | 391 | ||
392 | /** | 392 | /** |
393 | * cfg80211_chandef_valid - check if a channel definition is valid | 393 | * cfg80211_chandef_valid - check if a channel definition is valid |
394 | * @chandef: the channel definition to check | 394 | * @chandef: the channel definition to check |
395 | * Return: %true if the channel definition is valid. %false otherwise. | 395 | * Return: %true if the channel definition is valid. %false otherwise. |
396 | */ | 396 | */ |
397 | bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef); | 397 | bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef); |
398 | 398 | ||
399 | /** | 399 | /** |
400 | * cfg80211_chandef_usable - check if secondary channels can be used | 400 | * cfg80211_chandef_usable - check if secondary channels can be used |
401 | * @wiphy: the wiphy to validate against | 401 | * @wiphy: the wiphy to validate against |
402 | * @chandef: the channel definition to check | 402 | * @chandef: the channel definition to check |
403 | * @prohibited_flags: the regulatory channel flags that must not be set | 403 | * @prohibited_flags: the regulatory channel flags that must not be set |
404 | * Return: %true if secondary channels are usable. %false otherwise. | 404 | * Return: %true if secondary channels are usable. %false otherwise. |
405 | */ | 405 | */ |
406 | bool cfg80211_chandef_usable(struct wiphy *wiphy, | 406 | bool cfg80211_chandef_usable(struct wiphy *wiphy, |
407 | const struct cfg80211_chan_def *chandef, | 407 | const struct cfg80211_chan_def *chandef, |
408 | u32 prohibited_flags); | 408 | u32 prohibited_flags); |
409 | 409 | ||
410 | /** | 410 | /** |
411 | * enum survey_info_flags - survey information flags | 411 | * enum survey_info_flags - survey information flags |
412 | * | 412 | * |
413 | * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in | 413 | * @SURVEY_INFO_NOISE_DBM: noise (in dBm) was filled in |
414 | * @SURVEY_INFO_IN_USE: channel is currently being used | 414 | * @SURVEY_INFO_IN_USE: channel is currently being used |
415 | * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in | 415 | * @SURVEY_INFO_CHANNEL_TIME: channel active time (in ms) was filled in |
416 | * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in | 416 | * @SURVEY_INFO_CHANNEL_TIME_BUSY: channel busy time was filled in |
417 | * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in | 417 | * @SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: extension channel busy time was filled in |
418 | * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in | 418 | * @SURVEY_INFO_CHANNEL_TIME_RX: channel receive time was filled in |
419 | * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in | 419 | * @SURVEY_INFO_CHANNEL_TIME_TX: channel transmit time was filled in |
420 | * | 420 | * |
421 | * Used by the driver to indicate which info in &struct survey_info | 421 | * Used by the driver to indicate which info in &struct survey_info |
422 | * it has filled in during the get_survey(). | 422 | * it has filled in during the get_survey(). |
423 | */ | 423 | */ |
424 | enum survey_info_flags { | 424 | enum survey_info_flags { |
425 | SURVEY_INFO_NOISE_DBM = 1<<0, | 425 | SURVEY_INFO_NOISE_DBM = 1<<0, |
426 | SURVEY_INFO_IN_USE = 1<<1, | 426 | SURVEY_INFO_IN_USE = 1<<1, |
427 | SURVEY_INFO_CHANNEL_TIME = 1<<2, | 427 | SURVEY_INFO_CHANNEL_TIME = 1<<2, |
428 | SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3, | 428 | SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3, |
429 | SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4, | 429 | SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4, |
430 | SURVEY_INFO_CHANNEL_TIME_RX = 1<<5, | 430 | SURVEY_INFO_CHANNEL_TIME_RX = 1<<5, |
431 | SURVEY_INFO_CHANNEL_TIME_TX = 1<<6, | 431 | SURVEY_INFO_CHANNEL_TIME_TX = 1<<6, |
432 | }; | 432 | }; |
433 | 433 | ||
434 | /** | 434 | /** |
435 | * struct survey_info - channel survey response | 435 | * struct survey_info - channel survey response |
436 | * | 436 | * |
437 | * @channel: the channel this survey record reports, mandatory | 437 | * @channel: the channel this survey record reports, mandatory |
438 | * @filled: bitflag of flags from &enum survey_info_flags | 438 | * @filled: bitflag of flags from &enum survey_info_flags |
439 | * @noise: channel noise in dBm. This and all following fields are | 439 | * @noise: channel noise in dBm. This and all following fields are |
440 | * optional | 440 | * optional |
441 | * @channel_time: amount of time in ms the radio spent on the channel | 441 | * @channel_time: amount of time in ms the radio spent on the channel |
442 | * @channel_time_busy: amount of time the primary channel was sensed busy | 442 | * @channel_time_busy: amount of time the primary channel was sensed busy |
443 | * @channel_time_ext_busy: amount of time the extension channel was sensed busy | 443 | * @channel_time_ext_busy: amount of time the extension channel was sensed busy |
444 | * @channel_time_rx: amount of time the radio spent receiving data | 444 | * @channel_time_rx: amount of time the radio spent receiving data |
445 | * @channel_time_tx: amount of time the radio spent transmitting data | 445 | * @channel_time_tx: amount of time the radio spent transmitting data |
446 | * | 446 | * |
447 | * Used by dump_survey() to report back per-channel survey information. | 447 | * Used by dump_survey() to report back per-channel survey information. |
448 | * | 448 | * |
449 | * This structure can later be expanded with things like | 449 | * This structure can later be expanded with things like |
450 | * channel duty cycle etc. | 450 | * channel duty cycle etc. |
451 | */ | 451 | */ |
452 | struct survey_info { | 452 | struct survey_info { |
453 | struct ieee80211_channel *channel; | 453 | struct ieee80211_channel *channel; |
454 | u64 channel_time; | 454 | u64 channel_time; |
455 | u64 channel_time_busy; | 455 | u64 channel_time_busy; |
456 | u64 channel_time_ext_busy; | 456 | u64 channel_time_ext_busy; |
457 | u64 channel_time_rx; | 457 | u64 channel_time_rx; |
458 | u64 channel_time_tx; | 458 | u64 channel_time_tx; |
459 | u32 filled; | 459 | u32 filled; |
460 | s8 noise; | 460 | s8 noise; |
461 | }; | 461 | }; |
462 | 462 | ||
463 | /** | 463 | /** |
464 | * struct cfg80211_crypto_settings - Crypto settings | 464 | * struct cfg80211_crypto_settings - Crypto settings |
465 | * @wpa_versions: indicates which, if any, WPA versions are enabled | 465 | * @wpa_versions: indicates which, if any, WPA versions are enabled |
466 | * (from enum nl80211_wpa_versions) | 466 | * (from enum nl80211_wpa_versions) |
467 | * @cipher_group: group key cipher suite (or 0 if unset) | 467 | * @cipher_group: group key cipher suite (or 0 if unset) |
468 | * @n_ciphers_pairwise: number of AP supported unicast ciphers | 468 | * @n_ciphers_pairwise: number of AP supported unicast ciphers |
469 | * @ciphers_pairwise: unicast key cipher suites | 469 | * @ciphers_pairwise: unicast key cipher suites |
470 | * @n_akm_suites: number of AKM suites | 470 | * @n_akm_suites: number of AKM suites |
471 | * @akm_suites: AKM suites | 471 | * @akm_suites: AKM suites |
472 | * @control_port: Whether user space controls IEEE 802.1X port, i.e., | 472 | * @control_port: Whether user space controls IEEE 802.1X port, i.e., |
473 | * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is | 473 | * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is |
474 | * required to assume that the port is unauthorized until authorized by | 474 | * required to assume that the port is unauthorized until authorized by |
475 | * user space. Otherwise, port is marked authorized by default. | 475 | * user space. Otherwise, port is marked authorized by default. |
476 | * @control_port_ethertype: the control port protocol that should be | 476 | * @control_port_ethertype: the control port protocol that should be |
477 | * allowed through even on unauthorized ports | 477 | * allowed through even on unauthorized ports |
478 | * @control_port_no_encrypt: TRUE to prevent encryption of control port | 478 | * @control_port_no_encrypt: TRUE to prevent encryption of control port |
479 | * protocol frames. | 479 | * protocol frames. |
480 | */ | 480 | */ |
481 | struct cfg80211_crypto_settings { | 481 | struct cfg80211_crypto_settings { |
482 | u32 wpa_versions; | 482 | u32 wpa_versions; |
483 | u32 cipher_group; | 483 | u32 cipher_group; |
484 | int n_ciphers_pairwise; | 484 | int n_ciphers_pairwise; |
485 | u32 ciphers_pairwise[NL80211_MAX_NR_CIPHER_SUITES]; | 485 | u32 ciphers_pairwise[NL80211_MAX_NR_CIPHER_SUITES]; |
486 | int n_akm_suites; | 486 | int n_akm_suites; |
487 | u32 akm_suites[NL80211_MAX_NR_AKM_SUITES]; | 487 | u32 akm_suites[NL80211_MAX_NR_AKM_SUITES]; |
488 | bool control_port; | 488 | bool control_port; |
489 | __be16 control_port_ethertype; | 489 | __be16 control_port_ethertype; |
490 | bool control_port_no_encrypt; | 490 | bool control_port_no_encrypt; |
491 | }; | 491 | }; |
492 | 492 | ||
493 | /** | 493 | /** |
494 | * struct cfg80211_beacon_data - beacon data | 494 | * struct cfg80211_beacon_data - beacon data |
495 | * @head: head portion of beacon (before TIM IE) | 495 | * @head: head portion of beacon (before TIM IE) |
496 | * or %NULL if not changed | 496 | * or %NULL if not changed |
497 | * @tail: tail portion of beacon (after TIM IE) | 497 | * @tail: tail portion of beacon (after TIM IE) |
498 | * or %NULL if not changed | 498 | * or %NULL if not changed |
499 | * @head_len: length of @head | 499 | * @head_len: length of @head |
500 | * @tail_len: length of @tail | 500 | * @tail_len: length of @tail |
501 | * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL | 501 | * @beacon_ies: extra information element(s) to add into Beacon frames or %NULL |
502 | * @beacon_ies_len: length of beacon_ies in octets | 502 | * @beacon_ies_len: length of beacon_ies in octets |
503 | * @proberesp_ies: extra information element(s) to add into Probe Response | 503 | * @proberesp_ies: extra information element(s) to add into Probe Response |
504 | * frames or %NULL | 504 | * frames or %NULL |
505 | * @proberesp_ies_len: length of proberesp_ies in octets | 505 | * @proberesp_ies_len: length of proberesp_ies in octets |
506 | * @assocresp_ies: extra information element(s) to add into (Re)Association | 506 | * @assocresp_ies: extra information element(s) to add into (Re)Association |
507 | * Response frames or %NULL | 507 | * Response frames or %NULL |
508 | * @assocresp_ies_len: length of assocresp_ies in octets | 508 | * @assocresp_ies_len: length of assocresp_ies in octets |
509 | * @probe_resp_len: length of probe response template (@probe_resp) | 509 | * @probe_resp_len: length of probe response template (@probe_resp) |
510 | * @probe_resp: probe response template (AP mode only) | 510 | * @probe_resp: probe response template (AP mode only) |
511 | */ | 511 | */ |
512 | struct cfg80211_beacon_data { | 512 | struct cfg80211_beacon_data { |
513 | const u8 *head, *tail; | 513 | const u8 *head, *tail; |
514 | const u8 *beacon_ies; | 514 | const u8 *beacon_ies; |
515 | const u8 *proberesp_ies; | 515 | const u8 *proberesp_ies; |
516 | const u8 *assocresp_ies; | 516 | const u8 *assocresp_ies; |
517 | const u8 *probe_resp; | 517 | const u8 *probe_resp; |
518 | 518 | ||
519 | size_t head_len, tail_len; | 519 | size_t head_len, tail_len; |
520 | size_t beacon_ies_len; | 520 | size_t beacon_ies_len; |
521 | size_t proberesp_ies_len; | 521 | size_t proberesp_ies_len; |
522 | size_t assocresp_ies_len; | 522 | size_t assocresp_ies_len; |
523 | size_t probe_resp_len; | 523 | size_t probe_resp_len; |
524 | }; | 524 | }; |
525 | 525 | ||
526 | /** | 526 | /** |
527 | * struct cfg80211_ap_settings - AP configuration | 527 | * struct cfg80211_ap_settings - AP configuration |
528 | * | 528 | * |
529 | * Used to configure an AP interface. | 529 | * Used to configure an AP interface. |
530 | * | 530 | * |
531 | * @chandef: defines the channel to use | 531 | * @chandef: defines the channel to use |
532 | * @beacon: beacon data | 532 | * @beacon: beacon data |
533 | * @beacon_interval: beacon interval | 533 | * @beacon_interval: beacon interval |
534 | * @dtim_period: DTIM period | 534 | * @dtim_period: DTIM period |
535 | * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from | 535 | * @ssid: SSID to be used in the BSS (note: may be %NULL if not provided from |
536 | * user space) | 536 | * user space) |
537 | * @ssid_len: length of @ssid | 537 | * @ssid_len: length of @ssid |
538 | * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames | 538 | * @hidden_ssid: whether to hide the SSID in Beacon/Probe Response frames |
539 | * @crypto: crypto settings | 539 | * @crypto: crypto settings |
540 | * @privacy: the BSS uses privacy | 540 | * @privacy: the BSS uses privacy |
541 | * @auth_type: Authentication type (algorithm) | 541 | * @auth_type: Authentication type (algorithm) |
542 | * @inactivity_timeout: time in seconds to determine station's inactivity. | 542 | * @inactivity_timeout: time in seconds to determine station's inactivity. |
543 | * @p2p_ctwindow: P2P CT Window | 543 | * @p2p_ctwindow: P2P CT Window |
544 | * @p2p_opp_ps: P2P opportunistic PS | 544 | * @p2p_opp_ps: P2P opportunistic PS |
545 | */ | 545 | */ |
546 | struct cfg80211_ap_settings { | 546 | struct cfg80211_ap_settings { |
547 | struct cfg80211_chan_def chandef; | 547 | struct cfg80211_chan_def chandef; |
548 | 548 | ||
549 | struct cfg80211_beacon_data beacon; | 549 | struct cfg80211_beacon_data beacon; |
550 | 550 | ||
551 | int beacon_interval, dtim_period; | 551 | int beacon_interval, dtim_period; |
552 | const u8 *ssid; | 552 | const u8 *ssid; |
553 | size_t ssid_len; | 553 | size_t ssid_len; |
554 | enum nl80211_hidden_ssid hidden_ssid; | 554 | enum nl80211_hidden_ssid hidden_ssid; |
555 | struct cfg80211_crypto_settings crypto; | 555 | struct cfg80211_crypto_settings crypto; |
556 | bool privacy; | 556 | bool privacy; |
557 | enum nl80211_auth_type auth_type; | 557 | enum nl80211_auth_type auth_type; |
558 | int inactivity_timeout; | 558 | int inactivity_timeout; |
559 | u8 p2p_ctwindow; | 559 | u8 p2p_ctwindow; |
560 | bool p2p_opp_ps; | 560 | bool p2p_opp_ps; |
561 | }; | 561 | }; |
562 | 562 | ||
563 | /** | 563 | /** |
564 | * enum plink_action - actions to perform in mesh peers | 564 | * enum plink_action - actions to perform in mesh peers |
565 | * | 565 | * |
566 | * @PLINK_ACTION_INVALID: action 0 is reserved | 566 | * @PLINK_ACTION_INVALID: action 0 is reserved |
567 | * @PLINK_ACTION_OPEN: start mesh peer link establishment | 567 | * @PLINK_ACTION_OPEN: start mesh peer link establishment |
568 | * @PLINK_ACTION_BLOCK: block traffic from this mesh peer | 568 | * @PLINK_ACTION_BLOCK: block traffic from this mesh peer |
569 | */ | 569 | */ |
570 | enum plink_actions { | 570 | enum plink_actions { |
571 | PLINK_ACTION_INVALID, | 571 | PLINK_ACTION_INVALID, |
572 | PLINK_ACTION_OPEN, | 572 | PLINK_ACTION_OPEN, |
573 | PLINK_ACTION_BLOCK, | 573 | PLINK_ACTION_BLOCK, |
574 | }; | 574 | }; |
575 | 575 | ||
576 | /** | 576 | /** |
577 | * enum station_parameters_apply_mask - station parameter values to apply | 577 | * enum station_parameters_apply_mask - station parameter values to apply |
578 | * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) | 578 | * @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp) |
579 | * | 579 | * |
580 | * Not all station parameters have in-band "no change" signalling, | 580 | * Not all station parameters have in-band "no change" signalling, |
581 | * for those that don't these flags will are used. | 581 | * for those that don't these flags will are used. |
582 | */ | 582 | */ |
583 | enum station_parameters_apply_mask { | 583 | enum station_parameters_apply_mask { |
584 | STATION_PARAM_APPLY_UAPSD = BIT(0), | 584 | STATION_PARAM_APPLY_UAPSD = BIT(0), |
585 | }; | 585 | }; |
586 | 586 | ||
587 | /** | 587 | /** |
588 | * struct station_parameters - station parameters | 588 | * struct station_parameters - station parameters |
589 | * | 589 | * |
590 | * Used to change and create a new station. | 590 | * Used to change and create a new station. |
591 | * | 591 | * |
592 | * @vlan: vlan interface station should belong to | 592 | * @vlan: vlan interface station should belong to |
593 | * @supported_rates: supported rates in IEEE 802.11 format | 593 | * @supported_rates: supported rates in IEEE 802.11 format |
594 | * (or NULL for no change) | 594 | * (or NULL for no change) |
595 | * @supported_rates_len: number of supported rates | 595 | * @supported_rates_len: number of supported rates |
596 | * @sta_flags_mask: station flags that changed | 596 | * @sta_flags_mask: station flags that changed |
597 | * (bitmask of BIT(NL80211_STA_FLAG_...)) | 597 | * (bitmask of BIT(NL80211_STA_FLAG_...)) |
598 | * @sta_flags_set: station flags values | 598 | * @sta_flags_set: station flags values |
599 | * (bitmask of BIT(NL80211_STA_FLAG_...)) | 599 | * (bitmask of BIT(NL80211_STA_FLAG_...)) |
600 | * @listen_interval: listen interval or -1 for no change | 600 | * @listen_interval: listen interval or -1 for no change |
601 | * @aid: AID or zero for no change | 601 | * @aid: AID or zero for no change |
602 | * @plink_action: plink action to take | 602 | * @plink_action: plink action to take |
603 | * @plink_state: set the peer link state for a station | 603 | * @plink_state: set the peer link state for a station |
604 | * @ht_capa: HT capabilities of station | 604 | * @ht_capa: HT capabilities of station |
605 | * @vht_capa: VHT capabilities of station | 605 | * @vht_capa: VHT capabilities of station |
606 | * @uapsd_queues: bitmap of queues configured for uapsd. same format | 606 | * @uapsd_queues: bitmap of queues configured for uapsd. same format |
607 | * as the AC bitmap in the QoS info field | 607 | * as the AC bitmap in the QoS info field |
608 | * @max_sp: max Service Period. same format as the MAX_SP in the | 608 | * @max_sp: max Service Period. same format as the MAX_SP in the |
609 | * QoS info field (but already shifted down) | 609 | * QoS info field (but already shifted down) |
610 | * @sta_modify_mask: bitmap indicating which parameters changed | 610 | * @sta_modify_mask: bitmap indicating which parameters changed |
611 | * (for those that don't have a natural "no change" value), | 611 | * (for those that don't have a natural "no change" value), |
612 | * see &enum station_parameters_apply_mask | 612 | * see &enum station_parameters_apply_mask |
613 | * @local_pm: local link-specific mesh power save mode (no change when set | ||
614 | * to unknown) | ||
613 | */ | 615 | */ |
614 | struct station_parameters { | 616 | struct station_parameters { |
615 | u8 *supported_rates; | 617 | u8 *supported_rates; |
616 | struct net_device *vlan; | 618 | struct net_device *vlan; |
617 | u32 sta_flags_mask, sta_flags_set; | 619 | u32 sta_flags_mask, sta_flags_set; |
618 | u32 sta_modify_mask; | 620 | u32 sta_modify_mask; |
619 | int listen_interval; | 621 | int listen_interval; |
620 | u16 aid; | 622 | u16 aid; |
621 | u8 supported_rates_len; | 623 | u8 supported_rates_len; |
622 | u8 plink_action; | 624 | u8 plink_action; |
623 | u8 plink_state; | 625 | u8 plink_state; |
624 | struct ieee80211_ht_cap *ht_capa; | 626 | struct ieee80211_ht_cap *ht_capa; |
625 | struct ieee80211_vht_cap *vht_capa; | 627 | struct ieee80211_vht_cap *vht_capa; |
626 | u8 uapsd_queues; | 628 | u8 uapsd_queues; |
627 | u8 max_sp; | 629 | u8 max_sp; |
630 | enum nl80211_mesh_power_mode local_pm; | ||
628 | }; | 631 | }; |
629 | 632 | ||
630 | /** | 633 | /** |
631 | * enum station_info_flags - station information flags | 634 | * enum station_info_flags - station information flags |
632 | * | 635 | * |
633 | * Used by the driver to indicate which info in &struct station_info | 636 | * Used by the driver to indicate which info in &struct station_info |
634 | * it has filled in during get_station() or dump_station(). | 637 | * it has filled in during get_station() or dump_station(). |
635 | * | 638 | * |
636 | * @STATION_INFO_INACTIVE_TIME: @inactive_time filled | 639 | * @STATION_INFO_INACTIVE_TIME: @inactive_time filled |
637 | * @STATION_INFO_RX_BYTES: @rx_bytes filled | 640 | * @STATION_INFO_RX_BYTES: @rx_bytes filled |
638 | * @STATION_INFO_TX_BYTES: @tx_bytes filled | 641 | * @STATION_INFO_TX_BYTES: @tx_bytes filled |
639 | * @STATION_INFO_LLID: @llid filled | 642 | * @STATION_INFO_LLID: @llid filled |
640 | * @STATION_INFO_PLID: @plid filled | 643 | * @STATION_INFO_PLID: @plid filled |
641 | * @STATION_INFO_PLINK_STATE: @plink_state filled | 644 | * @STATION_INFO_PLINK_STATE: @plink_state filled |
642 | * @STATION_INFO_SIGNAL: @signal filled | 645 | * @STATION_INFO_SIGNAL: @signal filled |
643 | * @STATION_INFO_TX_BITRATE: @txrate fields are filled | 646 | * @STATION_INFO_TX_BITRATE: @txrate fields are filled |
644 | * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) | 647 | * (tx_bitrate, tx_bitrate_flags and tx_bitrate_mcs) |
645 | * @STATION_INFO_RX_PACKETS: @rx_packets filled | 648 | * @STATION_INFO_RX_PACKETS: @rx_packets filled |
646 | * @STATION_INFO_TX_PACKETS: @tx_packets filled | 649 | * @STATION_INFO_TX_PACKETS: @tx_packets filled |
647 | * @STATION_INFO_TX_RETRIES: @tx_retries filled | 650 | * @STATION_INFO_TX_RETRIES: @tx_retries filled |
648 | * @STATION_INFO_TX_FAILED: @tx_failed filled | 651 | * @STATION_INFO_TX_FAILED: @tx_failed filled |
649 | * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled | 652 | * @STATION_INFO_RX_DROP_MISC: @rx_dropped_misc filled |
650 | * @STATION_INFO_SIGNAL_AVG: @signal_avg filled | 653 | * @STATION_INFO_SIGNAL_AVG: @signal_avg filled |
651 | * @STATION_INFO_RX_BITRATE: @rxrate fields are filled | 654 | * @STATION_INFO_RX_BITRATE: @rxrate fields are filled |
652 | * @STATION_INFO_BSS_PARAM: @bss_param filled | 655 | * @STATION_INFO_BSS_PARAM: @bss_param filled |
653 | * @STATION_INFO_CONNECTED_TIME: @connected_time filled | 656 | * @STATION_INFO_CONNECTED_TIME: @connected_time filled |
654 | * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled | 657 | * @STATION_INFO_ASSOC_REQ_IES: @assoc_req_ies filled |
655 | * @STATION_INFO_STA_FLAGS: @sta_flags filled | 658 | * @STATION_INFO_STA_FLAGS: @sta_flags filled |
656 | * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled | 659 | * @STATION_INFO_BEACON_LOSS_COUNT: @beacon_loss_count filled |
657 | * @STATION_INFO_T_OFFSET: @t_offset filled | 660 | * @STATION_INFO_T_OFFSET: @t_offset filled |
661 | * @STATION_INFO_LOCAL_PM: @local_pm filled | ||
662 | * @STATION_INFO_PEER_PM: @peer_pm filled | ||
663 | * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled | ||
658 | */ | 664 | */ |
659 | enum station_info_flags { | 665 | enum station_info_flags { |
660 | STATION_INFO_INACTIVE_TIME = 1<<0, | 666 | STATION_INFO_INACTIVE_TIME = 1<<0, |
661 | STATION_INFO_RX_BYTES = 1<<1, | 667 | STATION_INFO_RX_BYTES = 1<<1, |
662 | STATION_INFO_TX_BYTES = 1<<2, | 668 | STATION_INFO_TX_BYTES = 1<<2, |
663 | STATION_INFO_LLID = 1<<3, | 669 | STATION_INFO_LLID = 1<<3, |
664 | STATION_INFO_PLID = 1<<4, | 670 | STATION_INFO_PLID = 1<<4, |
665 | STATION_INFO_PLINK_STATE = 1<<5, | 671 | STATION_INFO_PLINK_STATE = 1<<5, |
666 | STATION_INFO_SIGNAL = 1<<6, | 672 | STATION_INFO_SIGNAL = 1<<6, |
667 | STATION_INFO_TX_BITRATE = 1<<7, | 673 | STATION_INFO_TX_BITRATE = 1<<7, |
668 | STATION_INFO_RX_PACKETS = 1<<8, | 674 | STATION_INFO_RX_PACKETS = 1<<8, |
669 | STATION_INFO_TX_PACKETS = 1<<9, | 675 | STATION_INFO_TX_PACKETS = 1<<9, |
670 | STATION_INFO_TX_RETRIES = 1<<10, | 676 | STATION_INFO_TX_RETRIES = 1<<10, |
671 | STATION_INFO_TX_FAILED = 1<<11, | 677 | STATION_INFO_TX_FAILED = 1<<11, |
672 | STATION_INFO_RX_DROP_MISC = 1<<12, | 678 | STATION_INFO_RX_DROP_MISC = 1<<12, |
673 | STATION_INFO_SIGNAL_AVG = 1<<13, | 679 | STATION_INFO_SIGNAL_AVG = 1<<13, |
674 | STATION_INFO_RX_BITRATE = 1<<14, | 680 | STATION_INFO_RX_BITRATE = 1<<14, |
675 | STATION_INFO_BSS_PARAM = 1<<15, | 681 | STATION_INFO_BSS_PARAM = 1<<15, |
676 | STATION_INFO_CONNECTED_TIME = 1<<16, | 682 | STATION_INFO_CONNECTED_TIME = 1<<16, |
677 | STATION_INFO_ASSOC_REQ_IES = 1<<17, | 683 | STATION_INFO_ASSOC_REQ_IES = 1<<17, |
678 | STATION_INFO_STA_FLAGS = 1<<18, | 684 | STATION_INFO_STA_FLAGS = 1<<18, |
679 | STATION_INFO_BEACON_LOSS_COUNT = 1<<19, | 685 | STATION_INFO_BEACON_LOSS_COUNT = 1<<19, |
680 | STATION_INFO_T_OFFSET = 1<<20, | 686 | STATION_INFO_T_OFFSET = 1<<20, |
687 | STATION_INFO_LOCAL_PM = 1<<21, | ||
688 | STATION_INFO_PEER_PM = 1<<22, | ||
689 | STATION_INFO_NONPEER_PM = 1<<23, | ||
681 | }; | 690 | }; |
682 | 691 | ||
683 | /** | 692 | /** |
684 | * enum station_info_rate_flags - bitrate info flags | 693 | * enum station_info_rate_flags - bitrate info flags |
685 | * | 694 | * |
686 | * Used by the driver to indicate the specific rate transmission | 695 | * Used by the driver to indicate the specific rate transmission |
687 | * type for 802.11n transmissions. | 696 | * type for 802.11n transmissions. |
688 | * | 697 | * |
689 | * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS | 698 | * @RATE_INFO_FLAGS_MCS: mcs field filled with HT MCS |
690 | * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS | 699 | * @RATE_INFO_FLAGS_VHT_MCS: mcs field filled with VHT MCS |
691 | * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission | 700 | * @RATE_INFO_FLAGS_40_MHZ_WIDTH: 40 MHz width transmission |
692 | * @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission | 701 | * @RATE_INFO_FLAGS_80_MHZ_WIDTH: 80 MHz width transmission |
693 | * @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission | 702 | * @RATE_INFO_FLAGS_80P80_MHZ_WIDTH: 80+80 MHz width transmission |
694 | * @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission | 703 | * @RATE_INFO_FLAGS_160_MHZ_WIDTH: 160 MHz width transmission |
695 | * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval | 704 | * @RATE_INFO_FLAGS_SHORT_GI: 400ns guard interval |
696 | * @RATE_INFO_FLAGS_60G: 60GHz MCS | 705 | * @RATE_INFO_FLAGS_60G: 60GHz MCS |
697 | */ | 706 | */ |
698 | enum rate_info_flags { | 707 | enum rate_info_flags { |
699 | RATE_INFO_FLAGS_MCS = BIT(0), | 708 | RATE_INFO_FLAGS_MCS = BIT(0), |
700 | RATE_INFO_FLAGS_VHT_MCS = BIT(1), | 709 | RATE_INFO_FLAGS_VHT_MCS = BIT(1), |
701 | RATE_INFO_FLAGS_40_MHZ_WIDTH = BIT(2), | 710 | RATE_INFO_FLAGS_40_MHZ_WIDTH = BIT(2), |
702 | RATE_INFO_FLAGS_80_MHZ_WIDTH = BIT(3), | 711 | RATE_INFO_FLAGS_80_MHZ_WIDTH = BIT(3), |
703 | RATE_INFO_FLAGS_80P80_MHZ_WIDTH = BIT(4), | 712 | RATE_INFO_FLAGS_80P80_MHZ_WIDTH = BIT(4), |
704 | RATE_INFO_FLAGS_160_MHZ_WIDTH = BIT(5), | 713 | RATE_INFO_FLAGS_160_MHZ_WIDTH = BIT(5), |
705 | RATE_INFO_FLAGS_SHORT_GI = BIT(6), | 714 | RATE_INFO_FLAGS_SHORT_GI = BIT(6), |
706 | RATE_INFO_FLAGS_60G = BIT(7), | 715 | RATE_INFO_FLAGS_60G = BIT(7), |
707 | }; | 716 | }; |
708 | 717 | ||
709 | /** | 718 | /** |
710 | * struct rate_info - bitrate information | 719 | * struct rate_info - bitrate information |
711 | * | 720 | * |
712 | * Information about a receiving or transmitting bitrate | 721 | * Information about a receiving or transmitting bitrate |
713 | * | 722 | * |
714 | * @flags: bitflag of flags from &enum rate_info_flags | 723 | * @flags: bitflag of flags from &enum rate_info_flags |
715 | * @mcs: mcs index if struct describes a 802.11n bitrate | 724 | * @mcs: mcs index if struct describes a 802.11n bitrate |
716 | * @legacy: bitrate in 100kbit/s for 802.11abg | 725 | * @legacy: bitrate in 100kbit/s for 802.11abg |
717 | * @nss: number of streams (VHT only) | 726 | * @nss: number of streams (VHT only) |
718 | */ | 727 | */ |
719 | struct rate_info { | 728 | struct rate_info { |
720 | u8 flags; | 729 | u8 flags; |
721 | u8 mcs; | 730 | u8 mcs; |
722 | u16 legacy; | 731 | u16 legacy; |
723 | u8 nss; | 732 | u8 nss; |
724 | }; | 733 | }; |
725 | 734 | ||
726 | /** | 735 | /** |
727 | * enum station_info_rate_flags - bitrate info flags | 736 | * enum station_info_rate_flags - bitrate info flags |
728 | * | 737 | * |
729 | * Used by the driver to indicate the specific rate transmission | 738 | * Used by the driver to indicate the specific rate transmission |
730 | * type for 802.11n transmissions. | 739 | * type for 802.11n transmissions. |
731 | * | 740 | * |
732 | * @BSS_PARAM_FLAGS_CTS_PROT: whether CTS protection is enabled | 741 | * @BSS_PARAM_FLAGS_CTS_PROT: whether CTS protection is enabled |
733 | * @BSS_PARAM_FLAGS_SHORT_PREAMBLE: whether short preamble is enabled | 742 | * @BSS_PARAM_FLAGS_SHORT_PREAMBLE: whether short preamble is enabled |
734 | * @BSS_PARAM_FLAGS_SHORT_SLOT_TIME: whether short slot time is enabled | 743 | * @BSS_PARAM_FLAGS_SHORT_SLOT_TIME: whether short slot time is enabled |
735 | */ | 744 | */ |
736 | enum bss_param_flags { | 745 | enum bss_param_flags { |
737 | BSS_PARAM_FLAGS_CTS_PROT = 1<<0, | 746 | BSS_PARAM_FLAGS_CTS_PROT = 1<<0, |
738 | BSS_PARAM_FLAGS_SHORT_PREAMBLE = 1<<1, | 747 | BSS_PARAM_FLAGS_SHORT_PREAMBLE = 1<<1, |
739 | BSS_PARAM_FLAGS_SHORT_SLOT_TIME = 1<<2, | 748 | BSS_PARAM_FLAGS_SHORT_SLOT_TIME = 1<<2, |
740 | }; | 749 | }; |
741 | 750 | ||
742 | /** | 751 | /** |
743 | * struct sta_bss_parameters - BSS parameters for the attached station | 752 | * struct sta_bss_parameters - BSS parameters for the attached station |
744 | * | 753 | * |
745 | * Information about the currently associated BSS | 754 | * Information about the currently associated BSS |
746 | * | 755 | * |
747 | * @flags: bitflag of flags from &enum bss_param_flags | 756 | * @flags: bitflag of flags from &enum bss_param_flags |
748 | * @dtim_period: DTIM period for the BSS | 757 | * @dtim_period: DTIM period for the BSS |
749 | * @beacon_interval: beacon interval | 758 | * @beacon_interval: beacon interval |
750 | */ | 759 | */ |
751 | struct sta_bss_parameters { | 760 | struct sta_bss_parameters { |
752 | u8 flags; | 761 | u8 flags; |
753 | u8 dtim_period; | 762 | u8 dtim_period; |
754 | u16 beacon_interval; | 763 | u16 beacon_interval; |
755 | }; | 764 | }; |
756 | 765 | ||
757 | /** | 766 | /** |
758 | * struct station_info - station information | 767 | * struct station_info - station information |
759 | * | 768 | * |
760 | * Station information filled by driver for get_station() and dump_station. | 769 | * Station information filled by driver for get_station() and dump_station. |
761 | * | 770 | * |
762 | * @filled: bitflag of flags from &enum station_info_flags | 771 | * @filled: bitflag of flags from &enum station_info_flags |
763 | * @connected_time: time(in secs) since a station is last connected | 772 | * @connected_time: time(in secs) since a station is last connected |
764 | * @inactive_time: time since last station activity (tx/rx) in milliseconds | 773 | * @inactive_time: time since last station activity (tx/rx) in milliseconds |
765 | * @rx_bytes: bytes received from this station | 774 | * @rx_bytes: bytes received from this station |
766 | * @tx_bytes: bytes transmitted to this station | 775 | * @tx_bytes: bytes transmitted to this station |
767 | * @llid: mesh local link id | 776 | * @llid: mesh local link id |
768 | * @plid: mesh peer link id | 777 | * @plid: mesh peer link id |
769 | * @plink_state: mesh peer link state | 778 | * @plink_state: mesh peer link state |
770 | * @signal: The signal strength, type depends on the wiphy's signal_type. | 779 | * @signal: The signal strength, type depends on the wiphy's signal_type. |
771 | * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. | 780 | * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. |
772 | * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. | 781 | * @signal_avg: Average signal strength, type depends on the wiphy's signal_type. |
773 | * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. | 782 | * For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_. |
774 | * @txrate: current unicast bitrate from this station | 783 | * @txrate: current unicast bitrate from this station |
775 | * @rxrate: current unicast bitrate to this station | 784 | * @rxrate: current unicast bitrate to this station |
776 | * @rx_packets: packets received from this station | 785 | * @rx_packets: packets received from this station |
777 | * @tx_packets: packets transmitted to this station | 786 | * @tx_packets: packets transmitted to this station |
778 | * @tx_retries: cumulative retry counts | 787 | * @tx_retries: cumulative retry counts |
779 | * @tx_failed: number of failed transmissions (retries exceeded, no ACK) | 788 | * @tx_failed: number of failed transmissions (retries exceeded, no ACK) |
780 | * @rx_dropped_misc: Dropped for un-specified reason. | 789 | * @rx_dropped_misc: Dropped for un-specified reason. |
781 | * @bss_param: current BSS parameters | 790 | * @bss_param: current BSS parameters |
782 | * @generation: generation number for nl80211 dumps. | 791 | * @generation: generation number for nl80211 dumps. |
783 | * This number should increase every time the list of stations | 792 | * This number should increase every time the list of stations |
784 | * changes, i.e. when a station is added or removed, so that | 793 | * changes, i.e. when a station is added or removed, so that |
785 | * userspace can tell whether it got a consistent snapshot. | 794 | * userspace can tell whether it got a consistent snapshot. |
786 | * @assoc_req_ies: IEs from (Re)Association Request. | 795 | * @assoc_req_ies: IEs from (Re)Association Request. |
787 | * This is used only when in AP mode with drivers that do not use | 796 | * This is used only when in AP mode with drivers that do not use |
788 | * user space MLME/SME implementation. The information is provided for | 797 | * user space MLME/SME implementation. The information is provided for |
789 | * the cfg80211_new_sta() calls to notify user space of the IEs. | 798 | * the cfg80211_new_sta() calls to notify user space of the IEs. |
790 | * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. | 799 | * @assoc_req_ies_len: Length of assoc_req_ies buffer in octets. |
791 | * @sta_flags: station flags mask & values | 800 | * @sta_flags: station flags mask & values |
792 | * @beacon_loss_count: Number of times beacon loss event has triggered. | 801 | * @beacon_loss_count: Number of times beacon loss event has triggered. |
793 | * @t_offset: Time offset of the station relative to this host. | 802 | * @t_offset: Time offset of the station relative to this host. |
803 | * @local_pm: local mesh STA power save mode | ||
804 | * @peer_pm: peer mesh STA power save mode | ||
805 | * @nonpeer_pm: non-peer mesh STA power save mode | ||
794 | */ | 806 | */ |
795 | struct station_info { | 807 | struct station_info { |
796 | u32 filled; | 808 | u32 filled; |
797 | u32 connected_time; | 809 | u32 connected_time; |
798 | u32 inactive_time; | 810 | u32 inactive_time; |
799 | u32 rx_bytes; | 811 | u32 rx_bytes; |
800 | u32 tx_bytes; | 812 | u32 tx_bytes; |
801 | u16 llid; | 813 | u16 llid; |
802 | u16 plid; | 814 | u16 plid; |
803 | u8 plink_state; | 815 | u8 plink_state; |
804 | s8 signal; | 816 | s8 signal; |
805 | s8 signal_avg; | 817 | s8 signal_avg; |
806 | struct rate_info txrate; | 818 | struct rate_info txrate; |
807 | struct rate_info rxrate; | 819 | struct rate_info rxrate; |
808 | u32 rx_packets; | 820 | u32 rx_packets; |
809 | u32 tx_packets; | 821 | u32 tx_packets; |
810 | u32 tx_retries; | 822 | u32 tx_retries; |
811 | u32 tx_failed; | 823 | u32 tx_failed; |
812 | u32 rx_dropped_misc; | 824 | u32 rx_dropped_misc; |
813 | struct sta_bss_parameters bss_param; | 825 | struct sta_bss_parameters bss_param; |
814 | struct nl80211_sta_flag_update sta_flags; | 826 | struct nl80211_sta_flag_update sta_flags; |
815 | 827 | ||
816 | int generation; | 828 | int generation; |
817 | 829 | ||
818 | const u8 *assoc_req_ies; | 830 | const u8 *assoc_req_ies; |
819 | size_t assoc_req_ies_len; | 831 | size_t assoc_req_ies_len; |
820 | 832 | ||
821 | u32 beacon_loss_count; | 833 | u32 beacon_loss_count; |
822 | s64 t_offset; | 834 | s64 t_offset; |
835 | enum nl80211_mesh_power_mode local_pm; | ||
836 | enum nl80211_mesh_power_mode peer_pm; | ||
837 | enum nl80211_mesh_power_mode nonpeer_pm; | ||
823 | 838 | ||
824 | /* | 839 | /* |
825 | * Note: Add a new enum station_info_flags value for each new field and | 840 | * Note: Add a new enum station_info_flags value for each new field and |
826 | * use it to check which fields are initialized. | 841 | * use it to check which fields are initialized. |
827 | */ | 842 | */ |
828 | }; | 843 | }; |
829 | 844 | ||
830 | /** | 845 | /** |
831 | * enum monitor_flags - monitor flags | 846 | * enum monitor_flags - monitor flags |
832 | * | 847 | * |
833 | * Monitor interface configuration flags. Note that these must be the bits | 848 | * Monitor interface configuration flags. Note that these must be the bits |
834 | * according to the nl80211 flags. | 849 | * according to the nl80211 flags. |
835 | * | 850 | * |
836 | * @MONITOR_FLAG_FCSFAIL: pass frames with bad FCS | 851 | * @MONITOR_FLAG_FCSFAIL: pass frames with bad FCS |
837 | * @MONITOR_FLAG_PLCPFAIL: pass frames with bad PLCP | 852 | * @MONITOR_FLAG_PLCPFAIL: pass frames with bad PLCP |
838 | * @MONITOR_FLAG_CONTROL: pass control frames | 853 | * @MONITOR_FLAG_CONTROL: pass control frames |
839 | * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering | 854 | * @MONITOR_FLAG_OTHER_BSS: disable BSSID filtering |
840 | * @MONITOR_FLAG_COOK_FRAMES: report frames after processing | 855 | * @MONITOR_FLAG_COOK_FRAMES: report frames after processing |
841 | */ | 856 | */ |
842 | enum monitor_flags { | 857 | enum monitor_flags { |
843 | MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL, | 858 | MONITOR_FLAG_FCSFAIL = 1<<NL80211_MNTR_FLAG_FCSFAIL, |
844 | MONITOR_FLAG_PLCPFAIL = 1<<NL80211_MNTR_FLAG_PLCPFAIL, | 859 | MONITOR_FLAG_PLCPFAIL = 1<<NL80211_MNTR_FLAG_PLCPFAIL, |
845 | MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL, | 860 | MONITOR_FLAG_CONTROL = 1<<NL80211_MNTR_FLAG_CONTROL, |
846 | MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS, | 861 | MONITOR_FLAG_OTHER_BSS = 1<<NL80211_MNTR_FLAG_OTHER_BSS, |
847 | MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES, | 862 | MONITOR_FLAG_COOK_FRAMES = 1<<NL80211_MNTR_FLAG_COOK_FRAMES, |
848 | }; | 863 | }; |
849 | 864 | ||
850 | /** | 865 | /** |
851 | * enum mpath_info_flags - mesh path information flags | 866 | * enum mpath_info_flags - mesh path information flags |
852 | * | 867 | * |
853 | * Used by the driver to indicate which info in &struct mpath_info it has filled | 868 | * Used by the driver to indicate which info in &struct mpath_info it has filled |
854 | * in during get_station() or dump_station(). | 869 | * in during get_station() or dump_station(). |
855 | * | 870 | * |
856 | * @MPATH_INFO_FRAME_QLEN: @frame_qlen filled | 871 | * @MPATH_INFO_FRAME_QLEN: @frame_qlen filled |
857 | * @MPATH_INFO_SN: @sn filled | 872 | * @MPATH_INFO_SN: @sn filled |
858 | * @MPATH_INFO_METRIC: @metric filled | 873 | * @MPATH_INFO_METRIC: @metric filled |
859 | * @MPATH_INFO_EXPTIME: @exptime filled | 874 | * @MPATH_INFO_EXPTIME: @exptime filled |
860 | * @MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled | 875 | * @MPATH_INFO_DISCOVERY_TIMEOUT: @discovery_timeout filled |
861 | * @MPATH_INFO_DISCOVERY_RETRIES: @discovery_retries filled | 876 | * @MPATH_INFO_DISCOVERY_RETRIES: @discovery_retries filled |
862 | * @MPATH_INFO_FLAGS: @flags filled | 877 | * @MPATH_INFO_FLAGS: @flags filled |
863 | */ | 878 | */ |
864 | enum mpath_info_flags { | 879 | enum mpath_info_flags { |
865 | MPATH_INFO_FRAME_QLEN = BIT(0), | 880 | MPATH_INFO_FRAME_QLEN = BIT(0), |
866 | MPATH_INFO_SN = BIT(1), | 881 | MPATH_INFO_SN = BIT(1), |
867 | MPATH_INFO_METRIC = BIT(2), | 882 | MPATH_INFO_METRIC = BIT(2), |
868 | MPATH_INFO_EXPTIME = BIT(3), | 883 | MPATH_INFO_EXPTIME = BIT(3), |
869 | MPATH_INFO_DISCOVERY_TIMEOUT = BIT(4), | 884 | MPATH_INFO_DISCOVERY_TIMEOUT = BIT(4), |
870 | MPATH_INFO_DISCOVERY_RETRIES = BIT(5), | 885 | MPATH_INFO_DISCOVERY_RETRIES = BIT(5), |
871 | MPATH_INFO_FLAGS = BIT(6), | 886 | MPATH_INFO_FLAGS = BIT(6), |
872 | }; | 887 | }; |
873 | 888 | ||
874 | /** | 889 | /** |
875 | * struct mpath_info - mesh path information | 890 | * struct mpath_info - mesh path information |
876 | * | 891 | * |
877 | * Mesh path information filled by driver for get_mpath() and dump_mpath(). | 892 | * Mesh path information filled by driver for get_mpath() and dump_mpath(). |
878 | * | 893 | * |
879 | * @filled: bitfield of flags from &enum mpath_info_flags | 894 | * @filled: bitfield of flags from &enum mpath_info_flags |
880 | * @frame_qlen: number of queued frames for this destination | 895 | * @frame_qlen: number of queued frames for this destination |
881 | * @sn: target sequence number | 896 | * @sn: target sequence number |
882 | * @metric: metric (cost) of this mesh path | 897 | * @metric: metric (cost) of this mesh path |
883 | * @exptime: expiration time for the mesh path from now, in msecs | 898 | * @exptime: expiration time for the mesh path from now, in msecs |
884 | * @flags: mesh path flags | 899 | * @flags: mesh path flags |
885 | * @discovery_timeout: total mesh path discovery timeout, in msecs | 900 | * @discovery_timeout: total mesh path discovery timeout, in msecs |
886 | * @discovery_retries: mesh path discovery retries | 901 | * @discovery_retries: mesh path discovery retries |
887 | * @generation: generation number for nl80211 dumps. | 902 | * @generation: generation number for nl80211 dumps. |
888 | * This number should increase every time the list of mesh paths | 903 | * This number should increase every time the list of mesh paths |
889 | * changes, i.e. when a station is added or removed, so that | 904 | * changes, i.e. when a station is added or removed, so that |
890 | * userspace can tell whether it got a consistent snapshot. | 905 | * userspace can tell whether it got a consistent snapshot. |
891 | */ | 906 | */ |
892 | struct mpath_info { | 907 | struct mpath_info { |
893 | u32 filled; | 908 | u32 filled; |
894 | u32 frame_qlen; | 909 | u32 frame_qlen; |
895 | u32 sn; | 910 | u32 sn; |
896 | u32 metric; | 911 | u32 metric; |
897 | u32 exptime; | 912 | u32 exptime; |
898 | u32 discovery_timeout; | 913 | u32 discovery_timeout; |
899 | u8 discovery_retries; | 914 | u8 discovery_retries; |
900 | u8 flags; | 915 | u8 flags; |
901 | 916 | ||
902 | int generation; | 917 | int generation; |
903 | }; | 918 | }; |
904 | 919 | ||
905 | /** | 920 | /** |
906 | * struct bss_parameters - BSS parameters | 921 | * struct bss_parameters - BSS parameters |
907 | * | 922 | * |
908 | * Used to change BSS parameters (mainly for AP mode). | 923 | * Used to change BSS parameters (mainly for AP mode). |
909 | * | 924 | * |
910 | * @use_cts_prot: Whether to use CTS protection | 925 | * @use_cts_prot: Whether to use CTS protection |
911 | * (0 = no, 1 = yes, -1 = do not change) | 926 | * (0 = no, 1 = yes, -1 = do not change) |
912 | * @use_short_preamble: Whether the use of short preambles is allowed | 927 | * @use_short_preamble: Whether the use of short preambles is allowed |
913 | * (0 = no, 1 = yes, -1 = do not change) | 928 | * (0 = no, 1 = yes, -1 = do not change) |
914 | * @use_short_slot_time: Whether the use of short slot time is allowed | 929 | * @use_short_slot_time: Whether the use of short slot time is allowed |
915 | * (0 = no, 1 = yes, -1 = do not change) | 930 | * (0 = no, 1 = yes, -1 = do not change) |
916 | * @basic_rates: basic rates in IEEE 802.11 format | 931 | * @basic_rates: basic rates in IEEE 802.11 format |
917 | * (or NULL for no change) | 932 | * (or NULL for no change) |
918 | * @basic_rates_len: number of basic rates | 933 | * @basic_rates_len: number of basic rates |
919 | * @ap_isolate: do not forward packets between connected stations | 934 | * @ap_isolate: do not forward packets between connected stations |
920 | * @ht_opmode: HT Operation mode | 935 | * @ht_opmode: HT Operation mode |
921 | * (u16 = opmode, -1 = do not change) | 936 | * (u16 = opmode, -1 = do not change) |
922 | * @p2p_ctwindow: P2P CT Window (-1 = no change) | 937 | * @p2p_ctwindow: P2P CT Window (-1 = no change) |
923 | * @p2p_opp_ps: P2P opportunistic PS (-1 = no change) | 938 | * @p2p_opp_ps: P2P opportunistic PS (-1 = no change) |
924 | */ | 939 | */ |
925 | struct bss_parameters { | 940 | struct bss_parameters { |
926 | int use_cts_prot; | 941 | int use_cts_prot; |
927 | int use_short_preamble; | 942 | int use_short_preamble; |
928 | int use_short_slot_time; | 943 | int use_short_slot_time; |
929 | u8 *basic_rates; | 944 | u8 *basic_rates; |
930 | u8 basic_rates_len; | 945 | u8 basic_rates_len; |
931 | int ap_isolate; | 946 | int ap_isolate; |
932 | int ht_opmode; | 947 | int ht_opmode; |
933 | s8 p2p_ctwindow, p2p_opp_ps; | 948 | s8 p2p_ctwindow, p2p_opp_ps; |
934 | }; | 949 | }; |
935 | 950 | ||
936 | /** | 951 | /** |
937 | * struct mesh_config - 802.11s mesh configuration | 952 | * struct mesh_config - 802.11s mesh configuration |
938 | * | 953 | * |
939 | * These parameters can be changed while the mesh is active. | 954 | * These parameters can be changed while the mesh is active. |
940 | * | 955 | * |
941 | * @dot11MeshRetryTimeout: the initial retry timeout in millisecond units used | 956 | * @dot11MeshRetryTimeout: the initial retry timeout in millisecond units used |
942 | * by the Mesh Peering Open message | 957 | * by the Mesh Peering Open message |
943 | * @dot11MeshConfirmTimeout: the initial retry timeout in millisecond units | 958 | * @dot11MeshConfirmTimeout: the initial retry timeout in millisecond units |
944 | * used by the Mesh Peering Open message | 959 | * used by the Mesh Peering Open message |
945 | * @dot11MeshHoldingTimeout: the confirm timeout in millisecond units used by | 960 | * @dot11MeshHoldingTimeout: the confirm timeout in millisecond units used by |
946 | * the mesh peering management to close a mesh peering | 961 | * the mesh peering management to close a mesh peering |
947 | * @dot11MeshMaxPeerLinks: the maximum number of peer links allowed on this | 962 | * @dot11MeshMaxPeerLinks: the maximum number of peer links allowed on this |
948 | * mesh interface | 963 | * mesh interface |
949 | * @dot11MeshMaxRetries: the maximum number of peer link open retries that can | 964 | * @dot11MeshMaxRetries: the maximum number of peer link open retries that can |
950 | * be sent to establish a new peer link instance in a mesh | 965 | * be sent to establish a new peer link instance in a mesh |
951 | * @dot11MeshTTL: the value of TTL field set at a source mesh STA | 966 | * @dot11MeshTTL: the value of TTL field set at a source mesh STA |
952 | * @element_ttl: the value of TTL field set at a mesh STA for path selection | 967 | * @element_ttl: the value of TTL field set at a mesh STA for path selection |
953 | * elements | 968 | * elements |
954 | * @auto_open_plinks: whether we should automatically open peer links when we | 969 | * @auto_open_plinks: whether we should automatically open peer links when we |
955 | * detect compatible mesh peers | 970 | * detect compatible mesh peers |
956 | * @dot11MeshNbrOffsetMaxNeighbor: the maximum number of neighbors to | 971 | * @dot11MeshNbrOffsetMaxNeighbor: the maximum number of neighbors to |
957 | * synchronize to for 11s default synchronization method | 972 | * synchronize to for 11s default synchronization method |
958 | * @dot11MeshHWMPmaxPREQretries: the number of action frames containing a PREQ | 973 | * @dot11MeshHWMPmaxPREQretries: the number of action frames containing a PREQ |
959 | * that an originator mesh STA can send to a particular path target | 974 | * that an originator mesh STA can send to a particular path target |
960 | * @path_refresh_time: how frequently to refresh mesh paths in milliseconds | 975 | * @path_refresh_time: how frequently to refresh mesh paths in milliseconds |
961 | * @min_discovery_timeout: the minimum length of time to wait until giving up on | 976 | * @min_discovery_timeout: the minimum length of time to wait until giving up on |
962 | * a path discovery in milliseconds | 977 | * a path discovery in milliseconds |
963 | * @dot11MeshHWMPactivePathTimeout: the time (in TUs) for which mesh STAs | 978 | * @dot11MeshHWMPactivePathTimeout: the time (in TUs) for which mesh STAs |
964 | * receiving a PREQ shall consider the forwarding information from the | 979 | * receiving a PREQ shall consider the forwarding information from the |
965 | * root to be valid. (TU = time unit) | 980 | * root to be valid. (TU = time unit) |
966 | * @dot11MeshHWMPpreqMinInterval: the minimum interval of time (in TUs) during | 981 | * @dot11MeshHWMPpreqMinInterval: the minimum interval of time (in TUs) during |
967 | * which a mesh STA can send only one action frame containing a PREQ | 982 | * which a mesh STA can send only one action frame containing a PREQ |
968 | * element | 983 | * element |
969 | * @dot11MeshHWMPperrMinInterval: the minimum interval of time (in TUs) during | 984 | * @dot11MeshHWMPperrMinInterval: the minimum interval of time (in TUs) during |
970 | * which a mesh STA can send only one Action frame containing a PERR | 985 | * which a mesh STA can send only one Action frame containing a PERR |
971 | * element | 986 | * element |
972 | * @dot11MeshHWMPnetDiameterTraversalTime: the interval of time (in TUs) that | 987 | * @dot11MeshHWMPnetDiameterTraversalTime: the interval of time (in TUs) that |
973 | * it takes for an HWMP information element to propagate across the mesh | 988 | * it takes for an HWMP information element to propagate across the mesh |
974 | * @dot11MeshHWMPRootMode: the configuration of a mesh STA as root mesh STA | 989 | * @dot11MeshHWMPRootMode: the configuration of a mesh STA as root mesh STA |
975 | * @dot11MeshHWMPRannInterval: the interval of time (in TUs) between root | 990 | * @dot11MeshHWMPRannInterval: the interval of time (in TUs) between root |
976 | * announcements are transmitted | 991 | * announcements are transmitted |
977 | * @dot11MeshGateAnnouncementProtocol: whether to advertise that this mesh | 992 | * @dot11MeshGateAnnouncementProtocol: whether to advertise that this mesh |
978 | * station has access to a broader network beyond the MBSS. (This is | 993 | * station has access to a broader network beyond the MBSS. (This is |
979 | * missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol set to true | 994 | * missnamed in draft 12.0: dot11MeshGateAnnouncementProtocol set to true |
980 | * only means that the station will announce others it's a mesh gate, but | 995 | * only means that the station will announce others it's a mesh gate, but |
981 | * not necessarily using the gate announcement protocol. Still keeping the | 996 | * not necessarily using the gate announcement protocol. Still keeping the |
982 | * same nomenclature to be in sync with the spec) | 997 | * same nomenclature to be in sync with the spec) |
983 | * @dot11MeshForwarding: whether the Mesh STA is forwarding or non-forwarding | 998 | * @dot11MeshForwarding: whether the Mesh STA is forwarding or non-forwarding |
984 | * entity (default is TRUE - forwarding entity) | 999 | * entity (default is TRUE - forwarding entity) |
985 | * @rssi_threshold: the threshold for average signal strength of candidate | 1000 | * @rssi_threshold: the threshold for average signal strength of candidate |
986 | * station to establish a peer link | 1001 | * station to establish a peer link |
987 | * @ht_opmode: mesh HT protection mode | 1002 | * @ht_opmode: mesh HT protection mode |
988 | * | 1003 | * |
989 | * @dot11MeshHWMPactivePathToRootTimeout: The time (in TUs) for which mesh STAs | 1004 | * @dot11MeshHWMPactivePathToRootTimeout: The time (in TUs) for which mesh STAs |
990 | * receiving a proactive PREQ shall consider the forwarding information to | 1005 | * receiving a proactive PREQ shall consider the forwarding information to |
991 | * the root mesh STA to be valid. | 1006 | * the root mesh STA to be valid. |
992 | * | 1007 | * |
993 | * @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive | 1008 | * @dot11MeshHWMProotInterval: The interval of time (in TUs) between proactive |
994 | * PREQs are transmitted. | 1009 | * PREQs are transmitted. |
995 | * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs) | 1010 | * @dot11MeshHWMPconfirmationInterval: The minimum interval of time (in TUs) |
996 | * during which a mesh STA can send only one Action frame containing | 1011 | * during which a mesh STA can send only one Action frame containing |
997 | * a PREQ element for root path confirmation. | 1012 | * a PREQ element for root path confirmation. |
1013 | * @power_mode: The default mesh power save mode which will be the initial | ||
1014 | * setting for new peer links. | ||
1015 | * @dot11MeshAwakeWindowDuration: The duration in TUs the STA will remain awake | ||
1016 | * after transmitting its beacon. | ||
998 | */ | 1017 | */ |
999 | struct mesh_config { | 1018 | struct mesh_config { |
1000 | u16 dot11MeshRetryTimeout; | 1019 | u16 dot11MeshRetryTimeout; |
1001 | u16 dot11MeshConfirmTimeout; | 1020 | u16 dot11MeshConfirmTimeout; |
1002 | u16 dot11MeshHoldingTimeout; | 1021 | u16 dot11MeshHoldingTimeout; |
1003 | u16 dot11MeshMaxPeerLinks; | 1022 | u16 dot11MeshMaxPeerLinks; |
1004 | u8 dot11MeshMaxRetries; | 1023 | u8 dot11MeshMaxRetries; |
1005 | u8 dot11MeshTTL; | 1024 | u8 dot11MeshTTL; |
1006 | u8 element_ttl; | 1025 | u8 element_ttl; |
1007 | bool auto_open_plinks; | 1026 | bool auto_open_plinks; |
1008 | u32 dot11MeshNbrOffsetMaxNeighbor; | 1027 | u32 dot11MeshNbrOffsetMaxNeighbor; |
1009 | u8 dot11MeshHWMPmaxPREQretries; | 1028 | u8 dot11MeshHWMPmaxPREQretries; |
1010 | u32 path_refresh_time; | 1029 | u32 path_refresh_time; |
1011 | u16 min_discovery_timeout; | 1030 | u16 min_discovery_timeout; |
1012 | u32 dot11MeshHWMPactivePathTimeout; | 1031 | u32 dot11MeshHWMPactivePathTimeout; |
1013 | u16 dot11MeshHWMPpreqMinInterval; | 1032 | u16 dot11MeshHWMPpreqMinInterval; |
1014 | u16 dot11MeshHWMPperrMinInterval; | 1033 | u16 dot11MeshHWMPperrMinInterval; |
1015 | u16 dot11MeshHWMPnetDiameterTraversalTime; | 1034 | u16 dot11MeshHWMPnetDiameterTraversalTime; |
1016 | u8 dot11MeshHWMPRootMode; | 1035 | u8 dot11MeshHWMPRootMode; |
1017 | u16 dot11MeshHWMPRannInterval; | 1036 | u16 dot11MeshHWMPRannInterval; |
1018 | bool dot11MeshGateAnnouncementProtocol; | 1037 | bool dot11MeshGateAnnouncementProtocol; |
1019 | bool dot11MeshForwarding; | 1038 | bool dot11MeshForwarding; |
1020 | s32 rssi_threshold; | 1039 | s32 rssi_threshold; |
1021 | u16 ht_opmode; | 1040 | u16 ht_opmode; |
1022 | u32 dot11MeshHWMPactivePathToRootTimeout; | 1041 | u32 dot11MeshHWMPactivePathToRootTimeout; |
1023 | u16 dot11MeshHWMProotInterval; | 1042 | u16 dot11MeshHWMProotInterval; |
1024 | u16 dot11MeshHWMPconfirmationInterval; | 1043 | u16 dot11MeshHWMPconfirmationInterval; |
1044 | enum nl80211_mesh_power_mode power_mode; | ||
1045 | u16 dot11MeshAwakeWindowDuration; | ||
1025 | }; | 1046 | }; |
1026 | 1047 | ||
1027 | /** | 1048 | /** |
1028 | * struct mesh_setup - 802.11s mesh setup configuration | 1049 | * struct mesh_setup - 802.11s mesh setup configuration |
1029 | * @chandef: defines the channel to use | 1050 | * @chandef: defines the channel to use |
1030 | * @mesh_id: the mesh ID | 1051 | * @mesh_id: the mesh ID |
1031 | * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes | 1052 | * @mesh_id_len: length of the mesh ID, at least 1 and at most 32 bytes |
1032 | * @sync_method: which synchronization method to use | 1053 | * @sync_method: which synchronization method to use |
1033 | * @path_sel_proto: which path selection protocol to use | 1054 | * @path_sel_proto: which path selection protocol to use |
1034 | * @path_metric: which metric to use | 1055 | * @path_metric: which metric to use |
1035 | * @ie: vendor information elements (optional) | 1056 | * @ie: vendor information elements (optional) |
1036 | * @ie_len: length of vendor information elements | 1057 | * @ie_len: length of vendor information elements |
1037 | * @is_authenticated: this mesh requires authentication | 1058 | * @is_authenticated: this mesh requires authentication |
1038 | * @is_secure: this mesh uses security | 1059 | * @is_secure: this mesh uses security |
1039 | * @dtim_period: DTIM period to use | 1060 | * @dtim_period: DTIM period to use |
1040 | * @beacon_interval: beacon interval to use | 1061 | * @beacon_interval: beacon interval to use |
1041 | * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a] | 1062 | * @mcast_rate: multicat rate for Mesh Node [6Mbps is the default for 802.11a] |
1042 | * | 1063 | * |
1043 | * These parameters are fixed when the mesh is created. | 1064 | * These parameters are fixed when the mesh is created. |
1044 | */ | 1065 | */ |
1045 | struct mesh_setup { | 1066 | struct mesh_setup { |
1046 | struct cfg80211_chan_def chandef; | 1067 | struct cfg80211_chan_def chandef; |
1047 | const u8 *mesh_id; | 1068 | const u8 *mesh_id; |
1048 | u8 mesh_id_len; | 1069 | u8 mesh_id_len; |
1049 | u8 sync_method; | 1070 | u8 sync_method; |
1050 | u8 path_sel_proto; | 1071 | u8 path_sel_proto; |
1051 | u8 path_metric; | 1072 | u8 path_metric; |
1052 | const u8 *ie; | 1073 | const u8 *ie; |
1053 | u8 ie_len; | 1074 | u8 ie_len; |
1054 | bool is_authenticated; | 1075 | bool is_authenticated; |
1055 | bool is_secure; | 1076 | bool is_secure; |
1056 | u8 dtim_period; | 1077 | u8 dtim_period; |
1057 | u16 beacon_interval; | 1078 | u16 beacon_interval; |
1058 | int mcast_rate[IEEE80211_NUM_BANDS]; | 1079 | int mcast_rate[IEEE80211_NUM_BANDS]; |
1059 | }; | 1080 | }; |
1060 | 1081 | ||
1061 | /** | 1082 | /** |
1062 | * struct ieee80211_txq_params - TX queue parameters | 1083 | * struct ieee80211_txq_params - TX queue parameters |
1063 | * @ac: AC identifier | 1084 | * @ac: AC identifier |
1064 | * @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled | 1085 | * @txop: Maximum burst time in units of 32 usecs, 0 meaning disabled |
1065 | * @cwmin: Minimum contention window [a value of the form 2^n-1 in the range | 1086 | * @cwmin: Minimum contention window [a value of the form 2^n-1 in the range |
1066 | * 1..32767] | 1087 | * 1..32767] |
1067 | * @cwmax: Maximum contention window [a value of the form 2^n-1 in the range | 1088 | * @cwmax: Maximum contention window [a value of the form 2^n-1 in the range |
1068 | * 1..32767] | 1089 | * 1..32767] |
1069 | * @aifs: Arbitration interframe space [0..255] | 1090 | * @aifs: Arbitration interframe space [0..255] |
1070 | */ | 1091 | */ |
1071 | struct ieee80211_txq_params { | 1092 | struct ieee80211_txq_params { |
1072 | enum nl80211_ac ac; | 1093 | enum nl80211_ac ac; |
1073 | u16 txop; | 1094 | u16 txop; |
1074 | u16 cwmin; | 1095 | u16 cwmin; |
1075 | u16 cwmax; | 1096 | u16 cwmax; |
1076 | u8 aifs; | 1097 | u8 aifs; |
1077 | }; | 1098 | }; |
1078 | 1099 | ||
1079 | /** | 1100 | /** |
1080 | * DOC: Scanning and BSS list handling | 1101 | * DOC: Scanning and BSS list handling |
1081 | * | 1102 | * |
1082 | * The scanning process itself is fairly simple, but cfg80211 offers quite | 1103 | * The scanning process itself is fairly simple, but cfg80211 offers quite |
1083 | * a bit of helper functionality. To start a scan, the scan operation will | 1104 | * a bit of helper functionality. To start a scan, the scan operation will |
1084 | * be invoked with a scan definition. This scan definition contains the | 1105 | * be invoked with a scan definition. This scan definition contains the |
1085 | * channels to scan, and the SSIDs to send probe requests for (including the | 1106 | * channels to scan, and the SSIDs to send probe requests for (including the |
1086 | * wildcard, if desired). A passive scan is indicated by having no SSIDs to | 1107 | * wildcard, if desired). A passive scan is indicated by having no SSIDs to |
1087 | * probe. Additionally, a scan request may contain extra information elements | 1108 | * probe. Additionally, a scan request may contain extra information elements |
1088 | * that should be added to the probe request. The IEs are guaranteed to be | 1109 | * that should be added to the probe request. The IEs are guaranteed to be |
1089 | * well-formed, and will not exceed the maximum length the driver advertised | 1110 | * well-formed, and will not exceed the maximum length the driver advertised |
1090 | * in the wiphy structure. | 1111 | * in the wiphy structure. |
1091 | * | 1112 | * |
1092 | * When scanning finds a BSS, cfg80211 needs to be notified of that, because | 1113 | * When scanning finds a BSS, cfg80211 needs to be notified of that, because |
1093 | * it is responsible for maintaining the BSS list; the driver should not | 1114 | * it is responsible for maintaining the BSS list; the driver should not |
1094 | * maintain a list itself. For this notification, various functions exist. | 1115 | * maintain a list itself. For this notification, various functions exist. |
1095 | * | 1116 | * |
1096 | * Since drivers do not maintain a BSS list, there are also a number of | 1117 | * Since drivers do not maintain a BSS list, there are also a number of |
1097 | * functions to search for a BSS and obtain information about it from the | 1118 | * functions to search for a BSS and obtain information about it from the |
1098 | * BSS structure cfg80211 maintains. The BSS list is also made available | 1119 | * BSS structure cfg80211 maintains. The BSS list is also made available |
1099 | * to userspace. | 1120 | * to userspace. |
1100 | */ | 1121 | */ |
1101 | 1122 | ||
1102 | /** | 1123 | /** |
1103 | * struct cfg80211_ssid - SSID description | 1124 | * struct cfg80211_ssid - SSID description |
1104 | * @ssid: the SSID | 1125 | * @ssid: the SSID |
1105 | * @ssid_len: length of the ssid | 1126 | * @ssid_len: length of the ssid |
1106 | */ | 1127 | */ |
1107 | struct cfg80211_ssid { | 1128 | struct cfg80211_ssid { |
1108 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 1129 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
1109 | u8 ssid_len; | 1130 | u8 ssid_len; |
1110 | }; | 1131 | }; |
1111 | 1132 | ||
1112 | /** | 1133 | /** |
1113 | * struct cfg80211_scan_request - scan request description | 1134 | * struct cfg80211_scan_request - scan request description |
1114 | * | 1135 | * |
1115 | * @ssids: SSIDs to scan for (active scan only) | 1136 | * @ssids: SSIDs to scan for (active scan only) |
1116 | * @n_ssids: number of SSIDs | 1137 | * @n_ssids: number of SSIDs |
1117 | * @channels: channels to scan on. | 1138 | * @channels: channels to scan on. |
1118 | * @n_channels: total number of channels to scan | 1139 | * @n_channels: total number of channels to scan |
1119 | * @ie: optional information element(s) to add into Probe Request or %NULL | 1140 | * @ie: optional information element(s) to add into Probe Request or %NULL |
1120 | * @ie_len: length of ie in octets | 1141 | * @ie_len: length of ie in octets |
1121 | * @flags: bit field of flags controlling operation | 1142 | * @flags: bit field of flags controlling operation |
1122 | * @rates: bitmap of rates to advertise for each band | 1143 | * @rates: bitmap of rates to advertise for each band |
1123 | * @wiphy: the wiphy this was for | 1144 | * @wiphy: the wiphy this was for |
1124 | * @scan_start: time (in jiffies) when the scan started | 1145 | * @scan_start: time (in jiffies) when the scan started |
1125 | * @wdev: the wireless device to scan for | 1146 | * @wdev: the wireless device to scan for |
1126 | * @aborted: (internal) scan request was notified as aborted | 1147 | * @aborted: (internal) scan request was notified as aborted |
1127 | * @no_cck: used to send probe requests at non CCK rate in 2GHz band | 1148 | * @no_cck: used to send probe requests at non CCK rate in 2GHz band |
1128 | */ | 1149 | */ |
1129 | struct cfg80211_scan_request { | 1150 | struct cfg80211_scan_request { |
1130 | struct cfg80211_ssid *ssids; | 1151 | struct cfg80211_ssid *ssids; |
1131 | int n_ssids; | 1152 | int n_ssids; |
1132 | u32 n_channels; | 1153 | u32 n_channels; |
1133 | const u8 *ie; | 1154 | const u8 *ie; |
1134 | size_t ie_len; | 1155 | size_t ie_len; |
1135 | u32 flags; | 1156 | u32 flags; |
1136 | 1157 | ||
1137 | u32 rates[IEEE80211_NUM_BANDS]; | 1158 | u32 rates[IEEE80211_NUM_BANDS]; |
1138 | 1159 | ||
1139 | struct wireless_dev *wdev; | 1160 | struct wireless_dev *wdev; |
1140 | 1161 | ||
1141 | /* internal */ | 1162 | /* internal */ |
1142 | struct wiphy *wiphy; | 1163 | struct wiphy *wiphy; |
1143 | unsigned long scan_start; | 1164 | unsigned long scan_start; |
1144 | bool aborted; | 1165 | bool aborted; |
1145 | bool no_cck; | 1166 | bool no_cck; |
1146 | 1167 | ||
1147 | /* keep last */ | 1168 | /* keep last */ |
1148 | struct ieee80211_channel *channels[0]; | 1169 | struct ieee80211_channel *channels[0]; |
1149 | }; | 1170 | }; |
1150 | 1171 | ||
1151 | /** | 1172 | /** |
1152 | * struct cfg80211_match_set - sets of attributes to match | 1173 | * struct cfg80211_match_set - sets of attributes to match |
1153 | * | 1174 | * |
1154 | * @ssid: SSID to be matched | 1175 | * @ssid: SSID to be matched |
1155 | */ | 1176 | */ |
1156 | struct cfg80211_match_set { | 1177 | struct cfg80211_match_set { |
1157 | struct cfg80211_ssid ssid; | 1178 | struct cfg80211_ssid ssid; |
1158 | }; | 1179 | }; |
1159 | 1180 | ||
1160 | /** | 1181 | /** |
1161 | * struct cfg80211_sched_scan_request - scheduled scan request description | 1182 | * struct cfg80211_sched_scan_request - scheduled scan request description |
1162 | * | 1183 | * |
1163 | * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) | 1184 | * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) |
1164 | * @n_ssids: number of SSIDs | 1185 | * @n_ssids: number of SSIDs |
1165 | * @n_channels: total number of channels to scan | 1186 | * @n_channels: total number of channels to scan |
1166 | * @interval: interval between each scheduled scan cycle | 1187 | * @interval: interval between each scheduled scan cycle |
1167 | * @ie: optional information element(s) to add into Probe Request or %NULL | 1188 | * @ie: optional information element(s) to add into Probe Request or %NULL |
1168 | * @ie_len: length of ie in octets | 1189 | * @ie_len: length of ie in octets |
1169 | * @flags: bit field of flags controlling operation | 1190 | * @flags: bit field of flags controlling operation |
1170 | * @match_sets: sets of parameters to be matched for a scan result | 1191 | * @match_sets: sets of parameters to be matched for a scan result |
1171 | * entry to be considered valid and to be passed to the host | 1192 | * entry to be considered valid and to be passed to the host |
1172 | * (others are filtered out). | 1193 | * (others are filtered out). |
1173 | * If ommited, all results are passed. | 1194 | * If ommited, all results are passed. |
1174 | * @n_match_sets: number of match sets | 1195 | * @n_match_sets: number of match sets |
1175 | * @wiphy: the wiphy this was for | 1196 | * @wiphy: the wiphy this was for |
1176 | * @dev: the interface | 1197 | * @dev: the interface |
1177 | * @channels: channels to scan | 1198 | * @channels: channels to scan |
1178 | * @rssi_thold: don't report scan results below this threshold (in s32 dBm) | 1199 | * @rssi_thold: don't report scan results below this threshold (in s32 dBm) |
1179 | */ | 1200 | */ |
1180 | struct cfg80211_sched_scan_request { | 1201 | struct cfg80211_sched_scan_request { |
1181 | struct cfg80211_ssid *ssids; | 1202 | struct cfg80211_ssid *ssids; |
1182 | int n_ssids; | 1203 | int n_ssids; |
1183 | u32 n_channels; | 1204 | u32 n_channels; |
1184 | u32 interval; | 1205 | u32 interval; |
1185 | const u8 *ie; | 1206 | const u8 *ie; |
1186 | size_t ie_len; | 1207 | size_t ie_len; |
1187 | u32 flags; | 1208 | u32 flags; |
1188 | struct cfg80211_match_set *match_sets; | 1209 | struct cfg80211_match_set *match_sets; |
1189 | int n_match_sets; | 1210 | int n_match_sets; |
1190 | s32 rssi_thold; | 1211 | s32 rssi_thold; |
1191 | 1212 | ||
1192 | /* internal */ | 1213 | /* internal */ |
1193 | struct wiphy *wiphy; | 1214 | struct wiphy *wiphy; |
1194 | struct net_device *dev; | 1215 | struct net_device *dev; |
1195 | unsigned long scan_start; | 1216 | unsigned long scan_start; |
1196 | 1217 | ||
1197 | /* keep last */ | 1218 | /* keep last */ |
1198 | struct ieee80211_channel *channels[0]; | 1219 | struct ieee80211_channel *channels[0]; |
1199 | }; | 1220 | }; |
1200 | 1221 | ||
1201 | /** | 1222 | /** |
1202 | * enum cfg80211_signal_type - signal type | 1223 | * enum cfg80211_signal_type - signal type |
1203 | * | 1224 | * |
1204 | * @CFG80211_SIGNAL_TYPE_NONE: no signal strength information available | 1225 | * @CFG80211_SIGNAL_TYPE_NONE: no signal strength information available |
1205 | * @CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) | 1226 | * @CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) |
1206 | * @CFG80211_SIGNAL_TYPE_UNSPEC: signal strength, increasing from 0 through 100 | 1227 | * @CFG80211_SIGNAL_TYPE_UNSPEC: signal strength, increasing from 0 through 100 |
1207 | */ | 1228 | */ |
1208 | enum cfg80211_signal_type { | 1229 | enum cfg80211_signal_type { |
1209 | CFG80211_SIGNAL_TYPE_NONE, | 1230 | CFG80211_SIGNAL_TYPE_NONE, |
1210 | CFG80211_SIGNAL_TYPE_MBM, | 1231 | CFG80211_SIGNAL_TYPE_MBM, |
1211 | CFG80211_SIGNAL_TYPE_UNSPEC, | 1232 | CFG80211_SIGNAL_TYPE_UNSPEC, |
1212 | }; | 1233 | }; |
1213 | 1234 | ||
1214 | /** | 1235 | /** |
1215 | * struct cfg80211_bss_ie_data - BSS entry IE data | 1236 | * struct cfg80211_bss_ie_data - BSS entry IE data |
1216 | * @rcu_head: internal use, for freeing | 1237 | * @rcu_head: internal use, for freeing |
1217 | * @len: length of the IEs | 1238 | * @len: length of the IEs |
1218 | * @data: IE data | 1239 | * @data: IE data |
1219 | */ | 1240 | */ |
1220 | struct cfg80211_bss_ies { | 1241 | struct cfg80211_bss_ies { |
1221 | struct rcu_head rcu_head; | 1242 | struct rcu_head rcu_head; |
1222 | int len; | 1243 | int len; |
1223 | u8 data[]; | 1244 | u8 data[]; |
1224 | }; | 1245 | }; |
1225 | 1246 | ||
1226 | /** | 1247 | /** |
1227 | * struct cfg80211_bss - BSS description | 1248 | * struct cfg80211_bss - BSS description |
1228 | * | 1249 | * |
1229 | * This structure describes a BSS (which may also be a mesh network) | 1250 | * This structure describes a BSS (which may also be a mesh network) |
1230 | * for use in scan results and similar. | 1251 | * for use in scan results and similar. |
1231 | * | 1252 | * |
1232 | * @channel: channel this BSS is on | 1253 | * @channel: channel this BSS is on |
1233 | * @bssid: BSSID of the BSS | 1254 | * @bssid: BSSID of the BSS |
1234 | * @tsf: timestamp of last received update | 1255 | * @tsf: timestamp of last received update |
1235 | * @beacon_interval: the beacon interval as from the frame | 1256 | * @beacon_interval: the beacon interval as from the frame |
1236 | * @capability: the capability field in host byte order | 1257 | * @capability: the capability field in host byte order |
1237 | * @ies: the information elements (Note that there | 1258 | * @ies: the information elements (Note that there |
1238 | * is no guarantee that these are well-formed!); this is a pointer to | 1259 | * is no guarantee that these are well-formed!); this is a pointer to |
1239 | * either the beacon_ies or proberesp_ies depending on whether Probe | 1260 | * either the beacon_ies or proberesp_ies depending on whether Probe |
1240 | * Response frame has been received | 1261 | * Response frame has been received |
1241 | * @beacon_ies: the information elements from the last Beacon frame | 1262 | * @beacon_ies: the information elements from the last Beacon frame |
1242 | * @proberesp_ies: the information elements from the last Probe Response frame | 1263 | * @proberesp_ies: the information elements from the last Probe Response frame |
1243 | * @signal: signal strength value (type depends on the wiphy's signal_type) | 1264 | * @signal: signal strength value (type depends on the wiphy's signal_type) |
1244 | * @free_priv: function pointer to free private data | 1265 | * @free_priv: function pointer to free private data |
1245 | * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes | 1266 | * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes |
1246 | */ | 1267 | */ |
1247 | struct cfg80211_bss { | 1268 | struct cfg80211_bss { |
1248 | u64 tsf; | 1269 | u64 tsf; |
1249 | 1270 | ||
1250 | struct ieee80211_channel *channel; | 1271 | struct ieee80211_channel *channel; |
1251 | 1272 | ||
1252 | const struct cfg80211_bss_ies __rcu *ies; | 1273 | const struct cfg80211_bss_ies __rcu *ies; |
1253 | const struct cfg80211_bss_ies __rcu *beacon_ies; | 1274 | const struct cfg80211_bss_ies __rcu *beacon_ies; |
1254 | const struct cfg80211_bss_ies __rcu *proberesp_ies; | 1275 | const struct cfg80211_bss_ies __rcu *proberesp_ies; |
1255 | 1276 | ||
1256 | void (*free_priv)(struct cfg80211_bss *bss); | 1277 | void (*free_priv)(struct cfg80211_bss *bss); |
1257 | 1278 | ||
1258 | s32 signal; | 1279 | s32 signal; |
1259 | 1280 | ||
1260 | u16 beacon_interval; | 1281 | u16 beacon_interval; |
1261 | u16 capability; | 1282 | u16 capability; |
1262 | 1283 | ||
1263 | u8 bssid[ETH_ALEN]; | 1284 | u8 bssid[ETH_ALEN]; |
1264 | 1285 | ||
1265 | u8 priv[0] __aligned(sizeof(void *)); | 1286 | u8 priv[0] __aligned(sizeof(void *)); |
1266 | }; | 1287 | }; |
1267 | 1288 | ||
1268 | /** | 1289 | /** |
1269 | * ieee80211_bss_get_ie - find IE with given ID | 1290 | * ieee80211_bss_get_ie - find IE with given ID |
1270 | * @bss: the bss to search | 1291 | * @bss: the bss to search |
1271 | * @ie: the IE ID | 1292 | * @ie: the IE ID |
1272 | * | 1293 | * |
1273 | * Note that the return value is an RCU-protected pointer, so | 1294 | * Note that the return value is an RCU-protected pointer, so |
1274 | * rcu_read_lock() must be held when calling this function. | 1295 | * rcu_read_lock() must be held when calling this function. |
1275 | * Return: %NULL if not found. | 1296 | * Return: %NULL if not found. |
1276 | */ | 1297 | */ |
1277 | const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); | 1298 | const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie); |
1278 | 1299 | ||
1279 | 1300 | ||
1280 | /** | 1301 | /** |
1281 | * struct cfg80211_auth_request - Authentication request data | 1302 | * struct cfg80211_auth_request - Authentication request data |
1282 | * | 1303 | * |
1283 | * This structure provides information needed to complete IEEE 802.11 | 1304 | * This structure provides information needed to complete IEEE 802.11 |
1284 | * authentication. | 1305 | * authentication. |
1285 | * | 1306 | * |
1286 | * @bss: The BSS to authenticate with. | 1307 | * @bss: The BSS to authenticate with. |
1287 | * @auth_type: Authentication type (algorithm) | 1308 | * @auth_type: Authentication type (algorithm) |
1288 | * @ie: Extra IEs to add to Authentication frame or %NULL | 1309 | * @ie: Extra IEs to add to Authentication frame or %NULL |
1289 | * @ie_len: Length of ie buffer in octets | 1310 | * @ie_len: Length of ie buffer in octets |
1290 | * @key_len: length of WEP key for shared key authentication | 1311 | * @key_len: length of WEP key for shared key authentication |
1291 | * @key_idx: index of WEP key for shared key authentication | 1312 | * @key_idx: index of WEP key for shared key authentication |
1292 | * @key: WEP key for shared key authentication | 1313 | * @key: WEP key for shared key authentication |
1293 | * @sae_data: Non-IE data to use with SAE or %NULL. This starts with | 1314 | * @sae_data: Non-IE data to use with SAE or %NULL. This starts with |
1294 | * Authentication transaction sequence number field. | 1315 | * Authentication transaction sequence number field. |
1295 | * @sae_data_len: Length of sae_data buffer in octets | 1316 | * @sae_data_len: Length of sae_data buffer in octets |
1296 | */ | 1317 | */ |
1297 | struct cfg80211_auth_request { | 1318 | struct cfg80211_auth_request { |
1298 | struct cfg80211_bss *bss; | 1319 | struct cfg80211_bss *bss; |
1299 | const u8 *ie; | 1320 | const u8 *ie; |
1300 | size_t ie_len; | 1321 | size_t ie_len; |
1301 | enum nl80211_auth_type auth_type; | 1322 | enum nl80211_auth_type auth_type; |
1302 | const u8 *key; | 1323 | const u8 *key; |
1303 | u8 key_len, key_idx; | 1324 | u8 key_len, key_idx; |
1304 | const u8 *sae_data; | 1325 | const u8 *sae_data; |
1305 | size_t sae_data_len; | 1326 | size_t sae_data_len; |
1306 | }; | 1327 | }; |
1307 | 1328 | ||
1308 | /** | 1329 | /** |
1309 | * enum cfg80211_assoc_req_flags - Over-ride default behaviour in association. | 1330 | * enum cfg80211_assoc_req_flags - Over-ride default behaviour in association. |
1310 | * | 1331 | * |
1311 | * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) | 1332 | * @ASSOC_REQ_DISABLE_HT: Disable HT (802.11n) |
1312 | */ | 1333 | */ |
1313 | enum cfg80211_assoc_req_flags { | 1334 | enum cfg80211_assoc_req_flags { |
1314 | ASSOC_REQ_DISABLE_HT = BIT(0), | 1335 | ASSOC_REQ_DISABLE_HT = BIT(0), |
1315 | }; | 1336 | }; |
1316 | 1337 | ||
1317 | /** | 1338 | /** |
1318 | * struct cfg80211_assoc_request - (Re)Association request data | 1339 | * struct cfg80211_assoc_request - (Re)Association request data |
1319 | * | 1340 | * |
1320 | * This structure provides information needed to complete IEEE 802.11 | 1341 | * This structure provides information needed to complete IEEE 802.11 |
1321 | * (re)association. | 1342 | * (re)association. |
1322 | * @bss: The BSS to associate with. If the call is successful the driver | 1343 | * @bss: The BSS to associate with. If the call is successful the driver |
1323 | * is given a reference that it must release, normally via a call to | 1344 | * is given a reference that it must release, normally via a call to |
1324 | * cfg80211_send_rx_assoc(), or, if association timed out, with a | 1345 | * cfg80211_send_rx_assoc(), or, if association timed out, with a |
1325 | * call to cfg80211_put_bss() (in addition to calling | 1346 | * call to cfg80211_put_bss() (in addition to calling |
1326 | * cfg80211_send_assoc_timeout()) | 1347 | * cfg80211_send_assoc_timeout()) |
1327 | * @ie: Extra IEs to add to (Re)Association Request frame or %NULL | 1348 | * @ie: Extra IEs to add to (Re)Association Request frame or %NULL |
1328 | * @ie_len: Length of ie buffer in octets | 1349 | * @ie_len: Length of ie buffer in octets |
1329 | * @use_mfp: Use management frame protection (IEEE 802.11w) in this association | 1350 | * @use_mfp: Use management frame protection (IEEE 802.11w) in this association |
1330 | * @crypto: crypto settings | 1351 | * @crypto: crypto settings |
1331 | * @prev_bssid: previous BSSID, if not %NULL use reassociate frame | 1352 | * @prev_bssid: previous BSSID, if not %NULL use reassociate frame |
1332 | * @flags: See &enum cfg80211_assoc_req_flags | 1353 | * @flags: See &enum cfg80211_assoc_req_flags |
1333 | * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask | 1354 | * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask |
1334 | * will be used in ht_capa. Un-supported values will be ignored. | 1355 | * will be used in ht_capa. Un-supported values will be ignored. |
1335 | * @ht_capa_mask: The bits of ht_capa which are to be used. | 1356 | * @ht_capa_mask: The bits of ht_capa which are to be used. |
1336 | */ | 1357 | */ |
1337 | struct cfg80211_assoc_request { | 1358 | struct cfg80211_assoc_request { |
1338 | struct cfg80211_bss *bss; | 1359 | struct cfg80211_bss *bss; |
1339 | const u8 *ie, *prev_bssid; | 1360 | const u8 *ie, *prev_bssid; |
1340 | size_t ie_len; | 1361 | size_t ie_len; |
1341 | struct cfg80211_crypto_settings crypto; | 1362 | struct cfg80211_crypto_settings crypto; |
1342 | bool use_mfp; | 1363 | bool use_mfp; |
1343 | u32 flags; | 1364 | u32 flags; |
1344 | struct ieee80211_ht_cap ht_capa; | 1365 | struct ieee80211_ht_cap ht_capa; |
1345 | struct ieee80211_ht_cap ht_capa_mask; | 1366 | struct ieee80211_ht_cap ht_capa_mask; |
1346 | }; | 1367 | }; |
1347 | 1368 | ||
1348 | /** | 1369 | /** |
1349 | * struct cfg80211_deauth_request - Deauthentication request data | 1370 | * struct cfg80211_deauth_request - Deauthentication request data |
1350 | * | 1371 | * |
1351 | * This structure provides information needed to complete IEEE 802.11 | 1372 | * This structure provides information needed to complete IEEE 802.11 |
1352 | * deauthentication. | 1373 | * deauthentication. |
1353 | * | 1374 | * |
1354 | * @bssid: the BSSID of the BSS to deauthenticate from | 1375 | * @bssid: the BSSID of the BSS to deauthenticate from |
1355 | * @ie: Extra IEs to add to Deauthentication frame or %NULL | 1376 | * @ie: Extra IEs to add to Deauthentication frame or %NULL |
1356 | * @ie_len: Length of ie buffer in octets | 1377 | * @ie_len: Length of ie buffer in octets |
1357 | * @reason_code: The reason code for the deauthentication | 1378 | * @reason_code: The reason code for the deauthentication |
1358 | */ | 1379 | */ |
1359 | struct cfg80211_deauth_request { | 1380 | struct cfg80211_deauth_request { |
1360 | const u8 *bssid; | 1381 | const u8 *bssid; |
1361 | const u8 *ie; | 1382 | const u8 *ie; |
1362 | size_t ie_len; | 1383 | size_t ie_len; |
1363 | u16 reason_code; | 1384 | u16 reason_code; |
1364 | bool local_state_change; | 1385 | bool local_state_change; |
1365 | }; | 1386 | }; |
1366 | 1387 | ||
1367 | /** | 1388 | /** |
1368 | * struct cfg80211_disassoc_request - Disassociation request data | 1389 | * struct cfg80211_disassoc_request - Disassociation request data |
1369 | * | 1390 | * |
1370 | * This structure provides information needed to complete IEEE 802.11 | 1391 | * This structure provides information needed to complete IEEE 802.11 |
1371 | * disassocation. | 1392 | * disassocation. |
1372 | * | 1393 | * |
1373 | * @bss: the BSS to disassociate from | 1394 | * @bss: the BSS to disassociate from |
1374 | * @ie: Extra IEs to add to Disassociation frame or %NULL | 1395 | * @ie: Extra IEs to add to Disassociation frame or %NULL |
1375 | * @ie_len: Length of ie buffer in octets | 1396 | * @ie_len: Length of ie buffer in octets |
1376 | * @reason_code: The reason code for the disassociation | 1397 | * @reason_code: The reason code for the disassociation |
1377 | * @local_state_change: This is a request for a local state only, i.e., no | 1398 | * @local_state_change: This is a request for a local state only, i.e., no |
1378 | * Disassociation frame is to be transmitted. | 1399 | * Disassociation frame is to be transmitted. |
1379 | */ | 1400 | */ |
1380 | struct cfg80211_disassoc_request { | 1401 | struct cfg80211_disassoc_request { |
1381 | struct cfg80211_bss *bss; | 1402 | struct cfg80211_bss *bss; |
1382 | const u8 *ie; | 1403 | const u8 *ie; |
1383 | size_t ie_len; | 1404 | size_t ie_len; |
1384 | u16 reason_code; | 1405 | u16 reason_code; |
1385 | bool local_state_change; | 1406 | bool local_state_change; |
1386 | }; | 1407 | }; |
1387 | 1408 | ||
1388 | /** | 1409 | /** |
1389 | * struct cfg80211_ibss_params - IBSS parameters | 1410 | * struct cfg80211_ibss_params - IBSS parameters |
1390 | * | 1411 | * |
1391 | * This structure defines the IBSS parameters for the join_ibss() | 1412 | * This structure defines the IBSS parameters for the join_ibss() |
1392 | * method. | 1413 | * method. |
1393 | * | 1414 | * |
1394 | * @ssid: The SSID, will always be non-null. | 1415 | * @ssid: The SSID, will always be non-null. |
1395 | * @ssid_len: The length of the SSID, will always be non-zero. | 1416 | * @ssid_len: The length of the SSID, will always be non-zero. |
1396 | * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not | 1417 | * @bssid: Fixed BSSID requested, maybe be %NULL, if set do not |
1397 | * search for IBSSs with a different BSSID. | 1418 | * search for IBSSs with a different BSSID. |
1398 | * @chandef: defines the channel to use if no other IBSS to join can be found | 1419 | * @chandef: defines the channel to use if no other IBSS to join can be found |
1399 | * @channel_fixed: The channel should be fixed -- do not search for | 1420 | * @channel_fixed: The channel should be fixed -- do not search for |
1400 | * IBSSs to join on other channels. | 1421 | * IBSSs to join on other channels. |
1401 | * @ie: information element(s) to include in the beacon | 1422 | * @ie: information element(s) to include in the beacon |
1402 | * @ie_len: length of that | 1423 | * @ie_len: length of that |
1403 | * @beacon_interval: beacon interval to use | 1424 | * @beacon_interval: beacon interval to use |
1404 | * @privacy: this is a protected network, keys will be configured | 1425 | * @privacy: this is a protected network, keys will be configured |
1405 | * after joining | 1426 | * after joining |
1406 | * @control_port: whether user space controls IEEE 802.1X port, i.e., | 1427 | * @control_port: whether user space controls IEEE 802.1X port, i.e., |
1407 | * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is | 1428 | * sets/clears %NL80211_STA_FLAG_AUTHORIZED. If true, the driver is |
1408 | * required to assume that the port is unauthorized until authorized by | 1429 | * required to assume that the port is unauthorized until authorized by |
1409 | * user space. Otherwise, port is marked authorized by default. | 1430 | * user space. Otherwise, port is marked authorized by default. |
1410 | * @basic_rates: bitmap of basic rates to use when creating the IBSS | 1431 | * @basic_rates: bitmap of basic rates to use when creating the IBSS |
1411 | * @mcast_rate: per-band multicast rate index + 1 (0: disabled) | 1432 | * @mcast_rate: per-band multicast rate index + 1 (0: disabled) |
1412 | */ | 1433 | */ |
1413 | struct cfg80211_ibss_params { | 1434 | struct cfg80211_ibss_params { |
1414 | u8 *ssid; | 1435 | u8 *ssid; |
1415 | u8 *bssid; | 1436 | u8 *bssid; |
1416 | struct cfg80211_chan_def chandef; | 1437 | struct cfg80211_chan_def chandef; |
1417 | u8 *ie; | 1438 | u8 *ie; |
1418 | u8 ssid_len, ie_len; | 1439 | u8 ssid_len, ie_len; |
1419 | u16 beacon_interval; | 1440 | u16 beacon_interval; |
1420 | u32 basic_rates; | 1441 | u32 basic_rates; |
1421 | bool channel_fixed; | 1442 | bool channel_fixed; |
1422 | bool privacy; | 1443 | bool privacy; |
1423 | bool control_port; | 1444 | bool control_port; |
1424 | int mcast_rate[IEEE80211_NUM_BANDS]; | 1445 | int mcast_rate[IEEE80211_NUM_BANDS]; |
1425 | }; | 1446 | }; |
1426 | 1447 | ||
1427 | /** | 1448 | /** |
1428 | * struct cfg80211_connect_params - Connection parameters | 1449 | * struct cfg80211_connect_params - Connection parameters |
1429 | * | 1450 | * |
1430 | * This structure provides information needed to complete IEEE 802.11 | 1451 | * This structure provides information needed to complete IEEE 802.11 |
1431 | * authentication and association. | 1452 | * authentication and association. |
1432 | * | 1453 | * |
1433 | * @channel: The channel to use or %NULL if not specified (auto-select based | 1454 | * @channel: The channel to use or %NULL if not specified (auto-select based |
1434 | * on scan results) | 1455 | * on scan results) |
1435 | * @bssid: The AP BSSID or %NULL if not specified (auto-select based on scan | 1456 | * @bssid: The AP BSSID or %NULL if not specified (auto-select based on scan |
1436 | * results) | 1457 | * results) |
1437 | * @ssid: SSID | 1458 | * @ssid: SSID |
1438 | * @ssid_len: Length of ssid in octets | 1459 | * @ssid_len: Length of ssid in octets |
1439 | * @auth_type: Authentication type (algorithm) | 1460 | * @auth_type: Authentication type (algorithm) |
1440 | * @ie: IEs for association request | 1461 | * @ie: IEs for association request |
1441 | * @ie_len: Length of assoc_ie in octets | 1462 | * @ie_len: Length of assoc_ie in octets |
1442 | * @privacy: indicates whether privacy-enabled APs should be used | 1463 | * @privacy: indicates whether privacy-enabled APs should be used |
1443 | * @crypto: crypto settings | 1464 | * @crypto: crypto settings |
1444 | * @key_len: length of WEP key for shared key authentication | 1465 | * @key_len: length of WEP key for shared key authentication |
1445 | * @key_idx: index of WEP key for shared key authentication | 1466 | * @key_idx: index of WEP key for shared key authentication |
1446 | * @key: WEP key for shared key authentication | 1467 | * @key: WEP key for shared key authentication |
1447 | * @flags: See &enum cfg80211_assoc_req_flags | 1468 | * @flags: See &enum cfg80211_assoc_req_flags |
1448 | * @bg_scan_period: Background scan period in seconds | 1469 | * @bg_scan_period: Background scan period in seconds |
1449 | * or -1 to indicate that default value is to be used. | 1470 | * or -1 to indicate that default value is to be used. |
1450 | * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask | 1471 | * @ht_capa: HT Capabilities over-rides. Values set in ht_capa_mask |
1451 | * will be used in ht_capa. Un-supported values will be ignored. | 1472 | * will be used in ht_capa. Un-supported values will be ignored. |
1452 | * @ht_capa_mask: The bits of ht_capa which are to be used. | 1473 | * @ht_capa_mask: The bits of ht_capa which are to be used. |
1453 | */ | 1474 | */ |
1454 | struct cfg80211_connect_params { | 1475 | struct cfg80211_connect_params { |
1455 | struct ieee80211_channel *channel; | 1476 | struct ieee80211_channel *channel; |
1456 | u8 *bssid; | 1477 | u8 *bssid; |
1457 | u8 *ssid; | 1478 | u8 *ssid; |
1458 | size_t ssid_len; | 1479 | size_t ssid_len; |
1459 | enum nl80211_auth_type auth_type; | 1480 | enum nl80211_auth_type auth_type; |
1460 | u8 *ie; | 1481 | u8 *ie; |
1461 | size_t ie_len; | 1482 | size_t ie_len; |
1462 | bool privacy; | 1483 | bool privacy; |
1463 | struct cfg80211_crypto_settings crypto; | 1484 | struct cfg80211_crypto_settings crypto; |
1464 | const u8 *key; | 1485 | const u8 *key; |
1465 | u8 key_len, key_idx; | 1486 | u8 key_len, key_idx; |
1466 | u32 flags; | 1487 | u32 flags; |
1467 | int bg_scan_period; | 1488 | int bg_scan_period; |
1468 | struct ieee80211_ht_cap ht_capa; | 1489 | struct ieee80211_ht_cap ht_capa; |
1469 | struct ieee80211_ht_cap ht_capa_mask; | 1490 | struct ieee80211_ht_cap ht_capa_mask; |
1470 | }; | 1491 | }; |
1471 | 1492 | ||
1472 | /** | 1493 | /** |
1473 | * enum wiphy_params_flags - set_wiphy_params bitfield values | 1494 | * enum wiphy_params_flags - set_wiphy_params bitfield values |
1474 | * @WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed | 1495 | * @WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed |
1475 | * @WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed | 1496 | * @WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed |
1476 | * @WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed | 1497 | * @WIPHY_PARAM_FRAG_THRESHOLD: wiphy->frag_threshold has changed |
1477 | * @WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed | 1498 | * @WIPHY_PARAM_RTS_THRESHOLD: wiphy->rts_threshold has changed |
1478 | * @WIPHY_PARAM_COVERAGE_CLASS: coverage class changed | 1499 | * @WIPHY_PARAM_COVERAGE_CLASS: coverage class changed |
1479 | */ | 1500 | */ |
1480 | enum wiphy_params_flags { | 1501 | enum wiphy_params_flags { |
1481 | WIPHY_PARAM_RETRY_SHORT = 1 << 0, | 1502 | WIPHY_PARAM_RETRY_SHORT = 1 << 0, |
1482 | WIPHY_PARAM_RETRY_LONG = 1 << 1, | 1503 | WIPHY_PARAM_RETRY_LONG = 1 << 1, |
1483 | WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, | 1504 | WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, |
1484 | WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, | 1505 | WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, |
1485 | WIPHY_PARAM_COVERAGE_CLASS = 1 << 4, | 1506 | WIPHY_PARAM_COVERAGE_CLASS = 1 << 4, |
1486 | }; | 1507 | }; |
1487 | 1508 | ||
1488 | /* | 1509 | /* |
1489 | * cfg80211_bitrate_mask - masks for bitrate control | 1510 | * cfg80211_bitrate_mask - masks for bitrate control |
1490 | */ | 1511 | */ |
1491 | struct cfg80211_bitrate_mask { | 1512 | struct cfg80211_bitrate_mask { |
1492 | struct { | 1513 | struct { |
1493 | u32 legacy; | 1514 | u32 legacy; |
1494 | u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; | 1515 | u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; |
1495 | } control[IEEE80211_NUM_BANDS]; | 1516 | } control[IEEE80211_NUM_BANDS]; |
1496 | }; | 1517 | }; |
1497 | /** | 1518 | /** |
1498 | * struct cfg80211_pmksa - PMK Security Association | 1519 | * struct cfg80211_pmksa - PMK Security Association |
1499 | * | 1520 | * |
1500 | * This structure is passed to the set/del_pmksa() method for PMKSA | 1521 | * This structure is passed to the set/del_pmksa() method for PMKSA |
1501 | * caching. | 1522 | * caching. |
1502 | * | 1523 | * |
1503 | * @bssid: The AP's BSSID. | 1524 | * @bssid: The AP's BSSID. |
1504 | * @pmkid: The PMK material itself. | 1525 | * @pmkid: The PMK material itself. |
1505 | */ | 1526 | */ |
1506 | struct cfg80211_pmksa { | 1527 | struct cfg80211_pmksa { |
1507 | u8 *bssid; | 1528 | u8 *bssid; |
1508 | u8 *pmkid; | 1529 | u8 *pmkid; |
1509 | }; | 1530 | }; |
1510 | 1531 | ||
1511 | /** | 1532 | /** |
1512 | * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern | 1533 | * struct cfg80211_wowlan_trig_pkt_pattern - packet pattern |
1513 | * @mask: bitmask where to match pattern and where to ignore bytes, | 1534 | * @mask: bitmask where to match pattern and where to ignore bytes, |
1514 | * one bit per byte, in same format as nl80211 | 1535 | * one bit per byte, in same format as nl80211 |
1515 | * @pattern: bytes to match where bitmask is 1 | 1536 | * @pattern: bytes to match where bitmask is 1 |
1516 | * @pattern_len: length of pattern (in bytes) | 1537 | * @pattern_len: length of pattern (in bytes) |
1517 | * | 1538 | * |
1518 | * Internal note: @mask and @pattern are allocated in one chunk of | 1539 | * Internal note: @mask and @pattern are allocated in one chunk of |
1519 | * memory, free @mask only! | 1540 | * memory, free @mask only! |
1520 | */ | 1541 | */ |
1521 | struct cfg80211_wowlan_trig_pkt_pattern { | 1542 | struct cfg80211_wowlan_trig_pkt_pattern { |
1522 | u8 *mask, *pattern; | 1543 | u8 *mask, *pattern; |
1523 | int pattern_len; | 1544 | int pattern_len; |
1524 | }; | 1545 | }; |
1525 | 1546 | ||
1526 | /** | 1547 | /** |
1527 | * struct cfg80211_wowlan - Wake on Wireless-LAN support info | 1548 | * struct cfg80211_wowlan - Wake on Wireless-LAN support info |
1528 | * | 1549 | * |
1529 | * This structure defines the enabled WoWLAN triggers for the device. | 1550 | * This structure defines the enabled WoWLAN triggers for the device. |
1530 | * @any: wake up on any activity -- special trigger if device continues | 1551 | * @any: wake up on any activity -- special trigger if device continues |
1531 | * operating as normal during suspend | 1552 | * operating as normal during suspend |
1532 | * @disconnect: wake up if getting disconnected | 1553 | * @disconnect: wake up if getting disconnected |
1533 | * @magic_pkt: wake up on receiving magic packet | 1554 | * @magic_pkt: wake up on receiving magic packet |
1534 | * @patterns: wake up on receiving packet matching a pattern | 1555 | * @patterns: wake up on receiving packet matching a pattern |
1535 | * @n_patterns: number of patterns | 1556 | * @n_patterns: number of patterns |
1536 | * @gtk_rekey_failure: wake up on GTK rekey failure | 1557 | * @gtk_rekey_failure: wake up on GTK rekey failure |
1537 | * @eap_identity_req: wake up on EAP identity request packet | 1558 | * @eap_identity_req: wake up on EAP identity request packet |
1538 | * @four_way_handshake: wake up on 4-way handshake | 1559 | * @four_way_handshake: wake up on 4-way handshake |
1539 | * @rfkill_release: wake up when rfkill is released | 1560 | * @rfkill_release: wake up when rfkill is released |
1540 | */ | 1561 | */ |
1541 | struct cfg80211_wowlan { | 1562 | struct cfg80211_wowlan { |
1542 | bool any, disconnect, magic_pkt, gtk_rekey_failure, | 1563 | bool any, disconnect, magic_pkt, gtk_rekey_failure, |
1543 | eap_identity_req, four_way_handshake, | 1564 | eap_identity_req, four_way_handshake, |
1544 | rfkill_release; | 1565 | rfkill_release; |
1545 | struct cfg80211_wowlan_trig_pkt_pattern *patterns; | 1566 | struct cfg80211_wowlan_trig_pkt_pattern *patterns; |
1546 | int n_patterns; | 1567 | int n_patterns; |
1547 | }; | 1568 | }; |
1548 | 1569 | ||
1549 | /** | 1570 | /** |
1550 | * struct cfg80211_gtk_rekey_data - rekey data | 1571 | * struct cfg80211_gtk_rekey_data - rekey data |
1551 | * @kek: key encryption key | 1572 | * @kek: key encryption key |
1552 | * @kck: key confirmation key | 1573 | * @kck: key confirmation key |
1553 | * @replay_ctr: replay counter | 1574 | * @replay_ctr: replay counter |
1554 | */ | 1575 | */ |
1555 | struct cfg80211_gtk_rekey_data { | 1576 | struct cfg80211_gtk_rekey_data { |
1556 | u8 kek[NL80211_KEK_LEN]; | 1577 | u8 kek[NL80211_KEK_LEN]; |
1557 | u8 kck[NL80211_KCK_LEN]; | 1578 | u8 kck[NL80211_KCK_LEN]; |
1558 | u8 replay_ctr[NL80211_REPLAY_CTR_LEN]; | 1579 | u8 replay_ctr[NL80211_REPLAY_CTR_LEN]; |
1559 | }; | 1580 | }; |
1560 | 1581 | ||
1561 | /** | 1582 | /** |
1562 | * struct cfg80211_ops - backend description for wireless configuration | 1583 | * struct cfg80211_ops - backend description for wireless configuration |
1563 | * | 1584 | * |
1564 | * This struct is registered by fullmac card drivers and/or wireless stacks | 1585 | * This struct is registered by fullmac card drivers and/or wireless stacks |
1565 | * in order to handle configuration requests on their interfaces. | 1586 | * in order to handle configuration requests on their interfaces. |
1566 | * | 1587 | * |
1567 | * All callbacks except where otherwise noted should return 0 | 1588 | * All callbacks except where otherwise noted should return 0 |
1568 | * on success or a negative error code. | 1589 | * on success or a negative error code. |
1569 | * | 1590 | * |
1570 | * All operations are currently invoked under rtnl for consistency with the | 1591 | * All operations are currently invoked under rtnl for consistency with the |
1571 | * wireless extensions but this is subject to reevaluation as soon as this | 1592 | * wireless extensions but this is subject to reevaluation as soon as this |
1572 | * code is used more widely and we have a first user without wext. | 1593 | * code is used more widely and we have a first user without wext. |
1573 | * | 1594 | * |
1574 | * @suspend: wiphy device needs to be suspended. The variable @wow will | 1595 | * @suspend: wiphy device needs to be suspended. The variable @wow will |
1575 | * be %NULL or contain the enabled Wake-on-Wireless triggers that are | 1596 | * be %NULL or contain the enabled Wake-on-Wireless triggers that are |
1576 | * configured for the device. | 1597 | * configured for the device. |
1577 | * @resume: wiphy device needs to be resumed | 1598 | * @resume: wiphy device needs to be resumed |
1578 | * @set_wakeup: Called when WoWLAN is enabled/disabled, use this callback | 1599 | * @set_wakeup: Called when WoWLAN is enabled/disabled, use this callback |
1579 | * to call device_set_wakeup_enable() to enable/disable wakeup from | 1600 | * to call device_set_wakeup_enable() to enable/disable wakeup from |
1580 | * the device. | 1601 | * the device. |
1581 | * | 1602 | * |
1582 | * @add_virtual_intf: create a new virtual interface with the given name, | 1603 | * @add_virtual_intf: create a new virtual interface with the given name, |
1583 | * must set the struct wireless_dev's iftype. Beware: You must create | 1604 | * must set the struct wireless_dev's iftype. Beware: You must create |
1584 | * the new netdev in the wiphy's network namespace! Returns the struct | 1605 | * the new netdev in the wiphy's network namespace! Returns the struct |
1585 | * wireless_dev, or an ERR_PTR. For P2P device wdevs, the driver must | 1606 | * wireless_dev, or an ERR_PTR. For P2P device wdevs, the driver must |
1586 | * also set the address member in the wdev. | 1607 | * also set the address member in the wdev. |
1587 | * | 1608 | * |
1588 | * @del_virtual_intf: remove the virtual interface | 1609 | * @del_virtual_intf: remove the virtual interface |
1589 | * | 1610 | * |
1590 | * @change_virtual_intf: change type/configuration of virtual interface, | 1611 | * @change_virtual_intf: change type/configuration of virtual interface, |
1591 | * keep the struct wireless_dev's iftype updated. | 1612 | * keep the struct wireless_dev's iftype updated. |
1592 | * | 1613 | * |
1593 | * @add_key: add a key with the given parameters. @mac_addr will be %NULL | 1614 | * @add_key: add a key with the given parameters. @mac_addr will be %NULL |
1594 | * when adding a group key. | 1615 | * when adding a group key. |
1595 | * | 1616 | * |
1596 | * @get_key: get information about the key with the given parameters. | 1617 | * @get_key: get information about the key with the given parameters. |
1597 | * @mac_addr will be %NULL when requesting information for a group | 1618 | * @mac_addr will be %NULL when requesting information for a group |
1598 | * key. All pointers given to the @callback function need not be valid | 1619 | * key. All pointers given to the @callback function need not be valid |
1599 | * after it returns. This function should return an error if it is | 1620 | * after it returns. This function should return an error if it is |
1600 | * not possible to retrieve the key, -ENOENT if it doesn't exist. | 1621 | * not possible to retrieve the key, -ENOENT if it doesn't exist. |
1601 | * | 1622 | * |
1602 | * @del_key: remove a key given the @mac_addr (%NULL for a group key) | 1623 | * @del_key: remove a key given the @mac_addr (%NULL for a group key) |
1603 | * and @key_index, return -ENOENT if the key doesn't exist. | 1624 | * and @key_index, return -ENOENT if the key doesn't exist. |
1604 | * | 1625 | * |
1605 | * @set_default_key: set the default key on an interface | 1626 | * @set_default_key: set the default key on an interface |
1606 | * | 1627 | * |
1607 | * @set_default_mgmt_key: set the default management frame key on an interface | 1628 | * @set_default_mgmt_key: set the default management frame key on an interface |
1608 | * | 1629 | * |
1609 | * @set_rekey_data: give the data necessary for GTK rekeying to the driver | 1630 | * @set_rekey_data: give the data necessary for GTK rekeying to the driver |
1610 | * | 1631 | * |
1611 | * @start_ap: Start acting in AP mode defined by the parameters. | 1632 | * @start_ap: Start acting in AP mode defined by the parameters. |
1612 | * @change_beacon: Change the beacon parameters for an access point mode | 1633 | * @change_beacon: Change the beacon parameters for an access point mode |
1613 | * interface. This should reject the call when AP mode wasn't started. | 1634 | * interface. This should reject the call when AP mode wasn't started. |
1614 | * @stop_ap: Stop being an AP, including stopping beaconing. | 1635 | * @stop_ap: Stop being an AP, including stopping beaconing. |
1615 | * | 1636 | * |
1616 | * @add_station: Add a new station. | 1637 | * @add_station: Add a new station. |
1617 | * @del_station: Remove a station; @mac may be NULL to remove all stations. | 1638 | * @del_station: Remove a station; @mac may be NULL to remove all stations. |
1618 | * @change_station: Modify a given station. Note that flags changes are not much | 1639 | * @change_station: Modify a given station. Note that flags changes are not much |
1619 | * validated in cfg80211, in particular the auth/assoc/authorized flags | 1640 | * validated in cfg80211, in particular the auth/assoc/authorized flags |
1620 | * might come to the driver in invalid combinations -- make sure to check | 1641 | * might come to the driver in invalid combinations -- make sure to check |
1621 | * them, also against the existing state! Also, supported_rates changes are | 1642 | * them, also against the existing state! Also, supported_rates changes are |
1622 | * not checked in station mode -- drivers need to reject (or ignore) them | 1643 | * not checked in station mode -- drivers need to reject (or ignore) them |
1623 | * for anything but TDLS peers. | 1644 | * for anything but TDLS peers. |
1624 | * @get_station: get station information for the station identified by @mac | 1645 | * @get_station: get station information for the station identified by @mac |
1625 | * @dump_station: dump station callback -- resume dump at index @idx | 1646 | * @dump_station: dump station callback -- resume dump at index @idx |
1626 | * | 1647 | * |
1627 | * @add_mpath: add a fixed mesh path | 1648 | * @add_mpath: add a fixed mesh path |
1628 | * @del_mpath: delete a given mesh path | 1649 | * @del_mpath: delete a given mesh path |
1629 | * @change_mpath: change a given mesh path | 1650 | * @change_mpath: change a given mesh path |
1630 | * @get_mpath: get a mesh path for the given parameters | 1651 | * @get_mpath: get a mesh path for the given parameters |
1631 | * @dump_mpath: dump mesh path callback -- resume dump at index @idx | 1652 | * @dump_mpath: dump mesh path callback -- resume dump at index @idx |
1632 | * @join_mesh: join the mesh network with the specified parameters | 1653 | * @join_mesh: join the mesh network with the specified parameters |
1633 | * @leave_mesh: leave the current mesh network | 1654 | * @leave_mesh: leave the current mesh network |
1634 | * | 1655 | * |
1635 | * @get_mesh_config: Get the current mesh configuration | 1656 | * @get_mesh_config: Get the current mesh configuration |
1636 | * | 1657 | * |
1637 | * @update_mesh_config: Update mesh parameters on a running mesh. | 1658 | * @update_mesh_config: Update mesh parameters on a running mesh. |
1638 | * The mask is a bitfield which tells us which parameters to | 1659 | * The mask is a bitfield which tells us which parameters to |
1639 | * set, and which to leave alone. | 1660 | * set, and which to leave alone. |
1640 | * | 1661 | * |
1641 | * @change_bss: Modify parameters for a given BSS. | 1662 | * @change_bss: Modify parameters for a given BSS. |
1642 | * | 1663 | * |
1643 | * @set_txq_params: Set TX queue parameters | 1664 | * @set_txq_params: Set TX queue parameters |
1644 | * | 1665 | * |
1645 | * @libertas_set_mesh_channel: Only for backward compatibility for libertas, | 1666 | * @libertas_set_mesh_channel: Only for backward compatibility for libertas, |
1646 | * as it doesn't implement join_mesh and needs to set the channel to | 1667 | * as it doesn't implement join_mesh and needs to set the channel to |
1647 | * join the mesh instead. | 1668 | * join the mesh instead. |
1648 | * | 1669 | * |
1649 | * @set_monitor_channel: Set the monitor mode channel for the device. If other | 1670 | * @set_monitor_channel: Set the monitor mode channel for the device. If other |
1650 | * interfaces are active this callback should reject the configuration. | 1671 | * interfaces are active this callback should reject the configuration. |
1651 | * If no interfaces are active or the device is down, the channel should | 1672 | * If no interfaces are active or the device is down, the channel should |
1652 | * be stored for when a monitor interface becomes active. | 1673 | * be stored for when a monitor interface becomes active. |
1653 | * | 1674 | * |
1654 | * @scan: Request to do a scan. If returning zero, the scan request is given | 1675 | * @scan: Request to do a scan. If returning zero, the scan request is given |
1655 | * the driver, and will be valid until passed to cfg80211_scan_done(). | 1676 | * the driver, and will be valid until passed to cfg80211_scan_done(). |
1656 | * For scan results, call cfg80211_inform_bss(); you can call this outside | 1677 | * For scan results, call cfg80211_inform_bss(); you can call this outside |
1657 | * the scan/scan_done bracket too. | 1678 | * the scan/scan_done bracket too. |
1658 | * | 1679 | * |
1659 | * @auth: Request to authenticate with the specified peer | 1680 | * @auth: Request to authenticate with the specified peer |
1660 | * @assoc: Request to (re)associate with the specified peer | 1681 | * @assoc: Request to (re)associate with the specified peer |
1661 | * @deauth: Request to deauthenticate from the specified peer | 1682 | * @deauth: Request to deauthenticate from the specified peer |
1662 | * @disassoc: Request to disassociate from the specified peer | 1683 | * @disassoc: Request to disassociate from the specified peer |
1663 | * | 1684 | * |
1664 | * @connect: Connect to the ESS with the specified parameters. When connected, | 1685 | * @connect: Connect to the ESS with the specified parameters. When connected, |
1665 | * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. | 1686 | * call cfg80211_connect_result() with status code %WLAN_STATUS_SUCCESS. |
1666 | * If the connection fails for some reason, call cfg80211_connect_result() | 1687 | * If the connection fails for some reason, call cfg80211_connect_result() |
1667 | * with the status from the AP. | 1688 | * with the status from the AP. |
1668 | * @disconnect: Disconnect from the BSS/ESS. | 1689 | * @disconnect: Disconnect from the BSS/ESS. |
1669 | * | 1690 | * |
1670 | * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call | 1691 | * @join_ibss: Join the specified IBSS (or create if necessary). Once done, call |
1671 | * cfg80211_ibss_joined(), also call that function when changing BSSID due | 1692 | * cfg80211_ibss_joined(), also call that function when changing BSSID due |
1672 | * to a merge. | 1693 | * to a merge. |
1673 | * @leave_ibss: Leave the IBSS. | 1694 | * @leave_ibss: Leave the IBSS. |
1674 | * | 1695 | * |
1675 | * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or | 1696 | * @set_mcast_rate: Set the specified multicast rate (only if vif is in ADHOC or |
1676 | * MESH mode) | 1697 | * MESH mode) |
1677 | * | 1698 | * |
1678 | * @set_wiphy_params: Notify that wiphy parameters have changed; | 1699 | * @set_wiphy_params: Notify that wiphy parameters have changed; |
1679 | * @changed bitfield (see &enum wiphy_params_flags) describes which values | 1700 | * @changed bitfield (see &enum wiphy_params_flags) describes which values |
1680 | * have changed. The actual parameter values are available in | 1701 | * have changed. The actual parameter values are available in |
1681 | * struct wiphy. If returning an error, no value should be changed. | 1702 | * struct wiphy. If returning an error, no value should be changed. |
1682 | * | 1703 | * |
1683 | * @set_tx_power: set the transmit power according to the parameters, | 1704 | * @set_tx_power: set the transmit power according to the parameters, |
1684 | * the power passed is in mBm, to get dBm use MBM_TO_DBM(). The | 1705 | * the power passed is in mBm, to get dBm use MBM_TO_DBM(). The |
1685 | * wdev may be %NULL if power was set for the wiphy, and will | 1706 | * wdev may be %NULL if power was set for the wiphy, and will |
1686 | * always be %NULL unless the driver supports per-vif TX power | 1707 | * always be %NULL unless the driver supports per-vif TX power |
1687 | * (as advertised by the nl80211 feature flag.) | 1708 | * (as advertised by the nl80211 feature flag.) |
1688 | * @get_tx_power: store the current TX power into the dbm variable; | 1709 | * @get_tx_power: store the current TX power into the dbm variable; |
1689 | * return 0 if successful | 1710 | * return 0 if successful |
1690 | * | 1711 | * |
1691 | * @set_wds_peer: set the WDS peer for a WDS interface | 1712 | * @set_wds_peer: set the WDS peer for a WDS interface |
1692 | * | 1713 | * |
1693 | * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting | 1714 | * @rfkill_poll: polls the hw rfkill line, use cfg80211 reporting |
1694 | * functions to adjust rfkill hw state | 1715 | * functions to adjust rfkill hw state |
1695 | * | 1716 | * |
1696 | * @dump_survey: get site survey information. | 1717 | * @dump_survey: get site survey information. |
1697 | * | 1718 | * |
1698 | * @remain_on_channel: Request the driver to remain awake on the specified | 1719 | * @remain_on_channel: Request the driver to remain awake on the specified |
1699 | * channel for the specified duration to complete an off-channel | 1720 | * channel for the specified duration to complete an off-channel |
1700 | * operation (e.g., public action frame exchange). When the driver is | 1721 | * operation (e.g., public action frame exchange). When the driver is |
1701 | * ready on the requested channel, it must indicate this with an event | 1722 | * ready on the requested channel, it must indicate this with an event |
1702 | * notification by calling cfg80211_ready_on_channel(). | 1723 | * notification by calling cfg80211_ready_on_channel(). |
1703 | * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. | 1724 | * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation. |
1704 | * This allows the operation to be terminated prior to timeout based on | 1725 | * This allows the operation to be terminated prior to timeout based on |
1705 | * the duration value. | 1726 | * the duration value. |
1706 | * @mgmt_tx: Transmit a management frame. | 1727 | * @mgmt_tx: Transmit a management frame. |
1707 | * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management | 1728 | * @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management |
1708 | * frame on another channel | 1729 | * frame on another channel |
1709 | * | 1730 | * |
1710 | * @testmode_cmd: run a test mode command | 1731 | * @testmode_cmd: run a test mode command |
1711 | * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be | 1732 | * @testmode_dump: Implement a test mode dump. The cb->args[2] and up may be |
1712 | * used by the function, but 0 and 1 must not be touched. Additionally, | 1733 | * used by the function, but 0 and 1 must not be touched. Additionally, |
1713 | * return error codes other than -ENOBUFS and -ENOENT will terminate the | 1734 | * return error codes other than -ENOBUFS and -ENOENT will terminate the |
1714 | * dump and return to userspace with an error, so be careful. If any data | 1735 | * dump and return to userspace with an error, so be careful. If any data |
1715 | * was passed in from userspace then the data/len arguments will be present | 1736 | * was passed in from userspace then the data/len arguments will be present |
1716 | * and point to the data contained in %NL80211_ATTR_TESTDATA. | 1737 | * and point to the data contained in %NL80211_ATTR_TESTDATA. |
1717 | * | 1738 | * |
1718 | * @set_bitrate_mask: set the bitrate mask configuration | 1739 | * @set_bitrate_mask: set the bitrate mask configuration |
1719 | * | 1740 | * |
1720 | * @set_pmksa: Cache a PMKID for a BSSID. This is mostly useful for fullmac | 1741 | * @set_pmksa: Cache a PMKID for a BSSID. This is mostly useful for fullmac |
1721 | * devices running firmwares capable of generating the (re) association | 1742 | * devices running firmwares capable of generating the (re) association |
1722 | * RSN IE. It allows for faster roaming between WPA2 BSSIDs. | 1743 | * RSN IE. It allows for faster roaming between WPA2 BSSIDs. |
1723 | * @del_pmksa: Delete a cached PMKID. | 1744 | * @del_pmksa: Delete a cached PMKID. |
1724 | * @flush_pmksa: Flush all cached PMKIDs. | 1745 | * @flush_pmksa: Flush all cached PMKIDs. |
1725 | * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 | 1746 | * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 |
1726 | * allows the driver to adjust the dynamic ps timeout value. | 1747 | * allows the driver to adjust the dynamic ps timeout value. |
1727 | * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. | 1748 | * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. |
1728 | * @set_cqm_txe_config: Configure connection quality monitor TX error | 1749 | * @set_cqm_txe_config: Configure connection quality monitor TX error |
1729 | * thresholds. | 1750 | * thresholds. |
1730 | * @sched_scan_start: Tell the driver to start a scheduled scan. | 1751 | * @sched_scan_start: Tell the driver to start a scheduled scan. |
1731 | * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. | 1752 | * @sched_scan_stop: Tell the driver to stop an ongoing scheduled scan. |
1732 | * | 1753 | * |
1733 | * @mgmt_frame_register: Notify driver that a management frame type was | 1754 | * @mgmt_frame_register: Notify driver that a management frame type was |
1734 | * registered. Note that this callback may not sleep, and cannot run | 1755 | * registered. Note that this callback may not sleep, and cannot run |
1735 | * concurrently with itself. | 1756 | * concurrently with itself. |
1736 | * | 1757 | * |
1737 | * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. | 1758 | * @set_antenna: Set antenna configuration (tx_ant, rx_ant) on the device. |
1738 | * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may | 1759 | * Parameters are bitmaps of allowed antennas to use for TX/RX. Drivers may |
1739 | * reject TX/RX mask combinations they cannot support by returning -EINVAL | 1760 | * reject TX/RX mask combinations they cannot support by returning -EINVAL |
1740 | * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX). | 1761 | * (also see nl80211.h @NL80211_ATTR_WIPHY_ANTENNA_TX). |
1741 | * | 1762 | * |
1742 | * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant). | 1763 | * @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant). |
1743 | * | 1764 | * |
1744 | * @set_ringparam: Set tx and rx ring sizes. | 1765 | * @set_ringparam: Set tx and rx ring sizes. |
1745 | * | 1766 | * |
1746 | * @get_ringparam: Get tx and rx ring current and maximum sizes. | 1767 | * @get_ringparam: Get tx and rx ring current and maximum sizes. |
1747 | * | 1768 | * |
1748 | * @tdls_mgmt: Transmit a TDLS management frame. | 1769 | * @tdls_mgmt: Transmit a TDLS management frame. |
1749 | * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup). | 1770 | * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup). |
1750 | * | 1771 | * |
1751 | * @probe_client: probe an associated client, must return a cookie that it | 1772 | * @probe_client: probe an associated client, must return a cookie that it |
1752 | * later passes to cfg80211_probe_status(). | 1773 | * later passes to cfg80211_probe_status(). |
1753 | * | 1774 | * |
1754 | * @set_noack_map: Set the NoAck Map for the TIDs. | 1775 | * @set_noack_map: Set the NoAck Map for the TIDs. |
1755 | * | 1776 | * |
1756 | * @get_et_sset_count: Ethtool API to get string-set count. | 1777 | * @get_et_sset_count: Ethtool API to get string-set count. |
1757 | * See @ethtool_ops.get_sset_count | 1778 | * See @ethtool_ops.get_sset_count |
1758 | * | 1779 | * |
1759 | * @get_et_stats: Ethtool API to get a set of u64 stats. | 1780 | * @get_et_stats: Ethtool API to get a set of u64 stats. |
1760 | * See @ethtool_ops.get_ethtool_stats | 1781 | * See @ethtool_ops.get_ethtool_stats |
1761 | * | 1782 | * |
1762 | * @get_et_strings: Ethtool API to get a set of strings to describe stats | 1783 | * @get_et_strings: Ethtool API to get a set of strings to describe stats |
1763 | * and perhaps other supported types of ethtool data-sets. | 1784 | * and perhaps other supported types of ethtool data-sets. |
1764 | * See @ethtool_ops.get_strings | 1785 | * See @ethtool_ops.get_strings |
1765 | * | 1786 | * |
1766 | * @get_channel: Get the current operating channel for the virtual interface. | 1787 | * @get_channel: Get the current operating channel for the virtual interface. |
1767 | * For monitor interfaces, it should return %NULL unless there's a single | 1788 | * For monitor interfaces, it should return %NULL unless there's a single |
1768 | * current monitoring channel. | 1789 | * current monitoring channel. |
1769 | * | 1790 | * |
1770 | * @start_p2p_device: Start the given P2P device. | 1791 | * @start_p2p_device: Start the given P2P device. |
1771 | * @stop_p2p_device: Stop the given P2P device. | 1792 | * @stop_p2p_device: Stop the given P2P device. |
1772 | */ | 1793 | */ |
1773 | struct cfg80211_ops { | 1794 | struct cfg80211_ops { |
1774 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); | 1795 | int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); |
1775 | int (*resume)(struct wiphy *wiphy); | 1796 | int (*resume)(struct wiphy *wiphy); |
1776 | void (*set_wakeup)(struct wiphy *wiphy, bool enabled); | 1797 | void (*set_wakeup)(struct wiphy *wiphy, bool enabled); |
1777 | 1798 | ||
1778 | struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy, | 1799 | struct wireless_dev * (*add_virtual_intf)(struct wiphy *wiphy, |
1779 | const char *name, | 1800 | const char *name, |
1780 | enum nl80211_iftype type, | 1801 | enum nl80211_iftype type, |
1781 | u32 *flags, | 1802 | u32 *flags, |
1782 | struct vif_params *params); | 1803 | struct vif_params *params); |
1783 | int (*del_virtual_intf)(struct wiphy *wiphy, | 1804 | int (*del_virtual_intf)(struct wiphy *wiphy, |
1784 | struct wireless_dev *wdev); | 1805 | struct wireless_dev *wdev); |
1785 | int (*change_virtual_intf)(struct wiphy *wiphy, | 1806 | int (*change_virtual_intf)(struct wiphy *wiphy, |
1786 | struct net_device *dev, | 1807 | struct net_device *dev, |
1787 | enum nl80211_iftype type, u32 *flags, | 1808 | enum nl80211_iftype type, u32 *flags, |
1788 | struct vif_params *params); | 1809 | struct vif_params *params); |
1789 | 1810 | ||
1790 | int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, | 1811 | int (*add_key)(struct wiphy *wiphy, struct net_device *netdev, |
1791 | u8 key_index, bool pairwise, const u8 *mac_addr, | 1812 | u8 key_index, bool pairwise, const u8 *mac_addr, |
1792 | struct key_params *params); | 1813 | struct key_params *params); |
1793 | int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, | 1814 | int (*get_key)(struct wiphy *wiphy, struct net_device *netdev, |
1794 | u8 key_index, bool pairwise, const u8 *mac_addr, | 1815 | u8 key_index, bool pairwise, const u8 *mac_addr, |
1795 | void *cookie, | 1816 | void *cookie, |
1796 | void (*callback)(void *cookie, struct key_params*)); | 1817 | void (*callback)(void *cookie, struct key_params*)); |
1797 | int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, | 1818 | int (*del_key)(struct wiphy *wiphy, struct net_device *netdev, |
1798 | u8 key_index, bool pairwise, const u8 *mac_addr); | 1819 | u8 key_index, bool pairwise, const u8 *mac_addr); |
1799 | int (*set_default_key)(struct wiphy *wiphy, | 1820 | int (*set_default_key)(struct wiphy *wiphy, |
1800 | struct net_device *netdev, | 1821 | struct net_device *netdev, |
1801 | u8 key_index, bool unicast, bool multicast); | 1822 | u8 key_index, bool unicast, bool multicast); |
1802 | int (*set_default_mgmt_key)(struct wiphy *wiphy, | 1823 | int (*set_default_mgmt_key)(struct wiphy *wiphy, |
1803 | struct net_device *netdev, | 1824 | struct net_device *netdev, |
1804 | u8 key_index); | 1825 | u8 key_index); |
1805 | 1826 | ||
1806 | int (*start_ap)(struct wiphy *wiphy, struct net_device *dev, | 1827 | int (*start_ap)(struct wiphy *wiphy, struct net_device *dev, |
1807 | struct cfg80211_ap_settings *settings); | 1828 | struct cfg80211_ap_settings *settings); |
1808 | int (*change_beacon)(struct wiphy *wiphy, struct net_device *dev, | 1829 | int (*change_beacon)(struct wiphy *wiphy, struct net_device *dev, |
1809 | struct cfg80211_beacon_data *info); | 1830 | struct cfg80211_beacon_data *info); |
1810 | int (*stop_ap)(struct wiphy *wiphy, struct net_device *dev); | 1831 | int (*stop_ap)(struct wiphy *wiphy, struct net_device *dev); |
1811 | 1832 | ||
1812 | 1833 | ||
1813 | int (*add_station)(struct wiphy *wiphy, struct net_device *dev, | 1834 | int (*add_station)(struct wiphy *wiphy, struct net_device *dev, |
1814 | u8 *mac, struct station_parameters *params); | 1835 | u8 *mac, struct station_parameters *params); |
1815 | int (*del_station)(struct wiphy *wiphy, struct net_device *dev, | 1836 | int (*del_station)(struct wiphy *wiphy, struct net_device *dev, |
1816 | u8 *mac); | 1837 | u8 *mac); |
1817 | int (*change_station)(struct wiphy *wiphy, struct net_device *dev, | 1838 | int (*change_station)(struct wiphy *wiphy, struct net_device *dev, |
1818 | u8 *mac, struct station_parameters *params); | 1839 | u8 *mac, struct station_parameters *params); |
1819 | int (*get_station)(struct wiphy *wiphy, struct net_device *dev, | 1840 | int (*get_station)(struct wiphy *wiphy, struct net_device *dev, |
1820 | u8 *mac, struct station_info *sinfo); | 1841 | u8 *mac, struct station_info *sinfo); |
1821 | int (*dump_station)(struct wiphy *wiphy, struct net_device *dev, | 1842 | int (*dump_station)(struct wiphy *wiphy, struct net_device *dev, |
1822 | int idx, u8 *mac, struct station_info *sinfo); | 1843 | int idx, u8 *mac, struct station_info *sinfo); |
1823 | 1844 | ||
1824 | int (*add_mpath)(struct wiphy *wiphy, struct net_device *dev, | 1845 | int (*add_mpath)(struct wiphy *wiphy, struct net_device *dev, |
1825 | u8 *dst, u8 *next_hop); | 1846 | u8 *dst, u8 *next_hop); |
1826 | int (*del_mpath)(struct wiphy *wiphy, struct net_device *dev, | 1847 | int (*del_mpath)(struct wiphy *wiphy, struct net_device *dev, |
1827 | u8 *dst); | 1848 | u8 *dst); |
1828 | int (*change_mpath)(struct wiphy *wiphy, struct net_device *dev, | 1849 | int (*change_mpath)(struct wiphy *wiphy, struct net_device *dev, |
1829 | u8 *dst, u8 *next_hop); | 1850 | u8 *dst, u8 *next_hop); |
1830 | int (*get_mpath)(struct wiphy *wiphy, struct net_device *dev, | 1851 | int (*get_mpath)(struct wiphy *wiphy, struct net_device *dev, |
1831 | u8 *dst, u8 *next_hop, | 1852 | u8 *dst, u8 *next_hop, |
1832 | struct mpath_info *pinfo); | 1853 | struct mpath_info *pinfo); |
1833 | int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, | 1854 | int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, |
1834 | int idx, u8 *dst, u8 *next_hop, | 1855 | int idx, u8 *dst, u8 *next_hop, |
1835 | struct mpath_info *pinfo); | 1856 | struct mpath_info *pinfo); |
1836 | int (*get_mesh_config)(struct wiphy *wiphy, | 1857 | int (*get_mesh_config)(struct wiphy *wiphy, |
1837 | struct net_device *dev, | 1858 | struct net_device *dev, |
1838 | struct mesh_config *conf); | 1859 | struct mesh_config *conf); |
1839 | int (*update_mesh_config)(struct wiphy *wiphy, | 1860 | int (*update_mesh_config)(struct wiphy *wiphy, |
1840 | struct net_device *dev, u32 mask, | 1861 | struct net_device *dev, u32 mask, |
1841 | const struct mesh_config *nconf); | 1862 | const struct mesh_config *nconf); |
1842 | int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev, | 1863 | int (*join_mesh)(struct wiphy *wiphy, struct net_device *dev, |
1843 | const struct mesh_config *conf, | 1864 | const struct mesh_config *conf, |
1844 | const struct mesh_setup *setup); | 1865 | const struct mesh_setup *setup); |
1845 | int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); | 1866 | int (*leave_mesh)(struct wiphy *wiphy, struct net_device *dev); |
1846 | 1867 | ||
1847 | int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, | 1868 | int (*change_bss)(struct wiphy *wiphy, struct net_device *dev, |
1848 | struct bss_parameters *params); | 1869 | struct bss_parameters *params); |
1849 | 1870 | ||
1850 | int (*set_txq_params)(struct wiphy *wiphy, struct net_device *dev, | 1871 | int (*set_txq_params)(struct wiphy *wiphy, struct net_device *dev, |
1851 | struct ieee80211_txq_params *params); | 1872 | struct ieee80211_txq_params *params); |
1852 | 1873 | ||
1853 | int (*libertas_set_mesh_channel)(struct wiphy *wiphy, | 1874 | int (*libertas_set_mesh_channel)(struct wiphy *wiphy, |
1854 | struct net_device *dev, | 1875 | struct net_device *dev, |
1855 | struct ieee80211_channel *chan); | 1876 | struct ieee80211_channel *chan); |
1856 | 1877 | ||
1857 | int (*set_monitor_channel)(struct wiphy *wiphy, | 1878 | int (*set_monitor_channel)(struct wiphy *wiphy, |
1858 | struct cfg80211_chan_def *chandef); | 1879 | struct cfg80211_chan_def *chandef); |
1859 | 1880 | ||
1860 | int (*scan)(struct wiphy *wiphy, | 1881 | int (*scan)(struct wiphy *wiphy, |
1861 | struct cfg80211_scan_request *request); | 1882 | struct cfg80211_scan_request *request); |
1862 | 1883 | ||
1863 | int (*auth)(struct wiphy *wiphy, struct net_device *dev, | 1884 | int (*auth)(struct wiphy *wiphy, struct net_device *dev, |
1864 | struct cfg80211_auth_request *req); | 1885 | struct cfg80211_auth_request *req); |
1865 | int (*assoc)(struct wiphy *wiphy, struct net_device *dev, | 1886 | int (*assoc)(struct wiphy *wiphy, struct net_device *dev, |
1866 | struct cfg80211_assoc_request *req); | 1887 | struct cfg80211_assoc_request *req); |
1867 | int (*deauth)(struct wiphy *wiphy, struct net_device *dev, | 1888 | int (*deauth)(struct wiphy *wiphy, struct net_device *dev, |
1868 | struct cfg80211_deauth_request *req); | 1889 | struct cfg80211_deauth_request *req); |
1869 | int (*disassoc)(struct wiphy *wiphy, struct net_device *dev, | 1890 | int (*disassoc)(struct wiphy *wiphy, struct net_device *dev, |
1870 | struct cfg80211_disassoc_request *req); | 1891 | struct cfg80211_disassoc_request *req); |
1871 | 1892 | ||
1872 | int (*connect)(struct wiphy *wiphy, struct net_device *dev, | 1893 | int (*connect)(struct wiphy *wiphy, struct net_device *dev, |
1873 | struct cfg80211_connect_params *sme); | 1894 | struct cfg80211_connect_params *sme); |
1874 | int (*disconnect)(struct wiphy *wiphy, struct net_device *dev, | 1895 | int (*disconnect)(struct wiphy *wiphy, struct net_device *dev, |
1875 | u16 reason_code); | 1896 | u16 reason_code); |
1876 | 1897 | ||
1877 | int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev, | 1898 | int (*join_ibss)(struct wiphy *wiphy, struct net_device *dev, |
1878 | struct cfg80211_ibss_params *params); | 1899 | struct cfg80211_ibss_params *params); |
1879 | int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); | 1900 | int (*leave_ibss)(struct wiphy *wiphy, struct net_device *dev); |
1880 | 1901 | ||
1881 | int (*set_mcast_rate)(struct wiphy *wiphy, struct net_device *dev, | 1902 | int (*set_mcast_rate)(struct wiphy *wiphy, struct net_device *dev, |
1882 | int rate[IEEE80211_NUM_BANDS]); | 1903 | int rate[IEEE80211_NUM_BANDS]); |
1883 | 1904 | ||
1884 | int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); | 1905 | int (*set_wiphy_params)(struct wiphy *wiphy, u32 changed); |
1885 | 1906 | ||
1886 | int (*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, | 1907 | int (*set_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, |
1887 | enum nl80211_tx_power_setting type, int mbm); | 1908 | enum nl80211_tx_power_setting type, int mbm); |
1888 | int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, | 1909 | int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, |
1889 | int *dbm); | 1910 | int *dbm); |
1890 | 1911 | ||
1891 | int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, | 1912 | int (*set_wds_peer)(struct wiphy *wiphy, struct net_device *dev, |
1892 | const u8 *addr); | 1913 | const u8 *addr); |
1893 | 1914 | ||
1894 | void (*rfkill_poll)(struct wiphy *wiphy); | 1915 | void (*rfkill_poll)(struct wiphy *wiphy); |
1895 | 1916 | ||
1896 | #ifdef CONFIG_NL80211_TESTMODE | 1917 | #ifdef CONFIG_NL80211_TESTMODE |
1897 | int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len); | 1918 | int (*testmode_cmd)(struct wiphy *wiphy, void *data, int len); |
1898 | int (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb, | 1919 | int (*testmode_dump)(struct wiphy *wiphy, struct sk_buff *skb, |
1899 | struct netlink_callback *cb, | 1920 | struct netlink_callback *cb, |
1900 | void *data, int len); | 1921 | void *data, int len); |
1901 | #endif | 1922 | #endif |
1902 | 1923 | ||
1903 | int (*set_bitrate_mask)(struct wiphy *wiphy, | 1924 | int (*set_bitrate_mask)(struct wiphy *wiphy, |
1904 | struct net_device *dev, | 1925 | struct net_device *dev, |
1905 | const u8 *peer, | 1926 | const u8 *peer, |
1906 | const struct cfg80211_bitrate_mask *mask); | 1927 | const struct cfg80211_bitrate_mask *mask); |
1907 | 1928 | ||
1908 | int (*dump_survey)(struct wiphy *wiphy, struct net_device *netdev, | 1929 | int (*dump_survey)(struct wiphy *wiphy, struct net_device *netdev, |
1909 | int idx, struct survey_info *info); | 1930 | int idx, struct survey_info *info); |
1910 | 1931 | ||
1911 | int (*set_pmksa)(struct wiphy *wiphy, struct net_device *netdev, | 1932 | int (*set_pmksa)(struct wiphy *wiphy, struct net_device *netdev, |
1912 | struct cfg80211_pmksa *pmksa); | 1933 | struct cfg80211_pmksa *pmksa); |
1913 | int (*del_pmksa)(struct wiphy *wiphy, struct net_device *netdev, | 1934 | int (*del_pmksa)(struct wiphy *wiphy, struct net_device *netdev, |
1914 | struct cfg80211_pmksa *pmksa); | 1935 | struct cfg80211_pmksa *pmksa); |
1915 | int (*flush_pmksa)(struct wiphy *wiphy, struct net_device *netdev); | 1936 | int (*flush_pmksa)(struct wiphy *wiphy, struct net_device *netdev); |
1916 | 1937 | ||
1917 | int (*remain_on_channel)(struct wiphy *wiphy, | 1938 | int (*remain_on_channel)(struct wiphy *wiphy, |
1918 | struct wireless_dev *wdev, | 1939 | struct wireless_dev *wdev, |
1919 | struct ieee80211_channel *chan, | 1940 | struct ieee80211_channel *chan, |
1920 | unsigned int duration, | 1941 | unsigned int duration, |
1921 | u64 *cookie); | 1942 | u64 *cookie); |
1922 | int (*cancel_remain_on_channel)(struct wiphy *wiphy, | 1943 | int (*cancel_remain_on_channel)(struct wiphy *wiphy, |
1923 | struct wireless_dev *wdev, | 1944 | struct wireless_dev *wdev, |
1924 | u64 cookie); | 1945 | u64 cookie); |
1925 | 1946 | ||
1926 | int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, | 1947 | int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, |
1927 | struct ieee80211_channel *chan, bool offchan, | 1948 | struct ieee80211_channel *chan, bool offchan, |
1928 | unsigned int wait, const u8 *buf, size_t len, | 1949 | unsigned int wait, const u8 *buf, size_t len, |
1929 | bool no_cck, bool dont_wait_for_ack, u64 *cookie); | 1950 | bool no_cck, bool dont_wait_for_ack, u64 *cookie); |
1930 | int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, | 1951 | int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, |
1931 | struct wireless_dev *wdev, | 1952 | struct wireless_dev *wdev, |
1932 | u64 cookie); | 1953 | u64 cookie); |
1933 | 1954 | ||
1934 | int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, | 1955 | int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev, |
1935 | bool enabled, int timeout); | 1956 | bool enabled, int timeout); |
1936 | 1957 | ||
1937 | int (*set_cqm_rssi_config)(struct wiphy *wiphy, | 1958 | int (*set_cqm_rssi_config)(struct wiphy *wiphy, |
1938 | struct net_device *dev, | 1959 | struct net_device *dev, |
1939 | s32 rssi_thold, u32 rssi_hyst); | 1960 | s32 rssi_thold, u32 rssi_hyst); |
1940 | 1961 | ||
1941 | int (*set_cqm_txe_config)(struct wiphy *wiphy, | 1962 | int (*set_cqm_txe_config)(struct wiphy *wiphy, |
1942 | struct net_device *dev, | 1963 | struct net_device *dev, |
1943 | u32 rate, u32 pkts, u32 intvl); | 1964 | u32 rate, u32 pkts, u32 intvl); |
1944 | 1965 | ||
1945 | void (*mgmt_frame_register)(struct wiphy *wiphy, | 1966 | void (*mgmt_frame_register)(struct wiphy *wiphy, |
1946 | struct wireless_dev *wdev, | 1967 | struct wireless_dev *wdev, |
1947 | u16 frame_type, bool reg); | 1968 | u16 frame_type, bool reg); |
1948 | 1969 | ||
1949 | int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); | 1970 | int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant); |
1950 | int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant); | 1971 | int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant); |
1951 | 1972 | ||
1952 | int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx); | 1973 | int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx); |
1953 | void (*get_ringparam)(struct wiphy *wiphy, | 1974 | void (*get_ringparam)(struct wiphy *wiphy, |
1954 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); | 1975 | u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max); |
1955 | 1976 | ||
1956 | int (*sched_scan_start)(struct wiphy *wiphy, | 1977 | int (*sched_scan_start)(struct wiphy *wiphy, |
1957 | struct net_device *dev, | 1978 | struct net_device *dev, |
1958 | struct cfg80211_sched_scan_request *request); | 1979 | struct cfg80211_sched_scan_request *request); |
1959 | int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev); | 1980 | int (*sched_scan_stop)(struct wiphy *wiphy, struct net_device *dev); |
1960 | 1981 | ||
1961 | int (*set_rekey_data)(struct wiphy *wiphy, struct net_device *dev, | 1982 | int (*set_rekey_data)(struct wiphy *wiphy, struct net_device *dev, |
1962 | struct cfg80211_gtk_rekey_data *data); | 1983 | struct cfg80211_gtk_rekey_data *data); |
1963 | 1984 | ||
1964 | int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, | 1985 | int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, |
1965 | u8 *peer, u8 action_code, u8 dialog_token, | 1986 | u8 *peer, u8 action_code, u8 dialog_token, |
1966 | u16 status_code, const u8 *buf, size_t len); | 1987 | u16 status_code, const u8 *buf, size_t len); |
1967 | int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, | 1988 | int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, |
1968 | u8 *peer, enum nl80211_tdls_operation oper); | 1989 | u8 *peer, enum nl80211_tdls_operation oper); |
1969 | 1990 | ||
1970 | int (*probe_client)(struct wiphy *wiphy, struct net_device *dev, | 1991 | int (*probe_client)(struct wiphy *wiphy, struct net_device *dev, |
1971 | const u8 *peer, u64 *cookie); | 1992 | const u8 *peer, u64 *cookie); |
1972 | 1993 | ||
1973 | int (*set_noack_map)(struct wiphy *wiphy, | 1994 | int (*set_noack_map)(struct wiphy *wiphy, |
1974 | struct net_device *dev, | 1995 | struct net_device *dev, |
1975 | u16 noack_map); | 1996 | u16 noack_map); |
1976 | 1997 | ||
1977 | int (*get_et_sset_count)(struct wiphy *wiphy, | 1998 | int (*get_et_sset_count)(struct wiphy *wiphy, |
1978 | struct net_device *dev, int sset); | 1999 | struct net_device *dev, int sset); |
1979 | void (*get_et_stats)(struct wiphy *wiphy, struct net_device *dev, | 2000 | void (*get_et_stats)(struct wiphy *wiphy, struct net_device *dev, |
1980 | struct ethtool_stats *stats, u64 *data); | 2001 | struct ethtool_stats *stats, u64 *data); |
1981 | void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, | 2002 | void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev, |
1982 | u32 sset, u8 *data); | 2003 | u32 sset, u8 *data); |
1983 | 2004 | ||
1984 | int (*get_channel)(struct wiphy *wiphy, | 2005 | int (*get_channel)(struct wiphy *wiphy, |
1985 | struct wireless_dev *wdev, | 2006 | struct wireless_dev *wdev, |
1986 | struct cfg80211_chan_def *chandef); | 2007 | struct cfg80211_chan_def *chandef); |
1987 | 2008 | ||
1988 | int (*start_p2p_device)(struct wiphy *wiphy, | 2009 | int (*start_p2p_device)(struct wiphy *wiphy, |
1989 | struct wireless_dev *wdev); | 2010 | struct wireless_dev *wdev); |
1990 | void (*stop_p2p_device)(struct wiphy *wiphy, | 2011 | void (*stop_p2p_device)(struct wiphy *wiphy, |
1991 | struct wireless_dev *wdev); | 2012 | struct wireless_dev *wdev); |
1992 | }; | 2013 | }; |
1993 | 2014 | ||
1994 | /* | 2015 | /* |
1995 | * wireless hardware and networking interfaces structures | 2016 | * wireless hardware and networking interfaces structures |
1996 | * and registration/helper functions | 2017 | * and registration/helper functions |
1997 | */ | 2018 | */ |
1998 | 2019 | ||
1999 | /** | 2020 | /** |
2000 | * enum wiphy_flags - wiphy capability flags | 2021 | * enum wiphy_flags - wiphy capability flags |
2001 | * | 2022 | * |
2002 | * @WIPHY_FLAG_CUSTOM_REGULATORY: tells us the driver for this device | 2023 | * @WIPHY_FLAG_CUSTOM_REGULATORY: tells us the driver for this device |
2003 | * has its own custom regulatory domain and cannot identify the | 2024 | * has its own custom regulatory domain and cannot identify the |
2004 | * ISO / IEC 3166 alpha2 it belongs to. When this is enabled | 2025 | * ISO / IEC 3166 alpha2 it belongs to. When this is enabled |
2005 | * we will disregard the first regulatory hint (when the | 2026 | * we will disregard the first regulatory hint (when the |
2006 | * initiator is %REGDOM_SET_BY_CORE). | 2027 | * initiator is %REGDOM_SET_BY_CORE). |
2007 | * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will | 2028 | * @WIPHY_FLAG_STRICT_REGULATORY: tells us the driver for this device will |
2008 | * ignore regulatory domain settings until it gets its own regulatory | 2029 | * ignore regulatory domain settings until it gets its own regulatory |
2009 | * domain via its regulatory_hint() unless the regulatory hint is | 2030 | * domain via its regulatory_hint() unless the regulatory hint is |
2010 | * from a country IE. After its gets its own regulatory domain it will | 2031 | * from a country IE. After its gets its own regulatory domain it will |
2011 | * only allow further regulatory domain settings to further enhance | 2032 | * only allow further regulatory domain settings to further enhance |
2012 | * compliance. For example if channel 13 and 14 are disabled by this | 2033 | * compliance. For example if channel 13 and 14 are disabled by this |
2013 | * regulatory domain no user regulatory domain can enable these channels | 2034 | * regulatory domain no user regulatory domain can enable these channels |
2014 | * at a later time. This can be used for devices which do not have | 2035 | * at a later time. This can be used for devices which do not have |
2015 | * calibration information guaranteed for frequencies or settings | 2036 | * calibration information guaranteed for frequencies or settings |
2016 | * outside of its regulatory domain. If used in combination with | 2037 | * outside of its regulatory domain. If used in combination with |
2017 | * WIPHY_FLAG_CUSTOM_REGULATORY the inspected country IE power settings | 2038 | * WIPHY_FLAG_CUSTOM_REGULATORY the inspected country IE power settings |
2018 | * will be followed. | 2039 | * will be followed. |
2019 | * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure | 2040 | * @WIPHY_FLAG_DISABLE_BEACON_HINTS: enable this if your driver needs to ensure |
2020 | * that passive scan flags and beaconing flags may not be lifted by | 2041 | * that passive scan flags and beaconing flags may not be lifted by |
2021 | * cfg80211 due to regulatory beacon hints. For more information on beacon | 2042 | * cfg80211 due to regulatory beacon hints. For more information on beacon |
2022 | * hints read the documenation for regulatory_hint_found_beacon() | 2043 | * hints read the documenation for regulatory_hint_found_beacon() |
2023 | * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this | 2044 | * @WIPHY_FLAG_NETNS_OK: if not set, do not allow changing the netns of this |
2024 | * wiphy at all | 2045 | * wiphy at all |
2025 | * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled | 2046 | * @WIPHY_FLAG_PS_ON_BY_DEFAULT: if set to true, powersave will be enabled |
2026 | * by default -- this flag will be set depending on the kernel's default | 2047 | * by default -- this flag will be set depending on the kernel's default |
2027 | * on wiphy_new(), but can be changed by the driver if it has a good | 2048 | * on wiphy_new(), but can be changed by the driver if it has a good |
2028 | * reason to override the default | 2049 | * reason to override the default |
2029 | * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station | 2050 | * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station |
2030 | * on a VLAN interface) | 2051 | * on a VLAN interface) |
2031 | * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station | 2052 | * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station |
2032 | * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the | 2053 | * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the |
2033 | * control port protocol ethertype. The device also honours the | 2054 | * control port protocol ethertype. The device also honours the |
2034 | * control_port_no_encrypt flag. | 2055 | * control_port_no_encrypt flag. |
2035 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. | 2056 | * @WIPHY_FLAG_IBSS_RSN: The device supports IBSS RSN. |
2036 | * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing | 2057 | * @WIPHY_FLAG_MESH_AUTH: The device supports mesh authentication by routing |
2037 | * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. | 2058 | * auth frames to userspace. See @NL80211_MESH_SETUP_USERSPACE_AUTH. |
2038 | * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans. | 2059 | * @WIPHY_FLAG_SUPPORTS_SCHED_SCAN: The device supports scheduled scans. |
2039 | * @WIPHY_FLAG_SUPPORTS_FW_ROAM: The device supports roaming feature in the | 2060 | * @WIPHY_FLAG_SUPPORTS_FW_ROAM: The device supports roaming feature in the |
2040 | * firmware. | 2061 | * firmware. |
2041 | * @WIPHY_FLAG_AP_UAPSD: The device supports uapsd on AP. | 2062 | * @WIPHY_FLAG_AP_UAPSD: The device supports uapsd on AP. |
2042 | * @WIPHY_FLAG_SUPPORTS_TDLS: The device supports TDLS (802.11z) operation. | 2063 | * @WIPHY_FLAG_SUPPORTS_TDLS: The device supports TDLS (802.11z) operation. |
2043 | * @WIPHY_FLAG_TDLS_EXTERNAL_SETUP: The device does not handle TDLS (802.11z) | 2064 | * @WIPHY_FLAG_TDLS_EXTERNAL_SETUP: The device does not handle TDLS (802.11z) |
2044 | * link setup/discovery operations internally. Setup, discovery and | 2065 | * link setup/discovery operations internally. Setup, discovery and |
2045 | * teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT | 2066 | * teardown packets should be sent through the @NL80211_CMD_TDLS_MGMT |
2046 | * command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be | 2067 | * command. When this flag is not set, @NL80211_CMD_TDLS_OPER should be |
2047 | * used for asking the driver/firmware to perform a TDLS operation. | 2068 | * used for asking the driver/firmware to perform a TDLS operation. |
2048 | * @WIPHY_FLAG_HAVE_AP_SME: device integrates AP SME | 2069 | * @WIPHY_FLAG_HAVE_AP_SME: device integrates AP SME |
2049 | * @WIPHY_FLAG_REPORTS_OBSS: the device will report beacons from other BSSes | 2070 | * @WIPHY_FLAG_REPORTS_OBSS: the device will report beacons from other BSSes |
2050 | * when there are virtual interfaces in AP mode by calling | 2071 | * when there are virtual interfaces in AP mode by calling |
2051 | * cfg80211_report_obss_beacon(). | 2072 | * cfg80211_report_obss_beacon(). |
2052 | * @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD: When operating as an AP, the device | 2073 | * @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD: When operating as an AP, the device |
2053 | * responds to probe-requests in hardware. | 2074 | * responds to probe-requests in hardware. |
2054 | * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. | 2075 | * @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX. |
2055 | * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. | 2076 | * @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call. |
2056 | */ | 2077 | */ |
2057 | enum wiphy_flags { | 2078 | enum wiphy_flags { |
2058 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), | 2079 | WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0), |
2059 | WIPHY_FLAG_STRICT_REGULATORY = BIT(1), | 2080 | WIPHY_FLAG_STRICT_REGULATORY = BIT(1), |
2060 | WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), | 2081 | WIPHY_FLAG_DISABLE_BEACON_HINTS = BIT(2), |
2061 | WIPHY_FLAG_NETNS_OK = BIT(3), | 2082 | WIPHY_FLAG_NETNS_OK = BIT(3), |
2062 | WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), | 2083 | WIPHY_FLAG_PS_ON_BY_DEFAULT = BIT(4), |
2063 | WIPHY_FLAG_4ADDR_AP = BIT(5), | 2084 | WIPHY_FLAG_4ADDR_AP = BIT(5), |
2064 | WIPHY_FLAG_4ADDR_STATION = BIT(6), | 2085 | WIPHY_FLAG_4ADDR_STATION = BIT(6), |
2065 | WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), | 2086 | WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), |
2066 | WIPHY_FLAG_IBSS_RSN = BIT(8), | 2087 | WIPHY_FLAG_IBSS_RSN = BIT(8), |
2067 | WIPHY_FLAG_MESH_AUTH = BIT(10), | 2088 | WIPHY_FLAG_MESH_AUTH = BIT(10), |
2068 | WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), | 2089 | WIPHY_FLAG_SUPPORTS_SCHED_SCAN = BIT(11), |
2069 | /* use hole at 12 */ | 2090 | /* use hole at 12 */ |
2070 | WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13), | 2091 | WIPHY_FLAG_SUPPORTS_FW_ROAM = BIT(13), |
2071 | WIPHY_FLAG_AP_UAPSD = BIT(14), | 2092 | WIPHY_FLAG_AP_UAPSD = BIT(14), |
2072 | WIPHY_FLAG_SUPPORTS_TDLS = BIT(15), | 2093 | WIPHY_FLAG_SUPPORTS_TDLS = BIT(15), |
2073 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16), | 2094 | WIPHY_FLAG_TDLS_EXTERNAL_SETUP = BIT(16), |
2074 | WIPHY_FLAG_HAVE_AP_SME = BIT(17), | 2095 | WIPHY_FLAG_HAVE_AP_SME = BIT(17), |
2075 | WIPHY_FLAG_REPORTS_OBSS = BIT(18), | 2096 | WIPHY_FLAG_REPORTS_OBSS = BIT(18), |
2076 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), | 2097 | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19), |
2077 | WIPHY_FLAG_OFFCHAN_TX = BIT(20), | 2098 | WIPHY_FLAG_OFFCHAN_TX = BIT(20), |
2078 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), | 2099 | WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21), |
2079 | }; | 2100 | }; |
2080 | 2101 | ||
2081 | /** | 2102 | /** |
2082 | * struct ieee80211_iface_limit - limit on certain interface types | 2103 | * struct ieee80211_iface_limit - limit on certain interface types |
2083 | * @max: maximum number of interfaces of these types | 2104 | * @max: maximum number of interfaces of these types |
2084 | * @types: interface types (bits) | 2105 | * @types: interface types (bits) |
2085 | */ | 2106 | */ |
2086 | struct ieee80211_iface_limit { | 2107 | struct ieee80211_iface_limit { |
2087 | u16 max; | 2108 | u16 max; |
2088 | u16 types; | 2109 | u16 types; |
2089 | }; | 2110 | }; |
2090 | 2111 | ||
2091 | /** | 2112 | /** |
2092 | * struct ieee80211_iface_combination - possible interface combination | 2113 | * struct ieee80211_iface_combination - possible interface combination |
2093 | * @limits: limits for the given interface types | 2114 | * @limits: limits for the given interface types |
2094 | * @n_limits: number of limitations | 2115 | * @n_limits: number of limitations |
2095 | * @num_different_channels: can use up to this many different channels | 2116 | * @num_different_channels: can use up to this many different channels |
2096 | * @max_interfaces: maximum number of interfaces in total allowed in this | 2117 | * @max_interfaces: maximum number of interfaces in total allowed in this |
2097 | * group | 2118 | * group |
2098 | * @beacon_int_infra_match: In this combination, the beacon intervals | 2119 | * @beacon_int_infra_match: In this combination, the beacon intervals |
2099 | * between infrastructure and AP types must match. This is required | 2120 | * between infrastructure and AP types must match. This is required |
2100 | * only in special cases. | 2121 | * only in special cases. |
2101 | * | 2122 | * |
2102 | * These examples can be expressed as follows: | 2123 | * These examples can be expressed as follows: |
2103 | * | 2124 | * |
2104 | * Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total: | 2125 | * Allow #STA <= 1, #AP <= 1, matching BI, channels = 1, 2 total: |
2105 | * | 2126 | * |
2106 | * struct ieee80211_iface_limit limits1[] = { | 2127 | * struct ieee80211_iface_limit limits1[] = { |
2107 | * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, | 2128 | * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, |
2108 | * { .max = 1, .types = BIT(NL80211_IFTYPE_AP}, }, | 2129 | * { .max = 1, .types = BIT(NL80211_IFTYPE_AP}, }, |
2109 | * }; | 2130 | * }; |
2110 | * struct ieee80211_iface_combination combination1 = { | 2131 | * struct ieee80211_iface_combination combination1 = { |
2111 | * .limits = limits1, | 2132 | * .limits = limits1, |
2112 | * .n_limits = ARRAY_SIZE(limits1), | 2133 | * .n_limits = ARRAY_SIZE(limits1), |
2113 | * .max_interfaces = 2, | 2134 | * .max_interfaces = 2, |
2114 | * .beacon_int_infra_match = true, | 2135 | * .beacon_int_infra_match = true, |
2115 | * }; | 2136 | * }; |
2116 | * | 2137 | * |
2117 | * | 2138 | * |
2118 | * Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total: | 2139 | * Allow #{AP, P2P-GO} <= 8, channels = 1, 8 total: |
2119 | * | 2140 | * |
2120 | * struct ieee80211_iface_limit limits2[] = { | 2141 | * struct ieee80211_iface_limit limits2[] = { |
2121 | * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | | 2142 | * { .max = 8, .types = BIT(NL80211_IFTYPE_AP) | |
2122 | * BIT(NL80211_IFTYPE_P2P_GO), }, | 2143 | * BIT(NL80211_IFTYPE_P2P_GO), }, |
2123 | * }; | 2144 | * }; |
2124 | * struct ieee80211_iface_combination combination2 = { | 2145 | * struct ieee80211_iface_combination combination2 = { |
2125 | * .limits = limits2, | 2146 | * .limits = limits2, |
2126 | * .n_limits = ARRAY_SIZE(limits2), | 2147 | * .n_limits = ARRAY_SIZE(limits2), |
2127 | * .max_interfaces = 8, | 2148 | * .max_interfaces = 8, |
2128 | * .num_different_channels = 1, | 2149 | * .num_different_channels = 1, |
2129 | * }; | 2150 | * }; |
2130 | * | 2151 | * |
2131 | * | 2152 | * |
2132 | * Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total. | 2153 | * Allow #STA <= 1, #{P2P-client,P2P-GO} <= 3 on two channels, 4 total. |
2133 | * This allows for an infrastructure connection and three P2P connections. | 2154 | * This allows for an infrastructure connection and three P2P connections. |
2134 | * | 2155 | * |
2135 | * struct ieee80211_iface_limit limits3[] = { | 2156 | * struct ieee80211_iface_limit limits3[] = { |
2136 | * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, | 2157 | * { .max = 1, .types = BIT(NL80211_IFTYPE_STATION), }, |
2137 | * { .max = 3, .types = BIT(NL80211_IFTYPE_P2P_GO) | | 2158 | * { .max = 3, .types = BIT(NL80211_IFTYPE_P2P_GO) | |
2138 | * BIT(NL80211_IFTYPE_P2P_CLIENT), }, | 2159 | * BIT(NL80211_IFTYPE_P2P_CLIENT), }, |
2139 | * }; | 2160 | * }; |
2140 | * struct ieee80211_iface_combination combination3 = { | 2161 | * struct ieee80211_iface_combination combination3 = { |
2141 | * .limits = limits3, | 2162 | * .limits = limits3, |
2142 | * .n_limits = ARRAY_SIZE(limits3), | 2163 | * .n_limits = ARRAY_SIZE(limits3), |
2143 | * .max_interfaces = 4, | 2164 | * .max_interfaces = 4, |
2144 | * .num_different_channels = 2, | 2165 | * .num_different_channels = 2, |
2145 | * }; | 2166 | * }; |
2146 | */ | 2167 | */ |
2147 | struct ieee80211_iface_combination { | 2168 | struct ieee80211_iface_combination { |
2148 | const struct ieee80211_iface_limit *limits; | 2169 | const struct ieee80211_iface_limit *limits; |
2149 | u32 num_different_channels; | 2170 | u32 num_different_channels; |
2150 | u16 max_interfaces; | 2171 | u16 max_interfaces; |
2151 | u8 n_limits; | 2172 | u8 n_limits; |
2152 | bool beacon_int_infra_match; | 2173 | bool beacon_int_infra_match; |
2153 | }; | 2174 | }; |
2154 | 2175 | ||
2155 | struct mac_address { | 2176 | struct mac_address { |
2156 | u8 addr[ETH_ALEN]; | 2177 | u8 addr[ETH_ALEN]; |
2157 | }; | 2178 | }; |
2158 | 2179 | ||
2159 | struct ieee80211_txrx_stypes { | 2180 | struct ieee80211_txrx_stypes { |
2160 | u16 tx, rx; | 2181 | u16 tx, rx; |
2161 | }; | 2182 | }; |
2162 | 2183 | ||
2163 | /** | 2184 | /** |
2164 | * enum wiphy_wowlan_support_flags - WoWLAN support flags | 2185 | * enum wiphy_wowlan_support_flags - WoWLAN support flags |
2165 | * @WIPHY_WOWLAN_ANY: supports wakeup for the special "any" | 2186 | * @WIPHY_WOWLAN_ANY: supports wakeup for the special "any" |
2166 | * trigger that keeps the device operating as-is and | 2187 | * trigger that keeps the device operating as-is and |
2167 | * wakes up the host on any activity, for example a | 2188 | * wakes up the host on any activity, for example a |
2168 | * received packet that passed filtering; note that the | 2189 | * received packet that passed filtering; note that the |
2169 | * packet should be preserved in that case | 2190 | * packet should be preserved in that case |
2170 | * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet | 2191 | * @WIPHY_WOWLAN_MAGIC_PKT: supports wakeup on magic packet |
2171 | * (see nl80211.h) | 2192 | * (see nl80211.h) |
2172 | * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect | 2193 | * @WIPHY_WOWLAN_DISCONNECT: supports wakeup on disconnect |
2173 | * @WIPHY_WOWLAN_SUPPORTS_GTK_REKEY: supports GTK rekeying while asleep | 2194 | * @WIPHY_WOWLAN_SUPPORTS_GTK_REKEY: supports GTK rekeying while asleep |
2174 | * @WIPHY_WOWLAN_GTK_REKEY_FAILURE: supports wakeup on GTK rekey failure | 2195 | * @WIPHY_WOWLAN_GTK_REKEY_FAILURE: supports wakeup on GTK rekey failure |
2175 | * @WIPHY_WOWLAN_EAP_IDENTITY_REQ: supports wakeup on EAP identity request | 2196 | * @WIPHY_WOWLAN_EAP_IDENTITY_REQ: supports wakeup on EAP identity request |
2176 | * @WIPHY_WOWLAN_4WAY_HANDSHAKE: supports wakeup on 4-way handshake failure | 2197 | * @WIPHY_WOWLAN_4WAY_HANDSHAKE: supports wakeup on 4-way handshake failure |
2177 | * @WIPHY_WOWLAN_RFKILL_RELEASE: supports wakeup on RF-kill release | 2198 | * @WIPHY_WOWLAN_RFKILL_RELEASE: supports wakeup on RF-kill release |
2178 | */ | 2199 | */ |
2179 | enum wiphy_wowlan_support_flags { | 2200 | enum wiphy_wowlan_support_flags { |
2180 | WIPHY_WOWLAN_ANY = BIT(0), | 2201 | WIPHY_WOWLAN_ANY = BIT(0), |
2181 | WIPHY_WOWLAN_MAGIC_PKT = BIT(1), | 2202 | WIPHY_WOWLAN_MAGIC_PKT = BIT(1), |
2182 | WIPHY_WOWLAN_DISCONNECT = BIT(2), | 2203 | WIPHY_WOWLAN_DISCONNECT = BIT(2), |
2183 | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY = BIT(3), | 2204 | WIPHY_WOWLAN_SUPPORTS_GTK_REKEY = BIT(3), |
2184 | WIPHY_WOWLAN_GTK_REKEY_FAILURE = BIT(4), | 2205 | WIPHY_WOWLAN_GTK_REKEY_FAILURE = BIT(4), |
2185 | WIPHY_WOWLAN_EAP_IDENTITY_REQ = BIT(5), | 2206 | WIPHY_WOWLAN_EAP_IDENTITY_REQ = BIT(5), |
2186 | WIPHY_WOWLAN_4WAY_HANDSHAKE = BIT(6), | 2207 | WIPHY_WOWLAN_4WAY_HANDSHAKE = BIT(6), |
2187 | WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7), | 2208 | WIPHY_WOWLAN_RFKILL_RELEASE = BIT(7), |
2188 | }; | 2209 | }; |
2189 | 2210 | ||
2190 | /** | 2211 | /** |
2191 | * struct wiphy_wowlan_support - WoWLAN support data | 2212 | * struct wiphy_wowlan_support - WoWLAN support data |
2192 | * @flags: see &enum wiphy_wowlan_support_flags | 2213 | * @flags: see &enum wiphy_wowlan_support_flags |
2193 | * @n_patterns: number of supported wakeup patterns | 2214 | * @n_patterns: number of supported wakeup patterns |
2194 | * (see nl80211.h for the pattern definition) | 2215 | * (see nl80211.h for the pattern definition) |
2195 | * @pattern_max_len: maximum length of each pattern | 2216 | * @pattern_max_len: maximum length of each pattern |
2196 | * @pattern_min_len: minimum length of each pattern | 2217 | * @pattern_min_len: minimum length of each pattern |
2197 | */ | 2218 | */ |
2198 | struct wiphy_wowlan_support { | 2219 | struct wiphy_wowlan_support { |
2199 | u32 flags; | 2220 | u32 flags; |
2200 | int n_patterns; | 2221 | int n_patterns; |
2201 | int pattern_max_len; | 2222 | int pattern_max_len; |
2202 | int pattern_min_len; | 2223 | int pattern_min_len; |
2203 | }; | 2224 | }; |
2204 | 2225 | ||
2205 | /** | 2226 | /** |
2206 | * struct wiphy - wireless hardware description | 2227 | * struct wiphy - wireless hardware description |
2207 | * @reg_notifier: the driver's regulatory notification callback, | 2228 | * @reg_notifier: the driver's regulatory notification callback, |
2208 | * note that if your driver uses wiphy_apply_custom_regulatory() | 2229 | * note that if your driver uses wiphy_apply_custom_regulatory() |
2209 | * the reg_notifier's request can be passed as NULL | 2230 | * the reg_notifier's request can be passed as NULL |
2210 | * @regd: the driver's regulatory domain, if one was requested via | 2231 | * @regd: the driver's regulatory domain, if one was requested via |
2211 | * the regulatory_hint() API. This can be used by the driver | 2232 | * the regulatory_hint() API. This can be used by the driver |
2212 | * on the reg_notifier() if it chooses to ignore future | 2233 | * on the reg_notifier() if it chooses to ignore future |
2213 | * regulatory domain changes caused by other drivers. | 2234 | * regulatory domain changes caused by other drivers. |
2214 | * @signal_type: signal type reported in &struct cfg80211_bss. | 2235 | * @signal_type: signal type reported in &struct cfg80211_bss. |
2215 | * @cipher_suites: supported cipher suites | 2236 | * @cipher_suites: supported cipher suites |
2216 | * @n_cipher_suites: number of supported cipher suites | 2237 | * @n_cipher_suites: number of supported cipher suites |
2217 | * @retry_short: Retry limit for short frames (dot11ShortRetryLimit) | 2238 | * @retry_short: Retry limit for short frames (dot11ShortRetryLimit) |
2218 | * @retry_long: Retry limit for long frames (dot11LongRetryLimit) | 2239 | * @retry_long: Retry limit for long frames (dot11LongRetryLimit) |
2219 | * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold); | 2240 | * @frag_threshold: Fragmentation threshold (dot11FragmentationThreshold); |
2220 | * -1 = fragmentation disabled, only odd values >= 256 used | 2241 | * -1 = fragmentation disabled, only odd values >= 256 used |
2221 | * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled | 2242 | * @rts_threshold: RTS threshold (dot11RTSThreshold); -1 = RTS/CTS disabled |
2222 | * @_net: the network namespace this wiphy currently lives in | 2243 | * @_net: the network namespace this wiphy currently lives in |
2223 | * @perm_addr: permanent MAC address of this device | 2244 | * @perm_addr: permanent MAC address of this device |
2224 | * @addr_mask: If the device supports multiple MAC addresses by masking, | 2245 | * @addr_mask: If the device supports multiple MAC addresses by masking, |
2225 | * set this to a mask with variable bits set to 1, e.g. if the last | 2246 | * set this to a mask with variable bits set to 1, e.g. if the last |
2226 | * four bits are variable then set it to 00:...:00:0f. The actual | 2247 | * four bits are variable then set it to 00:...:00:0f. The actual |
2227 | * variable bits shall be determined by the interfaces added, with | 2248 | * variable bits shall be determined by the interfaces added, with |
2228 | * interfaces not matching the mask being rejected to be brought up. | 2249 | * interfaces not matching the mask being rejected to be brought up. |
2229 | * @n_addresses: number of addresses in @addresses. | 2250 | * @n_addresses: number of addresses in @addresses. |
2230 | * @addresses: If the device has more than one address, set this pointer | 2251 | * @addresses: If the device has more than one address, set this pointer |
2231 | * to a list of addresses (6 bytes each). The first one will be used | 2252 | * to a list of addresses (6 bytes each). The first one will be used |
2232 | * by default for perm_addr. In this case, the mask should be set to | 2253 | * by default for perm_addr. In this case, the mask should be set to |
2233 | * all-zeroes. In this case it is assumed that the device can handle | 2254 | * all-zeroes. In this case it is assumed that the device can handle |
2234 | * the same number of arbitrary MAC addresses. | 2255 | * the same number of arbitrary MAC addresses. |
2235 | * @registered: protects ->resume and ->suspend sysfs callbacks against | 2256 | * @registered: protects ->resume and ->suspend sysfs callbacks against |
2236 | * unregister hardware | 2257 | * unregister hardware |
2237 | * @debugfsdir: debugfs directory used for this wiphy, will be renamed | 2258 | * @debugfsdir: debugfs directory used for this wiphy, will be renamed |
2238 | * automatically on wiphy renames | 2259 | * automatically on wiphy renames |
2239 | * @dev: (virtual) struct device for this wiphy | 2260 | * @dev: (virtual) struct device for this wiphy |
2240 | * @registered: helps synchronize suspend/resume with wiphy unregister | 2261 | * @registered: helps synchronize suspend/resume with wiphy unregister |
2241 | * @wext: wireless extension handlers | 2262 | * @wext: wireless extension handlers |
2242 | * @priv: driver private data (sized according to wiphy_new() parameter) | 2263 | * @priv: driver private data (sized according to wiphy_new() parameter) |
2243 | * @interface_modes: bitmask of interfaces types valid for this wiphy, | 2264 | * @interface_modes: bitmask of interfaces types valid for this wiphy, |
2244 | * must be set by driver | 2265 | * must be set by driver |
2245 | * @iface_combinations: Valid interface combinations array, should not | 2266 | * @iface_combinations: Valid interface combinations array, should not |
2246 | * list single interface types. | 2267 | * list single interface types. |
2247 | * @n_iface_combinations: number of entries in @iface_combinations array. | 2268 | * @n_iface_combinations: number of entries in @iface_combinations array. |
2248 | * @software_iftypes: bitmask of software interface types, these are not | 2269 | * @software_iftypes: bitmask of software interface types, these are not |
2249 | * subject to any restrictions since they are purely managed in SW. | 2270 | * subject to any restrictions since they are purely managed in SW. |
2250 | * @flags: wiphy flags, see &enum wiphy_flags | 2271 | * @flags: wiphy flags, see &enum wiphy_flags |
2251 | * @features: features advertised to nl80211, see &enum nl80211_feature_flags. | 2272 | * @features: features advertised to nl80211, see &enum nl80211_feature_flags. |
2252 | * @bss_priv_size: each BSS struct has private data allocated with it, | 2273 | * @bss_priv_size: each BSS struct has private data allocated with it, |
2253 | * this variable determines its size | 2274 | * this variable determines its size |
2254 | * @max_scan_ssids: maximum number of SSIDs the device can scan for in | 2275 | * @max_scan_ssids: maximum number of SSIDs the device can scan for in |
2255 | * any given scan | 2276 | * any given scan |
2256 | * @max_sched_scan_ssids: maximum number of SSIDs the device can scan | 2277 | * @max_sched_scan_ssids: maximum number of SSIDs the device can scan |
2257 | * for in any given scheduled scan | 2278 | * for in any given scheduled scan |
2258 | * @max_match_sets: maximum number of match sets the device can handle | 2279 | * @max_match_sets: maximum number of match sets the device can handle |
2259 | * when performing a scheduled scan, 0 if filtering is not | 2280 | * when performing a scheduled scan, 0 if filtering is not |
2260 | * supported. | 2281 | * supported. |
2261 | * @max_scan_ie_len: maximum length of user-controlled IEs device can | 2282 | * @max_scan_ie_len: maximum length of user-controlled IEs device can |
2262 | * add to probe request frames transmitted during a scan, must not | 2283 | * add to probe request frames transmitted during a scan, must not |
2263 | * include fixed IEs like supported rates | 2284 | * include fixed IEs like supported rates |
2264 | * @max_sched_scan_ie_len: same as max_scan_ie_len, but for scheduled | 2285 | * @max_sched_scan_ie_len: same as max_scan_ie_len, but for scheduled |
2265 | * scans | 2286 | * scans |
2266 | * @coverage_class: current coverage class | 2287 | * @coverage_class: current coverage class |
2267 | * @fw_version: firmware version for ethtool reporting | 2288 | * @fw_version: firmware version for ethtool reporting |
2268 | * @hw_version: hardware version for ethtool reporting | 2289 | * @hw_version: hardware version for ethtool reporting |
2269 | * @max_num_pmkids: maximum number of PMKIDs supported by device | 2290 | * @max_num_pmkids: maximum number of PMKIDs supported by device |
2270 | * @privid: a pointer that drivers can use to identify if an arbitrary | 2291 | * @privid: a pointer that drivers can use to identify if an arbitrary |
2271 | * wiphy is theirs, e.g. in global notifiers | 2292 | * wiphy is theirs, e.g. in global notifiers |
2272 | * @bands: information about bands/channels supported by this device | 2293 | * @bands: information about bands/channels supported by this device |
2273 | * | 2294 | * |
2274 | * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or | 2295 | * @mgmt_stypes: bitmasks of frame subtypes that can be subscribed to or |
2275 | * transmitted through nl80211, points to an array indexed by interface | 2296 | * transmitted through nl80211, points to an array indexed by interface |
2276 | * type | 2297 | * type |
2277 | * | 2298 | * |
2278 | * @available_antennas_tx: bitmap of antennas which are available to be | 2299 | * @available_antennas_tx: bitmap of antennas which are available to be |
2279 | * configured as TX antennas. Antenna configuration commands will be | 2300 | * configured as TX antennas. Antenna configuration commands will be |
2280 | * rejected unless this or @available_antennas_rx is set. | 2301 | * rejected unless this or @available_antennas_rx is set. |
2281 | * | 2302 | * |
2282 | * @available_antennas_rx: bitmap of antennas which are available to be | 2303 | * @available_antennas_rx: bitmap of antennas which are available to be |
2283 | * configured as RX antennas. Antenna configuration commands will be | 2304 | * configured as RX antennas. Antenna configuration commands will be |
2284 | * rejected unless this or @available_antennas_tx is set. | 2305 | * rejected unless this or @available_antennas_tx is set. |
2285 | * | 2306 | * |
2286 | * @probe_resp_offload: | 2307 | * @probe_resp_offload: |
2287 | * Bitmap of supported protocols for probe response offloading. | 2308 | * Bitmap of supported protocols for probe response offloading. |
2288 | * See &enum nl80211_probe_resp_offload_support_attr. Only valid | 2309 | * See &enum nl80211_probe_resp_offload_support_attr. Only valid |
2289 | * when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set. | 2310 | * when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set. |
2290 | * | 2311 | * |
2291 | * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation | 2312 | * @max_remain_on_channel_duration: Maximum time a remain-on-channel operation |
2292 | * may request, if implemented. | 2313 | * may request, if implemented. |
2293 | * | 2314 | * |
2294 | * @wowlan: WoWLAN support information | 2315 | * @wowlan: WoWLAN support information |
2295 | * | 2316 | * |
2296 | * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features. | 2317 | * @ap_sme_capa: AP SME capabilities, flags from &enum nl80211_ap_sme_features. |
2297 | * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden. | 2318 | * @ht_capa_mod_mask: Specify what ht_cap values can be over-ridden. |
2298 | * If null, then none can be over-ridden. | 2319 | * If null, then none can be over-ridden. |
2299 | */ | 2320 | */ |
2300 | struct wiphy { | 2321 | struct wiphy { |
2301 | /* assign these fields before you register the wiphy */ | 2322 | /* assign these fields before you register the wiphy */ |
2302 | 2323 | ||
2303 | /* permanent MAC address(es) */ | 2324 | /* permanent MAC address(es) */ |
2304 | u8 perm_addr[ETH_ALEN]; | 2325 | u8 perm_addr[ETH_ALEN]; |
2305 | u8 addr_mask[ETH_ALEN]; | 2326 | u8 addr_mask[ETH_ALEN]; |
2306 | 2327 | ||
2307 | struct mac_address *addresses; | 2328 | struct mac_address *addresses; |
2308 | 2329 | ||
2309 | const struct ieee80211_txrx_stypes *mgmt_stypes; | 2330 | const struct ieee80211_txrx_stypes *mgmt_stypes; |
2310 | 2331 | ||
2311 | const struct ieee80211_iface_combination *iface_combinations; | 2332 | const struct ieee80211_iface_combination *iface_combinations; |
2312 | int n_iface_combinations; | 2333 | int n_iface_combinations; |
2313 | u16 software_iftypes; | 2334 | u16 software_iftypes; |
2314 | 2335 | ||
2315 | u16 n_addresses; | 2336 | u16 n_addresses; |
2316 | 2337 | ||
2317 | /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ | 2338 | /* Supported interface modes, OR together BIT(NL80211_IFTYPE_...) */ |
2318 | u16 interface_modes; | 2339 | u16 interface_modes; |
2319 | 2340 | ||
2320 | u32 flags, features; | 2341 | u32 flags, features; |
2321 | 2342 | ||
2322 | u32 ap_sme_capa; | 2343 | u32 ap_sme_capa; |
2323 | 2344 | ||
2324 | enum cfg80211_signal_type signal_type; | 2345 | enum cfg80211_signal_type signal_type; |
2325 | 2346 | ||
2326 | int bss_priv_size; | 2347 | int bss_priv_size; |
2327 | u8 max_scan_ssids; | 2348 | u8 max_scan_ssids; |
2328 | u8 max_sched_scan_ssids; | 2349 | u8 max_sched_scan_ssids; |
2329 | u8 max_match_sets; | 2350 | u8 max_match_sets; |
2330 | u16 max_scan_ie_len; | 2351 | u16 max_scan_ie_len; |
2331 | u16 max_sched_scan_ie_len; | 2352 | u16 max_sched_scan_ie_len; |
2332 | 2353 | ||
2333 | int n_cipher_suites; | 2354 | int n_cipher_suites; |
2334 | const u32 *cipher_suites; | 2355 | const u32 *cipher_suites; |
2335 | 2356 | ||
2336 | u8 retry_short; | 2357 | u8 retry_short; |
2337 | u8 retry_long; | 2358 | u8 retry_long; |
2338 | u32 frag_threshold; | 2359 | u32 frag_threshold; |
2339 | u32 rts_threshold; | 2360 | u32 rts_threshold; |
2340 | u8 coverage_class; | 2361 | u8 coverage_class; |
2341 | 2362 | ||
2342 | char fw_version[ETHTOOL_BUSINFO_LEN]; | 2363 | char fw_version[ETHTOOL_BUSINFO_LEN]; |
2343 | u32 hw_version; | 2364 | u32 hw_version; |
2344 | 2365 | ||
2345 | #ifdef CONFIG_PM | 2366 | #ifdef CONFIG_PM |
2346 | struct wiphy_wowlan_support wowlan; | 2367 | struct wiphy_wowlan_support wowlan; |
2347 | #endif | 2368 | #endif |
2348 | 2369 | ||
2349 | u16 max_remain_on_channel_duration; | 2370 | u16 max_remain_on_channel_duration; |
2350 | 2371 | ||
2351 | u8 max_num_pmkids; | 2372 | u8 max_num_pmkids; |
2352 | 2373 | ||
2353 | u32 available_antennas_tx; | 2374 | u32 available_antennas_tx; |
2354 | u32 available_antennas_rx; | 2375 | u32 available_antennas_rx; |
2355 | 2376 | ||
2356 | /* | 2377 | /* |
2357 | * Bitmap of supported protocols for probe response offloading | 2378 | * Bitmap of supported protocols for probe response offloading |
2358 | * see &enum nl80211_probe_resp_offload_support_attr. Only valid | 2379 | * see &enum nl80211_probe_resp_offload_support_attr. Only valid |
2359 | * when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set. | 2380 | * when the wiphy flag @WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD is set. |
2360 | */ | 2381 | */ |
2361 | u32 probe_resp_offload; | 2382 | u32 probe_resp_offload; |
2362 | 2383 | ||
2363 | /* If multiple wiphys are registered and you're handed e.g. | 2384 | /* If multiple wiphys are registered and you're handed e.g. |
2364 | * a regular netdev with assigned ieee80211_ptr, you won't | 2385 | * a regular netdev with assigned ieee80211_ptr, you won't |
2365 | * know whether it points to a wiphy your driver has registered | 2386 | * know whether it points to a wiphy your driver has registered |
2366 | * or not. Assign this to something global to your driver to | 2387 | * or not. Assign this to something global to your driver to |
2367 | * help determine whether you own this wiphy or not. */ | 2388 | * help determine whether you own this wiphy or not. */ |
2368 | const void *privid; | 2389 | const void *privid; |
2369 | 2390 | ||
2370 | struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; | 2391 | struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS]; |
2371 | 2392 | ||
2372 | /* Lets us get back the wiphy on the callback */ | 2393 | /* Lets us get back the wiphy on the callback */ |
2373 | void (*reg_notifier)(struct wiphy *wiphy, | 2394 | void (*reg_notifier)(struct wiphy *wiphy, |
2374 | struct regulatory_request *request); | 2395 | struct regulatory_request *request); |
2375 | 2396 | ||
2376 | /* fields below are read-only, assigned by cfg80211 */ | 2397 | /* fields below are read-only, assigned by cfg80211 */ |
2377 | 2398 | ||
2378 | const struct ieee80211_regdomain __rcu *regd; | 2399 | const struct ieee80211_regdomain __rcu *regd; |
2379 | 2400 | ||
2380 | /* the item in /sys/class/ieee80211/ points to this, | 2401 | /* the item in /sys/class/ieee80211/ points to this, |
2381 | * you need use set_wiphy_dev() (see below) */ | 2402 | * you need use set_wiphy_dev() (see below) */ |
2382 | struct device dev; | 2403 | struct device dev; |
2383 | 2404 | ||
2384 | /* protects ->resume, ->suspend sysfs callbacks against unregister hw */ | 2405 | /* protects ->resume, ->suspend sysfs callbacks against unregister hw */ |
2385 | bool registered; | 2406 | bool registered; |
2386 | 2407 | ||
2387 | /* dir in debugfs: ieee80211/<wiphyname> */ | 2408 | /* dir in debugfs: ieee80211/<wiphyname> */ |
2388 | struct dentry *debugfsdir; | 2409 | struct dentry *debugfsdir; |
2389 | 2410 | ||
2390 | const struct ieee80211_ht_cap *ht_capa_mod_mask; | 2411 | const struct ieee80211_ht_cap *ht_capa_mod_mask; |
2391 | 2412 | ||
2392 | #ifdef CONFIG_NET_NS | 2413 | #ifdef CONFIG_NET_NS |
2393 | /* the network namespace this phy lives in currently */ | 2414 | /* the network namespace this phy lives in currently */ |
2394 | struct net *_net; | 2415 | struct net *_net; |
2395 | #endif | 2416 | #endif |
2396 | 2417 | ||
2397 | #ifdef CONFIG_CFG80211_WEXT | 2418 | #ifdef CONFIG_CFG80211_WEXT |
2398 | const struct iw_handler_def *wext; | 2419 | const struct iw_handler_def *wext; |
2399 | #endif | 2420 | #endif |
2400 | 2421 | ||
2401 | char priv[0] __aligned(NETDEV_ALIGN); | 2422 | char priv[0] __aligned(NETDEV_ALIGN); |
2402 | }; | 2423 | }; |
2403 | 2424 | ||
2404 | static inline struct net *wiphy_net(struct wiphy *wiphy) | 2425 | static inline struct net *wiphy_net(struct wiphy *wiphy) |
2405 | { | 2426 | { |
2406 | return read_pnet(&wiphy->_net); | 2427 | return read_pnet(&wiphy->_net); |
2407 | } | 2428 | } |
2408 | 2429 | ||
2409 | static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net) | 2430 | static inline void wiphy_net_set(struct wiphy *wiphy, struct net *net) |
2410 | { | 2431 | { |
2411 | write_pnet(&wiphy->_net, net); | 2432 | write_pnet(&wiphy->_net, net); |
2412 | } | 2433 | } |
2413 | 2434 | ||
2414 | /** | 2435 | /** |
2415 | * wiphy_priv - return priv from wiphy | 2436 | * wiphy_priv - return priv from wiphy |
2416 | * | 2437 | * |
2417 | * @wiphy: the wiphy whose priv pointer to return | 2438 | * @wiphy: the wiphy whose priv pointer to return |
2418 | * Return: The priv of @wiphy. | 2439 | * Return: The priv of @wiphy. |
2419 | */ | 2440 | */ |
2420 | static inline void *wiphy_priv(struct wiphy *wiphy) | 2441 | static inline void *wiphy_priv(struct wiphy *wiphy) |
2421 | { | 2442 | { |
2422 | BUG_ON(!wiphy); | 2443 | BUG_ON(!wiphy); |
2423 | return &wiphy->priv; | 2444 | return &wiphy->priv; |
2424 | } | 2445 | } |
2425 | 2446 | ||
2426 | /** | 2447 | /** |
2427 | * priv_to_wiphy - return the wiphy containing the priv | 2448 | * priv_to_wiphy - return the wiphy containing the priv |
2428 | * | 2449 | * |
2429 | * @priv: a pointer previously returned by wiphy_priv | 2450 | * @priv: a pointer previously returned by wiphy_priv |
2430 | * Return: The wiphy of @priv. | 2451 | * Return: The wiphy of @priv. |
2431 | */ | 2452 | */ |
2432 | static inline struct wiphy *priv_to_wiphy(void *priv) | 2453 | static inline struct wiphy *priv_to_wiphy(void *priv) |
2433 | { | 2454 | { |
2434 | BUG_ON(!priv); | 2455 | BUG_ON(!priv); |
2435 | return container_of(priv, struct wiphy, priv); | 2456 | return container_of(priv, struct wiphy, priv); |
2436 | } | 2457 | } |
2437 | 2458 | ||
2438 | /** | 2459 | /** |
2439 | * set_wiphy_dev - set device pointer for wiphy | 2460 | * set_wiphy_dev - set device pointer for wiphy |
2440 | * | 2461 | * |
2441 | * @wiphy: The wiphy whose device to bind | 2462 | * @wiphy: The wiphy whose device to bind |
2442 | * @dev: The device to parent it to | 2463 | * @dev: The device to parent it to |
2443 | */ | 2464 | */ |
2444 | static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev) | 2465 | static inline void set_wiphy_dev(struct wiphy *wiphy, struct device *dev) |
2445 | { | 2466 | { |
2446 | wiphy->dev.parent = dev; | 2467 | wiphy->dev.parent = dev; |
2447 | } | 2468 | } |
2448 | 2469 | ||
2449 | /** | 2470 | /** |
2450 | * wiphy_dev - get wiphy dev pointer | 2471 | * wiphy_dev - get wiphy dev pointer |
2451 | * | 2472 | * |
2452 | * @wiphy: The wiphy whose device struct to look up | 2473 | * @wiphy: The wiphy whose device struct to look up |
2453 | * Return: The dev of @wiphy. | 2474 | * Return: The dev of @wiphy. |
2454 | */ | 2475 | */ |
2455 | static inline struct device *wiphy_dev(struct wiphy *wiphy) | 2476 | static inline struct device *wiphy_dev(struct wiphy *wiphy) |
2456 | { | 2477 | { |
2457 | return wiphy->dev.parent; | 2478 | return wiphy->dev.parent; |
2458 | } | 2479 | } |
2459 | 2480 | ||
2460 | /** | 2481 | /** |
2461 | * wiphy_name - get wiphy name | 2482 | * wiphy_name - get wiphy name |
2462 | * | 2483 | * |
2463 | * @wiphy: The wiphy whose name to return | 2484 | * @wiphy: The wiphy whose name to return |
2464 | * Return: The name of @wiphy. | 2485 | * Return: The name of @wiphy. |
2465 | */ | 2486 | */ |
2466 | static inline const char *wiphy_name(const struct wiphy *wiphy) | 2487 | static inline const char *wiphy_name(const struct wiphy *wiphy) |
2467 | { | 2488 | { |
2468 | return dev_name(&wiphy->dev); | 2489 | return dev_name(&wiphy->dev); |
2469 | } | 2490 | } |
2470 | 2491 | ||
2471 | /** | 2492 | /** |
2472 | * wiphy_new - create a new wiphy for use with cfg80211 | 2493 | * wiphy_new - create a new wiphy for use with cfg80211 |
2473 | * | 2494 | * |
2474 | * @ops: The configuration operations for this device | 2495 | * @ops: The configuration operations for this device |
2475 | * @sizeof_priv: The size of the private area to allocate | 2496 | * @sizeof_priv: The size of the private area to allocate |
2476 | * | 2497 | * |
2477 | * Create a new wiphy and associate the given operations with it. | 2498 | * Create a new wiphy and associate the given operations with it. |
2478 | * @sizeof_priv bytes are allocated for private use. | 2499 | * @sizeof_priv bytes are allocated for private use. |
2479 | * | 2500 | * |
2480 | * Return: A pointer to the new wiphy. This pointer must be | 2501 | * Return: A pointer to the new wiphy. This pointer must be |
2481 | * assigned to each netdev's ieee80211_ptr for proper operation. | 2502 | * assigned to each netdev's ieee80211_ptr for proper operation. |
2482 | */ | 2503 | */ |
2483 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv); | 2504 | struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv); |
2484 | 2505 | ||
2485 | /** | 2506 | /** |
2486 | * wiphy_register - register a wiphy with cfg80211 | 2507 | * wiphy_register - register a wiphy with cfg80211 |
2487 | * | 2508 | * |
2488 | * @wiphy: The wiphy to register. | 2509 | * @wiphy: The wiphy to register. |
2489 | * | 2510 | * |
2490 | * Return: A non-negative wiphy index or a negative error code. | 2511 | * Return: A non-negative wiphy index or a negative error code. |
2491 | */ | 2512 | */ |
2492 | extern int wiphy_register(struct wiphy *wiphy); | 2513 | extern int wiphy_register(struct wiphy *wiphy); |
2493 | 2514 | ||
2494 | /** | 2515 | /** |
2495 | * wiphy_unregister - deregister a wiphy from cfg80211 | 2516 | * wiphy_unregister - deregister a wiphy from cfg80211 |
2496 | * | 2517 | * |
2497 | * @wiphy: The wiphy to unregister. | 2518 | * @wiphy: The wiphy to unregister. |
2498 | * | 2519 | * |
2499 | * After this call, no more requests can be made with this priv | 2520 | * After this call, no more requests can be made with this priv |
2500 | * pointer, but the call may sleep to wait for an outstanding | 2521 | * pointer, but the call may sleep to wait for an outstanding |
2501 | * request that is being handled. | 2522 | * request that is being handled. |
2502 | */ | 2523 | */ |
2503 | extern void wiphy_unregister(struct wiphy *wiphy); | 2524 | extern void wiphy_unregister(struct wiphy *wiphy); |
2504 | 2525 | ||
2505 | /** | 2526 | /** |
2506 | * wiphy_free - free wiphy | 2527 | * wiphy_free - free wiphy |
2507 | * | 2528 | * |
2508 | * @wiphy: The wiphy to free | 2529 | * @wiphy: The wiphy to free |
2509 | */ | 2530 | */ |
2510 | extern void wiphy_free(struct wiphy *wiphy); | 2531 | extern void wiphy_free(struct wiphy *wiphy); |
2511 | 2532 | ||
2512 | /* internal structs */ | 2533 | /* internal structs */ |
2513 | struct cfg80211_conn; | 2534 | struct cfg80211_conn; |
2514 | struct cfg80211_internal_bss; | 2535 | struct cfg80211_internal_bss; |
2515 | struct cfg80211_cached_keys; | 2536 | struct cfg80211_cached_keys; |
2516 | 2537 | ||
2517 | /** | 2538 | /** |
2518 | * struct wireless_dev - wireless device state | 2539 | * struct wireless_dev - wireless device state |
2519 | * | 2540 | * |
2520 | * For netdevs, this structure must be allocated by the driver | 2541 | * For netdevs, this structure must be allocated by the driver |
2521 | * that uses the ieee80211_ptr field in struct net_device (this | 2542 | * that uses the ieee80211_ptr field in struct net_device (this |
2522 | * is intentional so it can be allocated along with the netdev.) | 2543 | * is intentional so it can be allocated along with the netdev.) |
2523 | * It need not be registered then as netdev registration will | 2544 | * It need not be registered then as netdev registration will |
2524 | * be intercepted by cfg80211 to see the new wireless device. | 2545 | * be intercepted by cfg80211 to see the new wireless device. |
2525 | * | 2546 | * |
2526 | * For non-netdev uses, it must also be allocated by the driver | 2547 | * For non-netdev uses, it must also be allocated by the driver |
2527 | * in response to the cfg80211 callbacks that require it, as | 2548 | * in response to the cfg80211 callbacks that require it, as |
2528 | * there's no netdev registration in that case it may not be | 2549 | * there's no netdev registration in that case it may not be |
2529 | * allocated outside of callback operations that return it. | 2550 | * allocated outside of callback operations that return it. |
2530 | * | 2551 | * |
2531 | * @wiphy: pointer to hardware description | 2552 | * @wiphy: pointer to hardware description |
2532 | * @iftype: interface type | 2553 | * @iftype: interface type |
2533 | * @list: (private) Used to collect the interfaces | 2554 | * @list: (private) Used to collect the interfaces |
2534 | * @netdev: (private) Used to reference back to the netdev, may be %NULL | 2555 | * @netdev: (private) Used to reference back to the netdev, may be %NULL |
2535 | * @identifier: (private) Identifier used in nl80211 to identify this | 2556 | * @identifier: (private) Identifier used in nl80211 to identify this |
2536 | * wireless device if it has no netdev | 2557 | * wireless device if it has no netdev |
2537 | * @current_bss: (private) Used by the internal configuration code | 2558 | * @current_bss: (private) Used by the internal configuration code |
2538 | * @channel: (private) Used by the internal configuration code to track | 2559 | * @channel: (private) Used by the internal configuration code to track |
2539 | * the user-set AP, monitor and WDS channel | 2560 | * the user-set AP, monitor and WDS channel |
2540 | * @preset_chan: (private) Used by the internal configuration code to | 2561 | * @preset_chan: (private) Used by the internal configuration code to |
2541 | * track the channel to be used for AP later | 2562 | * track the channel to be used for AP later |
2542 | * @preset_chantype: (private) the corresponding channel type | 2563 | * @preset_chantype: (private) the corresponding channel type |
2543 | * @bssid: (private) Used by the internal configuration code | 2564 | * @bssid: (private) Used by the internal configuration code |
2544 | * @ssid: (private) Used by the internal configuration code | 2565 | * @ssid: (private) Used by the internal configuration code |
2545 | * @ssid_len: (private) Used by the internal configuration code | 2566 | * @ssid_len: (private) Used by the internal configuration code |
2546 | * @mesh_id_len: (private) Used by the internal configuration code | 2567 | * @mesh_id_len: (private) Used by the internal configuration code |
2547 | * @mesh_id_up_len: (private) Used by the internal configuration code | 2568 | * @mesh_id_up_len: (private) Used by the internal configuration code |
2548 | * @wext: (private) Used by the internal wireless extensions compat code | 2569 | * @wext: (private) Used by the internal wireless extensions compat code |
2549 | * @use_4addr: indicates 4addr mode is used on this interface, must be | 2570 | * @use_4addr: indicates 4addr mode is used on this interface, must be |
2550 | * set by driver (if supported) on add_interface BEFORE registering the | 2571 | * set by driver (if supported) on add_interface BEFORE registering the |
2551 | * netdev and may otherwise be used by driver read-only, will be update | 2572 | * netdev and may otherwise be used by driver read-only, will be update |
2552 | * by cfg80211 on change_interface | 2573 | * by cfg80211 on change_interface |
2553 | * @mgmt_registrations: list of registrations for management frames | 2574 | * @mgmt_registrations: list of registrations for management frames |
2554 | * @mgmt_registrations_lock: lock for the list | 2575 | * @mgmt_registrations_lock: lock for the list |
2555 | * @mtx: mutex used to lock data in this struct | 2576 | * @mtx: mutex used to lock data in this struct |
2556 | * @cleanup_work: work struct used for cleanup that can't be done directly | 2577 | * @cleanup_work: work struct used for cleanup that can't be done directly |
2557 | * @beacon_interval: beacon interval used on this device for transmitting | 2578 | * @beacon_interval: beacon interval used on this device for transmitting |
2558 | * beacons, 0 when not valid | 2579 | * beacons, 0 when not valid |
2559 | * @address: The address for this device, valid only if @netdev is %NULL | 2580 | * @address: The address for this device, valid only if @netdev is %NULL |
2560 | * @p2p_started: true if this is a P2P Device that has been started | 2581 | * @p2p_started: true if this is a P2P Device that has been started |
2561 | */ | 2582 | */ |
2562 | struct wireless_dev { | 2583 | struct wireless_dev { |
2563 | struct wiphy *wiphy; | 2584 | struct wiphy *wiphy; |
2564 | enum nl80211_iftype iftype; | 2585 | enum nl80211_iftype iftype; |
2565 | 2586 | ||
2566 | /* the remainder of this struct should be private to cfg80211 */ | 2587 | /* the remainder of this struct should be private to cfg80211 */ |
2567 | struct list_head list; | 2588 | struct list_head list; |
2568 | struct net_device *netdev; | 2589 | struct net_device *netdev; |
2569 | 2590 | ||
2570 | u32 identifier; | 2591 | u32 identifier; |
2571 | 2592 | ||
2572 | struct list_head mgmt_registrations; | 2593 | struct list_head mgmt_registrations; |
2573 | spinlock_t mgmt_registrations_lock; | 2594 | spinlock_t mgmt_registrations_lock; |
2574 | 2595 | ||
2575 | struct mutex mtx; | 2596 | struct mutex mtx; |
2576 | 2597 | ||
2577 | struct work_struct cleanup_work; | 2598 | struct work_struct cleanup_work; |
2578 | 2599 | ||
2579 | bool use_4addr, p2p_started; | 2600 | bool use_4addr, p2p_started; |
2580 | 2601 | ||
2581 | u8 address[ETH_ALEN] __aligned(sizeof(u16)); | 2602 | u8 address[ETH_ALEN] __aligned(sizeof(u16)); |
2582 | 2603 | ||
2583 | /* currently used for IBSS and SME - might be rearranged later */ | 2604 | /* currently used for IBSS and SME - might be rearranged later */ |
2584 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 2605 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
2585 | u8 ssid_len, mesh_id_len, mesh_id_up_len; | 2606 | u8 ssid_len, mesh_id_len, mesh_id_up_len; |
2586 | enum { | 2607 | enum { |
2587 | CFG80211_SME_IDLE, | 2608 | CFG80211_SME_IDLE, |
2588 | CFG80211_SME_CONNECTING, | 2609 | CFG80211_SME_CONNECTING, |
2589 | CFG80211_SME_CONNECTED, | 2610 | CFG80211_SME_CONNECTED, |
2590 | } sme_state; | 2611 | } sme_state; |
2591 | struct cfg80211_conn *conn; | 2612 | struct cfg80211_conn *conn; |
2592 | struct cfg80211_cached_keys *connect_keys; | 2613 | struct cfg80211_cached_keys *connect_keys; |
2593 | 2614 | ||
2594 | struct list_head event_list; | 2615 | struct list_head event_list; |
2595 | spinlock_t event_lock; | 2616 | spinlock_t event_lock; |
2596 | 2617 | ||
2597 | struct cfg80211_internal_bss *current_bss; /* associated / joined */ | 2618 | struct cfg80211_internal_bss *current_bss; /* associated / joined */ |
2598 | struct cfg80211_chan_def preset_chandef; | 2619 | struct cfg80211_chan_def preset_chandef; |
2599 | 2620 | ||
2600 | /* for AP and mesh channel tracking */ | 2621 | /* for AP and mesh channel tracking */ |
2601 | struct ieee80211_channel *channel; | 2622 | struct ieee80211_channel *channel; |
2602 | 2623 | ||
2603 | bool ibss_fixed; | 2624 | bool ibss_fixed; |
2604 | 2625 | ||
2605 | bool ps; | 2626 | bool ps; |
2606 | int ps_timeout; | 2627 | int ps_timeout; |
2607 | 2628 | ||
2608 | int beacon_interval; | 2629 | int beacon_interval; |
2609 | 2630 | ||
2610 | u32 ap_unexpected_nlportid; | 2631 | u32 ap_unexpected_nlportid; |
2611 | 2632 | ||
2612 | #ifdef CONFIG_CFG80211_WEXT | 2633 | #ifdef CONFIG_CFG80211_WEXT |
2613 | /* wext data */ | 2634 | /* wext data */ |
2614 | struct { | 2635 | struct { |
2615 | struct cfg80211_ibss_params ibss; | 2636 | struct cfg80211_ibss_params ibss; |
2616 | struct cfg80211_connect_params connect; | 2637 | struct cfg80211_connect_params connect; |
2617 | struct cfg80211_cached_keys *keys; | 2638 | struct cfg80211_cached_keys *keys; |
2618 | u8 *ie; | 2639 | u8 *ie; |
2619 | size_t ie_len; | 2640 | size_t ie_len; |
2620 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; | 2641 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; |
2621 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 2642 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
2622 | s8 default_key, default_mgmt_key; | 2643 | s8 default_key, default_mgmt_key; |
2623 | bool prev_bssid_valid; | 2644 | bool prev_bssid_valid; |
2624 | } wext; | 2645 | } wext; |
2625 | #endif | 2646 | #endif |
2626 | }; | 2647 | }; |
2627 | 2648 | ||
2628 | static inline u8 *wdev_address(struct wireless_dev *wdev) | 2649 | static inline u8 *wdev_address(struct wireless_dev *wdev) |
2629 | { | 2650 | { |
2630 | if (wdev->netdev) | 2651 | if (wdev->netdev) |
2631 | return wdev->netdev->dev_addr; | 2652 | return wdev->netdev->dev_addr; |
2632 | return wdev->address; | 2653 | return wdev->address; |
2633 | } | 2654 | } |
2634 | 2655 | ||
2635 | /** | 2656 | /** |
2636 | * wdev_priv - return wiphy priv from wireless_dev | 2657 | * wdev_priv - return wiphy priv from wireless_dev |
2637 | * | 2658 | * |
2638 | * @wdev: The wireless device whose wiphy's priv pointer to return | 2659 | * @wdev: The wireless device whose wiphy's priv pointer to return |
2639 | * Return: The wiphy priv of @wdev. | 2660 | * Return: The wiphy priv of @wdev. |
2640 | */ | 2661 | */ |
2641 | static inline void *wdev_priv(struct wireless_dev *wdev) | 2662 | static inline void *wdev_priv(struct wireless_dev *wdev) |
2642 | { | 2663 | { |
2643 | BUG_ON(!wdev); | 2664 | BUG_ON(!wdev); |
2644 | return wiphy_priv(wdev->wiphy); | 2665 | return wiphy_priv(wdev->wiphy); |
2645 | } | 2666 | } |
2646 | 2667 | ||
2647 | /** | 2668 | /** |
2648 | * DOC: Utility functions | 2669 | * DOC: Utility functions |
2649 | * | 2670 | * |
2650 | * cfg80211 offers a number of utility functions that can be useful. | 2671 | * cfg80211 offers a number of utility functions that can be useful. |
2651 | */ | 2672 | */ |
2652 | 2673 | ||
2653 | /** | 2674 | /** |
2654 | * ieee80211_channel_to_frequency - convert channel number to frequency | 2675 | * ieee80211_channel_to_frequency - convert channel number to frequency |
2655 | * @chan: channel number | 2676 | * @chan: channel number |
2656 | * @band: band, necessary due to channel number overlap | 2677 | * @band: band, necessary due to channel number overlap |
2657 | * Return: The corresponding frequency (in MHz), or 0 if the conversion failed. | 2678 | * Return: The corresponding frequency (in MHz), or 0 if the conversion failed. |
2658 | */ | 2679 | */ |
2659 | extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band); | 2680 | extern int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band); |
2660 | 2681 | ||
2661 | /** | 2682 | /** |
2662 | * ieee80211_frequency_to_channel - convert frequency to channel number | 2683 | * ieee80211_frequency_to_channel - convert frequency to channel number |
2663 | * @freq: center frequency | 2684 | * @freq: center frequency |
2664 | * Return: The corresponding channel, or 0 if the conversion failed. | 2685 | * Return: The corresponding channel, or 0 if the conversion failed. |
2665 | */ | 2686 | */ |
2666 | extern int ieee80211_frequency_to_channel(int freq); | 2687 | extern int ieee80211_frequency_to_channel(int freq); |
2667 | 2688 | ||
2668 | /* | 2689 | /* |
2669 | * Name indirection necessary because the ieee80211 code also has | 2690 | * Name indirection necessary because the ieee80211 code also has |
2670 | * a function named "ieee80211_get_channel", so if you include | 2691 | * a function named "ieee80211_get_channel", so if you include |
2671 | * cfg80211's header file you get cfg80211's version, if you try | 2692 | * cfg80211's header file you get cfg80211's version, if you try |
2672 | * to include both header files you'll (rightfully!) get a symbol | 2693 | * to include both header files you'll (rightfully!) get a symbol |
2673 | * clash. | 2694 | * clash. |
2674 | */ | 2695 | */ |
2675 | extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, | 2696 | extern struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy, |
2676 | int freq); | 2697 | int freq); |
2677 | /** | 2698 | /** |
2678 | * ieee80211_get_channel - get channel struct from wiphy for specified frequency | 2699 | * ieee80211_get_channel - get channel struct from wiphy for specified frequency |
2679 | * @wiphy: the struct wiphy to get the channel for | 2700 | * @wiphy: the struct wiphy to get the channel for |
2680 | * @freq: the center frequency of the channel | 2701 | * @freq: the center frequency of the channel |
2681 | * Return: The channel struct from @wiphy at @freq. | 2702 | * Return: The channel struct from @wiphy at @freq. |
2682 | */ | 2703 | */ |
2683 | static inline struct ieee80211_channel * | 2704 | static inline struct ieee80211_channel * |
2684 | ieee80211_get_channel(struct wiphy *wiphy, int freq) | 2705 | ieee80211_get_channel(struct wiphy *wiphy, int freq) |
2685 | { | 2706 | { |
2686 | return __ieee80211_get_channel(wiphy, freq); | 2707 | return __ieee80211_get_channel(wiphy, freq); |
2687 | } | 2708 | } |
2688 | 2709 | ||
2689 | /** | 2710 | /** |
2690 | * ieee80211_get_response_rate - get basic rate for a given rate | 2711 | * ieee80211_get_response_rate - get basic rate for a given rate |
2691 | * | 2712 | * |
2692 | * @sband: the band to look for rates in | 2713 | * @sband: the band to look for rates in |
2693 | * @basic_rates: bitmap of basic rates | 2714 | * @basic_rates: bitmap of basic rates |
2694 | * @bitrate: the bitrate for which to find the basic rate | 2715 | * @bitrate: the bitrate for which to find the basic rate |
2695 | * | 2716 | * |
2696 | * Return: The basic rate corresponding to a given bitrate, that | 2717 | * Return: The basic rate corresponding to a given bitrate, that |
2697 | * is the next lower bitrate contained in the basic rate map, | 2718 | * is the next lower bitrate contained in the basic rate map, |
2698 | * which is, for this function, given as a bitmap of indices of | 2719 | * which is, for this function, given as a bitmap of indices of |
2699 | * rates in the band's bitrate table. | 2720 | * rates in the band's bitrate table. |
2700 | */ | 2721 | */ |
2701 | struct ieee80211_rate * | 2722 | struct ieee80211_rate * |
2702 | ieee80211_get_response_rate(struct ieee80211_supported_band *sband, | 2723 | ieee80211_get_response_rate(struct ieee80211_supported_band *sband, |
2703 | u32 basic_rates, int bitrate); | 2724 | u32 basic_rates, int bitrate); |
2704 | 2725 | ||
2705 | /* | 2726 | /* |
2706 | * Radiotap parsing functions -- for controlled injection support | 2727 | * Radiotap parsing functions -- for controlled injection support |
2707 | * | 2728 | * |
2708 | * Implemented in net/wireless/radiotap.c | 2729 | * Implemented in net/wireless/radiotap.c |
2709 | * Documentation in Documentation/networking/radiotap-headers.txt | 2730 | * Documentation in Documentation/networking/radiotap-headers.txt |
2710 | */ | 2731 | */ |
2711 | 2732 | ||
2712 | struct radiotap_align_size { | 2733 | struct radiotap_align_size { |
2713 | uint8_t align:4, size:4; | 2734 | uint8_t align:4, size:4; |
2714 | }; | 2735 | }; |
2715 | 2736 | ||
2716 | struct ieee80211_radiotap_namespace { | 2737 | struct ieee80211_radiotap_namespace { |
2717 | const struct radiotap_align_size *align_size; | 2738 | const struct radiotap_align_size *align_size; |
2718 | int n_bits; | 2739 | int n_bits; |
2719 | uint32_t oui; | 2740 | uint32_t oui; |
2720 | uint8_t subns; | 2741 | uint8_t subns; |
2721 | }; | 2742 | }; |
2722 | 2743 | ||
2723 | struct ieee80211_radiotap_vendor_namespaces { | 2744 | struct ieee80211_radiotap_vendor_namespaces { |
2724 | const struct ieee80211_radiotap_namespace *ns; | 2745 | const struct ieee80211_radiotap_namespace *ns; |
2725 | int n_ns; | 2746 | int n_ns; |
2726 | }; | 2747 | }; |
2727 | 2748 | ||
2728 | /** | 2749 | /** |
2729 | * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args | 2750 | * struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args |
2730 | * @this_arg_index: index of current arg, valid after each successful call | 2751 | * @this_arg_index: index of current arg, valid after each successful call |
2731 | * to ieee80211_radiotap_iterator_next() | 2752 | * to ieee80211_radiotap_iterator_next() |
2732 | * @this_arg: pointer to current radiotap arg; it is valid after each | 2753 | * @this_arg: pointer to current radiotap arg; it is valid after each |
2733 | * call to ieee80211_radiotap_iterator_next() but also after | 2754 | * call to ieee80211_radiotap_iterator_next() but also after |
2734 | * ieee80211_radiotap_iterator_init() where it will point to | 2755 | * ieee80211_radiotap_iterator_init() where it will point to |
2735 | * the beginning of the actual data portion | 2756 | * the beginning of the actual data portion |
2736 | * @this_arg_size: length of the current arg, for convenience | 2757 | * @this_arg_size: length of the current arg, for convenience |
2737 | * @current_namespace: pointer to the current namespace definition | 2758 | * @current_namespace: pointer to the current namespace definition |
2738 | * (or internally %NULL if the current namespace is unknown) | 2759 | * (or internally %NULL if the current namespace is unknown) |
2739 | * @is_radiotap_ns: indicates whether the current namespace is the default | 2760 | * @is_radiotap_ns: indicates whether the current namespace is the default |
2740 | * radiotap namespace or not | 2761 | * radiotap namespace or not |
2741 | * | 2762 | * |
2742 | * @_rtheader: pointer to the radiotap header we are walking through | 2763 | * @_rtheader: pointer to the radiotap header we are walking through |
2743 | * @_max_length: length of radiotap header in cpu byte ordering | 2764 | * @_max_length: length of radiotap header in cpu byte ordering |
2744 | * @_arg_index: next argument index | 2765 | * @_arg_index: next argument index |
2745 | * @_arg: next argument pointer | 2766 | * @_arg: next argument pointer |
2746 | * @_next_bitmap: internal pointer to next present u32 | 2767 | * @_next_bitmap: internal pointer to next present u32 |
2747 | * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present | 2768 | * @_bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present |
2748 | * @_vns: vendor namespace definitions | 2769 | * @_vns: vendor namespace definitions |
2749 | * @_next_ns_data: beginning of the next namespace's data | 2770 | * @_next_ns_data: beginning of the next namespace's data |
2750 | * @_reset_on_ext: internal; reset the arg index to 0 when going to the | 2771 | * @_reset_on_ext: internal; reset the arg index to 0 when going to the |
2751 | * next bitmap word | 2772 | * next bitmap word |
2752 | * | 2773 | * |
2753 | * Describes the radiotap parser state. Fields prefixed with an underscore | 2774 | * Describes the radiotap parser state. Fields prefixed with an underscore |
2754 | * must not be used by users of the parser, only by the parser internally. | 2775 | * must not be used by users of the parser, only by the parser internally. |
2755 | */ | 2776 | */ |
2756 | 2777 | ||
2757 | struct ieee80211_radiotap_iterator { | 2778 | struct ieee80211_radiotap_iterator { |
2758 | struct ieee80211_radiotap_header *_rtheader; | 2779 | struct ieee80211_radiotap_header *_rtheader; |
2759 | const struct ieee80211_radiotap_vendor_namespaces *_vns; | 2780 | const struct ieee80211_radiotap_vendor_namespaces *_vns; |
2760 | const struct ieee80211_radiotap_namespace *current_namespace; | 2781 | const struct ieee80211_radiotap_namespace *current_namespace; |
2761 | 2782 | ||
2762 | unsigned char *_arg, *_next_ns_data; | 2783 | unsigned char *_arg, *_next_ns_data; |
2763 | __le32 *_next_bitmap; | 2784 | __le32 *_next_bitmap; |
2764 | 2785 | ||
2765 | unsigned char *this_arg; | 2786 | unsigned char *this_arg; |
2766 | int this_arg_index; | 2787 | int this_arg_index; |
2767 | int this_arg_size; | 2788 | int this_arg_size; |
2768 | 2789 | ||
2769 | int is_radiotap_ns; | 2790 | int is_radiotap_ns; |
2770 | 2791 | ||
2771 | int _max_length; | 2792 | int _max_length; |
2772 | int _arg_index; | 2793 | int _arg_index; |
2773 | uint32_t _bitmap_shifter; | 2794 | uint32_t _bitmap_shifter; |
2774 | int _reset_on_ext; | 2795 | int _reset_on_ext; |
2775 | }; | 2796 | }; |
2776 | 2797 | ||
2777 | extern int ieee80211_radiotap_iterator_init( | 2798 | extern int ieee80211_radiotap_iterator_init( |
2778 | struct ieee80211_radiotap_iterator *iterator, | 2799 | struct ieee80211_radiotap_iterator *iterator, |
2779 | struct ieee80211_radiotap_header *radiotap_header, | 2800 | struct ieee80211_radiotap_header *radiotap_header, |
2780 | int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns); | 2801 | int max_length, const struct ieee80211_radiotap_vendor_namespaces *vns); |
2781 | 2802 | ||
2782 | extern int ieee80211_radiotap_iterator_next( | 2803 | extern int ieee80211_radiotap_iterator_next( |
2783 | struct ieee80211_radiotap_iterator *iterator); | 2804 | struct ieee80211_radiotap_iterator *iterator); |
2784 | 2805 | ||
2785 | 2806 | ||
2786 | extern const unsigned char rfc1042_header[6]; | 2807 | extern const unsigned char rfc1042_header[6]; |
2787 | extern const unsigned char bridge_tunnel_header[6]; | 2808 | extern const unsigned char bridge_tunnel_header[6]; |
2788 | 2809 | ||
2789 | /** | 2810 | /** |
2790 | * ieee80211_get_hdrlen_from_skb - get header length from data | 2811 | * ieee80211_get_hdrlen_from_skb - get header length from data |
2791 | * | 2812 | * |
2792 | * @skb: the frame | 2813 | * @skb: the frame |
2793 | * | 2814 | * |
2794 | * Given an skb with a raw 802.11 header at the data pointer this function | 2815 | * Given an skb with a raw 802.11 header at the data pointer this function |
2795 | * returns the 802.11 header length. | 2816 | * returns the 802.11 header length. |
2796 | * | 2817 | * |
2797 | * Return: The 802.11 header length in bytes (not including encryption | 2818 | * Return: The 802.11 header length in bytes (not including encryption |
2798 | * headers). Or 0 if the data in the sk_buff is too short to contain a valid | 2819 | * headers). Or 0 if the data in the sk_buff is too short to contain a valid |
2799 | * 802.11 header. | 2820 | * 802.11 header. |
2800 | */ | 2821 | */ |
2801 | unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); | 2822 | unsigned int ieee80211_get_hdrlen_from_skb(const struct sk_buff *skb); |
2802 | 2823 | ||
2803 | /** | 2824 | /** |
2804 | * ieee80211_hdrlen - get header length in bytes from frame control | 2825 | * ieee80211_hdrlen - get header length in bytes from frame control |
2805 | * @fc: frame control field in little-endian format | 2826 | * @fc: frame control field in little-endian format |
2806 | * Return: The header length in bytes. | 2827 | * Return: The header length in bytes. |
2807 | */ | 2828 | */ |
2808 | unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); | 2829 | unsigned int __attribute_const__ ieee80211_hdrlen(__le16 fc); |
2809 | 2830 | ||
2810 | /** | 2831 | /** |
2811 | * ieee80211_get_mesh_hdrlen - get mesh extension header length | 2832 | * ieee80211_get_mesh_hdrlen - get mesh extension header length |
2812 | * @meshhdr: the mesh extension header, only the flags field | 2833 | * @meshhdr: the mesh extension header, only the flags field |
2813 | * (first byte) will be accessed | 2834 | * (first byte) will be accessed |
2814 | * Return: The length of the extension header, which is always at | 2835 | * Return: The length of the extension header, which is always at |
2815 | * least 6 bytes and at most 18 if address 5 and 6 are present. | 2836 | * least 6 bytes and at most 18 if address 5 and 6 are present. |
2816 | */ | 2837 | */ |
2817 | unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); | 2838 | unsigned int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr); |
2818 | 2839 | ||
2819 | /** | 2840 | /** |
2820 | * DOC: Data path helpers | 2841 | * DOC: Data path helpers |
2821 | * | 2842 | * |
2822 | * In addition to generic utilities, cfg80211 also offers | 2843 | * In addition to generic utilities, cfg80211 also offers |
2823 | * functions that help implement the data path for devices | 2844 | * functions that help implement the data path for devices |
2824 | * that do not do the 802.11/802.3 conversion on the device. | 2845 | * that do not do the 802.11/802.3 conversion on the device. |
2825 | */ | 2846 | */ |
2826 | 2847 | ||
2827 | /** | 2848 | /** |
2828 | * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 | 2849 | * ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3 |
2829 | * @skb: the 802.11 data frame | 2850 | * @skb: the 802.11 data frame |
2830 | * @addr: the device MAC address | 2851 | * @addr: the device MAC address |
2831 | * @iftype: the virtual interface type | 2852 | * @iftype: the virtual interface type |
2832 | * Return: 0 on success. Non-zero on error. | 2853 | * Return: 0 on success. Non-zero on error. |
2833 | */ | 2854 | */ |
2834 | int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, | 2855 | int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, |
2835 | enum nl80211_iftype iftype); | 2856 | enum nl80211_iftype iftype); |
2836 | 2857 | ||
2837 | /** | 2858 | /** |
2838 | * ieee80211_data_from_8023 - convert an 802.3 frame to 802.11 | 2859 | * ieee80211_data_from_8023 - convert an 802.3 frame to 802.11 |
2839 | * @skb: the 802.3 frame | 2860 | * @skb: the 802.3 frame |
2840 | * @addr: the device MAC address | 2861 | * @addr: the device MAC address |
2841 | * @iftype: the virtual interface type | 2862 | * @iftype: the virtual interface type |
2842 | * @bssid: the network bssid (used only for iftype STATION and ADHOC) | 2863 | * @bssid: the network bssid (used only for iftype STATION and ADHOC) |
2843 | * @qos: build 802.11 QoS data frame | 2864 | * @qos: build 802.11 QoS data frame |
2844 | * Return: 0 on success, or a negative error code. | 2865 | * Return: 0 on success, or a negative error code. |
2845 | */ | 2866 | */ |
2846 | int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, | 2867 | int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, |
2847 | enum nl80211_iftype iftype, u8 *bssid, bool qos); | 2868 | enum nl80211_iftype iftype, u8 *bssid, bool qos); |
2848 | 2869 | ||
2849 | /** | 2870 | /** |
2850 | * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame | 2871 | * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame |
2851 | * | 2872 | * |
2852 | * Decode an IEEE 802.11n A-MSDU frame and convert it to a list of | 2873 | * Decode an IEEE 802.11n A-MSDU frame and convert it to a list of |
2853 | * 802.3 frames. The @list will be empty if the decode fails. The | 2874 | * 802.3 frames. The @list will be empty if the decode fails. The |
2854 | * @skb is consumed after the function returns. | 2875 | * @skb is consumed after the function returns. |
2855 | * | 2876 | * |
2856 | * @skb: The input IEEE 802.11n A-MSDU frame. | 2877 | * @skb: The input IEEE 802.11n A-MSDU frame. |
2857 | * @list: The output list of 802.3 frames. It must be allocated and | 2878 | * @list: The output list of 802.3 frames. It must be allocated and |
2858 | * initialized by by the caller. | 2879 | * initialized by by the caller. |
2859 | * @addr: The device MAC address. | 2880 | * @addr: The device MAC address. |
2860 | * @iftype: The device interface type. | 2881 | * @iftype: The device interface type. |
2861 | * @extra_headroom: The hardware extra headroom for SKBs in the @list. | 2882 | * @extra_headroom: The hardware extra headroom for SKBs in the @list. |
2862 | * @has_80211_header: Set it true if SKB is with IEEE 802.11 header. | 2883 | * @has_80211_header: Set it true if SKB is with IEEE 802.11 header. |
2863 | */ | 2884 | */ |
2864 | void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, | 2885 | void ieee80211_amsdu_to_8023s(struct sk_buff *skb, struct sk_buff_head *list, |
2865 | const u8 *addr, enum nl80211_iftype iftype, | 2886 | const u8 *addr, enum nl80211_iftype iftype, |
2866 | const unsigned int extra_headroom, | 2887 | const unsigned int extra_headroom, |
2867 | bool has_80211_header); | 2888 | bool has_80211_header); |
2868 | 2889 | ||
2869 | /** | 2890 | /** |
2870 | * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame | 2891 | * cfg80211_classify8021d - determine the 802.1p/1d tag for a data frame |
2871 | * @skb: the data frame | 2892 | * @skb: the data frame |
2872 | * Return: The 802.1p/1d tag. | 2893 | * Return: The 802.1p/1d tag. |
2873 | */ | 2894 | */ |
2874 | unsigned int cfg80211_classify8021d(struct sk_buff *skb); | 2895 | unsigned int cfg80211_classify8021d(struct sk_buff *skb); |
2875 | 2896 | ||
2876 | /** | 2897 | /** |
2877 | * cfg80211_find_ie - find information element in data | 2898 | * cfg80211_find_ie - find information element in data |
2878 | * | 2899 | * |
2879 | * @eid: element ID | 2900 | * @eid: element ID |
2880 | * @ies: data consisting of IEs | 2901 | * @ies: data consisting of IEs |
2881 | * @len: length of data | 2902 | * @len: length of data |
2882 | * | 2903 | * |
2883 | * Return: %NULL if the element ID could not be found or if | 2904 | * Return: %NULL if the element ID could not be found or if |
2884 | * the element is invalid (claims to be longer than the given | 2905 | * the element is invalid (claims to be longer than the given |
2885 | * data), or a pointer to the first byte of the requested | 2906 | * data), or a pointer to the first byte of the requested |
2886 | * element, that is the byte containing the element ID. | 2907 | * element, that is the byte containing the element ID. |
2887 | * | 2908 | * |
2888 | * Note: There are no checks on the element length other than | 2909 | * Note: There are no checks on the element length other than |
2889 | * having to fit into the given data. | 2910 | * having to fit into the given data. |
2890 | */ | 2911 | */ |
2891 | const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len); | 2912 | const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len); |
2892 | 2913 | ||
2893 | /** | 2914 | /** |
2894 | * cfg80211_find_vendor_ie - find vendor specific information element in data | 2915 | * cfg80211_find_vendor_ie - find vendor specific information element in data |
2895 | * | 2916 | * |
2896 | * @oui: vendor OUI | 2917 | * @oui: vendor OUI |
2897 | * @oui_type: vendor-specific OUI type | 2918 | * @oui_type: vendor-specific OUI type |
2898 | * @ies: data consisting of IEs | 2919 | * @ies: data consisting of IEs |
2899 | * @len: length of data | 2920 | * @len: length of data |
2900 | * | 2921 | * |
2901 | * Return: %NULL if the vendor specific element ID could not be found or if the | 2922 | * Return: %NULL if the vendor specific element ID could not be found or if the |
2902 | * element is invalid (claims to be longer than the given data), or a pointer to | 2923 | * element is invalid (claims to be longer than the given data), or a pointer to |
2903 | * the first byte of the requested element, that is the byte containing the | 2924 | * the first byte of the requested element, that is the byte containing the |
2904 | * element ID. | 2925 | * element ID. |
2905 | * | 2926 | * |
2906 | * Note: There are no checks on the element length other than having to fit into | 2927 | * Note: There are no checks on the element length other than having to fit into |
2907 | * the given data. | 2928 | * the given data. |
2908 | */ | 2929 | */ |
2909 | const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, | 2930 | const u8 *cfg80211_find_vendor_ie(unsigned int oui, u8 oui_type, |
2910 | const u8 *ies, int len); | 2931 | const u8 *ies, int len); |
2911 | 2932 | ||
2912 | /** | 2933 | /** |
2913 | * DOC: Regulatory enforcement infrastructure | 2934 | * DOC: Regulatory enforcement infrastructure |
2914 | * | 2935 | * |
2915 | * TODO | 2936 | * TODO |
2916 | */ | 2937 | */ |
2917 | 2938 | ||
2918 | /** | 2939 | /** |
2919 | * regulatory_hint - driver hint to the wireless core a regulatory domain | 2940 | * regulatory_hint - driver hint to the wireless core a regulatory domain |
2920 | * @wiphy: the wireless device giving the hint (used only for reporting | 2941 | * @wiphy: the wireless device giving the hint (used only for reporting |
2921 | * conflicts) | 2942 | * conflicts) |
2922 | * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain | 2943 | * @alpha2: the ISO/IEC 3166 alpha2 the driver claims its regulatory domain |
2923 | * should be in. If @rd is set this should be NULL. Note that if you | 2944 | * should be in. If @rd is set this should be NULL. Note that if you |
2924 | * set this to NULL you should still set rd->alpha2 to some accepted | 2945 | * set this to NULL you should still set rd->alpha2 to some accepted |
2925 | * alpha2. | 2946 | * alpha2. |
2926 | * | 2947 | * |
2927 | * Wireless drivers can use this function to hint to the wireless core | 2948 | * Wireless drivers can use this function to hint to the wireless core |
2928 | * what it believes should be the current regulatory domain by | 2949 | * what it believes should be the current regulatory domain by |
2929 | * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory | 2950 | * giving it an ISO/IEC 3166 alpha2 country code it knows its regulatory |
2930 | * domain should be in or by providing a completely build regulatory domain. | 2951 | * domain should be in or by providing a completely build regulatory domain. |
2931 | * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried | 2952 | * If the driver provides an ISO/IEC 3166 alpha2 userspace will be queried |
2932 | * for a regulatory domain structure for the respective country. | 2953 | * for a regulatory domain structure for the respective country. |
2933 | * | 2954 | * |
2934 | * The wiphy must have been registered to cfg80211 prior to this call. | 2955 | * The wiphy must have been registered to cfg80211 prior to this call. |
2935 | * For cfg80211 drivers this means you must first use wiphy_register(), | 2956 | * For cfg80211 drivers this means you must first use wiphy_register(), |
2936 | * for mac80211 drivers you must first use ieee80211_register_hw(). | 2957 | * for mac80211 drivers you must first use ieee80211_register_hw(). |
2937 | * | 2958 | * |
2938 | * Drivers should check the return value, its possible you can get | 2959 | * Drivers should check the return value, its possible you can get |
2939 | * an -ENOMEM. | 2960 | * an -ENOMEM. |
2940 | * | 2961 | * |
2941 | * Return: 0 on success. -ENOMEM. | 2962 | * Return: 0 on success. -ENOMEM. |
2942 | */ | 2963 | */ |
2943 | extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2); | 2964 | extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2); |
2944 | 2965 | ||
2945 | /** | 2966 | /** |
2946 | * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain | 2967 | * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain |
2947 | * @wiphy: the wireless device we want to process the regulatory domain on | 2968 | * @wiphy: the wireless device we want to process the regulatory domain on |
2948 | * @regd: the custom regulatory domain to use for this wiphy | 2969 | * @regd: the custom regulatory domain to use for this wiphy |
2949 | * | 2970 | * |
2950 | * Drivers can sometimes have custom regulatory domains which do not apply | 2971 | * Drivers can sometimes have custom regulatory domains which do not apply |
2951 | * to a specific country. Drivers can use this to apply such custom regulatory | 2972 | * to a specific country. Drivers can use this to apply such custom regulatory |
2952 | * domains. This routine must be called prior to wiphy registration. The | 2973 | * domains. This routine must be called prior to wiphy registration. The |
2953 | * custom regulatory domain will be trusted completely and as such previous | 2974 | * custom regulatory domain will be trusted completely and as such previous |
2954 | * default channel settings will be disregarded. If no rule is found for a | 2975 | * default channel settings will be disregarded. If no rule is found for a |
2955 | * channel on the regulatory domain the channel will be disabled. | 2976 | * channel on the regulatory domain the channel will be disabled. |
2956 | */ | 2977 | */ |
2957 | extern void wiphy_apply_custom_regulatory( | 2978 | extern void wiphy_apply_custom_regulatory( |
2958 | struct wiphy *wiphy, | 2979 | struct wiphy *wiphy, |
2959 | const struct ieee80211_regdomain *regd); | 2980 | const struct ieee80211_regdomain *regd); |
2960 | 2981 | ||
2961 | /** | 2982 | /** |
2962 | * freq_reg_info - get regulatory information for the given frequency | 2983 | * freq_reg_info - get regulatory information for the given frequency |
2963 | * @wiphy: the wiphy for which we want to process this rule for | 2984 | * @wiphy: the wiphy for which we want to process this rule for |
2964 | * @center_freq: Frequency in KHz for which we want regulatory information for | 2985 | * @center_freq: Frequency in KHz for which we want regulatory information for |
2965 | * | 2986 | * |
2966 | * Use this function to get the regulatory rule for a specific frequency on | 2987 | * Use this function to get the regulatory rule for a specific frequency on |
2967 | * a given wireless device. If the device has a specific regulatory domain | 2988 | * a given wireless device. If the device has a specific regulatory domain |
2968 | * it wants to follow we respect that unless a country IE has been received | 2989 | * it wants to follow we respect that unless a country IE has been received |
2969 | * and processed already. | 2990 | * and processed already. |
2970 | * | 2991 | * |
2971 | * Return: A valid pointer, or, when an error occurs, for example if no rule | 2992 | * Return: A valid pointer, or, when an error occurs, for example if no rule |
2972 | * can be found, the return value is encoded using ERR_PTR(). Use IS_ERR() to | 2993 | * can be found, the return value is encoded using ERR_PTR(). Use IS_ERR() to |
2973 | * check and PTR_ERR() to obtain the numeric return value. The numeric return | 2994 | * check and PTR_ERR() to obtain the numeric return value. The numeric return |
2974 | * value will be -ERANGE if we determine the given center_freq does not even | 2995 | * value will be -ERANGE if we determine the given center_freq does not even |
2975 | * have a regulatory rule for a frequency range in the center_freq's band. | 2996 | * have a regulatory rule for a frequency range in the center_freq's band. |
2976 | * See freq_in_rule_band() for our current definition of a band -- this is | 2997 | * See freq_in_rule_band() for our current definition of a band -- this is |
2977 | * purely subjective and right now it's 802.11 specific. | 2998 | * purely subjective and right now it's 802.11 specific. |
2978 | */ | 2999 | */ |
2979 | const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, | 3000 | const struct ieee80211_reg_rule *freq_reg_info(struct wiphy *wiphy, |
2980 | u32 center_freq); | 3001 | u32 center_freq); |
2981 | 3002 | ||
2982 | /* | 3003 | /* |
2983 | * callbacks for asynchronous cfg80211 methods, notification | 3004 | * callbacks for asynchronous cfg80211 methods, notification |
2984 | * functions and BSS handling helpers | 3005 | * functions and BSS handling helpers |
2985 | */ | 3006 | */ |
2986 | 3007 | ||
2987 | /** | 3008 | /** |
2988 | * cfg80211_scan_done - notify that scan finished | 3009 | * cfg80211_scan_done - notify that scan finished |
2989 | * | 3010 | * |
2990 | * @request: the corresponding scan request | 3011 | * @request: the corresponding scan request |
2991 | * @aborted: set to true if the scan was aborted for any reason, | 3012 | * @aborted: set to true if the scan was aborted for any reason, |
2992 | * userspace will be notified of that | 3013 | * userspace will be notified of that |
2993 | */ | 3014 | */ |
2994 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted); | 3015 | void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted); |
2995 | 3016 | ||
2996 | /** | 3017 | /** |
2997 | * cfg80211_sched_scan_results - notify that new scan results are available | 3018 | * cfg80211_sched_scan_results - notify that new scan results are available |
2998 | * | 3019 | * |
2999 | * @wiphy: the wiphy which got scheduled scan results | 3020 | * @wiphy: the wiphy which got scheduled scan results |
3000 | */ | 3021 | */ |
3001 | void cfg80211_sched_scan_results(struct wiphy *wiphy); | 3022 | void cfg80211_sched_scan_results(struct wiphy *wiphy); |
3002 | 3023 | ||
3003 | /** | 3024 | /** |
3004 | * cfg80211_sched_scan_stopped - notify that the scheduled scan has stopped | 3025 | * cfg80211_sched_scan_stopped - notify that the scheduled scan has stopped |
3005 | * | 3026 | * |
3006 | * @wiphy: the wiphy on which the scheduled scan stopped | 3027 | * @wiphy: the wiphy on which the scheduled scan stopped |
3007 | * | 3028 | * |
3008 | * The driver can call this function to inform cfg80211 that the | 3029 | * The driver can call this function to inform cfg80211 that the |
3009 | * scheduled scan had to be stopped, for whatever reason. The driver | 3030 | * scheduled scan had to be stopped, for whatever reason. The driver |
3010 | * is then called back via the sched_scan_stop operation when done. | 3031 | * is then called back via the sched_scan_stop operation when done. |
3011 | */ | 3032 | */ |
3012 | void cfg80211_sched_scan_stopped(struct wiphy *wiphy); | 3033 | void cfg80211_sched_scan_stopped(struct wiphy *wiphy); |
3013 | 3034 | ||
3014 | /** | 3035 | /** |
3015 | * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame | 3036 | * cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame |
3016 | * | 3037 | * |
3017 | * @wiphy: the wiphy reporting the BSS | 3038 | * @wiphy: the wiphy reporting the BSS |
3018 | * @channel: The channel the frame was received on | 3039 | * @channel: The channel the frame was received on |
3019 | * @mgmt: the management frame (probe response or beacon) | 3040 | * @mgmt: the management frame (probe response or beacon) |
3020 | * @len: length of the management frame | 3041 | * @len: length of the management frame |
3021 | * @signal: the signal strength, type depends on the wiphy's signal_type | 3042 | * @signal: the signal strength, type depends on the wiphy's signal_type |
3022 | * @gfp: context flags | 3043 | * @gfp: context flags |
3023 | * | 3044 | * |
3024 | * This informs cfg80211 that BSS information was found and | 3045 | * This informs cfg80211 that BSS information was found and |
3025 | * the BSS should be updated/added. | 3046 | * the BSS should be updated/added. |
3026 | * | 3047 | * |
3027 | * Return: A referenced struct, must be released with cfg80211_put_bss()! | 3048 | * Return: A referenced struct, must be released with cfg80211_put_bss()! |
3028 | * Or %NULL on error. | 3049 | * Or %NULL on error. |
3029 | */ | 3050 | */ |
3030 | struct cfg80211_bss * __must_check | 3051 | struct cfg80211_bss * __must_check |
3031 | cfg80211_inform_bss_frame(struct wiphy *wiphy, | 3052 | cfg80211_inform_bss_frame(struct wiphy *wiphy, |
3032 | struct ieee80211_channel *channel, | 3053 | struct ieee80211_channel *channel, |
3033 | struct ieee80211_mgmt *mgmt, size_t len, | 3054 | struct ieee80211_mgmt *mgmt, size_t len, |
3034 | s32 signal, gfp_t gfp); | 3055 | s32 signal, gfp_t gfp); |
3035 | 3056 | ||
3036 | /** | 3057 | /** |
3037 | * cfg80211_inform_bss - inform cfg80211 of a new BSS | 3058 | * cfg80211_inform_bss - inform cfg80211 of a new BSS |
3038 | * | 3059 | * |
3039 | * @wiphy: the wiphy reporting the BSS | 3060 | * @wiphy: the wiphy reporting the BSS |
3040 | * @channel: The channel the frame was received on | 3061 | * @channel: The channel the frame was received on |
3041 | * @bssid: the BSSID of the BSS | 3062 | * @bssid: the BSSID of the BSS |
3042 | * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) | 3063 | * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) |
3043 | * @capability: the capability field sent by the peer | 3064 | * @capability: the capability field sent by the peer |
3044 | * @beacon_interval: the beacon interval announced by the peer | 3065 | * @beacon_interval: the beacon interval announced by the peer |
3045 | * @ie: additional IEs sent by the peer | 3066 | * @ie: additional IEs sent by the peer |
3046 | * @ielen: length of the additional IEs | 3067 | * @ielen: length of the additional IEs |
3047 | * @signal: the signal strength, type depends on the wiphy's signal_type | 3068 | * @signal: the signal strength, type depends on the wiphy's signal_type |
3048 | * @gfp: context flags | 3069 | * @gfp: context flags |
3049 | * | 3070 | * |
3050 | * This informs cfg80211 that BSS information was found and | 3071 | * This informs cfg80211 that BSS information was found and |
3051 | * the BSS should be updated/added. | 3072 | * the BSS should be updated/added. |
3052 | * | 3073 | * |
3053 | * Return: A referenced struct, must be released with cfg80211_put_bss()! | 3074 | * Return: A referenced struct, must be released with cfg80211_put_bss()! |
3054 | * Or %NULL on error. | 3075 | * Or %NULL on error. |
3055 | */ | 3076 | */ |
3056 | struct cfg80211_bss * __must_check | 3077 | struct cfg80211_bss * __must_check |
3057 | cfg80211_inform_bss(struct wiphy *wiphy, | 3078 | cfg80211_inform_bss(struct wiphy *wiphy, |
3058 | struct ieee80211_channel *channel, | 3079 | struct ieee80211_channel *channel, |
3059 | const u8 *bssid, u64 tsf, u16 capability, | 3080 | const u8 *bssid, u64 tsf, u16 capability, |
3060 | u16 beacon_interval, const u8 *ie, size_t ielen, | 3081 | u16 beacon_interval, const u8 *ie, size_t ielen, |
3061 | s32 signal, gfp_t gfp); | 3082 | s32 signal, gfp_t gfp); |
3062 | 3083 | ||
3063 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, | 3084 | struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, |
3064 | struct ieee80211_channel *channel, | 3085 | struct ieee80211_channel *channel, |
3065 | const u8 *bssid, | 3086 | const u8 *bssid, |
3066 | const u8 *ssid, size_t ssid_len, | 3087 | const u8 *ssid, size_t ssid_len, |
3067 | u16 capa_mask, u16 capa_val); | 3088 | u16 capa_mask, u16 capa_val); |
3068 | static inline struct cfg80211_bss * | 3089 | static inline struct cfg80211_bss * |
3069 | cfg80211_get_ibss(struct wiphy *wiphy, | 3090 | cfg80211_get_ibss(struct wiphy *wiphy, |
3070 | struct ieee80211_channel *channel, | 3091 | struct ieee80211_channel *channel, |
3071 | const u8 *ssid, size_t ssid_len) | 3092 | const u8 *ssid, size_t ssid_len) |
3072 | { | 3093 | { |
3073 | return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len, | 3094 | return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len, |
3074 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); | 3095 | WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS); |
3075 | } | 3096 | } |
3076 | 3097 | ||
3077 | struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy, | 3098 | struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy, |
3078 | struct ieee80211_channel *channel, | 3099 | struct ieee80211_channel *channel, |
3079 | const u8 *meshid, size_t meshidlen, | 3100 | const u8 *meshid, size_t meshidlen, |
3080 | const u8 *meshcfg); | 3101 | const u8 *meshcfg); |
3081 | /** | 3102 | /** |
3082 | * cfg80211_ref_bss - reference BSS struct | 3103 | * cfg80211_ref_bss - reference BSS struct |
3083 | * @bss: the BSS struct to reference | 3104 | * @bss: the BSS struct to reference |
3084 | * | 3105 | * |
3085 | * Increments the refcount of the given BSS struct. | 3106 | * Increments the refcount of the given BSS struct. |
3086 | */ | 3107 | */ |
3087 | void cfg80211_ref_bss(struct cfg80211_bss *bss); | 3108 | void cfg80211_ref_bss(struct cfg80211_bss *bss); |
3088 | 3109 | ||
3089 | /** | 3110 | /** |
3090 | * cfg80211_put_bss - unref BSS struct | 3111 | * cfg80211_put_bss - unref BSS struct |
3091 | * @bss: the BSS struct | 3112 | * @bss: the BSS struct |
3092 | * | 3113 | * |
3093 | * Decrements the refcount of the given BSS struct. | 3114 | * Decrements the refcount of the given BSS struct. |
3094 | */ | 3115 | */ |
3095 | void cfg80211_put_bss(struct cfg80211_bss *bss); | 3116 | void cfg80211_put_bss(struct cfg80211_bss *bss); |
3096 | 3117 | ||
3097 | /** | 3118 | /** |
3098 | * cfg80211_unlink_bss - unlink BSS from internal data structures | 3119 | * cfg80211_unlink_bss - unlink BSS from internal data structures |
3099 | * @wiphy: the wiphy | 3120 | * @wiphy: the wiphy |
3100 | * @bss: the bss to remove | 3121 | * @bss: the bss to remove |
3101 | * | 3122 | * |
3102 | * This function removes the given BSS from the internal data structures | 3123 | * This function removes the given BSS from the internal data structures |
3103 | * thereby making it no longer show up in scan results etc. Use this | 3124 | * thereby making it no longer show up in scan results etc. Use this |
3104 | * function when you detect a BSS is gone. Normally BSSes will also time | 3125 | * function when you detect a BSS is gone. Normally BSSes will also time |
3105 | * out, so it is not necessary to use this function at all. | 3126 | * out, so it is not necessary to use this function at all. |
3106 | */ | 3127 | */ |
3107 | void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); | 3128 | void cfg80211_unlink_bss(struct wiphy *wiphy, struct cfg80211_bss *bss); |
3108 | 3129 | ||
3109 | /** | 3130 | /** |
3110 | * cfg80211_send_rx_auth - notification of processed authentication | 3131 | * cfg80211_send_rx_auth - notification of processed authentication |
3111 | * @dev: network device | 3132 | * @dev: network device |
3112 | * @buf: authentication frame (header + body) | 3133 | * @buf: authentication frame (header + body) |
3113 | * @len: length of the frame data | 3134 | * @len: length of the frame data |
3114 | * | 3135 | * |
3115 | * This function is called whenever an authentication has been processed in | 3136 | * This function is called whenever an authentication has been processed in |
3116 | * station mode. The driver is required to call either this function or | 3137 | * station mode. The driver is required to call either this function or |
3117 | * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth() | 3138 | * cfg80211_send_auth_timeout() to indicate the result of cfg80211_ops::auth() |
3118 | * call. This function may sleep. | 3139 | * call. This function may sleep. |
3119 | */ | 3140 | */ |
3120 | void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); | 3141 | void cfg80211_send_rx_auth(struct net_device *dev, const u8 *buf, size_t len); |
3121 | 3142 | ||
3122 | /** | 3143 | /** |
3123 | * cfg80211_send_auth_timeout - notification of timed out authentication | 3144 | * cfg80211_send_auth_timeout - notification of timed out authentication |
3124 | * @dev: network device | 3145 | * @dev: network device |
3125 | * @addr: The MAC address of the device with which the authentication timed out | 3146 | * @addr: The MAC address of the device with which the authentication timed out |
3126 | * | 3147 | * |
3127 | * This function may sleep. | 3148 | * This function may sleep. |
3128 | */ | 3149 | */ |
3129 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); | 3150 | void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr); |
3130 | 3151 | ||
3131 | /** | 3152 | /** |
3132 | * cfg80211_send_rx_assoc - notification of processed association | 3153 | * cfg80211_send_rx_assoc - notification of processed association |
3133 | * @dev: network device | 3154 | * @dev: network device |
3134 | * @bss: the BSS struct association was requested for, the struct reference | 3155 | * @bss: the BSS struct association was requested for, the struct reference |
3135 | * is owned by cfg80211 after this call | 3156 | * is owned by cfg80211 after this call |
3136 | * @buf: (re)association response frame (header + body) | 3157 | * @buf: (re)association response frame (header + body) |
3137 | * @len: length of the frame data | 3158 | * @len: length of the frame data |
3138 | * | 3159 | * |
3139 | * This function is called whenever a (re)association response has been | 3160 | * This function is called whenever a (re)association response has been |
3140 | * processed in station mode. The driver is required to call either this | 3161 | * processed in station mode. The driver is required to call either this |
3141 | * function or cfg80211_send_assoc_timeout() to indicate the result of | 3162 | * function or cfg80211_send_assoc_timeout() to indicate the result of |
3142 | * cfg80211_ops::assoc() call. This function may sleep. | 3163 | * cfg80211_ops::assoc() call. This function may sleep. |
3143 | */ | 3164 | */ |
3144 | void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, | 3165 | void cfg80211_send_rx_assoc(struct net_device *dev, struct cfg80211_bss *bss, |
3145 | const u8 *buf, size_t len); | 3166 | const u8 *buf, size_t len); |
3146 | 3167 | ||
3147 | /** | 3168 | /** |
3148 | * cfg80211_send_assoc_timeout - notification of timed out association | 3169 | * cfg80211_send_assoc_timeout - notification of timed out association |
3149 | * @dev: network device | 3170 | * @dev: network device |
3150 | * @addr: The MAC address of the device with which the association timed out | 3171 | * @addr: The MAC address of the device with which the association timed out |
3151 | * | 3172 | * |
3152 | * This function may sleep. | 3173 | * This function may sleep. |
3153 | */ | 3174 | */ |
3154 | void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); | 3175 | void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr); |
3155 | 3176 | ||
3156 | /** | 3177 | /** |
3157 | * cfg80211_send_deauth - notification of processed deauthentication | 3178 | * cfg80211_send_deauth - notification of processed deauthentication |
3158 | * @dev: network device | 3179 | * @dev: network device |
3159 | * @buf: deauthentication frame (header + body) | 3180 | * @buf: deauthentication frame (header + body) |
3160 | * @len: length of the frame data | 3181 | * @len: length of the frame data |
3161 | * | 3182 | * |
3162 | * This function is called whenever deauthentication has been processed in | 3183 | * This function is called whenever deauthentication has been processed in |
3163 | * station mode. This includes both received deauthentication frames and | 3184 | * station mode. This includes both received deauthentication frames and |
3164 | * locally generated ones. This function may sleep. | 3185 | * locally generated ones. This function may sleep. |
3165 | */ | 3186 | */ |
3166 | void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); | 3187 | void cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); |
3167 | 3188 | ||
3168 | /** | 3189 | /** |
3169 | * __cfg80211_send_deauth - notification of processed deauthentication | 3190 | * __cfg80211_send_deauth - notification of processed deauthentication |
3170 | * @dev: network device | 3191 | * @dev: network device |
3171 | * @buf: deauthentication frame (header + body) | 3192 | * @buf: deauthentication frame (header + body) |
3172 | * @len: length of the frame data | 3193 | * @len: length of the frame data |
3173 | * | 3194 | * |
3174 | * Like cfg80211_send_deauth(), but doesn't take the wdev lock. | 3195 | * Like cfg80211_send_deauth(), but doesn't take the wdev lock. |
3175 | */ | 3196 | */ |
3176 | void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); | 3197 | void __cfg80211_send_deauth(struct net_device *dev, const u8 *buf, size_t len); |
3177 | 3198 | ||
3178 | /** | 3199 | /** |
3179 | * cfg80211_send_disassoc - notification of processed disassociation | 3200 | * cfg80211_send_disassoc - notification of processed disassociation |
3180 | * @dev: network device | 3201 | * @dev: network device |
3181 | * @buf: disassociation response frame (header + body) | 3202 | * @buf: disassociation response frame (header + body) |
3182 | * @len: length of the frame data | 3203 | * @len: length of the frame data |
3183 | * | 3204 | * |
3184 | * This function is called whenever disassociation has been processed in | 3205 | * This function is called whenever disassociation has been processed in |
3185 | * station mode. This includes both received disassociation frames and locally | 3206 | * station mode. This includes both received disassociation frames and locally |
3186 | * generated ones. This function may sleep. | 3207 | * generated ones. This function may sleep. |
3187 | */ | 3208 | */ |
3188 | void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); | 3209 | void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len); |
3189 | 3210 | ||
3190 | /** | 3211 | /** |
3191 | * __cfg80211_send_disassoc - notification of processed disassociation | 3212 | * __cfg80211_send_disassoc - notification of processed disassociation |
3192 | * @dev: network device | 3213 | * @dev: network device |
3193 | * @buf: disassociation response frame (header + body) | 3214 | * @buf: disassociation response frame (header + body) |
3194 | * @len: length of the frame data | 3215 | * @len: length of the frame data |
3195 | * | 3216 | * |
3196 | * Like cfg80211_send_disassoc(), but doesn't take the wdev lock. | 3217 | * Like cfg80211_send_disassoc(), but doesn't take the wdev lock. |
3197 | */ | 3218 | */ |
3198 | void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, | 3219 | void __cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, |
3199 | size_t len); | 3220 | size_t len); |
3200 | 3221 | ||
3201 | /** | 3222 | /** |
3202 | * cfg80211_send_unprot_deauth - notification of unprotected deauthentication | 3223 | * cfg80211_send_unprot_deauth - notification of unprotected deauthentication |
3203 | * @dev: network device | 3224 | * @dev: network device |
3204 | * @buf: deauthentication frame (header + body) | 3225 | * @buf: deauthentication frame (header + body) |
3205 | * @len: length of the frame data | 3226 | * @len: length of the frame data |
3206 | * | 3227 | * |
3207 | * This function is called whenever a received Deauthentication frame has been | 3228 | * This function is called whenever a received Deauthentication frame has been |
3208 | * dropped in station mode because of MFP being used but the Deauthentication | 3229 | * dropped in station mode because of MFP being used but the Deauthentication |
3209 | * frame was not protected. This function may sleep. | 3230 | * frame was not protected. This function may sleep. |
3210 | */ | 3231 | */ |
3211 | void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, | 3232 | void cfg80211_send_unprot_deauth(struct net_device *dev, const u8 *buf, |
3212 | size_t len); | 3233 | size_t len); |
3213 | 3234 | ||
3214 | /** | 3235 | /** |
3215 | * cfg80211_send_unprot_disassoc - notification of unprotected disassociation | 3236 | * cfg80211_send_unprot_disassoc - notification of unprotected disassociation |
3216 | * @dev: network device | 3237 | * @dev: network device |
3217 | * @buf: disassociation frame (header + body) | 3238 | * @buf: disassociation frame (header + body) |
3218 | * @len: length of the frame data | 3239 | * @len: length of the frame data |
3219 | * | 3240 | * |
3220 | * This function is called whenever a received Disassociation frame has been | 3241 | * This function is called whenever a received Disassociation frame has been |
3221 | * dropped in station mode because of MFP being used but the Disassociation | 3242 | * dropped in station mode because of MFP being used but the Disassociation |
3222 | * frame was not protected. This function may sleep. | 3243 | * frame was not protected. This function may sleep. |
3223 | */ | 3244 | */ |
3224 | void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, | 3245 | void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, |
3225 | size_t len); | 3246 | size_t len); |
3226 | 3247 | ||
3227 | /** | 3248 | /** |
3228 | * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) | 3249 | * cfg80211_michael_mic_failure - notification of Michael MIC failure (TKIP) |
3229 | * @dev: network device | 3250 | * @dev: network device |
3230 | * @addr: The source MAC address of the frame | 3251 | * @addr: The source MAC address of the frame |
3231 | * @key_type: The key type that the received frame used | 3252 | * @key_type: The key type that the received frame used |
3232 | * @key_id: Key identifier (0..3). Can be -1 if missing. | 3253 | * @key_id: Key identifier (0..3). Can be -1 if missing. |
3233 | * @tsc: The TSC value of the frame that generated the MIC failure (6 octets) | 3254 | * @tsc: The TSC value of the frame that generated the MIC failure (6 octets) |
3234 | * @gfp: allocation flags | 3255 | * @gfp: allocation flags |
3235 | * | 3256 | * |
3236 | * This function is called whenever the local MAC detects a MIC failure in a | 3257 | * This function is called whenever the local MAC detects a MIC failure in a |
3237 | * received frame. This matches with MLME-MICHAELMICFAILURE.indication() | 3258 | * received frame. This matches with MLME-MICHAELMICFAILURE.indication() |
3238 | * primitive. | 3259 | * primitive. |
3239 | */ | 3260 | */ |
3240 | void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, | 3261 | void cfg80211_michael_mic_failure(struct net_device *dev, const u8 *addr, |
3241 | enum nl80211_key_type key_type, int key_id, | 3262 | enum nl80211_key_type key_type, int key_id, |
3242 | const u8 *tsc, gfp_t gfp); | 3263 | const u8 *tsc, gfp_t gfp); |
3243 | 3264 | ||
3244 | /** | 3265 | /** |
3245 | * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS | 3266 | * cfg80211_ibss_joined - notify cfg80211 that device joined an IBSS |
3246 | * | 3267 | * |
3247 | * @dev: network device | 3268 | * @dev: network device |
3248 | * @bssid: the BSSID of the IBSS joined | 3269 | * @bssid: the BSSID of the IBSS joined |
3249 | * @gfp: allocation flags | 3270 | * @gfp: allocation flags |
3250 | * | 3271 | * |
3251 | * This function notifies cfg80211 that the device joined an IBSS or | 3272 | * This function notifies cfg80211 that the device joined an IBSS or |
3252 | * switched to a different BSSID. Before this function can be called, | 3273 | * switched to a different BSSID. Before this function can be called, |
3253 | * either a beacon has to have been received from the IBSS, or one of | 3274 | * either a beacon has to have been received from the IBSS, or one of |
3254 | * the cfg80211_inform_bss{,_frame} functions must have been called | 3275 | * the cfg80211_inform_bss{,_frame} functions must have been called |
3255 | * with the locally generated beacon -- this guarantees that there is | 3276 | * with the locally generated beacon -- this guarantees that there is |
3256 | * always a scan result for this IBSS. cfg80211 will handle the rest. | 3277 | * always a scan result for this IBSS. cfg80211 will handle the rest. |
3257 | */ | 3278 | */ |
3258 | void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); | 3279 | void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp); |
3259 | 3280 | ||
3260 | /** | 3281 | /** |
3261 | * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate | 3282 | * cfg80211_notify_new_candidate - notify cfg80211 of a new mesh peer candidate |
3262 | * | 3283 | * |
3263 | * @dev: network device | 3284 | * @dev: network device |
3264 | * @macaddr: the MAC address of the new candidate | 3285 | * @macaddr: the MAC address of the new candidate |
3265 | * @ie: information elements advertised by the peer candidate | 3286 | * @ie: information elements advertised by the peer candidate |
3266 | * @ie_len: lenght of the information elements buffer | 3287 | * @ie_len: lenght of the information elements buffer |
3267 | * @gfp: allocation flags | 3288 | * @gfp: allocation flags |
3268 | * | 3289 | * |
3269 | * This function notifies cfg80211 that the mesh peer candidate has been | 3290 | * This function notifies cfg80211 that the mesh peer candidate has been |
3270 | * detected, most likely via a beacon or, less likely, via a probe response. | 3291 | * detected, most likely via a beacon or, less likely, via a probe response. |
3271 | * cfg80211 then sends a notification to userspace. | 3292 | * cfg80211 then sends a notification to userspace. |
3272 | */ | 3293 | */ |
3273 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, | 3294 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, |
3274 | const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); | 3295 | const u8 *macaddr, const u8 *ie, u8 ie_len, gfp_t gfp); |
3275 | 3296 | ||
3276 | /** | 3297 | /** |
3277 | * DOC: RFkill integration | 3298 | * DOC: RFkill integration |
3278 | * | 3299 | * |
3279 | * RFkill integration in cfg80211 is almost invisible to drivers, | 3300 | * RFkill integration in cfg80211 is almost invisible to drivers, |
3280 | * as cfg80211 automatically registers an rfkill instance for each | 3301 | * as cfg80211 automatically registers an rfkill instance for each |
3281 | * wireless device it knows about. Soft kill is also translated | 3302 | * wireless device it knows about. Soft kill is also translated |
3282 | * into disconnecting and turning all interfaces off, drivers are | 3303 | * into disconnecting and turning all interfaces off, drivers are |
3283 | * expected to turn off the device when all interfaces are down. | 3304 | * expected to turn off the device when all interfaces are down. |
3284 | * | 3305 | * |
3285 | * However, devices may have a hard RFkill line, in which case they | 3306 | * However, devices may have a hard RFkill line, in which case they |
3286 | * also need to interact with the rfkill subsystem, via cfg80211. | 3307 | * also need to interact with the rfkill subsystem, via cfg80211. |
3287 | * They can do this with a few helper functions documented here. | 3308 | * They can do this with a few helper functions documented here. |
3288 | */ | 3309 | */ |
3289 | 3310 | ||
3290 | /** | 3311 | /** |
3291 | * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state | 3312 | * wiphy_rfkill_set_hw_state - notify cfg80211 about hw block state |
3292 | * @wiphy: the wiphy | 3313 | * @wiphy: the wiphy |
3293 | * @blocked: block status | 3314 | * @blocked: block status |
3294 | */ | 3315 | */ |
3295 | void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked); | 3316 | void wiphy_rfkill_set_hw_state(struct wiphy *wiphy, bool blocked); |
3296 | 3317 | ||
3297 | /** | 3318 | /** |
3298 | * wiphy_rfkill_start_polling - start polling rfkill | 3319 | * wiphy_rfkill_start_polling - start polling rfkill |
3299 | * @wiphy: the wiphy | 3320 | * @wiphy: the wiphy |
3300 | */ | 3321 | */ |
3301 | void wiphy_rfkill_start_polling(struct wiphy *wiphy); | 3322 | void wiphy_rfkill_start_polling(struct wiphy *wiphy); |
3302 | 3323 | ||
3303 | /** | 3324 | /** |
3304 | * wiphy_rfkill_stop_polling - stop polling rfkill | 3325 | * wiphy_rfkill_stop_polling - stop polling rfkill |
3305 | * @wiphy: the wiphy | 3326 | * @wiphy: the wiphy |
3306 | */ | 3327 | */ |
3307 | void wiphy_rfkill_stop_polling(struct wiphy *wiphy); | 3328 | void wiphy_rfkill_stop_polling(struct wiphy *wiphy); |
3308 | 3329 | ||
3309 | #ifdef CONFIG_NL80211_TESTMODE | 3330 | #ifdef CONFIG_NL80211_TESTMODE |
3310 | /** | 3331 | /** |
3311 | * DOC: Test mode | 3332 | * DOC: Test mode |
3312 | * | 3333 | * |
3313 | * Test mode is a set of utility functions to allow drivers to | 3334 | * Test mode is a set of utility functions to allow drivers to |
3314 | * interact with driver-specific tools to aid, for instance, | 3335 | * interact with driver-specific tools to aid, for instance, |
3315 | * factory programming. | 3336 | * factory programming. |
3316 | * | 3337 | * |
3317 | * This chapter describes how drivers interact with it, for more | 3338 | * This chapter describes how drivers interact with it, for more |
3318 | * information see the nl80211 book's chapter on it. | 3339 | * information see the nl80211 book's chapter on it. |
3319 | */ | 3340 | */ |
3320 | 3341 | ||
3321 | /** | 3342 | /** |
3322 | * cfg80211_testmode_alloc_reply_skb - allocate testmode reply | 3343 | * cfg80211_testmode_alloc_reply_skb - allocate testmode reply |
3323 | * @wiphy: the wiphy | 3344 | * @wiphy: the wiphy |
3324 | * @approxlen: an upper bound of the length of the data that will | 3345 | * @approxlen: an upper bound of the length of the data that will |
3325 | * be put into the skb | 3346 | * be put into the skb |
3326 | * | 3347 | * |
3327 | * This function allocates and pre-fills an skb for a reply to | 3348 | * This function allocates and pre-fills an skb for a reply to |
3328 | * the testmode command. Since it is intended for a reply, calling | 3349 | * the testmode command. Since it is intended for a reply, calling |
3329 | * it outside of the @testmode_cmd operation is invalid. | 3350 | * it outside of the @testmode_cmd operation is invalid. |
3330 | * | 3351 | * |
3331 | * The returned skb is pre-filled with the wiphy index and set up in | 3352 | * The returned skb is pre-filled with the wiphy index and set up in |
3332 | * a way that any data that is put into the skb (with skb_put(), | 3353 | * a way that any data that is put into the skb (with skb_put(), |
3333 | * nla_put() or similar) will end up being within the | 3354 | * nla_put() or similar) will end up being within the |
3334 | * %NL80211_ATTR_TESTDATA attribute, so all that needs to be done | 3355 | * %NL80211_ATTR_TESTDATA attribute, so all that needs to be done |
3335 | * with the skb is adding data for the corresponding userspace tool | 3356 | * with the skb is adding data for the corresponding userspace tool |
3336 | * which can then read that data out of the testdata attribute. You | 3357 | * which can then read that data out of the testdata attribute. You |
3337 | * must not modify the skb in any other way. | 3358 | * must not modify the skb in any other way. |
3338 | * | 3359 | * |
3339 | * When done, call cfg80211_testmode_reply() with the skb and return | 3360 | * When done, call cfg80211_testmode_reply() with the skb and return |
3340 | * its error code as the result of the @testmode_cmd operation. | 3361 | * its error code as the result of the @testmode_cmd operation. |
3341 | * | 3362 | * |
3342 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. | 3363 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. |
3343 | */ | 3364 | */ |
3344 | struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy, | 3365 | struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy, |
3345 | int approxlen); | 3366 | int approxlen); |
3346 | 3367 | ||
3347 | /** | 3368 | /** |
3348 | * cfg80211_testmode_reply - send the reply skb | 3369 | * cfg80211_testmode_reply - send the reply skb |
3349 | * @skb: The skb, must have been allocated with | 3370 | * @skb: The skb, must have been allocated with |
3350 | * cfg80211_testmode_alloc_reply_skb() | 3371 | * cfg80211_testmode_alloc_reply_skb() |
3351 | * | 3372 | * |
3352 | * Since calling this function will usually be the last thing | 3373 | * Since calling this function will usually be the last thing |
3353 | * before returning from the @testmode_cmd you should return | 3374 | * before returning from the @testmode_cmd you should return |
3354 | * the error code. Note that this function consumes the skb | 3375 | * the error code. Note that this function consumes the skb |
3355 | * regardless of the return value. | 3376 | * regardless of the return value. |
3356 | * | 3377 | * |
3357 | * Return: An error code or 0 on success. | 3378 | * Return: An error code or 0 on success. |
3358 | */ | 3379 | */ |
3359 | int cfg80211_testmode_reply(struct sk_buff *skb); | 3380 | int cfg80211_testmode_reply(struct sk_buff *skb); |
3360 | 3381 | ||
3361 | /** | 3382 | /** |
3362 | * cfg80211_testmode_alloc_event_skb - allocate testmode event | 3383 | * cfg80211_testmode_alloc_event_skb - allocate testmode event |
3363 | * @wiphy: the wiphy | 3384 | * @wiphy: the wiphy |
3364 | * @approxlen: an upper bound of the length of the data that will | 3385 | * @approxlen: an upper bound of the length of the data that will |
3365 | * be put into the skb | 3386 | * be put into the skb |
3366 | * @gfp: allocation flags | 3387 | * @gfp: allocation flags |
3367 | * | 3388 | * |
3368 | * This function allocates and pre-fills an skb for an event on the | 3389 | * This function allocates and pre-fills an skb for an event on the |
3369 | * testmode multicast group. | 3390 | * testmode multicast group. |
3370 | * | 3391 | * |
3371 | * The returned skb is set up in the same way as with | 3392 | * The returned skb is set up in the same way as with |
3372 | * cfg80211_testmode_alloc_reply_skb() but prepared for an event. As | 3393 | * cfg80211_testmode_alloc_reply_skb() but prepared for an event. As |
3373 | * there, you should simply add data to it that will then end up in the | 3394 | * there, you should simply add data to it that will then end up in the |
3374 | * %NL80211_ATTR_TESTDATA attribute. Again, you must not modify the skb | 3395 | * %NL80211_ATTR_TESTDATA attribute. Again, you must not modify the skb |
3375 | * in any other way. | 3396 | * in any other way. |
3376 | * | 3397 | * |
3377 | * When done filling the skb, call cfg80211_testmode_event() with the | 3398 | * When done filling the skb, call cfg80211_testmode_event() with the |
3378 | * skb to send the event. | 3399 | * skb to send the event. |
3379 | * | 3400 | * |
3380 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. | 3401 | * Return: An allocated and pre-filled skb. %NULL if any errors happen. |
3381 | */ | 3402 | */ |
3382 | struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, | 3403 | struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, |
3383 | int approxlen, gfp_t gfp); | 3404 | int approxlen, gfp_t gfp); |
3384 | 3405 | ||
3385 | /** | 3406 | /** |
3386 | * cfg80211_testmode_event - send the event | 3407 | * cfg80211_testmode_event - send the event |
3387 | * @skb: The skb, must have been allocated with | 3408 | * @skb: The skb, must have been allocated with |
3388 | * cfg80211_testmode_alloc_event_skb() | 3409 | * cfg80211_testmode_alloc_event_skb() |
3389 | * @gfp: allocation flags | 3410 | * @gfp: allocation flags |
3390 | * | 3411 | * |
3391 | * This function sends the given @skb, which must have been allocated | 3412 | * This function sends the given @skb, which must have been allocated |
3392 | * by cfg80211_testmode_alloc_event_skb(), as an event. It always | 3413 | * by cfg80211_testmode_alloc_event_skb(), as an event. It always |
3393 | * consumes it. | 3414 | * consumes it. |
3394 | */ | 3415 | */ |
3395 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp); | 3416 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp); |
3396 | 3417 | ||
3397 | #define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), | 3418 | #define CFG80211_TESTMODE_CMD(cmd) .testmode_cmd = (cmd), |
3398 | #define CFG80211_TESTMODE_DUMP(cmd) .testmode_dump = (cmd), | 3419 | #define CFG80211_TESTMODE_DUMP(cmd) .testmode_dump = (cmd), |
3399 | #else | 3420 | #else |
3400 | #define CFG80211_TESTMODE_CMD(cmd) | 3421 | #define CFG80211_TESTMODE_CMD(cmd) |
3401 | #define CFG80211_TESTMODE_DUMP(cmd) | 3422 | #define CFG80211_TESTMODE_DUMP(cmd) |
3402 | #endif | 3423 | #endif |
3403 | 3424 | ||
3404 | /** | 3425 | /** |
3405 | * cfg80211_connect_result - notify cfg80211 of connection result | 3426 | * cfg80211_connect_result - notify cfg80211 of connection result |
3406 | * | 3427 | * |
3407 | * @dev: network device | 3428 | * @dev: network device |
3408 | * @bssid: the BSSID of the AP | 3429 | * @bssid: the BSSID of the AP |
3409 | * @req_ie: association request IEs (maybe be %NULL) | 3430 | * @req_ie: association request IEs (maybe be %NULL) |
3410 | * @req_ie_len: association request IEs length | 3431 | * @req_ie_len: association request IEs length |
3411 | * @resp_ie: association response IEs (may be %NULL) | 3432 | * @resp_ie: association response IEs (may be %NULL) |
3412 | * @resp_ie_len: assoc response IEs length | 3433 | * @resp_ie_len: assoc response IEs length |
3413 | * @status: status code, 0 for successful connection, use | 3434 | * @status: status code, 0 for successful connection, use |
3414 | * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you | 3435 | * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you |
3415 | * the real status code for failures. | 3436 | * the real status code for failures. |
3416 | * @gfp: allocation flags | 3437 | * @gfp: allocation flags |
3417 | * | 3438 | * |
3418 | * It should be called by the underlying driver whenever connect() has | 3439 | * It should be called by the underlying driver whenever connect() has |
3419 | * succeeded. | 3440 | * succeeded. |
3420 | */ | 3441 | */ |
3421 | void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 3442 | void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, |
3422 | const u8 *req_ie, size_t req_ie_len, | 3443 | const u8 *req_ie, size_t req_ie_len, |
3423 | const u8 *resp_ie, size_t resp_ie_len, | 3444 | const u8 *resp_ie, size_t resp_ie_len, |
3424 | u16 status, gfp_t gfp); | 3445 | u16 status, gfp_t gfp); |
3425 | 3446 | ||
3426 | /** | 3447 | /** |
3427 | * cfg80211_roamed - notify cfg80211 of roaming | 3448 | * cfg80211_roamed - notify cfg80211 of roaming |
3428 | * | 3449 | * |
3429 | * @dev: network device | 3450 | * @dev: network device |
3430 | * @channel: the channel of the new AP | 3451 | * @channel: the channel of the new AP |
3431 | * @bssid: the BSSID of the new AP | 3452 | * @bssid: the BSSID of the new AP |
3432 | * @req_ie: association request IEs (maybe be %NULL) | 3453 | * @req_ie: association request IEs (maybe be %NULL) |
3433 | * @req_ie_len: association request IEs length | 3454 | * @req_ie_len: association request IEs length |
3434 | * @resp_ie: association response IEs (may be %NULL) | 3455 | * @resp_ie: association response IEs (may be %NULL) |
3435 | * @resp_ie_len: assoc response IEs length | 3456 | * @resp_ie_len: assoc response IEs length |
3436 | * @gfp: allocation flags | 3457 | * @gfp: allocation flags |
3437 | * | 3458 | * |
3438 | * It should be called by the underlying driver whenever it roamed | 3459 | * It should be called by the underlying driver whenever it roamed |
3439 | * from one AP to another while connected. | 3460 | * from one AP to another while connected. |
3440 | */ | 3461 | */ |
3441 | void cfg80211_roamed(struct net_device *dev, | 3462 | void cfg80211_roamed(struct net_device *dev, |
3442 | struct ieee80211_channel *channel, | 3463 | struct ieee80211_channel *channel, |
3443 | const u8 *bssid, | 3464 | const u8 *bssid, |
3444 | const u8 *req_ie, size_t req_ie_len, | 3465 | const u8 *req_ie, size_t req_ie_len, |
3445 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); | 3466 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); |
3446 | 3467 | ||
3447 | /** | 3468 | /** |
3448 | * cfg80211_roamed_bss - notify cfg80211 of roaming | 3469 | * cfg80211_roamed_bss - notify cfg80211 of roaming |
3449 | * | 3470 | * |
3450 | * @dev: network device | 3471 | * @dev: network device |
3451 | * @bss: entry of bss to which STA got roamed | 3472 | * @bss: entry of bss to which STA got roamed |
3452 | * @req_ie: association request IEs (maybe be %NULL) | 3473 | * @req_ie: association request IEs (maybe be %NULL) |
3453 | * @req_ie_len: association request IEs length | 3474 | * @req_ie_len: association request IEs length |
3454 | * @resp_ie: association response IEs (may be %NULL) | 3475 | * @resp_ie: association response IEs (may be %NULL) |
3455 | * @resp_ie_len: assoc response IEs length | 3476 | * @resp_ie_len: assoc response IEs length |
3456 | * @gfp: allocation flags | 3477 | * @gfp: allocation flags |
3457 | * | 3478 | * |
3458 | * This is just a wrapper to notify cfg80211 of roaming event with driver | 3479 | * This is just a wrapper to notify cfg80211 of roaming event with driver |
3459 | * passing bss to avoid a race in timeout of the bss entry. It should be | 3480 | * passing bss to avoid a race in timeout of the bss entry. It should be |
3460 | * called by the underlying driver whenever it roamed from one AP to another | 3481 | * called by the underlying driver whenever it roamed from one AP to another |
3461 | * while connected. Drivers which have roaming implemented in firmware | 3482 | * while connected. Drivers which have roaming implemented in firmware |
3462 | * may use this function to avoid a race in bss entry timeout where the bss | 3483 | * may use this function to avoid a race in bss entry timeout where the bss |
3463 | * entry of the new AP is seen in the driver, but gets timed out by the time | 3484 | * entry of the new AP is seen in the driver, but gets timed out by the time |
3464 | * it is accessed in __cfg80211_roamed() due to delay in scheduling | 3485 | * it is accessed in __cfg80211_roamed() due to delay in scheduling |
3465 | * rdev->event_work. In case of any failures, the reference is released | 3486 | * rdev->event_work. In case of any failures, the reference is released |
3466 | * either in cfg80211_roamed_bss() or in __cfg80211_romed(), Otherwise, | 3487 | * either in cfg80211_roamed_bss() or in __cfg80211_romed(), Otherwise, |
3467 | * it will be released while diconneting from the current bss. | 3488 | * it will be released while diconneting from the current bss. |
3468 | */ | 3489 | */ |
3469 | void cfg80211_roamed_bss(struct net_device *dev, struct cfg80211_bss *bss, | 3490 | void cfg80211_roamed_bss(struct net_device *dev, struct cfg80211_bss *bss, |
3470 | const u8 *req_ie, size_t req_ie_len, | 3491 | const u8 *req_ie, size_t req_ie_len, |
3471 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); | 3492 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp); |
3472 | 3493 | ||
3473 | /** | 3494 | /** |
3474 | * cfg80211_disconnected - notify cfg80211 that connection was dropped | 3495 | * cfg80211_disconnected - notify cfg80211 that connection was dropped |
3475 | * | 3496 | * |
3476 | * @dev: network device | 3497 | * @dev: network device |
3477 | * @ie: information elements of the deauth/disassoc frame (may be %NULL) | 3498 | * @ie: information elements of the deauth/disassoc frame (may be %NULL) |
3478 | * @ie_len: length of IEs | 3499 | * @ie_len: length of IEs |
3479 | * @reason: reason code for the disconnection, set it to 0 if unknown | 3500 | * @reason: reason code for the disconnection, set it to 0 if unknown |
3480 | * @gfp: allocation flags | 3501 | * @gfp: allocation flags |
3481 | * | 3502 | * |
3482 | * After it calls this function, the driver should enter an idle state | 3503 | * After it calls this function, the driver should enter an idle state |
3483 | * and not try to connect to any AP any more. | 3504 | * and not try to connect to any AP any more. |
3484 | */ | 3505 | */ |
3485 | void cfg80211_disconnected(struct net_device *dev, u16 reason, | 3506 | void cfg80211_disconnected(struct net_device *dev, u16 reason, |
3486 | u8 *ie, size_t ie_len, gfp_t gfp); | 3507 | u8 *ie, size_t ie_len, gfp_t gfp); |
3487 | 3508 | ||
3488 | /** | 3509 | /** |
3489 | * cfg80211_ready_on_channel - notification of remain_on_channel start | 3510 | * cfg80211_ready_on_channel - notification of remain_on_channel start |
3490 | * @wdev: wireless device | 3511 | * @wdev: wireless device |
3491 | * @cookie: the request cookie | 3512 | * @cookie: the request cookie |
3492 | * @chan: The current channel (from remain_on_channel request) | 3513 | * @chan: The current channel (from remain_on_channel request) |
3493 | * @duration: Duration in milliseconds that the driver intents to remain on the | 3514 | * @duration: Duration in milliseconds that the driver intents to remain on the |
3494 | * channel | 3515 | * channel |
3495 | * @gfp: allocation flags | 3516 | * @gfp: allocation flags |
3496 | */ | 3517 | */ |
3497 | void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, | 3518 | void cfg80211_ready_on_channel(struct wireless_dev *wdev, u64 cookie, |
3498 | struct ieee80211_channel *chan, | 3519 | struct ieee80211_channel *chan, |
3499 | unsigned int duration, gfp_t gfp); | 3520 | unsigned int duration, gfp_t gfp); |
3500 | 3521 | ||
3501 | /** | 3522 | /** |
3502 | * cfg80211_remain_on_channel_expired - remain_on_channel duration expired | 3523 | * cfg80211_remain_on_channel_expired - remain_on_channel duration expired |
3503 | * @wdev: wireless device | 3524 | * @wdev: wireless device |
3504 | * @cookie: the request cookie | 3525 | * @cookie: the request cookie |
3505 | * @chan: The current channel (from remain_on_channel request) | 3526 | * @chan: The current channel (from remain_on_channel request) |
3506 | * @gfp: allocation flags | 3527 | * @gfp: allocation flags |
3507 | */ | 3528 | */ |
3508 | void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, | 3529 | void cfg80211_remain_on_channel_expired(struct wireless_dev *wdev, u64 cookie, |
3509 | struct ieee80211_channel *chan, | 3530 | struct ieee80211_channel *chan, |
3510 | gfp_t gfp); | 3531 | gfp_t gfp); |
3511 | 3532 | ||
3512 | 3533 | ||
3513 | /** | 3534 | /** |
3514 | * cfg80211_new_sta - notify userspace about station | 3535 | * cfg80211_new_sta - notify userspace about station |
3515 | * | 3536 | * |
3516 | * @dev: the netdev | 3537 | * @dev: the netdev |
3517 | * @mac_addr: the station's address | 3538 | * @mac_addr: the station's address |
3518 | * @sinfo: the station information | 3539 | * @sinfo: the station information |
3519 | * @gfp: allocation flags | 3540 | * @gfp: allocation flags |
3520 | */ | 3541 | */ |
3521 | void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, | 3542 | void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr, |
3522 | struct station_info *sinfo, gfp_t gfp); | 3543 | struct station_info *sinfo, gfp_t gfp); |
3523 | 3544 | ||
3524 | /** | 3545 | /** |
3525 | * cfg80211_del_sta - notify userspace about deletion of a station | 3546 | * cfg80211_del_sta - notify userspace about deletion of a station |
3526 | * | 3547 | * |
3527 | * @dev: the netdev | 3548 | * @dev: the netdev |
3528 | * @mac_addr: the station's address | 3549 | * @mac_addr: the station's address |
3529 | * @gfp: allocation flags | 3550 | * @gfp: allocation flags |
3530 | */ | 3551 | */ |
3531 | void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); | 3552 | void cfg80211_del_sta(struct net_device *dev, const u8 *mac_addr, gfp_t gfp); |
3532 | 3553 | ||
3533 | /** | 3554 | /** |
3534 | * cfg80211_conn_failed - connection request failed notification | 3555 | * cfg80211_conn_failed - connection request failed notification |
3535 | * | 3556 | * |
3536 | * @dev: the netdev | 3557 | * @dev: the netdev |
3537 | * @mac_addr: the station's address | 3558 | * @mac_addr: the station's address |
3538 | * @reason: the reason for connection failure | 3559 | * @reason: the reason for connection failure |
3539 | * @gfp: allocation flags | 3560 | * @gfp: allocation flags |
3540 | * | 3561 | * |
3541 | * Whenever a station tries to connect to an AP and if the station | 3562 | * Whenever a station tries to connect to an AP and if the station |
3542 | * could not connect to the AP as the AP has rejected the connection | 3563 | * could not connect to the AP as the AP has rejected the connection |
3543 | * for some reasons, this function is called. | 3564 | * for some reasons, this function is called. |
3544 | * | 3565 | * |
3545 | * The reason for connection failure can be any of the value from | 3566 | * The reason for connection failure can be any of the value from |
3546 | * nl80211_connect_failed_reason enum | 3567 | * nl80211_connect_failed_reason enum |
3547 | */ | 3568 | */ |
3548 | void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, | 3569 | void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, |
3549 | enum nl80211_connect_failed_reason reason, | 3570 | enum nl80211_connect_failed_reason reason, |
3550 | gfp_t gfp); | 3571 | gfp_t gfp); |
3551 | 3572 | ||
3552 | /** | 3573 | /** |
3553 | * cfg80211_rx_mgmt - notification of received, unprocessed management frame | 3574 | * cfg80211_rx_mgmt - notification of received, unprocessed management frame |
3554 | * @wdev: wireless device receiving the frame | 3575 | * @wdev: wireless device receiving the frame |
3555 | * @freq: Frequency on which the frame was received in MHz | 3576 | * @freq: Frequency on which the frame was received in MHz |
3556 | * @sig_dbm: signal strength in mBm, or 0 if unknown | 3577 | * @sig_dbm: signal strength in mBm, or 0 if unknown |
3557 | * @buf: Management frame (header + body) | 3578 | * @buf: Management frame (header + body) |
3558 | * @len: length of the frame data | 3579 | * @len: length of the frame data |
3559 | * @gfp: context flags | 3580 | * @gfp: context flags |
3560 | * | 3581 | * |
3561 | * This function is called whenever an Action frame is received for a station | 3582 | * This function is called whenever an Action frame is received for a station |
3562 | * mode interface, but is not processed in kernel. | 3583 | * mode interface, but is not processed in kernel. |
3563 | * | 3584 | * |
3564 | * Return: %true if a user space application has registered for this frame. | 3585 | * Return: %true if a user space application has registered for this frame. |
3565 | * For action frames, that makes it responsible for rejecting unrecognized | 3586 | * For action frames, that makes it responsible for rejecting unrecognized |
3566 | * action frames; %false otherwise, in which case for action frames the | 3587 | * action frames; %false otherwise, in which case for action frames the |
3567 | * driver is responsible for rejecting the frame. | 3588 | * driver is responsible for rejecting the frame. |
3568 | */ | 3589 | */ |
3569 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm, | 3590 | bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_dbm, |
3570 | const u8 *buf, size_t len, gfp_t gfp); | 3591 | const u8 *buf, size_t len, gfp_t gfp); |
3571 | 3592 | ||
3572 | /** | 3593 | /** |
3573 | * cfg80211_mgmt_tx_status - notification of TX status for management frame | 3594 | * cfg80211_mgmt_tx_status - notification of TX status for management frame |
3574 | * @wdev: wireless device receiving the frame | 3595 | * @wdev: wireless device receiving the frame |
3575 | * @cookie: Cookie returned by cfg80211_ops::mgmt_tx() | 3596 | * @cookie: Cookie returned by cfg80211_ops::mgmt_tx() |
3576 | * @buf: Management frame (header + body) | 3597 | * @buf: Management frame (header + body) |
3577 | * @len: length of the frame data | 3598 | * @len: length of the frame data |
3578 | * @ack: Whether frame was acknowledged | 3599 | * @ack: Whether frame was acknowledged |
3579 | * @gfp: context flags | 3600 | * @gfp: context flags |
3580 | * | 3601 | * |
3581 | * This function is called whenever a management frame was requested to be | 3602 | * This function is called whenever a management frame was requested to be |
3582 | * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the | 3603 | * transmitted with cfg80211_ops::mgmt_tx() to report the TX status of the |
3583 | * transmission attempt. | 3604 | * transmission attempt. |
3584 | */ | 3605 | */ |
3585 | void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, | 3606 | void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie, |
3586 | const u8 *buf, size_t len, bool ack, gfp_t gfp); | 3607 | const u8 *buf, size_t len, bool ack, gfp_t gfp); |
3587 | 3608 | ||
3588 | 3609 | ||
3589 | /** | 3610 | /** |
3590 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event | 3611 | * cfg80211_cqm_rssi_notify - connection quality monitoring rssi event |
3591 | * @dev: network device | 3612 | * @dev: network device |
3592 | * @rssi_event: the triggered RSSI event | 3613 | * @rssi_event: the triggered RSSI event |
3593 | * @gfp: context flags | 3614 | * @gfp: context flags |
3594 | * | 3615 | * |
3595 | * This function is called when a configured connection quality monitoring | 3616 | * This function is called when a configured connection quality monitoring |
3596 | * rssi threshold reached event occurs. | 3617 | * rssi threshold reached event occurs. |
3597 | */ | 3618 | */ |
3598 | void cfg80211_cqm_rssi_notify(struct net_device *dev, | 3619 | void cfg80211_cqm_rssi_notify(struct net_device *dev, |
3599 | enum nl80211_cqm_rssi_threshold_event rssi_event, | 3620 | enum nl80211_cqm_rssi_threshold_event rssi_event, |
3600 | gfp_t gfp); | 3621 | gfp_t gfp); |
3601 | 3622 | ||
3602 | /** | 3623 | /** |
3603 | * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer | 3624 | * cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer |
3604 | * @dev: network device | 3625 | * @dev: network device |
3605 | * @peer: peer's MAC address | 3626 | * @peer: peer's MAC address |
3606 | * @num_packets: how many packets were lost -- should be a fixed threshold | 3627 | * @num_packets: how many packets were lost -- should be a fixed threshold |
3607 | * but probably no less than maybe 50, or maybe a throughput dependent | 3628 | * but probably no less than maybe 50, or maybe a throughput dependent |
3608 | * threshold (to account for temporary interference) | 3629 | * threshold (to account for temporary interference) |
3609 | * @gfp: context flags | 3630 | * @gfp: context flags |
3610 | */ | 3631 | */ |
3611 | void cfg80211_cqm_pktloss_notify(struct net_device *dev, | 3632 | void cfg80211_cqm_pktloss_notify(struct net_device *dev, |
3612 | const u8 *peer, u32 num_packets, gfp_t gfp); | 3633 | const u8 *peer, u32 num_packets, gfp_t gfp); |
3613 | 3634 | ||
3614 | /** | 3635 | /** |
3615 | * cfg80211_cqm_txe_notify - TX error rate event | 3636 | * cfg80211_cqm_txe_notify - TX error rate event |
3616 | * @dev: network device | 3637 | * @dev: network device |
3617 | * @peer: peer's MAC address | 3638 | * @peer: peer's MAC address |
3618 | * @num_packets: how many packets were lost | 3639 | * @num_packets: how many packets were lost |
3619 | * @rate: % of packets which failed transmission | 3640 | * @rate: % of packets which failed transmission |
3620 | * @intvl: interval (in s) over which the TX failure threshold was breached. | 3641 | * @intvl: interval (in s) over which the TX failure threshold was breached. |
3621 | * @gfp: context flags | 3642 | * @gfp: context flags |
3622 | * | 3643 | * |
3623 | * Notify userspace when configured % TX failures over number of packets in a | 3644 | * Notify userspace when configured % TX failures over number of packets in a |
3624 | * given interval is exceeded. | 3645 | * given interval is exceeded. |
3625 | */ | 3646 | */ |
3626 | void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer, | 3647 | void cfg80211_cqm_txe_notify(struct net_device *dev, const u8 *peer, |
3627 | u32 num_packets, u32 rate, u32 intvl, gfp_t gfp); | 3648 | u32 num_packets, u32 rate, u32 intvl, gfp_t gfp); |
3628 | 3649 | ||
3629 | /** | 3650 | /** |
3630 | * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying | 3651 | * cfg80211_gtk_rekey_notify - notify userspace about driver rekeying |
3631 | * @dev: network device | 3652 | * @dev: network device |
3632 | * @bssid: BSSID of AP (to avoid races) | 3653 | * @bssid: BSSID of AP (to avoid races) |
3633 | * @replay_ctr: new replay counter | 3654 | * @replay_ctr: new replay counter |
3634 | * @gfp: allocation flags | 3655 | * @gfp: allocation flags |
3635 | */ | 3656 | */ |
3636 | void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, | 3657 | void cfg80211_gtk_rekey_notify(struct net_device *dev, const u8 *bssid, |
3637 | const u8 *replay_ctr, gfp_t gfp); | 3658 | const u8 *replay_ctr, gfp_t gfp); |
3638 | 3659 | ||
3639 | /** | 3660 | /** |
3640 | * cfg80211_pmksa_candidate_notify - notify about PMKSA caching candidate | 3661 | * cfg80211_pmksa_candidate_notify - notify about PMKSA caching candidate |
3641 | * @dev: network device | 3662 | * @dev: network device |
3642 | * @index: candidate index (the smaller the index, the higher the priority) | 3663 | * @index: candidate index (the smaller the index, the higher the priority) |
3643 | * @bssid: BSSID of AP | 3664 | * @bssid: BSSID of AP |
3644 | * @preauth: Whether AP advertises support for RSN pre-authentication | 3665 | * @preauth: Whether AP advertises support for RSN pre-authentication |
3645 | * @gfp: allocation flags | 3666 | * @gfp: allocation flags |
3646 | */ | 3667 | */ |
3647 | void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, | 3668 | void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index, |
3648 | const u8 *bssid, bool preauth, gfp_t gfp); | 3669 | const u8 *bssid, bool preauth, gfp_t gfp); |
3649 | 3670 | ||
3650 | /** | 3671 | /** |
3651 | * cfg80211_rx_spurious_frame - inform userspace about a spurious frame | 3672 | * cfg80211_rx_spurious_frame - inform userspace about a spurious frame |
3652 | * @dev: The device the frame matched to | 3673 | * @dev: The device the frame matched to |
3653 | * @addr: the transmitter address | 3674 | * @addr: the transmitter address |
3654 | * @gfp: context flags | 3675 | * @gfp: context flags |
3655 | * | 3676 | * |
3656 | * This function is used in AP mode (only!) to inform userspace that | 3677 | * This function is used in AP mode (only!) to inform userspace that |
3657 | * a spurious class 3 frame was received, to be able to deauth the | 3678 | * a spurious class 3 frame was received, to be able to deauth the |
3658 | * sender. | 3679 | * sender. |
3659 | * Return: %true if the frame was passed to userspace (or this failed | 3680 | * Return: %true if the frame was passed to userspace (or this failed |
3660 | * for a reason other than not having a subscription.) | 3681 | * for a reason other than not having a subscription.) |
3661 | */ | 3682 | */ |
3662 | bool cfg80211_rx_spurious_frame(struct net_device *dev, | 3683 | bool cfg80211_rx_spurious_frame(struct net_device *dev, |
3663 | const u8 *addr, gfp_t gfp); | 3684 | const u8 *addr, gfp_t gfp); |
3664 | 3685 | ||
3665 | /** | 3686 | /** |
3666 | * cfg80211_rx_unexpected_4addr_frame - inform about unexpected WDS frame | 3687 | * cfg80211_rx_unexpected_4addr_frame - inform about unexpected WDS frame |
3667 | * @dev: The device the frame matched to | 3688 | * @dev: The device the frame matched to |
3668 | * @addr: the transmitter address | 3689 | * @addr: the transmitter address |
3669 | * @gfp: context flags | 3690 | * @gfp: context flags |
3670 | * | 3691 | * |
3671 | * This function is used in AP mode (only!) to inform userspace that | 3692 | * This function is used in AP mode (only!) to inform userspace that |
3672 | * an associated station sent a 4addr frame but that wasn't expected. | 3693 | * an associated station sent a 4addr frame but that wasn't expected. |
3673 | * It is allowed and desirable to send this event only once for each | 3694 | * It is allowed and desirable to send this event only once for each |
3674 | * station to avoid event flooding. | 3695 | * station to avoid event flooding. |
3675 | * Return: %true if the frame was passed to userspace (or this failed | 3696 | * Return: %true if the frame was passed to userspace (or this failed |
3676 | * for a reason other than not having a subscription.) | 3697 | * for a reason other than not having a subscription.) |
3677 | */ | 3698 | */ |
3678 | bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, | 3699 | bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, |
3679 | const u8 *addr, gfp_t gfp); | 3700 | const u8 *addr, gfp_t gfp); |
3680 | 3701 | ||
3681 | /** | 3702 | /** |
3682 | * cfg80211_probe_status - notify userspace about probe status | 3703 | * cfg80211_probe_status - notify userspace about probe status |
3683 | * @dev: the device the probe was sent on | 3704 | * @dev: the device the probe was sent on |
3684 | * @addr: the address of the peer | 3705 | * @addr: the address of the peer |
3685 | * @cookie: the cookie filled in @probe_client previously | 3706 | * @cookie: the cookie filled in @probe_client previously |
3686 | * @acked: indicates whether probe was acked or not | 3707 | * @acked: indicates whether probe was acked or not |
3687 | * @gfp: allocation flags | 3708 | * @gfp: allocation flags |
3688 | */ | 3709 | */ |
3689 | void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | 3710 | void cfg80211_probe_status(struct net_device *dev, const u8 *addr, |
3690 | u64 cookie, bool acked, gfp_t gfp); | 3711 | u64 cookie, bool acked, gfp_t gfp); |
3691 | 3712 | ||
3692 | /** | 3713 | /** |
3693 | * cfg80211_report_obss_beacon - report beacon from other APs | 3714 | * cfg80211_report_obss_beacon - report beacon from other APs |
3694 | * @wiphy: The wiphy that received the beacon | 3715 | * @wiphy: The wiphy that received the beacon |
3695 | * @frame: the frame | 3716 | * @frame: the frame |
3696 | * @len: length of the frame | 3717 | * @len: length of the frame |
3697 | * @freq: frequency the frame was received on | 3718 | * @freq: frequency the frame was received on |
3698 | * @sig_dbm: signal strength in mBm, or 0 if unknown | 3719 | * @sig_dbm: signal strength in mBm, or 0 if unknown |
3699 | * | 3720 | * |
3700 | * Use this function to report to userspace when a beacon was | 3721 | * Use this function to report to userspace when a beacon was |
3701 | * received. It is not useful to call this when there is no | 3722 | * received. It is not useful to call this when there is no |
3702 | * netdev that is in AP/GO mode. | 3723 | * netdev that is in AP/GO mode. |
3703 | */ | 3724 | */ |
3704 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | 3725 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, |
3705 | const u8 *frame, size_t len, | 3726 | const u8 *frame, size_t len, |
3706 | int freq, int sig_dbm); | 3727 | int freq, int sig_dbm); |
3707 | 3728 | ||
3708 | /** | 3729 | /** |
3709 | * cfg80211_reg_can_beacon - check if beaconing is allowed | 3730 | * cfg80211_reg_can_beacon - check if beaconing is allowed |
3710 | * @wiphy: the wiphy | 3731 | * @wiphy: the wiphy |
3711 | * @chandef: the channel definition | 3732 | * @chandef: the channel definition |
3712 | * | 3733 | * |
3713 | * Return: %true if there is no secondary channel or the secondary channel(s) | 3734 | * Return: %true if there is no secondary channel or the secondary channel(s) |
3714 | * can be used for beaconing (i.e. is not a radar channel etc.) | 3735 | * can be used for beaconing (i.e. is not a radar channel etc.) |
3715 | */ | 3736 | */ |
3716 | bool cfg80211_reg_can_beacon(struct wiphy *wiphy, | 3737 | bool cfg80211_reg_can_beacon(struct wiphy *wiphy, |
3717 | struct cfg80211_chan_def *chandef); | 3738 | struct cfg80211_chan_def *chandef); |
3718 | 3739 | ||
3719 | /* | 3740 | /* |
3720 | * cfg80211_ch_switch_notify - update wdev channel and notify userspace | 3741 | * cfg80211_ch_switch_notify - update wdev channel and notify userspace |
3721 | * @dev: the device which switched channels | 3742 | * @dev: the device which switched channels |
3722 | * @chandef: the new channel definition | 3743 | * @chandef: the new channel definition |
3723 | * | 3744 | * |
3724 | * Acquires wdev_lock, so must only be called from sleepable driver context! | 3745 | * Acquires wdev_lock, so must only be called from sleepable driver context! |
3725 | */ | 3746 | */ |
3726 | void cfg80211_ch_switch_notify(struct net_device *dev, | 3747 | void cfg80211_ch_switch_notify(struct net_device *dev, |
3727 | struct cfg80211_chan_def *chandef); | 3748 | struct cfg80211_chan_def *chandef); |
3728 | 3749 | ||
3729 | /* | 3750 | /* |
3730 | * cfg80211_tdls_oper_request - request userspace to perform TDLS operation | 3751 | * cfg80211_tdls_oper_request - request userspace to perform TDLS operation |
3731 | * @dev: the device on which the operation is requested | 3752 | * @dev: the device on which the operation is requested |
3732 | * @peer: the MAC address of the peer device | 3753 | * @peer: the MAC address of the peer device |
3733 | * @oper: the requested TDLS operation (NL80211_TDLS_SETUP or | 3754 | * @oper: the requested TDLS operation (NL80211_TDLS_SETUP or |
3734 | * NL80211_TDLS_TEARDOWN) | 3755 | * NL80211_TDLS_TEARDOWN) |
3735 | * @reason_code: the reason code for teardown request | 3756 | * @reason_code: the reason code for teardown request |
3736 | * @gfp: allocation flags | 3757 | * @gfp: allocation flags |
3737 | * | 3758 | * |
3738 | * This function is used to request userspace to perform TDLS operation that | 3759 | * This function is used to request userspace to perform TDLS operation that |
3739 | * requires knowledge of keys, i.e., link setup or teardown when the AP | 3760 | * requires knowledge of keys, i.e., link setup or teardown when the AP |
3740 | * connection uses encryption. This is optional mechanism for the driver to use | 3761 | * connection uses encryption. This is optional mechanism for the driver to use |
3741 | * if it can automatically determine when a TDLS link could be useful (e.g., | 3762 | * if it can automatically determine when a TDLS link could be useful (e.g., |
3742 | * based on traffic and signal strength for a peer). | 3763 | * based on traffic and signal strength for a peer). |
3743 | */ | 3764 | */ |
3744 | void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, | 3765 | void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, |
3745 | enum nl80211_tdls_operation oper, | 3766 | enum nl80211_tdls_operation oper, |
3746 | u16 reason_code, gfp_t gfp); | 3767 | u16 reason_code, gfp_t gfp); |
3747 | 3768 | ||
3748 | /* | 3769 | /* |
3749 | * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units) | 3770 | * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units) |
3750 | * @rate: given rate_info to calculate bitrate from | 3771 | * @rate: given rate_info to calculate bitrate from |
3751 | * | 3772 | * |
3752 | * return 0 if MCS index >= 32 | 3773 | * return 0 if MCS index >= 32 |
3753 | */ | 3774 | */ |
3754 | u32 cfg80211_calculate_bitrate(struct rate_info *rate); | 3775 | u32 cfg80211_calculate_bitrate(struct rate_info *rate); |
3755 | 3776 | ||
3756 | /** | 3777 | /** |
3757 | * cfg80211_unregister_wdev - remove the given wdev | 3778 | * cfg80211_unregister_wdev - remove the given wdev |
3758 | * @wdev: struct wireless_dev to remove | 3779 | * @wdev: struct wireless_dev to remove |
3759 | * | 3780 | * |
3760 | * Call this function only for wdevs that have no netdev assigned, | 3781 | * Call this function only for wdevs that have no netdev assigned, |
3761 | * e.g. P2P Devices. It removes the device from the list so that | 3782 | * e.g. P2P Devices. It removes the device from the list so that |
3762 | * it can no longer be used. It is necessary to call this function | 3783 | * it can no longer be used. It is necessary to call this function |
3763 | * even when cfg80211 requests the removal of the interface by | 3784 | * even when cfg80211 requests the removal of the interface by |
3764 | * calling the del_virtual_intf() callback. The function must also | 3785 | * calling the del_virtual_intf() callback. The function must also |
3765 | * be called when the driver wishes to unregister the wdev, e.g. | 3786 | * be called when the driver wishes to unregister the wdev, e.g. |
3766 | * when the device is unbound from the driver. | 3787 | * when the device is unbound from the driver. |
3767 | * | 3788 | * |
3768 | * Requires the RTNL to be held. | 3789 | * Requires the RTNL to be held. |
3769 | */ | 3790 | */ |
3770 | void cfg80211_unregister_wdev(struct wireless_dev *wdev); | 3791 | void cfg80211_unregister_wdev(struct wireless_dev *wdev); |
3771 | 3792 | ||
3772 | /** | 3793 | /** |
3773 | * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer | 3794 | * cfg80211_get_p2p_attr - find and copy a P2P attribute from IE buffer |
3774 | * @ies: the input IE buffer | 3795 | * @ies: the input IE buffer |
3775 | * @len: the input length | 3796 | * @len: the input length |
3776 | * @attr: the attribute ID to find | 3797 | * @attr: the attribute ID to find |
3777 | * @buf: output buffer, can be %NULL if the data isn't needed, e.g. | 3798 | * @buf: output buffer, can be %NULL if the data isn't needed, e.g. |
3778 | * if the function is only called to get the needed buffer size | 3799 | * if the function is only called to get the needed buffer size |
3779 | * @bufsize: size of the output buffer | 3800 | * @bufsize: size of the output buffer |
3780 | * | 3801 | * |
3781 | * The function finds a given P2P attribute in the (vendor) IEs and | 3802 | * The function finds a given P2P attribute in the (vendor) IEs and |
3782 | * copies its contents to the given buffer. | 3803 | * copies its contents to the given buffer. |
3783 | * | 3804 | * |
3784 | * Return: A negative error code (-%EILSEQ or -%ENOENT) if the data is | 3805 | * Return: A negative error code (-%EILSEQ or -%ENOENT) if the data is |
3785 | * malformed or the attribute can't be found (respectively), or the | 3806 | * malformed or the attribute can't be found (respectively), or the |
3786 | * length of the found attribute (which can be zero). | 3807 | * length of the found attribute (which can be zero). |
3787 | */ | 3808 | */ |
3788 | int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, | 3809 | int cfg80211_get_p2p_attr(const u8 *ies, unsigned int len, |
3789 | enum ieee80211_p2p_attr_id attr, | 3810 | enum ieee80211_p2p_attr_id attr, |
3790 | u8 *buf, unsigned int bufsize); | 3811 | u8 *buf, unsigned int bufsize); |
3791 | 3812 | ||
3792 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ | 3813 | /* Logging, debugging and troubleshooting/diagnostic helpers. */ |
3793 | 3814 | ||
3794 | /* wiphy_printk helpers, similar to dev_printk */ | 3815 | /* wiphy_printk helpers, similar to dev_printk */ |
3795 | 3816 | ||
3796 | #define wiphy_printk(level, wiphy, format, args...) \ | 3817 | #define wiphy_printk(level, wiphy, format, args...) \ |
3797 | dev_printk(level, &(wiphy)->dev, format, ##args) | 3818 | dev_printk(level, &(wiphy)->dev, format, ##args) |
3798 | #define wiphy_emerg(wiphy, format, args...) \ | 3819 | #define wiphy_emerg(wiphy, format, args...) \ |
3799 | dev_emerg(&(wiphy)->dev, format, ##args) | 3820 | dev_emerg(&(wiphy)->dev, format, ##args) |
3800 | #define wiphy_alert(wiphy, format, args...) \ | 3821 | #define wiphy_alert(wiphy, format, args...) \ |
3801 | dev_alert(&(wiphy)->dev, format, ##args) | 3822 | dev_alert(&(wiphy)->dev, format, ##args) |
3802 | #define wiphy_crit(wiphy, format, args...) \ | 3823 | #define wiphy_crit(wiphy, format, args...) \ |
3803 | dev_crit(&(wiphy)->dev, format, ##args) | 3824 | dev_crit(&(wiphy)->dev, format, ##args) |
3804 | #define wiphy_err(wiphy, format, args...) \ | 3825 | #define wiphy_err(wiphy, format, args...) \ |
3805 | dev_err(&(wiphy)->dev, format, ##args) | 3826 | dev_err(&(wiphy)->dev, format, ##args) |
3806 | #define wiphy_warn(wiphy, format, args...) \ | 3827 | #define wiphy_warn(wiphy, format, args...) \ |
3807 | dev_warn(&(wiphy)->dev, format, ##args) | 3828 | dev_warn(&(wiphy)->dev, format, ##args) |
3808 | #define wiphy_notice(wiphy, format, args...) \ | 3829 | #define wiphy_notice(wiphy, format, args...) \ |
3809 | dev_notice(&(wiphy)->dev, format, ##args) | 3830 | dev_notice(&(wiphy)->dev, format, ##args) |
3810 | #define wiphy_info(wiphy, format, args...) \ | 3831 | #define wiphy_info(wiphy, format, args...) \ |
3811 | dev_info(&(wiphy)->dev, format, ##args) | 3832 | dev_info(&(wiphy)->dev, format, ##args) |
3812 | 3833 | ||
3813 | #define wiphy_debug(wiphy, format, args...) \ | 3834 | #define wiphy_debug(wiphy, format, args...) \ |
3814 | wiphy_printk(KERN_DEBUG, wiphy, format, ##args) | 3835 | wiphy_printk(KERN_DEBUG, wiphy, format, ##args) |
3815 | 3836 | ||
3816 | #define wiphy_dbg(wiphy, format, args...) \ | 3837 | #define wiphy_dbg(wiphy, format, args...) \ |
3817 | dev_dbg(&(wiphy)->dev, format, ##args) | 3838 | dev_dbg(&(wiphy)->dev, format, ##args) |
3818 | 3839 | ||
3819 | #if defined(VERBOSE_DEBUG) | 3840 | #if defined(VERBOSE_DEBUG) |
3820 | #define wiphy_vdbg wiphy_dbg | 3841 | #define wiphy_vdbg wiphy_dbg |
3821 | #else | 3842 | #else |
3822 | #define wiphy_vdbg(wiphy, format, args...) \ | 3843 | #define wiphy_vdbg(wiphy, format, args...) \ |
3823 | ({ \ | 3844 | ({ \ |
3824 | if (0) \ | 3845 | if (0) \ |
3825 | wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ | 3846 | wiphy_printk(KERN_DEBUG, wiphy, format, ##args); \ |
3826 | 0; \ | 3847 | 0; \ |
3827 | }) | 3848 | }) |
3828 | #endif | 3849 | #endif |
3829 | 3850 | ||
3830 | /* | 3851 | /* |
3831 | * wiphy_WARN() acts like wiphy_printk(), but with the key difference | 3852 | * wiphy_WARN() acts like wiphy_printk(), but with the key difference |
3832 | * of using a WARN/WARN_ON to get the message out, including the | 3853 | * of using a WARN/WARN_ON to get the message out, including the |
3833 | * file/line information and a backtrace. | 3854 | * file/line information and a backtrace. |
3834 | */ | 3855 | */ |
3835 | #define wiphy_WARN(wiphy, format, args...) \ | 3856 | #define wiphy_WARN(wiphy, format, args...) \ |
3836 | WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); | 3857 | WARN(1, "wiphy: %s\n" format, wiphy_name(wiphy), ##args); |
3837 | 3858 | ||
3838 | #endif /* __NET_CFG80211_H */ | 3859 | #endif /* __NET_CFG80211_H */ |
3839 | 3860 |
include/uapi/linux/nl80211.h
1 | #ifndef __LINUX_NL80211_H | 1 | #ifndef __LINUX_NL80211_H |
2 | #define __LINUX_NL80211_H | 2 | #define __LINUX_NL80211_H |
3 | /* | 3 | /* |
4 | * 802.11 netlink interface public header | 4 | * 802.11 netlink interface public header |
5 | * | 5 | * |
6 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 6 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
7 | * Copyright 2008 Michael Wu <flamingice@sourmilk.net> | 7 | * Copyright 2008 Michael Wu <flamingice@sourmilk.net> |
8 | * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com> | 8 | * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com> |
9 | * Copyright 2008 Michael Buesch <m@bues.ch> | 9 | * Copyright 2008 Michael Buesch <m@bues.ch> |
10 | * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com> | 10 | * Copyright 2008, 2009 Luis R. Rodriguez <lrodriguez@atheros.com> |
11 | * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> | 11 | * Copyright 2008 Jouni Malinen <jouni.malinen@atheros.com> |
12 | * Copyright 2008 Colin McCabe <colin@cozybit.com> | 12 | * Copyright 2008 Colin McCabe <colin@cozybit.com> |
13 | * | 13 | * |
14 | * Permission to use, copy, modify, and/or distribute this software for any | 14 | * Permission to use, copy, modify, and/or distribute this software for any |
15 | * purpose with or without fee is hereby granted, provided that the above | 15 | * purpose with or without fee is hereby granted, provided that the above |
16 | * copyright notice and this permission notice appear in all copies. | 16 | * copyright notice and this permission notice appear in all copies. |
17 | * | 17 | * |
18 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | 18 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
19 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | 19 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
20 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | 20 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
21 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 21 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
22 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 22 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
23 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 23 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
24 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 24 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
25 | * | 25 | * |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/types.h> | 28 | #include <linux/types.h> |
29 | 29 | ||
30 | /** | 30 | /** |
31 | * DOC: Station handling | 31 | * DOC: Station handling |
32 | * | 32 | * |
33 | * Stations are added per interface, but a special case exists with VLAN | 33 | * Stations are added per interface, but a special case exists with VLAN |
34 | * interfaces. When a station is bound to an AP interface, it may be moved | 34 | * interfaces. When a station is bound to an AP interface, it may be moved |
35 | * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN). | 35 | * into a VLAN identified by a VLAN interface index (%NL80211_ATTR_STA_VLAN). |
36 | * The station is still assumed to belong to the AP interface it was added | 36 | * The station is still assumed to belong to the AP interface it was added |
37 | * to. | 37 | * to. |
38 | * | 38 | * |
39 | * TODO: need more info? | 39 | * TODO: need more info? |
40 | */ | 40 | */ |
41 | 41 | ||
42 | /** | 42 | /** |
43 | * DOC: Frame transmission/registration support | 43 | * DOC: Frame transmission/registration support |
44 | * | 44 | * |
45 | * Frame transmission and registration support exists to allow userspace | 45 | * Frame transmission and registration support exists to allow userspace |
46 | * management entities such as wpa_supplicant react to management frames | 46 | * management entities such as wpa_supplicant react to management frames |
47 | * that are not being handled by the kernel. This includes, for example, | 47 | * that are not being handled by the kernel. This includes, for example, |
48 | * certain classes of action frames that cannot be handled in the kernel | 48 | * certain classes of action frames that cannot be handled in the kernel |
49 | * for various reasons. | 49 | * for various reasons. |
50 | * | 50 | * |
51 | * Frame registration is done on a per-interface basis and registrations | 51 | * Frame registration is done on a per-interface basis and registrations |
52 | * cannot be removed other than by closing the socket. It is possible to | 52 | * cannot be removed other than by closing the socket. It is possible to |
53 | * specify a registration filter to register, for example, only for a | 53 | * specify a registration filter to register, for example, only for a |
54 | * certain type of action frame. In particular with action frames, those | 54 | * certain type of action frame. In particular with action frames, those |
55 | * that userspace registers for will not be returned as unhandled by the | 55 | * that userspace registers for will not be returned as unhandled by the |
56 | * driver, so that the registered application has to take responsibility | 56 | * driver, so that the registered application has to take responsibility |
57 | * for doing that. | 57 | * for doing that. |
58 | * | 58 | * |
59 | * The type of frame that can be registered for is also dependent on the | 59 | * The type of frame that can be registered for is also dependent on the |
60 | * driver and interface type. The frame types are advertised in wiphy | 60 | * driver and interface type. The frame types are advertised in wiphy |
61 | * attributes so applications know what to expect. | 61 | * attributes so applications know what to expect. |
62 | * | 62 | * |
63 | * NOTE: When an interface changes type while registrations are active, | 63 | * NOTE: When an interface changes type while registrations are active, |
64 | * these registrations are ignored until the interface type is | 64 | * these registrations are ignored until the interface type is |
65 | * changed again. This means that changing the interface type can | 65 | * changed again. This means that changing the interface type can |
66 | * lead to a situation that couldn't otherwise be produced, but | 66 | * lead to a situation that couldn't otherwise be produced, but |
67 | * any such registrations will be dormant in the sense that they | 67 | * any such registrations will be dormant in the sense that they |
68 | * will not be serviced, i.e. they will not receive any frames. | 68 | * will not be serviced, i.e. they will not receive any frames. |
69 | * | 69 | * |
70 | * Frame transmission allows userspace to send for example the required | 70 | * Frame transmission allows userspace to send for example the required |
71 | * responses to action frames. It is subject to some sanity checking, | 71 | * responses to action frames. It is subject to some sanity checking, |
72 | * but many frames can be transmitted. When a frame was transmitted, its | 72 | * but many frames can be transmitted. When a frame was transmitted, its |
73 | * status is indicated to the sending socket. | 73 | * status is indicated to the sending socket. |
74 | * | 74 | * |
75 | * For more technical details, see the corresponding command descriptions | 75 | * For more technical details, see the corresponding command descriptions |
76 | * below. | 76 | * below. |
77 | */ | 77 | */ |
78 | 78 | ||
79 | /** | 79 | /** |
80 | * DOC: Virtual interface / concurrency capabilities | 80 | * DOC: Virtual interface / concurrency capabilities |
81 | * | 81 | * |
82 | * Some devices are able to operate with virtual MACs, they can have | 82 | * Some devices are able to operate with virtual MACs, they can have |
83 | * more than one virtual interface. The capability handling for this | 83 | * more than one virtual interface. The capability handling for this |
84 | * is a bit complex though, as there may be a number of restrictions | 84 | * is a bit complex though, as there may be a number of restrictions |
85 | * on the types of concurrency that are supported. | 85 | * on the types of concurrency that are supported. |
86 | * | 86 | * |
87 | * To start with, each device supports the interface types listed in | 87 | * To start with, each device supports the interface types listed in |
88 | * the %NL80211_ATTR_SUPPORTED_IFTYPES attribute, but by listing the | 88 | * the %NL80211_ATTR_SUPPORTED_IFTYPES attribute, but by listing the |
89 | * types there no concurrency is implied. | 89 | * types there no concurrency is implied. |
90 | * | 90 | * |
91 | * Once concurrency is desired, more attributes must be observed: | 91 | * Once concurrency is desired, more attributes must be observed: |
92 | * To start with, since some interface types are purely managed in | 92 | * To start with, since some interface types are purely managed in |
93 | * software, like the AP-VLAN type in mac80211 for example, there's | 93 | * software, like the AP-VLAN type in mac80211 for example, there's |
94 | * an additional list of these, they can be added at any time and | 94 | * an additional list of these, they can be added at any time and |
95 | * are only restricted by some semantic restrictions (e.g. AP-VLAN | 95 | * are only restricted by some semantic restrictions (e.g. AP-VLAN |
96 | * cannot be added without a corresponding AP interface). This list | 96 | * cannot be added without a corresponding AP interface). This list |
97 | * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute. | 97 | * is exported in the %NL80211_ATTR_SOFTWARE_IFTYPES attribute. |
98 | * | 98 | * |
99 | * Further, the list of supported combinations is exported. This is | 99 | * Further, the list of supported combinations is exported. This is |
100 | * in the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute. Basically, | 100 | * in the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute. Basically, |
101 | * it exports a list of "groups", and at any point in time the | 101 | * it exports a list of "groups", and at any point in time the |
102 | * interfaces that are currently active must fall into any one of | 102 | * interfaces that are currently active must fall into any one of |
103 | * the advertised groups. Within each group, there are restrictions | 103 | * the advertised groups. Within each group, there are restrictions |
104 | * on the number of interfaces of different types that are supported | 104 | * on the number of interfaces of different types that are supported |
105 | * and also the number of different channels, along with potentially | 105 | * and also the number of different channels, along with potentially |
106 | * some other restrictions. See &enum nl80211_if_combination_attrs. | 106 | * some other restrictions. See &enum nl80211_if_combination_attrs. |
107 | * | 107 | * |
108 | * All together, these attributes define the concurrency of virtual | 108 | * All together, these attributes define the concurrency of virtual |
109 | * interfaces that a given device supports. | 109 | * interfaces that a given device supports. |
110 | */ | 110 | */ |
111 | 111 | ||
112 | /** | 112 | /** |
113 | * enum nl80211_commands - supported nl80211 commands | 113 | * enum nl80211_commands - supported nl80211 commands |
114 | * | 114 | * |
115 | * @NL80211_CMD_UNSPEC: unspecified command to catch errors | 115 | * @NL80211_CMD_UNSPEC: unspecified command to catch errors |
116 | * | 116 | * |
117 | * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request | 117 | * @NL80211_CMD_GET_WIPHY: request information about a wiphy or dump request |
118 | * to get a list of all present wiphys. | 118 | * to get a list of all present wiphys. |
119 | * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or | 119 | * @NL80211_CMD_SET_WIPHY: set wiphy parameters, needs %NL80211_ATTR_WIPHY or |
120 | * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, | 120 | * %NL80211_ATTR_IFINDEX; can be used to set %NL80211_ATTR_WIPHY_NAME, |
121 | * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the | 121 | * %NL80211_ATTR_WIPHY_TXQ_PARAMS, %NL80211_ATTR_WIPHY_FREQ (and the |
122 | * attributes determining the channel width; this is used for setting | 122 | * attributes determining the channel width; this is used for setting |
123 | * monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT, | 123 | * monitor mode channel), %NL80211_ATTR_WIPHY_RETRY_SHORT, |
124 | * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, | 124 | * %NL80211_ATTR_WIPHY_RETRY_LONG, %NL80211_ATTR_WIPHY_FRAG_THRESHOLD, |
125 | * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. | 125 | * and/or %NL80211_ATTR_WIPHY_RTS_THRESHOLD. |
126 | * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL | 126 | * However, for setting the channel, see %NL80211_CMD_SET_CHANNEL |
127 | * instead, the support here is for backward compatibility only. | 127 | * instead, the support here is for backward compatibility only. |
128 | * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request | 128 | * @NL80211_CMD_NEW_WIPHY: Newly created wiphy, response to get request |
129 | * or rename notification. Has attributes %NL80211_ATTR_WIPHY and | 129 | * or rename notification. Has attributes %NL80211_ATTR_WIPHY and |
130 | * %NL80211_ATTR_WIPHY_NAME. | 130 | * %NL80211_ATTR_WIPHY_NAME. |
131 | * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes | 131 | * @NL80211_CMD_DEL_WIPHY: Wiphy deleted. Has attributes |
132 | * %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME. | 132 | * %NL80211_ATTR_WIPHY and %NL80211_ATTR_WIPHY_NAME. |
133 | * | 133 | * |
134 | * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration; | 134 | * @NL80211_CMD_GET_INTERFACE: Request an interface's configuration; |
135 | * either a dump request on a %NL80211_ATTR_WIPHY or a specific get | 135 | * either a dump request on a %NL80211_ATTR_WIPHY or a specific get |
136 | * on an %NL80211_ATTR_IFINDEX is supported. | 136 | * on an %NL80211_ATTR_IFINDEX is supported. |
137 | * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires | 137 | * @NL80211_CMD_SET_INTERFACE: Set type of a virtual interface, requires |
138 | * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. | 138 | * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_IFTYPE. |
139 | * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response | 139 | * @NL80211_CMD_NEW_INTERFACE: Newly created virtual interface or response |
140 | * to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX, | 140 | * to %NL80211_CMD_GET_INTERFACE. Has %NL80211_ATTR_IFINDEX, |
141 | * %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also | 141 | * %NL80211_ATTR_WIPHY and %NL80211_ATTR_IFTYPE attributes. Can also |
142 | * be sent from userspace to request creation of a new virtual interface, | 142 | * be sent from userspace to request creation of a new virtual interface, |
143 | * then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and | 143 | * then requires attributes %NL80211_ATTR_WIPHY, %NL80211_ATTR_IFTYPE and |
144 | * %NL80211_ATTR_IFNAME. | 144 | * %NL80211_ATTR_IFNAME. |
145 | * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes | 145 | * @NL80211_CMD_DEL_INTERFACE: Virtual interface was deleted, has attributes |
146 | * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from | 146 | * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_WIPHY. Can also be sent from |
147 | * userspace to request deletion of a virtual interface, then requires | 147 | * userspace to request deletion of a virtual interface, then requires |
148 | * attribute %NL80211_ATTR_IFINDEX. | 148 | * attribute %NL80211_ATTR_IFINDEX. |
149 | * | 149 | * |
150 | * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified | 150 | * @NL80211_CMD_GET_KEY: Get sequence counter information for a key specified |
151 | * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. | 151 | * by %NL80211_ATTR_KEY_IDX and/or %NL80211_ATTR_MAC. |
152 | * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT, | 152 | * @NL80211_CMD_SET_KEY: Set key attributes %NL80211_ATTR_KEY_DEFAULT, |
153 | * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD. | 153 | * %NL80211_ATTR_KEY_DEFAULT_MGMT, or %NL80211_ATTR_KEY_THRESHOLD. |
154 | * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA, | 154 | * @NL80211_CMD_NEW_KEY: add a key with given %NL80211_ATTR_KEY_DATA, |
155 | * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER, | 155 | * %NL80211_ATTR_KEY_IDX, %NL80211_ATTR_MAC, %NL80211_ATTR_KEY_CIPHER, |
156 | * and %NL80211_ATTR_KEY_SEQ attributes. | 156 | * and %NL80211_ATTR_KEY_SEQ attributes. |
157 | * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX | 157 | * @NL80211_CMD_DEL_KEY: delete a key identified by %NL80211_ATTR_KEY_IDX |
158 | * or %NL80211_ATTR_MAC. | 158 | * or %NL80211_ATTR_MAC. |
159 | * | 159 | * |
160 | * @NL80211_CMD_GET_BEACON: (not used) | 160 | * @NL80211_CMD_GET_BEACON: (not used) |
161 | * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface | 161 | * @NL80211_CMD_SET_BEACON: change the beacon on an access point interface |
162 | * using the %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL | 162 | * using the %NL80211_ATTR_BEACON_HEAD and %NL80211_ATTR_BEACON_TAIL |
163 | * attributes. For drivers that generate the beacon and probe responses | 163 | * attributes. For drivers that generate the beacon and probe responses |
164 | * internally, the following attributes must be provided: %NL80211_ATTR_IE, | 164 | * internally, the following attributes must be provided: %NL80211_ATTR_IE, |
165 | * %NL80211_ATTR_IE_PROBE_RESP and %NL80211_ATTR_IE_ASSOC_RESP. | 165 | * %NL80211_ATTR_IE_PROBE_RESP and %NL80211_ATTR_IE_ASSOC_RESP. |
166 | * @NL80211_CMD_START_AP: Start AP operation on an AP interface, parameters | 166 | * @NL80211_CMD_START_AP: Start AP operation on an AP interface, parameters |
167 | * are like for %NL80211_CMD_SET_BEACON, and additionally parameters that | 167 | * are like for %NL80211_CMD_SET_BEACON, and additionally parameters that |
168 | * do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL, | 168 | * do not change are used, these include %NL80211_ATTR_BEACON_INTERVAL, |
169 | * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, | 169 | * %NL80211_ATTR_DTIM_PERIOD, %NL80211_ATTR_SSID, |
170 | * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, | 170 | * %NL80211_ATTR_HIDDEN_SSID, %NL80211_ATTR_CIPHERS_PAIRWISE, |
171 | * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, | 171 | * %NL80211_ATTR_CIPHER_GROUP, %NL80211_ATTR_WPA_VERSIONS, |
172 | * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, | 172 | * %NL80211_ATTR_AKM_SUITES, %NL80211_ATTR_PRIVACY, |
173 | * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. | 173 | * %NL80211_ATTR_AUTH_TYPE and %NL80211_ATTR_INACTIVITY_TIMEOUT. |
174 | * The channel to use can be set on the interface or be given using the | 174 | * The channel to use can be set on the interface or be given using the |
175 | * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width. | 175 | * %NL80211_ATTR_WIPHY_FREQ and the attributes determining channel width. |
176 | * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP | 176 | * @NL80211_CMD_NEW_BEACON: old alias for %NL80211_CMD_START_AP |
177 | * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface | 177 | * @NL80211_CMD_STOP_AP: Stop AP operation on the given interface |
178 | * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP | 178 | * @NL80211_CMD_DEL_BEACON: old alias for %NL80211_CMD_STOP_AP |
179 | * | 179 | * |
180 | * @NL80211_CMD_GET_STATION: Get station attributes for station identified by | 180 | * @NL80211_CMD_GET_STATION: Get station attributes for station identified by |
181 | * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. | 181 | * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. |
182 | * @NL80211_CMD_SET_STATION: Set station attributes for station identified by | 182 | * @NL80211_CMD_SET_STATION: Set station attributes for station identified by |
183 | * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. | 183 | * %NL80211_ATTR_MAC on the interface identified by %NL80211_ATTR_IFINDEX. |
184 | * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the | 184 | * @NL80211_CMD_NEW_STATION: Add a station with given attributes to the |
185 | * the interface identified by %NL80211_ATTR_IFINDEX. | 185 | * the interface identified by %NL80211_ATTR_IFINDEX. |
186 | * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC | 186 | * @NL80211_CMD_DEL_STATION: Remove a station identified by %NL80211_ATTR_MAC |
187 | * or, if no MAC address given, all stations, on the interface identified | 187 | * or, if no MAC address given, all stations, on the interface identified |
188 | * by %NL80211_ATTR_IFINDEX. | 188 | * by %NL80211_ATTR_IFINDEX. |
189 | * | 189 | * |
190 | * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to | 190 | * @NL80211_CMD_GET_MPATH: Get mesh path attributes for mesh path to |
191 | * destination %NL80211_ATTR_MAC on the interface identified by | 191 | * destination %NL80211_ATTR_MAC on the interface identified by |
192 | * %NL80211_ATTR_IFINDEX. | 192 | * %NL80211_ATTR_IFINDEX. |
193 | * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to | 193 | * @NL80211_CMD_SET_MPATH: Set mesh path attributes for mesh path to |
194 | * destination %NL80211_ATTR_MAC on the interface identified by | 194 | * destination %NL80211_ATTR_MAC on the interface identified by |
195 | * %NL80211_ATTR_IFINDEX. | 195 | * %NL80211_ATTR_IFINDEX. |
196 | * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by | 196 | * @NL80211_CMD_NEW_MPATH: Create a new mesh path for the destination given by |
197 | * %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP. | 197 | * %NL80211_ATTR_MAC via %NL80211_ATTR_MPATH_NEXT_HOP. |
198 | * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by | 198 | * @NL80211_CMD_DEL_MPATH: Delete a mesh path to the destination given by |
199 | * %NL80211_ATTR_MAC. | 199 | * %NL80211_ATTR_MAC. |
200 | * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the | 200 | * @NL80211_CMD_NEW_PATH: Add a mesh path with given attributes to the |
201 | * the interface identified by %NL80211_ATTR_IFINDEX. | 201 | * the interface identified by %NL80211_ATTR_IFINDEX. |
202 | * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC | 202 | * @NL80211_CMD_DEL_PATH: Remove a mesh path identified by %NL80211_ATTR_MAC |
203 | * or, if no MAC address given, all mesh paths, on the interface identified | 203 | * or, if no MAC address given, all mesh paths, on the interface identified |
204 | * by %NL80211_ATTR_IFINDEX. | 204 | * by %NL80211_ATTR_IFINDEX. |
205 | * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by | 205 | * @NL80211_CMD_SET_BSS: Set BSS attributes for BSS identified by |
206 | * %NL80211_ATTR_IFINDEX. | 206 | * %NL80211_ATTR_IFINDEX. |
207 | * | 207 | * |
208 | * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set | 208 | * @NL80211_CMD_GET_REG: ask the wireless core to send us its currently set |
209 | * regulatory domain. | 209 | * regulatory domain. |
210 | * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command | 210 | * @NL80211_CMD_SET_REG: Set current regulatory domain. CRDA sends this command |
211 | * after being queried by the kernel. CRDA replies by sending a regulatory | 211 | * after being queried by the kernel. CRDA replies by sending a regulatory |
212 | * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our | 212 | * domain structure which consists of %NL80211_ATTR_REG_ALPHA set to our |
213 | * current alpha2 if it found a match. It also provides | 213 | * current alpha2 if it found a match. It also provides |
214 | * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each | 214 | * NL80211_ATTR_REG_RULE_FLAGS, and a set of regulatory rules. Each |
215 | * regulatory rule is a nested set of attributes given by | 215 | * regulatory rule is a nested set of attributes given by |
216 | * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and | 216 | * %NL80211_ATTR_REG_RULE_FREQ_[START|END] and |
217 | * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by | 217 | * %NL80211_ATTR_FREQ_RANGE_MAX_BW with an attached power rule given by |
218 | * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and | 218 | * %NL80211_ATTR_REG_RULE_POWER_MAX_ANT_GAIN and |
219 | * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP. | 219 | * %NL80211_ATTR_REG_RULE_POWER_MAX_EIRP. |
220 | * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain | 220 | * @NL80211_CMD_REQ_SET_REG: ask the wireless core to set the regulatory domain |
221 | * to the specified ISO/IEC 3166-1 alpha2 country code. The core will | 221 | * to the specified ISO/IEC 3166-1 alpha2 country code. The core will |
222 | * store this as a valid request and then query userspace for it. | 222 | * store this as a valid request and then query userspace for it. |
223 | * | 223 | * |
224 | * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the | 224 | * @NL80211_CMD_GET_MESH_CONFIG: Get mesh networking properties for the |
225 | * interface identified by %NL80211_ATTR_IFINDEX | 225 | * interface identified by %NL80211_ATTR_IFINDEX |
226 | * | 226 | * |
227 | * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the | 227 | * @NL80211_CMD_SET_MESH_CONFIG: Set mesh networking properties for the |
228 | * interface identified by %NL80211_ATTR_IFINDEX | 228 | * interface identified by %NL80211_ATTR_IFINDEX |
229 | * | 229 | * |
230 | * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The | 230 | * @NL80211_CMD_SET_MGMT_EXTRA_IE: Set extra IEs for management frames. The |
231 | * interface is identified with %NL80211_ATTR_IFINDEX and the management | 231 | * interface is identified with %NL80211_ATTR_IFINDEX and the management |
232 | * frame subtype with %NL80211_ATTR_MGMT_SUBTYPE. The extra IE data to be | 232 | * frame subtype with %NL80211_ATTR_MGMT_SUBTYPE. The extra IE data to be |
233 | * added to the end of the specified management frame is specified with | 233 | * added to the end of the specified management frame is specified with |
234 | * %NL80211_ATTR_IE. If the command succeeds, the requested data will be | 234 | * %NL80211_ATTR_IE. If the command succeeds, the requested data will be |
235 | * added to all specified management frames generated by | 235 | * added to all specified management frames generated by |
236 | * kernel/firmware/driver. | 236 | * kernel/firmware/driver. |
237 | * Note: This command has been removed and it is only reserved at this | 237 | * Note: This command has been removed and it is only reserved at this |
238 | * point to avoid re-using existing command number. The functionality this | 238 | * point to avoid re-using existing command number. The functionality this |
239 | * command was planned for has been provided with cleaner design with the | 239 | * command was planned for has been provided with cleaner design with the |
240 | * option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN, | 240 | * option to specify additional IEs in NL80211_CMD_TRIGGER_SCAN, |
241 | * NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE, | 241 | * NL80211_CMD_AUTHENTICATE, NL80211_CMD_ASSOCIATE, |
242 | * NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE. | 242 | * NL80211_CMD_DEAUTHENTICATE, and NL80211_CMD_DISASSOCIATE. |
243 | * | 243 | * |
244 | * @NL80211_CMD_GET_SCAN: get scan results | 244 | * @NL80211_CMD_GET_SCAN: get scan results |
245 | * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters | 245 | * @NL80211_CMD_TRIGGER_SCAN: trigger a new scan with the given parameters |
246 | * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the | 246 | * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the |
247 | * probe requests at CCK rate or not. | 247 | * probe requests at CCK rate or not. |
248 | * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to | 248 | * @NL80211_CMD_NEW_SCAN_RESULTS: scan notification (as a reply to |
249 | * NL80211_CMD_GET_SCAN and on the "scan" multicast group) | 249 | * NL80211_CMD_GET_SCAN and on the "scan" multicast group) |
250 | * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, | 250 | * @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons, |
251 | * partial scan results may be available | 251 | * partial scan results may be available |
252 | * | 252 | * |
253 | * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain | 253 | * @NL80211_CMD_START_SCHED_SCAN: start a scheduled scan at certain |
254 | * intervals, as specified by %NL80211_ATTR_SCHED_SCAN_INTERVAL. | 254 | * intervals, as specified by %NL80211_ATTR_SCHED_SCAN_INTERVAL. |
255 | * Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS) | 255 | * Like with normal scans, if SSIDs (%NL80211_ATTR_SCAN_SSIDS) |
256 | * are passed, they are used in the probe requests. For | 256 | * are passed, they are used in the probe requests. For |
257 | * broadcast, a broadcast SSID must be passed (ie. an empty | 257 | * broadcast, a broadcast SSID must be passed (ie. an empty |
258 | * string). If no SSID is passed, no probe requests are sent and | 258 | * string). If no SSID is passed, no probe requests are sent and |
259 | * a passive scan is performed. %NL80211_ATTR_SCAN_FREQUENCIES, | 259 | * a passive scan is performed. %NL80211_ATTR_SCAN_FREQUENCIES, |
260 | * if passed, define which channels should be scanned; if not | 260 | * if passed, define which channels should be scanned; if not |
261 | * passed, all channels allowed for the current regulatory domain | 261 | * passed, all channels allowed for the current regulatory domain |
262 | * are used. Extra IEs can also be passed from the userspace by | 262 | * are used. Extra IEs can also be passed from the userspace by |
263 | * using the %NL80211_ATTR_IE attribute. | 263 | * using the %NL80211_ATTR_IE attribute. |
264 | * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT | 264 | * @NL80211_CMD_STOP_SCHED_SCAN: stop a scheduled scan. Returns -ENOENT |
265 | * if scheduled scan is not running. | 265 | * if scheduled scan is not running. |
266 | * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan | 266 | * @NL80211_CMD_SCHED_SCAN_RESULTS: indicates that there are scheduled scan |
267 | * results available. | 267 | * results available. |
268 | * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has | 268 | * @NL80211_CMD_SCHED_SCAN_STOPPED: indicates that the scheduled scan has |
269 | * stopped. The driver may issue this event at any time during a | 269 | * stopped. The driver may issue this event at any time during a |
270 | * scheduled scan. One reason for stopping the scan is if the hardware | 270 | * scheduled scan. One reason for stopping the scan is if the hardware |
271 | * does not support starting an association or a normal scan while running | 271 | * does not support starting an association or a normal scan while running |
272 | * a scheduled scan. This event is also sent when the | 272 | * a scheduled scan. This event is also sent when the |
273 | * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface | 273 | * %NL80211_CMD_STOP_SCHED_SCAN command is received or when the interface |
274 | * is brought down while a scheduled scan was running. | 274 | * is brought down while a scheduled scan was running. |
275 | * | 275 | * |
276 | * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation | 276 | * @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation |
277 | * or noise level | 277 | * or noise level |
278 | * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to | 278 | * @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to |
279 | * NL80211_CMD_GET_SURVEY and on the "scan" multicast group) | 279 | * NL80211_CMD_GET_SURVEY and on the "scan" multicast group) |
280 | * | 280 | * |
281 | * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC | 281 | * @NL80211_CMD_SET_PMKSA: Add a PMKSA cache entry, using %NL80211_ATTR_MAC |
282 | * (for the BSSID) and %NL80211_ATTR_PMKID. | 282 | * (for the BSSID) and %NL80211_ATTR_PMKID. |
283 | * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC | 283 | * @NL80211_CMD_DEL_PMKSA: Delete a PMKSA cache entry, using %NL80211_ATTR_MAC |
284 | * (for the BSSID) and %NL80211_ATTR_PMKID. | 284 | * (for the BSSID) and %NL80211_ATTR_PMKID. |
285 | * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. | 285 | * @NL80211_CMD_FLUSH_PMKSA: Flush all PMKSA cache entries. |
286 | * | 286 | * |
287 | * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain | 287 | * @NL80211_CMD_REG_CHANGE: indicates to userspace the regulatory domain |
288 | * has been changed and provides details of the request information | 288 | * has been changed and provides details of the request information |
289 | * that caused the change such as who initiated the regulatory request | 289 | * that caused the change such as who initiated the regulatory request |
290 | * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx | 290 | * (%NL80211_ATTR_REG_INITIATOR), the wiphy_idx |
291 | * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if | 291 | * (%NL80211_ATTR_REG_ALPHA2) on which the request was made from if |
292 | * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or | 292 | * the initiator was %NL80211_REGDOM_SET_BY_COUNTRY_IE or |
293 | * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain | 293 | * %NL80211_REGDOM_SET_BY_DRIVER, the type of regulatory domain |
294 | * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is | 294 | * set (%NL80211_ATTR_REG_TYPE), if the type of regulatory domain is |
295 | * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on | 295 | * %NL80211_REG_TYPE_COUNTRY the alpha2 to which we have moved on |
296 | * to (%NL80211_ATTR_REG_ALPHA2). | 296 | * to (%NL80211_ATTR_REG_ALPHA2). |
297 | * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon | 297 | * @NL80211_CMD_REG_BEACON_HINT: indicates to userspace that an AP beacon |
298 | * has been found while world roaming thus enabling active scan or | 298 | * has been found while world roaming thus enabling active scan or |
299 | * any mode of operation that initiates TX (beacons) on a channel | 299 | * any mode of operation that initiates TX (beacons) on a channel |
300 | * where we would not have been able to do either before. As an example | 300 | * where we would not have been able to do either before. As an example |
301 | * if you are world roaming (regulatory domain set to world or if your | 301 | * if you are world roaming (regulatory domain set to world or if your |
302 | * driver is using a custom world roaming regulatory domain) and while | 302 | * driver is using a custom world roaming regulatory domain) and while |
303 | * doing a passive scan on the 5 GHz band you find an AP there (if not | 303 | * doing a passive scan on the 5 GHz band you find an AP there (if not |
304 | * on a DFS channel) you will now be able to actively scan for that AP | 304 | * on a DFS channel) you will now be able to actively scan for that AP |
305 | * or use AP mode on your card on that same channel. Note that this will | 305 | * or use AP mode on your card on that same channel. Note that this will |
306 | * never be used for channels 1-11 on the 2 GHz band as they are always | 306 | * never be used for channels 1-11 on the 2 GHz band as they are always |
307 | * enabled world wide. This beacon hint is only sent if your device had | 307 | * enabled world wide. This beacon hint is only sent if your device had |
308 | * either disabled active scanning or beaconing on a channel. We send to | 308 | * either disabled active scanning or beaconing on a channel. We send to |
309 | * userspace the wiphy on which we removed a restriction from | 309 | * userspace the wiphy on which we removed a restriction from |
310 | * (%NL80211_ATTR_WIPHY) and the channel on which this occurred | 310 | * (%NL80211_ATTR_WIPHY) and the channel on which this occurred |
311 | * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER) | 311 | * before (%NL80211_ATTR_FREQ_BEFORE) and after (%NL80211_ATTR_FREQ_AFTER) |
312 | * the beacon hint was processed. | 312 | * the beacon hint was processed. |
313 | * | 313 | * |
314 | * @NL80211_CMD_AUTHENTICATE: authentication request and notification. | 314 | * @NL80211_CMD_AUTHENTICATE: authentication request and notification. |
315 | * This command is used both as a command (request to authenticate) and | 315 | * This command is used both as a command (request to authenticate) and |
316 | * as an event on the "mlme" multicast group indicating completion of the | 316 | * as an event on the "mlme" multicast group indicating completion of the |
317 | * authentication process. | 317 | * authentication process. |
318 | * When used as a command, %NL80211_ATTR_IFINDEX is used to identify the | 318 | * When used as a command, %NL80211_ATTR_IFINDEX is used to identify the |
319 | * interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and | 319 | * interface. %NL80211_ATTR_MAC is used to specify PeerSTAAddress (and |
320 | * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify | 320 | * BSSID in case of station mode). %NL80211_ATTR_SSID is used to specify |
321 | * the SSID (mainly for association, but is included in authentication | 321 | * the SSID (mainly for association, but is included in authentication |
322 | * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used | 322 | * request, too, to help BSS selection. %NL80211_ATTR_WIPHY_FREQ is used |
323 | * to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE | 323 | * to specify the frequence of the channel in MHz. %NL80211_ATTR_AUTH_TYPE |
324 | * is used to specify the authentication type. %NL80211_ATTR_IE is used to | 324 | * is used to specify the authentication type. %NL80211_ATTR_IE is used to |
325 | * define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs) | 325 | * define IEs (VendorSpecificInfo, but also including RSN IE and FT IEs) |
326 | * to be added to the frame. | 326 | * to be added to the frame. |
327 | * When used as an event, this reports reception of an Authentication | 327 | * When used as an event, this reports reception of an Authentication |
328 | * frame in station and IBSS modes when the local MLME processed the | 328 | * frame in station and IBSS modes when the local MLME processed the |
329 | * frame, i.e., it was for the local STA and was received in correct | 329 | * frame, i.e., it was for the local STA and was received in correct |
330 | * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the | 330 | * state. This is similar to MLME-AUTHENTICATE.confirm primitive in the |
331 | * MLME SAP interface (kernel providing MLME, userspace SME). The | 331 | * MLME SAP interface (kernel providing MLME, userspace SME). The |
332 | * included %NL80211_ATTR_FRAME attribute contains the management frame | 332 | * included %NL80211_ATTR_FRAME attribute contains the management frame |
333 | * (including both the header and frame body, but not FCS). This event is | 333 | * (including both the header and frame body, but not FCS). This event is |
334 | * also used to indicate if the authentication attempt timed out. In that | 334 | * also used to indicate if the authentication attempt timed out. In that |
335 | * case the %NL80211_ATTR_FRAME attribute is replaced with a | 335 | * case the %NL80211_ATTR_FRAME attribute is replaced with a |
336 | * %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which | 336 | * %NL80211_ATTR_TIMED_OUT flag (and %NL80211_ATTR_MAC to indicate which |
337 | * pending authentication timed out). | 337 | * pending authentication timed out). |
338 | * @NL80211_CMD_ASSOCIATE: association request and notification; like | 338 | * @NL80211_CMD_ASSOCIATE: association request and notification; like |
339 | * NL80211_CMD_AUTHENTICATE but for Association and Reassociation | 339 | * NL80211_CMD_AUTHENTICATE but for Association and Reassociation |
340 | * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request, | 340 | * (similar to MLME-ASSOCIATE.request, MLME-REASSOCIATE.request, |
341 | * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). | 341 | * MLME-ASSOCIATE.confirm or MLME-REASSOCIATE.confirm primitives). |
342 | * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like | 342 | * @NL80211_CMD_DEAUTHENTICATE: deauthentication request and notification; like |
343 | * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to | 343 | * NL80211_CMD_AUTHENTICATE but for Deauthentication frames (similar to |
344 | * MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication | 344 | * MLME-DEAUTHENTICATION.request and MLME-DEAUTHENTICATE.indication |
345 | * primitives). | 345 | * primitives). |
346 | * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like | 346 | * @NL80211_CMD_DISASSOCIATE: disassociation request and notification; like |
347 | * NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to | 347 | * NL80211_CMD_AUTHENTICATE but for Disassociation frames (similar to |
348 | * MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives). | 348 | * MLME-DISASSOCIATE.request and MLME-DISASSOCIATE.indication primitives). |
349 | * | 349 | * |
350 | * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael | 350 | * @NL80211_CMD_MICHAEL_MIC_FAILURE: notification of a locally detected Michael |
351 | * MIC (part of TKIP) failure; sent on the "mlme" multicast group; the | 351 | * MIC (part of TKIP) failure; sent on the "mlme" multicast group; the |
352 | * event includes %NL80211_ATTR_MAC to describe the source MAC address of | 352 | * event includes %NL80211_ATTR_MAC to describe the source MAC address of |
353 | * the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key | 353 | * the frame with invalid MIC, %NL80211_ATTR_KEY_TYPE to show the key |
354 | * type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and | 354 | * type, %NL80211_ATTR_KEY_IDX to indicate the key identifier, and |
355 | * %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this | 355 | * %NL80211_ATTR_KEY_SEQ to indicate the TSC value of the frame; this |
356 | * event matches with MLME-MICHAELMICFAILURE.indication() primitive | 356 | * event matches with MLME-MICHAELMICFAILURE.indication() primitive |
357 | * | 357 | * |
358 | * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a | 358 | * @NL80211_CMD_JOIN_IBSS: Join a new IBSS -- given at least an SSID and a |
359 | * FREQ attribute (for the initial frequency if no peer can be found) | 359 | * FREQ attribute (for the initial frequency if no peer can be found) |
360 | * and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those | 360 | * and optionally a MAC (as BSSID) and FREQ_FIXED attribute if those |
361 | * should be fixed rather than automatically determined. Can only be | 361 | * should be fixed rather than automatically determined. Can only be |
362 | * executed on a network interface that is UP, and fixed BSSID/FREQ | 362 | * executed on a network interface that is UP, and fixed BSSID/FREQ |
363 | * may be rejected. Another optional parameter is the beacon interval, | 363 | * may be rejected. Another optional parameter is the beacon interval, |
364 | * given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not | 364 | * given in the %NL80211_ATTR_BEACON_INTERVAL attribute, which if not |
365 | * given defaults to 100 TU (102.4ms). | 365 | * given defaults to 100 TU (102.4ms). |
366 | * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is | 366 | * @NL80211_CMD_LEAVE_IBSS: Leave the IBSS -- no special arguments, the IBSS is |
367 | * determined by the network interface. | 367 | * determined by the network interface. |
368 | * | 368 | * |
369 | * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute | 369 | * @NL80211_CMD_TESTMODE: testmode command, takes a wiphy (or ifindex) attribute |
370 | * to identify the device, and the TESTDATA blob attribute to pass through | 370 | * to identify the device, and the TESTDATA blob attribute to pass through |
371 | * to the driver. | 371 | * to the driver. |
372 | * | 372 | * |
373 | * @NL80211_CMD_CONNECT: connection request and notification; this command | 373 | * @NL80211_CMD_CONNECT: connection request and notification; this command |
374 | * requests to connect to a specified network but without separating | 374 | * requests to connect to a specified network but without separating |
375 | * auth and assoc steps. For this, you need to specify the SSID in a | 375 | * auth and assoc steps. For this, you need to specify the SSID in a |
376 | * %NL80211_ATTR_SSID attribute, and can optionally specify the association | 376 | * %NL80211_ATTR_SSID attribute, and can optionally specify the association |
377 | * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC, | 377 | * IEs in %NL80211_ATTR_IE, %NL80211_ATTR_AUTH_TYPE, %NL80211_ATTR_MAC, |
378 | * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, | 378 | * %NL80211_ATTR_WIPHY_FREQ, %NL80211_ATTR_CONTROL_PORT, |
379 | * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and | 379 | * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE and |
380 | * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. | 380 | * %NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT. |
381 | * Background scan period can optionally be | 381 | * Background scan period can optionally be |
382 | * specified in %NL80211_ATTR_BG_SCAN_PERIOD, | 382 | * specified in %NL80211_ATTR_BG_SCAN_PERIOD, |
383 | * if not specified default background scan configuration | 383 | * if not specified default background scan configuration |
384 | * in driver is used and if period value is 0, bg scan will be disabled. | 384 | * in driver is used and if period value is 0, bg scan will be disabled. |
385 | * This attribute is ignored if driver does not support roam scan. | 385 | * This attribute is ignored if driver does not support roam scan. |
386 | * It is also sent as an event, with the BSSID and response IEs when the | 386 | * It is also sent as an event, with the BSSID and response IEs when the |
387 | * connection is established or failed to be established. This can be | 387 | * connection is established or failed to be established. This can be |
388 | * determined by the STATUS_CODE attribute. | 388 | * determined by the STATUS_CODE attribute. |
389 | * @NL80211_CMD_ROAM: request that the card roam (currently not implemented), | 389 | * @NL80211_CMD_ROAM: request that the card roam (currently not implemented), |
390 | * sent as an event when the card/driver roamed by itself. | 390 | * sent as an event when the card/driver roamed by itself. |
391 | * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify | 391 | * @NL80211_CMD_DISCONNECT: drop a given connection; also used to notify |
392 | * userspace that a connection was dropped by the AP or due to other | 392 | * userspace that a connection was dropped by the AP or due to other |
393 | * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and | 393 | * reasons, for this the %NL80211_ATTR_DISCONNECTED_BY_AP and |
394 | * %NL80211_ATTR_REASON_CODE attributes are used. | 394 | * %NL80211_ATTR_REASON_CODE attributes are used. |
395 | * | 395 | * |
396 | * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices | 396 | * @NL80211_CMD_SET_WIPHY_NETNS: Set a wiphy's netns. Note that all devices |
397 | * associated with this wiphy must be down and will follow. | 397 | * associated with this wiphy must be down and will follow. |
398 | * | 398 | * |
399 | * @NL80211_CMD_REMAIN_ON_CHANNEL: Request to remain awake on the specified | 399 | * @NL80211_CMD_REMAIN_ON_CHANNEL: Request to remain awake on the specified |
400 | * channel for the specified amount of time. This can be used to do | 400 | * channel for the specified amount of time. This can be used to do |
401 | * off-channel operations like transmit a Public Action frame and wait for | 401 | * off-channel operations like transmit a Public Action frame and wait for |
402 | * a response while being associated to an AP on another channel. | 402 | * a response while being associated to an AP on another channel. |
403 | * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus | 403 | * %NL80211_ATTR_IFINDEX is used to specify which interface (and thus |
404 | * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the | 404 | * radio) is used. %NL80211_ATTR_WIPHY_FREQ is used to specify the |
405 | * frequency for the operation. | 405 | * frequency for the operation. |
406 | * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds | 406 | * %NL80211_ATTR_DURATION is used to specify the duration in milliseconds |
407 | * to remain on the channel. This command is also used as an event to | 407 | * to remain on the channel. This command is also used as an event to |
408 | * notify when the requested duration starts (it may take a while for the | 408 | * notify when the requested duration starts (it may take a while for the |
409 | * driver to schedule this time due to other concurrent needs for the | 409 | * driver to schedule this time due to other concurrent needs for the |
410 | * radio). | 410 | * radio). |
411 | * When called, this operation returns a cookie (%NL80211_ATTR_COOKIE) | 411 | * When called, this operation returns a cookie (%NL80211_ATTR_COOKIE) |
412 | * that will be included with any events pertaining to this request; | 412 | * that will be included with any events pertaining to this request; |
413 | * the cookie is also used to cancel the request. | 413 | * the cookie is also used to cancel the request. |
414 | * @NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: This command can be used to cancel a | 414 | * @NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL: This command can be used to cancel a |
415 | * pending remain-on-channel duration if the desired operation has been | 415 | * pending remain-on-channel duration if the desired operation has been |
416 | * completed prior to expiration of the originally requested duration. | 416 | * completed prior to expiration of the originally requested duration. |
417 | * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify the | 417 | * %NL80211_ATTR_WIPHY or %NL80211_ATTR_IFINDEX is used to specify the |
418 | * radio. The %NL80211_ATTR_COOKIE attribute must be given as well to | 418 | * radio. The %NL80211_ATTR_COOKIE attribute must be given as well to |
419 | * uniquely identify the request. | 419 | * uniquely identify the request. |
420 | * This command is also used as an event to notify when a requested | 420 | * This command is also used as an event to notify when a requested |
421 | * remain-on-channel duration has expired. | 421 | * remain-on-channel duration has expired. |
422 | * | 422 | * |
423 | * @NL80211_CMD_SET_TX_BITRATE_MASK: Set the mask of rates to be used in TX | 423 | * @NL80211_CMD_SET_TX_BITRATE_MASK: Set the mask of rates to be used in TX |
424 | * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface | 424 | * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface |
425 | * and @NL80211_ATTR_TX_RATES the set of allowed rates. | 425 | * and @NL80211_ATTR_TX_RATES the set of allowed rates. |
426 | * | 426 | * |
427 | * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames | 427 | * @NL80211_CMD_REGISTER_FRAME: Register for receiving certain mgmt frames |
428 | * (via @NL80211_CMD_FRAME) for processing in userspace. This command | 428 | * (via @NL80211_CMD_FRAME) for processing in userspace. This command |
429 | * requires an interface index, a frame type attribute (optional for | 429 | * requires an interface index, a frame type attribute (optional for |
430 | * backward compatibility reasons, if not given assumes action frames) | 430 | * backward compatibility reasons, if not given assumes action frames) |
431 | * and a match attribute containing the first few bytes of the frame | 431 | * and a match attribute containing the first few bytes of the frame |
432 | * that should match, e.g. a single byte for only a category match or | 432 | * that should match, e.g. a single byte for only a category match or |
433 | * four bytes for vendor frames including the OUI. The registration | 433 | * four bytes for vendor frames including the OUI. The registration |
434 | * cannot be dropped, but is removed automatically when the netlink | 434 | * cannot be dropped, but is removed automatically when the netlink |
435 | * socket is closed. Multiple registrations can be made. | 435 | * socket is closed. Multiple registrations can be made. |
436 | * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for | 436 | * @NL80211_CMD_REGISTER_ACTION: Alias for @NL80211_CMD_REGISTER_FRAME for |
437 | * backward compatibility | 437 | * backward compatibility |
438 | * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This | 438 | * @NL80211_CMD_FRAME: Management frame TX request and RX notification. This |
439 | * command is used both as a request to transmit a management frame and | 439 | * command is used both as a request to transmit a management frame and |
440 | * as an event indicating reception of a frame that was not processed in | 440 | * as an event indicating reception of a frame that was not processed in |
441 | * kernel code, but is for us (i.e., which may need to be processed in a | 441 | * kernel code, but is for us (i.e., which may need to be processed in a |
442 | * user space application). %NL80211_ATTR_FRAME is used to specify the | 442 | * user space application). %NL80211_ATTR_FRAME is used to specify the |
443 | * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ is used | 443 | * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ is used |
444 | * to indicate on which channel the frame is to be transmitted or was | 444 | * to indicate on which channel the frame is to be transmitted or was |
445 | * received. If this channel is not the current channel (remain-on-channel | 445 | * received. If this channel is not the current channel (remain-on-channel |
446 | * or the operational channel) the device will switch to the given channel | 446 | * or the operational channel) the device will switch to the given channel |
447 | * and transmit the frame, optionally waiting for a response for the time | 447 | * and transmit the frame, optionally waiting for a response for the time |
448 | * specified using %NL80211_ATTR_DURATION. When called, this operation | 448 | * specified using %NL80211_ATTR_DURATION. When called, this operation |
449 | * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the | 449 | * returns a cookie (%NL80211_ATTR_COOKIE) that will be included with the |
450 | * TX status event pertaining to the TX request. | 450 | * TX status event pertaining to the TX request. |
451 | * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the | 451 | * %NL80211_ATTR_TX_NO_CCK_RATE is used to decide whether to send the |
452 | * management frames at CCK rate or not in 2GHz band. | 452 | * management frames at CCK rate or not in 2GHz band. |
453 | * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this | 453 | * @NL80211_CMD_FRAME_WAIT_CANCEL: When an off-channel TX was requested, this |
454 | * command may be used with the corresponding cookie to cancel the wait | 454 | * command may be used with the corresponding cookie to cancel the wait |
455 | * time if it is known that it is no longer necessary. | 455 | * time if it is known that it is no longer necessary. |
456 | * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. | 456 | * @NL80211_CMD_ACTION: Alias for @NL80211_CMD_FRAME for backward compatibility. |
457 | * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame | 457 | * @NL80211_CMD_FRAME_TX_STATUS: Report TX status of a management frame |
458 | * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies | 458 | * transmitted with %NL80211_CMD_FRAME. %NL80211_ATTR_COOKIE identifies |
459 | * the TX command and %NL80211_ATTR_FRAME includes the contents of the | 459 | * the TX command and %NL80211_ATTR_FRAME includes the contents of the |
460 | * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged | 460 | * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged |
461 | * the frame. | 461 | * the frame. |
462 | * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for | 462 | * @NL80211_CMD_ACTION_TX_STATUS: Alias for @NL80211_CMD_FRAME_TX_STATUS for |
463 | * backward compatibility. | 463 | * backward compatibility. |
464 | * | 464 | * |
465 | * @NL80211_CMD_SET_POWER_SAVE: Set powersave, using %NL80211_ATTR_PS_STATE | 465 | * @NL80211_CMD_SET_POWER_SAVE: Set powersave, using %NL80211_ATTR_PS_STATE |
466 | * @NL80211_CMD_GET_POWER_SAVE: Get powersave status in %NL80211_ATTR_PS_STATE | 466 | * @NL80211_CMD_GET_POWER_SAVE: Get powersave status in %NL80211_ATTR_PS_STATE |
467 | * | 467 | * |
468 | * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command | 468 | * @NL80211_CMD_SET_CQM: Connection quality monitor configuration. This command |
469 | * is used to configure connection quality monitoring notification trigger | 469 | * is used to configure connection quality monitoring notification trigger |
470 | * levels. | 470 | * levels. |
471 | * @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This | 471 | * @NL80211_CMD_NOTIFY_CQM: Connection quality monitor notification. This |
472 | * command is used as an event to indicate the that a trigger level was | 472 | * command is used as an event to indicate the that a trigger level was |
473 | * reached. | 473 | * reached. |
474 | * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ | 474 | * @NL80211_CMD_SET_CHANNEL: Set the channel (using %NL80211_ATTR_WIPHY_FREQ |
475 | * and the attributes determining channel width) the given interface | 475 | * and the attributes determining channel width) the given interface |
476 | * (identifed by %NL80211_ATTR_IFINDEX) shall operate on. | 476 | * (identifed by %NL80211_ATTR_IFINDEX) shall operate on. |
477 | * In case multiple channels are supported by the device, the mechanism | 477 | * In case multiple channels are supported by the device, the mechanism |
478 | * with which it switches channels is implementation-defined. | 478 | * with which it switches channels is implementation-defined. |
479 | * When a monitor interface is given, it can only switch channel while | 479 | * When a monitor interface is given, it can only switch channel while |
480 | * no other interfaces are operating to avoid disturbing the operation | 480 | * no other interfaces are operating to avoid disturbing the operation |
481 | * of any other interfaces, and other interfaces will again take | 481 | * of any other interfaces, and other interfaces will again take |
482 | * precedence when they are used. | 482 | * precedence when they are used. |
483 | * | 483 | * |
484 | * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. | 484 | * @NL80211_CMD_SET_WDS_PEER: Set the MAC address of the peer on a WDS interface. |
485 | * | 485 | * |
486 | * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial | 486 | * @NL80211_CMD_JOIN_MESH: Join a mesh. The mesh ID must be given, and initial |
487 | * mesh config parameters may be given. | 487 | * mesh config parameters may be given. |
488 | * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the | 488 | * @NL80211_CMD_LEAVE_MESH: Leave the mesh network -- no special arguments, the |
489 | * network is determined by the network interface. | 489 | * network is determined by the network interface. |
490 | * | 490 | * |
491 | * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame | 491 | * @NL80211_CMD_UNPROT_DEAUTHENTICATE: Unprotected deauthentication frame |
492 | * notification. This event is used to indicate that an unprotected | 492 | * notification. This event is used to indicate that an unprotected |
493 | * deauthentication frame was dropped when MFP is in use. | 493 | * deauthentication frame was dropped when MFP is in use. |
494 | * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame | 494 | * @NL80211_CMD_UNPROT_DISASSOCIATE: Unprotected disassociation frame |
495 | * notification. This event is used to indicate that an unprotected | 495 | * notification. This event is used to indicate that an unprotected |
496 | * disassociation frame was dropped when MFP is in use. | 496 | * disassociation frame was dropped when MFP is in use. |
497 | * | 497 | * |
498 | * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a | 498 | * @NL80211_CMD_NEW_PEER_CANDIDATE: Notification on the reception of a |
499 | * beacon or probe response from a compatible mesh peer. This is only | 499 | * beacon or probe response from a compatible mesh peer. This is only |
500 | * sent while no station information (sta_info) exists for the new peer | 500 | * sent while no station information (sta_info) exists for the new peer |
501 | * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On | 501 | * candidate and when @NL80211_MESH_SETUP_USERSPACE_AUTH is set. On |
502 | * reception of this notification, userspace may decide to create a new | 502 | * reception of this notification, userspace may decide to create a new |
503 | * station (@NL80211_CMD_NEW_STATION). To stop this notification from | 503 | * station (@NL80211_CMD_NEW_STATION). To stop this notification from |
504 | * reoccurring, the userspace authentication daemon may want to create the | 504 | * reoccurring, the userspace authentication daemon may want to create the |
505 | * new station with the AUTHENTICATED flag unset and maybe change it later | 505 | * new station with the AUTHENTICATED flag unset and maybe change it later |
506 | * depending on the authentication result. | 506 | * depending on the authentication result. |
507 | * | 507 | * |
508 | * @NL80211_CMD_GET_WOWLAN: get Wake-on-Wireless-LAN (WoWLAN) settings. | 508 | * @NL80211_CMD_GET_WOWLAN: get Wake-on-Wireless-LAN (WoWLAN) settings. |
509 | * @NL80211_CMD_SET_WOWLAN: set Wake-on-Wireless-LAN (WoWLAN) settings. | 509 | * @NL80211_CMD_SET_WOWLAN: set Wake-on-Wireless-LAN (WoWLAN) settings. |
510 | * Since wireless is more complex than wired ethernet, it supports | 510 | * Since wireless is more complex than wired ethernet, it supports |
511 | * various triggers. These triggers can be configured through this | 511 | * various triggers. These triggers can be configured through this |
512 | * command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For | 512 | * command with the %NL80211_ATTR_WOWLAN_TRIGGERS attribute. For |
513 | * more background information, see | 513 | * more background information, see |
514 | * http://wireless.kernel.org/en/users/Documentation/WoWLAN. | 514 | * http://wireless.kernel.org/en/users/Documentation/WoWLAN. |
515 | * | 515 | * |
516 | * @NL80211_CMD_SET_REKEY_OFFLOAD: This command is used give the driver | 516 | * @NL80211_CMD_SET_REKEY_OFFLOAD: This command is used give the driver |
517 | * the necessary information for supporting GTK rekey offload. This | 517 | * the necessary information for supporting GTK rekey offload. This |
518 | * feature is typically used during WoWLAN. The configuration data | 518 | * feature is typically used during WoWLAN. The configuration data |
519 | * is contained in %NL80211_ATTR_REKEY_DATA (which is nested and | 519 | * is contained in %NL80211_ATTR_REKEY_DATA (which is nested and |
520 | * contains the data in sub-attributes). After rekeying happened, | 520 | * contains the data in sub-attributes). After rekeying happened, |
521 | * this command may also be sent by the driver as an MLME event to | 521 | * this command may also be sent by the driver as an MLME event to |
522 | * inform userspace of the new replay counter. | 522 | * inform userspace of the new replay counter. |
523 | * | 523 | * |
524 | * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace | 524 | * @NL80211_CMD_PMKSA_CANDIDATE: This is used as an event to inform userspace |
525 | * of PMKSA caching dandidates. | 525 | * of PMKSA caching dandidates. |
526 | * | 526 | * |
527 | * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). | 527 | * @NL80211_CMD_TDLS_OPER: Perform a high-level TDLS command (e.g. link setup). |
528 | * In addition, this can be used as an event to request userspace to take | 528 | * In addition, this can be used as an event to request userspace to take |
529 | * actions on TDLS links (set up a new link or tear down an existing one). | 529 | * actions on TDLS links (set up a new link or tear down an existing one). |
530 | * In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested | 530 | * In such events, %NL80211_ATTR_TDLS_OPERATION indicates the requested |
531 | * operation, %NL80211_ATTR_MAC contains the peer MAC address, and | 531 | * operation, %NL80211_ATTR_MAC contains the peer MAC address, and |
532 | * %NL80211_ATTR_REASON_CODE the reason code to be used (only with | 532 | * %NL80211_ATTR_REASON_CODE the reason code to be used (only with |
533 | * %NL80211_TDLS_TEARDOWN). | 533 | * %NL80211_TDLS_TEARDOWN). |
534 | * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. | 534 | * @NL80211_CMD_TDLS_MGMT: Send a TDLS management frame. |
535 | * | 535 | * |
536 | * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP | 536 | * @NL80211_CMD_UNEXPECTED_FRAME: Used by an application controlling an AP |
537 | * (or GO) interface (i.e. hostapd) to ask for unexpected frames to | 537 | * (or GO) interface (i.e. hostapd) to ask for unexpected frames to |
538 | * implement sending deauth to stations that send unexpected class 3 | 538 | * implement sending deauth to stations that send unexpected class 3 |
539 | * frames. Also used as the event sent by the kernel when such a frame | 539 | * frames. Also used as the event sent by the kernel when such a frame |
540 | * is received. | 540 | * is received. |
541 | * For the event, the %NL80211_ATTR_MAC attribute carries the TA and | 541 | * For the event, the %NL80211_ATTR_MAC attribute carries the TA and |
542 | * other attributes like the interface index are present. | 542 | * other attributes like the interface index are present. |
543 | * If used as the command it must have an interface index and you can | 543 | * If used as the command it must have an interface index and you can |
544 | * only unsubscribe from the event by closing the socket. Subscription | 544 | * only unsubscribe from the event by closing the socket. Subscription |
545 | * is also for %NL80211_CMD_UNEXPECTED_4ADDR_FRAME events. | 545 | * is also for %NL80211_CMD_UNEXPECTED_4ADDR_FRAME events. |
546 | * | 546 | * |
547 | * @NL80211_CMD_UNEXPECTED_4ADDR_FRAME: Sent as an event indicating that the | 547 | * @NL80211_CMD_UNEXPECTED_4ADDR_FRAME: Sent as an event indicating that the |
548 | * associated station identified by %NL80211_ATTR_MAC sent a 4addr frame | 548 | * associated station identified by %NL80211_ATTR_MAC sent a 4addr frame |
549 | * and wasn't already in a 4-addr VLAN. The event will be sent similarly | 549 | * and wasn't already in a 4-addr VLAN. The event will be sent similarly |
550 | * to the %NL80211_CMD_UNEXPECTED_FRAME event, to the same listener. | 550 | * to the %NL80211_CMD_UNEXPECTED_FRAME event, to the same listener. |
551 | * | 551 | * |
552 | * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface | 552 | * @NL80211_CMD_PROBE_CLIENT: Probe an associated station on an AP interface |
553 | * by sending a null data frame to it and reporting when the frame is | 553 | * by sending a null data frame to it and reporting when the frame is |
554 | * acknowleged. This is used to allow timing out inactive clients. Uses | 554 | * acknowleged. This is used to allow timing out inactive clients. Uses |
555 | * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a | 555 | * %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a |
556 | * direct reply with an %NL80211_ATTR_COOKIE that is later used to match | 556 | * direct reply with an %NL80211_ATTR_COOKIE that is later used to match |
557 | * up the event with the request. The event includes the same data and | 557 | * up the event with the request. The event includes the same data and |
558 | * has %NL80211_ATTR_ACK set if the frame was ACKed. | 558 | * has %NL80211_ATTR_ACK set if the frame was ACKed. |
559 | * | 559 | * |
560 | * @NL80211_CMD_REGISTER_BEACONS: Register this socket to receive beacons from | 560 | * @NL80211_CMD_REGISTER_BEACONS: Register this socket to receive beacons from |
561 | * other BSSes when any interfaces are in AP mode. This helps implement | 561 | * other BSSes when any interfaces are in AP mode. This helps implement |
562 | * OLBC handling in hostapd. Beacons are reported in %NL80211_CMD_FRAME | 562 | * OLBC handling in hostapd. Beacons are reported in %NL80211_CMD_FRAME |
563 | * messages. Note that per PHY only one application may register. | 563 | * messages. Note that per PHY only one application may register. |
564 | * | 564 | * |
565 | * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether | 565 | * @NL80211_CMD_SET_NOACK_MAP: sets a bitmap for the individual TIDs whether |
566 | * No Acknowledgement Policy should be applied. | 566 | * No Acknowledgement Policy should be applied. |
567 | * | 567 | * |
568 | * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels | 568 | * @NL80211_CMD_CH_SWITCH_NOTIFY: An AP or GO may decide to switch channels |
569 | * independently of the userspace SME, send this event indicating | 569 | * independently of the userspace SME, send this event indicating |
570 | * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the | 570 | * %NL80211_ATTR_IFINDEX is now on %NL80211_ATTR_WIPHY_FREQ and the |
571 | * attributes determining channel width. | 571 | * attributes determining channel width. |
572 | * | 572 | * |
573 | * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by | 573 | * @NL80211_CMD_START_P2P_DEVICE: Start the given P2P Device, identified by |
574 | * its %NL80211_ATTR_WDEV identifier. It must have been created with | 574 | * its %NL80211_ATTR_WDEV identifier. It must have been created with |
575 | * %NL80211_CMD_NEW_INTERFACE previously. After it has been started, the | 575 | * %NL80211_CMD_NEW_INTERFACE previously. After it has been started, the |
576 | * P2P Device can be used for P2P operations, e.g. remain-on-channel and | 576 | * P2P Device can be used for P2P operations, e.g. remain-on-channel and |
577 | * public action frame TX. | 577 | * public action frame TX. |
578 | * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by | 578 | * @NL80211_CMD_STOP_P2P_DEVICE: Stop the given P2P Device, identified by |
579 | * its %NL80211_ATTR_WDEV identifier. | 579 | * its %NL80211_ATTR_WDEV identifier. |
580 | * | 580 | * |
581 | * @NL80211_CMD_CONN_FAILED: connection request to an AP failed; used to | 581 | * @NL80211_CMD_CONN_FAILED: connection request to an AP failed; used to |
582 | * notify userspace that AP has rejected the connection request from a | 582 | * notify userspace that AP has rejected the connection request from a |
583 | * station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON | 583 | * station, due to particular reason. %NL80211_ATTR_CONN_FAILED_REASON |
584 | * is used for this. | 584 | * is used for this. |
585 | * | 585 | * |
586 | * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames | 586 | * @NL80211_CMD_SET_MCAST_RATE: Change the rate used to send multicast frames |
587 | * for IBSS or MESH vif. | 587 | * for IBSS or MESH vif. |
588 | * | 588 | * |
589 | * @NL80211_CMD_MAX: highest used command number | 589 | * @NL80211_CMD_MAX: highest used command number |
590 | * @__NL80211_CMD_AFTER_LAST: internal use | 590 | * @__NL80211_CMD_AFTER_LAST: internal use |
591 | */ | 591 | */ |
592 | enum nl80211_commands { | 592 | enum nl80211_commands { |
593 | /* don't change the order or add anything between, this is ABI! */ | 593 | /* don't change the order or add anything between, this is ABI! */ |
594 | NL80211_CMD_UNSPEC, | 594 | NL80211_CMD_UNSPEC, |
595 | 595 | ||
596 | NL80211_CMD_GET_WIPHY, /* can dump */ | 596 | NL80211_CMD_GET_WIPHY, /* can dump */ |
597 | NL80211_CMD_SET_WIPHY, | 597 | NL80211_CMD_SET_WIPHY, |
598 | NL80211_CMD_NEW_WIPHY, | 598 | NL80211_CMD_NEW_WIPHY, |
599 | NL80211_CMD_DEL_WIPHY, | 599 | NL80211_CMD_DEL_WIPHY, |
600 | 600 | ||
601 | NL80211_CMD_GET_INTERFACE, /* can dump */ | 601 | NL80211_CMD_GET_INTERFACE, /* can dump */ |
602 | NL80211_CMD_SET_INTERFACE, | 602 | NL80211_CMD_SET_INTERFACE, |
603 | NL80211_CMD_NEW_INTERFACE, | 603 | NL80211_CMD_NEW_INTERFACE, |
604 | NL80211_CMD_DEL_INTERFACE, | 604 | NL80211_CMD_DEL_INTERFACE, |
605 | 605 | ||
606 | NL80211_CMD_GET_KEY, | 606 | NL80211_CMD_GET_KEY, |
607 | NL80211_CMD_SET_KEY, | 607 | NL80211_CMD_SET_KEY, |
608 | NL80211_CMD_NEW_KEY, | 608 | NL80211_CMD_NEW_KEY, |
609 | NL80211_CMD_DEL_KEY, | 609 | NL80211_CMD_DEL_KEY, |
610 | 610 | ||
611 | NL80211_CMD_GET_BEACON, | 611 | NL80211_CMD_GET_BEACON, |
612 | NL80211_CMD_SET_BEACON, | 612 | NL80211_CMD_SET_BEACON, |
613 | NL80211_CMD_START_AP, | 613 | NL80211_CMD_START_AP, |
614 | NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP, | 614 | NL80211_CMD_NEW_BEACON = NL80211_CMD_START_AP, |
615 | NL80211_CMD_STOP_AP, | 615 | NL80211_CMD_STOP_AP, |
616 | NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP, | 616 | NL80211_CMD_DEL_BEACON = NL80211_CMD_STOP_AP, |
617 | 617 | ||
618 | NL80211_CMD_GET_STATION, | 618 | NL80211_CMD_GET_STATION, |
619 | NL80211_CMD_SET_STATION, | 619 | NL80211_CMD_SET_STATION, |
620 | NL80211_CMD_NEW_STATION, | 620 | NL80211_CMD_NEW_STATION, |
621 | NL80211_CMD_DEL_STATION, | 621 | NL80211_CMD_DEL_STATION, |
622 | 622 | ||
623 | NL80211_CMD_GET_MPATH, | 623 | NL80211_CMD_GET_MPATH, |
624 | NL80211_CMD_SET_MPATH, | 624 | NL80211_CMD_SET_MPATH, |
625 | NL80211_CMD_NEW_MPATH, | 625 | NL80211_CMD_NEW_MPATH, |
626 | NL80211_CMD_DEL_MPATH, | 626 | NL80211_CMD_DEL_MPATH, |
627 | 627 | ||
628 | NL80211_CMD_SET_BSS, | 628 | NL80211_CMD_SET_BSS, |
629 | 629 | ||
630 | NL80211_CMD_SET_REG, | 630 | NL80211_CMD_SET_REG, |
631 | NL80211_CMD_REQ_SET_REG, | 631 | NL80211_CMD_REQ_SET_REG, |
632 | 632 | ||
633 | NL80211_CMD_GET_MESH_CONFIG, | 633 | NL80211_CMD_GET_MESH_CONFIG, |
634 | NL80211_CMD_SET_MESH_CONFIG, | 634 | NL80211_CMD_SET_MESH_CONFIG, |
635 | 635 | ||
636 | NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */, | 636 | NL80211_CMD_SET_MGMT_EXTRA_IE /* reserved; not used */, |
637 | 637 | ||
638 | NL80211_CMD_GET_REG, | 638 | NL80211_CMD_GET_REG, |
639 | 639 | ||
640 | NL80211_CMD_GET_SCAN, | 640 | NL80211_CMD_GET_SCAN, |
641 | NL80211_CMD_TRIGGER_SCAN, | 641 | NL80211_CMD_TRIGGER_SCAN, |
642 | NL80211_CMD_NEW_SCAN_RESULTS, | 642 | NL80211_CMD_NEW_SCAN_RESULTS, |
643 | NL80211_CMD_SCAN_ABORTED, | 643 | NL80211_CMD_SCAN_ABORTED, |
644 | 644 | ||
645 | NL80211_CMD_REG_CHANGE, | 645 | NL80211_CMD_REG_CHANGE, |
646 | 646 | ||
647 | NL80211_CMD_AUTHENTICATE, | 647 | NL80211_CMD_AUTHENTICATE, |
648 | NL80211_CMD_ASSOCIATE, | 648 | NL80211_CMD_ASSOCIATE, |
649 | NL80211_CMD_DEAUTHENTICATE, | 649 | NL80211_CMD_DEAUTHENTICATE, |
650 | NL80211_CMD_DISASSOCIATE, | 650 | NL80211_CMD_DISASSOCIATE, |
651 | 651 | ||
652 | NL80211_CMD_MICHAEL_MIC_FAILURE, | 652 | NL80211_CMD_MICHAEL_MIC_FAILURE, |
653 | 653 | ||
654 | NL80211_CMD_REG_BEACON_HINT, | 654 | NL80211_CMD_REG_BEACON_HINT, |
655 | 655 | ||
656 | NL80211_CMD_JOIN_IBSS, | 656 | NL80211_CMD_JOIN_IBSS, |
657 | NL80211_CMD_LEAVE_IBSS, | 657 | NL80211_CMD_LEAVE_IBSS, |
658 | 658 | ||
659 | NL80211_CMD_TESTMODE, | 659 | NL80211_CMD_TESTMODE, |
660 | 660 | ||
661 | NL80211_CMD_CONNECT, | 661 | NL80211_CMD_CONNECT, |
662 | NL80211_CMD_ROAM, | 662 | NL80211_CMD_ROAM, |
663 | NL80211_CMD_DISCONNECT, | 663 | NL80211_CMD_DISCONNECT, |
664 | 664 | ||
665 | NL80211_CMD_SET_WIPHY_NETNS, | 665 | NL80211_CMD_SET_WIPHY_NETNS, |
666 | 666 | ||
667 | NL80211_CMD_GET_SURVEY, | 667 | NL80211_CMD_GET_SURVEY, |
668 | NL80211_CMD_NEW_SURVEY_RESULTS, | 668 | NL80211_CMD_NEW_SURVEY_RESULTS, |
669 | 669 | ||
670 | NL80211_CMD_SET_PMKSA, | 670 | NL80211_CMD_SET_PMKSA, |
671 | NL80211_CMD_DEL_PMKSA, | 671 | NL80211_CMD_DEL_PMKSA, |
672 | NL80211_CMD_FLUSH_PMKSA, | 672 | NL80211_CMD_FLUSH_PMKSA, |
673 | 673 | ||
674 | NL80211_CMD_REMAIN_ON_CHANNEL, | 674 | NL80211_CMD_REMAIN_ON_CHANNEL, |
675 | NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, | 675 | NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, |
676 | 676 | ||
677 | NL80211_CMD_SET_TX_BITRATE_MASK, | 677 | NL80211_CMD_SET_TX_BITRATE_MASK, |
678 | 678 | ||
679 | NL80211_CMD_REGISTER_FRAME, | 679 | NL80211_CMD_REGISTER_FRAME, |
680 | NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME, | 680 | NL80211_CMD_REGISTER_ACTION = NL80211_CMD_REGISTER_FRAME, |
681 | NL80211_CMD_FRAME, | 681 | NL80211_CMD_FRAME, |
682 | NL80211_CMD_ACTION = NL80211_CMD_FRAME, | 682 | NL80211_CMD_ACTION = NL80211_CMD_FRAME, |
683 | NL80211_CMD_FRAME_TX_STATUS, | 683 | NL80211_CMD_FRAME_TX_STATUS, |
684 | NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS, | 684 | NL80211_CMD_ACTION_TX_STATUS = NL80211_CMD_FRAME_TX_STATUS, |
685 | 685 | ||
686 | NL80211_CMD_SET_POWER_SAVE, | 686 | NL80211_CMD_SET_POWER_SAVE, |
687 | NL80211_CMD_GET_POWER_SAVE, | 687 | NL80211_CMD_GET_POWER_SAVE, |
688 | 688 | ||
689 | NL80211_CMD_SET_CQM, | 689 | NL80211_CMD_SET_CQM, |
690 | NL80211_CMD_NOTIFY_CQM, | 690 | NL80211_CMD_NOTIFY_CQM, |
691 | 691 | ||
692 | NL80211_CMD_SET_CHANNEL, | 692 | NL80211_CMD_SET_CHANNEL, |
693 | NL80211_CMD_SET_WDS_PEER, | 693 | NL80211_CMD_SET_WDS_PEER, |
694 | 694 | ||
695 | NL80211_CMD_FRAME_WAIT_CANCEL, | 695 | NL80211_CMD_FRAME_WAIT_CANCEL, |
696 | 696 | ||
697 | NL80211_CMD_JOIN_MESH, | 697 | NL80211_CMD_JOIN_MESH, |
698 | NL80211_CMD_LEAVE_MESH, | 698 | NL80211_CMD_LEAVE_MESH, |
699 | 699 | ||
700 | NL80211_CMD_UNPROT_DEAUTHENTICATE, | 700 | NL80211_CMD_UNPROT_DEAUTHENTICATE, |
701 | NL80211_CMD_UNPROT_DISASSOCIATE, | 701 | NL80211_CMD_UNPROT_DISASSOCIATE, |
702 | 702 | ||
703 | NL80211_CMD_NEW_PEER_CANDIDATE, | 703 | NL80211_CMD_NEW_PEER_CANDIDATE, |
704 | 704 | ||
705 | NL80211_CMD_GET_WOWLAN, | 705 | NL80211_CMD_GET_WOWLAN, |
706 | NL80211_CMD_SET_WOWLAN, | 706 | NL80211_CMD_SET_WOWLAN, |
707 | 707 | ||
708 | NL80211_CMD_START_SCHED_SCAN, | 708 | NL80211_CMD_START_SCHED_SCAN, |
709 | NL80211_CMD_STOP_SCHED_SCAN, | 709 | NL80211_CMD_STOP_SCHED_SCAN, |
710 | NL80211_CMD_SCHED_SCAN_RESULTS, | 710 | NL80211_CMD_SCHED_SCAN_RESULTS, |
711 | NL80211_CMD_SCHED_SCAN_STOPPED, | 711 | NL80211_CMD_SCHED_SCAN_STOPPED, |
712 | 712 | ||
713 | NL80211_CMD_SET_REKEY_OFFLOAD, | 713 | NL80211_CMD_SET_REKEY_OFFLOAD, |
714 | 714 | ||
715 | NL80211_CMD_PMKSA_CANDIDATE, | 715 | NL80211_CMD_PMKSA_CANDIDATE, |
716 | 716 | ||
717 | NL80211_CMD_TDLS_OPER, | 717 | NL80211_CMD_TDLS_OPER, |
718 | NL80211_CMD_TDLS_MGMT, | 718 | NL80211_CMD_TDLS_MGMT, |
719 | 719 | ||
720 | NL80211_CMD_UNEXPECTED_FRAME, | 720 | NL80211_CMD_UNEXPECTED_FRAME, |
721 | 721 | ||
722 | NL80211_CMD_PROBE_CLIENT, | 722 | NL80211_CMD_PROBE_CLIENT, |
723 | 723 | ||
724 | NL80211_CMD_REGISTER_BEACONS, | 724 | NL80211_CMD_REGISTER_BEACONS, |
725 | 725 | ||
726 | NL80211_CMD_UNEXPECTED_4ADDR_FRAME, | 726 | NL80211_CMD_UNEXPECTED_4ADDR_FRAME, |
727 | 727 | ||
728 | NL80211_CMD_SET_NOACK_MAP, | 728 | NL80211_CMD_SET_NOACK_MAP, |
729 | 729 | ||
730 | NL80211_CMD_CH_SWITCH_NOTIFY, | 730 | NL80211_CMD_CH_SWITCH_NOTIFY, |
731 | 731 | ||
732 | NL80211_CMD_START_P2P_DEVICE, | 732 | NL80211_CMD_START_P2P_DEVICE, |
733 | NL80211_CMD_STOP_P2P_DEVICE, | 733 | NL80211_CMD_STOP_P2P_DEVICE, |
734 | 734 | ||
735 | NL80211_CMD_CONN_FAILED, | 735 | NL80211_CMD_CONN_FAILED, |
736 | 736 | ||
737 | NL80211_CMD_SET_MCAST_RATE, | 737 | NL80211_CMD_SET_MCAST_RATE, |
738 | 738 | ||
739 | /* add new commands above here */ | 739 | /* add new commands above here */ |
740 | 740 | ||
741 | /* used to define NL80211_CMD_MAX below */ | 741 | /* used to define NL80211_CMD_MAX below */ |
742 | __NL80211_CMD_AFTER_LAST, | 742 | __NL80211_CMD_AFTER_LAST, |
743 | NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 | 743 | NL80211_CMD_MAX = __NL80211_CMD_AFTER_LAST - 1 |
744 | }; | 744 | }; |
745 | 745 | ||
746 | /* | 746 | /* |
747 | * Allow user space programs to use #ifdef on new commands by defining them | 747 | * Allow user space programs to use #ifdef on new commands by defining them |
748 | * here | 748 | * here |
749 | */ | 749 | */ |
750 | #define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS | 750 | #define NL80211_CMD_SET_BSS NL80211_CMD_SET_BSS |
751 | #define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE | 751 | #define NL80211_CMD_SET_MGMT_EXTRA_IE NL80211_CMD_SET_MGMT_EXTRA_IE |
752 | #define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE | 752 | #define NL80211_CMD_REG_CHANGE NL80211_CMD_REG_CHANGE |
753 | #define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE | 753 | #define NL80211_CMD_AUTHENTICATE NL80211_CMD_AUTHENTICATE |
754 | #define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE | 754 | #define NL80211_CMD_ASSOCIATE NL80211_CMD_ASSOCIATE |
755 | #define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE | 755 | #define NL80211_CMD_DEAUTHENTICATE NL80211_CMD_DEAUTHENTICATE |
756 | #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE | 756 | #define NL80211_CMD_DISASSOCIATE NL80211_CMD_DISASSOCIATE |
757 | #define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT | 757 | #define NL80211_CMD_REG_BEACON_HINT NL80211_CMD_REG_BEACON_HINT |
758 | 758 | ||
759 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS | 759 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS |
760 | 760 | ||
761 | /* source-level API compatibility */ | 761 | /* source-level API compatibility */ |
762 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG | 762 | #define NL80211_CMD_GET_MESH_PARAMS NL80211_CMD_GET_MESH_CONFIG |
763 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG | 763 | #define NL80211_CMD_SET_MESH_PARAMS NL80211_CMD_SET_MESH_CONFIG |
764 | #define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE | 764 | #define NL80211_MESH_SETUP_VENDOR_PATH_SEL_IE NL80211_MESH_SETUP_IE |
765 | 765 | ||
766 | /** | 766 | /** |
767 | * enum nl80211_attrs - nl80211 netlink attributes | 767 | * enum nl80211_attrs - nl80211 netlink attributes |
768 | * | 768 | * |
769 | * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors | 769 | * @NL80211_ATTR_UNSPEC: unspecified attribute to catch errors |
770 | * | 770 | * |
771 | * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf. | 771 | * @NL80211_ATTR_WIPHY: index of wiphy to operate on, cf. |
772 | * /sys/class/ieee80211/<phyname>/index | 772 | * /sys/class/ieee80211/<phyname>/index |
773 | * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) | 773 | * @NL80211_ATTR_WIPHY_NAME: wiphy name (used for renaming) |
774 | * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters | 774 | * @NL80211_ATTR_WIPHY_TXQ_PARAMS: a nested array of TX queue parameters |
775 | * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz, | 775 | * @NL80211_ATTR_WIPHY_FREQ: frequency of the selected channel in MHz, |
776 | * defines the channel together with the (deprecated) | 776 | * defines the channel together with the (deprecated) |
777 | * %NL80211_ATTR_WIPHY_CHANNEL_TYPE attribute or the attributes | 777 | * %NL80211_ATTR_WIPHY_CHANNEL_TYPE attribute or the attributes |
778 | * %NL80211_ATTR_CHANNEL_WIDTH and if needed %NL80211_ATTR_CENTER_FREQ1 | 778 | * %NL80211_ATTR_CHANNEL_WIDTH and if needed %NL80211_ATTR_CENTER_FREQ1 |
779 | * and %NL80211_ATTR_CENTER_FREQ2 | 779 | * and %NL80211_ATTR_CENTER_FREQ2 |
780 | * @NL80211_ATTR_CHANNEL_WIDTH: u32 attribute containing one of the values | 780 | * @NL80211_ATTR_CHANNEL_WIDTH: u32 attribute containing one of the values |
781 | * of &enum nl80211_chan_width, describing the channel width. See the | 781 | * of &enum nl80211_chan_width, describing the channel width. See the |
782 | * documentation of the enum for more information. | 782 | * documentation of the enum for more information. |
783 | * @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the | 783 | * @NL80211_ATTR_CENTER_FREQ1: Center frequency of the first part of the |
784 | * channel, used for anything but 20 MHz bandwidth | 784 | * channel, used for anything but 20 MHz bandwidth |
785 | * @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the | 785 | * @NL80211_ATTR_CENTER_FREQ2: Center frequency of the second part of the |
786 | * channel, used only for 80+80 MHz bandwidth | 786 | * channel, used only for 80+80 MHz bandwidth |
787 | * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ | 787 | * @NL80211_ATTR_WIPHY_CHANNEL_TYPE: included with NL80211_ATTR_WIPHY_FREQ |
788 | * if HT20 or HT40 are to be used (i.e., HT disabled if not included): | 788 | * if HT20 or HT40 are to be used (i.e., HT disabled if not included): |
789 | * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including | 789 | * NL80211_CHAN_NO_HT = HT not allowed (i.e., same as not including |
790 | * this attribute) | 790 | * this attribute) |
791 | * NL80211_CHAN_HT20 = HT20 only | 791 | * NL80211_CHAN_HT20 = HT20 only |
792 | * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel | 792 | * NL80211_CHAN_HT40MINUS = secondary channel is below the primary channel |
793 | * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel | 793 | * NL80211_CHAN_HT40PLUS = secondary channel is above the primary channel |
794 | * This attribute is now deprecated. | 794 | * This attribute is now deprecated. |
795 | * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is | 795 | * @NL80211_ATTR_WIPHY_RETRY_SHORT: TX retry limit for frames whose length is |
796 | * less than or equal to the RTS threshold; allowed range: 1..255; | 796 | * less than or equal to the RTS threshold; allowed range: 1..255; |
797 | * dot11ShortRetryLimit; u8 | 797 | * dot11ShortRetryLimit; u8 |
798 | * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is | 798 | * @NL80211_ATTR_WIPHY_RETRY_LONG: TX retry limit for frames whose length is |
799 | * greater than the RTS threshold; allowed range: 1..255; | 799 | * greater than the RTS threshold; allowed range: 1..255; |
800 | * dot11ShortLongLimit; u8 | 800 | * dot11ShortLongLimit; u8 |
801 | * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum | 801 | * @NL80211_ATTR_WIPHY_FRAG_THRESHOLD: fragmentation threshold, i.e., maximum |
802 | * length in octets for frames; allowed range: 256..8000, disable | 802 | * length in octets for frames; allowed range: 256..8000, disable |
803 | * fragmentation with (u32)-1; dot11FragmentationThreshold; u32 | 803 | * fragmentation with (u32)-1; dot11FragmentationThreshold; u32 |
804 | * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length | 804 | * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length |
805 | * larger than or equal to this use RTS/CTS handshake); allowed range: | 805 | * larger than or equal to this use RTS/CTS handshake); allowed range: |
806 | * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32 | 806 | * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32 |
807 | * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11 | 807 | * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11 |
808 | * section 7.3.2.9; dot11CoverageClass; u8 | 808 | * section 7.3.2.9; dot11CoverageClass; u8 |
809 | * | 809 | * |
810 | * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on | 810 | * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on |
811 | * @NL80211_ATTR_IFNAME: network interface name | 811 | * @NL80211_ATTR_IFNAME: network interface name |
812 | * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype | 812 | * @NL80211_ATTR_IFTYPE: type of virtual interface, see &enum nl80211_iftype |
813 | * | 813 | * |
814 | * @NL80211_ATTR_WDEV: wireless device identifier, used for pseudo-devices | 814 | * @NL80211_ATTR_WDEV: wireless device identifier, used for pseudo-devices |
815 | * that don't have a netdev (u64) | 815 | * that don't have a netdev (u64) |
816 | * | 816 | * |
817 | * @NL80211_ATTR_MAC: MAC address (various uses) | 817 | * @NL80211_ATTR_MAC: MAC address (various uses) |
818 | * | 818 | * |
819 | * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of | 819 | * @NL80211_ATTR_KEY_DATA: (temporal) key data; for TKIP this consists of |
820 | * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC | 820 | * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC |
821 | * keys | 821 | * keys |
822 | * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3) | 822 | * @NL80211_ATTR_KEY_IDX: key ID (u8, 0-3) |
823 | * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 | 823 | * @NL80211_ATTR_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 |
824 | * section 7.3.2.25.1, e.g. 0x000FAC04) | 824 | * section 7.3.2.25.1, e.g. 0x000FAC04) |
825 | * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and | 825 | * @NL80211_ATTR_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and |
826 | * CCMP keys, each six bytes in little endian | 826 | * CCMP keys, each six bytes in little endian |
827 | * @NL80211_ATTR_KEY_DEFAULT: Flag attribute indicating the key is default key | 827 | * @NL80211_ATTR_KEY_DEFAULT: Flag attribute indicating the key is default key |
828 | * @NL80211_ATTR_KEY_DEFAULT_MGMT: Flag attribute indicating the key is the | 828 | * @NL80211_ATTR_KEY_DEFAULT_MGMT: Flag attribute indicating the key is the |
829 | * default management key | 829 | * default management key |
830 | * @NL80211_ATTR_CIPHER_SUITES_PAIRWISE: For crypto settings for connect or | 830 | * @NL80211_ATTR_CIPHER_SUITES_PAIRWISE: For crypto settings for connect or |
831 | * other commands, indicates which pairwise cipher suites are used | 831 | * other commands, indicates which pairwise cipher suites are used |
832 | * @NL80211_ATTR_CIPHER_SUITE_GROUP: For crypto settings for connect or | 832 | * @NL80211_ATTR_CIPHER_SUITE_GROUP: For crypto settings for connect or |
833 | * other commands, indicates which group cipher suite is used | 833 | * other commands, indicates which group cipher suite is used |
834 | * | 834 | * |
835 | * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU | 835 | * @NL80211_ATTR_BEACON_INTERVAL: beacon interval in TU |
836 | * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing | 836 | * @NL80211_ATTR_DTIM_PERIOD: DTIM period for beaconing |
837 | * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE | 837 | * @NL80211_ATTR_BEACON_HEAD: portion of the beacon before the TIM IE |
838 | * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE | 838 | * @NL80211_ATTR_BEACON_TAIL: portion of the beacon after the TIM IE |
839 | * | 839 | * |
840 | * @NL80211_ATTR_STA_AID: Association ID for the station (u16) | 840 | * @NL80211_ATTR_STA_AID: Association ID for the station (u16) |
841 | * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of | 841 | * @NL80211_ATTR_STA_FLAGS: flags, nested element with NLA_FLAG attributes of |
842 | * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2) | 842 | * &enum nl80211_sta_flags (deprecated, use %NL80211_ATTR_STA_FLAGS2) |
843 | * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by | 843 | * @NL80211_ATTR_STA_LISTEN_INTERVAL: listen interval as defined by |
844 | * IEEE 802.11 7.3.1.6 (u16). | 844 | * IEEE 802.11 7.3.1.6 (u16). |
845 | * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported | 845 | * @NL80211_ATTR_STA_SUPPORTED_RATES: supported rates, array of supported |
846 | * rates as defined by IEEE 802.11 7.3.2.2 but without the length | 846 | * rates as defined by IEEE 802.11 7.3.2.2 but without the length |
847 | * restriction (at most %NL80211_MAX_SUPP_RATES). | 847 | * restriction (at most %NL80211_MAX_SUPP_RATES). |
848 | * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station | 848 | * @NL80211_ATTR_STA_VLAN: interface index of VLAN interface to move station |
849 | * to, or the AP interface the station was originally added to to. | 849 | * to, or the AP interface the station was originally added to to. |
850 | * @NL80211_ATTR_STA_INFO: information about a station, part of station info | 850 | * @NL80211_ATTR_STA_INFO: information about a station, part of station info |
851 | * given for %NL80211_CMD_GET_STATION, nested attribute containing | 851 | * given for %NL80211_CMD_GET_STATION, nested attribute containing |
852 | * info as possible, see &enum nl80211_sta_info. | 852 | * info as possible, see &enum nl80211_sta_info. |
853 | * | 853 | * |
854 | * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands, | 854 | * @NL80211_ATTR_WIPHY_BANDS: Information about an operating bands, |
855 | * consisting of a nested array. | 855 | * consisting of a nested array. |
856 | * | 856 | * |
857 | * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). | 857 | * @NL80211_ATTR_MESH_ID: mesh id (1-32 bytes). |
858 | * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link. | 858 | * @NL80211_ATTR_STA_PLINK_ACTION: action to perform on the mesh peer link. |
859 | * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. | 859 | * @NL80211_ATTR_MPATH_NEXT_HOP: MAC address of the next hop for a mesh path. |
860 | * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path | 860 | * @NL80211_ATTR_MPATH_INFO: information about a mesh_path, part of mesh path |
861 | * info given for %NL80211_CMD_GET_MPATH, nested attribute described at | 861 | * info given for %NL80211_CMD_GET_MPATH, nested attribute described at |
862 | * &enum nl80211_mpath_info. | 862 | * &enum nl80211_mpath_info. |
863 | * | 863 | * |
864 | * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of | 864 | * @NL80211_ATTR_MNTR_FLAGS: flags, nested element with NLA_FLAG attributes of |
865 | * &enum nl80211_mntr_flags. | 865 | * &enum nl80211_mntr_flags. |
866 | * | 866 | * |
867 | * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the | 867 | * @NL80211_ATTR_REG_ALPHA2: an ISO-3166-alpha2 country code for which the |
868 | * current regulatory domain should be set to or is already set to. | 868 | * current regulatory domain should be set to or is already set to. |
869 | * For example, 'CR', for Costa Rica. This attribute is used by the kernel | 869 | * For example, 'CR', for Costa Rica. This attribute is used by the kernel |
870 | * to query the CRDA to retrieve one regulatory domain. This attribute can | 870 | * to query the CRDA to retrieve one regulatory domain. This attribute can |
871 | * also be used by userspace to query the kernel for the currently set | 871 | * also be used by userspace to query the kernel for the currently set |
872 | * regulatory domain. We chose an alpha2 as that is also used by the | 872 | * regulatory domain. We chose an alpha2 as that is also used by the |
873 | * IEEE-802.11d country information element to identify a country. | 873 | * IEEE-802.11d country information element to identify a country. |
874 | * Users can also simply ask the wireless core to set regulatory domain | 874 | * Users can also simply ask the wireless core to set regulatory domain |
875 | * to a specific alpha2. | 875 | * to a specific alpha2. |
876 | * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory | 876 | * @NL80211_ATTR_REG_RULES: a nested array of regulatory domain regulatory |
877 | * rules. | 877 | * rules. |
878 | * | 878 | * |
879 | * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1) | 879 | * @NL80211_ATTR_BSS_CTS_PROT: whether CTS protection is enabled (u8, 0 or 1) |
880 | * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled | 880 | * @NL80211_ATTR_BSS_SHORT_PREAMBLE: whether short preamble is enabled |
881 | * (u8, 0 or 1) | 881 | * (u8, 0 or 1) |
882 | * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled | 882 | * @NL80211_ATTR_BSS_SHORT_SLOT_TIME: whether short slot time enabled |
883 | * (u8, 0 or 1) | 883 | * (u8, 0 or 1) |
884 | * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic | 884 | * @NL80211_ATTR_BSS_BASIC_RATES: basic rates, array of basic |
885 | * rates in format defined by IEEE 802.11 7.3.2.2 but without the length | 885 | * rates in format defined by IEEE 802.11 7.3.2.2 but without the length |
886 | * restriction (at most %NL80211_MAX_SUPP_RATES). | 886 | * restriction (at most %NL80211_MAX_SUPP_RATES). |
887 | * | 887 | * |
888 | * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from | 888 | * @NL80211_ATTR_HT_CAPABILITY: HT Capability information element (from |
889 | * association request when used with NL80211_CMD_NEW_STATION) | 889 | * association request when used with NL80211_CMD_NEW_STATION) |
890 | * | 890 | * |
891 | * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all | 891 | * @NL80211_ATTR_SUPPORTED_IFTYPES: nested attribute containing all |
892 | * supported interface types, each a flag attribute with the number | 892 | * supported interface types, each a flag attribute with the number |
893 | * of the interface mode. | 893 | * of the interface mode. |
894 | * | 894 | * |
895 | * @NL80211_ATTR_MGMT_SUBTYPE: Management frame subtype for | 895 | * @NL80211_ATTR_MGMT_SUBTYPE: Management frame subtype for |
896 | * %NL80211_CMD_SET_MGMT_EXTRA_IE. | 896 | * %NL80211_CMD_SET_MGMT_EXTRA_IE. |
897 | * | 897 | * |
898 | * @NL80211_ATTR_IE: Information element(s) data (used, e.g., with | 898 | * @NL80211_ATTR_IE: Information element(s) data (used, e.g., with |
899 | * %NL80211_CMD_SET_MGMT_EXTRA_IE). | 899 | * %NL80211_CMD_SET_MGMT_EXTRA_IE). |
900 | * | 900 | * |
901 | * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with | 901 | * @NL80211_ATTR_MAX_NUM_SCAN_SSIDS: number of SSIDs you can scan with |
902 | * a single scan request, a wiphy attribute. | 902 | * a single scan request, a wiphy attribute. |
903 | * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS: number of SSIDs you can | 903 | * @NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS: number of SSIDs you can |
904 | * scan with a single scheduled scan request, a wiphy attribute. | 904 | * scan with a single scheduled scan request, a wiphy attribute. |
905 | * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements | 905 | * @NL80211_ATTR_MAX_SCAN_IE_LEN: maximum length of information elements |
906 | * that can be added to a scan request | 906 | * that can be added to a scan request |
907 | * @NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: maximum length of information | 907 | * @NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN: maximum length of information |
908 | * elements that can be added to a scheduled scan request | 908 | * elements that can be added to a scheduled scan request |
909 | * @NL80211_ATTR_MAX_MATCH_SETS: maximum number of sets that can be | 909 | * @NL80211_ATTR_MAX_MATCH_SETS: maximum number of sets that can be |
910 | * used with @NL80211_ATTR_SCHED_SCAN_MATCH, a wiphy attribute. | 910 | * used with @NL80211_ATTR_SCHED_SCAN_MATCH, a wiphy attribute. |
911 | * | 911 | * |
912 | * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz) | 912 | * @NL80211_ATTR_SCAN_FREQUENCIES: nested attribute with frequencies (in MHz) |
913 | * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive | 913 | * @NL80211_ATTR_SCAN_SSIDS: nested attribute with SSIDs, leave out for passive |
914 | * scanning and include a zero-length SSID (wildcard) for wildcard scan | 914 | * scanning and include a zero-length SSID (wildcard) for wildcard scan |
915 | * @NL80211_ATTR_BSS: scan result BSS | 915 | * @NL80211_ATTR_BSS: scan result BSS |
916 | * | 916 | * |
917 | * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain | 917 | * @NL80211_ATTR_REG_INITIATOR: indicates who requested the regulatory domain |
918 | * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_* | 918 | * currently in effect. This could be any of the %NL80211_REGDOM_SET_BY_* |
919 | * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently | 919 | * @NL80211_ATTR_REG_TYPE: indicates the type of the regulatory domain currently |
920 | * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*) | 920 | * set. This can be one of the nl80211_reg_type (%NL80211_REGDOM_TYPE_*) |
921 | * | 921 | * |
922 | * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies | 922 | * @NL80211_ATTR_SUPPORTED_COMMANDS: wiphy attribute that specifies |
923 | * an array of command numbers (i.e. a mapping index to command number) | 923 | * an array of command numbers (i.e. a mapping index to command number) |
924 | * that the driver for the given wiphy supports. | 924 | * that the driver for the given wiphy supports. |
925 | * | 925 | * |
926 | * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header | 926 | * @NL80211_ATTR_FRAME: frame data (binary attribute), including frame header |
927 | * and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and | 927 | * and body, but not FCS; used, e.g., with NL80211_CMD_AUTHENTICATE and |
928 | * NL80211_CMD_ASSOCIATE events | 928 | * NL80211_CMD_ASSOCIATE events |
929 | * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets) | 929 | * @NL80211_ATTR_SSID: SSID (binary attribute, 0..32 octets) |
930 | * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type, | 930 | * @NL80211_ATTR_AUTH_TYPE: AuthenticationType, see &enum nl80211_auth_type, |
931 | * represented as a u32 | 931 | * represented as a u32 |
932 | * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and | 932 | * @NL80211_ATTR_REASON_CODE: ReasonCode for %NL80211_CMD_DEAUTHENTICATE and |
933 | * %NL80211_CMD_DISASSOCIATE, u16 | 933 | * %NL80211_CMD_DISASSOCIATE, u16 |
934 | * | 934 | * |
935 | * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as | 935 | * @NL80211_ATTR_KEY_TYPE: Key Type, see &enum nl80211_key_type, represented as |
936 | * a u32 | 936 | * a u32 |
937 | * | 937 | * |
938 | * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change | 938 | * @NL80211_ATTR_FREQ_BEFORE: A channel which has suffered a regulatory change |
939 | * due to considerations from a beacon hint. This attribute reflects | 939 | * due to considerations from a beacon hint. This attribute reflects |
940 | * the state of the channel _before_ the beacon hint processing. This | 940 | * the state of the channel _before_ the beacon hint processing. This |
941 | * attributes consists of a nested attribute containing | 941 | * attributes consists of a nested attribute containing |
942 | * NL80211_FREQUENCY_ATTR_* | 942 | * NL80211_FREQUENCY_ATTR_* |
943 | * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change | 943 | * @NL80211_ATTR_FREQ_AFTER: A channel which has suffered a regulatory change |
944 | * due to considerations from a beacon hint. This attribute reflects | 944 | * due to considerations from a beacon hint. This attribute reflects |
945 | * the state of the channel _after_ the beacon hint processing. This | 945 | * the state of the channel _after_ the beacon hint processing. This |
946 | * attributes consists of a nested attribute containing | 946 | * attributes consists of a nested attribute containing |
947 | * NL80211_FREQUENCY_ATTR_* | 947 | * NL80211_FREQUENCY_ATTR_* |
948 | * | 948 | * |
949 | * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported | 949 | * @NL80211_ATTR_CIPHER_SUITES: a set of u32 values indicating the supported |
950 | * cipher suites | 950 | * cipher suites |
951 | * | 951 | * |
952 | * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look | 952 | * @NL80211_ATTR_FREQ_FIXED: a flag indicating the IBSS should not try to look |
953 | * for other networks on different channels | 953 | * for other networks on different channels |
954 | * | 954 | * |
955 | * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this | 955 | * @NL80211_ATTR_TIMED_OUT: a flag indicating than an operation timed out; this |
956 | * is used, e.g., with %NL80211_CMD_AUTHENTICATE event | 956 | * is used, e.g., with %NL80211_CMD_AUTHENTICATE event |
957 | * | 957 | * |
958 | * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is | 958 | * @NL80211_ATTR_USE_MFP: Whether management frame protection (IEEE 802.11w) is |
959 | * used for the association (&enum nl80211_mfp, represented as a u32); | 959 | * used for the association (&enum nl80211_mfp, represented as a u32); |
960 | * this attribute can be used | 960 | * this attribute can be used |
961 | * with %NL80211_CMD_ASSOCIATE request | 961 | * with %NL80211_CMD_ASSOCIATE request |
962 | * | 962 | * |
963 | * @NL80211_ATTR_STA_FLAGS2: Attribute containing a | 963 | * @NL80211_ATTR_STA_FLAGS2: Attribute containing a |
964 | * &struct nl80211_sta_flag_update. | 964 | * &struct nl80211_sta_flag_update. |
965 | * | 965 | * |
966 | * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls | 966 | * @NL80211_ATTR_CONTROL_PORT: A flag indicating whether user space controls |
967 | * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in | 967 | * IEEE 802.1X port, i.e., sets/clears %NL80211_STA_FLAG_AUTHORIZED, in |
968 | * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE | 968 | * station mode. If the flag is included in %NL80211_CMD_ASSOCIATE |
969 | * request, the driver will assume that the port is unauthorized until | 969 | * request, the driver will assume that the port is unauthorized until |
970 | * authorized by user space. Otherwise, port is marked authorized by | 970 | * authorized by user space. Otherwise, port is marked authorized by |
971 | * default in station mode. | 971 | * default in station mode. |
972 | * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the | 972 | * @NL80211_ATTR_CONTROL_PORT_ETHERTYPE: A 16-bit value indicating the |
973 | * ethertype that will be used for key negotiation. It can be | 973 | * ethertype that will be used for key negotiation. It can be |
974 | * specified with the associate and connect commands. If it is not | 974 | * specified with the associate and connect commands. If it is not |
975 | * specified, the value defaults to 0x888E (PAE, 802.1X). This | 975 | * specified, the value defaults to 0x888E (PAE, 802.1X). This |
976 | * attribute is also used as a flag in the wiphy information to | 976 | * attribute is also used as a flag in the wiphy information to |
977 | * indicate that protocols other than PAE are supported. | 977 | * indicate that protocols other than PAE are supported. |
978 | * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with | 978 | * @NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT: When included along with |
979 | * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom | 979 | * %NL80211_ATTR_CONTROL_PORT_ETHERTYPE, indicates that the custom |
980 | * ethertype frames used for key negotiation must not be encrypted. | 980 | * ethertype frames used for key negotiation must not be encrypted. |
981 | * | 981 | * |
982 | * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. | 982 | * @NL80211_ATTR_TESTDATA: Testmode data blob, passed through to the driver. |
983 | * We recommend using nested, driver-specific attributes within this. | 983 | * We recommend using nested, driver-specific attributes within this. |
984 | * | 984 | * |
985 | * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT | 985 | * @NL80211_ATTR_DISCONNECTED_BY_AP: A flag indicating that the DISCONNECT |
986 | * event was due to the AP disconnecting the station, and not due to | 986 | * event was due to the AP disconnecting the station, and not due to |
987 | * a local disconnect request. | 987 | * a local disconnect request. |
988 | * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT | 988 | * @NL80211_ATTR_STATUS_CODE: StatusCode for the %NL80211_CMD_CONNECT |
989 | * event (u16) | 989 | * event (u16) |
990 | * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating | 990 | * @NL80211_ATTR_PRIVACY: Flag attribute, used with connect(), indicating |
991 | * that protected APs should be used. This is also used with NEW_BEACON to | 991 | * that protected APs should be used. This is also used with NEW_BEACON to |
992 | * indicate that the BSS is to use protection. | 992 | * indicate that the BSS is to use protection. |
993 | * | 993 | * |
994 | * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON | 994 | * @NL80211_ATTR_CIPHERS_PAIRWISE: Used with CONNECT, ASSOCIATE, and NEW_BEACON |
995 | * to indicate which unicast key ciphers will be used with the connection | 995 | * to indicate which unicast key ciphers will be used with the connection |
996 | * (an array of u32). | 996 | * (an array of u32). |
997 | * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to | 997 | * @NL80211_ATTR_CIPHER_GROUP: Used with CONNECT, ASSOCIATE, and NEW_BEACON to |
998 | * indicate which group key cipher will be used with the connection (a | 998 | * indicate which group key cipher will be used with the connection (a |
999 | * u32). | 999 | * u32). |
1000 | * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to | 1000 | * @NL80211_ATTR_WPA_VERSIONS: Used with CONNECT, ASSOCIATE, and NEW_BEACON to |
1001 | * indicate which WPA version(s) the AP we want to associate with is using | 1001 | * indicate which WPA version(s) the AP we want to associate with is using |
1002 | * (a u32 with flags from &enum nl80211_wpa_versions). | 1002 | * (a u32 with flags from &enum nl80211_wpa_versions). |
1003 | * @NL80211_ATTR_AKM_SUITES: Used with CONNECT, ASSOCIATE, and NEW_BEACON to | 1003 | * @NL80211_ATTR_AKM_SUITES: Used with CONNECT, ASSOCIATE, and NEW_BEACON to |
1004 | * indicate which key management algorithm(s) to use (an array of u32). | 1004 | * indicate which key management algorithm(s) to use (an array of u32). |
1005 | * | 1005 | * |
1006 | * @NL80211_ATTR_REQ_IE: (Re)association request information elements as | 1006 | * @NL80211_ATTR_REQ_IE: (Re)association request information elements as |
1007 | * sent out by the card, for ROAM and successful CONNECT events. | 1007 | * sent out by the card, for ROAM and successful CONNECT events. |
1008 | * @NL80211_ATTR_RESP_IE: (Re)association response information elements as | 1008 | * @NL80211_ATTR_RESP_IE: (Re)association response information elements as |
1009 | * sent by peer, for ROAM and successful CONNECT events. | 1009 | * sent by peer, for ROAM and successful CONNECT events. |
1010 | * | 1010 | * |
1011 | * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE | 1011 | * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE |
1012 | * commands to specify using a reassociate frame | 1012 | * commands to specify using a reassociate frame |
1013 | * | 1013 | * |
1014 | * @NL80211_ATTR_KEY: key information in a nested attribute with | 1014 | * @NL80211_ATTR_KEY: key information in a nested attribute with |
1015 | * %NL80211_KEY_* sub-attributes | 1015 | * %NL80211_KEY_* sub-attributes |
1016 | * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect() | 1016 | * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect() |
1017 | * and join_ibss(), key information is in a nested attribute each | 1017 | * and join_ibss(), key information is in a nested attribute each |
1018 | * with %NL80211_KEY_* sub-attributes | 1018 | * with %NL80211_KEY_* sub-attributes |
1019 | * | 1019 | * |
1020 | * @NL80211_ATTR_PID: Process ID of a network namespace. | 1020 | * @NL80211_ATTR_PID: Process ID of a network namespace. |
1021 | * | 1021 | * |
1022 | * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for | 1022 | * @NL80211_ATTR_GENERATION: Used to indicate consistent snapshots for |
1023 | * dumps. This number increases whenever the object list being | 1023 | * dumps. This number increases whenever the object list being |
1024 | * dumped changes, and as such userspace can verify that it has | 1024 | * dumped changes, and as such userspace can verify that it has |
1025 | * obtained a complete and consistent snapshot by verifying that | 1025 | * obtained a complete and consistent snapshot by verifying that |
1026 | * all dump messages contain the same generation number. If it | 1026 | * all dump messages contain the same generation number. If it |
1027 | * changed then the list changed and the dump should be repeated | 1027 | * changed then the list changed and the dump should be repeated |
1028 | * completely from scratch. | 1028 | * completely from scratch. |
1029 | * | 1029 | * |
1030 | * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface | 1030 | * @NL80211_ATTR_4ADDR: Use 4-address frames on a virtual interface |
1031 | * | 1031 | * |
1032 | * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of | 1032 | * @NL80211_ATTR_SURVEY_INFO: survey information about a channel, part of |
1033 | * the survey response for %NL80211_CMD_GET_SURVEY, nested attribute | 1033 | * the survey response for %NL80211_CMD_GET_SURVEY, nested attribute |
1034 | * containing info as possible, see &enum survey_info. | 1034 | * containing info as possible, see &enum survey_info. |
1035 | * | 1035 | * |
1036 | * @NL80211_ATTR_PMKID: PMK material for PMKSA caching. | 1036 | * @NL80211_ATTR_PMKID: PMK material for PMKSA caching. |
1037 | * @NL80211_ATTR_MAX_NUM_PMKIDS: maximum number of PMKIDs a firmware can | 1037 | * @NL80211_ATTR_MAX_NUM_PMKIDS: maximum number of PMKIDs a firmware can |
1038 | * cache, a wiphy attribute. | 1038 | * cache, a wiphy attribute. |
1039 | * | 1039 | * |
1040 | * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32. | 1040 | * @NL80211_ATTR_DURATION: Duration of an operation in milliseconds, u32. |
1041 | * @NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: Device attribute that | 1041 | * @NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION: Device attribute that |
1042 | * specifies the maximum duration that can be requested with the | 1042 | * specifies the maximum duration that can be requested with the |
1043 | * remain-on-channel operation, in milliseconds, u32. | 1043 | * remain-on-channel operation, in milliseconds, u32. |
1044 | * | 1044 | * |
1045 | * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects. | 1045 | * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects. |
1046 | * | 1046 | * |
1047 | * @NL80211_ATTR_TX_RATES: Nested set of attributes | 1047 | * @NL80211_ATTR_TX_RATES: Nested set of attributes |
1048 | * (enum nl80211_tx_rate_attributes) describing TX rates per band. The | 1048 | * (enum nl80211_tx_rate_attributes) describing TX rates per band. The |
1049 | * enum nl80211_band value is used as the index (nla_type() of the nested | 1049 | * enum nl80211_band value is used as the index (nla_type() of the nested |
1050 | * data. If a band is not included, it will be configured to allow all | 1050 | * data. If a band is not included, it will be configured to allow all |
1051 | * rates based on negotiated supported rates information. This attribute | 1051 | * rates based on negotiated supported rates information. This attribute |
1052 | * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. | 1052 | * is used with %NL80211_CMD_SET_TX_BITRATE_MASK. |
1053 | * | 1053 | * |
1054 | * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain | 1054 | * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain |
1055 | * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. | 1055 | * at least one byte, currently used with @NL80211_CMD_REGISTER_FRAME. |
1056 | * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the | 1056 | * @NL80211_ATTR_FRAME_TYPE: A u16 indicating the frame type/subtype for the |
1057 | * @NL80211_CMD_REGISTER_FRAME command. | 1057 | * @NL80211_CMD_REGISTER_FRAME command. |
1058 | * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a | 1058 | * @NL80211_ATTR_TX_FRAME_TYPES: wiphy capability attribute, which is a |
1059 | * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing | 1059 | * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing |
1060 | * information about which frame types can be transmitted with | 1060 | * information about which frame types can be transmitted with |
1061 | * %NL80211_CMD_FRAME. | 1061 | * %NL80211_CMD_FRAME. |
1062 | * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a | 1062 | * @NL80211_ATTR_RX_FRAME_TYPES: wiphy capability attribute, which is a |
1063 | * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing | 1063 | * nested attribute of %NL80211_ATTR_FRAME_TYPE attributes, containing |
1064 | * information about which frame types can be registered for RX. | 1064 | * information about which frame types can be registered for RX. |
1065 | * | 1065 | * |
1066 | * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was | 1066 | * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was |
1067 | * acknowledged by the recipient. | 1067 | * acknowledged by the recipient. |
1068 | * | 1068 | * |
1069 | * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values. | 1069 | * @NL80211_ATTR_PS_STATE: powersave state, using &enum nl80211_ps_state values. |
1070 | * | 1070 | * |
1071 | * @NL80211_ATTR_CQM: connection quality monitor configuration in a | 1071 | * @NL80211_ATTR_CQM: connection quality monitor configuration in a |
1072 | * nested attribute with %NL80211_ATTR_CQM_* sub-attributes. | 1072 | * nested attribute with %NL80211_ATTR_CQM_* sub-attributes. |
1073 | * | 1073 | * |
1074 | * @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command | 1074 | * @NL80211_ATTR_LOCAL_STATE_CHANGE: Flag attribute to indicate that a command |
1075 | * is requesting a local authentication/association state change without | 1075 | * is requesting a local authentication/association state change without |
1076 | * invoking actual management frame exchange. This can be used with | 1076 | * invoking actual management frame exchange. This can be used with |
1077 | * NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE, | 1077 | * NL80211_CMD_AUTHENTICATE, NL80211_CMD_DEAUTHENTICATE, |
1078 | * NL80211_CMD_DISASSOCIATE. | 1078 | * NL80211_CMD_DISASSOCIATE. |
1079 | * | 1079 | * |
1080 | * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations | 1080 | * @NL80211_ATTR_AP_ISOLATE: (AP mode) Do not forward traffic between stations |
1081 | * connected to this BSS. | 1081 | * connected to this BSS. |
1082 | * | 1082 | * |
1083 | * @NL80211_ATTR_WIPHY_TX_POWER_SETTING: Transmit power setting type. See | 1083 | * @NL80211_ATTR_WIPHY_TX_POWER_SETTING: Transmit power setting type. See |
1084 | * &enum nl80211_tx_power_setting for possible values. | 1084 | * &enum nl80211_tx_power_setting for possible values. |
1085 | * @NL80211_ATTR_WIPHY_TX_POWER_LEVEL: Transmit power level in signed mBm units. | 1085 | * @NL80211_ATTR_WIPHY_TX_POWER_LEVEL: Transmit power level in signed mBm units. |
1086 | * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING | 1086 | * This is used in association with @NL80211_ATTR_WIPHY_TX_POWER_SETTING |
1087 | * for non-automatic settings. | 1087 | * for non-automatic settings. |
1088 | * | 1088 | * |
1089 | * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly | 1089 | * @NL80211_ATTR_SUPPORT_IBSS_RSN: The device supports IBSS RSN, which mostly |
1090 | * means support for per-station GTKs. | 1090 | * means support for per-station GTKs. |
1091 | * | 1091 | * |
1092 | * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting. | 1092 | * @NL80211_ATTR_WIPHY_ANTENNA_TX: Bitmap of allowed antennas for transmitting. |
1093 | * This can be used to mask out antennas which are not attached or should | 1093 | * This can be used to mask out antennas which are not attached or should |
1094 | * not be used for transmitting. If an antenna is not selected in this | 1094 | * not be used for transmitting. If an antenna is not selected in this |
1095 | * bitmap the hardware is not allowed to transmit on this antenna. | 1095 | * bitmap the hardware is not allowed to transmit on this antenna. |
1096 | * | 1096 | * |
1097 | * Each bit represents one antenna, starting with antenna 1 at the first | 1097 | * Each bit represents one antenna, starting with antenna 1 at the first |
1098 | * bit. Depending on which antennas are selected in the bitmap, 802.11n | 1098 | * bit. Depending on which antennas are selected in the bitmap, 802.11n |
1099 | * drivers can derive which chainmasks to use (if all antennas belonging to | 1099 | * drivers can derive which chainmasks to use (if all antennas belonging to |
1100 | * a particular chain are disabled this chain should be disabled) and if | 1100 | * a particular chain are disabled this chain should be disabled) and if |
1101 | * a chain has diversity antennas wether diversity should be used or not. | 1101 | * a chain has diversity antennas wether diversity should be used or not. |
1102 | * HT capabilities (STBC, TX Beamforming, Antenna selection) can be | 1102 | * HT capabilities (STBC, TX Beamforming, Antenna selection) can be |
1103 | * derived from the available chains after applying the antenna mask. | 1103 | * derived from the available chains after applying the antenna mask. |
1104 | * Non-802.11n drivers can derive wether to use diversity or not. | 1104 | * Non-802.11n drivers can derive wether to use diversity or not. |
1105 | * Drivers may reject configurations or RX/TX mask combinations they cannot | 1105 | * Drivers may reject configurations or RX/TX mask combinations they cannot |
1106 | * support by returning -EINVAL. | 1106 | * support by returning -EINVAL. |
1107 | * | 1107 | * |
1108 | * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving. | 1108 | * @NL80211_ATTR_WIPHY_ANTENNA_RX: Bitmap of allowed antennas for receiving. |
1109 | * This can be used to mask out antennas which are not attached or should | 1109 | * This can be used to mask out antennas which are not attached or should |
1110 | * not be used for receiving. If an antenna is not selected in this bitmap | 1110 | * not be used for receiving. If an antenna is not selected in this bitmap |
1111 | * the hardware should not be configured to receive on this antenna. | 1111 | * the hardware should not be configured to receive on this antenna. |
1112 | * For a more detailed description see @NL80211_ATTR_WIPHY_ANTENNA_TX. | 1112 | * For a more detailed description see @NL80211_ATTR_WIPHY_ANTENNA_TX. |
1113 | * | 1113 | * |
1114 | * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available | 1114 | * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX: Bitmap of antennas which are available |
1115 | * for configuration as TX antennas via the above parameters. | 1115 | * for configuration as TX antennas via the above parameters. |
1116 | * | 1116 | * |
1117 | * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available | 1117 | * @NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX: Bitmap of antennas which are available |
1118 | * for configuration as RX antennas via the above parameters. | 1118 | * for configuration as RX antennas via the above parameters. |
1119 | * | 1119 | * |
1120 | * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS | 1120 | * @NL80211_ATTR_MCAST_RATE: Multicast tx rate (in 100 kbps) for IBSS |
1121 | * | 1121 | * |
1122 | * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be | 1122 | * @NL80211_ATTR_OFFCHANNEL_TX_OK: For management frame TX, the frame may be |
1123 | * transmitted on another channel when the channel given doesn't match | 1123 | * transmitted on another channel when the channel given doesn't match |
1124 | * the current channel. If the current channel doesn't match and this | 1124 | * the current channel. If the current channel doesn't match and this |
1125 | * flag isn't set, the frame will be rejected. This is also used as an | 1125 | * flag isn't set, the frame will be rejected. This is also used as an |
1126 | * nl80211 capability flag. | 1126 | * nl80211 capability flag. |
1127 | * | 1127 | * |
1128 | * @NL80211_ATTR_BSS_HT_OPMODE: HT operation mode (u16) | 1128 | * @NL80211_ATTR_BSS_HT_OPMODE: HT operation mode (u16) |
1129 | * | 1129 | * |
1130 | * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags | 1130 | * @NL80211_ATTR_KEY_DEFAULT_TYPES: A nested attribute containing flags |
1131 | * attributes, specifying what a key should be set as default as. | 1131 | * attributes, specifying what a key should be set as default as. |
1132 | * See &enum nl80211_key_default_types. | 1132 | * See &enum nl80211_key_default_types. |
1133 | * | 1133 | * |
1134 | * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be | 1134 | * @NL80211_ATTR_MESH_SETUP: Optional mesh setup parameters. These cannot be |
1135 | * changed once the mesh is active. | 1135 | * changed once the mesh is active. |
1136 | * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute | 1136 | * @NL80211_ATTR_MESH_CONFIG: Mesh configuration parameters, a nested attribute |
1137 | * containing attributes from &enum nl80211_meshconf_params. | 1137 | * containing attributes from &enum nl80211_meshconf_params. |
1138 | * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver | 1138 | * @NL80211_ATTR_SUPPORT_MESH_AUTH: Currently, this means the underlying driver |
1139 | * allows auth frames in a mesh to be passed to userspace for processing via | 1139 | * allows auth frames in a mesh to be passed to userspace for processing via |
1140 | * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. | 1140 | * the @NL80211_MESH_SETUP_USERSPACE_AUTH flag. |
1141 | * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as | 1141 | * @NL80211_ATTR_STA_PLINK_STATE: The state of a mesh peer link as |
1142 | * defined in &enum nl80211_plink_state. Used when userspace is | 1142 | * defined in &enum nl80211_plink_state. Used when userspace is |
1143 | * driving the peer link management state machine. | 1143 | * driving the peer link management state machine. |
1144 | * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. | 1144 | * @NL80211_MESH_SETUP_USERSPACE_AMPE must be enabled. |
1145 | * | 1145 | * |
1146 | * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy | 1146 | * @NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED: indicates, as part of the wiphy |
1147 | * capabilities, the supported WoWLAN triggers | 1147 | * capabilities, the supported WoWLAN triggers |
1148 | * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to | 1148 | * @NL80211_ATTR_WOWLAN_TRIGGERS: used by %NL80211_CMD_SET_WOWLAN to |
1149 | * indicate which WoW triggers should be enabled. This is also | 1149 | * indicate which WoW triggers should be enabled. This is also |
1150 | * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN | 1150 | * used by %NL80211_CMD_GET_WOWLAN to get the currently enabled WoWLAN |
1151 | * triggers. | 1151 | * triggers. |
1152 | * | 1152 | * |
1153 | * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan | 1153 | * @NL80211_ATTR_SCHED_SCAN_INTERVAL: Interval between scheduled scan |
1154 | * cycles, in msecs. | 1154 | * cycles, in msecs. |
1155 | * | 1155 | * |
1156 | * @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more | 1156 | * @NL80211_ATTR_SCHED_SCAN_MATCH: Nested attribute with one or more |
1157 | * sets of attributes to match during scheduled scans. Only BSSs | 1157 | * sets of attributes to match during scheduled scans. Only BSSs |
1158 | * that match any of the sets will be reported. These are | 1158 | * that match any of the sets will be reported. These are |
1159 | * pass-thru filter rules. | 1159 | * pass-thru filter rules. |
1160 | * For a match to succeed, the BSS must match all attributes of a | 1160 | * For a match to succeed, the BSS must match all attributes of a |
1161 | * set. Since not every hardware supports matching all types of | 1161 | * set. Since not every hardware supports matching all types of |
1162 | * attributes, there is no guarantee that the reported BSSs are | 1162 | * attributes, there is no guarantee that the reported BSSs are |
1163 | * fully complying with the match sets and userspace needs to be | 1163 | * fully complying with the match sets and userspace needs to be |
1164 | * able to ignore them by itself. | 1164 | * able to ignore them by itself. |
1165 | * Thus, the implementation is somewhat hardware-dependent, but | 1165 | * Thus, the implementation is somewhat hardware-dependent, but |
1166 | * this is only an optimization and the userspace application | 1166 | * this is only an optimization and the userspace application |
1167 | * needs to handle all the non-filtered results anyway. | 1167 | * needs to handle all the non-filtered results anyway. |
1168 | * If the match attributes don't make sense when combined with | 1168 | * If the match attributes don't make sense when combined with |
1169 | * the values passed in @NL80211_ATTR_SCAN_SSIDS (eg. if an SSID | 1169 | * the values passed in @NL80211_ATTR_SCAN_SSIDS (eg. if an SSID |
1170 | * is included in the probe request, but the match attributes | 1170 | * is included in the probe request, but the match attributes |
1171 | * will never let it go through), -EINVAL may be returned. | 1171 | * will never let it go through), -EINVAL may be returned. |
1172 | * If ommited, no filtering is done. | 1172 | * If ommited, no filtering is done. |
1173 | * | 1173 | * |
1174 | * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported | 1174 | * @NL80211_ATTR_INTERFACE_COMBINATIONS: Nested attribute listing the supported |
1175 | * interface combinations. In each nested item, it contains attributes | 1175 | * interface combinations. In each nested item, it contains attributes |
1176 | * defined in &enum nl80211_if_combination_attrs. | 1176 | * defined in &enum nl80211_if_combination_attrs. |
1177 | * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like | 1177 | * @NL80211_ATTR_SOFTWARE_IFTYPES: Nested attribute (just like |
1178 | * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that | 1178 | * %NL80211_ATTR_SUPPORTED_IFTYPES) containing the interface types that |
1179 | * are managed in software: interfaces of these types aren't subject to | 1179 | * are managed in software: interfaces of these types aren't subject to |
1180 | * any restrictions in their number or combinations. | 1180 | * any restrictions in their number or combinations. |
1181 | * | 1181 | * |
1182 | * @NL80211_ATTR_REKEY_DATA: nested attribute containing the information | 1182 | * @NL80211_ATTR_REKEY_DATA: nested attribute containing the information |
1183 | * necessary for GTK rekeying in the device, see &enum nl80211_rekey_data. | 1183 | * necessary for GTK rekeying in the device, see &enum nl80211_rekey_data. |
1184 | * | 1184 | * |
1185 | * @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan, | 1185 | * @NL80211_ATTR_SCAN_SUPP_RATES: rates per to be advertised as supported in scan, |
1186 | * nested array attribute containing an entry for each band, with the entry | 1186 | * nested array attribute containing an entry for each band, with the entry |
1187 | * being a list of supported rates as defined by IEEE 802.11 7.3.2.2 but | 1187 | * being a list of supported rates as defined by IEEE 802.11 7.3.2.2 but |
1188 | * without the length restriction (at most %NL80211_MAX_SUPP_RATES). | 1188 | * without the length restriction (at most %NL80211_MAX_SUPP_RATES). |
1189 | * | 1189 | * |
1190 | * @NL80211_ATTR_HIDDEN_SSID: indicates whether SSID is to be hidden from Beacon | 1190 | * @NL80211_ATTR_HIDDEN_SSID: indicates whether SSID is to be hidden from Beacon |
1191 | * and Probe Response (when response to wildcard Probe Request); see | 1191 | * and Probe Response (when response to wildcard Probe Request); see |
1192 | * &enum nl80211_hidden_ssid, represented as a u32 | 1192 | * &enum nl80211_hidden_ssid, represented as a u32 |
1193 | * | 1193 | * |
1194 | * @NL80211_ATTR_IE_PROBE_RESP: Information element(s) for Probe Response frame. | 1194 | * @NL80211_ATTR_IE_PROBE_RESP: Information element(s) for Probe Response frame. |
1195 | * This is used with %NL80211_CMD_NEW_BEACON and %NL80211_CMD_SET_BEACON to | 1195 | * This is used with %NL80211_CMD_NEW_BEACON and %NL80211_CMD_SET_BEACON to |
1196 | * provide extra IEs (e.g., WPS/P2P IE) into Probe Response frames when the | 1196 | * provide extra IEs (e.g., WPS/P2P IE) into Probe Response frames when the |
1197 | * driver (or firmware) replies to Probe Request frames. | 1197 | * driver (or firmware) replies to Probe Request frames. |
1198 | * @NL80211_ATTR_IE_ASSOC_RESP: Information element(s) for (Re)Association | 1198 | * @NL80211_ATTR_IE_ASSOC_RESP: Information element(s) for (Re)Association |
1199 | * Response frames. This is used with %NL80211_CMD_NEW_BEACON and | 1199 | * Response frames. This is used with %NL80211_CMD_NEW_BEACON and |
1200 | * %NL80211_CMD_SET_BEACON to provide extra IEs (e.g., WPS/P2P IE) into | 1200 | * %NL80211_CMD_SET_BEACON to provide extra IEs (e.g., WPS/P2P IE) into |
1201 | * (Re)Association Response frames when the driver (or firmware) replies to | 1201 | * (Re)Association Response frames when the driver (or firmware) replies to |
1202 | * (Re)Association Request frames. | 1202 | * (Re)Association Request frames. |
1203 | * | 1203 | * |
1204 | * @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration | 1204 | * @NL80211_ATTR_STA_WME: Nested attribute containing the wme configuration |
1205 | * of the station, see &enum nl80211_sta_wme_attr. | 1205 | * of the station, see &enum nl80211_sta_wme_attr. |
1206 | * @NL80211_ATTR_SUPPORT_AP_UAPSD: the device supports uapsd when working | 1206 | * @NL80211_ATTR_SUPPORT_AP_UAPSD: the device supports uapsd when working |
1207 | * as AP. | 1207 | * as AP. |
1208 | * | 1208 | * |
1209 | * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of | 1209 | * @NL80211_ATTR_ROAM_SUPPORT: Indicates whether the firmware is capable of |
1210 | * roaming to another AP in the same ESS if the signal lever is low. | 1210 | * roaming to another AP in the same ESS if the signal lever is low. |
1211 | * | 1211 | * |
1212 | * @NL80211_ATTR_PMKSA_CANDIDATE: Nested attribute containing the PMKSA caching | 1212 | * @NL80211_ATTR_PMKSA_CANDIDATE: Nested attribute containing the PMKSA caching |
1213 | * candidate information, see &enum nl80211_pmksa_candidate_attr. | 1213 | * candidate information, see &enum nl80211_pmksa_candidate_attr. |
1214 | * | 1214 | * |
1215 | * @NL80211_ATTR_TX_NO_CCK_RATE: Indicates whether to use CCK rate or not | 1215 | * @NL80211_ATTR_TX_NO_CCK_RATE: Indicates whether to use CCK rate or not |
1216 | * for management frames transmission. In order to avoid p2p probe/action | 1216 | * for management frames transmission. In order to avoid p2p probe/action |
1217 | * frames are being transmitted at CCK rate in 2GHz band, the user space | 1217 | * frames are being transmitted at CCK rate in 2GHz band, the user space |
1218 | * applications use this attribute. | 1218 | * applications use this attribute. |
1219 | * This attribute is used with %NL80211_CMD_TRIGGER_SCAN and | 1219 | * This attribute is used with %NL80211_CMD_TRIGGER_SCAN and |
1220 | * %NL80211_CMD_FRAME commands. | 1220 | * %NL80211_CMD_FRAME commands. |
1221 | * | 1221 | * |
1222 | * @NL80211_ATTR_TDLS_ACTION: Low level TDLS action code (e.g. link setup | 1222 | * @NL80211_ATTR_TDLS_ACTION: Low level TDLS action code (e.g. link setup |
1223 | * request, link setup confirm, link teardown, etc.). Values are | 1223 | * request, link setup confirm, link teardown, etc.). Values are |
1224 | * described in the TDLS (802.11z) specification. | 1224 | * described in the TDLS (802.11z) specification. |
1225 | * @NL80211_ATTR_TDLS_DIALOG_TOKEN: Non-zero token for uniquely identifying a | 1225 | * @NL80211_ATTR_TDLS_DIALOG_TOKEN: Non-zero token for uniquely identifying a |
1226 | * TDLS conversation between two devices. | 1226 | * TDLS conversation between two devices. |
1227 | * @NL80211_ATTR_TDLS_OPERATION: High level TDLS operation; see | 1227 | * @NL80211_ATTR_TDLS_OPERATION: High level TDLS operation; see |
1228 | * &enum nl80211_tdls_operation, represented as a u8. | 1228 | * &enum nl80211_tdls_operation, represented as a u8. |
1229 | * @NL80211_ATTR_TDLS_SUPPORT: A flag indicating the device can operate | 1229 | * @NL80211_ATTR_TDLS_SUPPORT: A flag indicating the device can operate |
1230 | * as a TDLS peer sta. | 1230 | * as a TDLS peer sta. |
1231 | * @NL80211_ATTR_TDLS_EXTERNAL_SETUP: The TDLS discovery/setup and teardown | 1231 | * @NL80211_ATTR_TDLS_EXTERNAL_SETUP: The TDLS discovery/setup and teardown |
1232 | * procedures should be performed by sending TDLS packets via | 1232 | * procedures should be performed by sending TDLS packets via |
1233 | * %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be | 1233 | * %NL80211_CMD_TDLS_MGMT. Otherwise %NL80211_CMD_TDLS_OPER should be |
1234 | * used for asking the driver to perform a TDLS operation. | 1234 | * used for asking the driver to perform a TDLS operation. |
1235 | * | 1235 | * |
1236 | * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices | 1236 | * @NL80211_ATTR_DEVICE_AP_SME: This u32 attribute may be listed for devices |
1237 | * that have AP support to indicate that they have the AP SME integrated | 1237 | * that have AP support to indicate that they have the AP SME integrated |
1238 | * with support for the features listed in this attribute, see | 1238 | * with support for the features listed in this attribute, see |
1239 | * &enum nl80211_ap_sme_features. | 1239 | * &enum nl80211_ap_sme_features. |
1240 | * | 1240 | * |
1241 | * @NL80211_ATTR_DONT_WAIT_FOR_ACK: Used with %NL80211_CMD_FRAME, this tells | 1241 | * @NL80211_ATTR_DONT_WAIT_FOR_ACK: Used with %NL80211_CMD_FRAME, this tells |
1242 | * the driver to not wait for an acknowledgement. Note that due to this, | 1242 | * the driver to not wait for an acknowledgement. Note that due to this, |
1243 | * it will also not give a status callback nor return a cookie. This is | 1243 | * it will also not give a status callback nor return a cookie. This is |
1244 | * mostly useful for probe responses to save airtime. | 1244 | * mostly useful for probe responses to save airtime. |
1245 | * | 1245 | * |
1246 | * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from | 1246 | * @NL80211_ATTR_FEATURE_FLAGS: This u32 attribute contains flags from |
1247 | * &enum nl80211_feature_flags and is advertised in wiphy information. | 1247 | * &enum nl80211_feature_flags and is advertised in wiphy information. |
1248 | * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe | 1248 | * @NL80211_ATTR_PROBE_RESP_OFFLOAD: Indicates that the HW responds to probe |
1249 | * requests while operating in AP-mode. | 1249 | * requests while operating in AP-mode. |
1250 | * This attribute holds a bitmap of the supported protocols for | 1250 | * This attribute holds a bitmap of the supported protocols for |
1251 | * offloading (see &enum nl80211_probe_resp_offload_support_attr). | 1251 | * offloading (see &enum nl80211_probe_resp_offload_support_attr). |
1252 | * | 1252 | * |
1253 | * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire | 1253 | * @NL80211_ATTR_PROBE_RESP: Probe Response template data. Contains the entire |
1254 | * probe-response frame. The DA field in the 802.11 header is zero-ed out, | 1254 | * probe-response frame. The DA field in the 802.11 header is zero-ed out, |
1255 | * to be filled by the FW. | 1255 | * to be filled by the FW. |
1256 | * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable | 1256 | * @NL80211_ATTR_DISABLE_HT: Force HT capable interfaces to disable |
1257 | * this feature. Currently, only supported in mac80211 drivers. | 1257 | * this feature. Currently, only supported in mac80211 drivers. |
1258 | * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the | 1258 | * @NL80211_ATTR_HT_CAPABILITY_MASK: Specify which bits of the |
1259 | * ATTR_HT_CAPABILITY to which attention should be paid. | 1259 | * ATTR_HT_CAPABILITY to which attention should be paid. |
1260 | * Currently, only mac80211 NICs support this feature. | 1260 | * Currently, only mac80211 NICs support this feature. |
1261 | * The values that may be configured are: | 1261 | * The values that may be configured are: |
1262 | * MCS rates, MAX-AMSDU, HT-20-40 and HT_CAP_SGI_40 | 1262 | * MCS rates, MAX-AMSDU, HT-20-40 and HT_CAP_SGI_40 |
1263 | * AMPDU density and AMPDU factor. | 1263 | * AMPDU density and AMPDU factor. |
1264 | * All values are treated as suggestions and may be ignored | 1264 | * All values are treated as suggestions and may be ignored |
1265 | * by the driver as required. The actual values may be seen in | 1265 | * by the driver as required. The actual values may be seen in |
1266 | * the station debugfs ht_caps file. | 1266 | * the station debugfs ht_caps file. |
1267 | * | 1267 | * |
1268 | * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country | 1268 | * @NL80211_ATTR_DFS_REGION: region for regulatory rules which this country |
1269 | * abides to when initiating radiation on DFS channels. A country maps | 1269 | * abides to when initiating radiation on DFS channels. A country maps |
1270 | * to one DFS region. | 1270 | * to one DFS region. |
1271 | * | 1271 | * |
1272 | * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of | 1272 | * @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of |
1273 | * up to 16 TIDs. | 1273 | * up to 16 TIDs. |
1274 | * | 1274 | * |
1275 | * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be | 1275 | * @NL80211_ATTR_INACTIVITY_TIMEOUT: timeout value in seconds, this can be |
1276 | * used by the drivers which has MLME in firmware and does not have support | 1276 | * used by the drivers which has MLME in firmware and does not have support |
1277 | * to report per station tx/rx activity to free up the staion entry from | 1277 | * to report per station tx/rx activity to free up the staion entry from |
1278 | * the list. This needs to be used when the driver advertises the | 1278 | * the list. This needs to be used when the driver advertises the |
1279 | * capability to timeout the stations. | 1279 | * capability to timeout the stations. |
1280 | * | 1280 | * |
1281 | * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int); | 1281 | * @NL80211_ATTR_RX_SIGNAL_DBM: signal strength in dBm (as a 32-bit int); |
1282 | * this attribute is (depending on the driver capabilities) added to | 1282 | * this attribute is (depending on the driver capabilities) added to |
1283 | * received frames indicated with %NL80211_CMD_FRAME. | 1283 | * received frames indicated with %NL80211_CMD_FRAME. |
1284 | * | 1284 | * |
1285 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds | 1285 | * @NL80211_ATTR_BG_SCAN_PERIOD: Background scan period in seconds |
1286 | * or 0 to disable background scan. | 1286 | * or 0 to disable background scan. |
1287 | * | 1287 | * |
1288 | * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from | 1288 | * @NL80211_ATTR_USER_REG_HINT_TYPE: type of regulatory hint passed from |
1289 | * userspace. If unset it is assumed the hint comes directly from | 1289 | * userspace. If unset it is assumed the hint comes directly from |
1290 | * a user. If set code could specify exactly what type of source | 1290 | * a user. If set code could specify exactly what type of source |
1291 | * was used to provide the hint. For the different types of | 1291 | * was used to provide the hint. For the different types of |
1292 | * allowed user regulatory hints see nl80211_user_reg_hint_type. | 1292 | * allowed user regulatory hints see nl80211_user_reg_hint_type. |
1293 | * | 1293 | * |
1294 | * @NL80211_ATTR_CONN_FAILED_REASON: The reason for which AP has rejected | 1294 | * @NL80211_ATTR_CONN_FAILED_REASON: The reason for which AP has rejected |
1295 | * the connection request from a station. nl80211_connect_failed_reason | 1295 | * the connection request from a station. nl80211_connect_failed_reason |
1296 | * enum has different reasons of connection failure. | 1296 | * enum has different reasons of connection failure. |
1297 | * | 1297 | * |
1298 | * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts | 1298 | * @NL80211_ATTR_SAE_DATA: SAE elements in Authentication frames. This starts |
1299 | * with the Authentication transaction sequence number field. | 1299 | * with the Authentication transaction sequence number field. |
1300 | * | 1300 | * |
1301 | * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from | 1301 | * @NL80211_ATTR_VHT_CAPABILITY: VHT Capability information element (from |
1302 | * association request when used with NL80211_CMD_NEW_STATION) | 1302 | * association request when used with NL80211_CMD_NEW_STATION) |
1303 | * | 1303 | * |
1304 | * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32) | 1304 | * @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32) |
1305 | * | 1305 | * |
1306 | * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with | 1306 | * @NL80211_ATTR_P2P_CTWINDOW: P2P GO Client Traffic Window (u8), used with |
1307 | * the START_AP and SET_BSS commands | 1307 | * the START_AP and SET_BSS commands |
1308 | * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the | 1308 | * @NL80211_ATTR_P2P_OPPPS: P2P GO opportunistic PS (u8), used with the |
1309 | * START_AP and SET_BSS commands. This can have the values 0 or 1; | 1309 | * START_AP and SET_BSS commands. This can have the values 0 or 1; |
1310 | * if not given in START_AP 0 is assumed, if not given in SET_BSS | 1310 | * if not given in START_AP 0 is assumed, if not given in SET_BSS |
1311 | * no change is made. | 1311 | * no change is made. |
1312 | * | 1312 | * |
1313 | * @NL80211_ATTR_LOCAL_MESH_POWER_MODE: local mesh STA link-specific power mode | ||
1314 | * defined in &enum nl80211_mesh_power_mode. | ||
1315 | * | ||
1313 | * @NL80211_ATTR_MAX: highest attribute number currently defined | 1316 | * @NL80211_ATTR_MAX: highest attribute number currently defined |
1314 | * @__NL80211_ATTR_AFTER_LAST: internal use | 1317 | * @__NL80211_ATTR_AFTER_LAST: internal use |
1315 | */ | 1318 | */ |
1316 | enum nl80211_attrs { | 1319 | enum nl80211_attrs { |
1317 | /* don't change the order or add anything between, this is ABI! */ | 1320 | /* don't change the order or add anything between, this is ABI! */ |
1318 | NL80211_ATTR_UNSPEC, | 1321 | NL80211_ATTR_UNSPEC, |
1319 | 1322 | ||
1320 | NL80211_ATTR_WIPHY, | 1323 | NL80211_ATTR_WIPHY, |
1321 | NL80211_ATTR_WIPHY_NAME, | 1324 | NL80211_ATTR_WIPHY_NAME, |
1322 | 1325 | ||
1323 | NL80211_ATTR_IFINDEX, | 1326 | NL80211_ATTR_IFINDEX, |
1324 | NL80211_ATTR_IFNAME, | 1327 | NL80211_ATTR_IFNAME, |
1325 | NL80211_ATTR_IFTYPE, | 1328 | NL80211_ATTR_IFTYPE, |
1326 | 1329 | ||
1327 | NL80211_ATTR_MAC, | 1330 | NL80211_ATTR_MAC, |
1328 | 1331 | ||
1329 | NL80211_ATTR_KEY_DATA, | 1332 | NL80211_ATTR_KEY_DATA, |
1330 | NL80211_ATTR_KEY_IDX, | 1333 | NL80211_ATTR_KEY_IDX, |
1331 | NL80211_ATTR_KEY_CIPHER, | 1334 | NL80211_ATTR_KEY_CIPHER, |
1332 | NL80211_ATTR_KEY_SEQ, | 1335 | NL80211_ATTR_KEY_SEQ, |
1333 | NL80211_ATTR_KEY_DEFAULT, | 1336 | NL80211_ATTR_KEY_DEFAULT, |
1334 | 1337 | ||
1335 | NL80211_ATTR_BEACON_INTERVAL, | 1338 | NL80211_ATTR_BEACON_INTERVAL, |
1336 | NL80211_ATTR_DTIM_PERIOD, | 1339 | NL80211_ATTR_DTIM_PERIOD, |
1337 | NL80211_ATTR_BEACON_HEAD, | 1340 | NL80211_ATTR_BEACON_HEAD, |
1338 | NL80211_ATTR_BEACON_TAIL, | 1341 | NL80211_ATTR_BEACON_TAIL, |
1339 | 1342 | ||
1340 | NL80211_ATTR_STA_AID, | 1343 | NL80211_ATTR_STA_AID, |
1341 | NL80211_ATTR_STA_FLAGS, | 1344 | NL80211_ATTR_STA_FLAGS, |
1342 | NL80211_ATTR_STA_LISTEN_INTERVAL, | 1345 | NL80211_ATTR_STA_LISTEN_INTERVAL, |
1343 | NL80211_ATTR_STA_SUPPORTED_RATES, | 1346 | NL80211_ATTR_STA_SUPPORTED_RATES, |
1344 | NL80211_ATTR_STA_VLAN, | 1347 | NL80211_ATTR_STA_VLAN, |
1345 | NL80211_ATTR_STA_INFO, | 1348 | NL80211_ATTR_STA_INFO, |
1346 | 1349 | ||
1347 | NL80211_ATTR_WIPHY_BANDS, | 1350 | NL80211_ATTR_WIPHY_BANDS, |
1348 | 1351 | ||
1349 | NL80211_ATTR_MNTR_FLAGS, | 1352 | NL80211_ATTR_MNTR_FLAGS, |
1350 | 1353 | ||
1351 | NL80211_ATTR_MESH_ID, | 1354 | NL80211_ATTR_MESH_ID, |
1352 | NL80211_ATTR_STA_PLINK_ACTION, | 1355 | NL80211_ATTR_STA_PLINK_ACTION, |
1353 | NL80211_ATTR_MPATH_NEXT_HOP, | 1356 | NL80211_ATTR_MPATH_NEXT_HOP, |
1354 | NL80211_ATTR_MPATH_INFO, | 1357 | NL80211_ATTR_MPATH_INFO, |
1355 | 1358 | ||
1356 | NL80211_ATTR_BSS_CTS_PROT, | 1359 | NL80211_ATTR_BSS_CTS_PROT, |
1357 | NL80211_ATTR_BSS_SHORT_PREAMBLE, | 1360 | NL80211_ATTR_BSS_SHORT_PREAMBLE, |
1358 | NL80211_ATTR_BSS_SHORT_SLOT_TIME, | 1361 | NL80211_ATTR_BSS_SHORT_SLOT_TIME, |
1359 | 1362 | ||
1360 | NL80211_ATTR_HT_CAPABILITY, | 1363 | NL80211_ATTR_HT_CAPABILITY, |
1361 | 1364 | ||
1362 | NL80211_ATTR_SUPPORTED_IFTYPES, | 1365 | NL80211_ATTR_SUPPORTED_IFTYPES, |
1363 | 1366 | ||
1364 | NL80211_ATTR_REG_ALPHA2, | 1367 | NL80211_ATTR_REG_ALPHA2, |
1365 | NL80211_ATTR_REG_RULES, | 1368 | NL80211_ATTR_REG_RULES, |
1366 | 1369 | ||
1367 | NL80211_ATTR_MESH_CONFIG, | 1370 | NL80211_ATTR_MESH_CONFIG, |
1368 | 1371 | ||
1369 | NL80211_ATTR_BSS_BASIC_RATES, | 1372 | NL80211_ATTR_BSS_BASIC_RATES, |
1370 | 1373 | ||
1371 | NL80211_ATTR_WIPHY_TXQ_PARAMS, | 1374 | NL80211_ATTR_WIPHY_TXQ_PARAMS, |
1372 | NL80211_ATTR_WIPHY_FREQ, | 1375 | NL80211_ATTR_WIPHY_FREQ, |
1373 | NL80211_ATTR_WIPHY_CHANNEL_TYPE, | 1376 | NL80211_ATTR_WIPHY_CHANNEL_TYPE, |
1374 | 1377 | ||
1375 | NL80211_ATTR_KEY_DEFAULT_MGMT, | 1378 | NL80211_ATTR_KEY_DEFAULT_MGMT, |
1376 | 1379 | ||
1377 | NL80211_ATTR_MGMT_SUBTYPE, | 1380 | NL80211_ATTR_MGMT_SUBTYPE, |
1378 | NL80211_ATTR_IE, | 1381 | NL80211_ATTR_IE, |
1379 | 1382 | ||
1380 | NL80211_ATTR_MAX_NUM_SCAN_SSIDS, | 1383 | NL80211_ATTR_MAX_NUM_SCAN_SSIDS, |
1381 | 1384 | ||
1382 | NL80211_ATTR_SCAN_FREQUENCIES, | 1385 | NL80211_ATTR_SCAN_FREQUENCIES, |
1383 | NL80211_ATTR_SCAN_SSIDS, | 1386 | NL80211_ATTR_SCAN_SSIDS, |
1384 | NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */ | 1387 | NL80211_ATTR_GENERATION, /* replaces old SCAN_GENERATION */ |
1385 | NL80211_ATTR_BSS, | 1388 | NL80211_ATTR_BSS, |
1386 | 1389 | ||
1387 | NL80211_ATTR_REG_INITIATOR, | 1390 | NL80211_ATTR_REG_INITIATOR, |
1388 | NL80211_ATTR_REG_TYPE, | 1391 | NL80211_ATTR_REG_TYPE, |
1389 | 1392 | ||
1390 | NL80211_ATTR_SUPPORTED_COMMANDS, | 1393 | NL80211_ATTR_SUPPORTED_COMMANDS, |
1391 | 1394 | ||
1392 | NL80211_ATTR_FRAME, | 1395 | NL80211_ATTR_FRAME, |
1393 | NL80211_ATTR_SSID, | 1396 | NL80211_ATTR_SSID, |
1394 | NL80211_ATTR_AUTH_TYPE, | 1397 | NL80211_ATTR_AUTH_TYPE, |
1395 | NL80211_ATTR_REASON_CODE, | 1398 | NL80211_ATTR_REASON_CODE, |
1396 | 1399 | ||
1397 | NL80211_ATTR_KEY_TYPE, | 1400 | NL80211_ATTR_KEY_TYPE, |
1398 | 1401 | ||
1399 | NL80211_ATTR_MAX_SCAN_IE_LEN, | 1402 | NL80211_ATTR_MAX_SCAN_IE_LEN, |
1400 | NL80211_ATTR_CIPHER_SUITES, | 1403 | NL80211_ATTR_CIPHER_SUITES, |
1401 | 1404 | ||
1402 | NL80211_ATTR_FREQ_BEFORE, | 1405 | NL80211_ATTR_FREQ_BEFORE, |
1403 | NL80211_ATTR_FREQ_AFTER, | 1406 | NL80211_ATTR_FREQ_AFTER, |
1404 | 1407 | ||
1405 | NL80211_ATTR_FREQ_FIXED, | 1408 | NL80211_ATTR_FREQ_FIXED, |
1406 | 1409 | ||
1407 | 1410 | ||
1408 | NL80211_ATTR_WIPHY_RETRY_SHORT, | 1411 | NL80211_ATTR_WIPHY_RETRY_SHORT, |
1409 | NL80211_ATTR_WIPHY_RETRY_LONG, | 1412 | NL80211_ATTR_WIPHY_RETRY_LONG, |
1410 | NL80211_ATTR_WIPHY_FRAG_THRESHOLD, | 1413 | NL80211_ATTR_WIPHY_FRAG_THRESHOLD, |
1411 | NL80211_ATTR_WIPHY_RTS_THRESHOLD, | 1414 | NL80211_ATTR_WIPHY_RTS_THRESHOLD, |
1412 | 1415 | ||
1413 | NL80211_ATTR_TIMED_OUT, | 1416 | NL80211_ATTR_TIMED_OUT, |
1414 | 1417 | ||
1415 | NL80211_ATTR_USE_MFP, | 1418 | NL80211_ATTR_USE_MFP, |
1416 | 1419 | ||
1417 | NL80211_ATTR_STA_FLAGS2, | 1420 | NL80211_ATTR_STA_FLAGS2, |
1418 | 1421 | ||
1419 | NL80211_ATTR_CONTROL_PORT, | 1422 | NL80211_ATTR_CONTROL_PORT, |
1420 | 1423 | ||
1421 | NL80211_ATTR_TESTDATA, | 1424 | NL80211_ATTR_TESTDATA, |
1422 | 1425 | ||
1423 | NL80211_ATTR_PRIVACY, | 1426 | NL80211_ATTR_PRIVACY, |
1424 | 1427 | ||
1425 | NL80211_ATTR_DISCONNECTED_BY_AP, | 1428 | NL80211_ATTR_DISCONNECTED_BY_AP, |
1426 | NL80211_ATTR_STATUS_CODE, | 1429 | NL80211_ATTR_STATUS_CODE, |
1427 | 1430 | ||
1428 | NL80211_ATTR_CIPHER_SUITES_PAIRWISE, | 1431 | NL80211_ATTR_CIPHER_SUITES_PAIRWISE, |
1429 | NL80211_ATTR_CIPHER_SUITE_GROUP, | 1432 | NL80211_ATTR_CIPHER_SUITE_GROUP, |
1430 | NL80211_ATTR_WPA_VERSIONS, | 1433 | NL80211_ATTR_WPA_VERSIONS, |
1431 | NL80211_ATTR_AKM_SUITES, | 1434 | NL80211_ATTR_AKM_SUITES, |
1432 | 1435 | ||
1433 | NL80211_ATTR_REQ_IE, | 1436 | NL80211_ATTR_REQ_IE, |
1434 | NL80211_ATTR_RESP_IE, | 1437 | NL80211_ATTR_RESP_IE, |
1435 | 1438 | ||
1436 | NL80211_ATTR_PREV_BSSID, | 1439 | NL80211_ATTR_PREV_BSSID, |
1437 | 1440 | ||
1438 | NL80211_ATTR_KEY, | 1441 | NL80211_ATTR_KEY, |
1439 | NL80211_ATTR_KEYS, | 1442 | NL80211_ATTR_KEYS, |
1440 | 1443 | ||
1441 | NL80211_ATTR_PID, | 1444 | NL80211_ATTR_PID, |
1442 | 1445 | ||
1443 | NL80211_ATTR_4ADDR, | 1446 | NL80211_ATTR_4ADDR, |
1444 | 1447 | ||
1445 | NL80211_ATTR_SURVEY_INFO, | 1448 | NL80211_ATTR_SURVEY_INFO, |
1446 | 1449 | ||
1447 | NL80211_ATTR_PMKID, | 1450 | NL80211_ATTR_PMKID, |
1448 | NL80211_ATTR_MAX_NUM_PMKIDS, | 1451 | NL80211_ATTR_MAX_NUM_PMKIDS, |
1449 | 1452 | ||
1450 | NL80211_ATTR_DURATION, | 1453 | NL80211_ATTR_DURATION, |
1451 | 1454 | ||
1452 | NL80211_ATTR_COOKIE, | 1455 | NL80211_ATTR_COOKIE, |
1453 | 1456 | ||
1454 | NL80211_ATTR_WIPHY_COVERAGE_CLASS, | 1457 | NL80211_ATTR_WIPHY_COVERAGE_CLASS, |
1455 | 1458 | ||
1456 | NL80211_ATTR_TX_RATES, | 1459 | NL80211_ATTR_TX_RATES, |
1457 | 1460 | ||
1458 | NL80211_ATTR_FRAME_MATCH, | 1461 | NL80211_ATTR_FRAME_MATCH, |
1459 | 1462 | ||
1460 | NL80211_ATTR_ACK, | 1463 | NL80211_ATTR_ACK, |
1461 | 1464 | ||
1462 | NL80211_ATTR_PS_STATE, | 1465 | NL80211_ATTR_PS_STATE, |
1463 | 1466 | ||
1464 | NL80211_ATTR_CQM, | 1467 | NL80211_ATTR_CQM, |
1465 | 1468 | ||
1466 | NL80211_ATTR_LOCAL_STATE_CHANGE, | 1469 | NL80211_ATTR_LOCAL_STATE_CHANGE, |
1467 | 1470 | ||
1468 | NL80211_ATTR_AP_ISOLATE, | 1471 | NL80211_ATTR_AP_ISOLATE, |
1469 | 1472 | ||
1470 | NL80211_ATTR_WIPHY_TX_POWER_SETTING, | 1473 | NL80211_ATTR_WIPHY_TX_POWER_SETTING, |
1471 | NL80211_ATTR_WIPHY_TX_POWER_LEVEL, | 1474 | NL80211_ATTR_WIPHY_TX_POWER_LEVEL, |
1472 | 1475 | ||
1473 | NL80211_ATTR_TX_FRAME_TYPES, | 1476 | NL80211_ATTR_TX_FRAME_TYPES, |
1474 | NL80211_ATTR_RX_FRAME_TYPES, | 1477 | NL80211_ATTR_RX_FRAME_TYPES, |
1475 | NL80211_ATTR_FRAME_TYPE, | 1478 | NL80211_ATTR_FRAME_TYPE, |
1476 | 1479 | ||
1477 | NL80211_ATTR_CONTROL_PORT_ETHERTYPE, | 1480 | NL80211_ATTR_CONTROL_PORT_ETHERTYPE, |
1478 | NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, | 1481 | NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT, |
1479 | 1482 | ||
1480 | NL80211_ATTR_SUPPORT_IBSS_RSN, | 1483 | NL80211_ATTR_SUPPORT_IBSS_RSN, |
1481 | 1484 | ||
1482 | NL80211_ATTR_WIPHY_ANTENNA_TX, | 1485 | NL80211_ATTR_WIPHY_ANTENNA_TX, |
1483 | NL80211_ATTR_WIPHY_ANTENNA_RX, | 1486 | NL80211_ATTR_WIPHY_ANTENNA_RX, |
1484 | 1487 | ||
1485 | NL80211_ATTR_MCAST_RATE, | 1488 | NL80211_ATTR_MCAST_RATE, |
1486 | 1489 | ||
1487 | NL80211_ATTR_OFFCHANNEL_TX_OK, | 1490 | NL80211_ATTR_OFFCHANNEL_TX_OK, |
1488 | 1491 | ||
1489 | NL80211_ATTR_BSS_HT_OPMODE, | 1492 | NL80211_ATTR_BSS_HT_OPMODE, |
1490 | 1493 | ||
1491 | NL80211_ATTR_KEY_DEFAULT_TYPES, | 1494 | NL80211_ATTR_KEY_DEFAULT_TYPES, |
1492 | 1495 | ||
1493 | NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, | 1496 | NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, |
1494 | 1497 | ||
1495 | NL80211_ATTR_MESH_SETUP, | 1498 | NL80211_ATTR_MESH_SETUP, |
1496 | 1499 | ||
1497 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, | 1500 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, |
1498 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, | 1501 | NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, |
1499 | 1502 | ||
1500 | NL80211_ATTR_SUPPORT_MESH_AUTH, | 1503 | NL80211_ATTR_SUPPORT_MESH_AUTH, |
1501 | NL80211_ATTR_STA_PLINK_STATE, | 1504 | NL80211_ATTR_STA_PLINK_STATE, |
1502 | 1505 | ||
1503 | NL80211_ATTR_WOWLAN_TRIGGERS, | 1506 | NL80211_ATTR_WOWLAN_TRIGGERS, |
1504 | NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, | 1507 | NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, |
1505 | 1508 | ||
1506 | NL80211_ATTR_SCHED_SCAN_INTERVAL, | 1509 | NL80211_ATTR_SCHED_SCAN_INTERVAL, |
1507 | 1510 | ||
1508 | NL80211_ATTR_INTERFACE_COMBINATIONS, | 1511 | NL80211_ATTR_INTERFACE_COMBINATIONS, |
1509 | NL80211_ATTR_SOFTWARE_IFTYPES, | 1512 | NL80211_ATTR_SOFTWARE_IFTYPES, |
1510 | 1513 | ||
1511 | NL80211_ATTR_REKEY_DATA, | 1514 | NL80211_ATTR_REKEY_DATA, |
1512 | 1515 | ||
1513 | NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, | 1516 | NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, |
1514 | NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, | 1517 | NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, |
1515 | 1518 | ||
1516 | NL80211_ATTR_SCAN_SUPP_RATES, | 1519 | NL80211_ATTR_SCAN_SUPP_RATES, |
1517 | 1520 | ||
1518 | NL80211_ATTR_HIDDEN_SSID, | 1521 | NL80211_ATTR_HIDDEN_SSID, |
1519 | 1522 | ||
1520 | NL80211_ATTR_IE_PROBE_RESP, | 1523 | NL80211_ATTR_IE_PROBE_RESP, |
1521 | NL80211_ATTR_IE_ASSOC_RESP, | 1524 | NL80211_ATTR_IE_ASSOC_RESP, |
1522 | 1525 | ||
1523 | NL80211_ATTR_STA_WME, | 1526 | NL80211_ATTR_STA_WME, |
1524 | NL80211_ATTR_SUPPORT_AP_UAPSD, | 1527 | NL80211_ATTR_SUPPORT_AP_UAPSD, |
1525 | 1528 | ||
1526 | NL80211_ATTR_ROAM_SUPPORT, | 1529 | NL80211_ATTR_ROAM_SUPPORT, |
1527 | 1530 | ||
1528 | NL80211_ATTR_SCHED_SCAN_MATCH, | 1531 | NL80211_ATTR_SCHED_SCAN_MATCH, |
1529 | NL80211_ATTR_MAX_MATCH_SETS, | 1532 | NL80211_ATTR_MAX_MATCH_SETS, |
1530 | 1533 | ||
1531 | NL80211_ATTR_PMKSA_CANDIDATE, | 1534 | NL80211_ATTR_PMKSA_CANDIDATE, |
1532 | 1535 | ||
1533 | NL80211_ATTR_TX_NO_CCK_RATE, | 1536 | NL80211_ATTR_TX_NO_CCK_RATE, |
1534 | 1537 | ||
1535 | NL80211_ATTR_TDLS_ACTION, | 1538 | NL80211_ATTR_TDLS_ACTION, |
1536 | NL80211_ATTR_TDLS_DIALOG_TOKEN, | 1539 | NL80211_ATTR_TDLS_DIALOG_TOKEN, |
1537 | NL80211_ATTR_TDLS_OPERATION, | 1540 | NL80211_ATTR_TDLS_OPERATION, |
1538 | NL80211_ATTR_TDLS_SUPPORT, | 1541 | NL80211_ATTR_TDLS_SUPPORT, |
1539 | NL80211_ATTR_TDLS_EXTERNAL_SETUP, | 1542 | NL80211_ATTR_TDLS_EXTERNAL_SETUP, |
1540 | 1543 | ||
1541 | NL80211_ATTR_DEVICE_AP_SME, | 1544 | NL80211_ATTR_DEVICE_AP_SME, |
1542 | 1545 | ||
1543 | NL80211_ATTR_DONT_WAIT_FOR_ACK, | 1546 | NL80211_ATTR_DONT_WAIT_FOR_ACK, |
1544 | 1547 | ||
1545 | NL80211_ATTR_FEATURE_FLAGS, | 1548 | NL80211_ATTR_FEATURE_FLAGS, |
1546 | 1549 | ||
1547 | NL80211_ATTR_PROBE_RESP_OFFLOAD, | 1550 | NL80211_ATTR_PROBE_RESP_OFFLOAD, |
1548 | 1551 | ||
1549 | NL80211_ATTR_PROBE_RESP, | 1552 | NL80211_ATTR_PROBE_RESP, |
1550 | 1553 | ||
1551 | NL80211_ATTR_DFS_REGION, | 1554 | NL80211_ATTR_DFS_REGION, |
1552 | 1555 | ||
1553 | NL80211_ATTR_DISABLE_HT, | 1556 | NL80211_ATTR_DISABLE_HT, |
1554 | NL80211_ATTR_HT_CAPABILITY_MASK, | 1557 | NL80211_ATTR_HT_CAPABILITY_MASK, |
1555 | 1558 | ||
1556 | NL80211_ATTR_NOACK_MAP, | 1559 | NL80211_ATTR_NOACK_MAP, |
1557 | 1560 | ||
1558 | NL80211_ATTR_INACTIVITY_TIMEOUT, | 1561 | NL80211_ATTR_INACTIVITY_TIMEOUT, |
1559 | 1562 | ||
1560 | NL80211_ATTR_RX_SIGNAL_DBM, | 1563 | NL80211_ATTR_RX_SIGNAL_DBM, |
1561 | 1564 | ||
1562 | NL80211_ATTR_BG_SCAN_PERIOD, | 1565 | NL80211_ATTR_BG_SCAN_PERIOD, |
1563 | 1566 | ||
1564 | NL80211_ATTR_WDEV, | 1567 | NL80211_ATTR_WDEV, |
1565 | 1568 | ||
1566 | NL80211_ATTR_USER_REG_HINT_TYPE, | 1569 | NL80211_ATTR_USER_REG_HINT_TYPE, |
1567 | 1570 | ||
1568 | NL80211_ATTR_CONN_FAILED_REASON, | 1571 | NL80211_ATTR_CONN_FAILED_REASON, |
1569 | 1572 | ||
1570 | NL80211_ATTR_SAE_DATA, | 1573 | NL80211_ATTR_SAE_DATA, |
1571 | 1574 | ||
1572 | NL80211_ATTR_VHT_CAPABILITY, | 1575 | NL80211_ATTR_VHT_CAPABILITY, |
1573 | 1576 | ||
1574 | NL80211_ATTR_SCAN_FLAGS, | 1577 | NL80211_ATTR_SCAN_FLAGS, |
1575 | 1578 | ||
1576 | NL80211_ATTR_CHANNEL_WIDTH, | 1579 | NL80211_ATTR_CHANNEL_WIDTH, |
1577 | NL80211_ATTR_CENTER_FREQ1, | 1580 | NL80211_ATTR_CENTER_FREQ1, |
1578 | NL80211_ATTR_CENTER_FREQ2, | 1581 | NL80211_ATTR_CENTER_FREQ2, |
1579 | 1582 | ||
1580 | NL80211_ATTR_P2P_CTWINDOW, | 1583 | NL80211_ATTR_P2P_CTWINDOW, |
1581 | NL80211_ATTR_P2P_OPPPS, | 1584 | NL80211_ATTR_P2P_OPPPS, |
1582 | 1585 | ||
1586 | NL80211_ATTR_LOCAL_MESH_POWER_MODE, | ||
1587 | |||
1583 | /* add attributes here, update the policy in nl80211.c */ | 1588 | /* add attributes here, update the policy in nl80211.c */ |
1584 | 1589 | ||
1585 | __NL80211_ATTR_AFTER_LAST, | 1590 | __NL80211_ATTR_AFTER_LAST, |
1586 | NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 | 1591 | NL80211_ATTR_MAX = __NL80211_ATTR_AFTER_LAST - 1 |
1587 | }; | 1592 | }; |
1588 | 1593 | ||
1589 | /* source-level API compatibility */ | 1594 | /* source-level API compatibility */ |
1590 | #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION | 1595 | #define NL80211_ATTR_SCAN_GENERATION NL80211_ATTR_GENERATION |
1591 | #define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG | 1596 | #define NL80211_ATTR_MESH_PARAMS NL80211_ATTR_MESH_CONFIG |
1592 | 1597 | ||
1593 | /* | 1598 | /* |
1594 | * Allow user space programs to use #ifdef on new attributes by defining them | 1599 | * Allow user space programs to use #ifdef on new attributes by defining them |
1595 | * here | 1600 | * here |
1596 | */ | 1601 | */ |
1597 | #define NL80211_CMD_CONNECT NL80211_CMD_CONNECT | 1602 | #define NL80211_CMD_CONNECT NL80211_CMD_CONNECT |
1598 | #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY | 1603 | #define NL80211_ATTR_HT_CAPABILITY NL80211_ATTR_HT_CAPABILITY |
1599 | #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES | 1604 | #define NL80211_ATTR_BSS_BASIC_RATES NL80211_ATTR_BSS_BASIC_RATES |
1600 | #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS | 1605 | #define NL80211_ATTR_WIPHY_TXQ_PARAMS NL80211_ATTR_WIPHY_TXQ_PARAMS |
1601 | #define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ | 1606 | #define NL80211_ATTR_WIPHY_FREQ NL80211_ATTR_WIPHY_FREQ |
1602 | #define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE | 1607 | #define NL80211_ATTR_WIPHY_CHANNEL_TYPE NL80211_ATTR_WIPHY_CHANNEL_TYPE |
1603 | #define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE | 1608 | #define NL80211_ATTR_MGMT_SUBTYPE NL80211_ATTR_MGMT_SUBTYPE |
1604 | #define NL80211_ATTR_IE NL80211_ATTR_IE | 1609 | #define NL80211_ATTR_IE NL80211_ATTR_IE |
1605 | #define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR | 1610 | #define NL80211_ATTR_REG_INITIATOR NL80211_ATTR_REG_INITIATOR |
1606 | #define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE | 1611 | #define NL80211_ATTR_REG_TYPE NL80211_ATTR_REG_TYPE |
1607 | #define NL80211_ATTR_FRAME NL80211_ATTR_FRAME | 1612 | #define NL80211_ATTR_FRAME NL80211_ATTR_FRAME |
1608 | #define NL80211_ATTR_SSID NL80211_ATTR_SSID | 1613 | #define NL80211_ATTR_SSID NL80211_ATTR_SSID |
1609 | #define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE | 1614 | #define NL80211_ATTR_AUTH_TYPE NL80211_ATTR_AUTH_TYPE |
1610 | #define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE | 1615 | #define NL80211_ATTR_REASON_CODE NL80211_ATTR_REASON_CODE |
1611 | #define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE | 1616 | #define NL80211_ATTR_CIPHER_SUITES_PAIRWISE NL80211_ATTR_CIPHER_SUITES_PAIRWISE |
1612 | #define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP | 1617 | #define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP |
1613 | #define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS | 1618 | #define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS |
1614 | #define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES | 1619 | #define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES |
1615 | #define NL80211_ATTR_KEY NL80211_ATTR_KEY | 1620 | #define NL80211_ATTR_KEY NL80211_ATTR_KEY |
1616 | #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS | 1621 | #define NL80211_ATTR_KEYS NL80211_ATTR_KEYS |
1617 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS | 1622 | #define NL80211_ATTR_FEATURE_FLAGS NL80211_ATTR_FEATURE_FLAGS |
1618 | 1623 | ||
1619 | #define NL80211_MAX_SUPP_RATES 32 | 1624 | #define NL80211_MAX_SUPP_RATES 32 |
1620 | #define NL80211_MAX_SUPP_HT_RATES 77 | 1625 | #define NL80211_MAX_SUPP_HT_RATES 77 |
1621 | #define NL80211_MAX_SUPP_REG_RULES 32 | 1626 | #define NL80211_MAX_SUPP_REG_RULES 32 |
1622 | #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 | 1627 | #define NL80211_TKIP_DATA_OFFSET_ENCR_KEY 0 |
1623 | #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 | 1628 | #define NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY 16 |
1624 | #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 | 1629 | #define NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY 24 |
1625 | #define NL80211_HT_CAPABILITY_LEN 26 | 1630 | #define NL80211_HT_CAPABILITY_LEN 26 |
1626 | #define NL80211_VHT_CAPABILITY_LEN 12 | 1631 | #define NL80211_VHT_CAPABILITY_LEN 12 |
1627 | 1632 | ||
1628 | #define NL80211_MAX_NR_CIPHER_SUITES 5 | 1633 | #define NL80211_MAX_NR_CIPHER_SUITES 5 |
1629 | #define NL80211_MAX_NR_AKM_SUITES 2 | 1634 | #define NL80211_MAX_NR_AKM_SUITES 2 |
1630 | 1635 | ||
1631 | #define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10 | 1636 | #define NL80211_MIN_REMAIN_ON_CHANNEL_TIME 10 |
1632 | 1637 | ||
1633 | /* default RSSI threshold for scan results if none specified. */ | 1638 | /* default RSSI threshold for scan results if none specified. */ |
1634 | #define NL80211_SCAN_RSSI_THOLD_OFF -300 | 1639 | #define NL80211_SCAN_RSSI_THOLD_OFF -300 |
1635 | 1640 | ||
1636 | #define NL80211_CQM_TXE_MAX_INTVL 1800 | 1641 | #define NL80211_CQM_TXE_MAX_INTVL 1800 |
1637 | 1642 | ||
1638 | /** | 1643 | /** |
1639 | * enum nl80211_iftype - (virtual) interface types | 1644 | * enum nl80211_iftype - (virtual) interface types |
1640 | * | 1645 | * |
1641 | * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides | 1646 | * @NL80211_IFTYPE_UNSPECIFIED: unspecified type, driver decides |
1642 | * @NL80211_IFTYPE_ADHOC: independent BSS member | 1647 | * @NL80211_IFTYPE_ADHOC: independent BSS member |
1643 | * @NL80211_IFTYPE_STATION: managed BSS member | 1648 | * @NL80211_IFTYPE_STATION: managed BSS member |
1644 | * @NL80211_IFTYPE_AP: access point | 1649 | * @NL80211_IFTYPE_AP: access point |
1645 | * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces | 1650 | * @NL80211_IFTYPE_AP_VLAN: VLAN interface for access points; VLAN interfaces |
1646 | * are a bit special in that they must always be tied to a pre-existing | 1651 | * are a bit special in that they must always be tied to a pre-existing |
1647 | * AP type interface. | 1652 | * AP type interface. |
1648 | * @NL80211_IFTYPE_WDS: wireless distribution interface | 1653 | * @NL80211_IFTYPE_WDS: wireless distribution interface |
1649 | * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames | 1654 | * @NL80211_IFTYPE_MONITOR: monitor interface receiving all frames |
1650 | * @NL80211_IFTYPE_MESH_POINT: mesh point | 1655 | * @NL80211_IFTYPE_MESH_POINT: mesh point |
1651 | * @NL80211_IFTYPE_P2P_CLIENT: P2P client | 1656 | * @NL80211_IFTYPE_P2P_CLIENT: P2P client |
1652 | * @NL80211_IFTYPE_P2P_GO: P2P group owner | 1657 | * @NL80211_IFTYPE_P2P_GO: P2P group owner |
1653 | * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev | 1658 | * @NL80211_IFTYPE_P2P_DEVICE: P2P device interface type, this is not a netdev |
1654 | * and therefore can't be created in the normal ways, use the | 1659 | * and therefore can't be created in the normal ways, use the |
1655 | * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE | 1660 | * %NL80211_CMD_START_P2P_DEVICE and %NL80211_CMD_STOP_P2P_DEVICE |
1656 | * commands to create and destroy one | 1661 | * commands to create and destroy one |
1657 | * @NL80211_IFTYPE_MAX: highest interface type number currently defined | 1662 | * @NL80211_IFTYPE_MAX: highest interface type number currently defined |
1658 | * @NUM_NL80211_IFTYPES: number of defined interface types | 1663 | * @NUM_NL80211_IFTYPES: number of defined interface types |
1659 | * | 1664 | * |
1660 | * These values are used with the %NL80211_ATTR_IFTYPE | 1665 | * These values are used with the %NL80211_ATTR_IFTYPE |
1661 | * to set the type of an interface. | 1666 | * to set the type of an interface. |
1662 | * | 1667 | * |
1663 | */ | 1668 | */ |
1664 | enum nl80211_iftype { | 1669 | enum nl80211_iftype { |
1665 | NL80211_IFTYPE_UNSPECIFIED, | 1670 | NL80211_IFTYPE_UNSPECIFIED, |
1666 | NL80211_IFTYPE_ADHOC, | 1671 | NL80211_IFTYPE_ADHOC, |
1667 | NL80211_IFTYPE_STATION, | 1672 | NL80211_IFTYPE_STATION, |
1668 | NL80211_IFTYPE_AP, | 1673 | NL80211_IFTYPE_AP, |
1669 | NL80211_IFTYPE_AP_VLAN, | 1674 | NL80211_IFTYPE_AP_VLAN, |
1670 | NL80211_IFTYPE_WDS, | 1675 | NL80211_IFTYPE_WDS, |
1671 | NL80211_IFTYPE_MONITOR, | 1676 | NL80211_IFTYPE_MONITOR, |
1672 | NL80211_IFTYPE_MESH_POINT, | 1677 | NL80211_IFTYPE_MESH_POINT, |
1673 | NL80211_IFTYPE_P2P_CLIENT, | 1678 | NL80211_IFTYPE_P2P_CLIENT, |
1674 | NL80211_IFTYPE_P2P_GO, | 1679 | NL80211_IFTYPE_P2P_GO, |
1675 | NL80211_IFTYPE_P2P_DEVICE, | 1680 | NL80211_IFTYPE_P2P_DEVICE, |
1676 | 1681 | ||
1677 | /* keep last */ | 1682 | /* keep last */ |
1678 | NUM_NL80211_IFTYPES, | 1683 | NUM_NL80211_IFTYPES, |
1679 | NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 | 1684 | NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1 |
1680 | }; | 1685 | }; |
1681 | 1686 | ||
1682 | /** | 1687 | /** |
1683 | * enum nl80211_sta_flags - station flags | 1688 | * enum nl80211_sta_flags - station flags |
1684 | * | 1689 | * |
1685 | * Station flags. When a station is added to an AP interface, it is | 1690 | * Station flags. When a station is added to an AP interface, it is |
1686 | * assumed to be already associated (and hence authenticated.) | 1691 | * assumed to be already associated (and hence authenticated.) |
1687 | * | 1692 | * |
1688 | * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved | 1693 | * @__NL80211_STA_FLAG_INVALID: attribute number 0 is reserved |
1689 | * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) | 1694 | * @NL80211_STA_FLAG_AUTHORIZED: station is authorized (802.1X) |
1690 | * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames | 1695 | * @NL80211_STA_FLAG_SHORT_PREAMBLE: station is capable of receiving frames |
1691 | * with short barker preamble | 1696 | * with short barker preamble |
1692 | * @NL80211_STA_FLAG_WME: station is WME/QoS capable | 1697 | * @NL80211_STA_FLAG_WME: station is WME/QoS capable |
1693 | * @NL80211_STA_FLAG_MFP: station uses management frame protection | 1698 | * @NL80211_STA_FLAG_MFP: station uses management frame protection |
1694 | * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated | 1699 | * @NL80211_STA_FLAG_AUTHENTICATED: station is authenticated |
1695 | * @NL80211_STA_FLAG_TDLS_PEER: station is a TDLS peer -- this flag should | 1700 | * @NL80211_STA_FLAG_TDLS_PEER: station is a TDLS peer -- this flag should |
1696 | * only be used in managed mode (even in the flags mask). Note that the | 1701 | * only be used in managed mode (even in the flags mask). Note that the |
1697 | * flag can't be changed, it is only valid while adding a station, and | 1702 | * flag can't be changed, it is only valid while adding a station, and |
1698 | * attempts to change it will silently be ignored (rather than rejected | 1703 | * attempts to change it will silently be ignored (rather than rejected |
1699 | * as errors.) | 1704 | * as errors.) |
1700 | * @NL80211_STA_FLAG_ASSOCIATED: station is associated; used with drivers | 1705 | * @NL80211_STA_FLAG_ASSOCIATED: station is associated; used with drivers |
1701 | * that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a | 1706 | * that support %NL80211_FEATURE_FULL_AP_CLIENT_STATE to transition a |
1702 | * previously added station into associated state | 1707 | * previously added station into associated state |
1703 | * @NL80211_STA_FLAG_MAX: highest station flag number currently defined | 1708 | * @NL80211_STA_FLAG_MAX: highest station flag number currently defined |
1704 | * @__NL80211_STA_FLAG_AFTER_LAST: internal use | 1709 | * @__NL80211_STA_FLAG_AFTER_LAST: internal use |
1705 | */ | 1710 | */ |
1706 | enum nl80211_sta_flags { | 1711 | enum nl80211_sta_flags { |
1707 | __NL80211_STA_FLAG_INVALID, | 1712 | __NL80211_STA_FLAG_INVALID, |
1708 | NL80211_STA_FLAG_AUTHORIZED, | 1713 | NL80211_STA_FLAG_AUTHORIZED, |
1709 | NL80211_STA_FLAG_SHORT_PREAMBLE, | 1714 | NL80211_STA_FLAG_SHORT_PREAMBLE, |
1710 | NL80211_STA_FLAG_WME, | 1715 | NL80211_STA_FLAG_WME, |
1711 | NL80211_STA_FLAG_MFP, | 1716 | NL80211_STA_FLAG_MFP, |
1712 | NL80211_STA_FLAG_AUTHENTICATED, | 1717 | NL80211_STA_FLAG_AUTHENTICATED, |
1713 | NL80211_STA_FLAG_TDLS_PEER, | 1718 | NL80211_STA_FLAG_TDLS_PEER, |
1714 | NL80211_STA_FLAG_ASSOCIATED, | 1719 | NL80211_STA_FLAG_ASSOCIATED, |
1715 | 1720 | ||
1716 | /* keep last */ | 1721 | /* keep last */ |
1717 | __NL80211_STA_FLAG_AFTER_LAST, | 1722 | __NL80211_STA_FLAG_AFTER_LAST, |
1718 | NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 | 1723 | NL80211_STA_FLAG_MAX = __NL80211_STA_FLAG_AFTER_LAST - 1 |
1719 | }; | 1724 | }; |
1720 | 1725 | ||
1721 | #define NL80211_STA_FLAG_MAX_OLD_API NL80211_STA_FLAG_TDLS_PEER | 1726 | #define NL80211_STA_FLAG_MAX_OLD_API NL80211_STA_FLAG_TDLS_PEER |
1722 | 1727 | ||
1723 | /** | 1728 | /** |
1724 | * struct nl80211_sta_flag_update - station flags mask/set | 1729 | * struct nl80211_sta_flag_update - station flags mask/set |
1725 | * @mask: mask of station flags to set | 1730 | * @mask: mask of station flags to set |
1726 | * @set: which values to set them to | 1731 | * @set: which values to set them to |
1727 | * | 1732 | * |
1728 | * Both mask and set contain bits as per &enum nl80211_sta_flags. | 1733 | * Both mask and set contain bits as per &enum nl80211_sta_flags. |
1729 | */ | 1734 | */ |
1730 | struct nl80211_sta_flag_update { | 1735 | struct nl80211_sta_flag_update { |
1731 | __u32 mask; | 1736 | __u32 mask; |
1732 | __u32 set; | 1737 | __u32 set; |
1733 | } __attribute__((packed)); | 1738 | } __attribute__((packed)); |
1734 | 1739 | ||
1735 | /** | 1740 | /** |
1736 | * enum nl80211_rate_info - bitrate information | 1741 | * enum nl80211_rate_info - bitrate information |
1737 | * | 1742 | * |
1738 | * These attribute types are used with %NL80211_STA_INFO_TXRATE | 1743 | * These attribute types are used with %NL80211_STA_INFO_TXRATE |
1739 | * when getting information about the bitrate of a station. | 1744 | * when getting information about the bitrate of a station. |
1740 | * There are 2 attributes for bitrate, a legacy one that represents | 1745 | * There are 2 attributes for bitrate, a legacy one that represents |
1741 | * a 16-bit value, and new one that represents a 32-bit value. | 1746 | * a 16-bit value, and new one that represents a 32-bit value. |
1742 | * If the rate value fits into 16 bit, both attributes are reported | 1747 | * If the rate value fits into 16 bit, both attributes are reported |
1743 | * with the same value. If the rate is too high to fit into 16 bits | 1748 | * with the same value. If the rate is too high to fit into 16 bits |
1744 | * (>6.5535Gbps) only 32-bit attribute is included. | 1749 | * (>6.5535Gbps) only 32-bit attribute is included. |
1745 | * User space tools encouraged to use the 32-bit attribute and fall | 1750 | * User space tools encouraged to use the 32-bit attribute and fall |
1746 | * back to the 16-bit one for compatibility with older kernels. | 1751 | * back to the 16-bit one for compatibility with older kernels. |
1747 | * | 1752 | * |
1748 | * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved | 1753 | * @__NL80211_RATE_INFO_INVALID: attribute number 0 is reserved |
1749 | * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) | 1754 | * @NL80211_RATE_INFO_BITRATE: total bitrate (u16, 100kbit/s) |
1750 | * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) | 1755 | * @NL80211_RATE_INFO_MCS: mcs index for 802.11n (u8) |
1751 | * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate | 1756 | * @NL80211_RATE_INFO_40_MHZ_WIDTH: 40 MHz dualchannel bitrate |
1752 | * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval | 1757 | * @NL80211_RATE_INFO_SHORT_GI: 400ns guard interval |
1753 | * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s) | 1758 | * @NL80211_RATE_INFO_BITRATE32: total bitrate (u32, 100kbit/s) |
1754 | * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined | 1759 | * @NL80211_RATE_INFO_MAX: highest rate_info number currently defined |
1755 | * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8) | 1760 | * @NL80211_RATE_INFO_VHT_MCS: MCS index for VHT (u8) |
1756 | * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8) | 1761 | * @NL80211_RATE_INFO_VHT_NSS: number of streams in VHT (u8) |
1757 | * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate | 1762 | * @NL80211_RATE_INFO_80_MHZ_WIDTH: 80 MHz VHT rate |
1758 | * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate | 1763 | * @NL80211_RATE_INFO_80P80_MHZ_WIDTH: 80+80 MHz VHT rate |
1759 | * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate | 1764 | * @NL80211_RATE_INFO_160_MHZ_WIDTH: 160 MHz VHT rate |
1760 | * @__NL80211_RATE_INFO_AFTER_LAST: internal use | 1765 | * @__NL80211_RATE_INFO_AFTER_LAST: internal use |
1761 | */ | 1766 | */ |
1762 | enum nl80211_rate_info { | 1767 | enum nl80211_rate_info { |
1763 | __NL80211_RATE_INFO_INVALID, | 1768 | __NL80211_RATE_INFO_INVALID, |
1764 | NL80211_RATE_INFO_BITRATE, | 1769 | NL80211_RATE_INFO_BITRATE, |
1765 | NL80211_RATE_INFO_MCS, | 1770 | NL80211_RATE_INFO_MCS, |
1766 | NL80211_RATE_INFO_40_MHZ_WIDTH, | 1771 | NL80211_RATE_INFO_40_MHZ_WIDTH, |
1767 | NL80211_RATE_INFO_SHORT_GI, | 1772 | NL80211_RATE_INFO_SHORT_GI, |
1768 | NL80211_RATE_INFO_BITRATE32, | 1773 | NL80211_RATE_INFO_BITRATE32, |
1769 | NL80211_RATE_INFO_VHT_MCS, | 1774 | NL80211_RATE_INFO_VHT_MCS, |
1770 | NL80211_RATE_INFO_VHT_NSS, | 1775 | NL80211_RATE_INFO_VHT_NSS, |
1771 | NL80211_RATE_INFO_80_MHZ_WIDTH, | 1776 | NL80211_RATE_INFO_80_MHZ_WIDTH, |
1772 | NL80211_RATE_INFO_80P80_MHZ_WIDTH, | 1777 | NL80211_RATE_INFO_80P80_MHZ_WIDTH, |
1773 | NL80211_RATE_INFO_160_MHZ_WIDTH, | 1778 | NL80211_RATE_INFO_160_MHZ_WIDTH, |
1774 | 1779 | ||
1775 | /* keep last */ | 1780 | /* keep last */ |
1776 | __NL80211_RATE_INFO_AFTER_LAST, | 1781 | __NL80211_RATE_INFO_AFTER_LAST, |
1777 | NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 | 1782 | NL80211_RATE_INFO_MAX = __NL80211_RATE_INFO_AFTER_LAST - 1 |
1778 | }; | 1783 | }; |
1779 | 1784 | ||
1780 | /** | 1785 | /** |
1781 | * enum nl80211_sta_bss_param - BSS information collected by STA | 1786 | * enum nl80211_sta_bss_param - BSS information collected by STA |
1782 | * | 1787 | * |
1783 | * These attribute types are used with %NL80211_STA_INFO_BSS_PARAM | 1788 | * These attribute types are used with %NL80211_STA_INFO_BSS_PARAM |
1784 | * when getting information about the bitrate of a station. | 1789 | * when getting information about the bitrate of a station. |
1785 | * | 1790 | * |
1786 | * @__NL80211_STA_BSS_PARAM_INVALID: attribute number 0 is reserved | 1791 | * @__NL80211_STA_BSS_PARAM_INVALID: attribute number 0 is reserved |
1787 | * @NL80211_STA_BSS_PARAM_CTS_PROT: whether CTS protection is enabled (flag) | 1792 | * @NL80211_STA_BSS_PARAM_CTS_PROT: whether CTS protection is enabled (flag) |
1788 | * @NL80211_STA_BSS_PARAM_SHORT_PREAMBLE: whether short preamble is enabled | 1793 | * @NL80211_STA_BSS_PARAM_SHORT_PREAMBLE: whether short preamble is enabled |
1789 | * (flag) | 1794 | * (flag) |
1790 | * @NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME: whether short slot time is enabled | 1795 | * @NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME: whether short slot time is enabled |
1791 | * (flag) | 1796 | * (flag) |
1792 | * @NL80211_STA_BSS_PARAM_DTIM_PERIOD: DTIM period for beaconing (u8) | 1797 | * @NL80211_STA_BSS_PARAM_DTIM_PERIOD: DTIM period for beaconing (u8) |
1793 | * @NL80211_STA_BSS_PARAM_BEACON_INTERVAL: Beacon interval (u16) | 1798 | * @NL80211_STA_BSS_PARAM_BEACON_INTERVAL: Beacon interval (u16) |
1794 | * @NL80211_STA_BSS_PARAM_MAX: highest sta_bss_param number currently defined | 1799 | * @NL80211_STA_BSS_PARAM_MAX: highest sta_bss_param number currently defined |
1795 | * @__NL80211_STA_BSS_PARAM_AFTER_LAST: internal use | 1800 | * @__NL80211_STA_BSS_PARAM_AFTER_LAST: internal use |
1796 | */ | 1801 | */ |
1797 | enum nl80211_sta_bss_param { | 1802 | enum nl80211_sta_bss_param { |
1798 | __NL80211_STA_BSS_PARAM_INVALID, | 1803 | __NL80211_STA_BSS_PARAM_INVALID, |
1799 | NL80211_STA_BSS_PARAM_CTS_PROT, | 1804 | NL80211_STA_BSS_PARAM_CTS_PROT, |
1800 | NL80211_STA_BSS_PARAM_SHORT_PREAMBLE, | 1805 | NL80211_STA_BSS_PARAM_SHORT_PREAMBLE, |
1801 | NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME, | 1806 | NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME, |
1802 | NL80211_STA_BSS_PARAM_DTIM_PERIOD, | 1807 | NL80211_STA_BSS_PARAM_DTIM_PERIOD, |
1803 | NL80211_STA_BSS_PARAM_BEACON_INTERVAL, | 1808 | NL80211_STA_BSS_PARAM_BEACON_INTERVAL, |
1804 | 1809 | ||
1805 | /* keep last */ | 1810 | /* keep last */ |
1806 | __NL80211_STA_BSS_PARAM_AFTER_LAST, | 1811 | __NL80211_STA_BSS_PARAM_AFTER_LAST, |
1807 | NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1 | 1812 | NL80211_STA_BSS_PARAM_MAX = __NL80211_STA_BSS_PARAM_AFTER_LAST - 1 |
1808 | }; | 1813 | }; |
1809 | 1814 | ||
1810 | /** | 1815 | /** |
1811 | * enum nl80211_sta_info - station information | 1816 | * enum nl80211_sta_info - station information |
1812 | * | 1817 | * |
1813 | * These attribute types are used with %NL80211_ATTR_STA_INFO | 1818 | * These attribute types are used with %NL80211_ATTR_STA_INFO |
1814 | * when getting information about a station. | 1819 | * when getting information about a station. |
1815 | * | 1820 | * |
1816 | * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved | 1821 | * @__NL80211_STA_INFO_INVALID: attribute number 0 is reserved |
1817 | * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) | 1822 | * @NL80211_STA_INFO_INACTIVE_TIME: time since last activity (u32, msecs) |
1818 | * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station) | 1823 | * @NL80211_STA_INFO_RX_BYTES: total received bytes (u32, from this station) |
1819 | * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) | 1824 | * @NL80211_STA_INFO_TX_BYTES: total transmitted bytes (u32, to this station) |
1820 | * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) | 1825 | * @NL80211_STA_INFO_SIGNAL: signal strength of last received PPDU (u8, dBm) |
1821 | * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute | 1826 | * @NL80211_STA_INFO_TX_BITRATE: current unicast tx rate, nested attribute |
1822 | * containing info as possible, see &enum nl80211_rate_info | 1827 | * containing info as possible, see &enum nl80211_rate_info |
1823 | * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) | 1828 | * @NL80211_STA_INFO_RX_PACKETS: total received packet (u32, from this station) |
1824 | * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this | 1829 | * @NL80211_STA_INFO_TX_PACKETS: total transmitted packets (u32, to this |
1825 | * station) | 1830 | * station) |
1826 | * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) | 1831 | * @NL80211_STA_INFO_TX_RETRIES: total retries (u32, to this station) |
1827 | * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) | 1832 | * @NL80211_STA_INFO_TX_FAILED: total failed packets (u32, to this station) |
1828 | * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) | 1833 | * @NL80211_STA_INFO_SIGNAL_AVG: signal strength average (u8, dBm) |
1829 | * @NL80211_STA_INFO_LLID: the station's mesh LLID | 1834 | * @NL80211_STA_INFO_LLID: the station's mesh LLID |
1830 | * @NL80211_STA_INFO_PLID: the station's mesh PLID | 1835 | * @NL80211_STA_INFO_PLID: the station's mesh PLID |
1831 | * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station | 1836 | * @NL80211_STA_INFO_PLINK_STATE: peer link state for the station |
1832 | * (see %enum nl80211_plink_state) | 1837 | * (see %enum nl80211_plink_state) |
1833 | * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested | 1838 | * @NL80211_STA_INFO_RX_BITRATE: last unicast data frame rx rate, nested |
1834 | * attribute, like NL80211_STA_INFO_TX_BITRATE. | 1839 | * attribute, like NL80211_STA_INFO_TX_BITRATE. |
1835 | * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute | 1840 | * @NL80211_STA_INFO_BSS_PARAM: current station's view of BSS, nested attribute |
1836 | * containing info as possible, see &enum nl80211_sta_bss_param | 1841 | * containing info as possible, see &enum nl80211_sta_bss_param |
1837 | * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected | 1842 | * @NL80211_STA_INFO_CONNECTED_TIME: time since the station is last connected |
1838 | * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. | 1843 | * @NL80211_STA_INFO_STA_FLAGS: Contains a struct nl80211_sta_flag_update. |
1839 | * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32) | 1844 | * @NL80211_STA_INFO_BEACON_LOSS: count of times beacon loss was detected (u32) |
1840 | * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64) | 1845 | * @NL80211_STA_INFO_T_OFFSET: timing offset with respect to this STA (s64) |
1846 | * @NL80211_STA_INFO_LOCAL_PM: local mesh STA link-specific power mode | ||
1847 | * @NL80211_STA_INFO_PEER_PM: peer mesh STA link-specific power mode | ||
1848 | * @NL80211_STA_INFO_NONPEER_PM: neighbor mesh STA power save mode towards | ||
1849 | * non-peer STA | ||
1841 | * @__NL80211_STA_INFO_AFTER_LAST: internal | 1850 | * @__NL80211_STA_INFO_AFTER_LAST: internal |
1842 | * @NL80211_STA_INFO_MAX: highest possible station info attribute | 1851 | * @NL80211_STA_INFO_MAX: highest possible station info attribute |
1843 | */ | 1852 | */ |
1844 | enum nl80211_sta_info { | 1853 | enum nl80211_sta_info { |
1845 | __NL80211_STA_INFO_INVALID, | 1854 | __NL80211_STA_INFO_INVALID, |
1846 | NL80211_STA_INFO_INACTIVE_TIME, | 1855 | NL80211_STA_INFO_INACTIVE_TIME, |
1847 | NL80211_STA_INFO_RX_BYTES, | 1856 | NL80211_STA_INFO_RX_BYTES, |
1848 | NL80211_STA_INFO_TX_BYTES, | 1857 | NL80211_STA_INFO_TX_BYTES, |
1849 | NL80211_STA_INFO_LLID, | 1858 | NL80211_STA_INFO_LLID, |
1850 | NL80211_STA_INFO_PLID, | 1859 | NL80211_STA_INFO_PLID, |
1851 | NL80211_STA_INFO_PLINK_STATE, | 1860 | NL80211_STA_INFO_PLINK_STATE, |
1852 | NL80211_STA_INFO_SIGNAL, | 1861 | NL80211_STA_INFO_SIGNAL, |
1853 | NL80211_STA_INFO_TX_BITRATE, | 1862 | NL80211_STA_INFO_TX_BITRATE, |
1854 | NL80211_STA_INFO_RX_PACKETS, | 1863 | NL80211_STA_INFO_RX_PACKETS, |
1855 | NL80211_STA_INFO_TX_PACKETS, | 1864 | NL80211_STA_INFO_TX_PACKETS, |
1856 | NL80211_STA_INFO_TX_RETRIES, | 1865 | NL80211_STA_INFO_TX_RETRIES, |
1857 | NL80211_STA_INFO_TX_FAILED, | 1866 | NL80211_STA_INFO_TX_FAILED, |
1858 | NL80211_STA_INFO_SIGNAL_AVG, | 1867 | NL80211_STA_INFO_SIGNAL_AVG, |
1859 | NL80211_STA_INFO_RX_BITRATE, | 1868 | NL80211_STA_INFO_RX_BITRATE, |
1860 | NL80211_STA_INFO_BSS_PARAM, | 1869 | NL80211_STA_INFO_BSS_PARAM, |
1861 | NL80211_STA_INFO_CONNECTED_TIME, | 1870 | NL80211_STA_INFO_CONNECTED_TIME, |
1862 | NL80211_STA_INFO_STA_FLAGS, | 1871 | NL80211_STA_INFO_STA_FLAGS, |
1863 | NL80211_STA_INFO_BEACON_LOSS, | 1872 | NL80211_STA_INFO_BEACON_LOSS, |
1864 | NL80211_STA_INFO_T_OFFSET, | 1873 | NL80211_STA_INFO_T_OFFSET, |
1874 | NL80211_STA_INFO_LOCAL_PM, | ||
1875 | NL80211_STA_INFO_PEER_PM, | ||
1876 | NL80211_STA_INFO_NONPEER_PM, | ||
1865 | 1877 | ||
1866 | /* keep last */ | 1878 | /* keep last */ |
1867 | __NL80211_STA_INFO_AFTER_LAST, | 1879 | __NL80211_STA_INFO_AFTER_LAST, |
1868 | NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 | 1880 | NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 |
1869 | }; | 1881 | }; |
1870 | 1882 | ||
1871 | /** | 1883 | /** |
1872 | * enum nl80211_mpath_flags - nl80211 mesh path flags | 1884 | * enum nl80211_mpath_flags - nl80211 mesh path flags |
1873 | * | 1885 | * |
1874 | * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active | 1886 | * @NL80211_MPATH_FLAG_ACTIVE: the mesh path is active |
1875 | * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running | 1887 | * @NL80211_MPATH_FLAG_RESOLVING: the mesh path discovery process is running |
1876 | * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN | 1888 | * @NL80211_MPATH_FLAG_SN_VALID: the mesh path contains a valid SN |
1877 | * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set | 1889 | * @NL80211_MPATH_FLAG_FIXED: the mesh path has been manually set |
1878 | * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded | 1890 | * @NL80211_MPATH_FLAG_RESOLVED: the mesh path discovery process succeeded |
1879 | */ | 1891 | */ |
1880 | enum nl80211_mpath_flags { | 1892 | enum nl80211_mpath_flags { |
1881 | NL80211_MPATH_FLAG_ACTIVE = 1<<0, | 1893 | NL80211_MPATH_FLAG_ACTIVE = 1<<0, |
1882 | NL80211_MPATH_FLAG_RESOLVING = 1<<1, | 1894 | NL80211_MPATH_FLAG_RESOLVING = 1<<1, |
1883 | NL80211_MPATH_FLAG_SN_VALID = 1<<2, | 1895 | NL80211_MPATH_FLAG_SN_VALID = 1<<2, |
1884 | NL80211_MPATH_FLAG_FIXED = 1<<3, | 1896 | NL80211_MPATH_FLAG_FIXED = 1<<3, |
1885 | NL80211_MPATH_FLAG_RESOLVED = 1<<4, | 1897 | NL80211_MPATH_FLAG_RESOLVED = 1<<4, |
1886 | }; | 1898 | }; |
1887 | 1899 | ||
1888 | /** | 1900 | /** |
1889 | * enum nl80211_mpath_info - mesh path information | 1901 | * enum nl80211_mpath_info - mesh path information |
1890 | * | 1902 | * |
1891 | * These attribute types are used with %NL80211_ATTR_MPATH_INFO when getting | 1903 | * These attribute types are used with %NL80211_ATTR_MPATH_INFO when getting |
1892 | * information about a mesh path. | 1904 | * information about a mesh path. |
1893 | * | 1905 | * |
1894 | * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved | 1906 | * @__NL80211_MPATH_INFO_INVALID: attribute number 0 is reserved |
1895 | * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination | 1907 | * @NL80211_MPATH_INFO_FRAME_QLEN: number of queued frames for this destination |
1896 | * @NL80211_MPATH_INFO_SN: destination sequence number | 1908 | * @NL80211_MPATH_INFO_SN: destination sequence number |
1897 | * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path | 1909 | * @NL80211_MPATH_INFO_METRIC: metric (cost) of this mesh path |
1898 | * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now | 1910 | * @NL80211_MPATH_INFO_EXPTIME: expiration time for the path, in msec from now |
1899 | * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in | 1911 | * @NL80211_MPATH_INFO_FLAGS: mesh path flags, enumerated in |
1900 | * &enum nl80211_mpath_flags; | 1912 | * &enum nl80211_mpath_flags; |
1901 | * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec | 1913 | * @NL80211_MPATH_INFO_DISCOVERY_TIMEOUT: total path discovery timeout, in msec |
1902 | * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries | 1914 | * @NL80211_MPATH_INFO_DISCOVERY_RETRIES: mesh path discovery retries |
1903 | * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number | 1915 | * @NL80211_MPATH_INFO_MAX: highest mesh path information attribute number |
1904 | * currently defind | 1916 | * currently defind |
1905 | * @__NL80211_MPATH_INFO_AFTER_LAST: internal use | 1917 | * @__NL80211_MPATH_INFO_AFTER_LAST: internal use |
1906 | */ | 1918 | */ |
1907 | enum nl80211_mpath_info { | 1919 | enum nl80211_mpath_info { |
1908 | __NL80211_MPATH_INFO_INVALID, | 1920 | __NL80211_MPATH_INFO_INVALID, |
1909 | NL80211_MPATH_INFO_FRAME_QLEN, | 1921 | NL80211_MPATH_INFO_FRAME_QLEN, |
1910 | NL80211_MPATH_INFO_SN, | 1922 | NL80211_MPATH_INFO_SN, |
1911 | NL80211_MPATH_INFO_METRIC, | 1923 | NL80211_MPATH_INFO_METRIC, |
1912 | NL80211_MPATH_INFO_EXPTIME, | 1924 | NL80211_MPATH_INFO_EXPTIME, |
1913 | NL80211_MPATH_INFO_FLAGS, | 1925 | NL80211_MPATH_INFO_FLAGS, |
1914 | NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, | 1926 | NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, |
1915 | NL80211_MPATH_INFO_DISCOVERY_RETRIES, | 1927 | NL80211_MPATH_INFO_DISCOVERY_RETRIES, |
1916 | 1928 | ||
1917 | /* keep last */ | 1929 | /* keep last */ |
1918 | __NL80211_MPATH_INFO_AFTER_LAST, | 1930 | __NL80211_MPATH_INFO_AFTER_LAST, |
1919 | NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1 | 1931 | NL80211_MPATH_INFO_MAX = __NL80211_MPATH_INFO_AFTER_LAST - 1 |
1920 | }; | 1932 | }; |
1921 | 1933 | ||
1922 | /** | 1934 | /** |
1923 | * enum nl80211_band_attr - band attributes | 1935 | * enum nl80211_band_attr - band attributes |
1924 | * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved | 1936 | * @__NL80211_BAND_ATTR_INVALID: attribute number 0 is reserved |
1925 | * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band, | 1937 | * @NL80211_BAND_ATTR_FREQS: supported frequencies in this band, |
1926 | * an array of nested frequency attributes | 1938 | * an array of nested frequency attributes |
1927 | * @NL80211_BAND_ATTR_RATES: supported bitrates in this band, | 1939 | * @NL80211_BAND_ATTR_RATES: supported bitrates in this band, |
1928 | * an array of nested bitrate attributes | 1940 | * an array of nested bitrate attributes |
1929 | * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as | 1941 | * @NL80211_BAND_ATTR_HT_MCS_SET: 16-byte attribute containing the MCS set as |
1930 | * defined in 802.11n | 1942 | * defined in 802.11n |
1931 | * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE | 1943 | * @NL80211_BAND_ATTR_HT_CAPA: HT capabilities, as in the HT information IE |
1932 | * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n | 1944 | * @NL80211_BAND_ATTR_HT_AMPDU_FACTOR: A-MPDU factor, as in 11n |
1933 | * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n | 1945 | * @NL80211_BAND_ATTR_HT_AMPDU_DENSITY: A-MPDU density, as in 11n |
1934 | * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as | 1946 | * @NL80211_BAND_ATTR_VHT_MCS_SET: 32-byte attribute containing the MCS set as |
1935 | * defined in 802.11ac | 1947 | * defined in 802.11ac |
1936 | * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE | 1948 | * @NL80211_BAND_ATTR_VHT_CAPA: VHT capabilities, as in the HT information IE |
1937 | * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined | 1949 | * @NL80211_BAND_ATTR_MAX: highest band attribute currently defined |
1938 | * @__NL80211_BAND_ATTR_AFTER_LAST: internal use | 1950 | * @__NL80211_BAND_ATTR_AFTER_LAST: internal use |
1939 | */ | 1951 | */ |
1940 | enum nl80211_band_attr { | 1952 | enum nl80211_band_attr { |
1941 | __NL80211_BAND_ATTR_INVALID, | 1953 | __NL80211_BAND_ATTR_INVALID, |
1942 | NL80211_BAND_ATTR_FREQS, | 1954 | NL80211_BAND_ATTR_FREQS, |
1943 | NL80211_BAND_ATTR_RATES, | 1955 | NL80211_BAND_ATTR_RATES, |
1944 | 1956 | ||
1945 | NL80211_BAND_ATTR_HT_MCS_SET, | 1957 | NL80211_BAND_ATTR_HT_MCS_SET, |
1946 | NL80211_BAND_ATTR_HT_CAPA, | 1958 | NL80211_BAND_ATTR_HT_CAPA, |
1947 | NL80211_BAND_ATTR_HT_AMPDU_FACTOR, | 1959 | NL80211_BAND_ATTR_HT_AMPDU_FACTOR, |
1948 | NL80211_BAND_ATTR_HT_AMPDU_DENSITY, | 1960 | NL80211_BAND_ATTR_HT_AMPDU_DENSITY, |
1949 | 1961 | ||
1950 | NL80211_BAND_ATTR_VHT_MCS_SET, | 1962 | NL80211_BAND_ATTR_VHT_MCS_SET, |
1951 | NL80211_BAND_ATTR_VHT_CAPA, | 1963 | NL80211_BAND_ATTR_VHT_CAPA, |
1952 | 1964 | ||
1953 | /* keep last */ | 1965 | /* keep last */ |
1954 | __NL80211_BAND_ATTR_AFTER_LAST, | 1966 | __NL80211_BAND_ATTR_AFTER_LAST, |
1955 | NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 | 1967 | NL80211_BAND_ATTR_MAX = __NL80211_BAND_ATTR_AFTER_LAST - 1 |
1956 | }; | 1968 | }; |
1957 | 1969 | ||
1958 | #define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA | 1970 | #define NL80211_BAND_ATTR_HT_CAPA NL80211_BAND_ATTR_HT_CAPA |
1959 | 1971 | ||
1960 | /** | 1972 | /** |
1961 | * enum nl80211_frequency_attr - frequency attributes | 1973 | * enum nl80211_frequency_attr - frequency attributes |
1962 | * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved | 1974 | * @__NL80211_FREQUENCY_ATTR_INVALID: attribute number 0 is reserved |
1963 | * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz | 1975 | * @NL80211_FREQUENCY_ATTR_FREQ: Frequency in MHz |
1964 | * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current | 1976 | * @NL80211_FREQUENCY_ATTR_DISABLED: Channel is disabled in current |
1965 | * regulatory domain. | 1977 | * regulatory domain. |
1966 | * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is | 1978 | * @NL80211_FREQUENCY_ATTR_PASSIVE_SCAN: Only passive scanning is |
1967 | * permitted on this channel in current regulatory domain. | 1979 | * permitted on this channel in current regulatory domain. |
1968 | * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted | 1980 | * @NL80211_FREQUENCY_ATTR_NO_IBSS: IBSS networks are not permitted |
1969 | * on this channel in current regulatory domain. | 1981 | * on this channel in current regulatory domain. |
1970 | * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory | 1982 | * @NL80211_FREQUENCY_ATTR_RADAR: Radar detection is mandatory |
1971 | * on this channel in current regulatory domain. | 1983 | * on this channel in current regulatory domain. |
1972 | * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm | 1984 | * @NL80211_FREQUENCY_ATTR_MAX_TX_POWER: Maximum transmission power in mBm |
1973 | * (100 * dBm). | 1985 | * (100 * dBm). |
1974 | * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number | 1986 | * @NL80211_FREQUENCY_ATTR_MAX: highest frequency attribute number |
1975 | * currently defined | 1987 | * currently defined |
1976 | * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use | 1988 | * @__NL80211_FREQUENCY_ATTR_AFTER_LAST: internal use |
1977 | */ | 1989 | */ |
1978 | enum nl80211_frequency_attr { | 1990 | enum nl80211_frequency_attr { |
1979 | __NL80211_FREQUENCY_ATTR_INVALID, | 1991 | __NL80211_FREQUENCY_ATTR_INVALID, |
1980 | NL80211_FREQUENCY_ATTR_FREQ, | 1992 | NL80211_FREQUENCY_ATTR_FREQ, |
1981 | NL80211_FREQUENCY_ATTR_DISABLED, | 1993 | NL80211_FREQUENCY_ATTR_DISABLED, |
1982 | NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, | 1994 | NL80211_FREQUENCY_ATTR_PASSIVE_SCAN, |
1983 | NL80211_FREQUENCY_ATTR_NO_IBSS, | 1995 | NL80211_FREQUENCY_ATTR_NO_IBSS, |
1984 | NL80211_FREQUENCY_ATTR_RADAR, | 1996 | NL80211_FREQUENCY_ATTR_RADAR, |
1985 | NL80211_FREQUENCY_ATTR_MAX_TX_POWER, | 1997 | NL80211_FREQUENCY_ATTR_MAX_TX_POWER, |
1986 | 1998 | ||
1987 | /* keep last */ | 1999 | /* keep last */ |
1988 | __NL80211_FREQUENCY_ATTR_AFTER_LAST, | 2000 | __NL80211_FREQUENCY_ATTR_AFTER_LAST, |
1989 | NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1 | 2001 | NL80211_FREQUENCY_ATTR_MAX = __NL80211_FREQUENCY_ATTR_AFTER_LAST - 1 |
1990 | }; | 2002 | }; |
1991 | 2003 | ||
1992 | #define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER | 2004 | #define NL80211_FREQUENCY_ATTR_MAX_TX_POWER NL80211_FREQUENCY_ATTR_MAX_TX_POWER |
1993 | 2005 | ||
1994 | /** | 2006 | /** |
1995 | * enum nl80211_bitrate_attr - bitrate attributes | 2007 | * enum nl80211_bitrate_attr - bitrate attributes |
1996 | * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved | 2008 | * @__NL80211_BITRATE_ATTR_INVALID: attribute number 0 is reserved |
1997 | * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps | 2009 | * @NL80211_BITRATE_ATTR_RATE: Bitrate in units of 100 kbps |
1998 | * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported | 2010 | * @NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE: Short preamble supported |
1999 | * in 2.4 GHz band. | 2011 | * in 2.4 GHz band. |
2000 | * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number | 2012 | * @NL80211_BITRATE_ATTR_MAX: highest bitrate attribute number |
2001 | * currently defined | 2013 | * currently defined |
2002 | * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use | 2014 | * @__NL80211_BITRATE_ATTR_AFTER_LAST: internal use |
2003 | */ | 2015 | */ |
2004 | enum nl80211_bitrate_attr { | 2016 | enum nl80211_bitrate_attr { |
2005 | __NL80211_BITRATE_ATTR_INVALID, | 2017 | __NL80211_BITRATE_ATTR_INVALID, |
2006 | NL80211_BITRATE_ATTR_RATE, | 2018 | NL80211_BITRATE_ATTR_RATE, |
2007 | NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE, | 2019 | NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE, |
2008 | 2020 | ||
2009 | /* keep last */ | 2021 | /* keep last */ |
2010 | __NL80211_BITRATE_ATTR_AFTER_LAST, | 2022 | __NL80211_BITRATE_ATTR_AFTER_LAST, |
2011 | NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1 | 2023 | NL80211_BITRATE_ATTR_MAX = __NL80211_BITRATE_ATTR_AFTER_LAST - 1 |
2012 | }; | 2024 | }; |
2013 | 2025 | ||
2014 | /** | 2026 | /** |
2015 | * enum nl80211_initiator - Indicates the initiator of a reg domain request | 2027 | * enum nl80211_initiator - Indicates the initiator of a reg domain request |
2016 | * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world | 2028 | * @NL80211_REGDOM_SET_BY_CORE: Core queried CRDA for a dynamic world |
2017 | * regulatory domain. | 2029 | * regulatory domain. |
2018 | * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the | 2030 | * @NL80211_REGDOM_SET_BY_USER: User asked the wireless core to set the |
2019 | * regulatory domain. | 2031 | * regulatory domain. |
2020 | * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the | 2032 | * @NL80211_REGDOM_SET_BY_DRIVER: a wireless drivers has hinted to the |
2021 | * wireless core it thinks its knows the regulatory domain we should be in. | 2033 | * wireless core it thinks its knows the regulatory domain we should be in. |
2022 | * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an | 2034 | * @NL80211_REGDOM_SET_BY_COUNTRY_IE: the wireless core has received an |
2023 | * 802.11 country information element with regulatory information it | 2035 | * 802.11 country information element with regulatory information it |
2024 | * thinks we should consider. cfg80211 only processes the country | 2036 | * thinks we should consider. cfg80211 only processes the country |
2025 | * code from the IE, and relies on the regulatory domain information | 2037 | * code from the IE, and relies on the regulatory domain information |
2026 | * structure passed by userspace (CRDA) from our wireless-regdb. | 2038 | * structure passed by userspace (CRDA) from our wireless-regdb. |
2027 | * If a channel is enabled but the country code indicates it should | 2039 | * If a channel is enabled but the country code indicates it should |
2028 | * be disabled we disable the channel and re-enable it upon disassociation. | 2040 | * be disabled we disable the channel and re-enable it upon disassociation. |
2029 | */ | 2041 | */ |
2030 | enum nl80211_reg_initiator { | 2042 | enum nl80211_reg_initiator { |
2031 | NL80211_REGDOM_SET_BY_CORE, | 2043 | NL80211_REGDOM_SET_BY_CORE, |
2032 | NL80211_REGDOM_SET_BY_USER, | 2044 | NL80211_REGDOM_SET_BY_USER, |
2033 | NL80211_REGDOM_SET_BY_DRIVER, | 2045 | NL80211_REGDOM_SET_BY_DRIVER, |
2034 | NL80211_REGDOM_SET_BY_COUNTRY_IE, | 2046 | NL80211_REGDOM_SET_BY_COUNTRY_IE, |
2035 | }; | 2047 | }; |
2036 | 2048 | ||
2037 | /** | 2049 | /** |
2038 | * enum nl80211_reg_type - specifies the type of regulatory domain | 2050 | * enum nl80211_reg_type - specifies the type of regulatory domain |
2039 | * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains | 2051 | * @NL80211_REGDOM_TYPE_COUNTRY: the regulatory domain set is one that pertains |
2040 | * to a specific country. When this is set you can count on the | 2052 | * to a specific country. When this is set you can count on the |
2041 | * ISO / IEC 3166 alpha2 country code being valid. | 2053 | * ISO / IEC 3166 alpha2 country code being valid. |
2042 | * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory | 2054 | * @NL80211_REGDOM_TYPE_WORLD: the regulatory set domain is the world regulatory |
2043 | * domain. | 2055 | * domain. |
2044 | * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom | 2056 | * @NL80211_REGDOM_TYPE_CUSTOM_WORLD: the regulatory domain set is a custom |
2045 | * driver specific world regulatory domain. These do not apply system-wide | 2057 | * driver specific world regulatory domain. These do not apply system-wide |
2046 | * and are only applicable to the individual devices which have requested | 2058 | * and are only applicable to the individual devices which have requested |
2047 | * them to be applied. | 2059 | * them to be applied. |
2048 | * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product | 2060 | * @NL80211_REGDOM_TYPE_INTERSECTION: the regulatory domain set is the product |
2049 | * of an intersection between two regulatory domains -- the previously | 2061 | * of an intersection between two regulatory domains -- the previously |
2050 | * set regulatory domain on the system and the last accepted regulatory | 2062 | * set regulatory domain on the system and the last accepted regulatory |
2051 | * domain request to be processed. | 2063 | * domain request to be processed. |
2052 | */ | 2064 | */ |
2053 | enum nl80211_reg_type { | 2065 | enum nl80211_reg_type { |
2054 | NL80211_REGDOM_TYPE_COUNTRY, | 2066 | NL80211_REGDOM_TYPE_COUNTRY, |
2055 | NL80211_REGDOM_TYPE_WORLD, | 2067 | NL80211_REGDOM_TYPE_WORLD, |
2056 | NL80211_REGDOM_TYPE_CUSTOM_WORLD, | 2068 | NL80211_REGDOM_TYPE_CUSTOM_WORLD, |
2057 | NL80211_REGDOM_TYPE_INTERSECTION, | 2069 | NL80211_REGDOM_TYPE_INTERSECTION, |
2058 | }; | 2070 | }; |
2059 | 2071 | ||
2060 | /** | 2072 | /** |
2061 | * enum nl80211_reg_rule_attr - regulatory rule attributes | 2073 | * enum nl80211_reg_rule_attr - regulatory rule attributes |
2062 | * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved | 2074 | * @__NL80211_REG_RULE_ATTR_INVALID: attribute number 0 is reserved |
2063 | * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional | 2075 | * @NL80211_ATTR_REG_RULE_FLAGS: a set of flags which specify additional |
2064 | * considerations for a given frequency range. These are the | 2076 | * considerations for a given frequency range. These are the |
2065 | * &enum nl80211_reg_rule_flags. | 2077 | * &enum nl80211_reg_rule_flags. |
2066 | * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory | 2078 | * @NL80211_ATTR_FREQ_RANGE_START: starting frequencry for the regulatory |
2067 | * rule in KHz. This is not a center of frequency but an actual regulatory | 2079 | * rule in KHz. This is not a center of frequency but an actual regulatory |
2068 | * band edge. | 2080 | * band edge. |
2069 | * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule | 2081 | * @NL80211_ATTR_FREQ_RANGE_END: ending frequency for the regulatory rule |
2070 | * in KHz. This is not a center a frequency but an actual regulatory | 2082 | * in KHz. This is not a center a frequency but an actual regulatory |
2071 | * band edge. | 2083 | * band edge. |
2072 | * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this | 2084 | * @NL80211_ATTR_FREQ_RANGE_MAX_BW: maximum allowed bandwidth for this |
2073 | * frequency range, in KHz. | 2085 | * frequency range, in KHz. |
2074 | * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain | 2086 | * @NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN: the maximum allowed antenna gain |
2075 | * for a given frequency range. The value is in mBi (100 * dBi). | 2087 | * for a given frequency range. The value is in mBi (100 * dBi). |
2076 | * If you don't have one then don't send this. | 2088 | * If you don't have one then don't send this. |
2077 | * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for | 2089 | * @NL80211_ATTR_POWER_RULE_MAX_EIRP: the maximum allowed EIRP for |
2078 | * a given frequency range. The value is in mBm (100 * dBm). | 2090 | * a given frequency range. The value is in mBm (100 * dBm). |
2079 | * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number | 2091 | * @NL80211_REG_RULE_ATTR_MAX: highest regulatory rule attribute number |
2080 | * currently defined | 2092 | * currently defined |
2081 | * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use | 2093 | * @__NL80211_REG_RULE_ATTR_AFTER_LAST: internal use |
2082 | */ | 2094 | */ |
2083 | enum nl80211_reg_rule_attr { | 2095 | enum nl80211_reg_rule_attr { |
2084 | __NL80211_REG_RULE_ATTR_INVALID, | 2096 | __NL80211_REG_RULE_ATTR_INVALID, |
2085 | NL80211_ATTR_REG_RULE_FLAGS, | 2097 | NL80211_ATTR_REG_RULE_FLAGS, |
2086 | 2098 | ||
2087 | NL80211_ATTR_FREQ_RANGE_START, | 2099 | NL80211_ATTR_FREQ_RANGE_START, |
2088 | NL80211_ATTR_FREQ_RANGE_END, | 2100 | NL80211_ATTR_FREQ_RANGE_END, |
2089 | NL80211_ATTR_FREQ_RANGE_MAX_BW, | 2101 | NL80211_ATTR_FREQ_RANGE_MAX_BW, |
2090 | 2102 | ||
2091 | NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, | 2103 | NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, |
2092 | NL80211_ATTR_POWER_RULE_MAX_EIRP, | 2104 | NL80211_ATTR_POWER_RULE_MAX_EIRP, |
2093 | 2105 | ||
2094 | /* keep last */ | 2106 | /* keep last */ |
2095 | __NL80211_REG_RULE_ATTR_AFTER_LAST, | 2107 | __NL80211_REG_RULE_ATTR_AFTER_LAST, |
2096 | NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 | 2108 | NL80211_REG_RULE_ATTR_MAX = __NL80211_REG_RULE_ATTR_AFTER_LAST - 1 |
2097 | }; | 2109 | }; |
2098 | 2110 | ||
2099 | /** | 2111 | /** |
2100 | * enum nl80211_sched_scan_match_attr - scheduled scan match attributes | 2112 | * enum nl80211_sched_scan_match_attr - scheduled scan match attributes |
2101 | * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved | 2113 | * @__NL80211_SCHED_SCAN_MATCH_ATTR_INVALID: attribute number 0 is reserved |
2102 | * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, | 2114 | * @NL80211_SCHED_SCAN_MATCH_ATTR_SSID: SSID to be used for matching, |
2103 | * only report BSS with matching SSID. | 2115 | * only report BSS with matching SSID. |
2104 | * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a | 2116 | * @NL80211_SCHED_SCAN_MATCH_ATTR_RSSI: RSSI threshold (in dBm) for reporting a |
2105 | * BSS in scan results. Filtering is turned off if not specified. | 2117 | * BSS in scan results. Filtering is turned off if not specified. |
2106 | * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter | 2118 | * @NL80211_SCHED_SCAN_MATCH_ATTR_MAX: highest scheduled scan filter |
2107 | * attribute number currently defined | 2119 | * attribute number currently defined |
2108 | * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use | 2120 | * @__NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST: internal use |
2109 | */ | 2121 | */ |
2110 | enum nl80211_sched_scan_match_attr { | 2122 | enum nl80211_sched_scan_match_attr { |
2111 | __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID, | 2123 | __NL80211_SCHED_SCAN_MATCH_ATTR_INVALID, |
2112 | 2124 | ||
2113 | NL80211_SCHED_SCAN_MATCH_ATTR_SSID, | 2125 | NL80211_SCHED_SCAN_MATCH_ATTR_SSID, |
2114 | NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, | 2126 | NL80211_SCHED_SCAN_MATCH_ATTR_RSSI, |
2115 | 2127 | ||
2116 | /* keep last */ | 2128 | /* keep last */ |
2117 | __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, | 2129 | __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST, |
2118 | NL80211_SCHED_SCAN_MATCH_ATTR_MAX = | 2130 | NL80211_SCHED_SCAN_MATCH_ATTR_MAX = |
2119 | __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 | 2131 | __NL80211_SCHED_SCAN_MATCH_ATTR_AFTER_LAST - 1 |
2120 | }; | 2132 | }; |
2121 | 2133 | ||
2122 | /* only for backward compatibility */ | 2134 | /* only for backward compatibility */ |
2123 | #define NL80211_ATTR_SCHED_SCAN_MATCH_SSID NL80211_SCHED_SCAN_MATCH_ATTR_SSID | 2135 | #define NL80211_ATTR_SCHED_SCAN_MATCH_SSID NL80211_SCHED_SCAN_MATCH_ATTR_SSID |
2124 | 2136 | ||
2125 | /** | 2137 | /** |
2126 | * enum nl80211_reg_rule_flags - regulatory rule flags | 2138 | * enum nl80211_reg_rule_flags - regulatory rule flags |
2127 | * | 2139 | * |
2128 | * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed | 2140 | * @NL80211_RRF_NO_OFDM: OFDM modulation not allowed |
2129 | * @NL80211_RRF_NO_CCK: CCK modulation not allowed | 2141 | * @NL80211_RRF_NO_CCK: CCK modulation not allowed |
2130 | * @NL80211_RRF_NO_INDOOR: indoor operation not allowed | 2142 | * @NL80211_RRF_NO_INDOOR: indoor operation not allowed |
2131 | * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed | 2143 | * @NL80211_RRF_NO_OUTDOOR: outdoor operation not allowed |
2132 | * @NL80211_RRF_DFS: DFS support is required to be used | 2144 | * @NL80211_RRF_DFS: DFS support is required to be used |
2133 | * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links | 2145 | * @NL80211_RRF_PTP_ONLY: this is only for Point To Point links |
2134 | * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links | 2146 | * @NL80211_RRF_PTMP_ONLY: this is only for Point To Multi Point links |
2135 | * @NL80211_RRF_PASSIVE_SCAN: passive scan is required | 2147 | * @NL80211_RRF_PASSIVE_SCAN: passive scan is required |
2136 | * @NL80211_RRF_NO_IBSS: no IBSS is allowed | 2148 | * @NL80211_RRF_NO_IBSS: no IBSS is allowed |
2137 | */ | 2149 | */ |
2138 | enum nl80211_reg_rule_flags { | 2150 | enum nl80211_reg_rule_flags { |
2139 | NL80211_RRF_NO_OFDM = 1<<0, | 2151 | NL80211_RRF_NO_OFDM = 1<<0, |
2140 | NL80211_RRF_NO_CCK = 1<<1, | 2152 | NL80211_RRF_NO_CCK = 1<<1, |
2141 | NL80211_RRF_NO_INDOOR = 1<<2, | 2153 | NL80211_RRF_NO_INDOOR = 1<<2, |
2142 | NL80211_RRF_NO_OUTDOOR = 1<<3, | 2154 | NL80211_RRF_NO_OUTDOOR = 1<<3, |
2143 | NL80211_RRF_DFS = 1<<4, | 2155 | NL80211_RRF_DFS = 1<<4, |
2144 | NL80211_RRF_PTP_ONLY = 1<<5, | 2156 | NL80211_RRF_PTP_ONLY = 1<<5, |
2145 | NL80211_RRF_PTMP_ONLY = 1<<6, | 2157 | NL80211_RRF_PTMP_ONLY = 1<<6, |
2146 | NL80211_RRF_PASSIVE_SCAN = 1<<7, | 2158 | NL80211_RRF_PASSIVE_SCAN = 1<<7, |
2147 | NL80211_RRF_NO_IBSS = 1<<8, | 2159 | NL80211_RRF_NO_IBSS = 1<<8, |
2148 | }; | 2160 | }; |
2149 | 2161 | ||
2150 | /** | 2162 | /** |
2151 | * enum nl80211_dfs_regions - regulatory DFS regions | 2163 | * enum nl80211_dfs_regions - regulatory DFS regions |
2152 | * | 2164 | * |
2153 | * @NL80211_DFS_UNSET: Country has no DFS master region specified | 2165 | * @NL80211_DFS_UNSET: Country has no DFS master region specified |
2154 | * @NL80211_DFS_FCC: Country follows DFS master rules from FCC | 2166 | * @NL80211_DFS_FCC: Country follows DFS master rules from FCC |
2155 | * @NL80211_DFS_ETSI: Country follows DFS master rules from ETSI | 2167 | * @NL80211_DFS_ETSI: Country follows DFS master rules from ETSI |
2156 | * @NL80211_DFS_JP: Country follows DFS master rules from JP/MKK/Telec | 2168 | * @NL80211_DFS_JP: Country follows DFS master rules from JP/MKK/Telec |
2157 | */ | 2169 | */ |
2158 | enum nl80211_dfs_regions { | 2170 | enum nl80211_dfs_regions { |
2159 | NL80211_DFS_UNSET = 0, | 2171 | NL80211_DFS_UNSET = 0, |
2160 | NL80211_DFS_FCC = 1, | 2172 | NL80211_DFS_FCC = 1, |
2161 | NL80211_DFS_ETSI = 2, | 2173 | NL80211_DFS_ETSI = 2, |
2162 | NL80211_DFS_JP = 3, | 2174 | NL80211_DFS_JP = 3, |
2163 | }; | 2175 | }; |
2164 | 2176 | ||
2165 | /** | 2177 | /** |
2166 | * enum nl80211_user_reg_hint_type - type of user regulatory hint | 2178 | * enum nl80211_user_reg_hint_type - type of user regulatory hint |
2167 | * | 2179 | * |
2168 | * @NL80211_USER_REG_HINT_USER: a user sent the hint. This is always | 2180 | * @NL80211_USER_REG_HINT_USER: a user sent the hint. This is always |
2169 | * assumed if the attribute is not set. | 2181 | * assumed if the attribute is not set. |
2170 | * @NL80211_USER_REG_HINT_CELL_BASE: the hint comes from a cellular | 2182 | * @NL80211_USER_REG_HINT_CELL_BASE: the hint comes from a cellular |
2171 | * base station. Device drivers that have been tested to work | 2183 | * base station. Device drivers that have been tested to work |
2172 | * properly to support this type of hint can enable these hints | 2184 | * properly to support this type of hint can enable these hints |
2173 | * by setting the NL80211_FEATURE_CELL_BASE_REG_HINTS feature | 2185 | * by setting the NL80211_FEATURE_CELL_BASE_REG_HINTS feature |
2174 | * capability on the struct wiphy. The wireless core will | 2186 | * capability on the struct wiphy. The wireless core will |
2175 | * ignore all cell base station hints until at least one device | 2187 | * ignore all cell base station hints until at least one device |
2176 | * present has been registered with the wireless core that | 2188 | * present has been registered with the wireless core that |
2177 | * has listed NL80211_FEATURE_CELL_BASE_REG_HINTS as a | 2189 | * has listed NL80211_FEATURE_CELL_BASE_REG_HINTS as a |
2178 | * supported feature. | 2190 | * supported feature. |
2179 | */ | 2191 | */ |
2180 | enum nl80211_user_reg_hint_type { | 2192 | enum nl80211_user_reg_hint_type { |
2181 | NL80211_USER_REG_HINT_USER = 0, | 2193 | NL80211_USER_REG_HINT_USER = 0, |
2182 | NL80211_USER_REG_HINT_CELL_BASE = 1, | 2194 | NL80211_USER_REG_HINT_CELL_BASE = 1, |
2183 | }; | 2195 | }; |
2184 | 2196 | ||
2185 | /** | 2197 | /** |
2186 | * enum nl80211_survey_info - survey information | 2198 | * enum nl80211_survey_info - survey information |
2187 | * | 2199 | * |
2188 | * These attribute types are used with %NL80211_ATTR_SURVEY_INFO | 2200 | * These attribute types are used with %NL80211_ATTR_SURVEY_INFO |
2189 | * when getting information about a survey. | 2201 | * when getting information about a survey. |
2190 | * | 2202 | * |
2191 | * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved | 2203 | * @__NL80211_SURVEY_INFO_INVALID: attribute number 0 is reserved |
2192 | * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel | 2204 | * @NL80211_SURVEY_INFO_FREQUENCY: center frequency of channel |
2193 | * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) | 2205 | * @NL80211_SURVEY_INFO_NOISE: noise level of channel (u8, dBm) |
2194 | * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used | 2206 | * @NL80211_SURVEY_INFO_IN_USE: channel is currently being used |
2195 | * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio | 2207 | * @NL80211_SURVEY_INFO_CHANNEL_TIME: amount of time (in ms) that the radio |
2196 | * spent on this channel | 2208 | * spent on this channel |
2197 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary | 2209 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY: amount of the time the primary |
2198 | * channel was sensed busy (either due to activity or energy detect) | 2210 | * channel was sensed busy (either due to activity or energy detect) |
2199 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension | 2211 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY: amount of time the extension |
2200 | * channel was sensed busy | 2212 | * channel was sensed busy |
2201 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent | 2213 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_RX: amount of time the radio spent |
2202 | * receiving data | 2214 | * receiving data |
2203 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent | 2215 | * @NL80211_SURVEY_INFO_CHANNEL_TIME_TX: amount of time the radio spent |
2204 | * transmitting data | 2216 | * transmitting data |
2205 | * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number | 2217 | * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number |
2206 | * currently defined | 2218 | * currently defined |
2207 | * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use | 2219 | * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use |
2208 | */ | 2220 | */ |
2209 | enum nl80211_survey_info { | 2221 | enum nl80211_survey_info { |
2210 | __NL80211_SURVEY_INFO_INVALID, | 2222 | __NL80211_SURVEY_INFO_INVALID, |
2211 | NL80211_SURVEY_INFO_FREQUENCY, | 2223 | NL80211_SURVEY_INFO_FREQUENCY, |
2212 | NL80211_SURVEY_INFO_NOISE, | 2224 | NL80211_SURVEY_INFO_NOISE, |
2213 | NL80211_SURVEY_INFO_IN_USE, | 2225 | NL80211_SURVEY_INFO_IN_USE, |
2214 | NL80211_SURVEY_INFO_CHANNEL_TIME, | 2226 | NL80211_SURVEY_INFO_CHANNEL_TIME, |
2215 | NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, | 2227 | NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, |
2216 | NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, | 2228 | NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, |
2217 | NL80211_SURVEY_INFO_CHANNEL_TIME_RX, | 2229 | NL80211_SURVEY_INFO_CHANNEL_TIME_RX, |
2218 | NL80211_SURVEY_INFO_CHANNEL_TIME_TX, | 2230 | NL80211_SURVEY_INFO_CHANNEL_TIME_TX, |
2219 | 2231 | ||
2220 | /* keep last */ | 2232 | /* keep last */ |
2221 | __NL80211_SURVEY_INFO_AFTER_LAST, | 2233 | __NL80211_SURVEY_INFO_AFTER_LAST, |
2222 | NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 | 2234 | NL80211_SURVEY_INFO_MAX = __NL80211_SURVEY_INFO_AFTER_LAST - 1 |
2223 | }; | 2235 | }; |
2224 | 2236 | ||
2225 | /** | 2237 | /** |
2226 | * enum nl80211_mntr_flags - monitor configuration flags | 2238 | * enum nl80211_mntr_flags - monitor configuration flags |
2227 | * | 2239 | * |
2228 | * Monitor configuration flags. | 2240 | * Monitor configuration flags. |
2229 | * | 2241 | * |
2230 | * @__NL80211_MNTR_FLAG_INVALID: reserved | 2242 | * @__NL80211_MNTR_FLAG_INVALID: reserved |
2231 | * | 2243 | * |
2232 | * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS | 2244 | * @NL80211_MNTR_FLAG_FCSFAIL: pass frames with bad FCS |
2233 | * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP | 2245 | * @NL80211_MNTR_FLAG_PLCPFAIL: pass frames with bad PLCP |
2234 | * @NL80211_MNTR_FLAG_CONTROL: pass control frames | 2246 | * @NL80211_MNTR_FLAG_CONTROL: pass control frames |
2235 | * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering | 2247 | * @NL80211_MNTR_FLAG_OTHER_BSS: disable BSSID filtering |
2236 | * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing. | 2248 | * @NL80211_MNTR_FLAG_COOK_FRAMES: report frames after processing. |
2237 | * overrides all other flags. | 2249 | * overrides all other flags. |
2238 | * | 2250 | * |
2239 | * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use | 2251 | * @__NL80211_MNTR_FLAG_AFTER_LAST: internal use |
2240 | * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag | 2252 | * @NL80211_MNTR_FLAG_MAX: highest possible monitor flag |
2241 | */ | 2253 | */ |
2242 | enum nl80211_mntr_flags { | 2254 | enum nl80211_mntr_flags { |
2243 | __NL80211_MNTR_FLAG_INVALID, | 2255 | __NL80211_MNTR_FLAG_INVALID, |
2244 | NL80211_MNTR_FLAG_FCSFAIL, | 2256 | NL80211_MNTR_FLAG_FCSFAIL, |
2245 | NL80211_MNTR_FLAG_PLCPFAIL, | 2257 | NL80211_MNTR_FLAG_PLCPFAIL, |
2246 | NL80211_MNTR_FLAG_CONTROL, | 2258 | NL80211_MNTR_FLAG_CONTROL, |
2247 | NL80211_MNTR_FLAG_OTHER_BSS, | 2259 | NL80211_MNTR_FLAG_OTHER_BSS, |
2248 | NL80211_MNTR_FLAG_COOK_FRAMES, | 2260 | NL80211_MNTR_FLAG_COOK_FRAMES, |
2249 | 2261 | ||
2250 | /* keep last */ | 2262 | /* keep last */ |
2251 | __NL80211_MNTR_FLAG_AFTER_LAST, | 2263 | __NL80211_MNTR_FLAG_AFTER_LAST, |
2252 | NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1 | 2264 | NL80211_MNTR_FLAG_MAX = __NL80211_MNTR_FLAG_AFTER_LAST - 1 |
2253 | }; | 2265 | }; |
2254 | 2266 | ||
2255 | /** | 2267 | /** |
2268 | * enum nl80211_mesh_power_mode - mesh power save modes | ||
2269 | * | ||
2270 | * @NL80211_MESH_POWER_UNKNOWN: The mesh power mode of the mesh STA is | ||
2271 | * not known or has not been set yet. | ||
2272 | * @NL80211_MESH_POWER_ACTIVE: Active mesh power mode. The mesh STA is | ||
2273 | * in Awake state all the time. | ||
2274 | * @NL80211_MESH_POWER_LIGHT_SLEEP: Light sleep mode. The mesh STA will | ||
2275 | * alternate between Active and Doze states, but will wake up for | ||
2276 | * neighbor's beacons. | ||
2277 | * @NL80211_MESH_POWER_DEEP_SLEEP: Deep sleep mode. The mesh STA will | ||
2278 | * alternate between Active and Doze states, but may not wake up | ||
2279 | * for neighbor's beacons. | ||
2280 | * | ||
2281 | * @__NL80211_MESH_POWER_AFTER_LAST - internal use | ||
2282 | * @NL80211_MESH_POWER_MAX - highest possible power save level | ||
2283 | */ | ||
2284 | |||
2285 | enum nl80211_mesh_power_mode { | ||
2286 | NL80211_MESH_POWER_UNKNOWN, | ||
2287 | NL80211_MESH_POWER_ACTIVE, | ||
2288 | NL80211_MESH_POWER_LIGHT_SLEEP, | ||
2289 | NL80211_MESH_POWER_DEEP_SLEEP, | ||
2290 | |||
2291 | __NL80211_MESH_POWER_AFTER_LAST, | ||
2292 | NL80211_MESH_POWER_MAX = __NL80211_MESH_POWER_AFTER_LAST - 1 | ||
2293 | }; | ||
2294 | |||
2295 | /** | ||
2256 | * enum nl80211_meshconf_params - mesh configuration parameters | 2296 | * enum nl80211_meshconf_params - mesh configuration parameters |
2257 | * | 2297 | * |
2258 | * Mesh configuration parameters. These can be changed while the mesh is | 2298 | * Mesh configuration parameters. These can be changed while the mesh is |
2259 | * active. | 2299 | * active. |
2260 | * | 2300 | * |
2261 | * @__NL80211_MESHCONF_INVALID: internal use | 2301 | * @__NL80211_MESHCONF_INVALID: internal use |
2262 | * | 2302 | * |
2263 | * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in | 2303 | * @NL80211_MESHCONF_RETRY_TIMEOUT: specifies the initial retry timeout in |
2264 | * millisecond units, used by the Peer Link Open message | 2304 | * millisecond units, used by the Peer Link Open message |
2265 | * | 2305 | * |
2266 | * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in | 2306 | * @NL80211_MESHCONF_CONFIRM_TIMEOUT: specifies the initial confirm timeout, in |
2267 | * millisecond units, used by the peer link management to close a peer link | 2307 | * millisecond units, used by the peer link management to close a peer link |
2268 | * | 2308 | * |
2269 | * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in | 2309 | * @NL80211_MESHCONF_HOLDING_TIMEOUT: specifies the holding timeout, in |
2270 | * millisecond units | 2310 | * millisecond units |
2271 | * | 2311 | * |
2272 | * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed | 2312 | * @NL80211_MESHCONF_MAX_PEER_LINKS: maximum number of peer links allowed |
2273 | * on this mesh interface | 2313 | * on this mesh interface |
2274 | * | 2314 | * |
2275 | * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link | 2315 | * @NL80211_MESHCONF_MAX_RETRIES: specifies the maximum number of peer link |
2276 | * open retries that can be sent to establish a new peer link instance in a | 2316 | * open retries that can be sent to establish a new peer link instance in a |
2277 | * mesh | 2317 | * mesh |
2278 | * | 2318 | * |
2279 | * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh | 2319 | * @NL80211_MESHCONF_TTL: specifies the value of TTL field set at a source mesh |
2280 | * point. | 2320 | * point. |
2281 | * | 2321 | * |
2282 | * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically | 2322 | * @NL80211_MESHCONF_AUTO_OPEN_PLINKS: whether we should automatically |
2283 | * open peer links when we detect compatible mesh peers. | 2323 | * open peer links when we detect compatible mesh peers. |
2284 | * | 2324 | * |
2285 | * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames | 2325 | * @NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES: the number of action frames |
2286 | * containing a PREQ that an MP can send to a particular destination (path | 2326 | * containing a PREQ that an MP can send to a particular destination (path |
2287 | * target) | 2327 | * target) |
2288 | * | 2328 | * |
2289 | * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths | 2329 | * @NL80211_MESHCONF_PATH_REFRESH_TIME: how frequently to refresh mesh paths |
2290 | * (in milliseconds) | 2330 | * (in milliseconds) |
2291 | * | 2331 | * |
2292 | * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait | 2332 | * @NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT: minimum length of time to wait |
2293 | * until giving up on a path discovery (in milliseconds) | 2333 | * until giving up on a path discovery (in milliseconds) |
2294 | * | 2334 | * |
2295 | * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh | 2335 | * @NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT: The time (in TUs) for which mesh |
2296 | * points receiving a PREQ shall consider the forwarding information from | 2336 | * points receiving a PREQ shall consider the forwarding information from |
2297 | * the root to be valid. (TU = time unit) | 2337 | * the root to be valid. (TU = time unit) |
2298 | * | 2338 | * |
2299 | * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in | 2339 | * @NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL: The minimum interval of time (in |
2300 | * TUs) during which an MP can send only one action frame containing a PREQ | 2340 | * TUs) during which an MP can send only one action frame containing a PREQ |
2301 | * reference element | 2341 | * reference element |
2302 | * | 2342 | * |
2303 | * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) | 2343 | * @NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME: The interval of time (in TUs) |
2304 | * that it takes for an HWMP information element to propagate across the | 2344 | * that it takes for an HWMP information element to propagate across the |
2305 | * mesh | 2345 | * mesh |
2306 | * | 2346 | * |
2307 | * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not | 2347 | * @NL80211_MESHCONF_HWMP_ROOTMODE: whether root mode is enabled or not |
2308 | * | 2348 | * |
2309 | * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a | 2349 | * @NL80211_MESHCONF_ELEMENT_TTL: specifies the value of TTL field set at a |
2310 | * source mesh point for path selection elements. | 2350 | * source mesh point for path selection elements. |
2311 | * | 2351 | * |
2312 | * @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between | 2352 | * @NL80211_MESHCONF_HWMP_RANN_INTERVAL: The interval of time (in TUs) between |
2313 | * root announcements are transmitted. | 2353 | * root announcements are transmitted. |
2314 | * | 2354 | * |
2315 | * @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has | 2355 | * @NL80211_MESHCONF_GATE_ANNOUNCEMENTS: Advertise that this mesh station has |
2316 | * access to a broader network beyond the MBSS. This is done via Root | 2356 | * access to a broader network beyond the MBSS. This is done via Root |
2317 | * Announcement frames. | 2357 | * Announcement frames. |
2318 | * | 2358 | * |
2319 | * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in | 2359 | * @NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL: The minimum interval of time (in |
2320 | * TUs) during which a mesh STA can send only one Action frame containing a | 2360 | * TUs) during which a mesh STA can send only one Action frame containing a |
2321 | * PERR element. | 2361 | * PERR element. |
2322 | * | 2362 | * |
2323 | * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding | 2363 | * @NL80211_MESHCONF_FORWARDING: set Mesh STA as forwarding or non-forwarding |
2324 | * or forwarding entity (default is TRUE - forwarding entity) | 2364 | * or forwarding entity (default is TRUE - forwarding entity) |
2325 | * | 2365 | * |
2326 | * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the | 2366 | * @NL80211_MESHCONF_RSSI_THRESHOLD: RSSI threshold in dBm. This specifies the |
2327 | * threshold for average signal strength of candidate station to establish | 2367 | * threshold for average signal strength of candidate station to establish |
2328 | * a peer link. | 2368 | * a peer link. |
2329 | * | 2369 | * |
2330 | * @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors | 2370 | * @NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR: maximum number of neighbors |
2331 | * to synchronize to for 11s default synchronization method | 2371 | * to synchronize to for 11s default synchronization method |
2332 | * (see 11C.12.2.2) | 2372 | * (see 11C.12.2.2) |
2333 | * | 2373 | * |
2334 | * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode. | 2374 | * @NL80211_MESHCONF_HT_OPMODE: set mesh HT protection mode. |
2335 | * | 2375 | * |
2336 | * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute | 2376 | * @NL80211_MESHCONF_ATTR_MAX: highest possible mesh configuration attribute |
2337 | * | 2377 | * |
2338 | * @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for | 2378 | * @NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT: The time (in TUs) for |
2339 | * which mesh STAs receiving a proactive PREQ shall consider the forwarding | 2379 | * which mesh STAs receiving a proactive PREQ shall consider the forwarding |
2340 | * information to the root mesh STA to be valid. | 2380 | * information to the root mesh STA to be valid. |
2341 | * | 2381 | * |
2342 | * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between | 2382 | * @NL80211_MESHCONF_HWMP_ROOT_INTERVAL: The interval of time (in TUs) between |
2343 | * proactive PREQs are transmitted. | 2383 | * proactive PREQs are transmitted. |
2344 | * | 2384 | * |
2345 | * @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time | 2385 | * @NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL: The minimum interval of time |
2346 | * (in TUs) during which a mesh STA can send only one Action frame | 2386 | * (in TUs) during which a mesh STA can send only one Action frame |
2347 | * containing a PREQ element for root path confirmation. | 2387 | * containing a PREQ element for root path confirmation. |
2348 | * | 2388 | * |
2389 | * @NL80211_MESHCONF_POWER_MODE: Default mesh power mode for new peer links. | ||
2390 | * type &enum nl80211_mesh_power_mode (u32) | ||
2391 | * | ||
2392 | * @NL80211_MESHCONF_AWAKE_WINDOW: awake window duration (in TUs) | ||
2393 | * | ||
2349 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use | 2394 | * @__NL80211_MESHCONF_ATTR_AFTER_LAST: internal use |
2350 | */ | 2395 | */ |
2351 | enum nl80211_meshconf_params { | 2396 | enum nl80211_meshconf_params { |
2352 | __NL80211_MESHCONF_INVALID, | 2397 | __NL80211_MESHCONF_INVALID, |
2353 | NL80211_MESHCONF_RETRY_TIMEOUT, | 2398 | NL80211_MESHCONF_RETRY_TIMEOUT, |
2354 | NL80211_MESHCONF_CONFIRM_TIMEOUT, | 2399 | NL80211_MESHCONF_CONFIRM_TIMEOUT, |
2355 | NL80211_MESHCONF_HOLDING_TIMEOUT, | 2400 | NL80211_MESHCONF_HOLDING_TIMEOUT, |
2356 | NL80211_MESHCONF_MAX_PEER_LINKS, | 2401 | NL80211_MESHCONF_MAX_PEER_LINKS, |
2357 | NL80211_MESHCONF_MAX_RETRIES, | 2402 | NL80211_MESHCONF_MAX_RETRIES, |
2358 | NL80211_MESHCONF_TTL, | 2403 | NL80211_MESHCONF_TTL, |
2359 | NL80211_MESHCONF_AUTO_OPEN_PLINKS, | 2404 | NL80211_MESHCONF_AUTO_OPEN_PLINKS, |
2360 | NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, | 2405 | NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, |
2361 | NL80211_MESHCONF_PATH_REFRESH_TIME, | 2406 | NL80211_MESHCONF_PATH_REFRESH_TIME, |
2362 | NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, | 2407 | NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, |
2363 | NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, | 2408 | NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, |
2364 | NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, | 2409 | NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, |
2365 | NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, | 2410 | NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, |
2366 | NL80211_MESHCONF_HWMP_ROOTMODE, | 2411 | NL80211_MESHCONF_HWMP_ROOTMODE, |
2367 | NL80211_MESHCONF_ELEMENT_TTL, | 2412 | NL80211_MESHCONF_ELEMENT_TTL, |
2368 | NL80211_MESHCONF_HWMP_RANN_INTERVAL, | 2413 | NL80211_MESHCONF_HWMP_RANN_INTERVAL, |
2369 | NL80211_MESHCONF_GATE_ANNOUNCEMENTS, | 2414 | NL80211_MESHCONF_GATE_ANNOUNCEMENTS, |
2370 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, | 2415 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, |
2371 | NL80211_MESHCONF_FORWARDING, | 2416 | NL80211_MESHCONF_FORWARDING, |
2372 | NL80211_MESHCONF_RSSI_THRESHOLD, | 2417 | NL80211_MESHCONF_RSSI_THRESHOLD, |
2373 | NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, | 2418 | NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, |
2374 | NL80211_MESHCONF_HT_OPMODE, | 2419 | NL80211_MESHCONF_HT_OPMODE, |
2375 | NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, | 2420 | NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, |
2376 | NL80211_MESHCONF_HWMP_ROOT_INTERVAL, | 2421 | NL80211_MESHCONF_HWMP_ROOT_INTERVAL, |
2377 | NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, | 2422 | NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, |
2423 | NL80211_MESHCONF_POWER_MODE, | ||
2424 | NL80211_MESHCONF_AWAKE_WINDOW, | ||
2378 | 2425 | ||
2379 | /* keep last */ | 2426 | /* keep last */ |
2380 | __NL80211_MESHCONF_ATTR_AFTER_LAST, | 2427 | __NL80211_MESHCONF_ATTR_AFTER_LAST, |
2381 | NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1 | 2428 | NL80211_MESHCONF_ATTR_MAX = __NL80211_MESHCONF_ATTR_AFTER_LAST - 1 |
2382 | }; | 2429 | }; |
2383 | 2430 | ||
2384 | /** | 2431 | /** |
2385 | * enum nl80211_mesh_setup_params - mesh setup parameters | 2432 | * enum nl80211_mesh_setup_params - mesh setup parameters |
2386 | * | 2433 | * |
2387 | * Mesh setup parameters. These are used to start/join a mesh and cannot be | 2434 | * Mesh setup parameters. These are used to start/join a mesh and cannot be |
2388 | * changed while the mesh is active. | 2435 | * changed while the mesh is active. |
2389 | * | 2436 | * |
2390 | * @__NL80211_MESH_SETUP_INVALID: Internal use | 2437 | * @__NL80211_MESH_SETUP_INVALID: Internal use |
2391 | * | 2438 | * |
2392 | * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a | 2439 | * @NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL: Enable this option to use a |
2393 | * vendor specific path selection algorithm or disable it to use the | 2440 | * vendor specific path selection algorithm or disable it to use the |
2394 | * default HWMP. | 2441 | * default HWMP. |
2395 | * | 2442 | * |
2396 | * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a | 2443 | * @NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC: Enable this option to use a |
2397 | * vendor specific path metric or disable it to use the default Airtime | 2444 | * vendor specific path metric or disable it to use the default Airtime |
2398 | * metric. | 2445 | * metric. |
2399 | * | 2446 | * |
2400 | * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a | 2447 | * @NL80211_MESH_SETUP_IE: Information elements for this mesh, for instance, a |
2401 | * robust security network ie, or a vendor specific information element | 2448 | * robust security network ie, or a vendor specific information element |
2402 | * that vendors will use to identify the path selection methods and | 2449 | * that vendors will use to identify the path selection methods and |
2403 | * metrics in use. | 2450 | * metrics in use. |
2404 | * | 2451 | * |
2405 | * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication | 2452 | * @NL80211_MESH_SETUP_USERSPACE_AUTH: Enable this option if an authentication |
2406 | * daemon will be authenticating mesh candidates. | 2453 | * daemon will be authenticating mesh candidates. |
2407 | * | 2454 | * |
2408 | * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication | 2455 | * @NL80211_MESH_SETUP_USERSPACE_AMPE: Enable this option if an authentication |
2409 | * daemon will be securing peer link frames. AMPE is a secured version of | 2456 | * daemon will be securing peer link frames. AMPE is a secured version of |
2410 | * Mesh Peering Management (MPM) and is implemented with the assistance of | 2457 | * Mesh Peering Management (MPM) and is implemented with the assistance of |
2411 | * a userspace daemon. When this flag is set, the kernel will send peer | 2458 | * a userspace daemon. When this flag is set, the kernel will send peer |
2412 | * management frames to a userspace daemon that will implement AMPE | 2459 | * management frames to a userspace daemon that will implement AMPE |
2413 | * functionality (security capabilities selection, key confirmation, and | 2460 | * functionality (security capabilities selection, key confirmation, and |
2414 | * key management). When the flag is unset (default), the kernel can | 2461 | * key management). When the flag is unset (default), the kernel can |
2415 | * autonomously complete (unsecured) mesh peering without the need of a | 2462 | * autonomously complete (unsecured) mesh peering without the need of a |
2416 | * userspace daemon. | 2463 | * userspace daemon. |
2417 | * | 2464 | * |
2418 | * @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a | 2465 | * @NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC: Enable this option to use a |
2419 | * vendor specific synchronization method or disable it to use the default | 2466 | * vendor specific synchronization method or disable it to use the default |
2420 | * neighbor offset synchronization | 2467 | * neighbor offset synchronization |
2421 | * | 2468 | * |
2422 | * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number | 2469 | * @NL80211_MESH_SETUP_ATTR_MAX: highest possible mesh setup attribute number |
2423 | * | 2470 | * |
2424 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use | 2471 | * @__NL80211_MESH_SETUP_ATTR_AFTER_LAST: Internal use |
2425 | */ | 2472 | */ |
2426 | enum nl80211_mesh_setup_params { | 2473 | enum nl80211_mesh_setup_params { |
2427 | __NL80211_MESH_SETUP_INVALID, | 2474 | __NL80211_MESH_SETUP_INVALID, |
2428 | NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, | 2475 | NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL, |
2429 | NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, | 2476 | NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC, |
2430 | NL80211_MESH_SETUP_IE, | 2477 | NL80211_MESH_SETUP_IE, |
2431 | NL80211_MESH_SETUP_USERSPACE_AUTH, | 2478 | NL80211_MESH_SETUP_USERSPACE_AUTH, |
2432 | NL80211_MESH_SETUP_USERSPACE_AMPE, | 2479 | NL80211_MESH_SETUP_USERSPACE_AMPE, |
2433 | NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC, | 2480 | NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC, |
2434 | 2481 | ||
2435 | /* keep last */ | 2482 | /* keep last */ |
2436 | __NL80211_MESH_SETUP_ATTR_AFTER_LAST, | 2483 | __NL80211_MESH_SETUP_ATTR_AFTER_LAST, |
2437 | NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1 | 2484 | NL80211_MESH_SETUP_ATTR_MAX = __NL80211_MESH_SETUP_ATTR_AFTER_LAST - 1 |
2438 | }; | 2485 | }; |
2439 | 2486 | ||
2440 | /** | 2487 | /** |
2441 | * enum nl80211_txq_attr - TX queue parameter attributes | 2488 | * enum nl80211_txq_attr - TX queue parameter attributes |
2442 | * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved | 2489 | * @__NL80211_TXQ_ATTR_INVALID: Attribute number 0 is reserved |
2443 | * @NL80211_TXQ_ATTR_AC: AC identifier (NL80211_AC_*) | 2490 | * @NL80211_TXQ_ATTR_AC: AC identifier (NL80211_AC_*) |
2444 | * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning | 2491 | * @NL80211_TXQ_ATTR_TXOP: Maximum burst time in units of 32 usecs, 0 meaning |
2445 | * disabled | 2492 | * disabled |
2446 | * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form | 2493 | * @NL80211_TXQ_ATTR_CWMIN: Minimum contention window [a value of the form |
2447 | * 2^n-1 in the range 1..32767] | 2494 | * 2^n-1 in the range 1..32767] |
2448 | * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form | 2495 | * @NL80211_TXQ_ATTR_CWMAX: Maximum contention window [a value of the form |
2449 | * 2^n-1 in the range 1..32767] | 2496 | * 2^n-1 in the range 1..32767] |
2450 | * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255] | 2497 | * @NL80211_TXQ_ATTR_AIFS: Arbitration interframe space [0..255] |
2451 | * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal | 2498 | * @__NL80211_TXQ_ATTR_AFTER_LAST: Internal |
2452 | * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number | 2499 | * @NL80211_TXQ_ATTR_MAX: Maximum TXQ attribute number |
2453 | */ | 2500 | */ |
2454 | enum nl80211_txq_attr { | 2501 | enum nl80211_txq_attr { |
2455 | __NL80211_TXQ_ATTR_INVALID, | 2502 | __NL80211_TXQ_ATTR_INVALID, |
2456 | NL80211_TXQ_ATTR_AC, | 2503 | NL80211_TXQ_ATTR_AC, |
2457 | NL80211_TXQ_ATTR_TXOP, | 2504 | NL80211_TXQ_ATTR_TXOP, |
2458 | NL80211_TXQ_ATTR_CWMIN, | 2505 | NL80211_TXQ_ATTR_CWMIN, |
2459 | NL80211_TXQ_ATTR_CWMAX, | 2506 | NL80211_TXQ_ATTR_CWMAX, |
2460 | NL80211_TXQ_ATTR_AIFS, | 2507 | NL80211_TXQ_ATTR_AIFS, |
2461 | 2508 | ||
2462 | /* keep last */ | 2509 | /* keep last */ |
2463 | __NL80211_TXQ_ATTR_AFTER_LAST, | 2510 | __NL80211_TXQ_ATTR_AFTER_LAST, |
2464 | NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1 | 2511 | NL80211_TXQ_ATTR_MAX = __NL80211_TXQ_ATTR_AFTER_LAST - 1 |
2465 | }; | 2512 | }; |
2466 | 2513 | ||
2467 | enum nl80211_ac { | 2514 | enum nl80211_ac { |
2468 | NL80211_AC_VO, | 2515 | NL80211_AC_VO, |
2469 | NL80211_AC_VI, | 2516 | NL80211_AC_VI, |
2470 | NL80211_AC_BE, | 2517 | NL80211_AC_BE, |
2471 | NL80211_AC_BK, | 2518 | NL80211_AC_BK, |
2472 | NL80211_NUM_ACS | 2519 | NL80211_NUM_ACS |
2473 | }; | 2520 | }; |
2474 | 2521 | ||
2475 | /* backward compat */ | 2522 | /* backward compat */ |
2476 | #define NL80211_TXQ_ATTR_QUEUE NL80211_TXQ_ATTR_AC | 2523 | #define NL80211_TXQ_ATTR_QUEUE NL80211_TXQ_ATTR_AC |
2477 | #define NL80211_TXQ_Q_VO NL80211_AC_VO | 2524 | #define NL80211_TXQ_Q_VO NL80211_AC_VO |
2478 | #define NL80211_TXQ_Q_VI NL80211_AC_VI | 2525 | #define NL80211_TXQ_Q_VI NL80211_AC_VI |
2479 | #define NL80211_TXQ_Q_BE NL80211_AC_BE | 2526 | #define NL80211_TXQ_Q_BE NL80211_AC_BE |
2480 | #define NL80211_TXQ_Q_BK NL80211_AC_BK | 2527 | #define NL80211_TXQ_Q_BK NL80211_AC_BK |
2481 | 2528 | ||
2482 | /** | 2529 | /** |
2483 | * enum nl80211_channel_type - channel type | 2530 | * enum nl80211_channel_type - channel type |
2484 | * @NL80211_CHAN_NO_HT: 20 MHz, non-HT channel | 2531 | * @NL80211_CHAN_NO_HT: 20 MHz, non-HT channel |
2485 | * @NL80211_CHAN_HT20: 20 MHz HT channel | 2532 | * @NL80211_CHAN_HT20: 20 MHz HT channel |
2486 | * @NL80211_CHAN_HT40MINUS: HT40 channel, secondary channel | 2533 | * @NL80211_CHAN_HT40MINUS: HT40 channel, secondary channel |
2487 | * below the control channel | 2534 | * below the control channel |
2488 | * @NL80211_CHAN_HT40PLUS: HT40 channel, secondary channel | 2535 | * @NL80211_CHAN_HT40PLUS: HT40 channel, secondary channel |
2489 | * above the control channel | 2536 | * above the control channel |
2490 | */ | 2537 | */ |
2491 | enum nl80211_channel_type { | 2538 | enum nl80211_channel_type { |
2492 | NL80211_CHAN_NO_HT, | 2539 | NL80211_CHAN_NO_HT, |
2493 | NL80211_CHAN_HT20, | 2540 | NL80211_CHAN_HT20, |
2494 | NL80211_CHAN_HT40MINUS, | 2541 | NL80211_CHAN_HT40MINUS, |
2495 | NL80211_CHAN_HT40PLUS | 2542 | NL80211_CHAN_HT40PLUS |
2496 | }; | 2543 | }; |
2497 | 2544 | ||
2498 | /** | 2545 | /** |
2499 | * enum nl80211_chan_width - channel width definitions | 2546 | * enum nl80211_chan_width - channel width definitions |
2500 | * | 2547 | * |
2501 | * These values are used with the %NL80211_ATTR_CHANNEL_WIDTH | 2548 | * These values are used with the %NL80211_ATTR_CHANNEL_WIDTH |
2502 | * attribute. | 2549 | * attribute. |
2503 | * | 2550 | * |
2504 | * @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel | 2551 | * @NL80211_CHAN_WIDTH_20_NOHT: 20 MHz, non-HT channel |
2505 | * @NL80211_CHAN_WIDTH_20: 20 MHz HT channel | 2552 | * @NL80211_CHAN_WIDTH_20: 20 MHz HT channel |
2506 | * @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 | 2553 | * @NL80211_CHAN_WIDTH_40: 40 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 |
2507 | * attribute must be provided as well | 2554 | * attribute must be provided as well |
2508 | * @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 | 2555 | * @NL80211_CHAN_WIDTH_80: 80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 |
2509 | * attribute must be provided as well | 2556 | * attribute must be provided as well |
2510 | * @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 | 2557 | * @NL80211_CHAN_WIDTH_80P80: 80+80 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 |
2511 | * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well | 2558 | * and %NL80211_ATTR_CENTER_FREQ2 attributes must be provided as well |
2512 | * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 | 2559 | * @NL80211_CHAN_WIDTH_160: 160 MHz channel, the %NL80211_ATTR_CENTER_FREQ1 |
2513 | * attribute must be provided as well | 2560 | * attribute must be provided as well |
2514 | */ | 2561 | */ |
2515 | enum nl80211_chan_width { | 2562 | enum nl80211_chan_width { |
2516 | NL80211_CHAN_WIDTH_20_NOHT, | 2563 | NL80211_CHAN_WIDTH_20_NOHT, |
2517 | NL80211_CHAN_WIDTH_20, | 2564 | NL80211_CHAN_WIDTH_20, |
2518 | NL80211_CHAN_WIDTH_40, | 2565 | NL80211_CHAN_WIDTH_40, |
2519 | NL80211_CHAN_WIDTH_80, | 2566 | NL80211_CHAN_WIDTH_80, |
2520 | NL80211_CHAN_WIDTH_80P80, | 2567 | NL80211_CHAN_WIDTH_80P80, |
2521 | NL80211_CHAN_WIDTH_160, | 2568 | NL80211_CHAN_WIDTH_160, |
2522 | }; | 2569 | }; |
2523 | 2570 | ||
2524 | /** | 2571 | /** |
2525 | * enum nl80211_bss - netlink attributes for a BSS | 2572 | * enum nl80211_bss - netlink attributes for a BSS |
2526 | * | 2573 | * |
2527 | * @__NL80211_BSS_INVALID: invalid | 2574 | * @__NL80211_BSS_INVALID: invalid |
2528 | * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) | 2575 | * @NL80211_BSS_BSSID: BSSID of the BSS (6 octets) |
2529 | * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) | 2576 | * @NL80211_BSS_FREQUENCY: frequency in MHz (u32) |
2530 | * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) | 2577 | * @NL80211_BSS_TSF: TSF of the received probe response/beacon (u64) |
2531 | * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) | 2578 | * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) |
2532 | * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16) | 2579 | * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16) |
2533 | * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the | 2580 | * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the |
2534 | * raw information elements from the probe response/beacon (bin); | 2581 | * raw information elements from the probe response/beacon (bin); |
2535 | * if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are | 2582 | * if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are |
2536 | * from a Probe Response frame; otherwise they are from a Beacon frame. | 2583 | * from a Probe Response frame; otherwise they are from a Beacon frame. |
2537 | * However, if the driver does not indicate the source of the IEs, these | 2584 | * However, if the driver does not indicate the source of the IEs, these |
2538 | * IEs may be from either frame subtype. | 2585 | * IEs may be from either frame subtype. |
2539 | * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon | 2586 | * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon |
2540 | * in mBm (100 * dBm) (s32) | 2587 | * in mBm (100 * dBm) (s32) |
2541 | * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon | 2588 | * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon |
2542 | * in unspecified units, scaled to 0..100 (u8) | 2589 | * in unspecified units, scaled to 0..100 (u8) |
2543 | * @NL80211_BSS_STATUS: status, if this BSS is "used" | 2590 | * @NL80211_BSS_STATUS: status, if this BSS is "used" |
2544 | * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms | 2591 | * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms |
2545 | * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information | 2592 | * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information |
2546 | * elements from a Beacon frame (bin); not present if no Beacon frame has | 2593 | * elements from a Beacon frame (bin); not present if no Beacon frame has |
2547 | * yet been received | 2594 | * yet been received |
2548 | * @__NL80211_BSS_AFTER_LAST: internal | 2595 | * @__NL80211_BSS_AFTER_LAST: internal |
2549 | * @NL80211_BSS_MAX: highest BSS attribute | 2596 | * @NL80211_BSS_MAX: highest BSS attribute |
2550 | */ | 2597 | */ |
2551 | enum nl80211_bss { | 2598 | enum nl80211_bss { |
2552 | __NL80211_BSS_INVALID, | 2599 | __NL80211_BSS_INVALID, |
2553 | NL80211_BSS_BSSID, | 2600 | NL80211_BSS_BSSID, |
2554 | NL80211_BSS_FREQUENCY, | 2601 | NL80211_BSS_FREQUENCY, |
2555 | NL80211_BSS_TSF, | 2602 | NL80211_BSS_TSF, |
2556 | NL80211_BSS_BEACON_INTERVAL, | 2603 | NL80211_BSS_BEACON_INTERVAL, |
2557 | NL80211_BSS_CAPABILITY, | 2604 | NL80211_BSS_CAPABILITY, |
2558 | NL80211_BSS_INFORMATION_ELEMENTS, | 2605 | NL80211_BSS_INFORMATION_ELEMENTS, |
2559 | NL80211_BSS_SIGNAL_MBM, | 2606 | NL80211_BSS_SIGNAL_MBM, |
2560 | NL80211_BSS_SIGNAL_UNSPEC, | 2607 | NL80211_BSS_SIGNAL_UNSPEC, |
2561 | NL80211_BSS_STATUS, | 2608 | NL80211_BSS_STATUS, |
2562 | NL80211_BSS_SEEN_MS_AGO, | 2609 | NL80211_BSS_SEEN_MS_AGO, |
2563 | NL80211_BSS_BEACON_IES, | 2610 | NL80211_BSS_BEACON_IES, |
2564 | 2611 | ||
2565 | /* keep last */ | 2612 | /* keep last */ |
2566 | __NL80211_BSS_AFTER_LAST, | 2613 | __NL80211_BSS_AFTER_LAST, |
2567 | NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1 | 2614 | NL80211_BSS_MAX = __NL80211_BSS_AFTER_LAST - 1 |
2568 | }; | 2615 | }; |
2569 | 2616 | ||
2570 | /** | 2617 | /** |
2571 | * enum nl80211_bss_status - BSS "status" | 2618 | * enum nl80211_bss_status - BSS "status" |
2572 | * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. | 2619 | * @NL80211_BSS_STATUS_AUTHENTICATED: Authenticated with this BSS. |
2573 | * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. | 2620 | * @NL80211_BSS_STATUS_ASSOCIATED: Associated with this BSS. |
2574 | * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. | 2621 | * @NL80211_BSS_STATUS_IBSS_JOINED: Joined to this IBSS. |
2575 | * | 2622 | * |
2576 | * The BSS status is a BSS attribute in scan dumps, which | 2623 | * The BSS status is a BSS attribute in scan dumps, which |
2577 | * indicates the status the interface has wrt. this BSS. | 2624 | * indicates the status the interface has wrt. this BSS. |
2578 | */ | 2625 | */ |
2579 | enum nl80211_bss_status { | 2626 | enum nl80211_bss_status { |
2580 | NL80211_BSS_STATUS_AUTHENTICATED, | 2627 | NL80211_BSS_STATUS_AUTHENTICATED, |
2581 | NL80211_BSS_STATUS_ASSOCIATED, | 2628 | NL80211_BSS_STATUS_ASSOCIATED, |
2582 | NL80211_BSS_STATUS_IBSS_JOINED, | 2629 | NL80211_BSS_STATUS_IBSS_JOINED, |
2583 | }; | 2630 | }; |
2584 | 2631 | ||
2585 | /** | 2632 | /** |
2586 | * enum nl80211_auth_type - AuthenticationType | 2633 | * enum nl80211_auth_type - AuthenticationType |
2587 | * | 2634 | * |
2588 | * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication | 2635 | * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication |
2589 | * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) | 2636 | * @NL80211_AUTHTYPE_SHARED_KEY: Shared Key authentication (WEP only) |
2590 | * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) | 2637 | * @NL80211_AUTHTYPE_FT: Fast BSS Transition (IEEE 802.11r) |
2591 | * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) | 2638 | * @NL80211_AUTHTYPE_NETWORK_EAP: Network EAP (some Cisco APs and mainly LEAP) |
2592 | * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals | 2639 | * @NL80211_AUTHTYPE_SAE: Simultaneous authentication of equals |
2593 | * @__NL80211_AUTHTYPE_NUM: internal | 2640 | * @__NL80211_AUTHTYPE_NUM: internal |
2594 | * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm | 2641 | * @NL80211_AUTHTYPE_MAX: maximum valid auth algorithm |
2595 | * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by | 2642 | * @NL80211_AUTHTYPE_AUTOMATIC: determine automatically (if necessary by |
2596 | * trying multiple times); this is invalid in netlink -- leave out | 2643 | * trying multiple times); this is invalid in netlink -- leave out |
2597 | * the attribute for this on CONNECT commands. | 2644 | * the attribute for this on CONNECT commands. |
2598 | */ | 2645 | */ |
2599 | enum nl80211_auth_type { | 2646 | enum nl80211_auth_type { |
2600 | NL80211_AUTHTYPE_OPEN_SYSTEM, | 2647 | NL80211_AUTHTYPE_OPEN_SYSTEM, |
2601 | NL80211_AUTHTYPE_SHARED_KEY, | 2648 | NL80211_AUTHTYPE_SHARED_KEY, |
2602 | NL80211_AUTHTYPE_FT, | 2649 | NL80211_AUTHTYPE_FT, |
2603 | NL80211_AUTHTYPE_NETWORK_EAP, | 2650 | NL80211_AUTHTYPE_NETWORK_EAP, |
2604 | NL80211_AUTHTYPE_SAE, | 2651 | NL80211_AUTHTYPE_SAE, |
2605 | 2652 | ||
2606 | /* keep last */ | 2653 | /* keep last */ |
2607 | __NL80211_AUTHTYPE_NUM, | 2654 | __NL80211_AUTHTYPE_NUM, |
2608 | NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1, | 2655 | NL80211_AUTHTYPE_MAX = __NL80211_AUTHTYPE_NUM - 1, |
2609 | NL80211_AUTHTYPE_AUTOMATIC | 2656 | NL80211_AUTHTYPE_AUTOMATIC |
2610 | }; | 2657 | }; |
2611 | 2658 | ||
2612 | /** | 2659 | /** |
2613 | * enum nl80211_key_type - Key Type | 2660 | * enum nl80211_key_type - Key Type |
2614 | * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key | 2661 | * @NL80211_KEYTYPE_GROUP: Group (broadcast/multicast) key |
2615 | * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key | 2662 | * @NL80211_KEYTYPE_PAIRWISE: Pairwise (unicast/individual) key |
2616 | * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) | 2663 | * @NL80211_KEYTYPE_PEERKEY: PeerKey (DLS) |
2617 | * @NUM_NL80211_KEYTYPES: number of defined key types | 2664 | * @NUM_NL80211_KEYTYPES: number of defined key types |
2618 | */ | 2665 | */ |
2619 | enum nl80211_key_type { | 2666 | enum nl80211_key_type { |
2620 | NL80211_KEYTYPE_GROUP, | 2667 | NL80211_KEYTYPE_GROUP, |
2621 | NL80211_KEYTYPE_PAIRWISE, | 2668 | NL80211_KEYTYPE_PAIRWISE, |
2622 | NL80211_KEYTYPE_PEERKEY, | 2669 | NL80211_KEYTYPE_PEERKEY, |
2623 | 2670 | ||
2624 | NUM_NL80211_KEYTYPES | 2671 | NUM_NL80211_KEYTYPES |
2625 | }; | 2672 | }; |
2626 | 2673 | ||
2627 | /** | 2674 | /** |
2628 | * enum nl80211_mfp - Management frame protection state | 2675 | * enum nl80211_mfp - Management frame protection state |
2629 | * @NL80211_MFP_NO: Management frame protection not used | 2676 | * @NL80211_MFP_NO: Management frame protection not used |
2630 | * @NL80211_MFP_REQUIRED: Management frame protection required | 2677 | * @NL80211_MFP_REQUIRED: Management frame protection required |
2631 | */ | 2678 | */ |
2632 | enum nl80211_mfp { | 2679 | enum nl80211_mfp { |
2633 | NL80211_MFP_NO, | 2680 | NL80211_MFP_NO, |
2634 | NL80211_MFP_REQUIRED, | 2681 | NL80211_MFP_REQUIRED, |
2635 | }; | 2682 | }; |
2636 | 2683 | ||
2637 | enum nl80211_wpa_versions { | 2684 | enum nl80211_wpa_versions { |
2638 | NL80211_WPA_VERSION_1 = 1 << 0, | 2685 | NL80211_WPA_VERSION_1 = 1 << 0, |
2639 | NL80211_WPA_VERSION_2 = 1 << 1, | 2686 | NL80211_WPA_VERSION_2 = 1 << 1, |
2640 | }; | 2687 | }; |
2641 | 2688 | ||
2642 | /** | 2689 | /** |
2643 | * enum nl80211_key_default_types - key default types | 2690 | * enum nl80211_key_default_types - key default types |
2644 | * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid | 2691 | * @__NL80211_KEY_DEFAULT_TYPE_INVALID: invalid |
2645 | * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default | 2692 | * @NL80211_KEY_DEFAULT_TYPE_UNICAST: key should be used as default |
2646 | * unicast key | 2693 | * unicast key |
2647 | * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default | 2694 | * @NL80211_KEY_DEFAULT_TYPE_MULTICAST: key should be used as default |
2648 | * multicast key | 2695 | * multicast key |
2649 | * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types | 2696 | * @NUM_NL80211_KEY_DEFAULT_TYPES: number of default types |
2650 | */ | 2697 | */ |
2651 | enum nl80211_key_default_types { | 2698 | enum nl80211_key_default_types { |
2652 | __NL80211_KEY_DEFAULT_TYPE_INVALID, | 2699 | __NL80211_KEY_DEFAULT_TYPE_INVALID, |
2653 | NL80211_KEY_DEFAULT_TYPE_UNICAST, | 2700 | NL80211_KEY_DEFAULT_TYPE_UNICAST, |
2654 | NL80211_KEY_DEFAULT_TYPE_MULTICAST, | 2701 | NL80211_KEY_DEFAULT_TYPE_MULTICAST, |
2655 | 2702 | ||
2656 | NUM_NL80211_KEY_DEFAULT_TYPES | 2703 | NUM_NL80211_KEY_DEFAULT_TYPES |
2657 | }; | 2704 | }; |
2658 | 2705 | ||
2659 | /** | 2706 | /** |
2660 | * enum nl80211_key_attributes - key attributes | 2707 | * enum nl80211_key_attributes - key attributes |
2661 | * @__NL80211_KEY_INVALID: invalid | 2708 | * @__NL80211_KEY_INVALID: invalid |
2662 | * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of | 2709 | * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of |
2663 | * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC | 2710 | * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC |
2664 | * keys | 2711 | * keys |
2665 | * @NL80211_KEY_IDX: key ID (u8, 0-3) | 2712 | * @NL80211_KEY_IDX: key ID (u8, 0-3) |
2666 | * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 | 2713 | * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11 |
2667 | * section 7.3.2.25.1, e.g. 0x000FAC04) | 2714 | * section 7.3.2.25.1, e.g. 0x000FAC04) |
2668 | * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and | 2715 | * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and |
2669 | * CCMP keys, each six bytes in little endian | 2716 | * CCMP keys, each six bytes in little endian |
2670 | * @NL80211_KEY_DEFAULT: flag indicating default key | 2717 | * @NL80211_KEY_DEFAULT: flag indicating default key |
2671 | * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key | 2718 | * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key |
2672 | * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not | 2719 | * @NL80211_KEY_TYPE: the key type from enum nl80211_key_type, if not |
2673 | * specified the default depends on whether a MAC address was | 2720 | * specified the default depends on whether a MAC address was |
2674 | * given with the command using the key or not (u32) | 2721 | * given with the command using the key or not (u32) |
2675 | * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags | 2722 | * @NL80211_KEY_DEFAULT_TYPES: A nested attribute containing flags |
2676 | * attributes, specifying what a key should be set as default as. | 2723 | * attributes, specifying what a key should be set as default as. |
2677 | * See &enum nl80211_key_default_types. | 2724 | * See &enum nl80211_key_default_types. |
2678 | * @__NL80211_KEY_AFTER_LAST: internal | 2725 | * @__NL80211_KEY_AFTER_LAST: internal |
2679 | * @NL80211_KEY_MAX: highest key attribute | 2726 | * @NL80211_KEY_MAX: highest key attribute |
2680 | */ | 2727 | */ |
2681 | enum nl80211_key_attributes { | 2728 | enum nl80211_key_attributes { |
2682 | __NL80211_KEY_INVALID, | 2729 | __NL80211_KEY_INVALID, |
2683 | NL80211_KEY_DATA, | 2730 | NL80211_KEY_DATA, |
2684 | NL80211_KEY_IDX, | 2731 | NL80211_KEY_IDX, |
2685 | NL80211_KEY_CIPHER, | 2732 | NL80211_KEY_CIPHER, |
2686 | NL80211_KEY_SEQ, | 2733 | NL80211_KEY_SEQ, |
2687 | NL80211_KEY_DEFAULT, | 2734 | NL80211_KEY_DEFAULT, |
2688 | NL80211_KEY_DEFAULT_MGMT, | 2735 | NL80211_KEY_DEFAULT_MGMT, |
2689 | NL80211_KEY_TYPE, | 2736 | NL80211_KEY_TYPE, |
2690 | NL80211_KEY_DEFAULT_TYPES, | 2737 | NL80211_KEY_DEFAULT_TYPES, |
2691 | 2738 | ||
2692 | /* keep last */ | 2739 | /* keep last */ |
2693 | __NL80211_KEY_AFTER_LAST, | 2740 | __NL80211_KEY_AFTER_LAST, |
2694 | NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1 | 2741 | NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1 |
2695 | }; | 2742 | }; |
2696 | 2743 | ||
2697 | /** | 2744 | /** |
2698 | * enum nl80211_tx_rate_attributes - TX rate set attributes | 2745 | * enum nl80211_tx_rate_attributes - TX rate set attributes |
2699 | * @__NL80211_TXRATE_INVALID: invalid | 2746 | * @__NL80211_TXRATE_INVALID: invalid |
2700 | * @NL80211_TXRATE_LEGACY: Legacy (non-MCS) rates allowed for TX rate selection | 2747 | * @NL80211_TXRATE_LEGACY: Legacy (non-MCS) rates allowed for TX rate selection |
2701 | * in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with | 2748 | * in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with |
2702 | * 1 = 500 kbps) but without the IE length restriction (at most | 2749 | * 1 = 500 kbps) but without the IE length restriction (at most |
2703 | * %NL80211_MAX_SUPP_RATES in a single array). | 2750 | * %NL80211_MAX_SUPP_RATES in a single array). |
2704 | * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection | 2751 | * @NL80211_TXRATE_MCS: HT (MCS) rates allowed for TX rate selection |
2705 | * in an array of MCS numbers. | 2752 | * in an array of MCS numbers. |
2706 | * @__NL80211_TXRATE_AFTER_LAST: internal | 2753 | * @__NL80211_TXRATE_AFTER_LAST: internal |
2707 | * @NL80211_TXRATE_MAX: highest TX rate attribute | 2754 | * @NL80211_TXRATE_MAX: highest TX rate attribute |
2708 | */ | 2755 | */ |
2709 | enum nl80211_tx_rate_attributes { | 2756 | enum nl80211_tx_rate_attributes { |
2710 | __NL80211_TXRATE_INVALID, | 2757 | __NL80211_TXRATE_INVALID, |
2711 | NL80211_TXRATE_LEGACY, | 2758 | NL80211_TXRATE_LEGACY, |
2712 | NL80211_TXRATE_MCS, | 2759 | NL80211_TXRATE_MCS, |
2713 | 2760 | ||
2714 | /* keep last */ | 2761 | /* keep last */ |
2715 | __NL80211_TXRATE_AFTER_LAST, | 2762 | __NL80211_TXRATE_AFTER_LAST, |
2716 | NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 | 2763 | NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1 |
2717 | }; | 2764 | }; |
2718 | 2765 | ||
2719 | /** | 2766 | /** |
2720 | * enum nl80211_band - Frequency band | 2767 | * enum nl80211_band - Frequency band |
2721 | * @NL80211_BAND_2GHZ: 2.4 GHz ISM band | 2768 | * @NL80211_BAND_2GHZ: 2.4 GHz ISM band |
2722 | * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) | 2769 | * @NL80211_BAND_5GHZ: around 5 GHz band (4.9 - 5.7 GHz) |
2723 | * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) | 2770 | * @NL80211_BAND_60GHZ: around 60 GHz band (58.32 - 64.80 GHz) |
2724 | */ | 2771 | */ |
2725 | enum nl80211_band { | 2772 | enum nl80211_band { |
2726 | NL80211_BAND_2GHZ, | 2773 | NL80211_BAND_2GHZ, |
2727 | NL80211_BAND_5GHZ, | 2774 | NL80211_BAND_5GHZ, |
2728 | NL80211_BAND_60GHZ, | 2775 | NL80211_BAND_60GHZ, |
2729 | }; | 2776 | }; |
2730 | 2777 | ||
2731 | /** | 2778 | /** |
2732 | * enum nl80211_ps_state - powersave state | 2779 | * enum nl80211_ps_state - powersave state |
2733 | * @NL80211_PS_DISABLED: powersave is disabled | 2780 | * @NL80211_PS_DISABLED: powersave is disabled |
2734 | * @NL80211_PS_ENABLED: powersave is enabled | 2781 | * @NL80211_PS_ENABLED: powersave is enabled |
2735 | */ | 2782 | */ |
2736 | enum nl80211_ps_state { | 2783 | enum nl80211_ps_state { |
2737 | NL80211_PS_DISABLED, | 2784 | NL80211_PS_DISABLED, |
2738 | NL80211_PS_ENABLED, | 2785 | NL80211_PS_ENABLED, |
2739 | }; | 2786 | }; |
2740 | 2787 | ||
2741 | /** | 2788 | /** |
2742 | * enum nl80211_attr_cqm - connection quality monitor attributes | 2789 | * enum nl80211_attr_cqm - connection quality monitor attributes |
2743 | * @__NL80211_ATTR_CQM_INVALID: invalid | 2790 | * @__NL80211_ATTR_CQM_INVALID: invalid |
2744 | * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies | 2791 | * @NL80211_ATTR_CQM_RSSI_THOLD: RSSI threshold in dBm. This value specifies |
2745 | * the threshold for the RSSI level at which an event will be sent. Zero | 2792 | * the threshold for the RSSI level at which an event will be sent. Zero |
2746 | * to disable. | 2793 | * to disable. |
2747 | * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies | 2794 | * @NL80211_ATTR_CQM_RSSI_HYST: RSSI hysteresis in dBm. This value specifies |
2748 | * the minimum amount the RSSI level must change after an event before a | 2795 | * the minimum amount the RSSI level must change after an event before a |
2749 | * new event may be issued (to reduce effects of RSSI oscillation). | 2796 | * new event may be issued (to reduce effects of RSSI oscillation). |
2750 | * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event | 2797 | * @NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT: RSSI threshold event |
2751 | * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many | 2798 | * @NL80211_ATTR_CQM_PKT_LOSS_EVENT: a u32 value indicating that this many |
2752 | * consecutive packets were not acknowledged by the peer | 2799 | * consecutive packets were not acknowledged by the peer |
2753 | * @NL80211_ATTR_CQM_TXE_RATE: TX error rate in %. Minimum % of TX failures | 2800 | * @NL80211_ATTR_CQM_TXE_RATE: TX error rate in %. Minimum % of TX failures |
2754 | * during the given %NL80211_ATTR_CQM_TXE_INTVL before an | 2801 | * during the given %NL80211_ATTR_CQM_TXE_INTVL before an |
2755 | * %NL80211_CMD_NOTIFY_CQM with reported %NL80211_ATTR_CQM_TXE_RATE and | 2802 | * %NL80211_CMD_NOTIFY_CQM with reported %NL80211_ATTR_CQM_TXE_RATE and |
2756 | * %NL80211_ATTR_CQM_TXE_PKTS is generated. | 2803 | * %NL80211_ATTR_CQM_TXE_PKTS is generated. |
2757 | * @NL80211_ATTR_CQM_TXE_PKTS: number of attempted packets in a given | 2804 | * @NL80211_ATTR_CQM_TXE_PKTS: number of attempted packets in a given |
2758 | * %NL80211_ATTR_CQM_TXE_INTVL before %NL80211_ATTR_CQM_TXE_RATE is | 2805 | * %NL80211_ATTR_CQM_TXE_INTVL before %NL80211_ATTR_CQM_TXE_RATE is |
2759 | * checked. | 2806 | * checked. |
2760 | * @NL80211_ATTR_CQM_TXE_INTVL: interval in seconds. Specifies the periodic | 2807 | * @NL80211_ATTR_CQM_TXE_INTVL: interval in seconds. Specifies the periodic |
2761 | * interval in which %NL80211_ATTR_CQM_TXE_PKTS and | 2808 | * interval in which %NL80211_ATTR_CQM_TXE_PKTS and |
2762 | * %NL80211_ATTR_CQM_TXE_RATE must be satisfied before generating an | 2809 | * %NL80211_ATTR_CQM_TXE_RATE must be satisfied before generating an |
2763 | * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. | 2810 | * %NL80211_CMD_NOTIFY_CQM. Set to 0 to turn off TX error reporting. |
2764 | * @__NL80211_ATTR_CQM_AFTER_LAST: internal | 2811 | * @__NL80211_ATTR_CQM_AFTER_LAST: internal |
2765 | * @NL80211_ATTR_CQM_MAX: highest key attribute | 2812 | * @NL80211_ATTR_CQM_MAX: highest key attribute |
2766 | */ | 2813 | */ |
2767 | enum nl80211_attr_cqm { | 2814 | enum nl80211_attr_cqm { |
2768 | __NL80211_ATTR_CQM_INVALID, | 2815 | __NL80211_ATTR_CQM_INVALID, |
2769 | NL80211_ATTR_CQM_RSSI_THOLD, | 2816 | NL80211_ATTR_CQM_RSSI_THOLD, |
2770 | NL80211_ATTR_CQM_RSSI_HYST, | 2817 | NL80211_ATTR_CQM_RSSI_HYST, |
2771 | NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, | 2818 | NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, |
2772 | NL80211_ATTR_CQM_PKT_LOSS_EVENT, | 2819 | NL80211_ATTR_CQM_PKT_LOSS_EVENT, |
2773 | NL80211_ATTR_CQM_TXE_RATE, | 2820 | NL80211_ATTR_CQM_TXE_RATE, |
2774 | NL80211_ATTR_CQM_TXE_PKTS, | 2821 | NL80211_ATTR_CQM_TXE_PKTS, |
2775 | NL80211_ATTR_CQM_TXE_INTVL, | 2822 | NL80211_ATTR_CQM_TXE_INTVL, |
2776 | 2823 | ||
2777 | /* keep last */ | 2824 | /* keep last */ |
2778 | __NL80211_ATTR_CQM_AFTER_LAST, | 2825 | __NL80211_ATTR_CQM_AFTER_LAST, |
2779 | NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1 | 2826 | NL80211_ATTR_CQM_MAX = __NL80211_ATTR_CQM_AFTER_LAST - 1 |
2780 | }; | 2827 | }; |
2781 | 2828 | ||
2782 | /** | 2829 | /** |
2783 | * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event | 2830 | * enum nl80211_cqm_rssi_threshold_event - RSSI threshold event |
2784 | * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the | 2831 | * @NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW: The RSSI level is lower than the |
2785 | * configured threshold | 2832 | * configured threshold |
2786 | * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the | 2833 | * @NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH: The RSSI is higher than the |
2787 | * configured threshold | 2834 | * configured threshold |
2788 | * @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: The device experienced beacon loss. | 2835 | * @NL80211_CQM_RSSI_BEACON_LOSS_EVENT: The device experienced beacon loss. |
2789 | * (Note that deauth/disassoc will still follow if the AP is not | 2836 | * (Note that deauth/disassoc will still follow if the AP is not |
2790 | * available. This event might get used as roaming event, etc.) | 2837 | * available. This event might get used as roaming event, etc.) |
2791 | */ | 2838 | */ |
2792 | enum nl80211_cqm_rssi_threshold_event { | 2839 | enum nl80211_cqm_rssi_threshold_event { |
2793 | NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, | 2840 | NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW, |
2794 | NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, | 2841 | NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH, |
2795 | NL80211_CQM_RSSI_BEACON_LOSS_EVENT, | 2842 | NL80211_CQM_RSSI_BEACON_LOSS_EVENT, |
2796 | }; | 2843 | }; |
2797 | 2844 | ||
2798 | 2845 | ||
2799 | /** | 2846 | /** |
2800 | * enum nl80211_tx_power_setting - TX power adjustment | 2847 | * enum nl80211_tx_power_setting - TX power adjustment |
2801 | * @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power | 2848 | * @NL80211_TX_POWER_AUTOMATIC: automatically determine transmit power |
2802 | * @NL80211_TX_POWER_LIMITED: limit TX power by the mBm parameter | 2849 | * @NL80211_TX_POWER_LIMITED: limit TX power by the mBm parameter |
2803 | * @NL80211_TX_POWER_FIXED: fix TX power to the mBm parameter | 2850 | * @NL80211_TX_POWER_FIXED: fix TX power to the mBm parameter |
2804 | */ | 2851 | */ |
2805 | enum nl80211_tx_power_setting { | 2852 | enum nl80211_tx_power_setting { |
2806 | NL80211_TX_POWER_AUTOMATIC, | 2853 | NL80211_TX_POWER_AUTOMATIC, |
2807 | NL80211_TX_POWER_LIMITED, | 2854 | NL80211_TX_POWER_LIMITED, |
2808 | NL80211_TX_POWER_FIXED, | 2855 | NL80211_TX_POWER_FIXED, |
2809 | }; | 2856 | }; |
2810 | 2857 | ||
2811 | /** | 2858 | /** |
2812 | * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute | 2859 | * enum nl80211_wowlan_packet_pattern_attr - WoWLAN packet pattern attribute |
2813 | * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute | 2860 | * @__NL80211_WOWLAN_PKTPAT_INVALID: invalid number for nested attribute |
2814 | * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has | 2861 | * @NL80211_WOWLAN_PKTPAT_PATTERN: the pattern, values where the mask has |
2815 | * a zero bit are ignored | 2862 | * a zero bit are ignored |
2816 | * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have | 2863 | * @NL80211_WOWLAN_PKTPAT_MASK: pattern mask, must be long enough to have |
2817 | * a bit for each byte in the pattern. The lowest-order bit corresponds | 2864 | * a bit for each byte in the pattern. The lowest-order bit corresponds |
2818 | * to the first byte of the pattern, but the bytes of the pattern are | 2865 | * to the first byte of the pattern, but the bytes of the pattern are |
2819 | * in a little-endian-like format, i.e. the 9th byte of the pattern | 2866 | * in a little-endian-like format, i.e. the 9th byte of the pattern |
2820 | * corresponds to the lowest-order bit in the second byte of the mask. | 2867 | * corresponds to the lowest-order bit in the second byte of the mask. |
2821 | * For example: The match 00:xx:00:00:xx:00:00:00:00:xx:xx:xx (where | 2868 | * For example: The match 00:xx:00:00:xx:00:00:00:00:xx:xx:xx (where |
2822 | * xx indicates "don't care") would be represented by a pattern of | 2869 | * xx indicates "don't care") would be represented by a pattern of |
2823 | * twelve zero bytes, and a mask of "0xed,0x07". | 2870 | * twelve zero bytes, and a mask of "0xed,0x07". |
2824 | * Note that the pattern matching is done as though frames were not | 2871 | * Note that the pattern matching is done as though frames were not |
2825 | * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked | 2872 | * 802.11 frames but 802.3 frames, i.e. the frame is fully unpacked |
2826 | * first (including SNAP header unpacking) and then matched. | 2873 | * first (including SNAP header unpacking) and then matched. |
2827 | * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes | 2874 | * @NUM_NL80211_WOWLAN_PKTPAT: number of attributes |
2828 | * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number | 2875 | * @MAX_NL80211_WOWLAN_PKTPAT: max attribute number |
2829 | */ | 2876 | */ |
2830 | enum nl80211_wowlan_packet_pattern_attr { | 2877 | enum nl80211_wowlan_packet_pattern_attr { |
2831 | __NL80211_WOWLAN_PKTPAT_INVALID, | 2878 | __NL80211_WOWLAN_PKTPAT_INVALID, |
2832 | NL80211_WOWLAN_PKTPAT_MASK, | 2879 | NL80211_WOWLAN_PKTPAT_MASK, |
2833 | NL80211_WOWLAN_PKTPAT_PATTERN, | 2880 | NL80211_WOWLAN_PKTPAT_PATTERN, |
2834 | 2881 | ||
2835 | NUM_NL80211_WOWLAN_PKTPAT, | 2882 | NUM_NL80211_WOWLAN_PKTPAT, |
2836 | MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, | 2883 | MAX_NL80211_WOWLAN_PKTPAT = NUM_NL80211_WOWLAN_PKTPAT - 1, |
2837 | }; | 2884 | }; |
2838 | 2885 | ||
2839 | /** | 2886 | /** |
2840 | * struct nl80211_wowlan_pattern_support - pattern support information | 2887 | * struct nl80211_wowlan_pattern_support - pattern support information |
2841 | * @max_patterns: maximum number of patterns supported | 2888 | * @max_patterns: maximum number of patterns supported |
2842 | * @min_pattern_len: minimum length of each pattern | 2889 | * @min_pattern_len: minimum length of each pattern |
2843 | * @max_pattern_len: maximum length of each pattern | 2890 | * @max_pattern_len: maximum length of each pattern |
2844 | * | 2891 | * |
2845 | * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when | 2892 | * This struct is carried in %NL80211_WOWLAN_TRIG_PKT_PATTERN when |
2846 | * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the | 2893 | * that is part of %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED in the |
2847 | * capability information given by the kernel to userspace. | 2894 | * capability information given by the kernel to userspace. |
2848 | */ | 2895 | */ |
2849 | struct nl80211_wowlan_pattern_support { | 2896 | struct nl80211_wowlan_pattern_support { |
2850 | __u32 max_patterns; | 2897 | __u32 max_patterns; |
2851 | __u32 min_pattern_len; | 2898 | __u32 min_pattern_len; |
2852 | __u32 max_pattern_len; | 2899 | __u32 max_pattern_len; |
2853 | } __attribute__((packed)); | 2900 | } __attribute__((packed)); |
2854 | 2901 | ||
2855 | /** | 2902 | /** |
2856 | * enum nl80211_wowlan_triggers - WoWLAN trigger definitions | 2903 | * enum nl80211_wowlan_triggers - WoWLAN trigger definitions |
2857 | * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes | 2904 | * @__NL80211_WOWLAN_TRIG_INVALID: invalid number for nested attributes |
2858 | * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put | 2905 | * @NL80211_WOWLAN_TRIG_ANY: wake up on any activity, do not really put |
2859 | * the chip into a special state -- works best with chips that have | 2906 | * the chip into a special state -- works best with chips that have |
2860 | * support for low-power operation already (flag) | 2907 | * support for low-power operation already (flag) |
2861 | * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect | 2908 | * @NL80211_WOWLAN_TRIG_DISCONNECT: wake up on disconnect, the way disconnect |
2862 | * is detected is implementation-specific (flag) | 2909 | * is detected is implementation-specific (flag) |
2863 | * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed | 2910 | * @NL80211_WOWLAN_TRIG_MAGIC_PKT: wake up on magic packet (6x 0xff, followed |
2864 | * by 16 repetitions of MAC addr, anywhere in payload) (flag) | 2911 | * by 16 repetitions of MAC addr, anywhere in payload) (flag) |
2865 | * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns | 2912 | * @NL80211_WOWLAN_TRIG_PKT_PATTERN: wake up on the specified packet patterns |
2866 | * which are passed in an array of nested attributes, each nested attribute | 2913 | * which are passed in an array of nested attributes, each nested attribute |
2867 | * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern. | 2914 | * defining a with attributes from &struct nl80211_wowlan_trig_pkt_pattern. |
2868 | * Each pattern defines a wakeup packet. The matching is done on the MSDU, | 2915 | * Each pattern defines a wakeup packet. The matching is done on the MSDU, |
2869 | * i.e. as though the packet was an 802.3 packet, so the pattern matching | 2916 | * i.e. as though the packet was an 802.3 packet, so the pattern matching |
2870 | * is done after the packet is converted to the MSDU. | 2917 | * is done after the packet is converted to the MSDU. |
2871 | * | 2918 | * |
2872 | * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute | 2919 | * In %NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED, it is a binary attribute |
2873 | * carrying a &struct nl80211_wowlan_pattern_support. | 2920 | * carrying a &struct nl80211_wowlan_pattern_support. |
2874 | * @NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: Not a real trigger, and cannot be | 2921 | * @NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED: Not a real trigger, and cannot be |
2875 | * used when setting, used only to indicate that GTK rekeying is supported | 2922 | * used when setting, used only to indicate that GTK rekeying is supported |
2876 | * by the device (flag) | 2923 | * by the device (flag) |
2877 | * @NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: wake up on GTK rekey failure (if | 2924 | * @NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE: wake up on GTK rekey failure (if |
2878 | * done by the device) (flag) | 2925 | * done by the device) (flag) |
2879 | * @NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: wake up on EAP Identity Request | 2926 | * @NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST: wake up on EAP Identity Request |
2880 | * packet (flag) | 2927 | * packet (flag) |
2881 | * @NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: wake up on 4-way handshake (flag) | 2928 | * @NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE: wake up on 4-way handshake (flag) |
2882 | * @NL80211_WOWLAN_TRIG_RFKILL_RELEASE: wake up when rfkill is released | 2929 | * @NL80211_WOWLAN_TRIG_RFKILL_RELEASE: wake up when rfkill is released |
2883 | * (on devices that have rfkill in the device) (flag) | 2930 | * (on devices that have rfkill in the device) (flag) |
2884 | * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers | 2931 | * @NUM_NL80211_WOWLAN_TRIG: number of wake on wireless triggers |
2885 | * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number | 2932 | * @MAX_NL80211_WOWLAN_TRIG: highest wowlan trigger attribute number |
2886 | */ | 2933 | */ |
2887 | enum nl80211_wowlan_triggers { | 2934 | enum nl80211_wowlan_triggers { |
2888 | __NL80211_WOWLAN_TRIG_INVALID, | 2935 | __NL80211_WOWLAN_TRIG_INVALID, |
2889 | NL80211_WOWLAN_TRIG_ANY, | 2936 | NL80211_WOWLAN_TRIG_ANY, |
2890 | NL80211_WOWLAN_TRIG_DISCONNECT, | 2937 | NL80211_WOWLAN_TRIG_DISCONNECT, |
2891 | NL80211_WOWLAN_TRIG_MAGIC_PKT, | 2938 | NL80211_WOWLAN_TRIG_MAGIC_PKT, |
2892 | NL80211_WOWLAN_TRIG_PKT_PATTERN, | 2939 | NL80211_WOWLAN_TRIG_PKT_PATTERN, |
2893 | NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED, | 2940 | NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED, |
2894 | NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE, | 2941 | NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE, |
2895 | NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST, | 2942 | NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST, |
2896 | NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE, | 2943 | NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE, |
2897 | NL80211_WOWLAN_TRIG_RFKILL_RELEASE, | 2944 | NL80211_WOWLAN_TRIG_RFKILL_RELEASE, |
2898 | 2945 | ||
2899 | /* keep last */ | 2946 | /* keep last */ |
2900 | NUM_NL80211_WOWLAN_TRIG, | 2947 | NUM_NL80211_WOWLAN_TRIG, |
2901 | MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 | 2948 | MAX_NL80211_WOWLAN_TRIG = NUM_NL80211_WOWLAN_TRIG - 1 |
2902 | }; | 2949 | }; |
2903 | 2950 | ||
2904 | /** | 2951 | /** |
2905 | * enum nl80211_iface_limit_attrs - limit attributes | 2952 | * enum nl80211_iface_limit_attrs - limit attributes |
2906 | * @NL80211_IFACE_LIMIT_UNSPEC: (reserved) | 2953 | * @NL80211_IFACE_LIMIT_UNSPEC: (reserved) |
2907 | * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that | 2954 | * @NL80211_IFACE_LIMIT_MAX: maximum number of interfaces that |
2908 | * can be chosen from this set of interface types (u32) | 2955 | * can be chosen from this set of interface types (u32) |
2909 | * @NL80211_IFACE_LIMIT_TYPES: nested attribute containing a | 2956 | * @NL80211_IFACE_LIMIT_TYPES: nested attribute containing a |
2910 | * flag attribute for each interface type in this set | 2957 | * flag attribute for each interface type in this set |
2911 | * @NUM_NL80211_IFACE_LIMIT: number of attributes | 2958 | * @NUM_NL80211_IFACE_LIMIT: number of attributes |
2912 | * @MAX_NL80211_IFACE_LIMIT: highest attribute number | 2959 | * @MAX_NL80211_IFACE_LIMIT: highest attribute number |
2913 | */ | 2960 | */ |
2914 | enum nl80211_iface_limit_attrs { | 2961 | enum nl80211_iface_limit_attrs { |
2915 | NL80211_IFACE_LIMIT_UNSPEC, | 2962 | NL80211_IFACE_LIMIT_UNSPEC, |
2916 | NL80211_IFACE_LIMIT_MAX, | 2963 | NL80211_IFACE_LIMIT_MAX, |
2917 | NL80211_IFACE_LIMIT_TYPES, | 2964 | NL80211_IFACE_LIMIT_TYPES, |
2918 | 2965 | ||
2919 | /* keep last */ | 2966 | /* keep last */ |
2920 | NUM_NL80211_IFACE_LIMIT, | 2967 | NUM_NL80211_IFACE_LIMIT, |
2921 | MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1 | 2968 | MAX_NL80211_IFACE_LIMIT = NUM_NL80211_IFACE_LIMIT - 1 |
2922 | }; | 2969 | }; |
2923 | 2970 | ||
2924 | /** | 2971 | /** |
2925 | * enum nl80211_if_combination_attrs -- interface combination attributes | 2972 | * enum nl80211_if_combination_attrs -- interface combination attributes |
2926 | * | 2973 | * |
2927 | * @NL80211_IFACE_COMB_UNSPEC: (reserved) | 2974 | * @NL80211_IFACE_COMB_UNSPEC: (reserved) |
2928 | * @NL80211_IFACE_COMB_LIMITS: Nested attributes containing the limits | 2975 | * @NL80211_IFACE_COMB_LIMITS: Nested attributes containing the limits |
2929 | * for given interface types, see &enum nl80211_iface_limit_attrs. | 2976 | * for given interface types, see &enum nl80211_iface_limit_attrs. |
2930 | * @NL80211_IFACE_COMB_MAXNUM: u32 attribute giving the total number of | 2977 | * @NL80211_IFACE_COMB_MAXNUM: u32 attribute giving the total number of |
2931 | * interfaces that can be created in this group. This number doesn't | 2978 | * interfaces that can be created in this group. This number doesn't |
2932 | * apply to interfaces purely managed in software, which are listed | 2979 | * apply to interfaces purely managed in software, which are listed |
2933 | * in a separate attribute %NL80211_ATTR_INTERFACES_SOFTWARE. | 2980 | * in a separate attribute %NL80211_ATTR_INTERFACES_SOFTWARE. |
2934 | * @NL80211_IFACE_COMB_STA_AP_BI_MATCH: flag attribute specifying that | 2981 | * @NL80211_IFACE_COMB_STA_AP_BI_MATCH: flag attribute specifying that |
2935 | * beacon intervals within this group must be all the same even for | 2982 | * beacon intervals within this group must be all the same even for |
2936 | * infrastructure and AP/GO combinations, i.e. the GO(s) must adopt | 2983 | * infrastructure and AP/GO combinations, i.e. the GO(s) must adopt |
2937 | * the infrastructure network's beacon interval. | 2984 | * the infrastructure network's beacon interval. |
2938 | * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many | 2985 | * @NL80211_IFACE_COMB_NUM_CHANNELS: u32 attribute specifying how many |
2939 | * different channels may be used within this group. | 2986 | * different channels may be used within this group. |
2940 | * @NUM_NL80211_IFACE_COMB: number of attributes | 2987 | * @NUM_NL80211_IFACE_COMB: number of attributes |
2941 | * @MAX_NL80211_IFACE_COMB: highest attribute number | 2988 | * @MAX_NL80211_IFACE_COMB: highest attribute number |
2942 | * | 2989 | * |
2943 | * Examples: | 2990 | * Examples: |
2944 | * limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2 | 2991 | * limits = [ #{STA} <= 1, #{AP} <= 1 ], matching BI, channels = 1, max = 2 |
2945 | * => allows an AP and a STA that must match BIs | 2992 | * => allows an AP and a STA that must match BIs |
2946 | * | 2993 | * |
2947 | * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8 | 2994 | * numbers = [ #{AP, P2P-GO} <= 8 ], channels = 1, max = 8 |
2948 | * => allows 8 of AP/GO | 2995 | * => allows 8 of AP/GO |
2949 | * | 2996 | * |
2950 | * numbers = [ #{STA} <= 2 ], channels = 2, max = 2 | 2997 | * numbers = [ #{STA} <= 2 ], channels = 2, max = 2 |
2951 | * => allows two STAs on different channels | 2998 | * => allows two STAs on different channels |
2952 | * | 2999 | * |
2953 | * numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4 | 3000 | * numbers = [ #{STA} <= 1, #{P2P-client,P2P-GO} <= 3 ], max = 4 |
2954 | * => allows a STA plus three P2P interfaces | 3001 | * => allows a STA plus three P2P interfaces |
2955 | * | 3002 | * |
2956 | * The list of these four possiblities could completely be contained | 3003 | * The list of these four possiblities could completely be contained |
2957 | * within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate | 3004 | * within the %NL80211_ATTR_INTERFACE_COMBINATIONS attribute to indicate |
2958 | * that any of these groups must match. | 3005 | * that any of these groups must match. |
2959 | * | 3006 | * |
2960 | * "Combinations" of just a single interface will not be listed here, | 3007 | * "Combinations" of just a single interface will not be listed here, |
2961 | * a single interface of any valid interface type is assumed to always | 3008 | * a single interface of any valid interface type is assumed to always |
2962 | * be possible by itself. This means that implicitly, for each valid | 3009 | * be possible by itself. This means that implicitly, for each valid |
2963 | * interface type, the following group always exists: | 3010 | * interface type, the following group always exists: |
2964 | * numbers = [ #{<type>} <= 1 ], channels = 1, max = 1 | 3011 | * numbers = [ #{<type>} <= 1 ], channels = 1, max = 1 |
2965 | */ | 3012 | */ |
2966 | enum nl80211_if_combination_attrs { | 3013 | enum nl80211_if_combination_attrs { |
2967 | NL80211_IFACE_COMB_UNSPEC, | 3014 | NL80211_IFACE_COMB_UNSPEC, |
2968 | NL80211_IFACE_COMB_LIMITS, | 3015 | NL80211_IFACE_COMB_LIMITS, |
2969 | NL80211_IFACE_COMB_MAXNUM, | 3016 | NL80211_IFACE_COMB_MAXNUM, |
2970 | NL80211_IFACE_COMB_STA_AP_BI_MATCH, | 3017 | NL80211_IFACE_COMB_STA_AP_BI_MATCH, |
2971 | NL80211_IFACE_COMB_NUM_CHANNELS, | 3018 | NL80211_IFACE_COMB_NUM_CHANNELS, |
2972 | 3019 | ||
2973 | /* keep last */ | 3020 | /* keep last */ |
2974 | NUM_NL80211_IFACE_COMB, | 3021 | NUM_NL80211_IFACE_COMB, |
2975 | MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1 | 3022 | MAX_NL80211_IFACE_COMB = NUM_NL80211_IFACE_COMB - 1 |
2976 | }; | 3023 | }; |
2977 | 3024 | ||
2978 | 3025 | ||
2979 | /** | 3026 | /** |
2980 | * enum nl80211_plink_state - state of a mesh peer link finite state machine | 3027 | * enum nl80211_plink_state - state of a mesh peer link finite state machine |
2981 | * | 3028 | * |
2982 | * @NL80211_PLINK_LISTEN: initial state, considered the implicit | 3029 | * @NL80211_PLINK_LISTEN: initial state, considered the implicit |
2983 | * state of non existant mesh peer links | 3030 | * state of non existant mesh peer links |
2984 | * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to | 3031 | * @NL80211_PLINK_OPN_SNT: mesh plink open frame has been sent to |
2985 | * this mesh peer | 3032 | * this mesh peer |
2986 | * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received | 3033 | * @NL80211_PLINK_OPN_RCVD: mesh plink open frame has been received |
2987 | * from this mesh peer | 3034 | * from this mesh peer |
2988 | * @NL80211_PLINK_CNF_RCVD: mesh plink confirm frame has been | 3035 | * @NL80211_PLINK_CNF_RCVD: mesh plink confirm frame has been |
2989 | * received from this mesh peer | 3036 | * received from this mesh peer |
2990 | * @NL80211_PLINK_ESTAB: mesh peer link is established | 3037 | * @NL80211_PLINK_ESTAB: mesh peer link is established |
2991 | * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled | 3038 | * @NL80211_PLINK_HOLDING: mesh peer link is being closed or cancelled |
2992 | * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh | 3039 | * @NL80211_PLINK_BLOCKED: all frames transmitted from this mesh |
2993 | * plink are discarded | 3040 | * plink are discarded |
2994 | * @NUM_NL80211_PLINK_STATES: number of peer link states | 3041 | * @NUM_NL80211_PLINK_STATES: number of peer link states |
2995 | * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states | 3042 | * @MAX_NL80211_PLINK_STATES: highest numerical value of plink states |
2996 | */ | 3043 | */ |
2997 | enum nl80211_plink_state { | 3044 | enum nl80211_plink_state { |
2998 | NL80211_PLINK_LISTEN, | 3045 | NL80211_PLINK_LISTEN, |
2999 | NL80211_PLINK_OPN_SNT, | 3046 | NL80211_PLINK_OPN_SNT, |
3000 | NL80211_PLINK_OPN_RCVD, | 3047 | NL80211_PLINK_OPN_RCVD, |
3001 | NL80211_PLINK_CNF_RCVD, | 3048 | NL80211_PLINK_CNF_RCVD, |
3002 | NL80211_PLINK_ESTAB, | 3049 | NL80211_PLINK_ESTAB, |
3003 | NL80211_PLINK_HOLDING, | 3050 | NL80211_PLINK_HOLDING, |
3004 | NL80211_PLINK_BLOCKED, | 3051 | NL80211_PLINK_BLOCKED, |
3005 | 3052 | ||
3006 | /* keep last */ | 3053 | /* keep last */ |
3007 | NUM_NL80211_PLINK_STATES, | 3054 | NUM_NL80211_PLINK_STATES, |
3008 | MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 | 3055 | MAX_NL80211_PLINK_STATES = NUM_NL80211_PLINK_STATES - 1 |
3009 | }; | 3056 | }; |
3010 | 3057 | ||
3011 | #define NL80211_KCK_LEN 16 | 3058 | #define NL80211_KCK_LEN 16 |
3012 | #define NL80211_KEK_LEN 16 | 3059 | #define NL80211_KEK_LEN 16 |
3013 | #define NL80211_REPLAY_CTR_LEN 8 | 3060 | #define NL80211_REPLAY_CTR_LEN 8 |
3014 | 3061 | ||
3015 | /** | 3062 | /** |
3016 | * enum nl80211_rekey_data - attributes for GTK rekey offload | 3063 | * enum nl80211_rekey_data - attributes for GTK rekey offload |
3017 | * @__NL80211_REKEY_DATA_INVALID: invalid number for nested attributes | 3064 | * @__NL80211_REKEY_DATA_INVALID: invalid number for nested attributes |
3018 | * @NL80211_REKEY_DATA_KEK: key encryption key (binary) | 3065 | * @NL80211_REKEY_DATA_KEK: key encryption key (binary) |
3019 | * @NL80211_REKEY_DATA_KCK: key confirmation key (binary) | 3066 | * @NL80211_REKEY_DATA_KCK: key confirmation key (binary) |
3020 | * @NL80211_REKEY_DATA_REPLAY_CTR: replay counter (binary) | 3067 | * @NL80211_REKEY_DATA_REPLAY_CTR: replay counter (binary) |
3021 | * @NUM_NL80211_REKEY_DATA: number of rekey attributes (internal) | 3068 | * @NUM_NL80211_REKEY_DATA: number of rekey attributes (internal) |
3022 | * @MAX_NL80211_REKEY_DATA: highest rekey attribute (internal) | 3069 | * @MAX_NL80211_REKEY_DATA: highest rekey attribute (internal) |
3023 | */ | 3070 | */ |
3024 | enum nl80211_rekey_data { | 3071 | enum nl80211_rekey_data { |
3025 | __NL80211_REKEY_DATA_INVALID, | 3072 | __NL80211_REKEY_DATA_INVALID, |
3026 | NL80211_REKEY_DATA_KEK, | 3073 | NL80211_REKEY_DATA_KEK, |
3027 | NL80211_REKEY_DATA_KCK, | 3074 | NL80211_REKEY_DATA_KCK, |
3028 | NL80211_REKEY_DATA_REPLAY_CTR, | 3075 | NL80211_REKEY_DATA_REPLAY_CTR, |
3029 | 3076 | ||
3030 | /* keep last */ | 3077 | /* keep last */ |
3031 | NUM_NL80211_REKEY_DATA, | 3078 | NUM_NL80211_REKEY_DATA, |
3032 | MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1 | 3079 | MAX_NL80211_REKEY_DATA = NUM_NL80211_REKEY_DATA - 1 |
3033 | }; | 3080 | }; |
3034 | 3081 | ||
3035 | /** | 3082 | /** |
3036 | * enum nl80211_hidden_ssid - values for %NL80211_ATTR_HIDDEN_SSID | 3083 | * enum nl80211_hidden_ssid - values for %NL80211_ATTR_HIDDEN_SSID |
3037 | * @NL80211_HIDDEN_SSID_NOT_IN_USE: do not hide SSID (i.e., broadcast it in | 3084 | * @NL80211_HIDDEN_SSID_NOT_IN_USE: do not hide SSID (i.e., broadcast it in |
3038 | * Beacon frames) | 3085 | * Beacon frames) |
3039 | * @NL80211_HIDDEN_SSID_ZERO_LEN: hide SSID by using zero-length SSID element | 3086 | * @NL80211_HIDDEN_SSID_ZERO_LEN: hide SSID by using zero-length SSID element |
3040 | * in Beacon frames | 3087 | * in Beacon frames |
3041 | * @NL80211_HIDDEN_SSID_ZERO_CONTENTS: hide SSID by using correct length of SSID | 3088 | * @NL80211_HIDDEN_SSID_ZERO_CONTENTS: hide SSID by using correct length of SSID |
3042 | * element in Beacon frames but zero out each byte in the SSID | 3089 | * element in Beacon frames but zero out each byte in the SSID |
3043 | */ | 3090 | */ |
3044 | enum nl80211_hidden_ssid { | 3091 | enum nl80211_hidden_ssid { |
3045 | NL80211_HIDDEN_SSID_NOT_IN_USE, | 3092 | NL80211_HIDDEN_SSID_NOT_IN_USE, |
3046 | NL80211_HIDDEN_SSID_ZERO_LEN, | 3093 | NL80211_HIDDEN_SSID_ZERO_LEN, |
3047 | NL80211_HIDDEN_SSID_ZERO_CONTENTS | 3094 | NL80211_HIDDEN_SSID_ZERO_CONTENTS |
3048 | }; | 3095 | }; |
3049 | 3096 | ||
3050 | /** | 3097 | /** |
3051 | * enum nl80211_sta_wme_attr - station WME attributes | 3098 | * enum nl80211_sta_wme_attr - station WME attributes |
3052 | * @__NL80211_STA_WME_INVALID: invalid number for nested attribute | 3099 | * @__NL80211_STA_WME_INVALID: invalid number for nested attribute |
3053 | * @NL80211_STA_WME_UAPSD_QUEUES: bitmap of uapsd queues. the format | 3100 | * @NL80211_STA_WME_UAPSD_QUEUES: bitmap of uapsd queues. the format |
3054 | * is the same as the AC bitmap in the QoS info field. | 3101 | * is the same as the AC bitmap in the QoS info field. |
3055 | * @NL80211_STA_WME_MAX_SP: max service period. the format is the same | 3102 | * @NL80211_STA_WME_MAX_SP: max service period. the format is the same |
3056 | * as the MAX_SP field in the QoS info field (but already shifted down). | 3103 | * as the MAX_SP field in the QoS info field (but already shifted down). |
3057 | * @__NL80211_STA_WME_AFTER_LAST: internal | 3104 | * @__NL80211_STA_WME_AFTER_LAST: internal |
3058 | * @NL80211_STA_WME_MAX: highest station WME attribute | 3105 | * @NL80211_STA_WME_MAX: highest station WME attribute |
3059 | */ | 3106 | */ |
3060 | enum nl80211_sta_wme_attr { | 3107 | enum nl80211_sta_wme_attr { |
3061 | __NL80211_STA_WME_INVALID, | 3108 | __NL80211_STA_WME_INVALID, |
3062 | NL80211_STA_WME_UAPSD_QUEUES, | 3109 | NL80211_STA_WME_UAPSD_QUEUES, |
3063 | NL80211_STA_WME_MAX_SP, | 3110 | NL80211_STA_WME_MAX_SP, |
3064 | 3111 | ||
3065 | /* keep last */ | 3112 | /* keep last */ |
3066 | __NL80211_STA_WME_AFTER_LAST, | 3113 | __NL80211_STA_WME_AFTER_LAST, |
3067 | NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1 | 3114 | NL80211_STA_WME_MAX = __NL80211_STA_WME_AFTER_LAST - 1 |
3068 | }; | 3115 | }; |
3069 | 3116 | ||
3070 | /** | 3117 | /** |
3071 | * enum nl80211_pmksa_candidate_attr - attributes for PMKSA caching candidates | 3118 | * enum nl80211_pmksa_candidate_attr - attributes for PMKSA caching candidates |
3072 | * @__NL80211_PMKSA_CANDIDATE_INVALID: invalid number for nested attributes | 3119 | * @__NL80211_PMKSA_CANDIDATE_INVALID: invalid number for nested attributes |
3073 | * @NL80211_PMKSA_CANDIDATE_INDEX: candidate index (u32; the smaller, the higher | 3120 | * @NL80211_PMKSA_CANDIDATE_INDEX: candidate index (u32; the smaller, the higher |
3074 | * priority) | 3121 | * priority) |
3075 | * @NL80211_PMKSA_CANDIDATE_BSSID: candidate BSSID (6 octets) | 3122 | * @NL80211_PMKSA_CANDIDATE_BSSID: candidate BSSID (6 octets) |
3076 | * @NL80211_PMKSA_CANDIDATE_PREAUTH: RSN pre-authentication supported (flag) | 3123 | * @NL80211_PMKSA_CANDIDATE_PREAUTH: RSN pre-authentication supported (flag) |
3077 | * @NUM_NL80211_PMKSA_CANDIDATE: number of PMKSA caching candidate attributes | 3124 | * @NUM_NL80211_PMKSA_CANDIDATE: number of PMKSA caching candidate attributes |
3078 | * (internal) | 3125 | * (internal) |
3079 | * @MAX_NL80211_PMKSA_CANDIDATE: highest PMKSA caching candidate attribute | 3126 | * @MAX_NL80211_PMKSA_CANDIDATE: highest PMKSA caching candidate attribute |
3080 | * (internal) | 3127 | * (internal) |
3081 | */ | 3128 | */ |
3082 | enum nl80211_pmksa_candidate_attr { | 3129 | enum nl80211_pmksa_candidate_attr { |
3083 | __NL80211_PMKSA_CANDIDATE_INVALID, | 3130 | __NL80211_PMKSA_CANDIDATE_INVALID, |
3084 | NL80211_PMKSA_CANDIDATE_INDEX, | 3131 | NL80211_PMKSA_CANDIDATE_INDEX, |
3085 | NL80211_PMKSA_CANDIDATE_BSSID, | 3132 | NL80211_PMKSA_CANDIDATE_BSSID, |
3086 | NL80211_PMKSA_CANDIDATE_PREAUTH, | 3133 | NL80211_PMKSA_CANDIDATE_PREAUTH, |
3087 | 3134 | ||
3088 | /* keep last */ | 3135 | /* keep last */ |
3089 | NUM_NL80211_PMKSA_CANDIDATE, | 3136 | NUM_NL80211_PMKSA_CANDIDATE, |
3090 | MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1 | 3137 | MAX_NL80211_PMKSA_CANDIDATE = NUM_NL80211_PMKSA_CANDIDATE - 1 |
3091 | }; | 3138 | }; |
3092 | 3139 | ||
3093 | /** | 3140 | /** |
3094 | * enum nl80211_tdls_operation - values for %NL80211_ATTR_TDLS_OPERATION | 3141 | * enum nl80211_tdls_operation - values for %NL80211_ATTR_TDLS_OPERATION |
3095 | * @NL80211_TDLS_DISCOVERY_REQ: Send a TDLS discovery request | 3142 | * @NL80211_TDLS_DISCOVERY_REQ: Send a TDLS discovery request |
3096 | * @NL80211_TDLS_SETUP: Setup TDLS link | 3143 | * @NL80211_TDLS_SETUP: Setup TDLS link |
3097 | * @NL80211_TDLS_TEARDOWN: Teardown a TDLS link which is already established | 3144 | * @NL80211_TDLS_TEARDOWN: Teardown a TDLS link which is already established |
3098 | * @NL80211_TDLS_ENABLE_LINK: Enable TDLS link | 3145 | * @NL80211_TDLS_ENABLE_LINK: Enable TDLS link |
3099 | * @NL80211_TDLS_DISABLE_LINK: Disable TDLS link | 3146 | * @NL80211_TDLS_DISABLE_LINK: Disable TDLS link |
3100 | */ | 3147 | */ |
3101 | enum nl80211_tdls_operation { | 3148 | enum nl80211_tdls_operation { |
3102 | NL80211_TDLS_DISCOVERY_REQ, | 3149 | NL80211_TDLS_DISCOVERY_REQ, |
3103 | NL80211_TDLS_SETUP, | 3150 | NL80211_TDLS_SETUP, |
3104 | NL80211_TDLS_TEARDOWN, | 3151 | NL80211_TDLS_TEARDOWN, |
3105 | NL80211_TDLS_ENABLE_LINK, | 3152 | NL80211_TDLS_ENABLE_LINK, |
3106 | NL80211_TDLS_DISABLE_LINK, | 3153 | NL80211_TDLS_DISABLE_LINK, |
3107 | }; | 3154 | }; |
3108 | 3155 | ||
3109 | /* | 3156 | /* |
3110 | * enum nl80211_ap_sme_features - device-integrated AP features | 3157 | * enum nl80211_ap_sme_features - device-integrated AP features |
3111 | * Reserved for future use, no bits are defined in | 3158 | * Reserved for future use, no bits are defined in |
3112 | * NL80211_ATTR_DEVICE_AP_SME yet. | 3159 | * NL80211_ATTR_DEVICE_AP_SME yet. |
3113 | enum nl80211_ap_sme_features { | 3160 | enum nl80211_ap_sme_features { |
3114 | }; | 3161 | }; |
3115 | */ | 3162 | */ |
3116 | 3163 | ||
3117 | /** | 3164 | /** |
3118 | * enum nl80211_feature_flags - device/driver features | 3165 | * enum nl80211_feature_flags - device/driver features |
3119 | * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back | 3166 | * @NL80211_FEATURE_SK_TX_STATUS: This driver supports reflecting back |
3120 | * TX status to the socket error queue when requested with the | 3167 | * TX status to the socket error queue when requested with the |
3121 | * socket option. | 3168 | * socket option. |
3122 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. | 3169 | * @NL80211_FEATURE_HT_IBSS: This driver supports IBSS with HT datarates. |
3123 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up | 3170 | * @NL80211_FEATURE_INACTIVITY_TIMER: This driver takes care of freeing up |
3124 | * the connected inactive stations in AP mode. | 3171 | * the connected inactive stations in AP mode. |
3125 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested | 3172 | * @NL80211_FEATURE_CELL_BASE_REG_HINTS: This driver has been tested |
3126 | * to work properly to suppport receiving regulatory hints from | 3173 | * to work properly to suppport receiving regulatory hints from |
3127 | * cellular base stations. | 3174 | * cellular base stations. |
3128 | * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active | 3175 | * @NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL: If this is set, an active |
3129 | * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel | 3176 | * P2P Device (%NL80211_IFTYPE_P2P_DEVICE) requires its own channel |
3130 | * in the interface combinations, even when it's only used for scan | 3177 | * in the interface combinations, even when it's only used for scan |
3131 | * and remain-on-channel. This could be due to, for example, the | 3178 | * and remain-on-channel. This could be due to, for example, the |
3132 | * remain-on-channel implementation requiring a channel context. | 3179 | * remain-on-channel implementation requiring a channel context. |
3133 | * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of | 3180 | * @NL80211_FEATURE_SAE: This driver supports simultaneous authentication of |
3134 | * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station | 3181 | * equals (SAE) with user space SME (NL80211_CMD_AUTHENTICATE) in station |
3135 | * mode | 3182 | * mode |
3136 | * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan | 3183 | * @NL80211_FEATURE_LOW_PRIORITY_SCAN: This driver supports low priority scan |
3137 | * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported | 3184 | * @NL80211_FEATURE_SCAN_FLUSH: Scan flush is supported |
3138 | * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif | 3185 | * @NL80211_FEATURE_AP_SCAN: Support scanning using an AP vif |
3139 | * @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting | 3186 | * @NL80211_FEATURE_VIF_TXPOWER: The driver supports per-vif TX power setting |
3140 | * @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform | 3187 | * @NL80211_FEATURE_NEED_OBSS_SCAN: The driver expects userspace to perform |
3141 | * OBSS scans and generate 20/40 BSS coex reports. This flag is used only | 3188 | * OBSS scans and generate 20/40 BSS coex reports. This flag is used only |
3142 | * for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied. | 3189 | * for drivers implementing the CONNECT API, for AUTH/ASSOC it is implied. |
3143 | * @NL80211_FEATURE_P2P_GO_CTWIN: P2P GO implementation supports CT Window | 3190 | * @NL80211_FEATURE_P2P_GO_CTWIN: P2P GO implementation supports CT Window |
3144 | * setting | 3191 | * setting |
3145 | * @NL80211_FEATURE_P2P_GO_OPPPS: P2P GO implementation supports opportunistic | 3192 | * @NL80211_FEATURE_P2P_GO_OPPPS: P2P GO implementation supports opportunistic |
3146 | * powersave | 3193 | * powersave |
3147 | * @NL80211_FEATURE_FULL_AP_CLIENT_STATE: The driver supports full state | 3194 | * @NL80211_FEATURE_FULL_AP_CLIENT_STATE: The driver supports full state |
3148 | * transitions for AP clients. Without this flag (and if the driver | 3195 | * transitions for AP clients. Without this flag (and if the driver |
3149 | * doesn't have the AP SME in the device) the driver supports adding | 3196 | * doesn't have the AP SME in the device) the driver supports adding |
3150 | * stations only when they're associated and adds them in associated | 3197 | * stations only when they're associated and adds them in associated |
3151 | * state (to later be transitioned into authorized), with this flag | 3198 | * state (to later be transitioned into authorized), with this flag |
3152 | * they should be added before even sending the authentication reply | 3199 | * they should be added before even sending the authentication reply |
3153 | * and then transitioned into authenticated, associated and authorized | 3200 | * and then transitioned into authenticated, associated and authorized |
3154 | * states using station flags. | 3201 | * states using station flags. |
3155 | * Note that even for drivers that support this, the default is to add | 3202 | * Note that even for drivers that support this, the default is to add |
3156 | * stations in authenticated/associated state, so to add unauthenticated | 3203 | * stations in authenticated/associated state, so to add unauthenticated |
3157 | * stations the authenticated/associated bits have to be set in the mask. | 3204 | * stations the authenticated/associated bits have to be set in the mask. |
3158 | */ | 3205 | */ |
3159 | enum nl80211_feature_flags { | 3206 | enum nl80211_feature_flags { |
3160 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, | 3207 | NL80211_FEATURE_SK_TX_STATUS = 1 << 0, |
3161 | NL80211_FEATURE_HT_IBSS = 1 << 1, | 3208 | NL80211_FEATURE_HT_IBSS = 1 << 1, |
3162 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, | 3209 | NL80211_FEATURE_INACTIVITY_TIMER = 1 << 2, |
3163 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, | 3210 | NL80211_FEATURE_CELL_BASE_REG_HINTS = 1 << 3, |
3164 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, | 3211 | NL80211_FEATURE_P2P_DEVICE_NEEDS_CHANNEL = 1 << 4, |
3165 | NL80211_FEATURE_SAE = 1 << 5, | 3212 | NL80211_FEATURE_SAE = 1 << 5, |
3166 | NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, | 3213 | NL80211_FEATURE_LOW_PRIORITY_SCAN = 1 << 6, |
3167 | NL80211_FEATURE_SCAN_FLUSH = 1 << 7, | 3214 | NL80211_FEATURE_SCAN_FLUSH = 1 << 7, |
3168 | NL80211_FEATURE_AP_SCAN = 1 << 8, | 3215 | NL80211_FEATURE_AP_SCAN = 1 << 8, |
3169 | NL80211_FEATURE_VIF_TXPOWER = 1 << 9, | 3216 | NL80211_FEATURE_VIF_TXPOWER = 1 << 9, |
3170 | NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10, | 3217 | NL80211_FEATURE_NEED_OBSS_SCAN = 1 << 10, |
3171 | NL80211_FEATURE_P2P_GO_CTWIN = 1 << 11, | 3218 | NL80211_FEATURE_P2P_GO_CTWIN = 1 << 11, |
3172 | NL80211_FEATURE_P2P_GO_OPPPS = 1 << 12, | 3219 | NL80211_FEATURE_P2P_GO_OPPPS = 1 << 12, |
3173 | NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 13, | 3220 | NL80211_FEATURE_FULL_AP_CLIENT_STATE = 1 << 13, |
3174 | }; | 3221 | }; |
3175 | 3222 | ||
3176 | /** | 3223 | /** |
3177 | * enum nl80211_probe_resp_offload_support_attr - optional supported | 3224 | * enum nl80211_probe_resp_offload_support_attr - optional supported |
3178 | * protocols for probe-response offloading by the driver/FW. | 3225 | * protocols for probe-response offloading by the driver/FW. |
3179 | * To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute. | 3226 | * To be used with the %NL80211_ATTR_PROBE_RESP_OFFLOAD attribute. |
3180 | * Each enum value represents a bit in the bitmap of supported | 3227 | * Each enum value represents a bit in the bitmap of supported |
3181 | * protocols. Typically a subset of probe-requests belonging to a | 3228 | * protocols. Typically a subset of probe-requests belonging to a |
3182 | * supported protocol will be excluded from offload and uploaded | 3229 | * supported protocol will be excluded from offload and uploaded |
3183 | * to the host. | 3230 | * to the host. |
3184 | * | 3231 | * |
3185 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: Support for WPS ver. 1 | 3232 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS: Support for WPS ver. 1 |
3186 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: Support for WPS ver. 2 | 3233 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2: Support for WPS ver. 2 |
3187 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P | 3234 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P: Support for P2P |
3188 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: Support for 802.11u | 3235 | * @NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U: Support for 802.11u |
3189 | */ | 3236 | */ |
3190 | enum nl80211_probe_resp_offload_support_attr { | 3237 | enum nl80211_probe_resp_offload_support_attr { |
3191 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS = 1<<0, | 3238 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS = 1<<0, |
3192 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 = 1<<1, | 3239 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 = 1<<1, |
3193 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P = 1<<2, | 3240 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P = 1<<2, |
3194 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U = 1<<3, | 3241 | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U = 1<<3, |
3195 | }; | 3242 | }; |
3196 | 3243 | ||
3197 | /** | 3244 | /** |
3198 | * enum nl80211_connect_failed_reason - connection request failed reasons | 3245 | * enum nl80211_connect_failed_reason - connection request failed reasons |
3199 | * @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be | 3246 | * @NL80211_CONN_FAIL_MAX_CLIENTS: Maximum number of clients that can be |
3200 | * handled by the AP is reached. | 3247 | * handled by the AP is reached. |
3201 | * @NL80211_CONN_FAIL_BLOCKED_CLIENT: Client's MAC is in the AP's blocklist. | 3248 | * @NL80211_CONN_FAIL_BLOCKED_CLIENT: Client's MAC is in the AP's blocklist. |
3202 | */ | 3249 | */ |
3203 | enum nl80211_connect_failed_reason { | 3250 | enum nl80211_connect_failed_reason { |
3204 | NL80211_CONN_FAIL_MAX_CLIENTS, | 3251 | NL80211_CONN_FAIL_MAX_CLIENTS, |
3205 | NL80211_CONN_FAIL_BLOCKED_CLIENT, | 3252 | NL80211_CONN_FAIL_BLOCKED_CLIENT, |
3206 | }; | 3253 | }; |
3207 | 3254 | ||
3208 | /** | 3255 | /** |
3209 | * enum nl80211_scan_flags - scan request control flags | 3256 | * enum nl80211_scan_flags - scan request control flags |
3210 | * | 3257 | * |
3211 | * Scan request control flags are used to control the handling | 3258 | * Scan request control flags are used to control the handling |
3212 | * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN | 3259 | * of NL80211_CMD_TRIGGER_SCAN and NL80211_CMD_START_SCHED_SCAN |
3213 | * requests. | 3260 | * requests. |
3214 | * | 3261 | * |
3215 | * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority | 3262 | * @NL80211_SCAN_FLAG_LOW_PRIORITY: scan request has low priority |
3216 | * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning | 3263 | * @NL80211_SCAN_FLAG_FLUSH: flush cache before scanning |
3217 | * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured | 3264 | * @NL80211_SCAN_FLAG_AP: force a scan even if the interface is configured |
3218 | * as AP and the beaconing has already been configured. This attribute is | 3265 | * as AP and the beaconing has already been configured. This attribute is |
3219 | * dangerous because will destroy stations performance as a lot of frames | 3266 | * dangerous because will destroy stations performance as a lot of frames |
3220 | * will be lost while scanning off-channel, therefore it must be used only | 3267 | * will be lost while scanning off-channel, therefore it must be used only |
3221 | * when really needed | 3268 | * when really needed |
3222 | */ | 3269 | */ |
3223 | enum nl80211_scan_flags { | 3270 | enum nl80211_scan_flags { |
3224 | NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, | 3271 | NL80211_SCAN_FLAG_LOW_PRIORITY = 1<<0, |
3225 | NL80211_SCAN_FLAG_FLUSH = 1<<1, | 3272 | NL80211_SCAN_FLAG_FLUSH = 1<<1, |
3226 | NL80211_SCAN_FLAG_AP = 1<<2, | 3273 | NL80211_SCAN_FLAG_AP = 1<<2, |
3227 | }; | 3274 | }; |
3228 | 3275 | ||
3229 | #endif /* __LINUX_NL80211_H */ | 3276 | #endif /* __LINUX_NL80211_H */ |
3230 | 3277 |
net/wireless/mesh.c
1 | #include <linux/ieee80211.h> | 1 | #include <linux/ieee80211.h> |
2 | #include <linux/export.h> | 2 | #include <linux/export.h> |
3 | #include <net/cfg80211.h> | 3 | #include <net/cfg80211.h> |
4 | #include "nl80211.h" | 4 | #include "nl80211.h" |
5 | #include "core.h" | 5 | #include "core.h" |
6 | #include "rdev-ops.h" | 6 | #include "rdev-ops.h" |
7 | 7 | ||
8 | /* Default values, timeouts in ms */ | 8 | /* Default values, timeouts in ms */ |
9 | #define MESH_TTL 31 | 9 | #define MESH_TTL 31 |
10 | #define MESH_DEFAULT_ELEMENT_TTL 31 | 10 | #define MESH_DEFAULT_ELEMENT_TTL 31 |
11 | #define MESH_MAX_RETR 3 | 11 | #define MESH_MAX_RETR 3 |
12 | #define MESH_RET_T 100 | 12 | #define MESH_RET_T 100 |
13 | #define MESH_CONF_T 100 | 13 | #define MESH_CONF_T 100 |
14 | #define MESH_HOLD_T 100 | 14 | #define MESH_HOLD_T 100 |
15 | 15 | ||
16 | #define MESH_PATH_TIMEOUT 5000 | 16 | #define MESH_PATH_TIMEOUT 5000 |
17 | #define MESH_RANN_INTERVAL 5000 | 17 | #define MESH_RANN_INTERVAL 5000 |
18 | #define MESH_PATH_TO_ROOT_TIMEOUT 6000 | 18 | #define MESH_PATH_TO_ROOT_TIMEOUT 6000 |
19 | #define MESH_ROOT_INTERVAL 5000 | 19 | #define MESH_ROOT_INTERVAL 5000 |
20 | #define MESH_ROOT_CONFIRMATION_INTERVAL 2000 | 20 | #define MESH_ROOT_CONFIRMATION_INTERVAL 2000 |
21 | 21 | ||
22 | /* | 22 | /* |
23 | * Minimum interval between two consecutive PREQs originated by the same | 23 | * Minimum interval between two consecutive PREQs originated by the same |
24 | * interface | 24 | * interface |
25 | */ | 25 | */ |
26 | #define MESH_PREQ_MIN_INT 10 | 26 | #define MESH_PREQ_MIN_INT 10 |
27 | #define MESH_PERR_MIN_INT 100 | 27 | #define MESH_PERR_MIN_INT 100 |
28 | #define MESH_DIAM_TRAVERSAL_TIME 50 | 28 | #define MESH_DIAM_TRAVERSAL_TIME 50 |
29 | 29 | ||
30 | #define MESH_RSSI_THRESHOLD 0 | 30 | #define MESH_RSSI_THRESHOLD 0 |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds | 33 | * A path will be refreshed if it is used PATH_REFRESH_TIME milliseconds |
34 | * before timing out. This way it will remain ACTIVE and no data frames | 34 | * before timing out. This way it will remain ACTIVE and no data frames |
35 | * will be unnecessarily held in the pending queue. | 35 | * will be unnecessarily held in the pending queue. |
36 | */ | 36 | */ |
37 | #define MESH_PATH_REFRESH_TIME 1000 | 37 | #define MESH_PATH_REFRESH_TIME 1000 |
38 | #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) | 38 | #define MESH_MIN_DISCOVERY_TIMEOUT (2 * MESH_DIAM_TRAVERSAL_TIME) |
39 | 39 | ||
40 | /* Default maximum number of established plinks per interface */ | 40 | /* Default maximum number of established plinks per interface */ |
41 | #define MESH_MAX_ESTAB_PLINKS 32 | 41 | #define MESH_MAX_ESTAB_PLINKS 32 |
42 | 42 | ||
43 | #define MESH_MAX_PREQ_RETRIES 4 | 43 | #define MESH_MAX_PREQ_RETRIES 4 |
44 | 44 | ||
45 | #define MESH_SYNC_NEIGHBOR_OFFSET_MAX 50 | 45 | #define MESH_SYNC_NEIGHBOR_OFFSET_MAX 50 |
46 | 46 | ||
47 | #define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units (=TUs) */ | 47 | #define MESH_DEFAULT_BEACON_INTERVAL 1000 /* in 1024 us units (=TUs) */ |
48 | #define MESH_DEFAULT_DTIM_PERIOD 2 | 48 | #define MESH_DEFAULT_DTIM_PERIOD 2 |
49 | #define MESH_DEFAULT_AWAKE_WINDOW 10 /* in 1024 us units (=TUs) */ | ||
49 | 50 | ||
50 | const struct mesh_config default_mesh_config = { | 51 | const struct mesh_config default_mesh_config = { |
51 | .dot11MeshRetryTimeout = MESH_RET_T, | 52 | .dot11MeshRetryTimeout = MESH_RET_T, |
52 | .dot11MeshConfirmTimeout = MESH_CONF_T, | 53 | .dot11MeshConfirmTimeout = MESH_CONF_T, |
53 | .dot11MeshHoldingTimeout = MESH_HOLD_T, | 54 | .dot11MeshHoldingTimeout = MESH_HOLD_T, |
54 | .dot11MeshMaxRetries = MESH_MAX_RETR, | 55 | .dot11MeshMaxRetries = MESH_MAX_RETR, |
55 | .dot11MeshTTL = MESH_TTL, | 56 | .dot11MeshTTL = MESH_TTL, |
56 | .element_ttl = MESH_DEFAULT_ELEMENT_TTL, | 57 | .element_ttl = MESH_DEFAULT_ELEMENT_TTL, |
57 | .auto_open_plinks = true, | 58 | .auto_open_plinks = true, |
58 | .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS, | 59 | .dot11MeshMaxPeerLinks = MESH_MAX_ESTAB_PLINKS, |
59 | .dot11MeshNbrOffsetMaxNeighbor = MESH_SYNC_NEIGHBOR_OFFSET_MAX, | 60 | .dot11MeshNbrOffsetMaxNeighbor = MESH_SYNC_NEIGHBOR_OFFSET_MAX, |
60 | .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT, | 61 | .dot11MeshHWMPactivePathTimeout = MESH_PATH_TIMEOUT, |
61 | .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT, | 62 | .dot11MeshHWMPpreqMinInterval = MESH_PREQ_MIN_INT, |
62 | .dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT, | 63 | .dot11MeshHWMPperrMinInterval = MESH_PERR_MIN_INT, |
63 | .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME, | 64 | .dot11MeshHWMPnetDiameterTraversalTime = MESH_DIAM_TRAVERSAL_TIME, |
64 | .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, | 65 | .dot11MeshHWMPmaxPREQretries = MESH_MAX_PREQ_RETRIES, |
65 | .path_refresh_time = MESH_PATH_REFRESH_TIME, | 66 | .path_refresh_time = MESH_PATH_REFRESH_TIME, |
66 | .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, | 67 | .min_discovery_timeout = MESH_MIN_DISCOVERY_TIMEOUT, |
67 | .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, | 68 | .dot11MeshHWMPRannInterval = MESH_RANN_INTERVAL, |
68 | .dot11MeshGateAnnouncementProtocol = false, | 69 | .dot11MeshGateAnnouncementProtocol = false, |
69 | .dot11MeshForwarding = true, | 70 | .dot11MeshForwarding = true, |
70 | .rssi_threshold = MESH_RSSI_THRESHOLD, | 71 | .rssi_threshold = MESH_RSSI_THRESHOLD, |
71 | .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED, | 72 | .ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED, |
72 | .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT, | 73 | .dot11MeshHWMPactivePathToRootTimeout = MESH_PATH_TO_ROOT_TIMEOUT, |
73 | .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL, | 74 | .dot11MeshHWMProotInterval = MESH_ROOT_INTERVAL, |
74 | .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, | 75 | .dot11MeshHWMPconfirmationInterval = MESH_ROOT_CONFIRMATION_INTERVAL, |
76 | .power_mode = NL80211_MESH_POWER_ACTIVE, | ||
77 | .dot11MeshAwakeWindowDuration = MESH_DEFAULT_AWAKE_WINDOW, | ||
75 | }; | 78 | }; |
76 | 79 | ||
77 | const struct mesh_setup default_mesh_setup = { | 80 | const struct mesh_setup default_mesh_setup = { |
78 | /* cfg80211_join_mesh() will pick a channel if needed */ | 81 | /* cfg80211_join_mesh() will pick a channel if needed */ |
79 | .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, | 82 | .sync_method = IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET, |
80 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, | 83 | .path_sel_proto = IEEE80211_PATH_PROTOCOL_HWMP, |
81 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, | 84 | .path_metric = IEEE80211_PATH_METRIC_AIRTIME, |
82 | .ie = NULL, | 85 | .ie = NULL, |
83 | .ie_len = 0, | 86 | .ie_len = 0, |
84 | .is_secure = false, | 87 | .is_secure = false, |
85 | .beacon_interval = MESH_DEFAULT_BEACON_INTERVAL, | 88 | .beacon_interval = MESH_DEFAULT_BEACON_INTERVAL, |
86 | .dtim_period = MESH_DEFAULT_DTIM_PERIOD, | 89 | .dtim_period = MESH_DEFAULT_DTIM_PERIOD, |
87 | }; | 90 | }; |
88 | 91 | ||
89 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 92 | int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev, |
90 | struct net_device *dev, | 93 | struct net_device *dev, |
91 | struct mesh_setup *setup, | 94 | struct mesh_setup *setup, |
92 | const struct mesh_config *conf) | 95 | const struct mesh_config *conf) |
93 | { | 96 | { |
94 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 97 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
95 | int err; | 98 | int err; |
96 | 99 | ||
97 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); | 100 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != IEEE80211_MAX_MESH_ID_LEN); |
98 | 101 | ||
99 | ASSERT_WDEV_LOCK(wdev); | 102 | ASSERT_WDEV_LOCK(wdev); |
100 | 103 | ||
101 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 104 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
102 | return -EOPNOTSUPP; | 105 | return -EOPNOTSUPP; |
103 | 106 | ||
104 | if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && | 107 | if (!(rdev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && |
105 | setup->is_secure) | 108 | setup->is_secure) |
106 | return -EOPNOTSUPP; | 109 | return -EOPNOTSUPP; |
107 | 110 | ||
108 | if (wdev->mesh_id_len) | 111 | if (wdev->mesh_id_len) |
109 | return -EALREADY; | 112 | return -EALREADY; |
110 | 113 | ||
111 | if (!setup->mesh_id_len) | 114 | if (!setup->mesh_id_len) |
112 | return -EINVAL; | 115 | return -EINVAL; |
113 | 116 | ||
114 | if (!rdev->ops->join_mesh) | 117 | if (!rdev->ops->join_mesh) |
115 | return -EOPNOTSUPP; | 118 | return -EOPNOTSUPP; |
116 | 119 | ||
117 | if (!setup->chandef.chan) { | 120 | if (!setup->chandef.chan) { |
118 | /* if no channel explicitly given, use preset channel */ | 121 | /* if no channel explicitly given, use preset channel */ |
119 | setup->chandef = wdev->preset_chandef; | 122 | setup->chandef = wdev->preset_chandef; |
120 | } | 123 | } |
121 | 124 | ||
122 | if (!setup->chandef.chan) { | 125 | if (!setup->chandef.chan) { |
123 | /* if we don't have that either, use the first usable channel */ | 126 | /* if we don't have that either, use the first usable channel */ |
124 | enum ieee80211_band band; | 127 | enum ieee80211_band band; |
125 | 128 | ||
126 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 129 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
127 | struct ieee80211_supported_band *sband; | 130 | struct ieee80211_supported_band *sband; |
128 | struct ieee80211_channel *chan; | 131 | struct ieee80211_channel *chan; |
129 | int i; | 132 | int i; |
130 | 133 | ||
131 | sband = rdev->wiphy.bands[band]; | 134 | sband = rdev->wiphy.bands[band]; |
132 | if (!sband) | 135 | if (!sband) |
133 | continue; | 136 | continue; |
134 | 137 | ||
135 | for (i = 0; i < sband->n_channels; i++) { | 138 | for (i = 0; i < sband->n_channels; i++) { |
136 | chan = &sband->channels[i]; | 139 | chan = &sband->channels[i]; |
137 | if (chan->flags & (IEEE80211_CHAN_NO_IBSS | | 140 | if (chan->flags & (IEEE80211_CHAN_NO_IBSS | |
138 | IEEE80211_CHAN_PASSIVE_SCAN | | 141 | IEEE80211_CHAN_PASSIVE_SCAN | |
139 | IEEE80211_CHAN_DISABLED | | 142 | IEEE80211_CHAN_DISABLED | |
140 | IEEE80211_CHAN_RADAR)) | 143 | IEEE80211_CHAN_RADAR)) |
141 | continue; | 144 | continue; |
142 | setup->chandef.chan = chan; | 145 | setup->chandef.chan = chan; |
143 | break; | 146 | break; |
144 | } | 147 | } |
145 | 148 | ||
146 | if (setup->chandef.chan) | 149 | if (setup->chandef.chan) |
147 | break; | 150 | break; |
148 | } | 151 | } |
149 | 152 | ||
150 | /* no usable channel ... */ | 153 | /* no usable channel ... */ |
151 | if (!setup->chandef.chan) | 154 | if (!setup->chandef.chan) |
152 | return -EINVAL; | 155 | return -EINVAL; |
153 | 156 | ||
154 | setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT; | 157 | setup->chandef.width = NL80211_CHAN_WIDTH_20_NOHT; |
155 | setup->chandef.center_freq1 = setup->chandef.chan->center_freq; | 158 | setup->chandef.center_freq1 = setup->chandef.chan->center_freq; |
156 | } | 159 | } |
157 | 160 | ||
158 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef)) | 161 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef)) |
159 | return -EINVAL; | 162 | return -EINVAL; |
160 | 163 | ||
161 | err = cfg80211_can_use_chan(rdev, wdev, setup->chandef.chan, | 164 | err = cfg80211_can_use_chan(rdev, wdev, setup->chandef.chan, |
162 | CHAN_MODE_SHARED); | 165 | CHAN_MODE_SHARED); |
163 | if (err) | 166 | if (err) |
164 | return err; | 167 | return err; |
165 | 168 | ||
166 | err = rdev_join_mesh(rdev, dev, conf, setup); | 169 | err = rdev_join_mesh(rdev, dev, conf, setup); |
167 | if (!err) { | 170 | if (!err) { |
168 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); | 171 | memcpy(wdev->ssid, setup->mesh_id, setup->mesh_id_len); |
169 | wdev->mesh_id_len = setup->mesh_id_len; | 172 | wdev->mesh_id_len = setup->mesh_id_len; |
170 | wdev->channel = setup->chandef.chan; | 173 | wdev->channel = setup->chandef.chan; |
171 | } | 174 | } |
172 | 175 | ||
173 | return err; | 176 | return err; |
174 | } | 177 | } |
175 | 178 | ||
176 | int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, | 179 | int cfg80211_join_mesh(struct cfg80211_registered_device *rdev, |
177 | struct net_device *dev, | 180 | struct net_device *dev, |
178 | struct mesh_setup *setup, | 181 | struct mesh_setup *setup, |
179 | const struct mesh_config *conf) | 182 | const struct mesh_config *conf) |
180 | { | 183 | { |
181 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 184 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
182 | int err; | 185 | int err; |
183 | 186 | ||
184 | mutex_lock(&rdev->devlist_mtx); | 187 | mutex_lock(&rdev->devlist_mtx); |
185 | wdev_lock(wdev); | 188 | wdev_lock(wdev); |
186 | err = __cfg80211_join_mesh(rdev, dev, setup, conf); | 189 | err = __cfg80211_join_mesh(rdev, dev, setup, conf); |
187 | wdev_unlock(wdev); | 190 | wdev_unlock(wdev); |
188 | mutex_unlock(&rdev->devlist_mtx); | 191 | mutex_unlock(&rdev->devlist_mtx); |
189 | 192 | ||
190 | return err; | 193 | return err; |
191 | } | 194 | } |
192 | 195 | ||
193 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, | 196 | int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev, |
194 | struct wireless_dev *wdev, | 197 | struct wireless_dev *wdev, |
195 | struct cfg80211_chan_def *chandef) | 198 | struct cfg80211_chan_def *chandef) |
196 | { | 199 | { |
197 | int err; | 200 | int err; |
198 | 201 | ||
199 | /* | 202 | /* |
200 | * Workaround for libertas (only!), it puts the interface | 203 | * Workaround for libertas (only!), it puts the interface |
201 | * into mesh mode but doesn't implement join_mesh. Instead, | 204 | * into mesh mode but doesn't implement join_mesh. Instead, |
202 | * it is configured via sysfs and then joins the mesh when | 205 | * it is configured via sysfs and then joins the mesh when |
203 | * you set the channel. Note that the libertas mesh isn't | 206 | * you set the channel. Note that the libertas mesh isn't |
204 | * compatible with 802.11 mesh. | 207 | * compatible with 802.11 mesh. |
205 | */ | 208 | */ |
206 | if (rdev->ops->libertas_set_mesh_channel) { | 209 | if (rdev->ops->libertas_set_mesh_channel) { |
207 | if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT) | 210 | if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT) |
208 | return -EINVAL; | 211 | return -EINVAL; |
209 | 212 | ||
210 | if (!netif_running(wdev->netdev)) | 213 | if (!netif_running(wdev->netdev)) |
211 | return -ENETDOWN; | 214 | return -ENETDOWN; |
212 | 215 | ||
213 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, | 216 | err = cfg80211_can_use_chan(rdev, wdev, chandef->chan, |
214 | CHAN_MODE_SHARED); | 217 | CHAN_MODE_SHARED); |
215 | if (err) | 218 | if (err) |
216 | return err; | 219 | return err; |
217 | 220 | ||
218 | err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, | 221 | err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev, |
219 | chandef->chan); | 222 | chandef->chan); |
220 | if (!err) | 223 | if (!err) |
221 | wdev->channel = chandef->chan; | 224 | wdev->channel = chandef->chan; |
222 | 225 | ||
223 | return err; | 226 | return err; |
224 | } | 227 | } |
225 | 228 | ||
226 | if (wdev->mesh_id_len) | 229 | if (wdev->mesh_id_len) |
227 | return -EBUSY; | 230 | return -EBUSY; |
228 | 231 | ||
229 | wdev->preset_chandef = *chandef; | 232 | wdev->preset_chandef = *chandef; |
230 | return 0; | 233 | return 0; |
231 | } | 234 | } |
232 | 235 | ||
233 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, | 236 | void cfg80211_notify_new_peer_candidate(struct net_device *dev, |
234 | const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) | 237 | const u8 *macaddr, const u8* ie, u8 ie_len, gfp_t gfp) |
235 | { | 238 | { |
236 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 239 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
237 | 240 | ||
238 | trace_cfg80211_notify_new_peer_candidate(dev, macaddr); | 241 | trace_cfg80211_notify_new_peer_candidate(dev, macaddr); |
239 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) | 242 | if (WARN_ON(wdev->iftype != NL80211_IFTYPE_MESH_POINT)) |
240 | return; | 243 | return; |
241 | 244 | ||
242 | nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, | 245 | nl80211_send_new_peer_candidate(wiphy_to_dev(wdev->wiphy), dev, |
243 | macaddr, ie, ie_len, gfp); | 246 | macaddr, ie, ie_len, gfp); |
244 | } | 247 | } |
245 | EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); | 248 | EXPORT_SYMBOL(cfg80211_notify_new_peer_candidate); |
246 | 249 | ||
247 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 250 | static int __cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
248 | struct net_device *dev) | 251 | struct net_device *dev) |
249 | { | 252 | { |
250 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 253 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
251 | int err; | 254 | int err; |
252 | 255 | ||
253 | ASSERT_WDEV_LOCK(wdev); | 256 | ASSERT_WDEV_LOCK(wdev); |
254 | 257 | ||
255 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 258 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
256 | return -EOPNOTSUPP; | 259 | return -EOPNOTSUPP; |
257 | 260 | ||
258 | if (!rdev->ops->leave_mesh) | 261 | if (!rdev->ops->leave_mesh) |
259 | return -EOPNOTSUPP; | 262 | return -EOPNOTSUPP; |
260 | 263 | ||
261 | if (!wdev->mesh_id_len) | 264 | if (!wdev->mesh_id_len) |
262 | return -ENOTCONN; | 265 | return -ENOTCONN; |
263 | 266 | ||
264 | err = rdev_leave_mesh(rdev, dev); | 267 | err = rdev_leave_mesh(rdev, dev); |
265 | if (!err) { | 268 | if (!err) { |
266 | wdev->mesh_id_len = 0; | 269 | wdev->mesh_id_len = 0; |
267 | wdev->channel = NULL; | 270 | wdev->channel = NULL; |
268 | } | 271 | } |
269 | 272 | ||
270 | return err; | 273 | return err; |
271 | } | 274 | } |
272 | 275 | ||
273 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, | 276 | int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev, |
274 | struct net_device *dev) | 277 | struct net_device *dev) |
275 | { | 278 | { |
276 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 279 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
277 | int err; | 280 | int err; |
278 | 281 | ||
279 | wdev_lock(wdev); | 282 | wdev_lock(wdev); |
280 | err = __cfg80211_leave_mesh(rdev, dev); | 283 | err = __cfg80211_leave_mesh(rdev, dev); |
281 | wdev_unlock(wdev); | 284 | wdev_unlock(wdev); |
282 | 285 | ||
283 | return err; | 286 | return err; |
284 | } | 287 | } |
285 | 288 |
net/wireless/nl80211.c
1 | /* | 1 | /* |
2 | * This is the new netlink-based wireless configuration interface. | 2 | * This is the new netlink-based wireless configuration interface. |
3 | * | 3 | * |
4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> | 4 | * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/if.h> | 7 | #include <linux/if.h> |
8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
9 | #include <linux/err.h> | 9 | #include <linux/err.h> |
10 | #include <linux/slab.h> | 10 | #include <linux/slab.h> |
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/if_ether.h> | 12 | #include <linux/if_ether.h> |
13 | #include <linux/ieee80211.h> | 13 | #include <linux/ieee80211.h> |
14 | #include <linux/nl80211.h> | 14 | #include <linux/nl80211.h> |
15 | #include <linux/rtnetlink.h> | 15 | #include <linux/rtnetlink.h> |
16 | #include <linux/netlink.h> | 16 | #include <linux/netlink.h> |
17 | #include <linux/etherdevice.h> | 17 | #include <linux/etherdevice.h> |
18 | #include <net/net_namespace.h> | 18 | #include <net/net_namespace.h> |
19 | #include <net/genetlink.h> | 19 | #include <net/genetlink.h> |
20 | #include <net/cfg80211.h> | 20 | #include <net/cfg80211.h> |
21 | #include <net/sock.h> | 21 | #include <net/sock.h> |
22 | #include "core.h" | 22 | #include "core.h" |
23 | #include "nl80211.h" | 23 | #include "nl80211.h" |
24 | #include "reg.h" | 24 | #include "reg.h" |
25 | #include "rdev-ops.h" | 25 | #include "rdev-ops.h" |
26 | 26 | ||
27 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | 27 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, |
28 | struct genl_info *info, | 28 | struct genl_info *info, |
29 | struct cfg80211_crypto_settings *settings, | 29 | struct cfg80211_crypto_settings *settings, |
30 | int cipher_limit); | 30 | int cipher_limit); |
31 | 31 | ||
32 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | 32 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, |
33 | struct genl_info *info); | 33 | struct genl_info *info); |
34 | static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, | 34 | static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, |
35 | struct genl_info *info); | 35 | struct genl_info *info); |
36 | 36 | ||
37 | /* the netlink family */ | 37 | /* the netlink family */ |
38 | static struct genl_family nl80211_fam = { | 38 | static struct genl_family nl80211_fam = { |
39 | .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ | 39 | .id = GENL_ID_GENERATE, /* don't bother with a hardcoded ID */ |
40 | .name = "nl80211", /* have users key off the name instead */ | 40 | .name = "nl80211", /* have users key off the name instead */ |
41 | .hdrsize = 0, /* no private header */ | 41 | .hdrsize = 0, /* no private header */ |
42 | .version = 1, /* no particular meaning now */ | 42 | .version = 1, /* no particular meaning now */ |
43 | .maxattr = NL80211_ATTR_MAX, | 43 | .maxattr = NL80211_ATTR_MAX, |
44 | .netnsok = true, | 44 | .netnsok = true, |
45 | .pre_doit = nl80211_pre_doit, | 45 | .pre_doit = nl80211_pre_doit, |
46 | .post_doit = nl80211_post_doit, | 46 | .post_doit = nl80211_post_doit, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | /* returns ERR_PTR values */ | 49 | /* returns ERR_PTR values */ |
50 | static struct wireless_dev * | 50 | static struct wireless_dev * |
51 | __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) | 51 | __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs) |
52 | { | 52 | { |
53 | struct cfg80211_registered_device *rdev; | 53 | struct cfg80211_registered_device *rdev; |
54 | struct wireless_dev *result = NULL; | 54 | struct wireless_dev *result = NULL; |
55 | bool have_ifidx = attrs[NL80211_ATTR_IFINDEX]; | 55 | bool have_ifidx = attrs[NL80211_ATTR_IFINDEX]; |
56 | bool have_wdev_id = attrs[NL80211_ATTR_WDEV]; | 56 | bool have_wdev_id = attrs[NL80211_ATTR_WDEV]; |
57 | u64 wdev_id; | 57 | u64 wdev_id; |
58 | int wiphy_idx = -1; | 58 | int wiphy_idx = -1; |
59 | int ifidx = -1; | 59 | int ifidx = -1; |
60 | 60 | ||
61 | assert_cfg80211_lock(); | 61 | assert_cfg80211_lock(); |
62 | 62 | ||
63 | if (!have_ifidx && !have_wdev_id) | 63 | if (!have_ifidx && !have_wdev_id) |
64 | return ERR_PTR(-EINVAL); | 64 | return ERR_PTR(-EINVAL); |
65 | 65 | ||
66 | if (have_ifidx) | 66 | if (have_ifidx) |
67 | ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); | 67 | ifidx = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); |
68 | if (have_wdev_id) { | 68 | if (have_wdev_id) { |
69 | wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]); | 69 | wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]); |
70 | wiphy_idx = wdev_id >> 32; | 70 | wiphy_idx = wdev_id >> 32; |
71 | } | 71 | } |
72 | 72 | ||
73 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | 73 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
74 | struct wireless_dev *wdev; | 74 | struct wireless_dev *wdev; |
75 | 75 | ||
76 | if (wiphy_net(&rdev->wiphy) != netns) | 76 | if (wiphy_net(&rdev->wiphy) != netns) |
77 | continue; | 77 | continue; |
78 | 78 | ||
79 | if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) | 79 | if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) |
80 | continue; | 80 | continue; |
81 | 81 | ||
82 | mutex_lock(&rdev->devlist_mtx); | 82 | mutex_lock(&rdev->devlist_mtx); |
83 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | 83 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
84 | if (have_ifidx && wdev->netdev && | 84 | if (have_ifidx && wdev->netdev && |
85 | wdev->netdev->ifindex == ifidx) { | 85 | wdev->netdev->ifindex == ifidx) { |
86 | result = wdev; | 86 | result = wdev; |
87 | break; | 87 | break; |
88 | } | 88 | } |
89 | if (have_wdev_id && wdev->identifier == (u32)wdev_id) { | 89 | if (have_wdev_id && wdev->identifier == (u32)wdev_id) { |
90 | result = wdev; | 90 | result = wdev; |
91 | break; | 91 | break; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | mutex_unlock(&rdev->devlist_mtx); | 94 | mutex_unlock(&rdev->devlist_mtx); |
95 | 95 | ||
96 | if (result) | 96 | if (result) |
97 | break; | 97 | break; |
98 | } | 98 | } |
99 | 99 | ||
100 | if (result) | 100 | if (result) |
101 | return result; | 101 | return result; |
102 | return ERR_PTR(-ENODEV); | 102 | return ERR_PTR(-ENODEV); |
103 | } | 103 | } |
104 | 104 | ||
105 | static struct cfg80211_registered_device * | 105 | static struct cfg80211_registered_device * |
106 | __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) | 106 | __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs) |
107 | { | 107 | { |
108 | struct cfg80211_registered_device *rdev = NULL, *tmp; | 108 | struct cfg80211_registered_device *rdev = NULL, *tmp; |
109 | struct net_device *netdev; | 109 | struct net_device *netdev; |
110 | 110 | ||
111 | assert_cfg80211_lock(); | 111 | assert_cfg80211_lock(); |
112 | 112 | ||
113 | if (!attrs[NL80211_ATTR_WIPHY] && | 113 | if (!attrs[NL80211_ATTR_WIPHY] && |
114 | !attrs[NL80211_ATTR_IFINDEX] && | 114 | !attrs[NL80211_ATTR_IFINDEX] && |
115 | !attrs[NL80211_ATTR_WDEV]) | 115 | !attrs[NL80211_ATTR_WDEV]) |
116 | return ERR_PTR(-EINVAL); | 116 | return ERR_PTR(-EINVAL); |
117 | 117 | ||
118 | if (attrs[NL80211_ATTR_WIPHY]) | 118 | if (attrs[NL80211_ATTR_WIPHY]) |
119 | rdev = cfg80211_rdev_by_wiphy_idx( | 119 | rdev = cfg80211_rdev_by_wiphy_idx( |
120 | nla_get_u32(attrs[NL80211_ATTR_WIPHY])); | 120 | nla_get_u32(attrs[NL80211_ATTR_WIPHY])); |
121 | 121 | ||
122 | if (attrs[NL80211_ATTR_WDEV]) { | 122 | if (attrs[NL80211_ATTR_WDEV]) { |
123 | u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]); | 123 | u64 wdev_id = nla_get_u64(attrs[NL80211_ATTR_WDEV]); |
124 | struct wireless_dev *wdev; | 124 | struct wireless_dev *wdev; |
125 | bool found = false; | 125 | bool found = false; |
126 | 126 | ||
127 | tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); | 127 | tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); |
128 | if (tmp) { | 128 | if (tmp) { |
129 | /* make sure wdev exists */ | 129 | /* make sure wdev exists */ |
130 | mutex_lock(&tmp->devlist_mtx); | 130 | mutex_lock(&tmp->devlist_mtx); |
131 | list_for_each_entry(wdev, &tmp->wdev_list, list) { | 131 | list_for_each_entry(wdev, &tmp->wdev_list, list) { |
132 | if (wdev->identifier != (u32)wdev_id) | 132 | if (wdev->identifier != (u32)wdev_id) |
133 | continue; | 133 | continue; |
134 | found = true; | 134 | found = true; |
135 | break; | 135 | break; |
136 | } | 136 | } |
137 | mutex_unlock(&tmp->devlist_mtx); | 137 | mutex_unlock(&tmp->devlist_mtx); |
138 | 138 | ||
139 | if (!found) | 139 | if (!found) |
140 | tmp = NULL; | 140 | tmp = NULL; |
141 | 141 | ||
142 | if (rdev && tmp != rdev) | 142 | if (rdev && tmp != rdev) |
143 | return ERR_PTR(-EINVAL); | 143 | return ERR_PTR(-EINVAL); |
144 | rdev = tmp; | 144 | rdev = tmp; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | 147 | ||
148 | if (attrs[NL80211_ATTR_IFINDEX]) { | 148 | if (attrs[NL80211_ATTR_IFINDEX]) { |
149 | int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); | 149 | int ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]); |
150 | netdev = dev_get_by_index(netns, ifindex); | 150 | netdev = dev_get_by_index(netns, ifindex); |
151 | if (netdev) { | 151 | if (netdev) { |
152 | if (netdev->ieee80211_ptr) | 152 | if (netdev->ieee80211_ptr) |
153 | tmp = wiphy_to_dev( | 153 | tmp = wiphy_to_dev( |
154 | netdev->ieee80211_ptr->wiphy); | 154 | netdev->ieee80211_ptr->wiphy); |
155 | else | 155 | else |
156 | tmp = NULL; | 156 | tmp = NULL; |
157 | 157 | ||
158 | dev_put(netdev); | 158 | dev_put(netdev); |
159 | 159 | ||
160 | /* not wireless device -- return error */ | 160 | /* not wireless device -- return error */ |
161 | if (!tmp) | 161 | if (!tmp) |
162 | return ERR_PTR(-EINVAL); | 162 | return ERR_PTR(-EINVAL); |
163 | 163 | ||
164 | /* mismatch -- return error */ | 164 | /* mismatch -- return error */ |
165 | if (rdev && tmp != rdev) | 165 | if (rdev && tmp != rdev) |
166 | return ERR_PTR(-EINVAL); | 166 | return ERR_PTR(-EINVAL); |
167 | 167 | ||
168 | rdev = tmp; | 168 | rdev = tmp; |
169 | } | 169 | } |
170 | } | 170 | } |
171 | 171 | ||
172 | if (!rdev) | 172 | if (!rdev) |
173 | return ERR_PTR(-ENODEV); | 173 | return ERR_PTR(-ENODEV); |
174 | 174 | ||
175 | if (netns != wiphy_net(&rdev->wiphy)) | 175 | if (netns != wiphy_net(&rdev->wiphy)) |
176 | return ERR_PTR(-ENODEV); | 176 | return ERR_PTR(-ENODEV); |
177 | 177 | ||
178 | return rdev; | 178 | return rdev; |
179 | } | 179 | } |
180 | 180 | ||
181 | /* | 181 | /* |
182 | * This function returns a pointer to the driver | 182 | * This function returns a pointer to the driver |
183 | * that the genl_info item that is passed refers to. | 183 | * that the genl_info item that is passed refers to. |
184 | * If successful, it returns non-NULL and also locks | 184 | * If successful, it returns non-NULL and also locks |
185 | * the driver's mutex! | 185 | * the driver's mutex! |
186 | * | 186 | * |
187 | * This means that you need to call cfg80211_unlock_rdev() | 187 | * This means that you need to call cfg80211_unlock_rdev() |
188 | * before being allowed to acquire &cfg80211_mutex! | 188 | * before being allowed to acquire &cfg80211_mutex! |
189 | * | 189 | * |
190 | * This is necessary because we need to lock the global | 190 | * This is necessary because we need to lock the global |
191 | * mutex to get an item off the list safely, and then | 191 | * mutex to get an item off the list safely, and then |
192 | * we lock the rdev mutex so it doesn't go away under us. | 192 | * we lock the rdev mutex so it doesn't go away under us. |
193 | * | 193 | * |
194 | * We don't want to keep cfg80211_mutex locked | 194 | * We don't want to keep cfg80211_mutex locked |
195 | * for all the time in order to allow requests on | 195 | * for all the time in order to allow requests on |
196 | * other interfaces to go through at the same time. | 196 | * other interfaces to go through at the same time. |
197 | * | 197 | * |
198 | * The result of this can be a PTR_ERR and hence must | 198 | * The result of this can be a PTR_ERR and hence must |
199 | * be checked with IS_ERR() for errors. | 199 | * be checked with IS_ERR() for errors. |
200 | */ | 200 | */ |
201 | static struct cfg80211_registered_device * | 201 | static struct cfg80211_registered_device * |
202 | cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) | 202 | cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) |
203 | { | 203 | { |
204 | struct cfg80211_registered_device *rdev; | 204 | struct cfg80211_registered_device *rdev; |
205 | 205 | ||
206 | mutex_lock(&cfg80211_mutex); | 206 | mutex_lock(&cfg80211_mutex); |
207 | rdev = __cfg80211_rdev_from_attrs(netns, info->attrs); | 207 | rdev = __cfg80211_rdev_from_attrs(netns, info->attrs); |
208 | 208 | ||
209 | /* if it is not an error we grab the lock on | 209 | /* if it is not an error we grab the lock on |
210 | * it to assure it won't be going away while | 210 | * it to assure it won't be going away while |
211 | * we operate on it */ | 211 | * we operate on it */ |
212 | if (!IS_ERR(rdev)) | 212 | if (!IS_ERR(rdev)) |
213 | mutex_lock(&rdev->mtx); | 213 | mutex_lock(&rdev->mtx); |
214 | 214 | ||
215 | mutex_unlock(&cfg80211_mutex); | 215 | mutex_unlock(&cfg80211_mutex); |
216 | 216 | ||
217 | return rdev; | 217 | return rdev; |
218 | } | 218 | } |
219 | 219 | ||
220 | /* policy for the attributes */ | 220 | /* policy for the attributes */ |
221 | static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | 221 | static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { |
222 | [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, | 222 | [NL80211_ATTR_WIPHY] = { .type = NLA_U32 }, |
223 | [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, | 223 | [NL80211_ATTR_WIPHY_NAME] = { .type = NLA_NUL_STRING, |
224 | .len = 20-1 }, | 224 | .len = 20-1 }, |
225 | [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, | 225 | [NL80211_ATTR_WIPHY_TXQ_PARAMS] = { .type = NLA_NESTED }, |
226 | 226 | ||
227 | [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, | 227 | [NL80211_ATTR_WIPHY_FREQ] = { .type = NLA_U32 }, |
228 | [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, | 228 | [NL80211_ATTR_WIPHY_CHANNEL_TYPE] = { .type = NLA_U32 }, |
229 | [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 }, | 229 | [NL80211_ATTR_CHANNEL_WIDTH] = { .type = NLA_U32 }, |
230 | [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 }, | 230 | [NL80211_ATTR_CENTER_FREQ1] = { .type = NLA_U32 }, |
231 | [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 }, | 231 | [NL80211_ATTR_CENTER_FREQ2] = { .type = NLA_U32 }, |
232 | 232 | ||
233 | [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 }, | 233 | [NL80211_ATTR_WIPHY_RETRY_SHORT] = { .type = NLA_U8 }, |
234 | [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, | 234 | [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, |
235 | [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, | 235 | [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, |
236 | [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, | 236 | [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, |
237 | [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 }, | 237 | [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 }, |
238 | 238 | ||
239 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, | 239 | [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, |
240 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, | 240 | [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, |
241 | [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, | 241 | [NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 }, |
242 | 242 | ||
243 | [NL80211_ATTR_MAC] = { .len = ETH_ALEN }, | 243 | [NL80211_ATTR_MAC] = { .len = ETH_ALEN }, |
244 | [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN }, | 244 | [NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN }, |
245 | 245 | ||
246 | [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, | 246 | [NL80211_ATTR_KEY] = { .type = NLA_NESTED, }, |
247 | [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, | 247 | [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, |
248 | .len = WLAN_MAX_KEY_LEN }, | 248 | .len = WLAN_MAX_KEY_LEN }, |
249 | [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, | 249 | [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, |
250 | [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, | 250 | [NL80211_ATTR_KEY_CIPHER] = { .type = NLA_U32 }, |
251 | [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, | 251 | [NL80211_ATTR_KEY_DEFAULT] = { .type = NLA_FLAG }, |
252 | [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, | 252 | [NL80211_ATTR_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, |
253 | [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, | 253 | [NL80211_ATTR_KEY_TYPE] = { .type = NLA_U32 }, |
254 | 254 | ||
255 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, | 255 | [NL80211_ATTR_BEACON_INTERVAL] = { .type = NLA_U32 }, |
256 | [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, | 256 | [NL80211_ATTR_DTIM_PERIOD] = { .type = NLA_U32 }, |
257 | [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY, | 257 | [NL80211_ATTR_BEACON_HEAD] = { .type = NLA_BINARY, |
258 | .len = IEEE80211_MAX_DATA_LEN }, | 258 | .len = IEEE80211_MAX_DATA_LEN }, |
259 | [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY, | 259 | [NL80211_ATTR_BEACON_TAIL] = { .type = NLA_BINARY, |
260 | .len = IEEE80211_MAX_DATA_LEN }, | 260 | .len = IEEE80211_MAX_DATA_LEN }, |
261 | [NL80211_ATTR_STA_AID] = { .type = NLA_U16 }, | 261 | [NL80211_ATTR_STA_AID] = { .type = NLA_U16 }, |
262 | [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED }, | 262 | [NL80211_ATTR_STA_FLAGS] = { .type = NLA_NESTED }, |
263 | [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 }, | 263 | [NL80211_ATTR_STA_LISTEN_INTERVAL] = { .type = NLA_U16 }, |
264 | [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY, | 264 | [NL80211_ATTR_STA_SUPPORTED_RATES] = { .type = NLA_BINARY, |
265 | .len = NL80211_MAX_SUPP_RATES }, | 265 | .len = NL80211_MAX_SUPP_RATES }, |
266 | [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 }, | 266 | [NL80211_ATTR_STA_PLINK_ACTION] = { .type = NLA_U8 }, |
267 | [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, | 267 | [NL80211_ATTR_STA_VLAN] = { .type = NLA_U32 }, |
268 | [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, | 268 | [NL80211_ATTR_MNTR_FLAGS] = { /* NLA_NESTED can't be empty */ }, |
269 | [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, | 269 | [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, |
270 | .len = IEEE80211_MAX_MESH_ID_LEN }, | 270 | .len = IEEE80211_MAX_MESH_ID_LEN }, |
271 | [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, | 271 | [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, |
272 | 272 | ||
273 | [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, | 273 | [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 }, |
274 | [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED }, | 274 | [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED }, |
275 | 275 | ||
276 | [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 }, | 276 | [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 }, |
277 | [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 }, | 277 | [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 }, |
278 | [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 }, | 278 | [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 }, |
279 | [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY, | 279 | [NL80211_ATTR_BSS_BASIC_RATES] = { .type = NLA_BINARY, |
280 | .len = NL80211_MAX_SUPP_RATES }, | 280 | .len = NL80211_MAX_SUPP_RATES }, |
281 | [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, | 281 | [NL80211_ATTR_BSS_HT_OPMODE] = { .type = NLA_U16 }, |
282 | 282 | ||
283 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, | 283 | [NL80211_ATTR_MESH_CONFIG] = { .type = NLA_NESTED }, |
284 | [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, | 284 | [NL80211_ATTR_SUPPORT_MESH_AUTH] = { .type = NLA_FLAG }, |
285 | 285 | ||
286 | [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN }, | 286 | [NL80211_ATTR_HT_CAPABILITY] = { .len = NL80211_HT_CAPABILITY_LEN }, |
287 | 287 | ||
288 | [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, | 288 | [NL80211_ATTR_MGMT_SUBTYPE] = { .type = NLA_U8 }, |
289 | [NL80211_ATTR_IE] = { .type = NLA_BINARY, | 289 | [NL80211_ATTR_IE] = { .type = NLA_BINARY, |
290 | .len = IEEE80211_MAX_DATA_LEN }, | 290 | .len = IEEE80211_MAX_DATA_LEN }, |
291 | [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED }, | 291 | [NL80211_ATTR_SCAN_FREQUENCIES] = { .type = NLA_NESTED }, |
292 | [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED }, | 292 | [NL80211_ATTR_SCAN_SSIDS] = { .type = NLA_NESTED }, |
293 | 293 | ||
294 | [NL80211_ATTR_SSID] = { .type = NLA_BINARY, | 294 | [NL80211_ATTR_SSID] = { .type = NLA_BINARY, |
295 | .len = IEEE80211_MAX_SSID_LEN }, | 295 | .len = IEEE80211_MAX_SSID_LEN }, |
296 | [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 }, | 296 | [NL80211_ATTR_AUTH_TYPE] = { .type = NLA_U32 }, |
297 | [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, | 297 | [NL80211_ATTR_REASON_CODE] = { .type = NLA_U16 }, |
298 | [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, | 298 | [NL80211_ATTR_FREQ_FIXED] = { .type = NLA_FLAG }, |
299 | [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, | 299 | [NL80211_ATTR_TIMED_OUT] = { .type = NLA_FLAG }, |
300 | [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 }, | 300 | [NL80211_ATTR_USE_MFP] = { .type = NLA_U32 }, |
301 | [NL80211_ATTR_STA_FLAGS2] = { | 301 | [NL80211_ATTR_STA_FLAGS2] = { |
302 | .len = sizeof(struct nl80211_sta_flag_update), | 302 | .len = sizeof(struct nl80211_sta_flag_update), |
303 | }, | 303 | }, |
304 | [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG }, | 304 | [NL80211_ATTR_CONTROL_PORT] = { .type = NLA_FLAG }, |
305 | [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 }, | 305 | [NL80211_ATTR_CONTROL_PORT_ETHERTYPE] = { .type = NLA_U16 }, |
306 | [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, | 306 | [NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT] = { .type = NLA_FLAG }, |
307 | [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, | 307 | [NL80211_ATTR_PRIVACY] = { .type = NLA_FLAG }, |
308 | [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, | 308 | [NL80211_ATTR_CIPHER_SUITE_GROUP] = { .type = NLA_U32 }, |
309 | [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, | 309 | [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, |
310 | [NL80211_ATTR_PID] = { .type = NLA_U32 }, | 310 | [NL80211_ATTR_PID] = { .type = NLA_U32 }, |
311 | [NL80211_ATTR_4ADDR] = { .type = NLA_U8 }, | 311 | [NL80211_ATTR_4ADDR] = { .type = NLA_U8 }, |
312 | [NL80211_ATTR_PMKID] = { .type = NLA_BINARY, | 312 | [NL80211_ATTR_PMKID] = { .type = NLA_BINARY, |
313 | .len = WLAN_PMKID_LEN }, | 313 | .len = WLAN_PMKID_LEN }, |
314 | [NL80211_ATTR_DURATION] = { .type = NLA_U32 }, | 314 | [NL80211_ATTR_DURATION] = { .type = NLA_U32 }, |
315 | [NL80211_ATTR_COOKIE] = { .type = NLA_U64 }, | 315 | [NL80211_ATTR_COOKIE] = { .type = NLA_U64 }, |
316 | [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED }, | 316 | [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED }, |
317 | [NL80211_ATTR_FRAME] = { .type = NLA_BINARY, | 317 | [NL80211_ATTR_FRAME] = { .type = NLA_BINARY, |
318 | .len = IEEE80211_MAX_DATA_LEN }, | 318 | .len = IEEE80211_MAX_DATA_LEN }, |
319 | [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, | 319 | [NL80211_ATTR_FRAME_MATCH] = { .type = NLA_BINARY, }, |
320 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, | 320 | [NL80211_ATTR_PS_STATE] = { .type = NLA_U32 }, |
321 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, | 321 | [NL80211_ATTR_CQM] = { .type = NLA_NESTED, }, |
322 | [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, | 322 | [NL80211_ATTR_LOCAL_STATE_CHANGE] = { .type = NLA_FLAG }, |
323 | [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 }, | 323 | [NL80211_ATTR_AP_ISOLATE] = { .type = NLA_U8 }, |
324 | [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 }, | 324 | [NL80211_ATTR_WIPHY_TX_POWER_SETTING] = { .type = NLA_U32 }, |
325 | [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 }, | 325 | [NL80211_ATTR_WIPHY_TX_POWER_LEVEL] = { .type = NLA_U32 }, |
326 | [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, | 326 | [NL80211_ATTR_FRAME_TYPE] = { .type = NLA_U16 }, |
327 | [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 }, | 327 | [NL80211_ATTR_WIPHY_ANTENNA_TX] = { .type = NLA_U32 }, |
328 | [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, | 328 | [NL80211_ATTR_WIPHY_ANTENNA_RX] = { .type = NLA_U32 }, |
329 | [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, | 329 | [NL80211_ATTR_MCAST_RATE] = { .type = NLA_U32 }, |
330 | [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, | 330 | [NL80211_ATTR_OFFCHANNEL_TX_OK] = { .type = NLA_FLAG }, |
331 | [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, | 331 | [NL80211_ATTR_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, |
332 | [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, | 332 | [NL80211_ATTR_WOWLAN_TRIGGERS] = { .type = NLA_NESTED }, |
333 | [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, | 333 | [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, |
334 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, | 334 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, |
335 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, | 335 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, |
336 | [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, | 336 | [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, |
337 | [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 }, | 337 | [NL80211_ATTR_HIDDEN_SSID] = { .type = NLA_U32 }, |
338 | [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY, | 338 | [NL80211_ATTR_IE_PROBE_RESP] = { .type = NLA_BINARY, |
339 | .len = IEEE80211_MAX_DATA_LEN }, | 339 | .len = IEEE80211_MAX_DATA_LEN }, |
340 | [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY, | 340 | [NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY, |
341 | .len = IEEE80211_MAX_DATA_LEN }, | 341 | .len = IEEE80211_MAX_DATA_LEN }, |
342 | [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, | 342 | [NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG }, |
343 | [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, | 343 | [NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED }, |
344 | [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG }, | 344 | [NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG }, |
345 | [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 }, | 345 | [NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 }, |
346 | [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 }, | 346 | [NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 }, |
347 | [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, | 347 | [NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 }, |
348 | [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, | 348 | [NL80211_ATTR_TDLS_SUPPORT] = { .type = NLA_FLAG }, |
349 | [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, | 349 | [NL80211_ATTR_TDLS_EXTERNAL_SETUP] = { .type = NLA_FLAG }, |
350 | [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG }, | 350 | [NL80211_ATTR_DONT_WAIT_FOR_ACK] = { .type = NLA_FLAG }, |
351 | [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, | 351 | [NL80211_ATTR_PROBE_RESP] = { .type = NLA_BINARY, |
352 | .len = IEEE80211_MAX_DATA_LEN }, | 352 | .len = IEEE80211_MAX_DATA_LEN }, |
353 | [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 }, | 353 | [NL80211_ATTR_DFS_REGION] = { .type = NLA_U8 }, |
354 | [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG }, | 354 | [NL80211_ATTR_DISABLE_HT] = { .type = NLA_FLAG }, |
355 | [NL80211_ATTR_HT_CAPABILITY_MASK] = { | 355 | [NL80211_ATTR_HT_CAPABILITY_MASK] = { |
356 | .len = NL80211_HT_CAPABILITY_LEN | 356 | .len = NL80211_HT_CAPABILITY_LEN |
357 | }, | 357 | }, |
358 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, | 358 | [NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 }, |
359 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, | 359 | [NL80211_ATTR_INACTIVITY_TIMEOUT] = { .type = NLA_U16 }, |
360 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, | 360 | [NL80211_ATTR_BG_SCAN_PERIOD] = { .type = NLA_U16 }, |
361 | [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, | 361 | [NL80211_ATTR_WDEV] = { .type = NLA_U64 }, |
362 | [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, | 362 | [NL80211_ATTR_USER_REG_HINT_TYPE] = { .type = NLA_U32 }, |
363 | [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, }, | 363 | [NL80211_ATTR_SAE_DATA] = { .type = NLA_BINARY, }, |
364 | [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN }, | 364 | [NL80211_ATTR_VHT_CAPABILITY] = { .len = NL80211_VHT_CAPABILITY_LEN }, |
365 | [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, | 365 | [NL80211_ATTR_SCAN_FLAGS] = { .type = NLA_U32 }, |
366 | [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 }, | 366 | [NL80211_ATTR_P2P_CTWINDOW] = { .type = NLA_U8 }, |
367 | [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, | 367 | [NL80211_ATTR_P2P_OPPPS] = { .type = NLA_U8 }, |
368 | }; | 368 | }; |
369 | 369 | ||
370 | /* policy for the key attributes */ | 370 | /* policy for the key attributes */ |
371 | static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { | 371 | static const struct nla_policy nl80211_key_policy[NL80211_KEY_MAX + 1] = { |
372 | [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, | 372 | [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN }, |
373 | [NL80211_KEY_IDX] = { .type = NLA_U8 }, | 373 | [NL80211_KEY_IDX] = { .type = NLA_U8 }, |
374 | [NL80211_KEY_CIPHER] = { .type = NLA_U32 }, | 374 | [NL80211_KEY_CIPHER] = { .type = NLA_U32 }, |
375 | [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, | 375 | [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 16 }, |
376 | [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, | 376 | [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG }, |
377 | [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, | 377 | [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG }, |
378 | [NL80211_KEY_TYPE] = { .type = NLA_U32 }, | 378 | [NL80211_KEY_TYPE] = { .type = NLA_U32 }, |
379 | [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, | 379 | [NL80211_KEY_DEFAULT_TYPES] = { .type = NLA_NESTED }, |
380 | }; | 380 | }; |
381 | 381 | ||
382 | /* policy for the key default flags */ | 382 | /* policy for the key default flags */ |
383 | static const struct nla_policy | 383 | static const struct nla_policy |
384 | nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = { | 384 | nl80211_key_default_policy[NUM_NL80211_KEY_DEFAULT_TYPES] = { |
385 | [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG }, | 385 | [NL80211_KEY_DEFAULT_TYPE_UNICAST] = { .type = NLA_FLAG }, |
386 | [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG }, | 386 | [NL80211_KEY_DEFAULT_TYPE_MULTICAST] = { .type = NLA_FLAG }, |
387 | }; | 387 | }; |
388 | 388 | ||
389 | /* policy for WoWLAN attributes */ | 389 | /* policy for WoWLAN attributes */ |
390 | static const struct nla_policy | 390 | static const struct nla_policy |
391 | nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { | 391 | nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { |
392 | [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG }, | 392 | [NL80211_WOWLAN_TRIG_ANY] = { .type = NLA_FLAG }, |
393 | [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, | 393 | [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, |
394 | [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, | 394 | [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, |
395 | [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, | 395 | [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, |
396 | [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG }, | 396 | [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG }, |
397 | [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, | 397 | [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, |
398 | [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, | 398 | [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, |
399 | [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, | 399 | [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, |
400 | }; | 400 | }; |
401 | 401 | ||
402 | /* policy for GTK rekey offload attributes */ | 402 | /* policy for GTK rekey offload attributes */ |
403 | static const struct nla_policy | 403 | static const struct nla_policy |
404 | nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { | 404 | nl80211_rekey_policy[NUM_NL80211_REKEY_DATA] = { |
405 | [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN }, | 405 | [NL80211_REKEY_DATA_KEK] = { .len = NL80211_KEK_LEN }, |
406 | [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN }, | 406 | [NL80211_REKEY_DATA_KCK] = { .len = NL80211_KCK_LEN }, |
407 | [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, | 407 | [NL80211_REKEY_DATA_REPLAY_CTR] = { .len = NL80211_REPLAY_CTR_LEN }, |
408 | }; | 408 | }; |
409 | 409 | ||
410 | static const struct nla_policy | 410 | static const struct nla_policy |
411 | nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { | 411 | nl80211_match_policy[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1] = { |
412 | [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY, | 412 | [NL80211_SCHED_SCAN_MATCH_ATTR_SSID] = { .type = NLA_BINARY, |
413 | .len = IEEE80211_MAX_SSID_LEN }, | 413 | .len = IEEE80211_MAX_SSID_LEN }, |
414 | [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 }, | 414 | [NL80211_SCHED_SCAN_MATCH_ATTR_RSSI] = { .type = NLA_U32 }, |
415 | }; | 415 | }; |
416 | 416 | ||
417 | /* ifidx get helper */ | 417 | /* ifidx get helper */ |
418 | static int nl80211_get_ifidx(struct netlink_callback *cb) | 418 | static int nl80211_get_ifidx(struct netlink_callback *cb) |
419 | { | 419 | { |
420 | int res; | 420 | int res; |
421 | 421 | ||
422 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | 422 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
423 | nl80211_fam.attrbuf, nl80211_fam.maxattr, | 423 | nl80211_fam.attrbuf, nl80211_fam.maxattr, |
424 | nl80211_policy); | 424 | nl80211_policy); |
425 | if (res) | 425 | if (res) |
426 | return res; | 426 | return res; |
427 | 427 | ||
428 | if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]) | 428 | if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]) |
429 | return -EINVAL; | 429 | return -EINVAL; |
430 | 430 | ||
431 | res = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]); | 431 | res = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]); |
432 | if (!res) | 432 | if (!res) |
433 | return -EINVAL; | 433 | return -EINVAL; |
434 | return res; | 434 | return res; |
435 | } | 435 | } |
436 | 436 | ||
437 | static int nl80211_prepare_netdev_dump(struct sk_buff *skb, | 437 | static int nl80211_prepare_netdev_dump(struct sk_buff *skb, |
438 | struct netlink_callback *cb, | 438 | struct netlink_callback *cb, |
439 | struct cfg80211_registered_device **rdev, | 439 | struct cfg80211_registered_device **rdev, |
440 | struct net_device **dev) | 440 | struct net_device **dev) |
441 | { | 441 | { |
442 | int ifidx = cb->args[0]; | 442 | int ifidx = cb->args[0]; |
443 | int err; | 443 | int err; |
444 | 444 | ||
445 | if (!ifidx) | 445 | if (!ifidx) |
446 | ifidx = nl80211_get_ifidx(cb); | 446 | ifidx = nl80211_get_ifidx(cb); |
447 | if (ifidx < 0) | 447 | if (ifidx < 0) |
448 | return ifidx; | 448 | return ifidx; |
449 | 449 | ||
450 | cb->args[0] = ifidx; | 450 | cb->args[0] = ifidx; |
451 | 451 | ||
452 | rtnl_lock(); | 452 | rtnl_lock(); |
453 | 453 | ||
454 | *dev = __dev_get_by_index(sock_net(skb->sk), ifidx); | 454 | *dev = __dev_get_by_index(sock_net(skb->sk), ifidx); |
455 | if (!*dev) { | 455 | if (!*dev) { |
456 | err = -ENODEV; | 456 | err = -ENODEV; |
457 | goto out_rtnl; | 457 | goto out_rtnl; |
458 | } | 458 | } |
459 | 459 | ||
460 | *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); | 460 | *rdev = cfg80211_get_dev_from_ifindex(sock_net(skb->sk), ifidx); |
461 | if (IS_ERR(*rdev)) { | 461 | if (IS_ERR(*rdev)) { |
462 | err = PTR_ERR(*rdev); | 462 | err = PTR_ERR(*rdev); |
463 | goto out_rtnl; | 463 | goto out_rtnl; |
464 | } | 464 | } |
465 | 465 | ||
466 | return 0; | 466 | return 0; |
467 | out_rtnl: | 467 | out_rtnl: |
468 | rtnl_unlock(); | 468 | rtnl_unlock(); |
469 | return err; | 469 | return err; |
470 | } | 470 | } |
471 | 471 | ||
472 | static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev) | 472 | static void nl80211_finish_netdev_dump(struct cfg80211_registered_device *rdev) |
473 | { | 473 | { |
474 | cfg80211_unlock_rdev(rdev); | 474 | cfg80211_unlock_rdev(rdev); |
475 | rtnl_unlock(); | 475 | rtnl_unlock(); |
476 | } | 476 | } |
477 | 477 | ||
478 | /* IE validation */ | 478 | /* IE validation */ |
479 | static bool is_valid_ie_attr(const struct nlattr *attr) | 479 | static bool is_valid_ie_attr(const struct nlattr *attr) |
480 | { | 480 | { |
481 | const u8 *pos; | 481 | const u8 *pos; |
482 | int len; | 482 | int len; |
483 | 483 | ||
484 | if (!attr) | 484 | if (!attr) |
485 | return true; | 485 | return true; |
486 | 486 | ||
487 | pos = nla_data(attr); | 487 | pos = nla_data(attr); |
488 | len = nla_len(attr); | 488 | len = nla_len(attr); |
489 | 489 | ||
490 | while (len) { | 490 | while (len) { |
491 | u8 elemlen; | 491 | u8 elemlen; |
492 | 492 | ||
493 | if (len < 2) | 493 | if (len < 2) |
494 | return false; | 494 | return false; |
495 | len -= 2; | 495 | len -= 2; |
496 | 496 | ||
497 | elemlen = pos[1]; | 497 | elemlen = pos[1]; |
498 | if (elemlen > len) | 498 | if (elemlen > len) |
499 | return false; | 499 | return false; |
500 | 500 | ||
501 | len -= elemlen; | 501 | len -= elemlen; |
502 | pos += 2 + elemlen; | 502 | pos += 2 + elemlen; |
503 | } | 503 | } |
504 | 504 | ||
505 | return true; | 505 | return true; |
506 | } | 506 | } |
507 | 507 | ||
508 | /* message building helper */ | 508 | /* message building helper */ |
509 | static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq, | 509 | static inline void *nl80211hdr_put(struct sk_buff *skb, u32 portid, u32 seq, |
510 | int flags, u8 cmd) | 510 | int flags, u8 cmd) |
511 | { | 511 | { |
512 | /* since there is no private header just add the generic one */ | 512 | /* since there is no private header just add the generic one */ |
513 | return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd); | 513 | return genlmsg_put(skb, portid, seq, &nl80211_fam, flags, cmd); |
514 | } | 514 | } |
515 | 515 | ||
516 | static int nl80211_msg_put_channel(struct sk_buff *msg, | 516 | static int nl80211_msg_put_channel(struct sk_buff *msg, |
517 | struct ieee80211_channel *chan) | 517 | struct ieee80211_channel *chan) |
518 | { | 518 | { |
519 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ, | 519 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_FREQ, |
520 | chan->center_freq)) | 520 | chan->center_freq)) |
521 | goto nla_put_failure; | 521 | goto nla_put_failure; |
522 | 522 | ||
523 | if ((chan->flags & IEEE80211_CHAN_DISABLED) && | 523 | if ((chan->flags & IEEE80211_CHAN_DISABLED) && |
524 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) | 524 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_DISABLED)) |
525 | goto nla_put_failure; | 525 | goto nla_put_failure; |
526 | if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && | 526 | if ((chan->flags & IEEE80211_CHAN_PASSIVE_SCAN) && |
527 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN)) | 527 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_PASSIVE_SCAN)) |
528 | goto nla_put_failure; | 528 | goto nla_put_failure; |
529 | if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && | 529 | if ((chan->flags & IEEE80211_CHAN_NO_IBSS) && |
530 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) | 530 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_NO_IBSS)) |
531 | goto nla_put_failure; | 531 | goto nla_put_failure; |
532 | if ((chan->flags & IEEE80211_CHAN_RADAR) && | 532 | if ((chan->flags & IEEE80211_CHAN_RADAR) && |
533 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) | 533 | nla_put_flag(msg, NL80211_FREQUENCY_ATTR_RADAR)) |
534 | goto nla_put_failure; | 534 | goto nla_put_failure; |
535 | 535 | ||
536 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, | 536 | if (nla_put_u32(msg, NL80211_FREQUENCY_ATTR_MAX_TX_POWER, |
537 | DBM_TO_MBM(chan->max_power))) | 537 | DBM_TO_MBM(chan->max_power))) |
538 | goto nla_put_failure; | 538 | goto nla_put_failure; |
539 | 539 | ||
540 | return 0; | 540 | return 0; |
541 | 541 | ||
542 | nla_put_failure: | 542 | nla_put_failure: |
543 | return -ENOBUFS; | 543 | return -ENOBUFS; |
544 | } | 544 | } |
545 | 545 | ||
546 | /* netlink command implementations */ | 546 | /* netlink command implementations */ |
547 | 547 | ||
548 | struct key_parse { | 548 | struct key_parse { |
549 | struct key_params p; | 549 | struct key_params p; |
550 | int idx; | 550 | int idx; |
551 | int type; | 551 | int type; |
552 | bool def, defmgmt; | 552 | bool def, defmgmt; |
553 | bool def_uni, def_multi; | 553 | bool def_uni, def_multi; |
554 | }; | 554 | }; |
555 | 555 | ||
556 | static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) | 556 | static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k) |
557 | { | 557 | { |
558 | struct nlattr *tb[NL80211_KEY_MAX + 1]; | 558 | struct nlattr *tb[NL80211_KEY_MAX + 1]; |
559 | int err = nla_parse_nested(tb, NL80211_KEY_MAX, key, | 559 | int err = nla_parse_nested(tb, NL80211_KEY_MAX, key, |
560 | nl80211_key_policy); | 560 | nl80211_key_policy); |
561 | if (err) | 561 | if (err) |
562 | return err; | 562 | return err; |
563 | 563 | ||
564 | k->def = !!tb[NL80211_KEY_DEFAULT]; | 564 | k->def = !!tb[NL80211_KEY_DEFAULT]; |
565 | k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; | 565 | k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT]; |
566 | 566 | ||
567 | if (k->def) { | 567 | if (k->def) { |
568 | k->def_uni = true; | 568 | k->def_uni = true; |
569 | k->def_multi = true; | 569 | k->def_multi = true; |
570 | } | 570 | } |
571 | if (k->defmgmt) | 571 | if (k->defmgmt) |
572 | k->def_multi = true; | 572 | k->def_multi = true; |
573 | 573 | ||
574 | if (tb[NL80211_KEY_IDX]) | 574 | if (tb[NL80211_KEY_IDX]) |
575 | k->idx = nla_get_u8(tb[NL80211_KEY_IDX]); | 575 | k->idx = nla_get_u8(tb[NL80211_KEY_IDX]); |
576 | 576 | ||
577 | if (tb[NL80211_KEY_DATA]) { | 577 | if (tb[NL80211_KEY_DATA]) { |
578 | k->p.key = nla_data(tb[NL80211_KEY_DATA]); | 578 | k->p.key = nla_data(tb[NL80211_KEY_DATA]); |
579 | k->p.key_len = nla_len(tb[NL80211_KEY_DATA]); | 579 | k->p.key_len = nla_len(tb[NL80211_KEY_DATA]); |
580 | } | 580 | } |
581 | 581 | ||
582 | if (tb[NL80211_KEY_SEQ]) { | 582 | if (tb[NL80211_KEY_SEQ]) { |
583 | k->p.seq = nla_data(tb[NL80211_KEY_SEQ]); | 583 | k->p.seq = nla_data(tb[NL80211_KEY_SEQ]); |
584 | k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]); | 584 | k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]); |
585 | } | 585 | } |
586 | 586 | ||
587 | if (tb[NL80211_KEY_CIPHER]) | 587 | if (tb[NL80211_KEY_CIPHER]) |
588 | k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]); | 588 | k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]); |
589 | 589 | ||
590 | if (tb[NL80211_KEY_TYPE]) { | 590 | if (tb[NL80211_KEY_TYPE]) { |
591 | k->type = nla_get_u32(tb[NL80211_KEY_TYPE]); | 591 | k->type = nla_get_u32(tb[NL80211_KEY_TYPE]); |
592 | if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) | 592 | if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) |
593 | return -EINVAL; | 593 | return -EINVAL; |
594 | } | 594 | } |
595 | 595 | ||
596 | if (tb[NL80211_KEY_DEFAULT_TYPES]) { | 596 | if (tb[NL80211_KEY_DEFAULT_TYPES]) { |
597 | struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; | 597 | struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; |
598 | err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1, | 598 | err = nla_parse_nested(kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1, |
599 | tb[NL80211_KEY_DEFAULT_TYPES], | 599 | tb[NL80211_KEY_DEFAULT_TYPES], |
600 | nl80211_key_default_policy); | 600 | nl80211_key_default_policy); |
601 | if (err) | 601 | if (err) |
602 | return err; | 602 | return err; |
603 | 603 | ||
604 | k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST]; | 604 | k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST]; |
605 | k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST]; | 605 | k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST]; |
606 | } | 606 | } |
607 | 607 | ||
608 | return 0; | 608 | return 0; |
609 | } | 609 | } |
610 | 610 | ||
611 | static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k) | 611 | static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k) |
612 | { | 612 | { |
613 | if (info->attrs[NL80211_ATTR_KEY_DATA]) { | 613 | if (info->attrs[NL80211_ATTR_KEY_DATA]) { |
614 | k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]); | 614 | k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]); |
615 | k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]); | 615 | k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]); |
616 | } | 616 | } |
617 | 617 | ||
618 | if (info->attrs[NL80211_ATTR_KEY_SEQ]) { | 618 | if (info->attrs[NL80211_ATTR_KEY_SEQ]) { |
619 | k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]); | 619 | k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]); |
620 | k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]); | 620 | k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]); |
621 | } | 621 | } |
622 | 622 | ||
623 | if (info->attrs[NL80211_ATTR_KEY_IDX]) | 623 | if (info->attrs[NL80211_ATTR_KEY_IDX]) |
624 | k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); | 624 | k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); |
625 | 625 | ||
626 | if (info->attrs[NL80211_ATTR_KEY_CIPHER]) | 626 | if (info->attrs[NL80211_ATTR_KEY_CIPHER]) |
627 | k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]); | 627 | k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]); |
628 | 628 | ||
629 | k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; | 629 | k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT]; |
630 | k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; | 630 | k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]; |
631 | 631 | ||
632 | if (k->def) { | 632 | if (k->def) { |
633 | k->def_uni = true; | 633 | k->def_uni = true; |
634 | k->def_multi = true; | 634 | k->def_multi = true; |
635 | } | 635 | } |
636 | if (k->defmgmt) | 636 | if (k->defmgmt) |
637 | k->def_multi = true; | 637 | k->def_multi = true; |
638 | 638 | ||
639 | if (info->attrs[NL80211_ATTR_KEY_TYPE]) { | 639 | if (info->attrs[NL80211_ATTR_KEY_TYPE]) { |
640 | k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); | 640 | k->type = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); |
641 | if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) | 641 | if (k->type < 0 || k->type >= NUM_NL80211_KEYTYPES) |
642 | return -EINVAL; | 642 | return -EINVAL; |
643 | } | 643 | } |
644 | 644 | ||
645 | if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) { | 645 | if (info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES]) { |
646 | struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; | 646 | struct nlattr *kdt[NUM_NL80211_KEY_DEFAULT_TYPES]; |
647 | int err = nla_parse_nested( | 647 | int err = nla_parse_nested( |
648 | kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1, | 648 | kdt, NUM_NL80211_KEY_DEFAULT_TYPES - 1, |
649 | info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES], | 649 | info->attrs[NL80211_ATTR_KEY_DEFAULT_TYPES], |
650 | nl80211_key_default_policy); | 650 | nl80211_key_default_policy); |
651 | if (err) | 651 | if (err) |
652 | return err; | 652 | return err; |
653 | 653 | ||
654 | k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST]; | 654 | k->def_uni = kdt[NL80211_KEY_DEFAULT_TYPE_UNICAST]; |
655 | k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST]; | 655 | k->def_multi = kdt[NL80211_KEY_DEFAULT_TYPE_MULTICAST]; |
656 | } | 656 | } |
657 | 657 | ||
658 | return 0; | 658 | return 0; |
659 | } | 659 | } |
660 | 660 | ||
661 | static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) | 661 | static int nl80211_parse_key(struct genl_info *info, struct key_parse *k) |
662 | { | 662 | { |
663 | int err; | 663 | int err; |
664 | 664 | ||
665 | memset(k, 0, sizeof(*k)); | 665 | memset(k, 0, sizeof(*k)); |
666 | k->idx = -1; | 666 | k->idx = -1; |
667 | k->type = -1; | 667 | k->type = -1; |
668 | 668 | ||
669 | if (info->attrs[NL80211_ATTR_KEY]) | 669 | if (info->attrs[NL80211_ATTR_KEY]) |
670 | err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k); | 670 | err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k); |
671 | else | 671 | else |
672 | err = nl80211_parse_key_old(info, k); | 672 | err = nl80211_parse_key_old(info, k); |
673 | 673 | ||
674 | if (err) | 674 | if (err) |
675 | return err; | 675 | return err; |
676 | 676 | ||
677 | if (k->def && k->defmgmt) | 677 | if (k->def && k->defmgmt) |
678 | return -EINVAL; | 678 | return -EINVAL; |
679 | 679 | ||
680 | if (k->defmgmt) { | 680 | if (k->defmgmt) { |
681 | if (k->def_uni || !k->def_multi) | 681 | if (k->def_uni || !k->def_multi) |
682 | return -EINVAL; | 682 | return -EINVAL; |
683 | } | 683 | } |
684 | 684 | ||
685 | if (k->idx != -1) { | 685 | if (k->idx != -1) { |
686 | if (k->defmgmt) { | 686 | if (k->defmgmt) { |
687 | if (k->idx < 4 || k->idx > 5) | 687 | if (k->idx < 4 || k->idx > 5) |
688 | return -EINVAL; | 688 | return -EINVAL; |
689 | } else if (k->def) { | 689 | } else if (k->def) { |
690 | if (k->idx < 0 || k->idx > 3) | 690 | if (k->idx < 0 || k->idx > 3) |
691 | return -EINVAL; | 691 | return -EINVAL; |
692 | } else { | 692 | } else { |
693 | if (k->idx < 0 || k->idx > 5) | 693 | if (k->idx < 0 || k->idx > 5) |
694 | return -EINVAL; | 694 | return -EINVAL; |
695 | } | 695 | } |
696 | } | 696 | } |
697 | 697 | ||
698 | return 0; | 698 | return 0; |
699 | } | 699 | } |
700 | 700 | ||
701 | static struct cfg80211_cached_keys * | 701 | static struct cfg80211_cached_keys * |
702 | nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, | 702 | nl80211_parse_connkeys(struct cfg80211_registered_device *rdev, |
703 | struct nlattr *keys, bool *no_ht) | 703 | struct nlattr *keys, bool *no_ht) |
704 | { | 704 | { |
705 | struct key_parse parse; | 705 | struct key_parse parse; |
706 | struct nlattr *key; | 706 | struct nlattr *key; |
707 | struct cfg80211_cached_keys *result; | 707 | struct cfg80211_cached_keys *result; |
708 | int rem, err, def = 0; | 708 | int rem, err, def = 0; |
709 | 709 | ||
710 | result = kzalloc(sizeof(*result), GFP_KERNEL); | 710 | result = kzalloc(sizeof(*result), GFP_KERNEL); |
711 | if (!result) | 711 | if (!result) |
712 | return ERR_PTR(-ENOMEM); | 712 | return ERR_PTR(-ENOMEM); |
713 | 713 | ||
714 | result->def = -1; | 714 | result->def = -1; |
715 | result->defmgmt = -1; | 715 | result->defmgmt = -1; |
716 | 716 | ||
717 | nla_for_each_nested(key, keys, rem) { | 717 | nla_for_each_nested(key, keys, rem) { |
718 | memset(&parse, 0, sizeof(parse)); | 718 | memset(&parse, 0, sizeof(parse)); |
719 | parse.idx = -1; | 719 | parse.idx = -1; |
720 | 720 | ||
721 | err = nl80211_parse_key_new(key, &parse); | 721 | err = nl80211_parse_key_new(key, &parse); |
722 | if (err) | 722 | if (err) |
723 | goto error; | 723 | goto error; |
724 | err = -EINVAL; | 724 | err = -EINVAL; |
725 | if (!parse.p.key) | 725 | if (!parse.p.key) |
726 | goto error; | 726 | goto error; |
727 | if (parse.idx < 0 || parse.idx > 4) | 727 | if (parse.idx < 0 || parse.idx > 4) |
728 | goto error; | 728 | goto error; |
729 | if (parse.def) { | 729 | if (parse.def) { |
730 | if (def) | 730 | if (def) |
731 | goto error; | 731 | goto error; |
732 | def = 1; | 732 | def = 1; |
733 | result->def = parse.idx; | 733 | result->def = parse.idx; |
734 | if (!parse.def_uni || !parse.def_multi) | 734 | if (!parse.def_uni || !parse.def_multi) |
735 | goto error; | 735 | goto error; |
736 | } else if (parse.defmgmt) | 736 | } else if (parse.defmgmt) |
737 | goto error; | 737 | goto error; |
738 | err = cfg80211_validate_key_settings(rdev, &parse.p, | 738 | err = cfg80211_validate_key_settings(rdev, &parse.p, |
739 | parse.idx, false, NULL); | 739 | parse.idx, false, NULL); |
740 | if (err) | 740 | if (err) |
741 | goto error; | 741 | goto error; |
742 | result->params[parse.idx].cipher = parse.p.cipher; | 742 | result->params[parse.idx].cipher = parse.p.cipher; |
743 | result->params[parse.idx].key_len = parse.p.key_len; | 743 | result->params[parse.idx].key_len = parse.p.key_len; |
744 | result->params[parse.idx].key = result->data[parse.idx]; | 744 | result->params[parse.idx].key = result->data[parse.idx]; |
745 | memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len); | 745 | memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len); |
746 | 746 | ||
747 | if (parse.p.cipher == WLAN_CIPHER_SUITE_WEP40 || | 747 | if (parse.p.cipher == WLAN_CIPHER_SUITE_WEP40 || |
748 | parse.p.cipher == WLAN_CIPHER_SUITE_WEP104) { | 748 | parse.p.cipher == WLAN_CIPHER_SUITE_WEP104) { |
749 | if (no_ht) | 749 | if (no_ht) |
750 | *no_ht = true; | 750 | *no_ht = true; |
751 | } | 751 | } |
752 | } | 752 | } |
753 | 753 | ||
754 | return result; | 754 | return result; |
755 | error: | 755 | error: |
756 | kfree(result); | 756 | kfree(result); |
757 | return ERR_PTR(err); | 757 | return ERR_PTR(err); |
758 | } | 758 | } |
759 | 759 | ||
760 | static int nl80211_key_allowed(struct wireless_dev *wdev) | 760 | static int nl80211_key_allowed(struct wireless_dev *wdev) |
761 | { | 761 | { |
762 | ASSERT_WDEV_LOCK(wdev); | 762 | ASSERT_WDEV_LOCK(wdev); |
763 | 763 | ||
764 | switch (wdev->iftype) { | 764 | switch (wdev->iftype) { |
765 | case NL80211_IFTYPE_AP: | 765 | case NL80211_IFTYPE_AP: |
766 | case NL80211_IFTYPE_AP_VLAN: | 766 | case NL80211_IFTYPE_AP_VLAN: |
767 | case NL80211_IFTYPE_P2P_GO: | 767 | case NL80211_IFTYPE_P2P_GO: |
768 | case NL80211_IFTYPE_MESH_POINT: | 768 | case NL80211_IFTYPE_MESH_POINT: |
769 | break; | 769 | break; |
770 | case NL80211_IFTYPE_ADHOC: | 770 | case NL80211_IFTYPE_ADHOC: |
771 | if (!wdev->current_bss) | 771 | if (!wdev->current_bss) |
772 | return -ENOLINK; | 772 | return -ENOLINK; |
773 | break; | 773 | break; |
774 | case NL80211_IFTYPE_STATION: | 774 | case NL80211_IFTYPE_STATION: |
775 | case NL80211_IFTYPE_P2P_CLIENT: | 775 | case NL80211_IFTYPE_P2P_CLIENT: |
776 | if (wdev->sme_state != CFG80211_SME_CONNECTED) | 776 | if (wdev->sme_state != CFG80211_SME_CONNECTED) |
777 | return -ENOLINK; | 777 | return -ENOLINK; |
778 | break; | 778 | break; |
779 | default: | 779 | default: |
780 | return -EINVAL; | 780 | return -EINVAL; |
781 | } | 781 | } |
782 | 782 | ||
783 | return 0; | 783 | return 0; |
784 | } | 784 | } |
785 | 785 | ||
786 | static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes) | 786 | static int nl80211_put_iftypes(struct sk_buff *msg, u32 attr, u16 ifmodes) |
787 | { | 787 | { |
788 | struct nlattr *nl_modes = nla_nest_start(msg, attr); | 788 | struct nlattr *nl_modes = nla_nest_start(msg, attr); |
789 | int i; | 789 | int i; |
790 | 790 | ||
791 | if (!nl_modes) | 791 | if (!nl_modes) |
792 | goto nla_put_failure; | 792 | goto nla_put_failure; |
793 | 793 | ||
794 | i = 0; | 794 | i = 0; |
795 | while (ifmodes) { | 795 | while (ifmodes) { |
796 | if ((ifmodes & 1) && nla_put_flag(msg, i)) | 796 | if ((ifmodes & 1) && nla_put_flag(msg, i)) |
797 | goto nla_put_failure; | 797 | goto nla_put_failure; |
798 | ifmodes >>= 1; | 798 | ifmodes >>= 1; |
799 | i++; | 799 | i++; |
800 | } | 800 | } |
801 | 801 | ||
802 | nla_nest_end(msg, nl_modes); | 802 | nla_nest_end(msg, nl_modes); |
803 | return 0; | 803 | return 0; |
804 | 804 | ||
805 | nla_put_failure: | 805 | nla_put_failure: |
806 | return -ENOBUFS; | 806 | return -ENOBUFS; |
807 | } | 807 | } |
808 | 808 | ||
809 | static int nl80211_put_iface_combinations(struct wiphy *wiphy, | 809 | static int nl80211_put_iface_combinations(struct wiphy *wiphy, |
810 | struct sk_buff *msg) | 810 | struct sk_buff *msg) |
811 | { | 811 | { |
812 | struct nlattr *nl_combis; | 812 | struct nlattr *nl_combis; |
813 | int i, j; | 813 | int i, j; |
814 | 814 | ||
815 | nl_combis = nla_nest_start(msg, | 815 | nl_combis = nla_nest_start(msg, |
816 | NL80211_ATTR_INTERFACE_COMBINATIONS); | 816 | NL80211_ATTR_INTERFACE_COMBINATIONS); |
817 | if (!nl_combis) | 817 | if (!nl_combis) |
818 | goto nla_put_failure; | 818 | goto nla_put_failure; |
819 | 819 | ||
820 | for (i = 0; i < wiphy->n_iface_combinations; i++) { | 820 | for (i = 0; i < wiphy->n_iface_combinations; i++) { |
821 | const struct ieee80211_iface_combination *c; | 821 | const struct ieee80211_iface_combination *c; |
822 | struct nlattr *nl_combi, *nl_limits; | 822 | struct nlattr *nl_combi, *nl_limits; |
823 | 823 | ||
824 | c = &wiphy->iface_combinations[i]; | 824 | c = &wiphy->iface_combinations[i]; |
825 | 825 | ||
826 | nl_combi = nla_nest_start(msg, i + 1); | 826 | nl_combi = nla_nest_start(msg, i + 1); |
827 | if (!nl_combi) | 827 | if (!nl_combi) |
828 | goto nla_put_failure; | 828 | goto nla_put_failure; |
829 | 829 | ||
830 | nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS); | 830 | nl_limits = nla_nest_start(msg, NL80211_IFACE_COMB_LIMITS); |
831 | if (!nl_limits) | 831 | if (!nl_limits) |
832 | goto nla_put_failure; | 832 | goto nla_put_failure; |
833 | 833 | ||
834 | for (j = 0; j < c->n_limits; j++) { | 834 | for (j = 0; j < c->n_limits; j++) { |
835 | struct nlattr *nl_limit; | 835 | struct nlattr *nl_limit; |
836 | 836 | ||
837 | nl_limit = nla_nest_start(msg, j + 1); | 837 | nl_limit = nla_nest_start(msg, j + 1); |
838 | if (!nl_limit) | 838 | if (!nl_limit) |
839 | goto nla_put_failure; | 839 | goto nla_put_failure; |
840 | if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX, | 840 | if (nla_put_u32(msg, NL80211_IFACE_LIMIT_MAX, |
841 | c->limits[j].max)) | 841 | c->limits[j].max)) |
842 | goto nla_put_failure; | 842 | goto nla_put_failure; |
843 | if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES, | 843 | if (nl80211_put_iftypes(msg, NL80211_IFACE_LIMIT_TYPES, |
844 | c->limits[j].types)) | 844 | c->limits[j].types)) |
845 | goto nla_put_failure; | 845 | goto nla_put_failure; |
846 | nla_nest_end(msg, nl_limit); | 846 | nla_nest_end(msg, nl_limit); |
847 | } | 847 | } |
848 | 848 | ||
849 | nla_nest_end(msg, nl_limits); | 849 | nla_nest_end(msg, nl_limits); |
850 | 850 | ||
851 | if (c->beacon_int_infra_match && | 851 | if (c->beacon_int_infra_match && |
852 | nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH)) | 852 | nla_put_flag(msg, NL80211_IFACE_COMB_STA_AP_BI_MATCH)) |
853 | goto nla_put_failure; | 853 | goto nla_put_failure; |
854 | if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS, | 854 | if (nla_put_u32(msg, NL80211_IFACE_COMB_NUM_CHANNELS, |
855 | c->num_different_channels) || | 855 | c->num_different_channels) || |
856 | nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, | 856 | nla_put_u32(msg, NL80211_IFACE_COMB_MAXNUM, |
857 | c->max_interfaces)) | 857 | c->max_interfaces)) |
858 | goto nla_put_failure; | 858 | goto nla_put_failure; |
859 | 859 | ||
860 | nla_nest_end(msg, nl_combi); | 860 | nla_nest_end(msg, nl_combi); |
861 | } | 861 | } |
862 | 862 | ||
863 | nla_nest_end(msg, nl_combis); | 863 | nla_nest_end(msg, nl_combis); |
864 | 864 | ||
865 | return 0; | 865 | return 0; |
866 | nla_put_failure: | 866 | nla_put_failure: |
867 | return -ENOBUFS; | 867 | return -ENOBUFS; |
868 | } | 868 | } |
869 | 869 | ||
870 | static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, | 870 | static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flags, |
871 | struct cfg80211_registered_device *dev) | 871 | struct cfg80211_registered_device *dev) |
872 | { | 872 | { |
873 | void *hdr; | 873 | void *hdr; |
874 | struct nlattr *nl_bands, *nl_band; | 874 | struct nlattr *nl_bands, *nl_band; |
875 | struct nlattr *nl_freqs, *nl_freq; | 875 | struct nlattr *nl_freqs, *nl_freq; |
876 | struct nlattr *nl_rates, *nl_rate; | 876 | struct nlattr *nl_rates, *nl_rate; |
877 | struct nlattr *nl_cmds; | 877 | struct nlattr *nl_cmds; |
878 | enum ieee80211_band band; | 878 | enum ieee80211_band band; |
879 | struct ieee80211_channel *chan; | 879 | struct ieee80211_channel *chan; |
880 | struct ieee80211_rate *rate; | 880 | struct ieee80211_rate *rate; |
881 | int i; | 881 | int i; |
882 | const struct ieee80211_txrx_stypes *mgmt_stypes = | 882 | const struct ieee80211_txrx_stypes *mgmt_stypes = |
883 | dev->wiphy.mgmt_stypes; | 883 | dev->wiphy.mgmt_stypes; |
884 | 884 | ||
885 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); | 885 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_WIPHY); |
886 | if (!hdr) | 886 | if (!hdr) |
887 | return -1; | 887 | return -1; |
888 | 888 | ||
889 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || | 889 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, dev->wiphy_idx) || |
890 | nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)) || | 890 | nla_put_string(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)) || |
891 | nla_put_u32(msg, NL80211_ATTR_GENERATION, | 891 | nla_put_u32(msg, NL80211_ATTR_GENERATION, |
892 | cfg80211_rdev_list_generation) || | 892 | cfg80211_rdev_list_generation) || |
893 | nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, | 893 | nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_SHORT, |
894 | dev->wiphy.retry_short) || | 894 | dev->wiphy.retry_short) || |
895 | nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, | 895 | nla_put_u8(msg, NL80211_ATTR_WIPHY_RETRY_LONG, |
896 | dev->wiphy.retry_long) || | 896 | dev->wiphy.retry_long) || |
897 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, | 897 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FRAG_THRESHOLD, |
898 | dev->wiphy.frag_threshold) || | 898 | dev->wiphy.frag_threshold) || |
899 | nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, | 899 | nla_put_u32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, |
900 | dev->wiphy.rts_threshold) || | 900 | dev->wiphy.rts_threshold) || |
901 | nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, | 901 | nla_put_u8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS, |
902 | dev->wiphy.coverage_class) || | 902 | dev->wiphy.coverage_class) || |
903 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, | 903 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, |
904 | dev->wiphy.max_scan_ssids) || | 904 | dev->wiphy.max_scan_ssids) || |
905 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, | 905 | nla_put_u8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, |
906 | dev->wiphy.max_sched_scan_ssids) || | 906 | dev->wiphy.max_sched_scan_ssids) || |
907 | nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, | 907 | nla_put_u16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, |
908 | dev->wiphy.max_scan_ie_len) || | 908 | dev->wiphy.max_scan_ie_len) || |
909 | nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, | 909 | nla_put_u16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, |
910 | dev->wiphy.max_sched_scan_ie_len) || | 910 | dev->wiphy.max_sched_scan_ie_len) || |
911 | nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS, | 911 | nla_put_u8(msg, NL80211_ATTR_MAX_MATCH_SETS, |
912 | dev->wiphy.max_match_sets)) | 912 | dev->wiphy.max_match_sets)) |
913 | goto nla_put_failure; | 913 | goto nla_put_failure; |
914 | 914 | ||
915 | if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) && | 915 | if ((dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) && |
916 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN)) | 916 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_IBSS_RSN)) |
917 | goto nla_put_failure; | 917 | goto nla_put_failure; |
918 | if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && | 918 | if ((dev->wiphy.flags & WIPHY_FLAG_MESH_AUTH) && |
919 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH)) | 919 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_MESH_AUTH)) |
920 | goto nla_put_failure; | 920 | goto nla_put_failure; |
921 | if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && | 921 | if ((dev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && |
922 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD)) | 922 | nla_put_flag(msg, NL80211_ATTR_SUPPORT_AP_UAPSD)) |
923 | goto nla_put_failure; | 923 | goto nla_put_failure; |
924 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) && | 924 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_FW_ROAM) && |
925 | nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT)) | 925 | nla_put_flag(msg, NL80211_ATTR_ROAM_SUPPORT)) |
926 | goto nla_put_failure; | 926 | goto nla_put_failure; |
927 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) && | 927 | if ((dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) && |
928 | nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT)) | 928 | nla_put_flag(msg, NL80211_ATTR_TDLS_SUPPORT)) |
929 | goto nla_put_failure; | 929 | goto nla_put_failure; |
930 | if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && | 930 | if ((dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP) && |
931 | nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) | 931 | nla_put_flag(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP)) |
932 | goto nla_put_failure; | 932 | goto nla_put_failure; |
933 | 933 | ||
934 | if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, | 934 | if (nla_put(msg, NL80211_ATTR_CIPHER_SUITES, |
935 | sizeof(u32) * dev->wiphy.n_cipher_suites, | 935 | sizeof(u32) * dev->wiphy.n_cipher_suites, |
936 | dev->wiphy.cipher_suites)) | 936 | dev->wiphy.cipher_suites)) |
937 | goto nla_put_failure; | 937 | goto nla_put_failure; |
938 | 938 | ||
939 | if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, | 939 | if (nla_put_u8(msg, NL80211_ATTR_MAX_NUM_PMKIDS, |
940 | dev->wiphy.max_num_pmkids)) | 940 | dev->wiphy.max_num_pmkids)) |
941 | goto nla_put_failure; | 941 | goto nla_put_failure; |
942 | 942 | ||
943 | if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && | 943 | if ((dev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && |
944 | nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE)) | 944 | nla_put_flag(msg, NL80211_ATTR_CONTROL_PORT_ETHERTYPE)) |
945 | goto nla_put_failure; | 945 | goto nla_put_failure; |
946 | 946 | ||
947 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, | 947 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX, |
948 | dev->wiphy.available_antennas_tx) || | 948 | dev->wiphy.available_antennas_tx) || |
949 | nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, | 949 | nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX, |
950 | dev->wiphy.available_antennas_rx)) | 950 | dev->wiphy.available_antennas_rx)) |
951 | goto nla_put_failure; | 951 | goto nla_put_failure; |
952 | 952 | ||
953 | if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) && | 953 | if ((dev->wiphy.flags & WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD) && |
954 | nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, | 954 | nla_put_u32(msg, NL80211_ATTR_PROBE_RESP_OFFLOAD, |
955 | dev->wiphy.probe_resp_offload)) | 955 | dev->wiphy.probe_resp_offload)) |
956 | goto nla_put_failure; | 956 | goto nla_put_failure; |
957 | 957 | ||
958 | if ((dev->wiphy.available_antennas_tx || | 958 | if ((dev->wiphy.available_antennas_tx || |
959 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { | 959 | dev->wiphy.available_antennas_rx) && dev->ops->get_antenna) { |
960 | u32 tx_ant = 0, rx_ant = 0; | 960 | u32 tx_ant = 0, rx_ant = 0; |
961 | int res; | 961 | int res; |
962 | res = rdev_get_antenna(dev, &tx_ant, &rx_ant); | 962 | res = rdev_get_antenna(dev, &tx_ant, &rx_ant); |
963 | if (!res) { | 963 | if (!res) { |
964 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, | 964 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_TX, |
965 | tx_ant) || | 965 | tx_ant) || |
966 | nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, | 966 | nla_put_u32(msg, NL80211_ATTR_WIPHY_ANTENNA_RX, |
967 | rx_ant)) | 967 | rx_ant)) |
968 | goto nla_put_failure; | 968 | goto nla_put_failure; |
969 | } | 969 | } |
970 | } | 970 | } |
971 | 971 | ||
972 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, | 972 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SUPPORTED_IFTYPES, |
973 | dev->wiphy.interface_modes)) | 973 | dev->wiphy.interface_modes)) |
974 | goto nla_put_failure; | 974 | goto nla_put_failure; |
975 | 975 | ||
976 | nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); | 976 | nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); |
977 | if (!nl_bands) | 977 | if (!nl_bands) |
978 | goto nla_put_failure; | 978 | goto nla_put_failure; |
979 | 979 | ||
980 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 980 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
981 | if (!dev->wiphy.bands[band]) | 981 | if (!dev->wiphy.bands[band]) |
982 | continue; | 982 | continue; |
983 | 983 | ||
984 | nl_band = nla_nest_start(msg, band); | 984 | nl_band = nla_nest_start(msg, band); |
985 | if (!nl_band) | 985 | if (!nl_band) |
986 | goto nla_put_failure; | 986 | goto nla_put_failure; |
987 | 987 | ||
988 | /* add HT info */ | 988 | /* add HT info */ |
989 | if (dev->wiphy.bands[band]->ht_cap.ht_supported && | 989 | if (dev->wiphy.bands[band]->ht_cap.ht_supported && |
990 | (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET, | 990 | (nla_put(msg, NL80211_BAND_ATTR_HT_MCS_SET, |
991 | sizeof(dev->wiphy.bands[band]->ht_cap.mcs), | 991 | sizeof(dev->wiphy.bands[band]->ht_cap.mcs), |
992 | &dev->wiphy.bands[band]->ht_cap.mcs) || | 992 | &dev->wiphy.bands[band]->ht_cap.mcs) || |
993 | nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA, | 993 | nla_put_u16(msg, NL80211_BAND_ATTR_HT_CAPA, |
994 | dev->wiphy.bands[band]->ht_cap.cap) || | 994 | dev->wiphy.bands[band]->ht_cap.cap) || |
995 | nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR, | 995 | nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_FACTOR, |
996 | dev->wiphy.bands[band]->ht_cap.ampdu_factor) || | 996 | dev->wiphy.bands[band]->ht_cap.ampdu_factor) || |
997 | nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY, | 997 | nla_put_u8(msg, NL80211_BAND_ATTR_HT_AMPDU_DENSITY, |
998 | dev->wiphy.bands[band]->ht_cap.ampdu_density))) | 998 | dev->wiphy.bands[band]->ht_cap.ampdu_density))) |
999 | goto nla_put_failure; | 999 | goto nla_put_failure; |
1000 | 1000 | ||
1001 | /* add VHT info */ | 1001 | /* add VHT info */ |
1002 | if (dev->wiphy.bands[band]->vht_cap.vht_supported && | 1002 | if (dev->wiphy.bands[band]->vht_cap.vht_supported && |
1003 | (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET, | 1003 | (nla_put(msg, NL80211_BAND_ATTR_VHT_MCS_SET, |
1004 | sizeof(dev->wiphy.bands[band]->vht_cap.vht_mcs), | 1004 | sizeof(dev->wiphy.bands[band]->vht_cap.vht_mcs), |
1005 | &dev->wiphy.bands[band]->vht_cap.vht_mcs) || | 1005 | &dev->wiphy.bands[band]->vht_cap.vht_mcs) || |
1006 | nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA, | 1006 | nla_put_u32(msg, NL80211_BAND_ATTR_VHT_CAPA, |
1007 | dev->wiphy.bands[band]->vht_cap.cap))) | 1007 | dev->wiphy.bands[band]->vht_cap.cap))) |
1008 | goto nla_put_failure; | 1008 | goto nla_put_failure; |
1009 | 1009 | ||
1010 | /* add frequencies */ | 1010 | /* add frequencies */ |
1011 | nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); | 1011 | nl_freqs = nla_nest_start(msg, NL80211_BAND_ATTR_FREQS); |
1012 | if (!nl_freqs) | 1012 | if (!nl_freqs) |
1013 | goto nla_put_failure; | 1013 | goto nla_put_failure; |
1014 | 1014 | ||
1015 | for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) { | 1015 | for (i = 0; i < dev->wiphy.bands[band]->n_channels; i++) { |
1016 | nl_freq = nla_nest_start(msg, i); | 1016 | nl_freq = nla_nest_start(msg, i); |
1017 | if (!nl_freq) | 1017 | if (!nl_freq) |
1018 | goto nla_put_failure; | 1018 | goto nla_put_failure; |
1019 | 1019 | ||
1020 | chan = &dev->wiphy.bands[band]->channels[i]; | 1020 | chan = &dev->wiphy.bands[band]->channels[i]; |
1021 | 1021 | ||
1022 | if (nl80211_msg_put_channel(msg, chan)) | 1022 | if (nl80211_msg_put_channel(msg, chan)) |
1023 | goto nla_put_failure; | 1023 | goto nla_put_failure; |
1024 | 1024 | ||
1025 | nla_nest_end(msg, nl_freq); | 1025 | nla_nest_end(msg, nl_freq); |
1026 | } | 1026 | } |
1027 | 1027 | ||
1028 | nla_nest_end(msg, nl_freqs); | 1028 | nla_nest_end(msg, nl_freqs); |
1029 | 1029 | ||
1030 | /* add bitrates */ | 1030 | /* add bitrates */ |
1031 | nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES); | 1031 | nl_rates = nla_nest_start(msg, NL80211_BAND_ATTR_RATES); |
1032 | if (!nl_rates) | 1032 | if (!nl_rates) |
1033 | goto nla_put_failure; | 1033 | goto nla_put_failure; |
1034 | 1034 | ||
1035 | for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) { | 1035 | for (i = 0; i < dev->wiphy.bands[band]->n_bitrates; i++) { |
1036 | nl_rate = nla_nest_start(msg, i); | 1036 | nl_rate = nla_nest_start(msg, i); |
1037 | if (!nl_rate) | 1037 | if (!nl_rate) |
1038 | goto nla_put_failure; | 1038 | goto nla_put_failure; |
1039 | 1039 | ||
1040 | rate = &dev->wiphy.bands[band]->bitrates[i]; | 1040 | rate = &dev->wiphy.bands[band]->bitrates[i]; |
1041 | if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE, | 1041 | if (nla_put_u32(msg, NL80211_BITRATE_ATTR_RATE, |
1042 | rate->bitrate)) | 1042 | rate->bitrate)) |
1043 | goto nla_put_failure; | 1043 | goto nla_put_failure; |
1044 | if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && | 1044 | if ((rate->flags & IEEE80211_RATE_SHORT_PREAMBLE) && |
1045 | nla_put_flag(msg, | 1045 | nla_put_flag(msg, |
1046 | NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE)) | 1046 | NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE)) |
1047 | goto nla_put_failure; | 1047 | goto nla_put_failure; |
1048 | 1048 | ||
1049 | nla_nest_end(msg, nl_rate); | 1049 | nla_nest_end(msg, nl_rate); |
1050 | } | 1050 | } |
1051 | 1051 | ||
1052 | nla_nest_end(msg, nl_rates); | 1052 | nla_nest_end(msg, nl_rates); |
1053 | 1053 | ||
1054 | nla_nest_end(msg, nl_band); | 1054 | nla_nest_end(msg, nl_band); |
1055 | } | 1055 | } |
1056 | nla_nest_end(msg, nl_bands); | 1056 | nla_nest_end(msg, nl_bands); |
1057 | 1057 | ||
1058 | nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); | 1058 | nl_cmds = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_COMMANDS); |
1059 | if (!nl_cmds) | 1059 | if (!nl_cmds) |
1060 | goto nla_put_failure; | 1060 | goto nla_put_failure; |
1061 | 1061 | ||
1062 | i = 0; | 1062 | i = 0; |
1063 | #define CMD(op, n) \ | 1063 | #define CMD(op, n) \ |
1064 | do { \ | 1064 | do { \ |
1065 | if (dev->ops->op) { \ | 1065 | if (dev->ops->op) { \ |
1066 | i++; \ | 1066 | i++; \ |
1067 | if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \ | 1067 | if (nla_put_u32(msg, i, NL80211_CMD_ ## n)) \ |
1068 | goto nla_put_failure; \ | 1068 | goto nla_put_failure; \ |
1069 | } \ | 1069 | } \ |
1070 | } while (0) | 1070 | } while (0) |
1071 | 1071 | ||
1072 | CMD(add_virtual_intf, NEW_INTERFACE); | 1072 | CMD(add_virtual_intf, NEW_INTERFACE); |
1073 | CMD(change_virtual_intf, SET_INTERFACE); | 1073 | CMD(change_virtual_intf, SET_INTERFACE); |
1074 | CMD(add_key, NEW_KEY); | 1074 | CMD(add_key, NEW_KEY); |
1075 | CMD(start_ap, START_AP); | 1075 | CMD(start_ap, START_AP); |
1076 | CMD(add_station, NEW_STATION); | 1076 | CMD(add_station, NEW_STATION); |
1077 | CMD(add_mpath, NEW_MPATH); | 1077 | CMD(add_mpath, NEW_MPATH); |
1078 | CMD(update_mesh_config, SET_MESH_CONFIG); | 1078 | CMD(update_mesh_config, SET_MESH_CONFIG); |
1079 | CMD(change_bss, SET_BSS); | 1079 | CMD(change_bss, SET_BSS); |
1080 | CMD(auth, AUTHENTICATE); | 1080 | CMD(auth, AUTHENTICATE); |
1081 | CMD(assoc, ASSOCIATE); | 1081 | CMD(assoc, ASSOCIATE); |
1082 | CMD(deauth, DEAUTHENTICATE); | 1082 | CMD(deauth, DEAUTHENTICATE); |
1083 | CMD(disassoc, DISASSOCIATE); | 1083 | CMD(disassoc, DISASSOCIATE); |
1084 | CMD(join_ibss, JOIN_IBSS); | 1084 | CMD(join_ibss, JOIN_IBSS); |
1085 | CMD(join_mesh, JOIN_MESH); | 1085 | CMD(join_mesh, JOIN_MESH); |
1086 | CMD(set_pmksa, SET_PMKSA); | 1086 | CMD(set_pmksa, SET_PMKSA); |
1087 | CMD(del_pmksa, DEL_PMKSA); | 1087 | CMD(del_pmksa, DEL_PMKSA); |
1088 | CMD(flush_pmksa, FLUSH_PMKSA); | 1088 | CMD(flush_pmksa, FLUSH_PMKSA); |
1089 | if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) | 1089 | if (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) |
1090 | CMD(remain_on_channel, REMAIN_ON_CHANNEL); | 1090 | CMD(remain_on_channel, REMAIN_ON_CHANNEL); |
1091 | CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); | 1091 | CMD(set_bitrate_mask, SET_TX_BITRATE_MASK); |
1092 | CMD(mgmt_tx, FRAME); | 1092 | CMD(mgmt_tx, FRAME); |
1093 | CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL); | 1093 | CMD(mgmt_tx_cancel_wait, FRAME_WAIT_CANCEL); |
1094 | if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { | 1094 | if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { |
1095 | i++; | 1095 | i++; |
1096 | if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) | 1096 | if (nla_put_u32(msg, i, NL80211_CMD_SET_WIPHY_NETNS)) |
1097 | goto nla_put_failure; | 1097 | goto nla_put_failure; |
1098 | } | 1098 | } |
1099 | if (dev->ops->set_monitor_channel || dev->ops->start_ap || | 1099 | if (dev->ops->set_monitor_channel || dev->ops->start_ap || |
1100 | dev->ops->join_mesh) { | 1100 | dev->ops->join_mesh) { |
1101 | i++; | 1101 | i++; |
1102 | if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) | 1102 | if (nla_put_u32(msg, i, NL80211_CMD_SET_CHANNEL)) |
1103 | goto nla_put_failure; | 1103 | goto nla_put_failure; |
1104 | } | 1104 | } |
1105 | CMD(set_wds_peer, SET_WDS_PEER); | 1105 | CMD(set_wds_peer, SET_WDS_PEER); |
1106 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) { | 1106 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) { |
1107 | CMD(tdls_mgmt, TDLS_MGMT); | 1107 | CMD(tdls_mgmt, TDLS_MGMT); |
1108 | CMD(tdls_oper, TDLS_OPER); | 1108 | CMD(tdls_oper, TDLS_OPER); |
1109 | } | 1109 | } |
1110 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) | 1110 | if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) |
1111 | CMD(sched_scan_start, START_SCHED_SCAN); | 1111 | CMD(sched_scan_start, START_SCHED_SCAN); |
1112 | CMD(probe_client, PROBE_CLIENT); | 1112 | CMD(probe_client, PROBE_CLIENT); |
1113 | CMD(set_noack_map, SET_NOACK_MAP); | 1113 | CMD(set_noack_map, SET_NOACK_MAP); |
1114 | if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { | 1114 | if (dev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS) { |
1115 | i++; | 1115 | i++; |
1116 | if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) | 1116 | if (nla_put_u32(msg, i, NL80211_CMD_REGISTER_BEACONS)) |
1117 | goto nla_put_failure; | 1117 | goto nla_put_failure; |
1118 | } | 1118 | } |
1119 | CMD(start_p2p_device, START_P2P_DEVICE); | 1119 | CMD(start_p2p_device, START_P2P_DEVICE); |
1120 | CMD(set_mcast_rate, SET_MCAST_RATE); | 1120 | CMD(set_mcast_rate, SET_MCAST_RATE); |
1121 | 1121 | ||
1122 | #ifdef CONFIG_NL80211_TESTMODE | 1122 | #ifdef CONFIG_NL80211_TESTMODE |
1123 | CMD(testmode_cmd, TESTMODE); | 1123 | CMD(testmode_cmd, TESTMODE); |
1124 | #endif | 1124 | #endif |
1125 | 1125 | ||
1126 | #undef CMD | 1126 | #undef CMD |
1127 | 1127 | ||
1128 | if (dev->ops->connect || dev->ops->auth) { | 1128 | if (dev->ops->connect || dev->ops->auth) { |
1129 | i++; | 1129 | i++; |
1130 | if (nla_put_u32(msg, i, NL80211_CMD_CONNECT)) | 1130 | if (nla_put_u32(msg, i, NL80211_CMD_CONNECT)) |
1131 | goto nla_put_failure; | 1131 | goto nla_put_failure; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | if (dev->ops->disconnect || dev->ops->deauth) { | 1134 | if (dev->ops->disconnect || dev->ops->deauth) { |
1135 | i++; | 1135 | i++; |
1136 | if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT)) | 1136 | if (nla_put_u32(msg, i, NL80211_CMD_DISCONNECT)) |
1137 | goto nla_put_failure; | 1137 | goto nla_put_failure; |
1138 | } | 1138 | } |
1139 | 1139 | ||
1140 | nla_nest_end(msg, nl_cmds); | 1140 | nla_nest_end(msg, nl_cmds); |
1141 | 1141 | ||
1142 | if (dev->ops->remain_on_channel && | 1142 | if (dev->ops->remain_on_channel && |
1143 | (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) && | 1143 | (dev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL) && |
1144 | nla_put_u32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, | 1144 | nla_put_u32(msg, NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION, |
1145 | dev->wiphy.max_remain_on_channel_duration)) | 1145 | dev->wiphy.max_remain_on_channel_duration)) |
1146 | goto nla_put_failure; | 1146 | goto nla_put_failure; |
1147 | 1147 | ||
1148 | if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) && | 1148 | if ((dev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX) && |
1149 | nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) | 1149 | nla_put_flag(msg, NL80211_ATTR_OFFCHANNEL_TX_OK)) |
1150 | goto nla_put_failure; | 1150 | goto nla_put_failure; |
1151 | 1151 | ||
1152 | if (mgmt_stypes) { | 1152 | if (mgmt_stypes) { |
1153 | u16 stypes; | 1153 | u16 stypes; |
1154 | struct nlattr *nl_ftypes, *nl_ifs; | 1154 | struct nlattr *nl_ftypes, *nl_ifs; |
1155 | enum nl80211_iftype ift; | 1155 | enum nl80211_iftype ift; |
1156 | 1156 | ||
1157 | nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES); | 1157 | nl_ifs = nla_nest_start(msg, NL80211_ATTR_TX_FRAME_TYPES); |
1158 | if (!nl_ifs) | 1158 | if (!nl_ifs) |
1159 | goto nla_put_failure; | 1159 | goto nla_put_failure; |
1160 | 1160 | ||
1161 | for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { | 1161 | for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { |
1162 | nl_ftypes = nla_nest_start(msg, ift); | 1162 | nl_ftypes = nla_nest_start(msg, ift); |
1163 | if (!nl_ftypes) | 1163 | if (!nl_ftypes) |
1164 | goto nla_put_failure; | 1164 | goto nla_put_failure; |
1165 | i = 0; | 1165 | i = 0; |
1166 | stypes = mgmt_stypes[ift].tx; | 1166 | stypes = mgmt_stypes[ift].tx; |
1167 | while (stypes) { | 1167 | while (stypes) { |
1168 | if ((stypes & 1) && | 1168 | if ((stypes & 1) && |
1169 | nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, | 1169 | nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, |
1170 | (i << 4) | IEEE80211_FTYPE_MGMT)) | 1170 | (i << 4) | IEEE80211_FTYPE_MGMT)) |
1171 | goto nla_put_failure; | 1171 | goto nla_put_failure; |
1172 | stypes >>= 1; | 1172 | stypes >>= 1; |
1173 | i++; | 1173 | i++; |
1174 | } | 1174 | } |
1175 | nla_nest_end(msg, nl_ftypes); | 1175 | nla_nest_end(msg, nl_ftypes); |
1176 | } | 1176 | } |
1177 | 1177 | ||
1178 | nla_nest_end(msg, nl_ifs); | 1178 | nla_nest_end(msg, nl_ifs); |
1179 | 1179 | ||
1180 | nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES); | 1180 | nl_ifs = nla_nest_start(msg, NL80211_ATTR_RX_FRAME_TYPES); |
1181 | if (!nl_ifs) | 1181 | if (!nl_ifs) |
1182 | goto nla_put_failure; | 1182 | goto nla_put_failure; |
1183 | 1183 | ||
1184 | for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { | 1184 | for (ift = 0; ift < NUM_NL80211_IFTYPES; ift++) { |
1185 | nl_ftypes = nla_nest_start(msg, ift); | 1185 | nl_ftypes = nla_nest_start(msg, ift); |
1186 | if (!nl_ftypes) | 1186 | if (!nl_ftypes) |
1187 | goto nla_put_failure; | 1187 | goto nla_put_failure; |
1188 | i = 0; | 1188 | i = 0; |
1189 | stypes = mgmt_stypes[ift].rx; | 1189 | stypes = mgmt_stypes[ift].rx; |
1190 | while (stypes) { | 1190 | while (stypes) { |
1191 | if ((stypes & 1) && | 1191 | if ((stypes & 1) && |
1192 | nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, | 1192 | nla_put_u16(msg, NL80211_ATTR_FRAME_TYPE, |
1193 | (i << 4) | IEEE80211_FTYPE_MGMT)) | 1193 | (i << 4) | IEEE80211_FTYPE_MGMT)) |
1194 | goto nla_put_failure; | 1194 | goto nla_put_failure; |
1195 | stypes >>= 1; | 1195 | stypes >>= 1; |
1196 | i++; | 1196 | i++; |
1197 | } | 1197 | } |
1198 | nla_nest_end(msg, nl_ftypes); | 1198 | nla_nest_end(msg, nl_ftypes); |
1199 | } | 1199 | } |
1200 | nla_nest_end(msg, nl_ifs); | 1200 | nla_nest_end(msg, nl_ifs); |
1201 | } | 1201 | } |
1202 | 1202 | ||
1203 | #ifdef CONFIG_PM | 1203 | #ifdef CONFIG_PM |
1204 | if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) { | 1204 | if (dev->wiphy.wowlan.flags || dev->wiphy.wowlan.n_patterns) { |
1205 | struct nlattr *nl_wowlan; | 1205 | struct nlattr *nl_wowlan; |
1206 | 1206 | ||
1207 | nl_wowlan = nla_nest_start(msg, | 1207 | nl_wowlan = nla_nest_start(msg, |
1208 | NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED); | 1208 | NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED); |
1209 | if (!nl_wowlan) | 1209 | if (!nl_wowlan) |
1210 | goto nla_put_failure; | 1210 | goto nla_put_failure; |
1211 | 1211 | ||
1212 | if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) && | 1212 | if (((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_ANY) && |
1213 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || | 1213 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || |
1214 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) && | 1214 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_DISCONNECT) && |
1215 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || | 1215 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || |
1216 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) && | 1216 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) && |
1217 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || | 1217 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || |
1218 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) && | 1218 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) && |
1219 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) || | 1219 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED)) || |
1220 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | 1220 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && |
1221 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || | 1221 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || |
1222 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) && | 1222 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) && |
1223 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || | 1223 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || |
1224 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) && | 1224 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) && |
1225 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || | 1225 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || |
1226 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) && | 1226 | ((dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) && |
1227 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) | 1227 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) |
1228 | goto nla_put_failure; | 1228 | goto nla_put_failure; |
1229 | if (dev->wiphy.wowlan.n_patterns) { | 1229 | if (dev->wiphy.wowlan.n_patterns) { |
1230 | struct nl80211_wowlan_pattern_support pat = { | 1230 | struct nl80211_wowlan_pattern_support pat = { |
1231 | .max_patterns = dev->wiphy.wowlan.n_patterns, | 1231 | .max_patterns = dev->wiphy.wowlan.n_patterns, |
1232 | .min_pattern_len = | 1232 | .min_pattern_len = |
1233 | dev->wiphy.wowlan.pattern_min_len, | 1233 | dev->wiphy.wowlan.pattern_min_len, |
1234 | .max_pattern_len = | 1234 | .max_pattern_len = |
1235 | dev->wiphy.wowlan.pattern_max_len, | 1235 | dev->wiphy.wowlan.pattern_max_len, |
1236 | }; | 1236 | }; |
1237 | if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, | 1237 | if (nla_put(msg, NL80211_WOWLAN_TRIG_PKT_PATTERN, |
1238 | sizeof(pat), &pat)) | 1238 | sizeof(pat), &pat)) |
1239 | goto nla_put_failure; | 1239 | goto nla_put_failure; |
1240 | } | 1240 | } |
1241 | 1241 | ||
1242 | nla_nest_end(msg, nl_wowlan); | 1242 | nla_nest_end(msg, nl_wowlan); |
1243 | } | 1243 | } |
1244 | #endif | 1244 | #endif |
1245 | 1245 | ||
1246 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, | 1246 | if (nl80211_put_iftypes(msg, NL80211_ATTR_SOFTWARE_IFTYPES, |
1247 | dev->wiphy.software_iftypes)) | 1247 | dev->wiphy.software_iftypes)) |
1248 | goto nla_put_failure; | 1248 | goto nla_put_failure; |
1249 | 1249 | ||
1250 | if (nl80211_put_iface_combinations(&dev->wiphy, msg)) | 1250 | if (nl80211_put_iface_combinations(&dev->wiphy, msg)) |
1251 | goto nla_put_failure; | 1251 | goto nla_put_failure; |
1252 | 1252 | ||
1253 | if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && | 1253 | if ((dev->wiphy.flags & WIPHY_FLAG_HAVE_AP_SME) && |
1254 | nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME, | 1254 | nla_put_u32(msg, NL80211_ATTR_DEVICE_AP_SME, |
1255 | dev->wiphy.ap_sme_capa)) | 1255 | dev->wiphy.ap_sme_capa)) |
1256 | goto nla_put_failure; | 1256 | goto nla_put_failure; |
1257 | 1257 | ||
1258 | if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, | 1258 | if (nla_put_u32(msg, NL80211_ATTR_FEATURE_FLAGS, |
1259 | dev->wiphy.features)) | 1259 | dev->wiphy.features)) |
1260 | goto nla_put_failure; | 1260 | goto nla_put_failure; |
1261 | 1261 | ||
1262 | if (dev->wiphy.ht_capa_mod_mask && | 1262 | if (dev->wiphy.ht_capa_mod_mask && |
1263 | nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, | 1263 | nla_put(msg, NL80211_ATTR_HT_CAPABILITY_MASK, |
1264 | sizeof(*dev->wiphy.ht_capa_mod_mask), | 1264 | sizeof(*dev->wiphy.ht_capa_mod_mask), |
1265 | dev->wiphy.ht_capa_mod_mask)) | 1265 | dev->wiphy.ht_capa_mod_mask)) |
1266 | goto nla_put_failure; | 1266 | goto nla_put_failure; |
1267 | 1267 | ||
1268 | return genlmsg_end(msg, hdr); | 1268 | return genlmsg_end(msg, hdr); |
1269 | 1269 | ||
1270 | nla_put_failure: | 1270 | nla_put_failure: |
1271 | genlmsg_cancel(msg, hdr); | 1271 | genlmsg_cancel(msg, hdr); |
1272 | return -EMSGSIZE; | 1272 | return -EMSGSIZE; |
1273 | } | 1273 | } |
1274 | 1274 | ||
1275 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | 1275 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) |
1276 | { | 1276 | { |
1277 | int idx = 0; | 1277 | int idx = 0; |
1278 | int start = cb->args[0]; | 1278 | int start = cb->args[0]; |
1279 | struct cfg80211_registered_device *dev; | 1279 | struct cfg80211_registered_device *dev; |
1280 | 1280 | ||
1281 | mutex_lock(&cfg80211_mutex); | 1281 | mutex_lock(&cfg80211_mutex); |
1282 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { | 1282 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { |
1283 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) | 1283 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) |
1284 | continue; | 1284 | continue; |
1285 | if (++idx <= start) | 1285 | if (++idx <= start) |
1286 | continue; | 1286 | continue; |
1287 | if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, | 1287 | if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, |
1288 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1288 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1289 | dev) < 0) { | 1289 | dev) < 0) { |
1290 | idx--; | 1290 | idx--; |
1291 | break; | 1291 | break; |
1292 | } | 1292 | } |
1293 | } | 1293 | } |
1294 | mutex_unlock(&cfg80211_mutex); | 1294 | mutex_unlock(&cfg80211_mutex); |
1295 | 1295 | ||
1296 | cb->args[0] = idx; | 1296 | cb->args[0] = idx; |
1297 | 1297 | ||
1298 | return skb->len; | 1298 | return skb->len; |
1299 | } | 1299 | } |
1300 | 1300 | ||
1301 | static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | 1301 | static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) |
1302 | { | 1302 | { |
1303 | struct sk_buff *msg; | 1303 | struct sk_buff *msg; |
1304 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1304 | struct cfg80211_registered_device *dev = info->user_ptr[0]; |
1305 | 1305 | ||
1306 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1306 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
1307 | if (!msg) | 1307 | if (!msg) |
1308 | return -ENOMEM; | 1308 | return -ENOMEM; |
1309 | 1309 | ||
1310 | if (nl80211_send_wiphy(msg, info->snd_portid, info->snd_seq, 0, dev) < 0) { | 1310 | if (nl80211_send_wiphy(msg, info->snd_portid, info->snd_seq, 0, dev) < 0) { |
1311 | nlmsg_free(msg); | 1311 | nlmsg_free(msg); |
1312 | return -ENOBUFS; | 1312 | return -ENOBUFS; |
1313 | } | 1313 | } |
1314 | 1314 | ||
1315 | return genlmsg_reply(msg, info); | 1315 | return genlmsg_reply(msg, info); |
1316 | } | 1316 | } |
1317 | 1317 | ||
1318 | static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { | 1318 | static const struct nla_policy txq_params_policy[NL80211_TXQ_ATTR_MAX + 1] = { |
1319 | [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 }, | 1319 | [NL80211_TXQ_ATTR_QUEUE] = { .type = NLA_U8 }, |
1320 | [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 }, | 1320 | [NL80211_TXQ_ATTR_TXOP] = { .type = NLA_U16 }, |
1321 | [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 }, | 1321 | [NL80211_TXQ_ATTR_CWMIN] = { .type = NLA_U16 }, |
1322 | [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 }, | 1322 | [NL80211_TXQ_ATTR_CWMAX] = { .type = NLA_U16 }, |
1323 | [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 }, | 1323 | [NL80211_TXQ_ATTR_AIFS] = { .type = NLA_U8 }, |
1324 | }; | 1324 | }; |
1325 | 1325 | ||
1326 | static int parse_txq_params(struct nlattr *tb[], | 1326 | static int parse_txq_params(struct nlattr *tb[], |
1327 | struct ieee80211_txq_params *txq_params) | 1327 | struct ieee80211_txq_params *txq_params) |
1328 | { | 1328 | { |
1329 | if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] || | 1329 | if (!tb[NL80211_TXQ_ATTR_AC] || !tb[NL80211_TXQ_ATTR_TXOP] || |
1330 | !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] || | 1330 | !tb[NL80211_TXQ_ATTR_CWMIN] || !tb[NL80211_TXQ_ATTR_CWMAX] || |
1331 | !tb[NL80211_TXQ_ATTR_AIFS]) | 1331 | !tb[NL80211_TXQ_ATTR_AIFS]) |
1332 | return -EINVAL; | 1332 | return -EINVAL; |
1333 | 1333 | ||
1334 | txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]); | 1334 | txq_params->ac = nla_get_u8(tb[NL80211_TXQ_ATTR_AC]); |
1335 | txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]); | 1335 | txq_params->txop = nla_get_u16(tb[NL80211_TXQ_ATTR_TXOP]); |
1336 | txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]); | 1336 | txq_params->cwmin = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMIN]); |
1337 | txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]); | 1337 | txq_params->cwmax = nla_get_u16(tb[NL80211_TXQ_ATTR_CWMAX]); |
1338 | txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]); | 1338 | txq_params->aifs = nla_get_u8(tb[NL80211_TXQ_ATTR_AIFS]); |
1339 | 1339 | ||
1340 | if (txq_params->ac >= NL80211_NUM_ACS) | 1340 | if (txq_params->ac >= NL80211_NUM_ACS) |
1341 | return -EINVAL; | 1341 | return -EINVAL; |
1342 | 1342 | ||
1343 | return 0; | 1343 | return 0; |
1344 | } | 1344 | } |
1345 | 1345 | ||
1346 | static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) | 1346 | static bool nl80211_can_set_dev_channel(struct wireless_dev *wdev) |
1347 | { | 1347 | { |
1348 | /* | 1348 | /* |
1349 | * You can only set the channel explicitly for WDS interfaces, | 1349 | * You can only set the channel explicitly for WDS interfaces, |
1350 | * all others have their channel managed via their respective | 1350 | * all others have their channel managed via their respective |
1351 | * "establish a connection" command (connect, join, ...) | 1351 | * "establish a connection" command (connect, join, ...) |
1352 | * | 1352 | * |
1353 | * For AP/GO and mesh mode, the channel can be set with the | 1353 | * For AP/GO and mesh mode, the channel can be set with the |
1354 | * channel userspace API, but is only stored and passed to the | 1354 | * channel userspace API, but is only stored and passed to the |
1355 | * low-level driver when the AP starts or the mesh is joined. | 1355 | * low-level driver when the AP starts or the mesh is joined. |
1356 | * This is for backward compatibility, userspace can also give | 1356 | * This is for backward compatibility, userspace can also give |
1357 | * the channel in the start-ap or join-mesh commands instead. | 1357 | * the channel in the start-ap or join-mesh commands instead. |
1358 | * | 1358 | * |
1359 | * Monitors are special as they are normally slaved to | 1359 | * Monitors are special as they are normally slaved to |
1360 | * whatever else is going on, so they have their own special | 1360 | * whatever else is going on, so they have their own special |
1361 | * operation to set the monitor channel if possible. | 1361 | * operation to set the monitor channel if possible. |
1362 | */ | 1362 | */ |
1363 | return !wdev || | 1363 | return !wdev || |
1364 | wdev->iftype == NL80211_IFTYPE_AP || | 1364 | wdev->iftype == NL80211_IFTYPE_AP || |
1365 | wdev->iftype == NL80211_IFTYPE_MESH_POINT || | 1365 | wdev->iftype == NL80211_IFTYPE_MESH_POINT || |
1366 | wdev->iftype == NL80211_IFTYPE_MONITOR || | 1366 | wdev->iftype == NL80211_IFTYPE_MONITOR || |
1367 | wdev->iftype == NL80211_IFTYPE_P2P_GO; | 1367 | wdev->iftype == NL80211_IFTYPE_P2P_GO; |
1368 | } | 1368 | } |
1369 | 1369 | ||
1370 | static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, | 1370 | static int nl80211_parse_chandef(struct cfg80211_registered_device *rdev, |
1371 | struct genl_info *info, | 1371 | struct genl_info *info, |
1372 | struct cfg80211_chan_def *chandef) | 1372 | struct cfg80211_chan_def *chandef) |
1373 | { | 1373 | { |
1374 | u32 control_freq; | 1374 | u32 control_freq; |
1375 | 1375 | ||
1376 | if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) | 1376 | if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) |
1377 | return -EINVAL; | 1377 | return -EINVAL; |
1378 | 1378 | ||
1379 | control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); | 1379 | control_freq = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ]); |
1380 | 1380 | ||
1381 | chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq); | 1381 | chandef->chan = ieee80211_get_channel(&rdev->wiphy, control_freq); |
1382 | chandef->width = NL80211_CHAN_WIDTH_20_NOHT; | 1382 | chandef->width = NL80211_CHAN_WIDTH_20_NOHT; |
1383 | chandef->center_freq1 = control_freq; | 1383 | chandef->center_freq1 = control_freq; |
1384 | chandef->center_freq2 = 0; | 1384 | chandef->center_freq2 = 0; |
1385 | 1385 | ||
1386 | /* Primary channel not allowed */ | 1386 | /* Primary channel not allowed */ |
1387 | if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) | 1387 | if (!chandef->chan || chandef->chan->flags & IEEE80211_CHAN_DISABLED) |
1388 | return -EINVAL; | 1388 | return -EINVAL; |
1389 | 1389 | ||
1390 | if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { | 1390 | if (info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]) { |
1391 | enum nl80211_channel_type chantype; | 1391 | enum nl80211_channel_type chantype; |
1392 | 1392 | ||
1393 | chantype = nla_get_u32( | 1393 | chantype = nla_get_u32( |
1394 | info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); | 1394 | info->attrs[NL80211_ATTR_WIPHY_CHANNEL_TYPE]); |
1395 | 1395 | ||
1396 | switch (chantype) { | 1396 | switch (chantype) { |
1397 | case NL80211_CHAN_NO_HT: | 1397 | case NL80211_CHAN_NO_HT: |
1398 | case NL80211_CHAN_HT20: | 1398 | case NL80211_CHAN_HT20: |
1399 | case NL80211_CHAN_HT40PLUS: | 1399 | case NL80211_CHAN_HT40PLUS: |
1400 | case NL80211_CHAN_HT40MINUS: | 1400 | case NL80211_CHAN_HT40MINUS: |
1401 | cfg80211_chandef_create(chandef, chandef->chan, | 1401 | cfg80211_chandef_create(chandef, chandef->chan, |
1402 | chantype); | 1402 | chantype); |
1403 | break; | 1403 | break; |
1404 | default: | 1404 | default: |
1405 | return -EINVAL; | 1405 | return -EINVAL; |
1406 | } | 1406 | } |
1407 | } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) { | 1407 | } else if (info->attrs[NL80211_ATTR_CHANNEL_WIDTH]) { |
1408 | chandef->width = | 1408 | chandef->width = |
1409 | nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]); | 1409 | nla_get_u32(info->attrs[NL80211_ATTR_CHANNEL_WIDTH]); |
1410 | if (info->attrs[NL80211_ATTR_CENTER_FREQ1]) | 1410 | if (info->attrs[NL80211_ATTR_CENTER_FREQ1]) |
1411 | chandef->center_freq1 = | 1411 | chandef->center_freq1 = |
1412 | nla_get_u32( | 1412 | nla_get_u32( |
1413 | info->attrs[NL80211_ATTR_CENTER_FREQ1]); | 1413 | info->attrs[NL80211_ATTR_CENTER_FREQ1]); |
1414 | if (info->attrs[NL80211_ATTR_CENTER_FREQ2]) | 1414 | if (info->attrs[NL80211_ATTR_CENTER_FREQ2]) |
1415 | chandef->center_freq2 = | 1415 | chandef->center_freq2 = |
1416 | nla_get_u32( | 1416 | nla_get_u32( |
1417 | info->attrs[NL80211_ATTR_CENTER_FREQ2]); | 1417 | info->attrs[NL80211_ATTR_CENTER_FREQ2]); |
1418 | } | 1418 | } |
1419 | 1419 | ||
1420 | if (!cfg80211_chandef_valid(chandef)) | 1420 | if (!cfg80211_chandef_valid(chandef)) |
1421 | return -EINVAL; | 1421 | return -EINVAL; |
1422 | 1422 | ||
1423 | if (!cfg80211_chandef_usable(&rdev->wiphy, chandef, | 1423 | if (!cfg80211_chandef_usable(&rdev->wiphy, chandef, |
1424 | IEEE80211_CHAN_DISABLED)) | 1424 | IEEE80211_CHAN_DISABLED)) |
1425 | return -EINVAL; | 1425 | return -EINVAL; |
1426 | 1426 | ||
1427 | return 0; | 1427 | return 0; |
1428 | } | 1428 | } |
1429 | 1429 | ||
1430 | static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, | 1430 | static int __nl80211_set_channel(struct cfg80211_registered_device *rdev, |
1431 | struct wireless_dev *wdev, | 1431 | struct wireless_dev *wdev, |
1432 | struct genl_info *info) | 1432 | struct genl_info *info) |
1433 | { | 1433 | { |
1434 | struct cfg80211_chan_def chandef; | 1434 | struct cfg80211_chan_def chandef; |
1435 | int result; | 1435 | int result; |
1436 | enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; | 1436 | enum nl80211_iftype iftype = NL80211_IFTYPE_MONITOR; |
1437 | 1437 | ||
1438 | if (wdev) | 1438 | if (wdev) |
1439 | iftype = wdev->iftype; | 1439 | iftype = wdev->iftype; |
1440 | 1440 | ||
1441 | if (!nl80211_can_set_dev_channel(wdev)) | 1441 | if (!nl80211_can_set_dev_channel(wdev)) |
1442 | return -EOPNOTSUPP; | 1442 | return -EOPNOTSUPP; |
1443 | 1443 | ||
1444 | result = nl80211_parse_chandef(rdev, info, &chandef); | 1444 | result = nl80211_parse_chandef(rdev, info, &chandef); |
1445 | if (result) | 1445 | if (result) |
1446 | return result; | 1446 | return result; |
1447 | 1447 | ||
1448 | mutex_lock(&rdev->devlist_mtx); | 1448 | mutex_lock(&rdev->devlist_mtx); |
1449 | switch (iftype) { | 1449 | switch (iftype) { |
1450 | case NL80211_IFTYPE_AP: | 1450 | case NL80211_IFTYPE_AP: |
1451 | case NL80211_IFTYPE_P2P_GO: | 1451 | case NL80211_IFTYPE_P2P_GO: |
1452 | if (wdev->beacon_interval) { | 1452 | if (wdev->beacon_interval) { |
1453 | result = -EBUSY; | 1453 | result = -EBUSY; |
1454 | break; | 1454 | break; |
1455 | } | 1455 | } |
1456 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) { | 1456 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &chandef)) { |
1457 | result = -EINVAL; | 1457 | result = -EINVAL; |
1458 | break; | 1458 | break; |
1459 | } | 1459 | } |
1460 | wdev->preset_chandef = chandef; | 1460 | wdev->preset_chandef = chandef; |
1461 | result = 0; | 1461 | result = 0; |
1462 | break; | 1462 | break; |
1463 | case NL80211_IFTYPE_MESH_POINT: | 1463 | case NL80211_IFTYPE_MESH_POINT: |
1464 | result = cfg80211_set_mesh_channel(rdev, wdev, &chandef); | 1464 | result = cfg80211_set_mesh_channel(rdev, wdev, &chandef); |
1465 | break; | 1465 | break; |
1466 | case NL80211_IFTYPE_MONITOR: | 1466 | case NL80211_IFTYPE_MONITOR: |
1467 | result = cfg80211_set_monitor_channel(rdev, &chandef); | 1467 | result = cfg80211_set_monitor_channel(rdev, &chandef); |
1468 | break; | 1468 | break; |
1469 | default: | 1469 | default: |
1470 | result = -EINVAL; | 1470 | result = -EINVAL; |
1471 | } | 1471 | } |
1472 | mutex_unlock(&rdev->devlist_mtx); | 1472 | mutex_unlock(&rdev->devlist_mtx); |
1473 | 1473 | ||
1474 | return result; | 1474 | return result; |
1475 | } | 1475 | } |
1476 | 1476 | ||
1477 | static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) | 1477 | static int nl80211_set_channel(struct sk_buff *skb, struct genl_info *info) |
1478 | { | 1478 | { |
1479 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 1479 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1480 | struct net_device *netdev = info->user_ptr[1]; | 1480 | struct net_device *netdev = info->user_ptr[1]; |
1481 | 1481 | ||
1482 | return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); | 1482 | return __nl80211_set_channel(rdev, netdev->ieee80211_ptr, info); |
1483 | } | 1483 | } |
1484 | 1484 | ||
1485 | static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) | 1485 | static int nl80211_set_wds_peer(struct sk_buff *skb, struct genl_info *info) |
1486 | { | 1486 | { |
1487 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 1487 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1488 | struct net_device *dev = info->user_ptr[1]; | 1488 | struct net_device *dev = info->user_ptr[1]; |
1489 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1489 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1490 | const u8 *bssid; | 1490 | const u8 *bssid; |
1491 | 1491 | ||
1492 | if (!info->attrs[NL80211_ATTR_MAC]) | 1492 | if (!info->attrs[NL80211_ATTR_MAC]) |
1493 | return -EINVAL; | 1493 | return -EINVAL; |
1494 | 1494 | ||
1495 | if (netif_running(dev)) | 1495 | if (netif_running(dev)) |
1496 | return -EBUSY; | 1496 | return -EBUSY; |
1497 | 1497 | ||
1498 | if (!rdev->ops->set_wds_peer) | 1498 | if (!rdev->ops->set_wds_peer) |
1499 | return -EOPNOTSUPP; | 1499 | return -EOPNOTSUPP; |
1500 | 1500 | ||
1501 | if (wdev->iftype != NL80211_IFTYPE_WDS) | 1501 | if (wdev->iftype != NL80211_IFTYPE_WDS) |
1502 | return -EOPNOTSUPP; | 1502 | return -EOPNOTSUPP; |
1503 | 1503 | ||
1504 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 1504 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
1505 | return rdev_set_wds_peer(rdev, dev, bssid); | 1505 | return rdev_set_wds_peer(rdev, dev, bssid); |
1506 | } | 1506 | } |
1507 | 1507 | ||
1508 | 1508 | ||
1509 | static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) | 1509 | static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info) |
1510 | { | 1510 | { |
1511 | struct cfg80211_registered_device *rdev; | 1511 | struct cfg80211_registered_device *rdev; |
1512 | struct net_device *netdev = NULL; | 1512 | struct net_device *netdev = NULL; |
1513 | struct wireless_dev *wdev; | 1513 | struct wireless_dev *wdev; |
1514 | int result = 0, rem_txq_params = 0; | 1514 | int result = 0, rem_txq_params = 0; |
1515 | struct nlattr *nl_txq_params; | 1515 | struct nlattr *nl_txq_params; |
1516 | u32 changed; | 1516 | u32 changed; |
1517 | u8 retry_short = 0, retry_long = 0; | 1517 | u8 retry_short = 0, retry_long = 0; |
1518 | u32 frag_threshold = 0, rts_threshold = 0; | 1518 | u32 frag_threshold = 0, rts_threshold = 0; |
1519 | u8 coverage_class = 0; | 1519 | u8 coverage_class = 0; |
1520 | 1520 | ||
1521 | /* | 1521 | /* |
1522 | * Try to find the wiphy and netdev. Normally this | 1522 | * Try to find the wiphy and netdev. Normally this |
1523 | * function shouldn't need the netdev, but this is | 1523 | * function shouldn't need the netdev, but this is |
1524 | * done for backward compatibility -- previously | 1524 | * done for backward compatibility -- previously |
1525 | * setting the channel was done per wiphy, but now | 1525 | * setting the channel was done per wiphy, but now |
1526 | * it is per netdev. Previous userland like hostapd | 1526 | * it is per netdev. Previous userland like hostapd |
1527 | * also passed a netdev to set_wiphy, so that it is | 1527 | * also passed a netdev to set_wiphy, so that it is |
1528 | * possible to let that go to the right netdev! | 1528 | * possible to let that go to the right netdev! |
1529 | */ | 1529 | */ |
1530 | mutex_lock(&cfg80211_mutex); | 1530 | mutex_lock(&cfg80211_mutex); |
1531 | 1531 | ||
1532 | if (info->attrs[NL80211_ATTR_IFINDEX]) { | 1532 | if (info->attrs[NL80211_ATTR_IFINDEX]) { |
1533 | int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); | 1533 | int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); |
1534 | 1534 | ||
1535 | netdev = dev_get_by_index(genl_info_net(info), ifindex); | 1535 | netdev = dev_get_by_index(genl_info_net(info), ifindex); |
1536 | if (netdev && netdev->ieee80211_ptr) { | 1536 | if (netdev && netdev->ieee80211_ptr) { |
1537 | rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); | 1537 | rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); |
1538 | mutex_lock(&rdev->mtx); | 1538 | mutex_lock(&rdev->mtx); |
1539 | } else | 1539 | } else |
1540 | netdev = NULL; | 1540 | netdev = NULL; |
1541 | } | 1541 | } |
1542 | 1542 | ||
1543 | if (!netdev) { | 1543 | if (!netdev) { |
1544 | rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), | 1544 | rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), |
1545 | info->attrs); | 1545 | info->attrs); |
1546 | if (IS_ERR(rdev)) { | 1546 | if (IS_ERR(rdev)) { |
1547 | mutex_unlock(&cfg80211_mutex); | 1547 | mutex_unlock(&cfg80211_mutex); |
1548 | return PTR_ERR(rdev); | 1548 | return PTR_ERR(rdev); |
1549 | } | 1549 | } |
1550 | wdev = NULL; | 1550 | wdev = NULL; |
1551 | netdev = NULL; | 1551 | netdev = NULL; |
1552 | result = 0; | 1552 | result = 0; |
1553 | 1553 | ||
1554 | mutex_lock(&rdev->mtx); | 1554 | mutex_lock(&rdev->mtx); |
1555 | } else | 1555 | } else |
1556 | wdev = netdev->ieee80211_ptr; | 1556 | wdev = netdev->ieee80211_ptr; |
1557 | 1557 | ||
1558 | /* | 1558 | /* |
1559 | * end workaround code, by now the rdev is available | 1559 | * end workaround code, by now the rdev is available |
1560 | * and locked, and wdev may or may not be NULL. | 1560 | * and locked, and wdev may or may not be NULL. |
1561 | */ | 1561 | */ |
1562 | 1562 | ||
1563 | if (info->attrs[NL80211_ATTR_WIPHY_NAME]) | 1563 | if (info->attrs[NL80211_ATTR_WIPHY_NAME]) |
1564 | result = cfg80211_dev_rename( | 1564 | result = cfg80211_dev_rename( |
1565 | rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); | 1565 | rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); |
1566 | 1566 | ||
1567 | mutex_unlock(&cfg80211_mutex); | 1567 | mutex_unlock(&cfg80211_mutex); |
1568 | 1568 | ||
1569 | if (result) | 1569 | if (result) |
1570 | goto bad_res; | 1570 | goto bad_res; |
1571 | 1571 | ||
1572 | if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { | 1572 | if (info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS]) { |
1573 | struct ieee80211_txq_params txq_params; | 1573 | struct ieee80211_txq_params txq_params; |
1574 | struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1]; | 1574 | struct nlattr *tb[NL80211_TXQ_ATTR_MAX + 1]; |
1575 | 1575 | ||
1576 | if (!rdev->ops->set_txq_params) { | 1576 | if (!rdev->ops->set_txq_params) { |
1577 | result = -EOPNOTSUPP; | 1577 | result = -EOPNOTSUPP; |
1578 | goto bad_res; | 1578 | goto bad_res; |
1579 | } | 1579 | } |
1580 | 1580 | ||
1581 | if (!netdev) { | 1581 | if (!netdev) { |
1582 | result = -EINVAL; | 1582 | result = -EINVAL; |
1583 | goto bad_res; | 1583 | goto bad_res; |
1584 | } | 1584 | } |
1585 | 1585 | ||
1586 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 1586 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
1587 | netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { | 1587 | netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) { |
1588 | result = -EINVAL; | 1588 | result = -EINVAL; |
1589 | goto bad_res; | 1589 | goto bad_res; |
1590 | } | 1590 | } |
1591 | 1591 | ||
1592 | if (!netif_running(netdev)) { | 1592 | if (!netif_running(netdev)) { |
1593 | result = -ENETDOWN; | 1593 | result = -ENETDOWN; |
1594 | goto bad_res; | 1594 | goto bad_res; |
1595 | } | 1595 | } |
1596 | 1596 | ||
1597 | nla_for_each_nested(nl_txq_params, | 1597 | nla_for_each_nested(nl_txq_params, |
1598 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], | 1598 | info->attrs[NL80211_ATTR_WIPHY_TXQ_PARAMS], |
1599 | rem_txq_params) { | 1599 | rem_txq_params) { |
1600 | nla_parse(tb, NL80211_TXQ_ATTR_MAX, | 1600 | nla_parse(tb, NL80211_TXQ_ATTR_MAX, |
1601 | nla_data(nl_txq_params), | 1601 | nla_data(nl_txq_params), |
1602 | nla_len(nl_txq_params), | 1602 | nla_len(nl_txq_params), |
1603 | txq_params_policy); | 1603 | txq_params_policy); |
1604 | result = parse_txq_params(tb, &txq_params); | 1604 | result = parse_txq_params(tb, &txq_params); |
1605 | if (result) | 1605 | if (result) |
1606 | goto bad_res; | 1606 | goto bad_res; |
1607 | 1607 | ||
1608 | result = rdev_set_txq_params(rdev, netdev, | 1608 | result = rdev_set_txq_params(rdev, netdev, |
1609 | &txq_params); | 1609 | &txq_params); |
1610 | if (result) | 1610 | if (result) |
1611 | goto bad_res; | 1611 | goto bad_res; |
1612 | } | 1612 | } |
1613 | } | 1613 | } |
1614 | 1614 | ||
1615 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | 1615 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { |
1616 | result = __nl80211_set_channel(rdev, | 1616 | result = __nl80211_set_channel(rdev, |
1617 | nl80211_can_set_dev_channel(wdev) ? wdev : NULL, | 1617 | nl80211_can_set_dev_channel(wdev) ? wdev : NULL, |
1618 | info); | 1618 | info); |
1619 | if (result) | 1619 | if (result) |
1620 | goto bad_res; | 1620 | goto bad_res; |
1621 | } | 1621 | } |
1622 | 1622 | ||
1623 | if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { | 1623 | if (info->attrs[NL80211_ATTR_WIPHY_TX_POWER_SETTING]) { |
1624 | struct wireless_dev *txp_wdev = wdev; | 1624 | struct wireless_dev *txp_wdev = wdev; |
1625 | enum nl80211_tx_power_setting type; | 1625 | enum nl80211_tx_power_setting type; |
1626 | int idx, mbm = 0; | 1626 | int idx, mbm = 0; |
1627 | 1627 | ||
1628 | if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER)) | 1628 | if (!(rdev->wiphy.features & NL80211_FEATURE_VIF_TXPOWER)) |
1629 | txp_wdev = NULL; | 1629 | txp_wdev = NULL; |
1630 | 1630 | ||
1631 | if (!rdev->ops->set_tx_power) { | 1631 | if (!rdev->ops->set_tx_power) { |
1632 | result = -EOPNOTSUPP; | 1632 | result = -EOPNOTSUPP; |
1633 | goto bad_res; | 1633 | goto bad_res; |
1634 | } | 1634 | } |
1635 | 1635 | ||
1636 | idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING; | 1636 | idx = NL80211_ATTR_WIPHY_TX_POWER_SETTING; |
1637 | type = nla_get_u32(info->attrs[idx]); | 1637 | type = nla_get_u32(info->attrs[idx]); |
1638 | 1638 | ||
1639 | if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] && | 1639 | if (!info->attrs[NL80211_ATTR_WIPHY_TX_POWER_LEVEL] && |
1640 | (type != NL80211_TX_POWER_AUTOMATIC)) { | 1640 | (type != NL80211_TX_POWER_AUTOMATIC)) { |
1641 | result = -EINVAL; | 1641 | result = -EINVAL; |
1642 | goto bad_res; | 1642 | goto bad_res; |
1643 | } | 1643 | } |
1644 | 1644 | ||
1645 | if (type != NL80211_TX_POWER_AUTOMATIC) { | 1645 | if (type != NL80211_TX_POWER_AUTOMATIC) { |
1646 | idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL; | 1646 | idx = NL80211_ATTR_WIPHY_TX_POWER_LEVEL; |
1647 | mbm = nla_get_u32(info->attrs[idx]); | 1647 | mbm = nla_get_u32(info->attrs[idx]); |
1648 | } | 1648 | } |
1649 | 1649 | ||
1650 | result = rdev_set_tx_power(rdev, txp_wdev, type, mbm); | 1650 | result = rdev_set_tx_power(rdev, txp_wdev, type, mbm); |
1651 | if (result) | 1651 | if (result) |
1652 | goto bad_res; | 1652 | goto bad_res; |
1653 | } | 1653 | } |
1654 | 1654 | ||
1655 | if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && | 1655 | if (info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX] && |
1656 | info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { | 1656 | info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]) { |
1657 | u32 tx_ant, rx_ant; | 1657 | u32 tx_ant, rx_ant; |
1658 | if ((!rdev->wiphy.available_antennas_tx && | 1658 | if ((!rdev->wiphy.available_antennas_tx && |
1659 | !rdev->wiphy.available_antennas_rx) || | 1659 | !rdev->wiphy.available_antennas_rx) || |
1660 | !rdev->ops->set_antenna) { | 1660 | !rdev->ops->set_antenna) { |
1661 | result = -EOPNOTSUPP; | 1661 | result = -EOPNOTSUPP; |
1662 | goto bad_res; | 1662 | goto bad_res; |
1663 | } | 1663 | } |
1664 | 1664 | ||
1665 | tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); | 1665 | tx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_TX]); |
1666 | rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); | 1666 | rx_ant = nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_ANTENNA_RX]); |
1667 | 1667 | ||
1668 | /* reject antenna configurations which don't match the | 1668 | /* reject antenna configurations which don't match the |
1669 | * available antenna masks, except for the "all" mask */ | 1669 | * available antenna masks, except for the "all" mask */ |
1670 | if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) || | 1670 | if ((~tx_ant && (tx_ant & ~rdev->wiphy.available_antennas_tx)) || |
1671 | (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) { | 1671 | (~rx_ant && (rx_ant & ~rdev->wiphy.available_antennas_rx))) { |
1672 | result = -EINVAL; | 1672 | result = -EINVAL; |
1673 | goto bad_res; | 1673 | goto bad_res; |
1674 | } | 1674 | } |
1675 | 1675 | ||
1676 | tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; | 1676 | tx_ant = tx_ant & rdev->wiphy.available_antennas_tx; |
1677 | rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; | 1677 | rx_ant = rx_ant & rdev->wiphy.available_antennas_rx; |
1678 | 1678 | ||
1679 | result = rdev_set_antenna(rdev, tx_ant, rx_ant); | 1679 | result = rdev_set_antenna(rdev, tx_ant, rx_ant); |
1680 | if (result) | 1680 | if (result) |
1681 | goto bad_res; | 1681 | goto bad_res; |
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | changed = 0; | 1684 | changed = 0; |
1685 | 1685 | ||
1686 | if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) { | 1686 | if (info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]) { |
1687 | retry_short = nla_get_u8( | 1687 | retry_short = nla_get_u8( |
1688 | info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]); | 1688 | info->attrs[NL80211_ATTR_WIPHY_RETRY_SHORT]); |
1689 | if (retry_short == 0) { | 1689 | if (retry_short == 0) { |
1690 | result = -EINVAL; | 1690 | result = -EINVAL; |
1691 | goto bad_res; | 1691 | goto bad_res; |
1692 | } | 1692 | } |
1693 | changed |= WIPHY_PARAM_RETRY_SHORT; | 1693 | changed |= WIPHY_PARAM_RETRY_SHORT; |
1694 | } | 1694 | } |
1695 | 1695 | ||
1696 | if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) { | 1696 | if (info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]) { |
1697 | retry_long = nla_get_u8( | 1697 | retry_long = nla_get_u8( |
1698 | info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]); | 1698 | info->attrs[NL80211_ATTR_WIPHY_RETRY_LONG]); |
1699 | if (retry_long == 0) { | 1699 | if (retry_long == 0) { |
1700 | result = -EINVAL; | 1700 | result = -EINVAL; |
1701 | goto bad_res; | 1701 | goto bad_res; |
1702 | } | 1702 | } |
1703 | changed |= WIPHY_PARAM_RETRY_LONG; | 1703 | changed |= WIPHY_PARAM_RETRY_LONG; |
1704 | } | 1704 | } |
1705 | 1705 | ||
1706 | if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) { | 1706 | if (info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]) { |
1707 | frag_threshold = nla_get_u32( | 1707 | frag_threshold = nla_get_u32( |
1708 | info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]); | 1708 | info->attrs[NL80211_ATTR_WIPHY_FRAG_THRESHOLD]); |
1709 | if (frag_threshold < 256) { | 1709 | if (frag_threshold < 256) { |
1710 | result = -EINVAL; | 1710 | result = -EINVAL; |
1711 | goto bad_res; | 1711 | goto bad_res; |
1712 | } | 1712 | } |
1713 | if (frag_threshold != (u32) -1) { | 1713 | if (frag_threshold != (u32) -1) { |
1714 | /* | 1714 | /* |
1715 | * Fragments (apart from the last one) are required to | 1715 | * Fragments (apart from the last one) are required to |
1716 | * have even length. Make the fragmentation code | 1716 | * have even length. Make the fragmentation code |
1717 | * simpler by stripping LSB should someone try to use | 1717 | * simpler by stripping LSB should someone try to use |
1718 | * odd threshold value. | 1718 | * odd threshold value. |
1719 | */ | 1719 | */ |
1720 | frag_threshold &= ~0x1; | 1720 | frag_threshold &= ~0x1; |
1721 | } | 1721 | } |
1722 | changed |= WIPHY_PARAM_FRAG_THRESHOLD; | 1722 | changed |= WIPHY_PARAM_FRAG_THRESHOLD; |
1723 | } | 1723 | } |
1724 | 1724 | ||
1725 | if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) { | 1725 | if (info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]) { |
1726 | rts_threshold = nla_get_u32( | 1726 | rts_threshold = nla_get_u32( |
1727 | info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]); | 1727 | info->attrs[NL80211_ATTR_WIPHY_RTS_THRESHOLD]); |
1728 | changed |= WIPHY_PARAM_RTS_THRESHOLD; | 1728 | changed |= WIPHY_PARAM_RTS_THRESHOLD; |
1729 | } | 1729 | } |
1730 | 1730 | ||
1731 | if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { | 1731 | if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) { |
1732 | coverage_class = nla_get_u8( | 1732 | coverage_class = nla_get_u8( |
1733 | info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); | 1733 | info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]); |
1734 | changed |= WIPHY_PARAM_COVERAGE_CLASS; | 1734 | changed |= WIPHY_PARAM_COVERAGE_CLASS; |
1735 | } | 1735 | } |
1736 | 1736 | ||
1737 | if (changed) { | 1737 | if (changed) { |
1738 | u8 old_retry_short, old_retry_long; | 1738 | u8 old_retry_short, old_retry_long; |
1739 | u32 old_frag_threshold, old_rts_threshold; | 1739 | u32 old_frag_threshold, old_rts_threshold; |
1740 | u8 old_coverage_class; | 1740 | u8 old_coverage_class; |
1741 | 1741 | ||
1742 | if (!rdev->ops->set_wiphy_params) { | 1742 | if (!rdev->ops->set_wiphy_params) { |
1743 | result = -EOPNOTSUPP; | 1743 | result = -EOPNOTSUPP; |
1744 | goto bad_res; | 1744 | goto bad_res; |
1745 | } | 1745 | } |
1746 | 1746 | ||
1747 | old_retry_short = rdev->wiphy.retry_short; | 1747 | old_retry_short = rdev->wiphy.retry_short; |
1748 | old_retry_long = rdev->wiphy.retry_long; | 1748 | old_retry_long = rdev->wiphy.retry_long; |
1749 | old_frag_threshold = rdev->wiphy.frag_threshold; | 1749 | old_frag_threshold = rdev->wiphy.frag_threshold; |
1750 | old_rts_threshold = rdev->wiphy.rts_threshold; | 1750 | old_rts_threshold = rdev->wiphy.rts_threshold; |
1751 | old_coverage_class = rdev->wiphy.coverage_class; | 1751 | old_coverage_class = rdev->wiphy.coverage_class; |
1752 | 1752 | ||
1753 | if (changed & WIPHY_PARAM_RETRY_SHORT) | 1753 | if (changed & WIPHY_PARAM_RETRY_SHORT) |
1754 | rdev->wiphy.retry_short = retry_short; | 1754 | rdev->wiphy.retry_short = retry_short; |
1755 | if (changed & WIPHY_PARAM_RETRY_LONG) | 1755 | if (changed & WIPHY_PARAM_RETRY_LONG) |
1756 | rdev->wiphy.retry_long = retry_long; | 1756 | rdev->wiphy.retry_long = retry_long; |
1757 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) | 1757 | if (changed & WIPHY_PARAM_FRAG_THRESHOLD) |
1758 | rdev->wiphy.frag_threshold = frag_threshold; | 1758 | rdev->wiphy.frag_threshold = frag_threshold; |
1759 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) | 1759 | if (changed & WIPHY_PARAM_RTS_THRESHOLD) |
1760 | rdev->wiphy.rts_threshold = rts_threshold; | 1760 | rdev->wiphy.rts_threshold = rts_threshold; |
1761 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) | 1761 | if (changed & WIPHY_PARAM_COVERAGE_CLASS) |
1762 | rdev->wiphy.coverage_class = coverage_class; | 1762 | rdev->wiphy.coverage_class = coverage_class; |
1763 | 1763 | ||
1764 | result = rdev_set_wiphy_params(rdev, changed); | 1764 | result = rdev_set_wiphy_params(rdev, changed); |
1765 | if (result) { | 1765 | if (result) { |
1766 | rdev->wiphy.retry_short = old_retry_short; | 1766 | rdev->wiphy.retry_short = old_retry_short; |
1767 | rdev->wiphy.retry_long = old_retry_long; | 1767 | rdev->wiphy.retry_long = old_retry_long; |
1768 | rdev->wiphy.frag_threshold = old_frag_threshold; | 1768 | rdev->wiphy.frag_threshold = old_frag_threshold; |
1769 | rdev->wiphy.rts_threshold = old_rts_threshold; | 1769 | rdev->wiphy.rts_threshold = old_rts_threshold; |
1770 | rdev->wiphy.coverage_class = old_coverage_class; | 1770 | rdev->wiphy.coverage_class = old_coverage_class; |
1771 | } | 1771 | } |
1772 | } | 1772 | } |
1773 | 1773 | ||
1774 | bad_res: | 1774 | bad_res: |
1775 | mutex_unlock(&rdev->mtx); | 1775 | mutex_unlock(&rdev->mtx); |
1776 | if (netdev) | 1776 | if (netdev) |
1777 | dev_put(netdev); | 1777 | dev_put(netdev); |
1778 | return result; | 1778 | return result; |
1779 | } | 1779 | } |
1780 | 1780 | ||
1781 | static inline u64 wdev_id(struct wireless_dev *wdev) | 1781 | static inline u64 wdev_id(struct wireless_dev *wdev) |
1782 | { | 1782 | { |
1783 | return (u64)wdev->identifier | | 1783 | return (u64)wdev->identifier | |
1784 | ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); | 1784 | ((u64)wiphy_to_dev(wdev->wiphy)->wiphy_idx << 32); |
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | static int nl80211_send_chandef(struct sk_buff *msg, | 1787 | static int nl80211_send_chandef(struct sk_buff *msg, |
1788 | struct cfg80211_chan_def *chandef) | 1788 | struct cfg80211_chan_def *chandef) |
1789 | { | 1789 | { |
1790 | WARN_ON(!cfg80211_chandef_valid(chandef)); | 1790 | WARN_ON(!cfg80211_chandef_valid(chandef)); |
1791 | 1791 | ||
1792 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, | 1792 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, |
1793 | chandef->chan->center_freq)) | 1793 | chandef->chan->center_freq)) |
1794 | return -ENOBUFS; | 1794 | return -ENOBUFS; |
1795 | switch (chandef->width) { | 1795 | switch (chandef->width) { |
1796 | case NL80211_CHAN_WIDTH_20_NOHT: | 1796 | case NL80211_CHAN_WIDTH_20_NOHT: |
1797 | case NL80211_CHAN_WIDTH_20: | 1797 | case NL80211_CHAN_WIDTH_20: |
1798 | case NL80211_CHAN_WIDTH_40: | 1798 | case NL80211_CHAN_WIDTH_40: |
1799 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, | 1799 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, |
1800 | cfg80211_get_chandef_type(chandef))) | 1800 | cfg80211_get_chandef_type(chandef))) |
1801 | return -ENOBUFS; | 1801 | return -ENOBUFS; |
1802 | break; | 1802 | break; |
1803 | default: | 1803 | default: |
1804 | break; | 1804 | break; |
1805 | } | 1805 | } |
1806 | if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width)) | 1806 | if (nla_put_u32(msg, NL80211_ATTR_CHANNEL_WIDTH, chandef->width)) |
1807 | return -ENOBUFS; | 1807 | return -ENOBUFS; |
1808 | if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1)) | 1808 | if (nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ1, chandef->center_freq1)) |
1809 | return -ENOBUFS; | 1809 | return -ENOBUFS; |
1810 | if (chandef->center_freq2 && | 1810 | if (chandef->center_freq2 && |
1811 | nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2)) | 1811 | nla_put_u32(msg, NL80211_ATTR_CENTER_FREQ2, chandef->center_freq2)) |
1812 | return -ENOBUFS; | 1812 | return -ENOBUFS; |
1813 | return 0; | 1813 | return 0; |
1814 | } | 1814 | } |
1815 | 1815 | ||
1816 | static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, | 1816 | static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flags, |
1817 | struct cfg80211_registered_device *rdev, | 1817 | struct cfg80211_registered_device *rdev, |
1818 | struct wireless_dev *wdev) | 1818 | struct wireless_dev *wdev) |
1819 | { | 1819 | { |
1820 | struct net_device *dev = wdev->netdev; | 1820 | struct net_device *dev = wdev->netdev; |
1821 | void *hdr; | 1821 | void *hdr; |
1822 | 1822 | ||
1823 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_INTERFACE); | 1823 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_INTERFACE); |
1824 | if (!hdr) | 1824 | if (!hdr) |
1825 | return -1; | 1825 | return -1; |
1826 | 1826 | ||
1827 | if (dev && | 1827 | if (dev && |
1828 | (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 1828 | (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
1829 | nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name))) | 1829 | nla_put_string(msg, NL80211_ATTR_IFNAME, dev->name))) |
1830 | goto nla_put_failure; | 1830 | goto nla_put_failure; |
1831 | 1831 | ||
1832 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 1832 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
1833 | nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) || | 1833 | nla_put_u32(msg, NL80211_ATTR_IFTYPE, wdev->iftype) || |
1834 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || | 1834 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || |
1835 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) || | 1835 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, wdev_address(wdev)) || |
1836 | nla_put_u32(msg, NL80211_ATTR_GENERATION, | 1836 | nla_put_u32(msg, NL80211_ATTR_GENERATION, |
1837 | rdev->devlist_generation ^ | 1837 | rdev->devlist_generation ^ |
1838 | (cfg80211_rdev_list_generation << 2))) | 1838 | (cfg80211_rdev_list_generation << 2))) |
1839 | goto nla_put_failure; | 1839 | goto nla_put_failure; |
1840 | 1840 | ||
1841 | if (rdev->ops->get_channel) { | 1841 | if (rdev->ops->get_channel) { |
1842 | int ret; | 1842 | int ret; |
1843 | struct cfg80211_chan_def chandef; | 1843 | struct cfg80211_chan_def chandef; |
1844 | 1844 | ||
1845 | ret = rdev_get_channel(rdev, wdev, &chandef); | 1845 | ret = rdev_get_channel(rdev, wdev, &chandef); |
1846 | if (ret == 0) { | 1846 | if (ret == 0) { |
1847 | if (nl80211_send_chandef(msg, &chandef)) | 1847 | if (nl80211_send_chandef(msg, &chandef)) |
1848 | goto nla_put_failure; | 1848 | goto nla_put_failure; |
1849 | } | 1849 | } |
1850 | } | 1850 | } |
1851 | 1851 | ||
1852 | if (wdev->ssid_len) { | 1852 | if (wdev->ssid_len) { |
1853 | if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) | 1853 | if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) |
1854 | goto nla_put_failure; | 1854 | goto nla_put_failure; |
1855 | } | 1855 | } |
1856 | 1856 | ||
1857 | return genlmsg_end(msg, hdr); | 1857 | return genlmsg_end(msg, hdr); |
1858 | 1858 | ||
1859 | nla_put_failure: | 1859 | nla_put_failure: |
1860 | genlmsg_cancel(msg, hdr); | 1860 | genlmsg_cancel(msg, hdr); |
1861 | return -EMSGSIZE; | 1861 | return -EMSGSIZE; |
1862 | } | 1862 | } |
1863 | 1863 | ||
1864 | static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb) | 1864 | static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *cb) |
1865 | { | 1865 | { |
1866 | int wp_idx = 0; | 1866 | int wp_idx = 0; |
1867 | int if_idx = 0; | 1867 | int if_idx = 0; |
1868 | int wp_start = cb->args[0]; | 1868 | int wp_start = cb->args[0]; |
1869 | int if_start = cb->args[1]; | 1869 | int if_start = cb->args[1]; |
1870 | struct cfg80211_registered_device *rdev; | 1870 | struct cfg80211_registered_device *rdev; |
1871 | struct wireless_dev *wdev; | 1871 | struct wireless_dev *wdev; |
1872 | 1872 | ||
1873 | mutex_lock(&cfg80211_mutex); | 1873 | mutex_lock(&cfg80211_mutex); |
1874 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { | 1874 | list_for_each_entry(rdev, &cfg80211_rdev_list, list) { |
1875 | if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) | 1875 | if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) |
1876 | continue; | 1876 | continue; |
1877 | if (wp_idx < wp_start) { | 1877 | if (wp_idx < wp_start) { |
1878 | wp_idx++; | 1878 | wp_idx++; |
1879 | continue; | 1879 | continue; |
1880 | } | 1880 | } |
1881 | if_idx = 0; | 1881 | if_idx = 0; |
1882 | 1882 | ||
1883 | mutex_lock(&rdev->devlist_mtx); | 1883 | mutex_lock(&rdev->devlist_mtx); |
1884 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | 1884 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
1885 | if (if_idx < if_start) { | 1885 | if (if_idx < if_start) { |
1886 | if_idx++; | 1886 | if_idx++; |
1887 | continue; | 1887 | continue; |
1888 | } | 1888 | } |
1889 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, | 1889 | if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, |
1890 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1890 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1891 | rdev, wdev) < 0) { | 1891 | rdev, wdev) < 0) { |
1892 | mutex_unlock(&rdev->devlist_mtx); | 1892 | mutex_unlock(&rdev->devlist_mtx); |
1893 | goto out; | 1893 | goto out; |
1894 | } | 1894 | } |
1895 | if_idx++; | 1895 | if_idx++; |
1896 | } | 1896 | } |
1897 | mutex_unlock(&rdev->devlist_mtx); | 1897 | mutex_unlock(&rdev->devlist_mtx); |
1898 | 1898 | ||
1899 | wp_idx++; | 1899 | wp_idx++; |
1900 | } | 1900 | } |
1901 | out: | 1901 | out: |
1902 | mutex_unlock(&cfg80211_mutex); | 1902 | mutex_unlock(&cfg80211_mutex); |
1903 | 1903 | ||
1904 | cb->args[0] = wp_idx; | 1904 | cb->args[0] = wp_idx; |
1905 | cb->args[1] = if_idx; | 1905 | cb->args[1] = if_idx; |
1906 | 1906 | ||
1907 | return skb->len; | 1907 | return skb->len; |
1908 | } | 1908 | } |
1909 | 1909 | ||
1910 | static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) | 1910 | static int nl80211_get_interface(struct sk_buff *skb, struct genl_info *info) |
1911 | { | 1911 | { |
1912 | struct sk_buff *msg; | 1912 | struct sk_buff *msg; |
1913 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1913 | struct cfg80211_registered_device *dev = info->user_ptr[0]; |
1914 | struct wireless_dev *wdev = info->user_ptr[1]; | 1914 | struct wireless_dev *wdev = info->user_ptr[1]; |
1915 | 1915 | ||
1916 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1916 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
1917 | if (!msg) | 1917 | if (!msg) |
1918 | return -ENOMEM; | 1918 | return -ENOMEM; |
1919 | 1919 | ||
1920 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, | 1920 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, |
1921 | dev, wdev) < 0) { | 1921 | dev, wdev) < 0) { |
1922 | nlmsg_free(msg); | 1922 | nlmsg_free(msg); |
1923 | return -ENOBUFS; | 1923 | return -ENOBUFS; |
1924 | } | 1924 | } |
1925 | 1925 | ||
1926 | return genlmsg_reply(msg, info); | 1926 | return genlmsg_reply(msg, info); |
1927 | } | 1927 | } |
1928 | 1928 | ||
1929 | static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { | 1929 | static const struct nla_policy mntr_flags_policy[NL80211_MNTR_FLAG_MAX + 1] = { |
1930 | [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG }, | 1930 | [NL80211_MNTR_FLAG_FCSFAIL] = { .type = NLA_FLAG }, |
1931 | [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG }, | 1931 | [NL80211_MNTR_FLAG_PLCPFAIL] = { .type = NLA_FLAG }, |
1932 | [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG }, | 1932 | [NL80211_MNTR_FLAG_CONTROL] = { .type = NLA_FLAG }, |
1933 | [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, | 1933 | [NL80211_MNTR_FLAG_OTHER_BSS] = { .type = NLA_FLAG }, |
1934 | [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, | 1934 | [NL80211_MNTR_FLAG_COOK_FRAMES] = { .type = NLA_FLAG }, |
1935 | }; | 1935 | }; |
1936 | 1936 | ||
1937 | static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) | 1937 | static int parse_monitor_flags(struct nlattr *nla, u32 *mntrflags) |
1938 | { | 1938 | { |
1939 | struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1]; | 1939 | struct nlattr *flags[NL80211_MNTR_FLAG_MAX + 1]; |
1940 | int flag; | 1940 | int flag; |
1941 | 1941 | ||
1942 | *mntrflags = 0; | 1942 | *mntrflags = 0; |
1943 | 1943 | ||
1944 | if (!nla) | 1944 | if (!nla) |
1945 | return -EINVAL; | 1945 | return -EINVAL; |
1946 | 1946 | ||
1947 | if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX, | 1947 | if (nla_parse_nested(flags, NL80211_MNTR_FLAG_MAX, |
1948 | nla, mntr_flags_policy)) | 1948 | nla, mntr_flags_policy)) |
1949 | return -EINVAL; | 1949 | return -EINVAL; |
1950 | 1950 | ||
1951 | for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++) | 1951 | for (flag = 1; flag <= NL80211_MNTR_FLAG_MAX; flag++) |
1952 | if (flags[flag]) | 1952 | if (flags[flag]) |
1953 | *mntrflags |= (1<<flag); | 1953 | *mntrflags |= (1<<flag); |
1954 | 1954 | ||
1955 | return 0; | 1955 | return 0; |
1956 | } | 1956 | } |
1957 | 1957 | ||
1958 | static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, | 1958 | static int nl80211_valid_4addr(struct cfg80211_registered_device *rdev, |
1959 | struct net_device *netdev, u8 use_4addr, | 1959 | struct net_device *netdev, u8 use_4addr, |
1960 | enum nl80211_iftype iftype) | 1960 | enum nl80211_iftype iftype) |
1961 | { | 1961 | { |
1962 | if (!use_4addr) { | 1962 | if (!use_4addr) { |
1963 | if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT)) | 1963 | if (netdev && (netdev->priv_flags & IFF_BRIDGE_PORT)) |
1964 | return -EBUSY; | 1964 | return -EBUSY; |
1965 | return 0; | 1965 | return 0; |
1966 | } | 1966 | } |
1967 | 1967 | ||
1968 | switch (iftype) { | 1968 | switch (iftype) { |
1969 | case NL80211_IFTYPE_AP_VLAN: | 1969 | case NL80211_IFTYPE_AP_VLAN: |
1970 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP) | 1970 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP) |
1971 | return 0; | 1971 | return 0; |
1972 | break; | 1972 | break; |
1973 | case NL80211_IFTYPE_STATION: | 1973 | case NL80211_IFTYPE_STATION: |
1974 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION) | 1974 | if (rdev->wiphy.flags & WIPHY_FLAG_4ADDR_STATION) |
1975 | return 0; | 1975 | return 0; |
1976 | break; | 1976 | break; |
1977 | default: | 1977 | default: |
1978 | break; | 1978 | break; |
1979 | } | 1979 | } |
1980 | 1980 | ||
1981 | return -EOPNOTSUPP; | 1981 | return -EOPNOTSUPP; |
1982 | } | 1982 | } |
1983 | 1983 | ||
1984 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) | 1984 | static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info) |
1985 | { | 1985 | { |
1986 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 1986 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
1987 | struct vif_params params; | 1987 | struct vif_params params; |
1988 | int err; | 1988 | int err; |
1989 | enum nl80211_iftype otype, ntype; | 1989 | enum nl80211_iftype otype, ntype; |
1990 | struct net_device *dev = info->user_ptr[1]; | 1990 | struct net_device *dev = info->user_ptr[1]; |
1991 | u32 _flags, *flags = NULL; | 1991 | u32 _flags, *flags = NULL; |
1992 | bool change = false; | 1992 | bool change = false; |
1993 | 1993 | ||
1994 | memset(¶ms, 0, sizeof(params)); | 1994 | memset(¶ms, 0, sizeof(params)); |
1995 | 1995 | ||
1996 | otype = ntype = dev->ieee80211_ptr->iftype; | 1996 | otype = ntype = dev->ieee80211_ptr->iftype; |
1997 | 1997 | ||
1998 | if (info->attrs[NL80211_ATTR_IFTYPE]) { | 1998 | if (info->attrs[NL80211_ATTR_IFTYPE]) { |
1999 | ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); | 1999 | ntype = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); |
2000 | if (otype != ntype) | 2000 | if (otype != ntype) |
2001 | change = true; | 2001 | change = true; |
2002 | if (ntype > NL80211_IFTYPE_MAX) | 2002 | if (ntype > NL80211_IFTYPE_MAX) |
2003 | return -EINVAL; | 2003 | return -EINVAL; |
2004 | } | 2004 | } |
2005 | 2005 | ||
2006 | if (info->attrs[NL80211_ATTR_MESH_ID]) { | 2006 | if (info->attrs[NL80211_ATTR_MESH_ID]) { |
2007 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 2007 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
2008 | 2008 | ||
2009 | if (ntype != NL80211_IFTYPE_MESH_POINT) | 2009 | if (ntype != NL80211_IFTYPE_MESH_POINT) |
2010 | return -EINVAL; | 2010 | return -EINVAL; |
2011 | if (netif_running(dev)) | 2011 | if (netif_running(dev)) |
2012 | return -EBUSY; | 2012 | return -EBUSY; |
2013 | 2013 | ||
2014 | wdev_lock(wdev); | 2014 | wdev_lock(wdev); |
2015 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != | 2015 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != |
2016 | IEEE80211_MAX_MESH_ID_LEN); | 2016 | IEEE80211_MAX_MESH_ID_LEN); |
2017 | wdev->mesh_id_up_len = | 2017 | wdev->mesh_id_up_len = |
2018 | nla_len(info->attrs[NL80211_ATTR_MESH_ID]); | 2018 | nla_len(info->attrs[NL80211_ATTR_MESH_ID]); |
2019 | memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), | 2019 | memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), |
2020 | wdev->mesh_id_up_len); | 2020 | wdev->mesh_id_up_len); |
2021 | wdev_unlock(wdev); | 2021 | wdev_unlock(wdev); |
2022 | } | 2022 | } |
2023 | 2023 | ||
2024 | if (info->attrs[NL80211_ATTR_4ADDR]) { | 2024 | if (info->attrs[NL80211_ATTR_4ADDR]) { |
2025 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); | 2025 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); |
2026 | change = true; | 2026 | change = true; |
2027 | err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype); | 2027 | err = nl80211_valid_4addr(rdev, dev, params.use_4addr, ntype); |
2028 | if (err) | 2028 | if (err) |
2029 | return err; | 2029 | return err; |
2030 | } else { | 2030 | } else { |
2031 | params.use_4addr = -1; | 2031 | params.use_4addr = -1; |
2032 | } | 2032 | } |
2033 | 2033 | ||
2034 | if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { | 2034 | if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) { |
2035 | if (ntype != NL80211_IFTYPE_MONITOR) | 2035 | if (ntype != NL80211_IFTYPE_MONITOR) |
2036 | return -EINVAL; | 2036 | return -EINVAL; |
2037 | err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS], | 2037 | err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS], |
2038 | &_flags); | 2038 | &_flags); |
2039 | if (err) | 2039 | if (err) |
2040 | return err; | 2040 | return err; |
2041 | 2041 | ||
2042 | flags = &_flags; | 2042 | flags = &_flags; |
2043 | change = true; | 2043 | change = true; |
2044 | } | 2044 | } |
2045 | 2045 | ||
2046 | if (change) | 2046 | if (change) |
2047 | err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms); | 2047 | err = cfg80211_change_iface(rdev, dev, ntype, flags, ¶ms); |
2048 | else | 2048 | else |
2049 | err = 0; | 2049 | err = 0; |
2050 | 2050 | ||
2051 | if (!err && params.use_4addr != -1) | 2051 | if (!err && params.use_4addr != -1) |
2052 | dev->ieee80211_ptr->use_4addr = params.use_4addr; | 2052 | dev->ieee80211_ptr->use_4addr = params.use_4addr; |
2053 | 2053 | ||
2054 | return err; | 2054 | return err; |
2055 | } | 2055 | } |
2056 | 2056 | ||
2057 | static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | 2057 | static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) |
2058 | { | 2058 | { |
2059 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2059 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2060 | struct vif_params params; | 2060 | struct vif_params params; |
2061 | struct wireless_dev *wdev; | 2061 | struct wireless_dev *wdev; |
2062 | struct sk_buff *msg; | 2062 | struct sk_buff *msg; |
2063 | int err; | 2063 | int err; |
2064 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; | 2064 | enum nl80211_iftype type = NL80211_IFTYPE_UNSPECIFIED; |
2065 | u32 flags; | 2065 | u32 flags; |
2066 | 2066 | ||
2067 | memset(¶ms, 0, sizeof(params)); | 2067 | memset(¶ms, 0, sizeof(params)); |
2068 | 2068 | ||
2069 | if (!info->attrs[NL80211_ATTR_IFNAME]) | 2069 | if (!info->attrs[NL80211_ATTR_IFNAME]) |
2070 | return -EINVAL; | 2070 | return -EINVAL; |
2071 | 2071 | ||
2072 | if (info->attrs[NL80211_ATTR_IFTYPE]) { | 2072 | if (info->attrs[NL80211_ATTR_IFTYPE]) { |
2073 | type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); | 2073 | type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]); |
2074 | if (type > NL80211_IFTYPE_MAX) | 2074 | if (type > NL80211_IFTYPE_MAX) |
2075 | return -EINVAL; | 2075 | return -EINVAL; |
2076 | } | 2076 | } |
2077 | 2077 | ||
2078 | if (!rdev->ops->add_virtual_intf || | 2078 | if (!rdev->ops->add_virtual_intf || |
2079 | !(rdev->wiphy.interface_modes & (1 << type))) | 2079 | !(rdev->wiphy.interface_modes & (1 << type))) |
2080 | return -EOPNOTSUPP; | 2080 | return -EOPNOTSUPP; |
2081 | 2081 | ||
2082 | if (info->attrs[NL80211_ATTR_4ADDR]) { | 2082 | if (info->attrs[NL80211_ATTR_4ADDR]) { |
2083 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); | 2083 | params.use_4addr = !!nla_get_u8(info->attrs[NL80211_ATTR_4ADDR]); |
2084 | err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); | 2084 | err = nl80211_valid_4addr(rdev, NULL, params.use_4addr, type); |
2085 | if (err) | 2085 | if (err) |
2086 | return err; | 2086 | return err; |
2087 | } | 2087 | } |
2088 | 2088 | ||
2089 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 2089 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
2090 | if (!msg) | 2090 | if (!msg) |
2091 | return -ENOMEM; | 2091 | return -ENOMEM; |
2092 | 2092 | ||
2093 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 2093 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
2094 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2094 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
2095 | &flags); | 2095 | &flags); |
2096 | wdev = rdev_add_virtual_intf(rdev, | 2096 | wdev = rdev_add_virtual_intf(rdev, |
2097 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2097 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
2098 | type, err ? NULL : &flags, ¶ms); | 2098 | type, err ? NULL : &flags, ¶ms); |
2099 | if (IS_ERR(wdev)) { | 2099 | if (IS_ERR(wdev)) { |
2100 | nlmsg_free(msg); | 2100 | nlmsg_free(msg); |
2101 | return PTR_ERR(wdev); | 2101 | return PTR_ERR(wdev); |
2102 | } | 2102 | } |
2103 | 2103 | ||
2104 | switch (type) { | 2104 | switch (type) { |
2105 | case NL80211_IFTYPE_MESH_POINT: | 2105 | case NL80211_IFTYPE_MESH_POINT: |
2106 | if (!info->attrs[NL80211_ATTR_MESH_ID]) | 2106 | if (!info->attrs[NL80211_ATTR_MESH_ID]) |
2107 | break; | 2107 | break; |
2108 | wdev_lock(wdev); | 2108 | wdev_lock(wdev); |
2109 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != | 2109 | BUILD_BUG_ON(IEEE80211_MAX_SSID_LEN != |
2110 | IEEE80211_MAX_MESH_ID_LEN); | 2110 | IEEE80211_MAX_MESH_ID_LEN); |
2111 | wdev->mesh_id_up_len = | 2111 | wdev->mesh_id_up_len = |
2112 | nla_len(info->attrs[NL80211_ATTR_MESH_ID]); | 2112 | nla_len(info->attrs[NL80211_ATTR_MESH_ID]); |
2113 | memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), | 2113 | memcpy(wdev->ssid, nla_data(info->attrs[NL80211_ATTR_MESH_ID]), |
2114 | wdev->mesh_id_up_len); | 2114 | wdev->mesh_id_up_len); |
2115 | wdev_unlock(wdev); | 2115 | wdev_unlock(wdev); |
2116 | break; | 2116 | break; |
2117 | case NL80211_IFTYPE_P2P_DEVICE: | 2117 | case NL80211_IFTYPE_P2P_DEVICE: |
2118 | /* | 2118 | /* |
2119 | * P2P Device doesn't have a netdev, so doesn't go | 2119 | * P2P Device doesn't have a netdev, so doesn't go |
2120 | * through the netdev notifier and must be added here | 2120 | * through the netdev notifier and must be added here |
2121 | */ | 2121 | */ |
2122 | mutex_init(&wdev->mtx); | 2122 | mutex_init(&wdev->mtx); |
2123 | INIT_LIST_HEAD(&wdev->event_list); | 2123 | INIT_LIST_HEAD(&wdev->event_list); |
2124 | spin_lock_init(&wdev->event_lock); | 2124 | spin_lock_init(&wdev->event_lock); |
2125 | INIT_LIST_HEAD(&wdev->mgmt_registrations); | 2125 | INIT_LIST_HEAD(&wdev->mgmt_registrations); |
2126 | spin_lock_init(&wdev->mgmt_registrations_lock); | 2126 | spin_lock_init(&wdev->mgmt_registrations_lock); |
2127 | 2127 | ||
2128 | mutex_lock(&rdev->devlist_mtx); | 2128 | mutex_lock(&rdev->devlist_mtx); |
2129 | wdev->identifier = ++rdev->wdev_id; | 2129 | wdev->identifier = ++rdev->wdev_id; |
2130 | list_add_rcu(&wdev->list, &rdev->wdev_list); | 2130 | list_add_rcu(&wdev->list, &rdev->wdev_list); |
2131 | rdev->devlist_generation++; | 2131 | rdev->devlist_generation++; |
2132 | mutex_unlock(&rdev->devlist_mtx); | 2132 | mutex_unlock(&rdev->devlist_mtx); |
2133 | break; | 2133 | break; |
2134 | default: | 2134 | default: |
2135 | break; | 2135 | break; |
2136 | } | 2136 | } |
2137 | 2137 | ||
2138 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, | 2138 | if (nl80211_send_iface(msg, info->snd_portid, info->snd_seq, 0, |
2139 | rdev, wdev) < 0) { | 2139 | rdev, wdev) < 0) { |
2140 | nlmsg_free(msg); | 2140 | nlmsg_free(msg); |
2141 | return -ENOBUFS; | 2141 | return -ENOBUFS; |
2142 | } | 2142 | } |
2143 | 2143 | ||
2144 | return genlmsg_reply(msg, info); | 2144 | return genlmsg_reply(msg, info); |
2145 | } | 2145 | } |
2146 | 2146 | ||
2147 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) | 2147 | static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info) |
2148 | { | 2148 | { |
2149 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2149 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2150 | struct wireless_dev *wdev = info->user_ptr[1]; | 2150 | struct wireless_dev *wdev = info->user_ptr[1]; |
2151 | 2151 | ||
2152 | if (!rdev->ops->del_virtual_intf) | 2152 | if (!rdev->ops->del_virtual_intf) |
2153 | return -EOPNOTSUPP; | 2153 | return -EOPNOTSUPP; |
2154 | 2154 | ||
2155 | /* | 2155 | /* |
2156 | * If we remove a wireless device without a netdev then clear | 2156 | * If we remove a wireless device without a netdev then clear |
2157 | * user_ptr[1] so that nl80211_post_doit won't dereference it | 2157 | * user_ptr[1] so that nl80211_post_doit won't dereference it |
2158 | * to check if it needs to do dev_put(). Otherwise it crashes | 2158 | * to check if it needs to do dev_put(). Otherwise it crashes |
2159 | * since the wdev has been freed, unlike with a netdev where | 2159 | * since the wdev has been freed, unlike with a netdev where |
2160 | * we need the dev_put() for the netdev to really be freed. | 2160 | * we need the dev_put() for the netdev to really be freed. |
2161 | */ | 2161 | */ |
2162 | if (!wdev->netdev) | 2162 | if (!wdev->netdev) |
2163 | info->user_ptr[1] = NULL; | 2163 | info->user_ptr[1] = NULL; |
2164 | 2164 | ||
2165 | return rdev_del_virtual_intf(rdev, wdev); | 2165 | return rdev_del_virtual_intf(rdev, wdev); |
2166 | } | 2166 | } |
2167 | 2167 | ||
2168 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) | 2168 | static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info) |
2169 | { | 2169 | { |
2170 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2170 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2171 | struct net_device *dev = info->user_ptr[1]; | 2171 | struct net_device *dev = info->user_ptr[1]; |
2172 | u16 noack_map; | 2172 | u16 noack_map; |
2173 | 2173 | ||
2174 | if (!info->attrs[NL80211_ATTR_NOACK_MAP]) | 2174 | if (!info->attrs[NL80211_ATTR_NOACK_MAP]) |
2175 | return -EINVAL; | 2175 | return -EINVAL; |
2176 | 2176 | ||
2177 | if (!rdev->ops->set_noack_map) | 2177 | if (!rdev->ops->set_noack_map) |
2178 | return -EOPNOTSUPP; | 2178 | return -EOPNOTSUPP; |
2179 | 2179 | ||
2180 | noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]); | 2180 | noack_map = nla_get_u16(info->attrs[NL80211_ATTR_NOACK_MAP]); |
2181 | 2181 | ||
2182 | return rdev_set_noack_map(rdev, dev, noack_map); | 2182 | return rdev_set_noack_map(rdev, dev, noack_map); |
2183 | } | 2183 | } |
2184 | 2184 | ||
2185 | struct get_key_cookie { | 2185 | struct get_key_cookie { |
2186 | struct sk_buff *msg; | 2186 | struct sk_buff *msg; |
2187 | int error; | 2187 | int error; |
2188 | int idx; | 2188 | int idx; |
2189 | }; | 2189 | }; |
2190 | 2190 | ||
2191 | static void get_key_callback(void *c, struct key_params *params) | 2191 | static void get_key_callback(void *c, struct key_params *params) |
2192 | { | 2192 | { |
2193 | struct nlattr *key; | 2193 | struct nlattr *key; |
2194 | struct get_key_cookie *cookie = c; | 2194 | struct get_key_cookie *cookie = c; |
2195 | 2195 | ||
2196 | if ((params->key && | 2196 | if ((params->key && |
2197 | nla_put(cookie->msg, NL80211_ATTR_KEY_DATA, | 2197 | nla_put(cookie->msg, NL80211_ATTR_KEY_DATA, |
2198 | params->key_len, params->key)) || | 2198 | params->key_len, params->key)) || |
2199 | (params->seq && | 2199 | (params->seq && |
2200 | nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ, | 2200 | nla_put(cookie->msg, NL80211_ATTR_KEY_SEQ, |
2201 | params->seq_len, params->seq)) || | 2201 | params->seq_len, params->seq)) || |
2202 | (params->cipher && | 2202 | (params->cipher && |
2203 | nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER, | 2203 | nla_put_u32(cookie->msg, NL80211_ATTR_KEY_CIPHER, |
2204 | params->cipher))) | 2204 | params->cipher))) |
2205 | goto nla_put_failure; | 2205 | goto nla_put_failure; |
2206 | 2206 | ||
2207 | key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY); | 2207 | key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY); |
2208 | if (!key) | 2208 | if (!key) |
2209 | goto nla_put_failure; | 2209 | goto nla_put_failure; |
2210 | 2210 | ||
2211 | if ((params->key && | 2211 | if ((params->key && |
2212 | nla_put(cookie->msg, NL80211_KEY_DATA, | 2212 | nla_put(cookie->msg, NL80211_KEY_DATA, |
2213 | params->key_len, params->key)) || | 2213 | params->key_len, params->key)) || |
2214 | (params->seq && | 2214 | (params->seq && |
2215 | nla_put(cookie->msg, NL80211_KEY_SEQ, | 2215 | nla_put(cookie->msg, NL80211_KEY_SEQ, |
2216 | params->seq_len, params->seq)) || | 2216 | params->seq_len, params->seq)) || |
2217 | (params->cipher && | 2217 | (params->cipher && |
2218 | nla_put_u32(cookie->msg, NL80211_KEY_CIPHER, | 2218 | nla_put_u32(cookie->msg, NL80211_KEY_CIPHER, |
2219 | params->cipher))) | 2219 | params->cipher))) |
2220 | goto nla_put_failure; | 2220 | goto nla_put_failure; |
2221 | 2221 | ||
2222 | if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx)) | 2222 | if (nla_put_u8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx)) |
2223 | goto nla_put_failure; | 2223 | goto nla_put_failure; |
2224 | 2224 | ||
2225 | nla_nest_end(cookie->msg, key); | 2225 | nla_nest_end(cookie->msg, key); |
2226 | 2226 | ||
2227 | return; | 2227 | return; |
2228 | nla_put_failure: | 2228 | nla_put_failure: |
2229 | cookie->error = 1; | 2229 | cookie->error = 1; |
2230 | } | 2230 | } |
2231 | 2231 | ||
2232 | static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) | 2232 | static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info) |
2233 | { | 2233 | { |
2234 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2234 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2235 | int err; | 2235 | int err; |
2236 | struct net_device *dev = info->user_ptr[1]; | 2236 | struct net_device *dev = info->user_ptr[1]; |
2237 | u8 key_idx = 0; | 2237 | u8 key_idx = 0; |
2238 | const u8 *mac_addr = NULL; | 2238 | const u8 *mac_addr = NULL; |
2239 | bool pairwise; | 2239 | bool pairwise; |
2240 | struct get_key_cookie cookie = { | 2240 | struct get_key_cookie cookie = { |
2241 | .error = 0, | 2241 | .error = 0, |
2242 | }; | 2242 | }; |
2243 | void *hdr; | 2243 | void *hdr; |
2244 | struct sk_buff *msg; | 2244 | struct sk_buff *msg; |
2245 | 2245 | ||
2246 | if (info->attrs[NL80211_ATTR_KEY_IDX]) | 2246 | if (info->attrs[NL80211_ATTR_KEY_IDX]) |
2247 | key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); | 2247 | key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); |
2248 | 2248 | ||
2249 | if (key_idx > 5) | 2249 | if (key_idx > 5) |
2250 | return -EINVAL; | 2250 | return -EINVAL; |
2251 | 2251 | ||
2252 | if (info->attrs[NL80211_ATTR_MAC]) | 2252 | if (info->attrs[NL80211_ATTR_MAC]) |
2253 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 2253 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
2254 | 2254 | ||
2255 | pairwise = !!mac_addr; | 2255 | pairwise = !!mac_addr; |
2256 | if (info->attrs[NL80211_ATTR_KEY_TYPE]) { | 2256 | if (info->attrs[NL80211_ATTR_KEY_TYPE]) { |
2257 | u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); | 2257 | u32 kt = nla_get_u32(info->attrs[NL80211_ATTR_KEY_TYPE]); |
2258 | if (kt >= NUM_NL80211_KEYTYPES) | 2258 | if (kt >= NUM_NL80211_KEYTYPES) |
2259 | return -EINVAL; | 2259 | return -EINVAL; |
2260 | if (kt != NL80211_KEYTYPE_GROUP && | 2260 | if (kt != NL80211_KEYTYPE_GROUP && |
2261 | kt != NL80211_KEYTYPE_PAIRWISE) | 2261 | kt != NL80211_KEYTYPE_PAIRWISE) |
2262 | return -EINVAL; | 2262 | return -EINVAL; |
2263 | pairwise = kt == NL80211_KEYTYPE_PAIRWISE; | 2263 | pairwise = kt == NL80211_KEYTYPE_PAIRWISE; |
2264 | } | 2264 | } |
2265 | 2265 | ||
2266 | if (!rdev->ops->get_key) | 2266 | if (!rdev->ops->get_key) |
2267 | return -EOPNOTSUPP; | 2267 | return -EOPNOTSUPP; |
2268 | 2268 | ||
2269 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 2269 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
2270 | if (!msg) | 2270 | if (!msg) |
2271 | return -ENOMEM; | 2271 | return -ENOMEM; |
2272 | 2272 | ||
2273 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 2273 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
2274 | NL80211_CMD_NEW_KEY); | 2274 | NL80211_CMD_NEW_KEY); |
2275 | if (IS_ERR(hdr)) | 2275 | if (IS_ERR(hdr)) |
2276 | return PTR_ERR(hdr); | 2276 | return PTR_ERR(hdr); |
2277 | 2277 | ||
2278 | cookie.msg = msg; | 2278 | cookie.msg = msg; |
2279 | cookie.idx = key_idx; | 2279 | cookie.idx = key_idx; |
2280 | 2280 | ||
2281 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 2281 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
2282 | nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx)) | 2282 | nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_idx)) |
2283 | goto nla_put_failure; | 2283 | goto nla_put_failure; |
2284 | if (mac_addr && | 2284 | if (mac_addr && |
2285 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) | 2285 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) |
2286 | goto nla_put_failure; | 2286 | goto nla_put_failure; |
2287 | 2287 | ||
2288 | if (pairwise && mac_addr && | 2288 | if (pairwise && mac_addr && |
2289 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | 2289 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) |
2290 | return -ENOENT; | 2290 | return -ENOENT; |
2291 | 2291 | ||
2292 | err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, | 2292 | err = rdev_get_key(rdev, dev, key_idx, pairwise, mac_addr, &cookie, |
2293 | get_key_callback); | 2293 | get_key_callback); |
2294 | 2294 | ||
2295 | if (err) | 2295 | if (err) |
2296 | goto free_msg; | 2296 | goto free_msg; |
2297 | 2297 | ||
2298 | if (cookie.error) | 2298 | if (cookie.error) |
2299 | goto nla_put_failure; | 2299 | goto nla_put_failure; |
2300 | 2300 | ||
2301 | genlmsg_end(msg, hdr); | 2301 | genlmsg_end(msg, hdr); |
2302 | return genlmsg_reply(msg, info); | 2302 | return genlmsg_reply(msg, info); |
2303 | 2303 | ||
2304 | nla_put_failure: | 2304 | nla_put_failure: |
2305 | err = -ENOBUFS; | 2305 | err = -ENOBUFS; |
2306 | free_msg: | 2306 | free_msg: |
2307 | nlmsg_free(msg); | 2307 | nlmsg_free(msg); |
2308 | return err; | 2308 | return err; |
2309 | } | 2309 | } |
2310 | 2310 | ||
2311 | static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) | 2311 | static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) |
2312 | { | 2312 | { |
2313 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2313 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2314 | struct key_parse key; | 2314 | struct key_parse key; |
2315 | int err; | 2315 | int err; |
2316 | struct net_device *dev = info->user_ptr[1]; | 2316 | struct net_device *dev = info->user_ptr[1]; |
2317 | 2317 | ||
2318 | err = nl80211_parse_key(info, &key); | 2318 | err = nl80211_parse_key(info, &key); |
2319 | if (err) | 2319 | if (err) |
2320 | return err; | 2320 | return err; |
2321 | 2321 | ||
2322 | if (key.idx < 0) | 2322 | if (key.idx < 0) |
2323 | return -EINVAL; | 2323 | return -EINVAL; |
2324 | 2324 | ||
2325 | /* only support setting default key */ | 2325 | /* only support setting default key */ |
2326 | if (!key.def && !key.defmgmt) | 2326 | if (!key.def && !key.defmgmt) |
2327 | return -EINVAL; | 2327 | return -EINVAL; |
2328 | 2328 | ||
2329 | wdev_lock(dev->ieee80211_ptr); | 2329 | wdev_lock(dev->ieee80211_ptr); |
2330 | 2330 | ||
2331 | if (key.def) { | 2331 | if (key.def) { |
2332 | if (!rdev->ops->set_default_key) { | 2332 | if (!rdev->ops->set_default_key) { |
2333 | err = -EOPNOTSUPP; | 2333 | err = -EOPNOTSUPP; |
2334 | goto out; | 2334 | goto out; |
2335 | } | 2335 | } |
2336 | 2336 | ||
2337 | err = nl80211_key_allowed(dev->ieee80211_ptr); | 2337 | err = nl80211_key_allowed(dev->ieee80211_ptr); |
2338 | if (err) | 2338 | if (err) |
2339 | goto out; | 2339 | goto out; |
2340 | 2340 | ||
2341 | err = rdev_set_default_key(rdev, dev, key.idx, | 2341 | err = rdev_set_default_key(rdev, dev, key.idx, |
2342 | key.def_uni, key.def_multi); | 2342 | key.def_uni, key.def_multi); |
2343 | 2343 | ||
2344 | if (err) | 2344 | if (err) |
2345 | goto out; | 2345 | goto out; |
2346 | 2346 | ||
2347 | #ifdef CONFIG_CFG80211_WEXT | 2347 | #ifdef CONFIG_CFG80211_WEXT |
2348 | dev->ieee80211_ptr->wext.default_key = key.idx; | 2348 | dev->ieee80211_ptr->wext.default_key = key.idx; |
2349 | #endif | 2349 | #endif |
2350 | } else { | 2350 | } else { |
2351 | if (key.def_uni || !key.def_multi) { | 2351 | if (key.def_uni || !key.def_multi) { |
2352 | err = -EINVAL; | 2352 | err = -EINVAL; |
2353 | goto out; | 2353 | goto out; |
2354 | } | 2354 | } |
2355 | 2355 | ||
2356 | if (!rdev->ops->set_default_mgmt_key) { | 2356 | if (!rdev->ops->set_default_mgmt_key) { |
2357 | err = -EOPNOTSUPP; | 2357 | err = -EOPNOTSUPP; |
2358 | goto out; | 2358 | goto out; |
2359 | } | 2359 | } |
2360 | 2360 | ||
2361 | err = nl80211_key_allowed(dev->ieee80211_ptr); | 2361 | err = nl80211_key_allowed(dev->ieee80211_ptr); |
2362 | if (err) | 2362 | if (err) |
2363 | goto out; | 2363 | goto out; |
2364 | 2364 | ||
2365 | err = rdev_set_default_mgmt_key(rdev, dev, key.idx); | 2365 | err = rdev_set_default_mgmt_key(rdev, dev, key.idx); |
2366 | if (err) | 2366 | if (err) |
2367 | goto out; | 2367 | goto out; |
2368 | 2368 | ||
2369 | #ifdef CONFIG_CFG80211_WEXT | 2369 | #ifdef CONFIG_CFG80211_WEXT |
2370 | dev->ieee80211_ptr->wext.default_mgmt_key = key.idx; | 2370 | dev->ieee80211_ptr->wext.default_mgmt_key = key.idx; |
2371 | #endif | 2371 | #endif |
2372 | } | 2372 | } |
2373 | 2373 | ||
2374 | out: | 2374 | out: |
2375 | wdev_unlock(dev->ieee80211_ptr); | 2375 | wdev_unlock(dev->ieee80211_ptr); |
2376 | 2376 | ||
2377 | return err; | 2377 | return err; |
2378 | } | 2378 | } |
2379 | 2379 | ||
2380 | static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) | 2380 | static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) |
2381 | { | 2381 | { |
2382 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2382 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2383 | int err; | 2383 | int err; |
2384 | struct net_device *dev = info->user_ptr[1]; | 2384 | struct net_device *dev = info->user_ptr[1]; |
2385 | struct key_parse key; | 2385 | struct key_parse key; |
2386 | const u8 *mac_addr = NULL; | 2386 | const u8 *mac_addr = NULL; |
2387 | 2387 | ||
2388 | err = nl80211_parse_key(info, &key); | 2388 | err = nl80211_parse_key(info, &key); |
2389 | if (err) | 2389 | if (err) |
2390 | return err; | 2390 | return err; |
2391 | 2391 | ||
2392 | if (!key.p.key) | 2392 | if (!key.p.key) |
2393 | return -EINVAL; | 2393 | return -EINVAL; |
2394 | 2394 | ||
2395 | if (info->attrs[NL80211_ATTR_MAC]) | 2395 | if (info->attrs[NL80211_ATTR_MAC]) |
2396 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 2396 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
2397 | 2397 | ||
2398 | if (key.type == -1) { | 2398 | if (key.type == -1) { |
2399 | if (mac_addr) | 2399 | if (mac_addr) |
2400 | key.type = NL80211_KEYTYPE_PAIRWISE; | 2400 | key.type = NL80211_KEYTYPE_PAIRWISE; |
2401 | else | 2401 | else |
2402 | key.type = NL80211_KEYTYPE_GROUP; | 2402 | key.type = NL80211_KEYTYPE_GROUP; |
2403 | } | 2403 | } |
2404 | 2404 | ||
2405 | /* for now */ | 2405 | /* for now */ |
2406 | if (key.type != NL80211_KEYTYPE_PAIRWISE && | 2406 | if (key.type != NL80211_KEYTYPE_PAIRWISE && |
2407 | key.type != NL80211_KEYTYPE_GROUP) | 2407 | key.type != NL80211_KEYTYPE_GROUP) |
2408 | return -EINVAL; | 2408 | return -EINVAL; |
2409 | 2409 | ||
2410 | if (!rdev->ops->add_key) | 2410 | if (!rdev->ops->add_key) |
2411 | return -EOPNOTSUPP; | 2411 | return -EOPNOTSUPP; |
2412 | 2412 | ||
2413 | if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, | 2413 | if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, |
2414 | key.type == NL80211_KEYTYPE_PAIRWISE, | 2414 | key.type == NL80211_KEYTYPE_PAIRWISE, |
2415 | mac_addr)) | 2415 | mac_addr)) |
2416 | return -EINVAL; | 2416 | return -EINVAL; |
2417 | 2417 | ||
2418 | wdev_lock(dev->ieee80211_ptr); | 2418 | wdev_lock(dev->ieee80211_ptr); |
2419 | err = nl80211_key_allowed(dev->ieee80211_ptr); | 2419 | err = nl80211_key_allowed(dev->ieee80211_ptr); |
2420 | if (!err) | 2420 | if (!err) |
2421 | err = rdev_add_key(rdev, dev, key.idx, | 2421 | err = rdev_add_key(rdev, dev, key.idx, |
2422 | key.type == NL80211_KEYTYPE_PAIRWISE, | 2422 | key.type == NL80211_KEYTYPE_PAIRWISE, |
2423 | mac_addr, &key.p); | 2423 | mac_addr, &key.p); |
2424 | wdev_unlock(dev->ieee80211_ptr); | 2424 | wdev_unlock(dev->ieee80211_ptr); |
2425 | 2425 | ||
2426 | return err; | 2426 | return err; |
2427 | } | 2427 | } |
2428 | 2428 | ||
2429 | static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) | 2429 | static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info) |
2430 | { | 2430 | { |
2431 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2431 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2432 | int err; | 2432 | int err; |
2433 | struct net_device *dev = info->user_ptr[1]; | 2433 | struct net_device *dev = info->user_ptr[1]; |
2434 | u8 *mac_addr = NULL; | 2434 | u8 *mac_addr = NULL; |
2435 | struct key_parse key; | 2435 | struct key_parse key; |
2436 | 2436 | ||
2437 | err = nl80211_parse_key(info, &key); | 2437 | err = nl80211_parse_key(info, &key); |
2438 | if (err) | 2438 | if (err) |
2439 | return err; | 2439 | return err; |
2440 | 2440 | ||
2441 | if (info->attrs[NL80211_ATTR_MAC]) | 2441 | if (info->attrs[NL80211_ATTR_MAC]) |
2442 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 2442 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
2443 | 2443 | ||
2444 | if (key.type == -1) { | 2444 | if (key.type == -1) { |
2445 | if (mac_addr) | 2445 | if (mac_addr) |
2446 | key.type = NL80211_KEYTYPE_PAIRWISE; | 2446 | key.type = NL80211_KEYTYPE_PAIRWISE; |
2447 | else | 2447 | else |
2448 | key.type = NL80211_KEYTYPE_GROUP; | 2448 | key.type = NL80211_KEYTYPE_GROUP; |
2449 | } | 2449 | } |
2450 | 2450 | ||
2451 | /* for now */ | 2451 | /* for now */ |
2452 | if (key.type != NL80211_KEYTYPE_PAIRWISE && | 2452 | if (key.type != NL80211_KEYTYPE_PAIRWISE && |
2453 | key.type != NL80211_KEYTYPE_GROUP) | 2453 | key.type != NL80211_KEYTYPE_GROUP) |
2454 | return -EINVAL; | 2454 | return -EINVAL; |
2455 | 2455 | ||
2456 | if (!rdev->ops->del_key) | 2456 | if (!rdev->ops->del_key) |
2457 | return -EOPNOTSUPP; | 2457 | return -EOPNOTSUPP; |
2458 | 2458 | ||
2459 | wdev_lock(dev->ieee80211_ptr); | 2459 | wdev_lock(dev->ieee80211_ptr); |
2460 | err = nl80211_key_allowed(dev->ieee80211_ptr); | 2460 | err = nl80211_key_allowed(dev->ieee80211_ptr); |
2461 | 2461 | ||
2462 | if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr && | 2462 | if (key.type == NL80211_KEYTYPE_PAIRWISE && mac_addr && |
2463 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) | 2463 | !(rdev->wiphy.flags & WIPHY_FLAG_IBSS_RSN)) |
2464 | err = -ENOENT; | 2464 | err = -ENOENT; |
2465 | 2465 | ||
2466 | if (!err) | 2466 | if (!err) |
2467 | err = rdev_del_key(rdev, dev, key.idx, | 2467 | err = rdev_del_key(rdev, dev, key.idx, |
2468 | key.type == NL80211_KEYTYPE_PAIRWISE, | 2468 | key.type == NL80211_KEYTYPE_PAIRWISE, |
2469 | mac_addr); | 2469 | mac_addr); |
2470 | 2470 | ||
2471 | #ifdef CONFIG_CFG80211_WEXT | 2471 | #ifdef CONFIG_CFG80211_WEXT |
2472 | if (!err) { | 2472 | if (!err) { |
2473 | if (key.idx == dev->ieee80211_ptr->wext.default_key) | 2473 | if (key.idx == dev->ieee80211_ptr->wext.default_key) |
2474 | dev->ieee80211_ptr->wext.default_key = -1; | 2474 | dev->ieee80211_ptr->wext.default_key = -1; |
2475 | else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key) | 2475 | else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key) |
2476 | dev->ieee80211_ptr->wext.default_mgmt_key = -1; | 2476 | dev->ieee80211_ptr->wext.default_mgmt_key = -1; |
2477 | } | 2477 | } |
2478 | #endif | 2478 | #endif |
2479 | wdev_unlock(dev->ieee80211_ptr); | 2479 | wdev_unlock(dev->ieee80211_ptr); |
2480 | 2480 | ||
2481 | return err; | 2481 | return err; |
2482 | } | 2482 | } |
2483 | 2483 | ||
2484 | static int nl80211_parse_beacon(struct genl_info *info, | 2484 | static int nl80211_parse_beacon(struct genl_info *info, |
2485 | struct cfg80211_beacon_data *bcn) | 2485 | struct cfg80211_beacon_data *bcn) |
2486 | { | 2486 | { |
2487 | bool haveinfo = false; | 2487 | bool haveinfo = false; |
2488 | 2488 | ||
2489 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) || | 2489 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_BEACON_TAIL]) || |
2490 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) || | 2490 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]) || |
2491 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) || | 2491 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_PROBE_RESP]) || |
2492 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP])) | 2492 | !is_valid_ie_attr(info->attrs[NL80211_ATTR_IE_ASSOC_RESP])) |
2493 | return -EINVAL; | 2493 | return -EINVAL; |
2494 | 2494 | ||
2495 | memset(bcn, 0, sizeof(*bcn)); | 2495 | memset(bcn, 0, sizeof(*bcn)); |
2496 | 2496 | ||
2497 | if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { | 2497 | if (info->attrs[NL80211_ATTR_BEACON_HEAD]) { |
2498 | bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); | 2498 | bcn->head = nla_data(info->attrs[NL80211_ATTR_BEACON_HEAD]); |
2499 | bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); | 2499 | bcn->head_len = nla_len(info->attrs[NL80211_ATTR_BEACON_HEAD]); |
2500 | if (!bcn->head_len) | 2500 | if (!bcn->head_len) |
2501 | return -EINVAL; | 2501 | return -EINVAL; |
2502 | haveinfo = true; | 2502 | haveinfo = true; |
2503 | } | 2503 | } |
2504 | 2504 | ||
2505 | if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { | 2505 | if (info->attrs[NL80211_ATTR_BEACON_TAIL]) { |
2506 | bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); | 2506 | bcn->tail = nla_data(info->attrs[NL80211_ATTR_BEACON_TAIL]); |
2507 | bcn->tail_len = | 2507 | bcn->tail_len = |
2508 | nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]); | 2508 | nla_len(info->attrs[NL80211_ATTR_BEACON_TAIL]); |
2509 | haveinfo = true; | 2509 | haveinfo = true; |
2510 | } | 2510 | } |
2511 | 2511 | ||
2512 | if (!haveinfo) | 2512 | if (!haveinfo) |
2513 | return -EINVAL; | 2513 | return -EINVAL; |
2514 | 2514 | ||
2515 | if (info->attrs[NL80211_ATTR_IE]) { | 2515 | if (info->attrs[NL80211_ATTR_IE]) { |
2516 | bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]); | 2516 | bcn->beacon_ies = nla_data(info->attrs[NL80211_ATTR_IE]); |
2517 | bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 2517 | bcn->beacon_ies_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
2518 | } | 2518 | } |
2519 | 2519 | ||
2520 | if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) { | 2520 | if (info->attrs[NL80211_ATTR_IE_PROBE_RESP]) { |
2521 | bcn->proberesp_ies = | 2521 | bcn->proberesp_ies = |
2522 | nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); | 2522 | nla_data(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); |
2523 | bcn->proberesp_ies_len = | 2523 | bcn->proberesp_ies_len = |
2524 | nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); | 2524 | nla_len(info->attrs[NL80211_ATTR_IE_PROBE_RESP]); |
2525 | } | 2525 | } |
2526 | 2526 | ||
2527 | if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) { | 2527 | if (info->attrs[NL80211_ATTR_IE_ASSOC_RESP]) { |
2528 | bcn->assocresp_ies = | 2528 | bcn->assocresp_ies = |
2529 | nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | 2529 | nla_data(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); |
2530 | bcn->assocresp_ies_len = | 2530 | bcn->assocresp_ies_len = |
2531 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); | 2531 | nla_len(info->attrs[NL80211_ATTR_IE_ASSOC_RESP]); |
2532 | } | 2532 | } |
2533 | 2533 | ||
2534 | if (info->attrs[NL80211_ATTR_PROBE_RESP]) { | 2534 | if (info->attrs[NL80211_ATTR_PROBE_RESP]) { |
2535 | bcn->probe_resp = | 2535 | bcn->probe_resp = |
2536 | nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]); | 2536 | nla_data(info->attrs[NL80211_ATTR_PROBE_RESP]); |
2537 | bcn->probe_resp_len = | 2537 | bcn->probe_resp_len = |
2538 | nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]); | 2538 | nla_len(info->attrs[NL80211_ATTR_PROBE_RESP]); |
2539 | } | 2539 | } |
2540 | 2540 | ||
2541 | return 0; | 2541 | return 0; |
2542 | } | 2542 | } |
2543 | 2543 | ||
2544 | static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, | 2544 | static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev, |
2545 | struct cfg80211_ap_settings *params) | 2545 | struct cfg80211_ap_settings *params) |
2546 | { | 2546 | { |
2547 | struct wireless_dev *wdev; | 2547 | struct wireless_dev *wdev; |
2548 | bool ret = false; | 2548 | bool ret = false; |
2549 | 2549 | ||
2550 | mutex_lock(&rdev->devlist_mtx); | 2550 | mutex_lock(&rdev->devlist_mtx); |
2551 | 2551 | ||
2552 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | 2552 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
2553 | if (wdev->iftype != NL80211_IFTYPE_AP && | 2553 | if (wdev->iftype != NL80211_IFTYPE_AP && |
2554 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | 2554 | wdev->iftype != NL80211_IFTYPE_P2P_GO) |
2555 | continue; | 2555 | continue; |
2556 | 2556 | ||
2557 | if (!wdev->preset_chandef.chan) | 2557 | if (!wdev->preset_chandef.chan) |
2558 | continue; | 2558 | continue; |
2559 | 2559 | ||
2560 | params->chandef = wdev->preset_chandef; | 2560 | params->chandef = wdev->preset_chandef; |
2561 | ret = true; | 2561 | ret = true; |
2562 | break; | 2562 | break; |
2563 | } | 2563 | } |
2564 | 2564 | ||
2565 | mutex_unlock(&rdev->devlist_mtx); | 2565 | mutex_unlock(&rdev->devlist_mtx); |
2566 | 2566 | ||
2567 | return ret; | 2567 | return ret; |
2568 | } | 2568 | } |
2569 | 2569 | ||
2570 | static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev, | 2570 | static bool nl80211_valid_auth_type(struct cfg80211_registered_device *rdev, |
2571 | enum nl80211_auth_type auth_type, | 2571 | enum nl80211_auth_type auth_type, |
2572 | enum nl80211_commands cmd) | 2572 | enum nl80211_commands cmd) |
2573 | { | 2573 | { |
2574 | if (auth_type > NL80211_AUTHTYPE_MAX) | 2574 | if (auth_type > NL80211_AUTHTYPE_MAX) |
2575 | return false; | 2575 | return false; |
2576 | 2576 | ||
2577 | switch (cmd) { | 2577 | switch (cmd) { |
2578 | case NL80211_CMD_AUTHENTICATE: | 2578 | case NL80211_CMD_AUTHENTICATE: |
2579 | if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) && | 2579 | if (!(rdev->wiphy.features & NL80211_FEATURE_SAE) && |
2580 | auth_type == NL80211_AUTHTYPE_SAE) | 2580 | auth_type == NL80211_AUTHTYPE_SAE) |
2581 | return false; | 2581 | return false; |
2582 | return true; | 2582 | return true; |
2583 | case NL80211_CMD_CONNECT: | 2583 | case NL80211_CMD_CONNECT: |
2584 | case NL80211_CMD_START_AP: | 2584 | case NL80211_CMD_START_AP: |
2585 | /* SAE not supported yet */ | 2585 | /* SAE not supported yet */ |
2586 | if (auth_type == NL80211_AUTHTYPE_SAE) | 2586 | if (auth_type == NL80211_AUTHTYPE_SAE) |
2587 | return false; | 2587 | return false; |
2588 | return true; | 2588 | return true; |
2589 | default: | 2589 | default: |
2590 | return false; | 2590 | return false; |
2591 | } | 2591 | } |
2592 | } | 2592 | } |
2593 | 2593 | ||
2594 | static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) | 2594 | static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) |
2595 | { | 2595 | { |
2596 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2596 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2597 | struct net_device *dev = info->user_ptr[1]; | 2597 | struct net_device *dev = info->user_ptr[1]; |
2598 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 2598 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
2599 | struct cfg80211_ap_settings params; | 2599 | struct cfg80211_ap_settings params; |
2600 | int err; | 2600 | int err; |
2601 | 2601 | ||
2602 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2602 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
2603 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 2603 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
2604 | return -EOPNOTSUPP; | 2604 | return -EOPNOTSUPP; |
2605 | 2605 | ||
2606 | if (!rdev->ops->start_ap) | 2606 | if (!rdev->ops->start_ap) |
2607 | return -EOPNOTSUPP; | 2607 | return -EOPNOTSUPP; |
2608 | 2608 | ||
2609 | if (wdev->beacon_interval) | 2609 | if (wdev->beacon_interval) |
2610 | return -EALREADY; | 2610 | return -EALREADY; |
2611 | 2611 | ||
2612 | memset(¶ms, 0, sizeof(params)); | 2612 | memset(¶ms, 0, sizeof(params)); |
2613 | 2613 | ||
2614 | /* these are required for START_AP */ | 2614 | /* these are required for START_AP */ |
2615 | if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || | 2615 | if (!info->attrs[NL80211_ATTR_BEACON_INTERVAL] || |
2616 | !info->attrs[NL80211_ATTR_DTIM_PERIOD] || | 2616 | !info->attrs[NL80211_ATTR_DTIM_PERIOD] || |
2617 | !info->attrs[NL80211_ATTR_BEACON_HEAD]) | 2617 | !info->attrs[NL80211_ATTR_BEACON_HEAD]) |
2618 | return -EINVAL; | 2618 | return -EINVAL; |
2619 | 2619 | ||
2620 | err = nl80211_parse_beacon(info, ¶ms.beacon); | 2620 | err = nl80211_parse_beacon(info, ¶ms.beacon); |
2621 | if (err) | 2621 | if (err) |
2622 | return err; | 2622 | return err; |
2623 | 2623 | ||
2624 | params.beacon_interval = | 2624 | params.beacon_interval = |
2625 | nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); | 2625 | nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); |
2626 | params.dtim_period = | 2626 | params.dtim_period = |
2627 | nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); | 2627 | nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); |
2628 | 2628 | ||
2629 | err = cfg80211_validate_beacon_int(rdev, params.beacon_interval); | 2629 | err = cfg80211_validate_beacon_int(rdev, params.beacon_interval); |
2630 | if (err) | 2630 | if (err) |
2631 | return err; | 2631 | return err; |
2632 | 2632 | ||
2633 | /* | 2633 | /* |
2634 | * In theory, some of these attributes should be required here | 2634 | * In theory, some of these attributes should be required here |
2635 | * but since they were not used when the command was originally | 2635 | * but since they were not used when the command was originally |
2636 | * added, keep them optional for old user space programs to let | 2636 | * added, keep them optional for old user space programs to let |
2637 | * them continue to work with drivers that do not need the | 2637 | * them continue to work with drivers that do not need the |
2638 | * additional information -- drivers must check! | 2638 | * additional information -- drivers must check! |
2639 | */ | 2639 | */ |
2640 | if (info->attrs[NL80211_ATTR_SSID]) { | 2640 | if (info->attrs[NL80211_ATTR_SSID]) { |
2641 | params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 2641 | params.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
2642 | params.ssid_len = | 2642 | params.ssid_len = |
2643 | nla_len(info->attrs[NL80211_ATTR_SSID]); | 2643 | nla_len(info->attrs[NL80211_ATTR_SSID]); |
2644 | if (params.ssid_len == 0 || | 2644 | if (params.ssid_len == 0 || |
2645 | params.ssid_len > IEEE80211_MAX_SSID_LEN) | 2645 | params.ssid_len > IEEE80211_MAX_SSID_LEN) |
2646 | return -EINVAL; | 2646 | return -EINVAL; |
2647 | } | 2647 | } |
2648 | 2648 | ||
2649 | if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) { | 2649 | if (info->attrs[NL80211_ATTR_HIDDEN_SSID]) { |
2650 | params.hidden_ssid = nla_get_u32( | 2650 | params.hidden_ssid = nla_get_u32( |
2651 | info->attrs[NL80211_ATTR_HIDDEN_SSID]); | 2651 | info->attrs[NL80211_ATTR_HIDDEN_SSID]); |
2652 | if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE && | 2652 | if (params.hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE && |
2653 | params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN && | 2653 | params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_LEN && |
2654 | params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS) | 2654 | params.hidden_ssid != NL80211_HIDDEN_SSID_ZERO_CONTENTS) |
2655 | return -EINVAL; | 2655 | return -EINVAL; |
2656 | } | 2656 | } |
2657 | 2657 | ||
2658 | params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; | 2658 | params.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; |
2659 | 2659 | ||
2660 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { | 2660 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { |
2661 | params.auth_type = nla_get_u32( | 2661 | params.auth_type = nla_get_u32( |
2662 | info->attrs[NL80211_ATTR_AUTH_TYPE]); | 2662 | info->attrs[NL80211_ATTR_AUTH_TYPE]); |
2663 | if (!nl80211_valid_auth_type(rdev, params.auth_type, | 2663 | if (!nl80211_valid_auth_type(rdev, params.auth_type, |
2664 | NL80211_CMD_START_AP)) | 2664 | NL80211_CMD_START_AP)) |
2665 | return -EINVAL; | 2665 | return -EINVAL; |
2666 | } else | 2666 | } else |
2667 | params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; | 2667 | params.auth_type = NL80211_AUTHTYPE_AUTOMATIC; |
2668 | 2668 | ||
2669 | err = nl80211_crypto_settings(rdev, info, ¶ms.crypto, | 2669 | err = nl80211_crypto_settings(rdev, info, ¶ms.crypto, |
2670 | NL80211_MAX_NR_CIPHER_SUITES); | 2670 | NL80211_MAX_NR_CIPHER_SUITES); |
2671 | if (err) | 2671 | if (err) |
2672 | return err; | 2672 | return err; |
2673 | 2673 | ||
2674 | if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) { | 2674 | if (info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]) { |
2675 | if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER)) | 2675 | if (!(rdev->wiphy.features & NL80211_FEATURE_INACTIVITY_TIMER)) |
2676 | return -EOPNOTSUPP; | 2676 | return -EOPNOTSUPP; |
2677 | params.inactivity_timeout = nla_get_u16( | 2677 | params.inactivity_timeout = nla_get_u16( |
2678 | info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); | 2678 | info->attrs[NL80211_ATTR_INACTIVITY_TIMEOUT]); |
2679 | } | 2679 | } |
2680 | 2680 | ||
2681 | if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) { | 2681 | if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) { |
2682 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 2682 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
2683 | return -EINVAL; | 2683 | return -EINVAL; |
2684 | params.p2p_ctwindow = | 2684 | params.p2p_ctwindow = |
2685 | nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]); | 2685 | nla_get_u8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]); |
2686 | if (params.p2p_ctwindow > 127) | 2686 | if (params.p2p_ctwindow > 127) |
2687 | return -EINVAL; | 2687 | return -EINVAL; |
2688 | if (params.p2p_ctwindow != 0 && | 2688 | if (params.p2p_ctwindow != 0 && |
2689 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) | 2689 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) |
2690 | return -EINVAL; | 2690 | return -EINVAL; |
2691 | } | 2691 | } |
2692 | 2692 | ||
2693 | if (info->attrs[NL80211_ATTR_P2P_OPPPS]) { | 2693 | if (info->attrs[NL80211_ATTR_P2P_OPPPS]) { |
2694 | u8 tmp; | 2694 | u8 tmp; |
2695 | 2695 | ||
2696 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 2696 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
2697 | return -EINVAL; | 2697 | return -EINVAL; |
2698 | tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]); | 2698 | tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]); |
2699 | if (tmp > 1) | 2699 | if (tmp > 1) |
2700 | return -EINVAL; | 2700 | return -EINVAL; |
2701 | params.p2p_opp_ps = tmp; | 2701 | params.p2p_opp_ps = tmp; |
2702 | if (params.p2p_opp_ps != 0 && | 2702 | if (params.p2p_opp_ps != 0 && |
2703 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) | 2703 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) |
2704 | return -EINVAL; | 2704 | return -EINVAL; |
2705 | } | 2705 | } |
2706 | 2706 | ||
2707 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | 2707 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { |
2708 | err = nl80211_parse_chandef(rdev, info, ¶ms.chandef); | 2708 | err = nl80211_parse_chandef(rdev, info, ¶ms.chandef); |
2709 | if (err) | 2709 | if (err) |
2710 | return err; | 2710 | return err; |
2711 | } else if (wdev->preset_chandef.chan) { | 2711 | } else if (wdev->preset_chandef.chan) { |
2712 | params.chandef = wdev->preset_chandef; | 2712 | params.chandef = wdev->preset_chandef; |
2713 | } else if (!nl80211_get_ap_channel(rdev, ¶ms)) | 2713 | } else if (!nl80211_get_ap_channel(rdev, ¶ms)) |
2714 | return -EINVAL; | 2714 | return -EINVAL; |
2715 | 2715 | ||
2716 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) | 2716 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, ¶ms.chandef)) |
2717 | return -EINVAL; | 2717 | return -EINVAL; |
2718 | 2718 | ||
2719 | mutex_lock(&rdev->devlist_mtx); | 2719 | mutex_lock(&rdev->devlist_mtx); |
2720 | err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan, | 2720 | err = cfg80211_can_use_chan(rdev, wdev, params.chandef.chan, |
2721 | CHAN_MODE_SHARED); | 2721 | CHAN_MODE_SHARED); |
2722 | mutex_unlock(&rdev->devlist_mtx); | 2722 | mutex_unlock(&rdev->devlist_mtx); |
2723 | 2723 | ||
2724 | if (err) | 2724 | if (err) |
2725 | return err; | 2725 | return err; |
2726 | 2726 | ||
2727 | err = rdev_start_ap(rdev, dev, ¶ms); | 2727 | err = rdev_start_ap(rdev, dev, ¶ms); |
2728 | if (!err) { | 2728 | if (!err) { |
2729 | wdev->preset_chandef = params.chandef; | 2729 | wdev->preset_chandef = params.chandef; |
2730 | wdev->beacon_interval = params.beacon_interval; | 2730 | wdev->beacon_interval = params.beacon_interval; |
2731 | wdev->channel = params.chandef.chan; | 2731 | wdev->channel = params.chandef.chan; |
2732 | wdev->ssid_len = params.ssid_len; | 2732 | wdev->ssid_len = params.ssid_len; |
2733 | memcpy(wdev->ssid, params.ssid, wdev->ssid_len); | 2733 | memcpy(wdev->ssid, params.ssid, wdev->ssid_len); |
2734 | } | 2734 | } |
2735 | return err; | 2735 | return err; |
2736 | } | 2736 | } |
2737 | 2737 | ||
2738 | static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) | 2738 | static int nl80211_set_beacon(struct sk_buff *skb, struct genl_info *info) |
2739 | { | 2739 | { |
2740 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2740 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2741 | struct net_device *dev = info->user_ptr[1]; | 2741 | struct net_device *dev = info->user_ptr[1]; |
2742 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 2742 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
2743 | struct cfg80211_beacon_data params; | 2743 | struct cfg80211_beacon_data params; |
2744 | int err; | 2744 | int err; |
2745 | 2745 | ||
2746 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 2746 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
2747 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 2747 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
2748 | return -EOPNOTSUPP; | 2748 | return -EOPNOTSUPP; |
2749 | 2749 | ||
2750 | if (!rdev->ops->change_beacon) | 2750 | if (!rdev->ops->change_beacon) |
2751 | return -EOPNOTSUPP; | 2751 | return -EOPNOTSUPP; |
2752 | 2752 | ||
2753 | if (!wdev->beacon_interval) | 2753 | if (!wdev->beacon_interval) |
2754 | return -EINVAL; | 2754 | return -EINVAL; |
2755 | 2755 | ||
2756 | err = nl80211_parse_beacon(info, ¶ms); | 2756 | err = nl80211_parse_beacon(info, ¶ms); |
2757 | if (err) | 2757 | if (err) |
2758 | return err; | 2758 | return err; |
2759 | 2759 | ||
2760 | return rdev_change_beacon(rdev, dev, ¶ms); | 2760 | return rdev_change_beacon(rdev, dev, ¶ms); |
2761 | } | 2761 | } |
2762 | 2762 | ||
2763 | static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) | 2763 | static int nl80211_stop_ap(struct sk_buff *skb, struct genl_info *info) |
2764 | { | 2764 | { |
2765 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 2765 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
2766 | struct net_device *dev = info->user_ptr[1]; | 2766 | struct net_device *dev = info->user_ptr[1]; |
2767 | 2767 | ||
2768 | return cfg80211_stop_ap(rdev, dev); | 2768 | return cfg80211_stop_ap(rdev, dev); |
2769 | } | 2769 | } |
2770 | 2770 | ||
2771 | static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { | 2771 | static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { |
2772 | [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG }, | 2772 | [NL80211_STA_FLAG_AUTHORIZED] = { .type = NLA_FLAG }, |
2773 | [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, | 2773 | [NL80211_STA_FLAG_SHORT_PREAMBLE] = { .type = NLA_FLAG }, |
2774 | [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, | 2774 | [NL80211_STA_FLAG_WME] = { .type = NLA_FLAG }, |
2775 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, | 2775 | [NL80211_STA_FLAG_MFP] = { .type = NLA_FLAG }, |
2776 | [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, | 2776 | [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, |
2777 | [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG }, | 2777 | [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG }, |
2778 | }; | 2778 | }; |
2779 | 2779 | ||
2780 | static int parse_station_flags(struct genl_info *info, | 2780 | static int parse_station_flags(struct genl_info *info, |
2781 | enum nl80211_iftype iftype, | 2781 | enum nl80211_iftype iftype, |
2782 | struct station_parameters *params) | 2782 | struct station_parameters *params) |
2783 | { | 2783 | { |
2784 | struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; | 2784 | struct nlattr *flags[NL80211_STA_FLAG_MAX + 1]; |
2785 | struct nlattr *nla; | 2785 | struct nlattr *nla; |
2786 | int flag; | 2786 | int flag; |
2787 | 2787 | ||
2788 | /* | 2788 | /* |
2789 | * Try parsing the new attribute first so userspace | 2789 | * Try parsing the new attribute first so userspace |
2790 | * can specify both for older kernels. | 2790 | * can specify both for older kernels. |
2791 | */ | 2791 | */ |
2792 | nla = info->attrs[NL80211_ATTR_STA_FLAGS2]; | 2792 | nla = info->attrs[NL80211_ATTR_STA_FLAGS2]; |
2793 | if (nla) { | 2793 | if (nla) { |
2794 | struct nl80211_sta_flag_update *sta_flags; | 2794 | struct nl80211_sta_flag_update *sta_flags; |
2795 | 2795 | ||
2796 | sta_flags = nla_data(nla); | 2796 | sta_flags = nla_data(nla); |
2797 | params->sta_flags_mask = sta_flags->mask; | 2797 | params->sta_flags_mask = sta_flags->mask; |
2798 | params->sta_flags_set = sta_flags->set; | 2798 | params->sta_flags_set = sta_flags->set; |
2799 | if ((params->sta_flags_mask | | 2799 | if ((params->sta_flags_mask | |
2800 | params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID)) | 2800 | params->sta_flags_set) & BIT(__NL80211_STA_FLAG_INVALID)) |
2801 | return -EINVAL; | 2801 | return -EINVAL; |
2802 | return 0; | 2802 | return 0; |
2803 | } | 2803 | } |
2804 | 2804 | ||
2805 | /* if present, parse the old attribute */ | 2805 | /* if present, parse the old attribute */ |
2806 | 2806 | ||
2807 | nla = info->attrs[NL80211_ATTR_STA_FLAGS]; | 2807 | nla = info->attrs[NL80211_ATTR_STA_FLAGS]; |
2808 | if (!nla) | 2808 | if (!nla) |
2809 | return 0; | 2809 | return 0; |
2810 | 2810 | ||
2811 | if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX, | 2811 | if (nla_parse_nested(flags, NL80211_STA_FLAG_MAX, |
2812 | nla, sta_flags_policy)) | 2812 | nla, sta_flags_policy)) |
2813 | return -EINVAL; | 2813 | return -EINVAL; |
2814 | 2814 | ||
2815 | /* | 2815 | /* |
2816 | * Only allow certain flags for interface types so that | 2816 | * Only allow certain flags for interface types so that |
2817 | * other attributes are silently ignored. Remember that | 2817 | * other attributes are silently ignored. Remember that |
2818 | * this is backward compatibility code with old userspace | 2818 | * this is backward compatibility code with old userspace |
2819 | * and shouldn't be hit in other cases anyway. | 2819 | * and shouldn't be hit in other cases anyway. |
2820 | */ | 2820 | */ |
2821 | switch (iftype) { | 2821 | switch (iftype) { |
2822 | case NL80211_IFTYPE_AP: | 2822 | case NL80211_IFTYPE_AP: |
2823 | case NL80211_IFTYPE_AP_VLAN: | 2823 | case NL80211_IFTYPE_AP_VLAN: |
2824 | case NL80211_IFTYPE_P2P_GO: | 2824 | case NL80211_IFTYPE_P2P_GO: |
2825 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | | 2825 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | |
2826 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | | 2826 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | |
2827 | BIT(NL80211_STA_FLAG_WME) | | 2827 | BIT(NL80211_STA_FLAG_WME) | |
2828 | BIT(NL80211_STA_FLAG_MFP); | 2828 | BIT(NL80211_STA_FLAG_MFP); |
2829 | break; | 2829 | break; |
2830 | case NL80211_IFTYPE_P2P_CLIENT: | 2830 | case NL80211_IFTYPE_P2P_CLIENT: |
2831 | case NL80211_IFTYPE_STATION: | 2831 | case NL80211_IFTYPE_STATION: |
2832 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | | 2832 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHORIZED) | |
2833 | BIT(NL80211_STA_FLAG_TDLS_PEER); | 2833 | BIT(NL80211_STA_FLAG_TDLS_PEER); |
2834 | break; | 2834 | break; |
2835 | case NL80211_IFTYPE_MESH_POINT: | 2835 | case NL80211_IFTYPE_MESH_POINT: |
2836 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 2836 | params->sta_flags_mask = BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
2837 | BIT(NL80211_STA_FLAG_MFP) | | 2837 | BIT(NL80211_STA_FLAG_MFP) | |
2838 | BIT(NL80211_STA_FLAG_AUTHORIZED); | 2838 | BIT(NL80211_STA_FLAG_AUTHORIZED); |
2839 | default: | 2839 | default: |
2840 | return -EINVAL; | 2840 | return -EINVAL; |
2841 | } | 2841 | } |
2842 | 2842 | ||
2843 | for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) { | 2843 | for (flag = 1; flag <= NL80211_STA_FLAG_MAX; flag++) { |
2844 | if (flags[flag]) { | 2844 | if (flags[flag]) { |
2845 | params->sta_flags_set |= (1<<flag); | 2845 | params->sta_flags_set |= (1<<flag); |
2846 | 2846 | ||
2847 | /* no longer support new API additions in old API */ | 2847 | /* no longer support new API additions in old API */ |
2848 | if (flag > NL80211_STA_FLAG_MAX_OLD_API) | 2848 | if (flag > NL80211_STA_FLAG_MAX_OLD_API) |
2849 | return -EINVAL; | 2849 | return -EINVAL; |
2850 | } | 2850 | } |
2851 | } | 2851 | } |
2852 | 2852 | ||
2853 | return 0; | 2853 | return 0; |
2854 | } | 2854 | } |
2855 | 2855 | ||
2856 | static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, | 2856 | static bool nl80211_put_sta_rate(struct sk_buff *msg, struct rate_info *info, |
2857 | int attr) | 2857 | int attr) |
2858 | { | 2858 | { |
2859 | struct nlattr *rate; | 2859 | struct nlattr *rate; |
2860 | u32 bitrate; | 2860 | u32 bitrate; |
2861 | u16 bitrate_compat; | 2861 | u16 bitrate_compat; |
2862 | 2862 | ||
2863 | rate = nla_nest_start(msg, attr); | 2863 | rate = nla_nest_start(msg, attr); |
2864 | if (!rate) | 2864 | if (!rate) |
2865 | return false; | 2865 | return false; |
2866 | 2866 | ||
2867 | /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ | 2867 | /* cfg80211_calculate_bitrate will return 0 for mcs >= 32 */ |
2868 | bitrate = cfg80211_calculate_bitrate(info); | 2868 | bitrate = cfg80211_calculate_bitrate(info); |
2869 | /* report 16-bit bitrate only if we can */ | 2869 | /* report 16-bit bitrate only if we can */ |
2870 | bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; | 2870 | bitrate_compat = bitrate < (1UL << 16) ? bitrate : 0; |
2871 | if (bitrate > 0 && | 2871 | if (bitrate > 0 && |
2872 | nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) | 2872 | nla_put_u32(msg, NL80211_RATE_INFO_BITRATE32, bitrate)) |
2873 | return false; | 2873 | return false; |
2874 | if (bitrate_compat > 0 && | 2874 | if (bitrate_compat > 0 && |
2875 | nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) | 2875 | nla_put_u16(msg, NL80211_RATE_INFO_BITRATE, bitrate_compat)) |
2876 | return false; | 2876 | return false; |
2877 | 2877 | ||
2878 | if (info->flags & RATE_INFO_FLAGS_MCS) { | 2878 | if (info->flags & RATE_INFO_FLAGS_MCS) { |
2879 | if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) | 2879 | if (nla_put_u8(msg, NL80211_RATE_INFO_MCS, info->mcs)) |
2880 | return false; | 2880 | return false; |
2881 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && | 2881 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && |
2882 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) | 2882 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) |
2883 | return false; | 2883 | return false; |
2884 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && | 2884 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && |
2885 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) | 2885 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) |
2886 | return false; | 2886 | return false; |
2887 | } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) { | 2887 | } else if (info->flags & RATE_INFO_FLAGS_VHT_MCS) { |
2888 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs)) | 2888 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_MCS, info->mcs)) |
2889 | return false; | 2889 | return false; |
2890 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss)) | 2890 | if (nla_put_u8(msg, NL80211_RATE_INFO_VHT_NSS, info->nss)) |
2891 | return false; | 2891 | return false; |
2892 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && | 2892 | if (info->flags & RATE_INFO_FLAGS_40_MHZ_WIDTH && |
2893 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) | 2893 | nla_put_flag(msg, NL80211_RATE_INFO_40_MHZ_WIDTH)) |
2894 | return false; | 2894 | return false; |
2895 | if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH && | 2895 | if (info->flags & RATE_INFO_FLAGS_80_MHZ_WIDTH && |
2896 | nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH)) | 2896 | nla_put_flag(msg, NL80211_RATE_INFO_80_MHZ_WIDTH)) |
2897 | return false; | 2897 | return false; |
2898 | if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH && | 2898 | if (info->flags & RATE_INFO_FLAGS_80P80_MHZ_WIDTH && |
2899 | nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH)) | 2899 | nla_put_flag(msg, NL80211_RATE_INFO_80P80_MHZ_WIDTH)) |
2900 | return false; | 2900 | return false; |
2901 | if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH && | 2901 | if (info->flags & RATE_INFO_FLAGS_160_MHZ_WIDTH && |
2902 | nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH)) | 2902 | nla_put_flag(msg, NL80211_RATE_INFO_160_MHZ_WIDTH)) |
2903 | return false; | 2903 | return false; |
2904 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && | 2904 | if (info->flags & RATE_INFO_FLAGS_SHORT_GI && |
2905 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) | 2905 | nla_put_flag(msg, NL80211_RATE_INFO_SHORT_GI)) |
2906 | return false; | 2906 | return false; |
2907 | } | 2907 | } |
2908 | 2908 | ||
2909 | nla_nest_end(msg, rate); | 2909 | nla_nest_end(msg, rate); |
2910 | return true; | 2910 | return true; |
2911 | } | 2911 | } |
2912 | 2912 | ||
2913 | static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | 2913 | static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, |
2914 | int flags, | 2914 | int flags, |
2915 | struct cfg80211_registered_device *rdev, | 2915 | struct cfg80211_registered_device *rdev, |
2916 | struct net_device *dev, | 2916 | struct net_device *dev, |
2917 | const u8 *mac_addr, struct station_info *sinfo) | 2917 | const u8 *mac_addr, struct station_info *sinfo) |
2918 | { | 2918 | { |
2919 | void *hdr; | 2919 | void *hdr; |
2920 | struct nlattr *sinfoattr, *bss_param; | 2920 | struct nlattr *sinfoattr, *bss_param; |
2921 | 2921 | ||
2922 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); | 2922 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); |
2923 | if (!hdr) | 2923 | if (!hdr) |
2924 | return -1; | 2924 | return -1; |
2925 | 2925 | ||
2926 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 2926 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
2927 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) || | 2927 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) || |
2928 | nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation)) | 2928 | nla_put_u32(msg, NL80211_ATTR_GENERATION, sinfo->generation)) |
2929 | goto nla_put_failure; | 2929 | goto nla_put_failure; |
2930 | 2930 | ||
2931 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); | 2931 | sinfoattr = nla_nest_start(msg, NL80211_ATTR_STA_INFO); |
2932 | if (!sinfoattr) | 2932 | if (!sinfoattr) |
2933 | goto nla_put_failure; | 2933 | goto nla_put_failure; |
2934 | if ((sinfo->filled & STATION_INFO_CONNECTED_TIME) && | 2934 | if ((sinfo->filled & STATION_INFO_CONNECTED_TIME) && |
2935 | nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME, | 2935 | nla_put_u32(msg, NL80211_STA_INFO_CONNECTED_TIME, |
2936 | sinfo->connected_time)) | 2936 | sinfo->connected_time)) |
2937 | goto nla_put_failure; | 2937 | goto nla_put_failure; |
2938 | if ((sinfo->filled & STATION_INFO_INACTIVE_TIME) && | 2938 | if ((sinfo->filled & STATION_INFO_INACTIVE_TIME) && |
2939 | nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME, | 2939 | nla_put_u32(msg, NL80211_STA_INFO_INACTIVE_TIME, |
2940 | sinfo->inactive_time)) | 2940 | sinfo->inactive_time)) |
2941 | goto nla_put_failure; | 2941 | goto nla_put_failure; |
2942 | if ((sinfo->filled & STATION_INFO_RX_BYTES) && | 2942 | if ((sinfo->filled & STATION_INFO_RX_BYTES) && |
2943 | nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, | 2943 | nla_put_u32(msg, NL80211_STA_INFO_RX_BYTES, |
2944 | sinfo->rx_bytes)) | 2944 | sinfo->rx_bytes)) |
2945 | goto nla_put_failure; | 2945 | goto nla_put_failure; |
2946 | if ((sinfo->filled & STATION_INFO_TX_BYTES) && | 2946 | if ((sinfo->filled & STATION_INFO_TX_BYTES) && |
2947 | nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, | 2947 | nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, |
2948 | sinfo->tx_bytes)) | 2948 | sinfo->tx_bytes)) |
2949 | goto nla_put_failure; | 2949 | goto nla_put_failure; |
2950 | if ((sinfo->filled & STATION_INFO_LLID) && | 2950 | if ((sinfo->filled & STATION_INFO_LLID) && |
2951 | nla_put_u16(msg, NL80211_STA_INFO_LLID, sinfo->llid)) | 2951 | nla_put_u16(msg, NL80211_STA_INFO_LLID, sinfo->llid)) |
2952 | goto nla_put_failure; | 2952 | goto nla_put_failure; |
2953 | if ((sinfo->filled & STATION_INFO_PLID) && | 2953 | if ((sinfo->filled & STATION_INFO_PLID) && |
2954 | nla_put_u16(msg, NL80211_STA_INFO_PLID, sinfo->plid)) | 2954 | nla_put_u16(msg, NL80211_STA_INFO_PLID, sinfo->plid)) |
2955 | goto nla_put_failure; | 2955 | goto nla_put_failure; |
2956 | if ((sinfo->filled & STATION_INFO_PLINK_STATE) && | 2956 | if ((sinfo->filled & STATION_INFO_PLINK_STATE) && |
2957 | nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE, | 2957 | nla_put_u8(msg, NL80211_STA_INFO_PLINK_STATE, |
2958 | sinfo->plink_state)) | 2958 | sinfo->plink_state)) |
2959 | goto nla_put_failure; | 2959 | goto nla_put_failure; |
2960 | switch (rdev->wiphy.signal_type) { | 2960 | switch (rdev->wiphy.signal_type) { |
2961 | case CFG80211_SIGNAL_TYPE_MBM: | 2961 | case CFG80211_SIGNAL_TYPE_MBM: |
2962 | if ((sinfo->filled & STATION_INFO_SIGNAL) && | 2962 | if ((sinfo->filled & STATION_INFO_SIGNAL) && |
2963 | nla_put_u8(msg, NL80211_STA_INFO_SIGNAL, | 2963 | nla_put_u8(msg, NL80211_STA_INFO_SIGNAL, |
2964 | sinfo->signal)) | 2964 | sinfo->signal)) |
2965 | goto nla_put_failure; | 2965 | goto nla_put_failure; |
2966 | if ((sinfo->filled & STATION_INFO_SIGNAL_AVG) && | 2966 | if ((sinfo->filled & STATION_INFO_SIGNAL_AVG) && |
2967 | nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG, | 2967 | nla_put_u8(msg, NL80211_STA_INFO_SIGNAL_AVG, |
2968 | sinfo->signal_avg)) | 2968 | sinfo->signal_avg)) |
2969 | goto nla_put_failure; | 2969 | goto nla_put_failure; |
2970 | break; | 2970 | break; |
2971 | default: | 2971 | default: |
2972 | break; | 2972 | break; |
2973 | } | 2973 | } |
2974 | if (sinfo->filled & STATION_INFO_TX_BITRATE) { | 2974 | if (sinfo->filled & STATION_INFO_TX_BITRATE) { |
2975 | if (!nl80211_put_sta_rate(msg, &sinfo->txrate, | 2975 | if (!nl80211_put_sta_rate(msg, &sinfo->txrate, |
2976 | NL80211_STA_INFO_TX_BITRATE)) | 2976 | NL80211_STA_INFO_TX_BITRATE)) |
2977 | goto nla_put_failure; | 2977 | goto nla_put_failure; |
2978 | } | 2978 | } |
2979 | if (sinfo->filled & STATION_INFO_RX_BITRATE) { | 2979 | if (sinfo->filled & STATION_INFO_RX_BITRATE) { |
2980 | if (!nl80211_put_sta_rate(msg, &sinfo->rxrate, | 2980 | if (!nl80211_put_sta_rate(msg, &sinfo->rxrate, |
2981 | NL80211_STA_INFO_RX_BITRATE)) | 2981 | NL80211_STA_INFO_RX_BITRATE)) |
2982 | goto nla_put_failure; | 2982 | goto nla_put_failure; |
2983 | } | 2983 | } |
2984 | if ((sinfo->filled & STATION_INFO_RX_PACKETS) && | 2984 | if ((sinfo->filled & STATION_INFO_RX_PACKETS) && |
2985 | nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS, | 2985 | nla_put_u32(msg, NL80211_STA_INFO_RX_PACKETS, |
2986 | sinfo->rx_packets)) | 2986 | sinfo->rx_packets)) |
2987 | goto nla_put_failure; | 2987 | goto nla_put_failure; |
2988 | if ((sinfo->filled & STATION_INFO_TX_PACKETS) && | 2988 | if ((sinfo->filled & STATION_INFO_TX_PACKETS) && |
2989 | nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS, | 2989 | nla_put_u32(msg, NL80211_STA_INFO_TX_PACKETS, |
2990 | sinfo->tx_packets)) | 2990 | sinfo->tx_packets)) |
2991 | goto nla_put_failure; | 2991 | goto nla_put_failure; |
2992 | if ((sinfo->filled & STATION_INFO_TX_RETRIES) && | 2992 | if ((sinfo->filled & STATION_INFO_TX_RETRIES) && |
2993 | nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES, | 2993 | nla_put_u32(msg, NL80211_STA_INFO_TX_RETRIES, |
2994 | sinfo->tx_retries)) | 2994 | sinfo->tx_retries)) |
2995 | goto nla_put_failure; | 2995 | goto nla_put_failure; |
2996 | if ((sinfo->filled & STATION_INFO_TX_FAILED) && | 2996 | if ((sinfo->filled & STATION_INFO_TX_FAILED) && |
2997 | nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, | 2997 | nla_put_u32(msg, NL80211_STA_INFO_TX_FAILED, |
2998 | sinfo->tx_failed)) | 2998 | sinfo->tx_failed)) |
2999 | goto nla_put_failure; | 2999 | goto nla_put_failure; |
3000 | if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) && | 3000 | if ((sinfo->filled & STATION_INFO_BEACON_LOSS_COUNT) && |
3001 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, | 3001 | nla_put_u32(msg, NL80211_STA_INFO_BEACON_LOSS, |
3002 | sinfo->beacon_loss_count)) | 3002 | sinfo->beacon_loss_count)) |
3003 | goto nla_put_failure; | 3003 | goto nla_put_failure; |
3004 | if ((sinfo->filled & STATION_INFO_LOCAL_PM) && | ||
3005 | nla_put_u32(msg, NL80211_STA_INFO_LOCAL_PM, | ||
3006 | sinfo->local_pm)) | ||
3007 | goto nla_put_failure; | ||
3008 | if ((sinfo->filled & STATION_INFO_PEER_PM) && | ||
3009 | nla_put_u32(msg, NL80211_STA_INFO_PEER_PM, | ||
3010 | sinfo->peer_pm)) | ||
3011 | goto nla_put_failure; | ||
3012 | if ((sinfo->filled & STATION_INFO_NONPEER_PM) && | ||
3013 | nla_put_u32(msg, NL80211_STA_INFO_NONPEER_PM, | ||
3014 | sinfo->nonpeer_pm)) | ||
3015 | goto nla_put_failure; | ||
3004 | if (sinfo->filled & STATION_INFO_BSS_PARAM) { | 3016 | if (sinfo->filled & STATION_INFO_BSS_PARAM) { |
3005 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); | 3017 | bss_param = nla_nest_start(msg, NL80211_STA_INFO_BSS_PARAM); |
3006 | if (!bss_param) | 3018 | if (!bss_param) |
3007 | goto nla_put_failure; | 3019 | goto nla_put_failure; |
3008 | 3020 | ||
3009 | if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) && | 3021 | if (((sinfo->bss_param.flags & BSS_PARAM_FLAGS_CTS_PROT) && |
3010 | nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) || | 3022 | nla_put_flag(msg, NL80211_STA_BSS_PARAM_CTS_PROT)) || |
3011 | ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) && | 3023 | ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_PREAMBLE) && |
3012 | nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) || | 3024 | nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_PREAMBLE)) || |
3013 | ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) && | 3025 | ((sinfo->bss_param.flags & BSS_PARAM_FLAGS_SHORT_SLOT_TIME) && |
3014 | nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) || | 3026 | nla_put_flag(msg, NL80211_STA_BSS_PARAM_SHORT_SLOT_TIME)) || |
3015 | nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, | 3027 | nla_put_u8(msg, NL80211_STA_BSS_PARAM_DTIM_PERIOD, |
3016 | sinfo->bss_param.dtim_period) || | 3028 | sinfo->bss_param.dtim_period) || |
3017 | nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, | 3029 | nla_put_u16(msg, NL80211_STA_BSS_PARAM_BEACON_INTERVAL, |
3018 | sinfo->bss_param.beacon_interval)) | 3030 | sinfo->bss_param.beacon_interval)) |
3019 | goto nla_put_failure; | 3031 | goto nla_put_failure; |
3020 | 3032 | ||
3021 | nla_nest_end(msg, bss_param); | 3033 | nla_nest_end(msg, bss_param); |
3022 | } | 3034 | } |
3023 | if ((sinfo->filled & STATION_INFO_STA_FLAGS) && | 3035 | if ((sinfo->filled & STATION_INFO_STA_FLAGS) && |
3024 | nla_put(msg, NL80211_STA_INFO_STA_FLAGS, | 3036 | nla_put(msg, NL80211_STA_INFO_STA_FLAGS, |
3025 | sizeof(struct nl80211_sta_flag_update), | 3037 | sizeof(struct nl80211_sta_flag_update), |
3026 | &sinfo->sta_flags)) | 3038 | &sinfo->sta_flags)) |
3027 | goto nla_put_failure; | 3039 | goto nla_put_failure; |
3028 | if ((sinfo->filled & STATION_INFO_T_OFFSET) && | 3040 | if ((sinfo->filled & STATION_INFO_T_OFFSET) && |
3029 | nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET, | 3041 | nla_put_u64(msg, NL80211_STA_INFO_T_OFFSET, |
3030 | sinfo->t_offset)) | 3042 | sinfo->t_offset)) |
3031 | goto nla_put_failure; | 3043 | goto nla_put_failure; |
3032 | nla_nest_end(msg, sinfoattr); | 3044 | nla_nest_end(msg, sinfoattr); |
3033 | 3045 | ||
3034 | if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) && | 3046 | if ((sinfo->filled & STATION_INFO_ASSOC_REQ_IES) && |
3035 | nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, | 3047 | nla_put(msg, NL80211_ATTR_IE, sinfo->assoc_req_ies_len, |
3036 | sinfo->assoc_req_ies)) | 3048 | sinfo->assoc_req_ies)) |
3037 | goto nla_put_failure; | 3049 | goto nla_put_failure; |
3038 | 3050 | ||
3039 | return genlmsg_end(msg, hdr); | 3051 | return genlmsg_end(msg, hdr); |
3040 | 3052 | ||
3041 | nla_put_failure: | 3053 | nla_put_failure: |
3042 | genlmsg_cancel(msg, hdr); | 3054 | genlmsg_cancel(msg, hdr); |
3043 | return -EMSGSIZE; | 3055 | return -EMSGSIZE; |
3044 | } | 3056 | } |
3045 | 3057 | ||
3046 | static int nl80211_dump_station(struct sk_buff *skb, | 3058 | static int nl80211_dump_station(struct sk_buff *skb, |
3047 | struct netlink_callback *cb) | 3059 | struct netlink_callback *cb) |
3048 | { | 3060 | { |
3049 | struct station_info sinfo; | 3061 | struct station_info sinfo; |
3050 | struct cfg80211_registered_device *dev; | 3062 | struct cfg80211_registered_device *dev; |
3051 | struct net_device *netdev; | 3063 | struct net_device *netdev; |
3052 | u8 mac_addr[ETH_ALEN]; | 3064 | u8 mac_addr[ETH_ALEN]; |
3053 | int sta_idx = cb->args[1]; | 3065 | int sta_idx = cb->args[1]; |
3054 | int err; | 3066 | int err; |
3055 | 3067 | ||
3056 | err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); | 3068 | err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); |
3057 | if (err) | 3069 | if (err) |
3058 | return err; | 3070 | return err; |
3059 | 3071 | ||
3060 | if (!dev->ops->dump_station) { | 3072 | if (!dev->ops->dump_station) { |
3061 | err = -EOPNOTSUPP; | 3073 | err = -EOPNOTSUPP; |
3062 | goto out_err; | 3074 | goto out_err; |
3063 | } | 3075 | } |
3064 | 3076 | ||
3065 | while (1) { | 3077 | while (1) { |
3066 | memset(&sinfo, 0, sizeof(sinfo)); | 3078 | memset(&sinfo, 0, sizeof(sinfo)); |
3067 | err = rdev_dump_station(dev, netdev, sta_idx, | 3079 | err = rdev_dump_station(dev, netdev, sta_idx, |
3068 | mac_addr, &sinfo); | 3080 | mac_addr, &sinfo); |
3069 | if (err == -ENOENT) | 3081 | if (err == -ENOENT) |
3070 | break; | 3082 | break; |
3071 | if (err) | 3083 | if (err) |
3072 | goto out_err; | 3084 | goto out_err; |
3073 | 3085 | ||
3074 | if (nl80211_send_station(skb, | 3086 | if (nl80211_send_station(skb, |
3075 | NETLINK_CB(cb->skb).portid, | 3087 | NETLINK_CB(cb->skb).portid, |
3076 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3088 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
3077 | dev, netdev, mac_addr, | 3089 | dev, netdev, mac_addr, |
3078 | &sinfo) < 0) | 3090 | &sinfo) < 0) |
3079 | goto out; | 3091 | goto out; |
3080 | 3092 | ||
3081 | sta_idx++; | 3093 | sta_idx++; |
3082 | } | 3094 | } |
3083 | 3095 | ||
3084 | 3096 | ||
3085 | out: | 3097 | out: |
3086 | cb->args[1] = sta_idx; | 3098 | cb->args[1] = sta_idx; |
3087 | err = skb->len; | 3099 | err = skb->len; |
3088 | out_err: | 3100 | out_err: |
3089 | nl80211_finish_netdev_dump(dev); | 3101 | nl80211_finish_netdev_dump(dev); |
3090 | 3102 | ||
3091 | return err; | 3103 | return err; |
3092 | } | 3104 | } |
3093 | 3105 | ||
3094 | static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) | 3106 | static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info) |
3095 | { | 3107 | { |
3096 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3108 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3097 | struct net_device *dev = info->user_ptr[1]; | 3109 | struct net_device *dev = info->user_ptr[1]; |
3098 | struct station_info sinfo; | 3110 | struct station_info sinfo; |
3099 | struct sk_buff *msg; | 3111 | struct sk_buff *msg; |
3100 | u8 *mac_addr = NULL; | 3112 | u8 *mac_addr = NULL; |
3101 | int err; | 3113 | int err; |
3102 | 3114 | ||
3103 | memset(&sinfo, 0, sizeof(sinfo)); | 3115 | memset(&sinfo, 0, sizeof(sinfo)); |
3104 | 3116 | ||
3105 | if (!info->attrs[NL80211_ATTR_MAC]) | 3117 | if (!info->attrs[NL80211_ATTR_MAC]) |
3106 | return -EINVAL; | 3118 | return -EINVAL; |
3107 | 3119 | ||
3108 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3120 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3109 | 3121 | ||
3110 | if (!rdev->ops->get_station) | 3122 | if (!rdev->ops->get_station) |
3111 | return -EOPNOTSUPP; | 3123 | return -EOPNOTSUPP; |
3112 | 3124 | ||
3113 | err = rdev_get_station(rdev, dev, mac_addr, &sinfo); | 3125 | err = rdev_get_station(rdev, dev, mac_addr, &sinfo); |
3114 | if (err) | 3126 | if (err) |
3115 | return err; | 3127 | return err; |
3116 | 3128 | ||
3117 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 3129 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
3118 | if (!msg) | 3130 | if (!msg) |
3119 | return -ENOMEM; | 3131 | return -ENOMEM; |
3120 | 3132 | ||
3121 | if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0, | 3133 | if (nl80211_send_station(msg, info->snd_portid, info->snd_seq, 0, |
3122 | rdev, dev, mac_addr, &sinfo) < 0) { | 3134 | rdev, dev, mac_addr, &sinfo) < 0) { |
3123 | nlmsg_free(msg); | 3135 | nlmsg_free(msg); |
3124 | return -ENOBUFS; | 3136 | return -ENOBUFS; |
3125 | } | 3137 | } |
3126 | 3138 | ||
3127 | return genlmsg_reply(msg, info); | 3139 | return genlmsg_reply(msg, info); |
3128 | } | 3140 | } |
3129 | 3141 | ||
3130 | /* | 3142 | /* |
3131 | * Get vlan interface making sure it is running and on the right wiphy. | 3143 | * Get vlan interface making sure it is running and on the right wiphy. |
3132 | */ | 3144 | */ |
3133 | static struct net_device *get_vlan(struct genl_info *info, | 3145 | static struct net_device *get_vlan(struct genl_info *info, |
3134 | struct cfg80211_registered_device *rdev) | 3146 | struct cfg80211_registered_device *rdev) |
3135 | { | 3147 | { |
3136 | struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN]; | 3148 | struct nlattr *vlanattr = info->attrs[NL80211_ATTR_STA_VLAN]; |
3137 | struct net_device *v; | 3149 | struct net_device *v; |
3138 | int ret; | 3150 | int ret; |
3139 | 3151 | ||
3140 | if (!vlanattr) | 3152 | if (!vlanattr) |
3141 | return NULL; | 3153 | return NULL; |
3142 | 3154 | ||
3143 | v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr)); | 3155 | v = dev_get_by_index(genl_info_net(info), nla_get_u32(vlanattr)); |
3144 | if (!v) | 3156 | if (!v) |
3145 | return ERR_PTR(-ENODEV); | 3157 | return ERR_PTR(-ENODEV); |
3146 | 3158 | ||
3147 | if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) { | 3159 | if (!v->ieee80211_ptr || v->ieee80211_ptr->wiphy != &rdev->wiphy) { |
3148 | ret = -EINVAL; | 3160 | ret = -EINVAL; |
3149 | goto error; | 3161 | goto error; |
3150 | } | 3162 | } |
3151 | 3163 | ||
3152 | if (!netif_running(v)) { | 3164 | if (!netif_running(v)) { |
3153 | ret = -ENETDOWN; | 3165 | ret = -ENETDOWN; |
3154 | goto error; | 3166 | goto error; |
3155 | } | 3167 | } |
3156 | 3168 | ||
3157 | return v; | 3169 | return v; |
3158 | error: | 3170 | error: |
3159 | dev_put(v); | 3171 | dev_put(v); |
3160 | return ERR_PTR(ret); | 3172 | return ERR_PTR(ret); |
3161 | } | 3173 | } |
3162 | 3174 | ||
3163 | static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) | 3175 | static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info) |
3164 | { | 3176 | { |
3165 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3177 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3166 | int err; | 3178 | int err; |
3167 | struct net_device *dev = info->user_ptr[1]; | 3179 | struct net_device *dev = info->user_ptr[1]; |
3168 | struct station_parameters params; | 3180 | struct station_parameters params; |
3169 | u8 *mac_addr = NULL; | 3181 | u8 *mac_addr = NULL; |
3170 | 3182 | ||
3171 | memset(¶ms, 0, sizeof(params)); | 3183 | memset(¶ms, 0, sizeof(params)); |
3172 | 3184 | ||
3173 | params.listen_interval = -1; | 3185 | params.listen_interval = -1; |
3174 | params.plink_state = -1; | 3186 | params.plink_state = -1; |
3175 | 3187 | ||
3176 | if (info->attrs[NL80211_ATTR_STA_AID]) | 3188 | if (info->attrs[NL80211_ATTR_STA_AID]) |
3177 | return -EINVAL; | 3189 | return -EINVAL; |
3178 | 3190 | ||
3179 | if (!info->attrs[NL80211_ATTR_MAC]) | 3191 | if (!info->attrs[NL80211_ATTR_MAC]) |
3180 | return -EINVAL; | 3192 | return -EINVAL; |
3181 | 3193 | ||
3182 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3194 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3183 | 3195 | ||
3184 | if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) { | 3196 | if (info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) { |
3185 | params.supported_rates = | 3197 | params.supported_rates = |
3186 | nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); | 3198 | nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); |
3187 | params.supported_rates_len = | 3199 | params.supported_rates_len = |
3188 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); | 3200 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); |
3189 | } | 3201 | } |
3190 | 3202 | ||
3191 | if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL] || | 3203 | if (info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL] || |
3192 | info->attrs[NL80211_ATTR_HT_CAPABILITY]) | 3204 | info->attrs[NL80211_ATTR_HT_CAPABILITY]) |
3193 | return -EINVAL; | 3205 | return -EINVAL; |
3194 | 3206 | ||
3195 | if (!rdev->ops->change_station) | 3207 | if (!rdev->ops->change_station) |
3196 | return -EOPNOTSUPP; | 3208 | return -EOPNOTSUPP; |
3197 | 3209 | ||
3198 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) | 3210 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) |
3199 | return -EINVAL; | 3211 | return -EINVAL; |
3200 | 3212 | ||
3201 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | 3213 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) |
3202 | params.plink_action = | 3214 | params.plink_action = |
3203 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | 3215 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); |
3204 | 3216 | ||
3205 | if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) | 3217 | if (info->attrs[NL80211_ATTR_STA_PLINK_STATE]) |
3206 | params.plink_state = | 3218 | params.plink_state = |
3207 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); | 3219 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_STATE]); |
3208 | 3220 | ||
3221 | if (info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]) { | ||
3222 | enum nl80211_mesh_power_mode pm = nla_get_u32( | ||
3223 | info->attrs[NL80211_ATTR_LOCAL_MESH_POWER_MODE]); | ||
3224 | |||
3225 | if (pm <= NL80211_MESH_POWER_UNKNOWN || | ||
3226 | pm > NL80211_MESH_POWER_MAX) | ||
3227 | return -EINVAL; | ||
3228 | |||
3229 | params.local_pm = pm; | ||
3230 | } | ||
3231 | |||
3209 | switch (dev->ieee80211_ptr->iftype) { | 3232 | switch (dev->ieee80211_ptr->iftype) { |
3210 | case NL80211_IFTYPE_AP: | 3233 | case NL80211_IFTYPE_AP: |
3211 | case NL80211_IFTYPE_AP_VLAN: | 3234 | case NL80211_IFTYPE_AP_VLAN: |
3212 | case NL80211_IFTYPE_P2P_GO: | 3235 | case NL80211_IFTYPE_P2P_GO: |
3213 | /* disallow mesh-specific things */ | 3236 | /* disallow mesh-specific things */ |
3214 | if (params.plink_action) | 3237 | if (params.plink_action) |
3215 | return -EINVAL; | 3238 | return -EINVAL; |
3239 | if (params.local_pm) | ||
3240 | return -EINVAL; | ||
3216 | 3241 | ||
3217 | /* TDLS can't be set, ... */ | 3242 | /* TDLS can't be set, ... */ |
3218 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) | 3243 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) |
3219 | return -EINVAL; | 3244 | return -EINVAL; |
3220 | /* | 3245 | /* |
3221 | * ... but don't bother the driver with it. This works around | 3246 | * ... but don't bother the driver with it. This works around |
3222 | * a hostapd/wpa_supplicant issue -- it always includes the | 3247 | * a hostapd/wpa_supplicant issue -- it always includes the |
3223 | * TLDS_PEER flag in the mask even for AP mode. | 3248 | * TLDS_PEER flag in the mask even for AP mode. |
3224 | */ | 3249 | */ |
3225 | params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); | 3250 | params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); |
3226 | 3251 | ||
3227 | /* accept only the listed bits */ | 3252 | /* accept only the listed bits */ |
3228 | if (params.sta_flags_mask & | 3253 | if (params.sta_flags_mask & |
3229 | ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | | 3254 | ~(BIT(NL80211_STA_FLAG_AUTHORIZED) | |
3230 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 3255 | BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
3231 | BIT(NL80211_STA_FLAG_ASSOCIATED) | | 3256 | BIT(NL80211_STA_FLAG_ASSOCIATED) | |
3232 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | | 3257 | BIT(NL80211_STA_FLAG_SHORT_PREAMBLE) | |
3233 | BIT(NL80211_STA_FLAG_WME) | | 3258 | BIT(NL80211_STA_FLAG_WME) | |
3234 | BIT(NL80211_STA_FLAG_MFP))) | 3259 | BIT(NL80211_STA_FLAG_MFP))) |
3235 | return -EINVAL; | 3260 | return -EINVAL; |
3236 | 3261 | ||
3237 | /* but authenticated/associated only if driver handles it */ | 3262 | /* but authenticated/associated only if driver handles it */ |
3238 | if (!(rdev->wiphy.features & | 3263 | if (!(rdev->wiphy.features & |
3239 | NL80211_FEATURE_FULL_AP_CLIENT_STATE) && | 3264 | NL80211_FEATURE_FULL_AP_CLIENT_STATE) && |
3240 | params.sta_flags_mask & | 3265 | params.sta_flags_mask & |
3241 | (BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 3266 | (BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
3242 | BIT(NL80211_STA_FLAG_ASSOCIATED))) | 3267 | BIT(NL80211_STA_FLAG_ASSOCIATED))) |
3243 | return -EINVAL; | 3268 | return -EINVAL; |
3244 | 3269 | ||
3245 | /* reject other things that can't change */ | 3270 | /* reject other things that can't change */ |
3246 | if (params.supported_rates) | 3271 | if (params.supported_rates) |
3247 | return -EINVAL; | 3272 | return -EINVAL; |
3248 | 3273 | ||
3249 | /* must be last in here for error handling */ | 3274 | /* must be last in here for error handling */ |
3250 | params.vlan = get_vlan(info, rdev); | 3275 | params.vlan = get_vlan(info, rdev); |
3251 | if (IS_ERR(params.vlan)) | 3276 | if (IS_ERR(params.vlan)) |
3252 | return PTR_ERR(params.vlan); | 3277 | return PTR_ERR(params.vlan); |
3253 | break; | 3278 | break; |
3254 | case NL80211_IFTYPE_P2P_CLIENT: | 3279 | case NL80211_IFTYPE_P2P_CLIENT: |
3255 | case NL80211_IFTYPE_STATION: | 3280 | case NL80211_IFTYPE_STATION: |
3256 | /* | 3281 | /* |
3257 | * Don't allow userspace to change the TDLS_PEER flag, | 3282 | * Don't allow userspace to change the TDLS_PEER flag, |
3258 | * but silently ignore attempts to change it since we | 3283 | * but silently ignore attempts to change it since we |
3259 | * don't have state here to verify that it doesn't try | 3284 | * don't have state here to verify that it doesn't try |
3260 | * to change the flag. | 3285 | * to change the flag. |
3261 | */ | 3286 | */ |
3262 | params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); | 3287 | params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); |
3263 | /* fall through */ | 3288 | /* fall through */ |
3264 | case NL80211_IFTYPE_ADHOC: | 3289 | case NL80211_IFTYPE_ADHOC: |
3265 | /* disallow things sta doesn't support */ | 3290 | /* disallow things sta doesn't support */ |
3266 | if (params.plink_action) | 3291 | if (params.plink_action) |
3267 | return -EINVAL; | 3292 | return -EINVAL; |
3293 | if (params.local_pm) | ||
3294 | return -EINVAL; | ||
3268 | /* reject any changes other than AUTHORIZED */ | 3295 | /* reject any changes other than AUTHORIZED */ |
3269 | if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) | 3296 | if (params.sta_flags_mask & ~BIT(NL80211_STA_FLAG_AUTHORIZED)) |
3270 | return -EINVAL; | 3297 | return -EINVAL; |
3271 | break; | 3298 | break; |
3272 | case NL80211_IFTYPE_MESH_POINT: | 3299 | case NL80211_IFTYPE_MESH_POINT: |
3273 | /* disallow things mesh doesn't support */ | 3300 | /* disallow things mesh doesn't support */ |
3274 | if (params.vlan) | 3301 | if (params.vlan) |
3275 | return -EINVAL; | 3302 | return -EINVAL; |
3276 | if (params.supported_rates) | 3303 | if (params.supported_rates) |
3277 | return -EINVAL; | 3304 | return -EINVAL; |
3278 | /* | 3305 | /* |
3279 | * No special handling for TDLS here -- the userspace | 3306 | * No special handling for TDLS here -- the userspace |
3280 | * mesh code doesn't have this bug. | 3307 | * mesh code doesn't have this bug. |
3281 | */ | 3308 | */ |
3282 | if (params.sta_flags_mask & | 3309 | if (params.sta_flags_mask & |
3283 | ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 3310 | ~(BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
3284 | BIT(NL80211_STA_FLAG_MFP) | | 3311 | BIT(NL80211_STA_FLAG_MFP) | |
3285 | BIT(NL80211_STA_FLAG_AUTHORIZED))) | 3312 | BIT(NL80211_STA_FLAG_AUTHORIZED))) |
3286 | return -EINVAL; | 3313 | return -EINVAL; |
3287 | break; | 3314 | break; |
3288 | default: | 3315 | default: |
3289 | return -EOPNOTSUPP; | 3316 | return -EOPNOTSUPP; |
3290 | } | 3317 | } |
3291 | 3318 | ||
3292 | /* be aware of params.vlan when changing code here */ | 3319 | /* be aware of params.vlan when changing code here */ |
3293 | 3320 | ||
3294 | err = rdev_change_station(rdev, dev, mac_addr, ¶ms); | 3321 | err = rdev_change_station(rdev, dev, mac_addr, ¶ms); |
3295 | 3322 | ||
3296 | if (params.vlan) | 3323 | if (params.vlan) |
3297 | dev_put(params.vlan); | 3324 | dev_put(params.vlan); |
3298 | 3325 | ||
3299 | return err; | 3326 | return err; |
3300 | } | 3327 | } |
3301 | 3328 | ||
3302 | static struct nla_policy | 3329 | static struct nla_policy |
3303 | nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = { | 3330 | nl80211_sta_wme_policy[NL80211_STA_WME_MAX + 1] __read_mostly = { |
3304 | [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 }, | 3331 | [NL80211_STA_WME_UAPSD_QUEUES] = { .type = NLA_U8 }, |
3305 | [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 }, | 3332 | [NL80211_STA_WME_MAX_SP] = { .type = NLA_U8 }, |
3306 | }; | 3333 | }; |
3307 | 3334 | ||
3308 | static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | 3335 | static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) |
3309 | { | 3336 | { |
3310 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3337 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3311 | int err; | 3338 | int err; |
3312 | struct net_device *dev = info->user_ptr[1]; | 3339 | struct net_device *dev = info->user_ptr[1]; |
3313 | struct station_parameters params; | 3340 | struct station_parameters params; |
3314 | u8 *mac_addr = NULL; | 3341 | u8 *mac_addr = NULL; |
3315 | 3342 | ||
3316 | memset(¶ms, 0, sizeof(params)); | 3343 | memset(¶ms, 0, sizeof(params)); |
3317 | 3344 | ||
3318 | if (!info->attrs[NL80211_ATTR_MAC]) | 3345 | if (!info->attrs[NL80211_ATTR_MAC]) |
3319 | return -EINVAL; | 3346 | return -EINVAL; |
3320 | 3347 | ||
3321 | if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) | 3348 | if (!info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]) |
3322 | return -EINVAL; | 3349 | return -EINVAL; |
3323 | 3350 | ||
3324 | if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) | 3351 | if (!info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]) |
3325 | return -EINVAL; | 3352 | return -EINVAL; |
3326 | 3353 | ||
3327 | if (!info->attrs[NL80211_ATTR_STA_AID]) | 3354 | if (!info->attrs[NL80211_ATTR_STA_AID]) |
3328 | return -EINVAL; | 3355 | return -EINVAL; |
3329 | 3356 | ||
3330 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3357 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3331 | params.supported_rates = | 3358 | params.supported_rates = |
3332 | nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); | 3359 | nla_data(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); |
3333 | params.supported_rates_len = | 3360 | params.supported_rates_len = |
3334 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); | 3361 | nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]); |
3335 | params.listen_interval = | 3362 | params.listen_interval = |
3336 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); | 3363 | nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); |
3337 | 3364 | ||
3338 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); | 3365 | params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); |
3339 | if (!params.aid || params.aid > IEEE80211_MAX_AID) | 3366 | if (!params.aid || params.aid > IEEE80211_MAX_AID) |
3340 | return -EINVAL; | 3367 | return -EINVAL; |
3341 | 3368 | ||
3342 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) | 3369 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) |
3343 | params.ht_capa = | 3370 | params.ht_capa = |
3344 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 3371 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
3345 | 3372 | ||
3346 | if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) | 3373 | if (info->attrs[NL80211_ATTR_VHT_CAPABILITY]) |
3347 | params.vht_capa = | 3374 | params.vht_capa = |
3348 | nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); | 3375 | nla_data(info->attrs[NL80211_ATTR_VHT_CAPABILITY]); |
3349 | 3376 | ||
3350 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) | 3377 | if (info->attrs[NL80211_ATTR_STA_PLINK_ACTION]) |
3351 | params.plink_action = | 3378 | params.plink_action = |
3352 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); | 3379 | nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]); |
3353 | 3380 | ||
3354 | if (!rdev->ops->add_station) | 3381 | if (!rdev->ops->add_station) |
3355 | return -EOPNOTSUPP; | 3382 | return -EOPNOTSUPP; |
3356 | 3383 | ||
3357 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) | 3384 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) |
3358 | return -EINVAL; | 3385 | return -EINVAL; |
3359 | 3386 | ||
3360 | switch (dev->ieee80211_ptr->iftype) { | 3387 | switch (dev->ieee80211_ptr->iftype) { |
3361 | case NL80211_IFTYPE_AP: | 3388 | case NL80211_IFTYPE_AP: |
3362 | case NL80211_IFTYPE_AP_VLAN: | 3389 | case NL80211_IFTYPE_AP_VLAN: |
3363 | case NL80211_IFTYPE_P2P_GO: | 3390 | case NL80211_IFTYPE_P2P_GO: |
3364 | /* parse WME attributes if sta is WME capable */ | 3391 | /* parse WME attributes if sta is WME capable */ |
3365 | if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && | 3392 | if ((rdev->wiphy.flags & WIPHY_FLAG_AP_UAPSD) && |
3366 | (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) && | 3393 | (params.sta_flags_set & BIT(NL80211_STA_FLAG_WME)) && |
3367 | info->attrs[NL80211_ATTR_STA_WME]) { | 3394 | info->attrs[NL80211_ATTR_STA_WME]) { |
3368 | struct nlattr *tb[NL80211_STA_WME_MAX + 1]; | 3395 | struct nlattr *tb[NL80211_STA_WME_MAX + 1]; |
3369 | struct nlattr *nla; | 3396 | struct nlattr *nla; |
3370 | 3397 | ||
3371 | nla = info->attrs[NL80211_ATTR_STA_WME]; | 3398 | nla = info->attrs[NL80211_ATTR_STA_WME]; |
3372 | err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla, | 3399 | err = nla_parse_nested(tb, NL80211_STA_WME_MAX, nla, |
3373 | nl80211_sta_wme_policy); | 3400 | nl80211_sta_wme_policy); |
3374 | if (err) | 3401 | if (err) |
3375 | return err; | 3402 | return err; |
3376 | 3403 | ||
3377 | if (tb[NL80211_STA_WME_UAPSD_QUEUES]) | 3404 | if (tb[NL80211_STA_WME_UAPSD_QUEUES]) |
3378 | params.uapsd_queues = | 3405 | params.uapsd_queues = |
3379 | nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]); | 3406 | nla_get_u8(tb[NL80211_STA_WME_UAPSD_QUEUES]); |
3380 | if (params.uapsd_queues & | 3407 | if (params.uapsd_queues & |
3381 | ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) | 3408 | ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK) |
3382 | return -EINVAL; | 3409 | return -EINVAL; |
3383 | 3410 | ||
3384 | if (tb[NL80211_STA_WME_MAX_SP]) | 3411 | if (tb[NL80211_STA_WME_MAX_SP]) |
3385 | params.max_sp = | 3412 | params.max_sp = |
3386 | nla_get_u8(tb[NL80211_STA_WME_MAX_SP]); | 3413 | nla_get_u8(tb[NL80211_STA_WME_MAX_SP]); |
3387 | 3414 | ||
3388 | if (params.max_sp & | 3415 | if (params.max_sp & |
3389 | ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) | 3416 | ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK) |
3390 | return -EINVAL; | 3417 | return -EINVAL; |
3391 | 3418 | ||
3392 | params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD; | 3419 | params.sta_modify_mask |= STATION_PARAM_APPLY_UAPSD; |
3393 | } | 3420 | } |
3394 | /* TDLS peers cannot be added */ | 3421 | /* TDLS peers cannot be added */ |
3395 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) | 3422 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) |
3396 | return -EINVAL; | 3423 | return -EINVAL; |
3397 | /* but don't bother the driver with it */ | 3424 | /* but don't bother the driver with it */ |
3398 | params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); | 3425 | params.sta_flags_mask &= ~BIT(NL80211_STA_FLAG_TDLS_PEER); |
3399 | 3426 | ||
3400 | /* allow authenticated/associated only if driver handles it */ | 3427 | /* allow authenticated/associated only if driver handles it */ |
3401 | if (!(rdev->wiphy.features & | 3428 | if (!(rdev->wiphy.features & |
3402 | NL80211_FEATURE_FULL_AP_CLIENT_STATE) && | 3429 | NL80211_FEATURE_FULL_AP_CLIENT_STATE) && |
3403 | params.sta_flags_mask & | 3430 | params.sta_flags_mask & |
3404 | (BIT(NL80211_STA_FLAG_AUTHENTICATED) | | 3431 | (BIT(NL80211_STA_FLAG_AUTHENTICATED) | |
3405 | BIT(NL80211_STA_FLAG_ASSOCIATED))) | 3432 | BIT(NL80211_STA_FLAG_ASSOCIATED))) |
3406 | return -EINVAL; | 3433 | return -EINVAL; |
3407 | 3434 | ||
3408 | /* must be last in here for error handling */ | 3435 | /* must be last in here for error handling */ |
3409 | params.vlan = get_vlan(info, rdev); | 3436 | params.vlan = get_vlan(info, rdev); |
3410 | if (IS_ERR(params.vlan)) | 3437 | if (IS_ERR(params.vlan)) |
3411 | return PTR_ERR(params.vlan); | 3438 | return PTR_ERR(params.vlan); |
3412 | break; | 3439 | break; |
3413 | case NL80211_IFTYPE_MESH_POINT: | 3440 | case NL80211_IFTYPE_MESH_POINT: |
3414 | /* associated is disallowed */ | 3441 | /* associated is disallowed */ |
3415 | if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) | 3442 | if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) |
3416 | return -EINVAL; | 3443 | return -EINVAL; |
3417 | /* TDLS peers cannot be added */ | 3444 | /* TDLS peers cannot be added */ |
3418 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) | 3445 | if (params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) |
3419 | return -EINVAL; | 3446 | return -EINVAL; |
3420 | break; | 3447 | break; |
3421 | case NL80211_IFTYPE_STATION: | 3448 | case NL80211_IFTYPE_STATION: |
3422 | /* associated is disallowed */ | 3449 | /* associated is disallowed */ |
3423 | if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) | 3450 | if (params.sta_flags_mask & BIT(NL80211_STA_FLAG_ASSOCIATED)) |
3424 | return -EINVAL; | 3451 | return -EINVAL; |
3425 | /* Only TDLS peers can be added */ | 3452 | /* Only TDLS peers can be added */ |
3426 | if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) | 3453 | if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER))) |
3427 | return -EINVAL; | 3454 | return -EINVAL; |
3428 | /* Can only add if TDLS ... */ | 3455 | /* Can only add if TDLS ... */ |
3429 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)) | 3456 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS)) |
3430 | return -EOPNOTSUPP; | 3457 | return -EOPNOTSUPP; |
3431 | /* ... with external setup is supported */ | 3458 | /* ... with external setup is supported */ |
3432 | if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)) | 3459 | if (!(rdev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)) |
3433 | return -EOPNOTSUPP; | 3460 | return -EOPNOTSUPP; |
3434 | break; | 3461 | break; |
3435 | default: | 3462 | default: |
3436 | return -EOPNOTSUPP; | 3463 | return -EOPNOTSUPP; |
3437 | } | 3464 | } |
3438 | 3465 | ||
3439 | /* be aware of params.vlan when changing code here */ | 3466 | /* be aware of params.vlan when changing code here */ |
3440 | 3467 | ||
3441 | err = rdev_add_station(rdev, dev, mac_addr, ¶ms); | 3468 | err = rdev_add_station(rdev, dev, mac_addr, ¶ms); |
3442 | 3469 | ||
3443 | if (params.vlan) | 3470 | if (params.vlan) |
3444 | dev_put(params.vlan); | 3471 | dev_put(params.vlan); |
3445 | return err; | 3472 | return err; |
3446 | } | 3473 | } |
3447 | 3474 | ||
3448 | static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) | 3475 | static int nl80211_del_station(struct sk_buff *skb, struct genl_info *info) |
3449 | { | 3476 | { |
3450 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3477 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3451 | struct net_device *dev = info->user_ptr[1]; | 3478 | struct net_device *dev = info->user_ptr[1]; |
3452 | u8 *mac_addr = NULL; | 3479 | u8 *mac_addr = NULL; |
3453 | 3480 | ||
3454 | if (info->attrs[NL80211_ATTR_MAC]) | 3481 | if (info->attrs[NL80211_ATTR_MAC]) |
3455 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3482 | mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3456 | 3483 | ||
3457 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 3484 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
3458 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && | 3485 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP_VLAN && |
3459 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && | 3486 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT && |
3460 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 3487 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
3461 | return -EINVAL; | 3488 | return -EINVAL; |
3462 | 3489 | ||
3463 | if (!rdev->ops->del_station) | 3490 | if (!rdev->ops->del_station) |
3464 | return -EOPNOTSUPP; | 3491 | return -EOPNOTSUPP; |
3465 | 3492 | ||
3466 | return rdev_del_station(rdev, dev, mac_addr); | 3493 | return rdev_del_station(rdev, dev, mac_addr); |
3467 | } | 3494 | } |
3468 | 3495 | ||
3469 | static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, | 3496 | static int nl80211_send_mpath(struct sk_buff *msg, u32 portid, u32 seq, |
3470 | int flags, struct net_device *dev, | 3497 | int flags, struct net_device *dev, |
3471 | u8 *dst, u8 *next_hop, | 3498 | u8 *dst, u8 *next_hop, |
3472 | struct mpath_info *pinfo) | 3499 | struct mpath_info *pinfo) |
3473 | { | 3500 | { |
3474 | void *hdr; | 3501 | void *hdr; |
3475 | struct nlattr *pinfoattr; | 3502 | struct nlattr *pinfoattr; |
3476 | 3503 | ||
3477 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); | 3504 | hdr = nl80211hdr_put(msg, portid, seq, flags, NL80211_CMD_NEW_STATION); |
3478 | if (!hdr) | 3505 | if (!hdr) |
3479 | return -1; | 3506 | return -1; |
3480 | 3507 | ||
3481 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 3508 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
3482 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) || | 3509 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, dst) || |
3483 | nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) || | 3510 | nla_put(msg, NL80211_ATTR_MPATH_NEXT_HOP, ETH_ALEN, next_hop) || |
3484 | nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation)) | 3511 | nla_put_u32(msg, NL80211_ATTR_GENERATION, pinfo->generation)) |
3485 | goto nla_put_failure; | 3512 | goto nla_put_failure; |
3486 | 3513 | ||
3487 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO); | 3514 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_MPATH_INFO); |
3488 | if (!pinfoattr) | 3515 | if (!pinfoattr) |
3489 | goto nla_put_failure; | 3516 | goto nla_put_failure; |
3490 | if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) && | 3517 | if ((pinfo->filled & MPATH_INFO_FRAME_QLEN) && |
3491 | nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN, | 3518 | nla_put_u32(msg, NL80211_MPATH_INFO_FRAME_QLEN, |
3492 | pinfo->frame_qlen)) | 3519 | pinfo->frame_qlen)) |
3493 | goto nla_put_failure; | 3520 | goto nla_put_failure; |
3494 | if (((pinfo->filled & MPATH_INFO_SN) && | 3521 | if (((pinfo->filled & MPATH_INFO_SN) && |
3495 | nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) || | 3522 | nla_put_u32(msg, NL80211_MPATH_INFO_SN, pinfo->sn)) || |
3496 | ((pinfo->filled & MPATH_INFO_METRIC) && | 3523 | ((pinfo->filled & MPATH_INFO_METRIC) && |
3497 | nla_put_u32(msg, NL80211_MPATH_INFO_METRIC, | 3524 | nla_put_u32(msg, NL80211_MPATH_INFO_METRIC, |
3498 | pinfo->metric)) || | 3525 | pinfo->metric)) || |
3499 | ((pinfo->filled & MPATH_INFO_EXPTIME) && | 3526 | ((pinfo->filled & MPATH_INFO_EXPTIME) && |
3500 | nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME, | 3527 | nla_put_u32(msg, NL80211_MPATH_INFO_EXPTIME, |
3501 | pinfo->exptime)) || | 3528 | pinfo->exptime)) || |
3502 | ((pinfo->filled & MPATH_INFO_FLAGS) && | 3529 | ((pinfo->filled & MPATH_INFO_FLAGS) && |
3503 | nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS, | 3530 | nla_put_u8(msg, NL80211_MPATH_INFO_FLAGS, |
3504 | pinfo->flags)) || | 3531 | pinfo->flags)) || |
3505 | ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) && | 3532 | ((pinfo->filled & MPATH_INFO_DISCOVERY_TIMEOUT) && |
3506 | nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, | 3533 | nla_put_u32(msg, NL80211_MPATH_INFO_DISCOVERY_TIMEOUT, |
3507 | pinfo->discovery_timeout)) || | 3534 | pinfo->discovery_timeout)) || |
3508 | ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) && | 3535 | ((pinfo->filled & MPATH_INFO_DISCOVERY_RETRIES) && |
3509 | nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES, | 3536 | nla_put_u8(msg, NL80211_MPATH_INFO_DISCOVERY_RETRIES, |
3510 | pinfo->discovery_retries))) | 3537 | pinfo->discovery_retries))) |
3511 | goto nla_put_failure; | 3538 | goto nla_put_failure; |
3512 | 3539 | ||
3513 | nla_nest_end(msg, pinfoattr); | 3540 | nla_nest_end(msg, pinfoattr); |
3514 | 3541 | ||
3515 | return genlmsg_end(msg, hdr); | 3542 | return genlmsg_end(msg, hdr); |
3516 | 3543 | ||
3517 | nla_put_failure: | 3544 | nla_put_failure: |
3518 | genlmsg_cancel(msg, hdr); | 3545 | genlmsg_cancel(msg, hdr); |
3519 | return -EMSGSIZE; | 3546 | return -EMSGSIZE; |
3520 | } | 3547 | } |
3521 | 3548 | ||
3522 | static int nl80211_dump_mpath(struct sk_buff *skb, | 3549 | static int nl80211_dump_mpath(struct sk_buff *skb, |
3523 | struct netlink_callback *cb) | 3550 | struct netlink_callback *cb) |
3524 | { | 3551 | { |
3525 | struct mpath_info pinfo; | 3552 | struct mpath_info pinfo; |
3526 | struct cfg80211_registered_device *dev; | 3553 | struct cfg80211_registered_device *dev; |
3527 | struct net_device *netdev; | 3554 | struct net_device *netdev; |
3528 | u8 dst[ETH_ALEN]; | 3555 | u8 dst[ETH_ALEN]; |
3529 | u8 next_hop[ETH_ALEN]; | 3556 | u8 next_hop[ETH_ALEN]; |
3530 | int path_idx = cb->args[1]; | 3557 | int path_idx = cb->args[1]; |
3531 | int err; | 3558 | int err; |
3532 | 3559 | ||
3533 | err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); | 3560 | err = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); |
3534 | if (err) | 3561 | if (err) |
3535 | return err; | 3562 | return err; |
3536 | 3563 | ||
3537 | if (!dev->ops->dump_mpath) { | 3564 | if (!dev->ops->dump_mpath) { |
3538 | err = -EOPNOTSUPP; | 3565 | err = -EOPNOTSUPP; |
3539 | goto out_err; | 3566 | goto out_err; |
3540 | } | 3567 | } |
3541 | 3568 | ||
3542 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { | 3569 | if (netdev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) { |
3543 | err = -EOPNOTSUPP; | 3570 | err = -EOPNOTSUPP; |
3544 | goto out_err; | 3571 | goto out_err; |
3545 | } | 3572 | } |
3546 | 3573 | ||
3547 | while (1) { | 3574 | while (1) { |
3548 | err = rdev_dump_mpath(dev, netdev, path_idx, dst, next_hop, | 3575 | err = rdev_dump_mpath(dev, netdev, path_idx, dst, next_hop, |
3549 | &pinfo); | 3576 | &pinfo); |
3550 | if (err == -ENOENT) | 3577 | if (err == -ENOENT) |
3551 | break; | 3578 | break; |
3552 | if (err) | 3579 | if (err) |
3553 | goto out_err; | 3580 | goto out_err; |
3554 | 3581 | ||
3555 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, | 3582 | if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).portid, |
3556 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 3583 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
3557 | netdev, dst, next_hop, | 3584 | netdev, dst, next_hop, |
3558 | &pinfo) < 0) | 3585 | &pinfo) < 0) |
3559 | goto out; | 3586 | goto out; |
3560 | 3587 | ||
3561 | path_idx++; | 3588 | path_idx++; |
3562 | } | 3589 | } |
3563 | 3590 | ||
3564 | 3591 | ||
3565 | out: | 3592 | out: |
3566 | cb->args[1] = path_idx; | 3593 | cb->args[1] = path_idx; |
3567 | err = skb->len; | 3594 | err = skb->len; |
3568 | out_err: | 3595 | out_err: |
3569 | nl80211_finish_netdev_dump(dev); | 3596 | nl80211_finish_netdev_dump(dev); |
3570 | return err; | 3597 | return err; |
3571 | } | 3598 | } |
3572 | 3599 | ||
3573 | static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) | 3600 | static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info) |
3574 | { | 3601 | { |
3575 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3602 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3576 | int err; | 3603 | int err; |
3577 | struct net_device *dev = info->user_ptr[1]; | 3604 | struct net_device *dev = info->user_ptr[1]; |
3578 | struct mpath_info pinfo; | 3605 | struct mpath_info pinfo; |
3579 | struct sk_buff *msg; | 3606 | struct sk_buff *msg; |
3580 | u8 *dst = NULL; | 3607 | u8 *dst = NULL; |
3581 | u8 next_hop[ETH_ALEN]; | 3608 | u8 next_hop[ETH_ALEN]; |
3582 | 3609 | ||
3583 | memset(&pinfo, 0, sizeof(pinfo)); | 3610 | memset(&pinfo, 0, sizeof(pinfo)); |
3584 | 3611 | ||
3585 | if (!info->attrs[NL80211_ATTR_MAC]) | 3612 | if (!info->attrs[NL80211_ATTR_MAC]) |
3586 | return -EINVAL; | 3613 | return -EINVAL; |
3587 | 3614 | ||
3588 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3615 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3589 | 3616 | ||
3590 | if (!rdev->ops->get_mpath) | 3617 | if (!rdev->ops->get_mpath) |
3591 | return -EOPNOTSUPP; | 3618 | return -EOPNOTSUPP; |
3592 | 3619 | ||
3593 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 3620 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
3594 | return -EOPNOTSUPP; | 3621 | return -EOPNOTSUPP; |
3595 | 3622 | ||
3596 | err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo); | 3623 | err = rdev_get_mpath(rdev, dev, dst, next_hop, &pinfo); |
3597 | if (err) | 3624 | if (err) |
3598 | return err; | 3625 | return err; |
3599 | 3626 | ||
3600 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 3627 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
3601 | if (!msg) | 3628 | if (!msg) |
3602 | return -ENOMEM; | 3629 | return -ENOMEM; |
3603 | 3630 | ||
3604 | if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, | 3631 | if (nl80211_send_mpath(msg, info->snd_portid, info->snd_seq, 0, |
3605 | dev, dst, next_hop, &pinfo) < 0) { | 3632 | dev, dst, next_hop, &pinfo) < 0) { |
3606 | nlmsg_free(msg); | 3633 | nlmsg_free(msg); |
3607 | return -ENOBUFS; | 3634 | return -ENOBUFS; |
3608 | } | 3635 | } |
3609 | 3636 | ||
3610 | return genlmsg_reply(msg, info); | 3637 | return genlmsg_reply(msg, info); |
3611 | } | 3638 | } |
3612 | 3639 | ||
3613 | static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) | 3640 | static int nl80211_set_mpath(struct sk_buff *skb, struct genl_info *info) |
3614 | { | 3641 | { |
3615 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3642 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3616 | struct net_device *dev = info->user_ptr[1]; | 3643 | struct net_device *dev = info->user_ptr[1]; |
3617 | u8 *dst = NULL; | 3644 | u8 *dst = NULL; |
3618 | u8 *next_hop = NULL; | 3645 | u8 *next_hop = NULL; |
3619 | 3646 | ||
3620 | if (!info->attrs[NL80211_ATTR_MAC]) | 3647 | if (!info->attrs[NL80211_ATTR_MAC]) |
3621 | return -EINVAL; | 3648 | return -EINVAL; |
3622 | 3649 | ||
3623 | if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]) | 3650 | if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]) |
3624 | return -EINVAL; | 3651 | return -EINVAL; |
3625 | 3652 | ||
3626 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3653 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3627 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); | 3654 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); |
3628 | 3655 | ||
3629 | if (!rdev->ops->change_mpath) | 3656 | if (!rdev->ops->change_mpath) |
3630 | return -EOPNOTSUPP; | 3657 | return -EOPNOTSUPP; |
3631 | 3658 | ||
3632 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 3659 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
3633 | return -EOPNOTSUPP; | 3660 | return -EOPNOTSUPP; |
3634 | 3661 | ||
3635 | return rdev_change_mpath(rdev, dev, dst, next_hop); | 3662 | return rdev_change_mpath(rdev, dev, dst, next_hop); |
3636 | } | 3663 | } |
3637 | 3664 | ||
3638 | static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) | 3665 | static int nl80211_new_mpath(struct sk_buff *skb, struct genl_info *info) |
3639 | { | 3666 | { |
3640 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3667 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3641 | struct net_device *dev = info->user_ptr[1]; | 3668 | struct net_device *dev = info->user_ptr[1]; |
3642 | u8 *dst = NULL; | 3669 | u8 *dst = NULL; |
3643 | u8 *next_hop = NULL; | 3670 | u8 *next_hop = NULL; |
3644 | 3671 | ||
3645 | if (!info->attrs[NL80211_ATTR_MAC]) | 3672 | if (!info->attrs[NL80211_ATTR_MAC]) |
3646 | return -EINVAL; | 3673 | return -EINVAL; |
3647 | 3674 | ||
3648 | if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]) | 3675 | if (!info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]) |
3649 | return -EINVAL; | 3676 | return -EINVAL; |
3650 | 3677 | ||
3651 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3678 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3652 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); | 3679 | next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]); |
3653 | 3680 | ||
3654 | if (!rdev->ops->add_mpath) | 3681 | if (!rdev->ops->add_mpath) |
3655 | return -EOPNOTSUPP; | 3682 | return -EOPNOTSUPP; |
3656 | 3683 | ||
3657 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 3684 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
3658 | return -EOPNOTSUPP; | 3685 | return -EOPNOTSUPP; |
3659 | 3686 | ||
3660 | return rdev_add_mpath(rdev, dev, dst, next_hop); | 3687 | return rdev_add_mpath(rdev, dev, dst, next_hop); |
3661 | } | 3688 | } |
3662 | 3689 | ||
3663 | static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) | 3690 | static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info) |
3664 | { | 3691 | { |
3665 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3692 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3666 | struct net_device *dev = info->user_ptr[1]; | 3693 | struct net_device *dev = info->user_ptr[1]; |
3667 | u8 *dst = NULL; | 3694 | u8 *dst = NULL; |
3668 | 3695 | ||
3669 | if (info->attrs[NL80211_ATTR_MAC]) | 3696 | if (info->attrs[NL80211_ATTR_MAC]) |
3670 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); | 3697 | dst = nla_data(info->attrs[NL80211_ATTR_MAC]); |
3671 | 3698 | ||
3672 | if (!rdev->ops->del_mpath) | 3699 | if (!rdev->ops->del_mpath) |
3673 | return -EOPNOTSUPP; | 3700 | return -EOPNOTSUPP; |
3674 | 3701 | ||
3675 | return rdev_del_mpath(rdev, dev, dst); | 3702 | return rdev_del_mpath(rdev, dev, dst); |
3676 | } | 3703 | } |
3677 | 3704 | ||
3678 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) | 3705 | static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info) |
3679 | { | 3706 | { |
3680 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3707 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3681 | struct net_device *dev = info->user_ptr[1]; | 3708 | struct net_device *dev = info->user_ptr[1]; |
3682 | struct bss_parameters params; | 3709 | struct bss_parameters params; |
3683 | 3710 | ||
3684 | memset(¶ms, 0, sizeof(params)); | 3711 | memset(¶ms, 0, sizeof(params)); |
3685 | /* default to not changing parameters */ | 3712 | /* default to not changing parameters */ |
3686 | params.use_cts_prot = -1; | 3713 | params.use_cts_prot = -1; |
3687 | params.use_short_preamble = -1; | 3714 | params.use_short_preamble = -1; |
3688 | params.use_short_slot_time = -1; | 3715 | params.use_short_slot_time = -1; |
3689 | params.ap_isolate = -1; | 3716 | params.ap_isolate = -1; |
3690 | params.ht_opmode = -1; | 3717 | params.ht_opmode = -1; |
3691 | params.p2p_ctwindow = -1; | 3718 | params.p2p_ctwindow = -1; |
3692 | params.p2p_opp_ps = -1; | 3719 | params.p2p_opp_ps = -1; |
3693 | 3720 | ||
3694 | if (info->attrs[NL80211_ATTR_BSS_CTS_PROT]) | 3721 | if (info->attrs[NL80211_ATTR_BSS_CTS_PROT]) |
3695 | params.use_cts_prot = | 3722 | params.use_cts_prot = |
3696 | nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]); | 3723 | nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]); |
3697 | if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]) | 3724 | if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]) |
3698 | params.use_short_preamble = | 3725 | params.use_short_preamble = |
3699 | nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]); | 3726 | nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]); |
3700 | if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]) | 3727 | if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]) |
3701 | params.use_short_slot_time = | 3728 | params.use_short_slot_time = |
3702 | nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]); | 3729 | nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]); |
3703 | if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { | 3730 | if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { |
3704 | params.basic_rates = | 3731 | params.basic_rates = |
3705 | nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | 3732 | nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); |
3706 | params.basic_rates_len = | 3733 | params.basic_rates_len = |
3707 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | 3734 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); |
3708 | } | 3735 | } |
3709 | if (info->attrs[NL80211_ATTR_AP_ISOLATE]) | 3736 | if (info->attrs[NL80211_ATTR_AP_ISOLATE]) |
3710 | params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); | 3737 | params.ap_isolate = !!nla_get_u8(info->attrs[NL80211_ATTR_AP_ISOLATE]); |
3711 | if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE]) | 3738 | if (info->attrs[NL80211_ATTR_BSS_HT_OPMODE]) |
3712 | params.ht_opmode = | 3739 | params.ht_opmode = |
3713 | nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]); | 3740 | nla_get_u16(info->attrs[NL80211_ATTR_BSS_HT_OPMODE]); |
3714 | 3741 | ||
3715 | if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) { | 3742 | if (info->attrs[NL80211_ATTR_P2P_CTWINDOW]) { |
3716 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 3743 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
3717 | return -EINVAL; | 3744 | return -EINVAL; |
3718 | params.p2p_ctwindow = | 3745 | params.p2p_ctwindow = |
3719 | nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]); | 3746 | nla_get_s8(info->attrs[NL80211_ATTR_P2P_CTWINDOW]); |
3720 | if (params.p2p_ctwindow < 0) | 3747 | if (params.p2p_ctwindow < 0) |
3721 | return -EINVAL; | 3748 | return -EINVAL; |
3722 | if (params.p2p_ctwindow != 0 && | 3749 | if (params.p2p_ctwindow != 0 && |
3723 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) | 3750 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_CTWIN)) |
3724 | return -EINVAL; | 3751 | return -EINVAL; |
3725 | } | 3752 | } |
3726 | 3753 | ||
3727 | if (info->attrs[NL80211_ATTR_P2P_OPPPS]) { | 3754 | if (info->attrs[NL80211_ATTR_P2P_OPPPS]) { |
3728 | u8 tmp; | 3755 | u8 tmp; |
3729 | 3756 | ||
3730 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 3757 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
3731 | return -EINVAL; | 3758 | return -EINVAL; |
3732 | tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]); | 3759 | tmp = nla_get_u8(info->attrs[NL80211_ATTR_P2P_OPPPS]); |
3733 | if (tmp > 1) | 3760 | if (tmp > 1) |
3734 | return -EINVAL; | 3761 | return -EINVAL; |
3735 | params.p2p_opp_ps = tmp; | 3762 | params.p2p_opp_ps = tmp; |
3736 | if (params.p2p_opp_ps && | 3763 | if (params.p2p_opp_ps && |
3737 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) | 3764 | !(rdev->wiphy.features & NL80211_FEATURE_P2P_GO_OPPPS)) |
3738 | return -EINVAL; | 3765 | return -EINVAL; |
3739 | } | 3766 | } |
3740 | 3767 | ||
3741 | if (!rdev->ops->change_bss) | 3768 | if (!rdev->ops->change_bss) |
3742 | return -EOPNOTSUPP; | 3769 | return -EOPNOTSUPP; |
3743 | 3770 | ||
3744 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && | 3771 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_AP && |
3745 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) | 3772 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_GO) |
3746 | return -EOPNOTSUPP; | 3773 | return -EOPNOTSUPP; |
3747 | 3774 | ||
3748 | return rdev_change_bss(rdev, dev, ¶ms); | 3775 | return rdev_change_bss(rdev, dev, ¶ms); |
3749 | } | 3776 | } |
3750 | 3777 | ||
3751 | static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { | 3778 | static const struct nla_policy reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = { |
3752 | [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 }, | 3779 | [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 }, |
3753 | [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 }, | 3780 | [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 }, |
3754 | [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 }, | 3781 | [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 }, |
3755 | [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 }, | 3782 | [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 }, |
3756 | [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 }, | 3783 | [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 }, |
3757 | [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, | 3784 | [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 }, |
3758 | }; | 3785 | }; |
3759 | 3786 | ||
3760 | static int parse_reg_rule(struct nlattr *tb[], | 3787 | static int parse_reg_rule(struct nlattr *tb[], |
3761 | struct ieee80211_reg_rule *reg_rule) | 3788 | struct ieee80211_reg_rule *reg_rule) |
3762 | { | 3789 | { |
3763 | struct ieee80211_freq_range *freq_range = ®_rule->freq_range; | 3790 | struct ieee80211_freq_range *freq_range = ®_rule->freq_range; |
3764 | struct ieee80211_power_rule *power_rule = ®_rule->power_rule; | 3791 | struct ieee80211_power_rule *power_rule = ®_rule->power_rule; |
3765 | 3792 | ||
3766 | if (!tb[NL80211_ATTR_REG_RULE_FLAGS]) | 3793 | if (!tb[NL80211_ATTR_REG_RULE_FLAGS]) |
3767 | return -EINVAL; | 3794 | return -EINVAL; |
3768 | if (!tb[NL80211_ATTR_FREQ_RANGE_START]) | 3795 | if (!tb[NL80211_ATTR_FREQ_RANGE_START]) |
3769 | return -EINVAL; | 3796 | return -EINVAL; |
3770 | if (!tb[NL80211_ATTR_FREQ_RANGE_END]) | 3797 | if (!tb[NL80211_ATTR_FREQ_RANGE_END]) |
3771 | return -EINVAL; | 3798 | return -EINVAL; |
3772 | if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) | 3799 | if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]) |
3773 | return -EINVAL; | 3800 | return -EINVAL; |
3774 | if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) | 3801 | if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]) |
3775 | return -EINVAL; | 3802 | return -EINVAL; |
3776 | 3803 | ||
3777 | reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]); | 3804 | reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]); |
3778 | 3805 | ||
3779 | freq_range->start_freq_khz = | 3806 | freq_range->start_freq_khz = |
3780 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); | 3807 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]); |
3781 | freq_range->end_freq_khz = | 3808 | freq_range->end_freq_khz = |
3782 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); | 3809 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]); |
3783 | freq_range->max_bandwidth_khz = | 3810 | freq_range->max_bandwidth_khz = |
3784 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); | 3811 | nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]); |
3785 | 3812 | ||
3786 | power_rule->max_eirp = | 3813 | power_rule->max_eirp = |
3787 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); | 3814 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]); |
3788 | 3815 | ||
3789 | if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]) | 3816 | if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]) |
3790 | power_rule->max_antenna_gain = | 3817 | power_rule->max_antenna_gain = |
3791 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]); | 3818 | nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]); |
3792 | 3819 | ||
3793 | return 0; | 3820 | return 0; |
3794 | } | 3821 | } |
3795 | 3822 | ||
3796 | static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) | 3823 | static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info) |
3797 | { | 3824 | { |
3798 | int r; | 3825 | int r; |
3799 | char *data = NULL; | 3826 | char *data = NULL; |
3800 | enum nl80211_user_reg_hint_type user_reg_hint_type; | 3827 | enum nl80211_user_reg_hint_type user_reg_hint_type; |
3801 | 3828 | ||
3802 | /* | 3829 | /* |
3803 | * You should only get this when cfg80211 hasn't yet initialized | 3830 | * You should only get this when cfg80211 hasn't yet initialized |
3804 | * completely when built-in to the kernel right between the time | 3831 | * completely when built-in to the kernel right between the time |
3805 | * window between nl80211_init() and regulatory_init(), if that is | 3832 | * window between nl80211_init() and regulatory_init(), if that is |
3806 | * even possible. | 3833 | * even possible. |
3807 | */ | 3834 | */ |
3808 | if (unlikely(!rcu_access_pointer(cfg80211_regdomain))) | 3835 | if (unlikely(!rcu_access_pointer(cfg80211_regdomain))) |
3809 | return -EINPROGRESS; | 3836 | return -EINPROGRESS; |
3810 | 3837 | ||
3811 | if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) | 3838 | if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) |
3812 | return -EINVAL; | 3839 | return -EINVAL; |
3813 | 3840 | ||
3814 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); | 3841 | data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); |
3815 | 3842 | ||
3816 | if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]) | 3843 | if (info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]) |
3817 | user_reg_hint_type = | 3844 | user_reg_hint_type = |
3818 | nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]); | 3845 | nla_get_u32(info->attrs[NL80211_ATTR_USER_REG_HINT_TYPE]); |
3819 | else | 3846 | else |
3820 | user_reg_hint_type = NL80211_USER_REG_HINT_USER; | 3847 | user_reg_hint_type = NL80211_USER_REG_HINT_USER; |
3821 | 3848 | ||
3822 | switch (user_reg_hint_type) { | 3849 | switch (user_reg_hint_type) { |
3823 | case NL80211_USER_REG_HINT_USER: | 3850 | case NL80211_USER_REG_HINT_USER: |
3824 | case NL80211_USER_REG_HINT_CELL_BASE: | 3851 | case NL80211_USER_REG_HINT_CELL_BASE: |
3825 | break; | 3852 | break; |
3826 | default: | 3853 | default: |
3827 | return -EINVAL; | 3854 | return -EINVAL; |
3828 | } | 3855 | } |
3829 | 3856 | ||
3830 | r = regulatory_hint_user(data, user_reg_hint_type); | 3857 | r = regulatory_hint_user(data, user_reg_hint_type); |
3831 | 3858 | ||
3832 | return r; | 3859 | return r; |
3833 | } | 3860 | } |
3834 | 3861 | ||
3835 | static int nl80211_get_mesh_config(struct sk_buff *skb, | 3862 | static int nl80211_get_mesh_config(struct sk_buff *skb, |
3836 | struct genl_info *info) | 3863 | struct genl_info *info) |
3837 | { | 3864 | { |
3838 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3865 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3839 | struct net_device *dev = info->user_ptr[1]; | 3866 | struct net_device *dev = info->user_ptr[1]; |
3840 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 3867 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
3841 | struct mesh_config cur_params; | 3868 | struct mesh_config cur_params; |
3842 | int err = 0; | 3869 | int err = 0; |
3843 | void *hdr; | 3870 | void *hdr; |
3844 | struct nlattr *pinfoattr; | 3871 | struct nlattr *pinfoattr; |
3845 | struct sk_buff *msg; | 3872 | struct sk_buff *msg; |
3846 | 3873 | ||
3847 | if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) | 3874 | if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) |
3848 | return -EOPNOTSUPP; | 3875 | return -EOPNOTSUPP; |
3849 | 3876 | ||
3850 | if (!rdev->ops->get_mesh_config) | 3877 | if (!rdev->ops->get_mesh_config) |
3851 | return -EOPNOTSUPP; | 3878 | return -EOPNOTSUPP; |
3852 | 3879 | ||
3853 | wdev_lock(wdev); | 3880 | wdev_lock(wdev); |
3854 | /* If not connected, get default parameters */ | 3881 | /* If not connected, get default parameters */ |
3855 | if (!wdev->mesh_id_len) | 3882 | if (!wdev->mesh_id_len) |
3856 | memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); | 3883 | memcpy(&cur_params, &default_mesh_config, sizeof(cur_params)); |
3857 | else | 3884 | else |
3858 | err = rdev_get_mesh_config(rdev, dev, &cur_params); | 3885 | err = rdev_get_mesh_config(rdev, dev, &cur_params); |
3859 | wdev_unlock(wdev); | 3886 | wdev_unlock(wdev); |
3860 | 3887 | ||
3861 | if (err) | 3888 | if (err) |
3862 | return err; | 3889 | return err; |
3863 | 3890 | ||
3864 | /* Draw up a netlink message to send back */ | 3891 | /* Draw up a netlink message to send back */ |
3865 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 3892 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
3866 | if (!msg) | 3893 | if (!msg) |
3867 | return -ENOMEM; | 3894 | return -ENOMEM; |
3868 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 3895 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
3869 | NL80211_CMD_GET_MESH_CONFIG); | 3896 | NL80211_CMD_GET_MESH_CONFIG); |
3870 | if (!hdr) | 3897 | if (!hdr) |
3871 | goto out; | 3898 | goto out; |
3872 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG); | 3899 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_MESH_CONFIG); |
3873 | if (!pinfoattr) | 3900 | if (!pinfoattr) |
3874 | goto nla_put_failure; | 3901 | goto nla_put_failure; |
3875 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 3902 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
3876 | nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT, | 3903 | nla_put_u16(msg, NL80211_MESHCONF_RETRY_TIMEOUT, |
3877 | cur_params.dot11MeshRetryTimeout) || | 3904 | cur_params.dot11MeshRetryTimeout) || |
3878 | nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT, | 3905 | nla_put_u16(msg, NL80211_MESHCONF_CONFIRM_TIMEOUT, |
3879 | cur_params.dot11MeshConfirmTimeout) || | 3906 | cur_params.dot11MeshConfirmTimeout) || |
3880 | nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT, | 3907 | nla_put_u16(msg, NL80211_MESHCONF_HOLDING_TIMEOUT, |
3881 | cur_params.dot11MeshHoldingTimeout) || | 3908 | cur_params.dot11MeshHoldingTimeout) || |
3882 | nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS, | 3909 | nla_put_u16(msg, NL80211_MESHCONF_MAX_PEER_LINKS, |
3883 | cur_params.dot11MeshMaxPeerLinks) || | 3910 | cur_params.dot11MeshMaxPeerLinks) || |
3884 | nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES, | 3911 | nla_put_u8(msg, NL80211_MESHCONF_MAX_RETRIES, |
3885 | cur_params.dot11MeshMaxRetries) || | 3912 | cur_params.dot11MeshMaxRetries) || |
3886 | nla_put_u8(msg, NL80211_MESHCONF_TTL, | 3913 | nla_put_u8(msg, NL80211_MESHCONF_TTL, |
3887 | cur_params.dot11MeshTTL) || | 3914 | cur_params.dot11MeshTTL) || |
3888 | nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL, | 3915 | nla_put_u8(msg, NL80211_MESHCONF_ELEMENT_TTL, |
3889 | cur_params.element_ttl) || | 3916 | cur_params.element_ttl) || |
3890 | nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, | 3917 | nla_put_u8(msg, NL80211_MESHCONF_AUTO_OPEN_PLINKS, |
3891 | cur_params.auto_open_plinks) || | 3918 | cur_params.auto_open_plinks) || |
3892 | nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, | 3919 | nla_put_u32(msg, NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, |
3893 | cur_params.dot11MeshNbrOffsetMaxNeighbor) || | 3920 | cur_params.dot11MeshNbrOffsetMaxNeighbor) || |
3894 | nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, | 3921 | nla_put_u8(msg, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, |
3895 | cur_params.dot11MeshHWMPmaxPREQretries) || | 3922 | cur_params.dot11MeshHWMPmaxPREQretries) || |
3896 | nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME, | 3923 | nla_put_u32(msg, NL80211_MESHCONF_PATH_REFRESH_TIME, |
3897 | cur_params.path_refresh_time) || | 3924 | cur_params.path_refresh_time) || |
3898 | nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, | 3925 | nla_put_u16(msg, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, |
3899 | cur_params.min_discovery_timeout) || | 3926 | cur_params.min_discovery_timeout) || |
3900 | nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, | 3927 | nla_put_u32(msg, NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, |
3901 | cur_params.dot11MeshHWMPactivePathTimeout) || | 3928 | cur_params.dot11MeshHWMPactivePathTimeout) || |
3902 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, | 3929 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, |
3903 | cur_params.dot11MeshHWMPpreqMinInterval) || | 3930 | cur_params.dot11MeshHWMPpreqMinInterval) || |
3904 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, | 3931 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, |
3905 | cur_params.dot11MeshHWMPperrMinInterval) || | 3932 | cur_params.dot11MeshHWMPperrMinInterval) || |
3906 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, | 3933 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, |
3907 | cur_params.dot11MeshHWMPnetDiameterTraversalTime) || | 3934 | cur_params.dot11MeshHWMPnetDiameterTraversalTime) || |
3908 | nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, | 3935 | nla_put_u8(msg, NL80211_MESHCONF_HWMP_ROOTMODE, |
3909 | cur_params.dot11MeshHWMPRootMode) || | 3936 | cur_params.dot11MeshHWMPRootMode) || |
3910 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL, | 3937 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_RANN_INTERVAL, |
3911 | cur_params.dot11MeshHWMPRannInterval) || | 3938 | cur_params.dot11MeshHWMPRannInterval) || |
3912 | nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, | 3939 | nla_put_u8(msg, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, |
3913 | cur_params.dot11MeshGateAnnouncementProtocol) || | 3940 | cur_params.dot11MeshGateAnnouncementProtocol) || |
3914 | nla_put_u8(msg, NL80211_MESHCONF_FORWARDING, | 3941 | nla_put_u8(msg, NL80211_MESHCONF_FORWARDING, |
3915 | cur_params.dot11MeshForwarding) || | 3942 | cur_params.dot11MeshForwarding) || |
3916 | nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, | 3943 | nla_put_u32(msg, NL80211_MESHCONF_RSSI_THRESHOLD, |
3917 | cur_params.rssi_threshold) || | 3944 | cur_params.rssi_threshold) || |
3918 | nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE, | 3945 | nla_put_u32(msg, NL80211_MESHCONF_HT_OPMODE, |
3919 | cur_params.ht_opmode) || | 3946 | cur_params.ht_opmode) || |
3920 | nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, | 3947 | nla_put_u32(msg, NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, |
3921 | cur_params.dot11MeshHWMPactivePathToRootTimeout) || | 3948 | cur_params.dot11MeshHWMPactivePathToRootTimeout) || |
3922 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, | 3949 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, |
3923 | cur_params.dot11MeshHWMProotInterval) || | 3950 | cur_params.dot11MeshHWMProotInterval) || |
3924 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, | 3951 | nla_put_u16(msg, NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, |
3925 | cur_params.dot11MeshHWMPconfirmationInterval)) | 3952 | cur_params.dot11MeshHWMPconfirmationInterval) || |
3953 | nla_put_u32(msg, NL80211_MESHCONF_POWER_MODE, | ||
3954 | cur_params.power_mode) || | ||
3955 | nla_put_u16(msg, NL80211_MESHCONF_AWAKE_WINDOW, | ||
3956 | cur_params.dot11MeshAwakeWindowDuration)) | ||
3926 | goto nla_put_failure; | 3957 | goto nla_put_failure; |
3927 | nla_nest_end(msg, pinfoattr); | 3958 | nla_nest_end(msg, pinfoattr); |
3928 | genlmsg_end(msg, hdr); | 3959 | genlmsg_end(msg, hdr); |
3929 | return genlmsg_reply(msg, info); | 3960 | return genlmsg_reply(msg, info); |
3930 | 3961 | ||
3931 | nla_put_failure: | 3962 | nla_put_failure: |
3932 | genlmsg_cancel(msg, hdr); | 3963 | genlmsg_cancel(msg, hdr); |
3933 | out: | 3964 | out: |
3934 | nlmsg_free(msg); | 3965 | nlmsg_free(msg); |
3935 | return -ENOBUFS; | 3966 | return -ENOBUFS; |
3936 | } | 3967 | } |
3937 | 3968 | ||
3938 | static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { | 3969 | static const struct nla_policy nl80211_meshconf_params_policy[NL80211_MESHCONF_ATTR_MAX+1] = { |
3939 | [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 }, | 3970 | [NL80211_MESHCONF_RETRY_TIMEOUT] = { .type = NLA_U16 }, |
3940 | [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 }, | 3971 | [NL80211_MESHCONF_CONFIRM_TIMEOUT] = { .type = NLA_U16 }, |
3941 | [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 }, | 3972 | [NL80211_MESHCONF_HOLDING_TIMEOUT] = { .type = NLA_U16 }, |
3942 | [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 }, | 3973 | [NL80211_MESHCONF_MAX_PEER_LINKS] = { .type = NLA_U16 }, |
3943 | [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 }, | 3974 | [NL80211_MESHCONF_MAX_RETRIES] = { .type = NLA_U8 }, |
3944 | [NL80211_MESHCONF_TTL] = { .type = NLA_U8 }, | 3975 | [NL80211_MESHCONF_TTL] = { .type = NLA_U8 }, |
3945 | [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, | 3976 | [NL80211_MESHCONF_ELEMENT_TTL] = { .type = NLA_U8 }, |
3946 | [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, | 3977 | [NL80211_MESHCONF_AUTO_OPEN_PLINKS] = { .type = NLA_U8 }, |
3947 | [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 }, | 3978 | [NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR] = { .type = NLA_U32 }, |
3948 | [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, | 3979 | [NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES] = { .type = NLA_U8 }, |
3949 | [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, | 3980 | [NL80211_MESHCONF_PATH_REFRESH_TIME] = { .type = NLA_U32 }, |
3950 | [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, | 3981 | [NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT] = { .type = NLA_U16 }, |
3951 | [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, | 3982 | [NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT] = { .type = NLA_U32 }, |
3952 | [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, | 3983 | [NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL] = { .type = NLA_U16 }, |
3953 | [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 }, | 3984 | [NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL] = { .type = NLA_U16 }, |
3954 | [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, | 3985 | [NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME] = { .type = NLA_U16 }, |
3955 | [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 }, | 3986 | [NL80211_MESHCONF_HWMP_ROOTMODE] = { .type = NLA_U8 }, |
3956 | [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, | 3987 | [NL80211_MESHCONF_HWMP_RANN_INTERVAL] = { .type = NLA_U16 }, |
3957 | [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, | 3988 | [NL80211_MESHCONF_GATE_ANNOUNCEMENTS] = { .type = NLA_U8 }, |
3958 | [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, | 3989 | [NL80211_MESHCONF_FORWARDING] = { .type = NLA_U8 }, |
3959 | [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 }, | 3990 | [NL80211_MESHCONF_RSSI_THRESHOLD] = { .type = NLA_U32 }, |
3960 | [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 }, | 3991 | [NL80211_MESHCONF_HT_OPMODE] = { .type = NLA_U16 }, |
3961 | [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, | 3992 | [NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT] = { .type = NLA_U32 }, |
3962 | [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, | 3993 | [NL80211_MESHCONF_HWMP_ROOT_INTERVAL] = { .type = NLA_U16 }, |
3963 | [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, | 3994 | [NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL] = { .type = NLA_U16 }, |
3995 | [NL80211_MESHCONF_POWER_MODE] = { .type = NLA_U32 }, | ||
3996 | [NL80211_MESHCONF_AWAKE_WINDOW] = { .type = NLA_U16 }, | ||
3964 | }; | 3997 | }; |
3965 | 3998 | ||
3966 | static const struct nla_policy | 3999 | static const struct nla_policy |
3967 | nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { | 4000 | nl80211_mesh_setup_params_policy[NL80211_MESH_SETUP_ATTR_MAX+1] = { |
3968 | [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 }, | 4001 | [NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC] = { .type = NLA_U8 }, |
3969 | [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, | 4002 | [NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL] = { .type = NLA_U8 }, |
3970 | [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, | 4003 | [NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC] = { .type = NLA_U8 }, |
3971 | [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, | 4004 | [NL80211_MESH_SETUP_USERSPACE_AUTH] = { .type = NLA_FLAG }, |
3972 | [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, | 4005 | [NL80211_MESH_SETUP_IE] = { .type = NLA_BINARY, |
3973 | .len = IEEE80211_MAX_DATA_LEN }, | 4006 | .len = IEEE80211_MAX_DATA_LEN }, |
3974 | [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, | 4007 | [NL80211_MESH_SETUP_USERSPACE_AMPE] = { .type = NLA_FLAG }, |
3975 | }; | 4008 | }; |
3976 | 4009 | ||
3977 | static int nl80211_parse_mesh_config(struct genl_info *info, | 4010 | static int nl80211_parse_mesh_config(struct genl_info *info, |
3978 | struct mesh_config *cfg, | 4011 | struct mesh_config *cfg, |
3979 | u32 *mask_out) | 4012 | u32 *mask_out) |
3980 | { | 4013 | { |
3981 | struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; | 4014 | struct nlattr *tb[NL80211_MESHCONF_ATTR_MAX + 1]; |
3982 | u32 mask = 0; | 4015 | u32 mask = 0; |
3983 | 4016 | ||
3984 | #define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \ | 4017 | #define FILL_IN_MESH_PARAM_IF_SET(tb, cfg, param, min, max, mask, attr, fn) \ |
3985 | do { \ | 4018 | do { \ |
3986 | if (tb[attr]) { \ | 4019 | if (tb[attr]) { \ |
3987 | if (fn(tb[attr]) < min || fn(tb[attr]) > max) \ | 4020 | if (fn(tb[attr]) < min || fn(tb[attr]) > max) \ |
3988 | return -EINVAL; \ | 4021 | return -EINVAL; \ |
3989 | cfg->param = fn(tb[attr]); \ | 4022 | cfg->param = fn(tb[attr]); \ |
3990 | mask |= (1 << (attr - 1)); \ | 4023 | mask |= (1 << (attr - 1)); \ |
3991 | } \ | 4024 | } \ |
3992 | } while (0) | 4025 | } while (0) |
3993 | 4026 | ||
3994 | 4027 | ||
3995 | if (!info->attrs[NL80211_ATTR_MESH_CONFIG]) | 4028 | if (!info->attrs[NL80211_ATTR_MESH_CONFIG]) |
3996 | return -EINVAL; | 4029 | return -EINVAL; |
3997 | if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, | 4030 | if (nla_parse_nested(tb, NL80211_MESHCONF_ATTR_MAX, |
3998 | info->attrs[NL80211_ATTR_MESH_CONFIG], | 4031 | info->attrs[NL80211_ATTR_MESH_CONFIG], |
3999 | nl80211_meshconf_params_policy)) | 4032 | nl80211_meshconf_params_policy)) |
4000 | return -EINVAL; | 4033 | return -EINVAL; |
4001 | 4034 | ||
4002 | /* This makes sure that there aren't more than 32 mesh config | 4035 | /* This makes sure that there aren't more than 32 mesh config |
4003 | * parameters (otherwise our bitfield scheme would not work.) */ | 4036 | * parameters (otherwise our bitfield scheme would not work.) */ |
4004 | BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); | 4037 | BUILD_BUG_ON(NL80211_MESHCONF_ATTR_MAX > 32); |
4005 | 4038 | ||
4006 | /* Fill in the params struct */ | 4039 | /* Fill in the params struct */ |
4007 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255, | 4040 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshRetryTimeout, 1, 255, |
4008 | mask, NL80211_MESHCONF_RETRY_TIMEOUT, | 4041 | mask, NL80211_MESHCONF_RETRY_TIMEOUT, |
4009 | nla_get_u16); | 4042 | nla_get_u16); |
4010 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255, | 4043 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshConfirmTimeout, 1, 255, |
4011 | mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, | 4044 | mask, NL80211_MESHCONF_CONFIRM_TIMEOUT, |
4012 | nla_get_u16); | 4045 | nla_get_u16); |
4013 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255, | 4046 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHoldingTimeout, 1, 255, |
4014 | mask, NL80211_MESHCONF_HOLDING_TIMEOUT, | 4047 | mask, NL80211_MESHCONF_HOLDING_TIMEOUT, |
4015 | nla_get_u16); | 4048 | nla_get_u16); |
4016 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255, | 4049 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxPeerLinks, 0, 255, |
4017 | mask, NL80211_MESHCONF_MAX_PEER_LINKS, | 4050 | mask, NL80211_MESHCONF_MAX_PEER_LINKS, |
4018 | nla_get_u16); | 4051 | nla_get_u16); |
4019 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16, | 4052 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshMaxRetries, 0, 16, |
4020 | mask, NL80211_MESHCONF_MAX_RETRIES, | 4053 | mask, NL80211_MESHCONF_MAX_RETRIES, |
4021 | nla_get_u8); | 4054 | nla_get_u8); |
4022 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255, | 4055 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshTTL, 1, 255, |
4023 | mask, NL80211_MESHCONF_TTL, nla_get_u8); | 4056 | mask, NL80211_MESHCONF_TTL, nla_get_u8); |
4024 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255, | 4057 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, element_ttl, 1, 255, |
4025 | mask, NL80211_MESHCONF_ELEMENT_TTL, | 4058 | mask, NL80211_MESHCONF_ELEMENT_TTL, |
4026 | nla_get_u8); | 4059 | nla_get_u8); |
4027 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1, | 4060 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, auto_open_plinks, 0, 1, |
4028 | mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, | 4061 | mask, NL80211_MESHCONF_AUTO_OPEN_PLINKS, |
4029 | nla_get_u8); | 4062 | nla_get_u8); |
4030 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, | 4063 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshNbrOffsetMaxNeighbor, |
4031 | 1, 255, mask, | 4064 | 1, 255, mask, |
4032 | NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, | 4065 | NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, |
4033 | nla_get_u32); | 4066 | nla_get_u32); |
4034 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255, | 4067 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPmaxPREQretries, 0, 255, |
4035 | mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, | 4068 | mask, NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, |
4036 | nla_get_u8); | 4069 | nla_get_u8); |
4037 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535, | 4070 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, path_refresh_time, 1, 65535, |
4038 | mask, NL80211_MESHCONF_PATH_REFRESH_TIME, | 4071 | mask, NL80211_MESHCONF_PATH_REFRESH_TIME, |
4039 | nla_get_u32); | 4072 | nla_get_u32); |
4040 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535, | 4073 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, min_discovery_timeout, 1, 65535, |
4041 | mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, | 4074 | mask, NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, |
4042 | nla_get_u16); | 4075 | nla_get_u16); |
4043 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, | 4076 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathTimeout, |
4044 | 1, 65535, mask, | 4077 | 1, 65535, mask, |
4045 | NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, | 4078 | NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, |
4046 | nla_get_u32); | 4079 | nla_get_u32); |
4047 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, | 4080 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPpreqMinInterval, |
4048 | 1, 65535, mask, | 4081 | 1, 65535, mask, |
4049 | NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, | 4082 | NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, |
4050 | nla_get_u16); | 4083 | nla_get_u16); |
4051 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, | 4084 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPperrMinInterval, |
4052 | 1, 65535, mask, | 4085 | 1, 65535, mask, |
4053 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, | 4086 | NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, |
4054 | nla_get_u16); | 4087 | nla_get_u16); |
4055 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, | 4088 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, |
4056 | dot11MeshHWMPnetDiameterTraversalTime, | 4089 | dot11MeshHWMPnetDiameterTraversalTime, |
4057 | 1, 65535, mask, | 4090 | 1, 65535, mask, |
4058 | NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, | 4091 | NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, |
4059 | nla_get_u16); | 4092 | nla_get_u16); |
4060 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4, | 4093 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRootMode, 0, 4, |
4061 | mask, NL80211_MESHCONF_HWMP_ROOTMODE, | 4094 | mask, NL80211_MESHCONF_HWMP_ROOTMODE, |
4062 | nla_get_u8); | 4095 | nla_get_u8); |
4063 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535, | 4096 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPRannInterval, 1, 65535, |
4064 | mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL, | 4097 | mask, NL80211_MESHCONF_HWMP_RANN_INTERVAL, |
4065 | nla_get_u16); | 4098 | nla_get_u16); |
4066 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, | 4099 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, |
4067 | dot11MeshGateAnnouncementProtocol, 0, 1, | 4100 | dot11MeshGateAnnouncementProtocol, 0, 1, |
4068 | mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, | 4101 | mask, NL80211_MESHCONF_GATE_ANNOUNCEMENTS, |
4069 | nla_get_u8); | 4102 | nla_get_u8); |
4070 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1, | 4103 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshForwarding, 0, 1, |
4071 | mask, NL80211_MESHCONF_FORWARDING, | 4104 | mask, NL80211_MESHCONF_FORWARDING, |
4072 | nla_get_u8); | 4105 | nla_get_u8); |
4073 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, 1, 255, | 4106 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, rssi_threshold, 1, 255, |
4074 | mask, NL80211_MESHCONF_RSSI_THRESHOLD, | 4107 | mask, NL80211_MESHCONF_RSSI_THRESHOLD, |
4075 | nla_get_u32); | 4108 | nla_get_u32); |
4076 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16, | 4109 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, ht_opmode, 0, 16, |
4077 | mask, NL80211_MESHCONF_HT_OPMODE, | 4110 | mask, NL80211_MESHCONF_HT_OPMODE, |
4078 | nla_get_u16); | 4111 | nla_get_u16); |
4079 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout, | 4112 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMPactivePathToRootTimeout, |
4080 | 1, 65535, mask, | 4113 | 1, 65535, mask, |
4081 | NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, | 4114 | NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, |
4082 | nla_get_u32); | 4115 | nla_get_u32); |
4083 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535, | 4116 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshHWMProotInterval, 1, 65535, |
4084 | mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, | 4117 | mask, NL80211_MESHCONF_HWMP_ROOT_INTERVAL, |
4085 | nla_get_u16); | 4118 | nla_get_u16); |
4086 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, | 4119 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, |
4087 | dot11MeshHWMPconfirmationInterval, | 4120 | dot11MeshHWMPconfirmationInterval, |
4088 | 1, 65535, mask, | 4121 | 1, 65535, mask, |
4089 | NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, | 4122 | NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, |
4090 | nla_get_u16); | 4123 | nla_get_u16); |
4124 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, power_mode, | ||
4125 | NL80211_MESH_POWER_ACTIVE, | ||
4126 | NL80211_MESH_POWER_MAX, | ||
4127 | mask, NL80211_MESHCONF_POWER_MODE, | ||
4128 | nla_get_u32); | ||
4129 | FILL_IN_MESH_PARAM_IF_SET(tb, cfg, dot11MeshAwakeWindowDuration, | ||
4130 | 0, 65535, mask, | ||
4131 | NL80211_MESHCONF_AWAKE_WINDOW, nla_get_u16); | ||
4091 | if (mask_out) | 4132 | if (mask_out) |
4092 | *mask_out = mask; | 4133 | *mask_out = mask; |
4093 | 4134 | ||
4094 | return 0; | 4135 | return 0; |
4095 | 4136 | ||
4096 | #undef FILL_IN_MESH_PARAM_IF_SET | 4137 | #undef FILL_IN_MESH_PARAM_IF_SET |
4097 | } | 4138 | } |
4098 | 4139 | ||
4099 | static int nl80211_parse_mesh_setup(struct genl_info *info, | 4140 | static int nl80211_parse_mesh_setup(struct genl_info *info, |
4100 | struct mesh_setup *setup) | 4141 | struct mesh_setup *setup) |
4101 | { | 4142 | { |
4102 | struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1]; | 4143 | struct nlattr *tb[NL80211_MESH_SETUP_ATTR_MAX + 1]; |
4103 | 4144 | ||
4104 | if (!info->attrs[NL80211_ATTR_MESH_SETUP]) | 4145 | if (!info->attrs[NL80211_ATTR_MESH_SETUP]) |
4105 | return -EINVAL; | 4146 | return -EINVAL; |
4106 | if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX, | 4147 | if (nla_parse_nested(tb, NL80211_MESH_SETUP_ATTR_MAX, |
4107 | info->attrs[NL80211_ATTR_MESH_SETUP], | 4148 | info->attrs[NL80211_ATTR_MESH_SETUP], |
4108 | nl80211_mesh_setup_params_policy)) | 4149 | nl80211_mesh_setup_params_policy)) |
4109 | return -EINVAL; | 4150 | return -EINVAL; |
4110 | 4151 | ||
4111 | if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC]) | 4152 | if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC]) |
4112 | setup->sync_method = | 4153 | setup->sync_method = |
4113 | (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ? | 4154 | (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_SYNC])) ? |
4114 | IEEE80211_SYNC_METHOD_VENDOR : | 4155 | IEEE80211_SYNC_METHOD_VENDOR : |
4115 | IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET; | 4156 | IEEE80211_SYNC_METHOD_NEIGHBOR_OFFSET; |
4116 | 4157 | ||
4117 | if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL]) | 4158 | if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL]) |
4118 | setup->path_sel_proto = | 4159 | setup->path_sel_proto = |
4119 | (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ? | 4160 | (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_PATH_SEL])) ? |
4120 | IEEE80211_PATH_PROTOCOL_VENDOR : | 4161 | IEEE80211_PATH_PROTOCOL_VENDOR : |
4121 | IEEE80211_PATH_PROTOCOL_HWMP; | 4162 | IEEE80211_PATH_PROTOCOL_HWMP; |
4122 | 4163 | ||
4123 | if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC]) | 4164 | if (tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC]) |
4124 | setup->path_metric = | 4165 | setup->path_metric = |
4125 | (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ? | 4166 | (nla_get_u8(tb[NL80211_MESH_SETUP_ENABLE_VENDOR_METRIC])) ? |
4126 | IEEE80211_PATH_METRIC_VENDOR : | 4167 | IEEE80211_PATH_METRIC_VENDOR : |
4127 | IEEE80211_PATH_METRIC_AIRTIME; | 4168 | IEEE80211_PATH_METRIC_AIRTIME; |
4128 | 4169 | ||
4129 | 4170 | ||
4130 | if (tb[NL80211_MESH_SETUP_IE]) { | 4171 | if (tb[NL80211_MESH_SETUP_IE]) { |
4131 | struct nlattr *ieattr = | 4172 | struct nlattr *ieattr = |
4132 | tb[NL80211_MESH_SETUP_IE]; | 4173 | tb[NL80211_MESH_SETUP_IE]; |
4133 | if (!is_valid_ie_attr(ieattr)) | 4174 | if (!is_valid_ie_attr(ieattr)) |
4134 | return -EINVAL; | 4175 | return -EINVAL; |
4135 | setup->ie = nla_data(ieattr); | 4176 | setup->ie = nla_data(ieattr); |
4136 | setup->ie_len = nla_len(ieattr); | 4177 | setup->ie_len = nla_len(ieattr); |
4137 | } | 4178 | } |
4138 | setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); | 4179 | setup->is_authenticated = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AUTH]); |
4139 | setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]); | 4180 | setup->is_secure = nla_get_flag(tb[NL80211_MESH_SETUP_USERSPACE_AMPE]); |
4140 | 4181 | ||
4141 | return 0; | 4182 | return 0; |
4142 | } | 4183 | } |
4143 | 4184 | ||
4144 | static int nl80211_update_mesh_config(struct sk_buff *skb, | 4185 | static int nl80211_update_mesh_config(struct sk_buff *skb, |
4145 | struct genl_info *info) | 4186 | struct genl_info *info) |
4146 | { | 4187 | { |
4147 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4188 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
4148 | struct net_device *dev = info->user_ptr[1]; | 4189 | struct net_device *dev = info->user_ptr[1]; |
4149 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 4190 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
4150 | struct mesh_config cfg; | 4191 | struct mesh_config cfg; |
4151 | u32 mask; | 4192 | u32 mask; |
4152 | int err; | 4193 | int err; |
4153 | 4194 | ||
4154 | if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) | 4195 | if (wdev->iftype != NL80211_IFTYPE_MESH_POINT) |
4155 | return -EOPNOTSUPP; | 4196 | return -EOPNOTSUPP; |
4156 | 4197 | ||
4157 | if (!rdev->ops->update_mesh_config) | 4198 | if (!rdev->ops->update_mesh_config) |
4158 | return -EOPNOTSUPP; | 4199 | return -EOPNOTSUPP; |
4159 | 4200 | ||
4160 | err = nl80211_parse_mesh_config(info, &cfg, &mask); | 4201 | err = nl80211_parse_mesh_config(info, &cfg, &mask); |
4161 | if (err) | 4202 | if (err) |
4162 | return err; | 4203 | return err; |
4163 | 4204 | ||
4164 | wdev_lock(wdev); | 4205 | wdev_lock(wdev); |
4165 | if (!wdev->mesh_id_len) | 4206 | if (!wdev->mesh_id_len) |
4166 | err = -ENOLINK; | 4207 | err = -ENOLINK; |
4167 | 4208 | ||
4168 | if (!err) | 4209 | if (!err) |
4169 | err = rdev_update_mesh_config(rdev, dev, mask, &cfg); | 4210 | err = rdev_update_mesh_config(rdev, dev, mask, &cfg); |
4170 | 4211 | ||
4171 | wdev_unlock(wdev); | 4212 | wdev_unlock(wdev); |
4172 | 4213 | ||
4173 | return err; | 4214 | return err; |
4174 | } | 4215 | } |
4175 | 4216 | ||
4176 | static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) | 4217 | static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info) |
4177 | { | 4218 | { |
4178 | const struct ieee80211_regdomain *regdom; | 4219 | const struct ieee80211_regdomain *regdom; |
4179 | struct sk_buff *msg; | 4220 | struct sk_buff *msg; |
4180 | void *hdr = NULL; | 4221 | void *hdr = NULL; |
4181 | struct nlattr *nl_reg_rules; | 4222 | struct nlattr *nl_reg_rules; |
4182 | unsigned int i; | 4223 | unsigned int i; |
4183 | int err = -EINVAL; | 4224 | int err = -EINVAL; |
4184 | 4225 | ||
4185 | mutex_lock(&cfg80211_mutex); | 4226 | mutex_lock(&cfg80211_mutex); |
4186 | 4227 | ||
4187 | if (!cfg80211_regdomain) | 4228 | if (!cfg80211_regdomain) |
4188 | goto out; | 4229 | goto out; |
4189 | 4230 | ||
4190 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 4231 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
4191 | if (!msg) { | 4232 | if (!msg) { |
4192 | err = -ENOBUFS; | 4233 | err = -ENOBUFS; |
4193 | goto out; | 4234 | goto out; |
4194 | } | 4235 | } |
4195 | 4236 | ||
4196 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 4237 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
4197 | NL80211_CMD_GET_REG); | 4238 | NL80211_CMD_GET_REG); |
4198 | if (!hdr) | 4239 | if (!hdr) |
4199 | goto put_failure; | 4240 | goto put_failure; |
4200 | 4241 | ||
4201 | if (reg_last_request_cell_base() && | 4242 | if (reg_last_request_cell_base() && |
4202 | nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE, | 4243 | nla_put_u32(msg, NL80211_ATTR_USER_REG_HINT_TYPE, |
4203 | NL80211_USER_REG_HINT_CELL_BASE)) | 4244 | NL80211_USER_REG_HINT_CELL_BASE)) |
4204 | goto nla_put_failure; | 4245 | goto nla_put_failure; |
4205 | 4246 | ||
4206 | rcu_read_lock(); | 4247 | rcu_read_lock(); |
4207 | regdom = rcu_dereference(cfg80211_regdomain); | 4248 | regdom = rcu_dereference(cfg80211_regdomain); |
4208 | 4249 | ||
4209 | if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) || | 4250 | if (nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, regdom->alpha2) || |
4210 | (regdom->dfs_region && | 4251 | (regdom->dfs_region && |
4211 | nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region))) | 4252 | nla_put_u8(msg, NL80211_ATTR_DFS_REGION, regdom->dfs_region))) |
4212 | goto nla_put_failure_rcu; | 4253 | goto nla_put_failure_rcu; |
4213 | 4254 | ||
4214 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); | 4255 | nl_reg_rules = nla_nest_start(msg, NL80211_ATTR_REG_RULES); |
4215 | if (!nl_reg_rules) | 4256 | if (!nl_reg_rules) |
4216 | goto nla_put_failure_rcu; | 4257 | goto nla_put_failure_rcu; |
4217 | 4258 | ||
4218 | for (i = 0; i < regdom->n_reg_rules; i++) { | 4259 | for (i = 0; i < regdom->n_reg_rules; i++) { |
4219 | struct nlattr *nl_reg_rule; | 4260 | struct nlattr *nl_reg_rule; |
4220 | const struct ieee80211_reg_rule *reg_rule; | 4261 | const struct ieee80211_reg_rule *reg_rule; |
4221 | const struct ieee80211_freq_range *freq_range; | 4262 | const struct ieee80211_freq_range *freq_range; |
4222 | const struct ieee80211_power_rule *power_rule; | 4263 | const struct ieee80211_power_rule *power_rule; |
4223 | 4264 | ||
4224 | reg_rule = ®dom->reg_rules[i]; | 4265 | reg_rule = ®dom->reg_rules[i]; |
4225 | freq_range = ®_rule->freq_range; | 4266 | freq_range = ®_rule->freq_range; |
4226 | power_rule = ®_rule->power_rule; | 4267 | power_rule = ®_rule->power_rule; |
4227 | 4268 | ||
4228 | nl_reg_rule = nla_nest_start(msg, i); | 4269 | nl_reg_rule = nla_nest_start(msg, i); |
4229 | if (!nl_reg_rule) | 4270 | if (!nl_reg_rule) |
4230 | goto nla_put_failure_rcu; | 4271 | goto nla_put_failure_rcu; |
4231 | 4272 | ||
4232 | if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS, | 4273 | if (nla_put_u32(msg, NL80211_ATTR_REG_RULE_FLAGS, |
4233 | reg_rule->flags) || | 4274 | reg_rule->flags) || |
4234 | nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START, | 4275 | nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_START, |
4235 | freq_range->start_freq_khz) || | 4276 | freq_range->start_freq_khz) || |
4236 | nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END, | 4277 | nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_END, |
4237 | freq_range->end_freq_khz) || | 4278 | freq_range->end_freq_khz) || |
4238 | nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW, | 4279 | nla_put_u32(msg, NL80211_ATTR_FREQ_RANGE_MAX_BW, |
4239 | freq_range->max_bandwidth_khz) || | 4280 | freq_range->max_bandwidth_khz) || |
4240 | nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, | 4281 | nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, |
4241 | power_rule->max_antenna_gain) || | 4282 | power_rule->max_antenna_gain) || |
4242 | nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP, | 4283 | nla_put_u32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP, |
4243 | power_rule->max_eirp)) | 4284 | power_rule->max_eirp)) |
4244 | goto nla_put_failure_rcu; | 4285 | goto nla_put_failure_rcu; |
4245 | 4286 | ||
4246 | nla_nest_end(msg, nl_reg_rule); | 4287 | nla_nest_end(msg, nl_reg_rule); |
4247 | } | 4288 | } |
4248 | rcu_read_unlock(); | 4289 | rcu_read_unlock(); |
4249 | 4290 | ||
4250 | nla_nest_end(msg, nl_reg_rules); | 4291 | nla_nest_end(msg, nl_reg_rules); |
4251 | 4292 | ||
4252 | genlmsg_end(msg, hdr); | 4293 | genlmsg_end(msg, hdr); |
4253 | err = genlmsg_reply(msg, info); | 4294 | err = genlmsg_reply(msg, info); |
4254 | goto out; | 4295 | goto out; |
4255 | 4296 | ||
4256 | nla_put_failure_rcu: | 4297 | nla_put_failure_rcu: |
4257 | rcu_read_unlock(); | 4298 | rcu_read_unlock(); |
4258 | nla_put_failure: | 4299 | nla_put_failure: |
4259 | genlmsg_cancel(msg, hdr); | 4300 | genlmsg_cancel(msg, hdr); |
4260 | put_failure: | 4301 | put_failure: |
4261 | nlmsg_free(msg); | 4302 | nlmsg_free(msg); |
4262 | err = -EMSGSIZE; | 4303 | err = -EMSGSIZE; |
4263 | out: | 4304 | out: |
4264 | mutex_unlock(&cfg80211_mutex); | 4305 | mutex_unlock(&cfg80211_mutex); |
4265 | return err; | 4306 | return err; |
4266 | } | 4307 | } |
4267 | 4308 | ||
4268 | static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) | 4309 | static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) |
4269 | { | 4310 | { |
4270 | struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; | 4311 | struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1]; |
4271 | struct nlattr *nl_reg_rule; | 4312 | struct nlattr *nl_reg_rule; |
4272 | char *alpha2 = NULL; | 4313 | char *alpha2 = NULL; |
4273 | int rem_reg_rules = 0, r = 0; | 4314 | int rem_reg_rules = 0, r = 0; |
4274 | u32 num_rules = 0, rule_idx = 0, size_of_regd; | 4315 | u32 num_rules = 0, rule_idx = 0, size_of_regd; |
4275 | u8 dfs_region = 0; | 4316 | u8 dfs_region = 0; |
4276 | struct ieee80211_regdomain *rd = NULL; | 4317 | struct ieee80211_regdomain *rd = NULL; |
4277 | 4318 | ||
4278 | if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) | 4319 | if (!info->attrs[NL80211_ATTR_REG_ALPHA2]) |
4279 | return -EINVAL; | 4320 | return -EINVAL; |
4280 | 4321 | ||
4281 | if (!info->attrs[NL80211_ATTR_REG_RULES]) | 4322 | if (!info->attrs[NL80211_ATTR_REG_RULES]) |
4282 | return -EINVAL; | 4323 | return -EINVAL; |
4283 | 4324 | ||
4284 | alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); | 4325 | alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]); |
4285 | 4326 | ||
4286 | if (info->attrs[NL80211_ATTR_DFS_REGION]) | 4327 | if (info->attrs[NL80211_ATTR_DFS_REGION]) |
4287 | dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]); | 4328 | dfs_region = nla_get_u8(info->attrs[NL80211_ATTR_DFS_REGION]); |
4288 | 4329 | ||
4289 | nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], | 4330 | nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], |
4290 | rem_reg_rules) { | 4331 | rem_reg_rules) { |
4291 | num_rules++; | 4332 | num_rules++; |
4292 | if (num_rules > NL80211_MAX_SUPP_REG_RULES) | 4333 | if (num_rules > NL80211_MAX_SUPP_REG_RULES) |
4293 | return -EINVAL; | 4334 | return -EINVAL; |
4294 | } | 4335 | } |
4295 | 4336 | ||
4296 | size_of_regd = sizeof(struct ieee80211_regdomain) + | 4337 | size_of_regd = sizeof(struct ieee80211_regdomain) + |
4297 | num_rules * sizeof(struct ieee80211_reg_rule); | 4338 | num_rules * sizeof(struct ieee80211_reg_rule); |
4298 | 4339 | ||
4299 | rd = kzalloc(size_of_regd, GFP_KERNEL); | 4340 | rd = kzalloc(size_of_regd, GFP_KERNEL); |
4300 | if (!rd) | 4341 | if (!rd) |
4301 | return -ENOMEM; | 4342 | return -ENOMEM; |
4302 | 4343 | ||
4303 | rd->n_reg_rules = num_rules; | 4344 | rd->n_reg_rules = num_rules; |
4304 | rd->alpha2[0] = alpha2[0]; | 4345 | rd->alpha2[0] = alpha2[0]; |
4305 | rd->alpha2[1] = alpha2[1]; | 4346 | rd->alpha2[1] = alpha2[1]; |
4306 | 4347 | ||
4307 | /* | 4348 | /* |
4308 | * Disable DFS master mode if the DFS region was | 4349 | * Disable DFS master mode if the DFS region was |
4309 | * not supported or known on this kernel. | 4350 | * not supported or known on this kernel. |
4310 | */ | 4351 | */ |
4311 | if (reg_supported_dfs_region(dfs_region)) | 4352 | if (reg_supported_dfs_region(dfs_region)) |
4312 | rd->dfs_region = dfs_region; | 4353 | rd->dfs_region = dfs_region; |
4313 | 4354 | ||
4314 | nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], | 4355 | nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES], |
4315 | rem_reg_rules) { | 4356 | rem_reg_rules) { |
4316 | nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, | 4357 | nla_parse(tb, NL80211_REG_RULE_ATTR_MAX, |
4317 | nla_data(nl_reg_rule), nla_len(nl_reg_rule), | 4358 | nla_data(nl_reg_rule), nla_len(nl_reg_rule), |
4318 | reg_rule_policy); | 4359 | reg_rule_policy); |
4319 | r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]); | 4360 | r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]); |
4320 | if (r) | 4361 | if (r) |
4321 | goto bad_reg; | 4362 | goto bad_reg; |
4322 | 4363 | ||
4323 | rule_idx++; | 4364 | rule_idx++; |
4324 | 4365 | ||
4325 | if (rule_idx > NL80211_MAX_SUPP_REG_RULES) { | 4366 | if (rule_idx > NL80211_MAX_SUPP_REG_RULES) { |
4326 | r = -EINVAL; | 4367 | r = -EINVAL; |
4327 | goto bad_reg; | 4368 | goto bad_reg; |
4328 | } | 4369 | } |
4329 | } | 4370 | } |
4330 | 4371 | ||
4331 | mutex_lock(&cfg80211_mutex); | 4372 | mutex_lock(&cfg80211_mutex); |
4332 | 4373 | ||
4333 | r = set_regdom(rd); | 4374 | r = set_regdom(rd); |
4334 | /* set_regdom took ownership */ | 4375 | /* set_regdom took ownership */ |
4335 | rd = NULL; | 4376 | rd = NULL; |
4336 | mutex_unlock(&cfg80211_mutex); | 4377 | mutex_unlock(&cfg80211_mutex); |
4337 | 4378 | ||
4338 | bad_reg: | 4379 | bad_reg: |
4339 | kfree(rd); | 4380 | kfree(rd); |
4340 | return r; | 4381 | return r; |
4341 | } | 4382 | } |
4342 | 4383 | ||
4343 | static int validate_scan_freqs(struct nlattr *freqs) | 4384 | static int validate_scan_freqs(struct nlattr *freqs) |
4344 | { | 4385 | { |
4345 | struct nlattr *attr1, *attr2; | 4386 | struct nlattr *attr1, *attr2; |
4346 | int n_channels = 0, tmp1, tmp2; | 4387 | int n_channels = 0, tmp1, tmp2; |
4347 | 4388 | ||
4348 | nla_for_each_nested(attr1, freqs, tmp1) { | 4389 | nla_for_each_nested(attr1, freqs, tmp1) { |
4349 | n_channels++; | 4390 | n_channels++; |
4350 | /* | 4391 | /* |
4351 | * Some hardware has a limited channel list for | 4392 | * Some hardware has a limited channel list for |
4352 | * scanning, and it is pretty much nonsensical | 4393 | * scanning, and it is pretty much nonsensical |
4353 | * to scan for a channel twice, so disallow that | 4394 | * to scan for a channel twice, so disallow that |
4354 | * and don't require drivers to check that the | 4395 | * and don't require drivers to check that the |
4355 | * channel list they get isn't longer than what | 4396 | * channel list they get isn't longer than what |
4356 | * they can scan, as long as they can scan all | 4397 | * they can scan, as long as they can scan all |
4357 | * the channels they registered at once. | 4398 | * the channels they registered at once. |
4358 | */ | 4399 | */ |
4359 | nla_for_each_nested(attr2, freqs, tmp2) | 4400 | nla_for_each_nested(attr2, freqs, tmp2) |
4360 | if (attr1 != attr2 && | 4401 | if (attr1 != attr2 && |
4361 | nla_get_u32(attr1) == nla_get_u32(attr2)) | 4402 | nla_get_u32(attr1) == nla_get_u32(attr2)) |
4362 | return 0; | 4403 | return 0; |
4363 | } | 4404 | } |
4364 | 4405 | ||
4365 | return n_channels; | 4406 | return n_channels; |
4366 | } | 4407 | } |
4367 | 4408 | ||
4368 | static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | 4409 | static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) |
4369 | { | 4410 | { |
4370 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4411 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
4371 | struct wireless_dev *wdev = info->user_ptr[1]; | 4412 | struct wireless_dev *wdev = info->user_ptr[1]; |
4372 | struct cfg80211_scan_request *request; | 4413 | struct cfg80211_scan_request *request; |
4373 | struct nlattr *attr; | 4414 | struct nlattr *attr; |
4374 | struct wiphy *wiphy; | 4415 | struct wiphy *wiphy; |
4375 | int err, tmp, n_ssids = 0, n_channels, i; | 4416 | int err, tmp, n_ssids = 0, n_channels, i; |
4376 | size_t ie_len; | 4417 | size_t ie_len; |
4377 | 4418 | ||
4378 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 4419 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
4379 | return -EINVAL; | 4420 | return -EINVAL; |
4380 | 4421 | ||
4381 | wiphy = &rdev->wiphy; | 4422 | wiphy = &rdev->wiphy; |
4382 | 4423 | ||
4383 | if (!rdev->ops->scan) | 4424 | if (!rdev->ops->scan) |
4384 | return -EOPNOTSUPP; | 4425 | return -EOPNOTSUPP; |
4385 | 4426 | ||
4386 | if (rdev->scan_req) | 4427 | if (rdev->scan_req) |
4387 | return -EBUSY; | 4428 | return -EBUSY; |
4388 | 4429 | ||
4389 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { | 4430 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { |
4390 | n_channels = validate_scan_freqs( | 4431 | n_channels = validate_scan_freqs( |
4391 | info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); | 4432 | info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); |
4392 | if (!n_channels) | 4433 | if (!n_channels) |
4393 | return -EINVAL; | 4434 | return -EINVAL; |
4394 | } else { | 4435 | } else { |
4395 | enum ieee80211_band band; | 4436 | enum ieee80211_band band; |
4396 | n_channels = 0; | 4437 | n_channels = 0; |
4397 | 4438 | ||
4398 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | 4439 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) |
4399 | if (wiphy->bands[band]) | 4440 | if (wiphy->bands[band]) |
4400 | n_channels += wiphy->bands[band]->n_channels; | 4441 | n_channels += wiphy->bands[band]->n_channels; |
4401 | } | 4442 | } |
4402 | 4443 | ||
4403 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) | 4444 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) |
4404 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) | 4445 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) |
4405 | n_ssids++; | 4446 | n_ssids++; |
4406 | 4447 | ||
4407 | if (n_ssids > wiphy->max_scan_ssids) | 4448 | if (n_ssids > wiphy->max_scan_ssids) |
4408 | return -EINVAL; | 4449 | return -EINVAL; |
4409 | 4450 | ||
4410 | if (info->attrs[NL80211_ATTR_IE]) | 4451 | if (info->attrs[NL80211_ATTR_IE]) |
4411 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 4452 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
4412 | else | 4453 | else |
4413 | ie_len = 0; | 4454 | ie_len = 0; |
4414 | 4455 | ||
4415 | if (ie_len > wiphy->max_scan_ie_len) | 4456 | if (ie_len > wiphy->max_scan_ie_len) |
4416 | return -EINVAL; | 4457 | return -EINVAL; |
4417 | 4458 | ||
4418 | request = kzalloc(sizeof(*request) | 4459 | request = kzalloc(sizeof(*request) |
4419 | + sizeof(*request->ssids) * n_ssids | 4460 | + sizeof(*request->ssids) * n_ssids |
4420 | + sizeof(*request->channels) * n_channels | 4461 | + sizeof(*request->channels) * n_channels |
4421 | + ie_len, GFP_KERNEL); | 4462 | + ie_len, GFP_KERNEL); |
4422 | if (!request) | 4463 | if (!request) |
4423 | return -ENOMEM; | 4464 | return -ENOMEM; |
4424 | 4465 | ||
4425 | if (n_ssids) | 4466 | if (n_ssids) |
4426 | request->ssids = (void *)&request->channels[n_channels]; | 4467 | request->ssids = (void *)&request->channels[n_channels]; |
4427 | request->n_ssids = n_ssids; | 4468 | request->n_ssids = n_ssids; |
4428 | if (ie_len) { | 4469 | if (ie_len) { |
4429 | if (request->ssids) | 4470 | if (request->ssids) |
4430 | request->ie = (void *)(request->ssids + n_ssids); | 4471 | request->ie = (void *)(request->ssids + n_ssids); |
4431 | else | 4472 | else |
4432 | request->ie = (void *)(request->channels + n_channels); | 4473 | request->ie = (void *)(request->channels + n_channels); |
4433 | } | 4474 | } |
4434 | 4475 | ||
4435 | i = 0; | 4476 | i = 0; |
4436 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { | 4477 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { |
4437 | /* user specified, bail out if channel not found */ | 4478 | /* user specified, bail out if channel not found */ |
4438 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { | 4479 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { |
4439 | struct ieee80211_channel *chan; | 4480 | struct ieee80211_channel *chan; |
4440 | 4481 | ||
4441 | chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); | 4482 | chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); |
4442 | 4483 | ||
4443 | if (!chan) { | 4484 | if (!chan) { |
4444 | err = -EINVAL; | 4485 | err = -EINVAL; |
4445 | goto out_free; | 4486 | goto out_free; |
4446 | } | 4487 | } |
4447 | 4488 | ||
4448 | /* ignore disabled channels */ | 4489 | /* ignore disabled channels */ |
4449 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 4490 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
4450 | continue; | 4491 | continue; |
4451 | 4492 | ||
4452 | request->channels[i] = chan; | 4493 | request->channels[i] = chan; |
4453 | i++; | 4494 | i++; |
4454 | } | 4495 | } |
4455 | } else { | 4496 | } else { |
4456 | enum ieee80211_band band; | 4497 | enum ieee80211_band band; |
4457 | 4498 | ||
4458 | /* all channels */ | 4499 | /* all channels */ |
4459 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 4500 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
4460 | int j; | 4501 | int j; |
4461 | if (!wiphy->bands[band]) | 4502 | if (!wiphy->bands[band]) |
4462 | continue; | 4503 | continue; |
4463 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | 4504 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { |
4464 | struct ieee80211_channel *chan; | 4505 | struct ieee80211_channel *chan; |
4465 | 4506 | ||
4466 | chan = &wiphy->bands[band]->channels[j]; | 4507 | chan = &wiphy->bands[band]->channels[j]; |
4467 | 4508 | ||
4468 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 4509 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
4469 | continue; | 4510 | continue; |
4470 | 4511 | ||
4471 | request->channels[i] = chan; | 4512 | request->channels[i] = chan; |
4472 | i++; | 4513 | i++; |
4473 | } | 4514 | } |
4474 | } | 4515 | } |
4475 | } | 4516 | } |
4476 | 4517 | ||
4477 | if (!i) { | 4518 | if (!i) { |
4478 | err = -EINVAL; | 4519 | err = -EINVAL; |
4479 | goto out_free; | 4520 | goto out_free; |
4480 | } | 4521 | } |
4481 | 4522 | ||
4482 | request->n_channels = i; | 4523 | request->n_channels = i; |
4483 | 4524 | ||
4484 | i = 0; | 4525 | i = 0; |
4485 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 4526 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
4486 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { | 4527 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { |
4487 | if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { | 4528 | if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { |
4488 | err = -EINVAL; | 4529 | err = -EINVAL; |
4489 | goto out_free; | 4530 | goto out_free; |
4490 | } | 4531 | } |
4491 | request->ssids[i].ssid_len = nla_len(attr); | 4532 | request->ssids[i].ssid_len = nla_len(attr); |
4492 | memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); | 4533 | memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr)); |
4493 | i++; | 4534 | i++; |
4494 | } | 4535 | } |
4495 | } | 4536 | } |
4496 | 4537 | ||
4497 | if (info->attrs[NL80211_ATTR_IE]) { | 4538 | if (info->attrs[NL80211_ATTR_IE]) { |
4498 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 4539 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
4499 | memcpy((void *)request->ie, | 4540 | memcpy((void *)request->ie, |
4500 | nla_data(info->attrs[NL80211_ATTR_IE]), | 4541 | nla_data(info->attrs[NL80211_ATTR_IE]), |
4501 | request->ie_len); | 4542 | request->ie_len); |
4502 | } | 4543 | } |
4503 | 4544 | ||
4504 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | 4545 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) |
4505 | if (wiphy->bands[i]) | 4546 | if (wiphy->bands[i]) |
4506 | request->rates[i] = | 4547 | request->rates[i] = |
4507 | (1 << wiphy->bands[i]->n_bitrates) - 1; | 4548 | (1 << wiphy->bands[i]->n_bitrates) - 1; |
4508 | 4549 | ||
4509 | if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) { | 4550 | if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) { |
4510 | nla_for_each_nested(attr, | 4551 | nla_for_each_nested(attr, |
4511 | info->attrs[NL80211_ATTR_SCAN_SUPP_RATES], | 4552 | info->attrs[NL80211_ATTR_SCAN_SUPP_RATES], |
4512 | tmp) { | 4553 | tmp) { |
4513 | enum ieee80211_band band = nla_type(attr); | 4554 | enum ieee80211_band band = nla_type(attr); |
4514 | 4555 | ||
4515 | if (band < 0 || band >= IEEE80211_NUM_BANDS) { | 4556 | if (band < 0 || band >= IEEE80211_NUM_BANDS) { |
4516 | err = -EINVAL; | 4557 | err = -EINVAL; |
4517 | goto out_free; | 4558 | goto out_free; |
4518 | } | 4559 | } |
4519 | err = ieee80211_get_ratemask(wiphy->bands[band], | 4560 | err = ieee80211_get_ratemask(wiphy->bands[band], |
4520 | nla_data(attr), | 4561 | nla_data(attr), |
4521 | nla_len(attr), | 4562 | nla_len(attr), |
4522 | &request->rates[band]); | 4563 | &request->rates[band]); |
4523 | if (err) | 4564 | if (err) |
4524 | goto out_free; | 4565 | goto out_free; |
4525 | } | 4566 | } |
4526 | } | 4567 | } |
4527 | 4568 | ||
4528 | if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { | 4569 | if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { |
4529 | request->flags = nla_get_u32( | 4570 | request->flags = nla_get_u32( |
4530 | info->attrs[NL80211_ATTR_SCAN_FLAGS]); | 4571 | info->attrs[NL80211_ATTR_SCAN_FLAGS]); |
4531 | if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && | 4572 | if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && |
4532 | !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || | 4573 | !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || |
4533 | ((request->flags & NL80211_SCAN_FLAG_FLUSH) && | 4574 | ((request->flags & NL80211_SCAN_FLAG_FLUSH) && |
4534 | !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { | 4575 | !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { |
4535 | err = -EOPNOTSUPP; | 4576 | err = -EOPNOTSUPP; |
4536 | goto out_free; | 4577 | goto out_free; |
4537 | } | 4578 | } |
4538 | } | 4579 | } |
4539 | 4580 | ||
4540 | request->no_cck = | 4581 | request->no_cck = |
4541 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | 4582 | nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); |
4542 | 4583 | ||
4543 | request->wdev = wdev; | 4584 | request->wdev = wdev; |
4544 | request->wiphy = &rdev->wiphy; | 4585 | request->wiphy = &rdev->wiphy; |
4545 | request->scan_start = jiffies; | 4586 | request->scan_start = jiffies; |
4546 | 4587 | ||
4547 | rdev->scan_req = request; | 4588 | rdev->scan_req = request; |
4548 | err = rdev_scan(rdev, request); | 4589 | err = rdev_scan(rdev, request); |
4549 | 4590 | ||
4550 | if (!err) { | 4591 | if (!err) { |
4551 | nl80211_send_scan_start(rdev, wdev); | 4592 | nl80211_send_scan_start(rdev, wdev); |
4552 | if (wdev->netdev) | 4593 | if (wdev->netdev) |
4553 | dev_hold(wdev->netdev); | 4594 | dev_hold(wdev->netdev); |
4554 | } else { | 4595 | } else { |
4555 | out_free: | 4596 | out_free: |
4556 | rdev->scan_req = NULL; | 4597 | rdev->scan_req = NULL; |
4557 | kfree(request); | 4598 | kfree(request); |
4558 | } | 4599 | } |
4559 | 4600 | ||
4560 | return err; | 4601 | return err; |
4561 | } | 4602 | } |
4562 | 4603 | ||
4563 | static int nl80211_start_sched_scan(struct sk_buff *skb, | 4604 | static int nl80211_start_sched_scan(struct sk_buff *skb, |
4564 | struct genl_info *info) | 4605 | struct genl_info *info) |
4565 | { | 4606 | { |
4566 | struct cfg80211_sched_scan_request *request; | 4607 | struct cfg80211_sched_scan_request *request; |
4567 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4608 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
4568 | struct net_device *dev = info->user_ptr[1]; | 4609 | struct net_device *dev = info->user_ptr[1]; |
4569 | struct nlattr *attr; | 4610 | struct nlattr *attr; |
4570 | struct wiphy *wiphy; | 4611 | struct wiphy *wiphy; |
4571 | int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i; | 4612 | int err, tmp, n_ssids = 0, n_match_sets = 0, n_channels, i; |
4572 | u32 interval; | 4613 | u32 interval; |
4573 | enum ieee80211_band band; | 4614 | enum ieee80211_band band; |
4574 | size_t ie_len; | 4615 | size_t ie_len; |
4575 | struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; | 4616 | struct nlattr *tb[NL80211_SCHED_SCAN_MATCH_ATTR_MAX + 1]; |
4576 | 4617 | ||
4577 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 4618 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
4578 | !rdev->ops->sched_scan_start) | 4619 | !rdev->ops->sched_scan_start) |
4579 | return -EOPNOTSUPP; | 4620 | return -EOPNOTSUPP; |
4580 | 4621 | ||
4581 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 4622 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
4582 | return -EINVAL; | 4623 | return -EINVAL; |
4583 | 4624 | ||
4584 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) | 4625 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) |
4585 | return -EINVAL; | 4626 | return -EINVAL; |
4586 | 4627 | ||
4587 | interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]); | 4628 | interval = nla_get_u32(info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]); |
4588 | if (interval == 0) | 4629 | if (interval == 0) |
4589 | return -EINVAL; | 4630 | return -EINVAL; |
4590 | 4631 | ||
4591 | wiphy = &rdev->wiphy; | 4632 | wiphy = &rdev->wiphy; |
4592 | 4633 | ||
4593 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { | 4634 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { |
4594 | n_channels = validate_scan_freqs( | 4635 | n_channels = validate_scan_freqs( |
4595 | info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); | 4636 | info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]); |
4596 | if (!n_channels) | 4637 | if (!n_channels) |
4597 | return -EINVAL; | 4638 | return -EINVAL; |
4598 | } else { | 4639 | } else { |
4599 | n_channels = 0; | 4640 | n_channels = 0; |
4600 | 4641 | ||
4601 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | 4642 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) |
4602 | if (wiphy->bands[band]) | 4643 | if (wiphy->bands[band]) |
4603 | n_channels += wiphy->bands[band]->n_channels; | 4644 | n_channels += wiphy->bands[band]->n_channels; |
4604 | } | 4645 | } |
4605 | 4646 | ||
4606 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) | 4647 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) |
4607 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], | 4648 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], |
4608 | tmp) | 4649 | tmp) |
4609 | n_ssids++; | 4650 | n_ssids++; |
4610 | 4651 | ||
4611 | if (n_ssids > wiphy->max_sched_scan_ssids) | 4652 | if (n_ssids > wiphy->max_sched_scan_ssids) |
4612 | return -EINVAL; | 4653 | return -EINVAL; |
4613 | 4654 | ||
4614 | if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) | 4655 | if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) |
4615 | nla_for_each_nested(attr, | 4656 | nla_for_each_nested(attr, |
4616 | info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], | 4657 | info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], |
4617 | tmp) | 4658 | tmp) |
4618 | n_match_sets++; | 4659 | n_match_sets++; |
4619 | 4660 | ||
4620 | if (n_match_sets > wiphy->max_match_sets) | 4661 | if (n_match_sets > wiphy->max_match_sets) |
4621 | return -EINVAL; | 4662 | return -EINVAL; |
4622 | 4663 | ||
4623 | if (info->attrs[NL80211_ATTR_IE]) | 4664 | if (info->attrs[NL80211_ATTR_IE]) |
4624 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 4665 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
4625 | else | 4666 | else |
4626 | ie_len = 0; | 4667 | ie_len = 0; |
4627 | 4668 | ||
4628 | if (ie_len > wiphy->max_sched_scan_ie_len) | 4669 | if (ie_len > wiphy->max_sched_scan_ie_len) |
4629 | return -EINVAL; | 4670 | return -EINVAL; |
4630 | 4671 | ||
4631 | mutex_lock(&rdev->sched_scan_mtx); | 4672 | mutex_lock(&rdev->sched_scan_mtx); |
4632 | 4673 | ||
4633 | if (rdev->sched_scan_req) { | 4674 | if (rdev->sched_scan_req) { |
4634 | err = -EINPROGRESS; | 4675 | err = -EINPROGRESS; |
4635 | goto out; | 4676 | goto out; |
4636 | } | 4677 | } |
4637 | 4678 | ||
4638 | request = kzalloc(sizeof(*request) | 4679 | request = kzalloc(sizeof(*request) |
4639 | + sizeof(*request->ssids) * n_ssids | 4680 | + sizeof(*request->ssids) * n_ssids |
4640 | + sizeof(*request->match_sets) * n_match_sets | 4681 | + sizeof(*request->match_sets) * n_match_sets |
4641 | + sizeof(*request->channels) * n_channels | 4682 | + sizeof(*request->channels) * n_channels |
4642 | + ie_len, GFP_KERNEL); | 4683 | + ie_len, GFP_KERNEL); |
4643 | if (!request) { | 4684 | if (!request) { |
4644 | err = -ENOMEM; | 4685 | err = -ENOMEM; |
4645 | goto out; | 4686 | goto out; |
4646 | } | 4687 | } |
4647 | 4688 | ||
4648 | if (n_ssids) | 4689 | if (n_ssids) |
4649 | request->ssids = (void *)&request->channels[n_channels]; | 4690 | request->ssids = (void *)&request->channels[n_channels]; |
4650 | request->n_ssids = n_ssids; | 4691 | request->n_ssids = n_ssids; |
4651 | if (ie_len) { | 4692 | if (ie_len) { |
4652 | if (request->ssids) | 4693 | if (request->ssids) |
4653 | request->ie = (void *)(request->ssids + n_ssids); | 4694 | request->ie = (void *)(request->ssids + n_ssids); |
4654 | else | 4695 | else |
4655 | request->ie = (void *)(request->channels + n_channels); | 4696 | request->ie = (void *)(request->channels + n_channels); |
4656 | } | 4697 | } |
4657 | 4698 | ||
4658 | if (n_match_sets) { | 4699 | if (n_match_sets) { |
4659 | if (request->ie) | 4700 | if (request->ie) |
4660 | request->match_sets = (void *)(request->ie + ie_len); | 4701 | request->match_sets = (void *)(request->ie + ie_len); |
4661 | else if (request->ssids) | 4702 | else if (request->ssids) |
4662 | request->match_sets = | 4703 | request->match_sets = |
4663 | (void *)(request->ssids + n_ssids); | 4704 | (void *)(request->ssids + n_ssids); |
4664 | else | 4705 | else |
4665 | request->match_sets = | 4706 | request->match_sets = |
4666 | (void *)(request->channels + n_channels); | 4707 | (void *)(request->channels + n_channels); |
4667 | } | 4708 | } |
4668 | request->n_match_sets = n_match_sets; | 4709 | request->n_match_sets = n_match_sets; |
4669 | 4710 | ||
4670 | i = 0; | 4711 | i = 0; |
4671 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { | 4712 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { |
4672 | /* user specified, bail out if channel not found */ | 4713 | /* user specified, bail out if channel not found */ |
4673 | nla_for_each_nested(attr, | 4714 | nla_for_each_nested(attr, |
4674 | info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], | 4715 | info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], |
4675 | tmp) { | 4716 | tmp) { |
4676 | struct ieee80211_channel *chan; | 4717 | struct ieee80211_channel *chan; |
4677 | 4718 | ||
4678 | chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); | 4719 | chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); |
4679 | 4720 | ||
4680 | if (!chan) { | 4721 | if (!chan) { |
4681 | err = -EINVAL; | 4722 | err = -EINVAL; |
4682 | goto out_free; | 4723 | goto out_free; |
4683 | } | 4724 | } |
4684 | 4725 | ||
4685 | /* ignore disabled channels */ | 4726 | /* ignore disabled channels */ |
4686 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 4727 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
4687 | continue; | 4728 | continue; |
4688 | 4729 | ||
4689 | request->channels[i] = chan; | 4730 | request->channels[i] = chan; |
4690 | i++; | 4731 | i++; |
4691 | } | 4732 | } |
4692 | } else { | 4733 | } else { |
4693 | /* all channels */ | 4734 | /* all channels */ |
4694 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 4735 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
4695 | int j; | 4736 | int j; |
4696 | if (!wiphy->bands[band]) | 4737 | if (!wiphy->bands[band]) |
4697 | continue; | 4738 | continue; |
4698 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | 4739 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { |
4699 | struct ieee80211_channel *chan; | 4740 | struct ieee80211_channel *chan; |
4700 | 4741 | ||
4701 | chan = &wiphy->bands[band]->channels[j]; | 4742 | chan = &wiphy->bands[band]->channels[j]; |
4702 | 4743 | ||
4703 | if (chan->flags & IEEE80211_CHAN_DISABLED) | 4744 | if (chan->flags & IEEE80211_CHAN_DISABLED) |
4704 | continue; | 4745 | continue; |
4705 | 4746 | ||
4706 | request->channels[i] = chan; | 4747 | request->channels[i] = chan; |
4707 | i++; | 4748 | i++; |
4708 | } | 4749 | } |
4709 | } | 4750 | } |
4710 | } | 4751 | } |
4711 | 4752 | ||
4712 | if (!i) { | 4753 | if (!i) { |
4713 | err = -EINVAL; | 4754 | err = -EINVAL; |
4714 | goto out_free; | 4755 | goto out_free; |
4715 | } | 4756 | } |
4716 | 4757 | ||
4717 | request->n_channels = i; | 4758 | request->n_channels = i; |
4718 | 4759 | ||
4719 | i = 0; | 4760 | i = 0; |
4720 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 4761 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
4721 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], | 4762 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], |
4722 | tmp) { | 4763 | tmp) { |
4723 | if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { | 4764 | if (nla_len(attr) > IEEE80211_MAX_SSID_LEN) { |
4724 | err = -EINVAL; | 4765 | err = -EINVAL; |
4725 | goto out_free; | 4766 | goto out_free; |
4726 | } | 4767 | } |
4727 | request->ssids[i].ssid_len = nla_len(attr); | 4768 | request->ssids[i].ssid_len = nla_len(attr); |
4728 | memcpy(request->ssids[i].ssid, nla_data(attr), | 4769 | memcpy(request->ssids[i].ssid, nla_data(attr), |
4729 | nla_len(attr)); | 4770 | nla_len(attr)); |
4730 | i++; | 4771 | i++; |
4731 | } | 4772 | } |
4732 | } | 4773 | } |
4733 | 4774 | ||
4734 | i = 0; | 4775 | i = 0; |
4735 | if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { | 4776 | if (info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH]) { |
4736 | nla_for_each_nested(attr, | 4777 | nla_for_each_nested(attr, |
4737 | info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], | 4778 | info->attrs[NL80211_ATTR_SCHED_SCAN_MATCH], |
4738 | tmp) { | 4779 | tmp) { |
4739 | struct nlattr *ssid, *rssi; | 4780 | struct nlattr *ssid, *rssi; |
4740 | 4781 | ||
4741 | nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, | 4782 | nla_parse(tb, NL80211_SCHED_SCAN_MATCH_ATTR_MAX, |
4742 | nla_data(attr), nla_len(attr), | 4783 | nla_data(attr), nla_len(attr), |
4743 | nl80211_match_policy); | 4784 | nl80211_match_policy); |
4744 | ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]; | 4785 | ssid = tb[NL80211_SCHED_SCAN_MATCH_ATTR_SSID]; |
4745 | if (ssid) { | 4786 | if (ssid) { |
4746 | if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { | 4787 | if (nla_len(ssid) > IEEE80211_MAX_SSID_LEN) { |
4747 | err = -EINVAL; | 4788 | err = -EINVAL; |
4748 | goto out_free; | 4789 | goto out_free; |
4749 | } | 4790 | } |
4750 | memcpy(request->match_sets[i].ssid.ssid, | 4791 | memcpy(request->match_sets[i].ssid.ssid, |
4751 | nla_data(ssid), nla_len(ssid)); | 4792 | nla_data(ssid), nla_len(ssid)); |
4752 | request->match_sets[i].ssid.ssid_len = | 4793 | request->match_sets[i].ssid.ssid_len = |
4753 | nla_len(ssid); | 4794 | nla_len(ssid); |
4754 | } | 4795 | } |
4755 | rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI]; | 4796 | rssi = tb[NL80211_SCHED_SCAN_MATCH_ATTR_RSSI]; |
4756 | if (rssi) | 4797 | if (rssi) |
4757 | request->rssi_thold = nla_get_u32(rssi); | 4798 | request->rssi_thold = nla_get_u32(rssi); |
4758 | else | 4799 | else |
4759 | request->rssi_thold = | 4800 | request->rssi_thold = |
4760 | NL80211_SCAN_RSSI_THOLD_OFF; | 4801 | NL80211_SCAN_RSSI_THOLD_OFF; |
4761 | i++; | 4802 | i++; |
4762 | } | 4803 | } |
4763 | } | 4804 | } |
4764 | 4805 | ||
4765 | if (info->attrs[NL80211_ATTR_IE]) { | 4806 | if (info->attrs[NL80211_ATTR_IE]) { |
4766 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 4807 | request->ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
4767 | memcpy((void *)request->ie, | 4808 | memcpy((void *)request->ie, |
4768 | nla_data(info->attrs[NL80211_ATTR_IE]), | 4809 | nla_data(info->attrs[NL80211_ATTR_IE]), |
4769 | request->ie_len); | 4810 | request->ie_len); |
4770 | } | 4811 | } |
4771 | 4812 | ||
4772 | if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { | 4813 | if (info->attrs[NL80211_ATTR_SCAN_FLAGS]) { |
4773 | request->flags = nla_get_u32( | 4814 | request->flags = nla_get_u32( |
4774 | info->attrs[NL80211_ATTR_SCAN_FLAGS]); | 4815 | info->attrs[NL80211_ATTR_SCAN_FLAGS]); |
4775 | if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && | 4816 | if (((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) && |
4776 | !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || | 4817 | !(wiphy->features & NL80211_FEATURE_LOW_PRIORITY_SCAN)) || |
4777 | ((request->flags & NL80211_SCAN_FLAG_FLUSH) && | 4818 | ((request->flags & NL80211_SCAN_FLAG_FLUSH) && |
4778 | !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { | 4819 | !(wiphy->features & NL80211_FEATURE_SCAN_FLUSH))) { |
4779 | err = -EOPNOTSUPP; | 4820 | err = -EOPNOTSUPP; |
4780 | goto out_free; | 4821 | goto out_free; |
4781 | } | 4822 | } |
4782 | } | 4823 | } |
4783 | 4824 | ||
4784 | request->dev = dev; | 4825 | request->dev = dev; |
4785 | request->wiphy = &rdev->wiphy; | 4826 | request->wiphy = &rdev->wiphy; |
4786 | request->interval = interval; | 4827 | request->interval = interval; |
4787 | request->scan_start = jiffies; | 4828 | request->scan_start = jiffies; |
4788 | 4829 | ||
4789 | err = rdev_sched_scan_start(rdev, dev, request); | 4830 | err = rdev_sched_scan_start(rdev, dev, request); |
4790 | if (!err) { | 4831 | if (!err) { |
4791 | rdev->sched_scan_req = request; | 4832 | rdev->sched_scan_req = request; |
4792 | nl80211_send_sched_scan(rdev, dev, | 4833 | nl80211_send_sched_scan(rdev, dev, |
4793 | NL80211_CMD_START_SCHED_SCAN); | 4834 | NL80211_CMD_START_SCHED_SCAN); |
4794 | goto out; | 4835 | goto out; |
4795 | } | 4836 | } |
4796 | 4837 | ||
4797 | out_free: | 4838 | out_free: |
4798 | kfree(request); | 4839 | kfree(request); |
4799 | out: | 4840 | out: |
4800 | mutex_unlock(&rdev->sched_scan_mtx); | 4841 | mutex_unlock(&rdev->sched_scan_mtx); |
4801 | return err; | 4842 | return err; |
4802 | } | 4843 | } |
4803 | 4844 | ||
4804 | static int nl80211_stop_sched_scan(struct sk_buff *skb, | 4845 | static int nl80211_stop_sched_scan(struct sk_buff *skb, |
4805 | struct genl_info *info) | 4846 | struct genl_info *info) |
4806 | { | 4847 | { |
4807 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 4848 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
4808 | int err; | 4849 | int err; |
4809 | 4850 | ||
4810 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 4851 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
4811 | !rdev->ops->sched_scan_stop) | 4852 | !rdev->ops->sched_scan_stop) |
4812 | return -EOPNOTSUPP; | 4853 | return -EOPNOTSUPP; |
4813 | 4854 | ||
4814 | mutex_lock(&rdev->sched_scan_mtx); | 4855 | mutex_lock(&rdev->sched_scan_mtx); |
4815 | err = __cfg80211_stop_sched_scan(rdev, false); | 4856 | err = __cfg80211_stop_sched_scan(rdev, false); |
4816 | mutex_unlock(&rdev->sched_scan_mtx); | 4857 | mutex_unlock(&rdev->sched_scan_mtx); |
4817 | 4858 | ||
4818 | return err; | 4859 | return err; |
4819 | } | 4860 | } |
4820 | 4861 | ||
4821 | static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, | 4862 | static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb, |
4822 | u32 seq, int flags, | 4863 | u32 seq, int flags, |
4823 | struct cfg80211_registered_device *rdev, | 4864 | struct cfg80211_registered_device *rdev, |
4824 | struct wireless_dev *wdev, | 4865 | struct wireless_dev *wdev, |
4825 | struct cfg80211_internal_bss *intbss) | 4866 | struct cfg80211_internal_bss *intbss) |
4826 | { | 4867 | { |
4827 | struct cfg80211_bss *res = &intbss->pub; | 4868 | struct cfg80211_bss *res = &intbss->pub; |
4828 | const struct cfg80211_bss_ies *ies; | 4869 | const struct cfg80211_bss_ies *ies; |
4829 | void *hdr; | 4870 | void *hdr; |
4830 | struct nlattr *bss; | 4871 | struct nlattr *bss; |
4831 | 4872 | ||
4832 | ASSERT_WDEV_LOCK(wdev); | 4873 | ASSERT_WDEV_LOCK(wdev); |
4833 | 4874 | ||
4834 | hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags, | 4875 | hdr = nl80211hdr_put(msg, NETLINK_CB(cb->skb).portid, seq, flags, |
4835 | NL80211_CMD_NEW_SCAN_RESULTS); | 4876 | NL80211_CMD_NEW_SCAN_RESULTS); |
4836 | if (!hdr) | 4877 | if (!hdr) |
4837 | return -1; | 4878 | return -1; |
4838 | 4879 | ||
4839 | genl_dump_check_consistent(cb, hdr, &nl80211_fam); | 4880 | genl_dump_check_consistent(cb, hdr, &nl80211_fam); |
4840 | 4881 | ||
4841 | if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation) || | 4882 | if (nla_put_u32(msg, NL80211_ATTR_GENERATION, rdev->bss_generation) || |
4842 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex)) | 4883 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex)) |
4843 | goto nla_put_failure; | 4884 | goto nla_put_failure; |
4844 | 4885 | ||
4845 | bss = nla_nest_start(msg, NL80211_ATTR_BSS); | 4886 | bss = nla_nest_start(msg, NL80211_ATTR_BSS); |
4846 | if (!bss) | 4887 | if (!bss) |
4847 | goto nla_put_failure; | 4888 | goto nla_put_failure; |
4848 | if ((!is_zero_ether_addr(res->bssid) && | 4889 | if ((!is_zero_ether_addr(res->bssid) && |
4849 | nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid))) | 4890 | nla_put(msg, NL80211_BSS_BSSID, ETH_ALEN, res->bssid))) |
4850 | goto nla_put_failure; | 4891 | goto nla_put_failure; |
4851 | 4892 | ||
4852 | rcu_read_lock(); | 4893 | rcu_read_lock(); |
4853 | ies = rcu_dereference(res->ies); | 4894 | ies = rcu_dereference(res->ies); |
4854 | if (ies && ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, | 4895 | if (ies && ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, |
4855 | ies->len, ies->data)) { | 4896 | ies->len, ies->data)) { |
4856 | rcu_read_unlock(); | 4897 | rcu_read_unlock(); |
4857 | goto nla_put_failure; | 4898 | goto nla_put_failure; |
4858 | } | 4899 | } |
4859 | ies = rcu_dereference(res->beacon_ies); | 4900 | ies = rcu_dereference(res->beacon_ies); |
4860 | if (ies && ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, | 4901 | if (ies && ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, |
4861 | ies->len, ies->data)) { | 4902 | ies->len, ies->data)) { |
4862 | rcu_read_unlock(); | 4903 | rcu_read_unlock(); |
4863 | goto nla_put_failure; | 4904 | goto nla_put_failure; |
4864 | } | 4905 | } |
4865 | rcu_read_unlock(); | 4906 | rcu_read_unlock(); |
4866 | 4907 | ||
4867 | if (res->tsf && | 4908 | if (res->tsf && |
4868 | nla_put_u64(msg, NL80211_BSS_TSF, res->tsf)) | 4909 | nla_put_u64(msg, NL80211_BSS_TSF, res->tsf)) |
4869 | goto nla_put_failure; | 4910 | goto nla_put_failure; |
4870 | if (res->beacon_interval && | 4911 | if (res->beacon_interval && |
4871 | nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval)) | 4912 | nla_put_u16(msg, NL80211_BSS_BEACON_INTERVAL, res->beacon_interval)) |
4872 | goto nla_put_failure; | 4913 | goto nla_put_failure; |
4873 | if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) || | 4914 | if (nla_put_u16(msg, NL80211_BSS_CAPABILITY, res->capability) || |
4874 | nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) || | 4915 | nla_put_u32(msg, NL80211_BSS_FREQUENCY, res->channel->center_freq) || |
4875 | nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO, | 4916 | nla_put_u32(msg, NL80211_BSS_SEEN_MS_AGO, |
4876 | jiffies_to_msecs(jiffies - intbss->ts))) | 4917 | jiffies_to_msecs(jiffies - intbss->ts))) |
4877 | goto nla_put_failure; | 4918 | goto nla_put_failure; |
4878 | 4919 | ||
4879 | switch (rdev->wiphy.signal_type) { | 4920 | switch (rdev->wiphy.signal_type) { |
4880 | case CFG80211_SIGNAL_TYPE_MBM: | 4921 | case CFG80211_SIGNAL_TYPE_MBM: |
4881 | if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal)) | 4922 | if (nla_put_u32(msg, NL80211_BSS_SIGNAL_MBM, res->signal)) |
4882 | goto nla_put_failure; | 4923 | goto nla_put_failure; |
4883 | break; | 4924 | break; |
4884 | case CFG80211_SIGNAL_TYPE_UNSPEC: | 4925 | case CFG80211_SIGNAL_TYPE_UNSPEC: |
4885 | if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal)) | 4926 | if (nla_put_u8(msg, NL80211_BSS_SIGNAL_UNSPEC, res->signal)) |
4886 | goto nla_put_failure; | 4927 | goto nla_put_failure; |
4887 | break; | 4928 | break; |
4888 | default: | 4929 | default: |
4889 | break; | 4930 | break; |
4890 | } | 4931 | } |
4891 | 4932 | ||
4892 | switch (wdev->iftype) { | 4933 | switch (wdev->iftype) { |
4893 | case NL80211_IFTYPE_P2P_CLIENT: | 4934 | case NL80211_IFTYPE_P2P_CLIENT: |
4894 | case NL80211_IFTYPE_STATION: | 4935 | case NL80211_IFTYPE_STATION: |
4895 | if (intbss == wdev->current_bss && | 4936 | if (intbss == wdev->current_bss && |
4896 | nla_put_u32(msg, NL80211_BSS_STATUS, | 4937 | nla_put_u32(msg, NL80211_BSS_STATUS, |
4897 | NL80211_BSS_STATUS_ASSOCIATED)) | 4938 | NL80211_BSS_STATUS_ASSOCIATED)) |
4898 | goto nla_put_failure; | 4939 | goto nla_put_failure; |
4899 | break; | 4940 | break; |
4900 | case NL80211_IFTYPE_ADHOC: | 4941 | case NL80211_IFTYPE_ADHOC: |
4901 | if (intbss == wdev->current_bss && | 4942 | if (intbss == wdev->current_bss && |
4902 | nla_put_u32(msg, NL80211_BSS_STATUS, | 4943 | nla_put_u32(msg, NL80211_BSS_STATUS, |
4903 | NL80211_BSS_STATUS_IBSS_JOINED)) | 4944 | NL80211_BSS_STATUS_IBSS_JOINED)) |
4904 | goto nla_put_failure; | 4945 | goto nla_put_failure; |
4905 | break; | 4946 | break; |
4906 | default: | 4947 | default: |
4907 | break; | 4948 | break; |
4908 | } | 4949 | } |
4909 | 4950 | ||
4910 | nla_nest_end(msg, bss); | 4951 | nla_nest_end(msg, bss); |
4911 | 4952 | ||
4912 | return genlmsg_end(msg, hdr); | 4953 | return genlmsg_end(msg, hdr); |
4913 | 4954 | ||
4914 | nla_put_failure: | 4955 | nla_put_failure: |
4915 | genlmsg_cancel(msg, hdr); | 4956 | genlmsg_cancel(msg, hdr); |
4916 | return -EMSGSIZE; | 4957 | return -EMSGSIZE; |
4917 | } | 4958 | } |
4918 | 4959 | ||
4919 | static int nl80211_dump_scan(struct sk_buff *skb, | 4960 | static int nl80211_dump_scan(struct sk_buff *skb, |
4920 | struct netlink_callback *cb) | 4961 | struct netlink_callback *cb) |
4921 | { | 4962 | { |
4922 | struct cfg80211_registered_device *rdev; | 4963 | struct cfg80211_registered_device *rdev; |
4923 | struct net_device *dev; | 4964 | struct net_device *dev; |
4924 | struct cfg80211_internal_bss *scan; | 4965 | struct cfg80211_internal_bss *scan; |
4925 | struct wireless_dev *wdev; | 4966 | struct wireless_dev *wdev; |
4926 | int start = cb->args[1], idx = 0; | 4967 | int start = cb->args[1], idx = 0; |
4927 | int err; | 4968 | int err; |
4928 | 4969 | ||
4929 | err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev); | 4970 | err = nl80211_prepare_netdev_dump(skb, cb, &rdev, &dev); |
4930 | if (err) | 4971 | if (err) |
4931 | return err; | 4972 | return err; |
4932 | 4973 | ||
4933 | wdev = dev->ieee80211_ptr; | 4974 | wdev = dev->ieee80211_ptr; |
4934 | 4975 | ||
4935 | wdev_lock(wdev); | 4976 | wdev_lock(wdev); |
4936 | spin_lock_bh(&rdev->bss_lock); | 4977 | spin_lock_bh(&rdev->bss_lock); |
4937 | cfg80211_bss_expire(rdev); | 4978 | cfg80211_bss_expire(rdev); |
4938 | 4979 | ||
4939 | cb->seq = rdev->bss_generation; | 4980 | cb->seq = rdev->bss_generation; |
4940 | 4981 | ||
4941 | list_for_each_entry(scan, &rdev->bss_list, list) { | 4982 | list_for_each_entry(scan, &rdev->bss_list, list) { |
4942 | if (++idx <= start) | 4983 | if (++idx <= start) |
4943 | continue; | 4984 | continue; |
4944 | if (nl80211_send_bss(skb, cb, | 4985 | if (nl80211_send_bss(skb, cb, |
4945 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 4986 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
4946 | rdev, wdev, scan) < 0) { | 4987 | rdev, wdev, scan) < 0) { |
4947 | idx--; | 4988 | idx--; |
4948 | break; | 4989 | break; |
4949 | } | 4990 | } |
4950 | } | 4991 | } |
4951 | 4992 | ||
4952 | spin_unlock_bh(&rdev->bss_lock); | 4993 | spin_unlock_bh(&rdev->bss_lock); |
4953 | wdev_unlock(wdev); | 4994 | wdev_unlock(wdev); |
4954 | 4995 | ||
4955 | cb->args[1] = idx; | 4996 | cb->args[1] = idx; |
4956 | nl80211_finish_netdev_dump(rdev); | 4997 | nl80211_finish_netdev_dump(rdev); |
4957 | 4998 | ||
4958 | return skb->len; | 4999 | return skb->len; |
4959 | } | 5000 | } |
4960 | 5001 | ||
4961 | static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, | 5002 | static int nl80211_send_survey(struct sk_buff *msg, u32 portid, u32 seq, |
4962 | int flags, struct net_device *dev, | 5003 | int flags, struct net_device *dev, |
4963 | struct survey_info *survey) | 5004 | struct survey_info *survey) |
4964 | { | 5005 | { |
4965 | void *hdr; | 5006 | void *hdr; |
4966 | struct nlattr *infoattr; | 5007 | struct nlattr *infoattr; |
4967 | 5008 | ||
4968 | hdr = nl80211hdr_put(msg, portid, seq, flags, | 5009 | hdr = nl80211hdr_put(msg, portid, seq, flags, |
4969 | NL80211_CMD_NEW_SURVEY_RESULTS); | 5010 | NL80211_CMD_NEW_SURVEY_RESULTS); |
4970 | if (!hdr) | 5011 | if (!hdr) |
4971 | return -ENOMEM; | 5012 | return -ENOMEM; |
4972 | 5013 | ||
4973 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) | 5014 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex)) |
4974 | goto nla_put_failure; | 5015 | goto nla_put_failure; |
4975 | 5016 | ||
4976 | infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO); | 5017 | infoattr = nla_nest_start(msg, NL80211_ATTR_SURVEY_INFO); |
4977 | if (!infoattr) | 5018 | if (!infoattr) |
4978 | goto nla_put_failure; | 5019 | goto nla_put_failure; |
4979 | 5020 | ||
4980 | if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, | 5021 | if (nla_put_u32(msg, NL80211_SURVEY_INFO_FREQUENCY, |
4981 | survey->channel->center_freq)) | 5022 | survey->channel->center_freq)) |
4982 | goto nla_put_failure; | 5023 | goto nla_put_failure; |
4983 | 5024 | ||
4984 | if ((survey->filled & SURVEY_INFO_NOISE_DBM) && | 5025 | if ((survey->filled & SURVEY_INFO_NOISE_DBM) && |
4985 | nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise)) | 5026 | nla_put_u8(msg, NL80211_SURVEY_INFO_NOISE, survey->noise)) |
4986 | goto nla_put_failure; | 5027 | goto nla_put_failure; |
4987 | if ((survey->filled & SURVEY_INFO_IN_USE) && | 5028 | if ((survey->filled & SURVEY_INFO_IN_USE) && |
4988 | nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE)) | 5029 | nla_put_flag(msg, NL80211_SURVEY_INFO_IN_USE)) |
4989 | goto nla_put_failure; | 5030 | goto nla_put_failure; |
4990 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME) && | 5031 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME) && |
4991 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, | 5032 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME, |
4992 | survey->channel_time)) | 5033 | survey->channel_time)) |
4993 | goto nla_put_failure; | 5034 | goto nla_put_failure; |
4994 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) && | 5035 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_BUSY) && |
4995 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, | 5036 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_BUSY, |
4996 | survey->channel_time_busy)) | 5037 | survey->channel_time_busy)) |
4997 | goto nla_put_failure; | 5038 | goto nla_put_failure; |
4998 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) && | 5039 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_EXT_BUSY) && |
4999 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, | 5040 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_EXT_BUSY, |
5000 | survey->channel_time_ext_busy)) | 5041 | survey->channel_time_ext_busy)) |
5001 | goto nla_put_failure; | 5042 | goto nla_put_failure; |
5002 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) && | 5043 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_RX) && |
5003 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, | 5044 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_RX, |
5004 | survey->channel_time_rx)) | 5045 | survey->channel_time_rx)) |
5005 | goto nla_put_failure; | 5046 | goto nla_put_failure; |
5006 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) && | 5047 | if ((survey->filled & SURVEY_INFO_CHANNEL_TIME_TX) && |
5007 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, | 5048 | nla_put_u64(msg, NL80211_SURVEY_INFO_CHANNEL_TIME_TX, |
5008 | survey->channel_time_tx)) | 5049 | survey->channel_time_tx)) |
5009 | goto nla_put_failure; | 5050 | goto nla_put_failure; |
5010 | 5051 | ||
5011 | nla_nest_end(msg, infoattr); | 5052 | nla_nest_end(msg, infoattr); |
5012 | 5053 | ||
5013 | return genlmsg_end(msg, hdr); | 5054 | return genlmsg_end(msg, hdr); |
5014 | 5055 | ||
5015 | nla_put_failure: | 5056 | nla_put_failure: |
5016 | genlmsg_cancel(msg, hdr); | 5057 | genlmsg_cancel(msg, hdr); |
5017 | return -EMSGSIZE; | 5058 | return -EMSGSIZE; |
5018 | } | 5059 | } |
5019 | 5060 | ||
5020 | static int nl80211_dump_survey(struct sk_buff *skb, | 5061 | static int nl80211_dump_survey(struct sk_buff *skb, |
5021 | struct netlink_callback *cb) | 5062 | struct netlink_callback *cb) |
5022 | { | 5063 | { |
5023 | struct survey_info survey; | 5064 | struct survey_info survey; |
5024 | struct cfg80211_registered_device *dev; | 5065 | struct cfg80211_registered_device *dev; |
5025 | struct net_device *netdev; | 5066 | struct net_device *netdev; |
5026 | int survey_idx = cb->args[1]; | 5067 | int survey_idx = cb->args[1]; |
5027 | int res; | 5068 | int res; |
5028 | 5069 | ||
5029 | res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); | 5070 | res = nl80211_prepare_netdev_dump(skb, cb, &dev, &netdev); |
5030 | if (res) | 5071 | if (res) |
5031 | return res; | 5072 | return res; |
5032 | 5073 | ||
5033 | if (!dev->ops->dump_survey) { | 5074 | if (!dev->ops->dump_survey) { |
5034 | res = -EOPNOTSUPP; | 5075 | res = -EOPNOTSUPP; |
5035 | goto out_err; | 5076 | goto out_err; |
5036 | } | 5077 | } |
5037 | 5078 | ||
5038 | while (1) { | 5079 | while (1) { |
5039 | struct ieee80211_channel *chan; | 5080 | struct ieee80211_channel *chan; |
5040 | 5081 | ||
5041 | res = rdev_dump_survey(dev, netdev, survey_idx, &survey); | 5082 | res = rdev_dump_survey(dev, netdev, survey_idx, &survey); |
5042 | if (res == -ENOENT) | 5083 | if (res == -ENOENT) |
5043 | break; | 5084 | break; |
5044 | if (res) | 5085 | if (res) |
5045 | goto out_err; | 5086 | goto out_err; |
5046 | 5087 | ||
5047 | /* Survey without a channel doesn't make sense */ | 5088 | /* Survey without a channel doesn't make sense */ |
5048 | if (!survey.channel) { | 5089 | if (!survey.channel) { |
5049 | res = -EINVAL; | 5090 | res = -EINVAL; |
5050 | goto out; | 5091 | goto out; |
5051 | } | 5092 | } |
5052 | 5093 | ||
5053 | chan = ieee80211_get_channel(&dev->wiphy, | 5094 | chan = ieee80211_get_channel(&dev->wiphy, |
5054 | survey.channel->center_freq); | 5095 | survey.channel->center_freq); |
5055 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { | 5096 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { |
5056 | survey_idx++; | 5097 | survey_idx++; |
5057 | continue; | 5098 | continue; |
5058 | } | 5099 | } |
5059 | 5100 | ||
5060 | if (nl80211_send_survey(skb, | 5101 | if (nl80211_send_survey(skb, |
5061 | NETLINK_CB(cb->skb).portid, | 5102 | NETLINK_CB(cb->skb).portid, |
5062 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 5103 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
5063 | netdev, | 5104 | netdev, |
5064 | &survey) < 0) | 5105 | &survey) < 0) |
5065 | goto out; | 5106 | goto out; |
5066 | survey_idx++; | 5107 | survey_idx++; |
5067 | } | 5108 | } |
5068 | 5109 | ||
5069 | out: | 5110 | out: |
5070 | cb->args[1] = survey_idx; | 5111 | cb->args[1] = survey_idx; |
5071 | res = skb->len; | 5112 | res = skb->len; |
5072 | out_err: | 5113 | out_err: |
5073 | nl80211_finish_netdev_dump(dev); | 5114 | nl80211_finish_netdev_dump(dev); |
5074 | return res; | 5115 | return res; |
5075 | } | 5116 | } |
5076 | 5117 | ||
5077 | static bool nl80211_valid_wpa_versions(u32 wpa_versions) | 5118 | static bool nl80211_valid_wpa_versions(u32 wpa_versions) |
5078 | { | 5119 | { |
5079 | return !(wpa_versions & ~(NL80211_WPA_VERSION_1 | | 5120 | return !(wpa_versions & ~(NL80211_WPA_VERSION_1 | |
5080 | NL80211_WPA_VERSION_2)); | 5121 | NL80211_WPA_VERSION_2)); |
5081 | } | 5122 | } |
5082 | 5123 | ||
5083 | static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) | 5124 | static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info) |
5084 | { | 5125 | { |
5085 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5126 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5086 | struct net_device *dev = info->user_ptr[1]; | 5127 | struct net_device *dev = info->user_ptr[1]; |
5087 | struct ieee80211_channel *chan; | 5128 | struct ieee80211_channel *chan; |
5088 | const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL; | 5129 | const u8 *bssid, *ssid, *ie = NULL, *sae_data = NULL; |
5089 | int err, ssid_len, ie_len = 0, sae_data_len = 0; | 5130 | int err, ssid_len, ie_len = 0, sae_data_len = 0; |
5090 | enum nl80211_auth_type auth_type; | 5131 | enum nl80211_auth_type auth_type; |
5091 | struct key_parse key; | 5132 | struct key_parse key; |
5092 | bool local_state_change; | 5133 | bool local_state_change; |
5093 | 5134 | ||
5094 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 5135 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
5095 | return -EINVAL; | 5136 | return -EINVAL; |
5096 | 5137 | ||
5097 | if (!info->attrs[NL80211_ATTR_MAC]) | 5138 | if (!info->attrs[NL80211_ATTR_MAC]) |
5098 | return -EINVAL; | 5139 | return -EINVAL; |
5099 | 5140 | ||
5100 | if (!info->attrs[NL80211_ATTR_AUTH_TYPE]) | 5141 | if (!info->attrs[NL80211_ATTR_AUTH_TYPE]) |
5101 | return -EINVAL; | 5142 | return -EINVAL; |
5102 | 5143 | ||
5103 | if (!info->attrs[NL80211_ATTR_SSID]) | 5144 | if (!info->attrs[NL80211_ATTR_SSID]) |
5104 | return -EINVAL; | 5145 | return -EINVAL; |
5105 | 5146 | ||
5106 | if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) | 5147 | if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) |
5107 | return -EINVAL; | 5148 | return -EINVAL; |
5108 | 5149 | ||
5109 | err = nl80211_parse_key(info, &key); | 5150 | err = nl80211_parse_key(info, &key); |
5110 | if (err) | 5151 | if (err) |
5111 | return err; | 5152 | return err; |
5112 | 5153 | ||
5113 | if (key.idx >= 0) { | 5154 | if (key.idx >= 0) { |
5114 | if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP) | 5155 | if (key.type != -1 && key.type != NL80211_KEYTYPE_GROUP) |
5115 | return -EINVAL; | 5156 | return -EINVAL; |
5116 | if (!key.p.key || !key.p.key_len) | 5157 | if (!key.p.key || !key.p.key_len) |
5117 | return -EINVAL; | 5158 | return -EINVAL; |
5118 | if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 || | 5159 | if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 || |
5119 | key.p.key_len != WLAN_KEY_LEN_WEP40) && | 5160 | key.p.key_len != WLAN_KEY_LEN_WEP40) && |
5120 | (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 || | 5161 | (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 || |
5121 | key.p.key_len != WLAN_KEY_LEN_WEP104)) | 5162 | key.p.key_len != WLAN_KEY_LEN_WEP104)) |
5122 | return -EINVAL; | 5163 | return -EINVAL; |
5123 | if (key.idx > 4) | 5164 | if (key.idx > 4) |
5124 | return -EINVAL; | 5165 | return -EINVAL; |
5125 | } else { | 5166 | } else { |
5126 | key.p.key_len = 0; | 5167 | key.p.key_len = 0; |
5127 | key.p.key = NULL; | 5168 | key.p.key = NULL; |
5128 | } | 5169 | } |
5129 | 5170 | ||
5130 | if (key.idx >= 0) { | 5171 | if (key.idx >= 0) { |
5131 | int i; | 5172 | int i; |
5132 | bool ok = false; | 5173 | bool ok = false; |
5133 | for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) { | 5174 | for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) { |
5134 | if (key.p.cipher == rdev->wiphy.cipher_suites[i]) { | 5175 | if (key.p.cipher == rdev->wiphy.cipher_suites[i]) { |
5135 | ok = true; | 5176 | ok = true; |
5136 | break; | 5177 | break; |
5137 | } | 5178 | } |
5138 | } | 5179 | } |
5139 | if (!ok) | 5180 | if (!ok) |
5140 | return -EINVAL; | 5181 | return -EINVAL; |
5141 | } | 5182 | } |
5142 | 5183 | ||
5143 | if (!rdev->ops->auth) | 5184 | if (!rdev->ops->auth) |
5144 | return -EOPNOTSUPP; | 5185 | return -EOPNOTSUPP; |
5145 | 5186 | ||
5146 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 5187 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
5147 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 5188 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
5148 | return -EOPNOTSUPP; | 5189 | return -EOPNOTSUPP; |
5149 | 5190 | ||
5150 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5191 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5151 | chan = ieee80211_get_channel(&rdev->wiphy, | 5192 | chan = ieee80211_get_channel(&rdev->wiphy, |
5152 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); | 5193 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); |
5153 | if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) | 5194 | if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) |
5154 | return -EINVAL; | 5195 | return -EINVAL; |
5155 | 5196 | ||
5156 | ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 5197 | ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
5157 | ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | 5198 | ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
5158 | 5199 | ||
5159 | if (info->attrs[NL80211_ATTR_IE]) { | 5200 | if (info->attrs[NL80211_ATTR_IE]) { |
5160 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 5201 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
5161 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5202 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
5162 | } | 5203 | } |
5163 | 5204 | ||
5164 | auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); | 5205 | auth_type = nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); |
5165 | if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE)) | 5206 | if (!nl80211_valid_auth_type(rdev, auth_type, NL80211_CMD_AUTHENTICATE)) |
5166 | return -EINVAL; | 5207 | return -EINVAL; |
5167 | 5208 | ||
5168 | if (auth_type == NL80211_AUTHTYPE_SAE && | 5209 | if (auth_type == NL80211_AUTHTYPE_SAE && |
5169 | !info->attrs[NL80211_ATTR_SAE_DATA]) | 5210 | !info->attrs[NL80211_ATTR_SAE_DATA]) |
5170 | return -EINVAL; | 5211 | return -EINVAL; |
5171 | 5212 | ||
5172 | if (info->attrs[NL80211_ATTR_SAE_DATA]) { | 5213 | if (info->attrs[NL80211_ATTR_SAE_DATA]) { |
5173 | if (auth_type != NL80211_AUTHTYPE_SAE) | 5214 | if (auth_type != NL80211_AUTHTYPE_SAE) |
5174 | return -EINVAL; | 5215 | return -EINVAL; |
5175 | sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]); | 5216 | sae_data = nla_data(info->attrs[NL80211_ATTR_SAE_DATA]); |
5176 | sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]); | 5217 | sae_data_len = nla_len(info->attrs[NL80211_ATTR_SAE_DATA]); |
5177 | /* need to include at least Auth Transaction and Status Code */ | 5218 | /* need to include at least Auth Transaction and Status Code */ |
5178 | if (sae_data_len < 4) | 5219 | if (sae_data_len < 4) |
5179 | return -EINVAL; | 5220 | return -EINVAL; |
5180 | } | 5221 | } |
5181 | 5222 | ||
5182 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; | 5223 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
5183 | 5224 | ||
5184 | /* | 5225 | /* |
5185 | * Since we no longer track auth state, ignore | 5226 | * Since we no longer track auth state, ignore |
5186 | * requests to only change local state. | 5227 | * requests to only change local state. |
5187 | */ | 5228 | */ |
5188 | if (local_state_change) | 5229 | if (local_state_change) |
5189 | return 0; | 5230 | return 0; |
5190 | 5231 | ||
5191 | return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, | 5232 | return cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, |
5192 | ssid, ssid_len, ie, ie_len, | 5233 | ssid, ssid_len, ie, ie_len, |
5193 | key.p.key, key.p.key_len, key.idx, | 5234 | key.p.key, key.p.key_len, key.idx, |
5194 | sae_data, sae_data_len); | 5235 | sae_data, sae_data_len); |
5195 | } | 5236 | } |
5196 | 5237 | ||
5197 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, | 5238 | static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev, |
5198 | struct genl_info *info, | 5239 | struct genl_info *info, |
5199 | struct cfg80211_crypto_settings *settings, | 5240 | struct cfg80211_crypto_settings *settings, |
5200 | int cipher_limit) | 5241 | int cipher_limit) |
5201 | { | 5242 | { |
5202 | memset(settings, 0, sizeof(*settings)); | 5243 | memset(settings, 0, sizeof(*settings)); |
5203 | 5244 | ||
5204 | settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT]; | 5245 | settings->control_port = info->attrs[NL80211_ATTR_CONTROL_PORT]; |
5205 | 5246 | ||
5206 | if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) { | 5247 | if (info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]) { |
5207 | u16 proto; | 5248 | u16 proto; |
5208 | proto = nla_get_u16( | 5249 | proto = nla_get_u16( |
5209 | info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]); | 5250 | info->attrs[NL80211_ATTR_CONTROL_PORT_ETHERTYPE]); |
5210 | settings->control_port_ethertype = cpu_to_be16(proto); | 5251 | settings->control_port_ethertype = cpu_to_be16(proto); |
5211 | if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && | 5252 | if (!(rdev->wiphy.flags & WIPHY_FLAG_CONTROL_PORT_PROTOCOL) && |
5212 | proto != ETH_P_PAE) | 5253 | proto != ETH_P_PAE) |
5213 | return -EINVAL; | 5254 | return -EINVAL; |
5214 | if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]) | 5255 | if (info->attrs[NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT]) |
5215 | settings->control_port_no_encrypt = true; | 5256 | settings->control_port_no_encrypt = true; |
5216 | } else | 5257 | } else |
5217 | settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE); | 5258 | settings->control_port_ethertype = cpu_to_be16(ETH_P_PAE); |
5218 | 5259 | ||
5219 | if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) { | 5260 | if (info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]) { |
5220 | void *data; | 5261 | void *data; |
5221 | int len, i; | 5262 | int len, i; |
5222 | 5263 | ||
5223 | data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]); | 5264 | data = nla_data(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]); |
5224 | len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]); | 5265 | len = nla_len(info->attrs[NL80211_ATTR_CIPHER_SUITES_PAIRWISE]); |
5225 | settings->n_ciphers_pairwise = len / sizeof(u32); | 5266 | settings->n_ciphers_pairwise = len / sizeof(u32); |
5226 | 5267 | ||
5227 | if (len % sizeof(u32)) | 5268 | if (len % sizeof(u32)) |
5228 | return -EINVAL; | 5269 | return -EINVAL; |
5229 | 5270 | ||
5230 | if (settings->n_ciphers_pairwise > cipher_limit) | 5271 | if (settings->n_ciphers_pairwise > cipher_limit) |
5231 | return -EINVAL; | 5272 | return -EINVAL; |
5232 | 5273 | ||
5233 | memcpy(settings->ciphers_pairwise, data, len); | 5274 | memcpy(settings->ciphers_pairwise, data, len); |
5234 | 5275 | ||
5235 | for (i = 0; i < settings->n_ciphers_pairwise; i++) | 5276 | for (i = 0; i < settings->n_ciphers_pairwise; i++) |
5236 | if (!cfg80211_supported_cipher_suite( | 5277 | if (!cfg80211_supported_cipher_suite( |
5237 | &rdev->wiphy, | 5278 | &rdev->wiphy, |
5238 | settings->ciphers_pairwise[i])) | 5279 | settings->ciphers_pairwise[i])) |
5239 | return -EINVAL; | 5280 | return -EINVAL; |
5240 | } | 5281 | } |
5241 | 5282 | ||
5242 | if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { | 5283 | if (info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]) { |
5243 | settings->cipher_group = | 5284 | settings->cipher_group = |
5244 | nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); | 5285 | nla_get_u32(info->attrs[NL80211_ATTR_CIPHER_SUITE_GROUP]); |
5245 | if (!cfg80211_supported_cipher_suite(&rdev->wiphy, | 5286 | if (!cfg80211_supported_cipher_suite(&rdev->wiphy, |
5246 | settings->cipher_group)) | 5287 | settings->cipher_group)) |
5247 | return -EINVAL; | 5288 | return -EINVAL; |
5248 | } | 5289 | } |
5249 | 5290 | ||
5250 | if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) { | 5291 | if (info->attrs[NL80211_ATTR_WPA_VERSIONS]) { |
5251 | settings->wpa_versions = | 5292 | settings->wpa_versions = |
5252 | nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]); | 5293 | nla_get_u32(info->attrs[NL80211_ATTR_WPA_VERSIONS]); |
5253 | if (!nl80211_valid_wpa_versions(settings->wpa_versions)) | 5294 | if (!nl80211_valid_wpa_versions(settings->wpa_versions)) |
5254 | return -EINVAL; | 5295 | return -EINVAL; |
5255 | } | 5296 | } |
5256 | 5297 | ||
5257 | if (info->attrs[NL80211_ATTR_AKM_SUITES]) { | 5298 | if (info->attrs[NL80211_ATTR_AKM_SUITES]) { |
5258 | void *data; | 5299 | void *data; |
5259 | int len; | 5300 | int len; |
5260 | 5301 | ||
5261 | data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); | 5302 | data = nla_data(info->attrs[NL80211_ATTR_AKM_SUITES]); |
5262 | len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); | 5303 | len = nla_len(info->attrs[NL80211_ATTR_AKM_SUITES]); |
5263 | settings->n_akm_suites = len / sizeof(u32); | 5304 | settings->n_akm_suites = len / sizeof(u32); |
5264 | 5305 | ||
5265 | if (len % sizeof(u32)) | 5306 | if (len % sizeof(u32)) |
5266 | return -EINVAL; | 5307 | return -EINVAL; |
5267 | 5308 | ||
5268 | if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES) | 5309 | if (settings->n_akm_suites > NL80211_MAX_NR_AKM_SUITES) |
5269 | return -EINVAL; | 5310 | return -EINVAL; |
5270 | 5311 | ||
5271 | memcpy(settings->akm_suites, data, len); | 5312 | memcpy(settings->akm_suites, data, len); |
5272 | } | 5313 | } |
5273 | 5314 | ||
5274 | return 0; | 5315 | return 0; |
5275 | } | 5316 | } |
5276 | 5317 | ||
5277 | static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) | 5318 | static int nl80211_associate(struct sk_buff *skb, struct genl_info *info) |
5278 | { | 5319 | { |
5279 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5320 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5280 | struct net_device *dev = info->user_ptr[1]; | 5321 | struct net_device *dev = info->user_ptr[1]; |
5281 | struct cfg80211_crypto_settings crypto; | 5322 | struct cfg80211_crypto_settings crypto; |
5282 | struct ieee80211_channel *chan; | 5323 | struct ieee80211_channel *chan; |
5283 | const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; | 5324 | const u8 *bssid, *ssid, *ie = NULL, *prev_bssid = NULL; |
5284 | int err, ssid_len, ie_len = 0; | 5325 | int err, ssid_len, ie_len = 0; |
5285 | bool use_mfp = false; | 5326 | bool use_mfp = false; |
5286 | u32 flags = 0; | 5327 | u32 flags = 0; |
5287 | struct ieee80211_ht_cap *ht_capa = NULL; | 5328 | struct ieee80211_ht_cap *ht_capa = NULL; |
5288 | struct ieee80211_ht_cap *ht_capa_mask = NULL; | 5329 | struct ieee80211_ht_cap *ht_capa_mask = NULL; |
5289 | 5330 | ||
5290 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 5331 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
5291 | return -EINVAL; | 5332 | return -EINVAL; |
5292 | 5333 | ||
5293 | if (!info->attrs[NL80211_ATTR_MAC] || | 5334 | if (!info->attrs[NL80211_ATTR_MAC] || |
5294 | !info->attrs[NL80211_ATTR_SSID] || | 5335 | !info->attrs[NL80211_ATTR_SSID] || |
5295 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) | 5336 | !info->attrs[NL80211_ATTR_WIPHY_FREQ]) |
5296 | return -EINVAL; | 5337 | return -EINVAL; |
5297 | 5338 | ||
5298 | if (!rdev->ops->assoc) | 5339 | if (!rdev->ops->assoc) |
5299 | return -EOPNOTSUPP; | 5340 | return -EOPNOTSUPP; |
5300 | 5341 | ||
5301 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 5342 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
5302 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 5343 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
5303 | return -EOPNOTSUPP; | 5344 | return -EOPNOTSUPP; |
5304 | 5345 | ||
5305 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5346 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5306 | 5347 | ||
5307 | chan = ieee80211_get_channel(&rdev->wiphy, | 5348 | chan = ieee80211_get_channel(&rdev->wiphy, |
5308 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); | 5349 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); |
5309 | if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) | 5350 | if (!chan || (chan->flags & IEEE80211_CHAN_DISABLED)) |
5310 | return -EINVAL; | 5351 | return -EINVAL; |
5311 | 5352 | ||
5312 | ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 5353 | ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
5313 | ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | 5354 | ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
5314 | 5355 | ||
5315 | if (info->attrs[NL80211_ATTR_IE]) { | 5356 | if (info->attrs[NL80211_ATTR_IE]) { |
5316 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 5357 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
5317 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5358 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
5318 | } | 5359 | } |
5319 | 5360 | ||
5320 | if (info->attrs[NL80211_ATTR_USE_MFP]) { | 5361 | if (info->attrs[NL80211_ATTR_USE_MFP]) { |
5321 | enum nl80211_mfp mfp = | 5362 | enum nl80211_mfp mfp = |
5322 | nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); | 5363 | nla_get_u32(info->attrs[NL80211_ATTR_USE_MFP]); |
5323 | if (mfp == NL80211_MFP_REQUIRED) | 5364 | if (mfp == NL80211_MFP_REQUIRED) |
5324 | use_mfp = true; | 5365 | use_mfp = true; |
5325 | else if (mfp != NL80211_MFP_NO) | 5366 | else if (mfp != NL80211_MFP_NO) |
5326 | return -EINVAL; | 5367 | return -EINVAL; |
5327 | } | 5368 | } |
5328 | 5369 | ||
5329 | if (info->attrs[NL80211_ATTR_PREV_BSSID]) | 5370 | if (info->attrs[NL80211_ATTR_PREV_BSSID]) |
5330 | prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); | 5371 | prev_bssid = nla_data(info->attrs[NL80211_ATTR_PREV_BSSID]); |
5331 | 5372 | ||
5332 | if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT])) | 5373 | if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT])) |
5333 | flags |= ASSOC_REQ_DISABLE_HT; | 5374 | flags |= ASSOC_REQ_DISABLE_HT; |
5334 | 5375 | ||
5335 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) | 5376 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) |
5336 | ht_capa_mask = | 5377 | ht_capa_mask = |
5337 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]); | 5378 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]); |
5338 | 5379 | ||
5339 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { | 5380 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { |
5340 | if (!ht_capa_mask) | 5381 | if (!ht_capa_mask) |
5341 | return -EINVAL; | 5382 | return -EINVAL; |
5342 | ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); | 5383 | ht_capa = nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]); |
5343 | } | 5384 | } |
5344 | 5385 | ||
5345 | err = nl80211_crypto_settings(rdev, info, &crypto, 1); | 5386 | err = nl80211_crypto_settings(rdev, info, &crypto, 1); |
5346 | if (!err) | 5387 | if (!err) |
5347 | err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, | 5388 | err = cfg80211_mlme_assoc(rdev, dev, chan, bssid, prev_bssid, |
5348 | ssid, ssid_len, ie, ie_len, use_mfp, | 5389 | ssid, ssid_len, ie, ie_len, use_mfp, |
5349 | &crypto, flags, ht_capa, | 5390 | &crypto, flags, ht_capa, |
5350 | ht_capa_mask); | 5391 | ht_capa_mask); |
5351 | 5392 | ||
5352 | return err; | 5393 | return err; |
5353 | } | 5394 | } |
5354 | 5395 | ||
5355 | static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) | 5396 | static int nl80211_deauthenticate(struct sk_buff *skb, struct genl_info *info) |
5356 | { | 5397 | { |
5357 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5398 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5358 | struct net_device *dev = info->user_ptr[1]; | 5399 | struct net_device *dev = info->user_ptr[1]; |
5359 | const u8 *ie = NULL, *bssid; | 5400 | const u8 *ie = NULL, *bssid; |
5360 | int ie_len = 0; | 5401 | int ie_len = 0; |
5361 | u16 reason_code; | 5402 | u16 reason_code; |
5362 | bool local_state_change; | 5403 | bool local_state_change; |
5363 | 5404 | ||
5364 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 5405 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
5365 | return -EINVAL; | 5406 | return -EINVAL; |
5366 | 5407 | ||
5367 | if (!info->attrs[NL80211_ATTR_MAC]) | 5408 | if (!info->attrs[NL80211_ATTR_MAC]) |
5368 | return -EINVAL; | 5409 | return -EINVAL; |
5369 | 5410 | ||
5370 | if (!info->attrs[NL80211_ATTR_REASON_CODE]) | 5411 | if (!info->attrs[NL80211_ATTR_REASON_CODE]) |
5371 | return -EINVAL; | 5412 | return -EINVAL; |
5372 | 5413 | ||
5373 | if (!rdev->ops->deauth) | 5414 | if (!rdev->ops->deauth) |
5374 | return -EOPNOTSUPP; | 5415 | return -EOPNOTSUPP; |
5375 | 5416 | ||
5376 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 5417 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
5377 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 5418 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
5378 | return -EOPNOTSUPP; | 5419 | return -EOPNOTSUPP; |
5379 | 5420 | ||
5380 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5421 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5381 | 5422 | ||
5382 | reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); | 5423 | reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); |
5383 | if (reason_code == 0) { | 5424 | if (reason_code == 0) { |
5384 | /* Reason Code 0 is reserved */ | 5425 | /* Reason Code 0 is reserved */ |
5385 | return -EINVAL; | 5426 | return -EINVAL; |
5386 | } | 5427 | } |
5387 | 5428 | ||
5388 | if (info->attrs[NL80211_ATTR_IE]) { | 5429 | if (info->attrs[NL80211_ATTR_IE]) { |
5389 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 5430 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
5390 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5431 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
5391 | } | 5432 | } |
5392 | 5433 | ||
5393 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; | 5434 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
5394 | 5435 | ||
5395 | return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, | 5436 | return cfg80211_mlme_deauth(rdev, dev, bssid, ie, ie_len, reason_code, |
5396 | local_state_change); | 5437 | local_state_change); |
5397 | } | 5438 | } |
5398 | 5439 | ||
5399 | static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) | 5440 | static int nl80211_disassociate(struct sk_buff *skb, struct genl_info *info) |
5400 | { | 5441 | { |
5401 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5442 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5402 | struct net_device *dev = info->user_ptr[1]; | 5443 | struct net_device *dev = info->user_ptr[1]; |
5403 | const u8 *ie = NULL, *bssid; | 5444 | const u8 *ie = NULL, *bssid; |
5404 | int ie_len = 0; | 5445 | int ie_len = 0; |
5405 | u16 reason_code; | 5446 | u16 reason_code; |
5406 | bool local_state_change; | 5447 | bool local_state_change; |
5407 | 5448 | ||
5408 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 5449 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
5409 | return -EINVAL; | 5450 | return -EINVAL; |
5410 | 5451 | ||
5411 | if (!info->attrs[NL80211_ATTR_MAC]) | 5452 | if (!info->attrs[NL80211_ATTR_MAC]) |
5412 | return -EINVAL; | 5453 | return -EINVAL; |
5413 | 5454 | ||
5414 | if (!info->attrs[NL80211_ATTR_REASON_CODE]) | 5455 | if (!info->attrs[NL80211_ATTR_REASON_CODE]) |
5415 | return -EINVAL; | 5456 | return -EINVAL; |
5416 | 5457 | ||
5417 | if (!rdev->ops->disassoc) | 5458 | if (!rdev->ops->disassoc) |
5418 | return -EOPNOTSUPP; | 5459 | return -EOPNOTSUPP; |
5419 | 5460 | ||
5420 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 5461 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
5421 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 5462 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
5422 | return -EOPNOTSUPP; | 5463 | return -EOPNOTSUPP; |
5423 | 5464 | ||
5424 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5465 | bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5425 | 5466 | ||
5426 | reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); | 5467 | reason_code = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); |
5427 | if (reason_code == 0) { | 5468 | if (reason_code == 0) { |
5428 | /* Reason Code 0 is reserved */ | 5469 | /* Reason Code 0 is reserved */ |
5429 | return -EINVAL; | 5470 | return -EINVAL; |
5430 | } | 5471 | } |
5431 | 5472 | ||
5432 | if (info->attrs[NL80211_ATTR_IE]) { | 5473 | if (info->attrs[NL80211_ATTR_IE]) { |
5433 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 5474 | ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
5434 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5475 | ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
5435 | } | 5476 | } |
5436 | 5477 | ||
5437 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; | 5478 | local_state_change = !!info->attrs[NL80211_ATTR_LOCAL_STATE_CHANGE]; |
5438 | 5479 | ||
5439 | return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, | 5480 | return cfg80211_mlme_disassoc(rdev, dev, bssid, ie, ie_len, reason_code, |
5440 | local_state_change); | 5481 | local_state_change); |
5441 | } | 5482 | } |
5442 | 5483 | ||
5443 | static bool | 5484 | static bool |
5444 | nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev, | 5485 | nl80211_parse_mcast_rate(struct cfg80211_registered_device *rdev, |
5445 | int mcast_rate[IEEE80211_NUM_BANDS], | 5486 | int mcast_rate[IEEE80211_NUM_BANDS], |
5446 | int rateval) | 5487 | int rateval) |
5447 | { | 5488 | { |
5448 | struct wiphy *wiphy = &rdev->wiphy; | 5489 | struct wiphy *wiphy = &rdev->wiphy; |
5449 | bool found = false; | 5490 | bool found = false; |
5450 | int band, i; | 5491 | int band, i; |
5451 | 5492 | ||
5452 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 5493 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
5453 | struct ieee80211_supported_band *sband; | 5494 | struct ieee80211_supported_band *sband; |
5454 | 5495 | ||
5455 | sband = wiphy->bands[band]; | 5496 | sband = wiphy->bands[band]; |
5456 | if (!sband) | 5497 | if (!sband) |
5457 | continue; | 5498 | continue; |
5458 | 5499 | ||
5459 | for (i = 0; i < sband->n_bitrates; i++) { | 5500 | for (i = 0; i < sband->n_bitrates; i++) { |
5460 | if (sband->bitrates[i].bitrate == rateval) { | 5501 | if (sband->bitrates[i].bitrate == rateval) { |
5461 | mcast_rate[band] = i + 1; | 5502 | mcast_rate[band] = i + 1; |
5462 | found = true; | 5503 | found = true; |
5463 | break; | 5504 | break; |
5464 | } | 5505 | } |
5465 | } | 5506 | } |
5466 | } | 5507 | } |
5467 | 5508 | ||
5468 | return found; | 5509 | return found; |
5469 | } | 5510 | } |
5470 | 5511 | ||
5471 | static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | 5512 | static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) |
5472 | { | 5513 | { |
5473 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5514 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5474 | struct net_device *dev = info->user_ptr[1]; | 5515 | struct net_device *dev = info->user_ptr[1]; |
5475 | struct cfg80211_ibss_params ibss; | 5516 | struct cfg80211_ibss_params ibss; |
5476 | struct wiphy *wiphy; | 5517 | struct wiphy *wiphy; |
5477 | struct cfg80211_cached_keys *connkeys = NULL; | 5518 | struct cfg80211_cached_keys *connkeys = NULL; |
5478 | int err; | 5519 | int err; |
5479 | 5520 | ||
5480 | memset(&ibss, 0, sizeof(ibss)); | 5521 | memset(&ibss, 0, sizeof(ibss)); |
5481 | 5522 | ||
5482 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 5523 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
5483 | return -EINVAL; | 5524 | return -EINVAL; |
5484 | 5525 | ||
5485 | if (!info->attrs[NL80211_ATTR_SSID] || | 5526 | if (!info->attrs[NL80211_ATTR_SSID] || |
5486 | !nla_len(info->attrs[NL80211_ATTR_SSID])) | 5527 | !nla_len(info->attrs[NL80211_ATTR_SSID])) |
5487 | return -EINVAL; | 5528 | return -EINVAL; |
5488 | 5529 | ||
5489 | ibss.beacon_interval = 100; | 5530 | ibss.beacon_interval = 100; |
5490 | 5531 | ||
5491 | if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { | 5532 | if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { |
5492 | ibss.beacon_interval = | 5533 | ibss.beacon_interval = |
5493 | nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); | 5534 | nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); |
5494 | if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000) | 5535 | if (ibss.beacon_interval < 1 || ibss.beacon_interval > 10000) |
5495 | return -EINVAL; | 5536 | return -EINVAL; |
5496 | } | 5537 | } |
5497 | 5538 | ||
5498 | if (!rdev->ops->join_ibss) | 5539 | if (!rdev->ops->join_ibss) |
5499 | return -EOPNOTSUPP; | 5540 | return -EOPNOTSUPP; |
5500 | 5541 | ||
5501 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) | 5542 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) |
5502 | return -EOPNOTSUPP; | 5543 | return -EOPNOTSUPP; |
5503 | 5544 | ||
5504 | wiphy = &rdev->wiphy; | 5545 | wiphy = &rdev->wiphy; |
5505 | 5546 | ||
5506 | if (info->attrs[NL80211_ATTR_MAC]) { | 5547 | if (info->attrs[NL80211_ATTR_MAC]) { |
5507 | ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5548 | ibss.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5508 | 5549 | ||
5509 | if (!is_valid_ether_addr(ibss.bssid)) | 5550 | if (!is_valid_ether_addr(ibss.bssid)) |
5510 | return -EINVAL; | 5551 | return -EINVAL; |
5511 | } | 5552 | } |
5512 | ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 5553 | ibss.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
5513 | ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | 5554 | ibss.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
5514 | 5555 | ||
5515 | if (info->attrs[NL80211_ATTR_IE]) { | 5556 | if (info->attrs[NL80211_ATTR_IE]) { |
5516 | ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 5557 | ibss.ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
5517 | ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5558 | ibss.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
5518 | } | 5559 | } |
5519 | 5560 | ||
5520 | err = nl80211_parse_chandef(rdev, info, &ibss.chandef); | 5561 | err = nl80211_parse_chandef(rdev, info, &ibss.chandef); |
5521 | if (err) | 5562 | if (err) |
5522 | return err; | 5563 | return err; |
5523 | 5564 | ||
5524 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) | 5565 | if (!cfg80211_reg_can_beacon(&rdev->wiphy, &ibss.chandef)) |
5525 | return -EINVAL; | 5566 | return -EINVAL; |
5526 | 5567 | ||
5527 | if (ibss.chandef.width > NL80211_CHAN_WIDTH_40) | 5568 | if (ibss.chandef.width > NL80211_CHAN_WIDTH_40) |
5528 | return -EINVAL; | 5569 | return -EINVAL; |
5529 | if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && | 5570 | if (ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && |
5530 | !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) | 5571 | !(rdev->wiphy.features & NL80211_FEATURE_HT_IBSS)) |
5531 | return -EINVAL; | 5572 | return -EINVAL; |
5532 | 5573 | ||
5533 | ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; | 5574 | ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; |
5534 | ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; | 5575 | ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY]; |
5535 | 5576 | ||
5536 | if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { | 5577 | if (info->attrs[NL80211_ATTR_BSS_BASIC_RATES]) { |
5537 | u8 *rates = | 5578 | u8 *rates = |
5538 | nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | 5579 | nla_data(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); |
5539 | int n_rates = | 5580 | int n_rates = |
5540 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | 5581 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); |
5541 | struct ieee80211_supported_band *sband = | 5582 | struct ieee80211_supported_band *sband = |
5542 | wiphy->bands[ibss.chandef.chan->band]; | 5583 | wiphy->bands[ibss.chandef.chan->band]; |
5543 | 5584 | ||
5544 | err = ieee80211_get_ratemask(sband, rates, n_rates, | 5585 | err = ieee80211_get_ratemask(sband, rates, n_rates, |
5545 | &ibss.basic_rates); | 5586 | &ibss.basic_rates); |
5546 | if (err) | 5587 | if (err) |
5547 | return err; | 5588 | return err; |
5548 | } | 5589 | } |
5549 | 5590 | ||
5550 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && | 5591 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && |
5551 | !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate, | 5592 | !nl80211_parse_mcast_rate(rdev, ibss.mcast_rate, |
5552 | nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]))) | 5593 | nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]))) |
5553 | return -EINVAL; | 5594 | return -EINVAL; |
5554 | 5595 | ||
5555 | if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { | 5596 | if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) { |
5556 | bool no_ht = false; | 5597 | bool no_ht = false; |
5557 | 5598 | ||
5558 | connkeys = nl80211_parse_connkeys(rdev, | 5599 | connkeys = nl80211_parse_connkeys(rdev, |
5559 | info->attrs[NL80211_ATTR_KEYS], | 5600 | info->attrs[NL80211_ATTR_KEYS], |
5560 | &no_ht); | 5601 | &no_ht); |
5561 | if (IS_ERR(connkeys)) | 5602 | if (IS_ERR(connkeys)) |
5562 | return PTR_ERR(connkeys); | 5603 | return PTR_ERR(connkeys); |
5563 | 5604 | ||
5564 | if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) && | 5605 | if ((ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT) && |
5565 | no_ht) { | 5606 | no_ht) { |
5566 | kfree(connkeys); | 5607 | kfree(connkeys); |
5567 | return -EINVAL; | 5608 | return -EINVAL; |
5568 | } | 5609 | } |
5569 | } | 5610 | } |
5570 | 5611 | ||
5571 | ibss.control_port = | 5612 | ibss.control_port = |
5572 | nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]); | 5613 | nla_get_flag(info->attrs[NL80211_ATTR_CONTROL_PORT]); |
5573 | 5614 | ||
5574 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); | 5615 | err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys); |
5575 | if (err) | 5616 | if (err) |
5576 | kfree(connkeys); | 5617 | kfree(connkeys); |
5577 | return err; | 5618 | return err; |
5578 | } | 5619 | } |
5579 | 5620 | ||
5580 | static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) | 5621 | static int nl80211_leave_ibss(struct sk_buff *skb, struct genl_info *info) |
5581 | { | 5622 | { |
5582 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5623 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5583 | struct net_device *dev = info->user_ptr[1]; | 5624 | struct net_device *dev = info->user_ptr[1]; |
5584 | 5625 | ||
5585 | if (!rdev->ops->leave_ibss) | 5626 | if (!rdev->ops->leave_ibss) |
5586 | return -EOPNOTSUPP; | 5627 | return -EOPNOTSUPP; |
5587 | 5628 | ||
5588 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) | 5629 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC) |
5589 | return -EOPNOTSUPP; | 5630 | return -EOPNOTSUPP; |
5590 | 5631 | ||
5591 | return cfg80211_leave_ibss(rdev, dev, false); | 5632 | return cfg80211_leave_ibss(rdev, dev, false); |
5592 | } | 5633 | } |
5593 | 5634 | ||
5594 | static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info) | 5635 | static int nl80211_set_mcast_rate(struct sk_buff *skb, struct genl_info *info) |
5595 | { | 5636 | { |
5596 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5637 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5597 | struct net_device *dev = info->user_ptr[1]; | 5638 | struct net_device *dev = info->user_ptr[1]; |
5598 | int mcast_rate[IEEE80211_NUM_BANDS]; | 5639 | int mcast_rate[IEEE80211_NUM_BANDS]; |
5599 | u32 nla_rate; | 5640 | u32 nla_rate; |
5600 | int err; | 5641 | int err; |
5601 | 5642 | ||
5602 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && | 5643 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_ADHOC && |
5603 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) | 5644 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT) |
5604 | return -EOPNOTSUPP; | 5645 | return -EOPNOTSUPP; |
5605 | 5646 | ||
5606 | if (!rdev->ops->set_mcast_rate) | 5647 | if (!rdev->ops->set_mcast_rate) |
5607 | return -EOPNOTSUPP; | 5648 | return -EOPNOTSUPP; |
5608 | 5649 | ||
5609 | memset(mcast_rate, 0, sizeof(mcast_rate)); | 5650 | memset(mcast_rate, 0, sizeof(mcast_rate)); |
5610 | 5651 | ||
5611 | if (!info->attrs[NL80211_ATTR_MCAST_RATE]) | 5652 | if (!info->attrs[NL80211_ATTR_MCAST_RATE]) |
5612 | return -EINVAL; | 5653 | return -EINVAL; |
5613 | 5654 | ||
5614 | nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]); | 5655 | nla_rate = nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]); |
5615 | if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate)) | 5656 | if (!nl80211_parse_mcast_rate(rdev, mcast_rate, nla_rate)) |
5616 | return -EINVAL; | 5657 | return -EINVAL; |
5617 | 5658 | ||
5618 | err = rdev->ops->set_mcast_rate(&rdev->wiphy, dev, mcast_rate); | 5659 | err = rdev->ops->set_mcast_rate(&rdev->wiphy, dev, mcast_rate); |
5619 | 5660 | ||
5620 | return err; | 5661 | return err; |
5621 | } | 5662 | } |
5622 | 5663 | ||
5623 | 5664 | ||
5624 | #ifdef CONFIG_NL80211_TESTMODE | 5665 | #ifdef CONFIG_NL80211_TESTMODE |
5625 | static struct genl_multicast_group nl80211_testmode_mcgrp = { | 5666 | static struct genl_multicast_group nl80211_testmode_mcgrp = { |
5626 | .name = "testmode", | 5667 | .name = "testmode", |
5627 | }; | 5668 | }; |
5628 | 5669 | ||
5629 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) | 5670 | static int nl80211_testmode_do(struct sk_buff *skb, struct genl_info *info) |
5630 | { | 5671 | { |
5631 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5672 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5632 | int err; | 5673 | int err; |
5633 | 5674 | ||
5634 | if (!info->attrs[NL80211_ATTR_TESTDATA]) | 5675 | if (!info->attrs[NL80211_ATTR_TESTDATA]) |
5635 | return -EINVAL; | 5676 | return -EINVAL; |
5636 | 5677 | ||
5637 | err = -EOPNOTSUPP; | 5678 | err = -EOPNOTSUPP; |
5638 | if (rdev->ops->testmode_cmd) { | 5679 | if (rdev->ops->testmode_cmd) { |
5639 | rdev->testmode_info = info; | 5680 | rdev->testmode_info = info; |
5640 | err = rdev_testmode_cmd(rdev, | 5681 | err = rdev_testmode_cmd(rdev, |
5641 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), | 5682 | nla_data(info->attrs[NL80211_ATTR_TESTDATA]), |
5642 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); | 5683 | nla_len(info->attrs[NL80211_ATTR_TESTDATA])); |
5643 | rdev->testmode_info = NULL; | 5684 | rdev->testmode_info = NULL; |
5644 | } | 5685 | } |
5645 | 5686 | ||
5646 | return err; | 5687 | return err; |
5647 | } | 5688 | } |
5648 | 5689 | ||
5649 | static int nl80211_testmode_dump(struct sk_buff *skb, | 5690 | static int nl80211_testmode_dump(struct sk_buff *skb, |
5650 | struct netlink_callback *cb) | 5691 | struct netlink_callback *cb) |
5651 | { | 5692 | { |
5652 | struct cfg80211_registered_device *rdev; | 5693 | struct cfg80211_registered_device *rdev; |
5653 | int err; | 5694 | int err; |
5654 | long phy_idx; | 5695 | long phy_idx; |
5655 | void *data = NULL; | 5696 | void *data = NULL; |
5656 | int data_len = 0; | 5697 | int data_len = 0; |
5657 | 5698 | ||
5658 | if (cb->args[0]) { | 5699 | if (cb->args[0]) { |
5659 | /* | 5700 | /* |
5660 | * 0 is a valid index, but not valid for args[0], | 5701 | * 0 is a valid index, but not valid for args[0], |
5661 | * so we need to offset by 1. | 5702 | * so we need to offset by 1. |
5662 | */ | 5703 | */ |
5663 | phy_idx = cb->args[0] - 1; | 5704 | phy_idx = cb->args[0] - 1; |
5664 | } else { | 5705 | } else { |
5665 | err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | 5706 | err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
5666 | nl80211_fam.attrbuf, nl80211_fam.maxattr, | 5707 | nl80211_fam.attrbuf, nl80211_fam.maxattr, |
5667 | nl80211_policy); | 5708 | nl80211_policy); |
5668 | if (err) | 5709 | if (err) |
5669 | return err; | 5710 | return err; |
5670 | 5711 | ||
5671 | mutex_lock(&cfg80211_mutex); | 5712 | mutex_lock(&cfg80211_mutex); |
5672 | rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), | 5713 | rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), |
5673 | nl80211_fam.attrbuf); | 5714 | nl80211_fam.attrbuf); |
5674 | if (IS_ERR(rdev)) { | 5715 | if (IS_ERR(rdev)) { |
5675 | mutex_unlock(&cfg80211_mutex); | 5716 | mutex_unlock(&cfg80211_mutex); |
5676 | return PTR_ERR(rdev); | 5717 | return PTR_ERR(rdev); |
5677 | } | 5718 | } |
5678 | phy_idx = rdev->wiphy_idx; | 5719 | phy_idx = rdev->wiphy_idx; |
5679 | rdev = NULL; | 5720 | rdev = NULL; |
5680 | mutex_unlock(&cfg80211_mutex); | 5721 | mutex_unlock(&cfg80211_mutex); |
5681 | 5722 | ||
5682 | if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) | 5723 | if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) |
5683 | cb->args[1] = | 5724 | cb->args[1] = |
5684 | (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; | 5725 | (long)nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]; |
5685 | } | 5726 | } |
5686 | 5727 | ||
5687 | if (cb->args[1]) { | 5728 | if (cb->args[1]) { |
5688 | data = nla_data((void *)cb->args[1]); | 5729 | data = nla_data((void *)cb->args[1]); |
5689 | data_len = nla_len((void *)cb->args[1]); | 5730 | data_len = nla_len((void *)cb->args[1]); |
5690 | } | 5731 | } |
5691 | 5732 | ||
5692 | mutex_lock(&cfg80211_mutex); | 5733 | mutex_lock(&cfg80211_mutex); |
5693 | rdev = cfg80211_rdev_by_wiphy_idx(phy_idx); | 5734 | rdev = cfg80211_rdev_by_wiphy_idx(phy_idx); |
5694 | if (!rdev) { | 5735 | if (!rdev) { |
5695 | mutex_unlock(&cfg80211_mutex); | 5736 | mutex_unlock(&cfg80211_mutex); |
5696 | return -ENOENT; | 5737 | return -ENOENT; |
5697 | } | 5738 | } |
5698 | cfg80211_lock_rdev(rdev); | 5739 | cfg80211_lock_rdev(rdev); |
5699 | mutex_unlock(&cfg80211_mutex); | 5740 | mutex_unlock(&cfg80211_mutex); |
5700 | 5741 | ||
5701 | if (!rdev->ops->testmode_dump) { | 5742 | if (!rdev->ops->testmode_dump) { |
5702 | err = -EOPNOTSUPP; | 5743 | err = -EOPNOTSUPP; |
5703 | goto out_err; | 5744 | goto out_err; |
5704 | } | 5745 | } |
5705 | 5746 | ||
5706 | while (1) { | 5747 | while (1) { |
5707 | void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid, | 5748 | void *hdr = nl80211hdr_put(skb, NETLINK_CB(cb->skb).portid, |
5708 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 5749 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
5709 | NL80211_CMD_TESTMODE); | 5750 | NL80211_CMD_TESTMODE); |
5710 | struct nlattr *tmdata; | 5751 | struct nlattr *tmdata; |
5711 | 5752 | ||
5712 | if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) { | 5753 | if (nla_put_u32(skb, NL80211_ATTR_WIPHY, phy_idx)) { |
5713 | genlmsg_cancel(skb, hdr); | 5754 | genlmsg_cancel(skb, hdr); |
5714 | break; | 5755 | break; |
5715 | } | 5756 | } |
5716 | 5757 | ||
5717 | tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA); | 5758 | tmdata = nla_nest_start(skb, NL80211_ATTR_TESTDATA); |
5718 | if (!tmdata) { | 5759 | if (!tmdata) { |
5719 | genlmsg_cancel(skb, hdr); | 5760 | genlmsg_cancel(skb, hdr); |
5720 | break; | 5761 | break; |
5721 | } | 5762 | } |
5722 | err = rdev_testmode_dump(rdev, skb, cb, data, data_len); | 5763 | err = rdev_testmode_dump(rdev, skb, cb, data, data_len); |
5723 | nla_nest_end(skb, tmdata); | 5764 | nla_nest_end(skb, tmdata); |
5724 | 5765 | ||
5725 | if (err == -ENOBUFS || err == -ENOENT) { | 5766 | if (err == -ENOBUFS || err == -ENOENT) { |
5726 | genlmsg_cancel(skb, hdr); | 5767 | genlmsg_cancel(skb, hdr); |
5727 | break; | 5768 | break; |
5728 | } else if (err) { | 5769 | } else if (err) { |
5729 | genlmsg_cancel(skb, hdr); | 5770 | genlmsg_cancel(skb, hdr); |
5730 | goto out_err; | 5771 | goto out_err; |
5731 | } | 5772 | } |
5732 | 5773 | ||
5733 | genlmsg_end(skb, hdr); | 5774 | genlmsg_end(skb, hdr); |
5734 | } | 5775 | } |
5735 | 5776 | ||
5736 | err = skb->len; | 5777 | err = skb->len; |
5737 | /* see above */ | 5778 | /* see above */ |
5738 | cb->args[0] = phy_idx + 1; | 5779 | cb->args[0] = phy_idx + 1; |
5739 | out_err: | 5780 | out_err: |
5740 | cfg80211_unlock_rdev(rdev); | 5781 | cfg80211_unlock_rdev(rdev); |
5741 | return err; | 5782 | return err; |
5742 | } | 5783 | } |
5743 | 5784 | ||
5744 | static struct sk_buff * | 5785 | static struct sk_buff * |
5745 | __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, | 5786 | __cfg80211_testmode_alloc_skb(struct cfg80211_registered_device *rdev, |
5746 | int approxlen, u32 portid, u32 seq, gfp_t gfp) | 5787 | int approxlen, u32 portid, u32 seq, gfp_t gfp) |
5747 | { | 5788 | { |
5748 | struct sk_buff *skb; | 5789 | struct sk_buff *skb; |
5749 | void *hdr; | 5790 | void *hdr; |
5750 | struct nlattr *data; | 5791 | struct nlattr *data; |
5751 | 5792 | ||
5752 | skb = nlmsg_new(approxlen + 100, gfp); | 5793 | skb = nlmsg_new(approxlen + 100, gfp); |
5753 | if (!skb) | 5794 | if (!skb) |
5754 | return NULL; | 5795 | return NULL; |
5755 | 5796 | ||
5756 | hdr = nl80211hdr_put(skb, portid, seq, 0, NL80211_CMD_TESTMODE); | 5797 | hdr = nl80211hdr_put(skb, portid, seq, 0, NL80211_CMD_TESTMODE); |
5757 | if (!hdr) { | 5798 | if (!hdr) { |
5758 | kfree_skb(skb); | 5799 | kfree_skb(skb); |
5759 | return NULL; | 5800 | return NULL; |
5760 | } | 5801 | } |
5761 | 5802 | ||
5762 | if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) | 5803 | if (nla_put_u32(skb, NL80211_ATTR_WIPHY, rdev->wiphy_idx)) |
5763 | goto nla_put_failure; | 5804 | goto nla_put_failure; |
5764 | data = nla_nest_start(skb, NL80211_ATTR_TESTDATA); | 5805 | data = nla_nest_start(skb, NL80211_ATTR_TESTDATA); |
5765 | 5806 | ||
5766 | ((void **)skb->cb)[0] = rdev; | 5807 | ((void **)skb->cb)[0] = rdev; |
5767 | ((void **)skb->cb)[1] = hdr; | 5808 | ((void **)skb->cb)[1] = hdr; |
5768 | ((void **)skb->cb)[2] = data; | 5809 | ((void **)skb->cb)[2] = data; |
5769 | 5810 | ||
5770 | return skb; | 5811 | return skb; |
5771 | 5812 | ||
5772 | nla_put_failure: | 5813 | nla_put_failure: |
5773 | kfree_skb(skb); | 5814 | kfree_skb(skb); |
5774 | return NULL; | 5815 | return NULL; |
5775 | } | 5816 | } |
5776 | 5817 | ||
5777 | struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy, | 5818 | struct sk_buff *cfg80211_testmode_alloc_reply_skb(struct wiphy *wiphy, |
5778 | int approxlen) | 5819 | int approxlen) |
5779 | { | 5820 | { |
5780 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 5821 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
5781 | 5822 | ||
5782 | if (WARN_ON(!rdev->testmode_info)) | 5823 | if (WARN_ON(!rdev->testmode_info)) |
5783 | return NULL; | 5824 | return NULL; |
5784 | 5825 | ||
5785 | return __cfg80211_testmode_alloc_skb(rdev, approxlen, | 5826 | return __cfg80211_testmode_alloc_skb(rdev, approxlen, |
5786 | rdev->testmode_info->snd_portid, | 5827 | rdev->testmode_info->snd_portid, |
5787 | rdev->testmode_info->snd_seq, | 5828 | rdev->testmode_info->snd_seq, |
5788 | GFP_KERNEL); | 5829 | GFP_KERNEL); |
5789 | } | 5830 | } |
5790 | EXPORT_SYMBOL(cfg80211_testmode_alloc_reply_skb); | 5831 | EXPORT_SYMBOL(cfg80211_testmode_alloc_reply_skb); |
5791 | 5832 | ||
5792 | int cfg80211_testmode_reply(struct sk_buff *skb) | 5833 | int cfg80211_testmode_reply(struct sk_buff *skb) |
5793 | { | 5834 | { |
5794 | struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0]; | 5835 | struct cfg80211_registered_device *rdev = ((void **)skb->cb)[0]; |
5795 | void *hdr = ((void **)skb->cb)[1]; | 5836 | void *hdr = ((void **)skb->cb)[1]; |
5796 | struct nlattr *data = ((void **)skb->cb)[2]; | 5837 | struct nlattr *data = ((void **)skb->cb)[2]; |
5797 | 5838 | ||
5798 | if (WARN_ON(!rdev->testmode_info)) { | 5839 | if (WARN_ON(!rdev->testmode_info)) { |
5799 | kfree_skb(skb); | 5840 | kfree_skb(skb); |
5800 | return -EINVAL; | 5841 | return -EINVAL; |
5801 | } | 5842 | } |
5802 | 5843 | ||
5803 | nla_nest_end(skb, data); | 5844 | nla_nest_end(skb, data); |
5804 | genlmsg_end(skb, hdr); | 5845 | genlmsg_end(skb, hdr); |
5805 | return genlmsg_reply(skb, rdev->testmode_info); | 5846 | return genlmsg_reply(skb, rdev->testmode_info); |
5806 | } | 5847 | } |
5807 | EXPORT_SYMBOL(cfg80211_testmode_reply); | 5848 | EXPORT_SYMBOL(cfg80211_testmode_reply); |
5808 | 5849 | ||
5809 | struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, | 5850 | struct sk_buff *cfg80211_testmode_alloc_event_skb(struct wiphy *wiphy, |
5810 | int approxlen, gfp_t gfp) | 5851 | int approxlen, gfp_t gfp) |
5811 | { | 5852 | { |
5812 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 5853 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
5813 | 5854 | ||
5814 | return __cfg80211_testmode_alloc_skb(rdev, approxlen, 0, 0, gfp); | 5855 | return __cfg80211_testmode_alloc_skb(rdev, approxlen, 0, 0, gfp); |
5815 | } | 5856 | } |
5816 | EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb); | 5857 | EXPORT_SYMBOL(cfg80211_testmode_alloc_event_skb); |
5817 | 5858 | ||
5818 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) | 5859 | void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp) |
5819 | { | 5860 | { |
5820 | void *hdr = ((void **)skb->cb)[1]; | 5861 | void *hdr = ((void **)skb->cb)[1]; |
5821 | struct nlattr *data = ((void **)skb->cb)[2]; | 5862 | struct nlattr *data = ((void **)skb->cb)[2]; |
5822 | 5863 | ||
5823 | nla_nest_end(skb, data); | 5864 | nla_nest_end(skb, data); |
5824 | genlmsg_end(skb, hdr); | 5865 | genlmsg_end(skb, hdr); |
5825 | genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp); | 5866 | genlmsg_multicast(skb, 0, nl80211_testmode_mcgrp.id, gfp); |
5826 | } | 5867 | } |
5827 | EXPORT_SYMBOL(cfg80211_testmode_event); | 5868 | EXPORT_SYMBOL(cfg80211_testmode_event); |
5828 | #endif | 5869 | #endif |
5829 | 5870 | ||
5830 | static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) | 5871 | static int nl80211_connect(struct sk_buff *skb, struct genl_info *info) |
5831 | { | 5872 | { |
5832 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5873 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5833 | struct net_device *dev = info->user_ptr[1]; | 5874 | struct net_device *dev = info->user_ptr[1]; |
5834 | struct cfg80211_connect_params connect; | 5875 | struct cfg80211_connect_params connect; |
5835 | struct wiphy *wiphy; | 5876 | struct wiphy *wiphy; |
5836 | struct cfg80211_cached_keys *connkeys = NULL; | 5877 | struct cfg80211_cached_keys *connkeys = NULL; |
5837 | int err; | 5878 | int err; |
5838 | 5879 | ||
5839 | memset(&connect, 0, sizeof(connect)); | 5880 | memset(&connect, 0, sizeof(connect)); |
5840 | 5881 | ||
5841 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 5882 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
5842 | return -EINVAL; | 5883 | return -EINVAL; |
5843 | 5884 | ||
5844 | if (!info->attrs[NL80211_ATTR_SSID] || | 5885 | if (!info->attrs[NL80211_ATTR_SSID] || |
5845 | !nla_len(info->attrs[NL80211_ATTR_SSID])) | 5886 | !nla_len(info->attrs[NL80211_ATTR_SSID])) |
5846 | return -EINVAL; | 5887 | return -EINVAL; |
5847 | 5888 | ||
5848 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { | 5889 | if (info->attrs[NL80211_ATTR_AUTH_TYPE]) { |
5849 | connect.auth_type = | 5890 | connect.auth_type = |
5850 | nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); | 5891 | nla_get_u32(info->attrs[NL80211_ATTR_AUTH_TYPE]); |
5851 | if (!nl80211_valid_auth_type(rdev, connect.auth_type, | 5892 | if (!nl80211_valid_auth_type(rdev, connect.auth_type, |
5852 | NL80211_CMD_CONNECT)) | 5893 | NL80211_CMD_CONNECT)) |
5853 | return -EINVAL; | 5894 | return -EINVAL; |
5854 | } else | 5895 | } else |
5855 | connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; | 5896 | connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; |
5856 | 5897 | ||
5857 | connect.privacy = info->attrs[NL80211_ATTR_PRIVACY]; | 5898 | connect.privacy = info->attrs[NL80211_ATTR_PRIVACY]; |
5858 | 5899 | ||
5859 | err = nl80211_crypto_settings(rdev, info, &connect.crypto, | 5900 | err = nl80211_crypto_settings(rdev, info, &connect.crypto, |
5860 | NL80211_MAX_NR_CIPHER_SUITES); | 5901 | NL80211_MAX_NR_CIPHER_SUITES); |
5861 | if (err) | 5902 | if (err) |
5862 | return err; | 5903 | return err; |
5863 | 5904 | ||
5864 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 5905 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
5865 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 5906 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
5866 | return -EOPNOTSUPP; | 5907 | return -EOPNOTSUPP; |
5867 | 5908 | ||
5868 | wiphy = &rdev->wiphy; | 5909 | wiphy = &rdev->wiphy; |
5869 | 5910 | ||
5870 | connect.bg_scan_period = -1; | 5911 | connect.bg_scan_period = -1; |
5871 | if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] && | 5912 | if (info->attrs[NL80211_ATTR_BG_SCAN_PERIOD] && |
5872 | (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) { | 5913 | (wiphy->flags & WIPHY_FLAG_SUPPORTS_FW_ROAM)) { |
5873 | connect.bg_scan_period = | 5914 | connect.bg_scan_period = |
5874 | nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]); | 5915 | nla_get_u16(info->attrs[NL80211_ATTR_BG_SCAN_PERIOD]); |
5875 | } | 5916 | } |
5876 | 5917 | ||
5877 | if (info->attrs[NL80211_ATTR_MAC]) | 5918 | if (info->attrs[NL80211_ATTR_MAC]) |
5878 | connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 5919 | connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5879 | connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); | 5920 | connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); |
5880 | connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); | 5921 | connect.ssid_len = nla_len(info->attrs[NL80211_ATTR_SSID]); |
5881 | 5922 | ||
5882 | if (info->attrs[NL80211_ATTR_IE]) { | 5923 | if (info->attrs[NL80211_ATTR_IE]) { |
5883 | connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]); | 5924 | connect.ie = nla_data(info->attrs[NL80211_ATTR_IE]); |
5884 | connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); | 5925 | connect.ie_len = nla_len(info->attrs[NL80211_ATTR_IE]); |
5885 | } | 5926 | } |
5886 | 5927 | ||
5887 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | 5928 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { |
5888 | connect.channel = | 5929 | connect.channel = |
5889 | ieee80211_get_channel(wiphy, | 5930 | ieee80211_get_channel(wiphy, |
5890 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); | 5931 | nla_get_u32(info->attrs[NL80211_ATTR_WIPHY_FREQ])); |
5891 | if (!connect.channel || | 5932 | if (!connect.channel || |
5892 | connect.channel->flags & IEEE80211_CHAN_DISABLED) | 5933 | connect.channel->flags & IEEE80211_CHAN_DISABLED) |
5893 | return -EINVAL; | 5934 | return -EINVAL; |
5894 | } | 5935 | } |
5895 | 5936 | ||
5896 | if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { | 5937 | if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) { |
5897 | connkeys = nl80211_parse_connkeys(rdev, | 5938 | connkeys = nl80211_parse_connkeys(rdev, |
5898 | info->attrs[NL80211_ATTR_KEYS], NULL); | 5939 | info->attrs[NL80211_ATTR_KEYS], NULL); |
5899 | if (IS_ERR(connkeys)) | 5940 | if (IS_ERR(connkeys)) |
5900 | return PTR_ERR(connkeys); | 5941 | return PTR_ERR(connkeys); |
5901 | } | 5942 | } |
5902 | 5943 | ||
5903 | if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT])) | 5944 | if (nla_get_flag(info->attrs[NL80211_ATTR_DISABLE_HT])) |
5904 | connect.flags |= ASSOC_REQ_DISABLE_HT; | 5945 | connect.flags |= ASSOC_REQ_DISABLE_HT; |
5905 | 5946 | ||
5906 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) | 5947 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) |
5907 | memcpy(&connect.ht_capa_mask, | 5948 | memcpy(&connect.ht_capa_mask, |
5908 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]), | 5949 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]), |
5909 | sizeof(connect.ht_capa_mask)); | 5950 | sizeof(connect.ht_capa_mask)); |
5910 | 5951 | ||
5911 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { | 5952 | if (info->attrs[NL80211_ATTR_HT_CAPABILITY]) { |
5912 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { | 5953 | if (!info->attrs[NL80211_ATTR_HT_CAPABILITY_MASK]) { |
5913 | kfree(connkeys); | 5954 | kfree(connkeys); |
5914 | return -EINVAL; | 5955 | return -EINVAL; |
5915 | } | 5956 | } |
5916 | memcpy(&connect.ht_capa, | 5957 | memcpy(&connect.ht_capa, |
5917 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]), | 5958 | nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]), |
5918 | sizeof(connect.ht_capa)); | 5959 | sizeof(connect.ht_capa)); |
5919 | } | 5960 | } |
5920 | 5961 | ||
5921 | err = cfg80211_connect(rdev, dev, &connect, connkeys); | 5962 | err = cfg80211_connect(rdev, dev, &connect, connkeys); |
5922 | if (err) | 5963 | if (err) |
5923 | kfree(connkeys); | 5964 | kfree(connkeys); |
5924 | return err; | 5965 | return err; |
5925 | } | 5966 | } |
5926 | 5967 | ||
5927 | static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) | 5968 | static int nl80211_disconnect(struct sk_buff *skb, struct genl_info *info) |
5928 | { | 5969 | { |
5929 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5970 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5930 | struct net_device *dev = info->user_ptr[1]; | 5971 | struct net_device *dev = info->user_ptr[1]; |
5931 | u16 reason; | 5972 | u16 reason; |
5932 | 5973 | ||
5933 | if (!info->attrs[NL80211_ATTR_REASON_CODE]) | 5974 | if (!info->attrs[NL80211_ATTR_REASON_CODE]) |
5934 | reason = WLAN_REASON_DEAUTH_LEAVING; | 5975 | reason = WLAN_REASON_DEAUTH_LEAVING; |
5935 | else | 5976 | else |
5936 | reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); | 5977 | reason = nla_get_u16(info->attrs[NL80211_ATTR_REASON_CODE]); |
5937 | 5978 | ||
5938 | if (reason == 0) | 5979 | if (reason == 0) |
5939 | return -EINVAL; | 5980 | return -EINVAL; |
5940 | 5981 | ||
5941 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 5982 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
5942 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 5983 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
5943 | return -EOPNOTSUPP; | 5984 | return -EOPNOTSUPP; |
5944 | 5985 | ||
5945 | return cfg80211_disconnect(rdev, dev, reason, true); | 5986 | return cfg80211_disconnect(rdev, dev, reason, true); |
5946 | } | 5987 | } |
5947 | 5988 | ||
5948 | static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) | 5989 | static int nl80211_wiphy_netns(struct sk_buff *skb, struct genl_info *info) |
5949 | { | 5990 | { |
5950 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 5991 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5951 | struct net *net; | 5992 | struct net *net; |
5952 | int err; | 5993 | int err; |
5953 | u32 pid; | 5994 | u32 pid; |
5954 | 5995 | ||
5955 | if (!info->attrs[NL80211_ATTR_PID]) | 5996 | if (!info->attrs[NL80211_ATTR_PID]) |
5956 | return -EINVAL; | 5997 | return -EINVAL; |
5957 | 5998 | ||
5958 | pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]); | 5999 | pid = nla_get_u32(info->attrs[NL80211_ATTR_PID]); |
5959 | 6000 | ||
5960 | net = get_net_ns_by_pid(pid); | 6001 | net = get_net_ns_by_pid(pid); |
5961 | if (IS_ERR(net)) | 6002 | if (IS_ERR(net)) |
5962 | return PTR_ERR(net); | 6003 | return PTR_ERR(net); |
5963 | 6004 | ||
5964 | err = 0; | 6005 | err = 0; |
5965 | 6006 | ||
5966 | /* check if anything to do */ | 6007 | /* check if anything to do */ |
5967 | if (!net_eq(wiphy_net(&rdev->wiphy), net)) | 6008 | if (!net_eq(wiphy_net(&rdev->wiphy), net)) |
5968 | err = cfg80211_switch_netns(rdev, net); | 6009 | err = cfg80211_switch_netns(rdev, net); |
5969 | 6010 | ||
5970 | put_net(net); | 6011 | put_net(net); |
5971 | return err; | 6012 | return err; |
5972 | } | 6013 | } |
5973 | 6014 | ||
5974 | static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) | 6015 | static int nl80211_setdel_pmksa(struct sk_buff *skb, struct genl_info *info) |
5975 | { | 6016 | { |
5976 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6017 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
5977 | int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev, | 6018 | int (*rdev_ops)(struct wiphy *wiphy, struct net_device *dev, |
5978 | struct cfg80211_pmksa *pmksa) = NULL; | 6019 | struct cfg80211_pmksa *pmksa) = NULL; |
5979 | struct net_device *dev = info->user_ptr[1]; | 6020 | struct net_device *dev = info->user_ptr[1]; |
5980 | struct cfg80211_pmksa pmksa; | 6021 | struct cfg80211_pmksa pmksa; |
5981 | 6022 | ||
5982 | memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); | 6023 | memset(&pmksa, 0, sizeof(struct cfg80211_pmksa)); |
5983 | 6024 | ||
5984 | if (!info->attrs[NL80211_ATTR_MAC]) | 6025 | if (!info->attrs[NL80211_ATTR_MAC]) |
5985 | return -EINVAL; | 6026 | return -EINVAL; |
5986 | 6027 | ||
5987 | if (!info->attrs[NL80211_ATTR_PMKID]) | 6028 | if (!info->attrs[NL80211_ATTR_PMKID]) |
5988 | return -EINVAL; | 6029 | return -EINVAL; |
5989 | 6030 | ||
5990 | pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); | 6031 | pmksa.pmkid = nla_data(info->attrs[NL80211_ATTR_PMKID]); |
5991 | pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); | 6032 | pmksa.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); |
5992 | 6033 | ||
5993 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 6034 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
5994 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 6035 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
5995 | return -EOPNOTSUPP; | 6036 | return -EOPNOTSUPP; |
5996 | 6037 | ||
5997 | switch (info->genlhdr->cmd) { | 6038 | switch (info->genlhdr->cmd) { |
5998 | case NL80211_CMD_SET_PMKSA: | 6039 | case NL80211_CMD_SET_PMKSA: |
5999 | rdev_ops = rdev->ops->set_pmksa; | 6040 | rdev_ops = rdev->ops->set_pmksa; |
6000 | break; | 6041 | break; |
6001 | case NL80211_CMD_DEL_PMKSA: | 6042 | case NL80211_CMD_DEL_PMKSA: |
6002 | rdev_ops = rdev->ops->del_pmksa; | 6043 | rdev_ops = rdev->ops->del_pmksa; |
6003 | break; | 6044 | break; |
6004 | default: | 6045 | default: |
6005 | WARN_ON(1); | 6046 | WARN_ON(1); |
6006 | break; | 6047 | break; |
6007 | } | 6048 | } |
6008 | 6049 | ||
6009 | if (!rdev_ops) | 6050 | if (!rdev_ops) |
6010 | return -EOPNOTSUPP; | 6051 | return -EOPNOTSUPP; |
6011 | 6052 | ||
6012 | return rdev_ops(&rdev->wiphy, dev, &pmksa); | 6053 | return rdev_ops(&rdev->wiphy, dev, &pmksa); |
6013 | } | 6054 | } |
6014 | 6055 | ||
6015 | static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) | 6056 | static int nl80211_flush_pmksa(struct sk_buff *skb, struct genl_info *info) |
6016 | { | 6057 | { |
6017 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6058 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6018 | struct net_device *dev = info->user_ptr[1]; | 6059 | struct net_device *dev = info->user_ptr[1]; |
6019 | 6060 | ||
6020 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && | 6061 | if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION && |
6021 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) | 6062 | dev->ieee80211_ptr->iftype != NL80211_IFTYPE_P2P_CLIENT) |
6022 | return -EOPNOTSUPP; | 6063 | return -EOPNOTSUPP; |
6023 | 6064 | ||
6024 | if (!rdev->ops->flush_pmksa) | 6065 | if (!rdev->ops->flush_pmksa) |
6025 | return -EOPNOTSUPP; | 6066 | return -EOPNOTSUPP; |
6026 | 6067 | ||
6027 | return rdev_flush_pmksa(rdev, dev); | 6068 | return rdev_flush_pmksa(rdev, dev); |
6028 | } | 6069 | } |
6029 | 6070 | ||
6030 | static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) | 6071 | static int nl80211_tdls_mgmt(struct sk_buff *skb, struct genl_info *info) |
6031 | { | 6072 | { |
6032 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6073 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6033 | struct net_device *dev = info->user_ptr[1]; | 6074 | struct net_device *dev = info->user_ptr[1]; |
6034 | u8 action_code, dialog_token; | 6075 | u8 action_code, dialog_token; |
6035 | u16 status_code; | 6076 | u16 status_code; |
6036 | u8 *peer; | 6077 | u8 *peer; |
6037 | 6078 | ||
6038 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) || | 6079 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) || |
6039 | !rdev->ops->tdls_mgmt) | 6080 | !rdev->ops->tdls_mgmt) |
6040 | return -EOPNOTSUPP; | 6081 | return -EOPNOTSUPP; |
6041 | 6082 | ||
6042 | if (!info->attrs[NL80211_ATTR_TDLS_ACTION] || | 6083 | if (!info->attrs[NL80211_ATTR_TDLS_ACTION] || |
6043 | !info->attrs[NL80211_ATTR_STATUS_CODE] || | 6084 | !info->attrs[NL80211_ATTR_STATUS_CODE] || |
6044 | !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] || | 6085 | !info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN] || |
6045 | !info->attrs[NL80211_ATTR_IE] || | 6086 | !info->attrs[NL80211_ATTR_IE] || |
6046 | !info->attrs[NL80211_ATTR_MAC]) | 6087 | !info->attrs[NL80211_ATTR_MAC]) |
6047 | return -EINVAL; | 6088 | return -EINVAL; |
6048 | 6089 | ||
6049 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); | 6090 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); |
6050 | action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); | 6091 | action_code = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_ACTION]); |
6051 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); | 6092 | status_code = nla_get_u16(info->attrs[NL80211_ATTR_STATUS_CODE]); |
6052 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); | 6093 | dialog_token = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_DIALOG_TOKEN]); |
6053 | 6094 | ||
6054 | return rdev_tdls_mgmt(rdev, dev, peer, action_code, | 6095 | return rdev_tdls_mgmt(rdev, dev, peer, action_code, |
6055 | dialog_token, status_code, | 6096 | dialog_token, status_code, |
6056 | nla_data(info->attrs[NL80211_ATTR_IE]), | 6097 | nla_data(info->attrs[NL80211_ATTR_IE]), |
6057 | nla_len(info->attrs[NL80211_ATTR_IE])); | 6098 | nla_len(info->attrs[NL80211_ATTR_IE])); |
6058 | } | 6099 | } |
6059 | 6100 | ||
6060 | static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info) | 6101 | static int nl80211_tdls_oper(struct sk_buff *skb, struct genl_info *info) |
6061 | { | 6102 | { |
6062 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6103 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6063 | struct net_device *dev = info->user_ptr[1]; | 6104 | struct net_device *dev = info->user_ptr[1]; |
6064 | enum nl80211_tdls_operation operation; | 6105 | enum nl80211_tdls_operation operation; |
6065 | u8 *peer; | 6106 | u8 *peer; |
6066 | 6107 | ||
6067 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) || | 6108 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_TDLS) || |
6068 | !rdev->ops->tdls_oper) | 6109 | !rdev->ops->tdls_oper) |
6069 | return -EOPNOTSUPP; | 6110 | return -EOPNOTSUPP; |
6070 | 6111 | ||
6071 | if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] || | 6112 | if (!info->attrs[NL80211_ATTR_TDLS_OPERATION] || |
6072 | !info->attrs[NL80211_ATTR_MAC]) | 6113 | !info->attrs[NL80211_ATTR_MAC]) |
6073 | return -EINVAL; | 6114 | return -EINVAL; |
6074 | 6115 | ||
6075 | operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]); | 6116 | operation = nla_get_u8(info->attrs[NL80211_ATTR_TDLS_OPERATION]); |
6076 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); | 6117 | peer = nla_data(info->attrs[NL80211_ATTR_MAC]); |
6077 | 6118 | ||
6078 | return rdev_tdls_oper(rdev, dev, peer, operation); | 6119 | return rdev_tdls_oper(rdev, dev, peer, operation); |
6079 | } | 6120 | } |
6080 | 6121 | ||
6081 | static int nl80211_remain_on_channel(struct sk_buff *skb, | 6122 | static int nl80211_remain_on_channel(struct sk_buff *skb, |
6082 | struct genl_info *info) | 6123 | struct genl_info *info) |
6083 | { | 6124 | { |
6084 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6125 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6085 | struct wireless_dev *wdev = info->user_ptr[1]; | 6126 | struct wireless_dev *wdev = info->user_ptr[1]; |
6086 | struct cfg80211_chan_def chandef; | 6127 | struct cfg80211_chan_def chandef; |
6087 | struct sk_buff *msg; | 6128 | struct sk_buff *msg; |
6088 | void *hdr; | 6129 | void *hdr; |
6089 | u64 cookie; | 6130 | u64 cookie; |
6090 | u32 duration; | 6131 | u32 duration; |
6091 | int err; | 6132 | int err; |
6092 | 6133 | ||
6093 | if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || | 6134 | if (!info->attrs[NL80211_ATTR_WIPHY_FREQ] || |
6094 | !info->attrs[NL80211_ATTR_DURATION]) | 6135 | !info->attrs[NL80211_ATTR_DURATION]) |
6095 | return -EINVAL; | 6136 | return -EINVAL; |
6096 | 6137 | ||
6097 | duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); | 6138 | duration = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); |
6098 | 6139 | ||
6099 | if (!rdev->ops->remain_on_channel || | 6140 | if (!rdev->ops->remain_on_channel || |
6100 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)) | 6141 | !(rdev->wiphy.flags & WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL)) |
6101 | return -EOPNOTSUPP; | 6142 | return -EOPNOTSUPP; |
6102 | 6143 | ||
6103 | /* | 6144 | /* |
6104 | * We should be on that channel for at least a minimum amount of | 6145 | * We should be on that channel for at least a minimum amount of |
6105 | * time (10ms) but no longer than the driver supports. | 6146 | * time (10ms) but no longer than the driver supports. |
6106 | */ | 6147 | */ |
6107 | if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || | 6148 | if (duration < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || |
6108 | duration > rdev->wiphy.max_remain_on_channel_duration) | 6149 | duration > rdev->wiphy.max_remain_on_channel_duration) |
6109 | return -EINVAL; | 6150 | return -EINVAL; |
6110 | 6151 | ||
6111 | err = nl80211_parse_chandef(rdev, info, &chandef); | 6152 | err = nl80211_parse_chandef(rdev, info, &chandef); |
6112 | if (err) | 6153 | if (err) |
6113 | return err; | 6154 | return err; |
6114 | 6155 | ||
6115 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 6156 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
6116 | if (!msg) | 6157 | if (!msg) |
6117 | return -ENOMEM; | 6158 | return -ENOMEM; |
6118 | 6159 | ||
6119 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 6160 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6120 | NL80211_CMD_REMAIN_ON_CHANNEL); | 6161 | NL80211_CMD_REMAIN_ON_CHANNEL); |
6121 | 6162 | ||
6122 | if (IS_ERR(hdr)) { | 6163 | if (IS_ERR(hdr)) { |
6123 | err = PTR_ERR(hdr); | 6164 | err = PTR_ERR(hdr); |
6124 | goto free_msg; | 6165 | goto free_msg; |
6125 | } | 6166 | } |
6126 | 6167 | ||
6127 | err = rdev_remain_on_channel(rdev, wdev, chandef.chan, | 6168 | err = rdev_remain_on_channel(rdev, wdev, chandef.chan, |
6128 | duration, &cookie); | 6169 | duration, &cookie); |
6129 | 6170 | ||
6130 | if (err) | 6171 | if (err) |
6131 | goto free_msg; | 6172 | goto free_msg; |
6132 | 6173 | ||
6133 | if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) | 6174 | if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) |
6134 | goto nla_put_failure; | 6175 | goto nla_put_failure; |
6135 | 6176 | ||
6136 | genlmsg_end(msg, hdr); | 6177 | genlmsg_end(msg, hdr); |
6137 | 6178 | ||
6138 | return genlmsg_reply(msg, info); | 6179 | return genlmsg_reply(msg, info); |
6139 | 6180 | ||
6140 | nla_put_failure: | 6181 | nla_put_failure: |
6141 | err = -ENOBUFS; | 6182 | err = -ENOBUFS; |
6142 | free_msg: | 6183 | free_msg: |
6143 | nlmsg_free(msg); | 6184 | nlmsg_free(msg); |
6144 | return err; | 6185 | return err; |
6145 | } | 6186 | } |
6146 | 6187 | ||
6147 | static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, | 6188 | static int nl80211_cancel_remain_on_channel(struct sk_buff *skb, |
6148 | struct genl_info *info) | 6189 | struct genl_info *info) |
6149 | { | 6190 | { |
6150 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6191 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6151 | struct wireless_dev *wdev = info->user_ptr[1]; | 6192 | struct wireless_dev *wdev = info->user_ptr[1]; |
6152 | u64 cookie; | 6193 | u64 cookie; |
6153 | 6194 | ||
6154 | if (!info->attrs[NL80211_ATTR_COOKIE]) | 6195 | if (!info->attrs[NL80211_ATTR_COOKIE]) |
6155 | return -EINVAL; | 6196 | return -EINVAL; |
6156 | 6197 | ||
6157 | if (!rdev->ops->cancel_remain_on_channel) | 6198 | if (!rdev->ops->cancel_remain_on_channel) |
6158 | return -EOPNOTSUPP; | 6199 | return -EOPNOTSUPP; |
6159 | 6200 | ||
6160 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); | 6201 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); |
6161 | 6202 | ||
6162 | return rdev_cancel_remain_on_channel(rdev, wdev, cookie); | 6203 | return rdev_cancel_remain_on_channel(rdev, wdev, cookie); |
6163 | } | 6204 | } |
6164 | 6205 | ||
6165 | static u32 rateset_to_mask(struct ieee80211_supported_band *sband, | 6206 | static u32 rateset_to_mask(struct ieee80211_supported_band *sband, |
6166 | u8 *rates, u8 rates_len) | 6207 | u8 *rates, u8 rates_len) |
6167 | { | 6208 | { |
6168 | u8 i; | 6209 | u8 i; |
6169 | u32 mask = 0; | 6210 | u32 mask = 0; |
6170 | 6211 | ||
6171 | for (i = 0; i < rates_len; i++) { | 6212 | for (i = 0; i < rates_len; i++) { |
6172 | int rate = (rates[i] & 0x7f) * 5; | 6213 | int rate = (rates[i] & 0x7f) * 5; |
6173 | int ridx; | 6214 | int ridx; |
6174 | for (ridx = 0; ridx < sband->n_bitrates; ridx++) { | 6215 | for (ridx = 0; ridx < sband->n_bitrates; ridx++) { |
6175 | struct ieee80211_rate *srate = | 6216 | struct ieee80211_rate *srate = |
6176 | &sband->bitrates[ridx]; | 6217 | &sband->bitrates[ridx]; |
6177 | if (rate == srate->bitrate) { | 6218 | if (rate == srate->bitrate) { |
6178 | mask |= 1 << ridx; | 6219 | mask |= 1 << ridx; |
6179 | break; | 6220 | break; |
6180 | } | 6221 | } |
6181 | } | 6222 | } |
6182 | if (ridx == sband->n_bitrates) | 6223 | if (ridx == sband->n_bitrates) |
6183 | return 0; /* rate not found */ | 6224 | return 0; /* rate not found */ |
6184 | } | 6225 | } |
6185 | 6226 | ||
6186 | return mask; | 6227 | return mask; |
6187 | } | 6228 | } |
6188 | 6229 | ||
6189 | static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband, | 6230 | static bool ht_rateset_to_mask(struct ieee80211_supported_band *sband, |
6190 | u8 *rates, u8 rates_len, | 6231 | u8 *rates, u8 rates_len, |
6191 | u8 mcs[IEEE80211_HT_MCS_MASK_LEN]) | 6232 | u8 mcs[IEEE80211_HT_MCS_MASK_LEN]) |
6192 | { | 6233 | { |
6193 | u8 i; | 6234 | u8 i; |
6194 | 6235 | ||
6195 | memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN); | 6236 | memset(mcs, 0, IEEE80211_HT_MCS_MASK_LEN); |
6196 | 6237 | ||
6197 | for (i = 0; i < rates_len; i++) { | 6238 | for (i = 0; i < rates_len; i++) { |
6198 | int ridx, rbit; | 6239 | int ridx, rbit; |
6199 | 6240 | ||
6200 | ridx = rates[i] / 8; | 6241 | ridx = rates[i] / 8; |
6201 | rbit = BIT(rates[i] % 8); | 6242 | rbit = BIT(rates[i] % 8); |
6202 | 6243 | ||
6203 | /* check validity */ | 6244 | /* check validity */ |
6204 | if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN)) | 6245 | if ((ridx < 0) || (ridx >= IEEE80211_HT_MCS_MASK_LEN)) |
6205 | return false; | 6246 | return false; |
6206 | 6247 | ||
6207 | /* check availability */ | 6248 | /* check availability */ |
6208 | if (sband->ht_cap.mcs.rx_mask[ridx] & rbit) | 6249 | if (sband->ht_cap.mcs.rx_mask[ridx] & rbit) |
6209 | mcs[ridx] |= rbit; | 6250 | mcs[ridx] |= rbit; |
6210 | else | 6251 | else |
6211 | return false; | 6252 | return false; |
6212 | } | 6253 | } |
6213 | 6254 | ||
6214 | return true; | 6255 | return true; |
6215 | } | 6256 | } |
6216 | 6257 | ||
6217 | static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { | 6258 | static const struct nla_policy nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] = { |
6218 | [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY, | 6259 | [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY, |
6219 | .len = NL80211_MAX_SUPP_RATES }, | 6260 | .len = NL80211_MAX_SUPP_RATES }, |
6220 | [NL80211_TXRATE_MCS] = { .type = NLA_BINARY, | 6261 | [NL80211_TXRATE_MCS] = { .type = NLA_BINARY, |
6221 | .len = NL80211_MAX_SUPP_HT_RATES }, | 6262 | .len = NL80211_MAX_SUPP_HT_RATES }, |
6222 | }; | 6263 | }; |
6223 | 6264 | ||
6224 | static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, | 6265 | static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb, |
6225 | struct genl_info *info) | 6266 | struct genl_info *info) |
6226 | { | 6267 | { |
6227 | struct nlattr *tb[NL80211_TXRATE_MAX + 1]; | 6268 | struct nlattr *tb[NL80211_TXRATE_MAX + 1]; |
6228 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6269 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6229 | struct cfg80211_bitrate_mask mask; | 6270 | struct cfg80211_bitrate_mask mask; |
6230 | int rem, i; | 6271 | int rem, i; |
6231 | struct net_device *dev = info->user_ptr[1]; | 6272 | struct net_device *dev = info->user_ptr[1]; |
6232 | struct nlattr *tx_rates; | 6273 | struct nlattr *tx_rates; |
6233 | struct ieee80211_supported_band *sband; | 6274 | struct ieee80211_supported_band *sband; |
6234 | 6275 | ||
6235 | if (info->attrs[NL80211_ATTR_TX_RATES] == NULL) | 6276 | if (info->attrs[NL80211_ATTR_TX_RATES] == NULL) |
6236 | return -EINVAL; | 6277 | return -EINVAL; |
6237 | 6278 | ||
6238 | if (!rdev->ops->set_bitrate_mask) | 6279 | if (!rdev->ops->set_bitrate_mask) |
6239 | return -EOPNOTSUPP; | 6280 | return -EOPNOTSUPP; |
6240 | 6281 | ||
6241 | memset(&mask, 0, sizeof(mask)); | 6282 | memset(&mask, 0, sizeof(mask)); |
6242 | /* Default to all rates enabled */ | 6283 | /* Default to all rates enabled */ |
6243 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 6284 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
6244 | sband = rdev->wiphy.bands[i]; | 6285 | sband = rdev->wiphy.bands[i]; |
6245 | mask.control[i].legacy = | 6286 | mask.control[i].legacy = |
6246 | sband ? (1 << sband->n_bitrates) - 1 : 0; | 6287 | sband ? (1 << sband->n_bitrates) - 1 : 0; |
6247 | if (sband) | 6288 | if (sband) |
6248 | memcpy(mask.control[i].mcs, | 6289 | memcpy(mask.control[i].mcs, |
6249 | sband->ht_cap.mcs.rx_mask, | 6290 | sband->ht_cap.mcs.rx_mask, |
6250 | sizeof(mask.control[i].mcs)); | 6291 | sizeof(mask.control[i].mcs)); |
6251 | else | 6292 | else |
6252 | memset(mask.control[i].mcs, 0, | 6293 | memset(mask.control[i].mcs, 0, |
6253 | sizeof(mask.control[i].mcs)); | 6294 | sizeof(mask.control[i].mcs)); |
6254 | } | 6295 | } |
6255 | 6296 | ||
6256 | /* | 6297 | /* |
6257 | * The nested attribute uses enum nl80211_band as the index. This maps | 6298 | * The nested attribute uses enum nl80211_band as the index. This maps |
6258 | * directly to the enum ieee80211_band values used in cfg80211. | 6299 | * directly to the enum ieee80211_band values used in cfg80211. |
6259 | */ | 6300 | */ |
6260 | BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8); | 6301 | BUILD_BUG_ON(NL80211_MAX_SUPP_HT_RATES > IEEE80211_HT_MCS_MASK_LEN * 8); |
6261 | nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) | 6302 | nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem) |
6262 | { | 6303 | { |
6263 | enum ieee80211_band band = nla_type(tx_rates); | 6304 | enum ieee80211_band band = nla_type(tx_rates); |
6264 | if (band < 0 || band >= IEEE80211_NUM_BANDS) | 6305 | if (band < 0 || band >= IEEE80211_NUM_BANDS) |
6265 | return -EINVAL; | 6306 | return -EINVAL; |
6266 | sband = rdev->wiphy.bands[band]; | 6307 | sband = rdev->wiphy.bands[band]; |
6267 | if (sband == NULL) | 6308 | if (sband == NULL) |
6268 | return -EINVAL; | 6309 | return -EINVAL; |
6269 | nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), | 6310 | nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates), |
6270 | nla_len(tx_rates), nl80211_txattr_policy); | 6311 | nla_len(tx_rates), nl80211_txattr_policy); |
6271 | if (tb[NL80211_TXRATE_LEGACY]) { | 6312 | if (tb[NL80211_TXRATE_LEGACY]) { |
6272 | mask.control[band].legacy = rateset_to_mask( | 6313 | mask.control[band].legacy = rateset_to_mask( |
6273 | sband, | 6314 | sband, |
6274 | nla_data(tb[NL80211_TXRATE_LEGACY]), | 6315 | nla_data(tb[NL80211_TXRATE_LEGACY]), |
6275 | nla_len(tb[NL80211_TXRATE_LEGACY])); | 6316 | nla_len(tb[NL80211_TXRATE_LEGACY])); |
6276 | if ((mask.control[band].legacy == 0) && | 6317 | if ((mask.control[band].legacy == 0) && |
6277 | nla_len(tb[NL80211_TXRATE_LEGACY])) | 6318 | nla_len(tb[NL80211_TXRATE_LEGACY])) |
6278 | return -EINVAL; | 6319 | return -EINVAL; |
6279 | } | 6320 | } |
6280 | if (tb[NL80211_TXRATE_MCS]) { | 6321 | if (tb[NL80211_TXRATE_MCS]) { |
6281 | if (!ht_rateset_to_mask( | 6322 | if (!ht_rateset_to_mask( |
6282 | sband, | 6323 | sband, |
6283 | nla_data(tb[NL80211_TXRATE_MCS]), | 6324 | nla_data(tb[NL80211_TXRATE_MCS]), |
6284 | nla_len(tb[NL80211_TXRATE_MCS]), | 6325 | nla_len(tb[NL80211_TXRATE_MCS]), |
6285 | mask.control[band].mcs)) | 6326 | mask.control[band].mcs)) |
6286 | return -EINVAL; | 6327 | return -EINVAL; |
6287 | } | 6328 | } |
6288 | 6329 | ||
6289 | if (mask.control[band].legacy == 0) { | 6330 | if (mask.control[band].legacy == 0) { |
6290 | /* don't allow empty legacy rates if HT | 6331 | /* don't allow empty legacy rates if HT |
6291 | * is not even supported. */ | 6332 | * is not even supported. */ |
6292 | if (!rdev->wiphy.bands[band]->ht_cap.ht_supported) | 6333 | if (!rdev->wiphy.bands[band]->ht_cap.ht_supported) |
6293 | return -EINVAL; | 6334 | return -EINVAL; |
6294 | 6335 | ||
6295 | for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) | 6336 | for (i = 0; i < IEEE80211_HT_MCS_MASK_LEN; i++) |
6296 | if (mask.control[band].mcs[i]) | 6337 | if (mask.control[band].mcs[i]) |
6297 | break; | 6338 | break; |
6298 | 6339 | ||
6299 | /* legacy and mcs rates may not be both empty */ | 6340 | /* legacy and mcs rates may not be both empty */ |
6300 | if (i == IEEE80211_HT_MCS_MASK_LEN) | 6341 | if (i == IEEE80211_HT_MCS_MASK_LEN) |
6301 | return -EINVAL; | 6342 | return -EINVAL; |
6302 | } | 6343 | } |
6303 | } | 6344 | } |
6304 | 6345 | ||
6305 | return rdev_set_bitrate_mask(rdev, dev, NULL, &mask); | 6346 | return rdev_set_bitrate_mask(rdev, dev, NULL, &mask); |
6306 | } | 6347 | } |
6307 | 6348 | ||
6308 | static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) | 6349 | static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) |
6309 | { | 6350 | { |
6310 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6351 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6311 | struct wireless_dev *wdev = info->user_ptr[1]; | 6352 | struct wireless_dev *wdev = info->user_ptr[1]; |
6312 | u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; | 6353 | u16 frame_type = IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION; |
6313 | 6354 | ||
6314 | if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) | 6355 | if (!info->attrs[NL80211_ATTR_FRAME_MATCH]) |
6315 | return -EINVAL; | 6356 | return -EINVAL; |
6316 | 6357 | ||
6317 | if (info->attrs[NL80211_ATTR_FRAME_TYPE]) | 6358 | if (info->attrs[NL80211_ATTR_FRAME_TYPE]) |
6318 | frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); | 6359 | frame_type = nla_get_u16(info->attrs[NL80211_ATTR_FRAME_TYPE]); |
6319 | 6360 | ||
6320 | switch (wdev->iftype) { | 6361 | switch (wdev->iftype) { |
6321 | case NL80211_IFTYPE_STATION: | 6362 | case NL80211_IFTYPE_STATION: |
6322 | case NL80211_IFTYPE_ADHOC: | 6363 | case NL80211_IFTYPE_ADHOC: |
6323 | case NL80211_IFTYPE_P2P_CLIENT: | 6364 | case NL80211_IFTYPE_P2P_CLIENT: |
6324 | case NL80211_IFTYPE_AP: | 6365 | case NL80211_IFTYPE_AP: |
6325 | case NL80211_IFTYPE_AP_VLAN: | 6366 | case NL80211_IFTYPE_AP_VLAN: |
6326 | case NL80211_IFTYPE_MESH_POINT: | 6367 | case NL80211_IFTYPE_MESH_POINT: |
6327 | case NL80211_IFTYPE_P2P_GO: | 6368 | case NL80211_IFTYPE_P2P_GO: |
6328 | case NL80211_IFTYPE_P2P_DEVICE: | 6369 | case NL80211_IFTYPE_P2P_DEVICE: |
6329 | break; | 6370 | break; |
6330 | default: | 6371 | default: |
6331 | return -EOPNOTSUPP; | 6372 | return -EOPNOTSUPP; |
6332 | } | 6373 | } |
6333 | 6374 | ||
6334 | /* not much point in registering if we can't reply */ | 6375 | /* not much point in registering if we can't reply */ |
6335 | if (!rdev->ops->mgmt_tx) | 6376 | if (!rdev->ops->mgmt_tx) |
6336 | return -EOPNOTSUPP; | 6377 | return -EOPNOTSUPP; |
6337 | 6378 | ||
6338 | return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type, | 6379 | return cfg80211_mlme_register_mgmt(wdev, info->snd_portid, frame_type, |
6339 | nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), | 6380 | nla_data(info->attrs[NL80211_ATTR_FRAME_MATCH]), |
6340 | nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); | 6381 | nla_len(info->attrs[NL80211_ATTR_FRAME_MATCH])); |
6341 | } | 6382 | } |
6342 | 6383 | ||
6343 | static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) | 6384 | static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) |
6344 | { | 6385 | { |
6345 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6386 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6346 | struct wireless_dev *wdev = info->user_ptr[1]; | 6387 | struct wireless_dev *wdev = info->user_ptr[1]; |
6347 | struct cfg80211_chan_def chandef; | 6388 | struct cfg80211_chan_def chandef; |
6348 | int err; | 6389 | int err; |
6349 | void *hdr = NULL; | 6390 | void *hdr = NULL; |
6350 | u64 cookie; | 6391 | u64 cookie; |
6351 | struct sk_buff *msg = NULL; | 6392 | struct sk_buff *msg = NULL; |
6352 | unsigned int wait = 0; | 6393 | unsigned int wait = 0; |
6353 | bool offchan, no_cck, dont_wait_for_ack; | 6394 | bool offchan, no_cck, dont_wait_for_ack; |
6354 | 6395 | ||
6355 | dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; | 6396 | dont_wait_for_ack = info->attrs[NL80211_ATTR_DONT_WAIT_FOR_ACK]; |
6356 | 6397 | ||
6357 | if (!info->attrs[NL80211_ATTR_FRAME]) | 6398 | if (!info->attrs[NL80211_ATTR_FRAME]) |
6358 | return -EINVAL; | 6399 | return -EINVAL; |
6359 | 6400 | ||
6360 | if (!rdev->ops->mgmt_tx) | 6401 | if (!rdev->ops->mgmt_tx) |
6361 | return -EOPNOTSUPP; | 6402 | return -EOPNOTSUPP; |
6362 | 6403 | ||
6363 | switch (wdev->iftype) { | 6404 | switch (wdev->iftype) { |
6364 | case NL80211_IFTYPE_STATION: | 6405 | case NL80211_IFTYPE_STATION: |
6365 | case NL80211_IFTYPE_ADHOC: | 6406 | case NL80211_IFTYPE_ADHOC: |
6366 | case NL80211_IFTYPE_P2P_CLIENT: | 6407 | case NL80211_IFTYPE_P2P_CLIENT: |
6367 | case NL80211_IFTYPE_AP: | 6408 | case NL80211_IFTYPE_AP: |
6368 | case NL80211_IFTYPE_AP_VLAN: | 6409 | case NL80211_IFTYPE_AP_VLAN: |
6369 | case NL80211_IFTYPE_MESH_POINT: | 6410 | case NL80211_IFTYPE_MESH_POINT: |
6370 | case NL80211_IFTYPE_P2P_GO: | 6411 | case NL80211_IFTYPE_P2P_GO: |
6371 | case NL80211_IFTYPE_P2P_DEVICE: | 6412 | case NL80211_IFTYPE_P2P_DEVICE: |
6372 | break; | 6413 | break; |
6373 | default: | 6414 | default: |
6374 | return -EOPNOTSUPP; | 6415 | return -EOPNOTSUPP; |
6375 | } | 6416 | } |
6376 | 6417 | ||
6377 | if (info->attrs[NL80211_ATTR_DURATION]) { | 6418 | if (info->attrs[NL80211_ATTR_DURATION]) { |
6378 | if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) | 6419 | if (!(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) |
6379 | return -EINVAL; | 6420 | return -EINVAL; |
6380 | wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); | 6421 | wait = nla_get_u32(info->attrs[NL80211_ATTR_DURATION]); |
6381 | 6422 | ||
6382 | /* | 6423 | /* |
6383 | * We should wait on the channel for at least a minimum amount | 6424 | * We should wait on the channel for at least a minimum amount |
6384 | * of time (10ms) but no longer than the driver supports. | 6425 | * of time (10ms) but no longer than the driver supports. |
6385 | */ | 6426 | */ |
6386 | if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || | 6427 | if (wait < NL80211_MIN_REMAIN_ON_CHANNEL_TIME || |
6387 | wait > rdev->wiphy.max_remain_on_channel_duration) | 6428 | wait > rdev->wiphy.max_remain_on_channel_duration) |
6388 | return -EINVAL; | 6429 | return -EINVAL; |
6389 | 6430 | ||
6390 | } | 6431 | } |
6391 | 6432 | ||
6392 | offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; | 6433 | offchan = info->attrs[NL80211_ATTR_OFFCHANNEL_TX_OK]; |
6393 | 6434 | ||
6394 | if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) | 6435 | if (offchan && !(rdev->wiphy.flags & WIPHY_FLAG_OFFCHAN_TX)) |
6395 | return -EINVAL; | 6436 | return -EINVAL; |
6396 | 6437 | ||
6397 | no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); | 6438 | no_cck = nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]); |
6398 | 6439 | ||
6399 | err = nl80211_parse_chandef(rdev, info, &chandef); | 6440 | err = nl80211_parse_chandef(rdev, info, &chandef); |
6400 | if (err) | 6441 | if (err) |
6401 | return err; | 6442 | return err; |
6402 | 6443 | ||
6403 | if (!dont_wait_for_ack) { | 6444 | if (!dont_wait_for_ack) { |
6404 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 6445 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
6405 | if (!msg) | 6446 | if (!msg) |
6406 | return -ENOMEM; | 6447 | return -ENOMEM; |
6407 | 6448 | ||
6408 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 6449 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6409 | NL80211_CMD_FRAME); | 6450 | NL80211_CMD_FRAME); |
6410 | 6451 | ||
6411 | if (IS_ERR(hdr)) { | 6452 | if (IS_ERR(hdr)) { |
6412 | err = PTR_ERR(hdr); | 6453 | err = PTR_ERR(hdr); |
6413 | goto free_msg; | 6454 | goto free_msg; |
6414 | } | 6455 | } |
6415 | } | 6456 | } |
6416 | 6457 | ||
6417 | err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait, | 6458 | err = cfg80211_mlme_mgmt_tx(rdev, wdev, chandef.chan, offchan, wait, |
6418 | nla_data(info->attrs[NL80211_ATTR_FRAME]), | 6459 | nla_data(info->attrs[NL80211_ATTR_FRAME]), |
6419 | nla_len(info->attrs[NL80211_ATTR_FRAME]), | 6460 | nla_len(info->attrs[NL80211_ATTR_FRAME]), |
6420 | no_cck, dont_wait_for_ack, &cookie); | 6461 | no_cck, dont_wait_for_ack, &cookie); |
6421 | if (err) | 6462 | if (err) |
6422 | goto free_msg; | 6463 | goto free_msg; |
6423 | 6464 | ||
6424 | if (msg) { | 6465 | if (msg) { |
6425 | if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) | 6466 | if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) |
6426 | goto nla_put_failure; | 6467 | goto nla_put_failure; |
6427 | 6468 | ||
6428 | genlmsg_end(msg, hdr); | 6469 | genlmsg_end(msg, hdr); |
6429 | return genlmsg_reply(msg, info); | 6470 | return genlmsg_reply(msg, info); |
6430 | } | 6471 | } |
6431 | 6472 | ||
6432 | return 0; | 6473 | return 0; |
6433 | 6474 | ||
6434 | nla_put_failure: | 6475 | nla_put_failure: |
6435 | err = -ENOBUFS; | 6476 | err = -ENOBUFS; |
6436 | free_msg: | 6477 | free_msg: |
6437 | nlmsg_free(msg); | 6478 | nlmsg_free(msg); |
6438 | return err; | 6479 | return err; |
6439 | } | 6480 | } |
6440 | 6481 | ||
6441 | static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info) | 6482 | static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *info) |
6442 | { | 6483 | { |
6443 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6484 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6444 | struct wireless_dev *wdev = info->user_ptr[1]; | 6485 | struct wireless_dev *wdev = info->user_ptr[1]; |
6445 | u64 cookie; | 6486 | u64 cookie; |
6446 | 6487 | ||
6447 | if (!info->attrs[NL80211_ATTR_COOKIE]) | 6488 | if (!info->attrs[NL80211_ATTR_COOKIE]) |
6448 | return -EINVAL; | 6489 | return -EINVAL; |
6449 | 6490 | ||
6450 | if (!rdev->ops->mgmt_tx_cancel_wait) | 6491 | if (!rdev->ops->mgmt_tx_cancel_wait) |
6451 | return -EOPNOTSUPP; | 6492 | return -EOPNOTSUPP; |
6452 | 6493 | ||
6453 | switch (wdev->iftype) { | 6494 | switch (wdev->iftype) { |
6454 | case NL80211_IFTYPE_STATION: | 6495 | case NL80211_IFTYPE_STATION: |
6455 | case NL80211_IFTYPE_ADHOC: | 6496 | case NL80211_IFTYPE_ADHOC: |
6456 | case NL80211_IFTYPE_P2P_CLIENT: | 6497 | case NL80211_IFTYPE_P2P_CLIENT: |
6457 | case NL80211_IFTYPE_AP: | 6498 | case NL80211_IFTYPE_AP: |
6458 | case NL80211_IFTYPE_AP_VLAN: | 6499 | case NL80211_IFTYPE_AP_VLAN: |
6459 | case NL80211_IFTYPE_P2P_GO: | 6500 | case NL80211_IFTYPE_P2P_GO: |
6460 | case NL80211_IFTYPE_P2P_DEVICE: | 6501 | case NL80211_IFTYPE_P2P_DEVICE: |
6461 | break; | 6502 | break; |
6462 | default: | 6503 | default: |
6463 | return -EOPNOTSUPP; | 6504 | return -EOPNOTSUPP; |
6464 | } | 6505 | } |
6465 | 6506 | ||
6466 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); | 6507 | cookie = nla_get_u64(info->attrs[NL80211_ATTR_COOKIE]); |
6467 | 6508 | ||
6468 | return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie); | 6509 | return rdev_mgmt_tx_cancel_wait(rdev, wdev, cookie); |
6469 | } | 6510 | } |
6470 | 6511 | ||
6471 | static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) | 6512 | static int nl80211_set_power_save(struct sk_buff *skb, struct genl_info *info) |
6472 | { | 6513 | { |
6473 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6514 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6474 | struct wireless_dev *wdev; | 6515 | struct wireless_dev *wdev; |
6475 | struct net_device *dev = info->user_ptr[1]; | 6516 | struct net_device *dev = info->user_ptr[1]; |
6476 | u8 ps_state; | 6517 | u8 ps_state; |
6477 | bool state; | 6518 | bool state; |
6478 | int err; | 6519 | int err; |
6479 | 6520 | ||
6480 | if (!info->attrs[NL80211_ATTR_PS_STATE]) | 6521 | if (!info->attrs[NL80211_ATTR_PS_STATE]) |
6481 | return -EINVAL; | 6522 | return -EINVAL; |
6482 | 6523 | ||
6483 | ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]); | 6524 | ps_state = nla_get_u32(info->attrs[NL80211_ATTR_PS_STATE]); |
6484 | 6525 | ||
6485 | if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) | 6526 | if (ps_state != NL80211_PS_DISABLED && ps_state != NL80211_PS_ENABLED) |
6486 | return -EINVAL; | 6527 | return -EINVAL; |
6487 | 6528 | ||
6488 | wdev = dev->ieee80211_ptr; | 6529 | wdev = dev->ieee80211_ptr; |
6489 | 6530 | ||
6490 | if (!rdev->ops->set_power_mgmt) | 6531 | if (!rdev->ops->set_power_mgmt) |
6491 | return -EOPNOTSUPP; | 6532 | return -EOPNOTSUPP; |
6492 | 6533 | ||
6493 | state = (ps_state == NL80211_PS_ENABLED) ? true : false; | 6534 | state = (ps_state == NL80211_PS_ENABLED) ? true : false; |
6494 | 6535 | ||
6495 | if (state == wdev->ps) | 6536 | if (state == wdev->ps) |
6496 | return 0; | 6537 | return 0; |
6497 | 6538 | ||
6498 | err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout); | 6539 | err = rdev_set_power_mgmt(rdev, dev, state, wdev->ps_timeout); |
6499 | if (!err) | 6540 | if (!err) |
6500 | wdev->ps = state; | 6541 | wdev->ps = state; |
6501 | return err; | 6542 | return err; |
6502 | } | 6543 | } |
6503 | 6544 | ||
6504 | static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) | 6545 | static int nl80211_get_power_save(struct sk_buff *skb, struct genl_info *info) |
6505 | { | 6546 | { |
6506 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6547 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6507 | enum nl80211_ps_state ps_state; | 6548 | enum nl80211_ps_state ps_state; |
6508 | struct wireless_dev *wdev; | 6549 | struct wireless_dev *wdev; |
6509 | struct net_device *dev = info->user_ptr[1]; | 6550 | struct net_device *dev = info->user_ptr[1]; |
6510 | struct sk_buff *msg; | 6551 | struct sk_buff *msg; |
6511 | void *hdr; | 6552 | void *hdr; |
6512 | int err; | 6553 | int err; |
6513 | 6554 | ||
6514 | wdev = dev->ieee80211_ptr; | 6555 | wdev = dev->ieee80211_ptr; |
6515 | 6556 | ||
6516 | if (!rdev->ops->set_power_mgmt) | 6557 | if (!rdev->ops->set_power_mgmt) |
6517 | return -EOPNOTSUPP; | 6558 | return -EOPNOTSUPP; |
6518 | 6559 | ||
6519 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 6560 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
6520 | if (!msg) | 6561 | if (!msg) |
6521 | return -ENOMEM; | 6562 | return -ENOMEM; |
6522 | 6563 | ||
6523 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 6564 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6524 | NL80211_CMD_GET_POWER_SAVE); | 6565 | NL80211_CMD_GET_POWER_SAVE); |
6525 | if (!hdr) { | 6566 | if (!hdr) { |
6526 | err = -ENOBUFS; | 6567 | err = -ENOBUFS; |
6527 | goto free_msg; | 6568 | goto free_msg; |
6528 | } | 6569 | } |
6529 | 6570 | ||
6530 | if (wdev->ps) | 6571 | if (wdev->ps) |
6531 | ps_state = NL80211_PS_ENABLED; | 6572 | ps_state = NL80211_PS_ENABLED; |
6532 | else | 6573 | else |
6533 | ps_state = NL80211_PS_DISABLED; | 6574 | ps_state = NL80211_PS_DISABLED; |
6534 | 6575 | ||
6535 | if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state)) | 6576 | if (nla_put_u32(msg, NL80211_ATTR_PS_STATE, ps_state)) |
6536 | goto nla_put_failure; | 6577 | goto nla_put_failure; |
6537 | 6578 | ||
6538 | genlmsg_end(msg, hdr); | 6579 | genlmsg_end(msg, hdr); |
6539 | return genlmsg_reply(msg, info); | 6580 | return genlmsg_reply(msg, info); |
6540 | 6581 | ||
6541 | nla_put_failure: | 6582 | nla_put_failure: |
6542 | err = -ENOBUFS; | 6583 | err = -ENOBUFS; |
6543 | free_msg: | 6584 | free_msg: |
6544 | nlmsg_free(msg); | 6585 | nlmsg_free(msg); |
6545 | return err; | 6586 | return err; |
6546 | } | 6587 | } |
6547 | 6588 | ||
6548 | static struct nla_policy | 6589 | static struct nla_policy |
6549 | nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = { | 6590 | nl80211_attr_cqm_policy[NL80211_ATTR_CQM_MAX + 1] __read_mostly = { |
6550 | [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 }, | 6591 | [NL80211_ATTR_CQM_RSSI_THOLD] = { .type = NLA_U32 }, |
6551 | [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 }, | 6592 | [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U32 }, |
6552 | [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 }, | 6593 | [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 }, |
6553 | [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 }, | 6594 | [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 }, |
6554 | [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 }, | 6595 | [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 }, |
6555 | [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 }, | 6596 | [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 }, |
6556 | }; | 6597 | }; |
6557 | 6598 | ||
6558 | static int nl80211_set_cqm_txe(struct genl_info *info, | 6599 | static int nl80211_set_cqm_txe(struct genl_info *info, |
6559 | u32 rate, u32 pkts, u32 intvl) | 6600 | u32 rate, u32 pkts, u32 intvl) |
6560 | { | 6601 | { |
6561 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6602 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6562 | struct wireless_dev *wdev; | 6603 | struct wireless_dev *wdev; |
6563 | struct net_device *dev = info->user_ptr[1]; | 6604 | struct net_device *dev = info->user_ptr[1]; |
6564 | 6605 | ||
6565 | if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL) | 6606 | if (rate > 100 || intvl > NL80211_CQM_TXE_MAX_INTVL) |
6566 | return -EINVAL; | 6607 | return -EINVAL; |
6567 | 6608 | ||
6568 | wdev = dev->ieee80211_ptr; | 6609 | wdev = dev->ieee80211_ptr; |
6569 | 6610 | ||
6570 | if (!rdev->ops->set_cqm_txe_config) | 6611 | if (!rdev->ops->set_cqm_txe_config) |
6571 | return -EOPNOTSUPP; | 6612 | return -EOPNOTSUPP; |
6572 | 6613 | ||
6573 | if (wdev->iftype != NL80211_IFTYPE_STATION && | 6614 | if (wdev->iftype != NL80211_IFTYPE_STATION && |
6574 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) | 6615 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) |
6575 | return -EOPNOTSUPP; | 6616 | return -EOPNOTSUPP; |
6576 | 6617 | ||
6577 | return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl); | 6618 | return rdev_set_cqm_txe_config(rdev, dev, rate, pkts, intvl); |
6578 | } | 6619 | } |
6579 | 6620 | ||
6580 | static int nl80211_set_cqm_rssi(struct genl_info *info, | 6621 | static int nl80211_set_cqm_rssi(struct genl_info *info, |
6581 | s32 threshold, u32 hysteresis) | 6622 | s32 threshold, u32 hysteresis) |
6582 | { | 6623 | { |
6583 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6624 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6584 | struct wireless_dev *wdev; | 6625 | struct wireless_dev *wdev; |
6585 | struct net_device *dev = info->user_ptr[1]; | 6626 | struct net_device *dev = info->user_ptr[1]; |
6586 | 6627 | ||
6587 | if (threshold > 0) | 6628 | if (threshold > 0) |
6588 | return -EINVAL; | 6629 | return -EINVAL; |
6589 | 6630 | ||
6590 | wdev = dev->ieee80211_ptr; | 6631 | wdev = dev->ieee80211_ptr; |
6591 | 6632 | ||
6592 | if (!rdev->ops->set_cqm_rssi_config) | 6633 | if (!rdev->ops->set_cqm_rssi_config) |
6593 | return -EOPNOTSUPP; | 6634 | return -EOPNOTSUPP; |
6594 | 6635 | ||
6595 | if (wdev->iftype != NL80211_IFTYPE_STATION && | 6636 | if (wdev->iftype != NL80211_IFTYPE_STATION && |
6596 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) | 6637 | wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) |
6597 | return -EOPNOTSUPP; | 6638 | return -EOPNOTSUPP; |
6598 | 6639 | ||
6599 | return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis); | 6640 | return rdev_set_cqm_rssi_config(rdev, dev, threshold, hysteresis); |
6600 | } | 6641 | } |
6601 | 6642 | ||
6602 | static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) | 6643 | static int nl80211_set_cqm(struct sk_buff *skb, struct genl_info *info) |
6603 | { | 6644 | { |
6604 | struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1]; | 6645 | struct nlattr *attrs[NL80211_ATTR_CQM_MAX + 1]; |
6605 | struct nlattr *cqm; | 6646 | struct nlattr *cqm; |
6606 | int err; | 6647 | int err; |
6607 | 6648 | ||
6608 | cqm = info->attrs[NL80211_ATTR_CQM]; | 6649 | cqm = info->attrs[NL80211_ATTR_CQM]; |
6609 | if (!cqm) { | 6650 | if (!cqm) { |
6610 | err = -EINVAL; | 6651 | err = -EINVAL; |
6611 | goto out; | 6652 | goto out; |
6612 | } | 6653 | } |
6613 | 6654 | ||
6614 | err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm, | 6655 | err = nla_parse_nested(attrs, NL80211_ATTR_CQM_MAX, cqm, |
6615 | nl80211_attr_cqm_policy); | 6656 | nl80211_attr_cqm_policy); |
6616 | if (err) | 6657 | if (err) |
6617 | goto out; | 6658 | goto out; |
6618 | 6659 | ||
6619 | if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] && | 6660 | if (attrs[NL80211_ATTR_CQM_RSSI_THOLD] && |
6620 | attrs[NL80211_ATTR_CQM_RSSI_HYST]) { | 6661 | attrs[NL80211_ATTR_CQM_RSSI_HYST]) { |
6621 | s32 threshold; | 6662 | s32 threshold; |
6622 | u32 hysteresis; | 6663 | u32 hysteresis; |
6623 | threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); | 6664 | threshold = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_THOLD]); |
6624 | hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); | 6665 | hysteresis = nla_get_u32(attrs[NL80211_ATTR_CQM_RSSI_HYST]); |
6625 | err = nl80211_set_cqm_rssi(info, threshold, hysteresis); | 6666 | err = nl80211_set_cqm_rssi(info, threshold, hysteresis); |
6626 | } else if (attrs[NL80211_ATTR_CQM_TXE_RATE] && | 6667 | } else if (attrs[NL80211_ATTR_CQM_TXE_RATE] && |
6627 | attrs[NL80211_ATTR_CQM_TXE_PKTS] && | 6668 | attrs[NL80211_ATTR_CQM_TXE_PKTS] && |
6628 | attrs[NL80211_ATTR_CQM_TXE_INTVL]) { | 6669 | attrs[NL80211_ATTR_CQM_TXE_INTVL]) { |
6629 | u32 rate, pkts, intvl; | 6670 | u32 rate, pkts, intvl; |
6630 | rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]); | 6671 | rate = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_RATE]); |
6631 | pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]); | 6672 | pkts = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_PKTS]); |
6632 | intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]); | 6673 | intvl = nla_get_u32(attrs[NL80211_ATTR_CQM_TXE_INTVL]); |
6633 | err = nl80211_set_cqm_txe(info, rate, pkts, intvl); | 6674 | err = nl80211_set_cqm_txe(info, rate, pkts, intvl); |
6634 | } else | 6675 | } else |
6635 | err = -EINVAL; | 6676 | err = -EINVAL; |
6636 | 6677 | ||
6637 | out: | 6678 | out: |
6638 | return err; | 6679 | return err; |
6639 | } | 6680 | } |
6640 | 6681 | ||
6641 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) | 6682 | static int nl80211_join_mesh(struct sk_buff *skb, struct genl_info *info) |
6642 | { | 6683 | { |
6643 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6684 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6644 | struct net_device *dev = info->user_ptr[1]; | 6685 | struct net_device *dev = info->user_ptr[1]; |
6645 | struct mesh_config cfg; | 6686 | struct mesh_config cfg; |
6646 | struct mesh_setup setup; | 6687 | struct mesh_setup setup; |
6647 | int err; | 6688 | int err; |
6648 | 6689 | ||
6649 | /* start with default */ | 6690 | /* start with default */ |
6650 | memcpy(&cfg, &default_mesh_config, sizeof(cfg)); | 6691 | memcpy(&cfg, &default_mesh_config, sizeof(cfg)); |
6651 | memcpy(&setup, &default_mesh_setup, sizeof(setup)); | 6692 | memcpy(&setup, &default_mesh_setup, sizeof(setup)); |
6652 | 6693 | ||
6653 | if (info->attrs[NL80211_ATTR_MESH_CONFIG]) { | 6694 | if (info->attrs[NL80211_ATTR_MESH_CONFIG]) { |
6654 | /* and parse parameters if given */ | 6695 | /* and parse parameters if given */ |
6655 | err = nl80211_parse_mesh_config(info, &cfg, NULL); | 6696 | err = nl80211_parse_mesh_config(info, &cfg, NULL); |
6656 | if (err) | 6697 | if (err) |
6657 | return err; | 6698 | return err; |
6658 | } | 6699 | } |
6659 | 6700 | ||
6660 | if (!info->attrs[NL80211_ATTR_MESH_ID] || | 6701 | if (!info->attrs[NL80211_ATTR_MESH_ID] || |
6661 | !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) | 6702 | !nla_len(info->attrs[NL80211_ATTR_MESH_ID])) |
6662 | return -EINVAL; | 6703 | return -EINVAL; |
6663 | 6704 | ||
6664 | setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); | 6705 | setup.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); |
6665 | setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); | 6706 | setup.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); |
6666 | 6707 | ||
6667 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && | 6708 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && |
6668 | !nl80211_parse_mcast_rate(rdev, setup.mcast_rate, | 6709 | !nl80211_parse_mcast_rate(rdev, setup.mcast_rate, |
6669 | nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]))) | 6710 | nla_get_u32(info->attrs[NL80211_ATTR_MCAST_RATE]))) |
6670 | return -EINVAL; | 6711 | return -EINVAL; |
6671 | 6712 | ||
6672 | if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { | 6713 | if (info->attrs[NL80211_ATTR_BEACON_INTERVAL]) { |
6673 | setup.beacon_interval = | 6714 | setup.beacon_interval = |
6674 | nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); | 6715 | nla_get_u32(info->attrs[NL80211_ATTR_BEACON_INTERVAL]); |
6675 | if (setup.beacon_interval < 10 || | 6716 | if (setup.beacon_interval < 10 || |
6676 | setup.beacon_interval > 10000) | 6717 | setup.beacon_interval > 10000) |
6677 | return -EINVAL; | 6718 | return -EINVAL; |
6678 | } | 6719 | } |
6679 | 6720 | ||
6680 | if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) { | 6721 | if (info->attrs[NL80211_ATTR_DTIM_PERIOD]) { |
6681 | setup.dtim_period = | 6722 | setup.dtim_period = |
6682 | nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); | 6723 | nla_get_u32(info->attrs[NL80211_ATTR_DTIM_PERIOD]); |
6683 | if (setup.dtim_period < 1 || setup.dtim_period > 100) | 6724 | if (setup.dtim_period < 1 || setup.dtim_period > 100) |
6684 | return -EINVAL; | 6725 | return -EINVAL; |
6685 | } | 6726 | } |
6686 | 6727 | ||
6687 | if (info->attrs[NL80211_ATTR_MESH_SETUP]) { | 6728 | if (info->attrs[NL80211_ATTR_MESH_SETUP]) { |
6688 | /* parse additional setup parameters if given */ | 6729 | /* parse additional setup parameters if given */ |
6689 | err = nl80211_parse_mesh_setup(info, &setup); | 6730 | err = nl80211_parse_mesh_setup(info, &setup); |
6690 | if (err) | 6731 | if (err) |
6691 | return err; | 6732 | return err; |
6692 | } | 6733 | } |
6693 | 6734 | ||
6694 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { | 6735 | if (info->attrs[NL80211_ATTR_WIPHY_FREQ]) { |
6695 | err = nl80211_parse_chandef(rdev, info, &setup.chandef); | 6736 | err = nl80211_parse_chandef(rdev, info, &setup.chandef); |
6696 | if (err) | 6737 | if (err) |
6697 | return err; | 6738 | return err; |
6698 | } else { | 6739 | } else { |
6699 | /* cfg80211_join_mesh() will sort it out */ | 6740 | /* cfg80211_join_mesh() will sort it out */ |
6700 | setup.chandef.chan = NULL; | 6741 | setup.chandef.chan = NULL; |
6701 | } | 6742 | } |
6702 | 6743 | ||
6703 | return cfg80211_join_mesh(rdev, dev, &setup, &cfg); | 6744 | return cfg80211_join_mesh(rdev, dev, &setup, &cfg); |
6704 | } | 6745 | } |
6705 | 6746 | ||
6706 | static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) | 6747 | static int nl80211_leave_mesh(struct sk_buff *skb, struct genl_info *info) |
6707 | { | 6748 | { |
6708 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6749 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6709 | struct net_device *dev = info->user_ptr[1]; | 6750 | struct net_device *dev = info->user_ptr[1]; |
6710 | 6751 | ||
6711 | return cfg80211_leave_mesh(rdev, dev); | 6752 | return cfg80211_leave_mesh(rdev, dev); |
6712 | } | 6753 | } |
6713 | 6754 | ||
6714 | #ifdef CONFIG_PM | 6755 | #ifdef CONFIG_PM |
6715 | static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) | 6756 | static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) |
6716 | { | 6757 | { |
6717 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6758 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6718 | struct sk_buff *msg; | 6759 | struct sk_buff *msg; |
6719 | void *hdr; | 6760 | void *hdr; |
6720 | 6761 | ||
6721 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) | 6762 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) |
6722 | return -EOPNOTSUPP; | 6763 | return -EOPNOTSUPP; |
6723 | 6764 | ||
6724 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 6765 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
6725 | if (!msg) | 6766 | if (!msg) |
6726 | return -ENOMEM; | 6767 | return -ENOMEM; |
6727 | 6768 | ||
6728 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 6769 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
6729 | NL80211_CMD_GET_WOWLAN); | 6770 | NL80211_CMD_GET_WOWLAN); |
6730 | if (!hdr) | 6771 | if (!hdr) |
6731 | goto nla_put_failure; | 6772 | goto nla_put_failure; |
6732 | 6773 | ||
6733 | if (rdev->wowlan) { | 6774 | if (rdev->wowlan) { |
6734 | struct nlattr *nl_wowlan; | 6775 | struct nlattr *nl_wowlan; |
6735 | 6776 | ||
6736 | nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); | 6777 | nl_wowlan = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); |
6737 | if (!nl_wowlan) | 6778 | if (!nl_wowlan) |
6738 | goto nla_put_failure; | 6779 | goto nla_put_failure; |
6739 | 6780 | ||
6740 | if ((rdev->wowlan->any && | 6781 | if ((rdev->wowlan->any && |
6741 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || | 6782 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_ANY)) || |
6742 | (rdev->wowlan->disconnect && | 6783 | (rdev->wowlan->disconnect && |
6743 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || | 6784 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_DISCONNECT)) || |
6744 | (rdev->wowlan->magic_pkt && | 6785 | (rdev->wowlan->magic_pkt && |
6745 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || | 6786 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT)) || |
6746 | (rdev->wowlan->gtk_rekey_failure && | 6787 | (rdev->wowlan->gtk_rekey_failure && |
6747 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || | 6788 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE)) || |
6748 | (rdev->wowlan->eap_identity_req && | 6789 | (rdev->wowlan->eap_identity_req && |
6749 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || | 6790 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST)) || |
6750 | (rdev->wowlan->four_way_handshake && | 6791 | (rdev->wowlan->four_way_handshake && |
6751 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || | 6792 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE)) || |
6752 | (rdev->wowlan->rfkill_release && | 6793 | (rdev->wowlan->rfkill_release && |
6753 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) | 6794 | nla_put_flag(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE))) |
6754 | goto nla_put_failure; | 6795 | goto nla_put_failure; |
6755 | if (rdev->wowlan->n_patterns) { | 6796 | if (rdev->wowlan->n_patterns) { |
6756 | struct nlattr *nl_pats, *nl_pat; | 6797 | struct nlattr *nl_pats, *nl_pat; |
6757 | int i, pat_len; | 6798 | int i, pat_len; |
6758 | 6799 | ||
6759 | nl_pats = nla_nest_start(msg, | 6800 | nl_pats = nla_nest_start(msg, |
6760 | NL80211_WOWLAN_TRIG_PKT_PATTERN); | 6801 | NL80211_WOWLAN_TRIG_PKT_PATTERN); |
6761 | if (!nl_pats) | 6802 | if (!nl_pats) |
6762 | goto nla_put_failure; | 6803 | goto nla_put_failure; |
6763 | 6804 | ||
6764 | for (i = 0; i < rdev->wowlan->n_patterns; i++) { | 6805 | for (i = 0; i < rdev->wowlan->n_patterns; i++) { |
6765 | nl_pat = nla_nest_start(msg, i + 1); | 6806 | nl_pat = nla_nest_start(msg, i + 1); |
6766 | if (!nl_pat) | 6807 | if (!nl_pat) |
6767 | goto nla_put_failure; | 6808 | goto nla_put_failure; |
6768 | pat_len = rdev->wowlan->patterns[i].pattern_len; | 6809 | pat_len = rdev->wowlan->patterns[i].pattern_len; |
6769 | if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK, | 6810 | if (nla_put(msg, NL80211_WOWLAN_PKTPAT_MASK, |
6770 | DIV_ROUND_UP(pat_len, 8), | 6811 | DIV_ROUND_UP(pat_len, 8), |
6771 | rdev->wowlan->patterns[i].mask) || | 6812 | rdev->wowlan->patterns[i].mask) || |
6772 | nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN, | 6813 | nla_put(msg, NL80211_WOWLAN_PKTPAT_PATTERN, |
6773 | pat_len, | 6814 | pat_len, |
6774 | rdev->wowlan->patterns[i].pattern)) | 6815 | rdev->wowlan->patterns[i].pattern)) |
6775 | goto nla_put_failure; | 6816 | goto nla_put_failure; |
6776 | nla_nest_end(msg, nl_pat); | 6817 | nla_nest_end(msg, nl_pat); |
6777 | } | 6818 | } |
6778 | nla_nest_end(msg, nl_pats); | 6819 | nla_nest_end(msg, nl_pats); |
6779 | } | 6820 | } |
6780 | 6821 | ||
6781 | nla_nest_end(msg, nl_wowlan); | 6822 | nla_nest_end(msg, nl_wowlan); |
6782 | } | 6823 | } |
6783 | 6824 | ||
6784 | genlmsg_end(msg, hdr); | 6825 | genlmsg_end(msg, hdr); |
6785 | return genlmsg_reply(msg, info); | 6826 | return genlmsg_reply(msg, info); |
6786 | 6827 | ||
6787 | nla_put_failure: | 6828 | nla_put_failure: |
6788 | nlmsg_free(msg); | 6829 | nlmsg_free(msg); |
6789 | return -ENOBUFS; | 6830 | return -ENOBUFS; |
6790 | } | 6831 | } |
6791 | 6832 | ||
6792 | static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | 6833 | static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) |
6793 | { | 6834 | { |
6794 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6835 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6795 | struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; | 6836 | struct nlattr *tb[NUM_NL80211_WOWLAN_TRIG]; |
6796 | struct cfg80211_wowlan new_triggers = {}; | 6837 | struct cfg80211_wowlan new_triggers = {}; |
6797 | struct cfg80211_wowlan *ntrig; | 6838 | struct cfg80211_wowlan *ntrig; |
6798 | struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; | 6839 | struct wiphy_wowlan_support *wowlan = &rdev->wiphy.wowlan; |
6799 | int err, i; | 6840 | int err, i; |
6800 | bool prev_enabled = rdev->wowlan; | 6841 | bool prev_enabled = rdev->wowlan; |
6801 | 6842 | ||
6802 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) | 6843 | if (!rdev->wiphy.wowlan.flags && !rdev->wiphy.wowlan.n_patterns) |
6803 | return -EOPNOTSUPP; | 6844 | return -EOPNOTSUPP; |
6804 | 6845 | ||
6805 | if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { | 6846 | if (!info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) { |
6806 | cfg80211_rdev_free_wowlan(rdev); | 6847 | cfg80211_rdev_free_wowlan(rdev); |
6807 | rdev->wowlan = NULL; | 6848 | rdev->wowlan = NULL; |
6808 | goto set_wakeup; | 6849 | goto set_wakeup; |
6809 | } | 6850 | } |
6810 | 6851 | ||
6811 | err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG, | 6852 | err = nla_parse(tb, MAX_NL80211_WOWLAN_TRIG, |
6812 | nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), | 6853 | nla_data(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), |
6813 | nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), | 6854 | nla_len(info->attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), |
6814 | nl80211_wowlan_policy); | 6855 | nl80211_wowlan_policy); |
6815 | if (err) | 6856 | if (err) |
6816 | return err; | 6857 | return err; |
6817 | 6858 | ||
6818 | if (tb[NL80211_WOWLAN_TRIG_ANY]) { | 6859 | if (tb[NL80211_WOWLAN_TRIG_ANY]) { |
6819 | if (!(wowlan->flags & WIPHY_WOWLAN_ANY)) | 6860 | if (!(wowlan->flags & WIPHY_WOWLAN_ANY)) |
6820 | return -EINVAL; | 6861 | return -EINVAL; |
6821 | new_triggers.any = true; | 6862 | new_triggers.any = true; |
6822 | } | 6863 | } |
6823 | 6864 | ||
6824 | if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) { | 6865 | if (tb[NL80211_WOWLAN_TRIG_DISCONNECT]) { |
6825 | if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT)) | 6866 | if (!(wowlan->flags & WIPHY_WOWLAN_DISCONNECT)) |
6826 | return -EINVAL; | 6867 | return -EINVAL; |
6827 | new_triggers.disconnect = true; | 6868 | new_triggers.disconnect = true; |
6828 | } | 6869 | } |
6829 | 6870 | ||
6830 | if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) { | 6871 | if (tb[NL80211_WOWLAN_TRIG_MAGIC_PKT]) { |
6831 | if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT)) | 6872 | if (!(wowlan->flags & WIPHY_WOWLAN_MAGIC_PKT)) |
6832 | return -EINVAL; | 6873 | return -EINVAL; |
6833 | new_triggers.magic_pkt = true; | 6874 | new_triggers.magic_pkt = true; |
6834 | } | 6875 | } |
6835 | 6876 | ||
6836 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) | 6877 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) |
6837 | return -EINVAL; | 6878 | return -EINVAL; |
6838 | 6879 | ||
6839 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) { | 6880 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) { |
6840 | if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)) | 6881 | if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)) |
6841 | return -EINVAL; | 6882 | return -EINVAL; |
6842 | new_triggers.gtk_rekey_failure = true; | 6883 | new_triggers.gtk_rekey_failure = true; |
6843 | } | 6884 | } |
6844 | 6885 | ||
6845 | if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) { | 6886 | if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) { |
6846 | if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)) | 6887 | if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)) |
6847 | return -EINVAL; | 6888 | return -EINVAL; |
6848 | new_triggers.eap_identity_req = true; | 6889 | new_triggers.eap_identity_req = true; |
6849 | } | 6890 | } |
6850 | 6891 | ||
6851 | if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) { | 6892 | if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) { |
6852 | if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)) | 6893 | if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)) |
6853 | return -EINVAL; | 6894 | return -EINVAL; |
6854 | new_triggers.four_way_handshake = true; | 6895 | new_triggers.four_way_handshake = true; |
6855 | } | 6896 | } |
6856 | 6897 | ||
6857 | if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) { | 6898 | if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) { |
6858 | if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE)) | 6899 | if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE)) |
6859 | return -EINVAL; | 6900 | return -EINVAL; |
6860 | new_triggers.rfkill_release = true; | 6901 | new_triggers.rfkill_release = true; |
6861 | } | 6902 | } |
6862 | 6903 | ||
6863 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { | 6904 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { |
6864 | struct nlattr *pat; | 6905 | struct nlattr *pat; |
6865 | int n_patterns = 0; | 6906 | int n_patterns = 0; |
6866 | int rem, pat_len, mask_len; | 6907 | int rem, pat_len, mask_len; |
6867 | struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT]; | 6908 | struct nlattr *pat_tb[NUM_NL80211_WOWLAN_PKTPAT]; |
6868 | 6909 | ||
6869 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], | 6910 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], |
6870 | rem) | 6911 | rem) |
6871 | n_patterns++; | 6912 | n_patterns++; |
6872 | if (n_patterns > wowlan->n_patterns) | 6913 | if (n_patterns > wowlan->n_patterns) |
6873 | return -EINVAL; | 6914 | return -EINVAL; |
6874 | 6915 | ||
6875 | new_triggers.patterns = kcalloc(n_patterns, | 6916 | new_triggers.patterns = kcalloc(n_patterns, |
6876 | sizeof(new_triggers.patterns[0]), | 6917 | sizeof(new_triggers.patterns[0]), |
6877 | GFP_KERNEL); | 6918 | GFP_KERNEL); |
6878 | if (!new_triggers.patterns) | 6919 | if (!new_triggers.patterns) |
6879 | return -ENOMEM; | 6920 | return -ENOMEM; |
6880 | 6921 | ||
6881 | new_triggers.n_patterns = n_patterns; | 6922 | new_triggers.n_patterns = n_patterns; |
6882 | i = 0; | 6923 | i = 0; |
6883 | 6924 | ||
6884 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], | 6925 | nla_for_each_nested(pat, tb[NL80211_WOWLAN_TRIG_PKT_PATTERN], |
6885 | rem) { | 6926 | rem) { |
6886 | nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT, | 6927 | nla_parse(pat_tb, MAX_NL80211_WOWLAN_PKTPAT, |
6887 | nla_data(pat), nla_len(pat), NULL); | 6928 | nla_data(pat), nla_len(pat), NULL); |
6888 | err = -EINVAL; | 6929 | err = -EINVAL; |
6889 | if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] || | 6930 | if (!pat_tb[NL80211_WOWLAN_PKTPAT_MASK] || |
6890 | !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]) | 6931 | !pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]) |
6891 | goto error; | 6932 | goto error; |
6892 | pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]); | 6933 | pat_len = nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]); |
6893 | mask_len = DIV_ROUND_UP(pat_len, 8); | 6934 | mask_len = DIV_ROUND_UP(pat_len, 8); |
6894 | if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) != | 6935 | if (nla_len(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]) != |
6895 | mask_len) | 6936 | mask_len) |
6896 | goto error; | 6937 | goto error; |
6897 | if (pat_len > wowlan->pattern_max_len || | 6938 | if (pat_len > wowlan->pattern_max_len || |
6898 | pat_len < wowlan->pattern_min_len) | 6939 | pat_len < wowlan->pattern_min_len) |
6899 | goto error; | 6940 | goto error; |
6900 | 6941 | ||
6901 | new_triggers.patterns[i].mask = | 6942 | new_triggers.patterns[i].mask = |
6902 | kmalloc(mask_len + pat_len, GFP_KERNEL); | 6943 | kmalloc(mask_len + pat_len, GFP_KERNEL); |
6903 | if (!new_triggers.patterns[i].mask) { | 6944 | if (!new_triggers.patterns[i].mask) { |
6904 | err = -ENOMEM; | 6945 | err = -ENOMEM; |
6905 | goto error; | 6946 | goto error; |
6906 | } | 6947 | } |
6907 | new_triggers.patterns[i].pattern = | 6948 | new_triggers.patterns[i].pattern = |
6908 | new_triggers.patterns[i].mask + mask_len; | 6949 | new_triggers.patterns[i].mask + mask_len; |
6909 | memcpy(new_triggers.patterns[i].mask, | 6950 | memcpy(new_triggers.patterns[i].mask, |
6910 | nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]), | 6951 | nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_MASK]), |
6911 | mask_len); | 6952 | mask_len); |
6912 | new_triggers.patterns[i].pattern_len = pat_len; | 6953 | new_triggers.patterns[i].pattern_len = pat_len; |
6913 | memcpy(new_triggers.patterns[i].pattern, | 6954 | memcpy(new_triggers.patterns[i].pattern, |
6914 | nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]), | 6955 | nla_data(pat_tb[NL80211_WOWLAN_PKTPAT_PATTERN]), |
6915 | pat_len); | 6956 | pat_len); |
6916 | i++; | 6957 | i++; |
6917 | } | 6958 | } |
6918 | } | 6959 | } |
6919 | 6960 | ||
6920 | ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); | 6961 | ntrig = kmemdup(&new_triggers, sizeof(new_triggers), GFP_KERNEL); |
6921 | if (!ntrig) { | 6962 | if (!ntrig) { |
6922 | err = -ENOMEM; | 6963 | err = -ENOMEM; |
6923 | goto error; | 6964 | goto error; |
6924 | } | 6965 | } |
6925 | cfg80211_rdev_free_wowlan(rdev); | 6966 | cfg80211_rdev_free_wowlan(rdev); |
6926 | rdev->wowlan = ntrig; | 6967 | rdev->wowlan = ntrig; |
6927 | 6968 | ||
6928 | set_wakeup: | 6969 | set_wakeup: |
6929 | if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) | 6970 | if (rdev->ops->set_wakeup && prev_enabled != !!rdev->wowlan) |
6930 | rdev_set_wakeup(rdev, rdev->wowlan); | 6971 | rdev_set_wakeup(rdev, rdev->wowlan); |
6931 | 6972 | ||
6932 | return 0; | 6973 | return 0; |
6933 | error: | 6974 | error: |
6934 | for (i = 0; i < new_triggers.n_patterns; i++) | 6975 | for (i = 0; i < new_triggers.n_patterns; i++) |
6935 | kfree(new_triggers.patterns[i].mask); | 6976 | kfree(new_triggers.patterns[i].mask); |
6936 | kfree(new_triggers.patterns); | 6977 | kfree(new_triggers.patterns); |
6937 | return err; | 6978 | return err; |
6938 | } | 6979 | } |
6939 | #endif | 6980 | #endif |
6940 | 6981 | ||
6941 | static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) | 6982 | static int nl80211_set_rekey_data(struct sk_buff *skb, struct genl_info *info) |
6942 | { | 6983 | { |
6943 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 6984 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
6944 | struct net_device *dev = info->user_ptr[1]; | 6985 | struct net_device *dev = info->user_ptr[1]; |
6945 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 6986 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
6946 | struct nlattr *tb[NUM_NL80211_REKEY_DATA]; | 6987 | struct nlattr *tb[NUM_NL80211_REKEY_DATA]; |
6947 | struct cfg80211_gtk_rekey_data rekey_data; | 6988 | struct cfg80211_gtk_rekey_data rekey_data; |
6948 | int err; | 6989 | int err; |
6949 | 6990 | ||
6950 | if (!info->attrs[NL80211_ATTR_REKEY_DATA]) | 6991 | if (!info->attrs[NL80211_ATTR_REKEY_DATA]) |
6951 | return -EINVAL; | 6992 | return -EINVAL; |
6952 | 6993 | ||
6953 | err = nla_parse(tb, MAX_NL80211_REKEY_DATA, | 6994 | err = nla_parse(tb, MAX_NL80211_REKEY_DATA, |
6954 | nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]), | 6995 | nla_data(info->attrs[NL80211_ATTR_REKEY_DATA]), |
6955 | nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]), | 6996 | nla_len(info->attrs[NL80211_ATTR_REKEY_DATA]), |
6956 | nl80211_rekey_policy); | 6997 | nl80211_rekey_policy); |
6957 | if (err) | 6998 | if (err) |
6958 | return err; | 6999 | return err; |
6959 | 7000 | ||
6960 | if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN) | 7001 | if (nla_len(tb[NL80211_REKEY_DATA_REPLAY_CTR]) != NL80211_REPLAY_CTR_LEN) |
6961 | return -ERANGE; | 7002 | return -ERANGE; |
6962 | if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN) | 7003 | if (nla_len(tb[NL80211_REKEY_DATA_KEK]) != NL80211_KEK_LEN) |
6963 | return -ERANGE; | 7004 | return -ERANGE; |
6964 | if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN) | 7005 | if (nla_len(tb[NL80211_REKEY_DATA_KCK]) != NL80211_KCK_LEN) |
6965 | return -ERANGE; | 7006 | return -ERANGE; |
6966 | 7007 | ||
6967 | memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]), | 7008 | memcpy(rekey_data.kek, nla_data(tb[NL80211_REKEY_DATA_KEK]), |
6968 | NL80211_KEK_LEN); | 7009 | NL80211_KEK_LEN); |
6969 | memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]), | 7010 | memcpy(rekey_data.kck, nla_data(tb[NL80211_REKEY_DATA_KCK]), |
6970 | NL80211_KCK_LEN); | 7011 | NL80211_KCK_LEN); |
6971 | memcpy(rekey_data.replay_ctr, | 7012 | memcpy(rekey_data.replay_ctr, |
6972 | nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]), | 7013 | nla_data(tb[NL80211_REKEY_DATA_REPLAY_CTR]), |
6973 | NL80211_REPLAY_CTR_LEN); | 7014 | NL80211_REPLAY_CTR_LEN); |
6974 | 7015 | ||
6975 | wdev_lock(wdev); | 7016 | wdev_lock(wdev); |
6976 | if (!wdev->current_bss) { | 7017 | if (!wdev->current_bss) { |
6977 | err = -ENOTCONN; | 7018 | err = -ENOTCONN; |
6978 | goto out; | 7019 | goto out; |
6979 | } | 7020 | } |
6980 | 7021 | ||
6981 | if (!rdev->ops->set_rekey_data) { | 7022 | if (!rdev->ops->set_rekey_data) { |
6982 | err = -EOPNOTSUPP; | 7023 | err = -EOPNOTSUPP; |
6983 | goto out; | 7024 | goto out; |
6984 | } | 7025 | } |
6985 | 7026 | ||
6986 | err = rdev_set_rekey_data(rdev, dev, &rekey_data); | 7027 | err = rdev_set_rekey_data(rdev, dev, &rekey_data); |
6987 | out: | 7028 | out: |
6988 | wdev_unlock(wdev); | 7029 | wdev_unlock(wdev); |
6989 | return err; | 7030 | return err; |
6990 | } | 7031 | } |
6991 | 7032 | ||
6992 | static int nl80211_register_unexpected_frame(struct sk_buff *skb, | 7033 | static int nl80211_register_unexpected_frame(struct sk_buff *skb, |
6993 | struct genl_info *info) | 7034 | struct genl_info *info) |
6994 | { | 7035 | { |
6995 | struct net_device *dev = info->user_ptr[1]; | 7036 | struct net_device *dev = info->user_ptr[1]; |
6996 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 7037 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
6997 | 7038 | ||
6998 | if (wdev->iftype != NL80211_IFTYPE_AP && | 7039 | if (wdev->iftype != NL80211_IFTYPE_AP && |
6999 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | 7040 | wdev->iftype != NL80211_IFTYPE_P2P_GO) |
7000 | return -EINVAL; | 7041 | return -EINVAL; |
7001 | 7042 | ||
7002 | if (wdev->ap_unexpected_nlportid) | 7043 | if (wdev->ap_unexpected_nlportid) |
7003 | return -EBUSY; | 7044 | return -EBUSY; |
7004 | 7045 | ||
7005 | wdev->ap_unexpected_nlportid = info->snd_portid; | 7046 | wdev->ap_unexpected_nlportid = info->snd_portid; |
7006 | return 0; | 7047 | return 0; |
7007 | } | 7048 | } |
7008 | 7049 | ||
7009 | static int nl80211_probe_client(struct sk_buff *skb, | 7050 | static int nl80211_probe_client(struct sk_buff *skb, |
7010 | struct genl_info *info) | 7051 | struct genl_info *info) |
7011 | { | 7052 | { |
7012 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7053 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7013 | struct net_device *dev = info->user_ptr[1]; | 7054 | struct net_device *dev = info->user_ptr[1]; |
7014 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 7055 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
7015 | struct sk_buff *msg; | 7056 | struct sk_buff *msg; |
7016 | void *hdr; | 7057 | void *hdr; |
7017 | const u8 *addr; | 7058 | const u8 *addr; |
7018 | u64 cookie; | 7059 | u64 cookie; |
7019 | int err; | 7060 | int err; |
7020 | 7061 | ||
7021 | if (wdev->iftype != NL80211_IFTYPE_AP && | 7062 | if (wdev->iftype != NL80211_IFTYPE_AP && |
7022 | wdev->iftype != NL80211_IFTYPE_P2P_GO) | 7063 | wdev->iftype != NL80211_IFTYPE_P2P_GO) |
7023 | return -EOPNOTSUPP; | 7064 | return -EOPNOTSUPP; |
7024 | 7065 | ||
7025 | if (!info->attrs[NL80211_ATTR_MAC]) | 7066 | if (!info->attrs[NL80211_ATTR_MAC]) |
7026 | return -EINVAL; | 7067 | return -EINVAL; |
7027 | 7068 | ||
7028 | if (!rdev->ops->probe_client) | 7069 | if (!rdev->ops->probe_client) |
7029 | return -EOPNOTSUPP; | 7070 | return -EOPNOTSUPP; |
7030 | 7071 | ||
7031 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 7072 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
7032 | if (!msg) | 7073 | if (!msg) |
7033 | return -ENOMEM; | 7074 | return -ENOMEM; |
7034 | 7075 | ||
7035 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, | 7076 | hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, |
7036 | NL80211_CMD_PROBE_CLIENT); | 7077 | NL80211_CMD_PROBE_CLIENT); |
7037 | 7078 | ||
7038 | if (IS_ERR(hdr)) { | 7079 | if (IS_ERR(hdr)) { |
7039 | err = PTR_ERR(hdr); | 7080 | err = PTR_ERR(hdr); |
7040 | goto free_msg; | 7081 | goto free_msg; |
7041 | } | 7082 | } |
7042 | 7083 | ||
7043 | addr = nla_data(info->attrs[NL80211_ATTR_MAC]); | 7084 | addr = nla_data(info->attrs[NL80211_ATTR_MAC]); |
7044 | 7085 | ||
7045 | err = rdev_probe_client(rdev, dev, addr, &cookie); | 7086 | err = rdev_probe_client(rdev, dev, addr, &cookie); |
7046 | if (err) | 7087 | if (err) |
7047 | goto free_msg; | 7088 | goto free_msg; |
7048 | 7089 | ||
7049 | if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) | 7090 | if (nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) |
7050 | goto nla_put_failure; | 7091 | goto nla_put_failure; |
7051 | 7092 | ||
7052 | genlmsg_end(msg, hdr); | 7093 | genlmsg_end(msg, hdr); |
7053 | 7094 | ||
7054 | return genlmsg_reply(msg, info); | 7095 | return genlmsg_reply(msg, info); |
7055 | 7096 | ||
7056 | nla_put_failure: | 7097 | nla_put_failure: |
7057 | err = -ENOBUFS; | 7098 | err = -ENOBUFS; |
7058 | free_msg: | 7099 | free_msg: |
7059 | nlmsg_free(msg); | 7100 | nlmsg_free(msg); |
7060 | return err; | 7101 | return err; |
7061 | } | 7102 | } |
7062 | 7103 | ||
7063 | static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) | 7104 | static int nl80211_register_beacons(struct sk_buff *skb, struct genl_info *info) |
7064 | { | 7105 | { |
7065 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7106 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7066 | struct cfg80211_beacon_registration *reg, *nreg; | 7107 | struct cfg80211_beacon_registration *reg, *nreg; |
7067 | int rv; | 7108 | int rv; |
7068 | 7109 | ||
7069 | if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) | 7110 | if (!(rdev->wiphy.flags & WIPHY_FLAG_REPORTS_OBSS)) |
7070 | return -EOPNOTSUPP; | 7111 | return -EOPNOTSUPP; |
7071 | 7112 | ||
7072 | nreg = kzalloc(sizeof(*nreg), GFP_KERNEL); | 7113 | nreg = kzalloc(sizeof(*nreg), GFP_KERNEL); |
7073 | if (!nreg) | 7114 | if (!nreg) |
7074 | return -ENOMEM; | 7115 | return -ENOMEM; |
7075 | 7116 | ||
7076 | /* First, check if already registered. */ | 7117 | /* First, check if already registered. */ |
7077 | spin_lock_bh(&rdev->beacon_registrations_lock); | 7118 | spin_lock_bh(&rdev->beacon_registrations_lock); |
7078 | list_for_each_entry(reg, &rdev->beacon_registrations, list) { | 7119 | list_for_each_entry(reg, &rdev->beacon_registrations, list) { |
7079 | if (reg->nlportid == info->snd_portid) { | 7120 | if (reg->nlportid == info->snd_portid) { |
7080 | rv = -EALREADY; | 7121 | rv = -EALREADY; |
7081 | goto out_err; | 7122 | goto out_err; |
7082 | } | 7123 | } |
7083 | } | 7124 | } |
7084 | /* Add it to the list */ | 7125 | /* Add it to the list */ |
7085 | nreg->nlportid = info->snd_portid; | 7126 | nreg->nlportid = info->snd_portid; |
7086 | list_add(&nreg->list, &rdev->beacon_registrations); | 7127 | list_add(&nreg->list, &rdev->beacon_registrations); |
7087 | 7128 | ||
7088 | spin_unlock_bh(&rdev->beacon_registrations_lock); | 7129 | spin_unlock_bh(&rdev->beacon_registrations_lock); |
7089 | 7130 | ||
7090 | return 0; | 7131 | return 0; |
7091 | out_err: | 7132 | out_err: |
7092 | spin_unlock_bh(&rdev->beacon_registrations_lock); | 7133 | spin_unlock_bh(&rdev->beacon_registrations_lock); |
7093 | kfree(nreg); | 7134 | kfree(nreg); |
7094 | return rv; | 7135 | return rv; |
7095 | } | 7136 | } |
7096 | 7137 | ||
7097 | static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) | 7138 | static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info) |
7098 | { | 7139 | { |
7099 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7140 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7100 | struct wireless_dev *wdev = info->user_ptr[1]; | 7141 | struct wireless_dev *wdev = info->user_ptr[1]; |
7101 | int err; | 7142 | int err; |
7102 | 7143 | ||
7103 | if (!rdev->ops->start_p2p_device) | 7144 | if (!rdev->ops->start_p2p_device) |
7104 | return -EOPNOTSUPP; | 7145 | return -EOPNOTSUPP; |
7105 | 7146 | ||
7106 | if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) | 7147 | if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) |
7107 | return -EOPNOTSUPP; | 7148 | return -EOPNOTSUPP; |
7108 | 7149 | ||
7109 | if (wdev->p2p_started) | 7150 | if (wdev->p2p_started) |
7110 | return 0; | 7151 | return 0; |
7111 | 7152 | ||
7112 | mutex_lock(&rdev->devlist_mtx); | 7153 | mutex_lock(&rdev->devlist_mtx); |
7113 | err = cfg80211_can_add_interface(rdev, wdev->iftype); | 7154 | err = cfg80211_can_add_interface(rdev, wdev->iftype); |
7114 | mutex_unlock(&rdev->devlist_mtx); | 7155 | mutex_unlock(&rdev->devlist_mtx); |
7115 | if (err) | 7156 | if (err) |
7116 | return err; | 7157 | return err; |
7117 | 7158 | ||
7118 | err = rdev_start_p2p_device(rdev, wdev); | 7159 | err = rdev_start_p2p_device(rdev, wdev); |
7119 | if (err) | 7160 | if (err) |
7120 | return err; | 7161 | return err; |
7121 | 7162 | ||
7122 | wdev->p2p_started = true; | 7163 | wdev->p2p_started = true; |
7123 | mutex_lock(&rdev->devlist_mtx); | 7164 | mutex_lock(&rdev->devlist_mtx); |
7124 | rdev->opencount++; | 7165 | rdev->opencount++; |
7125 | mutex_unlock(&rdev->devlist_mtx); | 7166 | mutex_unlock(&rdev->devlist_mtx); |
7126 | 7167 | ||
7127 | return 0; | 7168 | return 0; |
7128 | } | 7169 | } |
7129 | 7170 | ||
7130 | static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) | 7171 | static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info) |
7131 | { | 7172 | { |
7132 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 7173 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
7133 | struct wireless_dev *wdev = info->user_ptr[1]; | 7174 | struct wireless_dev *wdev = info->user_ptr[1]; |
7134 | 7175 | ||
7135 | if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) | 7176 | if (wdev->iftype != NL80211_IFTYPE_P2P_DEVICE) |
7136 | return -EOPNOTSUPP; | 7177 | return -EOPNOTSUPP; |
7137 | 7178 | ||
7138 | if (!rdev->ops->stop_p2p_device) | 7179 | if (!rdev->ops->stop_p2p_device) |
7139 | return -EOPNOTSUPP; | 7180 | return -EOPNOTSUPP; |
7140 | 7181 | ||
7141 | if (!wdev->p2p_started) | 7182 | if (!wdev->p2p_started) |
7142 | return 0; | 7183 | return 0; |
7143 | 7184 | ||
7144 | rdev_stop_p2p_device(rdev, wdev); | 7185 | rdev_stop_p2p_device(rdev, wdev); |
7145 | wdev->p2p_started = false; | 7186 | wdev->p2p_started = false; |
7146 | 7187 | ||
7147 | mutex_lock(&rdev->devlist_mtx); | 7188 | mutex_lock(&rdev->devlist_mtx); |
7148 | rdev->opencount--; | 7189 | rdev->opencount--; |
7149 | mutex_unlock(&rdev->devlist_mtx); | 7190 | mutex_unlock(&rdev->devlist_mtx); |
7150 | 7191 | ||
7151 | if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { | 7192 | if (WARN_ON(rdev->scan_req && rdev->scan_req->wdev == wdev)) { |
7152 | rdev->scan_req->aborted = true; | 7193 | rdev->scan_req->aborted = true; |
7153 | ___cfg80211_scan_done(rdev, true); | 7194 | ___cfg80211_scan_done(rdev, true); |
7154 | } | 7195 | } |
7155 | 7196 | ||
7156 | return 0; | 7197 | return 0; |
7157 | } | 7198 | } |
7158 | 7199 | ||
7159 | #define NL80211_FLAG_NEED_WIPHY 0x01 | 7200 | #define NL80211_FLAG_NEED_WIPHY 0x01 |
7160 | #define NL80211_FLAG_NEED_NETDEV 0x02 | 7201 | #define NL80211_FLAG_NEED_NETDEV 0x02 |
7161 | #define NL80211_FLAG_NEED_RTNL 0x04 | 7202 | #define NL80211_FLAG_NEED_RTNL 0x04 |
7162 | #define NL80211_FLAG_CHECK_NETDEV_UP 0x08 | 7203 | #define NL80211_FLAG_CHECK_NETDEV_UP 0x08 |
7163 | #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ | 7204 | #define NL80211_FLAG_NEED_NETDEV_UP (NL80211_FLAG_NEED_NETDEV |\ |
7164 | NL80211_FLAG_CHECK_NETDEV_UP) | 7205 | NL80211_FLAG_CHECK_NETDEV_UP) |
7165 | #define NL80211_FLAG_NEED_WDEV 0x10 | 7206 | #define NL80211_FLAG_NEED_WDEV 0x10 |
7166 | /* If a netdev is associated, it must be UP, P2P must be started */ | 7207 | /* If a netdev is associated, it must be UP, P2P must be started */ |
7167 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ | 7208 | #define NL80211_FLAG_NEED_WDEV_UP (NL80211_FLAG_NEED_WDEV |\ |
7168 | NL80211_FLAG_CHECK_NETDEV_UP) | 7209 | NL80211_FLAG_CHECK_NETDEV_UP) |
7169 | 7210 | ||
7170 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, | 7211 | static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb, |
7171 | struct genl_info *info) | 7212 | struct genl_info *info) |
7172 | { | 7213 | { |
7173 | struct cfg80211_registered_device *rdev; | 7214 | struct cfg80211_registered_device *rdev; |
7174 | struct wireless_dev *wdev; | 7215 | struct wireless_dev *wdev; |
7175 | struct net_device *dev; | 7216 | struct net_device *dev; |
7176 | bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL; | 7217 | bool rtnl = ops->internal_flags & NL80211_FLAG_NEED_RTNL; |
7177 | 7218 | ||
7178 | if (rtnl) | 7219 | if (rtnl) |
7179 | rtnl_lock(); | 7220 | rtnl_lock(); |
7180 | 7221 | ||
7181 | if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { | 7222 | if (ops->internal_flags & NL80211_FLAG_NEED_WIPHY) { |
7182 | rdev = cfg80211_get_dev_from_info(genl_info_net(info), info); | 7223 | rdev = cfg80211_get_dev_from_info(genl_info_net(info), info); |
7183 | if (IS_ERR(rdev)) { | 7224 | if (IS_ERR(rdev)) { |
7184 | if (rtnl) | 7225 | if (rtnl) |
7185 | rtnl_unlock(); | 7226 | rtnl_unlock(); |
7186 | return PTR_ERR(rdev); | 7227 | return PTR_ERR(rdev); |
7187 | } | 7228 | } |
7188 | info->user_ptr[0] = rdev; | 7229 | info->user_ptr[0] = rdev; |
7189 | } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV || | 7230 | } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV || |
7190 | ops->internal_flags & NL80211_FLAG_NEED_WDEV) { | 7231 | ops->internal_flags & NL80211_FLAG_NEED_WDEV) { |
7191 | mutex_lock(&cfg80211_mutex); | 7232 | mutex_lock(&cfg80211_mutex); |
7192 | wdev = __cfg80211_wdev_from_attrs(genl_info_net(info), | 7233 | wdev = __cfg80211_wdev_from_attrs(genl_info_net(info), |
7193 | info->attrs); | 7234 | info->attrs); |
7194 | if (IS_ERR(wdev)) { | 7235 | if (IS_ERR(wdev)) { |
7195 | mutex_unlock(&cfg80211_mutex); | 7236 | mutex_unlock(&cfg80211_mutex); |
7196 | if (rtnl) | 7237 | if (rtnl) |
7197 | rtnl_unlock(); | 7238 | rtnl_unlock(); |
7198 | return PTR_ERR(wdev); | 7239 | return PTR_ERR(wdev); |
7199 | } | 7240 | } |
7200 | 7241 | ||
7201 | dev = wdev->netdev; | 7242 | dev = wdev->netdev; |
7202 | rdev = wiphy_to_dev(wdev->wiphy); | 7243 | rdev = wiphy_to_dev(wdev->wiphy); |
7203 | 7244 | ||
7204 | if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { | 7245 | if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { |
7205 | if (!dev) { | 7246 | if (!dev) { |
7206 | mutex_unlock(&cfg80211_mutex); | 7247 | mutex_unlock(&cfg80211_mutex); |
7207 | if (rtnl) | 7248 | if (rtnl) |
7208 | rtnl_unlock(); | 7249 | rtnl_unlock(); |
7209 | return -EINVAL; | 7250 | return -EINVAL; |
7210 | } | 7251 | } |
7211 | 7252 | ||
7212 | info->user_ptr[1] = dev; | 7253 | info->user_ptr[1] = dev; |
7213 | } else { | 7254 | } else { |
7214 | info->user_ptr[1] = wdev; | 7255 | info->user_ptr[1] = wdev; |
7215 | } | 7256 | } |
7216 | 7257 | ||
7217 | if (dev) { | 7258 | if (dev) { |
7218 | if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && | 7259 | if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && |
7219 | !netif_running(dev)) { | 7260 | !netif_running(dev)) { |
7220 | mutex_unlock(&cfg80211_mutex); | 7261 | mutex_unlock(&cfg80211_mutex); |
7221 | if (rtnl) | 7262 | if (rtnl) |
7222 | rtnl_unlock(); | 7263 | rtnl_unlock(); |
7223 | return -ENETDOWN; | 7264 | return -ENETDOWN; |
7224 | } | 7265 | } |
7225 | 7266 | ||
7226 | dev_hold(dev); | 7267 | dev_hold(dev); |
7227 | } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { | 7268 | } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { |
7228 | if (!wdev->p2p_started) { | 7269 | if (!wdev->p2p_started) { |
7229 | mutex_unlock(&cfg80211_mutex); | 7270 | mutex_unlock(&cfg80211_mutex); |
7230 | if (rtnl) | 7271 | if (rtnl) |
7231 | rtnl_unlock(); | 7272 | rtnl_unlock(); |
7232 | return -ENETDOWN; | 7273 | return -ENETDOWN; |
7233 | } | 7274 | } |
7234 | } | 7275 | } |
7235 | 7276 | ||
7236 | cfg80211_lock_rdev(rdev); | 7277 | cfg80211_lock_rdev(rdev); |
7237 | 7278 | ||
7238 | mutex_unlock(&cfg80211_mutex); | 7279 | mutex_unlock(&cfg80211_mutex); |
7239 | 7280 | ||
7240 | info->user_ptr[0] = rdev; | 7281 | info->user_ptr[0] = rdev; |
7241 | } | 7282 | } |
7242 | 7283 | ||
7243 | return 0; | 7284 | return 0; |
7244 | } | 7285 | } |
7245 | 7286 | ||
7246 | static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, | 7287 | static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, |
7247 | struct genl_info *info) | 7288 | struct genl_info *info) |
7248 | { | 7289 | { |
7249 | if (info->user_ptr[0]) | 7290 | if (info->user_ptr[0]) |
7250 | cfg80211_unlock_rdev(info->user_ptr[0]); | 7291 | cfg80211_unlock_rdev(info->user_ptr[0]); |
7251 | if (info->user_ptr[1]) { | 7292 | if (info->user_ptr[1]) { |
7252 | if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) { | 7293 | if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) { |
7253 | struct wireless_dev *wdev = info->user_ptr[1]; | 7294 | struct wireless_dev *wdev = info->user_ptr[1]; |
7254 | 7295 | ||
7255 | if (wdev->netdev) | 7296 | if (wdev->netdev) |
7256 | dev_put(wdev->netdev); | 7297 | dev_put(wdev->netdev); |
7257 | } else { | 7298 | } else { |
7258 | dev_put(info->user_ptr[1]); | 7299 | dev_put(info->user_ptr[1]); |
7259 | } | 7300 | } |
7260 | } | 7301 | } |
7261 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) | 7302 | if (ops->internal_flags & NL80211_FLAG_NEED_RTNL) |
7262 | rtnl_unlock(); | 7303 | rtnl_unlock(); |
7263 | } | 7304 | } |
7264 | 7305 | ||
7265 | static struct genl_ops nl80211_ops[] = { | 7306 | static struct genl_ops nl80211_ops[] = { |
7266 | { | 7307 | { |
7267 | .cmd = NL80211_CMD_GET_WIPHY, | 7308 | .cmd = NL80211_CMD_GET_WIPHY, |
7268 | .doit = nl80211_get_wiphy, | 7309 | .doit = nl80211_get_wiphy, |
7269 | .dumpit = nl80211_dump_wiphy, | 7310 | .dumpit = nl80211_dump_wiphy, |
7270 | .policy = nl80211_policy, | 7311 | .policy = nl80211_policy, |
7271 | /* can be retrieved by unprivileged users */ | 7312 | /* can be retrieved by unprivileged users */ |
7272 | .internal_flags = NL80211_FLAG_NEED_WIPHY, | 7313 | .internal_flags = NL80211_FLAG_NEED_WIPHY, |
7273 | }, | 7314 | }, |
7274 | { | 7315 | { |
7275 | .cmd = NL80211_CMD_SET_WIPHY, | 7316 | .cmd = NL80211_CMD_SET_WIPHY, |
7276 | .doit = nl80211_set_wiphy, | 7317 | .doit = nl80211_set_wiphy, |
7277 | .policy = nl80211_policy, | 7318 | .policy = nl80211_policy, |
7278 | .flags = GENL_ADMIN_PERM, | 7319 | .flags = GENL_ADMIN_PERM, |
7279 | .internal_flags = NL80211_FLAG_NEED_RTNL, | 7320 | .internal_flags = NL80211_FLAG_NEED_RTNL, |
7280 | }, | 7321 | }, |
7281 | { | 7322 | { |
7282 | .cmd = NL80211_CMD_GET_INTERFACE, | 7323 | .cmd = NL80211_CMD_GET_INTERFACE, |
7283 | .doit = nl80211_get_interface, | 7324 | .doit = nl80211_get_interface, |
7284 | .dumpit = nl80211_dump_interface, | 7325 | .dumpit = nl80211_dump_interface, |
7285 | .policy = nl80211_policy, | 7326 | .policy = nl80211_policy, |
7286 | /* can be retrieved by unprivileged users */ | 7327 | /* can be retrieved by unprivileged users */ |
7287 | .internal_flags = NL80211_FLAG_NEED_WDEV, | 7328 | .internal_flags = NL80211_FLAG_NEED_WDEV, |
7288 | }, | 7329 | }, |
7289 | { | 7330 | { |
7290 | .cmd = NL80211_CMD_SET_INTERFACE, | 7331 | .cmd = NL80211_CMD_SET_INTERFACE, |
7291 | .doit = nl80211_set_interface, | 7332 | .doit = nl80211_set_interface, |
7292 | .policy = nl80211_policy, | 7333 | .policy = nl80211_policy, |
7293 | .flags = GENL_ADMIN_PERM, | 7334 | .flags = GENL_ADMIN_PERM, |
7294 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7335 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7295 | NL80211_FLAG_NEED_RTNL, | 7336 | NL80211_FLAG_NEED_RTNL, |
7296 | }, | 7337 | }, |
7297 | { | 7338 | { |
7298 | .cmd = NL80211_CMD_NEW_INTERFACE, | 7339 | .cmd = NL80211_CMD_NEW_INTERFACE, |
7299 | .doit = nl80211_new_interface, | 7340 | .doit = nl80211_new_interface, |
7300 | .policy = nl80211_policy, | 7341 | .policy = nl80211_policy, |
7301 | .flags = GENL_ADMIN_PERM, | 7342 | .flags = GENL_ADMIN_PERM, |
7302 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 7343 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
7303 | NL80211_FLAG_NEED_RTNL, | 7344 | NL80211_FLAG_NEED_RTNL, |
7304 | }, | 7345 | }, |
7305 | { | 7346 | { |
7306 | .cmd = NL80211_CMD_DEL_INTERFACE, | 7347 | .cmd = NL80211_CMD_DEL_INTERFACE, |
7307 | .doit = nl80211_del_interface, | 7348 | .doit = nl80211_del_interface, |
7308 | .policy = nl80211_policy, | 7349 | .policy = nl80211_policy, |
7309 | .flags = GENL_ADMIN_PERM, | 7350 | .flags = GENL_ADMIN_PERM, |
7310 | .internal_flags = NL80211_FLAG_NEED_WDEV | | 7351 | .internal_flags = NL80211_FLAG_NEED_WDEV | |
7311 | NL80211_FLAG_NEED_RTNL, | 7352 | NL80211_FLAG_NEED_RTNL, |
7312 | }, | 7353 | }, |
7313 | { | 7354 | { |
7314 | .cmd = NL80211_CMD_GET_KEY, | 7355 | .cmd = NL80211_CMD_GET_KEY, |
7315 | .doit = nl80211_get_key, | 7356 | .doit = nl80211_get_key, |
7316 | .policy = nl80211_policy, | 7357 | .policy = nl80211_policy, |
7317 | .flags = GENL_ADMIN_PERM, | 7358 | .flags = GENL_ADMIN_PERM, |
7318 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7359 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7319 | NL80211_FLAG_NEED_RTNL, | 7360 | NL80211_FLAG_NEED_RTNL, |
7320 | }, | 7361 | }, |
7321 | { | 7362 | { |
7322 | .cmd = NL80211_CMD_SET_KEY, | 7363 | .cmd = NL80211_CMD_SET_KEY, |
7323 | .doit = nl80211_set_key, | 7364 | .doit = nl80211_set_key, |
7324 | .policy = nl80211_policy, | 7365 | .policy = nl80211_policy, |
7325 | .flags = GENL_ADMIN_PERM, | 7366 | .flags = GENL_ADMIN_PERM, |
7326 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7367 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7327 | NL80211_FLAG_NEED_RTNL, | 7368 | NL80211_FLAG_NEED_RTNL, |
7328 | }, | 7369 | }, |
7329 | { | 7370 | { |
7330 | .cmd = NL80211_CMD_NEW_KEY, | 7371 | .cmd = NL80211_CMD_NEW_KEY, |
7331 | .doit = nl80211_new_key, | 7372 | .doit = nl80211_new_key, |
7332 | .policy = nl80211_policy, | 7373 | .policy = nl80211_policy, |
7333 | .flags = GENL_ADMIN_PERM, | 7374 | .flags = GENL_ADMIN_PERM, |
7334 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7375 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7335 | NL80211_FLAG_NEED_RTNL, | 7376 | NL80211_FLAG_NEED_RTNL, |
7336 | }, | 7377 | }, |
7337 | { | 7378 | { |
7338 | .cmd = NL80211_CMD_DEL_KEY, | 7379 | .cmd = NL80211_CMD_DEL_KEY, |
7339 | .doit = nl80211_del_key, | 7380 | .doit = nl80211_del_key, |
7340 | .policy = nl80211_policy, | 7381 | .policy = nl80211_policy, |
7341 | .flags = GENL_ADMIN_PERM, | 7382 | .flags = GENL_ADMIN_PERM, |
7342 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7383 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7343 | NL80211_FLAG_NEED_RTNL, | 7384 | NL80211_FLAG_NEED_RTNL, |
7344 | }, | 7385 | }, |
7345 | { | 7386 | { |
7346 | .cmd = NL80211_CMD_SET_BEACON, | 7387 | .cmd = NL80211_CMD_SET_BEACON, |
7347 | .policy = nl80211_policy, | 7388 | .policy = nl80211_policy, |
7348 | .flags = GENL_ADMIN_PERM, | 7389 | .flags = GENL_ADMIN_PERM, |
7349 | .doit = nl80211_set_beacon, | 7390 | .doit = nl80211_set_beacon, |
7350 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7391 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7351 | NL80211_FLAG_NEED_RTNL, | 7392 | NL80211_FLAG_NEED_RTNL, |
7352 | }, | 7393 | }, |
7353 | { | 7394 | { |
7354 | .cmd = NL80211_CMD_START_AP, | 7395 | .cmd = NL80211_CMD_START_AP, |
7355 | .policy = nl80211_policy, | 7396 | .policy = nl80211_policy, |
7356 | .flags = GENL_ADMIN_PERM, | 7397 | .flags = GENL_ADMIN_PERM, |
7357 | .doit = nl80211_start_ap, | 7398 | .doit = nl80211_start_ap, |
7358 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7399 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7359 | NL80211_FLAG_NEED_RTNL, | 7400 | NL80211_FLAG_NEED_RTNL, |
7360 | }, | 7401 | }, |
7361 | { | 7402 | { |
7362 | .cmd = NL80211_CMD_STOP_AP, | 7403 | .cmd = NL80211_CMD_STOP_AP, |
7363 | .policy = nl80211_policy, | 7404 | .policy = nl80211_policy, |
7364 | .flags = GENL_ADMIN_PERM, | 7405 | .flags = GENL_ADMIN_PERM, |
7365 | .doit = nl80211_stop_ap, | 7406 | .doit = nl80211_stop_ap, |
7366 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7407 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7367 | NL80211_FLAG_NEED_RTNL, | 7408 | NL80211_FLAG_NEED_RTNL, |
7368 | }, | 7409 | }, |
7369 | { | 7410 | { |
7370 | .cmd = NL80211_CMD_GET_STATION, | 7411 | .cmd = NL80211_CMD_GET_STATION, |
7371 | .doit = nl80211_get_station, | 7412 | .doit = nl80211_get_station, |
7372 | .dumpit = nl80211_dump_station, | 7413 | .dumpit = nl80211_dump_station, |
7373 | .policy = nl80211_policy, | 7414 | .policy = nl80211_policy, |
7374 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7415 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7375 | NL80211_FLAG_NEED_RTNL, | 7416 | NL80211_FLAG_NEED_RTNL, |
7376 | }, | 7417 | }, |
7377 | { | 7418 | { |
7378 | .cmd = NL80211_CMD_SET_STATION, | 7419 | .cmd = NL80211_CMD_SET_STATION, |
7379 | .doit = nl80211_set_station, | 7420 | .doit = nl80211_set_station, |
7380 | .policy = nl80211_policy, | 7421 | .policy = nl80211_policy, |
7381 | .flags = GENL_ADMIN_PERM, | 7422 | .flags = GENL_ADMIN_PERM, |
7382 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7423 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7383 | NL80211_FLAG_NEED_RTNL, | 7424 | NL80211_FLAG_NEED_RTNL, |
7384 | }, | 7425 | }, |
7385 | { | 7426 | { |
7386 | .cmd = NL80211_CMD_NEW_STATION, | 7427 | .cmd = NL80211_CMD_NEW_STATION, |
7387 | .doit = nl80211_new_station, | 7428 | .doit = nl80211_new_station, |
7388 | .policy = nl80211_policy, | 7429 | .policy = nl80211_policy, |
7389 | .flags = GENL_ADMIN_PERM, | 7430 | .flags = GENL_ADMIN_PERM, |
7390 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7431 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7391 | NL80211_FLAG_NEED_RTNL, | 7432 | NL80211_FLAG_NEED_RTNL, |
7392 | }, | 7433 | }, |
7393 | { | 7434 | { |
7394 | .cmd = NL80211_CMD_DEL_STATION, | 7435 | .cmd = NL80211_CMD_DEL_STATION, |
7395 | .doit = nl80211_del_station, | 7436 | .doit = nl80211_del_station, |
7396 | .policy = nl80211_policy, | 7437 | .policy = nl80211_policy, |
7397 | .flags = GENL_ADMIN_PERM, | 7438 | .flags = GENL_ADMIN_PERM, |
7398 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7439 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7399 | NL80211_FLAG_NEED_RTNL, | 7440 | NL80211_FLAG_NEED_RTNL, |
7400 | }, | 7441 | }, |
7401 | { | 7442 | { |
7402 | .cmd = NL80211_CMD_GET_MPATH, | 7443 | .cmd = NL80211_CMD_GET_MPATH, |
7403 | .doit = nl80211_get_mpath, | 7444 | .doit = nl80211_get_mpath, |
7404 | .dumpit = nl80211_dump_mpath, | 7445 | .dumpit = nl80211_dump_mpath, |
7405 | .policy = nl80211_policy, | 7446 | .policy = nl80211_policy, |
7406 | .flags = GENL_ADMIN_PERM, | 7447 | .flags = GENL_ADMIN_PERM, |
7407 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7448 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7408 | NL80211_FLAG_NEED_RTNL, | 7449 | NL80211_FLAG_NEED_RTNL, |
7409 | }, | 7450 | }, |
7410 | { | 7451 | { |
7411 | .cmd = NL80211_CMD_SET_MPATH, | 7452 | .cmd = NL80211_CMD_SET_MPATH, |
7412 | .doit = nl80211_set_mpath, | 7453 | .doit = nl80211_set_mpath, |
7413 | .policy = nl80211_policy, | 7454 | .policy = nl80211_policy, |
7414 | .flags = GENL_ADMIN_PERM, | 7455 | .flags = GENL_ADMIN_PERM, |
7415 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7456 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7416 | NL80211_FLAG_NEED_RTNL, | 7457 | NL80211_FLAG_NEED_RTNL, |
7417 | }, | 7458 | }, |
7418 | { | 7459 | { |
7419 | .cmd = NL80211_CMD_NEW_MPATH, | 7460 | .cmd = NL80211_CMD_NEW_MPATH, |
7420 | .doit = nl80211_new_mpath, | 7461 | .doit = nl80211_new_mpath, |
7421 | .policy = nl80211_policy, | 7462 | .policy = nl80211_policy, |
7422 | .flags = GENL_ADMIN_PERM, | 7463 | .flags = GENL_ADMIN_PERM, |
7423 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7464 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7424 | NL80211_FLAG_NEED_RTNL, | 7465 | NL80211_FLAG_NEED_RTNL, |
7425 | }, | 7466 | }, |
7426 | { | 7467 | { |
7427 | .cmd = NL80211_CMD_DEL_MPATH, | 7468 | .cmd = NL80211_CMD_DEL_MPATH, |
7428 | .doit = nl80211_del_mpath, | 7469 | .doit = nl80211_del_mpath, |
7429 | .policy = nl80211_policy, | 7470 | .policy = nl80211_policy, |
7430 | .flags = GENL_ADMIN_PERM, | 7471 | .flags = GENL_ADMIN_PERM, |
7431 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7472 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7432 | NL80211_FLAG_NEED_RTNL, | 7473 | NL80211_FLAG_NEED_RTNL, |
7433 | }, | 7474 | }, |
7434 | { | 7475 | { |
7435 | .cmd = NL80211_CMD_SET_BSS, | 7476 | .cmd = NL80211_CMD_SET_BSS, |
7436 | .doit = nl80211_set_bss, | 7477 | .doit = nl80211_set_bss, |
7437 | .policy = nl80211_policy, | 7478 | .policy = nl80211_policy, |
7438 | .flags = GENL_ADMIN_PERM, | 7479 | .flags = GENL_ADMIN_PERM, |
7439 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7480 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7440 | NL80211_FLAG_NEED_RTNL, | 7481 | NL80211_FLAG_NEED_RTNL, |
7441 | }, | 7482 | }, |
7442 | { | 7483 | { |
7443 | .cmd = NL80211_CMD_GET_REG, | 7484 | .cmd = NL80211_CMD_GET_REG, |
7444 | .doit = nl80211_get_reg, | 7485 | .doit = nl80211_get_reg, |
7445 | .policy = nl80211_policy, | 7486 | .policy = nl80211_policy, |
7446 | /* can be retrieved by unprivileged users */ | 7487 | /* can be retrieved by unprivileged users */ |
7447 | }, | 7488 | }, |
7448 | { | 7489 | { |
7449 | .cmd = NL80211_CMD_SET_REG, | 7490 | .cmd = NL80211_CMD_SET_REG, |
7450 | .doit = nl80211_set_reg, | 7491 | .doit = nl80211_set_reg, |
7451 | .policy = nl80211_policy, | 7492 | .policy = nl80211_policy, |
7452 | .flags = GENL_ADMIN_PERM, | 7493 | .flags = GENL_ADMIN_PERM, |
7453 | }, | 7494 | }, |
7454 | { | 7495 | { |
7455 | .cmd = NL80211_CMD_REQ_SET_REG, | 7496 | .cmd = NL80211_CMD_REQ_SET_REG, |
7456 | .doit = nl80211_req_set_reg, | 7497 | .doit = nl80211_req_set_reg, |
7457 | .policy = nl80211_policy, | 7498 | .policy = nl80211_policy, |
7458 | .flags = GENL_ADMIN_PERM, | 7499 | .flags = GENL_ADMIN_PERM, |
7459 | }, | 7500 | }, |
7460 | { | 7501 | { |
7461 | .cmd = NL80211_CMD_GET_MESH_CONFIG, | 7502 | .cmd = NL80211_CMD_GET_MESH_CONFIG, |
7462 | .doit = nl80211_get_mesh_config, | 7503 | .doit = nl80211_get_mesh_config, |
7463 | .policy = nl80211_policy, | 7504 | .policy = nl80211_policy, |
7464 | /* can be retrieved by unprivileged users */ | 7505 | /* can be retrieved by unprivileged users */ |
7465 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7506 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7466 | NL80211_FLAG_NEED_RTNL, | 7507 | NL80211_FLAG_NEED_RTNL, |
7467 | }, | 7508 | }, |
7468 | { | 7509 | { |
7469 | .cmd = NL80211_CMD_SET_MESH_CONFIG, | 7510 | .cmd = NL80211_CMD_SET_MESH_CONFIG, |
7470 | .doit = nl80211_update_mesh_config, | 7511 | .doit = nl80211_update_mesh_config, |
7471 | .policy = nl80211_policy, | 7512 | .policy = nl80211_policy, |
7472 | .flags = GENL_ADMIN_PERM, | 7513 | .flags = GENL_ADMIN_PERM, |
7473 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7514 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7474 | NL80211_FLAG_NEED_RTNL, | 7515 | NL80211_FLAG_NEED_RTNL, |
7475 | }, | 7516 | }, |
7476 | { | 7517 | { |
7477 | .cmd = NL80211_CMD_TRIGGER_SCAN, | 7518 | .cmd = NL80211_CMD_TRIGGER_SCAN, |
7478 | .doit = nl80211_trigger_scan, | 7519 | .doit = nl80211_trigger_scan, |
7479 | .policy = nl80211_policy, | 7520 | .policy = nl80211_policy, |
7480 | .flags = GENL_ADMIN_PERM, | 7521 | .flags = GENL_ADMIN_PERM, |
7481 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | 7522 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7482 | NL80211_FLAG_NEED_RTNL, | 7523 | NL80211_FLAG_NEED_RTNL, |
7483 | }, | 7524 | }, |
7484 | { | 7525 | { |
7485 | .cmd = NL80211_CMD_GET_SCAN, | 7526 | .cmd = NL80211_CMD_GET_SCAN, |
7486 | .policy = nl80211_policy, | 7527 | .policy = nl80211_policy, |
7487 | .dumpit = nl80211_dump_scan, | 7528 | .dumpit = nl80211_dump_scan, |
7488 | }, | 7529 | }, |
7489 | { | 7530 | { |
7490 | .cmd = NL80211_CMD_START_SCHED_SCAN, | 7531 | .cmd = NL80211_CMD_START_SCHED_SCAN, |
7491 | .doit = nl80211_start_sched_scan, | 7532 | .doit = nl80211_start_sched_scan, |
7492 | .policy = nl80211_policy, | 7533 | .policy = nl80211_policy, |
7493 | .flags = GENL_ADMIN_PERM, | 7534 | .flags = GENL_ADMIN_PERM, |
7494 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7535 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7495 | NL80211_FLAG_NEED_RTNL, | 7536 | NL80211_FLAG_NEED_RTNL, |
7496 | }, | 7537 | }, |
7497 | { | 7538 | { |
7498 | .cmd = NL80211_CMD_STOP_SCHED_SCAN, | 7539 | .cmd = NL80211_CMD_STOP_SCHED_SCAN, |
7499 | .doit = nl80211_stop_sched_scan, | 7540 | .doit = nl80211_stop_sched_scan, |
7500 | .policy = nl80211_policy, | 7541 | .policy = nl80211_policy, |
7501 | .flags = GENL_ADMIN_PERM, | 7542 | .flags = GENL_ADMIN_PERM, |
7502 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7543 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7503 | NL80211_FLAG_NEED_RTNL, | 7544 | NL80211_FLAG_NEED_RTNL, |
7504 | }, | 7545 | }, |
7505 | { | 7546 | { |
7506 | .cmd = NL80211_CMD_AUTHENTICATE, | 7547 | .cmd = NL80211_CMD_AUTHENTICATE, |
7507 | .doit = nl80211_authenticate, | 7548 | .doit = nl80211_authenticate, |
7508 | .policy = nl80211_policy, | 7549 | .policy = nl80211_policy, |
7509 | .flags = GENL_ADMIN_PERM, | 7550 | .flags = GENL_ADMIN_PERM, |
7510 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7551 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7511 | NL80211_FLAG_NEED_RTNL, | 7552 | NL80211_FLAG_NEED_RTNL, |
7512 | }, | 7553 | }, |
7513 | { | 7554 | { |
7514 | .cmd = NL80211_CMD_ASSOCIATE, | 7555 | .cmd = NL80211_CMD_ASSOCIATE, |
7515 | .doit = nl80211_associate, | 7556 | .doit = nl80211_associate, |
7516 | .policy = nl80211_policy, | 7557 | .policy = nl80211_policy, |
7517 | .flags = GENL_ADMIN_PERM, | 7558 | .flags = GENL_ADMIN_PERM, |
7518 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7559 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7519 | NL80211_FLAG_NEED_RTNL, | 7560 | NL80211_FLAG_NEED_RTNL, |
7520 | }, | 7561 | }, |
7521 | { | 7562 | { |
7522 | .cmd = NL80211_CMD_DEAUTHENTICATE, | 7563 | .cmd = NL80211_CMD_DEAUTHENTICATE, |
7523 | .doit = nl80211_deauthenticate, | 7564 | .doit = nl80211_deauthenticate, |
7524 | .policy = nl80211_policy, | 7565 | .policy = nl80211_policy, |
7525 | .flags = GENL_ADMIN_PERM, | 7566 | .flags = GENL_ADMIN_PERM, |
7526 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7567 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7527 | NL80211_FLAG_NEED_RTNL, | 7568 | NL80211_FLAG_NEED_RTNL, |
7528 | }, | 7569 | }, |
7529 | { | 7570 | { |
7530 | .cmd = NL80211_CMD_DISASSOCIATE, | 7571 | .cmd = NL80211_CMD_DISASSOCIATE, |
7531 | .doit = nl80211_disassociate, | 7572 | .doit = nl80211_disassociate, |
7532 | .policy = nl80211_policy, | 7573 | .policy = nl80211_policy, |
7533 | .flags = GENL_ADMIN_PERM, | 7574 | .flags = GENL_ADMIN_PERM, |
7534 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7575 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7535 | NL80211_FLAG_NEED_RTNL, | 7576 | NL80211_FLAG_NEED_RTNL, |
7536 | }, | 7577 | }, |
7537 | { | 7578 | { |
7538 | .cmd = NL80211_CMD_JOIN_IBSS, | 7579 | .cmd = NL80211_CMD_JOIN_IBSS, |
7539 | .doit = nl80211_join_ibss, | 7580 | .doit = nl80211_join_ibss, |
7540 | .policy = nl80211_policy, | 7581 | .policy = nl80211_policy, |
7541 | .flags = GENL_ADMIN_PERM, | 7582 | .flags = GENL_ADMIN_PERM, |
7542 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7583 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7543 | NL80211_FLAG_NEED_RTNL, | 7584 | NL80211_FLAG_NEED_RTNL, |
7544 | }, | 7585 | }, |
7545 | { | 7586 | { |
7546 | .cmd = NL80211_CMD_LEAVE_IBSS, | 7587 | .cmd = NL80211_CMD_LEAVE_IBSS, |
7547 | .doit = nl80211_leave_ibss, | 7588 | .doit = nl80211_leave_ibss, |
7548 | .policy = nl80211_policy, | 7589 | .policy = nl80211_policy, |
7549 | .flags = GENL_ADMIN_PERM, | 7590 | .flags = GENL_ADMIN_PERM, |
7550 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7591 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7551 | NL80211_FLAG_NEED_RTNL, | 7592 | NL80211_FLAG_NEED_RTNL, |
7552 | }, | 7593 | }, |
7553 | #ifdef CONFIG_NL80211_TESTMODE | 7594 | #ifdef CONFIG_NL80211_TESTMODE |
7554 | { | 7595 | { |
7555 | .cmd = NL80211_CMD_TESTMODE, | 7596 | .cmd = NL80211_CMD_TESTMODE, |
7556 | .doit = nl80211_testmode_do, | 7597 | .doit = nl80211_testmode_do, |
7557 | .dumpit = nl80211_testmode_dump, | 7598 | .dumpit = nl80211_testmode_dump, |
7558 | .policy = nl80211_policy, | 7599 | .policy = nl80211_policy, |
7559 | .flags = GENL_ADMIN_PERM, | 7600 | .flags = GENL_ADMIN_PERM, |
7560 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 7601 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
7561 | NL80211_FLAG_NEED_RTNL, | 7602 | NL80211_FLAG_NEED_RTNL, |
7562 | }, | 7603 | }, |
7563 | #endif | 7604 | #endif |
7564 | { | 7605 | { |
7565 | .cmd = NL80211_CMD_CONNECT, | 7606 | .cmd = NL80211_CMD_CONNECT, |
7566 | .doit = nl80211_connect, | 7607 | .doit = nl80211_connect, |
7567 | .policy = nl80211_policy, | 7608 | .policy = nl80211_policy, |
7568 | .flags = GENL_ADMIN_PERM, | 7609 | .flags = GENL_ADMIN_PERM, |
7569 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7610 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7570 | NL80211_FLAG_NEED_RTNL, | 7611 | NL80211_FLAG_NEED_RTNL, |
7571 | }, | 7612 | }, |
7572 | { | 7613 | { |
7573 | .cmd = NL80211_CMD_DISCONNECT, | 7614 | .cmd = NL80211_CMD_DISCONNECT, |
7574 | .doit = nl80211_disconnect, | 7615 | .doit = nl80211_disconnect, |
7575 | .policy = nl80211_policy, | 7616 | .policy = nl80211_policy, |
7576 | .flags = GENL_ADMIN_PERM, | 7617 | .flags = GENL_ADMIN_PERM, |
7577 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7618 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7578 | NL80211_FLAG_NEED_RTNL, | 7619 | NL80211_FLAG_NEED_RTNL, |
7579 | }, | 7620 | }, |
7580 | { | 7621 | { |
7581 | .cmd = NL80211_CMD_SET_WIPHY_NETNS, | 7622 | .cmd = NL80211_CMD_SET_WIPHY_NETNS, |
7582 | .doit = nl80211_wiphy_netns, | 7623 | .doit = nl80211_wiphy_netns, |
7583 | .policy = nl80211_policy, | 7624 | .policy = nl80211_policy, |
7584 | .flags = GENL_ADMIN_PERM, | 7625 | .flags = GENL_ADMIN_PERM, |
7585 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 7626 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
7586 | NL80211_FLAG_NEED_RTNL, | 7627 | NL80211_FLAG_NEED_RTNL, |
7587 | }, | 7628 | }, |
7588 | { | 7629 | { |
7589 | .cmd = NL80211_CMD_GET_SURVEY, | 7630 | .cmd = NL80211_CMD_GET_SURVEY, |
7590 | .policy = nl80211_policy, | 7631 | .policy = nl80211_policy, |
7591 | .dumpit = nl80211_dump_survey, | 7632 | .dumpit = nl80211_dump_survey, |
7592 | }, | 7633 | }, |
7593 | { | 7634 | { |
7594 | .cmd = NL80211_CMD_SET_PMKSA, | 7635 | .cmd = NL80211_CMD_SET_PMKSA, |
7595 | .doit = nl80211_setdel_pmksa, | 7636 | .doit = nl80211_setdel_pmksa, |
7596 | .policy = nl80211_policy, | 7637 | .policy = nl80211_policy, |
7597 | .flags = GENL_ADMIN_PERM, | 7638 | .flags = GENL_ADMIN_PERM, |
7598 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7639 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7599 | NL80211_FLAG_NEED_RTNL, | 7640 | NL80211_FLAG_NEED_RTNL, |
7600 | }, | 7641 | }, |
7601 | { | 7642 | { |
7602 | .cmd = NL80211_CMD_DEL_PMKSA, | 7643 | .cmd = NL80211_CMD_DEL_PMKSA, |
7603 | .doit = nl80211_setdel_pmksa, | 7644 | .doit = nl80211_setdel_pmksa, |
7604 | .policy = nl80211_policy, | 7645 | .policy = nl80211_policy, |
7605 | .flags = GENL_ADMIN_PERM, | 7646 | .flags = GENL_ADMIN_PERM, |
7606 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7647 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7607 | NL80211_FLAG_NEED_RTNL, | 7648 | NL80211_FLAG_NEED_RTNL, |
7608 | }, | 7649 | }, |
7609 | { | 7650 | { |
7610 | .cmd = NL80211_CMD_FLUSH_PMKSA, | 7651 | .cmd = NL80211_CMD_FLUSH_PMKSA, |
7611 | .doit = nl80211_flush_pmksa, | 7652 | .doit = nl80211_flush_pmksa, |
7612 | .policy = nl80211_policy, | 7653 | .policy = nl80211_policy, |
7613 | .flags = GENL_ADMIN_PERM, | 7654 | .flags = GENL_ADMIN_PERM, |
7614 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7655 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7615 | NL80211_FLAG_NEED_RTNL, | 7656 | NL80211_FLAG_NEED_RTNL, |
7616 | }, | 7657 | }, |
7617 | { | 7658 | { |
7618 | .cmd = NL80211_CMD_REMAIN_ON_CHANNEL, | 7659 | .cmd = NL80211_CMD_REMAIN_ON_CHANNEL, |
7619 | .doit = nl80211_remain_on_channel, | 7660 | .doit = nl80211_remain_on_channel, |
7620 | .policy = nl80211_policy, | 7661 | .policy = nl80211_policy, |
7621 | .flags = GENL_ADMIN_PERM, | 7662 | .flags = GENL_ADMIN_PERM, |
7622 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | 7663 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7623 | NL80211_FLAG_NEED_RTNL, | 7664 | NL80211_FLAG_NEED_RTNL, |
7624 | }, | 7665 | }, |
7625 | { | 7666 | { |
7626 | .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, | 7667 | .cmd = NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, |
7627 | .doit = nl80211_cancel_remain_on_channel, | 7668 | .doit = nl80211_cancel_remain_on_channel, |
7628 | .policy = nl80211_policy, | 7669 | .policy = nl80211_policy, |
7629 | .flags = GENL_ADMIN_PERM, | 7670 | .flags = GENL_ADMIN_PERM, |
7630 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | 7671 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7631 | NL80211_FLAG_NEED_RTNL, | 7672 | NL80211_FLAG_NEED_RTNL, |
7632 | }, | 7673 | }, |
7633 | { | 7674 | { |
7634 | .cmd = NL80211_CMD_SET_TX_BITRATE_MASK, | 7675 | .cmd = NL80211_CMD_SET_TX_BITRATE_MASK, |
7635 | .doit = nl80211_set_tx_bitrate_mask, | 7676 | .doit = nl80211_set_tx_bitrate_mask, |
7636 | .policy = nl80211_policy, | 7677 | .policy = nl80211_policy, |
7637 | .flags = GENL_ADMIN_PERM, | 7678 | .flags = GENL_ADMIN_PERM, |
7638 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7679 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7639 | NL80211_FLAG_NEED_RTNL, | 7680 | NL80211_FLAG_NEED_RTNL, |
7640 | }, | 7681 | }, |
7641 | { | 7682 | { |
7642 | .cmd = NL80211_CMD_REGISTER_FRAME, | 7683 | .cmd = NL80211_CMD_REGISTER_FRAME, |
7643 | .doit = nl80211_register_mgmt, | 7684 | .doit = nl80211_register_mgmt, |
7644 | .policy = nl80211_policy, | 7685 | .policy = nl80211_policy, |
7645 | .flags = GENL_ADMIN_PERM, | 7686 | .flags = GENL_ADMIN_PERM, |
7646 | .internal_flags = NL80211_FLAG_NEED_WDEV | | 7687 | .internal_flags = NL80211_FLAG_NEED_WDEV | |
7647 | NL80211_FLAG_NEED_RTNL, | 7688 | NL80211_FLAG_NEED_RTNL, |
7648 | }, | 7689 | }, |
7649 | { | 7690 | { |
7650 | .cmd = NL80211_CMD_FRAME, | 7691 | .cmd = NL80211_CMD_FRAME, |
7651 | .doit = nl80211_tx_mgmt, | 7692 | .doit = nl80211_tx_mgmt, |
7652 | .policy = nl80211_policy, | 7693 | .policy = nl80211_policy, |
7653 | .flags = GENL_ADMIN_PERM, | 7694 | .flags = GENL_ADMIN_PERM, |
7654 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | 7695 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7655 | NL80211_FLAG_NEED_RTNL, | 7696 | NL80211_FLAG_NEED_RTNL, |
7656 | }, | 7697 | }, |
7657 | { | 7698 | { |
7658 | .cmd = NL80211_CMD_FRAME_WAIT_CANCEL, | 7699 | .cmd = NL80211_CMD_FRAME_WAIT_CANCEL, |
7659 | .doit = nl80211_tx_mgmt_cancel_wait, | 7700 | .doit = nl80211_tx_mgmt_cancel_wait, |
7660 | .policy = nl80211_policy, | 7701 | .policy = nl80211_policy, |
7661 | .flags = GENL_ADMIN_PERM, | 7702 | .flags = GENL_ADMIN_PERM, |
7662 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | 7703 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7663 | NL80211_FLAG_NEED_RTNL, | 7704 | NL80211_FLAG_NEED_RTNL, |
7664 | }, | 7705 | }, |
7665 | { | 7706 | { |
7666 | .cmd = NL80211_CMD_SET_POWER_SAVE, | 7707 | .cmd = NL80211_CMD_SET_POWER_SAVE, |
7667 | .doit = nl80211_set_power_save, | 7708 | .doit = nl80211_set_power_save, |
7668 | .policy = nl80211_policy, | 7709 | .policy = nl80211_policy, |
7669 | .flags = GENL_ADMIN_PERM, | 7710 | .flags = GENL_ADMIN_PERM, |
7670 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7711 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7671 | NL80211_FLAG_NEED_RTNL, | 7712 | NL80211_FLAG_NEED_RTNL, |
7672 | }, | 7713 | }, |
7673 | { | 7714 | { |
7674 | .cmd = NL80211_CMD_GET_POWER_SAVE, | 7715 | .cmd = NL80211_CMD_GET_POWER_SAVE, |
7675 | .doit = nl80211_get_power_save, | 7716 | .doit = nl80211_get_power_save, |
7676 | .policy = nl80211_policy, | 7717 | .policy = nl80211_policy, |
7677 | /* can be retrieved by unprivileged users */ | 7718 | /* can be retrieved by unprivileged users */ |
7678 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7719 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7679 | NL80211_FLAG_NEED_RTNL, | 7720 | NL80211_FLAG_NEED_RTNL, |
7680 | }, | 7721 | }, |
7681 | { | 7722 | { |
7682 | .cmd = NL80211_CMD_SET_CQM, | 7723 | .cmd = NL80211_CMD_SET_CQM, |
7683 | .doit = nl80211_set_cqm, | 7724 | .doit = nl80211_set_cqm, |
7684 | .policy = nl80211_policy, | 7725 | .policy = nl80211_policy, |
7685 | .flags = GENL_ADMIN_PERM, | 7726 | .flags = GENL_ADMIN_PERM, |
7686 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7727 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7687 | NL80211_FLAG_NEED_RTNL, | 7728 | NL80211_FLAG_NEED_RTNL, |
7688 | }, | 7729 | }, |
7689 | { | 7730 | { |
7690 | .cmd = NL80211_CMD_SET_CHANNEL, | 7731 | .cmd = NL80211_CMD_SET_CHANNEL, |
7691 | .doit = nl80211_set_channel, | 7732 | .doit = nl80211_set_channel, |
7692 | .policy = nl80211_policy, | 7733 | .policy = nl80211_policy, |
7693 | .flags = GENL_ADMIN_PERM, | 7734 | .flags = GENL_ADMIN_PERM, |
7694 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7735 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7695 | NL80211_FLAG_NEED_RTNL, | 7736 | NL80211_FLAG_NEED_RTNL, |
7696 | }, | 7737 | }, |
7697 | { | 7738 | { |
7698 | .cmd = NL80211_CMD_SET_WDS_PEER, | 7739 | .cmd = NL80211_CMD_SET_WDS_PEER, |
7699 | .doit = nl80211_set_wds_peer, | 7740 | .doit = nl80211_set_wds_peer, |
7700 | .policy = nl80211_policy, | 7741 | .policy = nl80211_policy, |
7701 | .flags = GENL_ADMIN_PERM, | 7742 | .flags = GENL_ADMIN_PERM, |
7702 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7743 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7703 | NL80211_FLAG_NEED_RTNL, | 7744 | NL80211_FLAG_NEED_RTNL, |
7704 | }, | 7745 | }, |
7705 | { | 7746 | { |
7706 | .cmd = NL80211_CMD_JOIN_MESH, | 7747 | .cmd = NL80211_CMD_JOIN_MESH, |
7707 | .doit = nl80211_join_mesh, | 7748 | .doit = nl80211_join_mesh, |
7708 | .policy = nl80211_policy, | 7749 | .policy = nl80211_policy, |
7709 | .flags = GENL_ADMIN_PERM, | 7750 | .flags = GENL_ADMIN_PERM, |
7710 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7751 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7711 | NL80211_FLAG_NEED_RTNL, | 7752 | NL80211_FLAG_NEED_RTNL, |
7712 | }, | 7753 | }, |
7713 | { | 7754 | { |
7714 | .cmd = NL80211_CMD_LEAVE_MESH, | 7755 | .cmd = NL80211_CMD_LEAVE_MESH, |
7715 | .doit = nl80211_leave_mesh, | 7756 | .doit = nl80211_leave_mesh, |
7716 | .policy = nl80211_policy, | 7757 | .policy = nl80211_policy, |
7717 | .flags = GENL_ADMIN_PERM, | 7758 | .flags = GENL_ADMIN_PERM, |
7718 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7759 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7719 | NL80211_FLAG_NEED_RTNL, | 7760 | NL80211_FLAG_NEED_RTNL, |
7720 | }, | 7761 | }, |
7721 | #ifdef CONFIG_PM | 7762 | #ifdef CONFIG_PM |
7722 | { | 7763 | { |
7723 | .cmd = NL80211_CMD_GET_WOWLAN, | 7764 | .cmd = NL80211_CMD_GET_WOWLAN, |
7724 | .doit = nl80211_get_wowlan, | 7765 | .doit = nl80211_get_wowlan, |
7725 | .policy = nl80211_policy, | 7766 | .policy = nl80211_policy, |
7726 | /* can be retrieved by unprivileged users */ | 7767 | /* can be retrieved by unprivileged users */ |
7727 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 7768 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
7728 | NL80211_FLAG_NEED_RTNL, | 7769 | NL80211_FLAG_NEED_RTNL, |
7729 | }, | 7770 | }, |
7730 | { | 7771 | { |
7731 | .cmd = NL80211_CMD_SET_WOWLAN, | 7772 | .cmd = NL80211_CMD_SET_WOWLAN, |
7732 | .doit = nl80211_set_wowlan, | 7773 | .doit = nl80211_set_wowlan, |
7733 | .policy = nl80211_policy, | 7774 | .policy = nl80211_policy, |
7734 | .flags = GENL_ADMIN_PERM, | 7775 | .flags = GENL_ADMIN_PERM, |
7735 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 7776 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
7736 | NL80211_FLAG_NEED_RTNL, | 7777 | NL80211_FLAG_NEED_RTNL, |
7737 | }, | 7778 | }, |
7738 | #endif | 7779 | #endif |
7739 | { | 7780 | { |
7740 | .cmd = NL80211_CMD_SET_REKEY_OFFLOAD, | 7781 | .cmd = NL80211_CMD_SET_REKEY_OFFLOAD, |
7741 | .doit = nl80211_set_rekey_data, | 7782 | .doit = nl80211_set_rekey_data, |
7742 | .policy = nl80211_policy, | 7783 | .policy = nl80211_policy, |
7743 | .flags = GENL_ADMIN_PERM, | 7784 | .flags = GENL_ADMIN_PERM, |
7744 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7785 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7745 | NL80211_FLAG_NEED_RTNL, | 7786 | NL80211_FLAG_NEED_RTNL, |
7746 | }, | 7787 | }, |
7747 | { | 7788 | { |
7748 | .cmd = NL80211_CMD_TDLS_MGMT, | 7789 | .cmd = NL80211_CMD_TDLS_MGMT, |
7749 | .doit = nl80211_tdls_mgmt, | 7790 | .doit = nl80211_tdls_mgmt, |
7750 | .policy = nl80211_policy, | 7791 | .policy = nl80211_policy, |
7751 | .flags = GENL_ADMIN_PERM, | 7792 | .flags = GENL_ADMIN_PERM, |
7752 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7793 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7753 | NL80211_FLAG_NEED_RTNL, | 7794 | NL80211_FLAG_NEED_RTNL, |
7754 | }, | 7795 | }, |
7755 | { | 7796 | { |
7756 | .cmd = NL80211_CMD_TDLS_OPER, | 7797 | .cmd = NL80211_CMD_TDLS_OPER, |
7757 | .doit = nl80211_tdls_oper, | 7798 | .doit = nl80211_tdls_oper, |
7758 | .policy = nl80211_policy, | 7799 | .policy = nl80211_policy, |
7759 | .flags = GENL_ADMIN_PERM, | 7800 | .flags = GENL_ADMIN_PERM, |
7760 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7801 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7761 | NL80211_FLAG_NEED_RTNL, | 7802 | NL80211_FLAG_NEED_RTNL, |
7762 | }, | 7803 | }, |
7763 | { | 7804 | { |
7764 | .cmd = NL80211_CMD_UNEXPECTED_FRAME, | 7805 | .cmd = NL80211_CMD_UNEXPECTED_FRAME, |
7765 | .doit = nl80211_register_unexpected_frame, | 7806 | .doit = nl80211_register_unexpected_frame, |
7766 | .policy = nl80211_policy, | 7807 | .policy = nl80211_policy, |
7767 | .flags = GENL_ADMIN_PERM, | 7808 | .flags = GENL_ADMIN_PERM, |
7768 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7809 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7769 | NL80211_FLAG_NEED_RTNL, | 7810 | NL80211_FLAG_NEED_RTNL, |
7770 | }, | 7811 | }, |
7771 | { | 7812 | { |
7772 | .cmd = NL80211_CMD_PROBE_CLIENT, | 7813 | .cmd = NL80211_CMD_PROBE_CLIENT, |
7773 | .doit = nl80211_probe_client, | 7814 | .doit = nl80211_probe_client, |
7774 | .policy = nl80211_policy, | 7815 | .policy = nl80211_policy, |
7775 | .flags = GENL_ADMIN_PERM, | 7816 | .flags = GENL_ADMIN_PERM, |
7776 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 7817 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
7777 | NL80211_FLAG_NEED_RTNL, | 7818 | NL80211_FLAG_NEED_RTNL, |
7778 | }, | 7819 | }, |
7779 | { | 7820 | { |
7780 | .cmd = NL80211_CMD_REGISTER_BEACONS, | 7821 | .cmd = NL80211_CMD_REGISTER_BEACONS, |
7781 | .doit = nl80211_register_beacons, | 7822 | .doit = nl80211_register_beacons, |
7782 | .policy = nl80211_policy, | 7823 | .policy = nl80211_policy, |
7783 | .flags = GENL_ADMIN_PERM, | 7824 | .flags = GENL_ADMIN_PERM, |
7784 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 7825 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
7785 | NL80211_FLAG_NEED_RTNL, | 7826 | NL80211_FLAG_NEED_RTNL, |
7786 | }, | 7827 | }, |
7787 | { | 7828 | { |
7788 | .cmd = NL80211_CMD_SET_NOACK_MAP, | 7829 | .cmd = NL80211_CMD_SET_NOACK_MAP, |
7789 | .doit = nl80211_set_noack_map, | 7830 | .doit = nl80211_set_noack_map, |
7790 | .policy = nl80211_policy, | 7831 | .policy = nl80211_policy, |
7791 | .flags = GENL_ADMIN_PERM, | 7832 | .flags = GENL_ADMIN_PERM, |
7792 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7833 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7793 | NL80211_FLAG_NEED_RTNL, | 7834 | NL80211_FLAG_NEED_RTNL, |
7794 | }, | 7835 | }, |
7795 | { | 7836 | { |
7796 | .cmd = NL80211_CMD_START_P2P_DEVICE, | 7837 | .cmd = NL80211_CMD_START_P2P_DEVICE, |
7797 | .doit = nl80211_start_p2p_device, | 7838 | .doit = nl80211_start_p2p_device, |
7798 | .policy = nl80211_policy, | 7839 | .policy = nl80211_policy, |
7799 | .flags = GENL_ADMIN_PERM, | 7840 | .flags = GENL_ADMIN_PERM, |
7800 | .internal_flags = NL80211_FLAG_NEED_WDEV | | 7841 | .internal_flags = NL80211_FLAG_NEED_WDEV | |
7801 | NL80211_FLAG_NEED_RTNL, | 7842 | NL80211_FLAG_NEED_RTNL, |
7802 | }, | 7843 | }, |
7803 | { | 7844 | { |
7804 | .cmd = NL80211_CMD_STOP_P2P_DEVICE, | 7845 | .cmd = NL80211_CMD_STOP_P2P_DEVICE, |
7805 | .doit = nl80211_stop_p2p_device, | 7846 | .doit = nl80211_stop_p2p_device, |
7806 | .policy = nl80211_policy, | 7847 | .policy = nl80211_policy, |
7807 | .flags = GENL_ADMIN_PERM, | 7848 | .flags = GENL_ADMIN_PERM, |
7808 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | | 7849 | .internal_flags = NL80211_FLAG_NEED_WDEV_UP | |
7809 | NL80211_FLAG_NEED_RTNL, | 7850 | NL80211_FLAG_NEED_RTNL, |
7810 | }, | 7851 | }, |
7811 | { | 7852 | { |
7812 | .cmd = NL80211_CMD_SET_MCAST_RATE, | 7853 | .cmd = NL80211_CMD_SET_MCAST_RATE, |
7813 | .doit = nl80211_set_mcast_rate, | 7854 | .doit = nl80211_set_mcast_rate, |
7814 | .policy = nl80211_policy, | 7855 | .policy = nl80211_policy, |
7815 | .flags = GENL_ADMIN_PERM, | 7856 | .flags = GENL_ADMIN_PERM, |
7816 | .internal_flags = NL80211_FLAG_NEED_NETDEV | | 7857 | .internal_flags = NL80211_FLAG_NEED_NETDEV | |
7817 | NL80211_FLAG_NEED_RTNL, | 7858 | NL80211_FLAG_NEED_RTNL, |
7818 | }, | 7859 | }, |
7819 | }; | 7860 | }; |
7820 | 7861 | ||
7821 | static struct genl_multicast_group nl80211_mlme_mcgrp = { | 7862 | static struct genl_multicast_group nl80211_mlme_mcgrp = { |
7822 | .name = "mlme", | 7863 | .name = "mlme", |
7823 | }; | 7864 | }; |
7824 | 7865 | ||
7825 | /* multicast groups */ | 7866 | /* multicast groups */ |
7826 | static struct genl_multicast_group nl80211_config_mcgrp = { | 7867 | static struct genl_multicast_group nl80211_config_mcgrp = { |
7827 | .name = "config", | 7868 | .name = "config", |
7828 | }; | 7869 | }; |
7829 | static struct genl_multicast_group nl80211_scan_mcgrp = { | 7870 | static struct genl_multicast_group nl80211_scan_mcgrp = { |
7830 | .name = "scan", | 7871 | .name = "scan", |
7831 | }; | 7872 | }; |
7832 | static struct genl_multicast_group nl80211_regulatory_mcgrp = { | 7873 | static struct genl_multicast_group nl80211_regulatory_mcgrp = { |
7833 | .name = "regulatory", | 7874 | .name = "regulatory", |
7834 | }; | 7875 | }; |
7835 | 7876 | ||
7836 | /* notification functions */ | 7877 | /* notification functions */ |
7837 | 7878 | ||
7838 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) | 7879 | void nl80211_notify_dev_rename(struct cfg80211_registered_device *rdev) |
7839 | { | 7880 | { |
7840 | struct sk_buff *msg; | 7881 | struct sk_buff *msg; |
7841 | 7882 | ||
7842 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 7883 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
7843 | if (!msg) | 7884 | if (!msg) |
7844 | return; | 7885 | return; |
7845 | 7886 | ||
7846 | if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) { | 7887 | if (nl80211_send_wiphy(msg, 0, 0, 0, rdev) < 0) { |
7847 | nlmsg_free(msg); | 7888 | nlmsg_free(msg); |
7848 | return; | 7889 | return; |
7849 | } | 7890 | } |
7850 | 7891 | ||
7851 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 7892 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7852 | nl80211_config_mcgrp.id, GFP_KERNEL); | 7893 | nl80211_config_mcgrp.id, GFP_KERNEL); |
7853 | } | 7894 | } |
7854 | 7895 | ||
7855 | static int nl80211_add_scan_req(struct sk_buff *msg, | 7896 | static int nl80211_add_scan_req(struct sk_buff *msg, |
7856 | struct cfg80211_registered_device *rdev) | 7897 | struct cfg80211_registered_device *rdev) |
7857 | { | 7898 | { |
7858 | struct cfg80211_scan_request *req = rdev->scan_req; | 7899 | struct cfg80211_scan_request *req = rdev->scan_req; |
7859 | struct nlattr *nest; | 7900 | struct nlattr *nest; |
7860 | int i; | 7901 | int i; |
7861 | 7902 | ||
7862 | ASSERT_RDEV_LOCK(rdev); | 7903 | ASSERT_RDEV_LOCK(rdev); |
7863 | 7904 | ||
7864 | if (WARN_ON(!req)) | 7905 | if (WARN_ON(!req)) |
7865 | return 0; | 7906 | return 0; |
7866 | 7907 | ||
7867 | nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS); | 7908 | nest = nla_nest_start(msg, NL80211_ATTR_SCAN_SSIDS); |
7868 | if (!nest) | 7909 | if (!nest) |
7869 | goto nla_put_failure; | 7910 | goto nla_put_failure; |
7870 | for (i = 0; i < req->n_ssids; i++) { | 7911 | for (i = 0; i < req->n_ssids; i++) { |
7871 | if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid)) | 7912 | if (nla_put(msg, i, req->ssids[i].ssid_len, req->ssids[i].ssid)) |
7872 | goto nla_put_failure; | 7913 | goto nla_put_failure; |
7873 | } | 7914 | } |
7874 | nla_nest_end(msg, nest); | 7915 | nla_nest_end(msg, nest); |
7875 | 7916 | ||
7876 | nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); | 7917 | nest = nla_nest_start(msg, NL80211_ATTR_SCAN_FREQUENCIES); |
7877 | if (!nest) | 7918 | if (!nest) |
7878 | goto nla_put_failure; | 7919 | goto nla_put_failure; |
7879 | for (i = 0; i < req->n_channels; i++) { | 7920 | for (i = 0; i < req->n_channels; i++) { |
7880 | if (nla_put_u32(msg, i, req->channels[i]->center_freq)) | 7921 | if (nla_put_u32(msg, i, req->channels[i]->center_freq)) |
7881 | goto nla_put_failure; | 7922 | goto nla_put_failure; |
7882 | } | 7923 | } |
7883 | nla_nest_end(msg, nest); | 7924 | nla_nest_end(msg, nest); |
7884 | 7925 | ||
7885 | if (req->ie && | 7926 | if (req->ie && |
7886 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) | 7927 | nla_put(msg, NL80211_ATTR_IE, req->ie_len, req->ie)) |
7887 | goto nla_put_failure; | 7928 | goto nla_put_failure; |
7888 | 7929 | ||
7889 | if (req->flags) | 7930 | if (req->flags) |
7890 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags); | 7931 | nla_put_u32(msg, NL80211_ATTR_SCAN_FLAGS, req->flags); |
7891 | 7932 | ||
7892 | return 0; | 7933 | return 0; |
7893 | nla_put_failure: | 7934 | nla_put_failure: |
7894 | return -ENOBUFS; | 7935 | return -ENOBUFS; |
7895 | } | 7936 | } |
7896 | 7937 | ||
7897 | static int nl80211_send_scan_msg(struct sk_buff *msg, | 7938 | static int nl80211_send_scan_msg(struct sk_buff *msg, |
7898 | struct cfg80211_registered_device *rdev, | 7939 | struct cfg80211_registered_device *rdev, |
7899 | struct wireless_dev *wdev, | 7940 | struct wireless_dev *wdev, |
7900 | u32 portid, u32 seq, int flags, | 7941 | u32 portid, u32 seq, int flags, |
7901 | u32 cmd) | 7942 | u32 cmd) |
7902 | { | 7943 | { |
7903 | void *hdr; | 7944 | void *hdr; |
7904 | 7945 | ||
7905 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); | 7946 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); |
7906 | if (!hdr) | 7947 | if (!hdr) |
7907 | return -1; | 7948 | return -1; |
7908 | 7949 | ||
7909 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 7950 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
7910 | (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, | 7951 | (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
7911 | wdev->netdev->ifindex)) || | 7952 | wdev->netdev->ifindex)) || |
7912 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) | 7953 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev))) |
7913 | goto nla_put_failure; | 7954 | goto nla_put_failure; |
7914 | 7955 | ||
7915 | /* ignore errors and send incomplete event anyway */ | 7956 | /* ignore errors and send incomplete event anyway */ |
7916 | nl80211_add_scan_req(msg, rdev); | 7957 | nl80211_add_scan_req(msg, rdev); |
7917 | 7958 | ||
7918 | return genlmsg_end(msg, hdr); | 7959 | return genlmsg_end(msg, hdr); |
7919 | 7960 | ||
7920 | nla_put_failure: | 7961 | nla_put_failure: |
7921 | genlmsg_cancel(msg, hdr); | 7962 | genlmsg_cancel(msg, hdr); |
7922 | return -EMSGSIZE; | 7963 | return -EMSGSIZE; |
7923 | } | 7964 | } |
7924 | 7965 | ||
7925 | static int | 7966 | static int |
7926 | nl80211_send_sched_scan_msg(struct sk_buff *msg, | 7967 | nl80211_send_sched_scan_msg(struct sk_buff *msg, |
7927 | struct cfg80211_registered_device *rdev, | 7968 | struct cfg80211_registered_device *rdev, |
7928 | struct net_device *netdev, | 7969 | struct net_device *netdev, |
7929 | u32 portid, u32 seq, int flags, u32 cmd) | 7970 | u32 portid, u32 seq, int flags, u32 cmd) |
7930 | { | 7971 | { |
7931 | void *hdr; | 7972 | void *hdr; |
7932 | 7973 | ||
7933 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); | 7974 | hdr = nl80211hdr_put(msg, portid, seq, flags, cmd); |
7934 | if (!hdr) | 7975 | if (!hdr) |
7935 | return -1; | 7976 | return -1; |
7936 | 7977 | ||
7937 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 7978 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
7938 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) | 7979 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) |
7939 | goto nla_put_failure; | 7980 | goto nla_put_failure; |
7940 | 7981 | ||
7941 | return genlmsg_end(msg, hdr); | 7982 | return genlmsg_end(msg, hdr); |
7942 | 7983 | ||
7943 | nla_put_failure: | 7984 | nla_put_failure: |
7944 | genlmsg_cancel(msg, hdr); | 7985 | genlmsg_cancel(msg, hdr); |
7945 | return -EMSGSIZE; | 7986 | return -EMSGSIZE; |
7946 | } | 7987 | } |
7947 | 7988 | ||
7948 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, | 7989 | void nl80211_send_scan_start(struct cfg80211_registered_device *rdev, |
7949 | struct wireless_dev *wdev) | 7990 | struct wireless_dev *wdev) |
7950 | { | 7991 | { |
7951 | struct sk_buff *msg; | 7992 | struct sk_buff *msg; |
7952 | 7993 | ||
7953 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 7994 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
7954 | if (!msg) | 7995 | if (!msg) |
7955 | return; | 7996 | return; |
7956 | 7997 | ||
7957 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, | 7998 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
7958 | NL80211_CMD_TRIGGER_SCAN) < 0) { | 7999 | NL80211_CMD_TRIGGER_SCAN) < 0) { |
7959 | nlmsg_free(msg); | 8000 | nlmsg_free(msg); |
7960 | return; | 8001 | return; |
7961 | } | 8002 | } |
7962 | 8003 | ||
7963 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8004 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7964 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 8005 | nl80211_scan_mcgrp.id, GFP_KERNEL); |
7965 | } | 8006 | } |
7966 | 8007 | ||
7967 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, | 8008 | void nl80211_send_scan_done(struct cfg80211_registered_device *rdev, |
7968 | struct wireless_dev *wdev) | 8009 | struct wireless_dev *wdev) |
7969 | { | 8010 | { |
7970 | struct sk_buff *msg; | 8011 | struct sk_buff *msg; |
7971 | 8012 | ||
7972 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 8013 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
7973 | if (!msg) | 8014 | if (!msg) |
7974 | return; | 8015 | return; |
7975 | 8016 | ||
7976 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, | 8017 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
7977 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { | 8018 | NL80211_CMD_NEW_SCAN_RESULTS) < 0) { |
7978 | nlmsg_free(msg); | 8019 | nlmsg_free(msg); |
7979 | return; | 8020 | return; |
7980 | } | 8021 | } |
7981 | 8022 | ||
7982 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8023 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
7983 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 8024 | nl80211_scan_mcgrp.id, GFP_KERNEL); |
7984 | } | 8025 | } |
7985 | 8026 | ||
7986 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, | 8027 | void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev, |
7987 | struct wireless_dev *wdev) | 8028 | struct wireless_dev *wdev) |
7988 | { | 8029 | { |
7989 | struct sk_buff *msg; | 8030 | struct sk_buff *msg; |
7990 | 8031 | ||
7991 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 8032 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
7992 | if (!msg) | 8033 | if (!msg) |
7993 | return; | 8034 | return; |
7994 | 8035 | ||
7995 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, | 8036 | if (nl80211_send_scan_msg(msg, rdev, wdev, 0, 0, 0, |
7996 | NL80211_CMD_SCAN_ABORTED) < 0) { | 8037 | NL80211_CMD_SCAN_ABORTED) < 0) { |
7997 | nlmsg_free(msg); | 8038 | nlmsg_free(msg); |
7998 | return; | 8039 | return; |
7999 | } | 8040 | } |
8000 | 8041 | ||
8001 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8042 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8002 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 8043 | nl80211_scan_mcgrp.id, GFP_KERNEL); |
8003 | } | 8044 | } |
8004 | 8045 | ||
8005 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, | 8046 | void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev, |
8006 | struct net_device *netdev) | 8047 | struct net_device *netdev) |
8007 | { | 8048 | { |
8008 | struct sk_buff *msg; | 8049 | struct sk_buff *msg; |
8009 | 8050 | ||
8010 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 8051 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
8011 | if (!msg) | 8052 | if (!msg) |
8012 | return; | 8053 | return; |
8013 | 8054 | ||
8014 | if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, | 8055 | if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, |
8015 | NL80211_CMD_SCHED_SCAN_RESULTS) < 0) { | 8056 | NL80211_CMD_SCHED_SCAN_RESULTS) < 0) { |
8016 | nlmsg_free(msg); | 8057 | nlmsg_free(msg); |
8017 | return; | 8058 | return; |
8018 | } | 8059 | } |
8019 | 8060 | ||
8020 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8061 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8021 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 8062 | nl80211_scan_mcgrp.id, GFP_KERNEL); |
8022 | } | 8063 | } |
8023 | 8064 | ||
8024 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, | 8065 | void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev, |
8025 | struct net_device *netdev, u32 cmd) | 8066 | struct net_device *netdev, u32 cmd) |
8026 | { | 8067 | { |
8027 | struct sk_buff *msg; | 8068 | struct sk_buff *msg; |
8028 | 8069 | ||
8029 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 8070 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
8030 | if (!msg) | 8071 | if (!msg) |
8031 | return; | 8072 | return; |
8032 | 8073 | ||
8033 | if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) { | 8074 | if (nl80211_send_sched_scan_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) { |
8034 | nlmsg_free(msg); | 8075 | nlmsg_free(msg); |
8035 | return; | 8076 | return; |
8036 | } | 8077 | } |
8037 | 8078 | ||
8038 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8079 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8039 | nl80211_scan_mcgrp.id, GFP_KERNEL); | 8080 | nl80211_scan_mcgrp.id, GFP_KERNEL); |
8040 | } | 8081 | } |
8041 | 8082 | ||
8042 | /* | 8083 | /* |
8043 | * This can happen on global regulatory changes or device specific settings | 8084 | * This can happen on global regulatory changes or device specific settings |
8044 | * based on custom world regulatory domains. | 8085 | * based on custom world regulatory domains. |
8045 | */ | 8086 | */ |
8046 | void nl80211_send_reg_change_event(struct regulatory_request *request) | 8087 | void nl80211_send_reg_change_event(struct regulatory_request *request) |
8047 | { | 8088 | { |
8048 | struct sk_buff *msg; | 8089 | struct sk_buff *msg; |
8049 | void *hdr; | 8090 | void *hdr; |
8050 | 8091 | ||
8051 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 8092 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
8052 | if (!msg) | 8093 | if (!msg) |
8053 | return; | 8094 | return; |
8054 | 8095 | ||
8055 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE); | 8096 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_CHANGE); |
8056 | if (!hdr) { | 8097 | if (!hdr) { |
8057 | nlmsg_free(msg); | 8098 | nlmsg_free(msg); |
8058 | return; | 8099 | return; |
8059 | } | 8100 | } |
8060 | 8101 | ||
8061 | /* Userspace can always count this one always being set */ | 8102 | /* Userspace can always count this one always being set */ |
8062 | if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator)) | 8103 | if (nla_put_u8(msg, NL80211_ATTR_REG_INITIATOR, request->initiator)) |
8063 | goto nla_put_failure; | 8104 | goto nla_put_failure; |
8064 | 8105 | ||
8065 | if (request->alpha2[0] == '0' && request->alpha2[1] == '0') { | 8106 | if (request->alpha2[0] == '0' && request->alpha2[1] == '0') { |
8066 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, | 8107 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, |
8067 | NL80211_REGDOM_TYPE_WORLD)) | 8108 | NL80211_REGDOM_TYPE_WORLD)) |
8068 | goto nla_put_failure; | 8109 | goto nla_put_failure; |
8069 | } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') { | 8110 | } else if (request->alpha2[0] == '9' && request->alpha2[1] == '9') { |
8070 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, | 8111 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, |
8071 | NL80211_REGDOM_TYPE_CUSTOM_WORLD)) | 8112 | NL80211_REGDOM_TYPE_CUSTOM_WORLD)) |
8072 | goto nla_put_failure; | 8113 | goto nla_put_failure; |
8073 | } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') || | 8114 | } else if ((request->alpha2[0] == '9' && request->alpha2[1] == '8') || |
8074 | request->intersect) { | 8115 | request->intersect) { |
8075 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, | 8116 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, |
8076 | NL80211_REGDOM_TYPE_INTERSECTION)) | 8117 | NL80211_REGDOM_TYPE_INTERSECTION)) |
8077 | goto nla_put_failure; | 8118 | goto nla_put_failure; |
8078 | } else { | 8119 | } else { |
8079 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, | 8120 | if (nla_put_u8(msg, NL80211_ATTR_REG_TYPE, |
8080 | NL80211_REGDOM_TYPE_COUNTRY) || | 8121 | NL80211_REGDOM_TYPE_COUNTRY) || |
8081 | nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, | 8122 | nla_put_string(msg, NL80211_ATTR_REG_ALPHA2, |
8082 | request->alpha2)) | 8123 | request->alpha2)) |
8083 | goto nla_put_failure; | 8124 | goto nla_put_failure; |
8084 | } | 8125 | } |
8085 | 8126 | ||
8086 | if (request->wiphy_idx != WIPHY_IDX_INVALID && | 8127 | if (request->wiphy_idx != WIPHY_IDX_INVALID && |
8087 | nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx)) | 8128 | nla_put_u32(msg, NL80211_ATTR_WIPHY, request->wiphy_idx)) |
8088 | goto nla_put_failure; | 8129 | goto nla_put_failure; |
8089 | 8130 | ||
8090 | genlmsg_end(msg, hdr); | 8131 | genlmsg_end(msg, hdr); |
8091 | 8132 | ||
8092 | rcu_read_lock(); | 8133 | rcu_read_lock(); |
8093 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 8134 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, |
8094 | GFP_ATOMIC); | 8135 | GFP_ATOMIC); |
8095 | rcu_read_unlock(); | 8136 | rcu_read_unlock(); |
8096 | 8137 | ||
8097 | return; | 8138 | return; |
8098 | 8139 | ||
8099 | nla_put_failure: | 8140 | nla_put_failure: |
8100 | genlmsg_cancel(msg, hdr); | 8141 | genlmsg_cancel(msg, hdr); |
8101 | nlmsg_free(msg); | 8142 | nlmsg_free(msg); |
8102 | } | 8143 | } |
8103 | 8144 | ||
8104 | static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, | 8145 | static void nl80211_send_mlme_event(struct cfg80211_registered_device *rdev, |
8105 | struct net_device *netdev, | 8146 | struct net_device *netdev, |
8106 | const u8 *buf, size_t len, | 8147 | const u8 *buf, size_t len, |
8107 | enum nl80211_commands cmd, gfp_t gfp) | 8148 | enum nl80211_commands cmd, gfp_t gfp) |
8108 | { | 8149 | { |
8109 | struct sk_buff *msg; | 8150 | struct sk_buff *msg; |
8110 | void *hdr; | 8151 | void *hdr; |
8111 | 8152 | ||
8112 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8153 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8113 | if (!msg) | 8154 | if (!msg) |
8114 | return; | 8155 | return; |
8115 | 8156 | ||
8116 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); | 8157 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); |
8117 | if (!hdr) { | 8158 | if (!hdr) { |
8118 | nlmsg_free(msg); | 8159 | nlmsg_free(msg); |
8119 | return; | 8160 | return; |
8120 | } | 8161 | } |
8121 | 8162 | ||
8122 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8163 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8123 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8164 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8124 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) | 8165 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) |
8125 | goto nla_put_failure; | 8166 | goto nla_put_failure; |
8126 | 8167 | ||
8127 | genlmsg_end(msg, hdr); | 8168 | genlmsg_end(msg, hdr); |
8128 | 8169 | ||
8129 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8170 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8130 | nl80211_mlme_mcgrp.id, gfp); | 8171 | nl80211_mlme_mcgrp.id, gfp); |
8131 | return; | 8172 | return; |
8132 | 8173 | ||
8133 | nla_put_failure: | 8174 | nla_put_failure: |
8134 | genlmsg_cancel(msg, hdr); | 8175 | genlmsg_cancel(msg, hdr); |
8135 | nlmsg_free(msg); | 8176 | nlmsg_free(msg); |
8136 | } | 8177 | } |
8137 | 8178 | ||
8138 | void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, | 8179 | void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev, |
8139 | struct net_device *netdev, const u8 *buf, | 8180 | struct net_device *netdev, const u8 *buf, |
8140 | size_t len, gfp_t gfp) | 8181 | size_t len, gfp_t gfp) |
8141 | { | 8182 | { |
8142 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 8183 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
8143 | NL80211_CMD_AUTHENTICATE, gfp); | 8184 | NL80211_CMD_AUTHENTICATE, gfp); |
8144 | } | 8185 | } |
8145 | 8186 | ||
8146 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, | 8187 | void nl80211_send_rx_assoc(struct cfg80211_registered_device *rdev, |
8147 | struct net_device *netdev, const u8 *buf, | 8188 | struct net_device *netdev, const u8 *buf, |
8148 | size_t len, gfp_t gfp) | 8189 | size_t len, gfp_t gfp) |
8149 | { | 8190 | { |
8150 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 8191 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
8151 | NL80211_CMD_ASSOCIATE, gfp); | 8192 | NL80211_CMD_ASSOCIATE, gfp); |
8152 | } | 8193 | } |
8153 | 8194 | ||
8154 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, | 8195 | void nl80211_send_deauth(struct cfg80211_registered_device *rdev, |
8155 | struct net_device *netdev, const u8 *buf, | 8196 | struct net_device *netdev, const u8 *buf, |
8156 | size_t len, gfp_t gfp) | 8197 | size_t len, gfp_t gfp) |
8157 | { | 8198 | { |
8158 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 8199 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
8159 | NL80211_CMD_DEAUTHENTICATE, gfp); | 8200 | NL80211_CMD_DEAUTHENTICATE, gfp); |
8160 | } | 8201 | } |
8161 | 8202 | ||
8162 | void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, | 8203 | void nl80211_send_disassoc(struct cfg80211_registered_device *rdev, |
8163 | struct net_device *netdev, const u8 *buf, | 8204 | struct net_device *netdev, const u8 *buf, |
8164 | size_t len, gfp_t gfp) | 8205 | size_t len, gfp_t gfp) |
8165 | { | 8206 | { |
8166 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 8207 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
8167 | NL80211_CMD_DISASSOCIATE, gfp); | 8208 | NL80211_CMD_DISASSOCIATE, gfp); |
8168 | } | 8209 | } |
8169 | 8210 | ||
8170 | void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev, | 8211 | void nl80211_send_unprot_deauth(struct cfg80211_registered_device *rdev, |
8171 | struct net_device *netdev, const u8 *buf, | 8212 | struct net_device *netdev, const u8 *buf, |
8172 | size_t len, gfp_t gfp) | 8213 | size_t len, gfp_t gfp) |
8173 | { | 8214 | { |
8174 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 8215 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
8175 | NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp); | 8216 | NL80211_CMD_UNPROT_DEAUTHENTICATE, gfp); |
8176 | } | 8217 | } |
8177 | 8218 | ||
8178 | void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev, | 8219 | void nl80211_send_unprot_disassoc(struct cfg80211_registered_device *rdev, |
8179 | struct net_device *netdev, const u8 *buf, | 8220 | struct net_device *netdev, const u8 *buf, |
8180 | size_t len, gfp_t gfp) | 8221 | size_t len, gfp_t gfp) |
8181 | { | 8222 | { |
8182 | nl80211_send_mlme_event(rdev, netdev, buf, len, | 8223 | nl80211_send_mlme_event(rdev, netdev, buf, len, |
8183 | NL80211_CMD_UNPROT_DISASSOCIATE, gfp); | 8224 | NL80211_CMD_UNPROT_DISASSOCIATE, gfp); |
8184 | } | 8225 | } |
8185 | 8226 | ||
8186 | static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, | 8227 | static void nl80211_send_mlme_timeout(struct cfg80211_registered_device *rdev, |
8187 | struct net_device *netdev, int cmd, | 8228 | struct net_device *netdev, int cmd, |
8188 | const u8 *addr, gfp_t gfp) | 8229 | const u8 *addr, gfp_t gfp) |
8189 | { | 8230 | { |
8190 | struct sk_buff *msg; | 8231 | struct sk_buff *msg; |
8191 | void *hdr; | 8232 | void *hdr; |
8192 | 8233 | ||
8193 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8234 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8194 | if (!msg) | 8235 | if (!msg) |
8195 | return; | 8236 | return; |
8196 | 8237 | ||
8197 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); | 8238 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); |
8198 | if (!hdr) { | 8239 | if (!hdr) { |
8199 | nlmsg_free(msg); | 8240 | nlmsg_free(msg); |
8200 | return; | 8241 | return; |
8201 | } | 8242 | } |
8202 | 8243 | ||
8203 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8244 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8204 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8245 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8205 | nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) || | 8246 | nla_put_flag(msg, NL80211_ATTR_TIMED_OUT) || |
8206 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) | 8247 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) |
8207 | goto nla_put_failure; | 8248 | goto nla_put_failure; |
8208 | 8249 | ||
8209 | genlmsg_end(msg, hdr); | 8250 | genlmsg_end(msg, hdr); |
8210 | 8251 | ||
8211 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8252 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8212 | nl80211_mlme_mcgrp.id, gfp); | 8253 | nl80211_mlme_mcgrp.id, gfp); |
8213 | return; | 8254 | return; |
8214 | 8255 | ||
8215 | nla_put_failure: | 8256 | nla_put_failure: |
8216 | genlmsg_cancel(msg, hdr); | 8257 | genlmsg_cancel(msg, hdr); |
8217 | nlmsg_free(msg); | 8258 | nlmsg_free(msg); |
8218 | } | 8259 | } |
8219 | 8260 | ||
8220 | void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, | 8261 | void nl80211_send_auth_timeout(struct cfg80211_registered_device *rdev, |
8221 | struct net_device *netdev, const u8 *addr, | 8262 | struct net_device *netdev, const u8 *addr, |
8222 | gfp_t gfp) | 8263 | gfp_t gfp) |
8223 | { | 8264 | { |
8224 | nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE, | 8265 | nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_AUTHENTICATE, |
8225 | addr, gfp); | 8266 | addr, gfp); |
8226 | } | 8267 | } |
8227 | 8268 | ||
8228 | void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev, | 8269 | void nl80211_send_assoc_timeout(struct cfg80211_registered_device *rdev, |
8229 | struct net_device *netdev, const u8 *addr, | 8270 | struct net_device *netdev, const u8 *addr, |
8230 | gfp_t gfp) | 8271 | gfp_t gfp) |
8231 | { | 8272 | { |
8232 | nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, | 8273 | nl80211_send_mlme_timeout(rdev, netdev, NL80211_CMD_ASSOCIATE, |
8233 | addr, gfp); | 8274 | addr, gfp); |
8234 | } | 8275 | } |
8235 | 8276 | ||
8236 | void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, | 8277 | void nl80211_send_connect_result(struct cfg80211_registered_device *rdev, |
8237 | struct net_device *netdev, const u8 *bssid, | 8278 | struct net_device *netdev, const u8 *bssid, |
8238 | const u8 *req_ie, size_t req_ie_len, | 8279 | const u8 *req_ie, size_t req_ie_len, |
8239 | const u8 *resp_ie, size_t resp_ie_len, | 8280 | const u8 *resp_ie, size_t resp_ie_len, |
8240 | u16 status, gfp_t gfp) | 8281 | u16 status, gfp_t gfp) |
8241 | { | 8282 | { |
8242 | struct sk_buff *msg; | 8283 | struct sk_buff *msg; |
8243 | void *hdr; | 8284 | void *hdr; |
8244 | 8285 | ||
8245 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8286 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8246 | if (!msg) | 8287 | if (!msg) |
8247 | return; | 8288 | return; |
8248 | 8289 | ||
8249 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT); | 8290 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONNECT); |
8250 | if (!hdr) { | 8291 | if (!hdr) { |
8251 | nlmsg_free(msg); | 8292 | nlmsg_free(msg); |
8252 | return; | 8293 | return; |
8253 | } | 8294 | } |
8254 | 8295 | ||
8255 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8296 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8256 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8297 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8257 | (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) || | 8298 | (bssid && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) || |
8258 | nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status) || | 8299 | nla_put_u16(msg, NL80211_ATTR_STATUS_CODE, status) || |
8259 | (req_ie && | 8300 | (req_ie && |
8260 | nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) || | 8301 | nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) || |
8261 | (resp_ie && | 8302 | (resp_ie && |
8262 | nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie))) | 8303 | nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie))) |
8263 | goto nla_put_failure; | 8304 | goto nla_put_failure; |
8264 | 8305 | ||
8265 | genlmsg_end(msg, hdr); | 8306 | genlmsg_end(msg, hdr); |
8266 | 8307 | ||
8267 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8308 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8268 | nl80211_mlme_mcgrp.id, gfp); | 8309 | nl80211_mlme_mcgrp.id, gfp); |
8269 | return; | 8310 | return; |
8270 | 8311 | ||
8271 | nla_put_failure: | 8312 | nla_put_failure: |
8272 | genlmsg_cancel(msg, hdr); | 8313 | genlmsg_cancel(msg, hdr); |
8273 | nlmsg_free(msg); | 8314 | nlmsg_free(msg); |
8274 | 8315 | ||
8275 | } | 8316 | } |
8276 | 8317 | ||
8277 | void nl80211_send_roamed(struct cfg80211_registered_device *rdev, | 8318 | void nl80211_send_roamed(struct cfg80211_registered_device *rdev, |
8278 | struct net_device *netdev, const u8 *bssid, | 8319 | struct net_device *netdev, const u8 *bssid, |
8279 | const u8 *req_ie, size_t req_ie_len, | 8320 | const u8 *req_ie, size_t req_ie_len, |
8280 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp) | 8321 | const u8 *resp_ie, size_t resp_ie_len, gfp_t gfp) |
8281 | { | 8322 | { |
8282 | struct sk_buff *msg; | 8323 | struct sk_buff *msg; |
8283 | void *hdr; | 8324 | void *hdr; |
8284 | 8325 | ||
8285 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8326 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8286 | if (!msg) | 8327 | if (!msg) |
8287 | return; | 8328 | return; |
8288 | 8329 | ||
8289 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM); | 8330 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_ROAM); |
8290 | if (!hdr) { | 8331 | if (!hdr) { |
8291 | nlmsg_free(msg); | 8332 | nlmsg_free(msg); |
8292 | return; | 8333 | return; |
8293 | } | 8334 | } |
8294 | 8335 | ||
8295 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8336 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8296 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8337 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8297 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) || | 8338 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid) || |
8298 | (req_ie && | 8339 | (req_ie && |
8299 | nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) || | 8340 | nla_put(msg, NL80211_ATTR_REQ_IE, req_ie_len, req_ie)) || |
8300 | (resp_ie && | 8341 | (resp_ie && |
8301 | nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie))) | 8342 | nla_put(msg, NL80211_ATTR_RESP_IE, resp_ie_len, resp_ie))) |
8302 | goto nla_put_failure; | 8343 | goto nla_put_failure; |
8303 | 8344 | ||
8304 | genlmsg_end(msg, hdr); | 8345 | genlmsg_end(msg, hdr); |
8305 | 8346 | ||
8306 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8347 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8307 | nl80211_mlme_mcgrp.id, gfp); | 8348 | nl80211_mlme_mcgrp.id, gfp); |
8308 | return; | 8349 | return; |
8309 | 8350 | ||
8310 | nla_put_failure: | 8351 | nla_put_failure: |
8311 | genlmsg_cancel(msg, hdr); | 8352 | genlmsg_cancel(msg, hdr); |
8312 | nlmsg_free(msg); | 8353 | nlmsg_free(msg); |
8313 | 8354 | ||
8314 | } | 8355 | } |
8315 | 8356 | ||
8316 | void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, | 8357 | void nl80211_send_disconnected(struct cfg80211_registered_device *rdev, |
8317 | struct net_device *netdev, u16 reason, | 8358 | struct net_device *netdev, u16 reason, |
8318 | const u8 *ie, size_t ie_len, bool from_ap) | 8359 | const u8 *ie, size_t ie_len, bool from_ap) |
8319 | { | 8360 | { |
8320 | struct sk_buff *msg; | 8361 | struct sk_buff *msg; |
8321 | void *hdr; | 8362 | void *hdr; |
8322 | 8363 | ||
8323 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 8364 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); |
8324 | if (!msg) | 8365 | if (!msg) |
8325 | return; | 8366 | return; |
8326 | 8367 | ||
8327 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT); | 8368 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DISCONNECT); |
8328 | if (!hdr) { | 8369 | if (!hdr) { |
8329 | nlmsg_free(msg); | 8370 | nlmsg_free(msg); |
8330 | return; | 8371 | return; |
8331 | } | 8372 | } |
8332 | 8373 | ||
8333 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8374 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8334 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8375 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8335 | (from_ap && reason && | 8376 | (from_ap && reason && |
8336 | nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) || | 8377 | nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason)) || |
8337 | (from_ap && | 8378 | (from_ap && |
8338 | nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) || | 8379 | nla_put_flag(msg, NL80211_ATTR_DISCONNECTED_BY_AP)) || |
8339 | (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie))) | 8380 | (ie && nla_put(msg, NL80211_ATTR_IE, ie_len, ie))) |
8340 | goto nla_put_failure; | 8381 | goto nla_put_failure; |
8341 | 8382 | ||
8342 | genlmsg_end(msg, hdr); | 8383 | genlmsg_end(msg, hdr); |
8343 | 8384 | ||
8344 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8385 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8345 | nl80211_mlme_mcgrp.id, GFP_KERNEL); | 8386 | nl80211_mlme_mcgrp.id, GFP_KERNEL); |
8346 | return; | 8387 | return; |
8347 | 8388 | ||
8348 | nla_put_failure: | 8389 | nla_put_failure: |
8349 | genlmsg_cancel(msg, hdr); | 8390 | genlmsg_cancel(msg, hdr); |
8350 | nlmsg_free(msg); | 8391 | nlmsg_free(msg); |
8351 | 8392 | ||
8352 | } | 8393 | } |
8353 | 8394 | ||
8354 | void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, | 8395 | void nl80211_send_ibss_bssid(struct cfg80211_registered_device *rdev, |
8355 | struct net_device *netdev, const u8 *bssid, | 8396 | struct net_device *netdev, const u8 *bssid, |
8356 | gfp_t gfp) | 8397 | gfp_t gfp) |
8357 | { | 8398 | { |
8358 | struct sk_buff *msg; | 8399 | struct sk_buff *msg; |
8359 | void *hdr; | 8400 | void *hdr; |
8360 | 8401 | ||
8361 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8402 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8362 | if (!msg) | 8403 | if (!msg) |
8363 | return; | 8404 | return; |
8364 | 8405 | ||
8365 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS); | 8406 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_JOIN_IBSS); |
8366 | if (!hdr) { | 8407 | if (!hdr) { |
8367 | nlmsg_free(msg); | 8408 | nlmsg_free(msg); |
8368 | return; | 8409 | return; |
8369 | } | 8410 | } |
8370 | 8411 | ||
8371 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8412 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8372 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8413 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8373 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) | 8414 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) |
8374 | goto nla_put_failure; | 8415 | goto nla_put_failure; |
8375 | 8416 | ||
8376 | genlmsg_end(msg, hdr); | 8417 | genlmsg_end(msg, hdr); |
8377 | 8418 | ||
8378 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8419 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8379 | nl80211_mlme_mcgrp.id, gfp); | 8420 | nl80211_mlme_mcgrp.id, gfp); |
8380 | return; | 8421 | return; |
8381 | 8422 | ||
8382 | nla_put_failure: | 8423 | nla_put_failure: |
8383 | genlmsg_cancel(msg, hdr); | 8424 | genlmsg_cancel(msg, hdr); |
8384 | nlmsg_free(msg); | 8425 | nlmsg_free(msg); |
8385 | } | 8426 | } |
8386 | 8427 | ||
8387 | void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, | 8428 | void nl80211_send_new_peer_candidate(struct cfg80211_registered_device *rdev, |
8388 | struct net_device *netdev, | 8429 | struct net_device *netdev, |
8389 | const u8 *macaddr, const u8* ie, u8 ie_len, | 8430 | const u8 *macaddr, const u8* ie, u8 ie_len, |
8390 | gfp_t gfp) | 8431 | gfp_t gfp) |
8391 | { | 8432 | { |
8392 | struct sk_buff *msg; | 8433 | struct sk_buff *msg; |
8393 | void *hdr; | 8434 | void *hdr; |
8394 | 8435 | ||
8395 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8436 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8396 | if (!msg) | 8437 | if (!msg) |
8397 | return; | 8438 | return; |
8398 | 8439 | ||
8399 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE); | 8440 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NEW_PEER_CANDIDATE); |
8400 | if (!hdr) { | 8441 | if (!hdr) { |
8401 | nlmsg_free(msg); | 8442 | nlmsg_free(msg); |
8402 | return; | 8443 | return; |
8403 | } | 8444 | } |
8404 | 8445 | ||
8405 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8446 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8406 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8447 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8407 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr) || | 8448 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, macaddr) || |
8408 | (ie_len && ie && | 8449 | (ie_len && ie && |
8409 | nla_put(msg, NL80211_ATTR_IE, ie_len , ie))) | 8450 | nla_put(msg, NL80211_ATTR_IE, ie_len , ie))) |
8410 | goto nla_put_failure; | 8451 | goto nla_put_failure; |
8411 | 8452 | ||
8412 | genlmsg_end(msg, hdr); | 8453 | genlmsg_end(msg, hdr); |
8413 | 8454 | ||
8414 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8455 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8415 | nl80211_mlme_mcgrp.id, gfp); | 8456 | nl80211_mlme_mcgrp.id, gfp); |
8416 | return; | 8457 | return; |
8417 | 8458 | ||
8418 | nla_put_failure: | 8459 | nla_put_failure: |
8419 | genlmsg_cancel(msg, hdr); | 8460 | genlmsg_cancel(msg, hdr); |
8420 | nlmsg_free(msg); | 8461 | nlmsg_free(msg); |
8421 | } | 8462 | } |
8422 | 8463 | ||
8423 | void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | 8464 | void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, |
8424 | struct net_device *netdev, const u8 *addr, | 8465 | struct net_device *netdev, const u8 *addr, |
8425 | enum nl80211_key_type key_type, int key_id, | 8466 | enum nl80211_key_type key_type, int key_id, |
8426 | const u8 *tsc, gfp_t gfp) | 8467 | const u8 *tsc, gfp_t gfp) |
8427 | { | 8468 | { |
8428 | struct sk_buff *msg; | 8469 | struct sk_buff *msg; |
8429 | void *hdr; | 8470 | void *hdr; |
8430 | 8471 | ||
8431 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8472 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8432 | if (!msg) | 8473 | if (!msg) |
8433 | return; | 8474 | return; |
8434 | 8475 | ||
8435 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE); | 8476 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_MICHAEL_MIC_FAILURE); |
8436 | if (!hdr) { | 8477 | if (!hdr) { |
8437 | nlmsg_free(msg); | 8478 | nlmsg_free(msg); |
8438 | return; | 8479 | return; |
8439 | } | 8480 | } |
8440 | 8481 | ||
8441 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8482 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8442 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8483 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8443 | (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) || | 8484 | (addr && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) || |
8444 | nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) || | 8485 | nla_put_u32(msg, NL80211_ATTR_KEY_TYPE, key_type) || |
8445 | (key_id != -1 && | 8486 | (key_id != -1 && |
8446 | nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) || | 8487 | nla_put_u8(msg, NL80211_ATTR_KEY_IDX, key_id)) || |
8447 | (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc))) | 8488 | (tsc && nla_put(msg, NL80211_ATTR_KEY_SEQ, 6, tsc))) |
8448 | goto nla_put_failure; | 8489 | goto nla_put_failure; |
8449 | 8490 | ||
8450 | genlmsg_end(msg, hdr); | 8491 | genlmsg_end(msg, hdr); |
8451 | 8492 | ||
8452 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8493 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8453 | nl80211_mlme_mcgrp.id, gfp); | 8494 | nl80211_mlme_mcgrp.id, gfp); |
8454 | return; | 8495 | return; |
8455 | 8496 | ||
8456 | nla_put_failure: | 8497 | nla_put_failure: |
8457 | genlmsg_cancel(msg, hdr); | 8498 | genlmsg_cancel(msg, hdr); |
8458 | nlmsg_free(msg); | 8499 | nlmsg_free(msg); |
8459 | } | 8500 | } |
8460 | 8501 | ||
8461 | void nl80211_send_beacon_hint_event(struct wiphy *wiphy, | 8502 | void nl80211_send_beacon_hint_event(struct wiphy *wiphy, |
8462 | struct ieee80211_channel *channel_before, | 8503 | struct ieee80211_channel *channel_before, |
8463 | struct ieee80211_channel *channel_after) | 8504 | struct ieee80211_channel *channel_after) |
8464 | { | 8505 | { |
8465 | struct sk_buff *msg; | 8506 | struct sk_buff *msg; |
8466 | void *hdr; | 8507 | void *hdr; |
8467 | struct nlattr *nl_freq; | 8508 | struct nlattr *nl_freq; |
8468 | 8509 | ||
8469 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); | 8510 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC); |
8470 | if (!msg) | 8511 | if (!msg) |
8471 | return; | 8512 | return; |
8472 | 8513 | ||
8473 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT); | 8514 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_REG_BEACON_HINT); |
8474 | if (!hdr) { | 8515 | if (!hdr) { |
8475 | nlmsg_free(msg); | 8516 | nlmsg_free(msg); |
8476 | return; | 8517 | return; |
8477 | } | 8518 | } |
8478 | 8519 | ||
8479 | /* | 8520 | /* |
8480 | * Since we are applying the beacon hint to a wiphy we know its | 8521 | * Since we are applying the beacon hint to a wiphy we know its |
8481 | * wiphy_idx is valid | 8522 | * wiphy_idx is valid |
8482 | */ | 8523 | */ |
8483 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy))) | 8524 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, get_wiphy_idx(wiphy))) |
8484 | goto nla_put_failure; | 8525 | goto nla_put_failure; |
8485 | 8526 | ||
8486 | /* Before */ | 8527 | /* Before */ |
8487 | nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE); | 8528 | nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_BEFORE); |
8488 | if (!nl_freq) | 8529 | if (!nl_freq) |
8489 | goto nla_put_failure; | 8530 | goto nla_put_failure; |
8490 | if (nl80211_msg_put_channel(msg, channel_before)) | 8531 | if (nl80211_msg_put_channel(msg, channel_before)) |
8491 | goto nla_put_failure; | 8532 | goto nla_put_failure; |
8492 | nla_nest_end(msg, nl_freq); | 8533 | nla_nest_end(msg, nl_freq); |
8493 | 8534 | ||
8494 | /* After */ | 8535 | /* After */ |
8495 | nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER); | 8536 | nl_freq = nla_nest_start(msg, NL80211_ATTR_FREQ_AFTER); |
8496 | if (!nl_freq) | 8537 | if (!nl_freq) |
8497 | goto nla_put_failure; | 8538 | goto nla_put_failure; |
8498 | if (nl80211_msg_put_channel(msg, channel_after)) | 8539 | if (nl80211_msg_put_channel(msg, channel_after)) |
8499 | goto nla_put_failure; | 8540 | goto nla_put_failure; |
8500 | nla_nest_end(msg, nl_freq); | 8541 | nla_nest_end(msg, nl_freq); |
8501 | 8542 | ||
8502 | genlmsg_end(msg, hdr); | 8543 | genlmsg_end(msg, hdr); |
8503 | 8544 | ||
8504 | rcu_read_lock(); | 8545 | rcu_read_lock(); |
8505 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, | 8546 | genlmsg_multicast_allns(msg, 0, nl80211_regulatory_mcgrp.id, |
8506 | GFP_ATOMIC); | 8547 | GFP_ATOMIC); |
8507 | rcu_read_unlock(); | 8548 | rcu_read_unlock(); |
8508 | 8549 | ||
8509 | return; | 8550 | return; |
8510 | 8551 | ||
8511 | nla_put_failure: | 8552 | nla_put_failure: |
8512 | genlmsg_cancel(msg, hdr); | 8553 | genlmsg_cancel(msg, hdr); |
8513 | nlmsg_free(msg); | 8554 | nlmsg_free(msg); |
8514 | } | 8555 | } |
8515 | 8556 | ||
8516 | static void nl80211_send_remain_on_chan_event( | 8557 | static void nl80211_send_remain_on_chan_event( |
8517 | int cmd, struct cfg80211_registered_device *rdev, | 8558 | int cmd, struct cfg80211_registered_device *rdev, |
8518 | struct wireless_dev *wdev, u64 cookie, | 8559 | struct wireless_dev *wdev, u64 cookie, |
8519 | struct ieee80211_channel *chan, | 8560 | struct ieee80211_channel *chan, |
8520 | unsigned int duration, gfp_t gfp) | 8561 | unsigned int duration, gfp_t gfp) |
8521 | { | 8562 | { |
8522 | struct sk_buff *msg; | 8563 | struct sk_buff *msg; |
8523 | void *hdr; | 8564 | void *hdr; |
8524 | 8565 | ||
8525 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8566 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8526 | if (!msg) | 8567 | if (!msg) |
8527 | return; | 8568 | return; |
8528 | 8569 | ||
8529 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); | 8570 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); |
8530 | if (!hdr) { | 8571 | if (!hdr) { |
8531 | nlmsg_free(msg); | 8572 | nlmsg_free(msg); |
8532 | return; | 8573 | return; |
8533 | } | 8574 | } |
8534 | 8575 | ||
8535 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8576 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8536 | (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, | 8577 | (wdev->netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
8537 | wdev->netdev->ifindex)) || | 8578 | wdev->netdev->ifindex)) || |
8538 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || | 8579 | nla_put_u64(msg, NL80211_ATTR_WDEV, wdev_id(wdev)) || |
8539 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) || | 8580 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, chan->center_freq) || |
8540 | nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, | 8581 | nla_put_u32(msg, NL80211_ATTR_WIPHY_CHANNEL_TYPE, |
8541 | NL80211_CHAN_NO_HT) || | 8582 | NL80211_CHAN_NO_HT) || |
8542 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) | 8583 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie)) |
8543 | goto nla_put_failure; | 8584 | goto nla_put_failure; |
8544 | 8585 | ||
8545 | if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL && | 8586 | if (cmd == NL80211_CMD_REMAIN_ON_CHANNEL && |
8546 | nla_put_u32(msg, NL80211_ATTR_DURATION, duration)) | 8587 | nla_put_u32(msg, NL80211_ATTR_DURATION, duration)) |
8547 | goto nla_put_failure; | 8588 | goto nla_put_failure; |
8548 | 8589 | ||
8549 | genlmsg_end(msg, hdr); | 8590 | genlmsg_end(msg, hdr); |
8550 | 8591 | ||
8551 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8592 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8552 | nl80211_mlme_mcgrp.id, gfp); | 8593 | nl80211_mlme_mcgrp.id, gfp); |
8553 | return; | 8594 | return; |
8554 | 8595 | ||
8555 | nla_put_failure: | 8596 | nla_put_failure: |
8556 | genlmsg_cancel(msg, hdr); | 8597 | genlmsg_cancel(msg, hdr); |
8557 | nlmsg_free(msg); | 8598 | nlmsg_free(msg); |
8558 | } | 8599 | } |
8559 | 8600 | ||
8560 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, | 8601 | void nl80211_send_remain_on_channel(struct cfg80211_registered_device *rdev, |
8561 | struct wireless_dev *wdev, u64 cookie, | 8602 | struct wireless_dev *wdev, u64 cookie, |
8562 | struct ieee80211_channel *chan, | 8603 | struct ieee80211_channel *chan, |
8563 | unsigned int duration, gfp_t gfp) | 8604 | unsigned int duration, gfp_t gfp) |
8564 | { | 8605 | { |
8565 | nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, | 8606 | nl80211_send_remain_on_chan_event(NL80211_CMD_REMAIN_ON_CHANNEL, |
8566 | rdev, wdev, cookie, chan, | 8607 | rdev, wdev, cookie, chan, |
8567 | duration, gfp); | 8608 | duration, gfp); |
8568 | } | 8609 | } |
8569 | 8610 | ||
8570 | void nl80211_send_remain_on_channel_cancel( | 8611 | void nl80211_send_remain_on_channel_cancel( |
8571 | struct cfg80211_registered_device *rdev, | 8612 | struct cfg80211_registered_device *rdev, |
8572 | struct wireless_dev *wdev, | 8613 | struct wireless_dev *wdev, |
8573 | u64 cookie, struct ieee80211_channel *chan, gfp_t gfp) | 8614 | u64 cookie, struct ieee80211_channel *chan, gfp_t gfp) |
8574 | { | 8615 | { |
8575 | nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, | 8616 | nl80211_send_remain_on_chan_event(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, |
8576 | rdev, wdev, cookie, chan, 0, gfp); | 8617 | rdev, wdev, cookie, chan, 0, gfp); |
8577 | } | 8618 | } |
8578 | 8619 | ||
8579 | void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, | 8620 | void nl80211_send_sta_event(struct cfg80211_registered_device *rdev, |
8580 | struct net_device *dev, const u8 *mac_addr, | 8621 | struct net_device *dev, const u8 *mac_addr, |
8581 | struct station_info *sinfo, gfp_t gfp) | 8622 | struct station_info *sinfo, gfp_t gfp) |
8582 | { | 8623 | { |
8583 | struct sk_buff *msg; | 8624 | struct sk_buff *msg; |
8584 | 8625 | ||
8585 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8626 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8586 | if (!msg) | 8627 | if (!msg) |
8587 | return; | 8628 | return; |
8588 | 8629 | ||
8589 | if (nl80211_send_station(msg, 0, 0, 0, | 8630 | if (nl80211_send_station(msg, 0, 0, 0, |
8590 | rdev, dev, mac_addr, sinfo) < 0) { | 8631 | rdev, dev, mac_addr, sinfo) < 0) { |
8591 | nlmsg_free(msg); | 8632 | nlmsg_free(msg); |
8592 | return; | 8633 | return; |
8593 | } | 8634 | } |
8594 | 8635 | ||
8595 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8636 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8596 | nl80211_mlme_mcgrp.id, gfp); | 8637 | nl80211_mlme_mcgrp.id, gfp); |
8597 | } | 8638 | } |
8598 | 8639 | ||
8599 | void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, | 8640 | void nl80211_send_sta_del_event(struct cfg80211_registered_device *rdev, |
8600 | struct net_device *dev, const u8 *mac_addr, | 8641 | struct net_device *dev, const u8 *mac_addr, |
8601 | gfp_t gfp) | 8642 | gfp_t gfp) |
8602 | { | 8643 | { |
8603 | struct sk_buff *msg; | 8644 | struct sk_buff *msg; |
8604 | void *hdr; | 8645 | void *hdr; |
8605 | 8646 | ||
8606 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8647 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8607 | if (!msg) | 8648 | if (!msg) |
8608 | return; | 8649 | return; |
8609 | 8650 | ||
8610 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION); | 8651 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_DEL_STATION); |
8611 | if (!hdr) { | 8652 | if (!hdr) { |
8612 | nlmsg_free(msg); | 8653 | nlmsg_free(msg); |
8613 | return; | 8654 | return; |
8614 | } | 8655 | } |
8615 | 8656 | ||
8616 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 8657 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
8617 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) | 8658 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr)) |
8618 | goto nla_put_failure; | 8659 | goto nla_put_failure; |
8619 | 8660 | ||
8620 | genlmsg_end(msg, hdr); | 8661 | genlmsg_end(msg, hdr); |
8621 | 8662 | ||
8622 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8663 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8623 | nl80211_mlme_mcgrp.id, gfp); | 8664 | nl80211_mlme_mcgrp.id, gfp); |
8624 | return; | 8665 | return; |
8625 | 8666 | ||
8626 | nla_put_failure: | 8667 | nla_put_failure: |
8627 | genlmsg_cancel(msg, hdr); | 8668 | genlmsg_cancel(msg, hdr); |
8628 | nlmsg_free(msg); | 8669 | nlmsg_free(msg); |
8629 | } | 8670 | } |
8630 | 8671 | ||
8631 | void nl80211_send_conn_failed_event(struct cfg80211_registered_device *rdev, | 8672 | void nl80211_send_conn_failed_event(struct cfg80211_registered_device *rdev, |
8632 | struct net_device *dev, const u8 *mac_addr, | 8673 | struct net_device *dev, const u8 *mac_addr, |
8633 | enum nl80211_connect_failed_reason reason, | 8674 | enum nl80211_connect_failed_reason reason, |
8634 | gfp_t gfp) | 8675 | gfp_t gfp) |
8635 | { | 8676 | { |
8636 | struct sk_buff *msg; | 8677 | struct sk_buff *msg; |
8637 | void *hdr; | 8678 | void *hdr; |
8638 | 8679 | ||
8639 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | 8680 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); |
8640 | if (!msg) | 8681 | if (!msg) |
8641 | return; | 8682 | return; |
8642 | 8683 | ||
8643 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED); | 8684 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CONN_FAILED); |
8644 | if (!hdr) { | 8685 | if (!hdr) { |
8645 | nlmsg_free(msg); | 8686 | nlmsg_free(msg); |
8646 | return; | 8687 | return; |
8647 | } | 8688 | } |
8648 | 8689 | ||
8649 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 8690 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
8650 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) || | 8691 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, mac_addr) || |
8651 | nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason)) | 8692 | nla_put_u32(msg, NL80211_ATTR_CONN_FAILED_REASON, reason)) |
8652 | goto nla_put_failure; | 8693 | goto nla_put_failure; |
8653 | 8694 | ||
8654 | genlmsg_end(msg, hdr); | 8695 | genlmsg_end(msg, hdr); |
8655 | 8696 | ||
8656 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8697 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8657 | nl80211_mlme_mcgrp.id, gfp); | 8698 | nl80211_mlme_mcgrp.id, gfp); |
8658 | return; | 8699 | return; |
8659 | 8700 | ||
8660 | nla_put_failure: | 8701 | nla_put_failure: |
8661 | genlmsg_cancel(msg, hdr); | 8702 | genlmsg_cancel(msg, hdr); |
8662 | nlmsg_free(msg); | 8703 | nlmsg_free(msg); |
8663 | } | 8704 | } |
8664 | 8705 | ||
8665 | static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, | 8706 | static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd, |
8666 | const u8 *addr, gfp_t gfp) | 8707 | const u8 *addr, gfp_t gfp) |
8667 | { | 8708 | { |
8668 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 8709 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
8669 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 8710 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
8670 | struct sk_buff *msg; | 8711 | struct sk_buff *msg; |
8671 | void *hdr; | 8712 | void *hdr; |
8672 | int err; | 8713 | int err; |
8673 | u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid); | 8714 | u32 nlportid = ACCESS_ONCE(wdev->ap_unexpected_nlportid); |
8674 | 8715 | ||
8675 | if (!nlportid) | 8716 | if (!nlportid) |
8676 | return false; | 8717 | return false; |
8677 | 8718 | ||
8678 | msg = nlmsg_new(100, gfp); | 8719 | msg = nlmsg_new(100, gfp); |
8679 | if (!msg) | 8720 | if (!msg) |
8680 | return true; | 8721 | return true; |
8681 | 8722 | ||
8682 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); | 8723 | hdr = nl80211hdr_put(msg, 0, 0, 0, cmd); |
8683 | if (!hdr) { | 8724 | if (!hdr) { |
8684 | nlmsg_free(msg); | 8725 | nlmsg_free(msg); |
8685 | return true; | 8726 | return true; |
8686 | } | 8727 | } |
8687 | 8728 | ||
8688 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8729 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8689 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 8730 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
8690 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) | 8731 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr)) |
8691 | goto nla_put_failure; | 8732 | goto nla_put_failure; |
8692 | 8733 | ||
8693 | err = genlmsg_end(msg, hdr); | 8734 | err = genlmsg_end(msg, hdr); |
8694 | if (err < 0) { | 8735 | if (err < 0) { |
8695 | nlmsg_free(msg); | 8736 | nlmsg_free(msg); |
8696 | return true; | 8737 | return true; |
8697 | } | 8738 | } |
8698 | 8739 | ||
8699 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); | 8740 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); |
8700 | return true; | 8741 | return true; |
8701 | 8742 | ||
8702 | nla_put_failure: | 8743 | nla_put_failure: |
8703 | genlmsg_cancel(msg, hdr); | 8744 | genlmsg_cancel(msg, hdr); |
8704 | nlmsg_free(msg); | 8745 | nlmsg_free(msg); |
8705 | return true; | 8746 | return true; |
8706 | } | 8747 | } |
8707 | 8748 | ||
8708 | bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp) | 8749 | bool nl80211_unexpected_frame(struct net_device *dev, const u8 *addr, gfp_t gfp) |
8709 | { | 8750 | { |
8710 | return __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME, | 8751 | return __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME, |
8711 | addr, gfp); | 8752 | addr, gfp); |
8712 | } | 8753 | } |
8713 | 8754 | ||
8714 | bool nl80211_unexpected_4addr_frame(struct net_device *dev, | 8755 | bool nl80211_unexpected_4addr_frame(struct net_device *dev, |
8715 | const u8 *addr, gfp_t gfp) | 8756 | const u8 *addr, gfp_t gfp) |
8716 | { | 8757 | { |
8717 | return __nl80211_unexpected_frame(dev, | 8758 | return __nl80211_unexpected_frame(dev, |
8718 | NL80211_CMD_UNEXPECTED_4ADDR_FRAME, | 8759 | NL80211_CMD_UNEXPECTED_4ADDR_FRAME, |
8719 | addr, gfp); | 8760 | addr, gfp); |
8720 | } | 8761 | } |
8721 | 8762 | ||
8722 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, | 8763 | int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, |
8723 | struct wireless_dev *wdev, u32 nlportid, | 8764 | struct wireless_dev *wdev, u32 nlportid, |
8724 | int freq, int sig_dbm, | 8765 | int freq, int sig_dbm, |
8725 | const u8 *buf, size_t len, gfp_t gfp) | 8766 | const u8 *buf, size_t len, gfp_t gfp) |
8726 | { | 8767 | { |
8727 | struct net_device *netdev = wdev->netdev; | 8768 | struct net_device *netdev = wdev->netdev; |
8728 | struct sk_buff *msg; | 8769 | struct sk_buff *msg; |
8729 | void *hdr; | 8770 | void *hdr; |
8730 | 8771 | ||
8731 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8772 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8732 | if (!msg) | 8773 | if (!msg) |
8733 | return -ENOMEM; | 8774 | return -ENOMEM; |
8734 | 8775 | ||
8735 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); | 8776 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); |
8736 | if (!hdr) { | 8777 | if (!hdr) { |
8737 | nlmsg_free(msg); | 8778 | nlmsg_free(msg); |
8738 | return -ENOMEM; | 8779 | return -ENOMEM; |
8739 | } | 8780 | } |
8740 | 8781 | ||
8741 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8782 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8742 | (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, | 8783 | (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
8743 | netdev->ifindex)) || | 8784 | netdev->ifindex)) || |
8744 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || | 8785 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq) || |
8745 | (sig_dbm && | 8786 | (sig_dbm && |
8746 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || | 8787 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || |
8747 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) | 8788 | nla_put(msg, NL80211_ATTR_FRAME, len, buf)) |
8748 | goto nla_put_failure; | 8789 | goto nla_put_failure; |
8749 | 8790 | ||
8750 | genlmsg_end(msg, hdr); | 8791 | genlmsg_end(msg, hdr); |
8751 | 8792 | ||
8752 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); | 8793 | return genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, nlportid); |
8753 | 8794 | ||
8754 | nla_put_failure: | 8795 | nla_put_failure: |
8755 | genlmsg_cancel(msg, hdr); | 8796 | genlmsg_cancel(msg, hdr); |
8756 | nlmsg_free(msg); | 8797 | nlmsg_free(msg); |
8757 | return -ENOBUFS; | 8798 | return -ENOBUFS; |
8758 | } | 8799 | } |
8759 | 8800 | ||
8760 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, | 8801 | void nl80211_send_mgmt_tx_status(struct cfg80211_registered_device *rdev, |
8761 | struct wireless_dev *wdev, u64 cookie, | 8802 | struct wireless_dev *wdev, u64 cookie, |
8762 | const u8 *buf, size_t len, bool ack, | 8803 | const u8 *buf, size_t len, bool ack, |
8763 | gfp_t gfp) | 8804 | gfp_t gfp) |
8764 | { | 8805 | { |
8765 | struct net_device *netdev = wdev->netdev; | 8806 | struct net_device *netdev = wdev->netdev; |
8766 | struct sk_buff *msg; | 8807 | struct sk_buff *msg; |
8767 | void *hdr; | 8808 | void *hdr; |
8768 | 8809 | ||
8769 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8810 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8770 | if (!msg) | 8811 | if (!msg) |
8771 | return; | 8812 | return; |
8772 | 8813 | ||
8773 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS); | 8814 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME_TX_STATUS); |
8774 | if (!hdr) { | 8815 | if (!hdr) { |
8775 | nlmsg_free(msg); | 8816 | nlmsg_free(msg); |
8776 | return; | 8817 | return; |
8777 | } | 8818 | } |
8778 | 8819 | ||
8779 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8820 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8780 | (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, | 8821 | (netdev && nla_put_u32(msg, NL80211_ATTR_IFINDEX, |
8781 | netdev->ifindex)) || | 8822 | netdev->ifindex)) || |
8782 | nla_put(msg, NL80211_ATTR_FRAME, len, buf) || | 8823 | nla_put(msg, NL80211_ATTR_FRAME, len, buf) || |
8783 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) || | 8824 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) || |
8784 | (ack && nla_put_flag(msg, NL80211_ATTR_ACK))) | 8825 | (ack && nla_put_flag(msg, NL80211_ATTR_ACK))) |
8785 | goto nla_put_failure; | 8826 | goto nla_put_failure; |
8786 | 8827 | ||
8787 | genlmsg_end(msg, hdr); | 8828 | genlmsg_end(msg, hdr); |
8788 | 8829 | ||
8789 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); | 8830 | genlmsg_multicast(msg, 0, nl80211_mlme_mcgrp.id, gfp); |
8790 | return; | 8831 | return; |
8791 | 8832 | ||
8792 | nla_put_failure: | 8833 | nla_put_failure: |
8793 | genlmsg_cancel(msg, hdr); | 8834 | genlmsg_cancel(msg, hdr); |
8794 | nlmsg_free(msg); | 8835 | nlmsg_free(msg); |
8795 | } | 8836 | } |
8796 | 8837 | ||
8797 | void | 8838 | void |
8798 | nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, | 8839 | nl80211_send_cqm_rssi_notify(struct cfg80211_registered_device *rdev, |
8799 | struct net_device *netdev, | 8840 | struct net_device *netdev, |
8800 | enum nl80211_cqm_rssi_threshold_event rssi_event, | 8841 | enum nl80211_cqm_rssi_threshold_event rssi_event, |
8801 | gfp_t gfp) | 8842 | gfp_t gfp) |
8802 | { | 8843 | { |
8803 | struct sk_buff *msg; | 8844 | struct sk_buff *msg; |
8804 | struct nlattr *pinfoattr; | 8845 | struct nlattr *pinfoattr; |
8805 | void *hdr; | 8846 | void *hdr; |
8806 | 8847 | ||
8807 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8848 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8808 | if (!msg) | 8849 | if (!msg) |
8809 | return; | 8850 | return; |
8810 | 8851 | ||
8811 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); | 8852 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); |
8812 | if (!hdr) { | 8853 | if (!hdr) { |
8813 | nlmsg_free(msg); | 8854 | nlmsg_free(msg); |
8814 | return; | 8855 | return; |
8815 | } | 8856 | } |
8816 | 8857 | ||
8817 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8858 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8818 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) | 8859 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) |
8819 | goto nla_put_failure; | 8860 | goto nla_put_failure; |
8820 | 8861 | ||
8821 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); | 8862 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); |
8822 | if (!pinfoattr) | 8863 | if (!pinfoattr) |
8823 | goto nla_put_failure; | 8864 | goto nla_put_failure; |
8824 | 8865 | ||
8825 | if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, | 8866 | if (nla_put_u32(msg, NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT, |
8826 | rssi_event)) | 8867 | rssi_event)) |
8827 | goto nla_put_failure; | 8868 | goto nla_put_failure; |
8828 | 8869 | ||
8829 | nla_nest_end(msg, pinfoattr); | 8870 | nla_nest_end(msg, pinfoattr); |
8830 | 8871 | ||
8831 | genlmsg_end(msg, hdr); | 8872 | genlmsg_end(msg, hdr); |
8832 | 8873 | ||
8833 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8874 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8834 | nl80211_mlme_mcgrp.id, gfp); | 8875 | nl80211_mlme_mcgrp.id, gfp); |
8835 | return; | 8876 | return; |
8836 | 8877 | ||
8837 | nla_put_failure: | 8878 | nla_put_failure: |
8838 | genlmsg_cancel(msg, hdr); | 8879 | genlmsg_cancel(msg, hdr); |
8839 | nlmsg_free(msg); | 8880 | nlmsg_free(msg); |
8840 | } | 8881 | } |
8841 | 8882 | ||
8842 | void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, | 8883 | void nl80211_gtk_rekey_notify(struct cfg80211_registered_device *rdev, |
8843 | struct net_device *netdev, const u8 *bssid, | 8884 | struct net_device *netdev, const u8 *bssid, |
8844 | const u8 *replay_ctr, gfp_t gfp) | 8885 | const u8 *replay_ctr, gfp_t gfp) |
8845 | { | 8886 | { |
8846 | struct sk_buff *msg; | 8887 | struct sk_buff *msg; |
8847 | struct nlattr *rekey_attr; | 8888 | struct nlattr *rekey_attr; |
8848 | void *hdr; | 8889 | void *hdr; |
8849 | 8890 | ||
8850 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8891 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8851 | if (!msg) | 8892 | if (!msg) |
8852 | return; | 8893 | return; |
8853 | 8894 | ||
8854 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD); | 8895 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_SET_REKEY_OFFLOAD); |
8855 | if (!hdr) { | 8896 | if (!hdr) { |
8856 | nlmsg_free(msg); | 8897 | nlmsg_free(msg); |
8857 | return; | 8898 | return; |
8858 | } | 8899 | } |
8859 | 8900 | ||
8860 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8901 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8861 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 8902 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8862 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) | 8903 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, bssid)) |
8863 | goto nla_put_failure; | 8904 | goto nla_put_failure; |
8864 | 8905 | ||
8865 | rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA); | 8906 | rekey_attr = nla_nest_start(msg, NL80211_ATTR_REKEY_DATA); |
8866 | if (!rekey_attr) | 8907 | if (!rekey_attr) |
8867 | goto nla_put_failure; | 8908 | goto nla_put_failure; |
8868 | 8909 | ||
8869 | if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR, | 8910 | if (nla_put(msg, NL80211_REKEY_DATA_REPLAY_CTR, |
8870 | NL80211_REPLAY_CTR_LEN, replay_ctr)) | 8911 | NL80211_REPLAY_CTR_LEN, replay_ctr)) |
8871 | goto nla_put_failure; | 8912 | goto nla_put_failure; |
8872 | 8913 | ||
8873 | nla_nest_end(msg, rekey_attr); | 8914 | nla_nest_end(msg, rekey_attr); |
8874 | 8915 | ||
8875 | genlmsg_end(msg, hdr); | 8916 | genlmsg_end(msg, hdr); |
8876 | 8917 | ||
8877 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8918 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8878 | nl80211_mlme_mcgrp.id, gfp); | 8919 | nl80211_mlme_mcgrp.id, gfp); |
8879 | return; | 8920 | return; |
8880 | 8921 | ||
8881 | nla_put_failure: | 8922 | nla_put_failure: |
8882 | genlmsg_cancel(msg, hdr); | 8923 | genlmsg_cancel(msg, hdr); |
8883 | nlmsg_free(msg); | 8924 | nlmsg_free(msg); |
8884 | } | 8925 | } |
8885 | 8926 | ||
8886 | void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, | 8927 | void nl80211_pmksa_candidate_notify(struct cfg80211_registered_device *rdev, |
8887 | struct net_device *netdev, int index, | 8928 | struct net_device *netdev, int index, |
8888 | const u8 *bssid, bool preauth, gfp_t gfp) | 8929 | const u8 *bssid, bool preauth, gfp_t gfp) |
8889 | { | 8930 | { |
8890 | struct sk_buff *msg; | 8931 | struct sk_buff *msg; |
8891 | struct nlattr *attr; | 8932 | struct nlattr *attr; |
8892 | void *hdr; | 8933 | void *hdr; |
8893 | 8934 | ||
8894 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8935 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8895 | if (!msg) | 8936 | if (!msg) |
8896 | return; | 8937 | return; |
8897 | 8938 | ||
8898 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE); | 8939 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PMKSA_CANDIDATE); |
8899 | if (!hdr) { | 8940 | if (!hdr) { |
8900 | nlmsg_free(msg); | 8941 | nlmsg_free(msg); |
8901 | return; | 8942 | return; |
8902 | } | 8943 | } |
8903 | 8944 | ||
8904 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 8945 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8905 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) | 8946 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) |
8906 | goto nla_put_failure; | 8947 | goto nla_put_failure; |
8907 | 8948 | ||
8908 | attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); | 8949 | attr = nla_nest_start(msg, NL80211_ATTR_PMKSA_CANDIDATE); |
8909 | if (!attr) | 8950 | if (!attr) |
8910 | goto nla_put_failure; | 8951 | goto nla_put_failure; |
8911 | 8952 | ||
8912 | if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) || | 8953 | if (nla_put_u32(msg, NL80211_PMKSA_CANDIDATE_INDEX, index) || |
8913 | nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) || | 8954 | nla_put(msg, NL80211_PMKSA_CANDIDATE_BSSID, ETH_ALEN, bssid) || |
8914 | (preauth && | 8955 | (preauth && |
8915 | nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH))) | 8956 | nla_put_flag(msg, NL80211_PMKSA_CANDIDATE_PREAUTH))) |
8916 | goto nla_put_failure; | 8957 | goto nla_put_failure; |
8917 | 8958 | ||
8918 | nla_nest_end(msg, attr); | 8959 | nla_nest_end(msg, attr); |
8919 | 8960 | ||
8920 | genlmsg_end(msg, hdr); | 8961 | genlmsg_end(msg, hdr); |
8921 | 8962 | ||
8922 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8963 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8923 | nl80211_mlme_mcgrp.id, gfp); | 8964 | nl80211_mlme_mcgrp.id, gfp); |
8924 | return; | 8965 | return; |
8925 | 8966 | ||
8926 | nla_put_failure: | 8967 | nla_put_failure: |
8927 | genlmsg_cancel(msg, hdr); | 8968 | genlmsg_cancel(msg, hdr); |
8928 | nlmsg_free(msg); | 8969 | nlmsg_free(msg); |
8929 | } | 8970 | } |
8930 | 8971 | ||
8931 | void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, | 8972 | void nl80211_ch_switch_notify(struct cfg80211_registered_device *rdev, |
8932 | struct net_device *netdev, | 8973 | struct net_device *netdev, |
8933 | struct cfg80211_chan_def *chandef, gfp_t gfp) | 8974 | struct cfg80211_chan_def *chandef, gfp_t gfp) |
8934 | { | 8975 | { |
8935 | struct sk_buff *msg; | 8976 | struct sk_buff *msg; |
8936 | void *hdr; | 8977 | void *hdr; |
8937 | 8978 | ||
8938 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 8979 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
8939 | if (!msg) | 8980 | if (!msg) |
8940 | return; | 8981 | return; |
8941 | 8982 | ||
8942 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY); | 8983 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_CH_SWITCH_NOTIFY); |
8943 | if (!hdr) { | 8984 | if (!hdr) { |
8944 | nlmsg_free(msg); | 8985 | nlmsg_free(msg); |
8945 | return; | 8986 | return; |
8946 | } | 8987 | } |
8947 | 8988 | ||
8948 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) | 8989 | if (nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex)) |
8949 | goto nla_put_failure; | 8990 | goto nla_put_failure; |
8950 | 8991 | ||
8951 | if (nl80211_send_chandef(msg, chandef)) | 8992 | if (nl80211_send_chandef(msg, chandef)) |
8952 | goto nla_put_failure; | 8993 | goto nla_put_failure; |
8953 | 8994 | ||
8954 | genlmsg_end(msg, hdr); | 8995 | genlmsg_end(msg, hdr); |
8955 | 8996 | ||
8956 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 8997 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
8957 | nl80211_mlme_mcgrp.id, gfp); | 8998 | nl80211_mlme_mcgrp.id, gfp); |
8958 | return; | 8999 | return; |
8959 | 9000 | ||
8960 | nla_put_failure: | 9001 | nla_put_failure: |
8961 | genlmsg_cancel(msg, hdr); | 9002 | genlmsg_cancel(msg, hdr); |
8962 | nlmsg_free(msg); | 9003 | nlmsg_free(msg); |
8963 | } | 9004 | } |
8964 | 9005 | ||
8965 | void | 9006 | void |
8966 | nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev, | 9007 | nl80211_send_cqm_txe_notify(struct cfg80211_registered_device *rdev, |
8967 | struct net_device *netdev, const u8 *peer, | 9008 | struct net_device *netdev, const u8 *peer, |
8968 | u32 num_packets, u32 rate, u32 intvl, gfp_t gfp) | 9009 | u32 num_packets, u32 rate, u32 intvl, gfp_t gfp) |
8969 | { | 9010 | { |
8970 | struct sk_buff *msg; | 9011 | struct sk_buff *msg; |
8971 | struct nlattr *pinfoattr; | 9012 | struct nlattr *pinfoattr; |
8972 | void *hdr; | 9013 | void *hdr; |
8973 | 9014 | ||
8974 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); | 9015 | msg = nlmsg_new(NLMSG_GOODSIZE, gfp); |
8975 | if (!msg) | 9016 | if (!msg) |
8976 | return; | 9017 | return; |
8977 | 9018 | ||
8978 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); | 9019 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); |
8979 | if (!hdr) { | 9020 | if (!hdr) { |
8980 | nlmsg_free(msg); | 9021 | nlmsg_free(msg); |
8981 | return; | 9022 | return; |
8982 | } | 9023 | } |
8983 | 9024 | ||
8984 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 9025 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
8985 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 9026 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
8986 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) | 9027 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) |
8987 | goto nla_put_failure; | 9028 | goto nla_put_failure; |
8988 | 9029 | ||
8989 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); | 9030 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); |
8990 | if (!pinfoattr) | 9031 | if (!pinfoattr) |
8991 | goto nla_put_failure; | 9032 | goto nla_put_failure; |
8992 | 9033 | ||
8993 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets)) | 9034 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_PKTS, num_packets)) |
8994 | goto nla_put_failure; | 9035 | goto nla_put_failure; |
8995 | 9036 | ||
8996 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate)) | 9037 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_RATE, rate)) |
8997 | goto nla_put_failure; | 9038 | goto nla_put_failure; |
8998 | 9039 | ||
8999 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl)) | 9040 | if (nla_put_u32(msg, NL80211_ATTR_CQM_TXE_INTVL, intvl)) |
9000 | goto nla_put_failure; | 9041 | goto nla_put_failure; |
9001 | 9042 | ||
9002 | nla_nest_end(msg, pinfoattr); | 9043 | nla_nest_end(msg, pinfoattr); |
9003 | 9044 | ||
9004 | genlmsg_end(msg, hdr); | 9045 | genlmsg_end(msg, hdr); |
9005 | 9046 | ||
9006 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9047 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
9007 | nl80211_mlme_mcgrp.id, gfp); | 9048 | nl80211_mlme_mcgrp.id, gfp); |
9008 | return; | 9049 | return; |
9009 | 9050 | ||
9010 | nla_put_failure: | 9051 | nla_put_failure: |
9011 | genlmsg_cancel(msg, hdr); | 9052 | genlmsg_cancel(msg, hdr); |
9012 | nlmsg_free(msg); | 9053 | nlmsg_free(msg); |
9013 | } | 9054 | } |
9014 | 9055 | ||
9015 | void | 9056 | void |
9016 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, | 9057 | nl80211_send_cqm_pktloss_notify(struct cfg80211_registered_device *rdev, |
9017 | struct net_device *netdev, const u8 *peer, | 9058 | struct net_device *netdev, const u8 *peer, |
9018 | u32 num_packets, gfp_t gfp) | 9059 | u32 num_packets, gfp_t gfp) |
9019 | { | 9060 | { |
9020 | struct sk_buff *msg; | 9061 | struct sk_buff *msg; |
9021 | struct nlattr *pinfoattr; | 9062 | struct nlattr *pinfoattr; |
9022 | void *hdr; | 9063 | void *hdr; |
9023 | 9064 | ||
9024 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 9065 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
9025 | if (!msg) | 9066 | if (!msg) |
9026 | return; | 9067 | return; |
9027 | 9068 | ||
9028 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); | 9069 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_NOTIFY_CQM); |
9029 | if (!hdr) { | 9070 | if (!hdr) { |
9030 | nlmsg_free(msg); | 9071 | nlmsg_free(msg); |
9031 | return; | 9072 | return; |
9032 | } | 9073 | } |
9033 | 9074 | ||
9034 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 9075 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
9035 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || | 9076 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex) || |
9036 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) | 9077 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) |
9037 | goto nla_put_failure; | 9078 | goto nla_put_failure; |
9038 | 9079 | ||
9039 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); | 9080 | pinfoattr = nla_nest_start(msg, NL80211_ATTR_CQM); |
9040 | if (!pinfoattr) | 9081 | if (!pinfoattr) |
9041 | goto nla_put_failure; | 9082 | goto nla_put_failure; |
9042 | 9083 | ||
9043 | if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets)) | 9084 | if (nla_put_u32(msg, NL80211_ATTR_CQM_PKT_LOSS_EVENT, num_packets)) |
9044 | goto nla_put_failure; | 9085 | goto nla_put_failure; |
9045 | 9086 | ||
9046 | nla_nest_end(msg, pinfoattr); | 9087 | nla_nest_end(msg, pinfoattr); |
9047 | 9088 | ||
9048 | genlmsg_end(msg, hdr); | 9089 | genlmsg_end(msg, hdr); |
9049 | 9090 | ||
9050 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9091 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
9051 | nl80211_mlme_mcgrp.id, gfp); | 9092 | nl80211_mlme_mcgrp.id, gfp); |
9052 | return; | 9093 | return; |
9053 | 9094 | ||
9054 | nla_put_failure: | 9095 | nla_put_failure: |
9055 | genlmsg_cancel(msg, hdr); | 9096 | genlmsg_cancel(msg, hdr); |
9056 | nlmsg_free(msg); | 9097 | nlmsg_free(msg); |
9057 | } | 9098 | } |
9058 | 9099 | ||
9059 | void cfg80211_probe_status(struct net_device *dev, const u8 *addr, | 9100 | void cfg80211_probe_status(struct net_device *dev, const u8 *addr, |
9060 | u64 cookie, bool acked, gfp_t gfp) | 9101 | u64 cookie, bool acked, gfp_t gfp) |
9061 | { | 9102 | { |
9062 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 9103 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
9063 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 9104 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
9064 | struct sk_buff *msg; | 9105 | struct sk_buff *msg; |
9065 | void *hdr; | 9106 | void *hdr; |
9066 | int err; | 9107 | int err; |
9067 | 9108 | ||
9068 | trace_cfg80211_probe_status(dev, addr, cookie, acked); | 9109 | trace_cfg80211_probe_status(dev, addr, cookie, acked); |
9069 | 9110 | ||
9070 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 9111 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
9071 | 9112 | ||
9072 | if (!msg) | 9113 | if (!msg) |
9073 | return; | 9114 | return; |
9074 | 9115 | ||
9075 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT); | 9116 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_PROBE_CLIENT); |
9076 | if (!hdr) { | 9117 | if (!hdr) { |
9077 | nlmsg_free(msg); | 9118 | nlmsg_free(msg); |
9078 | return; | 9119 | return; |
9079 | } | 9120 | } |
9080 | 9121 | ||
9081 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 9122 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
9082 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 9123 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
9083 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || | 9124 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) || |
9084 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) || | 9125 | nla_put_u64(msg, NL80211_ATTR_COOKIE, cookie) || |
9085 | (acked && nla_put_flag(msg, NL80211_ATTR_ACK))) | 9126 | (acked && nla_put_flag(msg, NL80211_ATTR_ACK))) |
9086 | goto nla_put_failure; | 9127 | goto nla_put_failure; |
9087 | 9128 | ||
9088 | err = genlmsg_end(msg, hdr); | 9129 | err = genlmsg_end(msg, hdr); |
9089 | if (err < 0) { | 9130 | if (err < 0) { |
9090 | nlmsg_free(msg); | 9131 | nlmsg_free(msg); |
9091 | return; | 9132 | return; |
9092 | } | 9133 | } |
9093 | 9134 | ||
9094 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9135 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
9095 | nl80211_mlme_mcgrp.id, gfp); | 9136 | nl80211_mlme_mcgrp.id, gfp); |
9096 | return; | 9137 | return; |
9097 | 9138 | ||
9098 | nla_put_failure: | 9139 | nla_put_failure: |
9099 | genlmsg_cancel(msg, hdr); | 9140 | genlmsg_cancel(msg, hdr); |
9100 | nlmsg_free(msg); | 9141 | nlmsg_free(msg); |
9101 | } | 9142 | } |
9102 | EXPORT_SYMBOL(cfg80211_probe_status); | 9143 | EXPORT_SYMBOL(cfg80211_probe_status); |
9103 | 9144 | ||
9104 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, | 9145 | void cfg80211_report_obss_beacon(struct wiphy *wiphy, |
9105 | const u8 *frame, size_t len, | 9146 | const u8 *frame, size_t len, |
9106 | int freq, int sig_dbm) | 9147 | int freq, int sig_dbm) |
9107 | { | 9148 | { |
9108 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 9149 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
9109 | struct sk_buff *msg; | 9150 | struct sk_buff *msg; |
9110 | void *hdr; | 9151 | void *hdr; |
9111 | struct cfg80211_beacon_registration *reg; | 9152 | struct cfg80211_beacon_registration *reg; |
9112 | 9153 | ||
9113 | trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm); | 9154 | trace_cfg80211_report_obss_beacon(wiphy, frame, len, freq, sig_dbm); |
9114 | 9155 | ||
9115 | spin_lock_bh(&rdev->beacon_registrations_lock); | 9156 | spin_lock_bh(&rdev->beacon_registrations_lock); |
9116 | list_for_each_entry(reg, &rdev->beacon_registrations, list) { | 9157 | list_for_each_entry(reg, &rdev->beacon_registrations, list) { |
9117 | msg = nlmsg_new(len + 100, GFP_ATOMIC); | 9158 | msg = nlmsg_new(len + 100, GFP_ATOMIC); |
9118 | if (!msg) { | 9159 | if (!msg) { |
9119 | spin_unlock_bh(&rdev->beacon_registrations_lock); | 9160 | spin_unlock_bh(&rdev->beacon_registrations_lock); |
9120 | return; | 9161 | return; |
9121 | } | 9162 | } |
9122 | 9163 | ||
9123 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); | 9164 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_FRAME); |
9124 | if (!hdr) | 9165 | if (!hdr) |
9125 | goto nla_put_failure; | 9166 | goto nla_put_failure; |
9126 | 9167 | ||
9127 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 9168 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
9128 | (freq && | 9169 | (freq && |
9129 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) || | 9170 | nla_put_u32(msg, NL80211_ATTR_WIPHY_FREQ, freq)) || |
9130 | (sig_dbm && | 9171 | (sig_dbm && |
9131 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || | 9172 | nla_put_u32(msg, NL80211_ATTR_RX_SIGNAL_DBM, sig_dbm)) || |
9132 | nla_put(msg, NL80211_ATTR_FRAME, len, frame)) | 9173 | nla_put(msg, NL80211_ATTR_FRAME, len, frame)) |
9133 | goto nla_put_failure; | 9174 | goto nla_put_failure; |
9134 | 9175 | ||
9135 | genlmsg_end(msg, hdr); | 9176 | genlmsg_end(msg, hdr); |
9136 | 9177 | ||
9137 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid); | 9178 | genlmsg_unicast(wiphy_net(&rdev->wiphy), msg, reg->nlportid); |
9138 | } | 9179 | } |
9139 | spin_unlock_bh(&rdev->beacon_registrations_lock); | 9180 | spin_unlock_bh(&rdev->beacon_registrations_lock); |
9140 | return; | 9181 | return; |
9141 | 9182 | ||
9142 | nla_put_failure: | 9183 | nla_put_failure: |
9143 | spin_unlock_bh(&rdev->beacon_registrations_lock); | 9184 | spin_unlock_bh(&rdev->beacon_registrations_lock); |
9144 | if (hdr) | 9185 | if (hdr) |
9145 | genlmsg_cancel(msg, hdr); | 9186 | genlmsg_cancel(msg, hdr); |
9146 | nlmsg_free(msg); | 9187 | nlmsg_free(msg); |
9147 | } | 9188 | } |
9148 | EXPORT_SYMBOL(cfg80211_report_obss_beacon); | 9189 | EXPORT_SYMBOL(cfg80211_report_obss_beacon); |
9149 | 9190 | ||
9150 | void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, | 9191 | void cfg80211_tdls_oper_request(struct net_device *dev, const u8 *peer, |
9151 | enum nl80211_tdls_operation oper, | 9192 | enum nl80211_tdls_operation oper, |
9152 | u16 reason_code, gfp_t gfp) | 9193 | u16 reason_code, gfp_t gfp) |
9153 | { | 9194 | { |
9154 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 9195 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
9155 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); | 9196 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); |
9156 | struct sk_buff *msg; | 9197 | struct sk_buff *msg; |
9157 | void *hdr; | 9198 | void *hdr; |
9158 | int err; | 9199 | int err; |
9159 | 9200 | ||
9160 | trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper, | 9201 | trace_cfg80211_tdls_oper_request(wdev->wiphy, dev, peer, oper, |
9161 | reason_code); | 9202 | reason_code); |
9162 | 9203 | ||
9163 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); | 9204 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp); |
9164 | if (!msg) | 9205 | if (!msg) |
9165 | return; | 9206 | return; |
9166 | 9207 | ||
9167 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER); | 9208 | hdr = nl80211hdr_put(msg, 0, 0, 0, NL80211_CMD_TDLS_OPER); |
9168 | if (!hdr) { | 9209 | if (!hdr) { |
9169 | nlmsg_free(msg); | 9210 | nlmsg_free(msg); |
9170 | return; | 9211 | return; |
9171 | } | 9212 | } |
9172 | 9213 | ||
9173 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || | 9214 | if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) || |
9174 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || | 9215 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) || |
9175 | nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) || | 9216 | nla_put_u8(msg, NL80211_ATTR_TDLS_OPERATION, oper) || |
9176 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) || | 9217 | nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer) || |
9177 | (reason_code > 0 && | 9218 | (reason_code > 0 && |
9178 | nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code))) | 9219 | nla_put_u16(msg, NL80211_ATTR_REASON_CODE, reason_code))) |
9179 | goto nla_put_failure; | 9220 | goto nla_put_failure; |
9180 | 9221 | ||
9181 | err = genlmsg_end(msg, hdr); | 9222 | err = genlmsg_end(msg, hdr); |
9182 | if (err < 0) { | 9223 | if (err < 0) { |
9183 | nlmsg_free(msg); | 9224 | nlmsg_free(msg); |
9184 | return; | 9225 | return; |
9185 | } | 9226 | } |
9186 | 9227 | ||
9187 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, | 9228 | genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0, |
9188 | nl80211_mlme_mcgrp.id, gfp); | 9229 | nl80211_mlme_mcgrp.id, gfp); |
9189 | return; | 9230 | return; |
9190 | 9231 | ||
9191 | nla_put_failure: | 9232 | nla_put_failure: |
9192 | genlmsg_cancel(msg, hdr); | 9233 | genlmsg_cancel(msg, hdr); |
9193 | nlmsg_free(msg); | 9234 | nlmsg_free(msg); |
9194 | } | 9235 | } |
9195 | EXPORT_SYMBOL(cfg80211_tdls_oper_request); | 9236 | EXPORT_SYMBOL(cfg80211_tdls_oper_request); |
9196 | 9237 | ||
9197 | static int nl80211_netlink_notify(struct notifier_block * nb, | 9238 | static int nl80211_netlink_notify(struct notifier_block * nb, |
9198 | unsigned long state, | 9239 | unsigned long state, |
9199 | void *_notify) | 9240 | void *_notify) |
9200 | { | 9241 | { |
9201 | struct netlink_notify *notify = _notify; | 9242 | struct netlink_notify *notify = _notify; |
9202 | struct cfg80211_registered_device *rdev; | 9243 | struct cfg80211_registered_device *rdev; |
9203 | struct wireless_dev *wdev; | 9244 | struct wireless_dev *wdev; |
9204 | struct cfg80211_beacon_registration *reg, *tmp; | 9245 | struct cfg80211_beacon_registration *reg, *tmp; |
9205 | 9246 | ||
9206 | if (state != NETLINK_URELEASE) | 9247 | if (state != NETLINK_URELEASE) |
9207 | return NOTIFY_DONE; | 9248 | return NOTIFY_DONE; |
9208 | 9249 | ||
9209 | rcu_read_lock(); | 9250 | rcu_read_lock(); |
9210 | 9251 | ||
9211 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { | 9252 | list_for_each_entry_rcu(rdev, &cfg80211_rdev_list, list) { |
9212 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) | 9253 | list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) |
9213 | cfg80211_mlme_unregister_socket(wdev, notify->portid); | 9254 | cfg80211_mlme_unregister_socket(wdev, notify->portid); |
9214 | 9255 | ||
9215 | spin_lock_bh(&rdev->beacon_registrations_lock); | 9256 | spin_lock_bh(&rdev->beacon_registrations_lock); |
9216 | list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations, | 9257 | list_for_each_entry_safe(reg, tmp, &rdev->beacon_registrations, |
9217 | list) { | 9258 | list) { |
9218 | if (reg->nlportid == notify->portid) { | 9259 | if (reg->nlportid == notify->portid) { |
9219 | list_del(®->list); | 9260 | list_del(®->list); |
9220 | kfree(reg); | 9261 | kfree(reg); |
9221 | break; | 9262 | break; |
9222 | } | 9263 | } |
9223 | } | 9264 | } |
9224 | spin_unlock_bh(&rdev->beacon_registrations_lock); | 9265 | spin_unlock_bh(&rdev->beacon_registrations_lock); |
9225 | } | 9266 | } |
9226 | 9267 | ||
9227 | rcu_read_unlock(); | 9268 | rcu_read_unlock(); |
9228 | 9269 | ||
9229 | return NOTIFY_DONE; | 9270 | return NOTIFY_DONE; |
9230 | } | 9271 | } |
9231 | 9272 | ||
9232 | static struct notifier_block nl80211_netlink_notifier = { | 9273 | static struct notifier_block nl80211_netlink_notifier = { |
9233 | .notifier_call = nl80211_netlink_notify, | 9274 | .notifier_call = nl80211_netlink_notify, |
9234 | }; | 9275 | }; |
9235 | 9276 | ||
9236 | /* initialisation/exit functions */ | 9277 | /* initialisation/exit functions */ |
9237 | 9278 | ||
9238 | int nl80211_init(void) | 9279 | int nl80211_init(void) |
9239 | { | 9280 | { |
9240 | int err; | 9281 | int err; |
9241 | 9282 | ||
9242 | err = genl_register_family_with_ops(&nl80211_fam, | 9283 | err = genl_register_family_with_ops(&nl80211_fam, |
9243 | nl80211_ops, ARRAY_SIZE(nl80211_ops)); | 9284 | nl80211_ops, ARRAY_SIZE(nl80211_ops)); |
9244 | if (err) | 9285 | if (err) |
9245 | return err; | 9286 | return err; |
9246 | 9287 | ||
9247 | err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); | 9288 | err = genl_register_mc_group(&nl80211_fam, &nl80211_config_mcgrp); |
9248 | if (err) | 9289 | if (err) |
9249 | goto err_out; | 9290 | goto err_out; |
9250 | 9291 | ||
9251 | err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp); | 9292 | err = genl_register_mc_group(&nl80211_fam, &nl80211_scan_mcgrp); |
9252 | if (err) | 9293 | if (err) |
9253 | goto err_out; | 9294 | goto err_out; |
9254 | 9295 | ||
9255 | err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp); | 9296 | err = genl_register_mc_group(&nl80211_fam, &nl80211_regulatory_mcgrp); |
9256 | if (err) | 9297 | if (err) |
9257 | goto err_out; | 9298 | goto err_out; |
9258 | 9299 | ||
9259 | err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp); | 9300 | err = genl_register_mc_group(&nl80211_fam, &nl80211_mlme_mcgrp); |
9260 | if (err) | 9301 | if (err) |
9261 | goto err_out; | 9302 | goto err_out; |
9262 | 9303 | ||
9263 | #ifdef CONFIG_NL80211_TESTMODE | 9304 | #ifdef CONFIG_NL80211_TESTMODE |
9264 | err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp); | 9305 | err = genl_register_mc_group(&nl80211_fam, &nl80211_testmode_mcgrp); |
9265 | if (err) | 9306 | if (err) |
9266 | goto err_out; | 9307 | goto err_out; |
9267 | #endif | 9308 | #endif |
9268 | 9309 | ||
9269 | err = netlink_register_notifier(&nl80211_netlink_notifier); | 9310 | err = netlink_register_notifier(&nl80211_netlink_notifier); |
9270 | if (err) | 9311 | if (err) |
9271 | goto err_out; | 9312 | goto err_out; |
9272 | 9313 | ||
9273 | return 0; | 9314 | return 0; |
9274 | err_out: | 9315 | err_out: |
9275 | genl_unregister_family(&nl80211_fam); | 9316 | genl_unregister_family(&nl80211_fam); |
9276 | return err; | 9317 | return err; |
9277 | } | 9318 | } |
9278 | 9319 | ||
9279 | void nl80211_exit(void) | 9320 | void nl80211_exit(void) |
9280 | { | 9321 | { |
9281 | netlink_unregister_notifier(&nl80211_netlink_notifier); | 9322 | netlink_unregister_notifier(&nl80211_netlink_notifier); |
9282 | genl_unregister_family(&nl80211_fam); | 9323 | genl_unregister_family(&nl80211_fam); |
9283 | } | 9324 | } |
9284 | 9325 |