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-2009 Johannes Berg <johannes@sipsolutions.net>
11 #include <linux/wireless.h>
12 #include <linux/nl80211.h>
13 #include <linux/if_arp.h>
14 #include <linux/etherdevice.h>
15 #include <net/iw_handler.h>
16 #include <net/cfg80211.h>
19 int cfg80211_wext_giwname(struct net_device
*dev
,
20 struct iw_request_info
*info
,
21 char *name
, char *extra
)
23 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
24 struct ieee80211_supported_band
*sband
;
25 bool is_ht
= false, is_a
= false, is_b
= false, is_g
= false;
30 sband
= wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
];
33 is_ht
|= sband
->ht_cap
.ht_supported
;
36 sband
= wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
];
39 /* Check for mandatory rates */
40 for (i
= 0; i
< sband
->n_bitrates
; i
++) {
41 if (sband
->bitrates
[i
].bitrate
== 10)
43 if (sband
->bitrates
[i
].bitrate
== 60)
46 is_ht
|= sband
->ht_cap
.ht_supported
;
49 strcpy(name
, "IEEE 802.11");
61 EXPORT_SYMBOL_GPL(cfg80211_wext_giwname
);
63 int cfg80211_wext_siwmode(struct net_device
*dev
, struct iw_request_info
*info
,
64 u32
*mode
, char *extra
)
66 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
67 struct cfg80211_registered_device
*rdev
;
68 struct vif_params vifparams
;
69 enum nl80211_iftype type
;
75 rdev
= wiphy_to_dev(wdev
->wiphy
);
77 if (!rdev
->ops
->change_virtual_intf
)
80 /* don't support changing VLANs, you just re-create them */
81 if (wdev
->iftype
== NL80211_IFTYPE_AP_VLAN
)
86 type
= NL80211_IFTYPE_STATION
;
89 type
= NL80211_IFTYPE_ADHOC
;
92 type
= NL80211_IFTYPE_WDS
;
95 type
= NL80211_IFTYPE_MONITOR
;
101 if (type
== wdev
->iftype
)
104 memset(&vifparams
, 0, sizeof(vifparams
));
106 ret
= rdev
->ops
->change_virtual_intf(wdev
->wiphy
, dev
->ifindex
, type
,
108 WARN_ON(!ret
&& wdev
->iftype
!= type
);
112 EXPORT_SYMBOL_GPL(cfg80211_wext_siwmode
);
114 int cfg80211_wext_giwmode(struct net_device
*dev
, struct iw_request_info
*info
,
115 u32
*mode
, char *extra
)
117 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
122 switch (wdev
->iftype
) {
123 case NL80211_IFTYPE_AP
:
124 *mode
= IW_MODE_MASTER
;
126 case NL80211_IFTYPE_STATION
:
127 *mode
= IW_MODE_INFRA
;
129 case NL80211_IFTYPE_ADHOC
:
130 *mode
= IW_MODE_ADHOC
;
132 case NL80211_IFTYPE_MONITOR
:
133 *mode
= IW_MODE_MONITOR
;
135 case NL80211_IFTYPE_WDS
:
136 *mode
= IW_MODE_REPEAT
;
138 case NL80211_IFTYPE_AP_VLAN
:
139 *mode
= IW_MODE_SECOND
; /* FIXME */
142 *mode
= IW_MODE_AUTO
;
147 EXPORT_SYMBOL_GPL(cfg80211_wext_giwmode
);
150 int cfg80211_wext_giwrange(struct net_device
*dev
,
151 struct iw_request_info
*info
,
152 struct iw_point
*data
, char *extra
)
154 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
155 struct iw_range
*range
= (struct iw_range
*) extra
;
156 enum ieee80211_band band
;
162 data
->length
= sizeof(struct iw_range
);
163 memset(range
, 0, sizeof(struct iw_range
));
165 range
->we_version_compiled
= WIRELESS_EXT
;
166 range
->we_version_source
= 21;
167 range
->retry_capa
= IW_RETRY_LIMIT
;
168 range
->retry_flags
= IW_RETRY_LIMIT
;
169 range
->min_retry
= 0;
170 range
->max_retry
= 255;
172 range
->max_rts
= 2347;
173 range
->min_frag
= 256;
174 range
->max_frag
= 2346;
176 range
->encoding_size
[0] = 5;
177 range
->encoding_size
[1] = 13;
178 range
->num_encoding_sizes
= 2;
179 range
->max_encoding_tokens
= 4;
181 range
->max_qual
.updated
= IW_QUAL_NOISE_INVALID
;
183 switch (wdev
->wiphy
->signal_type
) {
184 case CFG80211_SIGNAL_TYPE_NONE
:
186 case CFG80211_SIGNAL_TYPE_MBM
:
187 range
->max_qual
.level
= -110;
188 range
->max_qual
.qual
= 70;
189 range
->avg_qual
.qual
= 35;
190 range
->max_qual
.updated
|= IW_QUAL_DBM
;
191 range
->max_qual
.updated
|= IW_QUAL_QUAL_UPDATED
;
192 range
->max_qual
.updated
|= IW_QUAL_LEVEL_UPDATED
;
194 case CFG80211_SIGNAL_TYPE_UNSPEC
:
195 range
->max_qual
.level
= 100;
196 range
->max_qual
.qual
= 100;
197 range
->avg_qual
.qual
= 50;
198 range
->max_qual
.updated
|= IW_QUAL_QUAL_UPDATED
;
199 range
->max_qual
.updated
|= IW_QUAL_LEVEL_UPDATED
;
203 range
->avg_qual
.level
= range
->max_qual
.level
/ 2;
204 range
->avg_qual
.noise
= range
->max_qual
.noise
/ 2;
205 range
->avg_qual
.updated
= range
->max_qual
.updated
;
207 range
->enc_capa
= IW_ENC_CAPA_WPA
| IW_ENC_CAPA_WPA2
|
208 IW_ENC_CAPA_CIPHER_TKIP
| IW_ENC_CAPA_CIPHER_CCMP
;
210 for (band
= 0; band
< IEEE80211_NUM_BANDS
; band
++) {
212 struct ieee80211_supported_band
*sband
;
214 sband
= wdev
->wiphy
->bands
[band
];
219 for (i
= 0; i
< sband
->n_channels
&& c
< IW_MAX_FREQUENCIES
; i
++) {
220 struct ieee80211_channel
*chan
= &sband
->channels
[i
];
222 if (!(chan
->flags
& IEEE80211_CHAN_DISABLED
)) {
224 ieee80211_frequency_to_channel(
226 range
->freq
[c
].m
= chan
->center_freq
;
227 range
->freq
[c
].e
= 6;
232 range
->num_channels
= c
;
233 range
->num_frequency
= c
;
235 IW_EVENT_CAPA_SET_KERNEL(range
->event_capa
);
236 IW_EVENT_CAPA_SET(range
->event_capa
, SIOCGIWAP
);
237 IW_EVENT_CAPA_SET(range
->event_capa
, SIOCGIWSCAN
);
239 range
->scan_capa
|= IW_SCAN_CAPA_ESSID
;
243 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrange
);
245 int cfg80211_wext_siwmlme(struct net_device
*dev
,
246 struct iw_request_info
*info
,
247 struct iw_point
*data
, char *extra
)
249 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
250 struct iw_mlme
*mlme
= (struct iw_mlme
*)extra
;
251 struct cfg80211_registered_device
*rdev
;
253 struct cfg80211_disassoc_request disassoc
;
254 struct cfg80211_deauth_request deauth
;
260 rdev
= wiphy_to_dev(wdev
->wiphy
);
262 if (wdev
->iftype
!= NL80211_IFTYPE_STATION
)
265 if (mlme
->addr
.sa_family
!= ARPHRD_ETHER
)
268 memset(&cmd
, 0, sizeof(cmd
));
272 if (!rdev
->ops
->deauth
)
274 cmd
.deauth
.peer_addr
= mlme
->addr
.sa_data
;
275 cmd
.deauth
.reason_code
= mlme
->reason_code
;
276 return rdev
->ops
->deauth(wdev
->wiphy
, dev
, &cmd
.deauth
);
277 case IW_MLME_DISASSOC
:
278 if (!rdev
->ops
->disassoc
)
280 cmd
.disassoc
.peer_addr
= mlme
->addr
.sa_data
;
281 cmd
.disassoc
.reason_code
= mlme
->reason_code
;
282 return rdev
->ops
->disassoc(wdev
->wiphy
, dev
, &cmd
.disassoc
);
287 EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme
);
291 * cfg80211_wext_freq - get wext frequency for non-"auto"
293 * @freq: the wext freq encoding
295 * Returns a channel, %NULL for auto, or an ERR_PTR for errors!
297 struct ieee80211_channel
*cfg80211_wext_freq(struct wiphy
*wiphy
,
298 struct iw_freq
*freq
)
300 struct ieee80211_channel
*chan
;
304 * Parse frequency - return NULL for auto and
305 * -EINVAL for impossible things.
310 f
= ieee80211_channel_to_frequency(freq
->m
);
312 int i
, div
= 1000000;
313 for (i
= 0; i
< freq
->e
; i
++)
316 return ERR_PTR(-EINVAL
);
321 * Look up channel struct and return -EINVAL when
322 * it cannot be found.
324 chan
= ieee80211_get_channel(wiphy
, f
);
326 return ERR_PTR(-EINVAL
);
329 EXPORT_SYMBOL_GPL(cfg80211_wext_freq
);
331 int cfg80211_wext_siwrts(struct net_device
*dev
,
332 struct iw_request_info
*info
,
333 struct iw_param
*rts
, char *extra
)
335 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
336 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
337 u32 orts
= wdev
->wiphy
->rts_threshold
;
340 if (rts
->disabled
|| !rts
->fixed
)
341 wdev
->wiphy
->rts_threshold
= (u32
) -1;
342 else if (rts
->value
< 0)
345 wdev
->wiphy
->rts_threshold
= rts
->value
;
347 err
= rdev
->ops
->set_wiphy_params(wdev
->wiphy
,
348 WIPHY_PARAM_RTS_THRESHOLD
);
350 wdev
->wiphy
->rts_threshold
= orts
;
354 EXPORT_SYMBOL_GPL(cfg80211_wext_siwrts
);
356 int cfg80211_wext_giwrts(struct net_device
*dev
,
357 struct iw_request_info
*info
,
358 struct iw_param
*rts
, char *extra
)
360 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
362 rts
->value
= wdev
->wiphy
->rts_threshold
;
363 rts
->disabled
= rts
->value
== (u32
) -1;
368 EXPORT_SYMBOL_GPL(cfg80211_wext_giwrts
);
370 int cfg80211_wext_siwfrag(struct net_device
*dev
,
371 struct iw_request_info
*info
,
372 struct iw_param
*frag
, char *extra
)
374 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
375 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
376 u32 ofrag
= wdev
->wiphy
->frag_threshold
;
379 if (frag
->disabled
|| !frag
->fixed
)
380 wdev
->wiphy
->frag_threshold
= (u32
) -1;
381 else if (frag
->value
< 256)
384 /* Fragment length must be even, so strip LSB. */
385 wdev
->wiphy
->frag_threshold
= frag
->value
& ~0x1;
388 err
= rdev
->ops
->set_wiphy_params(wdev
->wiphy
,
389 WIPHY_PARAM_FRAG_THRESHOLD
);
391 wdev
->wiphy
->frag_threshold
= ofrag
;
395 EXPORT_SYMBOL_GPL(cfg80211_wext_siwfrag
);
397 int cfg80211_wext_giwfrag(struct net_device
*dev
,
398 struct iw_request_info
*info
,
399 struct iw_param
*frag
, char *extra
)
401 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
403 frag
->value
= wdev
->wiphy
->frag_threshold
;
404 frag
->disabled
= frag
->value
== (u32
) -1;
409 EXPORT_SYMBOL_GPL(cfg80211_wext_giwfrag
);
411 int cfg80211_wext_siwretry(struct net_device
*dev
,
412 struct iw_request_info
*info
,
413 struct iw_param
*retry
, char *extra
)
415 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
416 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
418 u8 olong
= wdev
->wiphy
->retry_long
;
419 u8 oshort
= wdev
->wiphy
->retry_short
;
422 if (retry
->disabled
||
423 (retry
->flags
& IW_RETRY_TYPE
) != IW_RETRY_LIMIT
)
426 if (retry
->flags
& IW_RETRY_LONG
) {
427 wdev
->wiphy
->retry_long
= retry
->value
;
428 changed
|= WIPHY_PARAM_RETRY_LONG
;
429 } else if (retry
->flags
& IW_RETRY_SHORT
) {
430 wdev
->wiphy
->retry_short
= retry
->value
;
431 changed
|= WIPHY_PARAM_RETRY_SHORT
;
433 wdev
->wiphy
->retry_short
= retry
->value
;
434 wdev
->wiphy
->retry_long
= retry
->value
;
435 changed
|= WIPHY_PARAM_RETRY_LONG
;
436 changed
|= WIPHY_PARAM_RETRY_SHORT
;
442 err
= rdev
->ops
->set_wiphy_params(wdev
->wiphy
, changed
);
444 wdev
->wiphy
->retry_short
= oshort
;
445 wdev
->wiphy
->retry_long
= olong
;
450 EXPORT_SYMBOL_GPL(cfg80211_wext_siwretry
);
452 int cfg80211_wext_giwretry(struct net_device
*dev
,
453 struct iw_request_info
*info
,
454 struct iw_param
*retry
, char *extra
)
456 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
460 if (retry
->flags
== 0 || (retry
->flags
& IW_RETRY_SHORT
)) {
462 * First return short value, iwconfig will ask long value
465 retry
->flags
|= IW_RETRY_LIMIT
;
466 retry
->value
= wdev
->wiphy
->retry_short
;
467 if (wdev
->wiphy
->retry_long
!= wdev
->wiphy
->retry_short
)
468 retry
->flags
|= IW_RETRY_LONG
;
473 if (retry
->flags
& IW_RETRY_LONG
) {
474 retry
->flags
= IW_RETRY_LIMIT
| IW_RETRY_LONG
;
475 retry
->value
= wdev
->wiphy
->retry_long
;
480 EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry
);
482 static int cfg80211_set_encryption(struct cfg80211_registered_device
*rdev
,
483 struct net_device
*dev
, const u8
*addr
,
484 bool remove
, bool tx_key
, int idx
,
485 struct key_params
*params
)
487 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
490 if (params
->cipher
== WLAN_CIPHER_SUITE_AES_CMAC
) {
491 if (!rdev
->ops
->set_default_mgmt_key
)
494 if (idx
< 4 || idx
> 5)
496 } else if (idx
< 0 || idx
> 3)
500 err
= rdev
->ops
->del_key(&rdev
->wiphy
, dev
, idx
, addr
);
502 if (idx
== wdev
->wext
.default_key
)
503 wdev
->wext
.default_key
= -1;
504 else if (idx
== wdev
->wext
.default_mgmt_key
)
505 wdev
->wext
.default_mgmt_key
= -1;
508 * Applications using wireless extensions expect to be
509 * able to delete keys that don't exist, so allow that.
519 if (cfg80211_validate_key_settings(params
, idx
, addr
))
522 err
= rdev
->ops
->add_key(&rdev
->wiphy
, dev
, idx
, addr
, params
);
526 if (tx_key
|| (!addr
&& wdev
->wext
.default_key
== -1)) {
527 err
= rdev
->ops
->set_default_key(&rdev
->wiphy
,
530 wdev
->wext
.default_key
= idx
;
534 if (params
->cipher
== WLAN_CIPHER_SUITE_AES_CMAC
&&
535 (tx_key
|| (!addr
&& wdev
->wext
.default_mgmt_key
== -1))) {
536 err
= rdev
->ops
->set_default_mgmt_key(&rdev
->wiphy
,
539 wdev
->wext
.default_mgmt_key
= idx
;
547 int cfg80211_wext_siwencode(struct net_device
*dev
,
548 struct iw_request_info
*info
,
549 struct iw_point
*erq
, char *keybuf
)
551 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
552 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
555 struct key_params params
;
557 /* no use -- only MFP (set_default_mgmt_key) is optional */
558 if (!rdev
->ops
->del_key
||
559 !rdev
->ops
->add_key
||
560 !rdev
->ops
->set_default_key
)
563 idx
= erq
->flags
& IW_ENCODE_INDEX
;
565 idx
= wdev
->wext
.default_key
;
568 } else if (idx
< 1 || idx
> 4)
573 if (erq
->flags
& IW_ENCODE_DISABLED
)
575 else if (erq
->length
== 0) {
576 /* No key data - just set the default TX key index */
577 err
= rdev
->ops
->set_default_key(&rdev
->wiphy
, dev
, idx
);
579 wdev
->wext
.default_key
= idx
;
583 memset(¶ms
, 0, sizeof(params
));
585 params
.key_len
= erq
->length
;
586 if (erq
->length
== 5)
587 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
588 else if (erq
->length
== 13)
589 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
593 return cfg80211_set_encryption(rdev
, dev
, NULL
, remove
,
594 wdev
->wext
.default_key
== -1,
597 EXPORT_SYMBOL_GPL(cfg80211_wext_siwencode
);
599 int cfg80211_wext_siwencodeext(struct net_device
*dev
,
600 struct iw_request_info
*info
,
601 struct iw_point
*erq
, char *extra
)
603 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
604 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
605 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*) extra
;
609 struct key_params params
;
612 /* no use -- only MFP (set_default_mgmt_key) is optional */
613 if (!rdev
->ops
->del_key
||
614 !rdev
->ops
->add_key
||
615 !rdev
->ops
->set_default_key
)
619 case IW_ENCODE_ALG_NONE
:
623 case IW_ENCODE_ALG_WEP
:
624 if (ext
->key_len
== 5)
625 cipher
= WLAN_CIPHER_SUITE_WEP40
;
626 else if (ext
->key_len
== 13)
627 cipher
= WLAN_CIPHER_SUITE_WEP104
;
631 case IW_ENCODE_ALG_TKIP
:
632 cipher
= WLAN_CIPHER_SUITE_TKIP
;
634 case IW_ENCODE_ALG_CCMP
:
635 cipher
= WLAN_CIPHER_SUITE_CCMP
;
637 case IW_ENCODE_ALG_AES_CMAC
:
638 cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
644 if (erq
->flags
& IW_ENCODE_DISABLED
)
647 idx
= erq
->flags
& IW_ENCODE_INDEX
;
648 if (cipher
== WLAN_CIPHER_SUITE_AES_CMAC
) {
649 if (idx
< 4 || idx
> 5) {
650 idx
= wdev
->wext
.default_mgmt_key
;
656 if (idx
< 1 || idx
> 4) {
657 idx
= wdev
->wext
.default_key
;
664 addr
= ext
->addr
.sa_data
;
665 if (is_broadcast_ether_addr(addr
))
668 memset(¶ms
, 0, sizeof(params
));
669 params
.key
= ext
->key
;
670 params
.key_len
= ext
->key_len
;
671 params
.cipher
= cipher
;
673 if (ext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
) {
674 params
.seq
= ext
->rx_seq
;
678 return cfg80211_set_encryption(
679 rdev
, dev
, addr
, remove
,
680 ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
,
683 EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext
);
685 struct giwencode_cookie
{
690 static void giwencode_get_key_cb(void *cookie
, struct key_params
*params
)
692 struct giwencode_cookie
*data
= cookie
;
699 data
->buflen
= min_t(size_t, data
->buflen
, params
->key_len
);
700 memcpy(data
->keybuf
, params
->key
, data
->buflen
);
703 int cfg80211_wext_giwencode(struct net_device
*dev
,
704 struct iw_request_info
*info
,
705 struct iw_point
*erq
, char *keybuf
)
707 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
708 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
710 struct giwencode_cookie data
= {
712 .buflen
= erq
->length
,
715 if (!rdev
->ops
->get_key
)
718 idx
= erq
->flags
& IW_ENCODE_INDEX
;
720 idx
= wdev
->wext
.default_key
;
723 } else if (idx
< 1 || idx
> 4)
728 erq
->flags
= idx
+ 1;
730 err
= rdev
->ops
->get_key(&rdev
->wiphy
, dev
, idx
, NULL
, &data
,
731 giwencode_get_key_cb
);
733 erq
->length
= data
.buflen
;
734 erq
->flags
|= IW_ENCODE_ENABLED
;
738 if (err
== -ENOENT
) {
739 erq
->flags
|= IW_ENCODE_DISABLED
;
746 EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode
);
748 int cfg80211_wext_siwtxpower(struct net_device
*dev
,
749 struct iw_request_info
*info
,
750 union iwreq_data
*data
, char *extra
)
752 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
753 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
754 enum tx_power_setting type
;
757 if ((data
->txpower
.flags
& IW_TXPOW_TYPE
) != IW_TXPOW_DBM
)
759 if (data
->txpower
.flags
& IW_TXPOW_RANGE
)
762 if (!rdev
->ops
->set_tx_power
)
765 /* only change when not disabling */
766 if (!data
->txpower
.disabled
) {
767 rfkill_set_sw_state(rdev
->rfkill
, false);
769 if (data
->txpower
.fixed
) {
771 * wext doesn't support negative values, see
772 * below where it's for automatic
774 if (data
->txpower
.value
< 0)
776 dbm
= data
->txpower
.value
;
777 type
= TX_POWER_FIXED
;
778 /* TODO: do regulatory check! */
781 * Automatic power level setting, max being the value
782 * passed in from userland.
784 if (data
->txpower
.value
< 0) {
785 type
= TX_POWER_AUTOMATIC
;
787 dbm
= data
->txpower
.value
;
788 type
= TX_POWER_LIMITED
;
792 rfkill_set_sw_state(rdev
->rfkill
, true);
793 schedule_work(&rdev
->rfkill_sync
);
797 return rdev
->ops
->set_tx_power(wdev
->wiphy
, type
, dbm
);;
799 EXPORT_SYMBOL_GPL(cfg80211_wext_siwtxpower
);
801 int cfg80211_wext_giwtxpower(struct net_device
*dev
,
802 struct iw_request_info
*info
,
803 union iwreq_data
*data
, char *extra
)
805 struct wireless_dev
*wdev
= dev
->ieee80211_ptr
;
806 struct cfg80211_registered_device
*rdev
= wiphy_to_dev(wdev
->wiphy
);
809 if ((data
->txpower
.flags
& IW_TXPOW_TYPE
) != IW_TXPOW_DBM
)
811 if (data
->txpower
.flags
& IW_TXPOW_RANGE
)
814 if (!rdev
->ops
->get_tx_power
)
817 err
= rdev
->ops
->get_tx_power(wdev
->wiphy
, &val
);
821 /* well... oh well */
822 data
->txpower
.fixed
= 1;
823 data
->txpower
.disabled
= rfkill_blocked(rdev
->rfkill
);
824 data
->txpower
.value
= val
;
825 data
->txpower
.flags
= IW_TXPOW_DBM
;
829 EXPORT_SYMBOL_GPL(cfg80211_wext_giwtxpower
);