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 /*================================================================*/
56 /* Project Includes */
58 #include "p80211types.h"
59 #include "p80211hdr.h"
60 #include "p80211conv.h"
61 #include "p80211mgmt.h"
62 #include "p80211msg.h"
63 #include "p80211metastruct.h"
64 #include "p80211metadef.h"
65 #include "p80211netdev.h"
66 #include "p80211ioctl.h"
67 #include "p80211req.h"
69 static int p80211wext_giwrate(netdevice_t
* dev
,
70 struct iw_request_info
*info
,
71 struct iw_param
*rrq
, char *extra
);
72 static int p80211wext_giwessid(netdevice_t
* dev
,
73 struct iw_request_info
*info
,
74 struct iw_point
*data
, char *essid
);
76 static u8
p80211_mhz_to_channel(u16 mhz
)
79 return (mhz
- 5000) / 5;
85 return (mhz
- 2407) / 5;
90 static u16
p80211_channel_to_mhz(u8 ch
, int dot11a
)
100 return 5000 + (5 * ch
);
106 if ((ch
< 14) && (ch
> 0))
107 return 2407 + (5 * ch
);
112 /* taken from orinoco.c ;-) */
113 static const long p80211wext_channel_freq
[] = {
114 2412, 2417, 2422, 2427, 2432, 2437, 2442,
115 2447, 2452, 2457, 2462, 2467, 2472, 2484
118 #define NUM_CHANNELS ARRAY_SIZE(p80211wext_channel_freq)
120 /* steal a spare bit to store the shared/opensystems state.
121 should default to open if not set */
122 #define HOSTWEP_SHAREDKEY BIT(3)
124 static int qual_as_percent(int snr
)
133 static int p80211wext_dorequest(wlandevice_t
* wlandev
, u32 did
, u32 data
)
135 p80211msg_dot11req_mibset_t msg
;
136 p80211item_uint32_t mibitem
;
139 msg
.msgcode
= DIDmsg_dot11req_mibset
;
142 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
143 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
148 static int p80211wext_autojoin(wlandevice_t
* wlandev
)
150 p80211msg_lnxreq_autojoin_t msg
;
151 struct iw_point data
;
152 char ssid
[IW_ESSID_MAX_SIZE
];
158 result
= p80211wext_giwessid(wlandev
->netdev
, NULL
, &data
, ssid
);
165 if (wlandev
->hostwep
& HOSTWEP_SHAREDKEY
)
166 msg
.authtype
.data
= P80211ENUM_authalg_sharedkey
;
168 msg
.authtype
.data
= P80211ENUM_authalg_opensystem
;
170 msg
.msgcode
= DIDmsg_lnxreq_autojoin
;
172 /* Trim the last '\0' to fit the SSID format */
174 if (data
.length
&& ssid
[data
.length
- 1] == '\0')
175 data
.length
= data
.length
- 1;
177 memcpy(msg
.ssid
.data
.data
, ssid
, data
.length
);
178 msg
.ssid
.data
.len
= data
.length
;
180 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
193 /* called by /proc/net/wireless */
194 struct iw_statistics
*p80211wext_get_wireless_stats(netdevice_t
* dev
)
196 p80211msg_lnxreq_commsquality_t quality
;
197 wlandevice_t
*wlandev
= dev
->ml_priv
;
198 struct iw_statistics
*wstats
= &wlandev
->wstats
;
202 if ((wlandev
== NULL
) || (wlandev
->msdstate
!= WLAN_MSD_RUNNING
))
205 /* XXX Only valid in station mode */
208 /* build request message */
209 quality
.msgcode
= DIDmsg_lnxreq_commsquality
;
210 quality
.dbm
.data
= P80211ENUM_truth_true
;
211 quality
.dbm
.status
= P80211ENUM_msgitem_status_data_ok
;
213 /* send message to nsd */
214 if (wlandev
->mlmerequest
== NULL
)
217 retval
= wlandev
->mlmerequest(wlandev
, (p80211msg_t
*) & quality
);
219 wstats
->qual
.qual
= qual_as_percent(quality
.link
.data
); /* overall link quality */
220 wstats
->qual
.level
= quality
.level
.data
; /* instant signal level */
221 wstats
->qual
.noise
= quality
.noise
.data
; /* instant noise level */
223 wstats
->qual
.updated
= IW_QUAL_ALL_UPDATED
| IW_QUAL_DBM
;
224 wstats
->discard
.code
= wlandev
->rx
.decrypt_err
;
225 wstats
->discard
.nwid
= 0;
226 wstats
->discard
.misc
= 0;
228 wstats
->discard
.fragment
= 0; /* incomplete fragments */
229 wstats
->discard
.retries
= 0; /* tx retries. */
230 wstats
->miss
.beacon
= 0;
235 static int p80211wext_giwname(netdevice_t
* dev
,
236 struct iw_request_info
*info
,
237 char *name
, char *extra
)
239 struct iw_param rate
;
243 result
= p80211wext_giwrate(dev
, NULL
, &rate
, NULL
);
250 switch (rate
.value
) {
253 strcpy(name
, "IEEE 802.11-DS");
257 strcpy(name
, "IEEE 802.11-b");
264 static int p80211wext_giwfreq(netdevice_t
* dev
,
265 struct iw_request_info
*info
,
266 struct iw_freq
*freq
, char *extra
)
268 wlandevice_t
*wlandev
= dev
->ml_priv
;
269 p80211item_uint32_t mibitem
;
270 p80211msg_dot11req_mibset_t msg
;
274 msg
.msgcode
= DIDmsg_dot11req_mibget
;
275 mibitem
.did
= DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel
;
276 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
277 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
284 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
286 if (mibitem
.data
> NUM_CHANNELS
) {
291 /* convert into frequency instead of a channel */
293 freq
->m
= p80211_channel_to_mhz(mibitem
.data
, 0) * 100000;
299 static int p80211wext_siwfreq(netdevice_t
* dev
,
300 struct iw_request_info
*info
,
301 struct iw_freq
*freq
, char *extra
)
303 wlandevice_t
*wlandev
= dev
->ml_priv
;
304 p80211item_uint32_t mibitem
;
305 p80211msg_dot11req_mibset_t msg
;
309 if (!wlan_wext_write
) {
314 msg
.msgcode
= DIDmsg_dot11req_mibset
;
315 mibitem
.did
= DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel
;
316 mibitem
.status
= P80211ENUM_msgitem_status_data_ok
;
318 if ((freq
->e
== 0) && (freq
->m
<= 1000))
319 mibitem
.data
= freq
->m
;
321 mibitem
.data
= p80211_mhz_to_channel(freq
->m
);
323 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
324 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
335 static int p80211wext_giwmode(netdevice_t
* dev
,
336 struct iw_request_info
*info
,
337 __u32
* mode
, char *extra
)
339 wlandevice_t
*wlandev
= dev
->ml_priv
;
341 switch (wlandev
->macmode
) {
342 case WLAN_MACMODE_IBSS_STA
:
343 *mode
= IW_MODE_ADHOC
;
345 case WLAN_MACMODE_ESS_STA
:
346 *mode
= IW_MODE_INFRA
;
348 case WLAN_MACMODE_ESS_AP
:
349 *mode
= IW_MODE_MASTER
;
353 *mode
= IW_MODE_AUTO
;
359 static int p80211wext_siwmode(netdevice_t
* dev
,
360 struct iw_request_info
*info
,
361 __u32
* mode
, char *extra
)
363 wlandevice_t
*wlandev
= dev
->ml_priv
;
364 p80211item_uint32_t mibitem
;
365 p80211msg_dot11req_mibset_t msg
;
369 if (!wlan_wext_write
) {
374 if (*mode
!= IW_MODE_ADHOC
&& *mode
!= IW_MODE_INFRA
&&
375 *mode
!= IW_MODE_MASTER
) {
380 /* Operation mode is the same with current mode */
381 if (*mode
== wlandev
->macmode
)
386 wlandev
->macmode
= WLAN_MACMODE_IBSS_STA
;
389 wlandev
->macmode
= WLAN_MACMODE_ESS_STA
;
392 wlandev
->macmode
= WLAN_MACMODE_ESS_AP
;
396 printk(KERN_INFO
"Operation mode: %d not support\n", *mode
);
400 /* Set Operation mode to the PORT TYPE RID */
401 msg
.msgcode
= DIDmsg_dot11req_mibset
;
402 mibitem
.did
= DIDmib_p2_p2Static_p2CnfPortType
;
403 mibitem
.data
= (*mode
== IW_MODE_ADHOC
) ? 0 : 1;
404 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
405 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
414 static int p80211wext_giwrange(netdevice_t
* dev
,
415 struct iw_request_info
*info
,
416 struct iw_point
*data
, char *extra
)
418 struct iw_range
*range
= (struct iw_range
*)extra
;
421 /* for backward compatability set size and zero everything we don't understand */
422 data
->length
= sizeof(*range
);
423 memset(range
, 0, sizeof(*range
));
425 range
->txpower_capa
= IW_TXPOW_DBM
;
426 /* XXX what about min/max_pmp, min/max_pmt, etc. */
428 range
->we_version_compiled
= WIRELESS_EXT
;
429 range
->we_version_source
= 13;
431 range
->retry_capa
= IW_RETRY_LIMIT
;
432 range
->retry_flags
= IW_RETRY_LIMIT
;
433 range
->min_retry
= 0;
434 range
->max_retry
= 255;
436 range
->event_capa
[0] = (IW_EVENT_CAPA_K_0
| /* mode/freq/ssid */
437 IW_EVENT_CAPA_MASK(SIOCGIWAP
) |
438 IW_EVENT_CAPA_MASK(SIOCGIWSCAN
));
439 range
->event_capa
[1] = IW_EVENT_CAPA_K_1
; /* encode */
440 range
->event_capa
[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL
) |
441 IW_EVENT_CAPA_MASK(IWEVCUSTOM
));
443 range
->num_channels
= NUM_CHANNELS
;
445 /* XXX need to filter against the regulatory domain &| active set */
447 for (i
= 0; i
< NUM_CHANNELS
; i
++) {
448 range
->freq
[val
].i
= i
+ 1;
449 range
->freq
[val
].m
= p80211wext_channel_freq
[i
] * 100000;
450 range
->freq
[val
].e
= 1;
454 range
->num_frequency
= val
;
456 /* Max of /proc/net/wireless */
457 range
->max_qual
.qual
= 100;
458 range
->max_qual
.level
= 0;
459 range
->max_qual
.noise
= 0;
460 range
->sensitivity
= 3;
461 /* XXX these need to be nsd-specific! */
464 range
->max_rts
= 2347;
465 range
->min_frag
= 256;
466 range
->max_frag
= 2346;
468 range
->max_encoding_tokens
= NUM_WEPKEYS
;
469 range
->num_encoding_sizes
= 2;
470 range
->encoding_size
[0] = 5;
471 range
->encoding_size
[1] = 13;
473 /* XXX what about num_bitrates/throughput? */
474 range
->num_bitrates
= 0;
476 /* estimated max throughput */
477 /* XXX need to cap it if we're running at ~2Mbps.. */
478 range
->throughput
= 5500000;
483 static int p80211wext_giwap(netdevice_t
* dev
,
484 struct iw_request_info
*info
,
485 struct sockaddr
*ap_addr
, char *extra
)
488 wlandevice_t
*wlandev
= dev
->ml_priv
;
490 memcpy(ap_addr
->sa_data
, wlandev
->bssid
, WLAN_BSSID_LEN
);
491 ap_addr
->sa_family
= ARPHRD_ETHER
;
496 static int p80211wext_giwencode(netdevice_t
* dev
,
497 struct iw_request_info
*info
,
498 struct iw_point
*erq
, char *key
)
500 wlandevice_t
*wlandev
= dev
->ml_priv
;
504 i
= (erq
->flags
& IW_ENCODE_INDEX
) - 1;
507 if (wlandev
->hostwep
& HOSTWEP_PRIVACYINVOKED
)
508 erq
->flags
|= IW_ENCODE_ENABLED
;
510 erq
->flags
|= IW_ENCODE_DISABLED
;
512 if (wlandev
->hostwep
& HOSTWEP_EXCLUDEUNENCRYPTED
)
513 erq
->flags
|= IW_ENCODE_RESTRICTED
;
515 erq
->flags
|= IW_ENCODE_OPEN
;
517 i
= (erq
->flags
& IW_ENCODE_INDEX
) - 1;
520 i
= wlandev
->hostwep
& HOSTWEP_DEFAULTKEY_MASK
;
522 if ((i
< 0) || (i
>= NUM_WEPKEYS
)) {
529 /* copy the key from the driver cache as the keys are read-only MIBs */
530 erq
->length
= wlandev
->wep_keylens
[i
];
531 memcpy(key
, wlandev
->wep_keys
[i
], erq
->length
);
537 static int p80211wext_siwencode(netdevice_t
* dev
,
538 struct iw_request_info
*info
,
539 struct iw_point
*erq
, char *key
)
541 wlandevice_t
*wlandev
= dev
->ml_priv
;
542 p80211msg_dot11req_mibset_t msg
;
543 p80211item_pstr32_t pstr
;
549 if (!wlan_wext_write
) {
554 /* Check the Key index first. */
555 if ((i
= (erq
->flags
& IW_ENCODE_INDEX
))) {
557 if ((i
< 1) || (i
> NUM_WEPKEYS
)) {
563 /* Set current key number only if no keys are given */
564 if (erq
->flags
& IW_ENCODE_NOKEY
) {
566 p80211wext_dorequest(wlandev
,
567 DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID
,
577 /* Use defaultkey if no Key Index */
578 i
= wlandev
->hostwep
& HOSTWEP_DEFAULTKEY_MASK
;
581 /* Check if there is no key information in the iwconfig request */
582 if ((erq
->flags
& IW_ENCODE_NOKEY
) == 0) {
584 /*------------------------------------------------------------
585 * If there is WEP Key for setting, check the Key Information
586 * and then set it to the firmware.
587 -------------------------------------------------------------*/
589 if (erq
->length
> 0) {
591 /* copy the key from the driver cache as the keys are read-only MIBs */
592 wlandev
->wep_keylens
[i
] = erq
->length
;
593 memcpy(wlandev
->wep_keys
[i
], key
, erq
->length
);
595 /* Prepare data struture for p80211req_dorequest. */
596 memcpy(pstr
.data
.data
, key
, erq
->length
);
597 pstr
.data
.len
= erq
->length
;
602 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0
;
607 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1
;
612 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2
;
617 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3
;
625 msg
.msgcode
= DIDmsg_dot11req_mibset
;
626 memcpy(&msg
.mibattribute
.data
, &pstr
, sizeof(pstr
));
627 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
637 /* Check the PrivacyInvoked flag */
638 if (erq
->flags
& IW_ENCODE_DISABLED
) {
640 p80211wext_dorequest(wlandev
,
641 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
642 P80211ENUM_truth_false
);
645 p80211wext_dorequest(wlandev
,
646 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
647 P80211ENUM_truth_true
);
655 /* The security mode may be open or restricted, and its meaning
656 depends on the card used. With most cards, in open mode no
657 authentication is used and the card may also accept non-
658 encrypted sessions, whereas in restricted mode only encrypted
659 sessions are accepted and the card will use authentication if
662 if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
664 p80211wext_dorequest(wlandev
,
665 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
666 P80211ENUM_truth_true
);
667 } else if (erq
->flags
& IW_ENCODE_OPEN
) {
669 p80211wext_dorequest(wlandev
,
670 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
671 P80211ENUM_truth_false
);
684 static int p80211wext_giwessid(netdevice_t
* dev
,
685 struct iw_request_info
*info
,
686 struct iw_point
*data
, char *essid
)
688 wlandevice_t
*wlandev
= dev
->ml_priv
;
690 if (wlandev
->ssid
.len
) {
691 data
->length
= wlandev
->ssid
.len
;
693 memcpy(essid
, wlandev
->ssid
.data
, data
->length
);
694 essid
[data
->length
] = 0;
695 #if (WIRELESS_EXT < 21)
699 memset(essid
, 0, sizeof(wlandev
->ssid
.data
));
707 static int p80211wext_siwessid(netdevice_t
* dev
,
708 struct iw_request_info
*info
,
709 struct iw_point
*data
, char *essid
)
711 wlandevice_t
*wlandev
= dev
->ml_priv
;
712 p80211msg_lnxreq_autojoin_t msg
;
716 int length
= data
->length
;
718 if (!wlan_wext_write
) {
723 if (wlandev
->hostwep
& HOSTWEP_SHAREDKEY
)
724 msg
.authtype
.data
= P80211ENUM_authalg_sharedkey
;
726 msg
.authtype
.data
= P80211ENUM_authalg_opensystem
;
728 msg
.msgcode
= DIDmsg_lnxreq_autojoin
;
730 #if (WIRELESS_EXT < 21)
735 /* Trim the last '\0' to fit the SSID format */
736 if (length
&& essid
[length
- 1] == '\0')
739 memcpy(msg
.ssid
.data
.data
, essid
, length
);
740 msg
.ssid
.data
.len
= length
;
742 pr_debug("autojoin_ssid for %s \n", essid
);
743 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
744 pr_debug("autojoin_ssid %d\n", result
);
755 static int p80211wext_siwcommit(netdevice_t
* dev
,
756 struct iw_request_info
*info
,
757 struct iw_point
*data
, char *essid
)
759 wlandevice_t
*wlandev
= dev
->ml_priv
;
762 if (!wlan_wext_write
) {
768 err
= p80211wext_autojoin(wlandev
);
774 static int p80211wext_giwrate(netdevice_t
* dev
,
775 struct iw_request_info
*info
,
776 struct iw_param
*rrq
, char *extra
)
778 wlandevice_t
*wlandev
= dev
->ml_priv
;
779 p80211item_uint32_t mibitem
;
780 p80211msg_dot11req_mibset_t msg
;
784 msg
.msgcode
= DIDmsg_dot11req_mibget
;
785 mibitem
.did
= DIDmib_p2_p2MAC_p2CurrentTxRate
;
786 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
787 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
794 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
796 rrq
->fixed
= 0; /* can it change? */
800 #define HFA384x_RATEBIT_1 ((u16)1)
801 #define HFA384x_RATEBIT_2 ((u16)2)
802 #define HFA384x_RATEBIT_5dot5 ((u16)4)
803 #define HFA384x_RATEBIT_11 ((u16)8)
805 switch (mibitem
.data
) {
806 case HFA384x_RATEBIT_1
:
807 rrq
->value
= 1000000;
809 case HFA384x_RATEBIT_2
:
810 rrq
->value
= 2000000;
812 case HFA384x_RATEBIT_5dot5
:
813 rrq
->value
= 5500000;
815 case HFA384x_RATEBIT_11
:
816 rrq
->value
= 11000000;
825 static int p80211wext_giwrts(netdevice_t
* dev
,
826 struct iw_request_info
*info
,
827 struct iw_param
*rts
, char *extra
)
829 wlandevice_t
*wlandev
= dev
->ml_priv
;
830 p80211item_uint32_t mibitem
;
831 p80211msg_dot11req_mibset_t msg
;
835 msg
.msgcode
= DIDmsg_dot11req_mibget
;
836 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold
;
837 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
838 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
845 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
847 rts
->value
= mibitem
.data
;
848 rts
->disabled
= (rts
->value
== 2347);
855 static int p80211wext_siwrts(netdevice_t
* dev
,
856 struct iw_request_info
*info
,
857 struct iw_param
*rts
, char *extra
)
859 wlandevice_t
*wlandev
= dev
->ml_priv
;
860 p80211item_uint32_t mibitem
;
861 p80211msg_dot11req_mibset_t msg
;
865 if (!wlan_wext_write
) {
870 msg
.msgcode
= DIDmsg_dot11req_mibget
;
871 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold
;
875 mibitem
.data
= rts
->value
;
877 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
878 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
889 static int p80211wext_giwfrag(netdevice_t
* dev
,
890 struct iw_request_info
*info
,
891 struct iw_param
*frag
, char *extra
)
893 wlandevice_t
*wlandev
= dev
->ml_priv
;
894 p80211item_uint32_t mibitem
;
895 p80211msg_dot11req_mibset_t msg
;
899 msg
.msgcode
= DIDmsg_dot11req_mibget
;
901 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold
;
902 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
903 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
910 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
912 frag
->value
= mibitem
.data
;
913 frag
->disabled
= (frag
->value
== 2346);
920 static int p80211wext_siwfrag(netdevice_t
* dev
,
921 struct iw_request_info
*info
,
922 struct iw_param
*frag
, char *extra
)
924 wlandevice_t
*wlandev
= dev
->ml_priv
;
925 p80211item_uint32_t mibitem
;
926 p80211msg_dot11req_mibset_t msg
;
930 if (!wlan_wext_write
) {
935 msg
.msgcode
= DIDmsg_dot11req_mibset
;
937 DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold
;
942 mibitem
.data
= frag
->value
;
944 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
945 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
956 #ifndef IW_RETRY_LONG
957 #define IW_RETRY_LONG IW_RETRY_MAX
960 #ifndef IW_RETRY_SHORT
961 #define IW_RETRY_SHORT IW_RETRY_MIN
964 static int p80211wext_giwretry(netdevice_t
* dev
,
965 struct iw_request_info
*info
,
966 struct iw_param
*rrq
, char *extra
)
968 wlandevice_t
*wlandev
= dev
->ml_priv
;
969 p80211item_uint32_t mibitem
;
970 p80211msg_dot11req_mibset_t msg
;
973 u16 shortretry
, longretry
, lifetime
;
975 msg
.msgcode
= DIDmsg_dot11req_mibget
;
976 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit
;
978 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
979 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
986 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
988 shortretry
= mibitem
.data
;
990 mibitem
.did
= DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit
;
992 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
993 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1000 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
1002 longretry
= mibitem
.data
;
1005 DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime
;
1007 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
1008 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1015 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
1017 lifetime
= mibitem
.data
;
1021 if ((rrq
->flags
& IW_RETRY_TYPE
) == IW_RETRY_LIFETIME
) {
1022 rrq
->flags
= IW_RETRY_LIFETIME
;
1023 rrq
->value
= lifetime
* 1024;
1025 if (rrq
->flags
& IW_RETRY_LONG
) {
1026 rrq
->flags
= IW_RETRY_LIMIT
| IW_RETRY_LONG
;
1027 rrq
->value
= longretry
;
1029 rrq
->flags
= IW_RETRY_LIMIT
;
1030 rrq
->value
= shortretry
;
1031 if (shortretry
!= longretry
)
1032 rrq
->flags
|= IW_RETRY_SHORT
;
1041 static int p80211wext_siwretry(netdevice_t
* dev
,
1042 struct iw_request_info
*info
,
1043 struct iw_param
*rrq
, char *extra
)
1045 wlandevice_t
*wlandev
= dev
->ml_priv
;
1046 p80211item_uint32_t mibitem
;
1047 p80211msg_dot11req_mibset_t msg
;
1051 if (!wlan_wext_write
) {
1052 err
= (-EOPNOTSUPP
);
1056 if (rrq
->disabled
) {
1061 msg
.msgcode
= DIDmsg_dot11req_mibset
;
1063 if ((rrq
->flags
& IW_RETRY_TYPE
) == IW_RETRY_LIFETIME
) {
1065 DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime
;
1066 mibitem
.data
= rrq
->value
/= 1024;
1068 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
1069 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1076 if (rrq
->flags
& IW_RETRY_LONG
) {
1078 DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit
;
1079 mibitem
.data
= rrq
->value
;
1081 memcpy(&msg
.mibattribute
.data
, &mibitem
,
1083 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1091 if (rrq
->flags
& IW_RETRY_SHORT
) {
1093 DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit
;
1094 mibitem
.data
= rrq
->value
;
1096 memcpy(&msg
.mibattribute
.data
, &mibitem
,
1098 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1112 static int p80211wext_siwtxpow(netdevice_t
* dev
,
1113 struct iw_request_info
*info
,
1114 struct iw_param
*rrq
, char *extra
)
1116 wlandevice_t
*wlandev
= dev
->ml_priv
;
1117 p80211item_uint32_t mibitem
;
1118 p80211msg_dot11req_mibset_t msg
;
1122 if (!wlan_wext_write
) {
1123 err
= (-EOPNOTSUPP
);
1127 msg
.msgcode
= DIDmsg_dot11req_mibset
;
1129 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel
;
1130 if (rrq
->fixed
== 0)
1133 mibitem
.data
= rrq
->value
;
1134 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
1135 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1146 static int p80211wext_giwtxpow(netdevice_t
* dev
,
1147 struct iw_request_info
*info
,
1148 struct iw_param
*rrq
, char *extra
)
1150 wlandevice_t
*wlandev
= dev
->ml_priv
;
1151 p80211item_uint32_t mibitem
;
1152 p80211msg_dot11req_mibset_t msg
;
1156 msg
.msgcode
= DIDmsg_dot11req_mibget
;
1158 DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel
;
1160 memcpy(&msg
.mibattribute
.data
, &mibitem
, sizeof(mibitem
));
1161 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1168 memcpy(&mibitem
, &msg
.mibattribute
.data
, sizeof(mibitem
));
1170 /* XXX handle OFF by setting disabled = 1; */
1172 rrq
->flags
= 0; /* IW_TXPOW_DBM; */
1175 rrq
->value
= mibitem
.data
;
1181 static int p80211wext_siwspy(netdevice_t
* dev
,
1182 struct iw_request_info
*info
,
1183 struct iw_point
*srq
, char *extra
)
1185 wlandevice_t
*wlandev
= dev
->ml_priv
;
1186 struct sockaddr address
[IW_MAX_SPY
];
1187 int number
= srq
->length
;
1190 /* Copy the data from the input buffer */
1191 memcpy(address
, extra
, sizeof(struct sockaddr
) * number
);
1193 wlandev
->spy_number
= 0;
1197 /* extract the addresses */
1198 for (i
= 0; i
< number
; i
++) {
1200 memcpy(wlandev
->spy_address
[i
], address
[i
].sa_data
,
1205 memset(wlandev
->spy_stat
, 0,
1206 sizeof(struct iw_quality
) * IW_MAX_SPY
);
1208 /* set number of addresses */
1209 wlandev
->spy_number
= number
;
1215 /* jkriegl: from orinoco, modified */
1216 static int p80211wext_giwspy(netdevice_t
* dev
,
1217 struct iw_request_info
*info
,
1218 struct iw_point
*srq
, char *extra
)
1220 wlandevice_t
*wlandev
= dev
->ml_priv
;
1222 struct sockaddr address
[IW_MAX_SPY
];
1223 struct iw_quality spy_stat
[IW_MAX_SPY
];
1227 number
= wlandev
->spy_number
;
1231 /* populate address and spy struct's */
1232 for (i
= 0; i
< number
; i
++) {
1233 memcpy(address
[i
].sa_data
, wlandev
->spy_address
[i
],
1235 address
[i
].sa_family
= AF_UNIX
;
1236 memcpy(&spy_stat
[i
], &wlandev
->spy_stat
[i
],
1237 sizeof(struct iw_quality
));
1240 /* reset update flag */
1241 for (i
= 0; i
< number
; i
++)
1242 wlandev
->spy_stat
[i
].updated
= 0;
1245 /* push stuff to user space */
1246 srq
->length
= number
;
1247 memcpy(extra
, address
, sizeof(struct sockaddr
) * number
);
1248 memcpy(extra
+ sizeof(struct sockaddr
) * number
, spy_stat
,
1249 sizeof(struct iw_quality
) * number
);
1254 static int prism2_result2err(int prism2_result
)
1258 switch (prism2_result
) {
1259 case P80211ENUM_resultcode_invalid_parameters
:
1262 case P80211ENUM_resultcode_implementation_failure
:
1265 case P80211ENUM_resultcode_not_supported
:
1276 static int p80211wext_siwscan(netdevice_t
* dev
,
1277 struct iw_request_info
*info
,
1278 struct iw_point
*srq
, char *extra
)
1280 wlandevice_t
*wlandev
= dev
->ml_priv
;
1281 p80211msg_dot11req_scan_t msg
;
1286 if (wlandev
->macmode
== WLAN_MACMODE_ESS_AP
) {
1287 printk(KERN_ERR
"Can't scan in AP mode\n");
1288 err
= (-EOPNOTSUPP
);
1292 memset(&msg
, 0x00, sizeof(p80211msg_dot11req_scan_t
));
1293 msg
.msgcode
= DIDmsg_dot11req_scan
;
1294 msg
.bsstype
.data
= P80211ENUM_bsstype_any
;
1296 memset(&(msg
.bssid
.data
), 0xFF, sizeof(p80211item_pstr6_t
));
1297 msg
.bssid
.data
.len
= 6;
1299 msg
.scantype
.data
= P80211ENUM_scantype_active
;
1300 msg
.probedelay
.data
= 0;
1302 for (i
= 1; i
<= 14; i
++)
1303 msg
.channellist
.data
.data
[i
- 1] = i
;
1304 msg
.channellist
.data
.len
= 14;
1306 msg
.maxchanneltime
.data
= 250;
1307 msg
.minchanneltime
.data
= 200;
1309 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1311 err
= prism2_result2err(msg
.resultcode
.data
);
1317 /* Helper to translate scan into Wireless Extensions scan results.
1318 * Inspired by the prism54 code, which was in turn inspired by the
1321 static char *wext_translate_bss(struct iw_request_info
*info
, char *current_ev
,
1323 p80211msg_dot11req_scan_results_t
* bss
)
1325 struct iw_event iwe
; /* Temporary buffer */
1327 /* The first entry must be the MAC address */
1328 memcpy(iwe
.u
.ap_addr
.sa_data
, bss
->bssid
.data
.data
, WLAN_BSSID_LEN
);
1329 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1330 iwe
.cmd
= SIOCGIWAP
;
1332 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1335 /* The following entries will be displayed in the same order we give them */
1338 if (bss
->ssid
.data
.len
> 0) {
1339 char essid
[IW_ESSID_MAX_SIZE
+ 1];
1343 min_t(unsigned short, IW_ESSID_MAX_SIZE
,
1344 bss
->ssid
.data
.len
);
1345 memset(&essid
, 0, sizeof(essid
));
1346 memcpy(&essid
, bss
->ssid
.data
.data
, size
);
1347 pr_debug(" essid size = %d\n", size
);
1348 iwe
.u
.data
.length
= size
;
1349 iwe
.u
.data
.flags
= 1;
1350 iwe
.cmd
= SIOCGIWESSID
;
1352 iwe_stream_add_point(info
, current_ev
, end_buf
, &iwe
,
1354 pr_debug(" essid size OK.\n");
1357 switch (bss
->bsstype
.data
) {
1358 case P80211ENUM_bsstype_infrastructure
:
1359 iwe
.u
.mode
= IW_MODE_MASTER
;
1362 case P80211ENUM_bsstype_independent
:
1363 iwe
.u
.mode
= IW_MODE_ADHOC
;
1370 iwe
.cmd
= SIOCGIWMODE
;
1373 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1376 /* Encryption capability */
1377 if (bss
->privacy
.data
== P80211ENUM_truth_true
)
1378 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
1380 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
1381 iwe
.u
.data
.length
= 0;
1382 iwe
.cmd
= SIOCGIWENCODE
;
1384 iwe_stream_add_point(info
, current_ev
, end_buf
, &iwe
, NULL
);
1386 /* Add frequency. (short) bss->channel is the frequency in MHz */
1387 iwe
.u
.freq
.m
= bss
->dschannel
.data
;
1389 iwe
.cmd
= SIOCGIWFREQ
;
1391 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1394 /* Add quality statistics */
1395 iwe
.u
.qual
.level
= bss
->signal
.data
;
1396 iwe
.u
.qual
.noise
= bss
->noise
.data
;
1397 /* do a simple SNR for quality */
1398 iwe
.u
.qual
.qual
= qual_as_percent(bss
->signal
.data
- bss
->noise
.data
);
1401 iwe_stream_add_event(info
, current_ev
, end_buf
, &iwe
,
1407 static int p80211wext_giwscan(netdevice_t
* dev
,
1408 struct iw_request_info
*info
,
1409 struct iw_point
*srq
, char *extra
)
1411 wlandevice_t
*wlandev
= dev
->ml_priv
;
1412 p80211msg_dot11req_scan_results_t msg
;
1417 char *current_ev
= extra
;
1419 /* Since wireless tools doesn't really have a way of passing how
1420 * many scan results results there were back here, keep grabbing them
1424 memset(&msg
, 0, sizeof(msg
));
1425 msg
.msgcode
= DIDmsg_dot11req_scan_results
;
1426 msg
.bssindex
.data
= i
;
1428 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1429 if ((result
!= 0) ||
1430 (msg
.resultcode
.data
!= P80211ENUM_resultcode_success
)) {
1435 wext_translate_bss(info
, current_ev
,
1436 extra
+ IW_SCAN_MAX_DATA
, &msg
);
1439 } while (i
< IW_MAX_AP
);
1441 srq
->length
= (current_ev
- extra
);
1442 srq
->flags
= 0; /* todo */
1444 if (result
&& !scan_good
)
1445 err
= prism2_result2err(msg
.resultcode
.data
);
1450 /* extra wireless extensions stuff to support NetworkManager (I hope) */
1452 /* SIOCSIWENCODEEXT */
1453 static int p80211wext_set_encodeext(struct net_device
*dev
,
1454 struct iw_request_info
*info
,
1455 union iwreq_data
*wrqu
, char *extra
)
1457 wlandevice_t
*wlandev
= dev
->ml_priv
;
1458 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1459 p80211msg_dot11req_mibset_t msg
;
1460 p80211item_pstr32_t
*pstr
;
1463 struct iw_point
*encoding
= &wrqu
->encoding
;
1464 int idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1466 pr_debug("set_encode_ext flags[%d] alg[%d] keylen[%d]\n",
1467 ext
->ext_flags
, (int)ext
->alg
, (int)ext
->key_len
);
1469 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
1470 /* set default key ? I'm not sure if this the the correct thing to do here */
1473 if (idx
< 1 || idx
> NUM_WEPKEYS
)
1478 pr_debug("setting default key (%d)\n", idx
);
1480 p80211wext_dorequest(wlandev
,
1481 DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID
,
1487 if (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
1488 if (ext
->alg
!= IW_ENCODE_ALG_WEP
) {
1489 pr_debug("asked to set a non wep key :(\n");
1493 if (idx
< 1 || idx
> NUM_WEPKEYS
)
1498 pr_debug("Set WEP key (%d)\n", idx
);
1499 wlandev
->wep_keylens
[idx
] = ext
->key_len
;
1500 memcpy(wlandev
->wep_keys
[idx
], ext
->key
, ext
->key_len
);
1502 memset(&msg
, 0, sizeof(msg
));
1503 pstr
= (p80211item_pstr32_t
*) & msg
.mibattribute
.data
;
1504 memcpy(pstr
->data
.data
, ext
->key
, ext
->key_len
);
1505 pstr
->data
.len
= ext
->key_len
;
1509 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0
;
1513 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1
;
1517 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2
;
1521 DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3
;
1526 msg
.msgcode
= DIDmsg_dot11req_mibset
;
1527 result
= p80211req_dorequest(wlandev
, (u8
*) & msg
);
1528 pr_debug("result (%d)\n", result
);
1533 /* SIOCGIWENCODEEXT */
1534 static int p80211wext_get_encodeext(struct net_device
*dev
,
1535 struct iw_request_info
*info
,
1536 union iwreq_data
*wrqu
, char *extra
)
1538 wlandevice_t
*wlandev
= dev
->ml_priv
;
1539 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1541 struct iw_point
*encoding
= &wrqu
->encoding
;
1546 pr_debug("get_encode_ext flags[%d] alg[%d] keylen[%d]\n",
1547 ext
->ext_flags
, (int)ext
->alg
, (int)ext
->key_len
);
1549 max_len
= encoding
->length
- sizeof(*ext
);
1551 pr_debug("get_encodeext max_len [%d] invalid\n", max_len
);
1555 idx
= encoding
->flags
& IW_ENCODE_INDEX
;
1557 pr_debug("get_encode_ext index [%d]\n", idx
);
1560 if (idx
< 1 || idx
> NUM_WEPKEYS
) {
1561 pr_debug("get_encode_ext invalid key index [%d]\n",
1568 /* default key ? not sure what to do */
1569 /* will just use key[0] for now ! FIX ME */
1572 encoding
->flags
= idx
+ 1;
1573 memset(ext
, 0, sizeof(*ext
));
1575 ext
->alg
= IW_ENCODE_ALG_WEP
;
1576 ext
->key_len
= wlandev
->wep_keylens
[idx
];
1577 memcpy(ext
->key
, wlandev
->wep_keys
[idx
], ext
->key_len
);
1579 encoding
->flags
|= IW_ENCODE_ENABLED
;
1585 static int p80211_wext_set_iwauth(struct net_device
*dev
,
1586 struct iw_request_info
*info
,
1587 union iwreq_data
*wrqu
, char *extra
)
1589 wlandevice_t
*wlandev
= dev
->ml_priv
;
1590 struct iw_param
*param
= &wrqu
->param
;
1593 pr_debug("set_iwauth flags[%d]\n", (int)param
->flags
& IW_AUTH_INDEX
);
1595 switch (param
->flags
& IW_AUTH_INDEX
) {
1596 case IW_AUTH_DROP_UNENCRYPTED
:
1597 pr_debug("drop_unencrypted %d\n", param
->value
);
1600 p80211wext_dorequest(wlandev
,
1601 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
1602 P80211ENUM_truth_true
);
1605 p80211wext_dorequest(wlandev
,
1606 DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted
,
1607 P80211ENUM_truth_false
);
1610 case IW_AUTH_PRIVACY_INVOKED
:
1611 pr_debug("privacy invoked %d\n", param
->value
);
1614 p80211wext_dorequest(wlandev
,
1615 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
1616 P80211ENUM_truth_true
);
1619 p80211wext_dorequest(wlandev
,
1620 DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked
,
1621 P80211ENUM_truth_false
);
1625 case IW_AUTH_80211_AUTH_ALG
:
1626 if (param
->value
& IW_AUTH_ALG_OPEN_SYSTEM
) {
1627 pr_debug("set open_system\n");
1628 wlandev
->hostwep
&= ~HOSTWEP_SHAREDKEY
;
1629 } else if (param
->value
& IW_AUTH_ALG_SHARED_KEY
) {
1630 pr_debug("set shared key\n");
1631 wlandev
->hostwep
|= HOSTWEP_SHAREDKEY
;
1633 /* don't know what to do know */
1634 pr_debug("unknown AUTH_ALG (%d)\n", param
->value
);
1647 static int p80211_wext_get_iwauth(struct net_device
*dev
,
1648 struct iw_request_info
*info
,
1649 union iwreq_data
*wrqu
, char *extra
)
1651 wlandevice_t
*wlandev
= dev
->ml_priv
;
1652 struct iw_param
*param
= &wrqu
->param
;
1655 pr_debug("get_iwauth flags[%d]\n", (int)param
->flags
& IW_AUTH_INDEX
);
1657 switch (param
->flags
& IW_AUTH_INDEX
) {
1658 case IW_AUTH_DROP_UNENCRYPTED
:
1660 wlandev
->hostwep
& HOSTWEP_EXCLUDEUNENCRYPTED
? 1 : 0;
1663 case IW_AUTH_PRIVACY_INVOKED
:
1665 wlandev
->hostwep
& HOSTWEP_PRIVACYINVOKED
? 1 : 0;
1668 case IW_AUTH_80211_AUTH_ALG
:
1670 wlandev
->hostwep
& HOSTWEP_SHAREDKEY
?
1671 IW_AUTH_ALG_SHARED_KEY
: IW_AUTH_ALG_OPEN_SYSTEM
;
1681 static iw_handler p80211wext_handlers
[] = {
1682 (iw_handler
) p80211wext_siwcommit
, /* SIOCSIWCOMMIT */
1683 (iw_handler
) p80211wext_giwname
, /* SIOCGIWNAME */
1684 (iw_handler
) NULL
, /* SIOCSIWNWID */
1685 (iw_handler
) NULL
, /* SIOCGIWNWID */
1686 (iw_handler
) p80211wext_siwfreq
, /* SIOCSIWFREQ */
1687 (iw_handler
) p80211wext_giwfreq
, /* SIOCGIWFREQ */
1688 (iw_handler
) p80211wext_siwmode
, /* SIOCSIWMODE */
1689 (iw_handler
) p80211wext_giwmode
, /* SIOCGIWMODE */
1690 (iw_handler
) NULL
, /* SIOCSIWSENS */
1691 (iw_handler
) NULL
, /* SIOCGIWSENS */
1692 (iw_handler
) NULL
, /* not used *//* SIOCSIWRANGE */
1693 (iw_handler
) p80211wext_giwrange
, /* SIOCGIWRANGE */
1694 (iw_handler
) NULL
, /* not used *//* SIOCSIWPRIV */
1695 (iw_handler
) NULL
, /* kernel code *//* SIOCGIWPRIV */
1696 (iw_handler
) NULL
, /* not used *//* SIOCSIWSTATS */
1697 (iw_handler
) NULL
, /* kernel code *//* SIOCGIWSTATS */
1698 (iw_handler
) p80211wext_siwspy
, /* SIOCSIWSPY */
1699 (iw_handler
) p80211wext_giwspy
, /* SIOCGIWSPY */
1700 (iw_handler
) NULL
, /* -- hole -- */
1701 (iw_handler
) NULL
, /* -- hole -- */
1702 (iw_handler
) NULL
, /* SIOCSIWAP */
1703 (iw_handler
) p80211wext_giwap
, /* SIOCGIWAP */
1704 (iw_handler
) NULL
, /* -- hole -- */
1705 (iw_handler
) NULL
, /* SIOCGIWAPLIST */
1706 (iw_handler
) p80211wext_siwscan
, /* SIOCSIWSCAN */
1707 (iw_handler
) p80211wext_giwscan
, /* SIOCGIWSCAN */
1708 (iw_handler
) p80211wext_siwessid
, /* SIOCSIWESSID */
1709 (iw_handler
) p80211wext_giwessid
, /* SIOCGIWESSID */
1710 (iw_handler
) NULL
, /* SIOCSIWNICKN */
1711 (iw_handler
) p80211wext_giwessid
, /* SIOCGIWNICKN */
1712 (iw_handler
) NULL
, /* -- hole -- */
1713 (iw_handler
) NULL
, /* -- hole -- */
1714 (iw_handler
) NULL
, /* SIOCSIWRATE */
1715 (iw_handler
) p80211wext_giwrate
, /* SIOCGIWRATE */
1716 (iw_handler
) p80211wext_siwrts
, /* SIOCSIWRTS */
1717 (iw_handler
) p80211wext_giwrts
, /* SIOCGIWRTS */
1718 (iw_handler
) p80211wext_siwfrag
, /* SIOCSIWFRAG */
1719 (iw_handler
) p80211wext_giwfrag
, /* SIOCGIWFRAG */
1720 (iw_handler
) p80211wext_siwtxpow
, /* SIOCSIWTXPOW */
1721 (iw_handler
) p80211wext_giwtxpow
, /* SIOCGIWTXPOW */
1722 (iw_handler
) p80211wext_siwretry
, /* SIOCSIWRETRY */
1723 (iw_handler
) p80211wext_giwretry
, /* SIOCGIWRETRY */
1724 (iw_handler
) p80211wext_siwencode
, /* SIOCSIWENCODE */
1725 (iw_handler
) p80211wext_giwencode
, /* SIOCGIWENCODE */
1726 (iw_handler
) NULL
, /* SIOCSIWPOWER */
1727 (iw_handler
) NULL
, /* SIOCGIWPOWER */
1728 /* WPA operations */
1729 (iw_handler
) NULL
, /* -- hole -- */
1730 (iw_handler
) NULL
, /* -- hole -- */
1731 (iw_handler
) NULL
, /* SIOCSIWGENIE set generic IE */
1732 (iw_handler
) NULL
, /* SIOCGIWGENIE get generic IE */
1733 (iw_handler
) p80211_wext_set_iwauth
, /* SIOCSIWAUTH set authentication mode params */
1734 (iw_handler
) p80211_wext_get_iwauth
, /* SIOCGIWAUTH get authentication mode params */
1736 (iw_handler
) p80211wext_set_encodeext
, /* SIOCSIWENCODEEXT set encoding token & mode */
1737 (iw_handler
) p80211wext_get_encodeext
, /* SIOCGIWENCODEEXT get encoding token & mode */
1738 (iw_handler
) NULL
, /* SIOCSIWPMKSA PMKSA cache operation */
1741 struct iw_handler_def p80211wext_handler_def
= {
1742 .num_standard
= ARRAY_SIZE(p80211wext_handlers
),
1744 .num_private_args
= 0,
1745 .standard
= p80211wext_handlers
,
1747 .private_args
= NULL
,
1748 .get_wireless_stats
= p80211wext_get_wireless_stats
1751 int p80211wext_event_associated(wlandevice_t
* wlandev
, int assoc
)
1753 union iwreq_data data
;
1755 /* Send the association state first */
1756 data
.ap_addr
.sa_family
= ARPHRD_ETHER
;
1758 memcpy(data
.ap_addr
.sa_data
, wlandev
->bssid
, ETH_ALEN
);
1760 memset(data
.ap_addr
.sa_data
, 0, ETH_ALEN
);
1762 if (wlan_wext_write
)
1763 wireless_send_event(wlandev
->netdev
, SIOCGIWAP
, &data
, NULL
);
1768 /* XXX send association data, like IEs, etc etc. */