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 /*================================================================*/
41 #include <linux/version.h>
43 #include <linux/kernel.h>
44 #include <linux/sched.h>
45 #include <linux/types.h>
46 #include <linux/slab.h>
47 #include <linux/netdevice.h>
48 #include <linux/etherdevice.h>
49 #include <linux/wireless.h>
50 #include <net/iw_handler.h>
51 #include <linux/if_arp.h>
52 #include <asm/bitops.h>
53 #include <asm/uaccess.h>
54 #include <asm/byteorder.h>
56 /*================================================================*/
57 /* Project Includes */
59 #include "wlan_compat.h"
61 #include "p80211types.h"
62 #include "p80211hdr.h"
63 #include "p80211conv.h"
64 #include "p80211mgmt.h"
65 #include "p80211msg.h"
66 #include "p80211metastruct.h"
67 #include "p80211metadef.h"
68 #include "p80211netdev.h"
69 #include "p80211ioctl.h"
70 #include "p80211req.h"
72 static int p80211wext_giwrate(netdevice_t *dev,
73 struct iw_request_info *info,
74 struct iw_param *rrq, char *extra);
75 static int p80211wext_giwessid(netdevice_t *dev,
76 struct iw_request_info *info,
77 struct iw_point *data, char *essid);
78 /* compatibility to wireless extensions */
81 static UINT8 p80211_mhz_to_channel(UINT16 mhz)
84 return ((mhz - 5000) / 5);
91 return ((mhz - 2407) / 5);
97 static UINT16 p80211_channel_to_mhz(UINT8 ch, int dot11a)
108 return (5000 + (5 * ch));
116 if ((ch < 14) && (ch > 0)) {
117 return (2407 + (5 * ch));
123 /* taken from orinoco.c ;-) */
124 static const long p80211wext_channel_freq[] = {
125 2412, 2417, 2422, 2427, 2432, 2437, 2442,
126 2447, 2452, 2457, 2462, 2467, 2472, 2484
128 #define NUM_CHANNELS (sizeof(p80211wext_channel_freq) / sizeof(p80211wext_channel_freq[0]))
130 /* steal a spare bit to store the shared/opensystems state. should default to open if not set */
131 #define HOSTWEP_SHAREDKEY BIT3
134 /** function declarations =============== */
136 static int qual_as_percent(int snr ) {
147 static int p80211wext_dorequest(wlandevice_t *wlandev, UINT32 did, UINT32 data)
149 p80211msg_dot11req_mibset_t msg;
150 p80211item_uint32_t mibitem;
155 msg.msgcode = DIDmsg_dot11req_mibset;
158 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
159 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
165 static int p80211wext_autojoin(wlandevice_t *wlandev)
167 p80211msg_lnxreq_autojoin_t msg;
168 struct iw_point data;
169 char ssid[IW_ESSID_MAX_SIZE];
177 result = p80211wext_giwessid(wlandev->netdev, NULL, &data, ssid);
184 if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
185 msg.authtype.data = P80211ENUM_authalg_sharedkey;
187 msg.authtype.data = P80211ENUM_authalg_opensystem;
189 msg.msgcode = DIDmsg_lnxreq_autojoin;
191 /* Trim the last '\0' to fit the SSID format */
193 if (data.length && ssid[data.length-1] == '\0') {
194 data.length = data.length - 1;
197 memcpy(msg.ssid.data.data, ssid, data.length);
198 msg.ssid.data.len = data.length;
200 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
214 /* called by /proc/net/wireless */
215 struct iw_statistics* p80211wext_get_wireless_stats (netdevice_t *dev)
217 p80211msg_lnxreq_commsquality_t quality;
218 wlandevice_t *wlandev = dev->ml_priv;
219 struct iw_statistics* wstats = &wlandev->wstats;
224 if ( (wlandev == NULL) || (wlandev->msdstate != WLAN_MSD_RUNNING) )
227 /* XXX Only valid in station mode */
230 /* build request message */
231 quality.msgcode = DIDmsg_lnxreq_commsquality;
232 quality.dbm.data = P80211ENUM_truth_true;
233 quality.dbm.status = P80211ENUM_msgitem_status_data_ok;
235 /* send message to nsd */
236 if ( wlandev->mlmerequest == NULL )
239 retval = wlandev->mlmerequest(wlandev, (p80211msg_t*) &quality);
241 wstats->qual.qual = qual_as_percent(quality.link.data); /* overall link quality */
242 wstats->qual.level = quality.level.data; /* instant signal level */
243 wstats->qual.noise = quality.noise.data; /* instant noise level */
245 wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
246 wstats->discard.code = wlandev->rx.decrypt_err;
247 wstats->discard.nwid = 0;
248 wstats->discard.misc = 0;
250 wstats->discard.fragment = 0; // incomplete fragments
251 wstats->discard.retries = 0; // tx retries.
252 wstats->miss.beacon = 0;
259 static int p80211wext_giwname(netdevice_t *dev,
260 struct iw_request_info *info,
261 char *name, char *extra)
263 struct iw_param rate;
269 result = p80211wext_giwrate(dev, NULL, &rate, NULL);
276 switch (rate.value) {
279 strcpy(name, "IEEE 802.11-DS");
283 strcpy(name, "IEEE 802.11-b");
291 static int p80211wext_giwfreq(netdevice_t *dev,
292 struct iw_request_info *info,
293 struct iw_freq *freq, char *extra)
295 wlandevice_t *wlandev = dev->ml_priv;
296 p80211item_uint32_t mibitem;
297 p80211msg_dot11req_mibset_t msg;
303 msg.msgcode = DIDmsg_dot11req_mibget;
304 mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
305 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
306 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
313 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
315 if (mibitem.data > NUM_CHANNELS) {
320 /* convert into frequency instead of a channel */
322 freq->m = p80211_channel_to_mhz(mibitem.data, 0) * 100000;
329 static int p80211wext_siwfreq(netdevice_t *dev,
330 struct iw_request_info *info,
331 struct iw_freq *freq, char *extra)
333 wlandevice_t *wlandev = dev->ml_priv;
334 p80211item_uint32_t mibitem;
335 p80211msg_dot11req_mibset_t msg;
341 if (!wlan_wext_write) {
346 msg.msgcode = DIDmsg_dot11req_mibset;
347 mibitem.did = DIDmib_dot11phy_dot11PhyDSSSTable_dot11CurrentChannel;
348 mibitem.status = P80211ENUM_msgitem_status_data_ok;
350 if ( (freq->e == 0) && (freq->m <= 1000) )
351 mibitem.data = freq->m;
353 mibitem.data = p80211_mhz_to_channel(freq->m);
355 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
356 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
368 static int p80211wext_giwmode(netdevice_t *dev,
369 struct iw_request_info *info,
370 __u32 *mode, char *extra)
372 wlandevice_t *wlandev = dev->ml_priv;
376 switch (wlandev->macmode) {
377 case WLAN_MACMODE_IBSS_STA:
378 *mode = IW_MODE_ADHOC;
380 case WLAN_MACMODE_ESS_STA:
381 *mode = IW_MODE_INFRA;
383 case WLAN_MACMODE_ESS_AP:
384 *mode = IW_MODE_MASTER;
388 *mode = IW_MODE_AUTO;
395 static int p80211wext_siwmode(netdevice_t *dev,
396 struct iw_request_info *info,
397 __u32 *mode, char *extra)
399 wlandevice_t *wlandev = dev->ml_priv;
400 p80211item_uint32_t mibitem;
401 p80211msg_dot11req_mibset_t msg;
407 if (!wlan_wext_write) {
412 if (*mode != IW_MODE_ADHOC && *mode != IW_MODE_INFRA &&
413 *mode != IW_MODE_MASTER) {
418 /* Operation mode is the same with current mode */
419 if (*mode == wlandev->macmode)
424 wlandev->macmode = WLAN_MACMODE_IBSS_STA;
427 wlandev->macmode = WLAN_MACMODE_ESS_STA;
430 wlandev->macmode = WLAN_MACMODE_ESS_AP;
434 WLAN_LOG_INFO("Operation mode: %d not support\n", *mode);
438 /* Set Operation mode to the PORT TYPE RID */
440 #warning "get rid of p2mib here"
442 msg.msgcode = DIDmsg_dot11req_mibset;
443 mibitem.did = DIDmib_p2_p2Static_p2CnfPortType;
444 mibitem.data = (*mode == IW_MODE_ADHOC) ? 0 : 1;
445 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
446 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
458 static int p80211wext_giwrange(netdevice_t *dev,
459 struct iw_request_info *info,
460 struct iw_point *data, char *extra)
462 struct iw_range *range = (struct iw_range *) extra;
467 // for backward compatability set size & zero everything we don't understand
468 data->length = sizeof(*range);
469 memset(range,0,sizeof(*range));
471 range->txpower_capa = IW_TXPOW_DBM;
472 // XXX what about min/max_pmp, min/max_pmt, etc.
474 range->we_version_compiled = WIRELESS_EXT;
475 range->we_version_source = 13;
477 range->retry_capa = IW_RETRY_LIMIT;
478 range->retry_flags = IW_RETRY_LIMIT;
479 range->min_retry = 0;
480 range->max_retry = 255;
482 range->event_capa[0] = (IW_EVENT_CAPA_K_0 | //mode/freq/ssid
483 IW_EVENT_CAPA_MASK(SIOCGIWAP) |
484 IW_EVENT_CAPA_MASK(SIOCGIWSCAN));
485 range->event_capa[1] = IW_EVENT_CAPA_K_1; //encode
486 range->event_capa[4] = (IW_EVENT_CAPA_MASK(IWEVQUAL) |
487 IW_EVENT_CAPA_MASK(IWEVCUSTOM) );
489 range->num_channels = NUM_CHANNELS;
491 /* XXX need to filter against the regulatory domain &| active set */
493 for (i = 0; i < NUM_CHANNELS ; i++) {
494 range->freq[val].i = i + 1;
495 range->freq[val].m = p80211wext_channel_freq[i] * 100000;
496 range->freq[val].e = 1;
500 range->num_frequency = val;
502 /* Max of /proc/net/wireless */
503 range->max_qual.qual = 100;
504 range->max_qual.level = 0;
505 range->max_qual.noise = 0;
506 range->sensitivity = 3;
507 // XXX these need to be nsd-specific!
510 range->max_rts = 2347;
511 range->min_frag = 256;
512 range->max_frag = 2346;
514 range->max_encoding_tokens = NUM_WEPKEYS;
515 range->num_encoding_sizes = 2;
516 range->encoding_size[0] = 5;
517 range->encoding_size[1] = 13;
519 // XXX what about num_bitrates/throughput?
520 range->num_bitrates = 0;
522 /* estimated max throughput */
523 // XXX need to cap it if we're running at ~2Mbps..
524 range->throughput = 5500000;
530 static int p80211wext_giwap(netdevice_t *dev,
531 struct iw_request_info *info,
532 struct sockaddr *ap_addr, char *extra)
535 wlandevice_t *wlandev = dev->ml_priv;
539 memcpy(ap_addr->sa_data, wlandev->bssid, WLAN_BSSID_LEN);
540 ap_addr->sa_family = ARPHRD_ETHER;
546 static int p80211wext_giwencode(netdevice_t *dev,
547 struct iw_request_info *info,
548 struct iw_point *erq, char *key)
550 wlandevice_t *wlandev = dev->ml_priv;
556 if (wlandev->hostwep & HOSTWEP_PRIVACYINVOKED)
557 erq->flags = IW_ENCODE_ENABLED;
559 erq->flags = IW_ENCODE_DISABLED;
561 if (wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED)
562 erq->flags |= IW_ENCODE_RESTRICTED;
564 erq->flags |= IW_ENCODE_OPEN;
566 i = (erq->flags & IW_ENCODE_INDEX) - 1;
569 i = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK;
571 if ((i < 0) || (i >= NUM_WEPKEYS)) {
578 /* copy the key from the driver cache as the keys are read-only MIBs */
579 erq->length = wlandev->wep_keylens[i];
580 memcpy(key, wlandev->wep_keys[i], erq->length);
587 static int p80211wext_siwencode(netdevice_t *dev,
588 struct iw_request_info *info,
589 struct iw_point *erq, char *key)
591 wlandevice_t *wlandev = dev->ml_priv;
592 p80211msg_dot11req_mibset_t msg;
593 p80211item_pstr32_t pstr;
601 if (!wlan_wext_write) {
606 /* Check the Key index first. */
607 if((i = (erq->flags & IW_ENCODE_INDEX))) {
609 if ((i < 1) || (i > NUM_WEPKEYS)) {
616 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, i);
628 // Do not thing when no Key Index
631 /* Check if there is no key information in the iwconfig request */
632 if((erq->flags & IW_ENCODE_NOKEY) == 0 && enable == 1) {
634 /*------------------------------------------------------------
635 * If there is WEP Key for setting, check the Key Information
636 * and then set it to the firmware.
637 -------------------------------------------------------------*/
639 if (erq->length > 0) {
641 /* copy the key from the driver cache as the keys are read-only MIBs */
642 wlandev->wep_keylens[i] = erq->length;
643 memcpy(wlandev->wep_keys[i], key, erq->length);
645 /* Prepare data struture for p80211req_dorequest. */
646 memcpy(pstr.data.data, key, erq->length);
647 pstr.data.len = erq->length;
652 pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
656 pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
660 pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
664 pstr.did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
672 msg.msgcode = DIDmsg_dot11req_mibset;
673 memcpy(&msg.mibattribute.data, &pstr, sizeof(pstr));
674 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
684 /* Check the PrivacyInvoked flag */
685 if (erq->flags & IW_ENCODE_DISABLED) {
686 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
688 else if((erq->flags & IW_ENCODE_ENABLED) || enable == 1) {
689 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
697 /* Check the ExcludeUnencrypted flag */
698 if (erq->flags & IW_ENCODE_RESTRICTED) {
699 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
701 else if (erq->flags & IW_ENCODE_OPEN) {
702 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
716 static int p80211wext_giwessid(netdevice_t *dev,
717 struct iw_request_info *info,
718 struct iw_point *data, char *essid)
720 wlandevice_t *wlandev = dev->ml_priv;
724 if (wlandev->ssid.len) {
725 data->length = wlandev->ssid.len;
727 memcpy(essid, wlandev->ssid.data, data->length);
728 essid[data->length] = 0;
729 #if (WIRELESS_EXT < 21)
733 memset(essid, 0, sizeof(wlandev->ssid.data));
742 static int p80211wext_siwessid(netdevice_t *dev,
743 struct iw_request_info *info,
744 struct iw_point *data, char *essid)
746 wlandevice_t *wlandev = dev->ml_priv;
747 p80211msg_lnxreq_autojoin_t msg;
751 int length = data->length;
755 if (!wlan_wext_write) {
761 if ( wlandev->hostwep & HOSTWEP_SHAREDKEY )
762 msg.authtype.data = P80211ENUM_authalg_sharedkey;
764 msg.authtype.data = P80211ENUM_authalg_opensystem;
766 msg.msgcode = DIDmsg_lnxreq_autojoin;
768 #if (WIRELESS_EXT < 21)
769 if (length) length--;
772 /* Trim the last '\0' to fit the SSID format */
774 if (length && essid[length-1] == '\0') {
778 memcpy(msg.ssid.data.data, essid, length);
779 msg.ssid.data.len = length;
781 WLAN_LOG_DEBUG(1,"autojoin_ssid for %s \n",essid);
782 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
783 WLAN_LOG_DEBUG(1,"autojoin_ssid %d\n",result);
796 static int p80211wext_siwcommit(netdevice_t *dev,
797 struct iw_request_info *info,
798 struct iw_point *data, char *essid)
800 wlandevice_t *wlandev = dev->ml_priv;
805 if (!wlan_wext_write) {
811 err = p80211wext_autojoin(wlandev);
819 static int p80211wext_giwrate(netdevice_t *dev,
820 struct iw_request_info *info,
821 struct iw_param *rrq, char *extra)
823 wlandevice_t *wlandev = dev->ml_priv;
824 p80211item_uint32_t mibitem;
825 p80211msg_dot11req_mibset_t msg;
831 msg.msgcode = DIDmsg_dot11req_mibget;
832 mibitem.did = DIDmib_p2_p2MAC_p2CurrentTxRate;
833 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
834 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
841 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
843 rrq->fixed = 0; /* can it change? */
847 #define HFA384x_RATEBIT_1 ((UINT16)1)
848 #define HFA384x_RATEBIT_2 ((UINT16)2)
849 #define HFA384x_RATEBIT_5dot5 ((UINT16)4)
850 #define HFA384x_RATEBIT_11 ((UINT16)8)
852 switch (mibitem.data) {
853 case HFA384x_RATEBIT_1:
854 rrq->value = 1000000;
856 case HFA384x_RATEBIT_2:
857 rrq->value = 2000000;
859 case HFA384x_RATEBIT_5dot5:
860 rrq->value = 5500000;
862 case HFA384x_RATEBIT_11:
863 rrq->value = 11000000;
873 static int p80211wext_giwrts(netdevice_t *dev,
874 struct iw_request_info *info,
875 struct iw_param *rts, char *extra)
877 wlandevice_t *wlandev = dev->ml_priv;
878 p80211item_uint32_t mibitem;
879 p80211msg_dot11req_mibset_t msg;
885 msg.msgcode = DIDmsg_dot11req_mibget;
886 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
887 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
888 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
895 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
897 rts->value = mibitem.data;
898 rts->disabled = (rts->value == 2347);
907 static int p80211wext_siwrts(netdevice_t *dev,
908 struct iw_request_info *info,
909 struct iw_param *rts, char *extra)
911 wlandevice_t *wlandev = dev->ml_priv;
912 p80211item_uint32_t mibitem;
913 p80211msg_dot11req_mibset_t msg;
919 if (!wlan_wext_write) {
924 msg.msgcode = DIDmsg_dot11req_mibget;
925 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11RTSThreshold;
929 mibitem.data = rts->value;
931 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
932 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
944 static int p80211wext_giwfrag(netdevice_t *dev,
945 struct iw_request_info *info,
946 struct iw_param *frag, char *extra)
948 wlandevice_t *wlandev = dev->ml_priv;
949 p80211item_uint32_t mibitem;
950 p80211msg_dot11req_mibset_t msg;
956 msg.msgcode = DIDmsg_dot11req_mibget;
957 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
958 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
959 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
966 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
968 frag->value = mibitem.data;
969 frag->disabled = (frag->value == 2346);
977 static int p80211wext_siwfrag(netdevice_t *dev,
978 struct iw_request_info *info,
979 struct iw_param *frag, char *extra)
981 wlandevice_t *wlandev = dev->ml_priv;
982 p80211item_uint32_t mibitem;
983 p80211msg_dot11req_mibset_t msg;
989 if (!wlan_wext_write) {
994 msg.msgcode = DIDmsg_dot11req_mibset;
995 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11FragmentationThreshold;
1000 mibitem.data = frag->value;
1002 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1003 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1015 #ifndef IW_RETRY_LONG
1016 #define IW_RETRY_LONG IW_RETRY_MAX
1019 #ifndef IW_RETRY_SHORT
1020 #define IW_RETRY_SHORT IW_RETRY_MIN
1023 static int p80211wext_giwretry(netdevice_t *dev,
1024 struct iw_request_info *info,
1025 struct iw_param *rrq, char *extra)
1027 wlandevice_t *wlandev = dev->ml_priv;
1028 p80211item_uint32_t mibitem;
1029 p80211msg_dot11req_mibset_t msg;
1032 UINT16 shortretry, longretry, lifetime;
1036 msg.msgcode = DIDmsg_dot11req_mibget;
1037 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
1039 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1040 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1047 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
1049 shortretry = mibitem.data;
1051 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
1053 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1054 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1061 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
1063 longretry = mibitem.data;
1065 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
1067 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1068 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1075 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
1077 lifetime = mibitem.data;
1081 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1082 rrq->flags = IW_RETRY_LIFETIME;
1083 rrq->value = lifetime * 1024;
1085 if (rrq->flags & IW_RETRY_LONG) {
1086 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1087 rrq->value = longretry;
1089 rrq->flags = IW_RETRY_LIMIT;
1090 rrq->value = shortretry;
1091 if (shortretry != longretry)
1092 rrq->flags |= IW_RETRY_SHORT;
1102 static int p80211wext_siwretry(netdevice_t *dev,
1103 struct iw_request_info *info,
1104 struct iw_param *rrq, char *extra)
1106 wlandevice_t *wlandev = dev->ml_priv;
1107 p80211item_uint32_t mibitem;
1108 p80211msg_dot11req_mibset_t msg;
1114 if (!wlan_wext_write) {
1115 err = (-EOPNOTSUPP);
1119 if (rrq->disabled) {
1124 msg.msgcode = DIDmsg_dot11req_mibset;
1126 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1127 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11MaxTransmitMSDULifetime;
1128 mibitem.data = rrq->value /= 1024;
1130 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1131 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1138 if (rrq->flags & IW_RETRY_LONG) {
1139 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11LongRetryLimit;
1140 mibitem.data = rrq->value;
1142 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1143 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1151 if (rrq->flags & IW_RETRY_SHORT) {
1152 mibitem.did = DIDmib_dot11mac_dot11OperationTable_dot11ShortRetryLimit;
1153 mibitem.data = rrq->value;
1155 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1156 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1171 static int p80211wext_siwtxpow(netdevice_t *dev,
1172 struct iw_request_info *info,
1173 struct iw_param *rrq, char *extra)
1175 wlandevice_t *wlandev = dev->ml_priv;
1176 p80211item_uint32_t mibitem;
1177 p80211msg_dot11req_mibset_t msg;
1183 if (!wlan_wext_write) {
1184 err = (-EOPNOTSUPP);
1188 msg.msgcode = DIDmsg_dot11req_mibset;
1190 switch (rrq->value) {
1192 case 1 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel1; break;
1193 case 2 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel2; break;
1194 case 3 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel3; break;
1195 case 4 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel4; break;
1196 case 5 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel5; break;
1197 case 6 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel6; break;
1198 case 7 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel7; break;
1199 case 8 : mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
1200 default: mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11TxPowerLevel8; break;
1203 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1204 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1216 static int p80211wext_giwtxpow(netdevice_t *dev,
1217 struct iw_request_info *info,
1218 struct iw_param *rrq, char *extra)
1220 wlandevice_t *wlandev = dev->ml_priv;
1221 p80211item_uint32_t mibitem;
1222 p80211msg_dot11req_mibset_t msg;
1228 msg.msgcode = DIDmsg_dot11req_mibget;
1229 mibitem.did = DIDmib_dot11phy_dot11PhyTxPowerTable_dot11CurrentTxPowerLevel;
1231 memcpy(&msg.mibattribute.data, &mibitem, sizeof(mibitem));
1232 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1239 memcpy(&mibitem, &msg.mibattribute.data, sizeof(mibitem));
1241 // XXX handle OFF by setting disabled = 1;
1243 rrq->flags = 0; // IW_TXPOW_DBM;
1246 rrq->value = mibitem.data;
1253 static int p80211wext_siwspy(netdevice_t *dev,
1254 struct iw_request_info *info,
1255 struct iw_point *srq, char *extra)
1257 wlandevice_t *wlandev = dev->ml_priv;
1258 struct sockaddr address[IW_MAX_SPY];
1259 int number = srq->length;
1264 /* Copy the data from the input buffer */
1265 memcpy(address, extra, sizeof(struct sockaddr)*number);
1267 wlandev->spy_number = 0;
1271 /* extract the addresses */
1272 for (i = 0; i < number; i++) {
1274 memcpy(wlandev->spy_address[i], address[i].sa_data, ETH_ALEN);
1278 memset(wlandev->spy_stat, 0, sizeof(struct iw_quality) * IW_MAX_SPY);
1280 /* set number of addresses */
1281 wlandev->spy_number = number;
1288 /* jkriegl: from orinoco, modified */
1289 static int p80211wext_giwspy(netdevice_t *dev,
1290 struct iw_request_info *info,
1291 struct iw_point *srq, char *extra)
1293 wlandevice_t *wlandev = dev->ml_priv;
1295 struct sockaddr address[IW_MAX_SPY];
1296 struct iw_quality spy_stat[IW_MAX_SPY];
1302 number = wlandev->spy_number;
1306 /* populate address and spy struct's */
1307 for (i = 0; i < number; i++) {
1308 memcpy(address[i].sa_data, wlandev->spy_address[i], ETH_ALEN);
1309 address[i].sa_family = AF_UNIX;
1310 memcpy(&spy_stat[i], &wlandev->spy_stat[i], sizeof(struct iw_quality));
1313 /* reset update flag */
1314 for (i=0; i < number; i++)
1315 wlandev->spy_stat[i].updated = 0;
1318 /* push stuff to user space */
1319 srq->length = number;
1320 memcpy(extra, address, sizeof(struct sockaddr)*number);
1321 memcpy(extra+sizeof(struct sockaddr)*number, spy_stat, sizeof(struct iw_quality)*number);
1327 static int prism2_result2err (int prism2_result)
1331 switch (prism2_result) {
1332 case P80211ENUM_resultcode_invalid_parameters:
1335 case P80211ENUM_resultcode_implementation_failure:
1338 case P80211ENUM_resultcode_not_supported:
1349 static int p80211wext_siwscan(netdevice_t *dev,
1350 struct iw_request_info *info,
1351 struct iw_point *srq, char *extra)
1353 wlandevice_t *wlandev = dev->ml_priv;
1354 p80211msg_dot11req_scan_t msg;
1361 if (wlandev->macmode == WLAN_MACMODE_ESS_AP) {
1362 WLAN_LOG_ERROR("Can't scan in AP mode\n");
1363 err = (-EOPNOTSUPP);
1367 memset(&msg, 0x00, sizeof(p80211msg_dot11req_scan_t));
1368 msg.msgcode = DIDmsg_dot11req_scan;
1369 msg.bsstype.data = P80211ENUM_bsstype_any;
1371 memset(&(msg.bssid.data), 0xFF, sizeof (p80211item_pstr6_t));
1372 msg.bssid.data.len = 6;
1374 msg.scantype.data = P80211ENUM_scantype_active;
1375 msg.probedelay.data = 0;
1377 for (i = 1; i <= 14; i++)
1378 msg.channellist.data.data[i-1] = i;
1379 msg.channellist.data.len = 14;
1381 msg.maxchanneltime.data = 250;
1382 msg.minchanneltime.data = 200;
1384 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1386 err = prism2_result2err (msg.resultcode.data);
1394 /* Helper to translate scan into Wireless Extensions scan results.
1395 * Inspired by the prism54 code, which was in turn inspired by the
1399 wext_translate_bss(struct iw_request_info *info, char *current_ev,
1400 char *end_buf, p80211msg_dot11req_scan_results_t *bss)
1402 struct iw_event iwe; /* Temporary buffer */
1404 /* The first entry must be the MAC address */
1405 memcpy(iwe.u.ap_addr.sa_data, bss->bssid.data.data, WLAN_BSSID_LEN);
1406 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1407 iwe.cmd = SIOCGIWAP;
1408 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
1410 /* The following entries will be displayed in the same order we give them */
1413 if (bss->ssid.data.len > 0) {
1414 char essid[IW_ESSID_MAX_SIZE + 1];
1417 size = wlan_min(IW_ESSID_MAX_SIZE, bss->ssid.data.len);
1418 memset(&essid, 0, sizeof (essid));
1419 memcpy(&essid, bss->ssid.data.data, size);
1420 WLAN_LOG_DEBUG(1, " essid size = %d\n", size);
1421 iwe.u.data.length = size;
1422 iwe.u.data.flags = 1;
1423 iwe.cmd = SIOCGIWESSID;
1424 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, &essid[0]);
1425 WLAN_LOG_DEBUG(1, " essid size OK.\n");
1428 switch (bss->bsstype.data) {
1429 case P80211ENUM_bsstype_infrastructure:
1430 iwe.u.mode = IW_MODE_MASTER;
1433 case P80211ENUM_bsstype_independent:
1434 iwe.u.mode = IW_MODE_ADHOC;
1441 iwe.cmd = SIOCGIWMODE;
1443 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
1445 /* Encryption capability */
1446 if (bss->privacy.data == P80211ENUM_truth_true)
1447 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1449 iwe.u.data.flags = IW_ENCODE_DISABLED;
1450 iwe.u.data.length = 0;
1451 iwe.cmd = SIOCGIWENCODE;
1452 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, NULL);
1454 /* Add frequency. (short) bss->channel is the frequency in MHz */
1455 iwe.u.freq.m = bss->dschannel.data;
1457 iwe.cmd = SIOCGIWFREQ;
1458 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
1460 /* Add quality statistics */
1461 iwe.u.qual.level = bss->signal.data;
1462 iwe.u.qual.noise = bss->noise.data;
1463 /* do a simple SNR for quality */
1464 iwe.u.qual.qual = qual_as_percent(bss->signal.data - bss->noise.data);
1466 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
1472 static int p80211wext_giwscan(netdevice_t *dev,
1473 struct iw_request_info *info,
1474 struct iw_point *srq, char *extra)
1476 wlandevice_t *wlandev = dev->ml_priv;
1477 p80211msg_dot11req_scan_results_t msg;
1482 char *current_ev = extra;
1486 /* Since wireless tools doesn't really have a way of passing how
1487 * many scan results results there were back here, keep grabbing them
1491 memset(&msg, 0, sizeof(msg));
1492 msg.msgcode = DIDmsg_dot11req_scan_results;
1493 msg.bssindex.data = i;
1495 result = p80211req_dorequest(wlandev, (UINT8*)&msg);
1496 if ((result != 0) ||
1497 (msg.resultcode.data != P80211ENUM_resultcode_success)) {
1501 current_ev = wext_translate_bss(info, current_ev, extra + IW_SCAN_MAX_DATA, &msg);
1504 } while (i < IW_MAX_AP);
1506 srq->length = (current_ev - extra);
1507 srq->flags = 0; /* todo */
1509 if (result && !scan_good)
1510 err = prism2_result2err (msg.resultcode.data);
1516 /*****************************************************/
1517 //extra wireless extensions stuff to support NetworkManager (I hope)
1519 /* SIOCSIWENCODEEXT */
1520 static int p80211wext_set_encodeext(struct net_device *dev,
1521 struct iw_request_info *info,
1522 union iwreq_data *wrqu, char *extra)
1524 wlandevice_t *wlandev = dev->ml_priv;
1525 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1526 p80211msg_dot11req_mibset_t msg;
1527 p80211item_pstr32_t *pstr;
1530 struct iw_point *encoding = &wrqu->encoding;
1531 int idx = encoding->flags & IW_ENCODE_INDEX;
1533 WLAN_LOG_DEBUG(1,"set_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
1536 if ( ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY ) {
1537 // set default key ? I'm not sure if this the the correct thing to do here
1540 if (idx < 1 || idx > NUM_WEPKEYS) {
1545 WLAN_LOG_DEBUG(1,"setting default key (%d)\n",idx);
1546 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11WEPDefaultKeyID, idx);
1552 if ( ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY ) {
1553 if (!(ext->alg & IW_ENCODE_ALG_WEP)) {
1554 WLAN_LOG_DEBUG(1,"asked to set a non wep key :(");
1558 if (idx <1 || idx > NUM_WEPKEYS)
1563 WLAN_LOG_DEBUG(1,"Set WEP key (%d)\n",idx);
1564 wlandev->wep_keylens[idx] = ext->key_len;
1565 memcpy(wlandev->wep_keys[idx], ext->key, ext->key_len);
1567 memset( &msg,0,sizeof(msg));
1568 pstr = (p80211item_pstr32_t*)&msg.mibattribute.data;
1569 memcpy(pstr->data.data, ext->key,ext->key_len);
1570 pstr->data.len = ext->key_len;
1573 pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey0;
1576 pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey1;
1579 pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey2;
1582 pstr->did = DIDmib_dot11smt_dot11WEPDefaultKeysTable_dot11WEPDefaultKey3;
1587 msg.msgcode = DIDmsg_dot11req_mibset;
1588 result = p80211req_dorequest(wlandev,(UINT8*)&msg);
1589 WLAN_LOG_DEBUG(1,"result (%d)\n",result);
1594 /* SIOCGIWENCODEEXT */
1595 static int p80211wext_get_encodeext(struct net_device *dev,
1596 struct iw_request_info *info,
1597 union iwreq_data *wrqu, char *extra)
1600 wlandevice_t *wlandev = dev->ml_priv;
1601 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1603 struct iw_point *encoding = &wrqu->encoding;
1610 WLAN_LOG_DEBUG(1,"get_encode_ext flags[%d] alg[%d] keylen[%d]\n",ext->ext_flags,(int)ext->alg,(int)ext->key_len);
1613 max_len = encoding->length - sizeof(*ext);
1614 if ( max_len <= 0) {
1615 WLAN_LOG_DEBUG(1,"get_encodeext max_len [%d] invalid\n",max_len);
1619 idx = encoding->flags & IW_ENCODE_INDEX;
1621 WLAN_LOG_DEBUG(1,"get_encode_ext index [%d]\n",idx);
1624 if (idx < 1 || idx > NUM_WEPKEYS ) {
1625 WLAN_LOG_DEBUG(1,"get_encode_ext invalid key index [%d]\n",idx);
1631 /* default key ? not sure what to do */
1632 /* will just use key[0] for now ! FIX ME */
1635 encoding->flags = idx + 1;
1636 memset(ext,0,sizeof(*ext));
1638 ext->alg = IW_ENCODE_ALG_WEP;
1639 ext->key_len = wlandev->wep_keylens[idx];
1640 memcpy( ext->key, wlandev->wep_keys[idx] , ext->key_len );
1642 encoding->flags |= IW_ENCODE_ENABLED;
1651 static int p80211_wext_set_iwauth (struct net_device *dev,
1652 struct iw_request_info *info,
1653 union iwreq_data *wrqu, char *extra)
1655 wlandevice_t *wlandev = dev->ml_priv;
1656 struct iw_param *param = &wrqu->param;
1659 WLAN_LOG_DEBUG(1,"set_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
1661 switch (param->flags & IW_AUTH_INDEX) {
1662 case IW_AUTH_DROP_UNENCRYPTED:
1663 WLAN_LOG_DEBUG(1,"drop_unencrypted %d\n",param->value);
1665 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_true);
1667 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11ExcludeUnencrypted, P80211ENUM_truth_false);
1670 case IW_AUTH_PRIVACY_INVOKED:
1671 WLAN_LOG_DEBUG(1,"privacy invoked %d\n",param->value);
1673 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_true);
1675 result = p80211wext_dorequest(wlandev, DIDmib_dot11smt_dot11PrivacyTable_dot11PrivacyInvoked, P80211ENUM_truth_false);
1679 case IW_AUTH_80211_AUTH_ALG:
1680 if ( param->value & IW_AUTH_ALG_OPEN_SYSTEM ) {
1681 WLAN_LOG_DEBUG(1,"set open_system\n");
1682 wlandev->hostwep &= ~HOSTWEP_SHAREDKEY;
1683 } else if ( param->value & IW_AUTH_ALG_SHARED_KEY) {
1684 WLAN_LOG_DEBUG(1,"set shared key\n");
1685 wlandev->hostwep |= HOSTWEP_SHAREDKEY;
1687 /* don't know what to do know :( */
1688 WLAN_LOG_DEBUG(1,"unknown AUTH_ALG (%d)\n",param->value);
1703 static int p80211_wext_get_iwauth (struct net_device *dev,
1704 struct iw_request_info *info,
1705 union iwreq_data *wrqu, char *extra)
1707 wlandevice_t *wlandev = dev->ml_priv;
1708 struct iw_param *param = &wrqu->param;
1711 WLAN_LOG_DEBUG(1,"get_iwauth flags[%d]\n",(int)param->flags & IW_AUTH_INDEX );
1713 switch (param->flags & IW_AUTH_INDEX) {
1714 case IW_AUTH_DROP_UNENCRYPTED:
1715 param->value = wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED?1:0;
1718 case IW_AUTH_PRIVACY_INVOKED:
1719 param->value = wlandev->hostwep & HOSTWEP_PRIVACYINVOKED?1:0;
1722 case IW_AUTH_80211_AUTH_ALG:
1723 param->value = wlandev->hostwep & HOSTWEP_SHAREDKEY?IW_AUTH_ALG_SHARED_KEY:IW_AUTH_ALG_OPEN_SYSTEM;
1736 static iw_handler p80211wext_handlers[] = {
1737 (iw_handler) p80211wext_siwcommit, /* SIOCSIWCOMMIT */
1738 (iw_handler) p80211wext_giwname, /* SIOCGIWNAME */
1739 (iw_handler) NULL, /* SIOCSIWNWID */
1740 (iw_handler) NULL, /* SIOCGIWNWID */
1741 (iw_handler) p80211wext_siwfreq, /* SIOCSIWFREQ */
1742 (iw_handler) p80211wext_giwfreq, /* SIOCGIWFREQ */
1743 (iw_handler) p80211wext_siwmode, /* SIOCSIWMODE */
1744 (iw_handler) p80211wext_giwmode, /* SIOCGIWMODE */
1745 (iw_handler) NULL, /* SIOCSIWSENS */
1746 (iw_handler) NULL, /* SIOCGIWSENS */
1747 (iw_handler) NULL, /* not used */ /* SIOCSIWRANGE */
1748 (iw_handler) p80211wext_giwrange, /* SIOCGIWRANGE */
1749 (iw_handler) NULL, /* not used */ /* SIOCSIWPRIV */
1750 (iw_handler) NULL, /* kernel code */ /* SIOCGIWPRIV */
1751 (iw_handler) NULL, /* not used */ /* SIOCSIWSTATS */
1752 (iw_handler) NULL, /* kernel code */ /* SIOCGIWSTATS */
1753 (iw_handler) p80211wext_siwspy, /* SIOCSIWSPY */
1754 (iw_handler) p80211wext_giwspy, /* SIOCGIWSPY */
1755 (iw_handler) NULL, /* -- hole -- */
1756 (iw_handler) NULL, /* -- hole -- */
1757 (iw_handler) NULL, /* SIOCSIWAP */
1758 (iw_handler) p80211wext_giwap, /* SIOCGIWAP */
1759 (iw_handler) NULL, /* -- hole -- */
1760 (iw_handler) NULL, /* SIOCGIWAPLIST */
1761 (iw_handler) p80211wext_siwscan, /* SIOCSIWSCAN */
1762 (iw_handler) p80211wext_giwscan, /* SIOCGIWSCAN */
1763 (iw_handler) NULL, /* null */ /* SIOCSIWSCAN */
1764 (iw_handler) NULL, /* null */ /* SIOCGIWSCAN */
1765 (iw_handler) p80211wext_siwessid, /* SIOCSIWESSID */
1766 (iw_handler) p80211wext_giwessid, /* SIOCGIWESSID */
1767 (iw_handler) NULL, /* SIOCSIWNICKN */
1768 (iw_handler) p80211wext_giwessid, /* SIOCGIWNICKN */
1769 (iw_handler) NULL, /* -- hole -- */
1770 (iw_handler) NULL, /* -- hole -- */
1771 (iw_handler) NULL, /* SIOCSIWRATE */
1772 (iw_handler) p80211wext_giwrate, /* SIOCGIWRATE */
1773 (iw_handler) p80211wext_siwrts, /* SIOCSIWRTS */
1774 (iw_handler) p80211wext_giwrts, /* SIOCGIWRTS */
1775 (iw_handler) p80211wext_siwfrag, /* SIOCSIWFRAG */
1776 (iw_handler) p80211wext_giwfrag, /* SIOCGIWFRAG */
1777 (iw_handler) p80211wext_siwtxpow, /* SIOCSIWTXPOW */
1778 (iw_handler) p80211wext_giwtxpow, /* SIOCGIWTXPOW */
1779 (iw_handler) p80211wext_siwretry, /* SIOCSIWRETRY */
1780 (iw_handler) p80211wext_giwretry, /* SIOCGIWRETRY */
1781 (iw_handler) p80211wext_siwencode, /* SIOCSIWENCODE */
1782 (iw_handler) p80211wext_giwencode, /* SIOCGIWENCODE */
1783 (iw_handler) NULL, /* SIOCSIWPOWER */
1784 (iw_handler) NULL, /* SIOCGIWPOWER */
1785 /* WPA operations */
1786 (iw_handler) NULL, /* -- hole -- */
1787 (iw_handler) NULL, /* -- hole -- */
1788 (iw_handler) NULL, /* SIOCSIWGENIE set generic IE */
1789 (iw_handler) NULL, /* SIOCGIWGENIE get generic IE */
1790 (iw_handler) p80211_wext_set_iwauth, /* SIOCSIWAUTH set authentication mode params */
1791 (iw_handler) p80211_wext_get_iwauth, /* SIOCGIWAUTH get authentication mode params */
1793 (iw_handler) p80211wext_set_encodeext, /* SIOCSIWENCODEEXT set encoding token & mode */
1794 (iw_handler) p80211wext_get_encodeext, /* SIOCGIWENCODEEXT get encoding token & mode */
1795 (iw_handler) NULL, /* SIOCSIWPMKSA PMKSA cache operation */
1798 struct iw_handler_def p80211wext_handler_def = {
1799 .num_standard = sizeof(p80211wext_handlers) / sizeof(iw_handler),
1801 .num_private_args = 0,
1802 .standard = p80211wext_handlers,
1804 .private_args = NULL,
1805 .get_wireless_stats = p80211wext_get_wireless_stats
1809 int p80211wext_event_associated(wlandevice_t *wlandev, int assoc)
1811 union iwreq_data data;
1815 /* Send the association state first */
1816 data.ap_addr.sa_family = ARPHRD_ETHER;
1818 memcpy(data.ap_addr.sa_data, wlandev->bssid, WLAN_ADDR_LEN);
1820 memset(data.ap_addr.sa_data, 0, WLAN_ADDR_LEN);
1823 if (wlan_wext_write)
1824 wireless_send_event(wlandev->netdev, SIOCGIWAP, &data, NULL);
1826 if (!assoc) goto done;
1828 // XXX send association data, like IEs, etc etc.
1836 #endif /* compatibility to wireless extensions */