2 * cfg80211 - wext compat code
4 * This is temporary code until all wireless functionality is migrated
5 * into cfg80211, when that happens all the exports here go away and
6 * we directly assign the wireless handlers of wireless interfaces.
8 * Copyright 2008 Johannes Berg <johannes@sipsolutions.net>
11 #include <linux/wireless.h>
12 #include <linux/nl80211.h>
13 #include <linux/if_arp.h>
14 #include <net/iw_handler.h>
15 #include <net/cfg80211.h>
18 int cfg80211_wext_giwname(struct net_device
*dev
,
19 struct iw_request_info
*info
,
20 char *name
, char *extra
)
22 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
23 struct ieee80211_supported_band
*sband
;
24 bool is_ht
= false, is_a
= false, is_b
= false, is_g
= false;
29 sband
= wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
];
32 is_ht
|= sband
->ht_cap
.ht_supported
;
35 sband
= wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
];
38 /* Check for mandatory rates */
39 for (i
= 0; i
< sband
->n_bitrates
; i
++) {
40 if (sband
->bitrates
[i
].bitrate
== 10)
42 if (sband
->bitrates
[i
].bitrate
== 60)
45 is_ht
|= sband
->ht_cap
.ht_supported
;
48 strcpy(name
, "IEEE 802.11");
60 EXPORT_SYMBOL_GPL(cfg80211_wext_giwname
);
62 int cfg80211_wext_siwmode(struct net_device
*dev
, struct iw_request_info
*info
,
63 u32
*mode
, char *extra
)
65 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
66 struct cfg80211_registered_device
*rdev
;
67 struct vif_params vifparams
;
68 enum nl80211_iftype type
;
74 rdev
= wiphy_to_dev(wdev
->wiphy
);
76 if (!rdev
->ops
->change_virtual_intf
)
79 /* don't support changing VLANs, you just re-create them */
80 if (wdev
->iftype
== NL80211_IFTYPE_AP_VLAN
)
85 type
= NL80211_IFTYPE_STATION
;
88 type
= NL80211_IFTYPE_ADHOC
;
91 type
= NL80211_IFTYPE_WDS
;
94 type
= NL80211_IFTYPE_MONITOR
;
100 if (type
== wdev
->iftype
)
103 memset(&vifparams
, 0, sizeof(vifparams
));
105 ret
= rdev
->ops
->change_virtual_intf(wdev
->wiphy
, dev
->ifindex
, type
,
107 WARN_ON(!ret
&& wdev
->iftype
!= type
);
111 EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode
);
113 int cfg80211_wext_giwmode(struct net_device
*dev
, struct iw_request_info
*info
,
114 u32
*mode
, char *extra
)
116 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
121 switch (wdev
->iftype
) {
122 case NL80211_IFTYPE_AP
:
123 *mode
= IW_MODE_MASTER
;
125 case NL80211_IFTYPE_STATION
:
126 *mode
= IW_MODE_INFRA
;
128 case NL80211_IFTYPE_ADHOC
:
129 *mode
= IW_MODE_ADHOC
;
131 case NL80211_IFTYPE_MONITOR
:
132 *mode
= IW_MODE_MONITOR
;
134 case NL80211_IFTYPE_WDS
:
135 *mode
= IW_MODE_REPEAT
;
137 case NL80211_IFTYPE_AP_VLAN
:
138 *mode
= IW_MODE_SECOND
; /* FIXME */
141 *mode
= IW_MODE_AUTO
;
146 EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode
);
149 int cfg80211_wext_giwrange(struct net_device
*dev
,
150 struct iw_request_info
*info
,
151 struct iw_point
*data
, char *extra
)
153 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
154 struct iw_range
*range
= (struct iw_range
*) extra
;
155 enum ieee80211_band band
;
161 data
->length
= sizeof(struct iw_range
);
162 memset(range
, 0, sizeof(struct iw_range
));
164 range
->we_version_compiled
= WIRELESS_EXT
;
165 range
->we_version_source
= 21;
166 range
->retry_capa
= IW_RETRY_LIMIT
;
167 range
->retry_flags
= IW_RETRY_LIMIT
;
168 range
->min_retry
= 0;
169 range
->max_retry
= 255;
171 range
->max_rts
= 2347;
172 range
->min_frag
= 256;
173 range
->max_frag
= 2346;
175 range
->encoding_size
[0] = 5;
176 range
->encoding_size
[1] = 13;
177 range
->num_encoding_sizes
= 2;
178 range
->max_encoding_tokens
= 4;
180 range
->max_qual
.updated
= IW_QUAL_NOISE_INVALID
;
182 switch (wdev
->wiphy
->signal_type
) {
183 case CFG80211_SIGNAL_TYPE_NONE
:
185 case CFG80211_SIGNAL_TYPE_MBM
:
186 range
->max_qual
.level
= -110;
187 range
->max_qual
.qual
= 70;
188 range
->avg_qual
.qual
= 35;
189 range
->max_qual
.updated
|= IW_QUAL_DBM
;
190 range
->max_qual
.updated
|= IW_QUAL_QUAL_UPDATED
;
191 range
->max_qual
.updated
|= IW_QUAL_LEVEL_UPDATED
;
193 case CFG80211_SIGNAL_TYPE_UNSPEC
:
194 range
->max_qual
.level
= 100;
195 range
->max_qual
.qual
= 100;
196 range
->avg_qual
.qual
= 50;
197 range
->max_qual
.updated
|= IW_QUAL_QUAL_UPDATED
;
198 range
->max_qual
.updated
|= IW_QUAL_LEVEL_UPDATED
;
202 range
->avg_qual
.level
= range
->max_qual
.level
/ 2;
203 range
->avg_qual
.noise
= range
->max_qual
.noise
/ 2;
204 range
->avg_qual
.updated
= range
->max_qual
.updated
;
206 range
->enc_capa
= IW_ENC_CAPA_WPA
| IW_ENC_CAPA_WPA2
|
207 IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
209 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
211 struct ieee80211_supported_band
*sband
;
213 sband
= wdev
->wiphy
->bands
[band
];
218 for (i
= 0; i
< sband
->n_channels
&& c
< IW_MAX_FREQUENCIES
; i
++) {
219 struct ieee80211_channel
*chan
= &sband
->channels
[i
];
221 if (!(chan
->flags
& IEEE80211_CHAN_DISABLED
)) {
223 ieee80211_frequency_to_channel(
225 range
->freq
[c
].m
= chan
->center_freq
;
226 range
->freq
[c
].e
= 6;
231 range
->num_channels
= c
;
232 range
->num_frequency
= c
;
234 IW_EVENT_CAPA_SET_KERNEL(range
->event_capa
);
235 IW_EVENT_CAPA_SET(range
->event_capa
, SIOCGIWAP
);
236 IW_EVENT_CAPA_SET(range
->event_capa
, SIOCGIWSCAN
);
238 range
->scan_capa
|= IW_SCAN_CAPA_ESSID
;
242 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange
);
244 int cfg80211_wext_siwmlme(struct net_device
*dev
,
245 struct iw_request_info
*info
,
246 struct iw_point
*data
, char *extra
)
248 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
249 struct iw_mlme
*mlme
= (struct iw_mlme
*)extra
;
250 struct cfg80211_registered_device
*rdev
;
252 struct cfg80211_disassoc_request disassoc
;
253 struct cfg80211_deauth_request deauth
;
259 rdev
= wiphy_to_dev(wdev
->wiphy
);
261 if (wdev
->iftype
!= NL80211_IFTYPE_STATION
)
264 if (mlme
->addr
.sa_family
!= ARPHRD_ETHER
)
267 memset(&cmd
, 0, sizeof(cmd
));
271 if (!rdev
->ops
->deauth
)
273 cmd
.deauth
.peer_addr
= mlme
->addr
.sa_data
;
274 cmd
.deauth
.reason_code
= mlme
->reason_code
;
275 return rdev
->ops
->deauth(wdev
->wiphy
, dev
, &cmd
.deauth
);
276 case IW_MLME_DISASSOC
:
277 if (!rdev
->ops
->disassoc
)
279 cmd
.disassoc
.peer_addr
= mlme
->addr
.sa_data
;
280 cmd
.disassoc
.reason_code
= mlme
->reason_code
;
281 return rdev
->ops
->disassoc(wdev
->wiphy
, dev
, &cmd
.disassoc
);
286 EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme
);
290 * cfg80211_wext_freq - get wext frequency for non-"auto"
292 * @freq: the wext freq encoding
294 * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
296 struct ieee80211_channel
*cfg80211_wext_freq(struct wiphy
*wiphy
,
297 struct iw_freq
*freq
)
303 return ieee80211_get_channel(wiphy
,
304 ieee80211_channel_to_frequency(freq
->m
));
306 int i
, div
= 1000000;
307 for (i
= 0; i
< freq
->e
; i
++)
310 return ieee80211_get_channel(wiphy
, freq
->m
/ div
);
312 return ERR_PTR(-EINVAL
);
316 EXPORT_SYMBOL_GPL(cfg80211_wext_freq
);
318 int cfg80211_wext_siwrts(struct net_device
*dev
,
319 struct iw_request_info
*info
,
320 struct iw_param
*rts
, char *extra
)
322 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
323 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
324 u32 orts
= wdev
->wiphy
->rts_threshold
;
327 if (rts
->disabled
|| !rts
->fixed
)
328 wdev
->wiphy
->rts_threshold
= (u32
) -1;
329 else if (rts
->value
< 0)
332 wdev
->wiphy
->rts_threshold
= rts
->value
;
334 err
= rdev
->ops
->set_wiphy_params(wdev
->wiphy
,
335 WIPHY_PARAM_RTS_THRESHOLD
);
337 wdev
->wiphy
->rts_threshold
= orts
;
341 EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts
);
343 int cfg80211_wext_giwrts(struct net_device
*dev
,
344 struct iw_request_info
*info
,
345 struct iw_param
*rts
, char *extra
)
347 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
349 rts
->value
= wdev
->wiphy
->rts_threshold
;
350 rts
->disabled
= rts
->value
== (u32
) -1;
355 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts
);
357 int cfg80211_wext_siwfrag(struct net_device
*dev
,
358 struct iw_request_info
*info
,
359 struct iw_param
*frag
, char *extra
)
361 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
362 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
363 u32 ofrag
= wdev
->wiphy
->frag_threshold
;
366 if (frag
->disabled
|| !frag
->fixed
)
367 wdev
->wiphy
->frag_threshold
= (u32
) -1;
368 else if (frag
->value
< 256)
371 /* Fragment length must be even, so strip LSB. */
372 wdev
->wiphy
->frag_threshold
= frag
->value
& ~0x1;
375 err
= rdev
->ops
->set_wiphy_params(wdev
->wiphy
,
376 WIPHY_PARAM_FRAG_THRESHOLD
);
378 wdev
->wiphy
->frag_threshold
= ofrag
;
382 EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag
);
384 int cfg80211_wext_giwfrag(struct net_device
*dev
,
385 struct iw_request_info
*info
,
386 struct iw_param
*frag
, char *extra
)
388 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
390 frag
->value
= wdev
->wiphy
->frag_threshold
;
391 frag
->disabled
= frag
->value
== (u32
) -1;
396 EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag
);
398 int cfg80211_wext_siwretry(struct net_device
*dev
,
399 struct iw_request_info
*info
,
400 struct iw_param
*retry
, char *extra
)
402 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
403 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
405 u8 olong
= wdev
->wiphy
->retry_long
;
406 u8 oshort
= wdev
->wiphy
->retry_short
;
409 if (retry
->disabled
||
410 (retry
->flags
& IW_RETRY_TYPE
) != IW_RETRY_LIMIT
)
413 if (retry
->flags
& IW_RETRY_LONG
) {
414 wdev
->wiphy
->retry_long
= retry
->value
;
415 changed
|= WIPHY_PARAM_RETRY_LONG
;
416 } else if (retry
->flags
& IW_RETRY_SHORT
) {
417 wdev
->wiphy
->retry_short
= retry
->value
;
418 changed
|= WIPHY_PARAM_RETRY_SHORT
;
420 wdev
->wiphy
->retry_short
= retry
->value
;
421 wdev
->wiphy
->retry_long
= retry
->value
;
422 changed
|= WIPHY_PARAM_RETRY_LONG
;
423 changed
|= WIPHY_PARAM_RETRY_SHORT
;
429 err
= rdev
->ops
->set_wiphy_params(wdev
->wiphy
, changed
);
431 wdev
->wiphy
->retry_short
= oshort
;
432 wdev
->wiphy
->retry_long
= olong
;
437 EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry
);
439 int cfg80211_wext_giwretry(struct net_device
*dev
,
440 struct iw_request_info
*info
,
441 struct iw_param
*retry
, char *extra
)
443 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
447 if (retry
->flags
== 0 || (retry
->flags
& IW_RETRY_SHORT
)) {
449 * First return short value, iwconfig will ask long value
452 retry
->flags
|= IW_RETRY_LIMIT
;
453 retry
->value
= wdev
->wiphy
->retry_short
;
454 if (wdev
->wiphy
->retry_long
!= wdev
->wiphy
->retry_short
)
455 retry
->flags
|= IW_RETRY_LONG
;
460 if (retry
->flags
& IW_RETRY_LONG
) {
461 retry
->flags
= IW_RETRY_LIMIT
| IW_RETRY_LONG
;
462 retry
->value
= wdev
->wiphy
->retry_long
;
467 EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry
);