1 /* src/p80211/p80211wext.c
3 * Glue code to make linux-wlan-ng a happy wireless extension camper.
5 * original author: Reyk Floeter <reyk@synack.de>
6 * Completely re-written by Solomon Peachy <solomon@linux-wlan.com>
8 * Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved.
9 * --------------------------------------------------------------------
13 * The contents of this file are subject to the Mozilla Public
14 * License Version 1.1 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.mozilla.org/MPL/
18 * Software distributed under the License is distributed on an "AS
19 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
20 * implied. See the License for the specific language governing
21 * rights and limitations under the License.
23 * Alternatively, the contents of this file may be used under the
24 * terms of the GNU Public License version 2 (the "GPL"), in which
25 * case the provisions of the GPL are applicable instead of the
26 * above. If you wish to allow the use of your version of this file
27 * only under the terms of the GPL and not to allow others to use
28 * your version of this file under the MPL, indicate your decision
29 * by deleting the provisions above and replace them with the notice
30 * and other provisions required by the GPL. If you do not delete
31 * the provisions above, a recipient may use your version of this
32 * file under either the MPL or the GPL.
34 * --------------------------------------------------------------------
37 /*================================================================*/
40 #include <linux/kernel.h>
41 #include <linux/sched.h>
42 #include <linux/types.h>
43 #include <linux/slab.h>
44 #include <linux/netdevice.h>
45 #include <linux/etherdevice.h>
46 #include <linux/wireless.h>
47 #include <net/iw_handler.h>
48 #include <linux/if_arp.h>
49 #include <asm/bitops.h>
50 #include <asm/uaccess.h>
51 #include <asm/byteorder.h>
52 #include <linux/if_ether.h>
53 #include <linux/bitops.h>
55 #include "p80211types.h"
56 #include "p80211hdr.h"
57 #include "p80211conv.h"
58 #include "p80211mgmt.h"
59 #include "p80211msg.h"
60 #include "p80211metastruct.h"
61 #include "p80211metadef.h"
62 #include "p80211netdev.h"
63 #include "p80211ioctl.h"
64 #include "p80211req.h"
66 static int p80211wext_giwrate(netdevice_t
*dev
,
67 struct iw_request_info
*info
,
68 struct iw_param
*rrq
, char *extra
);
69 static int p80211wext_giwessid(netdevice_t
*dev
,
70 struct iw_request_info
*info
,
71 struct iw_point
*data
, char *essid
);
73 static u8
p80211_mhz_to_channel(u16 mhz
)
76 return (mhz
- 5000) / 5;
82 return (mhz
- 2407) / 5;
87 static u16
p80211_channel_to_mhz(u8 ch
, int dot11a
)
97 return 5000 + (5 * ch
);
103 if ((ch
< 14) && (ch
> 0))
104 return 2407 + (5 * ch
);
109 /* taken from orinoco.c ;-) */
110 static const long p80211wext_channel_freq
[] = {
111 2412, 2417, 2422, 2427, 2432, 2437, 2442,
112 2447, 2452, 2457, 2462, 2467, 2472, 2484
115 #define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
117 /* steal a spare bit to store the shared/opensystems state.
118 should default to open if not set */
119 #define HOSTWEP_SHAREDKEY BIT(3)
121 static int qual_as_percent(int snr
)
130 static int p80211wext_dorequest(wlandevice_t
*wlandev
, u32 did
, u32 data
)
132 p80211msg_dot11req_mibset_t msg
;
133 p80211item_uint32_t mibitem
;
136 msg
.msgcode
= DIDmsg_dot11req_mibset
;
139 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
140 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
145 static int p80211wext_autojoin(wlandevice_t
*wlandev
)
147 p80211msg_lnxreq_autojoin_t msg
;
148 struct iw_point data
;
149 char ssid
[IW_ESSID_MAX_SIZE
];
155 result
= p80211wext_giwessid(wlandev
->netdev
, NULL
, &data
, ssid
);
162 if (wlandev
->hostwep
& HOSTWEP_SHAREDKEY
)
163 msg
.authtype
.data
= P80211ENUM_authalg_sharedkey
;
165 msg
.authtype
.data
= P80211ENUM_authalg_opensystem
;
167 msg
.msgcode
= DIDmsg_lnxreq_autojoin
;
169 /* Trim the last '\0' to fit the SSID format */
171 if (data
.length
&& ssid
[data
.length
- 1] == '\0')
172 data
.length
= data
.length
- 1;
174 memcpy(msg
.ssid
.data
.data
, ssid
, data
.length
);
175 msg
.ssid
.data
.len
= data
.length
;
177 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
190 /* called by /proc/net/wireless */
191 struct iw_statistics
*p80211wext_get_wireless_stats(netdevice_t
*dev
)
193 p80211msg_lnxreq_commsquality_t quality
;
194 wlandevice_t
*wlandev
= dev
->ml_priv
;
195 struct iw_statistics
*wstats
= &wlandev
->wstats
;
199 if ((wlandev
== NULL
) || (wlandev
->msdstate
!= WLAN_MSD_RUNNING
))
202 /* XXX Only valid in station mode */
205 /* build request message */
206 quality
.msgcode
= DIDmsg_lnxreq_commsquality
;
207 quality
.dbm
.data
= P80211ENUM_truth_true
;
208 quality
.dbm
.status
= P80211ENUM_msgitem_status_data_ok
;
210 /* send message to nsd */
211 if (wlandev
->mlmerequest
== NULL
)
214 retval
= wlandev
->mlmerequest(wlandev
, (p80211msg_t
*) & quality
);
216 wstats
->qual
.qual
= qual_as_percent(quality
.link
.data
); /* overall link quality */
217 wstats
->qual
.level
= quality
.level
.data
; /* instant signal level */
218 wstats
->qual
.noise
= quality
.noise
.data
; /* instant noise level */
220 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
221 wstats
->discard
.code
= wlandev
->rx
.decrypt_err
;
222 wstats
->discard
.nwid
= 0;
223 wstats
->discard
.misc
= 0;
225 wstats
->discard
.fragment
= 0; /* incomplete fragments */
226 wstats
->discard
.retries
= 0; /* tx retries. */
227 wstats
->miss
.beacon
= 0;
232 static int p80211wext_giwname(netdevice_t
*dev
,
233 struct iw_request_info
*info
,
234 char *name
, char *extra
)
236 struct iw_param rate
;
240 result
= p80211wext_giwrate(dev
, NULL
, &rate
, NULL
);
247 switch (rate
.value
) {
250 strcpy(name
, "IEEE 802.11-DS");
254 strcpy(name
, "IEEE 802.11-b");
261 static int p80211wext_giwfreq(netdevice_t
*dev
,
262 struct iw_request_info
*info
,
263 struct iw_freq
*freq
, char *extra
)
265 wlandevice_t
*wlandev
= dev
->ml_priv
;
266 p80211item_uint32_t mibitem
;
267 p80211msg_dot11req_mibset_t msg
;
271 msg
.msgcode
= DIDmsg_dot11req_mibget
;
272 mibitem
.did
= DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel
;
273 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
274 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
281 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
283 if (mibitem
.data
> NUM_CHANNELS
) {
288 /* convert into frequency instead of a channel */
290 freq
->m
= p80211_channel_to_mhz(mibitem
.data
, 0) * 100000;
296 static int p80211wext_siwfreq(netdevice_t
*dev
,
297 struct iw_request_info
*info
,
298 struct iw_freq
*freq
, char *extra
)
300 wlandevice_t
*wlandev
= dev
->ml_priv
;
301 p80211item_uint32_t mibitem
;
302 p80211msg_dot11req_mibset_t msg
;
306 if (!wlan_wext_write
) {
311 msg
.msgcode
= DIDmsg_dot11req_mibset
;
312 mibitem
.did
= DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel
;
313 mibitem
.status
= P80211ENUM_msgitem_status_data_ok
;
315 if ((freq
->e
== 0) && (freq
->m
<= 1000))
316 mibitem
.data
= freq
->m
;
318 mibitem
.data
= p80211_mhz_to_channel(freq
->m
);
320 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
321 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
332 static int p80211wext_giwmode(netdevice_t
*dev
,
333 struct iw_request_info
*info
,
334 __u32
*mode
, char *extra
)
336 wlandevice_t
*wlandev
= dev
->ml_priv
;
338 switch (wlandev
->macmode
) {
339 case WLAN_MACMODE_IBSS_STA
:
340 *mode
= IW_MODE_ADHOC
;
342 case WLAN_MACMODE_ESS_STA
:
343 *mode
= IW_MODE_INFRA
;
345 case WLAN_MACMODE_ESS_AP
:
346 *mode
= IW_MODE_MASTER
;
350 *mode
= IW_MODE_AUTO
;
356 static int p80211wext_siwmode(netdevice_t
*dev
,
357 struct iw_request_info
*info
,
358 __u32
*mode
, char *extra
)
360 wlandevice_t
*wlandev
= dev
->ml_priv
;
361 p80211item_uint32_t mibitem
;
362 p80211msg_dot11req_mibset_t msg
;
366 if (!wlan_wext_write
) {
371 if (*mode
!= IW_MODE_ADHOC
&& *mode
!= IW_MODE_INFRA
&&
372 *mode
!= IW_MODE_MASTER
) {
377 /* Operation mode is the same with current mode */
378 if (*mode
== wlandev
->macmode
)
383 wlandev
->macmode
= WLAN_MACMODE_IBSS_STA
;
386 wlandev
->macmode
= WLAN_MACMODE_ESS_STA
;
389 wlandev
->macmode
= WLAN_MACMODE_ESS_AP
;
393 printk(KERN_INFO
"Operation mode: %d not support\n", *mode
);
397 /* Set Operation mode to the PORT TYPE RID */
398 msg
.msgcode
= DIDmsg_dot11req_mibset
;
399 mibitem
.did
= DIDmib_p2_p2Static_p2CnfPortType
;
400 mibitem
.data
= (*mode
== IW_MODE_ADHOC
) ? 0 : 1;
401 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
402 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
411 static int p80211wext_giwrange(netdevice_t
*dev
,
412 struct iw_request_info
*info
,
413 struct iw_point
*data
, char *extra
)
415 struct iw_range
*range
= (struct iw_range
*)extra
;
418 /* for backward compatability set size and zero everything we don't understand */
419 data
->length
= sizeof(*range
);
420 memset(range
, 0, sizeof(*range
));
422 range
->txpower_capa
= IW_TXPOW_DBM
;
423 /* XXX what about min/max_pmp, min/max_pmt, etc. */
425 range
->we_version_compiled
= WIRELESS_EXT
;
426 range
->we_version_source
= 13;
428 range
->retry_capa
= IW_RETRY_LIMIT
;
429 range
->retry_flags
= IW_RETRY_LIMIT
;
430 range
->min_retry
= 0;
431 range
->max_retry
= 255;
433 range
->event_capa
[0] = (IW_EVENT_CAPA_K_0
| /* mode/freq/ssid */
434 IW_EVENT_CAPA_MASK(SIOCGIWAP
) |
435 IW_EVENT_CAPA_MASK(SIOCGIWSCAN
));
436 range
->event_capa
[1] = IW_EVENT_CAPA_K_1
; /* encode */
437 range
->event_capa
[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL
) |
438 IW_EVENT_CAPA_MASK(IWEVCUSTOM
));
440 range
->num_channels
= NUM_CHANNELS
;
442 /* XXX need to filter against the regulatory domain &| active set */
444 for (i
= 0; i
< NUM_CHANNELS
; i
++) {
445 range
->freq
[val
].i
= i
+ 1;
446 range
->freq
[val
].m
= p80211wext_channel_freq
[i
] * 100000;
447 range
->freq
[val
].e
= 1;
451 range
->num_frequency
= val
;
453 /* Max of /proc/net/wireless */
454 range
->max_qual
.qual
= 100;
455 range
->max_qual
.level
= 0;
456 range
->max_qual
.noise
= 0;
457 range
->sensitivity
= 3;
458 /* XXX these need to be nsd-specific! */
461 range
->max_rts
= 2347;
462 range
->min_frag
= 256;
463 range
->max_frag
= 2346;
465 range
->max_encoding_tokens
= NUM_WEPKEYS
;
466 range
->num_encoding_sizes
= 2;
467 range
->encoding_size
[0] = 5;
468 range
->encoding_size
[1] = 13;
470 /* XXX what about num_bitrates/throughput? */
471 range
->num_bitrates
= 0;
473 /* estimated max throughput */
474 /* XXX need to cap it if we're running at ~2Mbps.. */
475 range
->throughput
= 5500000;
480 static int p80211wext_giwap(netdevice_t
*dev
,
481 struct iw_request_info
*info
,
482 struct sockaddr
*ap_addr
, char *extra
)
485 wlandevice_t
*wlandev
= dev
->ml_priv
;
487 memcpy(ap_addr
->sa_data
, wlandev
->bssid
, WLAN_BSSID_LEN
);
488 ap_addr
->sa_family
= ARPHRD_ETHER
;
493 static int p80211wext_giwencode(netdevice_t
*dev
,
494 struct iw_request_info
*info
,
495 struct iw_point
*erq
, char *key
)
497 wlandevice_t
*wlandev
= dev
->ml_priv
;
501 i
= (erq
->flags
& IW_ENCODE_INDEX
) - 1;
504 if (wlandev
->hostwep
& HOSTWEP_PRIVACYINVOKED
)
505 erq
->flags
|= IW_ENCODE_ENABLED
;
507 erq
->flags
|= IW_ENCODE_DISABLED
;
509 if (wlandev
->hostwep
& HOSTWEP_EXCLUDEUNENCRYPTED
)
510 erq
->flags
|= IW_ENCODE_RESTRICTED
;
512 erq
->flags
|= IW_ENCODE_OPEN
;
514 i
= (erq
->flags
& IW_ENCODE_INDEX
) - 1;
517 i
= wlandev
->hostwep
& HOSTWEP_DEFAULTKEY_MASK
;
519 if ((i
< 0) || (i
>= NUM_WEPKEYS
)) {
526 /* copy the key from the driver cache as the keys are read-only MIBs */
527 erq
->length
= wlandev
->wep_keylens
[i
];
528 memcpy(key
, wlandev
->wep_keys
[i
], erq
->length
);
534 static int p80211wext_siwencode(netdevice_t
*dev
,
535 struct iw_request_info
*info
,
536 struct iw_point
*erq
, char *key
)
538 wlandevice_t
*wlandev
= dev
->ml_priv
;
539 p80211msg_dot11req_mibset_t msg
;
540 p80211item_pstr32_t pstr
;
546 if (!wlan_wext_write
) {
551 /* Check the Key index first. */
552 if ((i
= (erq
->flags
& IW_ENCODE_INDEX
))) {
554 if ((i
< 1) || (i
> NUM_WEPKEYS
)) {
560 /* Set current key number only if no keys are given */
561 if (erq
->flags
& IW_ENCODE_NOKEY
) {
563 p80211wext_dorequest(wlandev
,
564 DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID
,
574 /* Use defaultkey if no Key Index */
575 i
= wlandev
->hostwep
& HOSTWEP_DEFAULTKEY_MASK
;
578 /* Check if there is no key information in the iwconfig request */
579 if ((erq
->flags
& IW_ENCODE_NOKEY
) == 0) {
581 /*------------------------------------------------------------
582 * If there is WEP Key for setting, check the Key Information
583 * and then set it to the firmware.
584 -------------------------------------------------------------*/
586 if (erq
->length
> 0) {
588 /* copy the key from the driver cache as the keys are read-only MIBs */
589 wlandev
->wep_keylens
[i
] = erq
->length
;
590 memcpy(wlandev
->wep_keys
[i
], key
, erq
->length
);
592 /* Prepare data struture for p80211req_dorequest. */
593 memcpy(pstr
.data
.data
, key
, erq
->length
);
594 pstr
.data
.len
= erq
->length
;
599 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0
;
604 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1
;
609 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2
;
614 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3
;
622 msg
.msgcode
= DIDmsg_dot11req_mibset
;
623 memcpy(&msg
.mibattribute
.data
, &pstr
, sizeof(pstr
));
624 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
634 /* Check the PrivacyInvoked flag */
635 if (erq
->flags
& IW_ENCODE_DISABLED
) {
637 p80211wext_dorequest(wlandev
,
638 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
639 P80211ENUM_truth_false
);
642 p80211wext_dorequest(wlandev
,
643 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
644 P80211ENUM_truth_true
);
652 /* The security mode may be open or restricted, and its meaning
653 depends on the card used. With most cards, in open mode no
654 authentication is used and the card may also accept non-
655 encrypted sessions, whereas in restricted mode only encrypted
656 sessions are accepted and the card will use authentication if
659 if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
661 p80211wext_dorequest(wlandev
,
662 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
663 P80211ENUM_truth_true
);
664 } else if (erq
->flags
& IW_ENCODE_OPEN
) {
666 p80211wext_dorequest(wlandev
,
667 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
668 P80211ENUM_truth_false
);
681 static int p80211wext_giwessid(netdevice_t
*dev
,
682 struct iw_request_info
*info
,
683 struct iw_point
*data
, char *essid
)
685 wlandevice_t
*wlandev
= dev
->ml_priv
;
687 if (wlandev
->ssid
.len
) {
688 data
->length
= wlandev
->ssid
.len
;
690 memcpy(essid
, wlandev
->ssid
.data
, data
->length
);
691 essid
[data
->length
] = 0;
693 memset(essid
, 0, sizeof(wlandev
->ssid
.data
));
701 static int p80211wext_siwessid(netdevice_t
*dev
,
702 struct iw_request_info
*info
,
703 struct iw_point
*data
, char *essid
)
705 wlandevice_t
*wlandev
= dev
->ml_priv
;
706 p80211msg_lnxreq_autojoin_t msg
;
710 int length
= data
->length
;
712 if (!wlan_wext_write
) {
717 if (wlandev
->hostwep
& HOSTWEP_SHAREDKEY
)
718 msg
.authtype
.data
= P80211ENUM_authalg_sharedkey
;
720 msg
.authtype
.data
= P80211ENUM_authalg_opensystem
;
722 msg
.msgcode
= DIDmsg_lnxreq_autojoin
;
724 /* Trim the last '\0' to fit the SSID format */
725 if (length
&& essid
[length
- 1] == '\0')
728 memcpy(msg
.ssid
.data
.data
, essid
, length
);
729 msg
.ssid
.data
.len
= length
;
731 pr_debug("autojoin_ssid for %s \n", essid
);
732 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
733 pr_debug("autojoin_ssid %d\n", result
);
744 static int p80211wext_siwcommit(netdevice_t
*dev
,
745 struct iw_request_info
*info
,
746 struct iw_point
*data
, char *essid
)
748 wlandevice_t
*wlandev
= dev
->ml_priv
;
751 if (!wlan_wext_write
) {
757 err
= p80211wext_autojoin(wlandev
);
763 static int p80211wext_giwrate(netdevice_t
*dev
,
764 struct iw_request_info
*info
,
765 struct iw_param
*rrq
, char *extra
)
767 wlandevice_t
*wlandev
= dev
->ml_priv
;
768 p80211item_uint32_t mibitem
;
769 p80211msg_dot11req_mibset_t msg
;
773 msg
.msgcode
= DIDmsg_dot11req_mibget
;
774 mibitem
.did
= DIDmib_p2_p2MAC_p2CurrentTxRate
;
775 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
776 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
783 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
785 rrq
->fixed
= 0; /* can it change? */
789 #define HFA384x_RATEBIT_1 ((u16)1)
790 #define HFA384x_RATEBIT_2 ((u16)2)
791 #define HFA384x_RATEBIT_5dot5 ((u16)4)
792 #define HFA384x_RATEBIT_11 ((u16)8)
794 switch (mibitem
.data
) {
795 case HFA384x_RATEBIT_1
:
796 rrq
->value
= 1000000;
798 case HFA384x_RATEBIT_2
:
799 rrq
->value
= 2000000;
801 case HFA384x_RATEBIT_5dot5
:
802 rrq
->value
= 5500000;
804 case HFA384x_RATEBIT_11
:
805 rrq
->value
= 11000000;
814 static int p80211wext_giwrts(netdevice_t
*dev
,
815 struct iw_request_info
*info
,
816 struct iw_param
*rts
, char *extra
)
818 wlandevice_t
*wlandev
= dev
->ml_priv
;
819 p80211item_uint32_t mibitem
;
820 p80211msg_dot11req_mibset_t msg
;
824 msg
.msgcode
= DIDmsg_dot11req_mibget
;
825 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold
;
826 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
827 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
834 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
836 rts
->value
= mibitem
.data
;
837 rts
->disabled
= (rts
->value
== 2347);
844 static int p80211wext_siwrts(netdevice_t
*dev
,
845 struct iw_request_info
*info
,
846 struct iw_param
*rts
, char *extra
)
848 wlandevice_t
*wlandev
= dev
->ml_priv
;
849 p80211item_uint32_t mibitem
;
850 p80211msg_dot11req_mibset_t msg
;
854 if (!wlan_wext_write
) {
859 msg
.msgcode
= DIDmsg_dot11req_mibget
;
860 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold
;
864 mibitem
.data
= rts
->value
;
866 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
867 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
878 static int p80211wext_giwfrag(netdevice_t
*dev
,
879 struct iw_request_info
*info
,
880 struct iw_param
*frag
, char *extra
)
882 wlandevice_t
*wlandev
= dev
->ml_priv
;
883 p80211item_uint32_t mibitem
;
884 p80211msg_dot11req_mibset_t msg
;
888 msg
.msgcode
= DIDmsg_dot11req_mibget
;
890 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold
;
891 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
892 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
899 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
901 frag
->value
= mibitem
.data
;
902 frag
->disabled
= (frag
->value
== 2346);
909 static int p80211wext_siwfrag(netdevice_t
*dev
,
910 struct iw_request_info
*info
,
911 struct iw_param
*frag
, char *extra
)
913 wlandevice_t
*wlandev
= dev
->ml_priv
;
914 p80211item_uint32_t mibitem
;
915 p80211msg_dot11req_mibset_t msg
;
919 if (!wlan_wext_write
) {
924 msg
.msgcode
= DIDmsg_dot11req_mibset
;
926 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold
;
931 mibitem
.data
= frag
->value
;
933 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
934 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
945 #ifndef IW_RETRY_LONG
946 #define IW_RETRY_LONG IW_RETRY_MAX
949 #ifndef IW_RETRY_SHORT
950 #define IW_RETRY_SHORT IW_RETRY_MIN
953 static int p80211wext_giwretry(netdevice_t
*dev
,
954 struct iw_request_info
*info
,
955 struct iw_param
*rrq
, char *extra
)
957 wlandevice_t
*wlandev
= dev
->ml_priv
;
958 p80211item_uint32_t mibitem
;
959 p80211msg_dot11req_mibset_t msg
;
962 u16 shortretry
, longretry
, lifetime
;
964 msg
.msgcode
= DIDmsg_dot11req_mibget
;
965 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit
;
967 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
968 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
975 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
977 shortretry
= mibitem
.data
;
979 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit
;
981 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
982 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
989 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
991 longretry
= mibitem
.data
;
994 DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime
;
996 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
997 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1004 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
1006 lifetime
= mibitem
.data
;
1010 if ((rrq
->flags
& IW_RETRY_TYPE
) == IW_RETRY_LIFETIME
) {
1011 rrq
->flags
= IW_RETRY_LIFETIME
;
1012 rrq
->value
= lifetime
* 1024;
1014 if (rrq
->flags
& IW_RETRY_LONG
) {
1015 rrq
->flags
= IW_RETRY_LIMIT
| IW_RETRY_LONG
;
1016 rrq
->value
= longretry
;
1018 rrq
->flags
= IW_RETRY_LIMIT
;
1019 rrq
->value
= shortretry
;
1020 if (shortretry
!= longretry
)
1021 rrq
->flags
|= IW_RETRY_SHORT
;
1030 static int p80211wext_siwretry(netdevice_t
*dev
,
1031 struct iw_request_info
*info
,
1032 struct iw_param
*rrq
, char *extra
)
1034 wlandevice_t
*wlandev
= dev
->ml_priv
;
1035 p80211item_uint32_t mibitem
;
1036 p80211msg_dot11req_mibset_t msg
;
1040 if (!wlan_wext_write
) {
1041 err
= (-EOPNOTSUPP
);
1045 if (rrq
->disabled
) {
1050 msg
.msgcode
= DIDmsg_dot11req_mibset
;
1052 if ((rrq
->flags
& IW_RETRY_TYPE
) == IW_RETRY_LIFETIME
) {
1054 DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime
;
1055 mibitem
.data
= rrq
->value
/= 1024;
1057 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
1058 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1065 if (rrq
->flags
& IW_RETRY_LONG
) {
1067 DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit
;
1068 mibitem
.data
= rrq
->value
;
1070 memcpy(&msg
.mibattribute
.data
, &mibitem
,
1072 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1080 if (rrq
->flags
& IW_RETRY_SHORT
) {
1082 DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit
;
1083 mibitem
.data
= rrq
->value
;
1085 memcpy(&msg
.mibattribute
.data
, &mibitem
,
1087 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1101 static int p80211wext_siwtxpow(netdevice_t
*dev
,
1102 struct iw_request_info
*info
,
1103 struct iw_param
*rrq
, char *extra
)
1105 wlandevice_t
*wlandev
= dev
->ml_priv
;
1106 p80211item_uint32_t mibitem
;
1107 p80211msg_dot11req_mibset_t msg
;
1111 if (!wlan_wext_write
) {
1112 err
= (-EOPNOTSUPP
);
1116 msg
.msgcode
= DIDmsg_dot11req_mibset
;
1118 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel
;
1119 if (rrq
->fixed
== 0)
1122 mibitem
.data
= rrq
->value
;
1123 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
1124 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1135 static int p80211wext_giwtxpow(netdevice_t
*dev
,
1136 struct iw_request_info
*info
,
1137 struct iw_param
*rrq
, char *extra
)
1139 wlandevice_t
*wlandev
= dev
->ml_priv
;
1140 p80211item_uint32_t mibitem
;
1141 p80211msg_dot11req_mibset_t msg
;
1145 msg
.msgcode
= DIDmsg_dot11req_mibget
;
1147 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel
;
1149 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
1150 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1157 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
1159 /* XXX handle OFF by setting disabled = 1; */
1161 rrq
->flags
= 0; /* IW_TXPOW_DBM; */
1164 rrq
->value
= mibitem
.data
;
1170 static int p80211wext_siwspy(netdevice_t
*dev
,
1171 struct iw_request_info
*info
,
1172 struct iw_point
*srq
, char *extra
)
1174 wlandevice_t
*wlandev
= dev
->ml_priv
;
1175 struct sockaddr address
[IW_MAX_SPY
];
1176 int number
= srq
->length
;
1179 /* Copy the data from the input buffer */
1180 memcpy(address
, extra
, sizeof(struct sockaddr
) * number
);
1182 wlandev
->spy_number
= 0;
1186 /* extract the addresses */
1187 for (i
= 0; i
< number
; i
++) {
1189 memcpy(wlandev
->spy_address
[i
], address
[i
].sa_data
,
1194 memset(wlandev
->spy_stat
, 0,
1195 sizeof(struct iw_quality
) * IW_MAX_SPY
);
1197 /* set number of addresses */
1198 wlandev
->spy_number
= number
;
1204 /* jkriegl: from orinoco, modified */
1205 static int p80211wext_giwspy(netdevice_t
*dev
,
1206 struct iw_request_info
*info
,
1207 struct iw_point
*srq
, char *extra
)
1209 wlandevice_t
*wlandev
= dev
->ml_priv
;
1211 struct sockaddr address
[IW_MAX_SPY
];
1212 struct iw_quality spy_stat
[IW_MAX_SPY
];
1216 number
= wlandev
->spy_number
;
1220 /* populate address and spy struct's */
1221 for (i
= 0; i
< number
; i
++) {
1222 memcpy(address
[i
].sa_data
, wlandev
->spy_address
[i
],
1224 address
[i
].sa_family
= AF_UNIX
;
1225 memcpy(&spy_stat
[i
], &wlandev
->spy_stat
[i
],
1226 sizeof(struct iw_quality
));
1229 /* reset update flag */
1230 for (i
= 0; i
< number
; i
++)
1231 wlandev
->spy_stat
[i
].updated
= 0;
1234 /* push stuff to user space */
1235 srq
->length
= number
;
1236 memcpy(extra
, address
, sizeof(struct sockaddr
) * number
);
1237 memcpy(extra
+ sizeof(struct sockaddr
) * number
, spy_stat
,
1238 sizeof(struct iw_quality
) * number
);
1243 static int prism2_result2err(int prism2_result
)
1247 switch (prism2_result
) {
1248 case P80211ENUM_resultcode_invalid_parameters
:
1251 case P80211ENUM_resultcode_implementation_failure
:
1254 case P80211ENUM_resultcode_not_supported
:
1265 static int p80211wext_siwscan(netdevice_t
*dev
,
1266 struct iw_request_info
*info
,
1267 struct iw_point
*srq
, char *extra
)
1269 wlandevice_t
*wlandev
= dev
->ml_priv
;
1270 p80211msg_dot11req_scan_t msg
;
1275 if (wlandev
->macmode
== WLAN_MACMODE_ESS_AP
) {
1276 printk(KERN_ERR
"Can't scan in AP mode\n");
1277 err
= (-EOPNOTSUPP
);
1281 memset(&msg
, 0x00, sizeof(p80211msg_dot11req_scan_t
));
1282 msg
.msgcode
= DIDmsg_dot11req_scan
;
1283 msg
.bsstype
.data
= P80211ENUM_bsstype_any
;
1285 memset(&(msg
.bssid
.data
), 0xFF, sizeof(p80211item_pstr6_t
));
1286 msg
.bssid
.data
.len
= 6;
1288 msg
.scantype
.data
= P80211ENUM_scantype_active
;
1289 msg
.probedelay
.data
= 0;
1291 for (i
= 1; i
<= 14; i
++)
1292 msg
.channellist
.data
.data
[i
- 1] = i
;
1293 msg
.channellist
.data
.len
= 14;
1295 msg
.maxchanneltime
.data
= 250;
1296 msg
.minchanneltime
.data
= 200;
1298 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1300 err
= prism2_result2err(msg
.resultcode
.data
);
1306 /* Helper to translate scan into Wireless Extensions scan results.
1307 * Inspired by the prism54 code, which was in turn inspired by the
1310 static char *wext_translate_bss(struct iw_request_info
*info
, char *current_ev
,
1312 p80211msg_dot11req_scan_results_t
*bss
)
1314 struct iw_event iwe
; /* Temporary buffer */
1316 /* The first entry must be the MAC address */
1317 memcpy(iwe
.u
.ap_addr
.sa_data
, bss
->bssid
.data
.data
, WLAN_BSSID_LEN
);
1318 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1319 iwe
.cmd
= SIOCGIWAP
;
1321 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1324 /* The following entries will be displayed in the same order we give them */
1327 if (bss
->ssid
.data
.len
> 0) {
1328 char essid
[IW_ESSID_MAX_SIZE
+ 1];
1332 min_t(unsigned short, IW_ESSID_MAX_SIZE
,
1333 bss
->ssid
.data
.len
);
1334 memset(&essid
, 0, sizeof(essid
));
1335 memcpy(&essid
, bss
->ssid
.data
.data
, size
);
1336 pr_debug(" essid size = %d\n", size
);
1337 iwe
.u
.data
.length
= size
;
1338 iwe
.u
.data
.flags
= 1;
1339 iwe
.cmd
= SIOCGIWESSID
;
1341 iwe_stream_add_point(info
, current_ev
, end_buf
, &iwe
,
1343 pr_debug(" essid size OK.\n");
1346 switch (bss
->bsstype
.data
) {
1347 case P80211ENUM_bsstype_infrastructure
:
1348 iwe
.u
.mode
= IW_MODE_MASTER
;
1351 case P80211ENUM_bsstype_independent
:
1352 iwe
.u
.mode
= IW_MODE_ADHOC
;
1359 iwe
.cmd
= SIOCGIWMODE
;
1362 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1365 /* Encryption capability */
1366 if (bss
->privacy
.data
== P80211ENUM_truth_true
)
1367 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
1369 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
1370 iwe
.u
.data
.length
= 0;
1371 iwe
.cmd
= SIOCGIWENCODE
;
1373 iwe_stream_add_point(info
, current_ev
, end_buf
, &iwe
, NULL
);
1375 /* Add frequency. (short) bss->channel is the frequency in MHz */
1376 iwe
.u
.freq
.m
= bss
->dschannel
.data
;
1378 iwe
.cmd
= SIOCGIWFREQ
;
1380 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1383 /* Add quality statistics */
1384 iwe
.u
.qual
.level
= bss
->signal
.data
;
1385 iwe
.u
.qual
.noise
= bss
->noise
.data
;
1386 /* do a simple SNR for quality */
1387 iwe
.u
.qual
.qual
= qual_as_percent(bss
->signal
.data
- bss
->noise
.data
);
1390 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1396 static int p80211wext_giwscan(netdevice_t
*dev
,
1397 struct iw_request_info
*info
,
1398 struct iw_point
*srq
, char *extra
)
1400 wlandevice_t
*wlandev
= dev
->ml_priv
;
1401 p80211msg_dot11req_scan_results_t msg
;
1406 char *current_ev
= extra
;
1408 /* Since wireless tools doesn't really have a way of passing how
1409 * many scan results results there were back here, keep grabbing them
1413 memset(&msg
, 0, sizeof(msg
));
1414 msg
.msgcode
= DIDmsg_dot11req_scan_results
;
1415 msg
.bssindex
.data
= i
;
1417 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1418 if ((result
!= 0) ||
1419 (msg
.resultcode
.data
!= P80211ENUM_resultcode_success
)) {
1424 wext_translate_bss(info
, current_ev
,
1425 extra
+ IW_SCAN_MAX_DATA
, &msg
);
1428 } while (i
< IW_MAX_AP
);
1430 srq
->length
= (current_ev
- extra
);
1431 srq
->flags
= 0; /* todo */
1433 if (result
&& !scan_good
)
1434 err
= prism2_result2err(msg
.resultcode
.data
);
1439 /* extra wireless extensions stuff to support NetworkManager (I hope) */
1441 /* SIOCSIWENCODEEXT */
1442 static int p80211wext_set_encodeext(struct net_device
*dev
,
1443 struct iw_request_info
*info
,
1444 union iwreq_data
*wrqu
, char *extra
)
1446 wlandevice_t
*wlandev
= dev
->ml_priv
;
1447 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1448 p80211msg_dot11req_mibset_t msg
;
1449 p80211item_pstr32_t
*pstr
;
1452 struct iw_point
*encoding
= &wrqu
->encoding
;
1453 int idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1455 pr_debug("set_encode_ext flags[%d] alg[%d] keylen[%d]\n",
1456 ext
->ext_flags
, (int)ext
->alg
, (int)ext
->key_len
);
1458 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
1459 /* set default key ? I'm not sure if this the the correct thing to do here */
1462 if (idx
< 1 || idx
> NUM_WEPKEYS
)
1467 pr_debug("setting default key (%d)\n", idx
);
1469 p80211wext_dorequest(wlandev
,
1470 DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID
,
1476 if (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
1477 if (ext
->alg
!= IW_ENCODE_ALG_WEP
) {
1478 pr_debug("asked to set a non wep key :(\n");
1482 if (idx
< 1 || idx
> NUM_WEPKEYS
)
1487 pr_debug("Set WEP key (%d)\n", idx
);
1488 wlandev
->wep_keylens
[idx
] = ext
->key_len
;
1489 memcpy(wlandev
->wep_keys
[idx
], ext
->key
, ext
->key_len
);
1491 memset(&msg
, 0, sizeof(msg
));
1492 pstr
= (p80211item_pstr32_t
*) & msg
.mibattribute
.data
;
1493 memcpy(pstr
->data
.data
, ext
->key
, ext
->key_len
);
1494 pstr
->data
.len
= ext
->key_len
;
1498 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0
;
1502 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1
;
1506 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2
;
1510 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3
;
1515 msg
.msgcode
= DIDmsg_dot11req_mibset
;
1516 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1517 pr_debug("result (%d)\n", result
);
1522 /* SIOCGIWENCODEEXT */
1523 static int p80211wext_get_encodeext(struct net_device
*dev
,
1524 struct iw_request_info
*info
,
1525 union iwreq_data
*wrqu
, char *extra
)
1527 wlandevice_t
*wlandev
= dev
->ml_priv
;
1528 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1530 struct iw_point
*encoding
= &wrqu
->encoding
;
1535 pr_debug("get_encode_ext flags[%d] alg[%d] keylen[%d]\n",
1536 ext
->ext_flags
, (int)ext
->alg
, (int)ext
->key_len
);
1538 max_len
= encoding
->length
- sizeof(*ext
);
1540 pr_debug("get_encodeext max_len [%d] invalid\n", max_len
);
1544 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1546 pr_debug("get_encode_ext index [%d]\n", idx
);
1549 if (idx
< 1 || idx
> NUM_WEPKEYS
) {
1550 pr_debug("get_encode_ext invalid key index [%d]\n",
1557 /* default key ? not sure what to do */
1558 /* will just use key[0] for now ! FIX ME */
1561 encoding
->flags
= idx
+ 1;
1562 memset(ext
, 0, sizeof(*ext
));
1564 ext
->alg
= IW_ENCODE_ALG_WEP
;
1565 ext
->key_len
= wlandev
->wep_keylens
[idx
];
1566 memcpy(ext
->key
, wlandev
->wep_keys
[idx
], ext
->key_len
);
1568 encoding
->flags
|= IW_ENCODE_ENABLED
;
1574 static int p80211_wext_set_iwauth(struct net_device
*dev
,
1575 struct iw_request_info
*info
,
1576 union iwreq_data
*wrqu
, char *extra
)
1578 wlandevice_t
*wlandev
= dev
->ml_priv
;
1579 struct iw_param
*param
= &wrqu
->param
;
1582 pr_debug("set_iwauth flags[%d]\n", (int)param
->flags
& IW_AUTH_INDEX
);
1584 switch (param
->flags
& IW_AUTH_INDEX
) {
1585 case IW_AUTH_DROP_UNENCRYPTED
:
1586 pr_debug("drop_unencrypted %d\n", param
->value
);
1589 p80211wext_dorequest(wlandev
,
1590 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
1591 P80211ENUM_truth_true
);
1594 p80211wext_dorequest(wlandev
,
1595 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
1596 P80211ENUM_truth_false
);
1599 case IW_AUTH_PRIVACY_INVOKED
:
1600 pr_debug("privacy invoked %d\n", param
->value
);
1603 p80211wext_dorequest(wlandev
,
1604 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
1605 P80211ENUM_truth_true
);
1608 p80211wext_dorequest(wlandev
,
1609 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
1610 P80211ENUM_truth_false
);
1614 case IW_AUTH_80211_AUTH_ALG
:
1615 if (param
->value
& IW_AUTH_ALG_OPEN_SYSTEM
) {
1616 pr_debug("set open_system\n");
1617 wlandev
->hostwep
&= ~HOSTWEP_SHAREDKEY
;
1618 } else if (param
->value
& IW_AUTH_ALG_SHARED_KEY
) {
1619 pr_debug("set shared key\n");
1620 wlandev
->hostwep
|= HOSTWEP_SHAREDKEY
;
1622 /* don't know what to do know */
1623 pr_debug("unknown AUTH_ALG (%d)\n", param
->value
);
1636 static int p80211_wext_get_iwauth(struct net_device
*dev
,
1637 struct iw_request_info
*info
,
1638 union iwreq_data
*wrqu
, char *extra
)
1640 wlandevice_t
*wlandev
= dev
->ml_priv
;
1641 struct iw_param
*param
= &wrqu
->param
;
1644 pr_debug("get_iwauth flags[%d]\n", (int)param
->flags
& IW_AUTH_INDEX
);
1646 switch (param
->flags
& IW_AUTH_INDEX
) {
1647 case IW_AUTH_DROP_UNENCRYPTED
:
1649 wlandev
->hostwep
& HOSTWEP_EXCLUDEUNENCRYPTED
? 1 : 0;
1652 case IW_AUTH_PRIVACY_INVOKED
:
1654 wlandev
->hostwep
& HOSTWEP_PRIVACYINVOKED
? 1 : 0;
1657 case IW_AUTH_80211_AUTH_ALG
:
1659 wlandev
->hostwep
& HOSTWEP_SHAREDKEY
?
1660 IW_AUTH_ALG_SHARED_KEY
: IW_AUTH_ALG_OPEN_SYSTEM
;
1670 static iw_handler p80211wext_handlers
[] = {
1671 (iw_handler
) p80211wext_siwcommit
, /* SIOCSIWCOMMIT */
1672 (iw_handler
) p80211wext_giwname
, /* SIOCGIWNAME */
1673 (iw_handler
) NULL
, /* SIOCSIWNWID */
1674 (iw_handler
) NULL
, /* SIOCGIWNWID */
1675 (iw_handler
) p80211wext_siwfreq
, /* SIOCSIWFREQ */
1676 (iw_handler
) p80211wext_giwfreq
, /* SIOCGIWFREQ */
1677 (iw_handler
) p80211wext_siwmode
, /* SIOCSIWMODE */
1678 (iw_handler
) p80211wext_giwmode
, /* SIOCGIWMODE */
1679 (iw_handler
) NULL
, /* SIOCSIWSENS */
1680 (iw_handler
) NULL
, /* SIOCGIWSENS */
1681 (iw_handler
) NULL
, /* not used *//* SIOCSIWRANGE */
1682 (iw_handler
) p80211wext_giwrange
, /* SIOCGIWRANGE */
1683 (iw_handler
) NULL
, /* not used *//* SIOCSIWPRIV */
1684 (iw_handler
) NULL
, /* kernel code *//* SIOCGIWPRIV */
1685 (iw_handler
) NULL
, /* not used *//* SIOCSIWSTATS */
1686 (iw_handler
) NULL
, /* kernel code *//* SIOCGIWSTATS */
1687 (iw_handler
) p80211wext_siwspy
, /* SIOCSIWSPY */
1688 (iw_handler
) p80211wext_giwspy
, /* SIOCGIWSPY */
1689 (iw_handler
) NULL
, /* -- hole -- */
1690 (iw_handler
) NULL
, /* -- hole -- */
1691 (iw_handler
) NULL
, /* SIOCSIWAP */
1692 (iw_handler
) p80211wext_giwap
, /* SIOCGIWAP */
1693 (iw_handler
) NULL
, /* -- hole -- */
1694 (iw_handler
) NULL
, /* SIOCGIWAPLIST */
1695 (iw_handler
) p80211wext_siwscan
, /* SIOCSIWSCAN */
1696 (iw_handler
) p80211wext_giwscan
, /* SIOCGIWSCAN */
1697 (iw_handler
) p80211wext_siwessid
, /* SIOCSIWESSID */
1698 (iw_handler
) p80211wext_giwessid
, /* SIOCGIWESSID */
1699 (iw_handler
) NULL
, /* SIOCSIWNICKN */
1700 (iw_handler
) p80211wext_giwessid
, /* SIOCGIWNICKN */
1701 (iw_handler
) NULL
, /* -- hole -- */
1702 (iw_handler
) NULL
, /* -- hole -- */
1703 (iw_handler
) NULL
, /* SIOCSIWRATE */
1704 (iw_handler
) p80211wext_giwrate
, /* SIOCGIWRATE */
1705 (iw_handler
) p80211wext_siwrts
, /* SIOCSIWRTS */
1706 (iw_handler
) p80211wext_giwrts
, /* SIOCGIWRTS */
1707 (iw_handler
) p80211wext_siwfrag
, /* SIOCSIWFRAG */
1708 (iw_handler
) p80211wext_giwfrag
, /* SIOCGIWFRAG */
1709 (iw_handler
) p80211wext_siwtxpow
, /* SIOCSIWTXPOW */
1710 (iw_handler
) p80211wext_giwtxpow
, /* SIOCGIWTXPOW */
1711 (iw_handler
) p80211wext_siwretry
, /* SIOCSIWRETRY */
1712 (iw_handler
) p80211wext_giwretry
, /* SIOCGIWRETRY */
1713 (iw_handler
) p80211wext_siwencode
, /* SIOCSIWENCODE */
1714 (iw_handler
) p80211wext_giwencode
, /* SIOCGIWENCODE */
1715 (iw_handler
) NULL
, /* SIOCSIWPOWER */
1716 (iw_handler
) NULL
, /* SIOCGIWPOWER */
1717 /* WPA operations */
1718 (iw_handler
) NULL
, /* -- hole -- */
1719 (iw_handler
) NULL
, /* -- hole -- */
1720 (iw_handler
) NULL
, /* SIOCSIWGENIE set generic IE */
1721 (iw_handler
) NULL
, /* SIOCGIWGENIE get generic IE */
1722 (iw_handler
) p80211_wext_set_iwauth
, /* SIOCSIWAUTH set authentication mode params */
1723 (iw_handler
) p80211_wext_get_iwauth
, /* SIOCGIWAUTH get authentication mode params */
1725 (iw_handler
) p80211wext_set_encodeext
, /* SIOCSIWENCODEEXT set encoding token & mode */
1726 (iw_handler
) p80211wext_get_encodeext
, /* SIOCGIWENCODEEXT get encoding token & mode */
1727 (iw_handler
) NULL
, /* SIOCSIWPMKSA PMKSA cache operation */
1730 struct iw_handler_def p80211wext_handler_def
= {
1731 .num_standard
= ARRAY_SIZE(p80211wext_handlers
),
1733 .num_private_args
= 0,
1734 .standard
= p80211wext_handlers
,
1736 .private_args
= NULL
,
1737 .get_wireless_stats
= p80211wext_get_wireless_stats
1740 int p80211wext_event_associated(wlandevice_t
* wlandev
, int assoc
)
1742 union iwreq_data data
;
1744 /* Send the association state first */
1745 data
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1747 memcpy(data
.ap_addr
.sa_data
, wlandev
->bssid
, ETH_ALEN
);
1749 memset(data
.ap_addr
.sa_data
, 0, ETH_ALEN
);
1751 if (wlan_wext_write
)
1752 wireless_send_event(wlandev
->netdev
, SIOCGIWAP
, &data
, NULL
);
1757 /* XXX send association data, like IEs, etc etc. */